diff options
author | Florian Westphal <fw@strlen.de> | 2020-07-24 14:34:46 +0300 |
---|---|---|
committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2020-07-31 20:28:00 +0300 |
commit | ffe8923f109b7ea92c0842c89e61300eefa11c94 (patch) | |
tree | 8b74558e4f43e92aa07e839a4a41f3cf145b3114 /net/netfilter/nf_tables_api.c | |
parent | 85496a29224188051b6135eb38da8afd4c584765 (diff) | |
download | linux-ffe8923f109b7ea92c0842c89e61300eefa11c94.tar.xz |
netfilter: nft_compat: make sure xtables destructors have run
Pablo Neira found that after recent update of xt_IDLETIMER the
iptables-nft tests sometimes show an error.
He tracked this down to the delayed cleanup used by nf_tables core:
del rule (transaction A)
add rule (transaction B)
Its possible that by time transaction B (both in same netns) runs,
the xt target destructor has not been invoked yet.
For native nft expressions this is no problem because all expressions
that have such side effects make sure these are handled from the commit
phase, rather than async cleanup.
For nft_compat however this isn't true.
Instead of forcing synchronous behaviour for nft_compat, keep track
of the number of outstanding destructor calls.
When we attempt to create a new expression, flush the cleanup worker
to make sure destructors have completed.
With lots of help from Pablo Neira.
Reported-by: Pablo Neira Ayso <pablo@netfilter.org>
Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'net/netfilter/nf_tables_api.c')
-rw-r--r-- | net/netfilter/nf_tables_api.c | 10 |
1 files changed, 8 insertions, 2 deletions
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c index 88325b264737..79e4db3cadec 100644 --- a/net/netfilter/nf_tables_api.c +++ b/net/netfilter/nf_tables_api.c @@ -7290,6 +7290,12 @@ static void nf_tables_trans_destroy_work(struct work_struct *w) } } +void nf_tables_trans_destroy_flush_work(void) +{ + flush_work(&trans_destroy_work); +} +EXPORT_SYMBOL_GPL(nf_tables_trans_destroy_flush_work); + static int nf_tables_commit_chain_prepare(struct net *net, struct nft_chain *chain) { struct nft_rule *rule; @@ -7472,9 +7478,9 @@ static void nf_tables_commit_release(struct net *net) spin_unlock(&nf_tables_destroy_list_lock); nf_tables_module_autoload_cleanup(net); - mutex_unlock(&net->nft.commit_mutex); - schedule_work(&trans_destroy_work); + + mutex_unlock(&net->nft.commit_mutex); } static int nf_tables_commit(struct net *net, struct sk_buff *skb) |