diff options
-rw-r--r-- | include/net/netns/conntrack.h | 4 | ||||
-rw-r--r-- | net/netfilter/nf_conntrack_standalone.c | 73 |
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 | ||
7 | struct ctl_table_header; | ||
7 | struct nf_conntrack_ecache; | 8 | struct nf_conntrack_ecache; |
8 | 9 | ||
9 | struct netns_ct { | 10 | struct 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); | |||
330 | static int log_invalid_proto_min = 0; | 330 | static int log_invalid_proto_min = 0; |
331 | static int log_invalid_proto_max = 255; | 331 | static int log_invalid_proto_max = 255; |
332 | 332 | ||
333 | static struct ctl_table_header *nf_ct_sysctl_header; | ||
334 | static struct ctl_table_header *nf_ct_netfilter_header; | 333 | static struct ctl_table_header *nf_ct_netfilter_header; |
335 | 334 | ||
336 | static ctl_table nf_ct_sysctl_table[] = { | 335 | static ctl_table nf_ct_sysctl_table[] = { |
@@ -409,40 +408,58 @@ static struct ctl_path nf_ct_path[] = { | |||
409 | 408 | ||
410 | EXPORT_SYMBOL_GPL(nf_ct_log_invalid); | 409 | EXPORT_SYMBOL_GPL(nf_ct_log_invalid); |
411 | 410 | ||
412 | static int nf_conntrack_standalone_init_sysctl(void) | 411 | static 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 | ||
427 | out_unregister_netfilter: | 436 | out_unregister_netfilter: |
428 | unregister_sysctl_table(nf_ct_netfilter_header); | 437 | kfree(table); |
438 | out_kmemdup: | ||
439 | if (net_eq(net, &init_net)) | ||
440 | unregister_sysctl_table(nf_ct_netfilter_header); | ||
429 | out: | 441 | out: |
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 | ||
434 | static void nf_conntrack_standalone_fini_sysctl(void) | 446 | static 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 |
440 | static int nf_conntrack_standalone_init_sysctl(void) | 457 | static int nf_conntrack_standalone_init_sysctl(struct net *net) |
441 | { | 458 | { |
442 | return 0; | 459 | return 0; |
443 | } | 460 | } |
444 | 461 | ||
445 | static void nf_conntrack_standalone_fini_sysctl(void) | 462 | static 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 | ||
482 | out_sysctl: | ||
483 | nf_conntrack_standalone_fini_proc(net); | ||
462 | out_proc: | 484 | out_proc: |
463 | nf_conntrack_cleanup(net); | 485 | nf_conntrack_cleanup(net); |
464 | out_init: | 486 | out_init: |
@@ -467,6 +489,7 @@ out_init: | |||
467 | 489 | ||
468 | static void nf_conntrack_net_exit(struct net *net) | 490 | static 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 | ||
479 | static int __init nf_conntrack_standalone_init(void) | 502 | static 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 | |||
491 | out_sysctl: | ||
492 | unregister_pernet_subsys(&nf_conntrack_net_ops); | ||
493 | out: | ||
494 | return ret; | ||
495 | } | 505 | } |
496 | 506 | ||
497 | static void __exit nf_conntrack_standalone_fini(void) | 507 | static 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 | ||