xref: /dpdk/examples/l3fwd/l3fwd_lpm.h (revision 4b01cabfb09b3284826c0134a5f1356c59dea24b)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2010-2016 Intel Corporation
3  */
4 
5 #ifndef __L3FWD_LPM_H__
6 #define __L3FWD_LPM_H__
7 
8 static __rte_always_inline void
l3fwd_lpm_simple_forward(struct rte_mbuf * m,uint16_t portid,struct lcore_conf * qconf)9 l3fwd_lpm_simple_forward(struct rte_mbuf *m, uint16_t portid,
10 		struct lcore_conf *qconf)
11 {
12 	struct rte_ether_hdr *eth_hdr;
13 	struct rte_ipv4_hdr *ipv4_hdr;
14 	uint16_t dst_port;
15 
16 	eth_hdr = rte_pktmbuf_mtod(m, struct rte_ether_hdr *);
17 
18 	if (RTE_ETH_IS_IPV4_HDR(m->packet_type)) {
19 		/* Handle IPv4 headers.*/
20 		ipv4_hdr = rte_pktmbuf_mtod_offset(m, struct rte_ipv4_hdr *,
21 						sizeof(struct rte_ether_hdr));
22 
23 #ifdef DO_RFC_1812_CHECKS
24 		/* Check to make sure the packet is valid (RFC1812) */
25 		if (is_valid_ipv4_pkt(ipv4_hdr, m->pkt_len, m->ol_flags) < 0) {
26 			rte_pktmbuf_free(m);
27 			return;
28 		}
29 #endif
30 		 dst_port = lpm_get_ipv4_dst_port(ipv4_hdr, portid,
31 						qconf->ipv4_lookup_struct);
32 
33 		if (dst_port >= RTE_MAX_ETHPORTS ||
34 			(enabled_port_mask & 1 << dst_port) == 0)
35 			dst_port = portid;
36 
37 #ifdef DO_RFC_1812_CHECKS
38 		/* Update time to live and header checksum */
39 		--(ipv4_hdr->time_to_live);
40 		++(ipv4_hdr->hdr_checksum);
41 #endif
42 		/* dst addr */
43 		*(uint64_t *)&eth_hdr->dst_addr = dest_eth_addr[dst_port];
44 
45 		/* src addr */
46 		rte_ether_addr_copy(&ports_eth_addr[dst_port],
47 				&eth_hdr->src_addr);
48 
49 		send_single_packet(qconf, m, dst_port);
50 	} else if (RTE_ETH_IS_IPV6_HDR(m->packet_type)) {
51 		/* Handle IPv6 headers.*/
52 		struct rte_ipv6_hdr *ipv6_hdr;
53 
54 		ipv6_hdr = rte_pktmbuf_mtod_offset(m, struct rte_ipv6_hdr *,
55 						sizeof(struct rte_ether_hdr));
56 
57 		dst_port = lpm_get_ipv6_dst_port(ipv6_hdr, portid,
58 					qconf->ipv6_lookup_struct);
59 
60 		if (dst_port >= RTE_MAX_ETHPORTS ||
61 			(enabled_port_mask & 1 << dst_port) == 0)
62 			dst_port = portid;
63 
64 		/* dst addr */
65 		*(uint64_t *)&eth_hdr->dst_addr = dest_eth_addr[dst_port];
66 
67 		/* src addr */
68 		rte_ether_addr_copy(&ports_eth_addr[dst_port],
69 				&eth_hdr->src_addr);
70 
71 		send_single_packet(qconf, m, dst_port);
72 	} else {
73 		/* Free the mbuf that contains non-IPV4/IPV6 packet */
74 		rte_pktmbuf_free(m);
75 	}
76 }
77 
78 static inline void
l3fwd_lpm_no_opt_send_packets(int nb_rx,struct rte_mbuf ** pkts_burst,uint16_t portid,struct lcore_conf * qconf)79 l3fwd_lpm_no_opt_send_packets(int nb_rx, struct rte_mbuf **pkts_burst,
80 				uint16_t portid, struct lcore_conf *qconf)
81 {
82 	int32_t j;
83 
84 	/* Prefetch first packets */
85 	for (j = 0; j < PREFETCH_OFFSET && j < nb_rx; j++)
86 		rte_prefetch0(rte_pktmbuf_mtod(pkts_burst[j], void *));
87 
88 	/* Prefetch and forward already prefetched packets. */
89 	for (j = 0; j < (nb_rx - PREFETCH_OFFSET); j++) {
90 		rte_prefetch0(rte_pktmbuf_mtod(pkts_burst[
91 				j + PREFETCH_OFFSET], void *));
92 		l3fwd_lpm_simple_forward(pkts_burst[j], portid, qconf);
93 	}
94 
95 	/* Forward remaining prefetched packets */
96 	for (; j < nb_rx; j++)
97 		l3fwd_lpm_simple_forward(pkts_burst[j], portid, qconf);
98 }
99 
100 #endif /* __L3FWD_LPM_H__ */
101