OSDN Git Service

netfilter: nf_tables: permit second nat hook if colliding hook is going away
authorFlorian Westphal <fw@strlen.de>
Sun, 18 Mar 2018 18:22:39 +0000 (19:22 +0100)
committerPablo Neira Ayuso <pablo@netfilter.org>
Tue, 20 Mar 2018 12:55:03 +0000 (13:55 +0100)
commitae6153b50f9bf75a4952050f32fe168f68cdd657
tree3e035f3177b2f60fa575df671fd377aa5901f3ee
parent4f2921ca21b71a9faaecd84a9fc74401d3a8d275
netfilter: nf_tables: permit second nat hook if colliding hook is going away

Sergei Trofimovich reported that restoring an nft ruleset doesn't work
anymore unless old rule content is flushed first.

The problem stems from a recent change designed to prevent multiple nat
hooks at the same hook point locations and nftables transaction model.

A 'flush ruleset' won't take effect until the entire transaction has
completed.

So, if one has a nft.rules file that contains a 'flush ruleset',
followed by a nat hook register request, then 'nft -f file' will work,
but running 'nft -f file' again will fail with -EBUSY.

Reason is that nftables will place the flush/removal requests in the
transaction list, but it will not act on the removal until after all new
rules are in place.

The netfilter core will therefore get request to register a new nat
hook before the old one is removed -- this now fails as the netfilter
core can't know the existing hook is staged for removal.

To fix this, we can search the transaction log when a hook collision
is detected.  The collision is okay if

 1. there is a delete request pending for the nat hook that is already
    registered.
 2. there is no second add request for a matching nat hook.
    This is required to only apply the exception once.

Fixes: f92b40a8b2645 ("netfilter: core: only allow one nat hook per hook point")
Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
net/netfilter/nf_tables_api.c