21#ifdef RTE_EXEC_ENV_WINDOWS
24#include <sys/socket.h>
26#include <netinet/in.h>
28#include <netinet/ip6.h>
43#define RTE_IPV6_ADDR_SIZE 16
48#define RTE_IPV6_MAX_DEPTH (RTE_IPV6_ADDR_SIZE * CHAR_BIT)
70 return memcmp(a, b,
sizeof(*a)) == 0;
87 unsigned int d = depth / CHAR_BIT;
88 uint8_t mask = ~(UINT8_MAX >> (depth % CHAR_BIT));
91 while (d <
sizeof(*ip))
112 unsigned int d = depth / CHAR_BIT;
113 uint8_t mask = ~(UINT8_MAX >> (depth % CHAR_BIT));
115 if ((a->a[d] ^ b->a[d]) & mask)
118 return memcmp(a, b, d) == 0;
136 for (
unsigned int i = 0; i <
RTE_DIM(mask->a); i++) {
137 uint8_t m = mask->a[i];
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))
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))
179#define RTE_IPV6(a, b, c, d, e, f, g, h) \
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) \
195#define RTE_IPV6_ADDR_FMT \
196 "%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x"
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])
229#define RTE_IPV6_MASK_FULL \
230 RTE_IPV6(0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff)
233#define RTE_IPV6_ADDR_UNSPEC RTE_IPV6(0, 0, 0, 0, 0, 0, 0, 0)
251#define RTE_IPV6_ADDR_LOOPBACK RTE_IPV6(0, 0, 0, 0, 0, 0, 0, 1)
280 return ip->a[0] == 0xfe && (ip->a[1] & 0xc0) == 0x80;
294 return ip->a[0] == 0xfe && (ip->a[1] & 0xc0) == 0xc0;
313#define RTE_IPV6_ADDR_PREFIX_V4MAPPED RTE_IPV6(0, 0, 0, 0, 0, 0xffff, 0, 0)
327 const struct rte_ipv6_addr prefix = RTE_IPV6_ADDR_PREFIX_V4MAPPED;
342 return ip->a[0] == 0xff;
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)
404rte_ipv6_llocal_from_ethernet(
struct rte_ipv6_addr *ip,
const struct rte_ether_addr *mac)
408 memset(&ip->a[2], 0, 6);
415 ip->a[9] = mac->addr_bytes[1];
416 ip->a[10] = mac->addr_bytes[2];
419 ip->a[13] = mac->addr_bytes[3];
420 ip->a[14] = mac->addr_bytes[4];
421 ip->a[15] = mac->addr_bytes[5];
438 memset(&sol->a[2], 0, 9);
441 sol->a[13] = ip->a[13];
442 sol->a[14] = ip->a[14];
443 sol->a[15] = ip->a[15];
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];
474#if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN
475 uint32_t flow_label:20;
479#elif RTE_BYTE_ORDER == RTE_BIG_ENDIAN
483 uint32_t flow_label:20;
504 uint8_t version = ((
const uint8_t *)ip)[0];
505 if ((version & 0xf0) != 0x60)
511#define RTE_IPV6_SRCRT_TYPE_4 4
520 uint8_t segments_left;
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
542#define RTE_IPV6_MIN_MTU 1280
560static inline uint16_t
569 psd_hdr.proto = (uint32_t)(ipv6_hdr->proto << 24);
573 psd_hdr.len = ipv6_hdr->payload_len;
575 sum = __rte_raw_cksum(&ipv6_hdr->src_addr,
576 sizeof(ipv6_hdr->src_addr) +
sizeof(ipv6_hdr->dst_addr),
578 sum = __rte_raw_cksum(&psd_hdr,
sizeof(psd_hdr), sum);
579 return __rte_raw_cksum_reduce(sum);
585static inline uint16_t
586__rte_ipv6_udptcp_cksum(
const struct rte_ipv6_hdr *ipv6_hdr,
const void *l4_hdr)
596 cksum = ((cksum & 0xffff0000) >> 16) + (cksum & 0xffff);
598 return (uint16_t)cksum;
614static inline uint16_t
617 uint16_t cksum = __rte_ipv6_udptcp_cksum(ipv6_hdr, l4_hdr);
626 if (cksum == 0 && ipv6_hdr->proto == IPPROTO_UDP)
635static inline uint16_t
636__rte_ipv6_udptcp_cksum_mbuf(
const struct rte_mbuf *m,
637 const struct rte_ipv6_hdr *ipv6_hdr,
651 cksum = ((cksum & 0xffff0000) >> 16) + (cksum & 0xffff);
653 return (uint16_t)cksum;
671static inline uint16_t
673 const struct rte_ipv6_hdr *ipv6_hdr, uint16_t l4_off)
675 uint16_t cksum = __rte_ipv6_udptcp_cksum_mbuf(m, ipv6_hdr, l4_off);
684 if (cksum == 0 && ipv6_hdr->proto == IPPROTO_UDP)
708 uint16_t cksum = __rte_ipv6_udptcp_cksum(ipv6_hdr, l4_hdr);
734 const struct rte_ipv6_hdr *ipv6_hdr,
737 uint16_t cksum = __rte_ipv6_udptcp_cksum_mbuf(m, ipv6_hdr, l4_off);
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)
752#define RTE_IPV6_FRAG_USED_MASK (RTE_IPV6_EHDR_MF_MASK | RTE_IPV6_EHDR_FO_MASK)
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)
757#define RTE_IPV6_SET_FRAG_DATA(fo, mf) \
758 (((fo) & RTE_IPV6_EHDR_FO_MASK) | ((mf) & RTE_IPV6_EHDR_MF_MASK))
768#define RTE_IPV6_FRAG_HDR_SIZE sizeof(struct rte_ipv6_fragment_ext)
794 *ext_len = (*p + 2) *
sizeof(uint32_t);
797 case IPPROTO_HOPOPTS:
798 case IPPROTO_ROUTING:
799 case IPPROTO_DSTOPTS:
801 *ext_len = (*p + 1) *
sizeof(uint64_t);
804 case IPPROTO_FRAGMENT:
806 *ext_len = RTE_IPV6_FRAG_HDR_SIZE;
static uint16_t rte_be_to_cpu_16(rte_be16_t x)
static uint16_t rte_raw_cksum(const void *buf, size_t len)
static int rte_raw_cksum_mbuf(const struct rte_mbuf *m, uint32_t off, uint32_t len, uint16_t *cksum)
#define __rte_packed_begin
#define RTE_ETHER_LOCAL_ADMIN_ADDR
static bool rte_ipv6_addr_is_linklocal(const struct rte_ipv6_addr *ip)
static bool rte_ipv6_addr_is_sitelocal(const struct rte_ipv6_addr *ip)
static uint16_t rte_ipv6_phdr_cksum(const struct rte_ipv6_hdr *ipv6_hdr, uint64_t ol_flags)
static uint16_t rte_ipv6_udptcp_cksum(const struct rte_ipv6_hdr *ipv6_hdr, const void *l4_hdr)
static bool rte_ipv6_addr_is_v4compat(const struct rte_ipv6_addr *ip)
static bool rte_ipv6_addr_is_unspec(const struct rte_ipv6_addr *ip)
static int rte_ipv6_check_version(const struct rte_ipv6_hdr *ip)
#define RTE_IPV6_ADDR_LOOPBACK
static bool rte_ipv6_addr_is_v4mapped(const struct rte_ipv6_addr *ip)
static void rte_ether_mcast_from_ipv6(struct rte_ether_addr *mac, const struct rte_ipv6_addr *ip)
static int rte_ipv6_udptcp_cksum_mbuf_verify(const struct rte_mbuf *m, const struct rte_ipv6_hdr *ipv6_hdr, uint16_t l4_off)
static int rte_ipv6_get_next_ext(const uint8_t *p, int proto, size_t *ext_len)
static int rte_ipv6_udptcp_cksum_verify(const struct rte_ipv6_hdr *ipv6_hdr, const void *l4_hdr)
#define RTE_IPV6_MAX_DEPTH
@ RTE_IPV6_MC_SCOPE_LINKLOCAL
@ RTE_IPV6_MC_SCOPE_GLOBAL
@ RTE_IPV6_MC_SCOPE_ORGLOCAL
@ RTE_IPV6_MC_SCOPE_IFACELOCAL
@ RTE_IPV6_MC_SCOPE_SITELOCAL
#define RTE_IPV6_ADDR_UNSPEC
static bool rte_ipv6_addr_eq(const struct rte_ipv6_addr *a, const struct rte_ipv6_addr *b)
static uint16_t rte_ipv6_udptcp_cksum_mbuf(const struct rte_mbuf *m, const struct rte_ipv6_hdr *ipv6_hdr, uint16_t l4_off)
#define RTE_IPV6_ADDR_SIZE
static void rte_ipv6_solnode_from_addr(struct rte_ipv6_addr *sol, const struct rte_ipv6_addr *ip)
static bool rte_ipv6_addr_is_loopback(const struct rte_ipv6_addr *ip)
static void rte_ipv6_addr_mask(struct rte_ipv6_addr *ip, uint8_t depth)
static bool rte_ipv6_addr_eq_prefix(const struct rte_ipv6_addr *a, const struct rte_ipv6_addr *b, uint8_t depth)
static uint8_t rte_ipv6_mask_depth(const struct rte_ipv6_addr *mask)
struct __rte_aligned(2) __rte_packed_begin rte_ipv6_hdr
static bool rte_ipv6_addr_is_mcast(const struct rte_ipv6_addr *ip)
#define RTE_MBUF_F_TX_UDP_SEG
#define RTE_MBUF_F_TX_TCP_SEG