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

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