struct geneve_sock *geneve_sock_add(struct net *net, __be16 port, geneve_rcv_t *rcv, void *data, bool no_share, bool ipv6) { struct geneve_sock *gs; gs = geneve_socket_create(net, port, rcv, data, ipv6); if (!IS_ERR(gs)) return gs; if (no_share) /* Return error if sharing is not allowed. */ return ERR_PTR(-EINVAL); gs = geneve_find_sock(net, port); if (gs) { if (gs->rcv == rcv) atomic_inc(&gs->refcnt); else gs = ERR_PTR(-EBUSY); } else { gs = ERR_PTR(-EINVAL); } return gs; }
struct geneve_sock *geneve_sock_add(struct net *net, __be16 port, geneve_rcv_t *rcv, void *data, bool no_share, bool ipv6) { struct geneve_net *gn = net_generic(net, geneve_net_id); struct geneve_sock *gs; gs = geneve_socket_create(net, port, rcv, data, ipv6); if (!IS_ERR(gs)) return gs; if (no_share) /* Return error if sharing is not allowed. */ return ERR_PTR(-EINVAL); spin_lock(&gn->sock_lock); gs = geneve_find_sock(net, port); if (gs && ((gs->rcv != rcv) || !atomic_add_unless(&gs->refcnt, 1, 0))) gs = ERR_PTR(-EBUSY); spin_unlock(&gn->sock_lock); if (!gs) gs = ERR_PTR(-EINVAL); return gs; }