summaryrefslogtreecommitdiffstats
path: root/iptables/nft-cache.c
diff options
context:
space:
mode:
Diffstat (limited to 'iptables/nft-cache.c')
-rw-r--r--iptables/nft-cache.c77
1 files changed, 20 insertions, 57 deletions
diff --git a/iptables/nft-cache.c b/iptables/nft-cache.c
index bf1fb346..32cfd6cf 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);
@@ -534,14 +502,14 @@ retry:
if (req->level >= NFT_CL_TABLES)
fetch_table_cache(h);
if (req->level == NFT_CL_FAKE)
- return;
+ goto genid_check;
if (req->level >= NFT_CL_CHAINS)
fetch_chain_cache(h, t, chains);
if (req->level >= NFT_CL_SETS)
fetch_set_cache(h, t, NULL);
if (req->level >= NFT_CL_RULES)
fetch_rule_cache(h, t);
-
+genid_check:
mnl_genid_get(h, &genid_check);
if (h->nft_genid != genid_check) {
flush_cache(h, h->cache, NULL);
@@ -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)
{