diff options
author | Florian Westphal <fw@strlen.de> | 2017-04-24 15:37:41 +0200 |
---|---|---|
committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2017-05-01 11:19:12 +0200 |
commit | 039b40ee5854dc733cf786fee4a88e240a012115 (patch) | |
tree | 49070019cfbd9dd9a86e32e50be465ca3346afcc /net/netfilter/nfnetlink_queue.c | |
parent | c83fa19603bdaeef17b815713dbbe3230c8a34ee (diff) | |
download | op-kernel-dev-039b40ee5854dc733cf786fee4a88e240a012115.zip op-kernel-dev-039b40ee5854dc733cf786fee4a88e240a012115.tar.gz |
netfilter: nf_queue: only call synchronize_net twice if nf_queue is active
nf_unregister_net_hook(s) can avoid a second call to synchronize_net,
provided there is no nfqueue active in that net namespace (which is
the common case).
This also gets rid of the extra arg to nf_queue_nf_hook_drop(), normally
this gets called during netns cleanup so no packets should be queued.
For the rare case of base chain being unregistered or module removal
while nfqueue is in use the extra hiccup due to the packet drops isn't
a big deal.
Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'net/netfilter/nfnetlink_queue.c')
-rw-r--r-- | net/netfilter/nfnetlink_queue.c | 18 |
1 files changed, 8 insertions, 10 deletions
diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c index d09ab49..dd8ec5b 100644 --- a/net/netfilter/nfnetlink_queue.c +++ b/net/netfilter/nfnetlink_queue.c @@ -922,16 +922,10 @@ static struct notifier_block nfqnl_dev_notifier = { .notifier_call = nfqnl_rcv_dev_event, }; -static int nf_hook_cmp(struct nf_queue_entry *entry, unsigned long entry_ptr) -{ - return rcu_access_pointer(entry->hook) == - (struct nf_hook_entry *)entry_ptr; -} - -static void nfqnl_nf_hook_drop(struct net *net, - const struct nf_hook_entry *hook) +static unsigned int nfqnl_nf_hook_drop(struct net *net) { struct nfnl_queue_net *q = nfnl_queue_pernet(net); + unsigned int instances = 0; int i; rcu_read_lock(); @@ -939,10 +933,14 @@ static void nfqnl_nf_hook_drop(struct net *net, struct nfqnl_instance *inst; struct hlist_head *head = &q->instance_table[i]; - hlist_for_each_entry_rcu(inst, head, hlist) - nfqnl_flush(inst, nf_hook_cmp, (unsigned long)hook); + hlist_for_each_entry_rcu(inst, head, hlist) { + nfqnl_flush(inst, NULL, 0); + instances++; + } } rcu_read_unlock(); + + return instances; } static int |