From a0698de9866d2e0ede5eee961a9da38e0ede7062 Mon Sep 17 00:00:00 2001 From: Phil Sutter Date: Fri, 3 Aug 2018 15:33:02 +0200 Subject: 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 Signed-off-by: Florian Westphal --- iptables/nft.c | 38 ++++++++++++++++++++++ .../shell/testcases/iptables/0001-chain-refs_0 | 14 ++++++++ 2 files changed, 52 insertions(+) create mode 100755 iptables/tests/shell/testcases/iptables/0001-chain-refs_0 (limited to 'iptables') 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)' -- cgit v1.2.3