]>
Commit | Line | Data |
---|---|---|
9f95a23c TL |
1 | /* SPDX-License-Identifier: BSD-3-Clause |
2 | * Copyright(c) 2010-2016 Intel Corporation | |
7c673cae FG |
3 | */ |
4 | ||
5 | #ifndef __L3FWD_LPM_H__ | |
6 | #define __L3FWD_LPM_H__ | |
7 | ||
9f95a23c TL |
8 | static __rte_always_inline void |
9 | l3fwd_lpm_simple_forward(struct rte_mbuf *m, uint16_t portid, | |
7c673cae FG |
10 | struct lcore_conf *qconf) |
11 | { | |
12 | struct ether_hdr *eth_hdr; | |
13 | struct ipv4_hdr *ipv4_hdr; | |
9f95a23c | 14 | uint16_t dst_port; |
7c673cae FG |
15 | |
16 | eth_hdr = rte_pktmbuf_mtod(m, struct 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 ipv4_hdr *, | |
21 | sizeof(struct 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) < 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 *)ð_hdr->d_addr = dest_eth_addr[dst_port]; | |
44 | ||
45 | /* src addr */ | |
46 | ether_addr_copy(&ports_eth_addr[dst_port], ð_hdr->s_addr); | |
47 | ||
48 | send_single_packet(qconf, m, dst_port); | |
49 | } else if (RTE_ETH_IS_IPV6_HDR(m->packet_type)) { | |
50 | /* Handle IPv6 headers.*/ | |
51 | struct ipv6_hdr *ipv6_hdr; | |
52 | ||
53 | ipv6_hdr = rte_pktmbuf_mtod_offset(m, struct ipv6_hdr *, | |
54 | sizeof(struct ether_hdr)); | |
55 | ||
56 | dst_port = lpm_get_ipv6_dst_port(ipv6_hdr, portid, | |
57 | qconf->ipv6_lookup_struct); | |
58 | ||
59 | if (dst_port >= RTE_MAX_ETHPORTS || | |
60 | (enabled_port_mask & 1 << dst_port) == 0) | |
61 | dst_port = portid; | |
62 | ||
63 | /* dst addr */ | |
64 | *(uint64_t *)ð_hdr->d_addr = dest_eth_addr[dst_port]; | |
65 | ||
66 | /* src addr */ | |
67 | ether_addr_copy(&ports_eth_addr[dst_port], ð_hdr->s_addr); | |
68 | ||
69 | send_single_packet(qconf, m, dst_port); | |
70 | } else { | |
71 | /* Free the mbuf that contains non-IPV4/IPV6 packet */ | |
72 | rte_pktmbuf_free(m); | |
73 | } | |
74 | } | |
75 | ||
76 | static inline void | |
77 | l3fwd_lpm_no_opt_send_packets(int nb_rx, struct rte_mbuf **pkts_burst, | |
9f95a23c | 78 | uint16_t portid, struct lcore_conf *qconf) |
7c673cae FG |
79 | { |
80 | int32_t j; | |
81 | ||
82 | /* Prefetch first packets */ | |
83 | for (j = 0; j < PREFETCH_OFFSET && j < nb_rx; j++) | |
84 | rte_prefetch0(rte_pktmbuf_mtod(pkts_burst[j], void *)); | |
85 | ||
86 | /* Prefetch and forward already prefetched packets. */ | |
87 | for (j = 0; j < (nb_rx - PREFETCH_OFFSET); j++) { | |
88 | rte_prefetch0(rte_pktmbuf_mtod(pkts_burst[ | |
89 | j + PREFETCH_OFFSET], void *)); | |
90 | l3fwd_lpm_simple_forward(pkts_burst[j], portid, qconf); | |
91 | } | |
92 | ||
93 | /* Forward remaining prefetched packets */ | |
94 | for (; j < nb_rx; j++) | |
95 | l3fwd_lpm_simple_forward(pkts_burst[j], portid, qconf); | |
96 | } | |
97 | ||
98 | #endif /* __L3FWD_LPM_H__ */ |