From 294f9ef5ee354ff902dfdc091a604f93083c248d Mon Sep 17 00:00:00 2001 From: Phil Sutter Date: Thu, 16 Aug 2018 18:14:36 +0200 Subject: ebtables: Fix entries count in chain listing The previous fix for reference counts in iptables-nft output wasn't complete: While iptables lists the number of references for each custom chain (i.e., the number of jumps to it), ebtables lists number of entries (i.e., the number of rules contained) for each chain. Both used the same value for it, although they are different metrics. Fix this by passing both numbers separately to the 'print_header' callback so that each tool may print the desired value. Fixes: a0698de9866d2 ("xtables: Do not count rules as chain references") Signed-off-by: Phil Sutter Signed-off-by: Pablo Neira Ayuso --- iptables/nft-arp.c | 3 ++- iptables/nft-bridge.c | 4 +-- iptables/nft-shared.c | 2 +- iptables/nft-shared.h | 4 +-- iptables/nft.c | 6 ++--- .../shell/testcases/ebtables/0001-ebtables-basic_0 | 30 ++++++++++++++++++++++ 6 files changed, 40 insertions(+), 9 deletions(-) diff --git a/iptables/nft-arp.c b/iptables/nft-arp.c index f58109e5..2843c440 100644 --- a/iptables/nft-arp.c +++ b/iptables/nft-arp.c @@ -418,7 +418,8 @@ static void nft_arp_rule_to_cs(const struct nftnl_rule *r, static void nft_arp_print_header(unsigned int format, const char *chain, const char *pol, const struct xt_counters *counters, - bool basechain, uint32_t refs) + bool basechain, uint32_t refs, + uint32_t entries) { printf("Chain %s", chain); if (basechain && pol) { diff --git a/iptables/nft-bridge.c b/iptables/nft-bridge.c index 7dcc0c1a..6854d5b6 100644 --- a/iptables/nft-bridge.c +++ b/iptables/nft-bridge.c @@ -397,10 +397,10 @@ static void nft_bridge_print_table_header(const char *tablename) static void nft_bridge_print_header(unsigned int format, const char *chain, const char *pol, const struct xt_counters *counters, - bool basechain, uint32_t refs) + bool basechain, uint32_t refs, uint32_t entries) { printf("Bridge chain: %s, entries: %u, policy: %s\n", - chain, refs, basechain ? pol : "RETURN"); + chain, entries, basechain ? pol : "RETURN"); } static void print_matches_and_watchers(const struct iptables_command_state *cs, diff --git a/iptables/nft-shared.c b/iptables/nft-shared.c index 871037d2..b31234ee 100644 --- a/iptables/nft-shared.c +++ b/iptables/nft-shared.c @@ -680,7 +680,7 @@ void nft_clear_iptables_command_state(struct iptables_command_state *cs) void print_header(unsigned int format, const char *chain, const char *pol, const struct xt_counters *counters, bool basechain, - uint32_t refs) + uint32_t refs, uint32_t entries) { printf("Chain %s", chain); if (basechain) { diff --git a/iptables/nft-shared.h b/iptables/nft-shared.h index 49e2fa10..80750784 100644 --- a/iptables/nft-shared.h +++ b/iptables/nft-shared.h @@ -88,7 +88,7 @@ struct nft_family_ops { void (*print_header)(unsigned int format, const char *chain, const char *pol, const struct xt_counters *counters, bool basechain, - uint32_t refs); + uint32_t refs, uint32_t entries); void (*print_rule)(struct nftnl_rule *r, unsigned int num, unsigned int format); void (*save_rule)(const void *data, unsigned int format); @@ -149,7 +149,7 @@ void nft_rule_to_iptables_command_state(const struct nftnl_rule *r, void nft_clear_iptables_command_state(struct iptables_command_state *cs); void print_header(unsigned int format, const char *chain, const char *pol, const struct xt_counters *counters, bool basechain, - uint32_t refs); + uint32_t refs, uint32_t entries); void print_rule_details(const struct iptables_command_state *cs, const char *targname, uint8_t flags, uint8_t invflags, uint8_t proto, diff --git a/iptables/nft.c b/iptables/nft.c index 54755fcd..0b29caeb 100644 --- a/iptables/nft.c +++ b/iptables/nft.c @@ -2335,6 +2335,7 @@ int nft_rule_list(struct nft_handle *h, const char *chain, const char *table, .bcnt = nftnl_chain_get_u64(c, NFTNL_CHAIN_BYTES), }; bool basechain = false; + uint32_t entries; if (nftnl_chain_get(c, NFTNL_CHAIN_HOOKNUM)) basechain = true; @@ -2348,13 +2349,12 @@ int nft_rule_list(struct nft_handle *h, const char *chain, const char *table, ops->print_table_header(table); } - refs -= nft_rule_count(h, chain_name, table); - if (found) printf("\n"); + entries = nft_rule_count(h, chain_name, table); ops->print_header(format, chain_name, policy_name[policy], - &ctrs, basechain, refs); + &ctrs, basechain, refs - entries, entries); __nft_rule_list(h, chain_name, table, rulenum, format, ops->print_rule); diff --git a/iptables/tests/shell/testcases/ebtables/0001-ebtables-basic_0 b/iptables/tests/shell/testcases/ebtables/0001-ebtables-basic_0 index 05a2715f..b0db216a 100755 --- a/iptables/tests/shell/testcases/ebtables/0001-ebtables-basic_0 +++ b/iptables/tests/shell/testcases/ebtables/0001-ebtables-basic_0 @@ -28,6 +28,36 @@ case "$XT_MULTI" in exit 1 fi + $XT_MULTI ebtables -L FOO | grep -q 'entries: 0' + if [ $? -ne 0 ]; then + echo "Unexpected entries count in empty unreferenced chain" + $XT_MULTI ebtables -L + exit 1 + fi + + $XT_MULTI ebtables -A FORWARD -j FOO + $XT_MULTI ebtables -L FORWARD | grep -q 'entries: 1' + if [ $? -ne 0 ]; then + echo "Unexpected entries count in FORWARD chain" + $XT_MULTI ebtables -L + exit 1 + fi + + $XT_MULTI ebtables -L FOO | grep -q 'entries: 0' + if [ $? -ne 0 ]; then + echo "Unexpected entries count in empty referenced chain" + $XT_MULTI ebtables -L + exit 1 + fi + + $XT_MULTI ebtables -A FOO -j ACCEPT + $XT_MULTI ebtables -L FOO | grep -q 'entries: 1' + if [ $? -ne 0 ]; then + echo "Unexpected entries count in non-empty referenced chain" + $XT_MULTI ebtables -L + exit 1 + fi + $XT_MULTI ebtables -t filter -N BAR || exit 1 $XT_MULTI ebtables -t filter -N BAZ || exit 1 -- cgit v1.2.3