[PATCH nft] src: cache gets out of sync in interactive mode

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Since 94a945ffa81b ("libnftables: Get rid of explicit cache flushes"),
the cache logic checks for the generation number to refresh the cache.

This breaks interactive mode when listing stateful objects though. This
patch adds a new flag to force a cache refresh when the user requests a
ruleset listing.

Signed-off-by: Pablo Neira Ayuso <pablo@xxxxxxxxxxxxx>
---
 include/cache.h | 1 +
 src/cache.c     | 2 ++
 src/rule.c      | 8 +++++++-
 3 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/include/cache.h b/include/cache.h
index 86a7eff78055..213a6eaf9104 100644
--- a/include/cache.h
+++ b/include/cache.h
@@ -30,6 +30,7 @@ enum cache_level_flags {
 				  NFT_CACHE_CHAIN_BIT |
 				  NFT_CACHE_RULE_BIT,
 	NFT_CACHE_FULL		= __NFT_CACHE_MAX_BIT - 1,
+	NFT_CACHE_REFRESH	= (1 << 29),
 	NFT_CACHE_UPDATE	= (1 << 30),
 	NFT_CACHE_FLUSHED	= (1 << 31),
 };
diff --git a/src/cache.c b/src/cache.c
index a45111a7920e..7797ff6b0460 100644
--- a/src/cache.c
+++ b/src/cache.c
@@ -143,6 +143,8 @@ unsigned int cache_evaluate(struct nft_ctx *nft, struct list_head *cmds)
 			break;
 		case CMD_LIST:
 		case CMD_EXPORT:
+			flags |= NFT_CACHE_FULL | NFT_CACHE_REFRESH;
+			break;
 		case CMD_MONITOR:
 			flags |= NFT_CACHE_FULL;
 			break;
diff --git a/src/rule.c b/src/rule.c
index 6335aa2189ad..8dc1792b4e5a 100644
--- a/src/rule.c
+++ b/src/rule.c
@@ -237,6 +237,11 @@ static bool cache_is_complete(struct nft_cache *cache, unsigned int flags)
 	return (cache->flags & flags) == flags;
 }
 
+static bool cache_needs_refresh(struct nft_cache *cache)
+{
+	return cache->flags & NFT_CACHE_REFRESH;
+}
+
 static bool cache_is_updated(struct nft_cache *cache, uint16_t genid)
 {
 	return genid && genid == cache->genid;
@@ -261,7 +266,8 @@ int cache_update(struct nft_ctx *nft, unsigned int flags, struct list_head *msgs
 replay:
 	ctx.seqnum = cache->seqnum++;
 	genid = mnl_genid_get(&ctx);
-	if (cache_is_complete(cache, flags) &&
+	if (!cache_needs_refresh(cache) &&
+	    cache_is_complete(cache, flags) &&
 	    cache_is_updated(cache, genid))
 		return 0;
 
-- 
2.20.1




[Index of Archives]     [Netfitler Users]     [Berkeley Packet Filter]     [LARTC]     [Bugtraq]     [Yosemite Forum]

  Powered by Linux