netfilter-devel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Pablo Neira Ayuso <pablo@netfilter.org>
To: Phil Sutter <phil@nwl.cc>, Eric Garver <eric@garver.life>,
	netfilter-devel@vger.kernel.org, nhofmeyr@sysmocom.de
Subject: Re: [PATCH nft 2/2,v2] cache: recycle existing cache with incremental updates
Date: Tue, 23 Jul 2024 14:19:19 +0200	[thread overview]
Message-ID: <Zp-fx35ewU1n8EE5@calendula> (raw)
In-Reply-To: <Zp-afhWpdM9R4hco@orbyte.nwl.cc>

[-- Attachment #1: Type: text/plain, Size: 3303 bytes --]

On Tue, Jul 23, 2024 at 01:56:46PM +0200, Phil Sutter wrote:
> Some digging and lots of printf's later:
> 
> On Mon, Jul 22, 2024 at 11:34:01PM +0200, Pablo Neira Ayuso wrote:
> [...]
> > I can reproduce it:
> > 
> > # nft -i
> > nft> add table inet foo
> > nft> add chain inet foo bar { type filter hook input priority filter; }
> > nft> add rule inet foo bar accept
> 
> This bumps cache->flags from 0 to 0x1f (no cache -> NFT_CACHE_OBJECT).
> 
> > nft> insert rule inet foo bar index 0 accept
> 
> This adds NFT_CACHE_RULE_BIT and NFT_CACHE_UPDATE, cache is updated (to
> fetch rules).
> 
> > nft> add rule inet foo bar index 0 accept
> 
> No new flags for this one, so the code hits the 'genid == cache->genid +
> 1' case in nft_cache_is_updated() which bumps the local genid and skips
> a cache update. The new rule then references the cached copy of the
> previously commited one which still does not have a handle. Therefore
> link_rules() does it's thing for references to  uncommitted rules which
> later fails.
> 
> Pablo: Could you please explain the logic around this cache->genid
> increment? Commit e791dbe109b6d ("cache: recycle existing cache with
> incremental updates") is not clear to me in this regard. How can the
> local process know it doesn't need whatever has changed in the kernel?

The idea is to use the ruleset generation ID as a hint to infer if the
existing cache can be recycled, to speed up incremental updates. This
is not sufficient for the index cache, see below.

> > Error: Could not process rule: No such file or directory
> 
> BTW: There are surprisingly many spots which emit a "Could not process
> rule:" error. I'm sure it may be provoked for non-rule-related commands
> (e.g. the calls in nft_netlink()).
> 
> > add rule inet foo bar index 0 accept
> > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> > 
> > Cache woes. Maybe a bug in
> > 
> > commit e5382c0d08e3c6d8246afa95b7380f0d6b8c1826
> > Author: Phil Sutter <phil@nwl.cc>
> > Date:   Fri Jun 7 19:21:21 2019 +0200
> > 
> >     src: Support intra-transaction rule references
> > 
> > that uncover now that cache is not flushed and sync with kernel so often?
> 
> The commit by itself is fine, as long as the cache is up to date. The
> problem is we have this previously inserted rule in cache which does not
> have a handle although it was committed to kernel already. This is
> something I don't see covered by e791dbe109b6d at all.

Yes, your commit relies on the frequent flush and resync at that time,
which is correct.

See attached patch, it sets on NFT_CACHE_REFRESH so a fresh cache from
the kernel is fetched in each run, it fixes the issue for me.

A quick recap:

Step #1 add rule inet foo bar accept

No cache is updated, because no NFT_CACHE_UPDATE is ever set on in
this case. It is not possible to know that the that the next command
will use the index feature.

After this point, the cache is inconsistent for this index feature.

Generation ID is checked, if cache is current, the previous rule in
step #1 is not there in the cache.

It should be possible to improve this logic to indicate that the cache
supports updates via index, instead of forcing a cache dump from the
kernel on each new index command.

So NFT_CACHE_UPDATE is only useful for intra-batch updates as you
commit describes.

[-- Attachment #2: x.patch --]
[-- Type: text/x-diff, Size: 421 bytes --]

diff --git a/src/cache.c b/src/cache.c
index 4b797ec79ae5..1fda3f6939f5 100644
--- a/src/cache.c
+++ b/src/cache.c
@@ -68,7 +68,7 @@ static unsigned int evaluate_cache_add(struct cmd *cmd, unsigned int flags)
 
 		if (cmd->handle.index.id ||
 		    cmd->handle.position.id)
-			flags |= NFT_CACHE_RULE | NFT_CACHE_UPDATE;
+			flags |= NFT_CACHE_RULE | NFT_CACHE_UPDATE | NFT_CACHE_REFRESH;
 		break;
 	default:
 		break;

  reply	other threads:[~2024-07-23 12:19 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-05-28 15:28 [PATCH nft 1/2,v2] cache: check for NFT_CACHE_REFRESH in current requested cache too Pablo Neira Ayuso
2024-05-28 15:28 ` [PATCH nft 2/2,v2] cache: recycle existing cache with incremental updates Pablo Neira Ayuso
2024-07-22 20:48   ` Eric Garver
2024-07-22 21:34     ` Pablo Neira Ayuso
2024-07-23  5:29       ` Phil Sutter
2024-07-23 11:56       ` Phil Sutter
2024-07-23 12:19         ` Pablo Neira Ayuso [this message]
2024-07-23 12:57           ` Pablo Neira Ayuso
2024-07-23 15:09             ` Phil Sutter
2024-07-24  7:51               ` Pablo Neira Ayuso
2024-07-23 14:34           ` Phil Sutter
2024-07-23 19:30             ` Eric Garver
2024-07-23 20:56               ` Phil Sutter
2024-07-24  7:44               ` Pablo Neira Ayuso
2024-07-24 11:51                 ` Eric Garver

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=Zp-fx35ewU1n8EE5@calendula \
    --to=pablo@netfilter.org \
    --cc=eric@garver.life \
    --cc=netfilter-devel@vger.kernel.org \
    --cc=nhofmeyr@sysmocom.de \
    --cc=phil@nwl.cc \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).