summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPhil Sutter <phil@nwl.cc>2018-08-03 15:33:02 +0200
committerFlorian Westphal <fw@strlen.de>2018-08-04 23:29:35 +0200
commita0698de9866d2e0ede5eee961a9da38e0ede7062 (patch)
tree778633a8c90ba7876e8dacb12c762bcfef6c688f
parentd11b6b8c3cc459eeec6438e2ad35e8ab46b3527f (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.c38
-rwxr-xr-xiptables/tests/shell/testcases/iptables/0001-chain-refs_014
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)'