From d4a1dc78a3bfee522eba22386c422f01d7ba4ee2 Mon Sep 17 00:00:00 2001 From: Eli Britstein Date: Mon, 13 Nov 2023 09:29:41 +0200 Subject: [PATCH] net/mlx5: zero UDP checksum over IPv4 in encapsulation [ upstream commit e407221d58ffdfd9b7c80f8e4fff99f67cdbd6e9 ] A zero UDP csum indicates it should not be validated by the receiver. The HW may not calculate UDP csum after encap. The cited commit made sure the UDP csum is zero for UDP over IPv6, mistakenly not handling UDP over IPv4. Fix it. Fixes: bf1d7d9a033a ("net/mlx5: zero out UDP checksum in encapsulation") Signed-off-by: Eli Britstein Acked-by: Suanming Mou --- drivers/net/mlx5/mlx5_flow_dv.c | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c index 1b6467e1b1..0c66c76ef5 100644 --- a/drivers/net/mlx5/mlx5_flow_dv.c +++ b/drivers/net/mlx5/mlx5_flow_dv.c @@ -4253,6 +4253,7 @@ flow_dv_zero_encap_udp_csum(void *data, struct rte_flow_error *error) { struct rte_ether_hdr *eth = NULL; struct rte_vlan_hdr *vlan = NULL; + struct rte_ipv4_hdr *ipv4 = NULL; struct rte_ipv6_hdr *ipv6 = NULL; struct rte_udp_hdr *udp = NULL; char *next_hdr; @@ -4269,24 +4270,27 @@ flow_dv_zero_encap_udp_csum(void *data, struct rte_flow_error *error) next_hdr += sizeof(struct rte_vlan_hdr); } - /* HW calculates IPv4 csum. no need to proceed */ - if (proto == RTE_ETHER_TYPE_IPV4) - return 0; - /* non IPv4/IPv6 header. not supported */ - if (proto != RTE_ETHER_TYPE_IPV6) { + if (proto != RTE_ETHER_TYPE_IPV4 && proto != RTE_ETHER_TYPE_IPV6) { return rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION, NULL, "Cannot offload non IPv4/IPv6"); } - ipv6 = (struct rte_ipv6_hdr *)next_hdr; - - /* ignore non UDP */ - if (ipv6->proto != IPPROTO_UDP) - return 0; + if (proto == RTE_ETHER_TYPE_IPV4) { + ipv4 = (struct rte_ipv4_hdr *)next_hdr; + /* ignore non UDP */ + if (ipv4->next_proto_id != IPPROTO_UDP) + return 0; + udp = (struct rte_udp_hdr *)(ipv4 + 1); + } else { + ipv6 = (struct rte_ipv6_hdr *)next_hdr; + /* ignore non UDP */ + if (ipv6->proto != IPPROTO_UDP) + return 0; + udp = (struct rte_udp_hdr *)(ipv6 + 1); + } - udp = (struct rte_udp_hdr *)(ipv6 + 1); udp->dgram_cksum = 0; return 0;