|
|
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 |
|