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);
409 ip->a[8] = mac->addr_bytes[0];
410 ip->a[9] = mac->addr_bytes[1];
411 ip->a[10] = mac->addr_bytes[2];
414 ip->a[13] = mac->addr_bytes[3];
415 ip->a[14] = mac->addr_bytes[4];
416 ip->a[15] = mac->addr_bytes[5];
433 memset(&sol->a[2], 0, 9);
436 sol->a[13] = ip->a[13];
437 sol->a[14] = ip->a[14];
438 sol->a[15] = ip->a[15];
453 mac->addr_bytes[0] = 0x33;
454 mac->addr_bytes[1] = 0x33;
455 mac->addr_bytes[2] = ip->a[12];
456 mac->addr_bytes[3] = ip->a[13];
457 mac->addr_bytes[4] = ip->a[14];
458 mac->addr_bytes[5] = ip->a[15];
469#if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN
470 uint32_t flow_label:20;
474#elif RTE_BYTE_ORDER == RTE_BIG_ENDIAN
478 uint32_t flow_label:20;
499 uint8_t version = ((
const uint8_t *)ip)[0];
500 if ((version & 0xf0) != 0x60)
506#define RTE_IPV6_SRCRT_TYPE_4 4
515 uint8_t segments_left;
529#define RTE_IPV6_HDR_FL_SHIFT 0
530#define RTE_IPV6_HDR_TC_SHIFT 20
531#define RTE_IPV6_HDR_FL_MASK ((1u << RTE_IPV6_HDR_TC_SHIFT) - 1)
532#define RTE_IPV6_HDR_TC_MASK (0xff << RTE_IPV6_HDR_TC_SHIFT)
533#define RTE_IPV6_HDR_DSCP_MASK (0xfc << RTE_IPV6_HDR_TC_SHIFT)
534#define RTE_IPV6_HDR_ECN_MASK (0x03 << RTE_IPV6_HDR_TC_SHIFT)
535#define RTE_IPV6_HDR_ECN_CE RTE_IPV6_HDR_ECN_MASK
537#define RTE_IPV6_MIN_MTU 1280
555static inline uint16_t
564 psd_hdr.proto = (uint32_t)(ipv6_hdr->proto << 24);
568 psd_hdr.len = ipv6_hdr->payload_len;
570 sum = __rte_raw_cksum(&ipv6_hdr->src_addr,
571 sizeof(ipv6_hdr->src_addr) +
sizeof(ipv6_hdr->dst_addr),
573 sum = __rte_raw_cksum(&psd_hdr,
sizeof(psd_hdr), sum);
574 return __rte_raw_cksum_reduce(sum);
580static inline uint16_t
581__rte_ipv6_udptcp_cksum(
const struct rte_ipv6_hdr *ipv6_hdr,
const void *l4_hdr)
591 cksum = ((cksum & 0xffff0000) >> 16) + (cksum & 0xffff);
593 return (uint16_t)cksum;
609static inline uint16_t
612 uint16_t cksum = __rte_ipv6_udptcp_cksum(ipv6_hdr, l4_hdr);
621 if (cksum == 0 && ipv6_hdr->proto == IPPROTO_UDP)
630static inline uint16_t
631__rte_ipv6_udptcp_cksum_mbuf(
const struct rte_mbuf *m,
632 const struct rte_ipv6_hdr *ipv6_hdr,
646 cksum = ((cksum & 0xffff0000) >> 16) + (cksum & 0xffff);
648 return (uint16_t)cksum;
666static inline uint16_t
668 const struct rte_ipv6_hdr *ipv6_hdr, uint16_t l4_off)
670 uint16_t cksum = __rte_ipv6_udptcp_cksum_mbuf(m, ipv6_hdr, l4_off);
679 if (cksum == 0 && ipv6_hdr->proto == IPPROTO_UDP)
703 uint16_t cksum = __rte_ipv6_udptcp_cksum(ipv6_hdr, l4_hdr);
729 const struct rte_ipv6_hdr *ipv6_hdr,
732 uint16_t cksum = __rte_ipv6_udptcp_cksum_mbuf(m, ipv6_hdr, l4_off);
741#define RTE_IPV6_EHDR_MF_SHIFT 0
742#define RTE_IPV6_EHDR_MF_MASK 1
743#define RTE_IPV6_EHDR_FO_SHIFT 3
744#define RTE_IPV6_EHDR_FO_MASK (~((1 << RTE_IPV6_EHDR_FO_SHIFT) - 1))
745#define RTE_IPV6_EHDR_FO_ALIGN (1 << RTE_IPV6_EHDR_FO_SHIFT)
747#define RTE_IPV6_FRAG_USED_MASK (RTE_IPV6_EHDR_MF_MASK | RTE_IPV6_EHDR_FO_MASK)
749#define RTE_IPV6_GET_MF(x) ((x) & RTE_IPV6_EHDR_MF_MASK)
750#define RTE_IPV6_GET_FO(x) ((x) >> RTE_IPV6_EHDR_FO_SHIFT)
752#define RTE_IPV6_SET_FRAG_DATA(fo, mf) \
753 (((fo) & RTE_IPV6_EHDR_FO_MASK) | ((mf) & RTE_IPV6_EHDR_MF_MASK))
763#define RTE_IPV6_FRAG_HDR_SIZE sizeof(struct rte_ipv6_fragment_ext)
789 *ext_len = (*p + 2) *
sizeof(uint32_t);
792 case IPPROTO_HOPOPTS:
793 case IPPROTO_ROUTING:
794 case IPPROTO_DSTOPTS:
796 *ext_len = (*p + 1) *
sizeof(uint64_t);
799 case IPPROTO_FRAGMENT:
801 *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)
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
struct __rte_aligned(2) rte_ipv6_hdr
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)
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