summaryrefslogtreecommitdiffstats
path: root/iptables
diff options
context:
space:
mode:
authorPhil Sutter <phil@nwl.cc>2018-08-07 12:29:35 +0200
committerFlorian Westphal <fw@strlen.de>2018-08-09 22:56:36 +0200
commit528cbf99ff6062420270e637df4d40a77514fe56 (patch)
tree7055aa1c7a02a8c314b7559781118786ee574c8b /iptables
parent9ca32c40ed4f0648893989c1e5d03e9fecc501ae (diff)
xtables: Fix for wrong counter format in -S output
Legacy iptables uses '-c PCNT BCNT' format in listed rules, nft-variant used '[PCNT BCNT]' prefix like with iptables-save. In order to pass the counter format preference along, FMT_C_COUNTS is introduced and related 'format' checks adjusted. Since legacy iptables prints the counters between matches and target, this change affects save_matches_and_target() function. In order to get access to the rule counters, it's declaration is adjusted to receive iptables_command_state pointer instead of match, target and jumpto pointers from the same object. While being at it, integrate jump to user-defined chain into it as well since the related code in both callers was almost identical. Though since different rule flags are used between iptables and ip6tables, pass a 'goto_flag' boolean instead of the actual 'flags' bitfield. Signed-off-by: Phil Sutter <phil@nwl.cc> Signed-off-by: Florian Westphal <fw@strlen.de>
Diffstat (limited to 'iptables')
-rw-r--r--iptables/nft-ipv4.c10
-rw-r--r--iptables/nft-ipv6.c10
-rw-r--r--iptables/nft-shared.c29
-rw-r--r--iptables/nft-shared.h7
-rw-r--r--iptables/nft.c10
-rwxr-xr-xiptables/tests/shell/testcases/iptables/0003-list-rules_048
6 files changed, 82 insertions, 32 deletions
diff --git a/iptables/nft-ipv4.c b/iptables/nft-ipv4.c
index 4f31a516..105b1341 100644
--- a/iptables/nft-ipv4.c
+++ b/iptables/nft-ipv4.c
@@ -358,14 +358,8 @@ static void nft_ipv4_save_rule(const void *data, unsigned int format)
printf("-f ");
}
- save_matches_and_target(cs->matches, cs->target,
- cs->jumpto, cs->fw.ip.flags, &cs->fw);
-
- if (cs->target == NULL && strlen(cs->jumpto) > 0) {
- printf("-%c %s", cs->fw.ip.flags & IPT_F_GOTO ? 'g' : 'j',
- cs->jumpto);
- }
- printf("\n");
+ save_matches_and_target(cs, cs->fw.ip.flags & IPT_F_GOTO,
+ &cs->fw, format);
}
static void nft_ipv4_proto_parse(struct iptables_command_state *cs,
diff --git a/iptables/nft-ipv6.c b/iptables/nft-ipv6.c
index c651b16d..dd23557c 100644
--- a/iptables/nft-ipv6.c
+++ b/iptables/nft-ipv6.c
@@ -296,14 +296,8 @@ static void nft_ipv6_save_rule(const void *data, unsigned int format)
cs->fw6.ipv6.iniface, cs->fw6.ipv6.iniface_mask,
cs->fw6.ipv6.outiface, cs->fw6.ipv6.outiface_mask);
- save_matches_and_target(cs->matches, cs->target,
- cs->jumpto, cs->fw6.ipv6.flags, &cs->fw6);
-
- if (cs->target == NULL && strlen(cs->jumpto) > 0) {
- printf("-%c %s", cs->fw6.ipv6.flags & IP6T_F_GOTO ? 'g' : 'j',
- cs->jumpto);
- }
- printf("\n");
+ save_matches_and_target(cs, cs->fw6.ipv6.flags & IP6T_F_GOTO,
+ &cs->fw6, format);
}
/* These are invalid numbers as upper layer protocol */
diff --git a/iptables/nft-shared.c b/iptables/nft-shared.c
index 66db7ed1..5b55c7c0 100644
--- a/iptables/nft-shared.c
+++ b/iptables/nft-shared.c
@@ -813,13 +813,13 @@ void nft_ipv46_save_chain(const struct nftnl_chain *c, const char *policy)
chain, policy ?: "-", pkts, bytes);
}
-void save_matches_and_target(struct xtables_rule_match *m,
- struct xtables_target *target,
- const char *jumpto, uint8_t flags, const void *fw)
+void save_matches_and_target(const struct iptables_command_state *cs,
+ bool goto_flag, const void *fw,
+ unsigned int format)
{
struct xtables_rule_match *matchp;
- for (matchp = m; matchp; matchp = matchp->next) {
+ for (matchp = cs->matches; matchp; matchp = matchp->next) {
if (matchp->match->alias) {
printf("-m %s",
matchp->match->alias(matchp->match->m));
@@ -833,15 +833,24 @@ void save_matches_and_target(struct xtables_rule_match *m,
printf(" ");
}
- if (target != NULL) {
- if (target->alias) {
- printf("-j %s", target->alias(target->t));
+ if ((format & (FMT_NOCOUNTS | FMT_C_COUNTS)) == FMT_C_COUNTS)
+ printf("-c %llu %llu ",
+ (unsigned long long)cs->counters.pcnt,
+ (unsigned long long)cs->counters.bcnt);
+
+ if (cs->target != NULL) {
+ if (cs->target->alias) {
+ printf("-j %s", cs->target->alias(cs->target->t));
} else
- printf("-j %s", jumpto);
+ printf("-j %s", cs->jumpto);
- if (target->save != NULL)
- target->save(fw, target->t);
+ if (cs->target->save != NULL)
+ cs->target->save(fw, cs->target->t);
+ } else if (strlen(cs->jumpto) > 0) {
+ printf("-%c %s", goto_flag ? 'g' : 'j', cs->jumpto);
}
+
+ printf("\n");
}
void print_matches_and_target(struct iptables_command_state *cs,
diff --git a/iptables/nft-shared.h b/iptables/nft-shared.h
index 1f5c8a81..49e2fa10 100644
--- a/iptables/nft-shared.h
+++ b/iptables/nft-shared.h
@@ -166,10 +166,9 @@ void save_rule_details(const struct iptables_command_state *cs,
unsigned const char *outiface_mask);
void save_counters(const void *data);
void nft_ipv46_save_chain(const struct nftnl_chain *c, const char *policy);
-void save_matches_and_target(struct xtables_rule_match *m,
- struct xtables_target *target,
- const char *jumpto,
- uint8_t flags, const void *fw);
+void save_matches_and_target(const struct iptables_command_state *cs,
+ bool goto_flag, const void *fw,
+ unsigned int format);
struct nft_family_ops *nft_family_ops_lookup(int family);
diff --git a/iptables/nft.c b/iptables/nft.c
index 1c076510..120039ed 100644
--- a/iptables/nft.c
+++ b/iptables/nft.c
@@ -1201,7 +1201,7 @@ nft_rule_print_save(const struct nftnl_rule *r, enum nft_rule_print type,
ops = nft_family_ops_lookup(family);
ops->rule_to_cs(r, &cs);
- if (!(format & FMT_NOCOUNTS) && ops->save_counters)
+ if (!(format & (FMT_NOCOUNTS | FMT_C_COUNTS)) && ops->save_counters)
ops->save_counters(&cs);
/* print chain name */
@@ -2396,6 +2396,7 @@ int nft_rule_list_save(struct nft_handle *h, const char *chain,
{
struct nftnl_chain_list *list;
struct nftnl_chain_list_iter *iter;
+ unsigned int format = 0;
struct nftnl_chain *c;
int ret = 1;
@@ -2410,6 +2411,11 @@ int nft_rule_list_save(struct nft_handle *h, const char *chain,
if (iter == NULL)
goto err;
+ if (counters < 0)
+ format = FMT_C_COUNTS;
+ else if (counters == 0)
+ format = FMT_NOCOUNTS;
+
c = nftnl_chain_list_iter_next(iter);
while (c != NULL) {
const char *chain_table =
@@ -2423,7 +2429,7 @@ int nft_rule_list_save(struct nft_handle *h, const char *chain,
goto next;
ret = __nft_rule_list(h, chain_name, table, rulenum,
- counters ? 0 : FMT_NOCOUNTS, list_save);
+ format, list_save);
/* we printed the chain we wanted, stop processing. */
if (chain)
diff --git a/iptables/tests/shell/testcases/iptables/0003-list-rules_0 b/iptables/tests/shell/testcases/iptables/0003-list-rules_0
new file mode 100755
index 00000000..2e87ce5a
--- /dev/null
+++ b/iptables/tests/shell/testcases/iptables/0003-list-rules_0
@@ -0,0 +1,48 @@
+#!/bin/bash
+
+set -e
+
+$XT_MULTI iptables -N foo
+$XT_MULTI iptables -A FORWARD -i eth23 -o eth42 -j ACCEPT
+$XT_MULTI iptables -A FORWARD -i eth42 -o eth23 -g foo
+$XT_MULTI iptables -t nat -A OUTPUT -o eth123 -m mark --mark 0x42 -j ACCEPT
+
+EXPECT='-P INPUT ACCEPT
+-P FORWARD ACCEPT
+-P OUTPUT ACCEPT
+-N foo
+-A FORWARD -i eth23 -o eth42 -j ACCEPT
+-A FORWARD -i eth42 -o eth23 -g foo'
+
+diff -u -Z <(echo -e "$EXPECT") <($XT_MULTI iptables -S)
+
+EXPECT='-P INPUT ACCEPT -c 0 0
+-P FORWARD ACCEPT -c 0 0
+-P OUTPUT ACCEPT -c 0 0
+-N foo
+-A FORWARD -i eth23 -o eth42 -c 0 0 -j ACCEPT
+-A FORWARD -i eth42 -o eth23 -c 0 0 -g foo'
+
+diff -u -Z <(echo -e "$EXPECT") <($XT_MULTI iptables -v -S)
+
+EXPECT='-P FORWARD ACCEPT
+-A FORWARD -i eth23 -o eth42 -j ACCEPT
+-A FORWARD -i eth42 -o eth23 -g foo'
+
+diff -u -Z <(echo -e "$EXPECT") <($XT_MULTI iptables -S FORWARD)
+
+EXPECT='-P FORWARD ACCEPT -c 0 0
+-A FORWARD -i eth23 -o eth42 -c 0 0 -j ACCEPT
+-A FORWARD -i eth42 -o eth23 -c 0 0 -g foo'
+
+diff -u -Z <(echo -e "$EXPECT") <($XT_MULTI iptables -v -S FORWARD)
+
+EXPECT='-P OUTPUT ACCEPT
+-A OUTPUT -o eth123 -m mark --mark 0x42 -j ACCEPT'
+
+diff -u -Z <(echo -e "$EXPECT") <($XT_MULTI iptables -t nat -S OUTPUT)
+
+EXPECT='-P OUTPUT ACCEPT -c 0 0
+-A OUTPUT -o eth123 -m mark --mark 0x42 -c 0 0 -j ACCEPT'
+
+diff -u -Z <(echo -e "$EXPECT") <($XT_MULTI iptables -v -t nat -S OUTPUT)