diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c index 5441b49ef89d..5988910db23e 100644 --- a/drivers/net/vxlan.c +++ b/drivers/net/vxlan.c @@ -2106,9 +2106,8 @@ static int vxlan_init(struct net_device *dev) spin_lock(&vn->sock_lock); vs = vxlan_find_sock(dev_net(dev), ipv6 ? AF_INET6 : AF_INET, vxlan->dst_port); - if (vs) { + if (vs && atomic_add_unless(&vs->refcnt, 1, 0)) { /* If we have a socket with same port already, reuse it */ - atomic_inc(&vs->refcnt); vxlan_vs_add_dev(vs, vxlan); } else { /* otherwise make new socket outside of RTNL */ @@ -2574,12 +2573,9 @@ struct vxlan_sock *vxlan_sock_add(struct net *net, __be16 port, spin_lock(&vn->sock_lock); vs = vxlan_find_sock(net, ipv6 ? AF_INET6 : AF_INET, port); - if (vs) { - if (vs->rcv == rcv) - atomic_inc(&vs->refcnt); - else + if (vs && ((vs->rcv != rcv) || + !atomic_add_unless(&vs->refcnt, 1, 0))) vs = ERR_PTR(-EBUSY); - } spin_unlock(&vn->sock_lock); if (!vs)