]> git.ipfire.org Git - thirdparty/iptables.git/commitdiff
xtables: Match verbose ip{,6}tables output with legacy
authorPhil Sutter <phil@nwl.cc>
Sat, 4 Aug 2018 11:10:19 +0000 (13:10 +0200)
committerFlorian Westphal <fw@strlen.de>
Sat, 4 Aug 2018 21:58:45 +0000 (23:58 +0200)
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@nwl.cc>
Signed-off-by: Florian Westphal <fw@strlen.de>
iptables/nft.c
iptables/nft.h
iptables/tests/shell/testcases/ip6tables/0002-verbose-output_0 [new file with mode: 0755]
iptables/tests/shell/testcases/iptables/0002-verbose-output_0 [new file with mode: 0755]
iptables/xtables-arp.c
iptables/xtables-eb.c
iptables/xtables.c

index 154ae19cebda13db93aa608695b920cf4d5a0ae4..ea58495be24aa0d59c08069d13671152261b6615 100644 (file)
@@ -1176,6 +1176,9 @@ nft_rule_append(struct nft_handle *h, const char *chain, const char *table,
        if (batch_rule_add(h, type, r) < 0)
                nftnl_rule_free(r);
 
+       if (verbose)
+               h->ops->print_rule(r, 0, FMT_PRINT_RULE);
+
        if (!nft_rule_list_get(h))
                return 0;
 
@@ -1474,7 +1477,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;
@@ -1511,6 +1515,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)
@@ -1558,7 +1565,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;
@@ -1593,6 +1601,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)
@@ -1958,7 +1969,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;
 
@@ -1966,11 +1977,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,
@@ -1991,6 +2006,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;
 
@@ -2016,6 +2033,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;
 }
 
@@ -2894,8 +2914,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;
@@ -2923,6 +2943,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);
 
index 6f58de251414f2347f75db9e9b30a0ba6cfd9b73..5febb9f9366e13f787f0c0c9ce7cdd52db1e50dd 100644 (file)
@@ -79,11 +79,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);
 
 /*
  * Operations with rule-set.
@@ -99,7 +99,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 (executable)
index 0000000..7b0e646
--- /dev/null
@@ -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 (executable)
index 0000000..2e80595
--- /dev/null
@@ -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)
index 28f449e857411a08f29ed046093e7dc63c5f7bfd..62282f42d00f490879199fac229113f9784327c1 100644 (file)
@@ -1421,10 +1421,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,
@@ -1433,13 +1434,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);
index b051e9f553c89ad5bc869d3bc24ddde4053ecd7b..763d1ad97fc06da4176d9f6427059410dc5dd15c 100644 (file)
@@ -856,7 +856,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;
                        }
 
@@ -1317,9 +1317,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);
index ca6119b30336d70406da1e4a4c13711f47b9fa8c..64081758a12bafbedbb354fd585fed1ced6cfb4e 100644 (file)
@@ -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);