[iptables PATCH] xtables: Match verbose ip{,6}tables output with legacy

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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



[Index of Archives]     [Netfitler Users]     [LARTC]     [Bugtraq]     [Yosemite Forum]

  Powered by Linux