Blame SOURCES/0023-xtables-Optimize-nft_chain_zero_counters.patch

8cce6c
From ecd80647d4b862324943ba8ecb40ae988a7e6376 Mon Sep 17 00:00:00 2001
8cce6c
From: Phil Sutter <phil@nwl.cc>
8cce6c
Date: Thu, 20 Dec 2018 16:09:15 +0100
8cce6c
Subject: [PATCH] xtables: Optimize nft_chain_zero_counters()
8cce6c
8cce6c
If a chain name was given, make use of nftnl_chain_list_lookup_byname().
8cce6c
Streamline nft_chain_zero_rule_counters() to be suitable for calling
8cce6c
from nftnl_chain_list_foreach().
8cce6c
8cce6c
There is an unrelated optimization in here, too: Add batch job
8cce6c
NFT_COMPAT_CHAIN_ZERO only if it is a base chain. Since user-defined
8cce6c
chains don't have counters, there is no need to do anything for them.
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 a6ce0c65d3a390bfff16e834c18650beedecf40c)
8cce6c
Signed-off-by: Phil Sutter <psutter@redhat.com>
8cce6c
---
8cce6c
 iptables/nft.c | 72 +++++++++++++++++++++++++-------------------------
8cce6c
 1 file changed, 36 insertions(+), 36 deletions(-)
8cce6c
8cce6c
diff --git a/iptables/nft.c b/iptables/nft.c
8cce6c
index a23acbcc9b100..9951bf3212197 100644
8cce6c
--- a/iptables/nft.c
8cce6c
+++ b/iptables/nft.c
8cce6c
@@ -2939,15 +2939,36 @@ int nft_xtables_config_load(struct nft_handle *h, const char *filename,
8cce6c
 	return h->config_done;
8cce6c
 }
8cce6c
 
8cce6c
-static void nft_chain_zero_rule_counters(struct nft_handle *h,
8cce6c
-					 struct nftnl_chain *c)
8cce6c
+struct chain_zero_data {
8cce6c
+	struct nft_handle	*handle;
8cce6c
+	bool			verbose;
8cce6c
+};
8cce6c
+
8cce6c
+static int __nft_chain_zero_counters(struct nftnl_chain *c, void *data)
8cce6c
 {
8cce6c
+	struct chain_zero_data *d = data;
8cce6c
+	struct nft_handle *h = d->handle;
8cce6c
 	struct nftnl_rule_iter *iter;
8cce6c
 	struct nftnl_rule *r;
8cce6c
+	int ret = 0;
8cce6c
+
8cce6c
+	if (d->verbose)
8cce6c
+		fprintf(stdout, "Zeroing chain `%s'\n",
8cce6c
+			nftnl_chain_get_str(c, NFTNL_CHAIN_NAME));
8cce6c
+
8cce6c
+	if (nftnl_chain_is_set(c, NFTNL_CHAIN_HOOKNUM)) {
8cce6c
+		/* zero base chain counters. */
8cce6c
+		nftnl_chain_set_u64(c, NFTNL_CHAIN_PACKETS, 0);
8cce6c
+		nftnl_chain_set_u64(c, NFTNL_CHAIN_BYTES, 0);
8cce6c
+		nftnl_chain_unset(c, NFTNL_CHAIN_HANDLE);
8cce6c
+		ret = batch_chain_add(h, NFT_COMPAT_CHAIN_ZERO, c);
8cce6c
+		if (ret)
8cce6c
+			return -1;
8cce6c
+	}
8cce6c
 
8cce6c
 	iter = nftnl_rule_iter_create(c);
8cce6c
 	if (iter == NULL)
8cce6c
-		return;
8cce6c
+		return -1;
8cce6c
 
8cce6c
 	r = nftnl_rule_iter_next(iter);
8cce6c
 	while (r != NULL) {
8cce6c
@@ -2989,13 +3010,17 @@ static void nft_chain_zero_rule_counters(struct nft_handle *h,
8cce6c
 	}
8cce6c
 
8cce6c
 	nftnl_rule_iter_destroy(iter);
8cce6c
+	return 0;
8cce6c
 }
8cce6c
 
8cce6c
 int nft_chain_zero_counters(struct nft_handle *h, const char *chain,
8cce6c
 			    const char *table, bool verbose)
8cce6c
 {
8cce6c
 	struct nftnl_chain_list *list;
8cce6c
-	struct nftnl_chain_list_iter *iter;
8cce6c
+	struct chain_zero_data d = {
8cce6c
+		.handle = h,
8cce6c
+		.verbose = verbose,
8cce6c
+	};
8cce6c
 	struct nftnl_chain *c;
8cce6c
 	int ret = 0;
8cce6c
 
8cce6c
@@ -3003,41 +3028,16 @@ int nft_chain_zero_counters(struct nft_handle *h, const char *chain,
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(c, NFTNL_CHAIN_NAME);
8cce6c
-
8cce6c
-		if (chain != NULL && strcmp(chain, chain_name) != 0)
8cce6c
-			goto next;
8cce6c
-
8cce6c
-		if (verbose)
8cce6c
-			fprintf(stdout, "Zeroing chain `%s'\n", chain_name);
8cce6c
-
8cce6c
-		if (nftnl_chain_is_set(c, NFTNL_CHAIN_HOOKNUM)) {
8cce6c
-			/* zero base chain counters. */
8cce6c
-			nftnl_chain_set_u64(c, NFTNL_CHAIN_PACKETS, 0);
8cce6c
-			nftnl_chain_set_u64(c, NFTNL_CHAIN_BYTES, 0);
8cce6c
-		}
8cce6c
-
8cce6c
-		nft_chain_zero_rule_counters(h, c);
8cce6c
-
8cce6c
-		nftnl_chain_unset(c, NFTNL_CHAIN_HANDLE);
8cce6c
-
8cce6c
-		ret = batch_chain_add(h, NFT_COMPAT_CHAIN_ZERO, c);
8cce6c
+	if (chain) {
8cce6c
+		c = nftnl_chain_list_lookup_byname(list, chain);
8cce6c
+		if (!c)
8cce6c
+			return 0;
8cce6c
 
8cce6c
-		if (chain != NULL)
8cce6c
-			break;
8cce6c
-next:
8cce6c
-		c = nftnl_chain_list_iter_next(iter);
8cce6c
+		ret = __nft_chain_zero_counters(c, &d);
8cce6c
+		goto err;
8cce6c
 	}
8cce6c
 
8cce6c
-	nftnl_chain_list_iter_destroy(iter);
8cce6c
-
8cce6c
+	ret = nftnl_chain_list_foreach(list, __nft_chain_zero_counters, &d);
8cce6c
 err:
8cce6c
 	/* the core expects 1 for success and 0 for error */
8cce6c
 	return ret == 0 ? 1 : 0;
8cce6c
-- 
8cce6c
2.20.1
8cce6c