mirror of
https://github.com/torvalds/linux.git
synced 2026-07-27 17:47:41 +02:00
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:
commit
ed36fad2cd
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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++) {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user