diff mbox series

[iptables-compat,2/3] iptables-compat: do not fail on restore if user chain exists

Message ID 20180504094920.23853-2-pablo@netfilter.org
State Accepted
Delegated to: Pablo Neira
Headers show
Series [iptables-compat,1/3] iptables-compat: remove non-batching routines | expand

Commit Message

Pablo Neira Ayuso May 4, 2018, 9:49 a.m. UTC
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>
---
 iptables/nft-shared.h      |  2 +-
 iptables/nft.c             | 25 +++++++++++++++++++++++++
 iptables/nft.h             |  1 +
 iptables/xtables-restore.c |  6 +++---
 4 files changed, 30 insertions(+), 4 deletions(-)

Comments

Arturo Borrero Gonzalez May 4, 2018, 10:06 a.m. UTC | #1
On 4 May 2018 at 11:49, Pablo Neira Ayuso <pablo@netfilter.org> wrote:
>
> +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)
> +               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;
> +}
> +

it seems ret is never set to something meaningful?
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Pablo Neira Ayuso May 4, 2018, 9:32 p.m. UTC | #2
On Fri, May 04, 2018 at 12:06:32PM +0200, Arturo Borrero Gonzalez wrote:
> On 4 May 2018 at 11:49, Pablo Neira Ayuso <pablo@netfilter.org> wrote:
> >
> > +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)
> > +               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;
> > +}
> > +
> 
> it seems ret is never set to something meaningful?

Indeed, will fix this before applying. Actually, I could revisit all
return values in the compat code. Thanks.
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox series

Patch

diff --git a/iptables/nft-shared.h b/iptables/nft-shared.h
index e13a1a8563c3..1520d613b528 100644
--- a/iptables/nft-shared.h
+++ b/iptables/nft-shared.h
@@ -255,7 +255,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 e60923d6ecbf..5858e01e52ac 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 {
@@ -1283,6 +1284,25 @@  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)
+		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)
 {
@@ -2294,6 +2314,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 aaf3cbe0c0e3..2d5c37e5b502 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 fc39ad9c4fa5..3de496f85387 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;