Commit 436a850d authored by Florian Westphal's avatar Florian Westphal Committed by Pablo Neira Ayuso

netfilter: helper: avoid extra expectation iterations on unregister

The expectation table is not duplicated per net namespace anymore, so we can move
the expectation table and conntrack table iteration out of the per-net loop.
Signed-off-by: default avatarFlorian Westphal <fw@strlen.de>
Signed-off-by: default avatarPablo Neira Ayuso <pablo@netfilter.org>
parent 402f9030
...@@ -388,13 +388,40 @@ EXPORT_SYMBOL_GPL(nf_conntrack_helper_register); ...@@ -388,13 +388,40 @@ EXPORT_SYMBOL_GPL(nf_conntrack_helper_register);
static void __nf_conntrack_helper_unregister(struct nf_conntrack_helper *me, static void __nf_conntrack_helper_unregister(struct nf_conntrack_helper *me,
struct net *net) struct net *net)
{
struct nf_conntrack_tuple_hash *h;
const struct hlist_nulls_node *nn;
int cpu;
/* Get rid of expecteds, set helpers to NULL. */
for_each_possible_cpu(cpu) {
struct ct_pcpu *pcpu = per_cpu_ptr(net->ct.pcpu_lists, cpu);
spin_lock_bh(&pcpu->lock);
hlist_nulls_for_each_entry(h, nn, &pcpu->unconfirmed, hnnode)
unhelp(h, me);
spin_unlock_bh(&pcpu->lock);
}
}
void nf_conntrack_helper_unregister(struct nf_conntrack_helper *me)
{ {
struct nf_conntrack_tuple_hash *h; struct nf_conntrack_tuple_hash *h;
struct nf_conntrack_expect *exp; struct nf_conntrack_expect *exp;
const struct hlist_node *next; const struct hlist_node *next;
const struct hlist_nulls_node *nn; const struct hlist_nulls_node *nn;
struct net *net;
unsigned int i; unsigned int i;
int cpu;
mutex_lock(&nf_ct_helper_mutex);
hlist_del_rcu(&me->hnode);
nf_ct_helper_count--;
mutex_unlock(&nf_ct_helper_mutex);
/* Make sure every nothing is still using the helper unless its a
* connection in the hash.
*/
synchronize_rcu();
/* Get rid of expectations */ /* Get rid of expectations */
spin_lock_bh(&nf_conntrack_expect_lock); spin_lock_bh(&nf_conntrack_expect_lock);
...@@ -414,15 +441,11 @@ static void __nf_conntrack_helper_unregister(struct nf_conntrack_helper *me, ...@@ -414,15 +441,11 @@ static void __nf_conntrack_helper_unregister(struct nf_conntrack_helper *me,
} }
spin_unlock_bh(&nf_conntrack_expect_lock); spin_unlock_bh(&nf_conntrack_expect_lock);
/* Get rid of expecteds, set helpers to NULL. */ rtnl_lock();
for_each_possible_cpu(cpu) { for_each_net(net)
struct ct_pcpu *pcpu = per_cpu_ptr(net->ct.pcpu_lists, cpu); __nf_conntrack_helper_unregister(me, net);
rtnl_unlock();
spin_lock_bh(&pcpu->lock);
hlist_nulls_for_each_entry(h, nn, &pcpu->unconfirmed, hnnode)
unhelp(h, me);
spin_unlock_bh(&pcpu->lock);
}
local_bh_disable(); local_bh_disable();
for (i = 0; i < nf_conntrack_htable_size; i++) { for (i = 0; i < nf_conntrack_htable_size; i++) {
nf_conntrack_lock(&nf_conntrack_locks[i % CONNTRACK_LOCKS]); nf_conntrack_lock(&nf_conntrack_locks[i % CONNTRACK_LOCKS]);
...@@ -434,26 +457,6 @@ static void __nf_conntrack_helper_unregister(struct nf_conntrack_helper *me, ...@@ -434,26 +457,6 @@ static void __nf_conntrack_helper_unregister(struct nf_conntrack_helper *me,
} }
local_bh_enable(); local_bh_enable();
} }
void nf_conntrack_helper_unregister(struct nf_conntrack_helper *me)
{
struct net *net;
mutex_lock(&nf_ct_helper_mutex);
hlist_del_rcu(&me->hnode);
nf_ct_helper_count--;
mutex_unlock(&nf_ct_helper_mutex);
/* Make sure every nothing is still using the helper unless its a
* connection in the hash.
*/
synchronize_rcu();
rtnl_lock();
for_each_net(net)
__nf_conntrack_helper_unregister(me, net);
rtnl_unlock();
}
EXPORT_SYMBOL_GPL(nf_conntrack_helper_unregister); EXPORT_SYMBOL_GPL(nf_conntrack_helper_unregister);
static struct nf_ct_ext_type helper_extend __read_mostly = { static struct nf_ct_ext_type helper_extend __read_mostly = {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment