Blame SOURCES/0025-xtables-Optimize-user-defined-chain-deletion.patch

8cce6c
From 7b071787e82cbc53a5a33364826d8e0495b84fc0 Mon Sep 17 00:00:00 2001
8cce6c
From: Phil Sutter <phil@nwl.cc>
8cce6c
Date: Thu, 20 Dec 2018 16:09:17 +0100
8cce6c
Subject: [PATCH] xtables: Optimize user-defined chain deletion
8cce6c
8cce6c
Make use of nftnl_chain_list_lookup_byname() if a chain name was given.
8cce6c
Move the actual chain deleting code into a callback suitable for passing
8cce6c
to nftnl_chain_list_foreach().
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 0b950ed4549308ef23ffc7561567df86c90cfed9)
8cce6c
Signed-off-by: Phil Sutter <psutter@redhat.com>
8cce6c
---
8cce6c
 iptables/nft.c | 89 ++++++++++++++++++++++++++------------------------
8cce6c
 1 file changed, 46 insertions(+), 43 deletions(-)
8cce6c
8cce6c
diff --git a/iptables/nft.c b/iptables/nft.c
8cce6c
index 9951bf3212197..162d91e82115b 100644
8cce6c
--- a/iptables/nft.c
8cce6c
+++ b/iptables/nft.c
8cce6c
@@ -1642,63 +1642,66 @@ int nft_chain_user_add(struct nft_handle *h, const char *chain, const char *tabl
8cce6c
 #define NLM_F_NONREC	0x100	/* Do not delete recursively    */
8cce6c
 #endif
8cce6c
 
8cce6c
+struct chain_user_del_data {
8cce6c
+	struct nft_handle	*handle;
8cce6c
+	bool			verbose;
8cce6c
+	int			builtin_err;
8cce6c
+};
8cce6c
+
8cce6c
+static int __nft_chain_user_del(struct nftnl_chain *c, void *data)
8cce6c
+{
8cce6c
+	struct chain_user_del_data *d = data;
8cce6c
+	struct nft_handle *h = d->handle;
8cce6c
+	int ret;
8cce6c
+
8cce6c
+	/* don't delete built-in chain */
8cce6c
+	if (nft_chain_builtin(c))
8cce6c
+		return d->builtin_err;
8cce6c
+
8cce6c
+	if (d->verbose)
8cce6c
+		fprintf(stdout, "Deleting chain `%s'\n",
8cce6c
+			nftnl_chain_get_str(c, NFTNL_CHAIN_NAME));
8cce6c
+
8cce6c
+	ret = batch_chain_add(h, NFT_COMPAT_CHAIN_USER_DEL, c);
8cce6c
+	if (ret)
8cce6c
+		return -1;
8cce6c
+
8cce6c
+	nftnl_chain_list_del(c);
8cce6c
+	return 0;
8cce6c
+}
8cce6c
+
8cce6c
 int nft_chain_user_del(struct nft_handle *h, const char *chain,
8cce6c
 		       const char *table, bool verbose)
8cce6c
 {
8cce6c
+	struct chain_user_del_data d = {
8cce6c
+		.handle = h,
8cce6c
+		.verbose = verbose,
8cce6c
+	};
8cce6c
 	struct nftnl_chain_list *list;
8cce6c
-	struct nftnl_chain_list_iter *iter;
8cce6c
 	struct nftnl_chain *c;
8cce6c
 	int ret = 0;
8cce6c
-	int deleted_ctr = 0;
8cce6c
 
8cce6c
 	nft_fn = nft_chain_user_del;
8cce6c
 
8cce6c
 	list = nft_chain_list_get(h, table);
8cce6c
 	if (list == NULL)
8cce6c
-		goto err;
8cce6c
-
8cce6c
-	iter = nftnl_chain_list_iter_create(list);
8cce6c
-	if (iter == NULL)
8cce6c
-		goto err;
8cce6c
-
8cce6c
-	c = nftnl_chain_list_iter_next(iter);
8cce6c
-	while (c != NULL) {
8cce6c
-		const char *chain_name =
8cce6c
-			nftnl_chain_get_str(c, NFTNL_CHAIN_NAME);
8cce6c
-
8cce6c
-		/* don't delete built-in chain */
8cce6c
-		if (nft_chain_builtin(c))
8cce6c
-			goto next;
8cce6c
-
8cce6c
-		if (chain != NULL && strcmp(chain, chain_name) != 0)
8cce6c
-			goto next;
8cce6c
-
8cce6c
-		if (verbose)
8cce6c
-			fprintf(stdout, "Deleting chain `%s'\n", chain);
8cce6c
-
8cce6c
-		ret = batch_chain_add(h, NFT_COMPAT_CHAIN_USER_DEL, c);
8cce6c
-
8cce6c
-		if (ret < 0)
8cce6c
-			break;
8cce6c
-
8cce6c
-		deleted_ctr++;
8cce6c
-		nftnl_chain_list_del(c);
8cce6c
-
8cce6c
-		if (chain != NULL)
8cce6c
-			break;
8cce6c
-next:
8cce6c
-		c = nftnl_chain_list_iter_next(iter);
8cce6c
-	}
8cce6c
-
8cce6c
-	nftnl_chain_list_iter_destroy(iter);
8cce6c
-err:
8cce6c
+		return 0;
8cce6c
 
8cce6c
-	/* chain not found */
8cce6c
-	if (chain != NULL && deleted_ctr == 0) {
8cce6c
-		ret = -1;
8cce6c
-		errno = ENOENT;
8cce6c
+	if (chain) {
8cce6c
+		c = nftnl_chain_list_lookup_byname(list, chain);
8cce6c
+		if (!c) {
8cce6c
+			errno = ENOENT;
8cce6c
+			return 0;
8cce6c
+		}
8cce6c
+		d.builtin_err = -2;
8cce6c
+		ret = __nft_chain_user_del(c, &d);
8cce6c
+		if (ret == -2)
8cce6c
+			errno = EINVAL;
8cce6c
+		goto out;
8cce6c
 	}
8cce6c
 
8cce6c
+	ret = nftnl_chain_list_foreach(list, __nft_chain_user_del, &d);
8cce6c
+out:
8cce6c
 	/* the core expects 1 for success and 0 for error */
8cce6c
 	return ret == 0 ? 1 : 0;
8cce6c
 }
8cce6c
-- 
8cce6c
2.20.1
8cce6c