From 03e1377b38af45292a3a55828ee8e7c7e41ae64c Mon Sep 17 00:00:00 2001 From: Florian Westphal Date: Thu, 24 May 2018 17:50:25 +0200 Subject: 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 --- iptables/nft.c | 32 +++++++++++++++++++++----------- iptables/nft.h | 2 +- iptables/xtables-restore.c | 2 +- iptables/xtables-save.c | 2 +- 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); -- cgit v1.2.3