Skip to content

Commit 21a216a

Browse files
edumazetkuba-moo
authored andcommitted
ipv6/addrconf: allocate a per netns hash table
Add a per netns hash table and a dedicated spinlock, first step to get rid of the global inet6_addr_lst[] one. Signed-off-by: Eric Dumazet <edumazet@google.com> Reviewed-by: David Ahern <dsahern@kernel.org> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
1 parent b2309a7 commit 21a216a

File tree

2 files changed

+24
-0
lines changed

2 files changed

+24
-0
lines changed

include/net/netns/ipv6.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,10 @@ struct netns_ipv6 {
9292
struct sock *tcp_sk;
9393
struct sock *igmp_sk;
9494
struct sock *mc_autojoin_sk;
95+
96+
struct hlist_head *inet6_addr_lst;
97+
spinlock_t addrconf_hash_lock;
98+
9599
#ifdef CONFIG_IPV6_MROUTE
96100
#ifndef CONFIG_IPV6_MROUTE_MULTIPLE_TABLES
97101
struct mr_table *mrt6;

net/ipv6/addrconf.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7111,6 +7111,13 @@ static int __net_init addrconf_init_net(struct net *net)
71117111
int err = -ENOMEM;
71127112
struct ipv6_devconf *all, *dflt;
71137113

7114+
spin_lock_init(&net->ipv6.addrconf_hash_lock);
7115+
net->ipv6.inet6_addr_lst = kcalloc(IN6_ADDR_HSIZE,
7116+
sizeof(struct hlist_head),
7117+
GFP_KERNEL);
7118+
if (!net->ipv6.inet6_addr_lst)
7119+
goto err_alloc_addr;
7120+
71147121
all = kmemdup(&ipv6_devconf, sizeof(ipv6_devconf), GFP_KERNEL);
71157122
if (!all)
71167123
goto err_alloc_all;
@@ -7172,11 +7179,15 @@ static int __net_init addrconf_init_net(struct net *net)
71727179
err_alloc_dflt:
71737180
kfree(all);
71747181
err_alloc_all:
7182+
kfree(net->ipv6.inet6_addr_lst);
7183+
err_alloc_addr:
71757184
return err;
71767185
}
71777186

71787187
static void __net_exit addrconf_exit_net(struct net *net)
71797188
{
7189+
int i;
7190+
71807191
#ifdef CONFIG_SYSCTL
71817192
__addrconf_sysctl_unregister(net, net->ipv6.devconf_dflt,
71827193
NETCONFA_IFINDEX_DEFAULT);
@@ -7187,6 +7198,15 @@ static void __net_exit addrconf_exit_net(struct net *net)
71877198
net->ipv6.devconf_dflt = NULL;
71887199
kfree(net->ipv6.devconf_all);
71897200
net->ipv6.devconf_all = NULL;
7201+
7202+
/*
7203+
* Check hash table, then free it.
7204+
*/
7205+
for (i = 0; i < IN6_ADDR_HSIZE; i++)
7206+
WARN_ON_ONCE(!hlist_empty(&net->ipv6.inet6_addr_lst[i]));
7207+
7208+
kfree(net->ipv6.inet6_addr_lst);
7209+
net->ipv6.inet6_addr_lst = NULL;
71907210
}
71917211

71927212
static struct pernet_operations addrconf_ops = {

0 commit comments

Comments
 (0)