diff options
author | Phil Sutter <phil@nwl.cc> | 2019-08-28 12:33:55 +0200 |
---|---|---|
committer | Phil Sutter <phil@nwl.cc> | 2019-10-17 19:03:00 +0200 |
commit | c41b98babd55f35834e5fea599a914d69d60a9bd (patch) | |
tree | 9ae60a41765df0d07b7863e98ef121ea5bef0ded /iptables/nft-cache.c | |
parent | 48a21d5c7af074bd502a4f6fa7d8a46cfa719732 (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.c | 22 |
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) |