]> git.baikalelectronics.ru Git - kernel.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)
commit82560e53d11eb059be5f3442189d6bde4fd1674e
treeb45c95130159d0d177305862612698a4db397592
parent097977b1d1c92d0808149e566a0b0477a87e65ee
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