Re: [PATCH nf,v2 2/2] netfilter: nf_tables: call set ops .commit when building new ruleset

Florian Westphal <[email protected]>
Newsgroups gmane.comp.security.firewalls.netfilter.devel
Message-ID <[email protected]>
Pablo Neira Ayuso <[email protected]> wrote:
> > Why must the blob be rebuilt before stale node purge in rbtree case?
> 
> ... there is a gap between the ruleset blob is built and published and
> the set .commit interface is called to publish the new version of the
> rbtree/pipapo datastructure.
> 
> See:
> https://lore.kernel.org/netfilter-devel/[email protected]/

Ah. That makes sense. So the problem is not rbtree specific.  Problem is
that packets switch over to the *new base chain* (linked to nf machinery,
nft rule blob becomes reachable on base_seq swap:

1. commit phase starts.
2. seqcount gets bumped.
 A.  	Packet p1 enters machinery
3. elements get purged / chains / tables unlinked, netlink notificatons
   etc. etc.
 B.     Packet p1 is in nft_lookup, which gets updated base_seq,
        but no match because rbtree blob resp. pipapo live blob
	are empty in the 'flush ruleset; table t { ..' case.
4. nft_set_commit_update() is called.

If the above is right your patch makes much more sense now :-)

The logic with (set->ops->abort_skip_removal && early_commit)
however is hard to grasp.

Even with NFT_COMMIT_PHASE_EARLY or whatever its bad because
the set implementation details leak into the transaction phase.
But I understand that you'd like to at least solve it for rbtree
with a smaller change, so thats ok.

Is there a long-term plan?

Maybe your 'pre-commit' phase could iterate the transaction
log and relink transactions (add/del/update of set elements
) to the owning set?  Contradicting transactions (destroy set x,
then remove element from x) should have been caught earlier, so
this delete-from-transaction-log-and-link-to-per-set-struct should
not be a problem.  Perhaps we might see issues with changes in the
netlink reporting order... but thats hopefully easy to avoid.

the ->commit() callback could then access the pending transactions
for the set (element adds/deletes) and always get invoked early.

Pipapo could walk its specific elem deletions internally, then swap.

The only other issue I see is that we need a second
list_for_each_entry_safe(trans, next, &nft_net->commit_list, list)

... walk, because the step-1 walk is allowed to fail.
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.