From: Huichao Cai Date: Sat, 9 Oct 2021 07:27:04 +0000 (+0800) Subject: ip_frag: fix fragmenting IPv4 fragment X-Git-Url: http://git.droids-corp.org/?a=commitdiff_plain;h=567473433b7e63e12943be29926c13bd491bcca6;p=dpdk.git ip_frag: fix fragmenting IPv4 fragment Current implementation of rte_ipv4_fragment_packet() doesn’t take into account offset and flag values of the given packet, but blindly assumes they are always zero (original packet is not fragmented). According to RFC791, fragment and flag values for new fragment should take into account values provided in the original IPv4 packet. Fixes: 4c38e5532a07 ("ip_frag: refactor IPv4 fragmentation into a proper library") Cc: stable@dpdk.org Signed-off-by: Huichao Cai Acked-by: Konstantin Ananyev --- diff --git a/lib/ip_frag/rte_ipv4_fragmentation.c b/lib/ip_frag/rte_ipv4_fragmentation.c index 2e7739d027..fead5a985a 100644 --- a/lib/ip_frag/rte_ipv4_fragmentation.c +++ b/lib/ip_frag/rte_ipv4_fragmentation.c @@ -75,7 +75,7 @@ rte_ipv4_fragment_packet(struct rte_mbuf *pkt_in, uint32_t out_pkt_pos, in_seg_data_pos; uint32_t more_in_segs; uint16_t fragment_offset, flag_offset, frag_size, header_len; - uint16_t frag_bytes_remaining; + uint16_t frag_bytes_remaining, not_last_frag; /* * Formal parameter checking. @@ -116,7 +116,9 @@ rte_ipv4_fragment_packet(struct rte_mbuf *pkt_in, in_seg = pkt_in; in_seg_data_pos = header_len; out_pkt_pos = 0; - fragment_offset = 0; + fragment_offset = (uint16_t)((flag_offset & + RTE_IPV4_HDR_OFFSET_MASK) << RTE_IPV4_HDR_FO_SHIFT); + not_last_frag = (uint16_t)(flag_offset & IPV4_HDR_MF_MASK); more_in_segs = 1; while (likely(more_in_segs)) { @@ -186,7 +188,8 @@ rte_ipv4_fragment_packet(struct rte_mbuf *pkt_in, __fill_ipv4hdr_frag(out_hdr, in_hdr, header_len, (uint16_t)out_pkt->pkt_len, - flag_offset, fragment_offset, more_in_segs); + flag_offset, fragment_offset, + not_last_frag || more_in_segs); fragment_offset = (uint16_t)(fragment_offset + out_pkt->pkt_len - header_len);