]> git.ipfire.org Git - thirdparty/iptables.git/commit
nft: Fix for concurrent noflush restore calls
authorPhil Sutter <phil@nwl.cc>
Mon, 5 Oct 2020 14:06:49 +0000 (16:06 +0200)
committerPhil Sutter <phil@nwl.cc>
Tue, 13 Oct 2020 10:08:37 +0000 (12:08 +0200)
commitdac904bdcd9a18aabafee7275ccf0c2bd53800f3
treee29b5f964110b6d213f8791fb2e42bc18a0631cb
parentc6cff7ddd4ee8ac8b500a9c928612acf39bfa9ec
nft: Fix for concurrent noflush restore calls

Transaction refresh was broken with regards to nft_chain_restore(): It
created a rule flush batch object only if the chain was found in cache
and a chain add object only if the chain was not found. Yet with
concurrent ruleset updates, one has to expect both situations:

* If a chain vanishes, the rule flush job must be skipped and instead
  the chain add job become active.

* If a chain appears, the chain add job must be skipped and instead
  rules flushed.

Change the code accordingly: Create both batch objects and set their
'skip' field depending on the situation in cache and adjust both in
nft_refresh_transaction().

As a side-effect, the implicit rule flush becomes explicit and all
handling of implicit batch jobs is dropped along with the related field
indicating such.

Reuse the 'implicit' parameter of __nft_rule_flush() to control the
initial 'skip' field value instead.

A subtle caveat is vanishing of existing chains: Creating the chain add
job based on the chain in cache causes a netlink message containing that
chain's handle which the kernel dislikes. Therefore unset the chain's
handle in that case.

Fixes: 58d7de0181f61 ("xtables: handle concurrent ruleset modifications")
Signed-off-by: Phil Sutter <phil@nwl.cc>
iptables/nft.c
iptables/tests/shell/testcases/ipt-restore/0016-concurrent-restores_0 [new file with mode: 0755]