summaryrefslogtreecommitdiffstats
path: root/iptables
diff options
context:
space:
mode:
authorFlorian Westphal <fw@strlen.de>2018-05-24 17:50:25 +0200
committerFlorian Westphal <fw@strlen.de>2018-05-25 12:54:58 +0200
commit03e1377b38af45292a3a55828ee8e7c7e41ae64c (patch)
treefa1c626353884bf4aecc7abad71977b851e233c4 /iptables
parent94fd83d957224eff6043ec6731851dd1a5ae2d4d (diff)
xtables: allow dumping of chains in specific table
This is used by a followup patch to avoid continuing the 'dump everything and then ignore what we don't need' model. Places that know they only need a particular table 'iptables-save -t filter' can ask the kernel to limit this for us. Signed-off-by: Florian Westphal <fw@strlen.de>
Diffstat (limited to 'iptables')
-rw-r--r--iptables/nft.c32
-rw-r--r--iptables/nft.h2
-rw-r--r--iptables/xtables-restore.c2
-rw-r--r--iptables/xtables-save.c2
4 files changed, 24 insertions, 14 deletions
diff --git a/iptables/nft.c b/iptables/nft.c
index 240e77bb..5204112c 100644
--- a/iptables/nft.c
+++ b/iptables/nft.c
@@ -617,7 +617,7 @@ static void nft_chain_builtin_init(struct nft_handle *h,
struct builtin_table *table)
{
int i;
- struct nftnl_chain_list *list = nft_chain_dump(h);
+ struct nftnl_chain_list *list = nft_chain_dump(h, NULL);
struct nftnl_chain *c;
/* Initialize built-in chains if they don't exist yet */
@@ -1109,7 +1109,8 @@ err:
return MNL_CB_OK;
}
-static struct nftnl_chain_list *nftnl_chain_list_get(struct nft_handle *h)
+static struct nftnl_chain_list *nftnl_chain_list_get(struct nft_handle *h,
+ const char *tablename)
{
char buf[16536];
struct nlmsghdr *nlh;
@@ -1125,6 +1126,15 @@ retry:
nlh = nftnl_chain_nlmsg_build_hdr(buf, NFT_MSG_GETCHAIN, h->family,
NLM_F_DUMP, h->seq);
+ if (tablename) {
+ struct nftnl_chain *t = nftnl_chain_alloc();
+
+ if (t) {
+ nftnl_chain_set(t, NFTNL_CHAIN_TABLE, tablename);
+ nftnl_chain_nlmsg_build_payload(nlh, t);
+ nftnl_chain_free(t);
+ }
+ }
ret = mnl_talk(h, nlh, nftnl_chain_list_cb, list);
if (ret < 0 && errno == EINTR) {
@@ -1136,9 +1146,9 @@ retry:
return list;
}
-struct nftnl_chain_list *nft_chain_dump(struct nft_handle *h)
+struct nftnl_chain_list *nft_chain_dump(struct nft_handle *h, const char *tablename)
{
- return nftnl_chain_list_get(h);
+ return nftnl_chain_list_get(h, tablename);
}
static const char *policy_name[NF_ACCEPT+1] = {
@@ -1365,7 +1375,7 @@ int nft_rule_flush(struct nft_handle *h, const char *chain, const char *table)
nft_fn = nft_rule_flush;
- list = nftnl_chain_list_get(h);
+ list = nftnl_chain_list_get(h, table);
if (list == NULL) {
ret = 0;
goto err;
@@ -1444,7 +1454,7 @@ int nft_chain_user_del(struct nft_handle *h, const char *chain, const char *tabl
nft_fn = nft_chain_user_del;
- list = nftnl_chain_list_get(h);
+ list = nftnl_chain_list_get(h, table);
if (list == NULL)
goto err;
@@ -1533,7 +1543,7 @@ nft_chain_find(struct nft_handle *h, const char *table, const char *chain)
{
struct nftnl_chain_list *list;
- list = nftnl_chain_list_get(h);
+ list = nftnl_chain_list_get(h, table);
if (list == NULL)
return NULL;
@@ -2065,7 +2075,7 @@ int nft_rule_list(struct nft_handle *h, const char *chain, const char *table,
return 1;
}
- list = nft_chain_dump(h);
+ list = nft_chain_dump(h, table);
iter = nftnl_chain_list_iter_create(list);
if (iter == NULL)
@@ -2189,7 +2199,7 @@ int nft_rule_list_save(struct nft_handle *h, const char *chain,
struct nftnl_chain *c;
int ret = 1;
- list = nft_chain_dump(h);
+ list = nft_chain_dump(h, table);
/* Dump policies and custom chains first */
if (!rulenum)
@@ -2656,7 +2666,7 @@ int nft_chain_zero_counters(struct nft_handle *h, const char *chain,
struct nftnl_chain *c;
int ret = 0;
- list = nftnl_chain_list_get(h);
+ list = nftnl_chain_list_get(h, table);
if (list == NULL)
goto err;
@@ -2801,7 +2811,7 @@ static int nft_are_chains_compatible(struct nft_handle *h)
struct nftnl_chain *chain;
int ret = 0;
- list = nftnl_chain_list_get(h);
+ list = nftnl_chain_list_get(h, NULL);
if (list == NULL)
return -1;
diff --git a/iptables/nft.h b/iptables/nft.h
index 0c4beb99..af229233 100644
--- a/iptables/nft.h
+++ b/iptables/nft.h
@@ -66,7 +66,7 @@ int nft_table_flush(struct nft_handle *h, const char *table);
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_dump(struct nft_handle *h);
+struct nftnl_chain_list *nft_chain_dump(struct nft_handle *h, const char *table);
struct nftnl_chain *nft_chain_list_find(struct nftnl_chain_list *list, const char *table, const char *chain);
int nft_chain_save(struct nft_handle *h, struct nftnl_chain_list *list, const char *table);
int nft_chain_user_add(struct nft_handle *h, const char *chain, const char *table);
diff --git a/iptables/xtables-restore.c b/iptables/xtables-restore.c
index 2ba0565d..d977dabf 100644
--- a/iptables/xtables-restore.c
+++ b/iptables/xtables-restore.c
@@ -169,7 +169,7 @@ static struct nftnl_chain_list *get_chain_list(struct nft_handle *h)
{
struct nftnl_chain_list *chain_list;
- chain_list = nft_chain_dump(h);
+ chain_list = nft_chain_dump(h, NULL);
if (chain_list == NULL)
xtables_error(OTHER_PROBLEM, "cannot retrieve chain list\n");
diff --git a/iptables/xtables-save.c b/iptables/xtables-save.c
index 1f643593..2305e878 100644
--- a/iptables/xtables-save.c
+++ b/iptables/xtables-save.c
@@ -57,7 +57,7 @@ do_output(struct nft_handle *h, const char *tablename, bool counters)
return 0;
}
- chain_list = nft_chain_dump(h);
+ chain_list = nft_chain_dump(h, tablename);
time_t now = time(NULL);