116 lines
3.7 KiB
Diff
116 lines
3.7 KiB
Diff
From 97ce308f4fe922009df5ca2ea84d7c32cdab2532 Mon Sep 17 00:00:00 2001
|
|
From: Eric Garver <eric@garver.life>
|
|
Date: Wed, 22 May 2019 21:44:04 +0200
|
|
Subject: [PATCH] src: update cache if cmd is more specific
|
|
|
|
If we've done a partial fetch of the cache and the genid is the same the
|
|
cache update will be skipped without fetching the needed items. This
|
|
change flushes the cache if the new request is more specific than the
|
|
current cache - forcing a cache update which includes the needed items.
|
|
|
|
Introduces a simple scoring system which reflects how
|
|
cache_init_objects() looks at the current command to decide if it is
|
|
finished already or not. Then use that in cache_needs_more(): If current
|
|
command's score is higher than old command's, cache needs an update.
|
|
|
|
Fixes: 816d8c7659c1 ("Support 'add/insert rule index <IDX>'")
|
|
Signed-off-by: Eric Garver <eric@garver.life>
|
|
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
|
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
(cherry picked from commit eeda228c2d1719f5b6276b40ad14a5b3c3e88536)
|
|
|
|
Conflicts:
|
|
src/rule.c
|
|
-> Context change due to missing commit 0562beb6544d3
|
|
("src: get rid of netlink_genid_get()").
|
|
|
|
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
|
---
|
|
include/nftables.h | 1 +
|
|
src/rule.c | 20 +++++++++++++++++++
|
|
.../shell/testcases/cache/0003_cache_update_0 | 14 +++++++++++++
|
|
3 files changed, 35 insertions(+)
|
|
|
|
diff --git a/include/nftables.h b/include/nftables.h
|
|
index 5e209b417d5a5..e9425d1fc8fb3 100644
|
|
--- a/include/nftables.h
|
|
+++ b/include/nftables.h
|
|
@@ -36,6 +36,7 @@ struct nft_cache {
|
|
uint16_t genid;
|
|
struct list_head list;
|
|
uint32_t seqnum;
|
|
+ uint32_t cmd;
|
|
};
|
|
|
|
struct mnl_socket;
|
|
diff --git a/src/rule.c b/src/rule.c
|
|
index 850b00cfc9874..a03abe1bf0c47 100644
|
|
--- a/src/rule.c
|
|
+++ b/src/rule.c
|
|
@@ -151,6 +151,23 @@ static int cache_init(struct netlink_ctx *ctx, enum cmd_ops cmd)
|
|
return 0;
|
|
}
|
|
|
|
+/* Return a "score" of how complete local cache will be if
|
|
+ * cache_init_objects() ran for given cmd. Higher value
|
|
+ * means more complete. */
|
|
+static int cache_completeness(enum cmd_ops cmd)
|
|
+{
|
|
+ if (cmd == CMD_LIST)
|
|
+ return 3;
|
|
+ if (cmd != CMD_RESET)
|
|
+ return 2;
|
|
+ return 1;
|
|
+}
|
|
+
|
|
+static bool cache_needs_more(enum cmd_ops old_cmd, enum cmd_ops cmd)
|
|
+{
|
|
+ return cache_completeness(old_cmd) < cache_completeness(cmd);
|
|
+}
|
|
+
|
|
int cache_update(struct nft_ctx *nft, enum cmd_ops cmd, struct list_head *msgs)
|
|
{
|
|
uint16_t genid;
|
|
@@ -166,6 +183,8 @@ int cache_update(struct nft_ctx *nft, enum cmd_ops cmd, struct list_head *msgs)
|
|
replay:
|
|
ctx.seqnum = cache->seqnum++;
|
|
genid = netlink_genid_get(&ctx);
|
|
+ if (cache->genid && cache_needs_more(cache->cmd, cmd))
|
|
+ cache_release(cache);
|
|
if (genid && genid == cache->genid)
|
|
return 0;
|
|
if (cache->genid)
|
|
@@ -181,6 +200,7 @@ replay:
|
|
return -1;
|
|
}
|
|
cache->genid = genid;
|
|
+ cache->cmd = cmd;
|
|
return 0;
|
|
}
|
|
|
|
diff --git a/tests/shell/testcases/cache/0003_cache_update_0 b/tests/shell/testcases/cache/0003_cache_update_0
|
|
index deb45db2c43be..fa9b5df380a41 100755
|
|
--- a/tests/shell/testcases/cache/0003_cache_update_0
|
|
+++ b/tests/shell/testcases/cache/0003_cache_update_0
|
|
@@ -27,3 +27,17 @@ EOF
|
|
$NFT -i >/dev/null <<EOF
|
|
add table ip t3; add chain ip t c
|
|
EOF
|
|
+
|
|
+# The following test exposes a problem with incremental cache update when
|
|
+# reading commands from a file that add a rule using the "index" keyword.
|
|
+#
|
|
+# add rule ip t4 c meta l4proto icmp accept -> rule to reference in next step
|
|
+# add rule ip t4 c index 0 drop -> index 0 is not found due to rule cache not
|
|
+# being updated
|
|
+$NFT -i >/dev/null <<EOF
|
|
+add table ip t4; add chain ip t4 c
|
|
+add rule ip t4 c meta l4proto icmp accept
|
|
+EOF
|
|
+$NFT -f - >/dev/null <<EOF
|
|
+add rule ip t4 c index 0 drop
|
|
+EOF
|
|
--
|
|
2.22.0
|
|
|