File: | home/bhubbard/working/src/ceph/build/src/dpdk/include/rte_ip.h |
Warning: | line 212, column 8 Access to field 'buf_addr' results in a dereference of a null pointer (loaded from variable 'seg') |
[?] Use j/k keys for keyboard navigation
1 | /* SPDX-License-Identifier: BSD-3-Clause | |||||
2 | * Copyright(c) 1982, 1986, 1990, 1993 | |||||
3 | * The Regents of the University of California. | |||||
4 | * Copyright(c) 2010-2014 Intel Corporation. | |||||
5 | * Copyright(c) 2014 6WIND S.A. | |||||
6 | * All rights reserved. | |||||
7 | */ | |||||
8 | ||||||
9 | #ifndef _RTE_IP_H_ | |||||
10 | #define _RTE_IP_H_ | |||||
11 | ||||||
12 | /** | |||||
13 | * @file | |||||
14 | * | |||||
15 | * IP-related defines | |||||
16 | */ | |||||
17 | ||||||
18 | #include <stdint.h> | |||||
19 | #include <netinet/in.h> | |||||
20 | ||||||
21 | #include <rte_byteorder.h> | |||||
22 | #include <rte_mbuf.h> | |||||
23 | ||||||
24 | #ifdef __cplusplus | |||||
25 | extern "C" { | |||||
26 | #endif | |||||
27 | ||||||
28 | /** | |||||
29 | * IPv4 Header | |||||
30 | */ | |||||
31 | struct ipv4_hdr { | |||||
32 | uint8_t version_ihl; /**< version and header length */ | |||||
33 | uint8_t type_of_service; /**< type of service */ | |||||
34 | uint16_t total_length; /**< length of packet */ | |||||
35 | uint16_t packet_id; /**< packet ID */ | |||||
36 | uint16_t fragment_offset; /**< fragmentation offset */ | |||||
37 | uint8_t time_to_live; /**< time to live */ | |||||
38 | uint8_t next_proto_id; /**< protocol ID */ | |||||
39 | uint16_t hdr_checksum; /**< header checksum */ | |||||
40 | uint32_t src_addr; /**< source address */ | |||||
41 | uint32_t dst_addr; /**< destination address */ | |||||
42 | } __attribute__((__packed__)); | |||||
43 | ||||||
44 | /** Create IPv4 address */ | |||||
45 | #define IPv4(a,b,c,d)((uint32_t)(((a) & 0xff) << 24) | (((b) & 0xff) << 16) | (((c) & 0xff) << 8) | ((d) & 0xff )) ((uint32_t)(((a) & 0xff) << 24) | \ | |||||
46 | (((b) & 0xff) << 16) | \ | |||||
47 | (((c) & 0xff) << 8) | \ | |||||
48 | ((d) & 0xff)) | |||||
49 | ||||||
50 | /** Maximal IPv4 packet length (including a header) */ | |||||
51 | #define IPV4_MAX_PKT_LEN65535 65535 | |||||
52 | ||||||
53 | /** Internet header length mask for version_ihl field */ | |||||
54 | #define IPV4_HDR_IHL_MASK(0x0f) (0x0f) | |||||
55 | /** | |||||
56 | * Internet header length field multiplier (IHL field specifies overall header | |||||
57 | * length in number of 4-byte words) | |||||
58 | */ | |||||
59 | #define IPV4_IHL_MULTIPLIER(4) (4) | |||||
60 | ||||||
61 | /* Fragment Offset * Flags. */ | |||||
62 | #define IPV4_HDR_DF_SHIFT14 14 | |||||
63 | #define IPV4_HDR_MF_SHIFT13 13 | |||||
64 | #define IPV4_HDR_FO_SHIFT3 3 | |||||
65 | ||||||
66 | #define IPV4_HDR_DF_FLAG(1 << 14) (1 << IPV4_HDR_DF_SHIFT14) | |||||
67 | #define IPV4_HDR_MF_FLAG(1 << 13) (1 << IPV4_HDR_MF_SHIFT13) | |||||
68 | ||||||
69 | #define IPV4_HDR_OFFSET_MASK((1 << 13) - 1) ((1 << IPV4_HDR_MF_SHIFT13) - 1) | |||||
70 | ||||||
71 | #define IPV4_HDR_OFFSET_UNITS8 8 | |||||
72 | ||||||
73 | /* | |||||
74 | * IPv4 address types | |||||
75 | */ | |||||
76 | #define IPV4_ANY((uint32_t)0x00000000) ((uint32_t)0x00000000) /**< 0.0.0.0 */ | |||||
77 | #define IPV4_LOOPBACK((uint32_t)0x7f000001) ((uint32_t)0x7f000001) /**< 127.0.0.1 */ | |||||
78 | #define IPV4_BROADCAST((uint32_t)0xe0000000) ((uint32_t)0xe0000000) /**< 224.0.0.0 */ | |||||
79 | #define IPV4_ALLHOSTS_GROUP((uint32_t)0xe0000001) ((uint32_t)0xe0000001) /**< 224.0.0.1 */ | |||||
80 | #define IPV4_ALLRTRS_GROUP((uint32_t)0xe0000002) ((uint32_t)0xe0000002) /**< 224.0.0.2 */ | |||||
81 | #define IPV4_MAX_LOCAL_GROUP((uint32_t)0xe00000ff) ((uint32_t)0xe00000ff) /**< 224.0.0.255 */ | |||||
82 | ||||||
83 | /* | |||||
84 | * IPv4 Multicast-related macros | |||||
85 | */ | |||||
86 | #define IPV4_MIN_MCAST((uint32_t)(((224) & 0xff) << 24) | (((0) & 0xff ) << 16) | (((0) & 0xff) << 8) | ((0) & 0xff )) IPv4(224, 0, 0, 0)((uint32_t)(((224) & 0xff) << 24) | (((0) & 0xff ) << 16) | (((0) & 0xff) << 8) | ((0) & 0xff )) /**< Minimal IPv4-multicast address */ | |||||
87 | #define IPV4_MAX_MCAST((uint32_t)(((239) & 0xff) << 24) | (((255) & 0xff ) << 16) | (((255) & 0xff) << 8) | ((255) & 0xff)) IPv4(239, 255, 255, 255)((uint32_t)(((239) & 0xff) << 24) | (((255) & 0xff ) << 16) | (((255) & 0xff) << 8) | ((255) & 0xff)) /**< Maximum IPv4 multicast address */ | |||||
88 | ||||||
89 | #define IS_IPV4_MCAST(x)((x) >= ((uint32_t)(((224) & 0xff) << 24) | (((0 ) & 0xff) << 16) | (((0) & 0xff) << 8) | ( (0) & 0xff)) && (x) <= ((uint32_t)(((239) & 0xff) << 24) | (((255) & 0xff) << 16) | (((255 ) & 0xff) << 8) | ((255) & 0xff))) \ | |||||
90 | ((x) >= IPV4_MIN_MCAST((uint32_t)(((224) & 0xff) << 24) | (((0) & 0xff ) << 16) | (((0) & 0xff) << 8) | ((0) & 0xff )) && (x) <= IPV4_MAX_MCAST((uint32_t)(((239) & 0xff) << 24) | (((255) & 0xff ) << 16) | (((255) & 0xff) << 8) | ((255) & 0xff))) /**< check if IPv4 address is multicast */ | |||||
91 | ||||||
92 | /** | |||||
93 | * @internal Calculate a sum of all words in the buffer. | |||||
94 | * Helper routine for the rte_raw_cksum(). | |||||
95 | * | |||||
96 | * @param buf | |||||
97 | * Pointer to the buffer. | |||||
98 | * @param len | |||||
99 | * Length of the buffer. | |||||
100 | * @param sum | |||||
101 | * Initial value of the sum. | |||||
102 | * @return | |||||
103 | * sum += Sum of all words in the buffer. | |||||
104 | */ | |||||
105 | static inline uint32_t | |||||
106 | __rte_raw_cksum(const void *buf, size_t len, uint32_t sum) | |||||
107 | { | |||||
108 | /* workaround gcc strict-aliasing warning */ | |||||
109 | uintptr_t ptr = (uintptr_t)buf; | |||||
110 | typedef uint16_t __attribute__((__may_alias__)) u16_p; | |||||
111 | const u16_p *u16_buf = (const u16_p *)ptr; | |||||
112 | ||||||
113 | while (len >= (sizeof(*u16_buf) * 4)) { | |||||
114 | sum += u16_buf[0]; | |||||
115 | sum += u16_buf[1]; | |||||
116 | sum += u16_buf[2]; | |||||
117 | sum += u16_buf[3]; | |||||
118 | len -= sizeof(*u16_buf) * 4; | |||||
119 | u16_buf += 4; | |||||
120 | } | |||||
121 | while (len >= sizeof(*u16_buf)) { | |||||
122 | sum += *u16_buf; | |||||
123 | len -= sizeof(*u16_buf); | |||||
124 | u16_buf += 1; | |||||
125 | } | |||||
126 | ||||||
127 | /* if length is in odd bytes */ | |||||
128 | if (len == 1) | |||||
129 | sum += *((const uint8_t *)u16_buf); | |||||
130 | ||||||
131 | return sum; | |||||
132 | } | |||||
133 | ||||||
134 | /** | |||||
135 | * @internal Reduce a sum to the non-complemented checksum. | |||||
136 | * Helper routine for the rte_raw_cksum(). | |||||
137 | * | |||||
138 | * @param sum | |||||
139 | * Value of the sum. | |||||
140 | * @return | |||||
141 | * The non-complemented checksum. | |||||
142 | */ | |||||
143 | static inline uint16_t | |||||
144 | __rte_raw_cksum_reduce(uint32_t sum) | |||||
145 | { | |||||
146 | sum = ((sum & 0xffff0000) >> 16) + (sum & 0xffff); | |||||
147 | sum = ((sum & 0xffff0000) >> 16) + (sum & 0xffff); | |||||
148 | return (uint16_t)sum; | |||||
149 | } | |||||
150 | ||||||
151 | /** | |||||
152 | * Process the non-complemented checksum of a buffer. | |||||
153 | * | |||||
154 | * @param buf | |||||
155 | * Pointer to the buffer. | |||||
156 | * @param len | |||||
157 | * Length of the buffer. | |||||
158 | * @return | |||||
159 | * The non-complemented checksum. | |||||
160 | */ | |||||
161 | static inline uint16_t | |||||
162 | rte_raw_cksum(const void *buf, size_t len) | |||||
163 | { | |||||
164 | uint32_t sum; | |||||
165 | ||||||
166 | sum = __rte_raw_cksum(buf, len, 0); | |||||
167 | return __rte_raw_cksum_reduce(sum); | |||||
168 | } | |||||
169 | ||||||
170 | /** | |||||
171 | * Compute the raw (non complemented) checksum of a packet. | |||||
172 | * | |||||
173 | * @param m | |||||
174 | * The pointer to the mbuf. | |||||
175 | * @param off | |||||
176 | * The offset in bytes to start the checksum. | |||||
177 | * @param len | |||||
178 | * The length in bytes of the data to checksum. | |||||
179 | * @param cksum | |||||
180 | * A pointer to the checksum, filled on success. | |||||
181 | * @return | |||||
182 | * 0 on success, -1 on error (bad length or offset). | |||||
183 | */ | |||||
184 | static inline int | |||||
185 | rte_raw_cksum_mbuf(const struct rte_mbuf *m, uint32_t off, uint32_t len, | |||||
186 | uint16_t *cksum) | |||||
187 | { | |||||
188 | const struct rte_mbuf *seg; | |||||
189 | const char *buf; | |||||
190 | uint32_t sum, tmp; | |||||
191 | uint32_t seglen, done; | |||||
192 | ||||||
193 | /* easy case: all data in the first segment */ | |||||
194 | if (off + len <= rte_pktmbuf_data_len(m)((m)->data_len)) { | |||||
| ||||||
195 | *cksum = rte_raw_cksum(rte_pktmbuf_mtod_offset(m,((const char *)((char *)(m)->buf_addr + (m)->data_off + (off))) | |||||
196 | const char *, off)((const char *)((char *)(m)->buf_addr + (m)->data_off + (off))), len); | |||||
197 | return 0; | |||||
198 | } | |||||
199 | ||||||
200 | if (unlikely(off + len > rte_pktmbuf_pkt_len(m))__builtin_expect(!!(off + len > ((m)->pkt_len)), 0)) | |||||
201 | return -1; /* invalid params, return a dummy value */ | |||||
202 | ||||||
203 | /* else browse the segment to find offset */ | |||||
204 | seglen = 0; | |||||
205 | for (seg = m; seg != NULL((void*)0); seg = seg->next) { | |||||
206 | seglen = rte_pktmbuf_data_len(seg)((seg)->data_len); | |||||
207 | if (off < seglen) | |||||
208 | break; | |||||
209 | off -= seglen; | |||||
210 | } | |||||
211 | seglen -= off; | |||||
212 | buf = rte_pktmbuf_mtod_offset(seg, const char *, off)((const char *)((char *)(seg)->buf_addr + (seg)->data_off + (off))); | |||||
| ||||||
213 | if (seglen >= len) { | |||||
214 | /* all in one segment */ | |||||
215 | *cksum = rte_raw_cksum(buf, len); | |||||
216 | return 0; | |||||
217 | } | |||||
218 | ||||||
219 | /* hard case: process checksum of several segments */ | |||||
220 | sum = 0; | |||||
221 | done = 0; | |||||
222 | for (;;) { | |||||
223 | tmp = __rte_raw_cksum(buf, seglen, 0); | |||||
224 | if (done & 1) | |||||
225 | tmp = rte_bswap16((uint16_t)tmp)((uint16_t)(__builtin_constant_p((uint16_t)tmp) ? rte_constant_bswap16 ((uint16_t)tmp) : rte_arch_bswap16((uint16_t)tmp))); | |||||
226 | sum += tmp; | |||||
227 | done += seglen; | |||||
228 | if (done == len) | |||||
229 | break; | |||||
230 | seg = seg->next; | |||||
231 | buf = rte_pktmbuf_mtod(seg, const char *)((const char *)((char *)(seg)->buf_addr + (seg)->data_off + (0))); | |||||
232 | seglen = rte_pktmbuf_data_len(seg)((seg)->data_len); | |||||
233 | if (seglen > len - done) | |||||
234 | seglen = len - done; | |||||
235 | } | |||||
236 | ||||||
237 | *cksum = __rte_raw_cksum_reduce(sum); | |||||
238 | return 0; | |||||
239 | } | |||||
240 | ||||||
241 | /** | |||||
242 | * Process the IPv4 checksum of an IPv4 header. | |||||
243 | * | |||||
244 | * The checksum field must be set to 0 by the caller. | |||||
245 | * | |||||
246 | * @param ipv4_hdr | |||||
247 | * The pointer to the contiguous IPv4 header. | |||||
248 | * @return | |||||
249 | * The complemented checksum to set in the IP packet. | |||||
250 | */ | |||||
251 | static inline uint16_t | |||||
252 | rte_ipv4_cksum(const struct ipv4_hdr *ipv4_hdr) | |||||
253 | { | |||||
254 | uint16_t cksum; | |||||
255 | cksum = rte_raw_cksum(ipv4_hdr, sizeof(struct ipv4_hdr)); | |||||
256 | return (cksum == 0xffff) ? cksum : (uint16_t)~cksum; | |||||
257 | } | |||||
258 | ||||||
259 | /** | |||||
260 | * Process the pseudo-header checksum of an IPv4 header. | |||||
261 | * | |||||
262 | * The checksum field must be set to 0 by the caller. | |||||
263 | * | |||||
264 | * Depending on the ol_flags, the pseudo-header checksum expected by the | |||||
265 | * drivers is not the same. For instance, when TSO is enabled, the IP | |||||
266 | * payload length must not be included in the packet. | |||||
267 | * | |||||
268 | * When ol_flags is 0, it computes the standard pseudo-header checksum. | |||||
269 | * | |||||
270 | * @param ipv4_hdr | |||||
271 | * The pointer to the contiguous IPv4 header. | |||||
272 | * @param ol_flags | |||||
273 | * The ol_flags of the associated mbuf. | |||||
274 | * @return | |||||
275 | * The non-complemented checksum to set in the L4 header. | |||||
276 | */ | |||||
277 | static inline uint16_t | |||||
278 | rte_ipv4_phdr_cksum(const struct ipv4_hdr *ipv4_hdr, uint64_t ol_flags) | |||||
279 | { | |||||
280 | struct ipv4_psd_header { | |||||
281 | uint32_t src_addr; /* IP address of source host. */ | |||||
282 | uint32_t dst_addr; /* IP address of destination host. */ | |||||
283 | uint8_t zero; /* zero. */ | |||||
284 | uint8_t proto; /* L4 protocol type. */ | |||||
285 | uint16_t len; /* L4 length. */ | |||||
286 | } psd_hdr; | |||||
287 | ||||||
288 | psd_hdr.src_addr = ipv4_hdr->src_addr; | |||||
289 | psd_hdr.dst_addr = ipv4_hdr->dst_addr; | |||||
290 | psd_hdr.zero = 0; | |||||
291 | psd_hdr.proto = ipv4_hdr->next_proto_id; | |||||
292 | if (ol_flags & PKT_TX_TCP_SEG(1ULL << 50)) { | |||||
293 | psd_hdr.len = 0; | |||||
294 | } else { | |||||
295 | psd_hdr.len = rte_cpu_to_be_16(((uint16_t)(__builtin_constant_p((uint16_t)(((uint16_t)(__builtin_constant_p (ipv4_hdr->total_length) ? rte_constant_bswap16(ipv4_hdr-> total_length) : rte_arch_bswap16(ipv4_hdr->total_length))) - sizeof(struct ipv4_hdr))) ? rte_constant_bswap16((uint16_t )(((uint16_t)(__builtin_constant_p(ipv4_hdr->total_length) ? rte_constant_bswap16(ipv4_hdr->total_length) : rte_arch_bswap16 (ipv4_hdr->total_length))) - sizeof(struct ipv4_hdr))) : rte_arch_bswap16 ((uint16_t)(((uint16_t)(__builtin_constant_p(ipv4_hdr->total_length ) ? rte_constant_bswap16(ipv4_hdr->total_length) : rte_arch_bswap16 (ipv4_hdr->total_length))) - sizeof(struct ipv4_hdr))))) | |||||
296 | (uint16_t)(rte_be_to_cpu_16(ipv4_hdr->total_length)((uint16_t)(__builtin_constant_p((uint16_t)(((uint16_t)(__builtin_constant_p (ipv4_hdr->total_length) ? rte_constant_bswap16(ipv4_hdr-> total_length) : rte_arch_bswap16(ipv4_hdr->total_length))) - sizeof(struct ipv4_hdr))) ? rte_constant_bswap16((uint16_t )(((uint16_t)(__builtin_constant_p(ipv4_hdr->total_length) ? rte_constant_bswap16(ipv4_hdr->total_length) : rte_arch_bswap16 (ipv4_hdr->total_length))) - sizeof(struct ipv4_hdr))) : rte_arch_bswap16 ((uint16_t)(((uint16_t)(__builtin_constant_p(ipv4_hdr->total_length ) ? rte_constant_bswap16(ipv4_hdr->total_length) : rte_arch_bswap16 (ipv4_hdr->total_length))) - sizeof(struct ipv4_hdr))))) | |||||
297 | - sizeof(struct ipv4_hdr)))((uint16_t)(__builtin_constant_p((uint16_t)(((uint16_t)(__builtin_constant_p (ipv4_hdr->total_length) ? rte_constant_bswap16(ipv4_hdr-> total_length) : rte_arch_bswap16(ipv4_hdr->total_length))) - sizeof(struct ipv4_hdr))) ? rte_constant_bswap16((uint16_t )(((uint16_t)(__builtin_constant_p(ipv4_hdr->total_length) ? rte_constant_bswap16(ipv4_hdr->total_length) : rte_arch_bswap16 (ipv4_hdr->total_length))) - sizeof(struct ipv4_hdr))) : rte_arch_bswap16 ((uint16_t)(((uint16_t)(__builtin_constant_p(ipv4_hdr->total_length ) ? rte_constant_bswap16(ipv4_hdr->total_length) : rte_arch_bswap16 (ipv4_hdr->total_length))) - sizeof(struct ipv4_hdr))))); | |||||
298 | } | |||||
299 | return rte_raw_cksum(&psd_hdr, sizeof(psd_hdr)); | |||||
300 | } | |||||
301 | ||||||
302 | /** | |||||
303 | * Process the IPv4 UDP or TCP checksum. | |||||
304 | * | |||||
305 | * The IPv4 header should not contains options. The IP and layer 4 | |||||
306 | * checksum must be set to 0 in the packet by the caller. | |||||
307 | * | |||||
308 | * @param ipv4_hdr | |||||
309 | * The pointer to the contiguous IPv4 header. | |||||
310 | * @param l4_hdr | |||||
311 | * The pointer to the beginning of the L4 header. | |||||
312 | * @return | |||||
313 | * The complemented checksum to set in the IP packet | |||||
314 | * or 0 on error | |||||
315 | */ | |||||
316 | static inline uint16_t | |||||
317 | rte_ipv4_udptcp_cksum(const struct ipv4_hdr *ipv4_hdr, const void *l4_hdr) | |||||
318 | { | |||||
319 | uint32_t cksum; | |||||
320 | uint32_t l3_len, l4_len; | |||||
321 | ||||||
322 | l3_len = rte_be_to_cpu_16(ipv4_hdr->total_length)((uint16_t)(__builtin_constant_p(ipv4_hdr->total_length) ? rte_constant_bswap16(ipv4_hdr->total_length) : rte_arch_bswap16 (ipv4_hdr->total_length))); | |||||
323 | if (l3_len < sizeof(struct ipv4_hdr)) | |||||
324 | return 0; | |||||
325 | ||||||
326 | l4_len = l3_len - sizeof(struct ipv4_hdr); | |||||
327 | ||||||
328 | cksum = rte_raw_cksum(l4_hdr, l4_len); | |||||
329 | cksum += rte_ipv4_phdr_cksum(ipv4_hdr, 0); | |||||
330 | ||||||
331 | cksum = ((cksum & 0xffff0000) >> 16) + (cksum & 0xffff); | |||||
332 | cksum = (~cksum) & 0xffff; | |||||
333 | if (cksum == 0) | |||||
334 | cksum = 0xffff; | |||||
335 | ||||||
336 | return (uint16_t)cksum; | |||||
337 | } | |||||
338 | ||||||
339 | /** | |||||
340 | * IPv6 Header | |||||
341 | */ | |||||
342 | struct ipv6_hdr { | |||||
343 | uint32_t vtc_flow; /**< IP version, traffic class & flow label. */ | |||||
344 | uint16_t payload_len; /**< IP packet length - includes sizeof(ip_header). */ | |||||
345 | uint8_t proto; /**< Protocol, next header. */ | |||||
346 | uint8_t hop_limits; /**< Hop limits. */ | |||||
347 | uint8_t src_addr[16]; /**< IP address of source host. */ | |||||
348 | uint8_t dst_addr[16]; /**< IP address of destination host(s). */ | |||||
349 | } __attribute__((__packed__)); | |||||
350 | ||||||
351 | /* IPv6 vtc_flow: IPv / TC / flow_label */ | |||||
352 | #define IPV6_HDR_FL_SHIFT0 0 | |||||
353 | #define IPV6_HDR_TC_SHIFT20 20 | |||||
354 | #define IPV6_HDR_FL_MASK((1u << 20) - 1) ((1u << IPV6_HDR_TC_SHIFT20) - 1) | |||||
355 | #define IPV6_HDR_TC_MASK(0xf << 20) (0xf << IPV6_HDR_TC_SHIFT20) | |||||
356 | ||||||
357 | /** | |||||
358 | * Process the pseudo-header checksum of an IPv6 header. | |||||
359 | * | |||||
360 | * Depending on the ol_flags, the pseudo-header checksum expected by the | |||||
361 | * drivers is not the same. For instance, when TSO is enabled, the IPv6 | |||||
362 | * payload length must not be included in the packet. | |||||
363 | * | |||||
364 | * When ol_flags is 0, it computes the standard pseudo-header checksum. | |||||
365 | * | |||||
366 | * @param ipv6_hdr | |||||
367 | * The pointer to the contiguous IPv6 header. | |||||
368 | * @param ol_flags | |||||
369 | * The ol_flags of the associated mbuf. | |||||
370 | * @return | |||||
371 | * The non-complemented checksum to set in the L4 header. | |||||
372 | */ | |||||
373 | static inline uint16_t | |||||
374 | rte_ipv6_phdr_cksum(const struct ipv6_hdr *ipv6_hdr, uint64_t ol_flags) | |||||
375 | { | |||||
376 | uint32_t sum; | |||||
377 | struct { | |||||
378 | uint32_t len; /* L4 length. */ | |||||
379 | uint32_t proto; /* L4 protocol - top 3 bytes must be zero */ | |||||
380 | } psd_hdr; | |||||
381 | ||||||
382 | psd_hdr.proto = (uint32_t)(ipv6_hdr->proto << 24); | |||||
383 | if (ol_flags & PKT_TX_TCP_SEG(1ULL << 50)) { | |||||
384 | psd_hdr.len = 0; | |||||
385 | } else { | |||||
386 | psd_hdr.len = ipv6_hdr->payload_len; | |||||
387 | } | |||||
388 | ||||||
389 | sum = __rte_raw_cksum(ipv6_hdr->src_addr, | |||||
390 | sizeof(ipv6_hdr->src_addr) + sizeof(ipv6_hdr->dst_addr), | |||||
391 | 0); | |||||
392 | sum = __rte_raw_cksum(&psd_hdr, sizeof(psd_hdr), sum); | |||||
393 | return __rte_raw_cksum_reduce(sum); | |||||
394 | } | |||||
395 | ||||||
396 | /** | |||||
397 | * Process the IPv6 UDP or TCP checksum. | |||||
398 | * | |||||
399 | * The IPv4 header should not contains options. The layer 4 checksum | |||||
400 | * must be set to 0 in the packet by the caller. | |||||
401 | * | |||||
402 | * @param ipv6_hdr | |||||
403 | * The pointer to the contiguous IPv6 header. | |||||
404 | * @param l4_hdr | |||||
405 | * The pointer to the beginning of the L4 header. | |||||
406 | * @return | |||||
407 | * The complemented checksum to set in the IP packet. | |||||
408 | */ | |||||
409 | static inline uint16_t | |||||
410 | rte_ipv6_udptcp_cksum(const struct ipv6_hdr *ipv6_hdr, const void *l4_hdr) | |||||
411 | { | |||||
412 | uint32_t cksum; | |||||
413 | uint32_t l4_len; | |||||
414 | ||||||
415 | l4_len = rte_be_to_cpu_16(ipv6_hdr->payload_len)((uint16_t)(__builtin_constant_p(ipv6_hdr->payload_len) ? rte_constant_bswap16 (ipv6_hdr->payload_len) : rte_arch_bswap16(ipv6_hdr->payload_len ))); | |||||
416 | ||||||
417 | cksum = rte_raw_cksum(l4_hdr, l4_len); | |||||
418 | cksum += rte_ipv6_phdr_cksum(ipv6_hdr, 0); | |||||
419 | ||||||
420 | cksum = ((cksum & 0xffff0000) >> 16) + (cksum & 0xffff); | |||||
421 | cksum = (~cksum) & 0xffff; | |||||
422 | if (cksum == 0) | |||||
423 | cksum = 0xffff; | |||||
424 | ||||||
425 | return (uint16_t)cksum; | |||||
426 | } | |||||
427 | ||||||
428 | #ifdef __cplusplus | |||||
429 | } | |||||
430 | #endif | |||||
431 | ||||||
432 | #endif /* _RTE_IP_H_ */ |