Merge branch 'udp_tunnel-speed-up-udp-tunnel-device-destruction-part-i'

Kuniyuki Iwashima says:

====================
udp_tunnel: Speed up UDP tunnel device destruction (Part I)

Most of the UDP tunnel devices call synchronize_rcu() twice
during destruction, for example, vxlan has

  1) synchronize_rcu() in udp_tunnel_sock_release()

  2) synchronize_net() in vxlan_sock_release()

The goal of this series is to remove the former, and another
followup series removes the latter.

synchronize_rcu() was added in udp_tunnel_sock_release() by
commit 3cf7203ca6 ("net/tunnel: wait until all sk_user_data
reader finish before releasing the sock").

This was intended to protect the fast path of a dying vxlan
from dereferencing vxlan_sock->sock->sk after sock_orphan()
has set sock->sk to NULL.

Most of the UDP tunnel devices store struct socket to its
private struct, but it is NOT needed in the fast paths;
struct sock is used there, but struct socket is only used
for tunnel setup / teardown.

This is probably because UDP tunnel functions accept struct
socket, but even such functions do not need it, except for
udp_tunnel_sock_release(), which can safely access sk->sk_socket.

The overview of the series:

  Patch 1 -  5 : Convert UDP tunnel helper to take struct sock
  Patch 6      : Small fix for 10-years-old bug
  Patch 7 - 14 : Store struct sock in tunnel devices
  Patch 15     : Remove synchronize_rcu() in udp_tunnel_sock_release()

With this change, a script creating/upping vxlan in 4000 netns
runs 10x faster.
====================

[See Link for benchmark results.]

Link: https://patch.msgid.link/20260502031401.3557229-1-kuniyu@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Jakub Kicinski 2026-05-05 17:47:09 -07:00
commit ed36fad2cd
21 changed files with 210 additions and 209 deletions

View File

@ -283,12 +283,12 @@ static struct socket *rxe_setup_udp_tunnel(struct net *net, __be16 port,
tnl_cfg.encap_rcv = rxe_udp_encap_recv;
/* Setup UDP tunnel */
setup_udp_tunnel_sock(net, sock, &tnl_cfg);
setup_udp_tunnel_sock(net, sock->sk, &tnl_cfg);
return sock;
}
static void rxe_release_udp_tunnel(struct socket *sk)
static void rxe_release_udp_tunnel(struct sock *sk)
{
if (sk)
udp_tunnel_sock_release(sk);
@ -636,7 +636,7 @@ static void rxe_sock_put(struct sock *sk,
if (refcount_read(&sk->sk_refcnt) > SK_REF_FOR_TUNNEL) {
__sock_put(sk);
} else {
rxe_release_udp_tunnel(sk->sk_socket);
rxe_release_udp_tunnel(sk);
sk = NULL;
set_sk(net, sk);
}

View File

@ -47,7 +47,7 @@ static void rxe_ns_exit(struct net *net)
rcu_read_unlock();
if (sk) {
rcu_assign_pointer(ns_sk->rxe_sk4, NULL);
udp_tunnel_sock_release(sk->sk_socket);
udp_tunnel_sock_release(sk);
}
#if IS_ENABLED(CONFIG_IPV6)
@ -56,7 +56,7 @@ static void rxe_ns_exit(struct net *net)
rcu_read_unlock();
if (sk) {
rcu_assign_pointer(ns_sk->rxe_sk6, NULL);
udp_tunnel_sock_release(sk->sk_socket);
udp_tunnel_sock_release(sk);
}
#endif
}

View File

@ -614,24 +614,24 @@ static void amt_send_discovery(struct amt_dev *amt)
{
struct amt_header_discovery *amtd;
int hlen, tlen, offset;
struct socket *sock;
struct udphdr *udph;
struct sk_buff *skb;
struct iphdr *iph;
struct rtable *rt;
struct flowi4 fl4;
struct sock *sk;
u32 len;
int err;
rcu_read_lock();
sock = rcu_dereference(amt->sock);
if (!sock)
sk = rcu_dereference(amt->sk);
if (!sk)
goto out;
if (!netif_running(amt->stream_dev) || !netif_running(amt->dev))
goto out;
rt = ip_route_output_ports(amt->net, &fl4, sock->sk,
rt = ip_route_output_ports(amt->net, &fl4, sk,
amt->discovery_ip, amt->local_ip,
amt->gw_port, amt->relay_port,
IPPROTO_UDP, 0,
@ -690,7 +690,7 @@ static void amt_send_discovery(struct amt_dev *amt)
skb->ip_summed = CHECKSUM_NONE;
ip_select_ident(amt->net, skb, NULL);
ip_send_check(iph);
err = ip_local_out(amt->net, sock->sk, skb);
err = ip_local_out(amt->net, sk, skb);
if (unlikely(net_xmit_eval(err)))
amt->dev->stats.tx_errors++;
@ -703,24 +703,24 @@ static void amt_send_request(struct amt_dev *amt, bool v6)
{
struct amt_header_request *amtrh;
int hlen, tlen, offset;
struct socket *sock;
struct udphdr *udph;
struct sk_buff *skb;
struct iphdr *iph;
struct rtable *rt;
struct flowi4 fl4;
struct sock *sk;
u32 len;
int err;
rcu_read_lock();
sock = rcu_dereference(amt->sock);
if (!sock)
sk = rcu_dereference(amt->sk);
if (!sk)
goto out;
if (!netif_running(amt->stream_dev) || !netif_running(amt->dev))
goto out;
rt = ip_route_output_ports(amt->net, &fl4, sock->sk,
rt = ip_route_output_ports(amt->net, &fl4, sk,
amt->remote_ip, amt->local_ip,
amt->gw_port, amt->relay_port,
IPPROTO_UDP, 0,
@ -781,7 +781,7 @@ static void amt_send_request(struct amt_dev *amt, bool v6)
skb->ip_summed = CHECKSUM_NONE;
ip_select_ident(amt->net, skb, NULL);
ip_send_check(iph);
err = ip_local_out(amt->net, sock->sk, skb);
err = ip_local_out(amt->net, sk, skb);
if (unlikely(net_xmit_eval(err)))
amt->dev->stats.tx_errors++;
@ -1000,14 +1000,14 @@ static bool amt_send_membership_update(struct amt_dev *amt,
bool v6)
{
struct amt_header_membership_update *amtmu;
struct socket *sock;
struct iphdr *iph;
struct flowi4 fl4;
struct rtable *rt;
struct sock *sk;
int err;
sock = rcu_dereference_bh(amt->sock);
if (!sock)
sk = rcu_dereference_bh(amt->sk);
if (!sk)
return true;
err = skb_cow_head(skb, LL_RESERVED_SPACE(amt->dev) + sizeof(*amtmu) +
@ -1039,7 +1039,7 @@ static bool amt_send_membership_update(struct amt_dev *amt,
skb_set_inner_protocol(skb, htons(ETH_P_IP));
else
skb_set_inner_protocol(skb, htons(ETH_P_IPV6));
udp_tunnel_xmit_skb(rt, sock->sk, skb,
udp_tunnel_xmit_skb(rt, sk, skb,
fl4.saddr,
fl4.daddr,
AMT_TOS,
@ -1060,14 +1060,14 @@ static void amt_send_multicast_data(struct amt_dev *amt,
bool v6)
{
struct amt_header_mcast_data *amtmd;
struct socket *sock;
struct sk_buff *skb;
struct iphdr *iph;
struct flowi4 fl4;
struct rtable *rt;
struct sock *sk;
sock = rcu_dereference_bh(amt->sock);
if (!sock)
sk = rcu_dereference_bh(amt->sk);
if (!sk)
return;
skb = skb_copy_expand(oskb, sizeof(*amtmd) + sizeof(*iph) +
@ -1097,7 +1097,7 @@ static void amt_send_multicast_data(struct amt_dev *amt,
skb_set_inner_protocol(skb, htons(ETH_P_IP));
else
skb_set_inner_protocol(skb, htons(ETH_P_IPV6));
udp_tunnel_xmit_skb(rt, sock->sk, skb,
udp_tunnel_xmit_skb(rt, sk, skb,
fl4.saddr,
fl4.daddr,
AMT_TOS,
@ -1116,13 +1116,13 @@ static bool amt_send_membership_query(struct amt_dev *amt,
bool v6)
{
struct amt_header_membership_query *amtmq;
struct socket *sock;
struct rtable *rt;
struct flowi4 fl4;
struct sock *sk;
int err;
sock = rcu_dereference_bh(amt->sock);
if (!sock)
sk = rcu_dereference_bh(amt->sk);
if (!sk)
return true;
err = skb_cow_head(skb, LL_RESERVED_SPACE(amt->dev) + sizeof(*amtmq) +
@ -1156,7 +1156,7 @@ static bool amt_send_membership_query(struct amt_dev *amt,
skb_set_inner_protocol(skb, htons(ETH_P_IP));
else
skb_set_inner_protocol(skb, htons(ETH_P_IPV6));
udp_tunnel_xmit_skb(rt, sock->sk, skb,
udp_tunnel_xmit_skb(rt, sk, skb,
fl4.saddr,
fl4.daddr,
AMT_TOS,
@ -2554,24 +2554,24 @@ static void amt_send_advertisement(struct amt_dev *amt, __be32 nonce,
{
struct amt_header_advertisement *amta;
int hlen, tlen, offset;
struct socket *sock;
struct udphdr *udph;
struct sk_buff *skb;
struct iphdr *iph;
struct rtable *rt;
struct flowi4 fl4;
struct sock *sk;
u32 len;
int err;
rcu_read_lock();
sock = rcu_dereference(amt->sock);
if (!sock)
sk = rcu_dereference(amt->sk);
if (!sk)
goto out;
if (!netif_running(amt->stream_dev) || !netif_running(amt->dev))
goto out;
rt = ip_route_output_ports(amt->net, &fl4, sock->sk,
rt = ip_route_output_ports(amt->net, &fl4, sk,
daddr, amt->local_ip,
dport, amt->relay_port,
IPPROTO_UDP, 0,
@ -2631,7 +2631,7 @@ static void amt_send_advertisement(struct amt_dev *amt, __be32 nonce,
skb->ip_summed = CHECKSUM_NONE;
ip_select_ident(amt->net, skb, NULL);
ip_send_check(iph);
err = ip_local_out(amt->net, sock->sk, skb);
err = ip_local_out(amt->net, sk, skb);
if (unlikely(net_xmit_eval(err)))
amt->dev->stats.tx_errors++;
@ -2944,7 +2944,7 @@ static int amt_err_lookup(struct sock *sk, struct sk_buff *skb)
return 0;
}
static struct socket *amt_create_sock(struct net *net, __be16 port)
static struct sock *amt_create_sock(struct net *net, __be16 port)
{
struct udp_port_cfg udp_conf;
struct socket *sock;
@ -2960,17 +2960,17 @@ static struct socket *amt_create_sock(struct net *net, __be16 port)
if (err < 0)
return ERR_PTR(err);
return sock;
return sock->sk;
}
static int amt_socket_create(struct amt_dev *amt)
{
struct udp_tunnel_sock_cfg tunnel_cfg;
struct socket *sock;
struct sock *sk;
sock = amt_create_sock(amt->net, amt->relay_port);
if (IS_ERR(sock))
return PTR_ERR(sock);
sk = amt_create_sock(amt->net, amt->relay_port);
if (IS_ERR(sk))
return PTR_ERR(sk);
/* Mark socket as an encapsulation socket */
memset(&tunnel_cfg, 0, sizeof(tunnel_cfg));
@ -2979,9 +2979,9 @@ static int amt_socket_create(struct amt_dev *amt)
tunnel_cfg.encap_rcv = amt_rcv;
tunnel_cfg.encap_err_lookup = amt_err_lookup;
tunnel_cfg.encap_destroy = NULL;
setup_udp_tunnel_sock(amt->net, sock, &tunnel_cfg);
setup_udp_tunnel_sock(amt->net, sk, &tunnel_cfg);
rcu_assign_pointer(amt->sock, sock);
rcu_assign_pointer(amt->sk, sk);
return 0;
}
@ -3019,8 +3019,8 @@ static int amt_dev_stop(struct net_device *dev)
{
struct amt_dev *amt = netdev_priv(dev);
struct amt_tunnel_list *tunnel, *tmp;
struct socket *sock;
struct sk_buff *skb;
struct sock *sk;
int i;
cancel_delayed_work_sync(&amt->req_wq);
@ -3028,11 +3028,11 @@ static int amt_dev_stop(struct net_device *dev)
cancel_delayed_work_sync(&amt->secret_wq);
/* shutdown */
sock = rtnl_dereference(amt->sock);
RCU_INIT_POINTER(amt->sock, NULL);
sk = rtnl_dereference(amt->sk);
RCU_INIT_POINTER(amt->sk, NULL);
synchronize_net();
if (sock)
udp_tunnel_sock_release(sock);
if (sk)
udp_tunnel_sock_release(sk);
cancel_work_sync(&amt->event_wq);
for (i = 0; i < AMT_MAX_EVENTS; i++) {

View File

@ -53,7 +53,7 @@ struct bareudp_dev {
__be16 port;
u16 sport_min;
bool multi_proto_mode;
struct socket __rcu *sock;
struct sock __rcu *sk;
struct list_head next; /* bareudp node on namespace list */
struct gro_cells gro_cells;
};
@ -228,7 +228,7 @@ static void bareudp_uninit(struct net_device *dev)
gro_cells_destroy(&bareudp->gro_cells);
}
static struct socket *bareudp_create_sock(struct net *net, __be16 port)
static struct sock *bareudp_create_sock(struct net *net, __be16 port)
{
struct udp_port_cfg udp_conf;
struct socket *sock;
@ -248,18 +248,18 @@ static struct socket *bareudp_create_sock(struct net *net, __be16 port)
return ERR_PTR(err);
udp_allow_gso(sock->sk);
return sock;
return sock->sk;
}
/* Create new listen socket if needed */
static int bareudp_socket_create(struct bareudp_dev *bareudp, __be16 port)
{
struct udp_tunnel_sock_cfg tunnel_cfg;
struct socket *sock;
struct sock *sk;
sock = bareudp_create_sock(bareudp->net, port);
if (IS_ERR(sock))
return PTR_ERR(sock);
sk = bareudp_create_sock(bareudp->net, port);
if (IS_ERR(sk))
return PTR_ERR(sk);
/* Mark socket as an encapsulation socket */
memset(&tunnel_cfg, 0, sizeof(tunnel_cfg));
@ -268,29 +268,27 @@ static int bareudp_socket_create(struct bareudp_dev *bareudp, __be16 port)
tunnel_cfg.encap_rcv = bareudp_udp_encap_recv;
tunnel_cfg.encap_err_lookup = bareudp_err_lookup;
tunnel_cfg.encap_destroy = NULL;
setup_udp_tunnel_sock(bareudp->net, sock, &tunnel_cfg);
setup_udp_tunnel_sock(bareudp->net, sk, &tunnel_cfg);
rcu_assign_pointer(bareudp->sock, sock);
rcu_assign_pointer(bareudp->sk, sk);
return 0;
}
static int bareudp_open(struct net_device *dev)
{
struct bareudp_dev *bareudp = netdev_priv(dev);
int ret = 0;
ret = bareudp_socket_create(bareudp, bareudp->port);
return ret;
return bareudp_socket_create(bareudp, bareudp->port);
}
static void bareudp_sock_release(struct bareudp_dev *bareudp)
{
struct socket *sock;
struct sock *sk;
sock = bareudp->sock;
rcu_assign_pointer(bareudp->sock, NULL);
sk = bareudp->sk;
rcu_assign_pointer(bareudp->sk, NULL);
synchronize_net();
udp_tunnel_sock_release(sock);
udp_tunnel_sock_release(sk);
}
static int bareudp_stop(struct net_device *dev)
@ -308,7 +306,7 @@ static int bareudp_xmit_skb(struct sk_buff *skb, struct net_device *dev,
bool udp_sum = test_bit(IP_TUNNEL_CSUM_BIT, info->key.tun_flags);
bool xnet = !net_eq(bareudp->net, dev_net(bareudp->dev));
bool use_cache = ip_tunnel_dst_cache_usable(skb, info);
struct socket *sock = rcu_dereference(bareudp->sock);
struct sock *sk = rcu_dereference(bareudp->sk);
const struct ip_tunnel_key *key = &info->key;
struct rtable *rt;
__be16 sport, df;
@ -320,7 +318,7 @@ static int bareudp_xmit_skb(struct sk_buff *skb, struct net_device *dev,
if (skb_vlan_inet_prepare(skb, skb->protocol != htons(ETH_P_TEB)))
return -EINVAL;
if (!sock)
if (!sk)
return -ESHUTDOWN;
sport = udp_flow_src_port(bareudp->net, skb,
@ -359,7 +357,7 @@ static int bareudp_xmit_skb(struct sk_buff *skb, struct net_device *dev,
goto free_dst;
skb_set_inner_protocol(skb, bareudp->ethertype);
udp_tunnel_xmit_skb(rt, sock->sk, skb, saddr, info->key.u.ipv4.dst,
udp_tunnel_xmit_skb(rt, sk, skb, saddr, info->key.u.ipv4.dst,
tos, ttl, df, sport, bareudp->port,
!net_eq(bareudp->net, dev_net(bareudp->dev)),
!test_bit(IP_TUNNEL_CSUM_BIT, info->key.tun_flags),
@ -378,7 +376,7 @@ static int bareudp6_xmit_skb(struct sk_buff *skb, struct net_device *dev,
bool udp_sum = test_bit(IP_TUNNEL_CSUM_BIT, info->key.tun_flags);
bool xnet = !net_eq(bareudp->net, dev_net(bareudp->dev));
bool use_cache = ip_tunnel_dst_cache_usable(skb, info);
struct socket *sock = rcu_dereference(bareudp->sock);
struct sock *sk = rcu_dereference(bareudp->sk);
const struct ip_tunnel_key *key = &info->key;
struct dst_entry *dst = NULL;
struct in6_addr saddr, daddr;
@ -390,13 +388,13 @@ static int bareudp6_xmit_skb(struct sk_buff *skb, struct net_device *dev,
if (skb_vlan_inet_prepare(skb, skb->protocol != htons(ETH_P_TEB)))
return -EINVAL;
if (!sock)
if (!sk)
return -ESHUTDOWN;
sport = udp_flow_src_port(bareudp->net, skb,
bareudp->sport_min, USHRT_MAX,
true);
dst = udp_tunnel6_dst_lookup(skb, dev, bareudp->net, sock, 0, &saddr,
dst = udp_tunnel6_dst_lookup(skb, dev, bareudp->net, sk, 0, &saddr,
key, sport, bareudp->port, key->tos,
use_cache ?
(struct dst_cache *) &info->dst_cache : NULL);
@ -427,7 +425,7 @@ static int bareudp6_xmit_skb(struct sk_buff *skb, struct net_device *dev,
goto free_dst;
daddr = info->key.u.ipv6.dst;
udp_tunnel6_xmit_skb(dst, sock->sk, skb, dev,
udp_tunnel6_xmit_skb(dst, sk, skb, dev,
&saddr, &daddr, prio, ttl,
info->key.label, sport, bareudp->port,
!test_bit(IP_TUNNEL_CSUM_BIT,
@ -527,12 +525,13 @@ static int bareudp_fill_metadata_dst(struct net_device *dev,
} else if (ip_tunnel_info_af(info) == AF_INET6) {
struct dst_entry *dst;
struct in6_addr saddr;
struct socket *sock = rcu_dereference(bareudp->sock);
struct sock *sk;
if (!sock)
sk = rcu_dereference(bareudp->sk);
if (!sk)
return -ESHUTDOWN;
dst = udp_tunnel6_dst_lookup(skb, dev, bareudp->net, sock,
dst = udp_tunnel6_dst_lookup(skb, dev, bareudp->net, sk,
0, &saddr, &info->key,
sport, bareudp->port, info->key.tos,
use_cache ? &info->dst_cache : NULL);

View File

@ -106,7 +106,7 @@ struct geneve_sock {
bool collect_md;
bool gro_hint;
struct list_head list;
struct socket *sock;
struct sock *sk;
struct rcu_head rcu;
int refcnt;
struct hlist_head vni_list[VNI_HASH_SIZE];
@ -167,7 +167,7 @@ static bool eq_tun_id_and_vni(u8 *tun_id, u8 *vni)
static sa_family_t geneve_get_sk_family(struct geneve_sock *gs)
{
return gs->sock->sk->sk_family;
return gs->sk->sk_family;
}
static struct geneve_dev *geneve_lookup(struct geneve_sock *gs,
@ -760,11 +760,11 @@ static int geneve_udp_encap_err_lookup(struct sock *sk, struct sk_buff *skb)
return -EPFNOSUPPORT;
}
static struct socket *geneve_create_sock(struct net *net, bool ipv6,
__be16 port, bool ipv6_rx_csum)
static struct sock *geneve_create_sock(struct net *net, bool ipv6,
__be16 port, bool ipv6_rx_csum)
{
struct socket *sock;
struct udp_port_cfg udp_conf;
struct socket *sock;
int err;
memset(&udp_conf, 0, sizeof(udp_conf));
@ -786,7 +786,7 @@ static struct socket *geneve_create_sock(struct net *net, bool ipv6,
return ERR_PTR(err);
udp_allow_gso(sock->sk);
return sock;
return sock->sk;
}
static bool geneve_hdr_match(struct sk_buff *skb,
@ -974,28 +974,28 @@ static struct geneve_sock *geneve_socket_create(struct net *net, __be16 port,
bool ipv6, bool ipv6_rx_csum)
{
struct geneve_net *gn = net_generic(net, geneve_net_id);
struct geneve_sock *gs;
struct socket *sock;
struct udp_tunnel_sock_cfg tunnel_cfg;
struct geneve_sock *gs;
struct sock *sk;
int h;
gs = kzalloc_obj(*gs);
if (!gs)
return ERR_PTR(-ENOMEM);
sock = geneve_create_sock(net, ipv6, port, ipv6_rx_csum);
if (IS_ERR(sock)) {
sk = geneve_create_sock(net, ipv6, port, ipv6_rx_csum);
if (IS_ERR(sk)) {
kfree(gs);
return ERR_CAST(sock);
return ERR_CAST(sk);
}
gs->sock = sock;
gs->sk = sk;
gs->refcnt = 1;
for (h = 0; h < VNI_HASH_SIZE; ++h)
INIT_HLIST_HEAD(&gs->vni_list[h]);
/* Initialize the geneve udp offloads structure */
udp_tunnel_notify_add_rx_port(gs->sock, UDP_TUNNEL_TYPE_GENEVE);
udp_tunnel_notify_add_rx_port(sk, UDP_TUNNEL_TYPE_GENEVE);
/* Mark socket as an encapsulation socket */
memset(&tunnel_cfg, 0, sizeof(tunnel_cfg));
@ -1006,7 +1006,7 @@ static struct geneve_sock *geneve_socket_create(struct net *net, __be16 port,
tunnel_cfg.encap_rcv = geneve_udp_encap_recv;
tunnel_cfg.encap_err_lookup = geneve_udp_encap_err_lookup;
tunnel_cfg.encap_destroy = NULL;
setup_udp_tunnel_sock(net, sock, &tunnel_cfg);
setup_udp_tunnel_sock(net, sk, &tunnel_cfg);
list_add(&gs->list, &gn->sock_list);
return gs;
}
@ -1017,8 +1017,8 @@ static void __geneve_sock_release(struct geneve_sock *gs)
return;
list_del(&gs->list);
udp_tunnel_notify_del_rx_port(gs->sock, UDP_TUNNEL_TYPE_GENEVE);
udp_tunnel_sock_release(gs->sock);
udp_tunnel_notify_del_rx_port(gs->sk, UDP_TUNNEL_TYPE_GENEVE);
udp_tunnel_sock_release(gs->sk);
kfree_rcu(gs, rcu);
}
@ -1048,7 +1048,7 @@ static struct geneve_sock *geneve_find_sock(struct geneve_net *gn,
struct geneve_sock *gs;
list_for_each_entry(gs, &gn->sock_list, list) {
if (inet_sk(gs->sock->sk)->inet_sport == dst_port &&
if (inet_sk(gs->sk)->inet_sport == dst_port &&
geneve_get_sk_family(gs) == family &&
gs->gro_hint == gro_hint) {
return gs;
@ -1390,7 +1390,7 @@ static int geneve_xmit_skb(struct sk_buff *skb, struct net_device *dev,
if (unlikely(err))
return err;
udp_tunnel_xmit_skb(rt, gs4->sock->sk, skb, saddr, info->key.u.ipv4.dst,
udp_tunnel_xmit_skb(rt, gs4->sk, skb, saddr, info->key.u.ipv4.dst,
tos, ttl, df, sport, geneve->cfg.info.key.tp_dst,
!net_eq(geneve->net, dev_net(geneve->dev)),
!test_bit(IP_TUNNEL_CSUM_BIT, info->key.tun_flags),
@ -1424,7 +1424,7 @@ static int geneve6_xmit_skb(struct sk_buff *skb, struct net_device *dev,
geneve->cfg.port_min,
geneve->cfg.port_max, true);
dst = udp_tunnel6_dst_lookup(skb, dev, geneve->net, gs6->sock, 0,
dst = udp_tunnel6_dst_lookup(skb, dev, geneve->net, gs6->sk, 0,
&saddr, key, sport,
geneve->cfg.info.key.tp_dst, prio,
use_cache ?
@ -1480,7 +1480,7 @@ static int geneve6_xmit_skb(struct sk_buff *skb, struct net_device *dev,
if (unlikely(err))
return err;
udp_tunnel6_xmit_skb(dst, gs6->sock->sk, skb, dev,
udp_tunnel6_xmit_skb(dst, gs6->sk, skb, dev,
&saddr, &key->u.ipv6.dst, prio, ttl,
info->key.label, sport, geneve->cfg.info.key.tp_dst,
!test_bit(IP_TUNNEL_CSUM_BIT,
@ -1592,7 +1592,7 @@ static int geneve_fill_metadata_dst(struct net_device *dev, struct sk_buff *skb)
geneve->cfg.port_min,
geneve->cfg.port_max, true);
dst = udp_tunnel6_dst_lookup(skb, dev, geneve->net, gs6->sock, 0,
dst = udp_tunnel6_dst_lookup(skb, dev, geneve->net, gs6->sk, 0,
&saddr, &info->key, sport,
geneve->cfg.info.key.tp_dst, prio,
use_cache ? &info->dst_cache : NULL);
@ -1654,10 +1654,10 @@ static void geneve_offload_rx_ports(struct net_device *dev, bool push)
list_for_each_entry(gs, &gn->sock_list, list) {
if (push) {
udp_tunnel_push_rx_port(dev, gs->sock,
udp_tunnel_push_rx_port(dev, gs->sk,
UDP_TUNNEL_TYPE_GENEVE);
} else {
udp_tunnel_drop_rx_port(dev, gs->sock,
udp_tunnel_drop_rx_port(dev, gs->sk,
UDP_TUNNEL_TYPE_GENEVE);
}
}
@ -2183,12 +2183,12 @@ static void geneve_quiesce(struct geneve_dev *geneve, struct geneve_sock **gs4,
*gs4 = rtnl_dereference(geneve->sock4);
rcu_assign_pointer(geneve->sock4, NULL);
if (*gs4)
rcu_assign_sk_user_data((*gs4)->sock->sk, NULL);
rcu_assign_sk_user_data((*gs4)->sk, NULL);
#if IS_ENABLED(CONFIG_IPV6)
*gs6 = rtnl_dereference(geneve->sock6);
rcu_assign_pointer(geneve->sock6, NULL);
if (*gs6)
rcu_assign_sk_user_data((*gs6)->sock->sk, NULL);
rcu_assign_sk_user_data((*gs6)->sk, NULL);
#else
*gs6 = NULL;
#endif
@ -2201,11 +2201,11 @@ static void geneve_unquiesce(struct geneve_dev *geneve, struct geneve_sock *gs4,
{
rcu_assign_pointer(geneve->sock4, gs4);
if (gs4)
rcu_assign_sk_user_data(gs4->sock->sk, gs4);
rcu_assign_sk_user_data(gs4->sk, gs4);
#if IS_ENABLED(CONFIG_IPV6)
rcu_assign_pointer(geneve->sock6, gs6);
if (gs6)
rcu_assign_sk_user_data(gs6->sock->sk, gs6);
rcu_assign_sk_user_data(gs6->sk, gs6);
#endif
synchronize_net();
}

View File

@ -885,8 +885,8 @@ static void gtp_encap_disable_sock(struct sock *sk)
static void gtp_encap_disable(struct gtp_dev *gtp)
{
if (gtp->sk_created) {
udp_tunnel_sock_release(gtp->sk0->sk_socket);
udp_tunnel_sock_release(gtp->sk1u->sk_socket);
udp_tunnel_sock_release(gtp->sk0);
udp_tunnel_sock_release(gtp->sk1u);
gtp->sk_created = false;
gtp->sk0 = NULL;
gtp->sk1u = NULL;
@ -1434,7 +1434,7 @@ static struct sock *gtp_create_sock(int type, struct gtp_dev *gtp,
tuncfg.encap_rcv = gtp_encap_recv;
tuncfg.encap_destroy = NULL;
setup_udp_tunnel_sock(net, sock, &tuncfg);
setup_udp_tunnel_sock(net, sock->sk, &tuncfg);
return sock->sk;
}
@ -1451,7 +1451,7 @@ static int gtp_create_sockets(struct gtp_dev *gtp, const struct nlattr *nla,
sk1u = gtp_create_sock(UDP_ENCAP_GTP1U, gtp, nla, family);
if (IS_ERR(sk1u)) {
udp_tunnel_sock_release(sk0->sk_socket);
udp_tunnel_sock_release(sk0);
return PTR_ERR(sk1u);
}
@ -1689,7 +1689,7 @@ static struct sock *gtp_encap_enable_socket(int fd, int type,
tuncfg.encap_rcv = gtp_encap_recv;
tuncfg.encap_destroy = gtp_encap_destroy;
setup_udp_tunnel_sock(sock_net(sock->sk), sock, &tuncfg);
setup_udp_tunnel_sock(sock_net(sock->sk), sk, &tuncfg);
out_rel_sock:
release_sock(sock->sk);

View File

@ -399,7 +399,7 @@ int ovpn_udp_socket_attach(struct ovpn_socket *ovpn_sock, struct socket *sock,
if (!old_data) {
/* socket is currently unused - we can take it */
rcu_read_unlock();
setup_udp_tunnel_sock(sock_net(ovpn_sock->sk), sock, &cfg);
setup_udp_tunnel_sock(sock_net(ovpn_sock->sk), sock->sk, &cfg);
return 0;
}

View File

@ -18,7 +18,7 @@
struct pfcp_dev {
struct list_head list;
struct socket *sock;
struct sock *sk;
struct net_device *dev;
struct net *net;
@ -104,8 +104,8 @@ static int pfcp_encap_recv(struct sock *sk, struct sk_buff *skb)
static void pfcp_del_sock(struct pfcp_dev *pfcp)
{
udp_tunnel_sock_release(pfcp->sock);
pfcp->sock = NULL;
udp_tunnel_sock_release(pfcp->sk);
pfcp->sk = NULL;
}
static void pfcp_dev_uninit(struct net_device *dev)
@ -151,7 +151,7 @@ static void pfcp_link_setup(struct net_device *dev)
netif_keep_dst(dev);
}
static struct socket *pfcp_create_sock(struct pfcp_dev *pfcp)
static struct sock *pfcp_create_sock(struct pfcp_dev *pfcp)
{
struct udp_tunnel_sock_cfg tuncfg = {};
struct udp_port_cfg udp_conf = {
@ -172,16 +172,16 @@ static struct socket *pfcp_create_sock(struct pfcp_dev *pfcp)
tuncfg.encap_rcv = pfcp_encap_recv;
tuncfg.encap_type = 1;
setup_udp_tunnel_sock(net, sock, &tuncfg);
setup_udp_tunnel_sock(net, sock->sk, &tuncfg);
return sock;
return sock->sk;
}
static int pfcp_add_sock(struct pfcp_dev *pfcp)
{
pfcp->sock = pfcp_create_sock(pfcp);
pfcp->sk = pfcp_create_sock(pfcp);
return PTR_ERR_OR_ZERO(pfcp->sock);
return PTR_ERR_OR_ZERO(pfcp->sk);
}
static int pfcp_newlink(struct net_device *dev,
@ -216,6 +216,7 @@ static int pfcp_newlink(struct net_device *dev,
exit_del_pfcp_sock:
pfcp_del_sock(pfcp);
synchronize_rcu();
exit_err:
pfcp->net = NULL;
return err;

View File

@ -88,10 +88,10 @@ static struct vxlan_sock *vxlan_find_sock(struct net *net, sa_family_t family,
flags &= VXLAN_F_RCV_FLAGS;
hlist_for_each_entry_rcu(vs, vs_head(net, port), hlist) {
if (inet_sk(vs->sock->sk)->inet_sport == port &&
if (inet_sk(vs->sk)->inet_sport == port &&
vxlan_get_sk_family(vs) == family &&
vs->flags == flags &&
vs->sock->sk->sk_bound_dev_if == ifindex)
vs->sk->sk_bound_dev_if == ifindex)
return vs;
}
return NULL;
@ -657,14 +657,18 @@ static struct vxlanhdr *vxlan_gro_prepare_receive(struct sock *sk,
struct sk_buff *skb,
struct gro_remcsum *grc)
{
struct sk_buff *p;
struct vxlanhdr *vh, *vh2;
unsigned int hlen, off_vx;
struct vxlan_sock *vs = rcu_dereference_sk_user_data(sk);
struct vxlan_sock *vs;
struct sk_buff *p;
__be32 flags;
skb_gro_remcsum_init(grc);
vs = rcu_dereference_sk_user_data(sk);
if (!vs)
return NULL;
off_vx = skb_gro_offset(skb);
hlen = off_vx + sizeof(*vh);
vh = skb_gro_header(skb, hlen, off_vx);
@ -1493,7 +1497,7 @@ static bool __vxlan_sock_release_prep(struct vxlan_sock *vs)
return false;
hlist_del_rcu(&vs->hlist);
udp_tunnel_notify_del_rx_port(vs->sock,
udp_tunnel_notify_del_rx_port(vs->sk,
(vs->flags & VXLAN_F_GPE) ?
UDP_TUNNEL_TYPE_VXLAN_GPE :
UDP_TUNNEL_TYPE_VXLAN);
@ -1519,14 +1523,14 @@ static void vxlan_sock_release(struct vxlan_dev *vxlan)
vxlan_vs_del_dev(vxlan);
if (__vxlan_sock_release_prep(sock4)) {
udp_tunnel_sock_release(sock4->sock);
kfree(sock4);
udp_tunnel_sock_release(sock4->sk);
kfree_rcu(sock4, rcu);
}
#if IS_ENABLED(CONFIG_IPV6)
if (__vxlan_sock_release_prep(sock6)) {
udp_tunnel_sock_release(sock6->sock);
kfree(sock6);
udp_tunnel_sock_release(sock6->sk);
kfree_rcu(sock6, rcu);
}
#endif
}
@ -2473,7 +2477,7 @@ void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
}
if (!ifindex)
ifindex = sock4->sock->sk->sk_bound_dev_if;
ifindex = sock4->sk->sk_bound_dev_if;
rt = udp_tunnel_dst_lookup(skb, dev, vxlan->net, ifindex,
&saddr, pkey, src_port, dst_port,
@ -2540,7 +2544,7 @@ void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
goto tx_error;
}
udp_tunnel_xmit_skb(rt, sock4->sock->sk, skb, saddr,
udp_tunnel_xmit_skb(rt, sock4->sk, skb, saddr,
pkey->u.ipv4.dst, tos, ttl, df,
src_port, dst_port, xnet, !udp_sum,
ipcb_flags);
@ -2557,9 +2561,9 @@ void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
}
if (!ifindex)
ifindex = sock6->sock->sk->sk_bound_dev_if;
ifindex = sock6->sk->sk_bound_dev_if;
ndst = udp_tunnel6_dst_lookup(skb, dev, vxlan->net, sock6->sock,
ndst = udp_tunnel6_dst_lookup(skb, dev, vxlan->net, sock6->sk,
ifindex, &saddr, pkey,
src_port, dst_port, tos,
use_cache ? dst_cache : NULL);
@ -2615,7 +2619,7 @@ void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
goto tx_error;
}
udp_tunnel6_xmit_skb(ndst, sock6->sock->sk, skb, dev,
udp_tunnel6_xmit_skb(ndst, sock6->sk, skb, dev,
&saddr, &pkey->u.ipv6.dst, tos, ttl,
pkey->label, src_port, dst_port, !udp_sum,
ip6cb_flags);
@ -3254,7 +3258,7 @@ static int vxlan_fill_metadata_dst(struct net_device *dev, struct sk_buff *skb)
if (!sock6)
return -EIO;
ndst = udp_tunnel6_dst_lookup(skb, dev, vxlan->net, sock6->sock,
ndst = udp_tunnel6_dst_lookup(skb, dev, vxlan->net, sock6->sk,
0, &info->key.u.ipv6.src,
&info->key,
sport, dport, info->key.tos,
@ -3332,9 +3336,9 @@ static void vxlan_offload_rx_ports(struct net_device *dev, bool push)
type = UDP_TUNNEL_TYPE_VXLAN;
if (push)
udp_tunnel_push_rx_port(dev, vs->sock, type);
udp_tunnel_push_rx_port(dev, vs->sk, type);
else
udp_tunnel_drop_rx_port(dev, vs->sock, type);
udp_tunnel_drop_rx_port(dev, vs->sk, type);
}
}
}
@ -3540,8 +3544,8 @@ static const struct ethtool_ops vxlan_ethtool_ops = {
.get_link_ksettings = vxlan_get_link_ksettings,
};
static struct socket *vxlan_create_sock(struct net *net, bool ipv6,
__be16 port, u32 flags, int ifindex)
static struct sock *vxlan_create_sock(struct net *net, bool ipv6,
__be16 port, u32 flags, int ifindex)
{
struct socket *sock;
struct udp_port_cfg udp_conf;
@ -3567,7 +3571,7 @@ static struct socket *vxlan_create_sock(struct net *net, bool ipv6,
return ERR_PTR(err);
udp_allow_gso(sock->sk);
return sock;
return sock->sk;
}
/* Create new listen socket if needed */
@ -3575,10 +3579,10 @@ static struct vxlan_sock *vxlan_socket_create(struct net *net, bool ipv6,
__be16 port, u32 flags,
int ifindex)
{
struct vxlan_sock *vs;
struct socket *sock;
unsigned int h;
struct udp_tunnel_sock_cfg tunnel_cfg;
struct vxlan_sock *vs;
struct sock *sk;
unsigned int h;
ASSERT_RTNL();
@ -3589,18 +3593,18 @@ static struct vxlan_sock *vxlan_socket_create(struct net *net, bool ipv6,
for (h = 0; h < VNI_HASH_SIZE; ++h)
INIT_HLIST_HEAD(&vs->vni_list[h]);
sock = vxlan_create_sock(net, ipv6, port, flags, ifindex);
if (IS_ERR(sock)) {
sk = vxlan_create_sock(net, ipv6, port, flags, ifindex);
if (IS_ERR(sk)) {
kfree(vs);
return ERR_CAST(sock);
return ERR_CAST(sk);
}
vs->sock = sock;
vs->sk = sk;
refcount_set(&vs->refcnt, 1);
vs->flags = (flags & VXLAN_F_RCV_FLAGS);
hlist_add_head_rcu(&vs->hlist, vs_head(net, port));
udp_tunnel_notify_add_rx_port(sock,
udp_tunnel_notify_add_rx_port(sk,
(vs->flags & VXLAN_F_GPE) ?
UDP_TUNNEL_TYPE_VXLAN_GPE :
UDP_TUNNEL_TYPE_VXLAN);
@ -3620,7 +3624,7 @@ static struct vxlan_sock *vxlan_socket_create(struct net *net, bool ipv6,
tunnel_cfg.gro_complete = vxlan_gro_complete;
}
setup_udp_tunnel_sock(net, sock, &tunnel_cfg);
setup_udp_tunnel_sock(net, sk, &tunnel_cfg);
return vs;
}

View File

@ -29,7 +29,7 @@ int vxlan_igmp_join(struct vxlan_dev *vxlan, union vxlan_addr *rip,
.imr_ifindex = ifindex,
};
sk = sock4->sock->sk;
sk = sock4->sk;
lock_sock(sk);
ret = ip_mc_join_group(sk, &mreq);
release_sock(sk);
@ -37,7 +37,7 @@ int vxlan_igmp_join(struct vxlan_dev *vxlan, union vxlan_addr *rip,
} else {
struct vxlan_sock *sock6 = rtnl_dereference(vxlan->vn6_sock);
sk = sock6->sock->sk;
sk = sock6->sk;
lock_sock(sk);
ret = ipv6_sock_mc_join(sk, ifindex, &ip->sin6.sin6_addr);
release_sock(sk);
@ -62,7 +62,7 @@ int vxlan_igmp_leave(struct vxlan_dev *vxlan, union vxlan_addr *rip,
.imr_ifindex = ifindex,
};
sk = sock4->sock->sk;
sk = sock4->sk;
lock_sock(sk);
ret = ip_mc_leave_group(sk, &mreq);
release_sock(sk);
@ -70,7 +70,7 @@ int vxlan_igmp_leave(struct vxlan_dev *vxlan, union vxlan_addr *rip,
} else {
struct vxlan_sock *sock6 = rtnl_dereference(vxlan->vn6_sock);
sk = sock6->sock->sk;
sk = sock6->sk;
lock_sock(sk);
ret = ipv6_sock_mc_drop(sk, ifindex, &ip->sin6.sin6_addr);
release_sock(sk);

View File

@ -335,7 +335,7 @@ static void sock_free(struct sock *sock)
if (unlikely(!sock))
return;
sk_clear_memalloc(sock);
udp_tunnel_sock_release(sock->sk_socket);
udp_tunnel_sock_release(sock);
}
static void set_sock_opts(struct socket *sock)
@ -389,14 +389,14 @@ int wg_socket_init(struct wg_device *wg, u16 port)
goto out;
}
set_sock_opts(new4);
setup_udp_tunnel_sock(net, new4, &cfg);
setup_udp_tunnel_sock(net, new4->sk, &cfg);
#if IS_ENABLED(CONFIG_IPV6)
if (ipv6_mod_enabled()) {
port6.local_udp_port = inet_sk(new4->sk)->inet_sport;
ret = udp_sock_create(net, &port6, &new6);
if (ret < 0) {
udp_tunnel_sock_release(new4);
udp_tunnel_sock_release(new4->sk);
if (ret == -EADDRINUSE && !port && retries++ < 100)
goto retry;
pr_err("%s: Could not create IPv6 socket\n",
@ -404,7 +404,7 @@ int wg_socket_init(struct wg_device *wg, u16 port)
goto out;
}
set_sock_opts(new6);
setup_udp_tunnel_sock(net, new6, &cfg);
setup_udp_tunnel_sock(net, new6->sk, &cfg);
}
#endif

View File

@ -331,7 +331,7 @@ struct amt_dev {
enum amt_status status;
/* Generated key */
siphash_key_t key;
struct socket __rcu *sock;
struct sock __rcu *sk;
u32 max_groups;
u32 max_sources;
u32 hash_buckets;

View File

@ -94,7 +94,7 @@ struct udp_tunnel_sock_cfg {
};
/* Setup the given (UDP) sock to receive UDP encapsulated packets */
void setup_udp_tunnel_sock(struct net *net, struct socket *sock,
void setup_udp_tunnel_sock(struct net *net, struct sock *sk,
struct udp_tunnel_sock_cfg *sock_cfg);
/* -- List of parsable UDP tunnel types --
@ -127,12 +127,12 @@ struct udp_tunnel_info {
};
/* Notify network devices of offloadable types */
void udp_tunnel_push_rx_port(struct net_device *dev, struct socket *sock,
void udp_tunnel_push_rx_port(struct net_device *dev, struct sock *sk,
unsigned short type);
void udp_tunnel_drop_rx_port(struct net_device *dev, struct socket *sock,
void udp_tunnel_drop_rx_port(struct net_device *dev, struct sock *sk,
unsigned short type);
void udp_tunnel_notify_add_rx_port(struct socket *sock, unsigned short type);
void udp_tunnel_notify_del_rx_port(struct socket *sock, unsigned short type);
void udp_tunnel_notify_add_rx_port(struct sock *sk, unsigned short type);
void udp_tunnel_notify_del_rx_port(struct sock *sk, unsigned short type);
/* Transmit the skb using UDP encapsulation. */
void udp_tunnel_xmit_skb(struct rtable *rt, struct sock *sk, struct sk_buff *skb,
@ -176,7 +176,7 @@ static inline void udp_tunnel_set_inner_protocol(struct sk_buff *skb,
skb_set_inner_protocol(skb, inner_proto);
}
void udp_tunnel_sock_release(struct socket *sock);
void udp_tunnel_sock_release(struct sock *sk);
struct rtable *udp_tunnel_dst_lookup(struct sk_buff *skb,
struct net_device *dev,
@ -188,7 +188,7 @@ struct rtable *udp_tunnel_dst_lookup(struct sk_buff *skb,
struct dst_entry *udp_tunnel6_dst_lookup(struct sk_buff *skb,
struct net_device *dev,
struct net *net,
struct socket *sock, int oif,
struct sock *sk, int oif,
struct in6_addr *saddr,
const struct ip_tunnel_key *key,
__be16 sport, __be16 dport, u8 dsfield,

View File

@ -185,7 +185,8 @@ struct vxlan_metadata {
/* per UDP socket information */
struct vxlan_sock {
struct hlist_node hlist;
struct socket *sock;
struct sock *sk;
struct rcu_head rcu;
struct hlist_head vni_list[VNI_HASH_SIZE];
refcount_t refcnt;
u32 flags;
@ -448,7 +449,7 @@ static inline __be32 vxlan_compute_rco(unsigned int start, unsigned int offset)
static inline unsigned short vxlan_get_sk_family(struct vxlan_sock *vs)
{
return vs->sock->sk->sk_family;
return vs->sk->sk_family;
}
#if IS_ENABLED(CONFIG_IPV6)

View File

@ -22,7 +22,7 @@
#include "fou_nl.h"
struct fou {
struct socket *sock;
struct sock *sk;
u8 protocol;
u8 flags;
__be16 port;
@ -508,8 +508,8 @@ static int gue_gro_complete(struct sock *sk, struct sk_buff *skb, int nhoff)
static bool fou_cfg_cmp(struct fou *fou, struct fou_cfg *cfg)
{
struct sock *sk = fou->sock->sk;
struct udp_port_cfg *udp_cfg = &cfg->udp_config;
struct sock *sk = fou->sk;
if (fou->family != udp_cfg->family ||
fou->port != udp_cfg->local_udp_port ||
@ -558,11 +558,8 @@ static int fou_add_to_port_list(struct net *net, struct fou *fou,
static void fou_release(struct fou *fou)
{
struct socket *sock = fou->sock;
list_del(&fou->list);
udp_tunnel_sock_release(sock);
udp_tunnel_sock_release(fou->sk);
kfree_rcu(fou, rcu);
}
@ -593,7 +590,7 @@ static int fou_create(struct net *net, struct fou_cfg *cfg,
fou->family = cfg->udp_config.family;
fou->flags = cfg->flags;
fou->type = cfg->type;
fou->sock = sock;
fou->sk = sk;
memset(&tunnel_cfg, 0, sizeof(tunnel_cfg));
tunnel_cfg.encap_type = 1;
@ -618,7 +615,7 @@ static int fou_create(struct net *net, struct fou_cfg *cfg,
goto error;
}
setup_udp_tunnel_sock(net, sock, &tunnel_cfg);
setup_udp_tunnel_sock(net, sk, &tunnel_cfg);
sk->sk_allocation = GFP_ATOMIC;
@ -634,7 +631,7 @@ static int fou_create(struct net *net, struct fou_cfg *cfg,
error:
kfree(fou);
if (sock)
udp_tunnel_sock_release(sock);
udp_tunnel_sock_release(sock->sk);
return err;
}
@ -779,9 +776,9 @@ int fou_nl_del_doit(struct sk_buff *skb, struct genl_info *info)
static int fou_fill_info(struct fou *fou, struct sk_buff *msg)
{
struct sock *sk = fou->sock->sk;
struct sock *sk = fou->sk;
if (nla_put_u8(msg, FOU_ATTR_AF, fou->sock->sk->sk_family) ||
if (nla_put_u8(msg, FOU_ATTR_AF, sk->sk_family) ||
nla_put_be16(msg, FOU_ATTR_PORT, fou->port) ||
nla_put_be16(msg, FOU_ATTR_PEER_PORT, sk->sk_dport) ||
nla_put_u8(msg, FOU_ATTR_IPPROTO, fou->protocol) ||
@ -793,7 +790,7 @@ static int fou_fill_info(struct fou *fou, struct sk_buff *msg)
if (nla_put_flag(msg, FOU_ATTR_REMCSUM_NOPARTIAL))
return -1;
if (fou->sock->sk->sk_family == AF_INET) {
if (sk->sk_family == AF_INET) {
if (nla_put_in_addr(msg, FOU_ATTR_LOCAL_V4, sk->sk_rcv_saddr))
return -1;

View File

@ -68,11 +68,9 @@ static bool sk_saddr_any(struct sock *sk)
#endif
}
void setup_udp_tunnel_sock(struct net *net, struct socket *sock,
void setup_udp_tunnel_sock(struct net *net, struct sock *sk,
struct udp_tunnel_sock_cfg *cfg)
{
struct sock *sk = sock->sk;
/* Disable multicast loopback */
inet_clear_bit(MC_LOOP, sk);
@ -99,10 +97,9 @@ void setup_udp_tunnel_sock(struct net *net, struct socket *sock,
}
EXPORT_SYMBOL_GPL(setup_udp_tunnel_sock);
void udp_tunnel_push_rx_port(struct net_device *dev, struct socket *sock,
void udp_tunnel_push_rx_port(struct net_device *dev, struct sock *sk,
unsigned short type)
{
struct sock *sk = sock->sk;
struct udp_tunnel_info ti;
ti.type = type;
@ -113,10 +110,9 @@ void udp_tunnel_push_rx_port(struct net_device *dev, struct socket *sock,
}
EXPORT_SYMBOL_GPL(udp_tunnel_push_rx_port);
void udp_tunnel_drop_rx_port(struct net_device *dev, struct socket *sock,
void udp_tunnel_drop_rx_port(struct net_device *dev, struct sock *sk,
unsigned short type)
{
struct sock *sk = sock->sk;
struct udp_tunnel_info ti;
ti.type = type;
@ -128,9 +124,8 @@ void udp_tunnel_drop_rx_port(struct net_device *dev, struct socket *sock,
EXPORT_SYMBOL_GPL(udp_tunnel_drop_rx_port);
/* Notify netdevs that UDP port started listening */
void udp_tunnel_notify_add_rx_port(struct socket *sock, unsigned short type)
void udp_tunnel_notify_add_rx_port(struct sock *sk, unsigned short type)
{
struct sock *sk = sock->sk;
struct net *net = sock_net(sk);
struct udp_tunnel_info ti;
struct net_device *dev;
@ -150,9 +145,8 @@ void udp_tunnel_notify_add_rx_port(struct socket *sock, unsigned short type)
EXPORT_SYMBOL_GPL(udp_tunnel_notify_add_rx_port);
/* Notify netdevs that UDP port is no more listening */
void udp_tunnel_notify_del_rx_port(struct socket *sock, unsigned short type)
void udp_tunnel_notify_del_rx_port(struct sock *sk, unsigned short type)
{
struct sock *sk = sock->sk;
struct net *net = sock_net(sk);
struct udp_tunnel_info ti;
struct net_device *dev;
@ -195,10 +189,11 @@ void udp_tunnel_xmit_skb(struct rtable *rt, struct sock *sk, struct sk_buff *skb
}
EXPORT_SYMBOL_GPL(udp_tunnel_xmit_skb);
void udp_tunnel_sock_release(struct socket *sock)
void udp_tunnel_sock_release(struct sock *sk)
{
rcu_assign_sk_user_data(sock->sk, NULL);
synchronize_rcu();
struct socket *sock = sk->sk_socket;
rcu_assign_sk_user_data(sk, NULL);
kernel_sock_shutdown(sock, SHUT_RDWR);
sock_release(sock);
}

View File

@ -118,7 +118,7 @@ EXPORT_SYMBOL_GPL(udp_tunnel6_xmit_skb);
* @skb: Packet for which lookup is done
* @dev: Tunnel device
* @net: Network namespace of tunnel device
* @sock: Socket which provides route info
* @sk: Socket which provides route info
* @oif: Index of the output interface
* @saddr: Memory to store the src ip address
* @key: Tunnel information
@ -135,7 +135,7 @@ EXPORT_SYMBOL_GPL(udp_tunnel6_xmit_skb);
struct dst_entry *udp_tunnel6_dst_lookup(struct sk_buff *skb,
struct net_device *dev,
struct net *net,
struct socket *sock,
struct sock *sk,
int oif,
struct in6_addr *saddr,
const struct ip_tunnel_key *key,
@ -162,7 +162,7 @@ struct dst_entry *udp_tunnel6_dst_lookup(struct sk_buff *skb,
fl6.fl6_dport = dport;
fl6.flowlabel = ip6_make_flowinfo(dsfield, key->label);
dst = ip6_dst_lookup_flow(net, sock->sk, &fl6, NULL);
dst = ip6_dst_lookup_flow(net, sk, &fl6, NULL);
if (IS_ERR(dst)) {
netdev_dbg(dev, "no route to %pI6\n", &fl6.daddr);
return ERR_PTR(-ENETUNREACH);

View File

@ -1683,7 +1683,7 @@ int l2tp_tunnel_register(struct l2tp_tunnel *tunnel, struct net *net,
.encap_destroy = l2tp_udp_encap_destroy,
};
setup_udp_tunnel_sock(net, sock, &udp_cfg);
setup_udp_tunnel_sock(net, sock->sk, &udp_cfg);
}
sk->sk_allocation = GFP_ATOMIC;

View File

@ -194,7 +194,7 @@ static int rxrpc_open_socket(struct rxrpc_local *local, struct net *net)
tuncfg.encap_rcv = rxrpc_encap_rcv;
tuncfg.encap_err_rcv = rxrpc_encap_err_rcv;
tuncfg.sk_user_data = local;
setup_udp_tunnel_sock(net, local->socket, &tuncfg);
setup_udp_tunnel_sock(net, local->socket->sk, &tuncfg);
/* set the socket up */
usk = local->socket->sk;

View File

@ -864,7 +864,7 @@ int sctp_udp_sock_start(struct net *net)
tuncfg.encap_type = 1;
tuncfg.encap_rcv = sctp_udp_rcv;
tuncfg.encap_err_lookup = sctp_udp_v4_err;
setup_udp_tunnel_sock(net, sock, &tuncfg);
setup_udp_tunnel_sock(net, sock->sk, &tuncfg);
net->sctp.udp4_sock = sock->sk;
#if IS_ENABLED(CONFIG_IPV6)
@ -878,7 +878,7 @@ int sctp_udp_sock_start(struct net *net)
err = udp_sock_create(net, &udp_conf, &sock);
if (err) {
pr_err("Failed to create the SCTP UDP tunneling v6 sock\n");
udp_tunnel_sock_release(net->sctp.udp4_sock->sk_socket);
udp_tunnel_sock_release(net->sctp.udp4_sock);
net->sctp.udp4_sock = NULL;
return err;
}
@ -886,7 +886,7 @@ int sctp_udp_sock_start(struct net *net)
tuncfg.encap_type = 1;
tuncfg.encap_rcv = sctp_udp_rcv;
tuncfg.encap_err_lookup = sctp_udp_v6_err;
setup_udp_tunnel_sock(net, sock, &tuncfg);
setup_udp_tunnel_sock(net, sock->sk, &tuncfg);
net->sctp.udp6_sock = sock->sk;
#endif
@ -896,11 +896,11 @@ int sctp_udp_sock_start(struct net *net)
void sctp_udp_sock_stop(struct net *net)
{
if (net->sctp.udp4_sock) {
udp_tunnel_sock_release(net->sctp.udp4_sock->sk_socket);
udp_tunnel_sock_release(net->sctp.udp4_sock);
net->sctp.udp4_sock = NULL;
}
if (net->sctp.udp6_sock) {
udp_tunnel_sock_release(net->sctp.udp6_sock->sk_socket);
udp_tunnel_sock_release(net->sctp.udp6_sock);
net->sctp.udp6_sock = NULL;
}
}

View File

@ -89,14 +89,14 @@ struct udp_replicast {
/**
* struct udp_bearer - ip/udp bearer data structure
* @bearer: associated generic tipc bearer
* @ubsock: bearer associated socket
* @sk: bearer associated socket
* @ifindex: local address scope
* @work: used to schedule deferred work on a bearer
* @rcast: associated udp_replicast container
*/
struct udp_bearer {
struct tipc_bearer __rcu *bearer;
struct socket *ubsock;
struct sock *sk;
u32 ifindex;
struct work_struct work;
struct udp_replicast rcast;
@ -194,7 +194,7 @@ static int tipc_udp_xmit(struct net *net, struct sk_buff *skb,
}
ttl = ip4_dst_hoplimit(&rt->dst);
udp_tunnel_xmit_skb(rt, ub->ubsock->sk, skb, src->ipv4.s_addr,
udp_tunnel_xmit_skb(rt, ub->sk, skb, src->ipv4.s_addr,
dst->ipv4.s_addr, 0, ttl, 0, src->port,
dst->port, false, true, 0);
#if IS_ENABLED(CONFIG_IPV6)
@ -206,7 +206,7 @@ static int tipc_udp_xmit(struct net *net, struct sk_buff *skb,
.saddr = src->ipv6,
.flowi6_proto = IPPROTO_UDP
};
ndst = ip6_dst_lookup_flow(net, ub->ubsock->sk,
ndst = ip6_dst_lookup_flow(net, ub->sk,
&fl6, NULL);
if (IS_ERR(ndst)) {
err = PTR_ERR(ndst);
@ -215,7 +215,7 @@ static int tipc_udp_xmit(struct net *net, struct sk_buff *skb,
dst_cache_set_ip6(cache, ndst, &fl6.saddr);
}
ttl = ip6_dst_hoplimit(ndst);
udp_tunnel6_xmit_skb(ndst, ub->ubsock->sk, skb, NULL,
udp_tunnel6_xmit_skb(ndst, ub->sk, skb, NULL,
&src->ipv6, &dst->ipv6, 0, ttl, 0,
src->port, dst->port, false, 0);
#endif
@ -405,9 +405,9 @@ static int tipc_udp_recv(struct sock *sk, struct sk_buff *skb)
static int enable_mcast(struct udp_bearer *ub, struct udp_media_addr *remote)
{
int err = 0;
struct sock *sk = ub->sk;
struct ip_mreqn mreqn;
struct sock *sk = ub->ubsock->sk;
int err = 0;
if (ntohs(remote->proto) == ETH_P_IP) {
mreqn.imr_multiaddr = remote->ipv4;
@ -670,6 +670,7 @@ static int tipc_udp_enable(struct net *net, struct tipc_bearer *b,
struct nlattr *opts[TIPC_NLA_UDP_MAX + 1];
u8 node_id[NODE_ID_LEN] = {0,};
struct net_device *dev;
struct socket *sock;
int rmcast = 0;
ub = kzalloc_obj(*ub, GFP_ATOMIC);
@ -764,14 +765,16 @@ static int tipc_udp_enable(struct net *net, struct tipc_bearer *b,
goto err;
}
udp_conf.local_udp_port = local.port;
err = udp_sock_create(net, &udp_conf, &ub->ubsock);
err = udp_sock_create(net, &udp_conf, &sock);
if (err)
goto err;
ub->sk = sock->sk;
tuncfg.sk_user_data = ub;
tuncfg.encap_type = 1;
tuncfg.encap_rcv = tipc_udp_recv;
tuncfg.encap_destroy = NULL;
setup_udp_tunnel_sock(net, ub->ubsock, &tuncfg);
setup_udp_tunnel_sock(net, ub->sk, &tuncfg);
err = dst_cache_init(&ub->rcast.dst_cache, GFP_ATOMIC);
if (err)
@ -793,7 +796,8 @@ static int tipc_udp_enable(struct net *net, struct tipc_bearer *b,
free:
dst_cache_destroy(&ub->rcast.dst_cache);
udp_tunnel_sock_release(ub->ubsock);
udp_tunnel_sock_release(ub->sk);
synchronize_rcu();
err:
kfree(ub);
return err;
@ -812,10 +816,10 @@ static void cleanup_bearer(struct work_struct *work)
kfree_rcu(rcast, rcu);
}
tn = tipc_net(sock_net(ub->ubsock->sk));
tn = tipc_net(sock_net(ub->sk));
dst_cache_destroy(&ub->rcast.dst_cache);
udp_tunnel_sock_release(ub->ubsock);
udp_tunnel_sock_release(ub->sk);
/* Note: could use a call_rcu() to avoid another synchronize_net() */
synchronize_net();
@ -833,11 +837,11 @@ static void tipc_udp_disable(struct tipc_bearer *b)
pr_err("UDP bearer instance not found\n");
return;
}
sock_set_flag(ub->ubsock->sk, SOCK_DEAD);
sock_set_flag(ub->sk, SOCK_DEAD);
RCU_INIT_POINTER(ub->bearer, NULL);
/* sock_release need to be done outside of rtnl lock */
atomic_inc(&tipc_net(sock_net(ub->ubsock->sk))->wq_count);
atomic_inc(&tipc_net(sock_net(ub->sk))->wq_count);
INIT_WORK(&ub->work, cleanup_bearer);
schedule_work(&ub->work);
}