netfilter: conntrack: remove __nf_ct_unconfirmed_destroy
Its not needed anymore: A. If entry is totally new, then the rcu-protected resource must already have been removed from global visibility before call to nf_ct_iterate_destroy. B. If entry was allocated before, but is not yet in the hash table (uncofirmed case), genid gets incremented and synchronize_rcu() call makes sure access has completed. C. Next attempt to peek at extension area will fail for unconfirmed conntracks, because ext->genid != genid. D. Conntracks in the hash are iterated as before. Signed-off-by: Florian Westphal <fw@strlen.de> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
This commit is contained in:
parent
42df4fb9b1
commit
ace53fdc26
|
@ -2457,34 +2457,6 @@ static int iter_net_only(struct nf_conn *i, void *data)
|
|||
return d->iter(i, d->data);
|
||||
}
|
||||
|
||||
static void
|
||||
__nf_ct_unconfirmed_destroy(struct net *net)
|
||||
{
|
||||
int cpu;
|
||||
|
||||
for_each_possible_cpu(cpu) {
|
||||
struct nf_conntrack_tuple_hash *h;
|
||||
struct hlist_nulls_node *n;
|
||||
struct ct_pcpu *pcpu;
|
||||
|
||||
pcpu = per_cpu_ptr(net->ct.pcpu_lists, cpu);
|
||||
|
||||
spin_lock_bh(&pcpu->lock);
|
||||
hlist_nulls_for_each_entry(h, n, &pcpu->unconfirmed, hnnode) {
|
||||
struct nf_conn *ct;
|
||||
|
||||
ct = nf_ct_tuplehash_to_ctrack(h);
|
||||
|
||||
/* we cannot call iter() on unconfirmed list, the
|
||||
* owning cpu can reallocate ct->ext at any time.
|
||||
*/
|
||||
set_bit(IPS_DYING_BIT, &ct->status);
|
||||
}
|
||||
spin_unlock_bh(&pcpu->lock);
|
||||
cond_resched();
|
||||
}
|
||||
}
|
||||
|
||||
void nf_ct_iterate_cleanup_net(struct net *net,
|
||||
int (*iter)(struct nf_conn *i, void *data),
|
||||
void *data, u32 portid, int report)
|
||||
|
@ -2527,26 +2499,34 @@ nf_ct_iterate_destroy(int (*iter)(struct nf_conn *i, void *data), void *data)
|
|||
|
||||
if (atomic_read(&cnet->count) == 0)
|
||||
continue;
|
||||
__nf_ct_unconfirmed_destroy(net);
|
||||
nf_queue_nf_hook_drop(net);
|
||||
}
|
||||
up_read(&net_rwsem);
|
||||
|
||||
/* Need to wait for netns cleanup worker to finish, if its
|
||||
* running -- it might have deleted a net namespace from
|
||||
* the global list, so our __nf_ct_unconfirmed_destroy() might
|
||||
* not have affected all namespaces.
|
||||
* the global list, so hook drop above might not have
|
||||
* affected all namespaces.
|
||||
*/
|
||||
net_ns_barrier();
|
||||
|
||||
/* a conntrack could have been unlinked from unconfirmed list
|
||||
* before we grabbed pcpu lock in __nf_ct_unconfirmed_destroy().
|
||||
/* a skb w. unconfirmed conntrack could have been reinjected just
|
||||
* before we called nf_queue_nf_hook_drop().
|
||||
*
|
||||
* This makes sure its inserted into conntrack table.
|
||||
*/
|
||||
synchronize_net();
|
||||
|
||||
nf_ct_ext_bump_genid();
|
||||
nf_ct_iterate_cleanup(iter, data, 0, 0);
|
||||
|
||||
/* Another cpu might be in a rcu read section with
|
||||
* rcu protected pointer cleared in iter callback
|
||||
* or hidden via nf_ct_ext_bump_genid() above.
|
||||
*
|
||||
* Wait until those are done.
|
||||
*/
|
||||
synchronize_rcu();
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nf_ct_iterate_destroy);
|
||||
|
||||
|
|
|
@ -468,11 +468,6 @@ void nf_conntrack_helper_unregister(struct nf_conntrack_helper *me)
|
|||
|
||||
nf_ct_expect_iterate_destroy(expect_iter_me, NULL);
|
||||
nf_ct_iterate_destroy(unhelp, me);
|
||||
|
||||
/* Maybe someone has gotten the helper already when unhelp above.
|
||||
* So need to wait it.
|
||||
*/
|
||||
synchronize_rcu();
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nf_conntrack_helper_unregister);
|
||||
|
||||
|
|
|
@ -674,7 +674,6 @@ static void __exit cttimeout_exit(void)
|
|||
RCU_INIT_POINTER(nf_ct_timeout_hook, NULL);
|
||||
|
||||
nf_ct_iterate_destroy(untimeout, NULL);
|
||||
synchronize_rcu();
|
||||
}
|
||||
|
||||
module_init(cttimeout_init);
|
||||
|
|
Loading…
Reference in New Issue