RTE_MBUF_F_TX_TCP_CKSUM is not a flag, but a 2-bit field, so checking
it with a simple binary 'and' is incorrect.  For example, this check
will succeed for a packet with UDP checksum requested as well.

Fix the check to avoid wrongly initializing tso_segz and potentially
accessing UDP header via TCP structure pointer.

The IPv4 checksum flag has to be set for any L4 checksum request,
regardless of the type, so moving this check out of the TCP condition.

Fixes: 8b5fe2dc6080 ("userspace: Add Generic Segmentation Offloading.")
Signed-off-by: Ilya Maximets <[email protected]>
---
 lib/netdev-dpdk.c | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/lib/netdev-dpdk.c b/lib/netdev-dpdk.c
index 270d3e11c..1ae2ef398 100644
--- a/lib/netdev-dpdk.c
+++ b/lib/netdev-dpdk.c
@@ -2634,7 +2634,7 @@ netdev_dpdk_prep_hwol_packet(struct netdev_dpdk *dev, 
struct rte_mbuf *mbuf)
         }
     }
 
-    if (mbuf->ol_flags & RTE_MBUF_F_TX_TCP_CKSUM) {
+    if ((mbuf->ol_flags & RTE_MBUF_F_TX_L4_MASK) == RTE_MBUF_F_TX_TCP_CKSUM) {
         if (!th) {
             VLOG_WARN_RL(&rl, "%s: TCP offloading without L4 header"
                          " pkt len: %"PRIu32"", dev->up.name, mbuf->pkt_len);
@@ -2661,11 +2661,14 @@ netdev_dpdk_prep_hwol_packet(struct netdev_dpdk *dev, 
struct rte_mbuf *mbuf)
                 return false;
             }
         }
+    }
 
-        if (mbuf->ol_flags & RTE_MBUF_F_TX_IPV4) {
-            mbuf->ol_flags |= RTE_MBUF_F_TX_IP_CKSUM;
-        }
+    /* If L4 checksum is requested, IPv4 should be requested as well. */
+    if (mbuf->ol_flags & RTE_MBUF_F_TX_L4_MASK
+        && mbuf->ol_flags & RTE_MBUF_F_TX_IPV4) {
+        mbuf->ol_flags |= RTE_MBUF_F_TX_IP_CKSUM;
     }
+
     return true;
 }
 
-- 
2.43.0

_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to