vxlan: fix test which detect duplicate vxlan iface
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 commit1c51a9159d
, 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:1c51a9159d
("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>
This commit is contained in:
parent
29c6dd591b
commit
07b9b37c22
|
@ -2751,7 +2751,7 @@ static int vxlan_dev_configure(struct net *src_net, struct net_device *dev,
|
||||||
struct vxlan_config *conf)
|
struct vxlan_config *conf)
|
||||||
{
|
{
|
||||||
struct vxlan_net *vn = net_generic(src_net, vxlan_net_id);
|
struct vxlan_net *vn = net_generic(src_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;
|
struct vxlan_rdst *dst = &vxlan->default_dst;
|
||||||
unsigned short needed_headroom = ETH_HLEN;
|
unsigned short needed_headroom = ETH_HLEN;
|
||||||
int err;
|
int err;
|
||||||
|
@ -2817,9 +2817,15 @@ static int vxlan_dev_configure(struct net *src_net, struct net_device *dev,
|
||||||
if (!vxlan->cfg.age_interval)
|
if (!vxlan->cfg.age_interval)
|
||||||
vxlan->cfg.age_interval = FDB_AGE_DEFAULT;
|
vxlan->cfg.age_interval = FDB_AGE_DEFAULT;
|
||||||
|
|
||||||
if (vxlan_find_vni(src_net, conf->vni, use_ipv6 ? AF_INET6 : AF_INET,
|
list_for_each_entry(tmp, &vn->vxlan_list, next) {
|
||||||
vxlan->cfg.dst_port, vxlan->flags))
|
if (tmp->cfg.vni == conf->vni &&
|
||||||
|
(tmp->default_dst.remote_ip.sa.sa_family == AF_INET6 ||
|
||||||
|
tmp->cfg.saddr.sa.sa_family == AF_INET6) == use_ipv6 &&
|
||||||
|
tmp->cfg.dst_port == vxlan->cfg.dst_port &&
|
||||||
|
(tmp->flags & VXLAN_F_RCV_FLAGS) ==
|
||||||
|
(vxlan->flags & VXLAN_F_RCV_FLAGS))
|
||||||
return -EEXIST;
|
return -EEXIST;
|
||||||
|
}
|
||||||
|
|
||||||
dev->ethtool_ops = &vxlan_ethtool_ops;
|
dev->ethtool_ops = &vxlan_ethtool_ops;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue