You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
129 lines
3.7 KiB
129 lines
3.7 KiB
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)
|
|
{
|
|
|