extern unsigned int cache_evaluate(struct nft_ctx *nft, struct list_head *cmds);
extern int cache_update(struct nft_ctx *ctx, enum cmd_ops cmd,
struct list_head *msgs);
-extern void cache_flush(struct nft_ctx *ctx, struct list_head *msgs);
+extern bool cache_needs_update(struct nft_cache *cache);
extern void cache_release(struct nft_cache *cache);
-extern bool cache_is_complete(struct nft_cache *cache, enum cmd_ops cmd);
struct timeout_protocol {
uint32_t array_size;
return -1;
}
- /* add rules to cache only if it is complete enough to contain them */
- if (!cache_is_complete(&ctx->nft->cache, NFT_CACHE_RULE))
- return 0;
+ if (cache_needs_update(&ctx->nft->cache))
+ return rule_cache_update(ctx, op);
- return rule_cache_update(ctx, op);
+ return 0;
}
static uint32_t str2hooknum(uint32_t family, const char *hook)
switch (cmd->obj) {
case CMD_OBJ_RULESET:
- cache_flush(ctx->nft, ctx->msgs);
break;
case CMD_OBJ_TABLE:
/* Flushing a table does not empty the sets in the table nor remove
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;
}
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 = {
.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++;
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);
cache_release(cache);
goto replay;
}
-
+skip:
cache->genid = genid;
cache->flags = flags;
return 0;
}
}
-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);