aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/netfilter/nf_conntrack_l3proto.h11
-rw-r--r--net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c22
-rw-r--r--net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c26
-rw-r--r--net/netfilter/nf_conntrack_proto.c31
4 files changed, 49 insertions, 41 deletions
diff --git a/include/net/netfilter/nf_conntrack_l3proto.h b/include/net/netfilter/nf_conntrack_l3proto.h
index 6f7c13f4ac03..3bb89eac3fa1 100644
--- a/include/net/netfilter/nf_conntrack_l3proto.h
+++ b/include/net/netfilter/nf_conntrack_l3proto.h
@@ -76,11 +76,16 @@ struct nf_conntrack_l3proto {
76 76
77extern struct nf_conntrack_l3proto __rcu *nf_ct_l3protos[AF_MAX]; 77extern struct nf_conntrack_l3proto __rcu *nf_ct_l3protos[AF_MAX];
78 78
79/* Protocol registration. */ 79/* Protocol pernet registration. */
80extern int nf_conntrack_l3proto_register(struct net *net, 80extern int nf_ct_l3proto_pernet_register(struct net *net,
81 struct nf_conntrack_l3proto *proto); 81 struct nf_conntrack_l3proto *proto);
82extern void nf_conntrack_l3proto_unregister(struct net *net, 82extern void nf_ct_l3proto_pernet_unregister(struct net *net,
83 struct nf_conntrack_l3proto *proto); 83 struct nf_conntrack_l3proto *proto);
84
85/* Protocol global registration. */
86extern int nf_ct_l3proto_register(struct nf_conntrack_l3proto *proto);
87extern void nf_ct_l3proto_unregister(struct nf_conntrack_l3proto *proto);
88
84extern struct nf_conntrack_l3proto *nf_ct_l3proto_find_get(u_int16_t l3proto); 89extern struct nf_conntrack_l3proto *nf_ct_l3proto_find_get(u_int16_t l3proto);
85extern void nf_ct_l3proto_put(struct nf_conntrack_l3proto *p); 90extern void nf_ct_l3proto_put(struct nf_conntrack_l3proto *p);
86 91
diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
index fcdd0c2406e6..76b84fc9acfc 100644
--- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
+++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
@@ -438,10 +438,9 @@ static int ipv4_net_init(struct net *net)
438 pr_err("nf_conntrack_l4proto_icmp4 :protocol register failed\n"); 438 pr_err("nf_conntrack_l4proto_icmp4 :protocol register failed\n");
439 goto out_icmp; 439 goto out_icmp;
440 } 440 }
441 ret = nf_conntrack_l3proto_register(net, 441 ret = nf_ct_l3proto_pernet_register(net, &nf_conntrack_l3proto_ipv4);
442 &nf_conntrack_l3proto_ipv4);
443 if (ret < 0) { 442 if (ret < 0) {
444 pr_err("nf_conntrack_l3proto_ipv4 :protocol register failed\n"); 443 pr_err("nf_conntrack_ipv4: pernet registration failed\n");
445 goto out_ipv4; 444 goto out_ipv4;
446 } 445 }
447 return 0; 446 return 0;
@@ -460,8 +459,7 @@ out_tcp:
460 459
461static void ipv4_net_exit(struct net *net) 460static void ipv4_net_exit(struct net *net)
462{ 461{
463 nf_conntrack_l3proto_unregister(net, 462 nf_ct_l3proto_pernet_unregister(net, &nf_conntrack_l3proto_ipv4);
464 &nf_conntrack_l3proto_ipv4);
465 nf_conntrack_l4proto_unregister(net, 463 nf_conntrack_l4proto_unregister(net,
466 &nf_conntrack_l4proto_icmp); 464 &nf_conntrack_l4proto_icmp);
467 nf_conntrack_l4proto_unregister(net, 465 nf_conntrack_l4proto_unregister(net,
@@ -500,16 +498,25 @@ static int __init nf_conntrack_l3proto_ipv4_init(void)
500 pr_err("nf_conntrack_ipv4: can't register hooks.\n"); 498 pr_err("nf_conntrack_ipv4: can't register hooks.\n");
501 goto cleanup_pernet; 499 goto cleanup_pernet;
502 } 500 }
501
502 ret = nf_ct_l3proto_register(&nf_conntrack_l3proto_ipv4);
503 if (ret < 0) {
504 pr_err("nf_conntrack_ipv4: can't register ipv4 proto.\n");
505 goto cleanup_hooks;
506 }
507
503#if defined(CONFIG_PROC_FS) && defined(CONFIG_NF_CONNTRACK_PROC_COMPAT) 508#if defined(CONFIG_PROC_FS) && defined(CONFIG_NF_CONNTRACK_PROC_COMPAT)
504 ret = nf_conntrack_ipv4_compat_init(); 509 ret = nf_conntrack_ipv4_compat_init();
505 if (ret < 0) 510 if (ret < 0)
506 goto cleanup_hooks; 511 goto cleanup_proto;
507#endif 512#endif
508 return ret; 513 return ret;
509#if defined(CONFIG_PROC_FS) && defined(CONFIG_NF_CONNTRACK_PROC_COMPAT) 514#if defined(CONFIG_PROC_FS) && defined(CONFIG_NF_CONNTRACK_PROC_COMPAT)
515 cleanup_proto:
516 nf_ct_l3proto_unregister(&nf_conntrack_l3proto_ipv4);
517#endif
510 cleanup_hooks: 518 cleanup_hooks:
511 nf_unregister_hooks(ipv4_conntrack_ops, ARRAY_SIZE(ipv4_conntrack_ops)); 519 nf_unregister_hooks(ipv4_conntrack_ops, ARRAY_SIZE(ipv4_conntrack_ops));
512#endif
513 cleanup_pernet: 520 cleanup_pernet:
514 unregister_pernet_subsys(&ipv4_net_ops); 521 unregister_pernet_subsys(&ipv4_net_ops);
515 cleanup_sockopt: 522 cleanup_sockopt:
@@ -523,6 +530,7 @@ static void __exit nf_conntrack_l3proto_ipv4_fini(void)
523#if defined(CONFIG_PROC_FS) && defined(CONFIG_NF_CONNTRACK_PROC_COMPAT) 530#if defined(CONFIG_PROC_FS) && defined(CONFIG_NF_CONNTRACK_PROC_COMPAT)
524 nf_conntrack_ipv4_compat_fini(); 531 nf_conntrack_ipv4_compat_fini();
525#endif 532#endif
533 nf_ct_l3proto_unregister(&nf_conntrack_l3proto_ipv4);
526 nf_unregister_hooks(ipv4_conntrack_ops, ARRAY_SIZE(ipv4_conntrack_ops)); 534 nf_unregister_hooks(ipv4_conntrack_ops, ARRAY_SIZE(ipv4_conntrack_ops));
527 unregister_pernet_subsys(&ipv4_net_ops); 535 unregister_pernet_subsys(&ipv4_net_ops);
528 nf_unregister_sockopt(&so_getorigdst); 536 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..3eaf6baf8f61 100644
--- a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
+++ b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
@@ -439,10 +439,9 @@ static int ipv6_net_init(struct net *net)
439 printk(KERN_ERR "nf_conntrack_l4proto_icmp6: protocol register failed\n"); 439 printk(KERN_ERR "nf_conntrack_l4proto_icmp6: protocol register failed\n");
440 goto cleanup_udp6; 440 goto cleanup_udp6;
441 } 441 }
442 ret = nf_conntrack_l3proto_register(net, 442 ret = nf_ct_l3proto_pernet_register(net, &nf_conntrack_l3proto_ipv6);
443 &nf_conntrack_l3proto_ipv6);
444 if (ret < 0) { 443 if (ret < 0) {
445 printk(KERN_ERR "nf_conntrack_l3proto_ipv6: protocol register failed\n"); 444 pr_err("nf_conntrack_ipv6: pernet registration failed.\n");
446 goto cleanup_icmpv6; 445 goto cleanup_icmpv6;
447 } 446 }
448 return 0; 447 return 0;
@@ -461,8 +460,7 @@ static int ipv6_net_init(struct net *net)
461 460
462static void ipv6_net_exit(struct net *net) 461static void ipv6_net_exit(struct net *net)
463{ 462{
464 nf_conntrack_l3proto_unregister(net, 463 nf_ct_l3proto_pernet_unregister(net, &nf_conntrack_l3proto_ipv6);
465 &nf_conntrack_l3proto_ipv6);
466 nf_conntrack_l4proto_unregister(net, 464 nf_conntrack_l4proto_unregister(net,
467 &nf_conntrack_l4proto_icmpv6); 465 &nf_conntrack_l4proto_icmpv6);
468 nf_conntrack_l4proto_unregister(net, 466 nf_conntrack_l4proto_unregister(net,
@@ -491,19 +489,28 @@ static int __init nf_conntrack_l3proto_ipv6_init(void)
491 489
492 ret = register_pernet_subsys(&ipv6_net_ops); 490 ret = register_pernet_subsys(&ipv6_net_ops);
493 if (ret < 0) 491 if (ret < 0)
494 goto cleanup_pernet; 492 goto cleanup_sockopt;
493
495 ret = nf_register_hooks(ipv6_conntrack_ops, 494 ret = nf_register_hooks(ipv6_conntrack_ops,
496 ARRAY_SIZE(ipv6_conntrack_ops)); 495 ARRAY_SIZE(ipv6_conntrack_ops));
497 if (ret < 0) { 496 if (ret < 0) {
498 pr_err("nf_conntrack_ipv6: can't register pre-routing defrag " 497 pr_err("nf_conntrack_ipv6: can't register pre-routing defrag "
499 "hook.\n"); 498 "hook.\n");
500 goto cleanup_ipv6; 499 goto cleanup_pernet;
500 }
501
502 ret = nf_ct_l3proto_register(&nf_conntrack_l3proto_ipv6);
503 if (ret < 0) {
504 pr_err("nf_conntrack_ipv6: can't register ipv6 proto.\n");
505 goto cleanup_hooks;
501 } 506 }
502 return ret; 507 return ret;
503 508
504 cleanup_ipv6: 509 cleanup_hooks:
505 unregister_pernet_subsys(&ipv6_net_ops); 510 nf_unregister_hooks(ipv6_conntrack_ops, ARRAY_SIZE(ipv6_conntrack_ops));
506 cleanup_pernet: 511 cleanup_pernet:
512 unregister_pernet_subsys(&ipv6_net_ops);
513 cleanup_sockopt:
507 nf_unregister_sockopt(&so_getorigdst6); 514 nf_unregister_sockopt(&so_getorigdst6);
508 return ret; 515 return ret;
509} 516}
@@ -511,6 +518,7 @@ static int __init nf_conntrack_l3proto_ipv6_init(void)
511static void __exit nf_conntrack_l3proto_ipv6_fini(void) 518static void __exit nf_conntrack_l3proto_ipv6_fini(void)
512{ 519{
513 synchronize_net(); 520 synchronize_net();
521 nf_ct_l3proto_unregister(&nf_conntrack_l3proto_ipv6);
514 nf_unregister_hooks(ipv6_conntrack_ops, ARRAY_SIZE(ipv6_conntrack_ops)); 522 nf_unregister_hooks(ipv6_conntrack_ops, ARRAY_SIZE(ipv6_conntrack_ops));
515 unregister_pernet_subsys(&ipv6_net_ops); 523 unregister_pernet_subsys(&ipv6_net_ops);
516 nf_unregister_sockopt(&so_getorigdst6); 524 nf_unregister_sockopt(&so_getorigdst6);
diff --git a/net/netfilter/nf_conntrack_proto.c b/net/netfilter/nf_conntrack_proto.c
index f0ec07c3fb6c..076d82707226 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)