+++ /dev/null
-From foo@baz Tue Jan 26 22:23:35 PST 2016
-From: Nicolas Dichtel <nicolas.dichtel@6wind.com>
-Date: Thu, 7 Jan 2016 11:26:53 +0100
-Subject: vxlan: fix test which detect duplicate vxlan iface
-Content-Length: 2895
-Lines: 75
-
-From: Nicolas Dichtel <nicolas.dichtel@6wind.com>
-
-[ Upstream commit 07b9b37c227cb8d88d478b4a9c5634fee514ede1 ]
-
-When a vxlan interface is created, the driver checks that there is not
-another vxlan interface with the same properties. To do this, it checks
-the existing vxlan udp socket. Since commit 1c51a9159dde, the creation of
-the vxlan socket is done only when the interface is set up, thus it breaks
-that test.
-
-Example:
-$ ip l a vxlan10 type vxlan id 10 group 239.0.0.10 dev eth0 dstport 0
-$ ip l a vxlan11 type vxlan id 10 group 239.0.0.10 dev eth0 dstport 0
-$ ip -br l | grep vxlan
-vxlan10 DOWN f2:55:1c:6a:fb:00 <BROADCAST,MULTICAST>
-vxlan11 DOWN 7a:cb:b9:38:59:0d <BROADCAST,MULTICAST>
-
-Instead of checking sockets, let's loop over the vxlan iface list.
-
-Fixes: 1c51a9159dde ("vxlan: fix race caused by dropping rtnl_unlock")
-Reported-by: Thomas Faivre <thomas.faivre@6wind.com>
-Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/net/vxlan.c | 12 ++++++++----
- include/net/vxlan.h | 5 +++++
- 2 files changed, 13 insertions(+), 4 deletions(-)
-
---- a/drivers/net/vxlan.c
-+++ b/drivers/net/vxlan.c
-@@ -2607,7 +2607,7 @@ static int vxlan_newlink(struct net *net
- struct nlattr *tb[], struct nlattr *data[])
- {
- struct vxlan_net *vn = net_generic(net, vxlan_net_id);
-- struct vxlan_dev *vxlan = netdev_priv(dev);
-+ struct vxlan_dev *vxlan = netdev_priv(dev), *tmp;
- struct vxlan_rdst *dst = &vxlan->default_dst;
- __u32 vni;
- int err;
-@@ -2715,9 +2715,13 @@ static int vxlan_newlink(struct net *net
- if (data[IFLA_VXLAN_PORT])
- vxlan->dst_port = nla_get_be16(data[IFLA_VXLAN_PORT]);
-
-- if (vxlan_find_vni(net, vni, use_ipv6 ? AF_INET6 : AF_INET,
-- vxlan->dst_port)) {
-- pr_info("duplicate VNI %u\n", vni);
-+ list_for_each_entry(tmp, &vn->vxlan_list, next) {
-+ if (tmp->default_dst.remote_vni == vni &&
-+ (tmp->default_dst.remote_ip.sa.sa_family == AF_INET6 ||
-+ tmp->saddr.sa.sa_family == AF_INET6) == use_ipv6 &&
-+ tmp->dst_port == vxlan->dst_port &&
-+ (tmp->flags & VXLAN_F_RCV_FLAGS) ==
-+ (vxlan->flags & VXLAN_F_RCV_FLAGS))
- return -EEXIST;
- }
-
---- a/include/net/vxlan.h
-+++ b/include/net/vxlan.h
-@@ -24,6 +24,11 @@ struct vxlan_sock {
- struct udp_offload udp_offloads;
- };
-
-+/* Flags that are used in the receive path. These flags must match in
-+ * order for a socket to be shareable
-+ */
-+#define VXLAN_F_RCV_FLAGS VXLAN_F_UDP_ZERO_CSUM6_RX
-+
- struct vxlan_sock *vxlan_sock_add(struct net *net, __be16 port,
- vxlan_rcv_t *rcv, void *data,
- bool no_share, bool ipv6);