Commit 814f7d11 authored by David S. Miller's avatar David S. Miller

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: default avatarDavid S. Miller <davem@davemloft.net>
parents 138a7f49 3dc2b6a8
...@@ -2306,9 +2306,9 @@ static struct socket *vxlan_create_sock(struct net *net, bool ipv6, ...@@ -2306,9 +2306,9 @@ static struct socket *vxlan_create_sock(struct net *net, bool ipv6,
if (ipv6) { if (ipv6) {
udp_conf.family = AF_INET6; udp_conf.family = AF_INET6;
udp_conf.use_udp6_tx_checksums = 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 = udp_conf.use_udp6_rx_checksums =
!!(flags & VXLAN_F_UDP_ZERO_CSUM6_RX); !(flags & VXLAN_F_UDP_ZERO_CSUM6_RX);
} else { } else {
udp_conf.family = AF_INET; udp_conf.family = AF_INET;
udp_conf.local_ip.s_addr = INADDR_ANY; udp_conf.local_ip.s_addr = INADDR_ANY;
......
...@@ -79,15 +79,13 @@ int udp_tunnel6_xmit_skb(struct socket *sock, struct dst_entry *dst, ...@@ -79,15 +79,13 @@ int udp_tunnel6_xmit_skb(struct socket *sock, struct dst_entry *dst,
uh->source = src_port; uh->source = src_port;
uh->len = htons(skb->len); uh->len = htons(skb->len);
uh->check = 0;
memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt)); memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt));
IPCB(skb)->flags &= ~(IPSKB_XFRM_TUNNEL_SIZE | IPSKB_XFRM_TRANSFORMED IPCB(skb)->flags &= ~(IPSKB_XFRM_TUNNEL_SIZE | IPSKB_XFRM_TRANSFORMED
| IPSKB_REROUTED); | IPSKB_REROUTED);
skb_dst_set(skb, dst); skb_dst_set(skb, dst);
udp6_set_csum(udp_get_no_check6_tx(sk), skb, &inet6_sk(sk)->saddr, udp6_set_csum(udp_get_no_check6_tx(sk), skb, saddr, daddr, skb->len);
&sk->sk_v6_daddr, skb->len);
__skb_push(skb, sizeof(*ip6h)); __skb_push(skb, sizeof(*ip6h));
skb_reset_network_header(skb); skb_reset_network_header(skb);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment