summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@netfilter.org>2018-05-04 11:25:00 +0200
committerPablo Neira Ayuso <pablo@netfilter.org>2018-05-05 10:05:44 +0200
commit09f0d47b213de944303a320a70bf57e143bfed62 (patch)
treeef510269f7c362031464ca8779f5cd94e0a9a9d0
parent8798eb8f48434b1a764788c8a0c133a983bc39e6 (diff)
iptables-compat: do not fail on restore if user chain exists
The following snippet fails if user chain FOO exists, but it should not fail: iptables-compat -F iptables-compat -N FOO iptables-compat-save > foo iptables-compat-restore < foo Reported-by: Florian Westphal <fw@strlen.de> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
-rw-r--r--iptables/nft-shared.h2
-rw-r--r--iptables/nft.c27
-rw-r--r--iptables/nft.h1
-rw-r--r--iptables/xtables-restore.c6
4 files changed, 32 insertions, 4 deletions
diff --git a/iptables/nft-shared.h b/iptables/nft-shared.h
index 525f3f0e..089828a3 100644
--- a/iptables/nft-shared.h
+++ b/iptables/nft-shared.h
@@ -256,7 +256,7 @@ struct nft_xt_restore_cb {
int (*chain_user_add)(struct nft_handle *h, const char *chain,
const char *table);
- int (*rule_flush)(struct nft_handle *h, const char *chain, const char *table);
+ int (*table_flush)(struct nft_handle *h, const char *table);
int (*do_command)(struct nft_handle *h, int argc, char *argv[],
char **table, bool restore);
diff --git a/iptables/nft.c b/iptables/nft.c
index bff73e76..271269f9 100644
--- a/iptables/nft.c
+++ b/iptables/nft.c
@@ -262,6 +262,7 @@ enum obj_update_type {
NFT_COMPAT_RULE_REPLACE,
NFT_COMPAT_RULE_DELETE,
NFT_COMPAT_RULE_FLUSH,
+ NFT_COMPAT_TABLE_FLUSH,
};
enum obj_action {
@@ -1289,6 +1290,27 @@ next:
return 1;
}
+int nft_table_flush(struct nft_handle *h, const char *table)
+{
+ struct nftnl_table *r;
+ int ret = 0;
+
+ nft_fn = nft_table_flush;
+
+ r = nftnl_table_alloc();
+ if (r == NULL) {
+ ret = -1;
+ goto err;
+ }
+
+ nftnl_table_set_str(r, NFTNL_TABLE_NAME, table);
+
+ batch_table_add(h, NFT_COMPAT_TABLE_FLUSH, r);
+err:
+ /* the core expects 1 for success and 0 for error */
+ return ret == 0 ? 1 : 0;
+}
+
static void
__nft_rule_flush(struct nft_handle *h, const char *table, const char *chain)
{
@@ -2300,6 +2322,11 @@ static int nft_action(struct nft_handle *h, int action)
nft_compat_rule_batch_add(h, NFT_MSG_DELRULE, 0,
seq++, n->rule);
break;
+ case NFT_COMPAT_TABLE_FLUSH:
+ nft_compat_table_batch_add(h, NFT_MSG_DELTABLE,
+ 0,
+ seq++, n->table);
+ break;
}
h->obj_list_num--;
diff --git a/iptables/nft.h b/iptables/nft.h
index aaf3cbe0..2d5c37e5 100644
--- a/iptables/nft.h
+++ b/iptables/nft.h
@@ -58,6 +58,7 @@ struct nftnl_chain_list;
int nft_for_each_table(struct nft_handle *h, int (*func)(struct nft_handle *h, const char *tablename, bool counters), bool counters);
bool nft_table_find(struct nft_handle *h, const char *tablename);
int nft_table_purge_chains(struct nft_handle *h, const char *table, struct nftnl_chain_list *list);
+int nft_table_flush(struct nft_handle *h, const char *table);
/*
* Operations with chains.
diff --git a/iptables/xtables-restore.c b/iptables/xtables-restore.c
index fc39ad9c..3de496f8 100644
--- a/iptables/xtables-restore.c
+++ b/iptables/xtables-restore.c
@@ -191,7 +191,7 @@ struct nft_xt_restore_cb restore_cb = {
.commit = nft_commit,
.abort = nft_abort,
.chains_purge = nft_table_purge_chains,
- .rule_flush = nft_rule_flush,
+ .table_flush = nft_table_flush,
.chain_del = chain_delete,
.do_command = do_commandx,
.chain_set = nft_chain_set,
@@ -270,8 +270,8 @@ void xtables_restore_parse(struct nft_handle *h,
if (noflush == 0) {
DEBUGP("Cleaning all chains of table '%s'\n",
table);
- if (cb->rule_flush)
- cb->rule_flush(h, NULL, table);
+ if (cb->table_flush)
+ cb->table_flush(h, table);
}
ret = 1;