]> git.ipfire.org Git - thirdparty/nftables.git/commitdiff
src: consolidate object cache infrastructure
authorPablo Neira Ayuso <pablo@netfilter.org>
Thu, 29 Apr 2021 19:55:34 +0000 (21:55 +0200)
committerPablo Neira Ayuso <pablo@netfilter.org>
Sun, 2 May 2021 21:30:35 +0000 (23:30 +0200)
This patch consolidates the object cache infrastructure. Update set and
chains to use it.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
include/cache.h
include/rule.h
src/cache.c
src/json.c
src/rule.c

index 987b122bc4fba5d43e8cfde852324d1b89432e4a..4d91a73624c8d9b188e0efb8ac0da1dc71bf288b 100644 (file)
@@ -72,4 +72,19 @@ struct chain *chain_cache_find(const struct table *table, const char *name);
 void set_cache_add(struct set *set, struct table *table);
 struct set *set_cache_find(const struct table *table, const char *name);
 
+struct cache {
+       struct list_head        *ht;
+       struct list_head        list;
+};
+
+struct cache_item {
+       struct list_head        hlist;
+       struct list_head        list;
+};
+
+void cache_init(struct cache *cache);
+void cache_free(struct cache *cache);
+void cache_add(struct cache_item *item, struct cache *cache, uint32_t hash);
+void cache_del(struct cache_item *item);
+
 #endif /* _NFT_CACHE_H_ */
