浏览代码

Merge branch 'ipv6_vxlan_outer_udp_csum'

Alexander Duyck says:

====================
Fix outer UDP checksums for IPv6 VXLAN tunnels

In testing against an older kernel I found a couple issues in the IPv6
VXLAN tunnel checksum logic for the outer UDP checksum.

First the default transitioned from using an outer checksum to not using
one.  Second, sometime after that the checksum inputs were changed
resulting the checksum not being correct if it were computed.

These two issues prevented a ping from the newer kernel to the older one.
With these two changes applied I verified I was able to send traffic over
the VXLAN tunnel to a link partner on an older kernel.

The boolean flip fix can be submitted for 3.17 stable as well since the
patch that introduced the issue was included in that kernel.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
David S. Miller 10 年之前
父节点
当前提交
814f7d115e
共有 2 个文件被更改,包括 3 次插入5 次删除
  1. 2 2
      drivers/net/vxlan.c
  2. 1 3
      net/ipv6/ip6_udp_tunnel.c

+ 2 - 2
drivers/net/vxlan.c

@@ -2306,9 +2306,9 @@ static struct socket *vxlan_create_sock(struct net *net, bool ipv6,
 	if (ipv6) {
 		udp_conf.family = AF_INET6;
 		udp_conf.use_udp6_tx_checksums =
-		    !!(flags & VXLAN_F_UDP_ZERO_CSUM6_TX);
+		    !(flags & VXLAN_F_UDP_ZERO_CSUM6_TX);
 		udp_conf.use_udp6_rx_checksums =
-		    !!(flags & VXLAN_F_UDP_ZERO_CSUM6_RX);
+		    !(flags & VXLAN_F_UDP_ZERO_CSUM6_RX);
 	} else {
 		udp_conf.family = AF_INET;
 		udp_conf.local_ip.s_addr = INADDR_ANY;

+ 1 - 3
net/ipv6/ip6_udp_tunnel.c

@@ -79,15 +79,13 @@ int udp_tunnel6_xmit_skb(struct socket *sock, struct dst_entry *dst,
 	uh->source = src_port;
 
 	uh->len = htons(skb->len);
-	uh->check = 0;
 
 	memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt));
 	IPCB(skb)->flags &= ~(IPSKB_XFRM_TUNNEL_SIZE | IPSKB_XFRM_TRANSFORMED
 			    | IPSKB_REROUTED);
 	skb_dst_set(skb, dst);
 
-	udp6_set_csum(udp_get_no_check6_tx(sk), skb, &inet6_sk(sk)->saddr,
-		      &sk->sk_v6_daddr, skb->len);
+	udp6_set_csum(udp_get_no_check6_tx(sk), skb, saddr, daddr, skb->len);
 
 	__skb_push(skb, sizeof(*ip6h));
 	skb_reset_network_header(skb);