DPDK  25.11.0
rte_ip6.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_IP6_H_
10 #define _RTE_IP6_H_
11 
18 #include <stdint.h>
19 #include <string.h>
20 
21 #ifdef RTE_EXEC_ENV_WINDOWS
22 #include <ws2tcpip.h>
23 #else
24 #include <sys/socket.h>
25 #include <sys/types.h>
26 #include <netinet/in.h>
27 #include <arpa/inet.h>
28 #include <netinet/ip6.h>
29 #endif
30 
31 #include <rte_byteorder.h>
32 #include <rte_cksum.h>
33 #include <rte_ether.h>
34 #include <rte_mbuf.h>
35 
36 #ifdef __cplusplus
37 extern "C" {
38 #endif
39 
43 #define RTE_IPV6_ADDR_SIZE 16
44 
48 #define RTE_IPV6_MAX_DEPTH (RTE_IPV6_ADDR_SIZE * CHAR_BIT)
49 
53 struct rte_ipv6_addr {
54  uint8_t a[RTE_IPV6_ADDR_SIZE];
55 };
56 
67 static inline bool
68 rte_ipv6_addr_eq(const struct rte_ipv6_addr *a, const struct rte_ipv6_addr *b)
69 {
70  return memcmp(a, b, sizeof(*a)) == 0;
71 }
72 
83 static inline void
84 rte_ipv6_addr_mask(struct rte_ipv6_addr *ip, uint8_t depth)
85 {
86  if (depth < RTE_IPV6_MAX_DEPTH) {
87  unsigned int d = depth / CHAR_BIT;
88  uint8_t mask = ~(UINT8_MAX >> (depth % CHAR_BIT));
89  ip->a[d] &= mask;
90  d++;
91  while (d < sizeof(*ip))
92  ip->a[d++] = 0;
93  }
94 }
95 
108 static inline bool
109 rte_ipv6_addr_eq_prefix(const struct rte_ipv6_addr *a, const struct rte_ipv6_addr *b, uint8_t depth)
110 {
111  if (depth < RTE_IPV6_MAX_DEPTH) {
112  unsigned int d = depth / CHAR_BIT;
113  uint8_t mask = ~(UINT8_MAX >> (depth % CHAR_BIT));
114 
115  if ((a->a[d] ^ b->a[d]) & mask)
116  return false;
117 
118  return memcmp(a, b, d) == 0;
119  }
120  return rte_ipv6_addr_eq(a, b);
121 }
122 
131 static inline uint8_t
133 {
134  uint8_t depth = 0;
135 
136  for (unsigned int i = 0; i < RTE_DIM(mask->a); i++) {
137  uint8_t m = mask->a[i];
138  if (m == 0xff) {
139  depth += 8;
140  } else {
141  while (m & 0x80) {
142  m <<= 1;
143  depth++;
144  }
145  break;
146  }
147  }
148 
149  return depth;
150 }
151 
161 #if RTE_BYTE_ORDER == RTE_BIG_ENDIAN
162 #define RTE_IPV6_U16_SPLIT(x) \
163  (uint8_t)((uint16_t)(x) & UINT16_C(0xff)), \
164  (uint8_t)(((uint16_t)(x) >> 8) & UINT16_C(0xff))
165 #else
166 #define RTE_IPV6_U16_SPLIT(x) \
167  (uint8_t)(((uint16_t)(x) >> 8) & UINT16_C(0xff)), \
168  (uint8_t)((uint16_t)(x) & UINT16_C(0xff))
169 #endif
170 
179 #define RTE_IPV6(a, b, c, d, e, f, g, h) \
180  {{ \
181  RTE_IPV6_U16_SPLIT(a), \
182  RTE_IPV6_U16_SPLIT(b), \
183  RTE_IPV6_U16_SPLIT(c), \
184  RTE_IPV6_U16_SPLIT(d), \
185  RTE_IPV6_U16_SPLIT(e), \
186  RTE_IPV6_U16_SPLIT(f), \
187  RTE_IPV6_U16_SPLIT(g), \
188  RTE_IPV6_U16_SPLIT(h) \
189  }}
190 
195 #define RTE_IPV6_ADDR_FMT \
196  "%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x"
197 
210 #define RTE_IPV6_ADDR_SPLIT(ip) \
211  ((uint8_t)(ip)->a[0]), \
212  ((uint8_t)(ip)->a[1]), \
213  ((uint8_t)(ip)->a[2]), \
214  ((uint8_t)(ip)->a[3]), \
215  ((uint8_t)(ip)->a[4]), \
216  ((uint8_t)(ip)->a[5]), \
217  ((uint8_t)(ip)->a[6]), \
218  ((uint8_t)(ip)->a[7]), \
219  ((uint8_t)(ip)->a[8]), \
220  ((uint8_t)(ip)->a[9]), \
221  ((uint8_t)(ip)->a[10]), \
222  ((uint8_t)(ip)->a[11]), \
223  ((uint8_t)(ip)->a[12]), \
224  ((uint8_t)(ip)->a[13]), \
225  ((uint8_t)(ip)->a[14]), \
226  ((uint8_t)(ip)->a[15])
227 
229 #define RTE_IPV6_MASK_FULL \
230  RTE_IPV6(0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff)
231 
233 #define RTE_IPV6_ADDR_UNSPEC RTE_IPV6(0, 0, 0, 0, 0, 0, 0, 0)
234 
243 static inline bool
245 {
246  const struct rte_ipv6_addr unspec = RTE_IPV6_ADDR_UNSPEC;
247  return rte_ipv6_addr_eq(ip, &unspec);
248 }
249 
251 #define RTE_IPV6_ADDR_LOOPBACK RTE_IPV6(0, 0, 0, 0, 0, 0, 0, 1)
252 
262 static inline bool
264 {
265  struct rte_ipv6_addr loopback = RTE_IPV6_ADDR_LOOPBACK;
266  return rte_ipv6_addr_eq(ip, &loopback);
267 }
268 
277 static inline bool
279 {
280  return ip->a[0] == 0xfe && (ip->a[1] & 0xc0) == 0x80;
281 }
282 
291 static inline bool
293 {
294  return ip->a[0] == 0xfe && (ip->a[1] & 0xc0) == 0xc0;
295 }
296 
306 static inline bool
308 {
309  const struct rte_ipv6_addr unspec = RTE_IPV6_ADDR_UNSPEC;
310  return rte_ipv6_addr_eq_prefix(ip, &unspec, 96) && !rte_ipv6_addr_is_loopback(ip);
311 }
312 
313 #define RTE_IPV6_ADDR_PREFIX_V4MAPPED RTE_IPV6(0, 0, 0, 0, 0, 0xffff, 0, 0)
314 
324 static inline bool
326 {
327  const struct rte_ipv6_addr prefix = RTE_IPV6_ADDR_PREFIX_V4MAPPED;
328  return rte_ipv6_addr_eq_prefix(ip, &prefix, 96);
329 }
330 
339 static inline bool
341 {
342  return ip->a[0] == 0xff;
343 }
344 
361 };
362 
372 static inline enum rte_ipv6_mc_scope
373 rte_ipv6_mc_scope(const struct rte_ipv6_addr *ip)
374 {
375  if (!rte_ipv6_addr_is_mcast(ip))
376  return RTE_IPV6_MC_SCOPE_NONE;
377  return (enum rte_ipv6_mc_scope)(ip->a[1] & 0x0f);
378 }
379 
383 #define RTE_IPV6_ADDR_ALLNODES_IFACE_LOCAL RTE_IPV6(0xff01, 0, 0, 0, 0, 0, 0, 1)
385 #define RTE_IPV6_ADDR_ALLNODES_LINK_LOCAL RTE_IPV6(0xff02, 0, 0, 0, 0, 0, 0, 1)
387 #define RTE_IPV6_ADDR_ALLROUTERS_IFACE_LOCAL RTE_IPV6(0xff01, 0, 0, 0, 0, 0, 0, 2)
389 #define RTE_IPV6_ADDR_ALLROUTERS_LINK_LOCAL RTE_IPV6(0xff02, 0, 0, 0, 0, 0, 0, 2)
391 #define RTE_IPV6_ADDR_ALLROUTERS_SITE_LOCAL RTE_IPV6(0xff05, 0, 0, 0, 0, 0, 0, 2)
394 /*
395  * Generate a link-local IPv6 address from an Ethernet address as specified in
396  * RFC 4291, section 2.5.1.
397  *
398  * @param[out] ip
399  * The link-local IPv6 address to generate.
400  * @param[in] mac
401  * An Ethernet address.
402  */
403 static inline void
404 rte_ipv6_llocal_from_ethernet(struct rte_ipv6_addr *ip, const struct rte_ether_addr *mac)
405 {
406  ip->a[0] = 0xfe;
407  ip->a[1] = 0x80;
408  memset(&ip->a[2], 0, 6);
409  /*
410  * The "u" bit (universal/local bit in IEEE EUI-64 terminology)
411  * must be inverted for IPv6 link local address.
412  * 0 means local scope, 1 means universal scope.
413  */
414  ip->a[8] = mac->addr_bytes[0] ^ RTE_ETHER_LOCAL_ADMIN_ADDR;
415  ip->a[9] = mac->addr_bytes[1];
416  ip->a[10] = mac->addr_bytes[2];
417  ip->a[11] = 0xff;
418  ip->a[12] = 0xfe;
419  ip->a[13] = mac->addr_bytes[3];
420  ip->a[14] = mac->addr_bytes[4];
421  ip->a[15] = mac->addr_bytes[5];
422 }
423 
433 static inline void
435 {
436  sol->a[0] = 0xff;
437  sol->a[1] = 0x02;
438  memset(&sol->a[2], 0, 9);
439  sol->a[11] = 0x01;
440  sol->a[12] = 0xff;
441  sol->a[13] = ip->a[13];
442  sol->a[14] = ip->a[14];
443  sol->a[15] = ip->a[15];
444 }
445 
455 static inline void
456 rte_ether_mcast_from_ipv6(struct rte_ether_addr *mac, const struct rte_ipv6_addr *ip)
457 {
458  mac->addr_bytes[0] = 0x33;
459  mac->addr_bytes[1] = 0x33;
460  mac->addr_bytes[2] = ip->a[12];
461  mac->addr_bytes[3] = ip->a[13];
462  mac->addr_bytes[4] = ip->a[14];
463  mac->addr_bytes[5] = ip->a[15];
464 }
465 
469 struct __rte_aligned(2) __rte_packed_begin rte_ipv6_hdr {
470  union {
471  rte_be32_t vtc_flow;
472  __extension__
473  struct {
474 #if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN
475  uint32_t flow_label:20;
476  uint32_t ecn:2;
477  uint32_t ds:6;
478  uint32_t version:4;
479 #elif RTE_BYTE_ORDER == RTE_BIG_ENDIAN
480  uint32_t version:4;
481  uint32_t ds:6;
482  uint32_t ecn:2;
483  uint32_t flow_label:20;
484 #endif
485  };
486  };
487  rte_be16_t payload_len;
488  uint8_t proto;
489  uint8_t hop_limits;
490  struct rte_ipv6_addr src_addr;
491  struct rte_ipv6_addr dst_addr;
492 } __rte_packed_end;
493 
502 static inline int rte_ipv6_check_version(const struct rte_ipv6_hdr *ip)
503 {
504  uint8_t version = ((const uint8_t *)ip)[0];
505  if ((version & 0xf0) != 0x60)
506  return -EINVAL;
507  return 0;
508 }
509 
510 /* IPv6 routing extension type definition. */
511 #define RTE_IPV6_SRCRT_TYPE_4 4
512 
516 struct __rte_aligned(2) __rte_packed_begin rte_ipv6_routing_ext {
517  uint8_t next_hdr;
518  uint8_t hdr_len;
519  uint8_t type;
520  uint8_t segments_left;
521  __extension__
522  union {
523  rte_be32_t flags;
524  struct {
525  uint8_t last_entry;
526  uint8_t flag;
527  rte_be16_t tag;
528  };
529  };
530  /* Next are 128-bit IPv6 address fields to describe segments. */
531 } __rte_packed_end;
532 
533 /* IPv6 vtc_flow: IPv / TC / flow_label */
534 #define RTE_IPV6_HDR_FL_SHIFT 0
535 #define RTE_IPV6_HDR_TC_SHIFT 20
536 #define RTE_IPV6_HDR_FL_MASK ((1u << RTE_IPV6_HDR_TC_SHIFT) - 1)
537 #define RTE_IPV6_HDR_TC_MASK (0xff << RTE_IPV6_HDR_TC_SHIFT)
538 #define RTE_IPV6_HDR_DSCP_MASK (0xfc << RTE_IPV6_HDR_TC_SHIFT)
539 #define RTE_IPV6_HDR_ECN_MASK (0x03 << RTE_IPV6_HDR_TC_SHIFT)
540 #define RTE_IPV6_HDR_ECN_CE RTE_IPV6_HDR_ECN_MASK
541 
542 #define RTE_IPV6_MIN_MTU 1280
560 static inline uint16_t
561 rte_ipv6_phdr_cksum(const struct rte_ipv6_hdr *ipv6_hdr, uint64_t ol_flags)
562 {
563  uint32_t sum;
564  struct {
565  rte_be32_t len; /* L4 length. */
566  rte_be32_t proto; /* L4 protocol - top 3 bytes must be zero */
567  } psd_hdr;
568 
569  psd_hdr.proto = (uint32_t)(ipv6_hdr->proto << 24);
570  if (ol_flags & (RTE_MBUF_F_TX_TCP_SEG | RTE_MBUF_F_TX_UDP_SEG))
571  psd_hdr.len = 0;
572  else
573  psd_hdr.len = ipv6_hdr->payload_len;
574 
575  sum = __rte_raw_cksum(&ipv6_hdr->src_addr,
576  sizeof(ipv6_hdr->src_addr) + sizeof(ipv6_hdr->dst_addr),
577  0);
578  sum = __rte_raw_cksum(&psd_hdr, sizeof(psd_hdr), sum);
579  return __rte_raw_cksum_reduce(sum);
580 }
581 
585 static inline uint16_t
586 __rte_ipv6_udptcp_cksum(const struct rte_ipv6_hdr *ipv6_hdr, const void *l4_hdr)
587 {
588  uint32_t cksum;
589  uint32_t l4_len;
590 
591  l4_len = rte_be_to_cpu_16(ipv6_hdr->payload_len);
592 
593  cksum = rte_raw_cksum(l4_hdr, l4_len);
594  cksum += rte_ipv6_phdr_cksum(ipv6_hdr, 0);
595 
596  cksum = ((cksum & 0xffff0000) >> 16) + (cksum & 0xffff);
597 
598  return (uint16_t)cksum;
599 }
600 
614 static inline uint16_t
615 rte_ipv6_udptcp_cksum(const struct rte_ipv6_hdr *ipv6_hdr, const void *l4_hdr)
616 {
617  uint16_t cksum = __rte_ipv6_udptcp_cksum(ipv6_hdr, l4_hdr);
618 
619  cksum = ~cksum;
620 
621  /*
622  * Per RFC 768: If the computed checksum is zero for UDP,
623  * it is transmitted as all ones
624  * (the equivalent in one's complement arithmetic).
625  */
626  if (cksum == 0 && ipv6_hdr->proto == IPPROTO_UDP)
627  cksum = 0xffff;
628 
629  return cksum;
630 }
631 
635 static inline uint16_t
636 __rte_ipv6_udptcp_cksum_mbuf(const struct rte_mbuf *m,
637  const struct rte_ipv6_hdr *ipv6_hdr,
638  uint16_t l4_off)
639 {
640  uint16_t raw_cksum;
641  uint32_t cksum;
642 
643  if (unlikely(l4_off > m->pkt_len))
644  return 0; /* invalid params, return a dummy value */
645 
646  if (rte_raw_cksum_mbuf(m, l4_off, rte_be_to_cpu_16(ipv6_hdr->payload_len), &raw_cksum))
647  return 0;
648 
649  cksum = raw_cksum + rte_ipv6_phdr_cksum(ipv6_hdr, 0);
650 
651  cksum = ((cksum & 0xffff0000) >> 16) + (cksum & 0xffff);
652 
653  return (uint16_t)cksum;
654 }
655 
671 static inline uint16_t
673  const struct rte_ipv6_hdr *ipv6_hdr, uint16_t l4_off)
674 {
675  uint16_t cksum = __rte_ipv6_udptcp_cksum_mbuf(m, ipv6_hdr, l4_off);
676 
677  cksum = ~cksum;
678 
679  /*
680  * Per RFC 768: If the computed checksum is zero for UDP,
681  * it is transmitted as all ones
682  * (the equivalent in one's complement arithmetic).
683  */
684  if (cksum == 0 && ipv6_hdr->proto == IPPROTO_UDP)
685  cksum = 0xffff;
686 
687  return cksum;
688 }
689 
704 static inline int
705 rte_ipv6_udptcp_cksum_verify(const struct rte_ipv6_hdr *ipv6_hdr,
706  const void *l4_hdr)
707 {
708  uint16_t cksum = __rte_ipv6_udptcp_cksum(ipv6_hdr, l4_hdr);
709 
710  if (cksum != 0xffff)
711  return -1;
712 
713  return 0;
714 }
715 
732 static inline int
734  const struct rte_ipv6_hdr *ipv6_hdr,
735  uint16_t l4_off)
736 {
737  uint16_t cksum = __rte_ipv6_udptcp_cksum_mbuf(m, ipv6_hdr, l4_off);
738 
739  if (cksum != 0xffff)
740  return -1;
741 
742  return 0;
743 }
744 
746 #define RTE_IPV6_EHDR_MF_SHIFT 0
747 #define RTE_IPV6_EHDR_MF_MASK 1
748 #define RTE_IPV6_EHDR_FO_SHIFT 3
749 #define RTE_IPV6_EHDR_FO_MASK (~((1 << RTE_IPV6_EHDR_FO_SHIFT) - 1))
750 #define RTE_IPV6_EHDR_FO_ALIGN (1 << RTE_IPV6_EHDR_FO_SHIFT)
751 
752 #define RTE_IPV6_FRAG_USED_MASK (RTE_IPV6_EHDR_MF_MASK | RTE_IPV6_EHDR_FO_MASK)
753 
754 #define RTE_IPV6_GET_MF(x) ((x) & RTE_IPV6_EHDR_MF_MASK)
755 #define RTE_IPV6_GET_FO(x) ((x) >> RTE_IPV6_EHDR_FO_SHIFT)
756 
757 #define RTE_IPV6_SET_FRAG_DATA(fo, mf) \
758  (((fo) & RTE_IPV6_EHDR_FO_MASK) | ((mf) & RTE_IPV6_EHDR_MF_MASK))
759 
760 struct __rte_aligned(2) __rte_packed_begin rte_ipv6_fragment_ext {
761  uint8_t next_header;
762  uint8_t reserved;
763  rte_be16_t frag_data;
764  rte_be32_t id;
765 } __rte_packed_end;
766 
767 /* IPv6 fragment extension header size */
768 #define RTE_IPV6_FRAG_HDR_SIZE sizeof(struct rte_ipv6_fragment_ext)
769 
786 static inline int
787 rte_ipv6_get_next_ext(const uint8_t *p, int proto, size_t *ext_len)
788 {
789  int next_proto;
790 
791  switch (proto) {
792  case IPPROTO_AH:
793  next_proto = *p++;
794  *ext_len = (*p + 2) * sizeof(uint32_t);
795  break;
796 
797  case IPPROTO_HOPOPTS:
798  case IPPROTO_ROUTING:
799  case IPPROTO_DSTOPTS:
800  next_proto = *p++;
801  *ext_len = (*p + 1) * sizeof(uint64_t);
802  break;
803 
804  case IPPROTO_FRAGMENT:
805  next_proto = *p;
806  *ext_len = RTE_IPV6_FRAG_HDR_SIZE;
807  break;
808 
809  default:
810  return -EINVAL;
811  }
812 
813  return next_proto;
814 }
815 
816 #ifdef __cplusplus
817 }
818 #endif
819 
820 #endif /* _RTE_IP6_H_ */
#define unlikely(x)
static uint16_t rte_be_to_cpu_16(rte_be16_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
#define RTE_DIM(a)
Definition: rte_common.h:905
#define RTE_ETHER_LOCAL_ADMIN_ADDR
Definition: rte_ether.h:85
static bool rte_ipv6_addr_is_linklocal(const struct rte_ipv6_addr *ip)
Definition: rte_ip6.h:278
static bool rte_ipv6_addr_is_sitelocal(const struct rte_ipv6_addr *ip)
Definition: rte_ip6.h:292
static uint16_t rte_ipv6_phdr_cksum(const struct rte_ipv6_hdr *ipv6_hdr, uint64_t ol_flags)
Definition: rte_ip6.h:561
static uint16_t rte_ipv6_udptcp_cksum(const struct rte_ipv6_hdr *ipv6_hdr, const void *l4_hdr)
Definition: rte_ip6.h:615
static bool rte_ipv6_addr_is_v4compat(const struct rte_ipv6_addr *ip)
Definition: rte_ip6.h:307
static bool rte_ipv6_addr_is_unspec(const struct rte_ipv6_addr *ip)
Definition: rte_ip6.h:244
static int rte_ipv6_check_version(const struct rte_ipv6_hdr *ip)
Definition: rte_ip6.h:502
#define RTE_IPV6_ADDR_LOOPBACK
Definition: rte_ip6.h:251
static bool rte_ipv6_addr_is_v4mapped(const struct rte_ipv6_addr *ip)
Definition: rte_ip6.h:325
static void rte_ether_mcast_from_ipv6(struct rte_ether_addr *mac, const struct rte_ipv6_addr *ip)
Definition: rte_ip6.h:456
static int rte_ipv6_udptcp_cksum_mbuf_verify(const struct rte_mbuf *m, const struct rte_ipv6_hdr *ipv6_hdr, uint16_t l4_off)
Definition: rte_ip6.h:733
static int rte_ipv6_get_next_ext(const uint8_t *p, int proto, size_t *ext_len)
Definition: rte_ip6.h:787
static int rte_ipv6_udptcp_cksum_verify(const struct rte_ipv6_hdr *ipv6_hdr, const void *l4_hdr)
Definition: rte_ip6.h:705
#define RTE_IPV6_MAX_DEPTH
Definition: rte_ip6.h:48
rte_ipv6_mc_scope
Definition: rte_ip6.h:348
@ RTE_IPV6_MC_SCOPE_NONE
Definition: rte_ip6.h:350
@ RTE_IPV6_MC_SCOPE_LINKLOCAL
Definition: rte_ip6.h:354
@ RTE_IPV6_MC_SCOPE_GLOBAL
Definition: rte_ip6.h:360
@ RTE_IPV6_MC_SCOPE_ORGLOCAL
Definition: rte_ip6.h:358
@ RTE_IPV6_MC_SCOPE_IFACELOCAL
Definition: rte_ip6.h:352
@ RTE_IPV6_MC_SCOPE_SITELOCAL
Definition: rte_ip6.h:356
#define RTE_IPV6_ADDR_UNSPEC
Definition: rte_ip6.h:233
static bool rte_ipv6_addr_eq(const struct rte_ipv6_addr *a, const struct rte_ipv6_addr *b)
Definition: rte_ip6.h:68
static uint16_t rte_ipv6_udptcp_cksum_mbuf(const struct rte_mbuf *m, const struct rte_ipv6_hdr *ipv6_hdr, uint16_t l4_off)
Definition: rte_ip6.h:672
#define RTE_IPV6_ADDR_SIZE
Definition: rte_ip6.h:43
static void rte_ipv6_solnode_from_addr(struct rte_ipv6_addr *sol, const struct rte_ipv6_addr *ip)
Definition: rte_ip6.h:434
static bool rte_ipv6_addr_is_loopback(const struct rte_ipv6_addr *ip)
Definition: rte_ip6.h:263
static void rte_ipv6_addr_mask(struct rte_ipv6_addr *ip, uint8_t depth)
Definition: rte_ip6.h:84
static bool rte_ipv6_addr_eq_prefix(const struct rte_ipv6_addr *a, const struct rte_ipv6_addr *b, uint8_t depth)
Definition: rte_ip6.h:109
static uint8_t rte_ipv6_mask_depth(const struct rte_ipv6_addr *mask)
Definition: rte_ip6.h:132
struct __rte_aligned(2) __rte_packed_begin rte_ipv6_hdr
Definition: rte_ip6.h:469
static bool rte_ipv6_addr_is_mcast(const struct rte_ipv6_addr *ip)
Definition: rte_ip6.h:340
#define RTE_MBUF_F_TX_UDP_SEG
#define RTE_MBUF_F_TX_TCP_SEG
uint32_t pkt_len