summaryrefslogtreecommitdiffstats
path: root/iptables/nft-cache.c
diff options
context:
space:
mode:
authorPhil Sutter <phil@nwl.cc>2019-08-28 12:33:55 +0200
committerPhil Sutter <phil@nwl.cc>2019-10-17 19:03:00 +0200
commitc41b98babd55f35834e5fea599a914d69d60a9bd (patch)
tree9ae60a41765df0d07b7863e98ef121ea5bef0ded /iptables/nft-cache.c
parent48a21d5c7af074bd502a4f6fa7d8a46cfa719732 (diff)
nft: Optimize flushing all chains of a table
Leverage nftables' support for flushing all chains of a table by omitting NFTNL_RULE_CHAIN attribute in NFT_MSG_DELRULE payload. The only caveat is with verbose output, as that still requires to have a list of (existing) chains to iterate over. Apart from that, implementing this shortcut is pretty straightforward: Don't retrieve a chain list and just call __nft_rule_flush() directly which doesn't set above attribute if chain name pointer is NULL. A bigger deal is keeping rule cache consistent: Instead of just clearing rule list for each flushed chain, flush_rule_cache() is updated to iterate over all cached chains of the given table, clearing their rule lists if not called for a specific chain. While being at it, sort local variable declarations in nft_rule_flush() from longest to shortest and drop the loop-local 'chain_name' variable (but instead use 'chain' function parameter which is not used at that point). Signed-off-by: Phil Sutter <phil@nwl.cc> Acked-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'iptables/nft-cache.c')
-rw-r--r--iptables/nft-cache.c22
1 files changed, 19 insertions, 3 deletions
diff --git a/iptables/nft-cache.c b/iptables/nft-cache.c
index 64dcda57..c55970d0 100644
--- a/iptables/nft-cache.c
+++ b/iptables/nft-cache.c
@@ -384,7 +384,7 @@ static void __nft_flush_cache(struct nft_handle *h)
}
}
-static int __flush_rule_cache(struct nftnl_rule *r, void *data)
+static int ____flush_rule_cache(struct nftnl_rule *r, void *data)
{
nftnl_rule_list_del(r);
nftnl_rule_free(r);
@@ -392,9 +392,25 @@ static int __flush_rule_cache(struct nftnl_rule *r, void *data)
return 0;
}
-void flush_rule_cache(struct nftnl_chain *c)
+static int __flush_rule_cache(struct nftnl_chain *c, void *data)
{
- nftnl_rule_foreach(c, __flush_rule_cache, NULL);
+ return nftnl_rule_foreach(c, ____flush_rule_cache, NULL);
+}
+
+int flush_rule_cache(struct nft_handle *h, const char *table,
+ struct nftnl_chain *c)
+{
+ const struct builtin_table *t;
+
+ if (c)
+ return __flush_rule_cache(c, NULL);
+
+ t = nft_table_builtin_find(h, table);
+ if (!t || !h->cache->table[t->type].chains)
+ return 0;
+
+ return nftnl_chain_list_foreach(h->cache->table[t->type].chains,
+ __flush_rule_cache, NULL);
}
static int __flush_chain_cache(struct nftnl_chain *c, void *data)