[PATCH] udp:nat:vxlan tx after nat should recsum if vxlan tx offload on

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: "chenwei.0515" <chenwei.0515@xxxxxxxxxxxxx>

    If vxlan-dev enable tx csum offload, there are two case of CHECKSUM_PARTIAL,
    but udp->check donot have the both meanings.

    1. vxlan-dev disable tx csum offload, udp->check is just pseudo hdr.
    2. vxlan-dev enable tx csum offload, udp->check is pseudo hdr and
       csum from outter l4 to innner l4.

    Unfortunately if there is a nat process after vxlan tx,udp_manip_pkt just use
    CSUM_PARTIAL to re csum PKT, which is just right on vxlan tx csum disable offload.

    This patch use skb->csum_local flag to identify two case, which will csum lco_csum if valid.

Signed-off-by: chenwei.0515 <chenwei.0515@xxxxxxxxxxxxx>
---
 include/linux/skbuff.h       | 1 +
 net/ipv4/udp.c               | 1 +
 net/netfilter/nf_nat_proto.c | 9 +++++++++
 3 files changed, 11 insertions(+)

diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index ff7ad331fb82..62996d8d0b4d 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -990,6 +990,7 @@ struct sk_buff {
 	__u8			slow_gro:1;
 	__u8			csum_not_inet:1;
 	__u8			scm_io_uring:1;
+	__u8			csum_local:1;
 
 #ifdef CONFIG_NET_SCHED
 	__u16			tc_index;	/* traffic control index */
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index c605d171eb2d..86bad0bbb76e 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -889,6 +889,7 @@ void udp_set_csum(bool nocheck, struct sk_buff *skb,
 		uh->check = udp_v4_check(len, saddr, daddr, lco_csum(skb));
 		if (uh->check == 0)
 			uh->check = CSUM_MANGLED_0;
+		skb->csum_local = 1;
 	} else {
 		skb->ip_summed = CHECKSUM_PARTIAL;
 		skb->csum_start = skb_transport_header(skb) - skb->head;
diff --git a/net/netfilter/nf_nat_proto.c b/net/netfilter/nf_nat_proto.c
index 48cc60084d28..a0261fe2d932 100644
--- a/net/netfilter/nf_nat_proto.c
+++ b/net/netfilter/nf_nat_proto.c
@@ -25,6 +25,7 @@
 #include <net/ip6_route.h>
 #include <net/xfrm.h>
 #include <net/ipv6.h>
+#include <net/udp.h>
 
 #include <net/netfilter/nf_conntrack_core.h>
 #include <net/netfilter/nf_conntrack.h>
@@ -75,6 +76,14 @@ static bool udp_manip_pkt(struct sk_buff *skb,
 	hdr = (struct udphdr *)(skb->data + hdroff);
 	__udp_manip_pkt(skb, iphdroff, hdr, tuple, maniptype, !!hdr->check);
 
+	if (skb->csum_local) {
+		hdr->check = 0;
+		hdr->check = udp_v4_check(htons(hdr->len), tuple->src.u3.ip, tuple->dst.u3.ip,
+					  lco_csum(skb));
+		if (hdr->check == 0)
+			hdr->check = CSUM_MANGLED_0;
+	}
+
 	return true;
 }
 
-- 
2.11.0




[Index of Archives]     [Netfitler Users]     [Berkeley Packet Filter]     [LARTC]     [Bugtraq]     [Yosemite Forum]

  Powered by Linux