]> git.ipfire.org Git - thirdparty/iptables.git/commitdiff
xtables: Optimize nft_chain_zero_counters()
authorPhil Sutter <phil@nwl.cc>
Thu, 20 Dec 2018 15:09:15 +0000 (16:09 +0100)
committerPablo Neira Ayuso <pablo@netfilter.org>
Thu, 27 Dec 2018 19:42:10 +0000 (20:42 +0100)
If a chain name was given, make use of nftnl_chain_list_lookup_byname().
Streamline nft_chain_zero_rule_counters() to be suitable for calling
from nftnl_chain_list_foreach().

There is an unrelated optimization in here, too: Add batch job
NFT_COMPAT_CHAIN_ZERO only if it is a base chain. Since user-defined
chains don't have counters, there is no need to do anything for them.

Signed-off-by: Phil Sutter <phil@nwl.cc>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
iptables/nft.c

index a23acbcc9b100efd755e124cd88e465023ec3154..9951bf3212197c3ef7ad5bd709a06921a75ada5c 100644 (file)
@@ -2939,15 +2939,36 @@ int nft_xtables_config_load(struct nft_handle *h, const char *filename,
        return h->config_done;
 }
 
-static void nft_chain_zero_rule_counters(struct nft_handle *h,
-                                        struct nftnl_chain *c)
+struct chain_zero_data {
+       struct nft_handle       *handle;
+       bool                    verbose;
+};
+
+static int __nft_chain_zero_counters(struct nftnl_chain *c, void *data)
 {
+       struct chain_zero_data *d = data;
+       struct nft_handle *h = d->handle;
        struct nftnl_rule_iter *iter;
        struct nftnl_rule *r;
+       int ret = 0;
+
+       if (d->verbose)
+               fprintf(stdout, "Zeroing chain `%s'\n",
+                       nftnl_chain_get_str(c, NFTNL_CHAIN_NAME));
+
+       if (nftnl_chain_is_set(c, NFTNL_CHAIN_HOOKNUM)) {
+               /* zero base chain counters. */
+               nftnl_chain_set_u64(c, NFTNL_CHAIN_PACKETS, 0);
+               nftnl_chain_set_u64(c, NFTNL_CHAIN_BYTES, 0);
+               nftnl_chain_unset(c, NFTNL_CHAIN_HANDLE);
+               ret = batch_chain_add(h, NFT_COMPAT_CHAIN_ZERO, c);
+               if (ret)
+                       return -1;
+       }
 
        iter = nftnl_rule_iter_create(c);
        if (iter == NULL)
-               return;
+               return -1;
 
        r = nftnl_rule_iter_next(iter);
        while (r != NULL) {
@@ -2989,13 +3010,17 @@ static void nft_chain_zero_rule_counters(struct nft_handle *h,
        }
 
        nftnl_rule_iter_destroy(iter);
+       return 0;
 }
 
 int nft_chain_zero_counters(struct nft_handle *h, const char *chain,
                            const char *table, bool verbose)
 {
        struct nftnl_chain_list *list;
-       struct nftnl_chain_list_iter *iter;
+       struct chain_zero_data d = {
+               .handle = h,
+               .verbose = verbose,
+       };
        struct nftnl_chain *c;
        int ret = 0;
 
@@ -3003,41 +3028,16 @@ int nft_chain_zero_counters(struct nft_handle *h, const char *chain,
        if (list == NULL)
                goto err;
 
-       iter = nftnl_chain_list_iter_create(list);
-       if (iter == NULL)
-               goto err;
-
-       c = nftnl_chain_list_iter_next(iter);
-       while (c != NULL) {
-               const char *chain_name =
-                       nftnl_chain_get(c, NFTNL_CHAIN_NAME);
-
-               if (chain != NULL && strcmp(chain, chain_name) != 0)
-                       goto next;
-
-               if (verbose)
-                       fprintf(stdout, "Zeroing chain `%s'\n", chain_name);
-
-               if (nftnl_chain_is_set(c, NFTNL_CHAIN_HOOKNUM)) {
-                       /* zero base chain counters. */
-                       nftnl_chain_set_u64(c, NFTNL_CHAIN_PACKETS, 0);
-                       nftnl_chain_set_u64(c, NFTNL_CHAIN_BYTES, 0);
-               }
-
-               nft_chain_zero_rule_counters(h, c);
-
-               nftnl_chain_unset(c, NFTNL_CHAIN_HANDLE);
-
-               ret = batch_chain_add(h, NFT_COMPAT_CHAIN_ZERO, c);
+       if (chain) {
+               c = nftnl_chain_list_lookup_byname(list, chain);
+               if (!c)
+                       return 0;
 
-               if (chain != NULL)
-                       break;
-next:
-               c = nftnl_chain_list_iter_next(iter);
+               ret = __nft_chain_zero_counters(c, &d);
+               goto err;
        }
 
-       nftnl_chain_list_iter_destroy(iter);
-
+       ret = nftnl_chain_list_foreach(list, __nft_chain_zero_counters, &d);
 err:
        /* the core expects 1 for success and 0 for error */
        return ret == 0 ? 1 : 0;