[dpdk-dev] [PATCH v4 3/3] ip_frag: extend IPv6 extension header parsing
Cody Doucette
doucette at bu.edu
Wed Oct 31 01:15:35 CET 2018
Please ignore v4 since I renamed something and caused a duplicate patch to
be sent. I will send a clean v5.
Cody
On Tue, Oct 30, 2018 at 8:12 PM Cody Doucette <doucette at bu.edu> wrote:
> Add the ability to parse IPv6 extenders to find the
> IPv6 fragment header, and update callers.
>
> According to RFC 8200, there is no guarantee that the IPv6
> Fragment extension header will come before any other extension
> header, even though it is recommended.
>
> Signed-off-by: Cody Doucette <doucette at bu.edu>
> Signed-off-by: Qiaobin Fu <qiaobinf at bu.edu>
> Reviewed-by: Michel Machado <michel at digirati.com.br>
> ---
> examples/ip_reassembly/main.c | 6 ++--
> lib/librte_ip_frag/rte_ip_frag.h | 23 ++++++-------
> lib/librte_ip_frag/rte_ip_frag_version.map | 1 +
> lib/librte_ip_frag/rte_ipv6_fragmentation.c | 38 +++++++++++++++++++++
> lib/librte_ip_frag/rte_ipv6_reassembly.c | 4 +--
> lib/librte_port/rte_port_ras.c | 6 ++--
> 6 files changed, 59 insertions(+), 19 deletions(-)
>
> diff --git a/examples/ip_reassembly/main.c b/examples/ip_reassembly/main.c
> index 17b55d4c7..3a827bd6c 100644
> --- a/examples/ip_reassembly/main.c
> +++ b/examples/ip_reassembly/main.c
> @@ -365,12 +365,14 @@ reassemble(struct rte_mbuf *m, uint16_t portid,
> uint32_t queue,
> eth_hdr->ether_type = rte_be_to_cpu_16(ETHER_TYPE_IPv4);
> } else if (RTE_ETH_IS_IPV6_HDR(m->packet_type)) {
> /* if packet is IPv6 */
> - struct ipv6_extension_fragment *frag_hdr;
> + const struct ipv6_extension_fragment *frag_hdr;
> + struct ipv6_extension_fragment frag_hdr_buf;
> struct ipv6_hdr *ip_hdr;
>
> ip_hdr = (struct ipv6_hdr *)(eth_hdr + 1);
>
> - frag_hdr = rte_ipv6_frag_get_ipv6_fragment_header(ip_hdr);
> + frag_hdr = rte_ipv6_frag_get_ipv6_fragment_header(m,
> + ip_hdr, &frag_hdr_buf);
>
> if (frag_hdr != NULL) {
> struct rte_mbuf *mo;
> diff --git a/lib/librte_ip_frag/rte_ip_frag.h
> b/lib/librte_ip_frag/rte_ip_frag.h
> index 7f425f610..6fc8106bc 100644
> --- a/lib/librte_ip_frag/rte_ip_frag.h
> +++ b/lib/librte_ip_frag/rte_ip_frag.h
> @@ -211,28 +211,25 @@ rte_ipv6_fragment_packet(struct rte_mbuf *pkt_in,
> struct rte_mbuf *rte_ipv6_frag_reassemble_packet(struct rte_ip_frag_tbl
> *tbl,
> struct rte_ip_frag_death_row *dr,
> struct rte_mbuf *mb, uint64_t tms, struct ipv6_hdr *ip_hdr,
> - struct ipv6_extension_fragment *frag_hdr);
> + const struct ipv6_extension_fragment *frag_hdr);
>
> /**
> * Return a pointer to the packet's fragment header, if found.
> - * It only looks at the extension header that's right after the fixed IPv6
> - * header, and doesn't follow the whole chain of extension headers.
> *
> - * @param hdr
> + * @param pkt
> + * Pointer to the mbuf of the packet.
> + * @param ip_hdr
> * Pointer to the IPv6 header.
> + * @param frag_hdr
> + * A pointer to the buffer where the fragment header
> + * will be copied if it is not contiguous in mbuf data.
> * @return
> * Pointer to the IPv6 fragment extension header, or NULL if it's not
> * present.
> */
> -static inline struct ipv6_extension_fragment *
> -rte_ipv6_frag_get_ipv6_fragment_header(struct ipv6_hdr *hdr)
> -{
> - if (hdr->proto == IPPROTO_FRAGMENT) {
> - return (struct ipv6_extension_fragment *) ++hdr;
> - }
> - else
> - return NULL;
> -}
> +const struct ipv6_extension_fragment
> *rte_ipv6_frag_get_ipv6_fragment_header(
> + struct rte_mbuf *pkt, const struct ipv6_hdr *ip_hdr,
> + struct ipv6_extension_fragment *frag_hdr);
>
> /**
> * IPv4 fragmentation.
> diff --git a/lib/librte_ip_frag/rte_ip_frag_version.map
> b/lib/librte_ip_frag/rte_ip_frag_version.map
> index d40d5515f..8b4c82d08 100644
> --- a/lib/librte_ip_frag/rte_ip_frag_version.map
> +++ b/lib/librte_ip_frag/rte_ip_frag_version.map
> @@ -8,6 +8,7 @@ DPDK_2.0 {
> rte_ipv4_fragment_packet;
> rte_ipv6_frag_reassemble_packet;
> rte_ipv6_fragment_packet;
> + rte_ipv6_frag_get_ipv6_fragment_header;
>
> local: *;
> };
> diff --git a/lib/librte_ip_frag/rte_ipv6_fragmentation.c
> b/lib/librte_ip_frag/rte_ipv6_fragmentation.c
> index 62a7e4e83..bd847dd3d 100644
> --- a/lib/librte_ip_frag/rte_ipv6_fragmentation.c
> +++ b/lib/librte_ip_frag/rte_ipv6_fragmentation.c
> @@ -176,3 +176,41 @@ rte_ipv6_fragment_packet(struct rte_mbuf *pkt_in,
>
> return out_pkt_pos;
> }
> +
> +const struct ipv6_extension_fragment *
> +rte_ipv6_frag_get_ipv6_fragment_header(struct rte_mbuf *pkt,
> + const struct ipv6_hdr *ip_hdr,
> + struct ipv6_extension_fragment *frag_hdr)
> +{
> + size_t offset = sizeof(struct ipv6_hdr);
> + uint8_t nexthdr = ip_hdr->proto;
> +
> + while (ipv6_ext_hdr(nexthdr)) {
> + struct ipv6_opt_hdr opt;
> + const struct ipv6_opt_hdr *popt = rte_pktmbuf_read(pkt,
> + offset, sizeof(opt), &opt);
> + if (popt == NULL)
> + return NULL;
> +
> + switch (nexthdr) {
> + case IPPROTO_NONE:
> + return NULL;
> +
> + case IPPROTO_FRAGMENT:
> + return rte_pktmbuf_read(pkt, offset,
> + sizeof(*frag_hdr), frag_hdr);
> +
> + case IPPROTO_AH:
> + offset += (popt->hdrlen + 2) << 2;
> + break;
> +
> + default:
> + offset += (popt->hdrlen + 1) << 3;
> + break;
> + }
> +
> + nexthdr = popt->nexthdr;
> + }
> +
> + return NULL;
> +}
> diff --git a/lib/librte_ip_frag/rte_ipv6_reassembly.c
> b/lib/librte_ip_frag/rte_ipv6_reassembly.c
> index db249fe60..b2d67a3f0 100644
> --- a/lib/librte_ip_frag/rte_ipv6_reassembly.c
> +++ b/lib/librte_ip_frag/rte_ipv6_reassembly.c
> @@ -135,8 +135,8 @@ ipv6_frag_reassemble(struct ip_frag_pkt *fp)
> #define FRAG_OFFSET(x) (rte_cpu_to_be_16(x) >> 3)
> struct rte_mbuf *
> rte_ipv6_frag_reassemble_packet(struct rte_ip_frag_tbl *tbl,
> - struct rte_ip_frag_death_row *dr, struct rte_mbuf *mb,
> uint64_t tms,
> - struct ipv6_hdr *ip_hdr, struct ipv6_extension_fragment
> *frag_hdr)
> + struct rte_ip_frag_death_row *dr, struct rte_mbuf *mb, uint64_t
> tms,
> + struct ipv6_hdr *ip_hdr, const struct ipv6_extension_fragment
> *frag_hdr)
> {
> struct ip_frag_pkt *fp;
> struct ip_frag_key key;
> diff --git a/lib/librte_port/rte_port_ras.c
> b/lib/librte_port/rte_port_ras.c
> index c8b2e19bf..28764f744 100644
> --- a/lib/librte_port/rte_port_ras.c
> +++ b/lib/librte_port/rte_port_ras.c
> @@ -184,9 +184,11 @@ process_ipv6(struct rte_port_ring_writer_ras *p,
> struct rte_mbuf *pkt)
> /* Assume there is no ethernet header */
> struct ipv6_hdr *pkt_hdr = rte_pktmbuf_mtod(pkt, struct ipv6_hdr
> *);
>
> - struct ipv6_extension_fragment *frag_hdr;
> + const struct ipv6_extension_fragment *frag_hdr;
> + struct ipv6_extension_fragment frag_hdr_buf;
> uint16_t frag_data = 0;
> - frag_hdr = rte_ipv6_frag_get_ipv6_fragment_header(pkt_hdr);
> + frag_hdr = rte_ipv6_frag_get_ipv6_fragment_header(pkt, pkt_hdr,
> + &frag_hdr_buf);
> if (frag_hdr != NULL)
> frag_data = rte_be_to_cpu_16(frag_hdr->frag_data);
>
> --
> 2.17.1
>
>
More information about the dev
mailing list