diff options
-rw-r--r-- | include/net/netfilter/nf_conntrack_l3proto.h | 11 | ||||
-rw-r--r-- | net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c | 22 | ||||
-rw-r--r-- | net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c | 26 | ||||
-rw-r--r-- | net/netfilter/nf_conntrack_proto.c | 31 |
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 | ||
77 | extern struct nf_conntrack_l3proto __rcu *nf_ct_l3protos[AF_MAX]; | 77 | extern struct nf_conntrack_l3proto __rcu *nf_ct_l3protos[AF_MAX]; |
78 | 78 | ||
79 | /* Protocol registration. */ | 79 | /* Protocol pernet registration. */ |
80 | extern int nf_conntrack_l3proto_register(struct net *net, | 80 | extern int nf_ct_l3proto_pernet_register(struct net *net, |
81 | struct nf_conntrack_l3proto *proto); | 81 | struct nf_conntrack_l3proto *proto); |
82 | extern void nf_conntrack_l3proto_unregister(struct net *net, | 82 | extern 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. */ | ||
86 | extern int nf_ct_l3proto_register(struct nf_conntrack_l3proto *proto); | ||
87 | extern void nf_ct_l3proto_unregister(struct nf_conntrack_l3proto *proto); | ||
88 | |||
84 | extern struct nf_conntrack_l3proto *nf_ct_l3proto_find_get(u_int16_t l3proto); | 89 | extern struct nf_conntrack_l3proto *nf_ct_l3proto_find_get(u_int16_t l3proto); |
85 | extern void nf_ct_l3proto_put(struct nf_conntrack_l3proto *p); | 90 | extern 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 | ||
461 | static void ipv4_net_exit(struct net *net) | 460 | static 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 | ||
462 | static void ipv6_net_exit(struct net *net) | 461 | static 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) | |||
511 | static void __exit nf_conntrack_l3proto_ipv6_fini(void) | 518 | static 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 | ||
215 | static int | 215 | int nf_ct_l3proto_register(struct nf_conntrack_l3proto *proto) |
216 | nf_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 | } |
244 | EXPORT_SYMBOL_GPL(nf_ct_l3proto_register); | ||
245 | 245 | ||
246 | int nf_conntrack_l3proto_register(struct net *net, | 246 | int 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 | } |
269 | EXPORT_SYMBOL_GPL(nf_conntrack_l3proto_register); | 259 | EXPORT_SYMBOL_GPL(nf_ct_l3proto_pernet_register); |
270 | 260 | ||
271 | static void | 261 | void nf_ct_l3proto_unregister(struct nf_conntrack_l3proto *proto) |
272 | nf_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 | } |
275 | EXPORT_SYMBOL_GPL(nf_ct_l3proto_unregister); | ||
286 | 276 | ||
287 | void nf_conntrack_l3proto_unregister(struct net *net, | 277 | void 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 | } |
298 | EXPORT_SYMBOL_GPL(nf_conntrack_l3proto_unregister); | 285 | EXPORT_SYMBOL_GPL(nf_ct_l3proto_pernet_unregister); |
299 | 286 | ||
300 | static struct nf_proto_net *nf_ct_l4proto_net(struct net *net, | 287 | static struct nf_proto_net *nf_ct_l4proto_net(struct net *net, |
301 | struct nf_conntrack_l4proto *l4proto) | 288 | struct nf_conntrack_l4proto *l4proto) |