From: Rahul Bhansali <rbhans...@marvell.com> In reassembly path, next header field in IPv6 header is not updated correctly, hence reassembled packet is corrupted. This fix will consider IPv6 fragment header presence at start/mid/end in extension list and update the next header field accordingly.
Fixes: ec28231ed260 ("net/cnxk: support reassembly of multi-segment packets") Signed-off-by: Rahul Bhansali <rbhans...@marvell.com> --- drivers/net/cnxk/cn10k_rx.h | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/drivers/net/cnxk/cn10k_rx.h b/drivers/net/cnxk/cn10k_rx.h index 982fd26045..41d11349fd 100644 --- a/drivers/net/cnxk/cn10k_rx.h +++ b/drivers/net/cnxk/cn10k_rx.h @@ -205,26 +205,36 @@ nix_sec_reass_first_frag_update(struct rte_mbuf *head, const uint8_t *m_ipptr, struct rte_ipv6_hdr *hdr = (struct rte_ipv6_hdr *)ipptr; size_t ext_len = sizeof(struct rte_ipv6_hdr); uint8_t *nxt_hdr = (uint8_t *)hdr; + uint8_t *nxt_proto = &hdr->proto; int nh = hdr->proto; *ihl = 0; + tot_len = 0; while (nh != -EINVAL) { nxt_hdr += ext_len; *ihl += ext_len; + if (nh == IPPROTO_FRAGMENT) { + *nxt_proto = *nxt_hdr; + tot_len = *ihl; + } nh = rte_ipv6_get_next_ext(nxt_hdr, nh, &ext_len); + nxt_proto = nxt_hdr; } /* Remove the frag header by moving header 8 bytes forward */ hdr->payload_len = rte_cpu_to_be_16(fragx_sum + *ihl - 8 - sizeof(struct rte_ipv6_hdr)); + /* tot_len is sum of all IP header's length before fragment header */ rte_memcpy(rte_pktmbuf_mtod_offset(head, void *, 8), rte_pktmbuf_mtod(head, void *), - lcptr + sizeof(struct rte_ipv6_hdr)); + lcptr + tot_len); head->data_len -= 8; head->data_off += 8; head->pkt_len = lcptr + *ihl - 8 + fragx_sum; + /* ihl l3hdr size value should be up to fragment header for next frags */ + *ihl = tot_len + 8; } } -- 2.25.1