DPDK 25.03.0-rc0
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_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;
66
68#define RTE_IPV4(a, b, c, d) ((uint32_t)(((a) & 0xff) << 24) | \
69 (((b) & 0xff) << 16) | \
70 (((c) & 0xff) << 8) | \
71 ((d) & 0xff))
72
74#define RTE_IPV4_MAX_PKT_LEN 65535
75
77#define RTE_IPV4_HDR_IHL_MASK (0x0f)
82#define RTE_IPV4_IHL_MULTIPLIER (4)
83
84/* Type of Service fields */
85#define RTE_IPV4_HDR_DSCP_MASK (0xfc)
86#define RTE_IPV4_HDR_ECN_MASK (0x03)
87#define RTE_IPV4_HDR_ECN_CE RTE_IPV4_HDR_ECN_MASK
88
89/* Fragment Offset * Flags. */
90#define RTE_IPV4_HDR_DF_SHIFT 14
91#define RTE_IPV4_HDR_MF_SHIFT 13
92#define RTE_IPV4_HDR_FO_SHIFT 3
93
94#define RTE_IPV4_HDR_DF_FLAG (1 << RTE_IPV4_HDR_DF_SHIFT)
95#define RTE_IPV4_HDR_MF_FLAG (1 << RTE_IPV4_HDR_MF_SHIFT)
96
97#define RTE_IPV4_HDR_OFFSET_MASK ((1 << RTE_IPV4_HDR_MF_SHIFT) - 1)
98
99#define RTE_IPV4_HDR_OFFSET_UNITS 8
100
101/* IPv4 options */
102#define RTE_IPV4_HDR_OPT_EOL 0
103#define RTE_IPV4_HDR_OPT_NOP 1
104#define RTE_IPV4_HDR_OPT_COPIED(v) ((v) & 0x80)
105#define RTE_IPV4_HDR_OPT_MAX_LEN 40
106
107/*
108 * IPv4 address types
109 */
110#define RTE_IPV4_ANY ((uint32_t)0x00000000)
111#define RTE_IPV4_LOOPBACK ((uint32_t)0x7f000001)
112#define RTE_IPV4_BROADCAST ((uint32_t)0xe0000000)
113#define RTE_IPV4_ALLHOSTS_GROUP ((uint32_t)0xe0000001)
114#define RTE_IPV4_ALLRTRS_GROUP ((uint32_t)0xe0000002)
115#define RTE_IPV4_MAX_LOCAL_GROUP ((uint32_t)0xe00000ff)
117/*
118 * IPv4 Multicast-related macros
119 */
120#define RTE_IPV4_MIN_MCAST \
121 RTE_IPV4(224, 0, 0, 0)
122#define RTE_IPV4_MAX_MCAST \
123 RTE_IPV4(239, 255, 255, 255)
125#define RTE_IS_IPV4_MCAST(x) \
126 ((x) >= RTE_IPV4_MIN_MCAST && (x) <= RTE_IPV4_MAX_MCAST)
129/* IPv4 default fields values */
130#define RTE_IPV4_MIN_IHL (0x5)
131#define RTE_IPV4_VHL_DEF ((IPVERSION << 4) | RTE_IPV4_MIN_IHL)
132
141static inline uint8_t
142rte_ipv4_hdr_len(const struct rte_ipv4_hdr *ipv4_hdr)
143{
144 return (uint8_t)((ipv4_hdr->version_ihl & RTE_IPV4_HDR_IHL_MASK) *
146}
147
158static inline uint16_t
159rte_ipv4_cksum(const struct rte_ipv4_hdr *ipv4_hdr)
160{
161 uint16_t cksum;
162 cksum = rte_raw_cksum(ipv4_hdr, rte_ipv4_hdr_len(ipv4_hdr));
163 return (uint16_t)~cksum;
164}
165
180__rte_experimental
181static inline uint16_t
182rte_ipv4_cksum_simple(const struct rte_ipv4_hdr *ipv4_hdr)
183{
184 const uint16_t *v16_h;
185 uint32_t ip_cksum;
186
187 /*
188 * Compute the sum of successive 16-bit words of the IPv4 header,
189 * skipping the checksum field of the header.
190 */
191 v16_h = (const uint16_t *)ipv4_hdr;
192 ip_cksum = v16_h[0] + v16_h[1] + v16_h[2] + v16_h[3] +
193 v16_h[4] + v16_h[6] + v16_h[7] + v16_h[8] + v16_h[9];
194
195 /* reduce 32 bit checksum to 16 bits and complement it */
196 ip_cksum = (ip_cksum & 0xffff) + (ip_cksum >> 16);
197 ip_cksum = (ip_cksum & 0xffff) + (ip_cksum >> 16);
198 return (uint16_t)(~ip_cksum);
199}
200
219static inline uint16_t
220rte_ipv4_phdr_cksum(const struct rte_ipv4_hdr *ipv4_hdr, uint64_t ol_flags)
221{
222 struct ipv4_psd_header {
223 uint32_t src_addr; /* IP address of source host. */
224 uint32_t dst_addr; /* IP address of destination host. */
225 uint8_t zero; /* zero. */
226 uint8_t proto; /* L4 protocol type. */
227 uint16_t len; /* L4 length. */
228 } psd_hdr;
229
230 uint32_t l3_len;
231
232 psd_hdr.src_addr = ipv4_hdr->src_addr;
233 psd_hdr.dst_addr = ipv4_hdr->dst_addr;
234 psd_hdr.zero = 0;
235 psd_hdr.proto = ipv4_hdr->next_proto_id;
236 if (ol_flags & (RTE_MBUF_F_TX_TCP_SEG | RTE_MBUF_F_TX_UDP_SEG)) {
237 psd_hdr.len = 0;
238 } else {
239 l3_len = rte_be_to_cpu_16(ipv4_hdr->total_length);
240 psd_hdr.len = rte_cpu_to_be_16((uint16_t)(l3_len -
241 rte_ipv4_hdr_len(ipv4_hdr)));
242 }
243 return rte_raw_cksum(&psd_hdr, sizeof(psd_hdr));
244}
245
249static inline uint16_t
250__rte_ipv4_udptcp_cksum(const struct rte_ipv4_hdr *ipv4_hdr, const void *l4_hdr)
251{
252 uint32_t cksum;
253 uint32_t l3_len, l4_len;
254 uint8_t ip_hdr_len;
255
256 ip_hdr_len = rte_ipv4_hdr_len(ipv4_hdr);
257 l3_len = rte_be_to_cpu_16(ipv4_hdr->total_length);
258 if (l3_len < ip_hdr_len)
259 return 0;
260
261 l4_len = l3_len - ip_hdr_len;
262
263 cksum = rte_raw_cksum(l4_hdr, l4_len);
264 cksum += rte_ipv4_phdr_cksum(ipv4_hdr, 0);
265
266 cksum = ((cksum & 0xffff0000) >> 16) + (cksum & 0xffff);
267
268 return (uint16_t)cksum;
269}
270
283static inline uint16_t
284rte_ipv4_udptcp_cksum(const struct rte_ipv4_hdr *ipv4_hdr, const void *l4_hdr)
285{
286 uint16_t cksum = __rte_ipv4_udptcp_cksum(ipv4_hdr, l4_hdr);
287
288 cksum = ~cksum;
289
290 /*
291 * Per RFC 768: If the computed checksum is zero for UDP,
292 * it is transmitted as all ones
293 * (the equivalent in one's complement arithmetic).
294 */
295 if (cksum == 0 && ipv4_hdr->next_proto_id == IPPROTO_UDP)
296 cksum = 0xffff;
297
298 return cksum;
299}
300
304static inline uint16_t
305__rte_ipv4_udptcp_cksum_mbuf(const struct rte_mbuf *m,
306 const struct rte_ipv4_hdr *ipv4_hdr,
307 uint16_t l4_off)
308{
309 uint16_t raw_cksum;
310 uint32_t cksum;
311 uint16_t len;
312
313 if (unlikely(l4_off > m->pkt_len))
314 return 0; /* invalid params, return a dummy value */
315
316 len = rte_be_to_cpu_16(ipv4_hdr->total_length) - (uint16_t)rte_ipv4_hdr_len(ipv4_hdr);
317
318 if (rte_raw_cksum_mbuf(m, l4_off, len, &raw_cksum))
319 return 0;
320
321 cksum = raw_cksum + rte_ipv4_phdr_cksum(ipv4_hdr, 0);
322
323 cksum = ((cksum & 0xffff0000) >> 16) + (cksum & 0xffff);
324
325 return (uint16_t)cksum;
326}
327
340static inline uint16_t
342 const struct rte_ipv4_hdr *ipv4_hdr, uint16_t l4_off)
344 uint16_t cksum = __rte_ipv4_udptcp_cksum_mbuf(m, ipv4_hdr, l4_off);
345
346 cksum = ~cksum;
347
348 /*
349 * Per RFC 768: If the computed checksum is zero for UDP,
350 * it is transmitted as all ones
351 * (the equivalent in one's complement arithmetic).
352 */
353 if (cksum == 0 && ipv4_hdr->next_proto_id == IPPROTO_UDP)
354 cksum = 0xffff;
355
356 return cksum;
357}
358
372static inline int
373rte_ipv4_udptcp_cksum_verify(const struct rte_ipv4_hdr *ipv4_hdr,
374 const void *l4_hdr)
376 uint16_t cksum = __rte_ipv4_udptcp_cksum(ipv4_hdr, l4_hdr);
377
378 if (cksum != 0xffff)
379 return -1;
380
381 return 0;
382}
383
399static inline int
401 const struct rte_ipv4_hdr *ipv4_hdr,
402 uint16_t l4_off)
403{
404 uint16_t cksum = __rte_ipv4_udptcp_cksum_mbuf(m, ipv4_hdr, l4_off);
405
406 if (cksum != 0xffff)
407 return -1;
408
409 return 0;
410}
411
412#ifdef __cplusplus
413}
414#endif
415
416#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
Definition: rte_common.h:108
static uint16_t rte_ipv4_phdr_cksum(const struct rte_ipv4_hdr *ipv4_hdr, uint64_t ol_flags)
Definition: rte_ip4.h:222
struct __rte_aligned(2) rte_ipv4_hdr
Definition: rte_ip4.h:42
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:402
static __rte_experimental uint16_t rte_ipv4_cksum_simple(const struct rte_ipv4_hdr *ipv4_hdr)
Definition: rte_ip4.h:184
static uint16_t rte_ipv4_udptcp_cksum(const struct rte_ipv4_hdr *ipv4_hdr, const void *l4_hdr)
Definition: rte_ip4.h:286
static uint16_t rte_ipv4_cksum(const struct rte_ipv4_hdr *ipv4_hdr)
Definition: rte_ip4.h:161
static uint8_t rte_ipv4_hdr_len(const struct rte_ipv4_hdr *ipv4_hdr)
Definition: rte_ip4.h:144
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:343
#define RTE_IPV4_HDR_IHL_MASK
Definition: rte_ip4.h:77
#define RTE_IPV4_IHL_MULTIPLIER
Definition: rte_ip4.h:82
static int rte_ipv4_udptcp_cksum_verify(const struct rte_ipv4_hdr *ipv4_hdr, const void *l4_hdr)
Definition: rte_ip4.h:375
#define RTE_MBUF_F_TX_UDP_SEG
#define RTE_MBUF_F_TX_TCP_SEG
uint32_t pkt_len