laurenceman / rpms / iptables

Forked from rpms/iptables 5 years ago
Clone

Blame SOURCES/0017-nft-Simplify-per-table-chain-cache-update.patch

029dc7
From eafa37433c920c6613bd351017d31cfd6e4cc397 Mon Sep 17 00:00:00 2001
029dc7
From: Phil Sutter <phil@nwl.cc>
029dc7
Date: Thu, 20 Dec 2018 16:09:08 +0100
029dc7
Subject: [PATCH] nft: Simplify per table chain cache update
029dc7
029dc7
Previously, each table's chain cache was potentially unallocated until
029dc7
nftnl_chain_list_cb() saw a chain for it. This means such callback had to
029dc7
check the chain_cache pointer for each chain belonging to that table.
029dc7
029dc7
In addition to the above, nft_chain_list_get() had to cover for the
029dc7
possibility that a given table didn't have any chains at all in kernel,
029dc7
so check requested table's chain cache once more and allocate it if
029dc7
NULL.
029dc7
029dc7
Instead, simply iterate over all tables and preallocate their chain
029dc7
caches prior to requesting the chain list from kernel. The only caveat
029dc7
is to flush the chain cache completely before retrying in case of EINTR.
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 402dac2190e6011d4f4ad81c2992b7126b3d79d9)
029dc7
Signed-off-by: Phil Sutter <psutter@redhat.com>
029dc7
---
029dc7
 iptables/nft.c | 23 +++++++++++++----------
029dc7
 1 file changed, 13 insertions(+), 10 deletions(-)
029dc7
029dc7
diff --git a/iptables/nft.c b/iptables/nft.c
029dc7
index 997d7bc58fd00..7d08a0884adde 100644
029dc7
--- a/iptables/nft.c
029dc7
+++ b/iptables/nft.c
029dc7
@@ -1286,12 +1286,6 @@ static int nftnl_chain_list_cb(const struct nlmsghdr *nlh, void *data)
029dc7
 	if (!t)
029dc7
 		goto out;
029dc7
 
029dc7
-	if (!h->table[t->type].chain_cache) {
029dc7
-		h->table[t->type].chain_cache = nftnl_chain_list_alloc();
029dc7
-		if (!h->table[t->type].chain_cache)
029dc7
-			goto out;
029dc7
-	}
029dc7
-
029dc7
 	nftnl_chain_list_add_tail(c, h->table[t->type].chain_cache);
029dc7
 
029dc7
 	return MNL_CB_OK;
029dc7
@@ -1307,7 +1301,7 @@ struct nftnl_chain_list *nft_chain_list_get(struct nft_handle *h,
029dc7
 	char buf[16536];
029dc7
 	struct nlmsghdr *nlh;
029dc7
 	const struct builtin_table *t;
029dc7
-	int ret;
029dc7
+	int i, ret;
029dc7
 
029dc7
 	t = nft_table_builtin_find(h, table);
029dc7
 	if (!t)
029dc7
@@ -1316,18 +1310,27 @@ struct nftnl_chain_list *nft_chain_list_get(struct nft_handle *h,
029dc7
 	if (h->table[t->type].chain_cache)
029dc7
 		return h->table[t->type].chain_cache;
029dc7
 retry:
029dc7
+	for (i = 0; i < NFT_TABLE_MAX; i++) {
029dc7
+		enum nft_table_type type = h->tables[i].type;
029dc7
+
029dc7
+		if (!h->tables[i].name)
029dc7
+			continue;
029dc7
+
029dc7
+		h->table[type].chain_cache = nftnl_chain_list_alloc();
029dc7
+		if (!h->table[type].chain_cache)
029dc7
+			return NULL;
029dc7
+	}
029dc7
+
029dc7
 	nlh = nftnl_chain_nlmsg_build_hdr(buf, NFT_MSG_GETCHAIN, h->family,
029dc7
 					NLM_F_DUMP, h->seq);
029dc7
 
029dc7
 	ret = mnl_talk(h, nlh, nftnl_chain_list_cb, h);
029dc7
 	if (ret < 0 && errno == EINTR) {
029dc7
 		assert(nft_restart(h) >= 0);
029dc7
+		flush_chain_cache(h, NULL);
029dc7
 		goto retry;
029dc7
 	}
029dc7
 
029dc7
-	if (!h->table[t->type].chain_cache)
029dc7
-		h->table[t->type].chain_cache = nftnl_chain_list_alloc();
029dc7
-
029dc7
 	return h->table[t->type].chain_cache;
029dc7
 }
029dc7
 
029dc7
-- 
029dc7
2.21.0
029dc7