]> git.proxmox.com Git - mirror_ubuntu-kernels.git/commit
netfilter: nf_tables: remove synchronize_rcu in commit phase
authorFlorian Westphal <fw@strlen.de>
Thu, 24 May 2018 22:25:48 +0000 (00:25 +0200)
committerPablo Neira Ayuso <pablo@netfilter.org>
Tue, 29 May 2018 12:49:59 +0000 (14:49 +0200)
commit0cbc06b3faba756113d4ac748b089529f813eda4
treeb45c95130159d0d177305862612698a4db397592
parent003087911af28941a95fa053db0ac36b2ee27207
netfilter: nf_tables: remove synchronize_rcu in commit phase

synchronize_rcu() is expensive.

The commit phase currently enforces an unconditional
synchronize_rcu() after incrementing the generation counter.

This is to make sure that a packet always sees a consistent chain, either
nft_do_chain is still using old generation (it will skip the newly added
rules), or the new one (it will skip old ones that might still be linked
into the list).

We could just remove the synchronize_rcu(), it would not cause a crash but
it could cause us to evaluate a rule that was removed and new rule for the
same packet, instead of either-or.

To resolve this, add rule pointer array holding two generations, the
current one and the future generation.

In commit phase, allocate the rule blob and populate it with the rules that
will be active in the new generation.

Then, make this rule blob public, replacing the old generation pointer.

Then the generation counter can be incremented.

nft_do_chain() will either continue to use the current generation
(in case loop was invoked right before increment), or the new one.

Suggested-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
include/net/netfilter/nf_tables.h
net/netfilter/nf_tables_api.c
net/netfilter/nf_tables_core.c