Blame SOURCES/0013-xtables-restore-Review-chain-handling.patch

1dc35b
From 757b84e866dc1f288c54ad5ca9868b1765da3948 Mon Sep 17 00:00:00 2001
8cce6c
From: Phil Sutter <phil@nwl.cc>
8cce6c
Date: Thu, 20 Dec 2018 16:09:04 +0100
8cce6c
Subject: [PATCH] xtables-restore: Review chain handling
8cce6c
8cce6c
There is no need to "delete" (actually, remove from cache) a chain if
8cce6c
noflush wasn't given: While handling the corresponding table line,
8cce6c
'table_flush' callback has already taken care of that.
8cce6c
8cce6c
This .chain_del indirection is not required since d1eb4d587297
8cce6c
("iptables-compat: chains are purge out already from table flush").
8cce6c
8cce6c
Streamlining the code further, move syntax checks to the top. If these
8cce6c
concede, there are three cases to distinguish:
8cce6c
8cce6c
A) Given chain name matches a builtin one in current table, so assume it
8cce6c
   exists already and just set policy and counters.
8cce6c
8cce6c
B) Noflush was given and the (custom) chain exists already, flush it.
8cce6c
8cce6c
C) Custom chain was either flushed (noflush not given) or didn't exist
8cce6c
   before, create it.
8cce6c
8cce6c
Signed-off-by: Phil Sutter <phil@nwl.cc>
8cce6c
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
8cce6c
(cherry picked from commit 9523b2e9dee3d9b4439214092c496542ce9f434e)
8cce6c
Signed-off-by: Phil Sutter <psutter@redhat.com>
8cce6c
---
8cce6c
 iptables/nft-shared.h      |  2 --
8cce6c
 iptables/xtables-restore.c | 68 +++++++++++---------------------------
8cce6c
 2 files changed, 19 insertions(+), 51 deletions(-)
