aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2013-01-27 00:56:10 -0500
committerDavid S. Miller <davem@davemloft.net>2013-01-27 00:56:10 -0500
commitb640bee6d9bb2e4ab803d1b1a119d271434ad960 (patch)
tree569900a59bbc4decf36dc48f51a0d67b5e9bac0d /net
parent93b9c1ddd3fb4a5b67d512e534b30070f9ecec28 (diff)
parent5f9f946b39bff31bc9a4a8be18cef3354d3382ae (diff)
Merge branch 'master' of git://1984.lsi.us.es/nf-next
Pablo Neira Ayuso says: ==================== This batch contains netfilter updates for you net-next tree, they are: * The new connlabel extension for x_tables, that allows us to attach labels to each conntrack flow. The kernel implementation uses a bitmask and there's a file in user-space that maps the bits with the corresponding string for each existing label. By now, you can attach up to 128 overlapping labels. From Florian Westphal. * A new round of improvements for the netns support for conntrack. Gao feng has moved many of the initialization code of each module of the netns init path. He also made several code refactoring, that code looks cleaner to me now. * Added documentation for all possible tweaks for nf_conntrack via sysctl, from Jiri Pirko. * Cisco 7941/7945 IP phone support for our SIP conntrack helper, from Kevin Cernekee. * Missing header file in the snmp helper, from Stephen Hemminger. * Finally, a couple of fixes to resolve minor issues with these changes, from myself. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r--net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c82
-rw-r--r--net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c86
-rw-r--r--net/netfilter/Kconfig27
-rw-r--r--net/netfilter/Makefile3
-rw-r--r--net/netfilter/nf_conntrack_acct.c36
-rw-r--r--net/netfilter/nf_conntrack_core.c191
-rw-r--r--net/netfilter/nf_conntrack_ecache.c37
-rw-r--r--net/netfilter/nf_conntrack_expect.c53
-rw-r--r--net/netfilter/nf_conntrack_helper.c53
-rw-r--r--net/netfilter/nf_conntrack_labels.c112
-rw-r--r--net/netfilter/nf_conntrack_netlink.c88
-rw-r--r--net/netfilter/nf_conntrack_proto.c92
-rw-r--r--net/netfilter/nf_conntrack_proto_dccp.c43
-rw-r--r--net/netfilter/nf_conntrack_proto_gre.c23
-rw-r--r--net/netfilter/nf_conntrack_proto_sctp.c43
-rw-r--r--net/netfilter/nf_conntrack_proto_udplite.c40
-rw-r--r--net/netfilter/nf_conntrack_sip.c17
-rw-r--r--net/netfilter/nf_conntrack_snmp.c1
-rw-r--r--net/netfilter/nf_conntrack_standalone.c63
-rw-r--r--net/netfilter/nf_conntrack_timeout.c23
-rw-r--r--net/netfilter/nf_conntrack_timestamp.c39
-rw-r--r--net/netfilter/nf_nat_sip.c27
-rw-r--r--net/netfilter/xt_bpf.c73
-rw-r--r--net/netfilter/xt_connlabel.c99
24 files changed, 950 insertions, 401 deletions
diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
index fcdd0c2406e6..48990ada0e1e 100644
--- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
+++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
@@ -420,54 +420,43 @@ static int ipv4_net_init(struct net *net)
420{ 420{
421 int ret = 0; 421 int ret = 0;
422 422
423 ret = nf_conntrack_l4proto_register(net, 423 ret = nf_ct_l4proto_pernet_register(net, &nf_conntrack_l4proto_tcp4);
424 &nf_conntrack_l4proto_tcp4);
425 if (ret < 0) { 424 if (ret < 0) {
426 pr_err("nf_conntrack_l4proto_tcp4 :protocol register failed\n"); 425 pr_err("nf_conntrack_tcp4: pernet registration failed\n");
427 goto out_tcp; 426 goto out_tcp;
428 } 427 }
429 ret = nf_conntrack_l4proto_register(net, 428 ret = nf_ct_l4proto_pernet_register(net, &nf_conntrack_l4proto_udp4);
430 &nf_conntrack_l4proto_udp4);
431 if (ret < 0) { 429 if (ret < 0) {
432 pr_err("nf_conntrack_l4proto_udp4 :protocol register failed\n"); 430 pr_err("nf_conntrack_udp4: pernet registration failed\n");
433 goto out_udp; 431 goto out_udp;
434 } 432 }
435 ret = nf_conntrack_l4proto_register(net, 433 ret = nf_ct_l4proto_pernet_register(net, &nf_conntrack_l4proto_icmp);
436 &nf_conntrack_l4proto_icmp);
437 if (ret < 0) { 434 if (ret < 0) {
438 pr_err("nf_conntrack_l4proto_icmp4 :protocol register failed\n"); 435 pr_err("nf_conntrack_icmp4: pernet registration failed\n");
439 goto out_icmp; 436 goto out_icmp;
440 } 437 }
441 ret = nf_conntrack_l3proto_register(net, 438 ret = nf_ct_l3proto_pernet_register(net, &nf_conntrack_l3proto_ipv4);
442 &nf_conntrack_l3proto_ipv4);
443 if (ret < 0) { 439 if (ret < 0) {
444 pr_err("nf_conntrack_l3proto_ipv4 :protocol register failed\n"); 440 pr_err("nf_conntrack_ipv4: pernet registration failed\n");
445 goto out_ipv4; 441 goto out_ipv4;
446 } 442 }
447 return 0; 443 return 0;
448out_ipv4: 444out_ipv4:
449 nf_conntrack_l4proto_unregister(net, 445 nf_ct_l4proto_pernet_unregister(net, &nf_conntrack_l4proto_icmp);
450 &nf_conntrack_l4proto_icmp);
451out_icmp: 446out_icmp:
452 nf_conntrack_l4proto_unregister(net, 447 nf_ct_l4proto_pernet_unregister(net, &nf_conntrack_l4proto_udp4);
453 &nf_conntrack_l4proto_udp4);
454out_udp: 448out_udp:
455 nf_conntrack_l4proto_unregister(net, 449 nf_ct_l4proto_pernet_unregister(net, &nf_conntrack_l4proto_tcp4);
456 &nf_conntrack_l4proto_tcp4);
457out_tcp: 450out_tcp:
458 return ret; 451 return ret;
459} 452}
460 453
461static void ipv4_net_exit(struct net *net) 454static void ipv4_net_exit(struct net *net)
462{ 455{
463 nf_conntrack_l3proto_unregister(net, 456 nf_ct_l3proto_pernet_unregister(net, &nf_conntrack_l3proto_ipv4);
464 &nf_conntrack_l3proto_ipv4); 457 nf_ct_l4proto_pernet_unregister(net, &nf_conntrack_l4proto_icmp);
465 nf_conntrack_l4proto_unregister(net, 458 nf_ct_l4proto_pernet_unregister(net, &nf_conntrack_l4proto_udp4);
466 &nf_conntrack_l4proto_icmp); 459 nf_ct_l4proto_pernet_unregister(net, &nf_conntrack_l4proto_tcp4);
467 nf_conntrack_l4proto_unregister(net,
468 &nf_conntrack_l4proto_udp4);
469 nf_conntrack_l4proto_unregister(net,
470 &nf_conntrack_l4proto_tcp4);
471} 460}
472 461
473static struct pernet_operations ipv4_net_ops = { 462static struct pernet_operations ipv4_net_ops = {
@@ -500,16 +489,49 @@ static int __init nf_conntrack_l3proto_ipv4_init(void)
500 pr_err("nf_conntrack_ipv4: can't register hooks.\n"); 489 pr_err("nf_conntrack_ipv4: can't register hooks.\n");
501 goto cleanup_pernet; 490 goto cleanup_pernet;
502 } 491 }
492
493 ret = nf_ct_l4proto_register(&nf_conntrack_l4proto_tcp4);
494 if (ret < 0) {
495 pr_err("nf_conntrack_ipv4: can't register tcp4 proto.\n");
496 goto cleanup_hooks;
497 }
498
499 ret = nf_ct_l4proto_register(&nf_conntrack_l4proto_udp4);
500 if (ret < 0) {
501 pr_err("nf_conntrack_ipv4: can't register udp4 proto.\n");
502 goto cleanup_tcp4;
503 }
504
505 ret = nf_ct_l4proto_register(&nf_conntrack_l4proto_icmp);
506 if (ret < 0) {
507 pr_err("nf_conntrack_ipv4: can't register icmpv4 proto.\n");
508 goto cleanup_udp4;
509 }
510
511 ret = nf_ct_l3proto_register(&nf_conntrack_l3proto_ipv4);
512 if (ret < 0) {
513 pr_err("nf_conntrack_ipv4: can't register ipv4 proto.\n");
514 goto cleanup_icmpv4;
515 }
516
503#if defined(CONFIG_PROC_FS) && defined(CONFIG_NF_CONNTRACK_PROC_COMPAT) 517#if defined(CONFIG_PROC_FS) && defined(CONFIG_NF_CONNTRACK_PROC_COMPAT)
504 ret = nf_conntrack_ipv4_compat_init(); 518 ret = nf_conntrack_ipv4_compat_init();
505 if (ret < 0) 519 if (ret < 0)
506 goto cleanup_hooks; 520 goto cleanup_proto;
507#endif 521#endif
508 return ret; 522 return ret;
509#if defined(CONFIG_PROC_FS) && defined(CONFIG_NF_CONNTRACK_PROC_COMPAT) 523#if defined(CONFIG_PROC_FS) && defined(CONFIG_NF_CONNTRACK_PROC_COMPAT)
524 cleanup_proto:
525 nf_ct_l3proto_unregister(&nf_conntrack_l3proto_ipv4);
526#endif
527 cleanup_icmpv4:
528 nf_ct_l4proto_unregister(&nf_conntrack_l4proto_icmp);
529 cleanup_udp4:
530 nf_ct_l4proto_unregister(&nf_conntrack_l4proto_udp4);
531 cleanup_tcp4:
532 nf_ct_l4proto_unregister(&nf_conntrack_l4proto_tcp4);
510 cleanup_hooks: 533 cleanup_hooks:
511 nf_unregister_hooks(ipv4_conntrack_ops, ARRAY_SIZE(ipv4_conntrack_ops)); 534 nf_unregister_hooks(ipv4_conntrack_ops, ARRAY_SIZE(ipv4_conntrack_ops));
512#endif
513 cleanup_pernet: 535 cleanup_pernet:
514 unregister_pernet_subsys(&ipv4_net_ops); 536 unregister_pernet_subsys(&ipv4_net_ops);
515 cleanup_sockopt: 537 cleanup_sockopt:
@@ -523,6 +545,10 @@ static void __exit nf_conntrack_l3proto_ipv4_fini(void)
523#if defined(CONFIG_PROC_FS) && defined(CONFIG_NF_CONNTRACK_PROC_COMPAT) 545#if defined(CONFIG_PROC_FS) && defined(CONFIG_NF_CONNTRACK_PROC_COMPAT)
524 nf_conntrack_ipv4_compat_fini(); 546 nf_conntrack_ipv4_compat_fini();
525#endif 547#endif
548 nf_ct_l3proto_unregister(&nf_conntrack_l3proto_ipv4);
549 nf_ct_l4proto_unregister(&nf_conntrack_l4proto_icmp);
550 nf_ct_l4proto_unregister(&nf_conntrack_l4proto_udp4);
551 nf_ct_l4proto_unregister(&nf_conntrack_l4proto_tcp4);
526 nf_unregister_hooks(ipv4_conntrack_ops, ARRAY_SIZE(ipv4_conntrack_ops)); 552 nf_unregister_hooks(ipv4_conntrack_ops, ARRAY_SIZE(ipv4_conntrack_ops));
527 unregister_pernet_subsys(&ipv4_net_ops); 553 unregister_pernet_subsys(&ipv4_net_ops);
528 nf_unregister_sockopt(&so_getorigdst); 554 nf_unregister_sockopt(&so_getorigdst);
diff --git a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
index 137e245860ab..8a45bb20bedb 100644
--- a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
+++ b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
@@ -421,54 +421,43 @@ static int ipv6_net_init(struct net *net)
421{ 421{
422 int ret = 0; 422 int ret = 0;
423 423
424 ret = nf_conntrack_l4proto_register(net, 424 ret = nf_ct_l4proto_pernet_register(net, &nf_conntrack_l4proto_tcp6);
425 &nf_conntrack_l4proto_tcp6);
426 if (ret < 0) { 425 if (ret < 0) {
427 printk(KERN_ERR "nf_conntrack_l4proto_tcp6: protocol register failed\n"); 426 pr_err("nf_conntrack_tcp6: pernet registration failed\n");
428 goto out; 427 goto out;
429 } 428 }
430 ret = nf_conntrack_l4proto_register(net, 429 ret = nf_ct_l4proto_pernet_register(net, &nf_conntrack_l4proto_udp6);
431 &nf_conntrack_l4proto_udp6);
432 if (ret < 0) { 430 if (ret < 0) {
433 printk(KERN_ERR "nf_conntrack_l4proto_udp6: protocol register failed\n"); 431 pr_err("nf_conntrack_udp6: pernet registration failed\n");
434 goto cleanup_tcp6; 432 goto cleanup_tcp6;
435 } 433 }
436 ret = nf_conntrack_l4proto_register(net, 434 ret = nf_ct_l4proto_pernet_register(net, &nf_conntrack_l4proto_icmpv6);
437 &nf_conntrack_l4proto_icmpv6);
438 if (ret < 0) { 435 if (ret < 0) {
439 printk(KERN_ERR "nf_conntrack_l4proto_icmp6: protocol register failed\n"); 436 pr_err("nf_conntrack_icmp6: pernet registration failed\n");
440 goto cleanup_udp6; 437 goto cleanup_udp6;
441 } 438 }
442 ret = nf_conntrack_l3proto_register(net, 439 ret = nf_ct_l3proto_pernet_register(net, &nf_conntrack_l3proto_ipv6);
443 &nf_conntrack_l3proto_ipv6);
444 if (ret < 0) { 440 if (ret < 0) {
445 printk(KERN_ERR "nf_conntrack_l3proto_ipv6: protocol register failed\n"); 441 pr_err("nf_conntrack_ipv6: pernet registration failed.\n");
446 goto cleanup_icmpv6; 442 goto cleanup_icmpv6;
447 } 443 }
448 return 0; 444 return 0;
449 cleanup_icmpv6: 445 cleanup_icmpv6:
450 nf_conntrack_l4proto_unregister(net, 446 nf_ct_l4proto_pernet_unregister(net, &nf_conntrack_l4proto_icmpv6);
451 &nf_conntrack_l4proto_icmpv6);
452 cleanup_udp6: 447 cleanup_udp6:
453 nf_conntrack_l4proto_unregister(net, 448 nf_ct_l4proto_pernet_unregister(net, &nf_conntrack_l4proto_udp6);
454 &nf_conntrack_l4proto_udp6);
455 cleanup_tcp6: 449 cleanup_tcp6:
456 nf_conntrack_l4proto_unregister(net, 450 nf_ct_l4proto_pernet_unregister(net, &nf_conntrack_l4proto_tcp6);
457 &nf_conntrack_l4proto_tcp6);
458 out: 451 out:
459 return ret; 452 return ret;
460} 453}
461 454
462static void ipv6_net_exit(struct net *net) 455static void ipv6_net_exit(struct net *net)
463{ 456{
464 nf_conntrack_l3proto_unregister(net, 457 nf_ct_l3proto_pernet_unregister(net, &nf_conntrack_l3proto_ipv6);
465 &nf_conntrack_l3proto_ipv6); 458 nf_ct_l4proto_pernet_unregister(net, &nf_conntrack_l4proto_icmpv6);
466 nf_conntrack_l4proto_unregister(net, 459 nf_ct_l4proto_pernet_unregister(net, &nf_conntrack_l4proto_udp6);
467 &nf_conntrack_l4proto_icmpv6); 460 nf_ct_l4proto_pernet_unregister(net, &nf_conntrack_l4proto_tcp6);
468 nf_conntrack_l4proto_unregister(net,
469 &nf_conntrack_l4proto_udp6);
470 nf_conntrack_l4proto_unregister(net,
471 &nf_conntrack_l4proto_tcp6);
472} 461}
473 462
474static struct pernet_operations ipv6_net_ops = { 463static struct pernet_operations ipv6_net_ops = {
@@ -491,19 +480,52 @@ static int __init nf_conntrack_l3proto_ipv6_init(void)
491 480
492 ret = register_pernet_subsys(&ipv6_net_ops); 481 ret = register_pernet_subsys(&ipv6_net_ops);
493 if (ret < 0) 482 if (ret < 0)
494 goto cleanup_pernet; 483 goto cleanup_sockopt;
484
495 ret = nf_register_hooks(ipv6_conntrack_ops, 485 ret = nf_register_hooks(ipv6_conntrack_ops,
496 ARRAY_SIZE(ipv6_conntrack_ops)); 486 ARRAY_SIZE(ipv6_conntrack_ops));
497 if (ret < 0) { 487 if (ret < 0) {
498 pr_err("nf_conntrack_ipv6: can't register pre-routing defrag " 488 pr_err("nf_conntrack_ipv6: can't register pre-routing defrag "
499 "hook.\n"); 489 "hook.\n");
500 goto cleanup_ipv6; 490 goto cleanup_pernet;
491 }
492
493 ret = nf_ct_l4proto_register(&nf_conntrack_l4proto_tcp6);
494 if (ret < 0) {
495 pr_err("nf_conntrack_ipv6: can't register tcp6 proto.\n");
496 goto cleanup_hooks;
497 }
498
499 ret = nf_ct_l4proto_register(&nf_conntrack_l4proto_udp6);
500 if (ret < 0) {
501 pr_err("nf_conntrack_ipv6: can't register udp6 proto.\n");
502 goto cleanup_tcp6;
503 }
504
505 ret = nf_ct_l4proto_register(&nf_conntrack_l4proto_icmpv6);
506 if (ret < 0) {
507 pr_err("nf_conntrack_ipv6: can't register icmpv6 proto.\n");
508 goto cleanup_udp6;
509 }
510
511 ret = nf_ct_l3proto_register(&nf_conntrack_l3proto_ipv6);
512 if (ret < 0) {
513 pr_err("nf_conntrack_ipv6: can't register ipv6 proto.\n");
514 goto cleanup_icmpv6;
501 } 515 }
502 return ret; 516 return ret;
503 517
504 cleanup_ipv6: 518 cleanup_icmpv6:
505 unregister_pernet_subsys(&ipv6_net_ops); 519 nf_ct_l4proto_unregister(&nf_conntrack_l4proto_icmpv6);
520 cleanup_udp6:
521 nf_ct_l4proto_unregister(&nf_conntrack_l4proto_udp6);
522 cleanup_tcp6:
523 nf_ct_l4proto_unregister(&nf_conntrack_l4proto_tcp6);
524 cleanup_hooks:
525 nf_unregister_hooks(ipv6_conntrack_ops, ARRAY_SIZE(ipv6_conntrack_ops));
506 cleanup_pernet: 526 cleanup_pernet:
527 unregister_pernet_subsys(&ipv6_net_ops);
528 cleanup_sockopt:
507 nf_unregister_sockopt(&so_getorigdst6); 529 nf_unregister_sockopt(&so_getorigdst6);
508 return ret; 530 return ret;
509} 531}
@@ -511,6 +533,10 @@ static int __init nf_conntrack_l3proto_ipv6_init(void)
511static void __exit nf_conntrack_l3proto_ipv6_fini(void) 533static void __exit nf_conntrack_l3proto_ipv6_fini(void)
512{ 534{
513 synchronize_net(); 535 synchronize_net();
536 nf_ct_l3proto_unregister(&nf_conntrack_l3proto_ipv6);
537 nf_ct_l4proto_unregister(&nf_conntrack_l4proto_tcp6);
538 nf_ct_l4proto_unregister(&nf_conntrack_l4proto_udp6);
539 nf_ct_l4proto_unregister(&nf_conntrack_l4proto_icmpv6);
514 nf_unregister_hooks(ipv6_conntrack_ops, ARRAY_SIZE(ipv6_conntrack_ops)); 540 nf_unregister_hooks(ipv6_conntrack_ops, ARRAY_SIZE(ipv6_conntrack_ops));
515 unregister_pernet_subsys(&ipv6_net_ops); 541 unregister_pernet_subsys(&ipv6_net_ops);
516 nf_unregister_sockopt(&so_getorigdst6); 542 nf_unregister_sockopt(&so_getorigdst6);
diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
index 49e96df5fbc4..eb2c8ebf6d99 100644
--- a/net/netfilter/Kconfig
+++ b/net/netfilter/Kconfig
@@ -124,6 +124,12 @@ config NF_CONNTRACK_TIMESTAMP
124 124
125 If unsure, say `N'. 125 If unsure, say `N'.
126 126
127config NF_CONNTRACK_LABELS
128 bool
129 help
130 This option enables support for assigning user-defined flag bits
131 to connection tracking entries. It selected by the connlabel match.
132
127config NF_CT_PROTO_DCCP 133config NF_CT_PROTO_DCCP
128 tristate 'DCCP protocol connection tracking support (EXPERIMENTAL)' 134 tristate 'DCCP protocol connection tracking support (EXPERIMENTAL)'
129 depends on EXPERIMENTAL 135 depends on EXPERIMENTAL
@@ -805,6 +811,15 @@ config NETFILTER_XT_MATCH_ADDRTYPE
805 If you want to compile it as a module, say M here and read 811 If you want to compile it as a module, say M here and read
806 <file:Documentation/kbuild/modules.txt>. If unsure, say `N'. 812 <file:Documentation/kbuild/modules.txt>. If unsure, say `N'.
807 813
814config NETFILTER_XT_MATCH_BPF
815 tristate '"bpf" match support'
816 depends on NETFILTER_ADVANCED
817 help
818 BPF matching applies a linux socket filter to each packet and
819 accepts those for which the filter returns non-zero.
820
821 To compile it as a module, choose M here. If unsure, say N.
822
808config NETFILTER_XT_MATCH_CLUSTER 823config NETFILTER_XT_MATCH_CLUSTER
809 tristate '"cluster" match support' 824 tristate '"cluster" match support'
810 depends on NF_CONNTRACK 825 depends on NF_CONNTRACK
@@ -842,6 +857,18 @@ config NETFILTER_XT_MATCH_CONNBYTES
842 If you want to compile it as a module, say M here and read 857 If you want to compile it as a module, say M here and read
843 <file:Documentation/kbuild/modules.txt>. If unsure, say `N'. 858 <file:Documentation/kbuild/modules.txt>. If unsure, say `N'.
844 859
860config NETFILTER_XT_MATCH_CONNLABEL
861 tristate '"connlabel" match support'
862 select NF_CONNTRACK_LABELS
863 depends on NETFILTER_ADVANCED
864 ---help---
865 This match allows you to test and assign userspace-defined labels names
866 to a connection. The kernel only stores bit values - mapping
867 names to bits is done by userspace.
868
869 Unlike connmark, more than 32 flag bits may be assigned to a
870 connection simultaneously.
871
845config NETFILTER_XT_MATCH_CONNLIMIT 872config NETFILTER_XT_MATCH_CONNLIMIT
846 tristate '"connlimit" match support"' 873 tristate '"connlimit" match support"'
847 depends on NF_CONNTRACK 874 depends on NF_CONNTRACK
diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile
index 32596978df1d..a1abf87d43bf 100644
--- a/net/netfilter/Makefile
+++ b/net/netfilter/Makefile
@@ -4,6 +4,7 @@ nf_conntrack-y := nf_conntrack_core.o nf_conntrack_standalone.o nf_conntrack_exp
4nf_conntrack-$(CONFIG_NF_CONNTRACK_TIMEOUT) += nf_conntrack_timeout.o 4nf_conntrack-$(CONFIG_NF_CONNTRACK_TIMEOUT) += nf_conntrack_timeout.o
5nf_conntrack-$(CONFIG_NF_CONNTRACK_TIMESTAMP) += nf_conntrack_timestamp.o 5nf_conntrack-$(CONFIG_NF_CONNTRACK_TIMESTAMP) += nf_conntrack_timestamp.o
6nf_conntrack-$(CONFIG_NF_CONNTRACK_EVENTS) += nf_conntrack_ecache.o 6nf_conntrack-$(CONFIG_NF_CONNTRACK_EVENTS) += nf_conntrack_ecache.o
7nf_conntrack-$(CONFIG_NF_CONNTRACK_LABELS) += nf_conntrack_labels.o
7 8
8obj-$(CONFIG_NETFILTER) = netfilter.o 9obj-$(CONFIG_NETFILTER) = netfilter.o
9 10
@@ -98,9 +99,11 @@ obj-$(CONFIG_NETFILTER_XT_TARGET_IDLETIMER) += xt_IDLETIMER.o
98 99
99# matches 100# matches
100obj-$(CONFIG_NETFILTER_XT_MATCH_ADDRTYPE) += xt_addrtype.o 101obj-$(CONFIG_NETFILTER_XT_MATCH_ADDRTYPE) += xt_addrtype.o
102obj-$(CONFIG_NETFILTER_XT_MATCH_BPF) += xt_bpf.o
101obj-$(CONFIG_NETFILTER_XT_MATCH_CLUSTER) += xt_cluster.o 103obj-$(CONFIG_NETFILTER_XT_MATCH_CLUSTER) += xt_cluster.o
102obj-$(CONFIG_NETFILTER_XT_MATCH_COMMENT) += xt_comment.o 104obj-$(CONFIG_NETFILTER_XT_MATCH_COMMENT) += xt_comment.o
103obj-$(CONFIG_NETFILTER_XT_MATCH_CONNBYTES) += xt_connbytes.o 105obj-$(CONFIG_NETFILTER_XT_MATCH_CONNBYTES) += xt_connbytes.o
106obj-$(CONFIG_NETFILTER_XT_MATCH_CONNLABEL) += xt_connlabel.o
104obj-$(CONFIG_NETFILTER_XT_MATCH_CONNLIMIT) += xt_connlimit.o 107obj-$(CONFIG_NETFILTER_XT_MATCH_CONNLIMIT) += xt_connlimit.o
105obj-$(CONFIG_NETFILTER_XT_MATCH_CONNTRACK) += xt_conntrack.o 108obj-$(CONFIG_NETFILTER_XT_MATCH_CONNTRACK) += xt_conntrack.o
106obj-$(CONFIG_NETFILTER_XT_MATCH_CPU) += xt_cpu.o 109obj-$(CONFIG_NETFILTER_XT_MATCH_CPU) += xt_cpu.o
diff --git a/net/netfilter/nf_conntrack_acct.c b/net/netfilter/nf_conntrack_acct.c
index 7df424e2d10c..2d3030ab5b61 100644
--- a/net/netfilter/nf_conntrack_acct.c
+++ b/net/netfilter/nf_conntrack_acct.c
@@ -106,36 +106,26 @@ static void nf_conntrack_acct_fini_sysctl(struct net *net)
106} 106}
107#endif 107#endif
108 108
109int nf_conntrack_acct_init(struct net *net) 109int nf_conntrack_acct_pernet_init(struct net *net)
110{ 110{
111 int ret;
112
113 net->ct.sysctl_acct = nf_ct_acct; 111 net->ct.sysctl_acct = nf_ct_acct;
112 return nf_conntrack_acct_init_sysctl(net);
113}
114 114
115 if (net_eq(net, &init_net)) { 115void nf_conntrack_acct_pernet_fini(struct net *net)
116 ret = nf_ct_extend_register(&acct_extend); 116{
117 if (ret < 0) { 117 nf_conntrack_acct_fini_sysctl(net);
118 printk(KERN_ERR "nf_conntrack_acct: Unable to register extension\n"); 118}
119 goto out_extend_register;
120 }
121 }
122 119
123 ret = nf_conntrack_acct_init_sysctl(net); 120int nf_conntrack_acct_init(void)
121{
122 int ret = nf_ct_extend_register(&acct_extend);
124 if (ret < 0) 123 if (ret < 0)
125 goto out_sysctl; 124 pr_err("nf_conntrack_acct: Unable to register extension\n");
126
127 return 0;
128
129out_sysctl:
130 if (net_eq(net, &init_net))
131 nf_ct_extend_unregister(&acct_extend);
132out_extend_register:
133 return ret; 125 return ret;
134} 126}
135 127
136void nf_conntrack_acct_fini(struct net *net) 128void nf_conntrack_acct_fini(void)
137{ 129{
138 nf_conntrack_acct_fini_sysctl(net); 130 nf_ct_extend_unregister(&acct_extend);
139 if (net_eq(net, &init_net))
140 nf_ct_extend_unregister(&acct_extend);
141} 131}
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
index e4a0c4fb3a7c..c8e001a9c45b 100644
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -45,6 +45,7 @@
45#include <net/netfilter/nf_conntrack_zones.h> 45#include <net/netfilter/nf_conntrack_zones.h>
46#include <net/netfilter/nf_conntrack_timestamp.h> 46#include <net/netfilter/nf_conntrack_timestamp.h>
47#include <net/netfilter/nf_conntrack_timeout.h> 47#include <net/netfilter/nf_conntrack_timeout.h>
48#include <net/netfilter/nf_conntrack_labels.h>
48#include <net/netfilter/nf_nat.h> 49#include <net/netfilter/nf_nat.h>
49#include <net/netfilter/nf_nat_core.h> 50#include <net/netfilter/nf_nat_core.h>
50 51
@@ -763,6 +764,7 @@ void nf_conntrack_free(struct nf_conn *ct)
763} 764}
764EXPORT_SYMBOL_GPL(nf_conntrack_free); 765EXPORT_SYMBOL_GPL(nf_conntrack_free);
765 766
767
766/* Allocate a new conntrack: we return -ENOMEM if classification 768/* Allocate a new conntrack: we return -ENOMEM if classification
767 failed due to stress. Otherwise it really is unclassifiable. */ 769 failed due to stress. Otherwise it really is unclassifiable. */
768static struct nf_conntrack_tuple_hash * 770static struct nf_conntrack_tuple_hash *
@@ -809,6 +811,7 @@ init_conntrack(struct net *net, struct nf_conn *tmpl,
809 811
810 nf_ct_acct_ext_add(ct, GFP_ATOMIC); 812 nf_ct_acct_ext_add(ct, GFP_ATOMIC);
811 nf_ct_tstamp_ext_add(ct, GFP_ATOMIC); 813 nf_ct_tstamp_ext_add(ct, GFP_ATOMIC);
814 nf_ct_labels_ext_add(ct);
812 815
813 ecache = tmpl ? nf_ct_ecache_find(tmpl) : NULL; 816 ecache = tmpl ? nf_ct_ecache_find(tmpl) : NULL;
814 nf_ct_ecache_ext_add(ct, ecache ? ecache->ctmask : 0, 817 nf_ct_ecache_ext_add(ct, ecache ? ecache->ctmask : 0,
@@ -1331,18 +1334,42 @@ static int untrack_refs(void)
1331 return cnt; 1334 return cnt;
1332} 1335}
1333 1336
1334static void nf_conntrack_cleanup_init_net(void) 1337void nf_conntrack_cleanup_start(void)
1338{
1339 RCU_INIT_POINTER(ip_ct_attach, NULL);
1340}
1341
1342void nf_conntrack_cleanup_end(void)
1335{ 1343{
1344 RCU_INIT_POINTER(nf_ct_destroy, NULL);
1336 while (untrack_refs() > 0) 1345 while (untrack_refs() > 0)
1337 schedule(); 1346 schedule();
1338 1347
1339#ifdef CONFIG_NF_CONNTRACK_ZONES 1348#ifdef CONFIG_NF_CONNTRACK_ZONES
1340 nf_ct_extend_unregister(&nf_ct_zone_extend); 1349 nf_ct_extend_unregister(&nf_ct_zone_extend);
1341#endif 1350#endif
1351 nf_conntrack_proto_fini();
1352 nf_conntrack_labels_fini();
1353 nf_conntrack_helper_fini();
1354 nf_conntrack_timeout_fini();
1355 nf_conntrack_ecache_fini();
1356 nf_conntrack_tstamp_fini();
1357 nf_conntrack_acct_fini();
1358 nf_conntrack_expect_fini();
1342} 1359}
1343 1360
1344static void nf_conntrack_cleanup_net(struct net *net) 1361/*
1362 * Mishearing the voices in his head, our hero wonders how he's
1363 * supposed to kill the mall.
1364 */
1365void nf_conntrack_cleanup_net(struct net *net)
1345{ 1366{
1367 /*
1368 * This makes sure all current packets have passed through
1369 * netfilter framework. Roll on, two-stage module
1370 * delete...
1371 */
1372 synchronize_net();
1346 i_see_dead_people: 1373 i_see_dead_people:
1347 nf_ct_iterate_cleanup(net, kill_all, NULL); 1374 nf_ct_iterate_cleanup(net, kill_all, NULL);
1348 nf_ct_release_dying_list(net); 1375 nf_ct_release_dying_list(net);
@@ -1352,38 +1379,17 @@ static void nf_conntrack_cleanup_net(struct net *net)
1352 } 1379 }
1353 1380
1354 nf_ct_free_hashtable(net->ct.hash, net->ct.htable_size); 1381 nf_ct_free_hashtable(net->ct.hash, net->ct.htable_size);
1355 nf_conntrack_helper_fini(net); 1382 nf_conntrack_proto_pernet_fini(net);
1356 nf_conntrack_timeout_fini(net); 1383 nf_conntrack_helper_pernet_fini(net);
1357 nf_conntrack_ecache_fini(net); 1384 nf_conntrack_ecache_pernet_fini(net);
1358 nf_conntrack_tstamp_fini(net); 1385 nf_conntrack_tstamp_pernet_fini(net);
1359 nf_conntrack_acct_fini(net); 1386 nf_conntrack_acct_pernet_fini(net);
1360 nf_conntrack_expect_fini(net); 1387 nf_conntrack_expect_pernet_fini(net);
1361 kmem_cache_destroy(net->ct.nf_conntrack_cachep); 1388 kmem_cache_destroy(net->ct.nf_conntrack_cachep);
1362 kfree(net->ct.slabname); 1389 kfree(net->ct.slabname);
1363 free_percpu(net->ct.stat); 1390 free_percpu(net->ct.stat);
1364} 1391}
1365 1392
1366/* Mishearing the voices in his head, our hero wonders how he's
1367 supposed to kill the mall. */
1368void nf_conntrack_cleanup(struct net *net)
1369{
1370 if (net_eq(net, &init_net))
1371 RCU_INIT_POINTER(ip_ct_attach, NULL);
1372
1373 /* This makes sure all current packets have passed through
1374 netfilter framework. Roll on, two-stage module
1375 delete... */
1376 synchronize_net();
1377 nf_conntrack_proto_fini(net);
1378 nf_conntrack_cleanup_net(net);
1379}
1380
1381void nf_conntrack_cleanup_end(void)
1382{
1383 RCU_INIT_POINTER(nf_ct_destroy, NULL);
1384 nf_conntrack_cleanup_init_net();
1385}
1386
1387void *nf_ct_alloc_hashtable(unsigned int *sizep, int nulls) 1393void *nf_ct_alloc_hashtable(unsigned int *sizep, int nulls)
1388{ 1394{
1389 struct hlist_nulls_head *hash; 1395 struct hlist_nulls_head *hash;
@@ -1474,7 +1480,7 @@ void nf_ct_untracked_status_or(unsigned long bits)
1474} 1480}
1475EXPORT_SYMBOL_GPL(nf_ct_untracked_status_or); 1481EXPORT_SYMBOL_GPL(nf_ct_untracked_status_or);
1476 1482
1477static int nf_conntrack_init_init_net(void) 1483int nf_conntrack_init_start(void)
1478{ 1484{
1479 int max_factor = 8; 1485 int max_factor = 8;
1480 int ret, cpu; 1486 int ret, cpu;
@@ -1501,11 +1507,44 @@ static int nf_conntrack_init_init_net(void)
1501 printk(KERN_INFO "nf_conntrack version %s (%u buckets, %d max)\n", 1507 printk(KERN_INFO "nf_conntrack version %s (%u buckets, %d max)\n",
1502 NF_CONNTRACK_VERSION, nf_conntrack_htable_size, 1508 NF_CONNTRACK_VERSION, nf_conntrack_htable_size,
1503 nf_conntrack_max); 1509 nf_conntrack_max);
1510
1511 ret = nf_conntrack_expect_init();
1512 if (ret < 0)
1513 goto err_expect;
1514
1515 ret = nf_conntrack_acct_init();
1516 if (ret < 0)
1517 goto err_acct;
1518
1519 ret = nf_conntrack_tstamp_init();
1520 if (ret < 0)
1521 goto err_tstamp;
1522
1523 ret = nf_conntrack_ecache_init();
1524 if (ret < 0)
1525 goto err_ecache;
1526
1527 ret = nf_conntrack_timeout_init();
1528 if (ret < 0)
1529 goto err_timeout;
1530
1531 ret = nf_conntrack_helper_init();
1532 if (ret < 0)
1533 goto err_helper;
1534
1535 ret = nf_conntrack_labels_init();
1536 if (ret < 0)
1537 goto err_labels;
1538
1504#ifdef CONFIG_NF_CONNTRACK_ZONES 1539#ifdef CONFIG_NF_CONNTRACK_ZONES
1505 ret = nf_ct_extend_register(&nf_ct_zone_extend); 1540 ret = nf_ct_extend_register(&nf_ct_zone_extend);
1506 if (ret < 0) 1541 if (ret < 0)
1507 goto err_extend; 1542 goto err_extend;
1508#endif 1543#endif
1544 ret = nf_conntrack_proto_init();
1545 if (ret < 0)
1546 goto err_proto;
1547
1509 /* Set up fake conntrack: to never be deleted, not in any hashes */ 1548 /* Set up fake conntrack: to never be deleted, not in any hashes */
1510 for_each_possible_cpu(cpu) { 1549 for_each_possible_cpu(cpu) {
1511 struct nf_conn *ct = &per_cpu(nf_conntrack_untracked, cpu); 1550 struct nf_conn *ct = &per_cpu(nf_conntrack_untracked, cpu);
@@ -1516,12 +1555,38 @@ static int nf_conntrack_init_init_net(void)
1516 nf_ct_untracked_status_or(IPS_CONFIRMED | IPS_UNTRACKED); 1555 nf_ct_untracked_status_or(IPS_CONFIRMED | IPS_UNTRACKED);
1517 return 0; 1556 return 0;
1518 1557
1558err_proto:
1519#ifdef CONFIG_NF_CONNTRACK_ZONES 1559#ifdef CONFIG_NF_CONNTRACK_ZONES
1560 nf_ct_extend_unregister(&nf_ct_zone_extend);
1520err_extend: 1561err_extend:
1521#endif 1562#endif
1563 nf_conntrack_labels_fini();
1564err_labels:
1565 nf_conntrack_helper_fini();
1566err_helper:
1567 nf_conntrack_timeout_fini();
1568err_timeout:
1569 nf_conntrack_ecache_fini();
1570err_ecache:
1571 nf_conntrack_tstamp_fini();
1572err_tstamp:
1573 nf_conntrack_acct_fini();
1574err_acct:
1575 nf_conntrack_expect_fini();
1576err_expect:
1522 return ret; 1577 return ret;
1523} 1578}
1524 1579
1580void nf_conntrack_init_end(void)
1581{
1582 /* For use by REJECT target */
1583 RCU_INIT_POINTER(ip_ct_attach, nf_conntrack_attach);
1584 RCU_INIT_POINTER(nf_ct_destroy, destroy_conntrack);
1585
1586 /* Howto get NAT offsets */
1587 RCU_INIT_POINTER(nf_ct_nat_offset, NULL);
1588}
1589
1525/* 1590/*
1526 * We need to use special "null" values, not used in hash table 1591 * We need to use special "null" values, not used in hash table
1527 */ 1592 */
@@ -1529,7 +1594,7 @@ err_extend:
1529#define DYING_NULLS_VAL ((1<<30)+1) 1594#define DYING_NULLS_VAL ((1<<30)+1)
1530#define TEMPLATE_NULLS_VAL ((1<<30)+2) 1595#define TEMPLATE_NULLS_VAL ((1<<30)+2)
1531 1596
1532static int nf_conntrack_init_net(struct net *net) 1597int nf_conntrack_init_net(struct net *net)
1533{ 1598{
1534 int ret; 1599 int ret;
1535 1600
@@ -1565,35 +1630,36 @@ static int nf_conntrack_init_net(struct net *net)
1565 printk(KERN_ERR "Unable to create nf_conntrack_hash\n"); 1630 printk(KERN_ERR "Unable to create nf_conntrack_hash\n");
1566 goto err_hash; 1631 goto err_hash;
1567 } 1632 }
1568 ret = nf_conntrack_expect_init(net); 1633 ret = nf_conntrack_expect_pernet_init(net);
1569 if (ret < 0) 1634 if (ret < 0)
1570 goto err_expect; 1635 goto err_expect;
1571 ret = nf_conntrack_acct_init(net); 1636 ret = nf_conntrack_acct_pernet_init(net);
1572 if (ret < 0) 1637 if (ret < 0)
1573 goto err_acct; 1638 goto err_acct;
1574 ret = nf_conntrack_tstamp_init(net); 1639 ret = nf_conntrack_tstamp_pernet_init(net);
1575 if (ret < 0) 1640 if (ret < 0)
1576 goto err_tstamp; 1641 goto err_tstamp;
1577 ret = nf_conntrack_ecache_init(net); 1642 ret = nf_conntrack_ecache_pernet_init(net);
1578 if (ret < 0) 1643 if (ret < 0)
1579 goto err_ecache; 1644 goto err_ecache;
1580 ret = nf_conntrack_timeout_init(net); 1645 ret = nf_conntrack_helper_pernet_init(net);
1581 if (ret < 0)
1582 goto err_timeout;
1583 ret = nf_conntrack_helper_init(net);
1584 if (ret < 0) 1646 if (ret < 0)
1585 goto err_helper; 1647 goto err_helper;
1648 ret = nf_conntrack_proto_pernet_init(net);
1649 if (ret < 0)
1650 goto err_proto;
1586 return 0; 1651 return 0;
1652
1653err_proto:
1654 nf_conntrack_helper_pernet_fini(net);
1587err_helper: 1655err_helper:
1588 nf_conntrack_timeout_fini(net); 1656 nf_conntrack_ecache_pernet_fini(net);
1589err_timeout:
1590 nf_conntrack_ecache_fini(net);
1591err_ecache: 1657err_ecache:
1592 nf_conntrack_tstamp_fini(net); 1658 nf_conntrack_tstamp_pernet_fini(net);
1593err_tstamp: 1659err_tstamp:
1594 nf_conntrack_acct_fini(net); 1660 nf_conntrack_acct_pernet_fini(net);
1595err_acct: 1661err_acct:
1596 nf_conntrack_expect_fini(net); 1662 nf_conntrack_expect_pernet_fini(net);
1597err_expect: 1663err_expect:
1598 nf_ct_free_hashtable(net->ct.hash, net->ct.htable_size); 1664 nf_ct_free_hashtable(net->ct.hash, net->ct.htable_size);
1599err_hash: 1665err_hash:
@@ -1610,38 +1676,3 @@ s16 (*nf_ct_nat_offset)(const struct nf_conn *ct,
1610 enum ip_conntrack_dir dir, 1676 enum ip_conntrack_dir dir,
1611 u32 seq); 1677 u32 seq);
1612EXPORT_SYMBOL_GPL(nf_ct_nat_offset); 1678EXPORT_SYMBOL_GPL(nf_ct_nat_offset);
1613
1614int nf_conntrack_init(struct net *net)
1615{
1616 int ret;
1617
1618 if (net_eq(net, &init_net)) {
1619 ret = nf_conntrack_init_init_net();
1620 if (ret < 0)
1621 goto out_init_net;
1622 }
1623 ret = nf_conntrack_proto_init(net);
1624 if (ret < 0)
1625 goto out_proto;
1626 ret = nf_conntrack_init_net(net);
1627 if (ret < 0)
1628 goto out_net;
1629
1630 if (net_eq(net, &init_net)) {
1631 /* For use by REJECT target */
1632 RCU_INIT_POINTER(ip_ct_attach, nf_conntrack_attach);
1633 RCU_INIT_POINTER(nf_ct_destroy, destroy_conntrack);
1634
1635 /* Howto get NAT offsets */
1636 RCU_INIT_POINTER(nf_ct_nat_offset, NULL);
1637 }
1638 return 0;
1639
1640out_net:
1641 nf_conntrack_proto_fini(net);
1642out_proto:
1643 if (net_eq(net, &init_net))
1644 nf_conntrack_cleanup_init_net();
1645out_init_net:
1646 return ret;
1647}
diff --git a/net/netfilter/nf_conntrack_ecache.c b/net/netfilter/nf_conntrack_ecache.c
index faa978f1714b..b5d2eb8bf0d5 100644
--- a/net/netfilter/nf_conntrack_ecache.c
+++ b/net/netfilter/nf_conntrack_ecache.c
@@ -233,38 +233,27 @@ static void nf_conntrack_event_fini_sysctl(struct net *net)
233} 233}
234#endif /* CONFIG_SYSCTL */ 234#endif /* CONFIG_SYSCTL */
235 235
236int nf_conntrack_ecache_init(struct net *net) 236int nf_conntrack_ecache_pernet_init(struct net *net)
237{ 237{
238 int ret;
239
240 net->ct.sysctl_events = nf_ct_events; 238 net->ct.sysctl_events = nf_ct_events;
241 net->ct.sysctl_events_retry_timeout = nf_ct_events_retry_timeout; 239 net->ct.sysctl_events_retry_timeout = nf_ct_events_retry_timeout;
240 return nf_conntrack_event_init_sysctl(net);
241}
242 242
243 if (net_eq(net, &init_net)) { 243void nf_conntrack_ecache_pernet_fini(struct net *net)
244 ret = nf_ct_extend_register(&event_extend); 244{
245 if (ret < 0) { 245 nf_conntrack_event_fini_sysctl(net);
246 printk(KERN_ERR "nf_ct_event: Unable to register " 246}
247 "event extension.\n");
248 goto out_extend_register;
249 }
250 }
251 247
252 ret = nf_conntrack_event_init_sysctl(net); 248int nf_conntrack_ecache_init(void)
249{
250 int ret = nf_ct_extend_register(&event_extend);
253 if (ret < 0) 251 if (ret < 0)
254 goto out_sysctl; 252 pr_err("nf_ct_event: Unable to register event extension.\n");
255
256 return 0;
257
258out_sysctl:
259 if (net_eq(net, &init_net))
260 nf_ct_extend_unregister(&event_extend);
261out_extend_register:
262 return ret; 253 return ret;
263} 254}
264 255
265void nf_conntrack_ecache_fini(struct net *net) 256void nf_conntrack_ecache_fini(void)
266{ 257{
267 nf_conntrack_event_fini_sysctl(net); 258 nf_ct_extend_unregister(&event_extend);
268 if (net_eq(net, &init_net))
269 nf_ct_extend_unregister(&event_extend);
270} 259}
diff --git a/net/netfilter/nf_conntrack_expect.c b/net/netfilter/nf_conntrack_expect.c
index 527651a53a45..bdd341899ed3 100644
--- a/net/netfilter/nf_conntrack_expect.c
+++ b/net/netfilter/nf_conntrack_expect.c
@@ -587,53 +587,50 @@ static void exp_proc_remove(struct net *net)
587 587
588module_param_named(expect_hashsize, nf_ct_expect_hsize, uint, 0400); 588module_param_named(expect_hashsize, nf_ct_expect_hsize, uint, 0400);
589 589
590int nf_conntrack_expect_init(struct net *net) 590int nf_conntrack_expect_pernet_init(struct net *net)
591{ 591{
592 int err = -ENOMEM; 592 int err = -ENOMEM;
593 593
594 if (net_eq(net, &init_net)) {
595 if (!nf_ct_expect_hsize) {
596 nf_ct_expect_hsize = net->ct.htable_size / 256;
597 if (!nf_ct_expect_hsize)
598 nf_ct_expect_hsize = 1;
599 }
600 nf_ct_expect_max = nf_ct_expect_hsize * 4;
601 }
602
603 net->ct.expect_count = 0; 594 net->ct.expect_count = 0;
604 net->ct.expect_hash = nf_ct_alloc_hashtable(&nf_ct_expect_hsize, 0); 595 net->ct.expect_hash = nf_ct_alloc_hashtable(&nf_ct_expect_hsize, 0);
605 if (net->ct.expect_hash == NULL) 596 if (net->ct.expect_hash == NULL)
606 goto err1; 597 goto err1;
607 598
608 if (net_eq(net, &init_net)) {
609 nf_ct_expect_cachep = kmem_cache_create("nf_conntrack_expect",
610 sizeof(struct nf_conntrack_expect),
611 0, 0, NULL);
612 if (!nf_ct_expect_cachep)
613 goto err2;
614 }
615
616 err = exp_proc_init(net); 599 err = exp_proc_init(net);
617 if (err < 0) 600 if (err < 0)
618 goto err3; 601 goto err2;
619 602
620 return 0; 603 return 0;
621
622err3:
623 if (net_eq(net, &init_net))
624 kmem_cache_destroy(nf_ct_expect_cachep);
625err2: 604err2:
626 nf_ct_free_hashtable(net->ct.expect_hash, nf_ct_expect_hsize); 605 nf_ct_free_hashtable(net->ct.expect_hash, nf_ct_expect_hsize);
627err1: 606err1:
628 return err; 607 return err;
629} 608}
630 609
631void nf_conntrack_expect_fini(struct net *net) 610void nf_conntrack_expect_pernet_fini(struct net *net)
632{ 611{
633 exp_proc_remove(net); 612 exp_proc_remove(net);
634 if (net_eq(net, &init_net)) {
635 rcu_barrier(); /* Wait for call_rcu() before destroy */
636 kmem_cache_destroy(nf_ct_expect_cachep);
637 }
638 nf_ct_free_hashtable(net->ct.expect_hash, nf_ct_expect_hsize); 613 nf_ct_free_hashtable(net->ct.expect_hash, nf_ct_expect_hsize);
639} 614}
615
616int nf_conntrack_expect_init(void)
617{
618 if (!nf_ct_expect_hsize) {
619 nf_ct_expect_hsize = nf_conntrack_htable_size / 256;
620 if (!nf_ct_expect_hsize)
621 nf_ct_expect_hsize = 1;
622 }
623 nf_ct_expect_max = nf_ct_expect_hsize * 4;
624 nf_ct_expect_cachep = kmem_cache_create("nf_conntrack_expect",
625 sizeof(struct nf_conntrack_expect),
626 0, 0, NULL);
627 if (!nf_ct_expect_cachep)
628 return -ENOMEM;
629 return 0;
630}
631
632void nf_conntrack_expect_fini(void)
633{
634 rcu_barrier(); /* Wait for call_rcu() before destroy */
635 kmem_cache_destroy(nf_ct_expect_cachep);
636}
diff --git a/net/netfilter/nf_conntrack_helper.c b/net/netfilter/nf_conntrack_helper.c
index 884f2b39319a..2f380f73c4c0 100644
--- a/net/netfilter/nf_conntrack_helper.c
+++ b/net/netfilter/nf_conntrack_helper.c
@@ -423,44 +423,41 @@ static struct nf_ct_ext_type helper_extend __read_mostly = {
423 .id = NF_CT_EXT_HELPER, 423 .id = NF_CT_EXT_HELPER,
424}; 424};
425 425
426int nf_conntrack_helper_init(struct net *net) 426int nf_conntrack_helper_pernet_init(struct net *net)
427{ 427{
428 int err;
429
430 net->ct.auto_assign_helper_warned = false; 428 net->ct.auto_assign_helper_warned = false;
431 net->ct.sysctl_auto_assign_helper = nf_ct_auto_assign_helper; 429 net->ct.sysctl_auto_assign_helper = nf_ct_auto_assign_helper;
430 return nf_conntrack_helper_init_sysctl(net);
431}
432 432
433 if (net_eq(net, &init_net)) { 433void nf_conntrack_helper_pernet_fini(struct net *net)
434 nf_ct_helper_hsize = 1; /* gets rounded up to use one page */ 434{
435 nf_ct_helper_hash = 435 nf_conntrack_helper_fini_sysctl(net);
436 nf_ct_alloc_hashtable(&nf_ct_helper_hsize, 0); 436}
437 if (!nf_ct_helper_hash)
438 return -ENOMEM;
439 437
440 err = nf_ct_extend_register(&helper_extend); 438int nf_conntrack_helper_init(void)
441 if (err < 0) 439{
442 goto err1; 440 int ret;
441 nf_ct_helper_hsize = 1; /* gets rounded up to use one page */
442 nf_ct_helper_hash =
443 nf_ct_alloc_hashtable(&nf_ct_helper_hsize, 0);
444 if (!nf_ct_helper_hash)
445 return -ENOMEM;
446
447 ret = nf_ct_extend_register(&helper_extend);
448 if (ret < 0) {
449 pr_err("nf_ct_helper: Unable to register helper extension.\n");
450 goto out_extend;
443 } 451 }
444 452
445 err = nf_conntrack_helper_init_sysctl(net);
446 if (err < 0)
447 goto out_sysctl;
448
449 return 0; 453 return 0;
450 454out_extend:
451out_sysctl:
452 if (net_eq(net, &init_net))
453 nf_ct_extend_unregister(&helper_extend);
454err1:
455 nf_ct_free_hashtable(nf_ct_helper_hash, nf_ct_helper_hsize); 455 nf_ct_free_hashtable(nf_ct_helper_hash, nf_ct_helper_hsize);
456 return err; 456 return ret;
457} 457}
458 458
459void nf_conntrack_helper_fini(struct net *net) 459void nf_conntrack_helper_fini(void)
460{ 460{
461 nf_conntrack_helper_fini_sysctl(net); 461 nf_ct_extend_unregister(&helper_extend);
462 if (net_eq(net, &init_net)) { 462 nf_ct_free_hashtable(nf_ct_helper_hash, nf_ct_helper_hsize);
463 nf_ct_extend_unregister(&helper_extend);
464 nf_ct_free_hashtable(nf_ct_helper_hash, nf_ct_helper_hsize);
465 }
466} 463}
diff --git a/net/netfilter/nf_conntrack_labels.c b/net/netfilter/nf_conntrack_labels.c
new file mode 100644
index 000000000000..8fe2e99428b7
--- /dev/null
+++ b/net/netfilter/nf_conntrack_labels.c
@@ -0,0 +1,112 @@
1/*
2 * test/set flag bits stored in conntrack extension area.
3 *
4 * (C) 2013 Astaro GmbH & Co KG
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#include <linux/ctype.h>
12#include <linux/export.h>
13#include <linux/jhash.h>
14#include <linux/spinlock.h>
15#include <linux/types.h>
16#include <linux/slab.h>
17
18#include <net/netfilter/nf_conntrack_ecache.h>
19#include <net/netfilter/nf_conntrack_labels.h>
20
21static unsigned int label_bits(const struct nf_conn_labels *l)
22{
23 unsigned int longs = l->words;
24 return longs * BITS_PER_LONG;
25}
26
27bool nf_connlabel_match(const struct nf_conn *ct, u16 bit)
28{
29 struct nf_conn_labels *labels = nf_ct_labels_find(ct);
30
31 if (!labels)
32 return false;
33
34 return bit < label_bits(labels) && test_bit(bit, labels->bits);
35}
36EXPORT_SYMBOL_GPL(nf_connlabel_match);
37
38int nf_connlabel_set(struct nf_conn *ct, u16 bit)
39{
40 struct nf_conn_labels *labels = nf_ct_labels_find(ct);
41
42 if (!labels || bit >= label_bits(labels))
43 return -ENOSPC;
44
45 if (test_bit(bit, labels->bits))
46 return 0;
47
48 if (test_and_set_bit(bit, labels->bits))
49 nf_conntrack_event_cache(IPCT_LABEL, ct);
50
51 return 0;
52}
53EXPORT_SYMBOL_GPL(nf_connlabel_set);
54
55#if IS_ENABLED(CONFIG_NF_CT_NETLINK)
56static void replace_u32(u32 *address, u32 mask, u32 new)
57{
58 u32 old, tmp;
59
60 do {
61 old = *address;
62 tmp = (old & mask) ^ new;
63 } while (cmpxchg(address, old, tmp) != old);
64}
65
66int nf_connlabels_replace(struct nf_conn *ct,
67 const u32 *data,
68 const u32 *mask, unsigned int words32)
69{
70 struct nf_conn_labels *labels;
71 unsigned int size, i;
72 u32 *dst;
73
74 labels = nf_ct_labels_find(ct);
75 if (!labels)
76 return -ENOSPC;
77
78 size = labels->words * sizeof(long);
79 if (size < (words32 * sizeof(u32)))
80 words32 = size / sizeof(u32);
81
82 dst = (u32 *) labels->bits;
83 if (words32) {
84 for (i = 0; i < words32; i++)
85 replace_u32(&dst[i], mask ? ~mask[i] : 0, data[i]);
86 }
87
88 size /= sizeof(u32);
89 for (i = words32; i < size; i++) /* pad */
90 replace_u32(&dst[i], 0, 0);
91
92 nf_conntrack_event_cache(IPCT_LABEL, ct);
93 return 0;
94}
95EXPORT_SYMBOL_GPL(nf_connlabels_replace);
96#endif
97
98static struct nf_ct_ext_type labels_extend __read_mostly = {
99 .len = sizeof(struct nf_conn_labels),
100 .align = __alignof__(struct nf_conn_labels),
101 .id = NF_CT_EXT_LABELS,
102};
103
104int nf_conntrack_labels_init(void)
105{
106 return nf_ct_extend_register(&labels_extend);
107}
108
109void nf_conntrack_labels_fini(void)
110{
111 nf_ct_extend_unregister(&labels_extend);
112}
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
index 627b0e50b238..2334cc5d2b16 100644
--- a/net/netfilter/nf_conntrack_netlink.c
+++ b/net/netfilter/nf_conntrack_netlink.c
@@ -43,6 +43,7 @@
43#include <net/netfilter/nf_conntrack_acct.h> 43#include <net/netfilter/nf_conntrack_acct.h>
44#include <net/netfilter/nf_conntrack_zones.h> 44#include <net/netfilter/nf_conntrack_zones.h>
45#include <net/netfilter/nf_conntrack_timestamp.h> 45#include <net/netfilter/nf_conntrack_timestamp.h>
46#include <net/netfilter/nf_conntrack_labels.h>
46#ifdef CONFIG_NF_NAT_NEEDED 47#ifdef CONFIG_NF_NAT_NEEDED
47#include <net/netfilter/nf_nat_core.h> 48#include <net/netfilter/nf_nat_core.h>
48#include <net/netfilter/nf_nat_l4proto.h> 49#include <net/netfilter/nf_nat_l4proto.h>
@@ -323,6 +324,40 @@ nla_put_failure:
323#define ctnetlink_dump_secctx(a, b) (0) 324#define ctnetlink_dump_secctx(a, b) (0)
324#endif 325#endif
325 326
327#ifdef CONFIG_NF_CONNTRACK_LABELS
328static int ctnetlink_label_size(const struct nf_conn *ct)
329{
330 struct nf_conn_labels *labels = nf_ct_labels_find(ct);
331
332 if (!labels)
333 return 0;
334 return nla_total_size(labels->words * sizeof(long));
335}
336
337static int
338ctnetlink_dump_labels(struct sk_buff *skb, const struct nf_conn *ct)
339{
340 struct nf_conn_labels *labels = nf_ct_labels_find(ct);
341 unsigned int len, i;
342
343 if (!labels)
344 return 0;
345
346 len = labels->words * sizeof(long);
347 i = 0;
348 do {
349 if (labels->bits[i] != 0)
350 return nla_put(skb, CTA_LABELS, len, labels->bits);
351 i++;
352 } while (i < labels->words);
353
354 return 0;
355}
356#else
357#define ctnetlink_dump_labels(a, b) (0)
358#define ctnetlink_label_size(a) (0)
359#endif
360
326#define master_tuple(ct) &(ct->master->tuplehash[IP_CT_DIR_ORIGINAL].tuple) 361#define master_tuple(ct) &(ct->master->tuplehash[IP_CT_DIR_ORIGINAL].tuple)
327 362
328static inline int 363static inline int
@@ -463,6 +498,7 @@ ctnetlink_fill_info(struct sk_buff *skb, u32 portid, u32 seq, u32 type,
463 ctnetlink_dump_helpinfo(skb, ct) < 0 || 498 ctnetlink_dump_helpinfo(skb, ct) < 0 ||
464 ctnetlink_dump_mark(skb, ct) < 0 || 499 ctnetlink_dump_mark(skb, ct) < 0 ||
465 ctnetlink_dump_secctx(skb, ct) < 0 || 500 ctnetlink_dump_secctx(skb, ct) < 0 ||
501 ctnetlink_dump_labels(skb, ct) < 0 ||
466 ctnetlink_dump_id(skb, ct) < 0 || 502 ctnetlink_dump_id(skb, ct) < 0 ||
467 ctnetlink_dump_use(skb, ct) < 0 || 503 ctnetlink_dump_use(skb, ct) < 0 ||
468 ctnetlink_dump_master(skb, ct) < 0 || 504 ctnetlink_dump_master(skb, ct) < 0 ||
@@ -561,6 +597,7 @@ ctnetlink_nlmsg_size(const struct nf_conn *ct)
561 + nla_total_size(sizeof(u_int32_t)) /* CTA_MARK */ 597 + nla_total_size(sizeof(u_int32_t)) /* CTA_MARK */
562#endif 598#endif
563 + ctnetlink_proto_size(ct) 599 + ctnetlink_proto_size(ct)
600 + ctnetlink_label_size(ct)
564 ; 601 ;
565} 602}
566 603
@@ -662,6 +699,9 @@ ctnetlink_conntrack_event(unsigned int events, struct nf_ct_event *item)
662 && ctnetlink_dump_secctx(skb, ct) < 0) 699 && ctnetlink_dump_secctx(skb, ct) < 0)
663 goto nla_put_failure; 700 goto nla_put_failure;
664#endif 701#endif
702 if (events & (1 << IPCT_LABEL) &&
703 ctnetlink_dump_labels(skb, ct) < 0)
704 goto nla_put_failure;
665 705
666 if (events & (1 << IPCT_RELATED) && 706 if (events & (1 << IPCT_RELATED) &&
667 ctnetlink_dump_master(skb, ct) < 0) 707 ctnetlink_dump_master(skb, ct) < 0)
@@ -921,6 +961,7 @@ ctnetlink_parse_help(const struct nlattr *attr, char **helper_name,
921 return 0; 961 return 0;
922} 962}
923 963
964#define __CTA_LABELS_MAX_LENGTH ((XT_CONNLABEL_MAXBIT + 1) / BITS_PER_BYTE)
924static const struct nla_policy ct_nla_policy[CTA_MAX+1] = { 965static const struct nla_policy ct_nla_policy[CTA_MAX+1] = {
925 [CTA_TUPLE_ORIG] = { .type = NLA_NESTED }, 966 [CTA_TUPLE_ORIG] = { .type = NLA_NESTED },
926 [CTA_TUPLE_REPLY] = { .type = NLA_NESTED }, 967 [CTA_TUPLE_REPLY] = { .type = NLA_NESTED },
@@ -937,6 +978,10 @@ static const struct nla_policy ct_nla_policy[CTA_MAX+1] = {
937 [CTA_NAT_SEQ_ADJ_REPLY] = { .type = NLA_NESTED }, 978 [CTA_NAT_SEQ_ADJ_REPLY] = { .type = NLA_NESTED },
938 [CTA_ZONE] = { .type = NLA_U16 }, 979 [CTA_ZONE] = { .type = NLA_U16 },
939 [CTA_MARK_MASK] = { .type = NLA_U32 }, 980 [CTA_MARK_MASK] = { .type = NLA_U32 },
981 [CTA_LABELS] = { .type = NLA_BINARY,
982 .len = __CTA_LABELS_MAX_LENGTH },
983 [CTA_LABELS_MASK] = { .type = NLA_BINARY,
984 .len = __CTA_LABELS_MAX_LENGTH },
940}; 985};
941 986
942static int 987static int
@@ -1465,6 +1510,31 @@ ctnetlink_change_nat_seq_adj(struct nf_conn *ct,
1465#endif 1510#endif
1466 1511
1467static int 1512static int
1513ctnetlink_attach_labels(struct nf_conn *ct, const struct nlattr * const cda[])
1514{
1515#ifdef CONFIG_NF_CONNTRACK_LABELS
1516 size_t len = nla_len(cda[CTA_LABELS]);
1517 const void *mask = cda[CTA_LABELS_MASK];
1518
1519 if (len & (sizeof(u32)-1)) /* must be multiple of u32 */
1520 return -EINVAL;
1521
1522 if (mask) {
1523 if (nla_len(cda[CTA_LABELS_MASK]) == 0 ||
1524 nla_len(cda[CTA_LABELS_MASK]) != len)
1525 return -EINVAL;
1526 mask = nla_data(cda[CTA_LABELS_MASK]);
1527 }
1528
1529 len /= sizeof(u32);
1530
1531 return nf_connlabels_replace(ct, nla_data(cda[CTA_LABELS]), mask, len);
1532#else
1533 return -EOPNOTSUPP;
1534#endif
1535}
1536
1537static int
1468ctnetlink_change_conntrack(struct nf_conn *ct, 1538ctnetlink_change_conntrack(struct nf_conn *ct,
1469 const struct nlattr * const cda[]) 1539 const struct nlattr * const cda[])
1470{ 1540{
@@ -1510,6 +1580,11 @@ ctnetlink_change_conntrack(struct nf_conn *ct,
1510 return err; 1580 return err;
1511 } 1581 }
1512#endif 1582#endif
1583 if (cda[CTA_LABELS]) {
1584 err = ctnetlink_attach_labels(ct, cda);
1585 if (err < 0)
1586 return err;
1587 }
1513 1588
1514 return 0; 1589 return 0;
1515} 1590}
@@ -1598,6 +1673,8 @@ ctnetlink_create_conntrack(struct net *net, u16 zone,
1598 nf_ct_acct_ext_add(ct, GFP_ATOMIC); 1673 nf_ct_acct_ext_add(ct, GFP_ATOMIC);
1599 nf_ct_tstamp_ext_add(ct, GFP_ATOMIC); 1674 nf_ct_tstamp_ext_add(ct, GFP_ATOMIC);
1600 nf_ct_ecache_ext_add(ct, 0, 0, GFP_ATOMIC); 1675 nf_ct_ecache_ext_add(ct, 0, 0, GFP_ATOMIC);
1676 nf_ct_labels_ext_add(ct);
1677
1601 /* we must add conntrack extensions before confirmation. */ 1678 /* we must add conntrack extensions before confirmation. */
1602 ct->status |= IPS_CONFIRMED; 1679 ct->status |= IPS_CONFIRMED;
1603 1680
@@ -1716,6 +1793,10 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb,
1716 else 1793 else
1717 events = IPCT_NEW; 1794 events = IPCT_NEW;
1718 1795
1796 if (cda[CTA_LABELS] &&
1797 ctnetlink_attach_labels(ct, cda) == 0)
1798 events |= (1 << IPCT_LABEL);
1799
1719 nf_conntrack_eventmask_report((1 << IPCT_REPLY) | 1800 nf_conntrack_eventmask_report((1 << IPCT_REPLY) |
1720 (1 << IPCT_ASSURED) | 1801 (1 << IPCT_ASSURED) |
1721 (1 << IPCT_HELPER) | 1802 (1 << IPCT_HELPER) |
@@ -1983,6 +2064,8 @@ ctnetlink_nfqueue_build(struct sk_buff *skb, struct nf_conn *ct)
1983 if (ct->mark && ctnetlink_dump_mark(skb, ct) < 0) 2064 if (ct->mark && ctnetlink_dump_mark(skb, ct) < 0)
1984 goto nla_put_failure; 2065 goto nla_put_failure;
1985#endif 2066#endif
2067 if (ctnetlink_dump_labels(skb, ct) < 0)
2068 goto nla_put_failure;
1986 rcu_read_unlock(); 2069 rcu_read_unlock();
1987 return 0; 2070 return 0;
1988 2071
@@ -2011,6 +2094,11 @@ ctnetlink_nfqueue_parse_ct(const struct nlattr *cda[], struct nf_conn *ct)
2011 if (err < 0) 2094 if (err < 0)
2012 return err; 2095 return err;
2013 } 2096 }
2097 if (cda[CTA_LABELS]) {
2098 err = ctnetlink_attach_labels(ct, cda);
2099 if (err < 0)
2100 return err;
2101 }
2014#if defined(CONFIG_NF_CONNTRACK_MARK) 2102#if defined(CONFIG_NF_CONNTRACK_MARK)
2015 if (cda[CTA_MARK]) 2103 if (cda[CTA_MARK])
2016 ct->mark = ntohl(nla_get_be32(cda[CTA_MARK])); 2104 ct->mark = ntohl(nla_get_be32(cda[CTA_MARK]));
diff --git a/net/netfilter/nf_conntrack_proto.c b/net/netfilter/nf_conntrack_proto.c
index 51e928db48c8..58ab4050830c 100644
--- a/net/netfilter/nf_conntrack_proto.c
+++ b/net/netfilter/nf_conntrack_proto.c
@@ -212,8 +212,7 @@ static void nf_ct_l3proto_unregister_sysctl(struct net *net,
212#endif 212#endif
213} 213}
214 214
215static int 215int nf_ct_l3proto_register(struct nf_conntrack_l3proto *proto)
216nf_conntrack_l3proto_register_net(struct nf_conntrack_l3proto *proto)
217{ 216{
218 int ret = 0; 217 int ret = 0;
219 struct nf_conntrack_l3proto *old; 218 struct nf_conntrack_l3proto *old;
@@ -242,8 +241,9 @@ out_unlock:
242 return ret; 241 return ret;
243 242
244} 243}
244EXPORT_SYMBOL_GPL(nf_ct_l3proto_register);
245 245
246int nf_conntrack_l3proto_register(struct net *net, 246int nf_ct_l3proto_pernet_register(struct net *net,
247 struct nf_conntrack_l3proto *proto) 247 struct nf_conntrack_l3proto *proto)
248{ 248{
249 int ret = 0; 249 int ret = 0;
@@ -254,22 +254,11 @@ int nf_conntrack_l3proto_register(struct net *net,
254 return ret; 254 return ret;
255 } 255 }
256 256
257 ret = nf_ct_l3proto_register_sysctl(net, proto); 257 return nf_ct_l3proto_register_sysctl(net, proto);
258 if (ret < 0)
259 return ret;
260
261 if (net == &init_net) {
262 ret = nf_conntrack_l3proto_register_net(proto);
263 if (ret < 0)
264 nf_ct_l3proto_unregister_sysctl(net, proto);
265 }
266
267 return ret;
268} 258}
269EXPORT_SYMBOL_GPL(nf_conntrack_l3proto_register); 259EXPORT_SYMBOL_GPL(nf_ct_l3proto_pernet_register);
270 260
271static void 261void nf_ct_l3proto_unregister(struct nf_conntrack_l3proto *proto)
272nf_conntrack_l3proto_unregister_net(struct nf_conntrack_l3proto *proto)
273{ 262{
274 BUG_ON(proto->l3proto >= AF_MAX); 263 BUG_ON(proto->l3proto >= AF_MAX);
275 264
@@ -283,19 +272,17 @@ nf_conntrack_l3proto_unregister_net(struct nf_conntrack_l3proto *proto)
283 272
284 synchronize_rcu(); 273 synchronize_rcu();
285} 274}
275EXPORT_SYMBOL_GPL(nf_ct_l3proto_unregister);
286 276
287void nf_conntrack_l3proto_unregister(struct net *net, 277void nf_ct_l3proto_pernet_unregister(struct net *net,
288 struct nf_conntrack_l3proto *proto) 278 struct nf_conntrack_l3proto *proto)
289{ 279{
290 if (net == &init_net)
291 nf_conntrack_l3proto_unregister_net(proto);
292
293 nf_ct_l3proto_unregister_sysctl(net, proto); 280 nf_ct_l3proto_unregister_sysctl(net, proto);
294 281
295 /* Remove all contrack entries for this protocol */ 282 /* Remove all contrack entries for this protocol */
296 nf_ct_iterate_cleanup(net, kill_l3proto, proto); 283 nf_ct_iterate_cleanup(net, kill_l3proto, proto);
297} 284}
298EXPORT_SYMBOL_GPL(nf_conntrack_l3proto_unregister); 285EXPORT_SYMBOL_GPL(nf_ct_l3proto_pernet_unregister);
299 286
300static struct nf_proto_net *nf_ct_l4proto_net(struct net *net, 287static struct nf_proto_net *nf_ct_l4proto_net(struct net *net,
301 struct nf_conntrack_l4proto *l4proto) 288 struct nf_conntrack_l4proto *l4proto)
@@ -376,8 +363,7 @@ void nf_ct_l4proto_unregister_sysctl(struct net *net,
376 363
377/* FIXME: Allow NULL functions and sub in pointers to generic for 364/* FIXME: Allow NULL functions and sub in pointers to generic for
378 them. --RR */ 365 them. --RR */
379static int 366int nf_ct_l4proto_register(struct nf_conntrack_l4proto *l4proto)
380nf_conntrack_l4proto_register_net(struct nf_conntrack_l4proto *l4proto)
381{ 367{
382 int ret = 0; 368 int ret = 0;
383 369
@@ -431,8 +417,9 @@ out_unlock:
431 mutex_unlock(&nf_ct_proto_mutex); 417 mutex_unlock(&nf_ct_proto_mutex);
432 return ret; 418 return ret;
433} 419}
420EXPORT_SYMBOL_GPL(nf_ct_l4proto_register);
434 421
435int nf_conntrack_l4proto_register(struct net *net, 422int nf_ct_l4proto_pernet_register(struct net *net,
436 struct nf_conntrack_l4proto *l4proto) 423 struct nf_conntrack_l4proto *l4proto)
437{ 424{
438 int ret = 0; 425 int ret = 0;
@@ -452,22 +439,13 @@ int nf_conntrack_l4proto_register(struct net *net,
452 if (ret < 0) 439 if (ret < 0)
453 goto out; 440 goto out;
454 441
455 if (net == &init_net) {
456 ret = nf_conntrack_l4proto_register_net(l4proto);
457 if (ret < 0) {
458 nf_ct_l4proto_unregister_sysctl(net, pn, l4proto);
459 goto out;
460 }
461 }
462
463 pn->users++; 442 pn->users++;
464out: 443out:
465 return ret; 444 return ret;
466} 445}
467EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_register); 446EXPORT_SYMBOL_GPL(nf_ct_l4proto_pernet_register);
468 447
469static void 448void nf_ct_l4proto_unregister(struct nf_conntrack_l4proto *l4proto)
470nf_conntrack_l4proto_unregister_net(struct nf_conntrack_l4proto *l4proto)
471{ 449{
472 BUG_ON(l4proto->l3proto >= PF_MAX); 450 BUG_ON(l4proto->l3proto >= PF_MAX);
473 451
@@ -482,15 +460,13 @@ nf_conntrack_l4proto_unregister_net(struct nf_conntrack_l4proto *l4proto)
482 460
483 synchronize_rcu(); 461 synchronize_rcu();
484} 462}
463EXPORT_SYMBOL_GPL(nf_ct_l4proto_unregister);
485 464
486void nf_conntrack_l4proto_unregister(struct net *net, 465void nf_ct_l4proto_pernet_unregister(struct net *net,
487 struct nf_conntrack_l4proto *l4proto) 466 struct nf_conntrack_l4proto *l4proto)
488{ 467{
489 struct nf_proto_net *pn = NULL; 468 struct nf_proto_net *pn = NULL;
490 469
491 if (net == &init_net)
492 nf_conntrack_l4proto_unregister_net(l4proto);
493
494 pn = nf_ct_l4proto_net(net, l4proto); 470 pn = nf_ct_l4proto_net(net, l4proto);
495 if (pn == NULL) 471 if (pn == NULL)
496 return; 472 return;
@@ -501,11 +477,10 @@ void nf_conntrack_l4proto_unregister(struct net *net,
501 /* Remove all contrack entries for this protocol */ 477 /* Remove all contrack entries for this protocol */
502 nf_ct_iterate_cleanup(net, kill_l4proto, l4proto); 478 nf_ct_iterate_cleanup(net, kill_l4proto, l4proto);
503} 479}
504EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_unregister); 480EXPORT_SYMBOL_GPL(nf_ct_l4proto_pernet_unregister);
505 481
506int nf_conntrack_proto_init(struct net *net) 482int nf_conntrack_proto_pernet_init(struct net *net)
507{ 483{
508 unsigned int i;
509 int err; 484 int err;
510 struct nf_proto_net *pn = nf_ct_l4proto_net(net, 485 struct nf_proto_net *pn = nf_ct_l4proto_net(net,
511 &nf_conntrack_l4proto_generic); 486 &nf_conntrack_l4proto_generic);
@@ -520,19 +495,12 @@ int nf_conntrack_proto_init(struct net *net)
520 if (err < 0) 495 if (err < 0)
521 return err; 496 return err;
522 497
523 if (net == &init_net) {
524 for (i = 0; i < AF_MAX; i++)
525 rcu_assign_pointer(nf_ct_l3protos[i],
526 &nf_conntrack_l3proto_generic);
527 }
528
529 pn->users++; 498 pn->users++;
530 return 0; 499 return 0;
531} 500}
532 501
533void nf_conntrack_proto_fini(struct net *net) 502void nf_conntrack_proto_pernet_fini(struct net *net)
534{ 503{
535 unsigned int i;
536 struct nf_proto_net *pn = nf_ct_l4proto_net(net, 504 struct nf_proto_net *pn = nf_ct_l4proto_net(net,
537 &nf_conntrack_l4proto_generic); 505 &nf_conntrack_l4proto_generic);
538 506
@@ -540,9 +508,21 @@ void nf_conntrack_proto_fini(struct net *net)
540 nf_ct_l4proto_unregister_sysctl(net, 508 nf_ct_l4proto_unregister_sysctl(net,
541 pn, 509 pn,
542 &nf_conntrack_l4proto_generic); 510 &nf_conntrack_l4proto_generic);
543 if (net == &init_net) { 511}
544 /* free l3proto protocol tables */ 512
545 for (i = 0; i < PF_MAX; i++) 513int nf_conntrack_proto_init(void)
546 kfree(nf_ct_protos[i]); 514{
547 } 515 unsigned int i;
516 for (i = 0; i < AF_MAX; i++)
517 rcu_assign_pointer(nf_ct_l3protos[i],
518 &nf_conntrack_l3proto_generic);
519 return 0;
520}
521
522void nf_conntrack_proto_fini(void)
523{
524 unsigned int i;
525 /* free l3proto protocol tables */
526 for (i = 0; i < PF_MAX; i++)
527 kfree(nf_ct_protos[i]);
548} 528}
diff --git a/net/netfilter/nf_conntrack_proto_dccp.c b/net/netfilter/nf_conntrack_proto_dccp.c
index a8ae287bc7af..432f95780003 100644
--- a/net/netfilter/nf_conntrack_proto_dccp.c
+++ b/net/netfilter/nf_conntrack_proto_dccp.c
@@ -935,32 +935,27 @@ static struct nf_conntrack_l4proto dccp_proto6 __read_mostly = {
935static __net_init int dccp_net_init(struct net *net) 935static __net_init int dccp_net_init(struct net *net)
936{ 936{
937 int ret = 0; 937 int ret = 0;
938 ret = nf_conntrack_l4proto_register(net, 938 ret = nf_ct_l4proto_pernet_register(net, &dccp_proto4);
939 &dccp_proto4);
940 if (ret < 0) { 939 if (ret < 0) {
941 pr_err("nf_conntrack_l4proto_dccp4 :protocol register failed.\n"); 940 pr_err("nf_conntrack_dccp4: pernet registration failed.\n");
942 goto out; 941 goto out;
943 } 942 }
944 ret = nf_conntrack_l4proto_register(net, 943 ret = nf_ct_l4proto_pernet_register(net, &dccp_proto6);
945 &dccp_proto6);
946 if (ret < 0) { 944 if (ret < 0) {
947 pr_err("nf_conntrack_l4proto_dccp6 :protocol register failed.\n"); 945 pr_err("nf_conntrack_dccp6: pernet registration failed.\n");
948 goto cleanup_dccp4; 946 goto cleanup_dccp4;
949 } 947 }
950 return 0; 948 return 0;
951cleanup_dccp4: 949cleanup_dccp4:
952 nf_conntrack_l4proto_unregister(net, 950 nf_ct_l4proto_pernet_unregister(net, &dccp_proto4);
953 &dccp_proto4);
954out: 951out:
955 return ret; 952 return ret;
956} 953}
957 954
958static __net_exit void dccp_net_exit(struct net *net) 955static __net_exit void dccp_net_exit(struct net *net)
959{ 956{
960 nf_conntrack_l4proto_unregister(net, 957 nf_ct_l4proto_pernet_unregister(net, &dccp_proto6);
961 &dccp_proto6); 958 nf_ct_l4proto_pernet_unregister(net, &dccp_proto4);
962 nf_conntrack_l4proto_unregister(net,
963 &dccp_proto4);
964} 959}
965 960
966static struct pernet_operations dccp_net_ops = { 961static struct pernet_operations dccp_net_ops = {
@@ -972,11 +967,33 @@ static struct pernet_operations dccp_net_ops = {
972 967
973static int __init nf_conntrack_proto_dccp_init(void) 968static int __init nf_conntrack_proto_dccp_init(void)
974{ 969{
975 return register_pernet_subsys(&dccp_net_ops); 970 int ret;
971
972 ret = nf_ct_l4proto_register(&dccp_proto4);
973 if (ret < 0)
974 goto out_dccp4;
975
976 ret = nf_ct_l4proto_register(&dccp_proto6);
977 if (ret < 0)
978 goto out_dccp6;
979
980 ret = register_pernet_subsys(&dccp_net_ops);
981 if (ret < 0)
982 goto out_pernet;
983
984 return 0;
985out_pernet:
986 nf_ct_l4proto_unregister(&dccp_proto6);
987out_dccp6:
988 nf_ct_l4proto_unregister(&dccp_proto4);
989out_dccp4:
990 return ret;
976} 991}
977 992
978static void __exit nf_conntrack_proto_dccp_fini(void) 993static void __exit nf_conntrack_proto_dccp_fini(void)
979{ 994{
995 nf_ct_l4proto_unregister(&dccp_proto6);
996 nf_ct_l4proto_unregister(&dccp_proto4);
980 unregister_pernet_subsys(&dccp_net_ops); 997 unregister_pernet_subsys(&dccp_net_ops);
981} 998}
982 999
diff --git a/net/netfilter/nf_conntrack_proto_gre.c b/net/netfilter/nf_conntrack_proto_gre.c
index b09b7af7f6f8..bd7d01d9c7e7 100644
--- a/net/netfilter/nf_conntrack_proto_gre.c
+++ b/net/netfilter/nf_conntrack_proto_gre.c
@@ -397,15 +397,15 @@ static struct nf_conntrack_l4proto nf_conntrack_l4proto_gre4 __read_mostly = {
397static int proto_gre_net_init(struct net *net) 397static int proto_gre_net_init(struct net *net)
398{ 398{
399 int ret = 0; 399 int ret = 0;
400 ret = nf_conntrack_l4proto_register(net, &nf_conntrack_l4proto_gre4); 400 ret = nf_ct_l4proto_pernet_register(net, &nf_conntrack_l4proto_gre4);
401 if (ret < 0) 401 if (ret < 0)
402 pr_err("nf_conntrack_l4proto_gre4 :protocol register failed.\n"); 402 pr_err("nf_conntrack_gre4: pernet registration failed.\n");
403 return ret; 403 return ret;
404} 404}
405 405
406static void proto_gre_net_exit(struct net *net) 406static void proto_gre_net_exit(struct net *net)
407{ 407{
408 nf_conntrack_l4proto_unregister(net, &nf_conntrack_l4proto_gre4); 408 nf_ct_l4proto_pernet_unregister(net, &nf_conntrack_l4proto_gre4);
409 nf_ct_gre_keymap_flush(net); 409 nf_ct_gre_keymap_flush(net);
410} 410}
411 411
@@ -418,11 +418,26 @@ static struct pernet_operations proto_gre_net_ops = {
418 418
419static int __init nf_ct_proto_gre_init(void) 419static int __init nf_ct_proto_gre_init(void)
420{ 420{
421 return register_pernet_subsys(&proto_gre_net_ops); 421 int ret;
422
423 ret = nf_ct_l4proto_register(&nf_conntrack_l4proto_gre4);
424 if (ret < 0)
425 goto out_gre4;
426
427 ret = register_pernet_subsys(&proto_gre_net_ops);
428 if (ret < 0)
429 goto out_pernet;
430
431 return 0;
432out_pernet:
433 nf_ct_l4proto_unregister(&nf_conntrack_l4proto_gre4);
434out_gre4:
435 return ret;
422} 436}
423 437
424static void __exit nf_ct_proto_gre_fini(void) 438static void __exit nf_ct_proto_gre_fini(void)
425{ 439{
440 nf_ct_l4proto_unregister(&nf_conntrack_l4proto_gre4);
426 unregister_pernet_subsys(&proto_gre_net_ops); 441 unregister_pernet_subsys(&proto_gre_net_ops);
427} 442}
428 443
diff --git a/net/netfilter/nf_conntrack_proto_sctp.c b/net/netfilter/nf_conntrack_proto_sctp.c
index c746d61f83ed..480f616d5936 100644
--- a/net/netfilter/nf_conntrack_proto_sctp.c
+++ b/net/netfilter/nf_conntrack_proto_sctp.c
@@ -853,33 +853,28 @@ static int sctp_net_init(struct net *net)
853{ 853{
854 int ret = 0; 854 int ret = 0;
855 855
856 ret = nf_conntrack_l4proto_register(net, 856 ret = nf_ct_l4proto_pernet_register(net, &nf_conntrack_l4proto_sctp4);
857 &nf_conntrack_l4proto_sctp4);
858 if (ret < 0) { 857 if (ret < 0) {
859 pr_err("nf_conntrack_l4proto_sctp4 :protocol register failed.\n"); 858 pr_err("nf_conntrack_sctp4: pernet registration failed.\n");
860 goto out; 859 goto out;
861 } 860 }
862 ret = nf_conntrack_l4proto_register(net, 861 ret = nf_ct_l4proto_pernet_register(net, &nf_conntrack_l4proto_sctp6);
863 &nf_conntrack_l4proto_sctp6);
864 if (ret < 0) { 862 if (ret < 0) {
865 pr_err("nf_conntrack_l4proto_sctp6 :protocol register failed.\n"); 863 pr_err("nf_conntrack_sctp6: pernet registration failed.\n");
866 goto cleanup_sctp4; 864 goto cleanup_sctp4;
867 } 865 }
868 return 0; 866 return 0;
869 867
870cleanup_sctp4: 868cleanup_sctp4:
871 nf_conntrack_l4proto_unregister(net, 869 nf_ct_l4proto_pernet_unregister(net, &nf_conntrack_l4proto_sctp4);
872 &nf_conntrack_l4proto_sctp4);
873out: 870out:
874 return ret; 871 return ret;
875} 872}
876 873
877static void sctp_net_exit(struct net *net) 874static void sctp_net_exit(struct net *net)
878{ 875{
879 nf_conntrack_l4proto_unregister(net, 876 nf_ct_l4proto_pernet_unregister(net, &nf_conntrack_l4proto_sctp6);
880 &nf_conntrack_l4proto_sctp6); 877 nf_ct_l4proto_pernet_unregister(net, &nf_conntrack_l4proto_sctp4);
881 nf_conntrack_l4proto_unregister(net,
882 &nf_conntrack_l4proto_sctp4);
883} 878}
884 879
885static struct pernet_operations sctp_net_ops = { 880static struct pernet_operations sctp_net_ops = {
@@ -891,11 +886,33 @@ static struct pernet_operations sctp_net_ops = {
891 886
892static int __init nf_conntrack_proto_sctp_init(void) 887static int __init nf_conntrack_proto_sctp_init(void)
893{ 888{
894 return register_pernet_subsys(&sctp_net_ops); 889 int ret;
890
891 ret = nf_ct_l4proto_register(&nf_conntrack_l4proto_sctp4);
892 if (ret < 0)
893 goto out_sctp4;
894
895 ret = nf_ct_l4proto_register(&nf_conntrack_l4proto_sctp6);
896 if (ret < 0)
897 goto out_sctp6;
898
899 ret = register_pernet_subsys(&sctp_net_ops);
900 if (ret < 0)
901 goto out_pernet;
902
903 return 0;
904out_pernet:
905 nf_ct_l4proto_unregister(&nf_conntrack_l4proto_sctp6);
906out_sctp6:
907 nf_ct_l4proto_unregister(&nf_conntrack_l4proto_sctp4);
908out_sctp4:
909 return ret;
895} 910}
896 911
897static void __exit nf_conntrack_proto_sctp_fini(void) 912static void __exit nf_conntrack_proto_sctp_fini(void)
898{ 913{
914 nf_ct_l4proto_unregister(&nf_conntrack_l4proto_sctp6);
915 nf_ct_l4proto_unregister(&nf_conntrack_l4proto_sctp4);
899 unregister_pernet_subsys(&sctp_net_ops); 916 unregister_pernet_subsys(&sctp_net_ops);
900} 917}
901 918
diff --git a/net/netfilter/nf_conntrack_proto_udplite.c b/net/netfilter/nf_conntrack_proto_udplite.c
index 4b66df209286..157489581c31 100644
--- a/net/netfilter/nf_conntrack_proto_udplite.c
+++ b/net/netfilter/nf_conntrack_proto_udplite.c
@@ -336,30 +336,28 @@ static int udplite_net_init(struct net *net)
336{ 336{
337 int ret = 0; 337 int ret = 0;
338 338
339 ret = nf_conntrack_l4proto_register(net, 339 ret = nf_ct_l4proto_pernet_register(net, &nf_conntrack_l4proto_udplite4);
340 &nf_conntrack_l4proto_udplite4);
341 if (ret < 0) { 340 if (ret < 0) {
342 pr_err("nf_conntrack_l4proto_udplite4 :protocol register failed.\n"); 341 pr_err("nf_conntrack_udplite4: pernet registration failed.\n");
343 goto out; 342 goto out;
344 } 343 }
345 ret = nf_conntrack_l4proto_register(net, 344 ret = nf_ct_l4proto_pernet_register(net, &nf_conntrack_l4proto_udplite6);
346 &nf_conntrack_l4proto_udplite6);
347 if (ret < 0) { 345 if (ret < 0) {
348 pr_err("nf_conntrack_l4proto_udplite4 :protocol register failed.\n"); 346 pr_err("nf_conntrack_udplite6: pernet registration failed.\n");
349 goto cleanup_udplite4; 347 goto cleanup_udplite4;
350 } 348 }
351 return 0; 349 return 0;
352 350
353cleanup_udplite4: 351cleanup_udplite4:
354 nf_conntrack_l4proto_unregister(net, &nf_conntrack_l4proto_udplite4); 352 nf_ct_l4proto_pernet_unregister(net, &nf_conntrack_l4proto_udplite4);
355out: 353out:
356 return ret; 354 return ret;
357} 355}
358 356
359static void udplite_net_exit(struct net *net) 357static void udplite_net_exit(struct net *net)
360{ 358{
361 nf_conntrack_l4proto_unregister(net, &nf_conntrack_l4proto_udplite6); 359 nf_ct_l4proto_pernet_unregister(net, &nf_conntrack_l4proto_udplite6);
362 nf_conntrack_l4proto_unregister(net, &nf_conntrack_l4proto_udplite4); 360 nf_ct_l4proto_pernet_unregister(net, &nf_conntrack_l4proto_udplite4);
363} 361}
364 362
365static struct pernet_operations udplite_net_ops = { 363static struct pernet_operations udplite_net_ops = {
@@ -371,11 +369,33 @@ static struct pernet_operations udplite_net_ops = {
371 369
372static int __init nf_conntrack_proto_udplite_init(void) 370static int __init nf_conntrack_proto_udplite_init(void)
373{ 371{
374 return register_pernet_subsys(&udplite_net_ops); 372 int ret;
373
374 ret = nf_ct_l4proto_register(&nf_conntrack_l4proto_udplite4);
375 if (ret < 0)
376 goto out_udplite4;
377
378 ret = nf_ct_l4proto_register(&nf_conntrack_l4proto_udplite6);
379 if (ret < 0)
380 goto out_udplite6;
381
382 ret = register_pernet_subsys(&udplite_net_ops);
383 if (ret < 0)
384 goto out_pernet;
385
386 return 0;
387out_pernet:
388 nf_ct_l4proto_unregister(&nf_conntrack_l4proto_udplite6);
389out_udplite6:
390 nf_ct_l4proto_unregister(&nf_conntrack_l4proto_udplite4);
391out_udplite4:
392 return ret;
375} 393}
376 394
377static void __exit nf_conntrack_proto_udplite_exit(void) 395static void __exit nf_conntrack_proto_udplite_exit(void)
378{ 396{
397 nf_ct_l4proto_unregister(&nf_conntrack_l4proto_udplite6);
398 nf_ct_l4proto_unregister(&nf_conntrack_l4proto_udplite4);
379 unregister_pernet_subsys(&udplite_net_ops); 399 unregister_pernet_subsys(&udplite_net_ops);
380} 400}
381 401
diff --git a/net/netfilter/nf_conntrack_sip.c b/net/netfilter/nf_conntrack_sip.c
index df8f4f284481..72a67bbe3518 100644
--- a/net/netfilter/nf_conntrack_sip.c
+++ b/net/netfilter/nf_conntrack_sip.c
@@ -1440,8 +1440,25 @@ static int process_sip_request(struct sk_buff *skb, unsigned int protoff,
1440{ 1440{
1441 enum ip_conntrack_info ctinfo; 1441 enum ip_conntrack_info ctinfo;
1442 struct nf_conn *ct = nf_ct_get(skb, &ctinfo); 1442 struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
1443 struct nf_ct_sip_master *ct_sip_info = nfct_help_data(ct);
1444 enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
1443 unsigned int matchoff, matchlen; 1445 unsigned int matchoff, matchlen;
1444 unsigned int cseq, i; 1446 unsigned int cseq, i;
1447 union nf_inet_addr addr;
1448 __be16 port;
1449
1450 /* Many Cisco IP phones use a high source port for SIP requests, but
1451 * listen for the response on port 5060. If we are the local
1452 * router for one of these phones, save the port number from the
1453 * Via: header so that nf_nat_sip can redirect the responses to
1454 * the correct port.
1455 */
1456 if (ct_sip_parse_header_uri(ct, *dptr, NULL, *datalen,
1457 SIP_HDR_VIA_UDP, NULL, &matchoff,
1458 &matchlen, &addr, &port) > 0 &&
1459 port != ct->tuplehash[dir].tuple.src.u.udp.port &&
1460 nf_inet_addr_cmp(&addr, &ct->tuplehash[dir].tuple.src.u3))
1461 ct_sip_info->forced_dport = port;
1445 1462
1446 for (i = 0; i < ARRAY_SIZE(sip_handlers); i++) { 1463 for (i = 0; i < ARRAY_SIZE(sip_handlers); i++) {
1447 const struct sip_handler *handler; 1464 const struct sip_handler *handler;
diff --git a/net/netfilter/nf_conntrack_snmp.c b/net/netfilter/nf_conntrack_snmp.c
index 6e545e26289e..87b95a2c270c 100644
--- a/net/netfilter/nf_conntrack_snmp.c
+++ b/net/netfilter/nf_conntrack_snmp.c
@@ -16,6 +16,7 @@
16#include <net/netfilter/nf_conntrack.h> 16#include <net/netfilter/nf_conntrack.h>
17#include <net/netfilter/nf_conntrack_helper.h> 17#include <net/netfilter/nf_conntrack_helper.h>
18#include <net/netfilter/nf_conntrack_expect.h> 18#include <net/netfilter/nf_conntrack_expect.h>
19#include <linux/netfilter/nf_conntrack_snmp.h>
19 20
20#define SNMP_PORT 161 21#define SNMP_PORT 161
21 22
diff --git a/net/netfilter/nf_conntrack_standalone.c b/net/netfilter/nf_conntrack_standalone.c
index e7185c684816..7936bf7f90ba 100644
--- a/net/netfilter/nf_conntrack_standalone.c
+++ b/net/netfilter/nf_conntrack_standalone.c
@@ -472,13 +472,6 @@ static int nf_conntrack_standalone_init_sysctl(struct net *net)
472{ 472{
473 struct ctl_table *table; 473 struct ctl_table *table;
474 474
475 if (net_eq(net, &init_net)) {
476 nf_ct_netfilter_header =
477 register_net_sysctl(&init_net, "net", nf_ct_netfilter_table);
478 if (!nf_ct_netfilter_header)
479 goto out;
480 }
481
482 table = kmemdup(nf_ct_sysctl_table, sizeof(nf_ct_sysctl_table), 475 table = kmemdup(nf_ct_sysctl_table, sizeof(nf_ct_sysctl_table),
483 GFP_KERNEL); 476 GFP_KERNEL);
484 if (!table) 477 if (!table)
@@ -502,10 +495,6 @@ static int nf_conntrack_standalone_init_sysctl(struct net *net)
502out_unregister_netfilter: 495out_unregister_netfilter:
503 kfree(table); 496 kfree(table);
504out_kmemdup: 497out_kmemdup:
505 if (net_eq(net, &init_net))
506 unregister_net_sysctl_table(nf_ct_netfilter_header);
507out:
508 printk(KERN_ERR "nf_conntrack: can't register to sysctl.\n");
509 return -ENOMEM; 498 return -ENOMEM;
510} 499}
511 500
@@ -513,8 +502,6 @@ static void nf_conntrack_standalone_fini_sysctl(struct net *net)
513{ 502{
514 struct ctl_table *table; 503 struct ctl_table *table;
515 504
516 if (net_eq(net, &init_net))
517 unregister_net_sysctl_table(nf_ct_netfilter_header);
518 table = net->ct.sysctl_header->ctl_table_arg; 505 table = net->ct.sysctl_header->ctl_table_arg;
519 unregister_net_sysctl_table(net->ct.sysctl_header); 506 unregister_net_sysctl_table(net->ct.sysctl_header);
520 kfree(table); 507 kfree(table);
@@ -530,51 +517,85 @@ static void nf_conntrack_standalone_fini_sysctl(struct net *net)
530} 517}
531#endif /* CONFIG_SYSCTL */ 518#endif /* CONFIG_SYSCTL */
532 519
533static int nf_conntrack_net_init(struct net *net) 520static int nf_conntrack_pernet_init(struct net *net)
534{ 521{
535 int ret; 522 int ret;
536 523
537 ret = nf_conntrack_init(net); 524 ret = nf_conntrack_init_net(net);
538 if (ret < 0) 525 if (ret < 0)
539 goto out_init; 526 goto out_init;
527
540 ret = nf_conntrack_standalone_init_proc(net); 528 ret = nf_conntrack_standalone_init_proc(net);
541 if (ret < 0) 529 if (ret < 0)
542 goto out_proc; 530 goto out_proc;
531
543 net->ct.sysctl_checksum = 1; 532 net->ct.sysctl_checksum = 1;
544 net->ct.sysctl_log_invalid = 0; 533 net->ct.sysctl_log_invalid = 0;
545 ret = nf_conntrack_standalone_init_sysctl(net); 534 ret = nf_conntrack_standalone_init_sysctl(net);
546 if (ret < 0) 535 if (ret < 0)
547 goto out_sysctl; 536 goto out_sysctl;
537
548 return 0; 538 return 0;
549 539
550out_sysctl: 540out_sysctl:
551 nf_conntrack_standalone_fini_proc(net); 541 nf_conntrack_standalone_fini_proc(net);
552out_proc: 542out_proc:
553 nf_conntrack_cleanup(net); 543 nf_conntrack_cleanup_net(net);
554out_init: 544out_init:
555 return ret; 545 return ret;
556} 546}
557 547
558static void nf_conntrack_net_exit(struct net *net) 548static void nf_conntrack_pernet_exit(struct net *net)
559{ 549{
560 nf_conntrack_standalone_fini_sysctl(net); 550 nf_conntrack_standalone_fini_sysctl(net);
561 nf_conntrack_standalone_fini_proc(net); 551 nf_conntrack_standalone_fini_proc(net);
562 nf_conntrack_cleanup(net); 552 nf_conntrack_cleanup_net(net);
563} 553}
564 554
565static struct pernet_operations nf_conntrack_net_ops = { 555static struct pernet_operations nf_conntrack_net_ops = {
566 .init = nf_conntrack_net_init, 556 .init = nf_conntrack_pernet_init,
567 .exit = nf_conntrack_net_exit, 557 .exit = nf_conntrack_pernet_exit,
568}; 558};
569 559
570static int __init nf_conntrack_standalone_init(void) 560static int __init nf_conntrack_standalone_init(void)
571{ 561{
572 return register_pernet_subsys(&nf_conntrack_net_ops); 562 int ret = nf_conntrack_init_start();
563 if (ret < 0)
564 goto out_start;
565
566#ifdef CONFIG_SYSCTL
567 nf_ct_netfilter_header =
568 register_net_sysctl(&init_net, "net", nf_ct_netfilter_table);
569 if (!nf_ct_netfilter_header) {
570 pr_err("nf_conntrack: can't register to sysctl.\n");
571 goto out_sysctl;
572 }
573#endif
574
575 ret = register_pernet_subsys(&nf_conntrack_net_ops);
576 if (ret < 0)
577 goto out_pernet;
578
579 nf_conntrack_init_end();
580 return 0;
581
582out_pernet:
583#ifdef CONFIG_SYSCTL
584 unregister_net_sysctl_table(nf_ct_netfilter_header);
585out_sysctl:
586#endif
587 nf_conntrack_cleanup_end();
588out_start:
589 return ret;
573} 590}
574 591
575static void __exit nf_conntrack_standalone_fini(void) 592static void __exit nf_conntrack_standalone_fini(void)
576{ 593{
594 nf_conntrack_cleanup_start();
577 unregister_pernet_subsys(&nf_conntrack_net_ops); 595 unregister_pernet_subsys(&nf_conntrack_net_ops);
596#ifdef CONFIG_SYSCTL
597 unregister_net_sysctl_table(nf_ct_netfilter_header);
598#endif
578 nf_conntrack_cleanup_end(); 599 nf_conntrack_cleanup_end();
579} 600}
580 601
diff --git a/net/netfilter/nf_conntrack_timeout.c b/net/netfilter/nf_conntrack_timeout.c
index a878ce5b252c..93da609d9d29 100644
--- a/net/netfilter/nf_conntrack_timeout.c
+++ b/net/netfilter/nf_conntrack_timeout.c
@@ -37,24 +37,15 @@ static struct nf_ct_ext_type timeout_extend __read_mostly = {
37 .id = NF_CT_EXT_TIMEOUT, 37 .id = NF_CT_EXT_TIMEOUT,
38}; 38};
39 39
40int nf_conntrack_timeout_init(struct net *net) 40int nf_conntrack_timeout_init(void)
41{ 41{
42 int ret = 0; 42 int ret = nf_ct_extend_register(&timeout_extend);
43 43 if (ret < 0)
44 if (net_eq(net, &init_net)) { 44 pr_err("nf_ct_timeout: Unable to register timeout extension.\n");
45 ret = nf_ct_extend_register(&timeout_extend); 45 return ret;
46 if (ret < 0) {
47 printk(KERN_ERR "nf_ct_timeout: Unable to register "
48 "timeout extension.\n");
49 return ret;
50 }
51 }
52
53 return 0;
54} 46}
55 47
56void nf_conntrack_timeout_fini(struct net *net) 48void nf_conntrack_timeout_fini(void)
57{ 49{
58 if (net_eq(net, &init_net)) 50 nf_ct_extend_unregister(&timeout_extend);
59 nf_ct_extend_unregister(&timeout_extend);
60} 51}
diff --git a/net/netfilter/nf_conntrack_timestamp.c b/net/netfilter/nf_conntrack_timestamp.c
index 7ea8026f07c9..902fb0a6b38a 100644
--- a/net/netfilter/nf_conntrack_timestamp.c
+++ b/net/netfilter/nf_conntrack_timestamp.c
@@ -88,37 +88,28 @@ static void nf_conntrack_tstamp_fini_sysctl(struct net *net)
88} 88}
89#endif 89#endif
90 90
91int nf_conntrack_tstamp_init(struct net *net) 91int nf_conntrack_tstamp_pernet_init(struct net *net)
92{ 92{
93 int ret;
94
95 net->ct.sysctl_tstamp = nf_ct_tstamp; 93 net->ct.sysctl_tstamp = nf_ct_tstamp;
94 return nf_conntrack_tstamp_init_sysctl(net);
95}
96 96
97 if (net_eq(net, &init_net)) { 97void nf_conntrack_tstamp_pernet_fini(struct net *net)
98 ret = nf_ct_extend_register(&tstamp_extend); 98{
99 if (ret < 0) { 99 nf_conntrack_tstamp_fini_sysctl(net);
100 printk(KERN_ERR "nf_ct_tstamp: Unable to register " 100 nf_ct_extend_unregister(&tstamp_extend);
101 "extension\n"); 101}
102 goto out_extend_register;
103 }
104 }
105 102
106 ret = nf_conntrack_tstamp_init_sysctl(net); 103int nf_conntrack_tstamp_init(void)
104{
105 int ret;
106 ret = nf_ct_extend_register(&tstamp_extend);
107 if (ret < 0) 107 if (ret < 0)
108 goto out_sysctl; 108 pr_err("nf_ct_tstamp: Unable to register extension\n");
109
110 return 0;
111
112out_sysctl:
113 if (net_eq(net, &init_net))
114 nf_ct_extend_unregister(&tstamp_extend);
115out_extend_register:
116 return ret; 109 return ret;
117} 110}
118 111
119void nf_conntrack_tstamp_fini(struct net *net) 112void nf_conntrack_tstamp_fini(void)
120{ 113{
121 nf_conntrack_tstamp_fini_sysctl(net); 114 nf_ct_extend_unregister(&tstamp_extend);
122 if (net_eq(net, &init_net))
123 nf_ct_extend_unregister(&tstamp_extend);
124} 115}
diff --git a/net/netfilter/nf_nat_sip.c b/net/netfilter/nf_nat_sip.c
index 16303c752213..5951146e7688 100644
--- a/net/netfilter/nf_nat_sip.c
+++ b/net/netfilter/nf_nat_sip.c
@@ -95,6 +95,7 @@ static int map_addr(struct sk_buff *skb, unsigned int protoff,
95 enum ip_conntrack_info ctinfo; 95 enum ip_conntrack_info ctinfo;
96 struct nf_conn *ct = nf_ct_get(skb, &ctinfo); 96 struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
97 enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo); 97 enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
98 struct nf_ct_sip_master *ct_sip_info = nfct_help_data(ct);
98 char buffer[INET6_ADDRSTRLEN + sizeof("[]:nnnnn")]; 99 char buffer[INET6_ADDRSTRLEN + sizeof("[]:nnnnn")];
99 unsigned int buflen; 100 unsigned int buflen;
100 union nf_inet_addr newaddr; 101 union nf_inet_addr newaddr;
@@ -107,7 +108,8 @@ static int map_addr(struct sk_buff *skb, unsigned int protoff,
107 } else if (nf_inet_addr_cmp(&ct->tuplehash[dir].tuple.dst.u3, addr) && 108 } else if (nf_inet_addr_cmp(&ct->tuplehash[dir].tuple.dst.u3, addr) &&
108 ct->tuplehash[dir].tuple.dst.u.udp.port == port) { 109 ct->tuplehash[dir].tuple.dst.u.udp.port == port) {
109 newaddr = ct->tuplehash[!dir].tuple.src.u3; 110 newaddr = ct->tuplehash[!dir].tuple.src.u3;
110 newport = ct->tuplehash[!dir].tuple.src.u.udp.port; 111 newport = ct_sip_info->forced_dport ? :
112 ct->tuplehash[!dir].tuple.src.u.udp.port;
111 } else 113 } else
112 return 1; 114 return 1;
113 115
@@ -144,6 +146,7 @@ static unsigned int nf_nat_sip(struct sk_buff *skb, unsigned int protoff,
144 enum ip_conntrack_info ctinfo; 146 enum ip_conntrack_info ctinfo;
145 struct nf_conn *ct = nf_ct_get(skb, &ctinfo); 147 struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
146 enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo); 148 enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
149 struct nf_ct_sip_master *ct_sip_info = nfct_help_data(ct);
147 unsigned int coff, matchoff, matchlen; 150 unsigned int coff, matchoff, matchlen;
148 enum sip_header_types hdr; 151 enum sip_header_types hdr;
149 union nf_inet_addr addr; 152 union nf_inet_addr addr;
@@ -258,6 +261,21 @@ next:
258 !map_sip_addr(skb, protoff, dataoff, dptr, datalen, SIP_HDR_TO)) 261 !map_sip_addr(skb, protoff, dataoff, dptr, datalen, SIP_HDR_TO))
259 return NF_DROP; 262 return NF_DROP;
260 263
264 /* Mangle destination port for Cisco phones, then fix up checksums */
265 if (dir == IP_CT_DIR_REPLY && ct_sip_info->forced_dport) {
266 struct udphdr *uh;
267
268 if (!skb_make_writable(skb, skb->len))
269 return NF_DROP;
270
271 uh = (void *)skb->data + protoff;
272 uh->dest = ct_sip_info->forced_dport;
273
274 if (!nf_nat_mangle_udp_packet(skb, ct, ctinfo, protoff,
275 0, 0, NULL, 0))
276 return NF_DROP;
277 }
278
261 return NF_ACCEPT; 279 return NF_ACCEPT;
262} 280}
263 281
@@ -311,8 +329,10 @@ static unsigned int nf_nat_sip_expect(struct sk_buff *skb, unsigned int protoff,
311 enum ip_conntrack_info ctinfo; 329 enum ip_conntrack_info ctinfo;
312 struct nf_conn *ct = nf_ct_get(skb, &ctinfo); 330 struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
313 enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo); 331 enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
332 struct nf_ct_sip_master *ct_sip_info = nfct_help_data(ct);
314 union nf_inet_addr newaddr; 333 union nf_inet_addr newaddr;
315 u_int16_t port; 334 u_int16_t port;
335 __be16 srcport;
316 char buffer[INET6_ADDRSTRLEN + sizeof("[]:nnnnn")]; 336 char buffer[INET6_ADDRSTRLEN + sizeof("[]:nnnnn")];
317 unsigned int buflen; 337 unsigned int buflen;
318 338
@@ -326,8 +346,9 @@ static unsigned int nf_nat_sip_expect(struct sk_buff *skb, unsigned int protoff,
326 /* If the signalling port matches the connection's source port in the 346 /* If the signalling port matches the connection's source port in the
327 * original direction, try to use the destination port in the opposite 347 * original direction, try to use the destination port in the opposite
328 * direction. */ 348 * direction. */
329 if (exp->tuple.dst.u.udp.port == 349 srcport = ct_sip_info->forced_dport ? :
330 ct->tuplehash[dir].tuple.src.u.udp.port) 350 ct->tuplehash[dir].tuple.src.u.udp.port;
351 if (exp->tuple.dst.u.udp.port == srcport)
331 port = ntohs(ct->tuplehash[!dir].tuple.dst.u.udp.port); 352 port = ntohs(ct->tuplehash[!dir].tuple.dst.u.udp.port);
332 else 353 else
333 port = ntohs(exp->tuple.dst.u.udp.port); 354 port = ntohs(exp->tuple.dst.u.udp.port);
diff --git a/net/netfilter/xt_bpf.c b/net/netfilter/xt_bpf.c
new file mode 100644
index 000000000000..12d4da8e6c77
--- /dev/null
+++ b/net/netfilter/xt_bpf.c
@@ -0,0 +1,73 @@
1/* Xtables module to match packets using a BPF filter.
2 * Copyright 2013 Google Inc.
3 * Written by Willem de Bruijn <willemb@google.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
8 */
9
10#include <linux/module.h>
11#include <linux/skbuff.h>
12#include <linux/filter.h>
13
14#include <linux/netfilter/xt_bpf.h>
15#include <linux/netfilter/x_tables.h>
16
17MODULE_AUTHOR("Willem de Bruijn <willemb@google.com>");
18MODULE_DESCRIPTION("Xtables: BPF filter match");
19MODULE_LICENSE("GPL");
20MODULE_ALIAS("ipt_bpf");
21MODULE_ALIAS("ip6t_bpf");
22
23static int bpf_mt_check(const struct xt_mtchk_param *par)
24{
25 struct xt_bpf_info *info = par->matchinfo;
26 struct sock_fprog program;
27
28 program.len = info->bpf_program_num_elem;
29 program.filter = (struct sock_filter __user *) info->bpf_program;
30 if (sk_unattached_filter_create(&info->filter, &program)) {
31 pr_info("bpf: check failed: parse error\n");
32 return -EINVAL;
33 }
34
35 return 0;
36}
37
38static bool bpf_mt(const struct sk_buff *skb, struct xt_action_param *par)
39{
40 const struct xt_bpf_info *info = par->matchinfo;
41
42 return SK_RUN_FILTER(info->filter, skb);
43}
44
45static void bpf_mt_destroy(const struct xt_mtdtor_param *par)
46{
47 const struct xt_bpf_info *info = par->matchinfo;
48 sk_unattached_filter_destroy(info->filter);
49}
50
51static struct xt_match bpf_mt_reg __read_mostly = {
52 .name = "bpf",
53 .revision = 0,
54 .family = NFPROTO_UNSPEC,
55 .checkentry = bpf_mt_check,
56 .match = bpf_mt,
57 .destroy = bpf_mt_destroy,
58 .matchsize = sizeof(struct xt_bpf_info),
59 .me = THIS_MODULE,
60};
61
62static int __init bpf_mt_init(void)
63{
64 return xt_register_match(&bpf_mt_reg);
65}
66
67static void __exit bpf_mt_exit(void)
68{
69 xt_unregister_match(&bpf_mt_reg);
70}
71
72module_init(bpf_mt_init);
73module_exit(bpf_mt_exit);
diff --git a/net/netfilter/xt_connlabel.c b/net/netfilter/xt_connlabel.c
new file mode 100644
index 000000000000..9f8719df2001
--- /dev/null
+++ b/net/netfilter/xt_connlabel.c
@@ -0,0 +1,99 @@
1/*
2 * (C) 2013 Astaro GmbH & Co KG
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8
9#include <linux/module.h>
10#include <linux/skbuff.h>
11#include <net/netfilter/nf_conntrack.h>
12#include <net/netfilter/nf_conntrack_labels.h>
13#include <linux/netfilter/x_tables.h>
14
15MODULE_LICENSE("GPL");
16MODULE_AUTHOR("Florian Westphal <fw@strlen.de>");
17MODULE_DESCRIPTION("Xtables: add/match connection trackling labels");
18MODULE_ALIAS("ipt_connlabel");
19MODULE_ALIAS("ip6t_connlabel");
20
21static bool
22connlabel_mt(const struct sk_buff *skb, struct xt_action_param *par)
23{
24 const struct xt_connlabel_mtinfo *info = par->matchinfo;
25 enum ip_conntrack_info ctinfo;
26 struct nf_conn *ct;
27 bool invert = info->options & XT_CONNLABEL_OP_INVERT;
28
29 ct = nf_ct_get(skb, &ctinfo);
30 if (ct == NULL || nf_ct_is_untracked(ct))
31 return invert;
32
33 if (info->options & XT_CONNLABEL_OP_SET)
34 return (nf_connlabel_set(ct, info->bit) == 0) ^ invert;
35
36 return nf_connlabel_match(ct, info->bit) ^ invert;
37}
38
39static int connlabel_mt_check(const struct xt_mtchk_param *par)
40{
41 const int options = XT_CONNLABEL_OP_INVERT |
42 XT_CONNLABEL_OP_SET;
43 struct xt_connlabel_mtinfo *info = par->matchinfo;
44 int ret;
45 size_t words;
46
47 if (info->bit > XT_CONNLABEL_MAXBIT)
48 return -ERANGE;
49
50 if (info->options & ~options) {
51 pr_err("Unknown options in mask %x\n", info->options);
52 return -EINVAL;
53 }
54
55 ret = nf_ct_l3proto_try_module_get(par->family);
56 if (ret < 0) {
57 pr_info("cannot load conntrack support for proto=%u\n",
58 par->family);
59 return ret;
60 }
61
62 par->net->ct.labels_used++;
63 words = BITS_TO_LONGS(info->bit+1);
64 if (words > par->net->ct.label_words)
65 par->net->ct.label_words = words;
66
67 return ret;
68}
69
70static void connlabel_mt_destroy(const struct xt_mtdtor_param *par)
71{
72 par->net->ct.labels_used--;
73 if (par->net->ct.labels_used == 0)
74 par->net->ct.label_words = 0;
75 nf_ct_l3proto_module_put(par->family);
76}
77
78static struct xt_match connlabels_mt_reg __read_mostly = {
79 .name = "connlabel",
80 .family = NFPROTO_UNSPEC,
81 .checkentry = connlabel_mt_check,
82 .match = connlabel_mt,
83 .matchsize = sizeof(struct xt_connlabel_mtinfo),
84 .destroy = connlabel_mt_destroy,
85 .me = THIS_MODULE,
86};
87
88static int __init connlabel_mt_init(void)
89{
90 return xt_register_match(&connlabels_mt_reg);
91}
92
93static void __exit connlabel_mt_exit(void)
94{
95 xt_unregister_match(&connlabels_mt_reg);
96}
97
98module_init(connlabel_mt_init);
99module_exit(connlabel_mt_exit);