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

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