udp: Access &udp_table via net.

We will soon introduce an optional per-netns hash table
for UDP.

This means we cannot use udp_table directly in most places.

Instead, access it via net->ipv4.udp_table.

The access will be valid only while initialising udp_table
itself and creating/destroying each netns.

Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Kuniyuki Iwashima 2022-11-14 13:57:56 -08:00 committed by David S. Miller
parent 478aee5d6b
commit ba6aac1516
6 changed files with 35 additions and 27 deletions

View file

@ -6432,7 +6432,7 @@ static struct sock *sk_lookup(struct net *net, struct bpf_sock_tuple *tuple,
else else
sk = __udp4_lib_lookup(net, src4, tuple->ipv4.sport, sk = __udp4_lib_lookup(net, src4, tuple->ipv4.sport,
dst4, tuple->ipv4.dport, dst4, tuple->ipv4.dport,
dif, sdif, &udp_table, NULL); dif, sdif, net->ipv4.udp_table, NULL);
#if IS_ENABLED(CONFIG_IPV6) #if IS_ENABLED(CONFIG_IPV6)
} else { } else {
struct in6_addr *src6 = (struct in6_addr *)&tuple->ipv6.saddr; struct in6_addr *src6 = (struct in6_addr *)&tuple->ipv6.saddr;
@ -6448,7 +6448,7 @@ static struct sock *sk_lookup(struct net *net, struct bpf_sock_tuple *tuple,
src6, tuple->ipv6.sport, src6, tuple->ipv6.sport,
dst6, tuple->ipv6.dport, dst6, tuple->ipv6.dport,
dif, sdif, dif, sdif,
&udp_table, NULL); net->ipv4.udp_table, NULL);
#endif #endif
} }

View file

