aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@netfilter.org>2017-12-09 09:30:26 -0500
committerPablo Neira Ayuso <pablo@netfilter.org>2018-01-08 12:01:19 -0500
commitcb7ccd835ebb333669e400f99c650e4f3abf11c0 (patch)
tree831fa70b01b2dfcdbfc56cc4a9006b6a0ee62bb1
parent30259408118f550f5969fda19c0d67020d21eda8 (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.c53
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
319int nf_register_net_hook(struct net *net, const struct nf_hook_ops *reg) 319static 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}
362EXPORT_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
403void nf_unregister_net_hook(struct net *net, const struct nf_hook_ops *reg) 403void __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
432void 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}
430EXPORT_SYMBOL(nf_unregister_net_hook); 441EXPORT_SYMBOL(nf_unregister_net_hook);
431 442
443int 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}
465EXPORT_SYMBOL(nf_register_net_hook);
466
432int nf_register_net_hooks(struct net *net, const struct nf_hook_ops *reg, 467int nf_register_net_hooks(struct net *net, const struct nf_hook_ops *reg,
433 unsigned int n) 468 unsigned int n)
434{ 469{