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.c40
1 files changed, 29 insertions, 11 deletions
diff --git a/iptables/nft-cache.c b/iptables/nft-cache.c
index 305f2c12..61184653 100644
--- a/iptables/nft-cache.c
+++ b/iptables/nft-cache.c
@@ -11,6 +11,7 @@
#include <assert.h>
#include <errno.h>
+#include <stdlib.h>
#include <string.h>
#include <xtables.h>
@@ -24,14 +25,21 @@
#include "nft.h"
#include "nft-cache.h"
-void nft_cache_level_set(struct nft_handle *h, int level)
+void nft_cache_level_set(struct nft_handle *h, int level,
+ const struct nft_cmd *cmd)
{
struct nft_cache_req *req = &h->cache_req;
- if (level <= req->level)
+ if (level > req->level)
+ req->level = level;
+
+ if (!cmd)
return;
- req->level = level;
+ if (!req->table)
+ req->table = strdup(cmd->table);
+ else
+ assert(!strcmp(req->table, cmd->table));
}
static int genid_cb(const struct nlmsghdr *nlh, void *data)
@@ -435,10 +443,14 @@ static void
__nft_build_cache(struct nft_handle *h)
{
struct nft_cache_req *req = &h->cache_req;
+ const struct builtin_table *t = NULL;
if (h->cache_init)
return;
+ if (req->table)
+ t = nft_table_builtin_find(h, req->table);
+
h->cache_init = true;
mnl_genid_get(h, &h->nft_genid);
@@ -447,11 +459,11 @@ __nft_build_cache(struct nft_handle *h)
if (req->level == NFT_CL_FAKE)
return;
if (req->level >= NFT_CL_CHAINS)
- fetch_chain_cache(h, NULL, NULL);
+ fetch_chain_cache(h, t, NULL);
if (req->level >= NFT_CL_SETS)
- fetch_set_cache(h, NULL, NULL);
+ fetch_set_cache(h, t, NULL);
if (req->level >= NFT_CL_RULES)
- fetch_rule_cache(h, NULL);
+ fetch_rule_cache(h, t);
}
static void __nft_flush_cache(struct nft_handle *h)
@@ -575,14 +587,20 @@ void nft_cache_build(struct nft_handle *h)
void nft_release_cache(struct nft_handle *h)
{
- if (!h->cache_index)
- return;
+ struct nft_cache_req *req = &h->cache_req;
+ while (h->cache_index)
+ flush_cache(h, &h->__cache[h->cache_index--], NULL);
flush_cache(h, &h->__cache[0], NULL);
- memcpy(&h->__cache[0], &h->__cache[1], sizeof(h->__cache[0]));
- memset(&h->__cache[1], 0, sizeof(h->__cache[1]));
- h->cache_index = 0;
h->cache = &h->__cache[0];
+ h->cache_init = false;
+
+ if (req->level != NFT_CL_FAKE)
+ req->level = NFT_CL_TABLES;
+ if (req->table) {
+ free(req->table);
+ req->table = NULL;
+ }
}
struct nftnl_table_list *nftnl_table_list_get(struct nft_handle *h)