@ -472,7 +472,7 @@ static struct sock *udp4_lookup_run_bpf(struct net *net,
struct sock *sk, *reuse_sk; struct sock *sk, *reuse_sk;
bool no_reuseport; bool no_reuseport;
if (udptable != &udp_table) if (udptable != net->ipv4.udp_table)
return NULL; /* only UDP is supported */ return NULL; /* only UDP is supported */
no_reuseport = bpf_sk_lookup_run_v4(net, IPPROTO_UDP, saddr, sport, no_reuseport = bpf_sk_lookup_run_v4(net, IPPROTO_UDP, saddr, sport,
@ -553,10 +553,11 @@ struct sock *udp4_lib_lookup_skb(const struct sk_buff *skb,
__be16 sport, __be16 dport) __be16 sport, __be16 dport)
{ {
const struct iphdr *iph = ip_hdr(skb); const struct iphdr *iph = ip_hdr(skb);
struct net *net = dev_net(skb->dev);
return __udp4_lib_lookup(dev_net(skb->dev), iph->saddr, sport, return __udp4_lib_lookup(net, iph->saddr, sport,
iph->daddr, dport, inet_iif(skb), iph->daddr, dport, inet_iif(skb),
inet_sdif(skb), &udp_table, NULL); inet_sdif(skb), net->ipv4.udp_table, NULL);
} }
/* Must be called under rcu_read_lock(). /* Must be called under rcu_read_lock().
@ -569,7 +570,7 @@ struct sock *udp4_lib_lookup(struct net *net, __be32 saddr, __be16 sport,
struct sock *sk; struct sock *sk;
sk = __udp4_lib_lookup(net, saddr, sport, daddr, dport, sk = __udp4_lib_lookup(net, saddr, sport, daddr, dport,
dif, 0, &udp_table, NULL); dif, 0, net->ipv4.udp_table, NULL);
if (sk && !refcount_inc_not_zero(&sk->sk_refcnt)) if (sk && !refcount_inc_not_zero(&sk->sk_refcnt))
sk = NULL; sk = NULL;
return sk; return sk;
@ -807,7 +808,7 @@ int __udp4_lib_err(struct sk_buff *skb, u32 info, struct udp_table *udptable)
int udp_err(struct sk_buff *skb, u32 info) int udp_err(struct sk_buff *skb, u32 info)
{ {
return __udp4_lib_err(skb, info, &udp_table); return __udp4_lib_err(skb, info, dev_net(skb->dev)->ipv4.udp_table);
} }
/* /*
@ -2524,13 +2525,14 @@ static struct sock *__udp4_lib_mcast_demux_lookup(struct net *net,
__be16 rmt_port, __be32 rmt_addr, __be16 rmt_port, __be32 rmt_addr,
int dif, int sdif) int dif, int sdif)
{ {
struct udp_table *udptable = net->ipv4.udp_table;
unsigned short hnum = ntohs(loc_port); unsigned short hnum = ntohs(loc_port);
struct sock *sk, *result; struct sock *sk, *result;
struct udp_hslot *hslot; struct udp_hslot *hslot;
unsigned int slot; unsigned int slot;
slot = udp_hashfn(net, hnum, udp_table.mask); slot = udp_hashfn(net, hnum, udptable->mask);
hslot = &udp_table.hash[slot]; hslot = &udptable->hash[slot];
/* Do not bother scanning a too big list */ /* Do not bother scanning a too big list */
if (hslot->count > 10) if (hslot->count > 10)
@ -2558,6 +2560,7 @@ static struct sock *__udp4_lib_demux_lookup(struct net *net,
__be16 rmt_port, __be32 rmt_addr, __be16 rmt_port, __be32 rmt_addr,
int dif, int sdif) int dif, int sdif)
{ {
struct udp_table *udptable = net->ipv4.udp_table;
INET_ADDR_COOKIE(acookie, rmt_addr, loc_addr); INET_ADDR_COOKIE(acookie, rmt_addr, loc_addr);
unsigned short hnum = ntohs(loc_port); unsigned short hnum = ntohs(loc_port);
unsigned int hash2, slot2; unsigned int hash2, slot2;
@ -2566,8 +2569,8 @@ static struct sock *__udp4_lib_demux_lookup(struct net *net,
struct sock *sk; struct sock *sk;
hash2 = ipv4_portaddr_hash(net, loc_addr, hnum); hash2 = ipv4_portaddr_hash(net, loc_addr, hnum);
slot2 = hash2 & udp_table.mask; slot2 = hash2 & udptable->mask;
hslot2 = &udp_table.hash2[slot2]; hslot2 = &udptable->hash2[slot2];
ports = INET_COMBINED_PORTS(rmt_port, hnum); ports = INET_COMBINED_PORTS(rmt_port, hnum);
udp_portaddr_for_each_entry_rcu(sk, &hslot2->head) { udp_portaddr_for_each_entry_rcu(sk, &hslot2->head) {
@ -2649,7 +2652,7 @@ int udp_v4_early_demux(struct sk_buff *skb)
int udp_rcv(struct sk_buff *skb) int udp_rcv(struct sk_buff *skb)
{ {
return __udp4_lib_rcv(skb, &udp_table, IPPROTO_UDP); return __udp4_lib_rcv(skb, dev_net(skb->dev)->ipv4.udp_table, IPPROTO_UDP);
} }
void udp_destroy_sock(struct sock *sk) void udp_destroy_sock(struct sock *sk)

View file

@ -147,13 +147,13 @@ static void udp_dump(struct udp_table *table, struct sk_buff *skb,
static void udp_diag_dump(struct sk_buff *skb, struct netlink_callback *cb, static void udp_diag_dump(struct sk_buff *skb, struct netlink_callback *cb,
const struct inet_diag_req_v2 *r) const struct inet_diag_req_v2 *r)
{ {
udp_dump(&udp_table, skb, cb, r); udp_dump(sock_net(cb->skb->sk)->ipv4.udp_table, skb, cb, r);
} }
static int udp_diag_dump_one(struct netlink_callback *cb, static int udp_diag_dump_one(struct netlink_callback *cb,
const struct inet_diag_req_v2 *req) const struct inet_diag_req_v2 *req)
{ {
return udp_dump_one(&udp_table, cb, req); return udp_dump_one(sock_net(cb->skb->sk)->ipv4.udp_table, cb, req);
} }
static void udp_diag_get_info(struct sock *sk, struct inet_diag_msg *r, static void udp_diag_get_info(struct sock *sk, struct inet_diag_msg *r,
@ -225,7 +225,7 @@ static int __udp_diag_destroy(struct sk_buff *in_skb,
static int udp_diag_destroy(struct sk_buff *in_skb, static int udp_diag_destroy(struct sk_buff *in_skb,
const struct inet_diag_req_v2 *req) const struct inet_diag_req_v2 *req)
{ {
return __udp_diag_destroy(in_skb, req, &udp_table); return __udp_diag_destroy(in_skb, req, sock_net(in_skb->sk)->ipv4.udp_table);
} }
static int udplite_diag_destroy(struct sk_buff *in_skb, static int udplite_diag_destroy(struct sk_buff *in_skb,

View file

@ -600,10 +600,11 @@ static struct sock *udp4_gro_lookup_skb(struct sk_buff *skb, __be16 sport,
__be16 dport) __be16 dport)
{ {
const struct iphdr *iph = skb_gro_network_header(skb); const struct iphdr *iph = skb_gro_network_header(skb);
struct net *net = dev_net(skb->dev);
return __udp4_lib_lookup(dev_net(skb->dev), iph->saddr, sport, return __udp4_lib_lookup(net, iph->saddr, sport,
iph->daddr, dport, inet_iif(skb), iph->daddr, dport, inet_iif(skb),
inet_sdif(skb), &udp_table, NULL); inet_sdif(skb), net->ipv4.udp_table, NULL);
} }
INDIRECT_CALLABLE_SCOPE INDIRECT_CALLABLE_SCOPE

View file

@ -217,7 +217,7 @@ static inline struct sock *udp6_lookup_run_bpf(struct net *net,
struct sock *sk, *reuse_sk; struct sock *sk, *reuse_sk;
bool no_reuseport; bool no_reuseport;
if (udptable != &udp_table) if (udptable != net->ipv4.udp_table)
return NULL; /* only UDP is supported */ return NULL; /* only UDP is supported */
no_reuseport = bpf_sk_lookup_run_v6(net, IPPROTO_UDP, saddr, sport, no_reuseport = bpf_sk_lookup_run_v6(net, IPPROTO_UDP, saddr, sport,
@ -298,10 +298,11 @@ struct sock *udp6_lib_lookup_skb(const struct sk_buff *skb,
__be16 sport, __be16 dport) __be16 sport, __be16 dport)
{ {
const struct ipv6hdr *iph = ipv6_hdr(skb); const struct ipv6hdr *iph = ipv6_hdr(skb);
struct net *net = dev_net(skb->dev);
return __udp6_lib_lookup(dev_net(skb->dev), &iph->saddr, sport, return __udp6_lib_lookup(net, &iph->saddr, sport,
&iph->daddr, dport, inet6_iif(skb), &iph->daddr, dport, inet6_iif(skb),
inet6_sdif(skb), &udp_table, NULL); inet6_sdif(skb), net->ipv4.udp_table, NULL);
} }
/* Must be called under rcu_read_lock(). /* Must be called under rcu_read_lock().
@ -314,7 +315,7 @@ struct sock *udp6_lib_lookup(struct net *net, const struct in6_addr *saddr, __be
struct sock *sk; struct sock *sk;
sk = __udp6_lib_lookup(net, saddr, sport, daddr, dport, sk = __udp6_lib_lookup(net, saddr, sport, daddr, dport,
dif, 0, &udp_table, NULL); dif, 0, net->ipv4.udp_table, NULL);
if (sk && !refcount_inc_not_zero(&sk->sk_refcnt)) if (sk && !refcount_inc_not_zero(&sk->sk_refcnt))
sk = NULL; sk = NULL;
return sk; return sk;
@ -689,7 +690,8 @@ static __inline__ int udpv6_err(struct sk_buff *skb,
struct inet6_skb_parm *opt, u8 type, struct inet6_skb_parm *opt, u8 type,
u8 code, int offset, __be32 info) u8 code, int offset, __be32 info)
{ {
return __udp6_lib_err(skb, opt, type, code, offset, info, &udp_table); return __udp6_lib_err(skb, opt, type, code, offset, info,
dev_net(skb->dev)->ipv4.udp_table);
} }
static int udpv6_queue_rcv_one_skb(struct sock *sk, struct sk_buff *skb) static int udpv6_queue_rcv_one_skb(struct sock *sk, struct sk_buff *skb)
@ -1063,6 +1065,7 @@ static struct sock *__udp6_lib_demux_lookup(struct net *net,
__be16 rmt_port, const struct in6_addr *rmt_addr, __be16 rmt_port, const struct in6_addr *rmt_addr,
int dif, int sdif) int dif, int sdif)
{ {
struct udp_table *udptable = net->ipv4.udp_table;
unsigned short hnum = ntohs(loc_port); unsigned short hnum = ntohs(loc_port);
unsigned int hash2, slot2; unsigned int hash2, slot2;
struct udp_hslot *hslot2; struct udp_hslot *hslot2;
@ -1070,8 +1073,8 @@ static struct sock *__udp6_lib_demux_lookup(struct net *net,
struct sock *sk; struct sock *sk;
hash2 = ipv6_portaddr_hash(net, loc_addr, hnum); hash2 = ipv6_portaddr_hash(net, loc_addr, hnum);
slot2 = hash2 & udp_table.mask; slot2 = hash2 & udptable->mask;
hslot2 = &udp_table.hash2[slot2]; hslot2 = &udptable->hash2[slot2];
ports = INET_COMBINED_PORTS(rmt_port, hnum); ports = INET_COMBINED_PORTS(rmt_port, hnum);
udp_portaddr_for_each_entry_rcu(sk, &hslot2->head) { udp_portaddr_for_each_entry_rcu(sk, &hslot2->head) {
@ -1127,7 +1130,7 @@ void udp_v6_early_demux(struct sk_buff *skb)
INDIRECT_CALLABLE_SCOPE int udpv6_rcv(struct sk_buff *skb) INDIRECT_CALLABLE_SCOPE int udpv6_rcv(struct sk_buff *skb)
{ {
return __udp6_lib_rcv(skb, &udp_table, IPPROTO_UDP); return __udp6_lib_rcv(skb, dev_net(skb->dev)->ipv4.udp_table, IPPROTO_UDP);
} }
/* /*

View file

@ -116,10 +116,11 @@ static struct sock *udp6_gro_lookup_skb(struct sk_buff *skb, __be16 sport,
__be16 dport) __be16 dport)
{ {
const struct ipv6hdr *iph = skb_gro_network_header(skb); const struct ipv6hdr *iph = skb_gro_network_header(skb);
struct net *net = dev_net(skb->dev);
return __udp6_lib_lookup(dev_net(skb->dev), &iph->saddr, sport, return __udp6_lib_lookup(net, &iph->saddr, sport,
&iph->daddr, dport, inet6_iif(skb), &iph->daddr, dport, inet6_iif(skb),
inet6_sdif(skb), &udp_table, NULL); inet6_sdif(skb), net->ipv4.udp_table, NULL);
} }
INDIRECT_CALLABLE_SCOPE INDIRECT_CALLABLE_SCOPE