-n still flushes user-define chains and its content, the following snippet: iptables -N FOO iptables -I INPUT iptables -I FOO iptables -I FOO iptables-save > A iptables-restore < A iptables-restore -n < A results in: iptables-save # Generated by iptables-save v1.6.2 on Mon May 7 16:22:03 2018 *filter :INPUT ACCEPT [9:863] :FORWARD ACCEPT [0:0] :OUTPUT ACCEPT [14:1029] :FOO - [0:0] -A INPUT -A INPUT -A FOO -A FOO COMMIT Reported-by: Florian Westphal <fw@xxxxxxxxx> Signed-off-by: Pablo Neira Ayuso <pablo@xxxxxxxxxxxxx> --- iptables/nft-shared.h | 1 + iptables/nft.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++ iptables/nft.h | 1 + iptables/xtables-restore.c | 7 +++++++ 4 files changed, 59 insertions(+) diff --git a/iptables/nft-shared.h b/iptables/nft-shared.h index 56b270e5a4b7..9bf9a0b55177 100644 --- a/iptables/nft-shared.h +++ b/iptables/nft-shared.h @@ -255,6 +255,7 @@ struct nft_xt_restore_cb { const char *table); int (*table_flush)(struct nft_handle *h, const char *table); + int (*chain_user_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 e3cfdf96cd85..e2533ee3efd1 100644 --- a/iptables/nft.c +++ b/iptables/nft.c @@ -1361,6 +1361,56 @@ err: return ret == 0 ? 1 : 0; } +static int __nft_chain_user_flush(struct nftnl_chain *c, void *data) +{ + const char *table_name = nftnl_chain_get_str(c, NFTNL_CHAIN_TABLE); + const char *chain_name = nftnl_chain_get_str(c, NFTNL_CHAIN_NAME); + struct flush_data *tfd = data; + struct nft_handle *h = tfd->handle; + const char *table = tfd->table; + int ret; + + if (strcmp(table, table_name) != 0) + return 0; + + if (!nftnl_chain_is_set(c, NFTNL_CHAIN_HOOKNUM)) { + __nft_rule_flush(h, table_name, chain_name); + ret = batch_chain_add(h, NFT_COMPAT_CHAIN_USER_DEL, c); + if (ret < 0) + return ret; + + nftnl_chain_list_del(c); + } + + return 0; +} + +int nft_chain_user_flush(struct nft_handle *h, const char *table) +{ + struct flush_data tfd = { + .handle = h, + .table = table, + }; + struct nftnl_chain_list *list; + int ret = 0; + + nft_fn = nft_table_flush; + + list = nftnl_chain_list_get(h); + if (list == NULL) { + ret = 0; + goto err; + } + + nftnl_chain_list_foreach(list, __nft_chain_user_flush, &tfd); + flush_rule_cache(h); +err: + nftnl_chain_list_free(list); + + /* the core expects 1 for success and 0 for error */ + return ret == 0 ? 1 : 0; +} + int nft_rule_flush(struct nft_handle *h, const char *chain, const char *table) { int ret; diff --git a/iptables/nft.h b/iptables/nft.h index 2d5c37e5b502..a1977e3ab7c2 100644 --- a/iptables/nft.h +++ b/iptables/nft.h @@ -73,6 +73,7 @@ int nft_chain_user_add(struct nft_handle *h, const char *chain, const char *tabl int nft_chain_user_del(struct nft_handle *h, 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_user_flush(struct nft_handle *h, const char *table); /* * Operations with rule-set. diff --git a/iptables/xtables-restore.c b/iptables/xtables-restore.c index a33a659341db..0f6fd2e17b00 100644 --- a/iptables/xtables-restore.c +++ b/iptables/xtables-restore.c @@ -191,6 +191,7 @@ struct nft_xt_restore_cb restore_cb = { .commit = nft_commit, .abort = nft_abort, .table_flush = nft_table_flush, + .chain_user_flush = nft_chain_user_flush, .chain_del = chain_delete, .do_command = do_commandx, .chain_set = nft_chain_set, @@ -267,6 +268,12 @@ void xtables_restore_parse(struct nft_handle *h, table); if (cb->table_flush) cb->table_flush(h, table); + } else { + /* Apparently -n still flushes existing user + * defined chains. + */ + if (cb->chain_user_flush) + cb->chain_user_flush(h, table); } ret = 1; -- 2.11.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