diff options
author | Phil Sutter <phil@nwl.cc> | 2020-07-30 11:54:36 +0200 |
---|---|---|
committer | Phil Sutter <phil@nwl.cc> | 2020-07-31 13:37:20 +0200 |
commit | 27d01216cf05eb0b49b6456137e01a44d4547796 (patch) | |
tree | 045bc6ac1f7ed2a7990863d59e4daf2b2821b347 /iptables/nft-cache.c | |
parent | cf3e9100eedce518e42dfb6933c7871d041a7d18 (diff) |
nft: Eliminate table list from cache
The full list of tables in kernel is not relevant, only those used by
iptables-nft and for those, knowing if they exist or not is sufficient.
For holding that information, the already existing 'table' array in
nft_cache suits well.
Consequently, nft_table_find() merely checks if the new 'exists' boolean
is true or not and nft_for_each_table() iterates over the builtin_table
array in nft_handle, additionally checking the boolean in cache for
whether to skip the entry or not.
Signed-off-by: Phil Sutter <phil@nwl.cc>
Diffstat (limited to 'iptables/nft-cache.c')
-rw-r--r-- | iptables/nft-cache.c | 73 |
1 files changed, 18 insertions, 55 deletions
diff --git a/iptables/nft-cache.c b/iptables/nft-cache.c index bf1fb346..c6baf090 100644 --- a/iptables/nft-cache.c +++ b/iptables/nft-cache.c @@ -107,59 +107,30 @@ static void mnl_genid_get(struct nft_handle *h, uint32_t *genid) "Could not fetch rule set generation id: %s\n", nft_strerror(errno)); } -static struct nft_table *nft_table_alloc(void) -{ - struct nftnl_table *nftnl; - struct nft_table *table; - - table = malloc(sizeof(struct nft_table)); - if (!table) - return NULL; - - nftnl = nftnl_table_alloc(); - if (!nftnl) { - free(table); - return NULL; - } - table->nftnl = nftnl; - - return table; -} - -static void nft_table_free(struct nft_table *table) +static int nftnl_table_list_cb(const struct nlmsghdr *nlh, void *data) { - nftnl_table_free(table->nftnl); - free(table); -} + struct nftnl_table *nftnl = nftnl_table_alloc(); + const struct builtin_table *t; + struct nft_handle *h = data; + const char *name; -static void nft_table_list_free(struct list_head *table_list) -{ - struct nft_table *table, *next; + if (!nftnl) + return MNL_CB_OK; - list_for_each_entry_safe(table, next, table_list, list) { - list_del(&table->list); - nft_table_free(table); - } -} + if (nftnl_table_nlmsg_parse(nlh, nftnl) < 0) + goto out; -static int nftnl_table_list_cb(const struct nlmsghdr *nlh, void *data) -{ - struct list_head *list = data; - struct nft_table *t; + name = nftnl_table_get_str(nftnl, NFTNL_TABLE_NAME); + if (!name) + goto out; - t = nft_table_alloc(); + t = nft_table_builtin_find(h, name); if (!t) - goto err; - - if (nftnl_table_nlmsg_parse(nlh, t->nftnl) < 0) goto out; - list_add_tail(&t->list, list); - - return MNL_CB_OK; + h->cache->table[t->type].exists = true; out: - nft_table_free(t); -err: + nftnl_table_free(nftnl); return MNL_CB_OK; } @@ -169,13 +140,10 @@ static int fetch_table_cache(struct nft_handle *h) char buf[16536]; int i, ret; - if (!list_empty(&h->cache->tables)) - return 0; - nlh = nftnl_rule_nlmsg_build_hdr(buf, NFT_MSG_GETTABLE, h->family, NLM_F_DUMP, h->seq); - ret = mnl_talk(h, nlh, nftnl_table_list_cb, &h->cache->tables); + ret = mnl_talk(h, nlh, nftnl_table_list_cb, h); if (ret < 0 && errno == EINTR) assert(nft_restart(h) >= 0); @@ -635,9 +603,9 @@ static int flush_cache(struct nft_handle *h, struct nft_cache *c, nftnl_set_list_free(c->table[i].sets); c->table[i].sets = NULL; } + + c->table[i].exists = false; } - if (!list_empty(&c->tables)) - nft_table_list_free(&c->tables); return 1; } @@ -710,11 +678,6 @@ void nft_release_cache(struct nft_handle *h) } } -struct list_head *nft_table_list_get(struct nft_handle *h) -{ - return &h->cache->tables; -} - struct nftnl_set_list * nft_set_list_get(struct nft_handle *h, const char *table, const char *set) { |