8cce6c
8cce6c
diff --git a/iptables/nft-shared.h b/iptables/nft-shared.h
8cce6c
index 9a61d8d2863e3..17fff984ba312 100644
8cce6c
--- a/iptables/nft-shared.h
8cce6c
+++ b/iptables/nft-shared.h
8cce6c
@@ -253,8 +253,6 @@ struct nft_xt_restore_cb {
8cce6c
 	void (*table_new)(struct nft_handle *h, const char *table);
8cce6c
 	struct nftnl_chain_list *(*chain_list)(struct nft_handle *h,
8cce6c
 					       const char *table);
8cce6c
-	void (*chain_del)(struct nftnl_chain_list *clist, const char *curtable,
8cce6c
-			  const char *chain);
8cce6c
 	int (*chain_user_flush)(struct nft_handle *h,
8cce6c
 				struct nftnl_chain_list *clist,
8cce6c
 				const char *table, const char *chain);
8cce6c
diff --git a/iptables/xtables-restore.c b/iptables/xtables-restore.c
8cce6c
index 642876d6c70ac..4e00ed86be06d 100644
8cce6c
--- a/iptables/xtables-restore.c
8cce6c
+++ b/iptables/xtables-restore.c
8cce6c
@@ -68,21 +68,6 @@ static struct nftnl_chain_list *get_chain_list(struct nft_handle *h,
8cce6c
 	return chain_list;
8cce6c
 }
8cce6c
 
8cce6c
-static void chain_delete(struct nftnl_chain_list *clist, const char *curtable,
8cce6c
-			 const char *chain)
8cce6c
-{
8cce6c
-	struct nftnl_chain *chain_obj;
8cce6c
-
8cce6c
-	chain_obj = nft_chain_list_find(clist, chain);
8cce6c
-	/* This chain has been found, delete from list. Later
8cce6c
-	 * on, unvisited chains will be purged out.
8cce6c
-	 */
8cce6c
-	if (chain_obj != NULL) {
8cce6c
-		nftnl_chain_list_del(chain_obj);
8cce6c
-		nftnl_chain_free(chain_obj);
8cce6c
-	}
8cce6c
-}
8cce6c
-
8cce6c
 struct nft_xt_restore_cb restore_cb = {
8cce6c
 	.chain_list	= get_chain_list,
8cce6c
 	.commit		= nft_commit,
8cce6c
@@ -90,7 +75,6 @@ struct nft_xt_restore_cb restore_cb = {
8cce6c
 	.table_new	= nft_table_new,
8cce6c
 	.table_flush	= nft_table_flush,
8cce6c
 	.chain_user_flush = nft_chain_user_flush,
8cce6c
-	.chain_del	= chain_delete,
8cce6c
 	.do_command	= do_commandx,
8cce6c
 	.chain_set	= nft_chain_set,
8cce6c
 	.chain_user_add	= nft_chain_user_add,
8cce6c
@@ -183,7 +167,6 @@ void xtables_restore_parse(struct nft_handle *h,
8cce6c
 			/* New chain. */
8cce6c
 			char *policy, *chain = NULL;
8cce6c
 			struct xt_counters count = {};
8cce6c
-			bool chain_exists = false;
8cce6c
 
8cce6c
 			chain = strtok(buffer+1, " \t\n");
8cce6c
 			DEBUGP("line %u, chain '%s'\n", line, chain);
8cce6c
@@ -194,21 +177,6 @@ void xtables_restore_parse(struct nft_handle *h,
8cce6c
 				exit(1);
8cce6c
 			}
8cce6c
 
8cce6c
-			if (noflush == 0) {
8cce6c
-				if (cb->chain_del)
8cce6c
-					cb->chain_del(chain_list, curtable->name,
8cce6c
-						      chain);
8cce6c
-			} else if (nft_chain_list_find(chain_list, chain)) {
8cce6c
-				chain_exists = true;
8cce6c
-				/* Apparently -n still flushes existing user
8cce6c
-				 * defined chains that are redefined. Otherwise,
8cce6c
-				 * leave them as is.
8cce6c
-				 */
8cce6c
-				if (cb->chain_user_flush)
8cce6c
-					cb->chain_user_flush(h, chain_list,
8cce6c
-							     curtable->name, chain);
8cce6c
-			}
8cce6c
-
8cce6c
 			if (strlen(chain) >= XT_EXTENSION_MAXNAMELEN)
8cce6c
 				xtables_error(PARAMETER_PROBLEM,
8cce6c
 					   "Invalid chain name `%s' "
8cce6c
@@ -246,24 +214,28 @@ void xtables_restore_parse(struct nft_handle *h,
8cce6c
 				}
8cce6c
 				DEBUGP("Setting policy of chain %s to %s\n",
8cce6c
 				       chain, policy);
8cce6c
-				ret = 1;
8cce6c
 
8cce6c
-			} else {
8cce6c
-				if (!chain_exists &&
8cce6c
-				    cb->chain_user_add &&
8cce6c
-				    cb->chain_user_add(h, chain,
8cce6c
-						       curtable->name) < 0) {
8cce6c
-					if (errno == EEXIST)
8cce6c
-						continue;
8cce6c
+			} else if (noflush &&
8cce6c
+				   nftnl_chain_list_lookup_byname(chain_list, chain)) {
8cce6c
+				/* Apparently -n still flushes existing user
8cce6c
+				 * defined chains that are redefined. Otherwise,
8cce6c
+				 * leave them as is.
8cce6c
+				 */
8cce6c
+				if (cb->chain_user_flush)
8cce6c
+					cb->chain_user_flush(h, chain_list,
8cce6c
+							     curtable->name, chain);
8cce6c
+			} else if (cb->chain_user_add &&
8cce6c
+				   cb->chain_user_add(h, chain,
8cce6c
+						      curtable->name) < 0) {
8cce6c
+				if (errno == EEXIST)
8cce6c
+					continue;
8cce6c
 
8cce6c
-					xtables_error(PARAMETER_PROBLEM,
8cce6c
-						      "cannot create chain "
8cce6c
-						      "'%s' (%s)\n", chain,
8cce6c
-						      strerror(errno));
8cce6c
-				}
8cce6c
-				continue;
8cce6c
+				xtables_error(PARAMETER_PROBLEM,
8cce6c
+					      "cannot create chain "
8cce6c
+					      "'%s' (%s)\n", chain,
8cce6c
+					      strerror(errno));
8cce6c
 			}
8cce6c
-
8cce6c
+			ret = 1;
8cce6c
 		} else if (in_table) {
8cce6c
 			int a;
8cce6c
 			char *pcnt = NULL;
8cce6c
@@ -496,7 +468,6 @@ struct nft_xt_restore_cb ebt_restore_cb = {
8cce6c
 	.table_new	= nft_table_new,
8cce6c
 	.table_flush	= nft_table_flush,
8cce6c
 	.chain_user_flush = nft_chain_user_flush,
8cce6c
-	.chain_del	= chain_delete,
8cce6c
 	.do_command	= do_commandeb,
8cce6c
 	.chain_set	= nft_chain_set,
8cce6c
 	.chain_user_add	= nft_chain_user_add,
8cce6c
@@ -542,7 +513,6 @@ struct nft_xt_restore_cb arp_restore_cb = {
8cce6c
 	.table_new	= nft_table_new,
8cce6c
 	.table_flush	= nft_table_flush,
8cce6c
 	.chain_user_flush = nft_chain_user_flush,
8cce6c
-	.chain_del	= chain_delete,
8cce6c
 	.do_command	= do_commandarp,
8cce6c
 	.chain_set	= nft_chain_set,
8cce6c
 	.chain_user_add	= nft_chain_user_add,
8cce6c
-- 
1dc35b
2.21.0
8cce6c