]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | /*- |
2 | * BSD LICENSE | |
3 | * | |
4 | * Copyright(c) 2010-2016 Intel Corporation. All rights reserved. | |
5 | * All rights reserved. | |
6 | * | |
7 | * Redistribution and use in source and binary forms, with or without | |
8 | * modification, are permitted provided that the following conditions | |
9 | * are met: | |
10 | * | |
11 | * * Redistributions of source code must retain the above copyright | |
12 | * notice, this list of conditions and the following disclaimer. | |
13 | * * Redistributions in binary form must reproduce the above copyright | |
14 | * notice, this list of conditions and the following disclaimer in | |
15 | * the documentation and/or other materials provided with the | |
16 | * distribution. | |
17 | * * Neither the name of Intel Corporation nor the names of its | |
18 | * contributors may be used to endorse or promote products derived | |
19 | * from this software without specific prior written permission. | |
20 | * | |
21 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
22 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
23 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |
24 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |
25 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
26 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |
27 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
28 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
29 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
30 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
31 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
32 | */ | |
33 | ||
34 | #ifndef __L3FWD_EM_H__ | |
35 | #define __L3FWD_EM_H__ | |
36 | ||
37 | static inline __attribute__((always_inline)) void | |
38 | l3fwd_em_simple_forward(struct rte_mbuf *m, uint8_t portid, | |
39 | struct lcore_conf *qconf) | |
40 | { | |
41 | struct ether_hdr *eth_hdr; | |
42 | struct ipv4_hdr *ipv4_hdr; | |
43 | uint8_t dst_port; | |
44 | uint32_t tcp_or_udp; | |
45 | uint32_t l3_ptypes; | |
46 | ||
47 | eth_hdr = rte_pktmbuf_mtod(m, struct ether_hdr *); | |
48 | tcp_or_udp = m->packet_type & (RTE_PTYPE_L4_TCP | RTE_PTYPE_L4_UDP); | |
49 | l3_ptypes = m->packet_type & RTE_PTYPE_L3_MASK; | |
50 | ||
51 | if (tcp_or_udp && (l3_ptypes == RTE_PTYPE_L3_IPV4)) { | |
52 | /* Handle IPv4 headers.*/ | |
53 | ipv4_hdr = rte_pktmbuf_mtod_offset(m, struct ipv4_hdr *, | |
54 | sizeof(struct ether_hdr)); | |
55 | ||
56 | #ifdef DO_RFC_1812_CHECKS | |
57 | /* Check to make sure the packet is valid (RFC1812) */ | |
58 | if (is_valid_ipv4_pkt(ipv4_hdr, m->pkt_len) < 0) { | |
59 | rte_pktmbuf_free(m); | |
60 | return; | |
61 | } | |
62 | #endif | |
63 | dst_port = em_get_ipv4_dst_port(ipv4_hdr, portid, | |
64 | qconf->ipv4_lookup_struct); | |
65 | ||
66 | if (dst_port >= RTE_MAX_ETHPORTS || | |
67 | (enabled_port_mask & 1 << dst_port) == 0) | |
68 | dst_port = portid; | |
69 | ||
70 | #ifdef DO_RFC_1812_CHECKS | |
71 | /* Update time to live and header checksum */ | |
72 | --(ipv4_hdr->time_to_live); | |
73 | ++(ipv4_hdr->hdr_checksum); | |
74 | #endif | |
75 | /* dst addr */ | |
76 | *(uint64_t *)ð_hdr->d_addr = dest_eth_addr[dst_port]; | |
77 | ||
78 | /* src addr */ | |
79 | ether_addr_copy(&ports_eth_addr[dst_port], ð_hdr->s_addr); | |
80 | ||
81 | send_single_packet(qconf, m, dst_port); | |
82 | } else if (tcp_or_udp && (l3_ptypes == RTE_PTYPE_L3_IPV6)) { | |
83 | /* Handle IPv6 headers.*/ | |
84 | struct ipv6_hdr *ipv6_hdr; | |
85 | ||
86 | ipv6_hdr = rte_pktmbuf_mtod_offset(m, struct ipv6_hdr *, | |
87 | sizeof(struct ether_hdr)); | |
88 | ||
89 | dst_port = em_get_ipv6_dst_port(ipv6_hdr, portid, | |
90 | qconf->ipv6_lookup_struct); | |
91 | ||
92 | if (dst_port >= RTE_MAX_ETHPORTS || | |
93 | (enabled_port_mask & 1 << dst_port) == 0) | |
94 | dst_port = portid; | |
95 | ||
96 | /* dst addr */ | |
97 | *(uint64_t *)ð_hdr->d_addr = dest_eth_addr[dst_port]; | |
98 | ||
99 | /* src addr */ | |
100 | ether_addr_copy(&ports_eth_addr[dst_port], ð_hdr->s_addr); | |
101 | ||
102 | send_single_packet(qconf, m, dst_port); | |
103 | } else { | |
104 | /* Free the mbuf that contains non-IPV4/IPV6 packet */ | |
105 | rte_pktmbuf_free(m); | |
106 | } | |
107 | } | |
108 | ||
109 | /* | |
110 | * Buffer non-optimized handling of packets, invoked | |
111 | * from main_loop. | |
112 | */ | |
113 | static inline void | |
114 | l3fwd_em_no_opt_send_packets(int nb_rx, struct rte_mbuf **pkts_burst, | |
115 | uint8_t portid, struct lcore_conf *qconf) | |
116 | { | |
117 | int32_t j; | |
118 | ||
119 | /* Prefetch first packets */ | |
120 | for (j = 0; j < PREFETCH_OFFSET && j < nb_rx; j++) | |
121 | rte_prefetch0(rte_pktmbuf_mtod(pkts_burst[j], void *)); | |
122 | ||
123 | /* | |
124 | * Prefetch and forward already prefetched | |
125 | * packets. | |
126 | */ | |
127 | for (j = 0; j < (nb_rx - PREFETCH_OFFSET); j++) { | |
128 | rte_prefetch0(rte_pktmbuf_mtod(pkts_burst[ | |
129 | j + PREFETCH_OFFSET], void *)); | |
130 | l3fwd_em_simple_forward(pkts_burst[j], portid, qconf); | |
131 | } | |
132 | ||
133 | /* Forward remaining prefetched packets */ | |
134 | for (; j < nb_rx; j++) | |
135 | l3fwd_em_simple_forward(pkts_burst[j], portid, qconf); | |
136 | } | |
137 | ||
138 | #endif /* __L3FWD_EM_H__ */ |