summaryrefslogtreecommitdiffstats
path: root/iptables
diff options
context:
space:
mode:
authorPhil Sutter <phil@nwl.cc>2019-10-01 15:09:55 +0200
committerPhil Sutter <phil@nwl.cc>2019-10-10 23:52:04 +0200
commitd812b91bc6e010dcdd4ed039c3979a02fb57eb1c (patch)
treeafc123ecee19bcdaa920cb95862432bf48e4deb7 /iptables
parent97fbef55d1e89ca73bf1e6b31ac46d756ac499f1 (diff)
nft: Extract cache routines into nft-cache.c
The amount of code dealing with caching only is considerable and hence deserves an own source file. Signed-off-by: Phil Sutter <phil@nwl.cc> Acked-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'iptables')
-rw-r--r--iptables/Makefile.am2
-rw-r--r--iptables/nft-cache.c376
-rw-r--r--iptables/nft-cache.h17
-rw-r--r--iptables/nft.c360
-rw-r--r--iptables/nft.h8
-rw-r--r--iptables/xtables-restore.c1
-rw-r--r--iptables/xtables-save.c1
7 files changed, 404 insertions, 361 deletions
diff --git a/iptables/Makefile.am b/iptables/Makefile.am
index 21ac7f08..fc834e0f 100644
--- a/iptables/Makefile.am
+++ b/iptables/Makefile.am
@@ -36,7 +36,7 @@ xtables_nft_multi_CFLAGS += -DENABLE_NFTABLES -DENABLE_IPV4 -DENABLE_IPV6
xtables_nft_multi_SOURCES += xtables-save.c xtables-restore.c \
xtables-standalone.c xtables.c nft.c \
nft-shared.c nft-ipv4.c nft-ipv6.c nft-arp.c \
- xtables-monitor.c \
+ xtables-monitor.c nft-cache.c \
xtables-arp-standalone.c xtables-arp.c \
nft-bridge.c \
xtables-eb-standalone.c xtables-eb.c \
diff --git a/iptables/nft-cache.c b/iptables/nft-cache.c
new file mode 100644
index 00000000..5444419a
--- /dev/null
+++ b/iptables/nft-cache.c
@@ -0,0 +1,376 @@
+/*
+ * (C) 2012 by Pablo Neira Ayuso <pablo@netfilter.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This code has been sponsored by Sophos Astaro <http://www.sophos.com>
+ */
+
+#include <assert.h>
+#include <errno.h>
+#include <xtables.h>
+
+#include <linux/netfilter/nf_tables.h>
+
+#include <libmnl/libmnl.h>
+#include <libnftnl/gen.h>
+#include <libnftnl/table.h>
+
+#include "nft.h"
+#include "nft-cache.h"
+
+static int genid_cb(const struct nlmsghdr *nlh, void *data)
+{
+ uint32_t *genid = data;
+ struct nftnl_gen *gen;
+
+ gen = nftnl_gen_alloc();
+ if (!gen)
+ return MNL_CB_ERROR;
+
+ if (nftnl_gen_nlmsg_parse(nlh, gen) < 0)
+ goto out;
+
+ *genid = nftnl_gen_get_u32(gen, NFTNL_GEN_ID);
+
+ nftnl_gen_free(gen);
+ return MNL_CB_STOP;
+out:
+ nftnl_gen_free(gen);
+ return MNL_CB_ERROR;
+}
+
+static void mnl_genid_get(struct nft_handle *h, uint32_t *genid)
+{
+ char buf[MNL_SOCKET_BUFFER_SIZE];
+ struct nlmsghdr *nlh;
+ int ret;
+
+ nlh = nftnl_nlmsg_build_hdr(buf, NFT_MSG_GETGEN, 0, 0, h->seq);
+ ret = mnl_talk(h, nlh, genid_cb, genid);
+ if (ret == 0)
+ return;
+
+ xtables_error(RESOURCE_PROBLEM,
+ "Could not fetch rule set generation id: %s\n", nft_strerror(errno));
+}
+
+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;
+
+ 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);
+
+ h->cache->tables = list;
+
+ return 1;
+}
+
+static int nftnl_chain_list_cb(const struct nlmsghdr *nlh, void *data)
+{
+ struct nft_handle *h = data;
+ const struct builtin_table *t;
+ struct nftnl_chain *c;
+
+ c = nftnl_chain_alloc();
+ if (c == NULL)
+ goto err;
+
+ if (nftnl_chain_nlmsg_parse(nlh, c) < 0)
+ goto out;
+
+ t = nft_table_builtin_find(h,
+ nftnl_chain_get_str(c, NFTNL_CHAIN_TABLE));
+ if (!t)
+ goto out;
+
+ nftnl_chain_list_add_tail(c, h->cache->table[t->type].chains);
+
+ return MNL_CB_OK;
+out:
+ nftnl_chain_free(c);
+err:
+ return MNL_CB_OK;
+}
+
+static int fetch_chain_cache(struct nft_handle *h)
+{
+ char buf[16536];
+ struct nlmsghdr *nlh;
+ int i, ret;
+
+ for (i = 0; i < NFT_TABLE_MAX; i++) {
+ enum nft_table_type type = h->tables[i].type;
+
+ if (!h->tables[i].name)
+ continue;
+
+ h->cache->table[type].chains = nftnl_chain_list_alloc();
+ if (!h->cache->table[type].chains)
+ return -1;
+ }
+
+ nlh = nftnl_chain_nlmsg_build_hdr(buf, NFT_MSG_GETCHAIN, h->family,
+ NLM_F_DUMP, h->seq);
+
+ ret = mnl_talk(h, nlh, nftnl_chain_list_cb, h);
+ if (ret < 0 && errno == EINTR)
+ assert(nft_restart(h) >= 0);
+
+ return ret;
+}
+
+static int nftnl_rule_list_cb(const struct nlmsghdr *nlh, void *data)
+{
+ struct nftnl_chain *c = data;
+ struct nftnl_rule *r;
+
+ r = nftnl_rule_alloc();
+ if (r == NULL)
+ return MNL_CB_OK;
+
+ if (nftnl_rule_nlmsg_parse(nlh, r) < 0) {
+ nftnl_rule_free(r);
+ return MNL_CB_OK;
+ }
+
+ nftnl_chain_rule_add_tail(r, c);
+ return MNL_CB_OK;
+}
+
+static int nft_rule_list_update(struct nftnl_chain *c, void *data)
+{
+ struct nft_handle *h = data;
+ char buf[16536];
+ struct nlmsghdr *nlh;
+ struct nftnl_rule *rule;
+ int ret;
+
+ rule = nftnl_rule_alloc();
+ if (!rule)
+ return -1;
+
+ nftnl_rule_set_str(rule, NFTNL_RULE_TABLE,
+ nftnl_chain_get_str(c, NFTNL_CHAIN_TABLE));
+ nftnl_rule_set_str(rule, NFTNL_RULE_CHAIN,
+ nftnl_chain_get_str(c, NFTNL_CHAIN_NAME));
+
+ nlh = nftnl_rule_nlmsg_build_hdr(buf, NFT_MSG_GETRULE, h->family,
+ NLM_F_DUMP, h->seq);
+ nftnl_rule_nlmsg_build_payload(nlh, rule);
+
+ ret = mnl_talk(h, nlh, nftnl_rule_list_cb, c);
+ if (ret < 0 && errno == EINTR)
+ assert(nft_restart(h) >= 0);
+
+ nftnl_rule_free(rule);
+
+ if (h->family == NFPROTO_BRIDGE)
+ nft_bridge_chain_postprocess(h, c);
+
+ return 0;
+}
+
+static int fetch_rule_cache(struct nft_handle *h)
+{
+ int i;
+
+ for (i = 0; i < NFT_TABLE_MAX; i++) {
+ enum nft_table_type type = h->tables[i].type;
+
+ if (!h->tables[i].name)
+ continue;
+
+ if (nftnl_chain_list_foreach(h->cache->table[type].chains,
+ nft_rule_list_update, h))
+ return -1;
+ }
+ return 0;
+}
+
+static void __nft_build_cache(struct nft_handle *h)
+{
+ uint32_t genid_start, genid_stop;
+
+retry:
+ mnl_genid_get(h, &genid_start);
+ fetch_table_cache(h);
+ fetch_chain_cache(h);
+ fetch_rule_cache(h);
+ h->have_cache = true;
+ mnl_genid_get(h, &genid_stop);
+
+ if (genid_start != genid_stop) {
+ flush_chain_cache(h, NULL);
+ goto retry;
+ }
+
+ h->nft_genid = genid_start;
+}
+
+void nft_build_cache(struct nft_handle *h)
+{
+ if (!h->have_cache)
+ __nft_build_cache(h);
+}
+
+void nft_fake_cache(struct nft_handle *h)
+{
+ int i;
+
+ fetch_table_cache(h);
+ for (i = 0; i < NFT_TABLE_MAX; i++) {
+ enum nft_table_type type = h->tables[i].type;
+
+ if (!h->tables[i].name)
+ continue;
+
+ h->cache->table[type].chains = nftnl_chain_list_alloc();
+ }
+ h->have_cache = true;
+ mnl_genid_get(h, &h->nft_genid);
+}
+
+static void __nft_flush_cache(struct nft_handle *h)
+{
+ if (!h->cache_index) {
+ h->cache_index++;
+ h->cache = &h->__cache[h->cache_index];
+ } else {
+ flush_chain_cache(h, NULL);
+ }
+}
+
+static int __flush_rule_cache(struct nftnl_rule *r, void *data)
+{
+ nftnl_rule_list_del(r);
+ nftnl_rule_free(r);
+
+ return 0;
+}
+
+void flush_rule_cache(struct nftnl_chain *c)
+{
+ nftnl_rule_foreach(c, __flush_rule_cache, NULL);
+}
+
+static int __flush_chain_cache(struct nftnl_chain *c, void *data)
+{
+ nftnl_chain_list_del(c);
+ nftnl_chain_free(c);
+
+ return 0;
+}
+
+static int flush_cache(struct nft_handle *h, struct nft_cache *c,
+ const char *tablename)
+{
+ const struct builtin_table *table;
+ int i;
+
+ if (tablename) {
+ table = nft_table_builtin_find(h, tablename);
+ if (!table || !c->table[table->type].chains)
+ return 0;
+ nftnl_chain_list_foreach(c->table[table->type].chains,
+ __flush_chain_cache, NULL);
+ return 0;
+ }
+
+ for (i = 0; i < NFT_TABLE_MAX; i++) {
+ if (h->tables[i].name == NULL)
+ continue;
+
+ if (!c->table[i].chains)
+ continue;
+
+ nftnl_chain_list_free(c->table[i].chains);
+ c->table[i].chains = NULL;
+ }
+ nftnl_table_list_free(c->tables);
+ c->tables = NULL;
+
+ return 1;
+}
+
+void flush_chain_cache(struct nft_handle *h, const char *tablename)
+{
+ if (!h->have_cache)
+ return;
+
+ if (flush_cache(h, h->cache, tablename))
+ h->have_cache = false;
+}
+
+void nft_rebuild_cache(struct nft_handle *h)
+{
+ if (h->have_cache)
+ __nft_flush_cache(h);
+
+ __nft_build_cache(h);
+}
+
+void nft_release_cache(struct nft_handle *h)
+{
+ if (h->cache_index)
+ flush_cache(h, &h->__cache[0], NULL);
+}
+
+struct nftnl_table_list *nftnl_table_list_get(struct nft_handle *h)
+{
+ if (!h->cache->tables)
+ fetch_table_cache(h);
+
+ return h->cache->tables;
+}
+
+struct nftnl_chain_list *nft_chain_list_get(struct nft_handle *h,
+ const char *table)
+{
+ const struct builtin_table *t;
+
+ t = nft_table_builtin_find(h, table);
+ if (!t)
+ return NULL;
+
+ nft_build_cache(h);
+
+ return h->cache->table[t->type].chains;
+}
+
diff --git a/iptables/nft-cache.h b/iptables/nft-cache.h
new file mode 100644
index 00000000..423c6516
--- /dev/null
+++ b/iptables/nft-cache.h
@@ -0,0 +1,17 @@
+#ifndef _NFT_CACHE_H_
+#define _NFT_CACHE_H_
+
+struct nft_handle;
+
+void nft_fake_cache(struct nft_handle *h);
+void nft_build_cache(struct nft_handle *h);
+void nft_rebuild_cache(struct nft_handle *h);
+void nft_release_cache(struct nft_handle *h);
+void flush_chain_cache(struct nft_handle *h, const char *tablename);
+void flush_rule_cache(struct nftnl_chain *c);
+
+struct nftnl_chain_list *nft_chain_list_get(struct nft_handle *h,
+ const char *table);
+struct nftnl_table_list *nftnl_table_list_get(struct nft_handle *h);
+
+#endif /* _NFT_CACHE_H_ */
diff --git a/iptables/nft.c b/iptables/nft.c
index 3228842c..81de10d8 100644
--- a/iptables/nft.c
+++ b/iptables/nft.c
@@ -55,47 +55,12 @@
#include "nft.h"
#include "xshared.h" /* proto_to_name */
+#include "nft-cache.h"
#include "nft-shared.h"
#include "nft-bridge.h" /* EBT_NOPROTO */
static void *nft_fn;
-static int genid_cb(const struct nlmsghdr *nlh, void *data)
-{
- uint32_t *genid = data;
- struct nftnl_gen *gen;
-
- gen = nftnl_gen_alloc();
- if (!gen)
- return MNL_CB_ERROR;
-
- if (nftnl_gen_nlmsg_parse(nlh, gen) < 0)
- goto out;
-
- *genid = nftnl_gen_get_u32(gen, NFTNL_GEN_ID);
-
- nftnl_gen_free(gen);
- return MNL_CB_STOP;
-out:
- nftnl_gen_free(gen);
- return MNL_CB_ERROR;
-}
-
-static void mnl_genid_get(struct nft_handle *h, uint32_t *genid)
-{
- char buf[MNL_SOCKET_BUFFER_SIZE];
- struct nlmsghdr *nlh;
- int ret;
-
- nlh = nftnl_nlmsg_build_hdr(buf, NFT_MSG_GETGEN, 0, 0, h->seq);
- ret = mnl_talk(h, nlh, genid_cb, genid);
- if (ret == 0)
- return;
-
- xtables_error(RESOURCE_PROBLEM,
- "Could not fetch rule set generation id: %s\n", nft_strerror(errno));
-}
-
int mnl_talk(struct nft_handle *h, struct nlmsghdr *nlh,
int (*cb)(const struct nlmsghdr *nlh, void *data),
void *data)
@@ -791,7 +756,7 @@ static bool nft_chain_builtin(struct nftnl_chain *c)
return nftnl_chain_get(c, NFTNL_CHAIN_HOOKNUM) != NULL;
}
-static int nft_restart(struct nft_handle *h)
+int nft_restart(struct nft_handle *h)
{
mnl_socket_close(h->nl);
@@ -830,67 +795,6 @@ int nft_init(struct nft_handle *h, const struct builtin_table *t)
return 0;
}
-static int __flush_rule_cache(struct nftnl_rule *r, void *data)
-{
- nftnl_rule_list_del(r);
- nftnl_rule_free(r);
-
- return 0;
-}
-
-static void flush_rule_cache(struct nftnl_chain *c)
-{
- nftnl_rule_foreach(c, __flush_rule_cache, NULL);
-}
-
-static int __flush_chain_cache(struct nftnl_chain *c, void *data)
-{
- nftnl_chain_list_del(c);
- nftnl_chain_free(c);
-
- return 0;
-}
-
-static int flush_cache(struct nft_handle *h, struct nft_cache *c,
- const char *tablename)
-{
- const struct builtin_table *table;
- int i;
-
- if (tablename) {
- table = nft_table_builtin_find(h, tablename);
- if (!table || !c->table[table->type].chains)
- return 0;
- nftnl_chain_list_foreach(c->table[table->type].chains,
- __flush_chain_cache, NULL);
- return 0;
- }
-
- for (i = 0; i < NFT_TABLE_MAX; i++) {
- if (h->tables[i].name == NULL)
- continue;
-
- if (!c->table[i].chains)
- continue;
-
- 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, h->cache, tablename))
- h->have_cache = false;
-}
-
void nft_fini(struct nft_handle *h)
{
flush_chain_cache(h, NULL);
@@ -1337,104 +1241,6 @@ nft_rule_print_save(const struct nftnl_rule *r, enum nft_rule_print type,
ops->clear_cs(&cs);
}
-static int nftnl_chain_list_cb(const struct nlmsghdr *nlh, void *data)
-{
- struct nft_handle *h = data;
- const struct builtin_table *t;
- struct nftnl_chain *c;
-
- c = nftnl_chain_alloc();
- if (c == NULL)
- goto err;
-
- if (nftnl_chain_nlmsg_parse(nlh, c) < 0)
- goto out;
-
- t = nft_table_builtin_find(h,
- nftnl_chain_get_str(c, NFTNL_CHAIN_TABLE));
- if (!t)
- goto out;
-
- nftnl_chain_list_add_tail(c, h->cache->table[t->type].chains);
-
- return MNL_CB_OK;
-out:
- nftnl_chain_free(c);
-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;
-
- 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);
-
- h->cache->tables = list;
-
- return 1;
-}
-
-static int fetch_chain_cache(struct nft_handle *h)
-{
- char buf[16536];
- struct nlmsghdr *nlh;
- int i, ret;
-
- for (i = 0; i < NFT_TABLE_MAX; i++) {
- enum nft_table_type type = h->tables[i].type;
-
- if (!h->tables[i].name)
- continue;
-
- h->cache->table[type].chains = nftnl_chain_list_alloc();
- if (!h->cache->table[type].chains)
- return -1;
- }
-
- nlh = nftnl_chain_nlmsg_build_hdr(buf, NFT_MSG_GETCHAIN, h->family,
- NLM_F_DUMP, h->seq);
-
- ret = mnl_talk(h, nlh, nftnl_chain_list_cb, h);
- if (ret < 0 && errno == EINTR)
- assert(nft_restart(h) >= 0);
-
- return ret;
-}
-
static bool nft_rule_is_policy_rule(struct nftnl_rule *r)
{
const struct nftnl_udata *tb[UDATA_TYPE_MAX + 1] = {};
@@ -1473,8 +1279,8 @@ static struct nftnl_rule *nft_chain_last_rule(struct nftnl_chain *c)
return last;
}
-static void nft_bridge_chain_postprocess(struct nft_handle *h,
- struct nftnl_chain *c)
+void nft_bridge_chain_postprocess(struct nft_handle *h,
+ struct nftnl_chain *c)
{
struct nftnl_rule *last = nft_chain_last_rule(c);
struct nftnl_expr_iter *iter;
@@ -1515,156 +1321,6 @@ static void nft_bridge_chain_postprocess(struct nft_handle *h,
out_iter:
nftnl_expr_iter_destroy(iter);
}
-
-static int nftnl_rule_list_cb(const struct nlmsghdr *nlh, void *data)
-{
- struct nftnl_chain *c = data;
- struct nftnl_rule *r;
-
- r = nftnl_rule_alloc();
- if (r == NULL)
- return MNL_CB_OK;
-
- if (nftnl_rule_nlmsg_parse(nlh, r) < 0) {
- nftnl_rule_free(r);
- return MNL_CB_OK;
- }
-
- nftnl_chain_rule_add_tail(r, c);
- return MNL_CB_OK;
-}
-
-static int nft_rule_list_update(struct nftnl_chain *c, void *data)
-{
- struct nft_handle *h = data;
- char buf[16536];
- struct nlmsghdr *nlh;
- struct nftnl_rule *rule;
- int ret;
-
- rule = nftnl_rule_alloc();
- if (!rule)
- return -1;
-
- nftnl_rule_set_str(rule, NFTNL_RULE_TABLE,
- nftnl_chain_get_str(c, NFTNL_CHAIN_TABLE));
- nftnl_rule_set_str(rule, NFTNL_RULE_CHAIN,
- nftnl_chain_get_str(c, NFTNL_CHAIN_NAME));
-
- nlh = nftnl_rule_nlmsg_build_hdr(buf, NFT_MSG_GETRULE, h->family,
- NLM_F_DUMP, h->seq);
- nftnl_rule_nlmsg_build_payload(nlh, rule);
-
- ret = mnl_talk(h, nlh, nftnl_rule_list_cb, c);
- if (ret < 0 && errno == EINTR)
- assert(nft_restart(h) >= 0);
-
- nftnl_rule_free(rule);
-
- if (h->family == NFPROTO_BRIDGE)
- nft_bridge_chain_postprocess(h, c);
-
- return 0;
-}
-
-static int fetch_rule_cache(struct nft_handle *h)
-{
- int i;
-
- for (i = 0; i < NFT_TABLE_MAX; i++) {
- enum nft_table_type type = h->tables[i].type;
-
- if (!h->tables[i].name)
- continue;
-
- if (nftnl_chain_list_foreach(h->cache->table[type].chains,
- nft_rule_list_update, h))
- return -1;
- }
- return 0;
-}
-
-static void __nft_build_cache(struct nft_handle *h)
-{
- uint32_t genid_start, genid_stop;
-
-retry:
- mnl_genid_get(h, &genid_start);
- fetch_table_cache(h);
- fetch_chain_cache(h);
- fetch_rule_cache(h);
- h->have_cache = true;
- mnl_genid_get(h, &genid_stop);
-
- if (genid_start != genid_stop) {
- flush_chain_cache(h, NULL);
- goto retry;
- }
-
- h->nft_genid = genid_start;
-}
-
-void nft_fake_cache(struct nft_handle *h)
-{
- int i;
-
- fetch_table_cache(h);
- for (i = 0; i < NFT_TABLE_MAX; i++) {
- enum nft_table_type type = h->tables[i].type;
-
- if (!h->tables[i].name)
- continue;
-
- h->cache->table[type].chains = nftnl_chain_list_alloc();
- }
- h->have_cache = true;
- mnl_genid_get(h, &h->nft_genid);
-}
-
-void nft_build_cache(struct nft_handle *h)
-{
- if (!h->have_cache)
- __nft_build_cache(h);
-}
-
-static void __nft_flush_cache(struct nft_handle *h)
-{
- if (!h->cache_index) {
- h->cache_index++;
- h->cache = &h->__cache[h->cache_index];
- } else {
- flush_chain_cache(h, NULL);
- }
-}
-
-static void nft_rebuild_cache(struct nft_handle *h)
-{
- if (h->have_cache)
- __nft_flush_cache(h);
-
- __nft_build_cache(h);
-}
-
-static void nft_release_cache(struct nft_handle *h)
-{
- if (h->cache_index)
- flush_cache(h, &h->__cache[0], NULL);
-}
-
-struct nftnl_chain_list *nft_chain_list_get(struct nft_handle *h,
- const char *table)
-{
- const struct builtin_table *t;
-
- t = nft_table_builtin_find(h, table);
- if (!t)
- return NULL;
-
- nft_build_cache(h);
-
- return h->cache->table[t->type].chains;
-}
-
static const char *policy_name[NF_ACCEPT+1] = {
[NF_DROP] = "DROP",
[NF_ACCEPT] = "ACCEPT",
@@ -2054,14 +1710,6 @@ int nft_chain_user_rename(struct nft_handle *h,const char *chain,
return ret == 0 ? 1 : 0;
}
-static struct nftnl_table_list *nftnl_table_list_get(struct nft_handle *h)
-{
- if (!h->cache->tables)
- fetch_table_cache(h);
-
- return h->cache->tables;
-}
-
bool nft_table_find(struct nft_handle *h, const char *tablename)
{
struct nftnl_table_list_iter *iter;
diff --git a/iptables/nft.h b/iptables/nft.h
index bcac8e22..451c2660 100644
--- a/iptables/nft.h
+++ b/iptables/nft.h
@@ -73,8 +73,7 @@ int mnl_talk(struct nft_handle *h, struct nlmsghdr *nlh,
void *data);
int nft_init(struct nft_handle *h, const struct builtin_table *t);
void nft_fini(struct nft_handle *h);
-void nft_fake_cache(struct nft_handle *h);
-void nft_build_cache(struct nft_handle *h);
+int nft_restart(struct nft_handle *h);
/*
* Operations with tables.
@@ -95,8 +94,6 @@ const struct builtin_table *nft_table_builtin_find(struct nft_handle *h, const c
struct nftnl_chain;
int nft_chain_set(struct nft_handle *h, const char *table, const char *chain, const char *policy, const struct xt_counters *counters);
-struct nftnl_chain_list *nft_chain_list_get(struct nft_handle *h,
- const char *table);
int nft_chain_save(struct nft_handle *h, struct nftnl_chain_list *list);
int nft_chain_user_add(struct nft_handle *h, const char *chain, const char *table);
int nft_chain_user_del(struct nft_handle *h, const char *chain, const char *table, bool verbose);
@@ -105,6 +102,9 @@ int nft_chain_user_rename(struct nft_handle *h, const char *chain, const char *t
int nft_chain_zero_counters(struct nft_handle *h, const char *chain, const char *table, bool verbose);
const struct builtin_chain *nft_chain_builtin_find(const struct builtin_table *t, const char *chain);
bool nft_chain_exists(struct nft_handle *h, const char *table, const char *chain);
+void nft_bridge_chain_postprocess(struct nft_handle *h,
+ struct nftnl_chain *c);
+
/*
* Operations with rule-set.
diff --git a/iptables/xtables-restore.c b/iptables/xtables-restore.c
index 7f28a05c..7641955d 100644
--- a/iptables/xtables-restore.c
+++ b/iptables/xtables-restore.c
@@ -18,6 +18,7 @@
#include "xtables-multi.h"
#include "nft.h"
#include "nft-bridge.h"
+#include "nft-cache.h"
#include <libnftnl/chain.h>
static int counters, verbose;
diff --git a/iptables/xtables-save.c b/iptables/xtables-save.c
index 77b13f7f..3741888f 100644
--- a/iptables/xtables-save.c
+++ b/iptables/xtables-save.c
@@ -21,6 +21,7 @@
#include "iptables.h"
#include "xtables-multi.h"
#include "nft.h"
+#include "nft-cache.h"
#include <libnftnl/chain.h>