From 11cbd7291f37fbfd5ebe6ffa1730f7d198ed2ac0 Mon Sep 17 00:00:00 2001 From: Phil Sutter Date: Thu, 20 Dec 2018 16:09:18 +0100 Subject: xtables: Optimize list command with given chain Make use of nftnl_chain_list_lookup_byname() even if not listing a specific rule. Introduce __nft_print_header() to consolidate chain value extraction for printing with ops->print_header(). Signed-off-by: Phil Sutter Signed-off-by: Pablo Neira Ayuso --- iptables/nft.c | 78 ++++++++++++++++++++++++---------------------------------- 1 file changed, 32 insertions(+), 46 deletions(-) diff --git a/iptables/nft.c b/iptables/nft.c index 162d91e8..e1c99783 100644 --- a/iptables/nft.c +++ b/iptables/nft.c @@ -2247,6 +2247,24 @@ static int nft_rule_count(struct nft_handle *h, struct nftnl_chain *c) return rule_ctr; } +static void __nft_print_header(struct nft_handle *h, + const struct nft_family_ops *ops, + struct nftnl_chain *c, unsigned int format) +{ + const char *chain_name = nftnl_chain_get_str(c, NFTNL_CHAIN_NAME); + uint32_t policy = nftnl_chain_get_u32(c, NFTNL_CHAIN_POLICY); + bool basechain = !!nftnl_chain_get(c, NFTNL_CHAIN_HOOKNUM); + uint32_t refs = nftnl_chain_get_u32(c, NFTNL_CHAIN_USE); + uint32_t entries = nft_rule_count(h, c); + struct xt_counters ctrs = { + .pcnt = nftnl_chain_get_u64(c, NFTNL_CHAIN_PACKETS), + .bcnt = nftnl_chain_get_u64(c, NFTNL_CHAIN_BYTES), + }; + + ops->print_header(format, chain_name, policy_name[policy], + &ctrs, basechain, refs - entries, entries); +} + int nft_rule_list(struct nft_handle *h, const char *chain, const char *table, int rulenum, unsigned int format) { @@ -2275,75 +2293,43 @@ int nft_rule_list(struct nft_handle *h, const char *chain, const char *table, return 0; } - if (chain && rulenum) { - c = nft_chain_find(h, table, chain); + list = nft_chain_list_get(h, table); + if (!list) + return 0; + + if (chain) { + c = nftnl_chain_list_lookup_byname(list, chain); if (!c) return 0; + if (!rulenum) { + if (ops->print_table_header) + ops->print_table_header(table); + __nft_print_header(h, ops, c, format); + } __nft_rule_list(h, c, rulenum, format, ops->print_rule); return 1; } - list = nft_chain_list_get(h, table); - if (!list) - return 0; - iter = nftnl_chain_list_iter_create(list); if (iter == NULL) - goto err; + return 0; - if (!chain && ops->print_table_header) + if (ops->print_table_header) ops->print_table_header(table); c = nftnl_chain_list_iter_next(iter); while (c != NULL) { - const char *chain_name = - nftnl_chain_get_str(c, NFTNL_CHAIN_NAME); - uint32_t policy = - nftnl_chain_get_u32(c, NFTNL_CHAIN_POLICY); - uint32_t refs = - nftnl_chain_get_u32(c, NFTNL_CHAIN_USE); - struct xt_counters ctrs = { - .pcnt = nftnl_chain_get_u64(c, NFTNL_CHAIN_PACKETS), - .bcnt = nftnl_chain_get_u64(c, NFTNL_CHAIN_BYTES), - }; - bool basechain = false; - uint32_t entries; - - if (nftnl_chain_get(c, NFTNL_CHAIN_HOOKNUM)) - basechain = true; - - if (chain) { - if (strcmp(chain, chain_name) != 0) - goto next; - else if (ops->print_table_header) - ops->print_table_header(table); - } - if (found) printf("\n"); - entries = nft_rule_count(h, c); - ops->print_header(format, chain_name, policy_name[policy], - &ctrs, basechain, refs - entries, entries); - + __nft_print_header(h, ops, c, format); __nft_rule_list(h, c, rulenum, format, ops->print_rule); found = true; - - /* we printed the chain we wanted, stop processing. */ - if (chain) - break; - -next: c = nftnl_chain_list_iter_next(iter); } - nftnl_chain_list_iter_destroy(iter); -err: - if (chain && !found) - return 0; - return 1; } -- cgit v1.2.3