From 9ab984b79bde82438d97145b4be72413b5e2a4ed Mon Sep 17 00:00:00 2001 From: Ilya Maximets Date: Fri, 8 Mar 2024 19:11:56 +0100 Subject: [PATCH] netdev-dpdk: Clean up all marker flags if no offloads requested. Some drivers (primarily, Intel ones) do not expect any marking flags being set if no offloads are requested. If these flags are present, driver will fail Tx preparation or behave abnormally. For exmaple, ixgbe driver will refuse to process the packet with only RTE_MBUF_F_TX_TUNNEL_GENEVE and RTE_MBUF_F_TX_OUTER_IPV4 set. This pretty much breaks geneve tunnels on these cards. Fixes: 084c8087292c ("userspace: Support VXLAN and GENEVE TSO.") Reported-at: https://github.com/openvswitch/ovs-issues/issues/321 Signed-off-by: Ilya Maximets --- lib/netdev-dpdk.c | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/lib/netdev-dpdk.c b/lib/netdev-dpdk.c index 9444c53b18f..10dc7270b2d 100644 --- a/lib/netdev-dpdk.c +++ b/lib/netdev-dpdk.c @@ -607,6 +607,9 @@ int netdev_dpdk_get_vid(const struct netdev_dpdk *dev); struct ingress_policer * netdev_dpdk_get_ingress_policer(const struct netdev_dpdk *dev); +static void netdev_dpdk_mbuf_dump(const char *prefix, const char *message, + const struct rte_mbuf *); + static bool is_dpdk_class(const struct netdev_class *class) { @@ -2569,9 +2572,29 @@ netdev_dpdk_prep_hwol_packet(struct netdev_dpdk *dev, struct rte_mbuf *mbuf) struct dp_packet *pkt = CONTAINER_OF(mbuf, struct dp_packet, mbuf); struct tcp_header *th; - if (!(mbuf->ol_flags & (RTE_MBUF_F_TX_IP_CKSUM | RTE_MBUF_F_TX_L4_MASK - | RTE_MBUF_F_TX_TCP_SEG))) { - mbuf->ol_flags &= ~(RTE_MBUF_F_TX_IPV4 | RTE_MBUF_F_TX_IPV6); + const uint64_t all_requests = (RTE_MBUF_F_TX_IP_CKSUM | + RTE_MBUF_F_TX_L4_MASK | + RTE_MBUF_F_TX_OUTER_IP_CKSUM | + RTE_MBUF_F_TX_OUTER_UDP_CKSUM | + RTE_MBUF_F_TX_TCP_SEG); + const uint64_t all_marks = (RTE_MBUF_F_TX_IPV4 | + RTE_MBUF_F_TX_IPV6 | + RTE_MBUF_F_TX_OUTER_IPV4 | + RTE_MBUF_F_TX_OUTER_IPV6 | + RTE_MBUF_F_TX_TUNNEL_MASK); + + if (!(mbuf->ol_flags & all_requests)) { + /* No offloads requested, no marks should be set. */ + mbuf->ol_flags &= ~all_marks; + + if (OVS_UNLIKELY(mbuf->ol_flags & RTE_MBUF_F_TX_OFFLOAD_MASK)) { + VLOG_WARN_RL(&rl, "%s: Unexpected Tx offload flags: 0x%"PRIx64, + netdev_get_name(&dev->up), + mbuf->ol_flags & RTE_MBUF_F_TX_OFFLOAD_MASK); + netdev_dpdk_mbuf_dump(netdev_get_name(&dev->up), + "Packet with unexpected ol_flags", mbuf); + return false; + } return true; }