summaryrefslogtreecommitdiffstats
path: root/src/rule.c
diff options
context:
space:
mode:
authorPhil Sutter <phil@nwl.cc>2017-10-25 13:40:29 +0200
committerPablo Neira Ayuso <pablo@netfilter.org>2017-10-26 20:14:24 +0200
commit94a945ffa81b7f1db250e519f0b4b808428ab223 (patch)
tree869b5960a682e6379762db0cd385b4aec52b6c4b /src/rule.c
parentf8596968a650c66e0b4d5895b700d03d7518b245 (diff)
libnftables: Get rid of explicit cache flushes
In the past, CLI as a potentially long running process had to make sure it kept it's cache up to date with kernel's rule set. A simple test case is this: | shell a | shell b | | # nft -i | # nft add table ip t | | | nft> list ruleset | | table ip t { | | } | # nft flush ruleset | | | nft> list ruleset | | nft> In order to make sure interactive CLI wouldn't incorrectly list the table again in the second 'list' command, it immediately flushed it's cache after every command execution. This patch eliminates the need for that by making cache updates depend on kernel's generation ID: A cache update stores the current rule set's ID in struct nft_cache, consecutive calls to cache_update() compare that stored value to the current generation ID received from kernel - if the stored value is zero (i.e. no previous cache update did happen) or if it doesn't match the kernel's value (i.e. cache is outdated) the cache is flushed and fully initialized again. Signed-off-by: Phil Sutter <phil@nwl.cc> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'src/rule.c')
-rw-r--r--src/rule.c12
1 files changed, 7 insertions, 5 deletions
diff --git a/src/rule.c b/src/rule.c
index 948478c9..6a322167 100644
--- a/src/rule.c
+++ b/src/rule.c
@@ -153,12 +153,14 @@ int cache_update(struct mnl_socket *nf_sock, struct nft_cache *cache,
enum cmd_ops cmd, struct list_head *msgs, bool debug,
struct output_ctx *octx)
{
+ uint16_t genid;
int ret;
- if (cache->initialized)
- return 0;
replay:
- netlink_genid_get(nf_sock, cache->seqnum++);
+ genid = netlink_genid_get(nf_sock, cache->seqnum++);
+ if (genid && genid == cache->genid)
+ return 0;
+ cache_release(cache);
ret = cache_init(nf_sock, cache, cmd, msgs, debug, octx);
if (ret < 0) {
cache_release(cache);
@@ -168,7 +170,7 @@ replay:
}
return -1;
}
- cache->initialized = true;
+ cache->genid = genid;
return 0;
}
@@ -185,7 +187,7 @@ void cache_flush(struct list_head *table_list)
void cache_release(struct nft_cache *cache)
{
cache_flush(&cache->list);
- cache->initialized = false;
+ cache->genid = 0;
}
/* internal ID to uniquely identify a set in the batch */