aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYunsheng Lin <linyunsheng@huawei.com>2018-06-01 17:52:09 +0100
committerDavid S. Miller <davem@davemloft.net>2018-06-01 14:23:57 -0400
commit3db084d28dc04e6ebe9123e0d4f6e8ef5a775ff0 (patch)
treeca9fc2901455cc1e807ed6d8e3ce72da9fc613dc
parentf0ad97ac12f0e91cf3846025256ca97845bcfccd (diff)
downloadnfc-next-3db084d28dc04e6ebe9123e0d4f6e8ef5a775ff0.tar.gz
net: hns3: Fix for vxlan tx checksum bug
when skb->encapsulation is 0, skb->ip_summed is CHECKSUM_PARTIAL and it is udp packet, which has a dest port as the IANA assigned. the hardware is expected to do the checksum offload, but the hardware will not do the checksum offload when udp dest port is 4789. This patch fixes it by doing the checksum in software. Fixes: 76ad4f0ee747 ("net: hns3: Add support of HNS3 Ethernet Driver for hip08 SoC") Signed-off-by: Yunsheng Lin <linyunsheng@huawei.com> Signed-off-by: Peng Li <lipeng321@huawei.com> Signed-off-by: Salil Mehta <salil.mehta@huawei.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/hisilicon/hns3/hns3_enet.c29
1 files changed, 29 insertions, 0 deletions
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
index 235eea1393bbe..e572804169cdf 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
@@ -655,6 +655,32 @@ static void hns3_set_l2l3l4_len(struct sk_buff *skb, u8 ol4_proto,
}
}
+/* when skb->encapsulation is 0, skb->ip_summed is CHECKSUM_PARTIAL
+ * and it is udp packet, which has a dest port as the IANA assigned.
+ * the hardware is expected to do the checksum offload, but the
+ * hardware will not do the checksum offload when udp dest port is
+ * 4789.
+ */
+static bool hns3_tunnel_csum_bug(struct sk_buff *skb)
+{
+#define IANA_VXLAN_PORT 4789
+ union {
+ struct tcphdr *tcp;
+ struct udphdr *udp;
+ struct gre_base_hdr *gre;
+ unsigned char *hdr;
+ } l4;
+
+ l4.hdr = skb_transport_header(skb);
+
+ if (!(!skb->encapsulation && l4.udp->dest == htons(IANA_VXLAN_PORT)))
+ return false;
+
+ skb_checksum_help(skb);
+
+ return true;
+}
+
static int hns3_set_l3l4_type_csum(struct sk_buff *skb, u8 ol4_proto,
u8 il4_proto, u32 *type_cs_vlan_tso,
u32 *ol_type_vlan_len_msec)
@@ -743,6 +769,9 @@ static int hns3_set_l3l4_type_csum(struct sk_buff *skb, u8 ol4_proto,
HNS3_L4T_TCP);
break;
case IPPROTO_UDP:
+ if (hns3_tunnel_csum_bug(skb))
+ break;
+
hnae_set_field(*type_cs_vlan_tso,
HNS3_TXD_L4T_M,
HNS3_TXD_L4T_S,