diff options
author | Pablo Neira Ayuso <pablo@netfilter.org> | 2019-07-23 15:03:23 +0200 |
---|---|---|
committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2019-07-23 20:47:19 +0200 |
commit | 3ab02db5f836ae0cf9fe7fba616d7eb52139d537 (patch) | |
tree | 38004431535ef5da7de95a31e2b0783ba2e5d8c8 /src/rule.c | |
parent | f4d0f16834f62e7e895f05f2e961d62487327f4b (diff) |
cache: add NFT_CACHE_UPDATE and NFT_CACHE_FLUSHED flags
NFT_CACHE_FLUSHED tells cache_update() to skip the netlink dump to
populate the cache, since the existing ruleset is going to flushed by
this batch.
NFT_CACHE_UPDATE tells rule_evaluate() to perform incremental updates to
the cache based on the existing batch, this is required by the rule
commands that use the index and the position selectors.
This patch removes cache_flush() which is not required anymore. This
cache removal is coming too late, in the evaluation phase, after the
initial cache_update() invocation.
Be careful with NFT_CACHE_UPDATE, this flag needs to be left in place if
NFT_CACHE_FLUSHED is set on.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'src/rule.c')
-rw-r--r-- | src/rule.c | 33 |
1 files changed, 16 insertions, 17 deletions
@@ -224,7 +224,7 @@ static int cache_init(struct netlink_ctx *ctx, unsigned int flags) return 0; } -bool cache_is_complete(struct nft_cache *cache, unsigned int flags) +static bool cache_is_complete(struct nft_cache *cache, unsigned int flags) { return (cache->flags & flags) == flags; } @@ -234,6 +234,11 @@ static bool cache_is_updated(struct nft_cache *cache, uint16_t genid) return genid && genid == cache->genid; } +bool cache_needs_update(struct nft_cache *cache) +{ + return cache->flags & NFT_CACHE_UPDATE; +} + int cache_update(struct nft_ctx *nft, unsigned int flags, struct list_head *msgs) { struct netlink_ctx ctx = { @@ -242,7 +247,7 @@ int cache_update(struct nft_ctx *nft, unsigned int flags, struct list_head *msgs .msgs = msgs, }; struct nft_cache *cache = &nft->cache; - uint32_t genid, genid_stop; + uint32_t genid, genid_stop, oldflags; int ret; replay: ctx.seqnum = cache->seqnum++; @@ -254,6 +259,14 @@ replay: if (cache->genid) cache_release(cache); + if (flags & NFT_CACHE_FLUSHED) { + oldflags = flags; + flags = NFT_CACHE_EMPTY; + if (oldflags & NFT_CACHE_UPDATE) + flags |= NFT_CACHE_UPDATE; + goto skip; + } + ret = cache_init(&ctx, flags); if (ret < 0) { cache_release(cache); @@ -269,7 +282,7 @@ replay: cache_release(cache); goto replay; } - +skip: cache->genid = genid; cache->flags = flags; return 0; @@ -285,20 +298,6 @@ static void __cache_flush(struct list_head *table_list) } } -void cache_flush(struct nft_ctx *nft, struct list_head *msgs) -{ - struct netlink_ctx ctx = { - .list = LIST_HEAD_INIT(ctx.list), - .nft = nft, - .msgs = msgs, - }; - struct nft_cache *cache = &nft->cache; - - __cache_flush(&cache->list); - cache->genid = mnl_genid_get(&ctx); - cache->flags = NFT_CACHE_FULL; -} - void cache_release(struct nft_cache *cache) { __cache_flush(&cache->list); |