summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Dumazet <edumazet@google.com>2019-05-24 12:03:39 -0400
committerDavid S. Miller <davem@davemloft.net>2019-05-26 17:08:05 -0400
commit4907abc605e328d61bee56e4e89db4f56ade2090 (patch)
tree764e708aaa78091e2a8ccb046cfbf8a59aa10c88
parenta39aca678a0626941aa99c18c1c452ca758e7865 (diff)
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>
-rw-r--r--include/net/inet_frag.h17
-rw-r--r--include/net/netns/ieee802154_6lowpan.h2
-rw-r--r--include/net/netns/ipv4.h2
-rw-r--r--include/net/netns/ipv6.h4
-rw-r--r--net/ieee802154/6lowpan/reassembly.c24
-rw-r--r--net/ipv4/inet_fragment.c1
-rw-r--r--net/ipv4/ip_fragment.c32
-rw-r--r--net/ipv4/proc.c4
-rw-r--r--net/ipv6/netfilter/nf_conntrack_reasm.c27
-rw-r--r--net/ipv6/proc.c4
-rw-r--r--net/ipv6/reassembly.c24
11 files changed, 78 insertions, 63 deletions
diff --git a/include/net/inet_frag.h b/include/net/inet_frag.h
index 37cde5c1498c..5f754c660cfa 100644
--- a/include/net/inet_frag.h
+++ b/include/net/inet_frag.h
@@ -105,14 +105,25 @@ struct inet_frags {
105int inet_frags_init(struct inet_frags *); 105int inet_frags_init(struct inet_frags *);
106void inet_frags_fini(struct inet_frags *); 106void inet_frags_fini(struct inet_frags *);
107 107
108static inline int fqdir_init(struct fqdir *fqdir, struct inet_frags *f, 108static inline int fqdir_init(struct fqdir **fqdirp, struct inet_frags *f,
109 struct net *net) 109 struct net *net)
110{ 110{
111 struct fqdir *fqdir = kzalloc(sizeof(*fqdir), GFP_KERNEL);
112 int res;
113
114 if (!fqdir)
115 return -ENOMEM;
111 fqdir->f = f; 116 fqdir->f = f;
112 fqdir->net = net; 117 fqdir->net = net;
113 atomic_long_set(&fqdir->mem, 0); 118 res = rhashtable_init(&fqdir->rhashtable, &fqdir->f->rhash_params);
114 return rhashtable_init(&fqdir->rhashtable, &fqdir->f->rhash_params); 119 if (res < 0) {
120 kfree(fqdir);
121 return res;
122 }
123 *fqdirp = fqdir;
124 return 0;
115} 125}
126
116void fqdir_exit(struct fqdir *fqdir); 127void fqdir_exit(struct fqdir *fqdir);
117 128
118void inet_frag_kill(struct inet_frag_queue *q); 129void inet_frag_kill(struct inet_frag_queue *q);
diff --git a/include/net/netns/ieee802154_6lowpan.h b/include/net/netns/ieee802154_6lowpan.h
index d27ac64f8dfe..95406e1342cb 100644
--- a/include/net/netns/ieee802154_6lowpan.h
+++ b/include/net/netns/ieee802154_6lowpan.h
@@ -16,7 +16,7 @@ struct netns_sysctl_lowpan {
16 16
17struct netns_ieee802154_lowpan { 17struct netns_ieee802154_lowpan {
18 struct netns_sysctl_lowpan sysctl; 18 struct netns_sysctl_lowpan sysctl;
19 struct fqdir fqdir; 19 struct fqdir *fqdir;
20}; 20};
21 21
22#endif 22#endif
diff --git a/include/net/netns/ipv4.h b/include/net/netns/ipv4.h
index 3c270baa32e0..c07cee1e0c9e 100644
--- a/include/net/netns/ipv4.h
+++ b/include/net/netns/ipv4.h
@@ -72,7 +72,7 @@ struct netns_ipv4 {
72 72
73 struct inet_peer_base *peers; 73 struct inet_peer_base *peers;
74 struct sock * __percpu *tcp_sk; 74 struct sock * __percpu *tcp_sk;
75 struct fqdir fqdir; 75 struct fqdir *fqdir;
76#ifdef CONFIG_NETFILTER 76#ifdef CONFIG_NETFILTER
77 struct xt_table *iptable_filter; 77 struct xt_table *iptable_filter;
78 struct xt_table *iptable_mangle; 78 struct xt_table *iptable_mangle;
diff --git a/include/net/netns/ipv6.h b/include/net/netns/ipv6.h
index 3dd2ae2a38e2..022a0fd1a5a4 100644
--- a/include/net/netns/ipv6.h
+++ b/include/net/netns/ipv6.h
@@ -58,7 +58,7 @@ struct netns_ipv6 {
58 struct ipv6_devconf *devconf_all; 58 struct ipv6_devconf *devconf_all;
59 struct ipv6_devconf *devconf_dflt; 59 struct ipv6_devconf *devconf_dflt;
60 struct inet_peer_base *peers; 60 struct inet_peer_base *peers;
61 struct fqdir fqdir; 61 struct fqdir *fqdir;
62#ifdef CONFIG_NETFILTER 62#ifdef CONFIG_NETFILTER
63 struct xt_table *ip6table_filter; 63 struct xt_table *ip6table_filter;
64 struct xt_table *ip6table_mangle; 64 struct xt_table *ip6table_mangle;
@@ -116,7 +116,7 @@ struct netns_ipv6 {
116 116
117#if IS_ENABLED(CONFIG_NF_DEFRAG_IPV6) 117#if IS_ENABLED(CONFIG_NF_DEFRAG_IPV6)
118struct netns_nf_frag { 118struct netns_nf_frag {
119 struct fqdir fqdir; 119 struct fqdir *fqdir;
120}; 120};
121#endif 121#endif
122 122
diff --git a/net/ieee802154/6lowpan/reassembly.c b/net/ieee802154/6lowpan/reassembly.c
index 03a444c9e191..e59c3b708969 100644
--- a/net/ieee802154/6lowpan/reassembly.c
+++ b/net/ieee802154/6lowpan/reassembly.c
@@ -79,7 +79,7 @@ fq_find(struct net *net, const struct lowpan_802154_cb *cb,
79 key.src = *src; 79 key.src = *src;
80 key.dst = *dst; 80 key.dst = *dst;
81 81
82 q = inet_frag_find(&ieee802154_lowpan->fqdir, &key); 82 q = inet_frag_find(ieee802154_lowpan->fqdir, &key);
83 if (!q) 83 if (!q)
84 return NULL; 84 return NULL;
85 85
@@ -377,11 +377,11 @@ static int __net_init lowpan_frags_ns_sysctl_register(struct net *net)
377 table[0].procname = NULL; 377 table[0].procname = NULL;
378 } 378 }
379 379
380 table[0].data = &ieee802154_lowpan->fqdir.high_thresh; 380 table[0].data = &ieee802154_lowpan->fqdir->high_thresh;
381 table[0].extra1 = &ieee802154_lowpan->fqdir.low_thresh; 381 table[0].extra1 = &ieee802154_lowpan->fqdir->low_thresh;
382 table[1].data = &ieee802154_lowpan->fqdir.low_thresh; 382 table[1].data = &ieee802154_lowpan->fqdir->low_thresh;
383 table[1].extra2 = &ieee802154_lowpan->fqdir.high_thresh; 383 table[1].extra2 = &ieee802154_lowpan->fqdir->high_thresh;
384 table[2].data = &ieee802154_lowpan->fqdir.timeout; 384 table[2].data = &ieee802154_lowpan->fqdir->timeout;
385 385
386 hdr = register_net_sysctl(net, "net/ieee802154/6lowpan", table); 386 hdr = register_net_sysctl(net, "net/ieee802154/6lowpan", table);
387 if (hdr == NULL) 387 if (hdr == NULL)
@@ -449,16 +449,18 @@ static int __net_init lowpan_frags_init_net(struct net *net)
449 net_ieee802154_lowpan(net); 449 net_ieee802154_lowpan(net);
450 int res; 450 int res;
451 451
452 ieee802154_lowpan->fqdir.high_thresh = IPV6_FRAG_HIGH_THRESH;
453 ieee802154_lowpan->fqdir.low_thresh = IPV6_FRAG_LOW_THRESH;
454 ieee802154_lowpan->fqdir.timeout = IPV6_FRAG_TIMEOUT;
455 452
456 res = fqdir_init(&ieee802154_lowpan->fqdir, &lowpan_frags, net); 453 res = fqdir_init(&ieee802154_lowpan->fqdir, &lowpan_frags, net);
457 if (res < 0) 454 if (res < 0)
458 return res; 455 return res;
456
457 ieee802154_lowpan->fqdir->high_thresh = IPV6_FRAG_HIGH_THRESH;
458 ieee802154_lowpan->fqdir->low_thresh = IPV6_FRAG_LOW_THRESH;
459 ieee802154_lowpan->fqdir->timeout = IPV6_FRAG_TIMEOUT;
460
459 res = lowpan_frags_ns_sysctl_register(net); 461 res = lowpan_frags_ns_sysctl_register(net);
460 if (res < 0) 462 if (res < 0)
461 fqdir_exit(&ieee802154_lowpan->fqdir); 463 fqdir_exit(ieee802154_lowpan->fqdir);
462 return res; 464 return res;
463} 465}
464 466
@@ -468,7 +470,7 @@ static void __net_exit lowpan_frags_exit_net(struct net *net)
468 net_ieee802154_lowpan(net); 470 net_ieee802154_lowpan(net);
469 471
470 lowpan_frags_ns_sysctl_unregister(net); 472 lowpan_frags_ns_sysctl_unregister(net);
471 fqdir_exit(&ieee802154_lowpan->fqdir); 473 fqdir_exit(ieee802154_lowpan->fqdir);
472} 474}
473 475
474static struct pernet_operations lowpan_frags_ops = { 476static struct pernet_operations lowpan_frags_ops = {
diff --git a/net/ipv4/inet_fragment.c b/net/ipv4/inet_fragment.c
index a5ec5d956793..b4432f209c71 100644
--- a/net/ipv4/inet_fragment.c
+++ b/net/ipv4/inet_fragment.c
@@ -150,6 +150,7 @@ void fqdir_exit(struct fqdir *fqdir)
150 fqdir->high_thresh = 0; /* prevent creation of new frags */ 150 fqdir->high_thresh = 0; /* prevent creation of new frags */
151 151
152 rhashtable_free_and_destroy(&fqdir->rhashtable, inet_frags_free_cb, NULL); 152 rhashtable_free_and_destroy(&fqdir->rhashtable, inet_frags_free_cb, NULL);
153 kfree(fqdir);
153} 154}
154EXPORT_SYMBOL(fqdir_exit); 155EXPORT_SYMBOL(fqdir_exit);
155 156
diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c
index d59269bbe1b6..1ffaec056821 100644
--- a/net/ipv4/ip_fragment.c
+++ b/net/ipv4/ip_fragment.c
@@ -209,7 +209,7 @@ static struct ipq *ip_find(struct net *net, struct iphdr *iph,
209 }; 209 };
210 struct inet_frag_queue *q; 210 struct inet_frag_queue *q;
211 211
212 q = inet_frag_find(&net->ipv4.fqdir, &key); 212 q = inet_frag_find(net->ipv4.fqdir, &key);
213 if (!q) 213 if (!q)
214 return NULL; 214 return NULL;
215 215
@@ -589,12 +589,12 @@ static int __net_init ip4_frags_ns_ctl_register(struct net *net)
589 goto err_alloc; 589 goto err_alloc;
590 590
591 } 591 }
592 table[0].data = &net->ipv4.fqdir.high_thresh; 592 table[0].data = &net->ipv4.fqdir->high_thresh;
593 table[0].extra1 = &net->ipv4.fqdir.low_thresh; 593 table[0].extra1 = &net->ipv4.fqdir->low_thresh;
594 table[1].data = &net->ipv4.fqdir.low_thresh; 594 table[1].data = &net->ipv4.fqdir->low_thresh;
595 table[1].extra2 = &net->ipv4.fqdir.high_thresh; 595 table[1].extra2 = &net->ipv4.fqdir->high_thresh;
596 table[2].data = &net->ipv4.fqdir.timeout; 596 table[2].data = &net->ipv4.fqdir->timeout;
597 table[3].data = &net->ipv4.fqdir.max_dist; 597 table[3].data = &net->ipv4.fqdir->max_dist;
598 598
599 hdr = register_net_sysctl(net, "net/ipv4", table); 599 hdr = register_net_sysctl(net, "net/ipv4", table);
600 if (!hdr) 600 if (!hdr)
@@ -642,6 +642,9 @@ static int __net_init ipv4_frags_init_net(struct net *net)
642{ 642{
643 int res; 643 int res;
644 644
645 res = fqdir_init(&net->ipv4.fqdir, &ip4_frags, net);
646 if (res < 0)
647 return res;
645 /* Fragment cache limits. 648 /* Fragment cache limits.
646 * 649 *
647 * The fragment memory accounting code, (tries to) account for 650 * The fragment memory accounting code, (tries to) account for
@@ -656,30 +659,27 @@ static int __net_init ipv4_frags_init_net(struct net *net)
656 * we will prune down to 3MB, making room for approx 8 big 64K 659 * we will prune down to 3MB, making room for approx 8 big 64K
657 * fragments 8x128k. 660 * fragments 8x128k.
658 */ 661 */
659 net->ipv4.fqdir.high_thresh = 4 * 1024 * 1024; 662 net->ipv4.fqdir->high_thresh = 4 * 1024 * 1024;
660 net->ipv4.fqdir.low_thresh = 3 * 1024 * 1024; 663 net->ipv4.fqdir->low_thresh = 3 * 1024 * 1024;
661 /* 664 /*
662 * Important NOTE! Fragment queue must be destroyed before MSL expires. 665 * Important NOTE! Fragment queue must be destroyed before MSL expires.
663 * RFC791 is wrong proposing to prolongate timer each fragment arrival 666 * RFC791 is wrong proposing to prolongate timer each fragment arrival
664 * by TTL. 667 * by TTL.
665 */ 668 */
666 net->ipv4.fqdir.timeout = IP_FRAG_TIME; 669 net->ipv4.fqdir->timeout = IP_FRAG_TIME;
667 670
668 net->ipv4.fqdir.max_dist = 64; 671 net->ipv4.fqdir->max_dist = 64;
669 672
670 res = fqdir_init(&net->ipv4.fqdir, &ip4_frags, net);
671 if (res < 0)
672 return res;
673 res = ip4_frags_ns_ctl_register(net); 673 res = ip4_frags_ns_ctl_register(net);
674 if (res < 0) 674 if (res < 0)
675 fqdir_exit(&net->ipv4.fqdir); 675 fqdir_exit(net->ipv4.fqdir);
676 return res; 676 return res;
677} 677}
678 678
679static void __net_exit ipv4_frags_exit_net(struct net *net) 679static void __net_exit ipv4_frags_exit_net(struct net *net)
680{ 680{
681 ip4_frags_ns_ctl_unregister(net); 681 ip4_frags_ns_ctl_unregister(net);
682 fqdir_exit(&net->ipv4.fqdir); 682 fqdir_exit(net->ipv4.fqdir);
683} 683}
684 684
685static struct pernet_operations ip4_frags_ops = { 685static struct pernet_operations ip4_frags_ops = {
diff --git a/net/ipv4/proc.c b/net/ipv4/proc.c
index 3927e00084e8..b613572c6616 100644
--- a/net/ipv4/proc.c
+++ b/net/ipv4/proc.c
@@ -72,8 +72,8 @@ static int sockstat_seq_show(struct seq_file *seq, void *v)
72 seq_printf(seq, "RAW: inuse %d\n", 72 seq_printf(seq, "RAW: inuse %d\n",
73 sock_prot_inuse_get(net, &raw_prot)); 73 sock_prot_inuse_get(net, &raw_prot));
74 seq_printf(seq, "FRAG: inuse %u memory %lu\n", 74 seq_printf(seq, "FRAG: inuse %u memory %lu\n",
75 atomic_read(&net->ipv4.fqdir.rhashtable.nelems), 75 atomic_read(&net->ipv4.fqdir->rhashtable.nelems),
76 frag_mem_limit(&net->ipv4.fqdir)); 76 frag_mem_limit(net->ipv4.fqdir));
77 return 0; 77 return 0;
78} 78}
79 79
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)
90 goto err_alloc; 90 goto err_alloc;
91 } 91 }
92 92
93 table[0].data = &net->nf_frag.fqdir.timeout; 93 table[0].data = &net->nf_frag.fqdir->timeout;
94 table[1].data = &net->nf_frag.fqdir.low_thresh; 94 table[1].data = &net->nf_frag.fqdir->low_thresh;
95 table[1].extra2 = &net->nf_frag.fqdir.high_thresh; 95 table[1].extra2 = &net->nf_frag.fqdir->high_thresh;
96 table[2].data = &net->nf_frag.fqdir.high_thresh; 96 table[2].data = &net->nf_frag.fqdir->high_thresh;
97 table[2].extra1 = &net->nf_frag.fqdir.low_thresh; 97 table[2].extra1 = &net->nf_frag.fqdir->low_thresh;
98 table[2].extra2 = &init_net.nf_frag.fqdir.high_thresh; 98 table[2].extra2 = &init_net.nf_frag.fqdir->high_thresh;
99 99
100 hdr = register_net_sysctl(net, "net/netfilter", table); 100 hdr = register_net_sysctl(net, "net/netfilter", table);
101 if (hdr == NULL) 101 if (hdr == NULL)
@@ -162,7 +162,7 @@ static struct frag_queue *fq_find(struct net *net, __be32 id, u32 user,
162 }; 162 };
163 struct inet_frag_queue *q; 163 struct inet_frag_queue *q;
164 164
165 q = inet_frag_find(&net->nf_frag.fqdir, &key); 165 q = inet_frag_find(net->nf_frag.fqdir, &key);
166 if (!q) 166 if (!q)
167 return NULL; 167 return NULL;
168 168
@@ -489,23 +489,24 @@ static int nf_ct_net_init(struct net *net)
489{ 489{
490 int res; 490 int res;
491 491
492 net->nf_frag.fqdir.high_thresh = IPV6_FRAG_HIGH_THRESH;
493 net->nf_frag.fqdir.low_thresh = IPV6_FRAG_LOW_THRESH;
494 net->nf_frag.fqdir.timeout = IPV6_FRAG_TIMEOUT;
495
496 res = fqdir_init(&net->nf_frag.fqdir, &nf_frags, net); 492 res = fqdir_init(&net->nf_frag.fqdir, &nf_frags, net);
497 if (res < 0) 493 if (res < 0)
498 return res; 494 return res;
495
496 net->nf_frag.fqdir->high_thresh = IPV6_FRAG_HIGH_THRESH;
497 net->nf_frag.fqdir->low_thresh = IPV6_FRAG_LOW_THRESH;
498 net->nf_frag.fqdir->timeout = IPV6_FRAG_TIMEOUT;
499
499 res = nf_ct_frag6_sysctl_register(net); 500 res = nf_ct_frag6_sysctl_register(net);
500 if (res < 0) 501 if (res < 0)
501 fqdir_exit(&net->nf_frag.fqdir); 502 fqdir_exit(net->nf_frag.fqdir);
502 return res; 503 return res;
503} 504}
504 505
505static void nf_ct_net_exit(struct net *net) 506static void nf_ct_net_exit(struct net *net)
506{ 507{
507 nf_ct_frags6_sysctl_unregister(net); 508 nf_ct_frags6_sysctl_unregister(net);
508 fqdir_exit(&net->nf_frag.fqdir); 509 fqdir_exit(net->nf_frag.fqdir);
509} 510}
510 511
511static struct pernet_operations nf_ct_net_ops = { 512static 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)
48 seq_printf(seq, "RAW6: inuse %d\n", 48 seq_printf(seq, "RAW6: inuse %d\n",
49 sock_prot_inuse_get(net, &rawv6_prot)); 49 sock_prot_inuse_get(net, &rawv6_prot));
50 seq_printf(seq, "FRAG6: inuse %u memory %lu\n", 50 seq_printf(seq, "FRAG6: inuse %u memory %lu\n",
51 atomic_read(&net->ipv6.fqdir.rhashtable.nelems), 51 atomic_read(&net->ipv6.fqdir->rhashtable.nelems),
52 frag_mem_limit(&net->ipv6.fqdir)); 52 frag_mem_limit(net->ipv6.fqdir));
53 return 0; 53 return 0;
54} 54}
55 55
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)
98 IPV6_ADDR_LINKLOCAL))) 98 IPV6_ADDR_LINKLOCAL)))
99 key.iif = 0; 99 key.iif = 0;
100 100
101 q = inet_frag_find(&net->ipv6.fqdir, &key); 101 q = inet_frag_find(net->ipv6.fqdir, &key);
102 if (!q) 102 if (!q)
103 return NULL; 103 return NULL;
104 104
@@ -443,11 +443,11 @@ static int __net_init ip6_frags_ns_sysctl_register(struct net *net)
443 goto err_alloc; 443 goto err_alloc;
444 444
445 } 445 }
446 table[0].data = &net->ipv6.fqdir.high_thresh; 446 table[0].data = &net->ipv6.fqdir->high_thresh;
447 table[0].extra1 = &net->ipv6.fqdir.low_thresh; 447 table[0].extra1 = &net->ipv6.fqdir->low_thresh;
448 table[1].data = &net->ipv6.fqdir.low_thresh; 448 table[1].data = &net->ipv6.fqdir->low_thresh;
449 table[1].extra2 = &net->ipv6.fqdir.high_thresh; 449 table[1].extra2 = &net->ipv6.fqdir->high_thresh;
450 table[2].data = &net->ipv6.fqdir.timeout; 450 table[2].data = &net->ipv6.fqdir->timeout;
451 451
452 hdr = register_net_sysctl(net, "net/ipv6", table); 452 hdr = register_net_sysctl(net, "net/ipv6", table);
453 if (!hdr) 453 if (!hdr)
@@ -510,24 +510,24 @@ static int __net_init ipv6_frags_init_net(struct net *net)
510{ 510{
511 int res; 511 int res;
512 512
513 net->ipv6.fqdir.high_thresh = IPV6_FRAG_HIGH_THRESH;
514 net->ipv6.fqdir.low_thresh = IPV6_FRAG_LOW_THRESH;
515 net->ipv6.fqdir.timeout = IPV6_FRAG_TIMEOUT;
516
517 res = fqdir_init(&net->ipv6.fqdir, &ip6_frags, net); 513 res = fqdir_init(&net->ipv6.fqdir, &ip6_frags, net);
518 if (res < 0) 514 if (res < 0)
519 return res; 515 return res;
520 516
517 net->ipv6.fqdir->high_thresh = IPV6_FRAG_HIGH_THRESH;
518 net->ipv6.fqdir->low_thresh = IPV6_FRAG_LOW_THRESH;
519 net->ipv6.fqdir->timeout = IPV6_FRAG_TIMEOUT;
520
521 res = ip6_frags_ns_sysctl_register(net); 521 res = ip6_frags_ns_sysctl_register(net);
522 if (res < 0) 522 if (res < 0)
523 fqdir_exit(&net->ipv6.fqdir); 523 fqdir_exit(net->ipv6.fqdir);
524 return res; 524 return res;
525} 525}
526 526
527static void __net_exit ipv6_frags_exit_net(struct net *net) 527static void __net_exit ipv6_frags_exit_net(struct net *net)
528{ 528{
529 ip6_frags_ns_sysctl_unregister(net); 529 ip6_frags_ns_sysctl_unregister(net);
530 fqdir_exit(&net->ipv6.fqdir); 530 fqdir_exit(net->ipv6.fqdir);
531} 531}
532 532
533static struct pernet_operations ip6_frags_ops = { 533static struct pernet_operations ip6_frags_ops = {