diff mbox series

[iptables,v2,11/14] xtables: Optimize nft_rule_list_save()

Message ID 20181213111607.5457-12-phil@nwl.cc
State Changes Requested
Delegated to: Pablo Neira
Headers show
Series Separate rule cache per chain et al. | expand

Commit Message

Phil Sutter Dec. 13, 2018, 11:16 a.m. UTC
If a chain name was given, make use of nftnl_chain_list_lookup_byname().

Likewise in nftnl_rule_list_chain_save(), but introduce
__nftnl_rule_list_chain_save() suitable for passing to
nftnl_chain_list_foreach().

Signed-off-by: Phil Sutter <phil@nwl.cc>
---
 iptables/nft.c | 93 +++++++++++++++++++++++---------------------------
 1 file changed, 43 insertions(+), 50 deletions(-)
diff mbox series

Patch

diff --git a/iptables/nft.c b/iptables/nft.c
index 40aedfb74fc70..be57aae297f50 100644
--- a/iptables/nft.c
+++ b/iptables/nft.c
@@ -2333,46 +2333,44 @@  list_save(struct nftnl_rule *r, unsigned int num, unsigned int format)
 	nft_rule_print_save(r, NFT_RULE_APPEND, format);
 }
 
+static int __nftnl_rule_list_chain_save(struct nftnl_chain *c, void *data)
+{
+	const char *chain_name = nftnl_chain_get_str(c, NFTNL_CHAIN_NAME);
+	uint32_t policy = nftnl_chain_get_u32(c, NFTNL_CHAIN_POLICY);
+	int *counters = data;
+
+	if (!nft_chain_builtin(c)) {
+		printf("-N %s\n", chain_name);
+		return 0;
+	}
+
+	/* this is a base chain */
+
+	printf("-P %s %s", chain_name, policy_name[policy]);
+	if (*counters)
+		printf(" -c %"PRIu64" %"PRIu64,
+		       nftnl_chain_get_u64(c, NFTNL_CHAIN_PACKETS),
+		       nftnl_chain_get_u64(c, NFTNL_CHAIN_BYTES));
+	printf("\n");
+	return 0;
+}
+
 static int
 nftnl_rule_list_chain_save(struct nft_handle *h, const char *chain,
 			   struct nftnl_chain_list *list, int counters)
 {
-	struct nftnl_chain_list_iter *iter;
 	struct nftnl_chain *c;
 
-	iter = nftnl_chain_list_iter_create(list);
-	if (iter == NULL)
-		return 0;
-
-	c = nftnl_chain_list_iter_next(iter);
-	while (c != NULL) {
-		const char *chain_name =
-			nftnl_chain_get_str(c, NFTNL_CHAIN_NAME);
-		uint32_t policy =
-			nftnl_chain_get_u32(c, NFTNL_CHAIN_POLICY);
-
-		if (chain && strcmp(chain, chain_name) != 0)
-			goto next;
+	if (chain) {
+		c = nftnl_chain_list_lookup_byname(list, chain);
+		if (!c)
+			return 0;
 
-		/* this is a base chain */
-		if (nft_chain_builtin(c)) {
-			printf("-P %s %s", chain_name, policy_name[policy]);
-
-			if (counters) {
-				printf(" -c %"PRIu64" %"PRIu64"\n",
-					nftnl_chain_get_u64(c, NFTNL_CHAIN_PACKETS),
-					nftnl_chain_get_u64(c, NFTNL_CHAIN_BYTES));
-			} else
-				printf("\n");
-		} else {
-			printf("-N %s\n", chain_name);
-		}
-next:
-		c = nftnl_chain_list_iter_next(iter);
+		__nftnl_rule_list_chain_save(c, &counters);
+		return 1;
 	}
 
-	nftnl_chain_list_iter_destroy(iter);
-
+	nftnl_chain_list_foreach(list, __nftnl_rule_list_chain_save, &counters);
 	return 1;
 }
 
@@ -2404,41 +2402,36 @@  int nft_rule_list_save(struct nft_handle *h, const char *chain,
 
 	list = nft_chain_list_get(h, table, true);
 	if (!list)
-		goto err;
+		return 0;
 
 	/* Dump policies and custom chains first */
 	if (!rulenum)
 		nftnl_rule_list_chain_save(h, chain, list, counters);
 
-	/* Now dump out rules in this table */
-	iter = nftnl_chain_list_iter_create(list);
-	if (iter == NULL)
-		goto err;
-
 	if (counters < 0)
 		format = FMT_C_COUNTS;
 	else if (counters == 0)
 		format = FMT_NOCOUNTS;
 
-	c = nftnl_chain_list_iter_next(iter);
-	while (c != NULL) {
-		const char *chain_name =
-			nftnl_chain_get_str(c, NFTNL_CHAIN_NAME);
+	if (chain) {
+		c = nftnl_chain_list_lookup_byname(list, chain);
+		if (!c)
+			return 0;
 
-		if (chain && strcmp(chain, chain_name) != 0)
-			goto next;
+		return __nft_rule_list(h, c, rulenum, format, list_save);
+	}
 
-		ret = __nft_rule_list(h, c, rulenum, format, list_save);
+	/* Now dump out rules in this table */
+	iter = nftnl_chain_list_iter_create(list);
+	if (iter == NULL)
+		return 0;
 
-		/* we printed the chain we wanted, stop processing. */
-		if (chain)
-			break;
-next:
+	c = nftnl_chain_list_iter_next(iter);
+	while (c != NULL) {
+		ret = __nft_rule_list(h, c, rulenum, format, list_save);
 		c = nftnl_chain_list_iter_next(iter);
 	}
-
 	nftnl_chain_list_iter_destroy(iter);
-err:
 	return ret;
 }