]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
vxlan: do not receive IPv4 packets on IPv6 socket
authorJiri Benc <jbenc@redhat.com>
Fri, 28 Aug 2015 18:48:22 +0000 (20:48 +0200)
committerChuck Anderson <chuck.anderson@oracle.com>
Mon, 12 Dec 2016 04:24:47 +0000 (20:24 -0800)
By default (subject to the sysctl settings), IPv6 sockets listen also for
IPv4 traffic. Vxlan is not prepared for that and expects IPv6 header in
packets received through an IPv6 socket.

In addition, it's currently not possible to have both IPv4 and IPv6 vxlan
tunnel on the same port (unless bindv6only sysctl is enabled), as it's not
possible to create and bind both IPv4 and IPv6 vxlan interfaces and there's
no way to specify both IPv4 and IPv6 remote/group IP addresses.

Set IPV6_V6ONLY on vxlan sockets to fix both of these issues. This is not
done globally in udp_tunnel, as l2tp and tipc seems to work okay when
receiving IPv4 packets on IPv6 socket and people may rely on this behavior.
The other tunnels (geneve and fou) do not support IPv6.

Signed-off-by: Jiri Benc <jbenc@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
(cherry picked from commit a43a9ef6a2e510fec61176ff2c34fab3e7d581da)

Orabug: 24579830
Signed-off-by: Jack Vogel <jack.vogel@oracle.com>
drivers/net/vxlan.c
include/net/udp_tunnel.h
net/ipv6/ip6_udp_tunnel.c

index 0085b8df83e20f28078c30a0bc8fc0fc80fb1984..17ed3d0850539e651ffba0c18bb8d9bf0d25522d 100644 (file)
@@ -2482,6 +2482,7 @@ static struct socket *vxlan_create_sock(struct net *net, bool ipv6,
                udp_conf.family = AF_INET6;
                udp_conf.use_udp6_rx_checksums =
                    !(flags & VXLAN_F_UDP_ZERO_CSUM6_RX);
+               udp_conf.ipv6_v6only = 1;
        } else {
                udp_conf.family = AF_INET;
        }
index c491c1221606e0f2625de8b53cfd8fdcd29282c9..93fe751c8064f62b9a38aff0fd4d7cf343f48b8a 100644 (file)
@@ -31,7 +31,8 @@ struct udp_port_cfg {
        __be16                  peer_udp_port;
        unsigned int            use_udp_checksums:1,
                                use_udp6_tx_checksums:1,
-                               use_udp6_rx_checksums:1;
+                               use_udp6_rx_checksums:1,
+                               ipv6_v6only:1;
 };
 
 int udp_sock_create4(struct net *net, struct udp_port_cfg *cfg,
index e1a1136bda7c8f15e589c92e7ea752ddceee70f4..14dacf1df529d9602cc497976db0868f68d9fbb7 100644 (file)
@@ -23,6 +23,15 @@ int udp_sock_create6(struct net *net, struct udp_port_cfg *cfg,
        if (err < 0)
                goto error;
 
+       if (cfg->ipv6_v6only) {
+               int val = 1;
+
+               err = kernel_setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY,
+                                       (char *) &val, sizeof(val));
+               if (err < 0)
+                       goto error;
+       }
+
        udp6_addr.sin6_family = AF_INET6;
        memcpy(&udp6_addr.sin6_addr, &cfg->local_ip6,
               sizeof(udp6_addr.sin6_addr));