gso: fix payload unit size for UDP
authorYi Yang <yangyi01@inspur.com>
Thu, 17 Sep 2020 02:12:49 +0000 (10:12 +0800)
committerFerruh Yigit <ferruh.yigit@intel.com>
Fri, 18 Sep 2020 16:55:12 +0000 (18:55 +0200)
Fragment offset of IPv4 header is measured in units of
8 bytes. Fragment offset of UDP fragments will be wrong
after GSO if pyld_unit_size isn't multiple of 8. Say
pyld_unit_size is 1500, fragment offset of the second
UDP fragment will be 187 (i.e. 1500 / 8), which means 1496,
and it will result in 4-byte data loss (1500 - 1496 = 4).
So UDP GRO will reassemble out a wrong packet.

Fixes: b166d4f30b66 ("gso: support UDP/IPv4 fragmentation")
Cc: stable@dpdk.org
Signed-off-by: Yi Yang <yangyi01@inspur.com>
Acked-by: Jiayu Hu <jiayu.hu@intel.com>
lib/librte_gso/gso_udp4.c

index 21fea09..6fa68f2 100644 (file)
@@ -69,7 +69,10 @@ gso_udp4_segment(struct rte_mbuf *pkt,
                return 1;
        }
 
-       pyld_unit_size = gso_size - hdr_offset;
+       /* pyld_unit_size must be a multiple of 8 because frag_off
+        * uses 8 bytes as unit.
+        */
+       pyld_unit_size = (gso_size - hdr_offset) & ~7U;
 
        /* Segment the payload */
        ret = gso_do_segment(pkt, hdr_offset, pyld_unit_size, direct_pool,