Blame SOURCES/0027-xtables-Optimize-list-command-with-given-chain.patch

1dc35b
From 8b38ab8ead7829569ab6a3c9fa7a193d568b707a Mon Sep 17 00:00:00 2001
8cce6c
From: Phil Sutter <phil@nwl.cc>
8cce6c
Date: Thu, 20 Dec 2018 16:09:18 +0100
8cce6c
Subject: [PATCH] xtables: Optimize list command with given chain
8cce6c
8cce6c
Make use of nftnl_chain_list_lookup_byname() even if not listing a
8cce6c
specific rule. Introduce __nft_print_header() to consolidate chain value
8cce6c
extraction for printing with ops->print_header().
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 11cbd7291f37fbfd5ebe6ffa1730f7d198ed2ac0)
8cce6c
Signed-off-by: Phil Sutter <psutter@redhat.com>
8cce6c
---
8cce6c
 iptables/nft.c | 78 +++++++++++++++++++++-----------------------------
8cce6c
 1 file changed, 32 insertions(+), 46 deletions(-)
8cce6c
8cce6c
diff --git a/iptables/nft.c b/iptables/nft.c
8cce6c
index 162d91e82115b..e1c997836cb97 100644
8cce6c
--- a/iptables/nft.c
8cce6c
+++ b/iptables/nft.c
8cce6c
@@ -2247,6 +2247,24 @@ static int nft_rule_count(struct nft_handle *h, struct nftnl_chain *c)
8cce6c
 	return rule_ctr;
8cce6c
 }
8cce6c
 
8cce6c
+static void __nft_print_header(struct nft_handle *h,
8cce6c
+			       const struct nft_family_ops *ops,
8cce6c
+			       struct nftnl_chain *c, unsigned int format)
8cce6c
+{
8cce6c
+	const char *chain_name = nftnl_chain_get_str(c, NFTNL_CHAIN_NAME);
8cce6c
+	uint32_t policy = nftnl_chain_get_u32(c, NFTNL_CHAIN_POLICY);
8cce6c
+	bool basechain = !!nftnl_chain_get(c, NFTNL_CHAIN_HOOKNUM);
8cce6c
+	uint32_t refs = nftnl_chain_get_u32(c, NFTNL_CHAIN_USE);
8cce6c
+	uint32_t entries = nft_rule_count(h, c);
8cce6c
+	struct xt_counters ctrs = {
8cce6c
+		.pcnt = nftnl_chain_get_u64(c, NFTNL_CHAIN_PACKETS),
8cce6c
+		.bcnt = nftnl_chain_get_u64(c, NFTNL_CHAIN_BYTES),
8cce6c
+	};
8cce6c
+
8cce6c
+	ops->print_header(format, chain_name, policy_name[policy],
8cce6c
+			&ctrs, basechain, refs - entries, entries);
8cce6c
+}
8cce6c
+
8cce6c
 int nft_rule_list(struct nft_handle *h, const char *chain, const char *table,
8cce6c
 		  int rulenum, unsigned int format)
8cce6c
 {
8cce6c
@@ -2275,75 +2293,43 @@ int nft_rule_list(struct nft_handle *h, const char *chain, const char *table,
8cce6c
 		return 0;
8cce6c
 	}
8cce6c
 
8cce6c
-	if (chain && rulenum) {
8cce6c
-		c = nft_chain_find(h, table, chain);
8cce6c
+	list = nft_chain_list_get(h, table);
8cce6c
+	if (!list)
8cce6c
+		return 0;
8cce6c
+
8cce6c
+	if (chain) {
8cce6c
+		c = nftnl_chain_list_lookup_byname(list, chain);
8cce6c
 		if (!c)
8cce6c
 			return 0;
8cce6c
 
8cce6c
+		if (!rulenum) {
8cce6c
+			if (ops->print_table_header)
8cce6c
+				ops->print_table_header(table);
8cce6c
+			__nft_print_header(h, ops, c, format);
8cce6c
+		}
8cce6c
 		__nft_rule_list(h, c, rulenum, format, ops->print_rule);
8cce6c
 		return 1;
8cce6c
 	}
8cce6c
 
8cce6c
-	list = nft_chain_list_get(h, table);
8cce6c
-	if (!list)
8cce6c
-		return 0;
8cce6c
-
8cce6c
 	iter = nftnl_chain_list_iter_create(list);
8cce6c
 	if (iter == NULL)
8cce6c
-		goto err;
8cce6c
+		return 0;
8cce6c
 
8cce6c
-	if (!chain && ops->print_table_header)
8cce6c
+	if (ops->print_table_header)
8cce6c
 		ops->print_table_header(table);
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
-		uint32_t policy =
8cce6c
-			nftnl_chain_get_u32(c, NFTNL_CHAIN_POLICY);
8cce6c
-		uint32_t refs =
8cce6c
-			nftnl_chain_get_u32(c, NFTNL_CHAIN_USE);
8cce6c
-		struct xt_counters ctrs = {
8cce6c
-			.pcnt = nftnl_chain_get_u64(c, NFTNL_CHAIN_PACKETS),
8cce6c
-			.bcnt = nftnl_chain_get_u64(c, NFTNL_CHAIN_BYTES),
8cce6c
-		};
8cce6c
-		bool basechain = false;
8cce6c
-		uint32_t entries;
8cce6c
-
8cce6c
-		if (nftnl_chain_get(c, NFTNL_CHAIN_HOOKNUM))
8cce6c
-			basechain = true;
8cce6c
-
8cce6c
-		if (chain) {
8cce6c
-			if (strcmp(chain, chain_name) != 0)
8cce6c
-				goto next;
8cce6c
-			else if (ops->print_table_header)
8cce6c
-				ops->print_table_header(table);
8cce6c
-		}
8cce6c
-
8cce6c
 		if (found)
8cce6c
 			printf("\n");
8cce6c
 
8cce6c
-		entries = nft_rule_count(h, c);
8cce6c
-		ops->print_header(format, chain_name, policy_name[policy],
8cce6c
-				  &ctrs, basechain, refs - entries, entries);
8cce6c
-
8cce6c
+		__nft_print_header(h, ops, c, format);
8cce6c
 		__nft_rule_list(h, c, rulenum, format, ops->print_rule);
8cce6c
 
8cce6c
 		found = true;
8cce6c
-
8cce6c
-		/* we printed the chain we wanted, stop processing. */
8cce6c
-		if (chain)
8cce6c
-			break;
8cce6c
-
8cce6c
-next:
8cce6c
 		c = nftnl_chain_list_iter_next(iter);
8cce6c
 	}
8cce6c
-
8cce6c
 	nftnl_chain_list_iter_destroy(iter);
8cce6c
-err:
8cce6c
-	if (chain && !found)
8cce6c
-		return 0;
8cce6c
-
8cce6c
 	return 1;
8cce6c
 }
8cce6c
 
8cce6c
-- 
1dc35b
2.21.0
8cce6c