> DPDK version of IPv6 reassembly only handles a fragment header placed
> directly after the IPv6 header. With other extension headers in the
> unfragmentable part, ipv6_frag_reassemble() patches the wrong
> next-header field, miscomputes the payload length, and shifts the
> wrong bytes, corrupting the result.
> 
> Drop the fragment when l3_len covers more than the IPv6 and fragment
> headers. RFC 8200 allows a receiver to discard packets whose extension
> headers are not in the recommended order, and RFC 9099 recommends
> dropping non-conforming fragmented IPv6 packets, so dropping here is
> permitted rather than a deviation.
> 
> Fixes: 4f1a8f633862 ("ip_frag: add IPv6 reassembly")
> Cc: [email protected]
> 
> Signed-off-by: Stephen Hemminger <[email protected]>
> ---
>  lib/ip_frag/rte_ipv6_reassembly.c | 13 +++++++++++++
>  1 file changed, 13 insertions(+)
> 
> diff --git a/lib/ip_frag/rte_ipv6_reassembly.c 
> b/lib/ip_frag/rte_ipv6_reassembly.c
> index 0e809a01e5..7c1659002b 100644
> --- a/lib/ip_frag/rte_ipv6_reassembly.c
> +++ b/lib/ip_frag/rte_ipv6_reassembly.c
> @@ -180,6 +180,19 @@ rte_ipv6_frag_reassemble_packet(struct rte_ip_frag_tbl
> *tbl,
>               return NULL;
>       }
> 
> +     /*
> +      * Only a fragment header directly following the IPv6 header is
> +      * supported. Other extension headers in the unfragmentable part are
> +      * not handled: ipv6_frag_reassemble() assumes l3_len covers exactly
> +      * the IPv6 and fragment headers when it patches the next-header field
> +      * and removes the fragment header. Drop the fragment rather than
> +      * produce a corrupt datagram.
> +      */
> +     if (mb->l3_len != sizeof(struct rte_ipv6_hdr) + sizeof(*frag_hdr)) {
> +             IP_FRAG_MBUF2DR(dr, mb);
> +             return NULL;
> +     }
> +

Hmm, not sure this is a right thing.
Yes, we don't support properly ipv6 options that are *before* fragment hreader
(so called Per-Fragment  Headers), but AFAIR we do support ipv6 options
that come *after* fragment header (Extension headers). 

>       if (unlikely(trim > 0))
>               rte_pktmbuf_trim(mb, trim);
> 
> --
> 2.53.0

Reply via email to