diff options
author | Pablo Neira Ayuso <pablo@netfilter.org> | 2017-12-09 09:30:26 -0500 |
---|---|---|
committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2018-01-08 12:01:19 -0500 |
commit | cb7ccd835ebb333669e400f99c650e4f3abf11c0 (patch) | |
tree | 831fa70b01b2dfcdbfc56cc4a9006b6a0ee62bb1 | |
parent | 30259408118f550f5969fda19c0d67020d21eda8 (diff) |
netfilter: core: support for NFPROTO_INET hook registration
Expand NFPROTO_INET in two hook registrations, one for NFPROTO_IPV4 and
another for NFPROTO_IPV6. Hence, we handle NFPROTO_INET from the core.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
-rw-r--r-- | net/netfilter/core.c | 53 |
1 files changed, 44 insertions, 9 deletions
diff --git a/net/netfilter/core.c b/net/netfilter/core.c index 6c9874c8b10a..606efc9b14e1 100644 --- a/net/netfilter/core.c +++ b/net/netfilter/core.c | |||
@@ -316,12 +316,13 @@ nf_hook_entry_head(struct net *net, int pf, unsigned int hooknum, | |||
316 | return NULL; | 316 | return NULL; |
317 | } | 317 | } |
318 | 318 | ||
319 | int nf_register_net_hook(struct net *net, const struct nf_hook_ops *reg) | 319 | static int __nf_register_net_hook(struct net *net, int pf, |
320 | const struct nf_hook_ops *reg) | ||
320 | { | 321 | { |
321 | struct nf_hook_entries *p, *new_hooks; | 322 | struct nf_hook_entries *p, *new_hooks; |
322 | struct nf_hook_entries __rcu **pp; | 323 | struct nf_hook_entries __rcu **pp; |
323 | 324 | ||
324 | if (reg->pf == NFPROTO_NETDEV) { | 325 | if (pf == NFPROTO_NETDEV) { |
325 | #ifndef CONFIG_NETFILTER_INGRESS | 326 | #ifndef CONFIG_NETFILTER_INGRESS |
326 | if (reg->hooknum == NF_NETDEV_INGRESS) | 327 | if (reg->hooknum == NF_NETDEV_INGRESS) |
327 | return -EOPNOTSUPP; | 328 | return -EOPNOTSUPP; |
@@ -331,7 +332,7 @@ int nf_register_net_hook(struct net *net, const struct nf_hook_ops *reg) | |||
331 | return -EINVAL; | 332 | return -EINVAL; |
332 | } | 333 | } |
333 | 334 | ||
334 | pp = nf_hook_entry_head(net, reg->pf, reg->hooknum, reg->dev); | 335 | pp = nf_hook_entry_head(net, pf, reg->hooknum, reg->dev); |
335 | if (!pp) | 336 | if (!pp) |
336 | return -EINVAL; | 337 | return -EINVAL; |
337 | 338 | ||
@@ -349,17 +350,16 @@ int nf_register_net_hook(struct net *net, const struct nf_hook_ops *reg) | |||
349 | 350 | ||
350 | hooks_validate(new_hooks); | 351 | hooks_validate(new_hooks); |
351 | #ifdef CONFIG_NETFILTER_INGRESS | 352 | #ifdef CONFIG_NETFILTER_INGRESS |
352 | if (reg->pf == NFPROTO_NETDEV && reg->hooknum == NF_NETDEV_INGRESS) | 353 | if (pf == NFPROTO_NETDEV && reg->hooknum == NF_NETDEV_INGRESS) |
353 | net_inc_ingress_queue(); | 354 | net_inc_ingress_queue(); |
354 | #endif | 355 | #endif |
355 | #ifdef HAVE_JUMP_LABEL | 356 | #ifdef HAVE_JUMP_LABEL |
356 | static_key_slow_inc(&nf_hooks_needed[reg->pf][reg->hooknum]); | 357 | static_key_slow_inc(&nf_hooks_needed[pf][reg->hooknum]); |
357 | #endif | 358 | #endif |
358 | BUG_ON(p == new_hooks); | 359 | BUG_ON(p == new_hooks); |
359 | nf_hook_entries_free(p); | 360 | nf_hook_entries_free(p); |
360 | return 0; | 361 | return 0; |
361 | } | 362 | } |
362 | EXPORT_SYMBOL(nf_register_net_hook); | ||
363 | 363 | ||
364 | /* | 364 | /* |
365 | * nf_remove_net_hook - remove a hook from blob | 365 | * nf_remove_net_hook - remove a hook from blob |
@@ -400,12 +400,13 @@ static void nf_remove_net_hook(struct nf_hook_entries *old, | |||
400 | } | 400 | } |
401 | } | 401 | } |
402 | 402 | ||
403 | void nf_unregister_net_hook(struct net *net, const struct nf_hook_ops *reg) | 403 | void __nf_unregister_net_hook(struct net *net, int pf, |
404 | const struct nf_hook_ops *reg) | ||
404 | { | 405 | { |
405 | struct nf_hook_entries __rcu **pp; | 406 | struct nf_hook_entries __rcu **pp; |
406 | struct nf_hook_entries *p; | 407 | struct nf_hook_entries *p; |
407 | 408 | ||
408 | pp = nf_hook_entry_head(net, reg->pf, reg->hooknum, reg->dev); | 409 | pp = nf_hook_entry_head(net, pf, reg->hooknum, reg->dev); |
409 | if (!pp) | 410 | if (!pp) |
410 | return; | 411 | return; |
411 | 412 | ||
@@ -417,7 +418,7 @@ void nf_unregister_net_hook(struct net *net, const struct nf_hook_ops *reg) | |||
417 | return; | 418 | return; |
418 | } | 419 | } |
419 | 420 | ||
420 | nf_remove_net_hook(p, reg, reg->pf); | 421 | nf_remove_net_hook(p, reg, pf); |
421 | 422 | ||
422 | p = __nf_hook_entries_try_shrink(pp); | 423 | p = __nf_hook_entries_try_shrink(pp); |
423 | mutex_unlock(&nf_hook_mutex); | 424 | mutex_unlock(&nf_hook_mutex); |
@@ -427,8 +428,42 @@ void nf_unregister_net_hook(struct net *net, const struct nf_hook_ops *reg) | |||
427 | nf_queue_nf_hook_drop(net); | 428 | nf_queue_nf_hook_drop(net); |
428 | nf_hook_entries_free(p); | 429 | nf_hook_entries_free(p); |
429 | } | 430 | } |
431 | |||
432 | void nf_unregister_net_hook(struct net *net, const struct nf_hook_ops *reg) | ||
433 | { | ||
434 | if (reg->pf == NFPROTO_INET) { | ||
435 | __nf_unregister_net_hook(net, NFPROTO_IPV4, reg); | ||
436 | __nf_unregister_net_hook(net, NFPROTO_IPV6, reg); | ||
437 | } else { | ||
438 | __nf_unregister_net_hook(net, reg->pf, reg); | ||
439 | } | ||
440 | } | ||
430 | EXPORT_SYMBOL(nf_unregister_net_hook); | 441 | EXPORT_SYMBOL(nf_unregister_net_hook); |
431 | 442 | ||
443 | int nf_register_net_hook(struct net *net, const struct nf_hook_ops *reg) | ||
444 | { | ||
445 | int err; | ||
446 | |||
447 | if (reg->pf == NFPROTO_INET) { | ||
448 | err = __nf_register_net_hook(net, NFPROTO_IPV4, reg); | ||
449 | if (err < 0) | ||
450 | return err; | ||
451 | |||
452 | err = __nf_register_net_hook(net, NFPROTO_IPV6, reg); | ||
453 | if (err < 0) { | ||
454 | __nf_unregister_net_hook(net, NFPROTO_IPV4, reg); | ||
455 | return err; | ||
456 | } | ||
457 | } else { | ||
458 | err = __nf_register_net_hook(net, reg->pf, reg); | ||
459 | if (err < 0) | ||
460 | return err; | ||
461 | } | ||
462 | |||
463 | return 0; | ||
464 | } | ||
465 | EXPORT_SYMBOL(nf_register_net_hook); | ||
466 | |||
432 | int nf_register_net_hooks(struct net *net, const struct nf_hook_ops *reg, | 467 | int nf_register_net_hooks(struct net *net, const struct nf_hook_ops *reg, |
433 | unsigned int n) | 468 | unsigned int n) |
434 | { | 469 | { |