summaryrefslogtreecommitdiff
path: root/net/ipv6
diff options
context:
space:
mode:
authorEric Dumazet <edumazet@google.com>2019-05-24 19:03:39 +0300
committerDavid S. Miller <davem@davemloft.net>2019-05-27 00:08:05 +0300
commit4907abc605e328d61bee56e4e89db4f56ade2090 (patch)
tree764e708aaa78091e2a8ccb046cfbf8a59aa10c88 /net/ipv6
parenta39aca678a0626941aa99c18c1c452ca758e7865 (diff)
downloadlinux-4907abc605e328d61bee56e4e89db4f56ade2090.tar.xz
net: dynamically allocate fqdir structures
Following patch will add rcu grace period before fqdir rhashtable destruction, so we need to dynamically allocate fqdir structures to not force expensive synchronize_rcu() calls in netns dismantle path. Signed-off-by: Eric Dumazet <edumazet@google.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6')
-rw-r--r--net/ipv6/netfilter/nf_conntrack_reasm.c27
-rw-r--r--net/ipv6/proc.c4
-rw-r--r--net/ipv6/reassembly.c24
3 files changed, 28 insertions, 27 deletions
diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c
index b6f7385ed93c..c5d59fa568d6 100644
--- a/net/ipv6/netfilter/nf_conntrack_reasm.c
+++ b/net/ipv6/netfilter/nf_conntrack_reasm.c
@@ -90,12 +90,12 @@ static int nf_ct_frag6_sysctl_register(struct net *net)
goto err_alloc;
}
- table[0].data = &net->nf_frag.fqdir.timeout;
- table[1].data = &net->nf_frag.fqdir.low_thresh;
- table[1].extra2 = &net->nf_frag.fqdir.high_thresh;
- table[2].data = &net->nf_frag.fqdir.high_thresh;
- table[2].extra1 = &net->nf_frag.fqdir.low_thresh;
- table[2].extra2 = &init_net.nf_frag.fqdir.high_thresh;
+ table[0].data = &net->nf_frag.fqdir->timeout;
+ table[1].data = &net->nf_frag.fqdir->low_thresh;
+ table[1].extra2 = &net->nf_frag.fqdir->high_thresh;
+ table[2].data = &net->nf_frag.fqdir->high_thresh;
+ table[2].extra1 = &net->nf_frag.fqdir->low_thresh;
+ table[2].extra2 = &init_net.nf_frag.fqdir->high_thresh;
hdr = register_net_sysctl(net, "net/netfilter", table);
if (hdr == NULL)
@@ -162,7 +162,7 @@ static struct frag_queue *fq_find(struct net *net, __be32 id, u32 user,
};
struct inet_frag_queue *q;
- q = inet_frag_find(&net->nf_frag.fqdir, &key);
+ q = inet_frag_find(net->nf_frag.fqdir, &key);
if (!q)
return NULL;
@@ -489,23 +489,24 @@ static int nf_ct_net_init(struct net *net)
{
int res;
- net->nf_frag.fqdir.high_thresh = IPV6_FRAG_HIGH_THRESH;
- net->nf_frag.fqdir.low_thresh = IPV6_FRAG_LOW_THRESH;
- net->nf_frag.fqdir.timeout = IPV6_FRAG_TIMEOUT;
-
res = fqdir_init(&net->nf_frag.fqdir, &nf_frags, net);
if (res < 0)
return res;
+
+ net->nf_frag.fqdir->high_thresh = IPV6_FRAG_HIGH_THRESH;
+ net->nf_frag.fqdir->low_thresh = IPV6_FRAG_LOW_THRESH;
+ net->nf_frag.fqdir->timeout = IPV6_FRAG_TIMEOUT;
+
res = nf_ct_frag6_sysctl_register(net);
if (res < 0)
- fqdir_exit(&net->nf_frag.fqdir);
+ fqdir_exit(net->nf_frag.fqdir);
return res;
}
static void nf_ct_net_exit(struct net *net)
{
nf_ct_frags6_sysctl_unregister(net);
- fqdir_exit(&net->nf_frag.fqdir);
+ fqdir_exit(net->nf_frag.fqdir);
}
static struct pernet_operations nf_ct_net_ops = {
diff --git a/net/ipv6/proc.c b/net/ipv6/proc.c
index f3e3118393c4..0bbefc440bcd 100644
--- a/net/ipv6/proc.c
+++ b/net/ipv6/proc.c
@@ -48,8 +48,8 @@ static int sockstat6_seq_show(struct seq_file *seq, void *v)
seq_printf(seq, "RAW6: inuse %d\n",
sock_prot_inuse_get(net, &rawv6_prot));
seq_printf(seq, "FRAG6: inuse %u memory %lu\n",
- atomic_read(&net->ipv6.fqdir.rhashtable.nelems),
- frag_mem_limit(&net->ipv6.fqdir));
+ atomic_read(&net->ipv6.fqdir->rhashtable.nelems),
+ frag_mem_limit(net->ipv6.fqdir));
return 0;
}
diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c
index a6f26aa648fb..836ea964cf14 100644
--- a/net/ipv6/reassembly.c
+++ b/net/ipv6/reassembly.c
@@ -98,7 +98,7 @@ fq_find(struct net *net, __be32 id, const struct ipv6hdr *hdr, int iif)
IPV6_ADDR_LINKLOCAL)))
key.iif = 0;
- q = inet_frag_find(&net->ipv6.fqdir, &key);
+ q = inet_frag_find(net->ipv6.fqdir, &key);
if (!q)
return NULL;
@@ -443,11 +443,11 @@ static int __net_init ip6_frags_ns_sysctl_register(struct net *net)
goto err_alloc;
}
- table[0].data = &net->ipv6.fqdir.high_thresh;
- table[0].extra1 = &net->ipv6.fqdir.low_thresh;
- table[1].data = &net->ipv6.fqdir.low_thresh;
- table[1].extra2 = &net->ipv6.fqdir.high_thresh;
- table[2].data = &net->ipv6.fqdir.timeout;
+ table[0].data = &net->ipv6.fqdir->high_thresh;
+ table[0].extra1 = &net->ipv6.fqdir->low_thresh;
+ table[1].data = &net->ipv6.fqdir->low_thresh;
+ table[1].extra2 = &net->ipv6.fqdir->high_thresh;
+ table[2].data = &net->ipv6.fqdir->timeout;
hdr = register_net_sysctl(net, "net/ipv6", table);
if (!hdr)
@@ -510,24 +510,24 @@ static int __net_init ipv6_frags_init_net(struct net *net)
{
int res;
- net->ipv6.fqdir.high_thresh = IPV6_FRAG_HIGH_THRESH;
- net->ipv6.fqdir.low_thresh = IPV6_FRAG_LOW_THRESH;
- net->ipv6.fqdir.timeout = IPV6_FRAG_TIMEOUT;
-
res = fqdir_init(&net->ipv6.fqdir, &ip6_frags, net);
if (res < 0)
return res;
+ net->ipv6.fqdir->high_thresh = IPV6_FRAG_HIGH_THRESH;
+ net->ipv6.fqdir->low_thresh = IPV6_FRAG_LOW_THRESH;
+ net->ipv6.fqdir->timeout = IPV6_FRAG_TIMEOUT;
+
res = ip6_frags_ns_sysctl_register(net);
if (res < 0)
- fqdir_exit(&net->ipv6.fqdir);
+ fqdir_exit(net->ipv6.fqdir);
return res;
}
static void __net_exit ipv6_frags_exit_net(struct net *net)
{
ip6_frags_ns_sysctl_unregister(net);
- fqdir_exit(&net->ipv6.fqdir);
+ fqdir_exit(net->ipv6.fqdir);
}
static struct pernet_operations ip6_frags_ops = {