|
@@ -1985,9 +1985,8 @@ static int vxlan_init(struct net_device *dev)
|
|
|
spin_lock(&vn->sock_lock);
|
|
|
vs = vxlan_find_sock(vxlan->net, 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 */
|
|
@@ -2389,12 +2388,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)
|