diff options
author | Phil Sutter <phil@nwl.cc> | 2018-08-03 15:33:02 +0200 |
---|---|---|
committer | Florian Westphal <fw@strlen.de> | 2018-08-04 23:29:35 +0200 |
commit | a0698de9866d2e0ede5eee961a9da38e0ede7062 (patch) | |
tree | 778633a8c90ba7876e8dacb12c762bcfef6c688f | |
parent | d11b6b8c3cc459eeec6438e2ad35e8ab46b3527f (diff) |
xtables: Do not count rules as chain references
Unlike iptables, nftables counts rules in a chain as references to that
chain. Align output of 'iptables-nft -L' with that of legacy iptables by
counting the number of rules in a chain and subtracting that value from
reference count before printing the chain header.
Signed-off-by: Phil Sutter <phil@nwl.cc>
Signed-off-by: Florian Westphal <fw@strlen.de>
-rw-r--r-- | iptables/nft.c | 38 | ||||
-rwxr-xr-x | iptables/tests/shell/testcases/iptables/0001-chain-refs_0 | 14 |
2 files changed, 52 insertions, 0 deletions
diff --git a/iptables/nft.c b/iptables/nft.c index f483eb6f..098b37ed 100644 --- a/iptables/nft.c +++ b/iptables/nft.c @@ -2184,6 +2184,42 @@ err: return ret; } +static int nft_rule_count(struct nft_handle *h, + const char *chain, const char *table) +{ + struct nftnl_rule_list_iter *iter; + struct nftnl_rule_list *list; + struct nftnl_rule *r; + int rule_ctr = 0; + + list = nft_rule_list_get(h); + if (list == NULL) + return 0; + + iter = nftnl_rule_list_iter_create(list); + if (iter == NULL) + return 0; + + r = nftnl_rule_list_iter_next(iter); + while (r != NULL) { + const char *rule_table = + nftnl_rule_get_str(r, NFTNL_RULE_TABLE); + const char *rule_chain = + nftnl_rule_get_str(r, NFTNL_RULE_CHAIN); + + if (strcmp(table, rule_table) != 0 || + strcmp(chain, rule_chain) != 0) + goto next; + + rule_ctr++; +next: + r = nftnl_rule_list_iter_next(iter); + } + + nftnl_rule_list_iter_destroy(iter); + return rule_ctr; +} + int nft_rule_list(struct nft_handle *h, const char *chain, const char *table, int rulenum, unsigned int format) { @@ -2249,6 +2285,8 @@ int nft_rule_list(struct nft_handle *h, const char *chain, const char *table, if (chain && strcmp(chain, chain_name) != 0) goto next; + refs -= nft_rule_count(h, chain_name, table); + if (found) printf("\n"); diff --git a/iptables/tests/shell/testcases/iptables/0001-chain-refs_0 b/iptables/tests/shell/testcases/iptables/0001-chain-refs_0 new file mode 100755 index 00000000..e55506e8 --- /dev/null +++ b/iptables/tests/shell/testcases/iptables/0001-chain-refs_0 @@ -0,0 +1,14 @@ +#!/bin/bash + +# make sure rules are not counted in references of iptables output + +set -e + +$XT_MULTI iptables -N foo +$XT_MULTI iptables -L | grep 'Chain foo (0 references)' + +$XT_MULTI iptables -A foo -j ACCEPT +$XT_MULTI iptables -L | grep 'Chain foo (0 references)' + +$XT_MULTI iptables -A FORWARD -j foo +$XT_MULTI iptables -L | grep 'Chain foo (1 references)' |