DPDK 25.11.0-rc1
rte_ip4.h
Go to the documentation of this file.
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_IP4_H_
10#define _RTE_IP4_H_
11
18#include <stdint.h>
19
20#ifdef RTE_EXEC_ENV_WINDOWS
21#include <ws2tcpip.h>
22#else
23#include <sys/socket.h>
24#include <sys/types.h>
25#include <netinet/in.h>
26#include <arpa/inet.h>
27#include <netinet/ip.h>
28#include <netinet/ip6.h>
29#endif
30
31#include <rte_byteorder.h>
32#include <rte_cksum.h>
33#include <rte_mbuf.h>
34
35#ifdef __cplusplus
36extern "C" {
37#endif
38
42struct __rte_aligned(2) __rte_packed_begin rte_ipv4_hdr {
43 __extension__
44 union {
45 uint8_t version_ihl;
46 struct {
47#if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN
48 uint8_t ihl:4;
49 uint8_t version:4;
50#elif RTE_BYTE_ORDER == RTE_BIG_ENDIAN
51 uint8_t version:4;
52 uint8_t ihl:4;
53#endif
54 };
55 };
56 uint8_t type_of_service;
57 rte_be16_t total_length;
58 rte_be16_t packet_id;
59 rte_be16_t fragment_offset;
60 uint8_t time_to_live;
61 uint8_t next_proto_id;
62 rte_be16_t hdr_checksum;
63 rte_be32_t src_addr;
64 rte_be32_t dst_addr;
65} __rte_packed_end;
66
68#define RTE_IPV4(a, b, c, d) (((uint32_t)((a) & 0xff) << 24) | ((uint32_t)((b) & 0xff) << 16) | \
69 ((uint32_t)((c) & 0xff) << 8) | ((uint32_t)((d) & 0xff)))
70
72#define RTE_IPV4_MAX_PKT_LEN 65535
73
75#define RTE_IPV4_HDR_IHL_MASK (0x0f)
80#define RTE_IPV4_IHL_MULTIPLIER (4)
81
82/* Type of Service fields */
83#define RTE_IPV4_HDR_DSCP_MASK (0xfc)
84#define RTE_IPV4_HDR_ECN_MASK (0x03)
85#define RTE_IPV4_HDR_ECN_CE RTE_IPV4_HDR_ECN_MASK
86
87/* Fragment Offset * Flags. */
88#define RTE_IPV4_HDR_DF_SHIFT 14
89#define RTE_IPV4_HDR_MF_SHIFT 13
90#define RTE_IPV4_HDR_FO_SHIFT 3
91
92#define RTE_IPV4_HDR_DF_FLAG (1 << RTE_IPV4_HDR_DF_SHIFT)
93#define RTE_IPV4_HDR_MF_FLAG (1 << RTE_IPV4_HDR_MF_SHIFT)
94
95#define RTE_IPV4_HDR_OFFSET_MASK ((1 << RTE_IPV4_HDR_MF_SHIFT) - 1)
96
97#define RTE_IPV4_HDR_OFFSET_UNITS 8
98
99/* IPv4 options */
100#define RTE_IPV4_HDR_OPT_EOL 0
101#define RTE_IPV4_HDR_OPT_NOP 1
102#define RTE_IPV4_HDR_OPT_COPIED(v) ((v) & 0x80)
103#define RTE_IPV4_HDR_OPT_MAX_LEN 40
104
105/*
106 * IPv4 address types
107 */
108#define RTE_IPV4_ANY ((uint32_t)0x00000000)
109#define RTE_IPV4_LOOPBACK ((uint32_t)0x7f000001)
110#define RTE_IPV4_BROADCAST ((uint32_t)0xe0000000)
111#define RTE_IPV4_ALLHOSTS_GROUP ((uint32_t)0xe0000001)
112#define RTE_IPV4_ALLRTRS_GROUP ((uint32_t)0xe0000002)
113#define RTE_IPV4_MAX_LOCAL_GROUP ((uint32_t)0xe00000ff)
115/*
116 * IPv4 Multicast-related macros
117 */
118#define RTE_IPV4_MIN_MCAST \
119 RTE_IPV4(224, 0, 0, 0)
120#define RTE_IPV4_MAX_MCAST \
121 RTE_IPV4(239, 255, 255, 255)
123#define RTE_IS_IPV4_MCAST(x) \
124 ((x) >= RTE_IPV4_MIN_MCAST && (x) <= RTE_IPV4_MAX_MCAST)
127/* IPv4 default fields values */
128#define RTE_IPV4_MIN_IHL (0x5)
129#define RTE_IPV4_VHL_DEF ((IPVERSION << 4) | RTE_IPV4_MIN_IHL)
130
139static inline uint8_t
140rte_ipv4_hdr_len(const struct rte_ipv4_hdr *ipv4_hdr)
141{
142 return (uint8_t)((ipv4_hdr->version_ihl & RTE_IPV4_HDR_IHL_MASK) *
144}
145
156static inline uint16_t
157rte_ipv4_cksum(const struct rte_ipv4_hdr *ipv4_hdr)
158{
159 uint16_t cksum;
160 cksum = rte_raw_cksum(ipv4_hdr, rte_ipv4_hdr_len(ipv4_hdr));
161 return (uint16_t)~cksum;
162}
163
178__rte_experimental
179static inline uint16_t
180rte_ipv4_cksum_simple(const struct rte_ipv4_hdr *ipv4_hdr)
181{
182 const uint16_t *v16_h;
183 uint32_t ip_cksum;
184
185 /*
186 * Compute the sum of successive 16-bit words of the IPv4 header,
187 * skipping the checksum field of the header.
188 */
189 v16_h = (const uint16_t *)ipv4_hdr;
190 ip_cksum = v16_h[0] + v16_h[1] + v16_h[2] + v16_h[3] +
191 v16_h[4] + v16_h[6] + v16_h[7] + v16_h[8] + v16_h[9];
192
193 /* reduce 32 bit checksum to 16 bits and complement it */
194 ip_cksum = (ip_cksum & 0xffff) + (ip_cksum >> 16);
195 ip_cksum = (ip_cksum & 0xffff) + (ip_cksum >> 16);
196 return (uint16_t)(~ip_cksum);
197}
198
217static inline uint16_t
218rte_ipv4_phdr_cksum(const struct rte_ipv4_hdr *ipv4_hdr, uint64_t ol_flags)
219{
220 struct ipv4_psd_header {
221 uint32_t src_addr; /* IP address of source host. */
222 uint32_t dst_addr; /* IP address of destination host. */
223 uint8_t zero; /* zero. */
224 uint8_t proto; /* L4 protocol type. */
225 uint16_t len; /* L4 length. */
226 } psd_hdr;
227
228 uint32_t l3_len;
229
230 psd_hdr.src_addr = ipv4_hdr->src_addr;
231 psd_hdr.dst_addr = ipv4_hdr->dst_addr;
232 psd_hdr.zero = 0;
233 psd_hdr.proto = ipv4_hdr->next_proto_id;
234 if (ol_flags & (RTE_MBUF_F_TX_TCP_SEG | RTE_MBUF_F_TX_UDP_SEG)) {
235 psd_hdr.len = 0;
236 } else {
237 l3_len = rte_be_to_cpu_16(ipv4_hdr->total_length);
238 psd_hdr.len = rte_cpu_to_be_16((uint16_t)(l3_len -
239 rte_ipv4_hdr_len(ipv4_hdr)));
240 }
241 return rte_raw_cksum(&psd_hdr, sizeof(psd_hdr));
242}
243
247static inline uint16_t
248__rte_ipv4_udptcp_cksum(const struct rte_ipv4_hdr *ipv4_hdr, const void *l4_hdr)
249{
250 uint32_t cksum;
251 uint32_t l3_len, l4_len;
252 uint8_t ip_hdr_len;
253
254 ip_hdr_len = rte_ipv4_hdr_len(ipv4_hdr);
255 l3_len = rte_be_to_cpu_16(ipv4_hdr->total_length);
256 if (l3_len < ip_hdr_len)
257 return 0;
258
259 l4_len = l3_len - ip_hdr_len;
260
261 cksum = rte_raw_cksum(l4_hdr, l4_len);
262 cksum += rte_ipv4_phdr_cksum(ipv4_hdr, 0);
263
264 cksum = ((cksum & 0xffff0000) >> 16) + (cksum & 0xffff);
265
266 return (uint16_t)cksum;
267}
268
281static inline uint16_t
282rte_ipv4_udptcp_cksum(const struct rte_ipv4_hdr *ipv4_hdr, const void *l4_hdr)
283{
284 uint16_t cksum = __rte_ipv4_udptcp_cksum(ipv4_hdr, l4_hdr);
285
286 cksum = ~cksum;
287
288 /*
289 * Per RFC 768: If the computed checksum is zero for UDP,
290 * it is transmitted as all ones
291 * (the equivalent in one's complement arithmetic).
292 */
293 if (cksum == 0 && ipv4_hdr->next_proto_id == IPPROTO_UDP)
294 cksum = 0xffff;
295
296 return cksum;
297}
298
302static inline uint16_t
303__rte_ipv4_udptcp_cksum_mbuf(const struct rte_mbuf *m,
304 const struct rte_ipv4_hdr *ipv4_hdr,
305 uint16_t l4_off)
306{
307 uint16_t raw_cksum;
308 uint32_t cksum;
309 uint16_t len;
310
311 if (unlikely(l4_off > m->pkt_len))
312 return 0; /* invalid params, return a dummy value */
313
314 len = rte_be_to_cpu_16(ipv4_hdr->total_length) - (uint16_t)rte_ipv4_hdr_len(ipv4_hdr);
315
316 if (rte_raw_cksum_mbuf(m, l4_off, len, &raw_cksum))
317 return 0;
318
319 cksum = raw_cksum + rte_ipv4_phdr_cksum(ipv4_hdr, 0);
320
321 cksum = ((cksum & 0xffff0000) >> 16) + (cksum & 0xffff);
322
323 return (uint16_t)cksum;
324}
325
338static inline uint16_t
340 const struct rte_ipv4_hdr *ipv4_hdr, uint16_t l4_off)
342 uint16_t cksum = __rte_ipv4_udptcp_cksum_mbuf(m, ipv4_hdr, l4_off);
343
344 cksum = ~cksum;
345
346 /*
347 * Per RFC 768: If the computed checksum is zero for UDP,
348 * it is transmitted as all ones
349 * (the equivalent in one's complement arithmetic).
350 */
351 if (cksum == 0 && ipv4_hdr->next_proto_id == IPPROTO_UDP)
352 cksum = 0xffff;
353
354 return cksum;
355}
356
370static inline int
371rte_ipv4_udptcp_cksum_verify(const struct rte_ipv4_hdr *ipv4_hdr,
372 const void *l4_hdr)
374 uint16_t cksum = __rte_ipv4_udptcp_cksum(ipv4_hdr, l4_hdr);
375
376 if (cksum != 0xffff)
377 return -1;
378
379 return 0;
380}
381
397static inline int
399 const struct rte_ipv4_hdr *ipv4_hdr,
400 uint16_t l4_off)
401{
402 uint16_t cksum = __rte_ipv4_udptcp_cksum_mbuf(m, ipv4_hdr, l4_off);
403
404 if (cksum != 0xffff)
405 return -1;
406
407 return 0;
408}
409
410#ifdef __cplusplus
411}
412#endif
413
414#endif /* _RTE_IP_H_ */
#define unlikely(x)
static uint16_t rte_be_to_cpu_16(rte_be16_t x)
static rte_be16_t rte_cpu_to_be_16(uint16_t x)
uint32_t rte_be32_t
uint16_t rte_be16_t
static uint16_t rte_raw_cksum(const void *buf, size_t len)
Definition: rte_cksum.h:94
static int rte_raw_cksum_mbuf(const struct rte_mbuf *m, uint32_t off, uint32_t len, uint16_t *cksum)
Definition: rte_cksum.h:117
#define __rte_packed_begin
Definition: rte_common.h:158
static uint16_t rte_ipv4_phdr_cksum(const struct rte_ipv4_hdr *ipv4_hdr, uint64_t ol_flags)
Definition: rte_ip4.h:220
static int rte_ipv4_udptcp_cksum_mbuf_verify(const struct rte_mbuf *m, const struct rte_ipv4_hdr *ipv4_hdr, uint16_t l4_off)
Definition: rte_ip4.h:400
static __rte_experimental uint16_t rte_ipv4_cksum_simple(const struct rte_ipv4_hdr *ipv4_hdr)
Definition: rte_ip4.h:182
static uint16_t rte_ipv4_udptcp_cksum(const struct rte_ipv4_hdr *ipv4_hdr, const void *l4_hdr)
Definition: rte_ip4.h:284
static uint16_t rte_ipv4_cksum(const struct rte_ipv4_hdr *ipv4_hdr)
Definition: rte_ip4.h:159
static uint8_t rte_ipv4_hdr_len(const struct rte_ipv4_hdr *ipv4_hdr)
Definition: rte_ip4.h:142
static uint16_t rte_ipv4_udptcp_cksum_mbuf(const struct rte_mbuf *m, const struct rte_ipv4_hdr *ipv4_hdr, uint16_t l4_off)
Definition: rte_ip4.h:341
#define RTE_IPV4_HDR_IHL_MASK
Definition: rte_ip4.h:75
struct __rte_aligned(2) __rte_packed_begin rte_ipv4_hdr
Definition: rte_ip4.h:42
#define RTE_IPV4_IHL_MULTIPLIER
Definition: rte_ip4.h:80
static int rte_ipv4_udptcp_cksum_verify(const struct rte_ipv4_hdr *ipv4_hdr, const void *l4_hdr)
Definition: rte_ip4.h:373
#define RTE_MBUF_F_TX_UDP_SEG
#define RTE_MBUF_F_TX_TCP_SEG
uint32_t pkt_len