From 3d4f0446be424668093fef4b30cb635e1b86cdfa Mon Sep 17 00:00:00 2001 From: "Chopra, Manish" Date: Mon, 24 Apr 2017 10:00:46 -0700 Subject: [PATCH] qede: Disable tunnel offloads for non offloaded UDP ports Orabug: 26783820 This patch disables tunnel offloads via ndo_features_check() if given UDP port is not offloaded to hardware. This in turn allows to run multiple tunnel interfaces using different UDP ports. Signed-off-by: Manish Chopra Signed-off-by: Yuval Mintz Signed-off-by: David S. Miller [ Upstream commit 369bfd4ec77f1668e48d395e95849d29fccaa4c3 ] Signed-off-by: Somasundaram Krishnasamy --- drivers/net/ethernet/qlogic/qede/qede.h | 1 + drivers/net/ethernet/qlogic/qede/qede_main.c | 27 +++++++++++++++----- 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/drivers/net/ethernet/qlogic/qede/qede.h b/drivers/net/ethernet/qlogic/qede/qede.h index 273336e0165b..48812d8f83a4 100644 --- a/drivers/net/ethernet/qlogic/qede/qede.h +++ b/drivers/net/ethernet/qlogic/qede/qede.h @@ -233,6 +233,7 @@ struct qede_dev { struct delayed_work sp_task; unsigned long sp_flags; u16 vxlan_dst_port; + u16 geneve_dst_port; #ifdef CONFIG_RFS_ACCEL struct qede_arfs *arfs; diff --git a/drivers/net/ethernet/qlogic/qede/qede_main.c b/drivers/net/ethernet/qlogic/qede/qede_main.c index 9a0e11bf553b..1ed2b7cf4466 100644 --- a/drivers/net/ethernet/qlogic/qede/qede_main.c +++ b/drivers/net/ethernet/qlogic/qede/qede_main.c @@ -101,6 +101,9 @@ static const struct qed_eth_ops *qed_ops; #endif +#define NETIF_F_CSUM_MASK (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | \ + NETIF_F_HW_CSUM) + enum qede_pci_private { QEDE_PRIVATE_PF, QEDE_PRIVATE_VF @@ -552,15 +555,25 @@ static void qede_del_vxlan_port(struct net_device *dev, default: return features; } - /* Disable offloads for geneve tunnels, as HW can't parse - * the geneve header which has option length greater than 32B. + * the geneve header which has option length greater than 32b + * and disable offloads for the ports which are not offloaded. */ - if ((l4_proto == IPPROTO_UDP) && - ((skb_inner_mac_header(skb) - - skb_transport_header(skb)) > QEDE_MAX_TUN_HDR_LEN)) - return features & ~((NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | \ - NETIF_F_HW_CSUM) | NETIF_F_GSO_MASK); + if (l4_proto == IPPROTO_UDP) { + struct qede_dev *edev = netdev_priv(dev); + u16 hdrlen, vxln_port, gnv_port; + + hdrlen = QEDE_MAX_TUN_HDR_LEN; + vxln_port = edev->vxlan_dst_port; + gnv_port = edev->geneve_dst_port; + + if ((skb_inner_mac_header(skb) - + skb_transport_header(skb)) > hdrlen || + (ntohs(udp_hdr(skb)->dest) != vxln_port && + ntohs(udp_hdr(skb)->dest) != gnv_port)) + return features & ~(NETIF_F_CSUM_MASK | + NETIF_F_GSO_MASK); + } } return features; -- 2.50.1