Legacy ip{,6}tables prints feedback for various commands if in verbose mode, make sure nft variants do the same. There is one difference, namely when checking a rule (-C command): Legacy ip{,6}tables print the rule in any case, nft variants don't in case the rule wasn't found. Changing this though would require to populate the nftnl_rule object just for printing, which is probably not feasible. Signed-off-by: Phil Sutter <phil@xxxxxx> --- iptables/nft.c | 39 +++++++++++--- iptables/nft.h | 6 +-- .../testcases/ip6tables/0002-verbose-output_0 | 51 +++++++++++++++++++ .../testcases/iptables/0002-verbose-output_0 | 51 +++++++++++++++++++ iptables/xtables-arp.c | 11 ++-- iptables/xtables-eb.c | 7 +-- iptables/xtables.c | 17 ++++--- 7 files changed, 157 insertions(+), 25 deletions(-) create mode 100755 iptables/tests/shell/testcases/ip6tables/0002-verbose-output_0 create mode 100755 iptables/tests/shell/testcases/iptables/0002-verbose-output_0 diff --git a/iptables/nft.c b/iptables/nft.c index 8e0885f3ee53d..1c076510962b3 100644 --- a/iptables/nft.c +++ b/iptables/nft.c @@ -1178,6 +1178,9 @@ nft_rule_append(struct nft_handle *h, const char *chain, const char *table, return 0; } + if (verbose) + h->ops->print_rule(r, 0, FMT_PRINT_RULE); + if (!nft_rule_list_get(h)) return 0; @@ -1476,7 +1479,8 @@ int nft_chain_user_flush(struct nft_handle *h, struct nftnl_chain_list *list, return 1; } -int nft_rule_flush(struct nft_handle *h, const char *chain, const char *table) +int nft_rule_flush(struct nft_handle *h, const char *chain, const char *table, + bool verbose) { int ret = 0; struct nftnl_chain_list *list; @@ -1513,6 +1517,9 @@ int nft_rule_flush(struct nft_handle *h, const char *chain, const char *table) if (chain != NULL && strcmp(chain, chain_name) != 0) goto next; + if (verbose) + fprintf(stdout, "Flushing chain `%s'\n", chain_name); + __nft_rule_flush(h, table_name, chain_name); if (chain != NULL) @@ -1560,7 +1567,8 @@ int nft_chain_user_add(struct nft_handle *h, const char *chain, const char *tabl #define NLM_F_NONREC 0x100 /* Do not delete recursively */ #endif -int nft_chain_user_del(struct nft_handle *h, const char *chain, const char *table) +int nft_chain_user_del(struct nft_handle *h, const char *chain, + const char *table, bool verbose) { struct nftnl_chain_list *list; struct nftnl_chain_list_iter *iter; @@ -1595,6 +1603,9 @@ int nft_chain_user_del(struct nft_handle *h, const char *chain, const char *tabl if (chain != NULL && strcmp(chain, chain_name) != 0) goto next; + if (verbose) + fprintf(stdout, "Deleting chain `%s'\n", chain); + ret = batch_chain_add(h, NFT_COMPAT_CHAIN_USER_DEL, c); if (ret < 0) @@ -1960,7 +1971,7 @@ int nft_rule_check(struct nft_handle *h, const char *chain, const char *table, void *data, bool verbose) { struct nftnl_rule_list *list; - int ret; + struct nftnl_rule *r; nft_fn = nft_rule_check; @@ -1968,11 +1979,15 @@ int nft_rule_check(struct nft_handle *h, const char *chain, if (list == NULL) return 0; - ret = nft_rule_find(h, list, chain, table, data, -1) ? 1 : 0; - if (ret == 0) + r = nft_rule_find(h, list, chain, table, data, -1); + if (r == NULL) { errno = ENOENT; + return 0; + } + if (verbose) + h->ops->print_rule(r, 0, FMT_PRINT_RULE); - return ret; + return 1; } int nft_rule_delete(struct nft_handle *h, const char *chain, @@ -1993,6 +2008,8 @@ int nft_rule_delete(struct nft_handle *h, const char *chain, ret =__nft_rule_del(h, list, r); if (ret < 0) errno = ENOMEM; + if (verbose) + h->ops->print_rule(r, 0, FMT_PRINT_RULE); } else errno = ENOENT; @@ -2018,6 +2035,9 @@ nft_rule_add(struct nft_handle *h, const char *chain, return NULL; } + if (verbose) + h->ops->print_rule(r, 0, FMT_PRINT_RULE); + return r; } @@ -2896,8 +2916,8 @@ int nft_xtables_config_load(struct nft_handle *h, const char *filename, return h->config_done; } -int nft_chain_zero_counters(struct nft_handle *h, const char *chain, - const char *table) +int nft_chain_zero_counters(struct nft_handle *h, const char *chain, + const char *table, bool verbose) { struct nftnl_chain_list *list; struct nftnl_chain_list_iter *iter; @@ -2925,6 +2945,9 @@ int nft_chain_zero_counters(struct nft_handle *h, const char *chain, if (chain != NULL && strcmp(chain, chain_name) != 0) goto next; + if (verbose) + fprintf(stdout, "Zeroing chain `%s'\n", chain_name); + nftnl_chain_set_u64(c, NFTNL_CHAIN_PACKETS, 0); nftnl_chain_set_u64(c, NFTNL_CHAIN_BYTES, 0); diff --git a/iptables/nft.h b/iptables/nft.h index 309fea56927b4..eb14e908ab924 100644 --- a/iptables/nft.h +++ b/iptables/nft.h @@ -80,11 +80,11 @@ struct nftnl_chain_list *nft_chain_dump(struct nft_handle *h); struct nftnl_chain *nft_chain_list_find(struct nftnl_chain_list *list, const char *table, const char *chain); int nft_chain_save(struct nft_handle *h, struct nftnl_chain_list *list, const char *table); int nft_chain_user_add(struct nft_handle *h, const char *chain, const char *table); -int nft_chain_user_del(struct nft_handle *h, const char *chain, const char *table); +int nft_chain_user_del(struct nft_handle *h, const char *chain, const char *table, bool verbose); int nft_chain_user_flush(struct nft_handle *h, struct nftnl_chain_list *list, const char *chain, const char *table); int nft_chain_user_rename(struct nft_handle *h, const char *chain, const char *table, const char *newname); -int nft_chain_zero_counters(struct nft_handle *h, const char *chain, const char *table); +int nft_chain_zero_counters(struct nft_handle *h, const char *chain, const char *table, bool verbose); struct builtin_chain *nft_chain_builtin_find(struct builtin_table *t, const char *chain); /* @@ -101,7 +101,7 @@ int nft_rule_replace(struct nft_handle *h, const char *chain, const char *table, int nft_rule_list(struct nft_handle *h, const char *chain, const char *table, int rulenum, unsigned int format); int nft_rule_list_save(struct nft_handle *h, const char *chain, const char *table, int rulenum, int counters); int nft_rule_save(struct nft_handle *h, const char *table, unsigned int format); -int nft_rule_flush(struct nft_handle *h, const char *chain, const char *table); +int nft_rule_flush(struct nft_handle *h, const char *chain, const char *table, bool verbose); int nft_rule_zero_counters(struct nft_handle *h, const char *chain, const char *table, int rulenum); /* diff --git a/iptables/tests/shell/testcases/ip6tables/0002-verbose-output_0 b/iptables/tests/shell/testcases/ip6tables/0002-verbose-output_0 new file mode 100755 index 0000000000000..7b0e64686c6b6 --- /dev/null +++ b/iptables/tests/shell/testcases/ip6tables/0002-verbose-output_0 @@ -0,0 +1,51 @@ +#!/bin/bash + +set -e +#set -x + +# ensure verbose output is identical between legacy and nft tools + +RULE1='-i eth2 -o eth3 -s feed:babe::1 -d feed:babe::2 -j ACCEPT' +VOUT1='ACCEPT all opt in eth2 out eth3 feed:babe::1 -> feed:babe::2' +RULE2='-i eth2 -o eth3 -s feed:babe::4 -d feed:babe::5 -j ACCEPT' +VOUT2='ACCEPT all opt in eth2 out eth3 feed:babe::4 -> feed:babe::5' + +diff -u -Z <(echo -e "$VOUT1") <($XT_MULTI ip6tables -v -A FORWARD $RULE1) +diff -u -Z <(echo -e "$VOUT2") <($XT_MULTI ip6tables -v -I FORWARD 2 $RULE2) + +diff -u -Z <(echo -e "$VOUT1") <($XT_MULTI ip6tables -v -C FORWARD $RULE1) +diff -u -Z <(echo -e "$VOUT2") <($XT_MULTI ip6tables -v -C FORWARD $RULE2) + +EXPECT='Chain INPUT (policy ACCEPT 0 packets, 0 bytes) + pkts bytes target prot opt in out source destination + +Chain FORWARD (policy ACCEPT 0 packets, 0 bytes) + pkts bytes target prot opt in out source destination + 0 0 ACCEPT all eth2 eth3 feed:babe::1 feed:babe::2 + 0 0 ACCEPT all eth2 eth3 feed:babe::4 feed:babe::5 + +Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes) + pkts bytes target prot opt in out source destination' + +diff -u -Z <(echo -e "$EXPECT") <($XT_MULTI ip6tables -v -n -L) + +diff -u -Z <(echo -e "$VOUT1") <($XT_MULTI ip6tables -v -D FORWARD $RULE1) +diff -u -Z <(echo -e "$VOUT2") <($XT_MULTI ip6tables -v -D FORWARD $RULE2) + +EXPECT="Flushing chain \`INPUT' +Flushing chain \`FORWARD' +Flushing chain \`OUTPUT'" + +diff -u <(echo -e "$EXPECT") <($XT_MULTI ip6tables -v -F) + +EXPECT="Zeroing chain \`INPUT' +Zeroing chain \`FORWARD' +Zeroing chain \`OUTPUT'" + +diff -u <(echo -e "$EXPECT") <($XT_MULTI ip6tables -v -Z) + +diff -u <(echo "Flushing chain \`OUTPUT'") <($XT_MULTI ip6tables -v -F OUTPUT) +diff -u <(echo "Zeroing chain \`OUTPUT'") <($XT_MULTI ip6tables -v -Z OUTPUT) + +$XT_MULTI ip6tables -N foo +diff -u <(echo "Deleting chain \`foo'") <($XT_MULTI ip6tables -v -X foo) diff --git a/iptables/tests/shell/testcases/iptables/0002-verbose-output_0 b/iptables/tests/shell/testcases/iptables/0002-verbose-output_0 new file mode 100755 index 0000000000000..2e8059536ea7b --- /dev/null +++ b/iptables/tests/shell/testcases/iptables/0002-verbose-output_0 @@ -0,0 +1,51 @@ +#!/bin/bash + +set -e +#set -x + +# ensure verbose output is identical between legacy and nft tools + +RULE1='-i eth2 -o eth3 -s 10.0.0.1 -d 10.0.0.2 -j ACCEPT' +VOUT1='ACCEPT all opt -- in eth2 out eth3 10.0.0.1 -> 10.0.0.2' +RULE2='-i eth2 -o eth3 -s 10.0.0.4 -d 10.0.0.5 -j ACCEPT' +VOUT2='ACCEPT all opt -- in eth2 out eth3 10.0.0.4 -> 10.0.0.5' + +diff -u -Z <(echo -e "$VOUT1") <($XT_MULTI iptables -v -A FORWARD $RULE1) +diff -u -Z <(echo -e "$VOUT2") <($XT_MULTI iptables -v -I FORWARD 2 $RULE2) + +diff -u -Z <(echo -e "$VOUT1") <($XT_MULTI iptables -v -C FORWARD $RULE1) +diff -u -Z <(echo -e "$VOUT2") <($XT_MULTI iptables -v -C FORWARD $RULE2) + +EXPECT='Chain INPUT (policy ACCEPT 0 packets, 0 bytes) + pkts bytes target prot opt in out source destination + +Chain FORWARD (policy ACCEPT 0 packets, 0 bytes) + pkts bytes target prot opt in out source destination + 0 0 ACCEPT all -- eth2 eth3 10.0.0.1 10.0.0.2 + 0 0 ACCEPT all -- eth2 eth3 10.0.0.4 10.0.0.5 + +Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes) + pkts bytes target prot opt in out source destination' + +diff -u -Z <(echo -e "$EXPECT") <($XT_MULTI iptables -v -n -L) + +diff -u -Z <(echo -e "$VOUT1") <($XT_MULTI iptables -v -D FORWARD $RULE1) +diff -u -Z <(echo -e "$VOUT2") <($XT_MULTI iptables -v -D FORWARD $RULE2) + +EXPECT="Flushing chain \`INPUT' +Flushing chain \`FORWARD' +Flushing chain \`OUTPUT'" + +diff -u <(echo -e "$EXPECT") <($XT_MULTI iptables -v -F) + +EXPECT="Zeroing chain \`INPUT' +Zeroing chain \`FORWARD' +Zeroing chain \`OUTPUT'" + +diff -u <(echo -e "$EXPECT") <($XT_MULTI iptables -v -Z) + +diff -u <(echo "Flushing chain \`OUTPUT'") <($XT_MULTI iptables -v -F OUTPUT) +diff -u <(echo "Zeroing chain \`OUTPUT'") <($XT_MULTI iptables -v -Z OUTPUT) + +$XT_MULTI iptables -N foo +diff -u <(echo "Deleting chain \`foo'") <($XT_MULTI iptables -v -X foo) diff --git a/iptables/xtables-arp.c b/iptables/xtables-arp.c index 9f98054ac6ff9..a457ea30ad685 100644 --- a/iptables/xtables-arp.c +++ b/iptables/xtables-arp.c @@ -1442,10 +1442,11 @@ int do_commandarp(struct nft_handle *h, int argc, char *argv[], char **table, options&OPT_LINENUMBERS); break; case CMD_FLUSH: - ret = nft_rule_flush(h, chain, *table); + ret = nft_rule_flush(h, chain, *table, options & OPT_VERBOSE); break; case CMD_ZERO: - ret = nft_chain_zero_counters(h, chain, *table); + ret = nft_chain_zero_counters(h, chain, *table, + options & OPT_VERBOSE); break; case CMD_LIST|CMD_ZERO: ret = list_entries(h, chain, *table, rulenum, @@ -1454,13 +1455,15 @@ int do_commandarp(struct nft_handle *h, int argc, char *argv[], char **table, /*options&OPT_EXPANDED*/0, options&OPT_LINENUMBERS); if (ret) - ret = nft_chain_zero_counters(h, chain, *table); + ret = nft_chain_zero_counters(h, chain, *table, + options & OPT_VERBOSE); break; case CMD_NEW_CHAIN: ret = nft_chain_user_add(h, chain, *table); break; case CMD_DELETE_CHAIN: - ret = nft_chain_user_del(h, chain, *table); + ret = nft_chain_user_del(h, chain, *table, + options & OPT_VERBOSE); break; case CMD_RENAME_CHAIN: ret = nft_chain_user_rename(h, chain, *table, newname); diff --git a/iptables/xtables-eb.c b/iptables/xtables-eb.c index 219dfe35ec40b..ac3ecb8ed6489 100644 --- a/iptables/xtables-eb.c +++ b/iptables/xtables-eb.c @@ -834,7 +834,7 @@ int do_commandeb(struct nft_handle *h, int argc, char *argv[], char **table, chain = argv[optind]; optind++; } - ret = nft_chain_user_del(h, chain, *table); + ret = nft_chain_user_del(h, chain, *table, 0); break; } @@ -1296,9 +1296,10 @@ check_extension: } if (flags & OPT_ZERO) { selected_chain = zerochain; - ret = nft_chain_zero_counters(h, chain, *table); + ret = nft_chain_zero_counters(h, chain, *table, + flags & OPT_VERBOSE); } else if (command == 'F') { - ret = nft_rule_flush(h, chain, *table); + ret = nft_rule_flush(h, chain, *table, flags & OPT_VERBOSE); } else if (command == 'A') { ret = append_entry(h, chain, *table, &cs, 0, flags&OPT_VERBOSE, true); diff --git a/iptables/xtables.c b/iptables/xtables.c index ca6119b30336d..64081758a12ba 100644 --- a/iptables/xtables.c +++ b/iptables/xtables.c @@ -1213,10 +1213,12 @@ int do_commandx(struct nft_handle *h, int argc, char *argv[], char **table, cs.options&OPT_VERBOSE, h, false); break; case CMD_FLUSH: - ret = nft_rule_flush(h, p.chain, p.table); + ret = nft_rule_flush(h, p.chain, p.table, + cs.options & OPT_VERBOSE); break; case CMD_ZERO: - ret = nft_chain_zero_counters(h, p.chain, p.table); + ret = nft_chain_zero_counters(h, p.chain, p.table, + cs.options & OPT_VERBOSE); break; case CMD_ZERO_NUM: ret = nft_rule_zero_counters(h, p.chain, p.table, @@ -1231,8 +1233,8 @@ int do_commandx(struct nft_handle *h, int argc, char *argv[], char **table, cs.options & OPT_EXPANDED, cs.options & OPT_LINENUMBERS); if (ret && (p.command & CMD_ZERO)) { - ret = nft_chain_zero_counters(h, p.chain, - p.table); + ret = nft_chain_zero_counters(h, p.chain, p.table, + cs.options & OPT_VERBOSE); } if (ret && (p.command & CMD_ZERO_NUM)) { ret = nft_rule_zero_counters(h, p.chain, p.table, @@ -1246,8 +1248,8 @@ int do_commandx(struct nft_handle *h, int argc, char *argv[], char **table, ret = list_rules(h, p.chain, p.table, p.rulenum, cs.options & OPT_VERBOSE); if (ret && (p.command & CMD_ZERO)) { - ret = nft_chain_zero_counters(h, p.chain, - p.table); + ret = nft_chain_zero_counters(h, p.chain, p.table, + cs.options & OPT_VERBOSE); } if (ret && (p.command & CMD_ZERO_NUM)) { ret = nft_rule_zero_counters(h, p.chain, p.table, @@ -1259,7 +1261,8 @@ int do_commandx(struct nft_handle *h, int argc, char *argv[], char **table, ret = nft_chain_user_add(h, p.chain, p.table); break; case CMD_DELETE_CHAIN: - ret = nft_chain_user_del(h, p.chain, p.table); + ret = nft_chain_user_del(h, p.chain, p.table, + cs.options & OPT_VERBOSE); break; case CMD_RENAME_CHAIN: ret = nft_chain_user_rename(h, p.chain, p.table, p.newname); -- 2.18.0 -- To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html