laurenceman / rpms / iptables

Forked from rpms/iptables 5 years ago
Clone

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

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