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

netfilter: add and use nf_ct_unconfirmed_destroy

This also removes __nf_ct_unconfirmed_destroy() call from
nf_ct_iterate_cleanup_net, so that function can be used only
when missing conntracks from unconfirmed list isn't a problem.
Signed-off-by: default avatarFlorian Westphal <fw@strlen.de>
Signed-off-by: default avatarPablo Neira Ayuso <pablo@netfilter.org>
parent ac7b8483
...@@ -224,6 +224,9 @@ extern s32 (*nf_ct_nat_offset)(const struct nf_conn *ct, ...@@ -224,6 +224,9 @@ extern s32 (*nf_ct_nat_offset)(const struct nf_conn *ct,
enum ip_conntrack_dir dir, enum ip_conntrack_dir dir,
u32 seq); u32 seq);
/* Set all unconfirmed conntrack as dying */
void nf_ct_unconfirmed_destroy(struct net *);
/* Iterate over all conntracks: if iter returns true, it's deleted. */ /* Iterate over all conntracks: if iter returns true, it's deleted. */
void nf_ct_iterate_cleanup_net(struct net *net, void nf_ct_iterate_cleanup_net(struct net *net,
int (*iter)(struct nf_conn *i, void *data), int (*iter)(struct nf_conn *i, void *data),
......
...@@ -1686,6 +1686,17 @@ __nf_ct_unconfirmed_destroy(struct net *net) ...@@ -1686,6 +1686,17 @@ __nf_ct_unconfirmed_destroy(struct net *net)
} }
} }
void nf_ct_unconfirmed_destroy(struct net *net)
{
might_sleep();
if (atomic_read(&net->ct.count) > 0) {
__nf_ct_unconfirmed_destroy(net);
synchronize_net();
}
}
EXPORT_SYMBOL_GPL(nf_ct_unconfirmed_destroy);
void nf_ct_iterate_cleanup_net(struct net *net, void nf_ct_iterate_cleanup_net(struct net *net,
int (*iter)(struct nf_conn *i, void *data), int (*iter)(struct nf_conn *i, void *data),
void *data, u32 portid, int report) void *data, u32 portid, int report)
...@@ -1697,14 +1708,10 @@ void nf_ct_iterate_cleanup_net(struct net *net, ...@@ -1697,14 +1708,10 @@ void nf_ct_iterate_cleanup_net(struct net *net,
if (atomic_read(&net->ct.count) == 0) if (atomic_read(&net->ct.count) == 0)
return; return;
__nf_ct_unconfirmed_destroy(net);
d.iter = iter; d.iter = iter;
d.data = data; d.data = data;
d.net = net; d.net = net;
synchronize_net();
nf_ct_iterate_cleanup(iter_net_only, &d, portid, report); nf_ct_iterate_cleanup(iter_net_only, &d, portid, report);
} }
EXPORT_SYMBOL_GPL(nf_ct_iterate_cleanup_net); EXPORT_SYMBOL_GPL(nf_ct_iterate_cleanup_net);
......
...@@ -570,6 +570,7 @@ static void __net_exit cttimeout_net_exit(struct net *net) ...@@ -570,6 +570,7 @@ static void __net_exit cttimeout_net_exit(struct net *net)
{ {
struct ctnl_timeout *cur, *tmp; struct ctnl_timeout *cur, *tmp;
nf_ct_unconfirmed_destroy(net);
ctnl_untimeout(net, NULL); ctnl_untimeout(net, NULL);
list_for_each_entry_safe(cur, tmp, &net->nfct_timeout_list, head) { list_for_each_entry_safe(cur, tmp, &net->nfct_timeout_list, head) {
......
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