index 7896eafec137dade2105088031be29ac29906234..b238c85bcba97885cc8c02e193a80ae214fb0fe3 100644 (file)
@@ -155,11 +155,9 @@ struct table {
        struct handle           handle;
        struct location         location;
        struct scope            scope;
-       struct list_head        *cache_chain_ht;
-       struct list_head        cache_chain;
+       struct cache            chain_cache;
+       struct cache            set_cache;
        struct list_head        chains;
-       struct list_head        *cache_set_ht;
-       struct list_head        cache_set;
        struct list_head        sets;
        struct list_head        objs;
        struct list_head        flowtables;
@@ -233,8 +231,7 @@ struct hook_spec {
  */
 struct chain {
        struct list_head        list;
-       struct list_head        cache_hlist;
-       struct list_head        cache_list;
+       struct cache_item       cache;
        struct handle           handle;
        struct location         location;
        unsigned int            refcnt;
@@ -333,8 +330,7 @@ void rule_stmt_insert_at(struct rule *rule, struct stmt *nstmt,
  */
 struct set {
        struct list_head        list;
-       struct list_head        cache_hlist;
-       struct list_head        cache_list;
+       struct cache_item       cache;
        struct handle           handle;
        struct location         location;
        unsigned int            refcnt;
index 53dbaaba8e209ee9389e1fd036da7b1e2370eac3..70e47064848e82af960f7dde4a56cdc3087fa950 100644 (file)
@@ -193,10 +193,9 @@ static int chain_cache_cb(struct nftnl_chain *nlc, void *arg)
        chain = netlink_delinearize_chain(ctx->nlctx, nlc);
 
        if (chain->flags & CHAIN_F_BINDING) {
-               list_add_tail(&chain->cache_list, &ctx->table->chain_bindings);
+               list_add_tail(&chain->cache.list, &ctx->table->chain_bindings);
        } else {
-               list_add_tail(&chain->cache_hlist, &ctx->table->cache_chain_ht[hash]);
-               list_add_tail(&chain->cache_list, &ctx->table->cache_chain);
+               cache_add(&chain->cache, &ctx->table->chain_cache, hash);
        }
 
        nftnl_chain_list_del(nlc);
@@ -240,8 +239,7 @@ void chain_cache_add(struct chain *chain, struct table *table)
        uint32_t hash;
 
        hash = djb_hash(chain->handle.chain.name) % NFT_CACHE_HSIZE;
-       list_add_tail(&chain->cache_hlist, &table->cache_chain_ht[hash]);
-       list_add_tail(&chain->cache_list, &table->cache_chain);
+       cache_add(&chain->cache, &table->chain_cache, hash);
 }
 
 struct chain *chain_cache_find(const struct table *table, const char *name)
@@ -250,7 +248,7 @@ struct chain *chain_cache_find(const struct table *table, const char *name)
        uint32_t hash;
 
        hash = djb_hash(name) % NFT_CACHE_HSIZE;
-       list_for_each_entry(chain, &table->cache_chain_ht[hash], cache_hlist) {
+       list_for_each_entry(chain, &table->chain_cache.ht[hash], cache.hlist) {
                if (!strcmp(chain->handle.chain.name, name))
                        return chain;
        }
@@ -276,8 +274,7 @@ static int set_cache_cb(struct nftnl_set *nls, void *arg)
 
        set_name = nftnl_set_get_str(nls, NFTNL_SET_NAME);
        hash = djb_hash(set_name) % NFT_CACHE_HSIZE;
-       list_add_tail(&set->cache_hlist, &ctx->table->cache_set_ht[hash]);
-       list_add_tail(&set->cache_list, &ctx->table->cache_set);
+       cache_add(&set->cache, &ctx->table->set_cache, hash);
 
        return 0;
 }
@@ -319,8 +316,7 @@ void set_cache_add(struct set *set, struct table *table)
        uint32_t hash;
 
        hash = djb_hash(set->handle.set.name) % NFT_CACHE_HSIZE;
-       list_add_tail(&set->cache_hlist, &table->cache_set_ht[hash]);
-       list_add_tail(&set->cache_list, &table->cache_set);
+       cache_add(&set->cache, &table->set_cache, hash);
 }
 
 struct set *set_cache_find(const struct table *table, const char *name)
@@ -329,7 +325,7 @@ struct set *set_cache_find(const struct table *table, const char *name)
        uint32_t hash;
 
        hash = djb_hash(name) % NFT_CACHE_HSIZE;
-       list_for_each_entry(set, &table->cache_set_ht[hash], cache_hlist) {
+       list_for_each_entry(set, &table->set_cache.ht[hash], cache.hlist) {
                if (!strcmp(set->handle.set.name, name))
                        return set;
        }
@@ -384,7 +380,7 @@ static int cache_init_objects(struct netlink_ctx *ctx, unsigned int flags)
                        }
                }
                if (flags & NFT_CACHE_SETELEM_BIT) {
-                       list_for_each_entry(set, &table->cache_set, cache_list) {
+                       list_for_each_entry(set, &table->set_cache.list, cache.list) {
                                ret = netlink_list_setelems(ctx, &set->handle,
                                                            set);
                                if (ret < 0) {
@@ -552,3 +548,31 @@ void nft_cache_release(struct nft_cache *cache)
        cache->genid = 0;
        cache->flags = NFT_CACHE_EMPTY;
 }
+
+void cache_init(struct cache *cache)
+{
+       int i;
+
+       cache->ht = xmalloc(sizeof(struct list_head) * NFT_CACHE_HSIZE);
+       for (i = 0; i < NFT_CACHE_HSIZE; i++)
+               init_list_head(&cache->ht[i]);
+
+       init_list_head(&cache->list);
+}
+
+void cache_free(struct cache *cache)
+{
+       xfree(cache->ht);
+}
+
+void cache_add(struct cache_item *item, struct cache *cache, uint32_t hash)
+{
+       list_add_tail(&item->hlist, &cache->ht[hash]);
+       list_add_tail(&item->list, &cache->list);
+}
+
+void cache_del(struct cache_item *item)
+{
+       list_del(&item->hlist);
+       list_del(&item->list);
+}
index 52603a57de5088e4cd943138e109dbd364b35fbb..a375093eb7858b0bf44999413c7c14e9a9e6f853 100644 (file)
@@ -1574,7 +1574,7 @@ static json_t *table_print_json_full(struct netlink_ctx *ctx,
                tmp = obj_print_json(obj);
                json_array_append_new(root, tmp);
        }
-       list_for_each_entry(set, &table->cache_set, cache_list) {
+       list_for_each_entry(set, &table->set_cache.list, cache.list) {
                if (set_is_anonymous(set->flags))
                        continue;
                tmp = set_print_json(&ctx->nft->output, set);
@@ -1584,7 +1584,7 @@ static json_t *table_print_json_full(struct netlink_ctx *ctx,
                tmp = flowtable_print_json(flowtable);
                json_array_append_new(root, tmp);
        }
-       list_for_each_entry(chain, &table->cache_chain, cache_list) {
+       list_for_each_entry(chain, &table->chain_cache.list, cache.list) {
                tmp = chain_print_json(chain);
                json_array_append_new(root, tmp);
 
@@ -1646,7 +1646,7 @@ static json_t *do_list_chain_json(struct netlink_ctx *ctx,
        struct chain *chain;
        struct rule *rule;
 
-       list_for_each_entry(chain, &table->cache_chain, cache_list) {
+       list_for_each_entry(chain, &table->chain_cache.list, cache.list) {
                if (chain->handle.family != cmd->handle.family ||
                    strcmp(cmd->handle.chain.name, chain->handle.chain.name))
                        continue;
@@ -1674,7 +1674,7 @@ static json_t *do_list_chains_json(struct netlink_ctx *ctx, struct cmd *cmd)
                    cmd->handle.family != table->handle.family)
                        continue;
 
-               list_for_each_entry(chain, &table->cache_chain, cache_list) {
+               list_for_each_entry(chain, &table->chain_cache.list, cache.list) {
                        json_t *tmp = chain_print_json(chain);
 
                        json_array_append_new(root, tmp);
@@ -1707,7 +1707,7 @@ static json_t *do_list_sets_json(struct netlink_ctx *ctx, struct cmd *cmd)
                    cmd->handle.family != table->handle.family)
                        continue;
 
-               list_for_each_entry(set, &table->cache_set, cache_list) {
+               list_for_each_entry(set, &table->set_cache.list, cache.list) {
                        if (cmd->obj == CMD_OBJ_SETS &&
                            !set_is_literal(set->flags))
                                continue;
index fac8d22a85ee8bc8937e7528c56718a6da1b5e46..7dbb02f5b04f963d258f33df4aa5a8aa721a3e57 100644 (file)
@@ -212,7 +212,7 @@ struct set *set_lookup_fuzzy(const char *set_name,
        string_misspell_init(&st);
 
        list_for_each_entry(table, &cache->list, list) {
-               list_for_each_entry(set, &table->cache_set, cache_list) {
+               list_for_each_entry(set, &table->set_cache.list, cache.list) {
                        if (set_is_anonymous(set->flags))
                                continue;
                        if (!strcmp(set->handle.set.name, set_name)) {
@@ -750,7 +750,7 @@ struct chain *chain_binding_lookup(const struct table *table,
 {
        struct chain *chain;
 
-       list_for_each_entry(chain, &table->chain_bindings, cache_list) {
+       list_for_each_entry(chain, &table->chain_bindings, cache.list) {
                if (!strcmp(chain->handle.chain.name, chain_name))
                        return chain;
        }
@@ -768,7 +768,7 @@ struct chain *chain_lookup_fuzzy(const struct handle *h,
        string_misspell_init(&st);
 
        list_for_each_entry(table, &cache->list, list) {
-               list_for_each_entry(chain, &table->cache_chain, cache_list) {
+               list_for_each_entry(chain, &table->chain_cache.list, cache.list) {
                        if (!strcmp(chain->handle.chain.name, h->chain.name)) {
                                *t = table;
                                return chain;
@@ -1102,28 +1102,18 @@ void chain_print_plain(const struct chain *chain, struct output_ctx *octx)
 struct table *table_alloc(void)
 {
        struct table *table;
-       int i;
 
        table = xzalloc(sizeof(*table));
        init_list_head(&table->chains);
-       init_list_head(&table->cache_chain);
        init_list_head(&table->sets);
-       init_list_head(&table->cache_set);
        init_list_head(&table->objs);
        init_list_head(&table->flowtables);
        init_list_head(&table->chain_bindings);
        init_list_head(&table->scope.symbols);
        table->refcnt = 1;
 
-       table->cache_chain_ht =
-               xmalloc(sizeof(struct list_head) * NFT_CACHE_HSIZE);
-       for (i = 0; i < NFT_CACHE_HSIZE; i++)
-               init_list_head(&table->cache_chain_ht[i]);
-
-       table->cache_set_ht =
-               xmalloc(sizeof(struct list_head) * NFT_CACHE_HSIZE);
-       for (i = 0; i < NFT_CACHE_HSIZE; i++)
-               init_list_head(&table->cache_set_ht[i]);
+       cache_init(&table->chain_cache);
+       cache_init(&table->set_cache);
 
        return table;
 }
@@ -1141,15 +1131,15 @@ void table_free(struct table *table)
                xfree(table->comment);
        list_for_each_entry_safe(chain, next, &table->chains, list)
                chain_free(chain);
-       list_for_each_entry_safe(chain, next, &table->chain_bindings, cache_list)
+       list_for_each_entry_safe(chain, next, &table->chain_bindings, cache.list)
                chain_free(chain);
        /* this is implicitly releasing chains in the hashtable cache */
-       list_for_each_entry_safe(chain, next, &table->cache_chain, cache_list)
+       list_for_each_entry_safe(chain, next, &table->chain_cache.list, cache.list)
                chain_free(chain);
        list_for_each_entry_safe(set, nset, &table->sets, list)
                set_free(set);
        /* this is implicitly releasing sets in the hashtable cache */
-       list_for_each_entry_safe(set, nset, &table->cache_set, cache_list)
+       list_for_each_entry_safe(set, nset, &table->set_cache.list, cache.list)
                set_free(set);
        list_for_each_entry_safe(ft, nft, &table->flowtables, list)
                flowtable_free(ft);
@@ -1157,8 +1147,8 @@ void table_free(struct table *table)
                obj_free(obj);
        handle_free(&table->handle);
        scope_release(&table->scope);
-       xfree(table->cache_chain_ht);
-       xfree(table->cache_set_ht);
+       cache_free(&table->chain_cache);
+       cache_free(&table->set_cache);
        xfree(table);
 }
 
@@ -1269,7 +1259,7 @@ static void table_print(const struct table *table, struct output_ctx *octx)
                obj_print(obj, octx);
                delim = "\n";
        }
-       list_for_each_entry(set, &table->cache_set, cache_list) {
+       list_for_each_entry(set, &table->set_cache.list, cache.list) {
                if (set_is_anonymous(set->flags))
                        continue;
                nft_print(octx, "%s", delim);
@@ -1281,7 +1271,7 @@ static void table_print(const struct table *table, struct output_ctx *octx)
                flowtable_print(flowtable, octx);
                delim = "\n";
        }
-       list_for_each_entry(chain, &table->cache_chain, cache_list) {
+       list_for_each_entry(chain, &table->chain_cache.list, cache.list) {
                nft_print(octx, "%s", delim);
                chain_print(chain, octx);
                delim = "\n";
@@ -1691,7 +1681,7 @@ static int do_list_sets(struct netlink_ctx *ctx, struct cmd *cmd)
                          family2str(table->handle.family),
                          table->handle.table.name);
 
-               list_for_each_entry(set, &table->cache_set, cache_list) {
+               list_for_each_entry(set, &table->set_cache.list, cache.list) {
                        if (cmd->obj == CMD_OBJ_SETS &&
                            !set_is_literal(set->flags))
                                continue;
@@ -2375,7 +2365,7 @@ static int do_list_chain(struct netlink_ctx *ctx, struct cmd *cmd,
 
        table_print_declaration(table, &ctx->nft->output);
 
-       list_for_each_entry(chain, &table->cache_chain, cache_list) {
+       list_for_each_entry(chain, &table->chain_cache.list, cache.list) {
                if (chain->handle.family != cmd->handle.family ||
                    strcmp(cmd->handle.chain.name, chain->handle.chain.name) != 0)
                        continue;
@@ -2400,7 +2390,7 @@ static int do_list_chains(struct netlink_ctx *ctx, struct cmd *cmd)
 
                table_print_declaration(table, &ctx->nft->output);
 
-               list_for_each_entry(chain, &table->cache_chain, cache_list) {
+               list_for_each_entry(chain, &table->chain_cache.list, cache.list) {
                        chain_print_declaration(chain, &ctx->nft->output);
                        nft_print(&ctx->nft->output, "\t}\n");
                }