aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/netns/conntrack.h4
-rw-r--r--net/netfilter/nf_conntrack_standalone.c73
2 files changed, 45 insertions, 32 deletions
diff --git a/include/net/netns/conntrack.h b/include/net/netns/conntrack.h
index fc0a46d64cc9..2b50758df6a1 100644
--- a/include/net/netns/conntrack.h
+++ b/include/net/netns/conntrack.h
@@ -4,6 +4,7 @@
4#include <linux/list.h> 4#include <linux/list.h>
5#include <asm/atomic.h> 5#include <asm/atomic.h>
6 6
7struct ctl_table_header;
7struct nf_conntrack_ecache; 8struct nf_conntrack_ecache;
8 9
9struct netns_ct { 10struct netns_ct {
@@ -16,6 +17,9 @@ struct netns_ct {
16#ifdef CONFIG_NF_CONNTRACK_EVENTS 17#ifdef CONFIG_NF_CONNTRACK_EVENTS
17 struct nf_conntrack_ecache *ecache; 18 struct nf_conntrack_ecache *ecache;
18#endif 19#endif
20#ifdef CONFIG_SYSCTL
21 struct ctl_table_header *sysctl_header;
22#endif
19 int hash_vmalloc; 23 int hash_vmalloc;
20 int expect_vmalloc; 24 int expect_vmalloc;
21}; 25};
diff --git a/net/netfilter/nf_conntrack_standalone.c b/net/netfilter/nf_conntrack_standalone.c
index 169760ddc16b..64b4f95b367e 100644
--- a/net/netfilter/nf_conntrack_standalone.c
+++ b/net/netfilter/nf_conntrack_standalone.c
@@ -330,7 +330,6 @@ EXPORT_SYMBOL_GPL(nf_conntrack_checksum);
330static int log_invalid_proto_min = 0; 330static int log_invalid_proto_min = 0;
331static int log_invalid_proto_max = 255; 331static int log_invalid_proto_max = 255;
332 332
333static struct ctl_table_header *nf_ct_sysctl_header;
334static struct ctl_table_header *nf_ct_netfilter_header; 333static struct ctl_table_header *nf_ct_netfilter_header;
335 334
336static ctl_table nf_ct_sysctl_table[] = { 335static ctl_table nf_ct_sysctl_table[] = {
@@ -409,40 +408,58 @@ static struct ctl_path nf_ct_path[] = {
409 408
410EXPORT_SYMBOL_GPL(nf_ct_log_invalid); 409EXPORT_SYMBOL_GPL(nf_ct_log_invalid);
411 410
412static int nf_conntrack_standalone_init_sysctl(void) 411static int nf_conntrack_standalone_init_sysctl(struct net *net)
413{ 412{
414 nf_ct_netfilter_header = 413 struct ctl_table *table;
415 register_sysctl_paths(nf_ct_path, nf_ct_netfilter_table); 414
416 if (!nf_ct_netfilter_header) 415 if (net_eq(net, &init_net)) {
417 goto out; 416 nf_ct_netfilter_header =
418 417 register_sysctl_paths(nf_ct_path, nf_ct_netfilter_table);
419 nf_ct_sysctl_header = 418 if (!nf_ct_netfilter_header)
420 register_sysctl_paths(nf_net_netfilter_sysctl_path, 419 goto out;
421 nf_ct_sysctl_table); 420 }
422 if (!nf_ct_sysctl_header) 421
422 table = kmemdup(nf_ct_sysctl_table, sizeof(nf_ct_sysctl_table),
423 GFP_KERNEL);
424 if (!table)
425 goto out_kmemdup;
426
427 table[1].data = &net->ct.count;
428
429 net->ct.sysctl_header = register_net_sysctl_table(net,
430 nf_net_netfilter_sysctl_path, table);
431 if (!net->ct.sysctl_header)
423 goto out_unregister_netfilter; 432 goto out_unregister_netfilter;
424 433
425 return 0; 434 return 0;
426 435
427out_unregister_netfilter: 436out_unregister_netfilter:
428 unregister_sysctl_table(nf_ct_netfilter_header); 437 kfree(table);
438out_kmemdup:
439 if (net_eq(net, &init_net))
440 unregister_sysctl_table(nf_ct_netfilter_header);
429out: 441out:
430 printk("nf_conntrack: can't register to sysctl.\n"); 442 printk("nf_conntrack: can't register to sysctl.\n");
431 return -ENOMEM; 443 return -ENOMEM;
432} 444}
433 445
434static void nf_conntrack_standalone_fini_sysctl(void) 446static void nf_conntrack_standalone_fini_sysctl(struct net *net)
435{ 447{
436 unregister_sysctl_table(nf_ct_netfilter_header); 448 struct ctl_table *table;
437 unregister_sysctl_table(nf_ct_sysctl_header); 449
450 if (net_eq(net, &init_net))
451 unregister_sysctl_table(nf_ct_netfilter_header);
452 table = net->ct.sysctl_header->ctl_table_arg;
453 unregister_net_sysctl_table(net->ct.sysctl_header);
454 kfree(table);
438} 455}
439#else 456#else
440static int nf_conntrack_standalone_init_sysctl(void) 457static int nf_conntrack_standalone_init_sysctl(struct net *net)
441{ 458{
442 return 0; 459 return 0;
443} 460}
444 461
445static void nf_conntrack_standalone_fini_sysctl(void) 462static void nf_conntrack_standalone_fini_sysctl(struct net *net)
446{ 463{
447} 464}
448#endif /* CONFIG_SYSCTL */ 465#endif /* CONFIG_SYSCTL */
@@ -457,8 +474,13 @@ static int nf_conntrack_net_init(struct net *net)
457 ret = nf_conntrack_standalone_init_proc(net); 474 ret = nf_conntrack_standalone_init_proc(net);
458 if (ret < 0) 475 if (ret < 0)
459 goto out_proc; 476 goto out_proc;
477 ret = nf_conntrack_standalone_init_sysctl(net);
478 if (ret < 0)
479 goto out_sysctl;
460 return 0; 480 return 0;
461 481
482out_sysctl:
483 nf_conntrack_standalone_fini_proc(net);
462out_proc: 484out_proc:
463 nf_conntrack_cleanup(net); 485 nf_conntrack_cleanup(net);
464out_init: 486out_init:
@@ -467,6 +489,7 @@ out_init:
467 489
468static void nf_conntrack_net_exit(struct net *net) 490static void nf_conntrack_net_exit(struct net *net)
469{ 491{
492 nf_conntrack_standalone_fini_sysctl(net);
470 nf_conntrack_standalone_fini_proc(net); 493 nf_conntrack_standalone_fini_proc(net);
471 nf_conntrack_cleanup(net); 494 nf_conntrack_cleanup(net);
472} 495}
@@ -478,25 +501,11 @@ static struct pernet_operations nf_conntrack_net_ops = {
478 501
479static int __init nf_conntrack_standalone_init(void) 502static int __init nf_conntrack_standalone_init(void)
480{ 503{
481 int ret; 504 return register_pernet_subsys(&nf_conntrack_net_ops);
482
483 ret = register_pernet_subsys(&nf_conntrack_net_ops);
484 if (ret < 0)
485 goto out;
486 ret = nf_conntrack_standalone_init_sysctl();
487 if (ret < 0)
488 goto out_sysctl;
489 return 0;
490
491out_sysctl:
492 unregister_pernet_subsys(&nf_conntrack_net_ops);
493out:
494 return ret;
495} 505}
496 506
497static void __exit nf_conntrack_standalone_fini(void) 507static void __exit nf_conntrack_standalone_fini(void)
498{ 508{
499 nf_conntrack_standalone_fini_sysctl();
500 unregister_pernet_subsys(&nf_conntrack_net_ops); 509 unregister_pernet_subsys(&nf_conntrack_net_ops);
501} 510}
502 511