]> git.ipfire.org Git - thirdparty/iptables.git/commitdiff
xtables-restore: Fix verbose mode table flushing
authorPhil Sutter <phil@nwl.cc>
Tue, 12 May 2020 10:59:42 +0000 (12:59 +0200)
committerPhil Sutter <phil@nwl.cc>
Mon, 8 Jun 2020 22:16:34 +0000 (00:16 +0200)
When called with --verbose mode, iptables-nft-restore did not print
anything when flushing the table. Fix this by adding a "manual" mode to
nft_cmd_table_flush(), turning it into a wrapper around '-F' and '-X'
commands, which is exactly what iptables-legacy-restore does to flush a
table. This though requires a real cache, so don't set NFT_CL_FAKE then.

Signed-off-by: Phil Sutter <phil@nwl.cc>
iptables/nft-cmd.c
iptables/nft-cmd.h
iptables/nft-shared.h
iptables/tests/shell/testcases/ipt-restore/0014-verbose-restore_0 [new file with mode: 0755]
iptables/xtables-eb.c
iptables/xtables-restore.c

index 9c0901e78703a357d611757b8c34909e449401e7..51cdfed41519cc522cf35dd91d5335007e2b6f35 100644 (file)
@@ -311,10 +311,15 @@ int nft_cmd_chain_set(struct nft_handle *h, const char *table,
        return 1;
 }
 
-int nft_cmd_table_flush(struct nft_handle *h, const char *table)
+int nft_cmd_table_flush(struct nft_handle *h, const char *table, bool verbose)
 {
        struct nft_cmd *cmd;
 
+       if (verbose) {
+               return nft_cmd_rule_flush(h, NULL, table, verbose) &&
+                      nft_cmd_chain_user_del(h, NULL, table, verbose);
+       }
+
        cmd = nft_cmd_new(h, NFT_COMPAT_TABLE_FLUSH, table, NULL, NULL, -1,
                          false);
        if (!cmd)
index 0e1776ce088bfdd238a1636775ee22d1783fdfff..ecf7655a4a6133808de457546e3b0950dd17e810 100644 (file)
@@ -65,7 +65,7 @@ int nft_cmd_chain_user_rename(struct nft_handle *h,const char *chain,
 int nft_cmd_rule_replace(struct nft_handle *h, const char *chain,
                         const char *table, void *data, int rulenum,
                         bool verbose);
-int nft_cmd_table_flush(struct nft_handle *h, const char *table);
+int nft_cmd_table_flush(struct nft_handle *h, const char *table, bool verbose);
 int nft_cmd_chain_restore(struct nft_handle *h, const char *chain,
                          const char *table);
 int nft_cmd_rule_zero_counters(struct nft_handle *h, const char *chain,
index 94437ffe7990c1b5f74037b89a33ac5ef6cc80e6..4440fd17bfeac22ff9f6229df21d3cb2270e3d9a 100644 (file)
@@ -225,7 +225,8 @@ struct nft_xt_restore_cb {
        int (*chain_restore)(struct nft_handle *h, const char *chain,
                             const char *table);
 
-       int (*table_flush)(struct nft_handle *h, const char *table);
+       int (*table_flush)(struct nft_handle *h, const char *table,
+                          bool verbose);
 
        int (*do_command)(struct nft_handle *h, int argc, char *argv[],
                          char **table, bool restore);
diff --git a/iptables/tests/shell/testcases/ipt-restore/0014-verbose-restore_0 b/iptables/tests/shell/testcases/ipt-restore/0014-verbose-restore_0
new file mode 100755 (executable)
index 0000000..94bed0e
--- /dev/null
@@ -0,0 +1,76 @@
+#!/bin/bash
+
+set -e
+
+DUMP="*filter
+:foo - [0:0]
+:bar - [0:0]
+-A foo -j ACCEPT
+COMMIT
+*nat
+:natfoo - [0:0]
+:natbar - [0:0]
+-A natfoo -j ACCEPT
+COMMIT
+*raw
+:rawfoo - [0:0]
+COMMIT
+*mangle
+:manglefoo - [0:0]
+COMMIT
+*security
+:secfoo - [0:0]
+COMMIT
+"
+
+$XT_MULTI iptables-restore <<< "$DUMP"
+$XT_MULTI ip6tables-restore <<< "$DUMP"
+
+EXPECT="Flushing chain \`INPUT'
+Flushing chain \`FORWARD'
+Flushing chain \`OUTPUT'
+Flushing chain \`bar'
+Flushing chain \`foo'
+Deleting chain \`bar'
+Deleting chain \`foo'
+Flushing chain \`PREROUTING'
+Flushing chain \`INPUT'
+Flushing chain \`OUTPUT'
+Flushing chain \`POSTROUTING'
+Flushing chain \`natbar'
+Flushing chain \`natfoo'
+Deleting chain \`natbar'
+Deleting chain \`natfoo'
+Flushing chain \`PREROUTING'
+Flushing chain \`OUTPUT'
+Flushing chain \`rawfoo'
+Deleting chain \`rawfoo'
+Flushing chain \`PREROUTING'
+Flushing chain \`INPUT'
+Flushing chain \`FORWARD'
+Flushing chain \`OUTPUT'
+Flushing chain \`POSTROUTING'
+Flushing chain \`manglefoo'
+Deleting chain \`manglefoo'
+Flushing chain \`INPUT'
+Flushing chain \`FORWARD'
+Flushing chain \`OUTPUT'
+Flushing chain \`secfoo'
+Deleting chain \`secfoo'"
+
+for ipt in iptables-restore ip6tables-restore; do
+       diff -u -Z <(sort <<< "$EXPECT") <($XT_MULTI $ipt -v <<< "$DUMP" | sort)
+done
+
+DUMP="*filter
+:baz - [0:0]
+-F foo
+-X bar
+-A foo -j ACCEPT
+COMMIT
+"
+
+EXPECT=""
+for ipt in iptables-restore ip6tables-restore; do
+       diff -u -Z <(echo -ne "$EXPECT") <($XT_MULTI $ipt -v --noflush <<< "$DUMP")
+done
index 375a95d1d5c750ec386cbbb24b0e450325fe579d..6641a21a72d321a82effd0171fa7d308e316c101 100644 (file)
@@ -1155,7 +1155,7 @@ print_zero:
                /*case 7 :*/ /* atomic-init */
                /*case 10:*/ /* atomic-save */
                case 11: /* init-table */
-                       nft_cmd_table_flush(h, *table);
+                       nft_cmd_table_flush(h, *table, false);
                        return 1;
                /*
                        replace->command = c;
index a3bb4f00e79c6ca624df1047138533ca22c45df7..eb25ec3dc83981a54d80216b82c27541aaf5d816 100644 (file)
@@ -135,7 +135,7 @@ static void xtables_restore_parse_line(struct nft_handle *h,
                if (h->noflush == 0) {
                        DEBUGP("Cleaning all chains of table '%s'\n", table);
                        if (cb->table_flush)
-                               cb->table_flush(h, table);
+                               cb->table_flush(h, table, verbose);
                }
 
                ret = 1;
@@ -260,7 +260,7 @@ void xtables_restore_parse(struct nft_handle *h,
        struct nft_xt_restore_state state = {};
        char buffer[10240] = {};
 
-       if (!h->noflush)
+       if (!verbose && !h->noflush)
                nft_cache_level_set(h, NFT_CL_FAKE, NULL);
 
        line = 0;