/branches/18.06.1/target/linux/generic/backport-4.14/299-v4.16-netfilter-core-support-for-NFPROTO_INET-hook-registr.patch |
@@ -0,0 +1,129 @@ |
From cb7ccd835ebb333669e400f99c650e4f3abf11c0 Mon Sep 17 00:00:00 2001 |
From: Pablo Neira Ayuso <pablo@netfilter.org> |
Date: Sat, 9 Dec 2017 15:30:26 +0100 |
Subject: [PATCH 11/11] 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> |
--- |
net/netfilter/core.c | 53 +++++++++++++++++++++++++++++++++++++++++++--------- |
1 file changed, 44 insertions(+), 9 deletions(-) |
|
--- a/net/netfilter/core.c |
+++ b/net/netfilter/core.c |
@@ -310,12 +310,13 @@ nf_hook_entry_head(struct net *net, int |
return NULL; |
} |
|
-int nf_register_net_hook(struct net *net, const struct nf_hook_ops *reg) |
+static int __nf_register_net_hook(struct net *net, int pf, |
+ const struct nf_hook_ops *reg) |
{ |
struct nf_hook_entries *p, *new_hooks; |
struct nf_hook_entries __rcu **pp; |
|
- if (reg->pf == NFPROTO_NETDEV) { |
+ if (pf == NFPROTO_NETDEV) { |
#ifndef CONFIG_NETFILTER_INGRESS |
if (reg->hooknum == NF_NETDEV_INGRESS) |
return -EOPNOTSUPP; |
@@ -325,7 +326,7 @@ int nf_register_net_hook(struct net *net |
return -EINVAL; |
} |
|
- pp = nf_hook_entry_head(net, reg->pf, reg->hooknum, reg->dev); |
+ pp = nf_hook_entry_head(net, pf, reg->hooknum, reg->dev); |
if (!pp) |
return -EINVAL; |
|
@@ -343,17 +344,16 @@ int nf_register_net_hook(struct net *net |
|
hooks_validate(new_hooks); |
#ifdef CONFIG_NETFILTER_INGRESS |
- if (reg->pf == NFPROTO_NETDEV && reg->hooknum == NF_NETDEV_INGRESS) |
+ if (pf == NFPROTO_NETDEV && reg->hooknum == NF_NETDEV_INGRESS) |
net_inc_ingress_queue(); |
#endif |
#ifdef HAVE_JUMP_LABEL |
- static_key_slow_inc(&nf_hooks_needed[reg->pf][reg->hooknum]); |
+ static_key_slow_inc(&nf_hooks_needed[pf][reg->hooknum]); |
#endif |
BUG_ON(p == new_hooks); |
nf_hook_entries_free(p); |
return 0; |
} |
-EXPORT_SYMBOL(nf_register_net_hook); |
|
/* |
* nf_remove_net_hook - remove a hook from blob |
@@ -394,12 +394,13 @@ static void nf_remove_net_hook(struct nf |
} |
} |
|
-void nf_unregister_net_hook(struct net *net, const struct nf_hook_ops *reg) |
+void __nf_unregister_net_hook(struct net *net, int pf, |
+ const struct nf_hook_ops *reg) |
{ |
struct nf_hook_entries __rcu **pp; |
struct nf_hook_entries *p; |
|
- pp = nf_hook_entry_head(net, reg->pf, reg->hooknum, reg->dev); |
+ pp = nf_hook_entry_head(net, pf, reg->hooknum, reg->dev); |
if (!pp) |
return; |
|
@@ -411,7 +412,7 @@ void nf_unregister_net_hook(struct net * |
return; |
} |
|
- nf_remove_net_hook(p, reg, reg->pf); |
+ nf_remove_net_hook(p, reg, pf); |
|
p = __nf_hook_entries_try_shrink(pp); |
mutex_unlock(&nf_hook_mutex); |
@@ -421,8 +422,42 @@ void nf_unregister_net_hook(struct net * |
nf_queue_nf_hook_drop(net); |
nf_hook_entries_free(p); |
} |
+ |
+void nf_unregister_net_hook(struct net *net, const struct nf_hook_ops *reg) |
+{ |
+ if (reg->pf == NFPROTO_INET) { |
+ __nf_unregister_net_hook(net, NFPROTO_IPV4, reg); |
+ __nf_unregister_net_hook(net, NFPROTO_IPV6, reg); |
+ } else { |
+ __nf_unregister_net_hook(net, reg->pf, reg); |
+ } |
+} |
EXPORT_SYMBOL(nf_unregister_net_hook); |
|
+int nf_register_net_hook(struct net *net, const struct nf_hook_ops *reg) |
+{ |
+ int err; |
+ |
+ if (reg->pf == NFPROTO_INET) { |
+ err = __nf_register_net_hook(net, NFPROTO_IPV4, reg); |
+ if (err < 0) |
+ return err; |
+ |
+ err = __nf_register_net_hook(net, NFPROTO_IPV6, reg); |
+ if (err < 0) { |
+ __nf_unregister_net_hook(net, NFPROTO_IPV4, reg); |
+ return err; |
+ } |
+ } else { |
+ err = __nf_register_net_hook(net, reg->pf, reg); |
+ if (err < 0) |
+ return err; |
+ } |
+ |
+ return 0; |
+} |
+EXPORT_SYMBOL(nf_register_net_hook); |
+ |
int nf_register_net_hooks(struct net *net, const struct nf_hook_ops *reg, |
unsigned int n) |
{ |