From 8f0e4d6a78a52e929aa4852bf94601ce7dc2199f Mon Sep 17 00:00:00 2001 From: Didier Pallard Date: Wed, 28 Mar 2018 17:43:42 +0200 Subject: [PATCH] net: export IPv6 header extensions skip function skip_ip6_ext function can be exported as a helper, it may be used by some PMD to skip IPv6 header extensions. Signed-off-by: Didier Pallard Acked-by: Olivier Matz Acked-by: Yong Wang --- lib/librte_net/Makefile | 1 + lib/librte_net/meson.build | 1 + lib/librte_net/rte_net.c | 21 ++++++++++++++------- lib/librte_net/rte_net.h | 27 +++++++++++++++++++++++++++ lib/librte_net/rte_net_version.map | 1 + 5 files changed, 44 insertions(+), 7 deletions(-) diff --git a/lib/librte_net/Makefile b/lib/librte_net/Makefile index 95ff54900d..85e403f417 100644 --- a/lib/librte_net/Makefile +++ b/lib/librte_net/Makefile @@ -5,6 +5,7 @@ include $(RTE_SDK)/mk/rte.vars.mk LIB = librte_net.a +CFLAGS += -DALLOW_EXPERIMENTAL_API CFLAGS += $(WERROR_FLAGS) -I$(SRCDIR) -O3 LDLIBS += -lrte_mbuf -lrte_eal -lrte_mempool diff --git a/lib/librte_net/meson.build b/lib/librte_net/meson.build index 78c0f03e57..d3ea1feb5b 100644 --- a/lib/librte_net/meson.build +++ b/lib/librte_net/meson.build @@ -2,6 +2,7 @@ # Copyright(c) 2017 Intel Corporation version = 1 +allow_experimental_apis = true headers = files('rte_ip.h', 'rte_tcp.h', 'rte_udp.h', diff --git a/lib/librte_net/rte_net.c b/lib/librte_net/rte_net.c index 56a13e3c4b..9eb7c74381 100644 --- a/lib/librte_net/rte_net.c +++ b/lib/librte_net/rte_net.c @@ -178,8 +178,8 @@ ip4_hlen(const struct ipv4_hdr *hdr) } /* parse ipv6 extended headers, update offset and return next proto */ -static uint16_t -skip_ip6_ext(uint16_t proto, const struct rte_mbuf *m, uint32_t *off, +int __rte_experimental +rte_net_skip_ip6_ext(uint16_t proto, const struct rte_mbuf *m, uint32_t *off, int *frag) { struct ext_hdr { @@ -201,7 +201,7 @@ skip_ip6_ext(uint16_t proto, const struct rte_mbuf *m, uint32_t *off, xh = rte_pktmbuf_read(m, *off, sizeof(*xh), &xh_copy); if (xh == NULL) - return 0; + return -1; *off += (xh->len + 1) * 8; proto = xh->next_hdr; break; @@ -209,7 +209,7 @@ skip_ip6_ext(uint16_t proto, const struct rte_mbuf *m, uint32_t *off, xh = rte_pktmbuf_read(m, *off, sizeof(*xh), &xh_copy); if (xh == NULL) - return 0; + return -1; *off += 8; proto = xh->next_hdr; *frag = 1; @@ -220,7 +220,7 @@ skip_ip6_ext(uint16_t proto, const struct rte_mbuf *m, uint32_t *off, return proto; } } - return 0; + return -1; } /* parse mbuf data to get packet type */ @@ -233,6 +233,7 @@ uint32_t rte_net_get_ptype(const struct rte_mbuf *m, uint32_t pkt_type = RTE_PTYPE_L2_ETHER; uint32_t off = 0; uint16_t proto; + int ret; if (hdr_lens == NULL) hdr_lens = &local_hdr_lens; @@ -316,7 +317,10 @@ uint32_t rte_net_get_ptype(const struct rte_mbuf *m, off += hdr_lens->l3_len; pkt_type |= ptype_l3_ip6(proto); if ((pkt_type & RTE_PTYPE_L3_MASK) == RTE_PTYPE_L3_IPV6_EXT) { - proto = skip_ip6_ext(proto, m, &off, &frag); + ret = rte_net_skip_ip6_ext(proto, m, &off, &frag); + if (ret < 0) + return pkt_type; + proto = ret; hdr_lens->l3_len = off - hdr_lens->l2_len; } if (proto == 0) @@ -449,7 +453,10 @@ uint32_t rte_net_get_ptype(const struct rte_mbuf *m, uint32_t prev_off; prev_off = off; - proto = skip_ip6_ext(proto, m, &off, &frag); + ret = rte_net_skip_ip6_ext(proto, m, &off, &frag); + if (ret < 0) + return pkt_type; + proto = ret; hdr_lens->inner_l3_len += off - prev_off; } if (proto == 0) diff --git a/lib/librte_net/rte_net.h b/lib/librte_net/rte_net.h index 0e97901f36..b6ab6e1d57 100644 --- a/lib/librte_net/rte_net.h +++ b/lib/librte_net/rte_net.h @@ -28,6 +28,33 @@ struct rte_net_hdr_lens { uint8_t inner_l4_len; }; +/** + * Skip IPv6 header extensions. + * + * This function skips all IPv6 extensions, returning size of + * complete header including options and final protocol value. + * + * @warning + * @b EXPERIMENTAL: this API may change without prior notice + * + * @param proto + * Protocol field of IPv6 header. + * @param m + * The packet mbuf to be parsed. + * @param off + * On input, must contain the offset to the first byte following + * IPv6 header, on output, contains offset to the first byte + * of next layer (after any IPv6 extension header) + * @param frag + * Contains 1 in output if packet is an IPv6 fragment. + * @return + * Protocol that follows IPv6 header. + * -1 if an error occurs during mbuf parsing. + */ +int __rte_experimental +rte_net_skip_ip6_ext(uint16_t proto, const struct rte_mbuf *m, uint32_t *off, + int *frag); + /** * Parse an Ethernet packet to get its packet type. * diff --git a/lib/librte_net/rte_net_version.map b/lib/librte_net/rte_net_version.map index 213e6fd327..8bc57d51c7 100644 --- a/lib/librte_net/rte_net_version.map +++ b/lib/librte_net/rte_net_version.map @@ -17,4 +17,5 @@ EXPERIMENTAL { global: rte_net_make_rarp_packet; + rte_net_skip_ip6_ext; } DPDK_17.05; -- 2.20.1