[PATCH iptables 5/6] nft: cache table list

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



nft_table_find() uses the table list cache to look up for existing
tables.

Signed-off-by: Pablo Neira Ayuso <pablo@xxxxxxxxxxxxx>
---
 iptables/nft.c | 102 ++++++++++++++++++++++++++++++++-------------------------
 iptables/nft.h |   1 +
 2 files changed, 58 insertions(+), 45 deletions(-)

diff --git a/iptables/nft.c b/iptables/nft.c
index 8f6f7a41ff33..063637e22fb8 100644
--- a/iptables/nft.c
+++ b/iptables/nft.c
@@ -865,12 +865,17 @@ static int flush_cache(struct nft_cache *c, const struct builtin_table *tables,
 		nftnl_chain_list_free(c->table[i].chains);
 		c->table[i].chains = NULL;
 	}
+	nftnl_table_list_free(c->tables);
+	c->tables = NULL;
 
 	return 1;
 }
 
 static void flush_chain_cache(struct nft_handle *h, const char *tablename)
 {
+	if (!h->have_cache)
+		return;
+
 	if (flush_cache(h->cache, h->tables, tablename))
 		h->have_cache = false;
 }
@@ -1350,6 +1355,53 @@ err:
 	return MNL_CB_OK;
 }
 
+static int nftnl_table_list_cb(const struct nlmsghdr *nlh, void *data)
+{
+	struct nftnl_table *t;
+	struct nftnl_table_list *list = data;
+
+	t = nftnl_table_alloc();
+	if (t == NULL)
+		goto err;
+
+	if (nftnl_table_nlmsg_parse(nlh, t) < 0)
+		goto out;
+
+	nftnl_table_list_add_tail(t, list);
+
+	return MNL_CB_OK;
+out:
+	nftnl_table_free(t);
+err:
+	return MNL_CB_OK;
+}
+
+static int fetch_table_cache(struct nft_handle *h)
+{
+	char buf[16536];
+	struct nlmsghdr *nlh;
+	struct nftnl_table_list *list;
+	int ret;
+
+retry:
+	list = nftnl_table_list_alloc();
+	if (list == NULL)
+		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, list);
+	if (ret < 0 && errno == EINTR) {
+		assert(nft_restart(h) >= 0);
+		nftnl_table_list_free(list);
+		goto retry;
+	}
+	h->cache->tables = list;
+
+	return 1;
+}
+
 static int fetch_chain_cache(struct nft_handle *h)
 {
 	char buf[16536];
@@ -1357,6 +1409,8 @@ static int fetch_chain_cache(struct nft_handle *h)
 	int i, ret;
 
 retry:
+	fetch_table_cache(h);
+
 	for (i = 0; i < NFT_TABLE_MAX; i++) {
 		enum nft_table_type type = h->tables[i].type;
 
@@ -1968,56 +2022,17 @@ int nft_chain_user_rename(struct nft_handle *h,const char *chain,
 	return ret == 0 ? 1 : 0;
 }
 
-static int nftnl_table_list_cb(const struct nlmsghdr *nlh, void *data)
-{
-	struct nftnl_table *t;
-	struct nftnl_table_list *list = data;
-
-	t = nftnl_table_alloc();
-	if (t == NULL)
-		goto err;
-
-	if (nftnl_table_nlmsg_parse(nlh, t) < 0)
-		goto out;
-
-	nftnl_table_list_add_tail(t, list);
-
-	return MNL_CB_OK;
-out:
-	nftnl_table_free(t);
-err:
-	return MNL_CB_OK;
-}
-
 static struct nftnl_table_list *nftnl_table_list_get(struct nft_handle *h)
 {
-	char buf[16536];
-	struct nlmsghdr *nlh;
-	struct nftnl_table_list *list;
-	int ret;
-
-retry:
-	list = nftnl_table_list_alloc();
-	if (list == NULL)
-		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, list);
-	if (ret < 0 && errno == EINTR) {
-		assert(nft_restart(h) >= 0);
-		nftnl_table_list_free(list);
-		goto retry;
-	}
+	nft_build_cache(h);
 
-	return list;
+	return h->cache->tables;
 }
 
 bool nft_table_find(struct nft_handle *h, const char *tablename)
 {
-	struct nftnl_table_list *list;
 	struct nftnl_table_list_iter *iter;
+	struct nftnl_table_list *list;
 	struct nftnl_table *t;
 	bool ret = false;
 
@@ -2043,7 +2058,6 @@ bool nft_table_find(struct nft_handle *h, const char *tablename)
 	}
 
 	nftnl_table_list_iter_destroy(iter);
-	nftnl_table_list_free(list);
 
 err:
 	return ret;
@@ -2076,7 +2090,6 @@ int nft_for_each_table(struct nft_handle *h,
 	}
 
 	nftnl_table_list_iter_destroy(iter);
-	nftnl_table_list_free(list);
 	return 0;
 }
 
@@ -2148,7 +2161,6 @@ int nft_table_flush(struct nft_handle *h, const char *table)
 	ret = __nft_table_flush(h, table, exists);
 	nftnl_table_list_iter_destroy(iter);
 err_table_list:
-	nftnl_table_list_free(list);
 err_out:
 	/* the core expects 1 for success and 0 for error */
 	return ret == 0 ? 1 : 0;
diff --git a/iptables/nft.h b/iptables/nft.h
index c137c5c6708d..dc0797d302b8 100644
--- a/iptables/nft.h
+++ b/iptables/nft.h
@@ -28,6 +28,7 @@ struct builtin_table {
 };
 
 struct nft_cache {
+	struct nftnl_table_list		*tables;
 	struct {
 		struct nftnl_chain_list *chains;
 		bool			initialized;
-- 
2.11.0




[Index of Archives]     [Netfitler Users]     [Berkeley Packet Filter]     [LARTC]     [Bugtraq]     [Yosemite Forum]

  Powered by Linux