Browse Source

netfilter: core: remove synchronize_net call if nfqueue is used

since commit 960632ece6949b ("netfilter: convert hook list to an array")
nfqueue no longer stores a pointer to the hook that caused the packet
to be queued.  Therefore no extra synchronize_net() call is needed after
dropping the packets enqueued by the old rule blob.

Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Florian Westphal 7 years ago
parent
commit
26888dfd7e

+ 1 - 1
include/net/netfilter/nf_queue.h

@@ -25,7 +25,7 @@ struct nf_queue_entry {
 struct nf_queue_handler {
 struct nf_queue_handler {
 	int		(*outfn)(struct nf_queue_entry *entry,
 	int		(*outfn)(struct nf_queue_entry *entry,
 				 unsigned int queuenum);
 				 unsigned int queuenum);
-	unsigned int	(*nf_hook_drop)(struct net *net);
+	void		(*nf_hook_drop)(struct net *net);
 };
 };
 
 
 void nf_register_queue_handler(struct net *net, const struct nf_queue_handler *qh);
 void nf_register_queue_handler(struct net *net, const struct nf_queue_handler *qh);

+ 1 - 5
net/netfilter/core.c

@@ -341,7 +341,6 @@ void nf_unregister_net_hook(struct net *net, const struct nf_hook_ops *reg)
 {
 {
 	struct nf_hook_entries __rcu **pp;
 	struct nf_hook_entries __rcu **pp;
 	struct nf_hook_entries *p;
 	struct nf_hook_entries *p;
-	unsigned int nfq;
 
 
 	pp = nf_hook_entry_head(net, reg);
 	pp = nf_hook_entry_head(net, reg);
 	if (!pp)
 	if (!pp)
@@ -364,10 +363,7 @@ void nf_unregister_net_hook(struct net *net, const struct nf_hook_ops *reg)
 
 
 	synchronize_net();
 	synchronize_net();
 
 
-	/* other cpu might still process nfqueue verdict that used reg */
-	nfq = nf_queue_nf_hook_drop(net);
-	if (nfq)
-		synchronize_net();
+	nf_queue_nf_hook_drop(net);
 	kvfree(p);
 	kvfree(p);
 }
 }
 EXPORT_SYMBOL(nf_unregister_net_hook);
 EXPORT_SYMBOL(nf_unregister_net_hook);

+ 1 - 1
net/netfilter/nf_internals.h

@@ -10,7 +10,7 @@
 int nf_queue(struct sk_buff *skb, struct nf_hook_state *state,
 int nf_queue(struct sk_buff *skb, struct nf_hook_state *state,
 	     const struct nf_hook_entries *entries, unsigned int index,
 	     const struct nf_hook_entries *entries, unsigned int index,
 	     unsigned int verdict);
 	     unsigned int verdict);
-unsigned int nf_queue_nf_hook_drop(struct net *net);
+void nf_queue_nf_hook_drop(struct net *net);
 
 
 /* nf_log.c */
 /* nf_log.c */
 int __init netfilter_log_init(void);
 int __init netfilter_log_init(void);

+ 2 - 5
net/netfilter/nf_queue.c

@@ -96,18 +96,15 @@ void nf_queue_entry_get_refs(struct nf_queue_entry *entry)
 }
 }
 EXPORT_SYMBOL_GPL(nf_queue_entry_get_refs);
 EXPORT_SYMBOL_GPL(nf_queue_entry_get_refs);
 
 
-unsigned int nf_queue_nf_hook_drop(struct net *net)
+void nf_queue_nf_hook_drop(struct net *net)
 {
 {
 	const struct nf_queue_handler *qh;
 	const struct nf_queue_handler *qh;
-	unsigned int count = 0;
 
 
 	rcu_read_lock();
 	rcu_read_lock();
 	qh = rcu_dereference(net->nf.queue_handler);
 	qh = rcu_dereference(net->nf.queue_handler);
 	if (qh)
 	if (qh)
-		count = qh->nf_hook_drop(net);
+		qh->nf_hook_drop(net);
 	rcu_read_unlock();
 	rcu_read_unlock();
-
-	return count;
 }
 }
 EXPORT_SYMBOL_GPL(nf_queue_nf_hook_drop);
 EXPORT_SYMBOL_GPL(nf_queue_nf_hook_drop);
 
 

+ 2 - 7
net/netfilter/nfnetlink_queue.c

@@ -941,23 +941,18 @@ static struct notifier_block nfqnl_dev_notifier = {
 	.notifier_call	= nfqnl_rcv_dev_event,
 	.notifier_call	= nfqnl_rcv_dev_event,
 };
 };
 
 
-static unsigned int nfqnl_nf_hook_drop(struct net *net)
+static void nfqnl_nf_hook_drop(struct net *net)
 {
 {
 	struct nfnl_queue_net *q = nfnl_queue_pernet(net);
 	struct nfnl_queue_net *q = nfnl_queue_pernet(net);
-	unsigned int instances = 0;
 	int i;
 	int i;
 
 
 	for (i = 0; i < INSTANCE_BUCKETS; i++) {
 	for (i = 0; i < INSTANCE_BUCKETS; i++) {
 		struct nfqnl_instance *inst;
 		struct nfqnl_instance *inst;
 		struct hlist_head *head = &q->instance_table[i];
 		struct hlist_head *head = &q->instance_table[i];
 
 
-		hlist_for_each_entry_rcu(inst, head, hlist) {
+		hlist_for_each_entry_rcu(inst, head, hlist)
 			nfqnl_flush(inst, NULL, 0);
 			nfqnl_flush(inst, NULL, 0);
-			instances++;
-		}
 	}
 	}
-
-	return instances;
 }
 }
 
 
 static int
 static int