summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@netfilter.org>2024-05-27 18:12:05 +0200
committerPablo Neira Ayuso <pablo@netfilter.org>2024-06-03 20:17:49 +0200
commitbbb0e944b59d355085e8f50b4b7b5057ae0d33a4 (patch)
tree2cfde3b2dddb7dc034e375655606747b6ac0671e
parentf6b579344eee17e5587b6a7fcc444fe997cd8cb6 (diff)
cache: check for NFT_CACHE_REFRESH in current requested cache too
NFT_CACHE_REFRESH is set on inconditionally by ruleset list commands to deal with stateful information in this ruleset. This flag results in dropping the existing cache and fully fetching all objects from the kernel. Set on this flag for reset commands too, this is missing. List/reset commands allow for filtering by specific family and object, therefore, NFT_CACHE_REFRESH also signals that the cache is partially populated. Check if this flag is requested by the current list/reset command, as well as cache->flags which represents the cache after the _previous_ list of commands. A follow up patch allows to recycle the existing cache if the flags report that the same objects are already available in the cache, NFT_CACHE_REFRESH is useful to report that cache cannot be recycled. Fixes: 407c54f71255 ("src: cache gets out of sync in interactive mode") Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
-rw-r--r--src/cache.c8
1 files changed, 5 insertions, 3 deletions
diff --git a/src/cache.c b/src/cache.c
index c000e32c..e88cbae2 100644
--- a/src/cache.c
+++ b/src/cache.c
@@ -297,6 +297,7 @@ static unsigned int evaluate_cache_reset(struct cmd *cmd, unsigned int flags,
flags |= NFT_CACHE_TABLE;
break;
}
+ flags |= NFT_CACHE_REFRESH;
return flags;
}
@@ -1177,9 +1178,10 @@ static bool nft_cache_is_complete(struct nft_cache *cache, unsigned int flags)
return (cache->flags & flags) == flags;
}
-static bool nft_cache_needs_refresh(struct nft_cache *cache)
+static bool nft_cache_needs_refresh(struct nft_cache *cache, unsigned int flags)
{
- return cache->flags & NFT_CACHE_REFRESH;
+ return (cache->flags & NFT_CACHE_REFRESH) ||
+ (flags & NFT_CACHE_REFRESH);
}
static bool nft_cache_is_updated(struct nft_cache *cache, uint16_t genid)
@@ -1207,7 +1209,7 @@ int nft_cache_update(struct nft_ctx *nft, unsigned int flags,
replay:
ctx.seqnum = cache->seqnum++;
genid = mnl_genid_get(&ctx);
- if (!nft_cache_needs_refresh(cache) &&
+ if (!nft_cache_needs_refresh(cache, flags) &&
nft_cache_is_complete(cache, flags) &&
nft_cache_is_updated(cache, genid))
return 0;