]> git.ipfire.org Git - thirdparty/nftables.git/commitdiff
src: add table_spec
authorPablo Neira Ayuso <pablo@netfilter.org>
Thu, 3 May 2018 10:06:27 +0000 (12:06 +0200)
committerPablo Neira Ayuso <pablo@netfilter.org>
Sun, 6 May 2018 20:48:30 +0000 (22:48 +0200)
Store location object in handle to improve error reporting.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
include/rule.h
src/evaluate.c
src/monitor.c
src/netlink.c
src/netlink_delinearize.c
src/parser_bison.y
src/rule.c

index ee22cf217ac6b25f25577de9af913107c1be7010..88750f0a4b54629932240cdb588bad881d28a93f 100644 (file)
@@ -27,6 +27,11 @@ struct position_spec {
        uint64_t                id;
 };
 
+struct table_spec {
+       struct location         location;
+       const char              *name;
+};
+
 /**
  * struct handle - handle for tables, chains, rules and sets
  *
@@ -42,7 +47,7 @@ struct position_spec {
  */
 struct handle {
        uint32_t                family;
-       const char              *table;
+       struct table_spec       table;
        const char              *chain;
        const char              *set;
        const char              *obj;
index 55e6ad1e0b749ba114050a5cb0f7a23fc618bfc8..de314c1d3b75872b0350c1cda26158f3da1f3ecb 100644 (file)
@@ -191,7 +191,7 @@ static int expr_evaluate_symbol(struct eval_ctx *ctx, struct expr **expr)
                table = table_lookup_global(ctx);
                if (table == NULL)
                        return cmd_error(ctx, "Could not process rule: Table '%s' does not exist",
-                                        ctx->cmd->handle.table);
+                                        ctx->cmd->handle.table.name);
 
                set = set_lookup(table, (*expr)->identifier);
                if (set == NULL)
@@ -2748,7 +2748,7 @@ static int setelem_evaluate(struct eval_ctx *ctx, struct expr **expr)
        table = table_lookup_global(ctx);
        if (table == NULL)
                return cmd_error(ctx, "Could not process rule: Table '%s' does not exist",
-                                ctx->cmd->handle.table);
+                                ctx->cmd->handle.table.name);
 
        set = set_lookup(table, ctx->cmd->handle.set);
        if (set == NULL)
@@ -2771,7 +2771,7 @@ static int set_evaluate(struct eval_ctx *ctx, struct set *set)
        table = table_lookup_global(ctx);
        if (table == NULL)
                return cmd_error(ctx, "Could not process rule: Table '%s' does not exist",
-                                ctx->cmd->handle.table);
+                                ctx->cmd->handle.table.name);
 
        if (!(set->flags & NFT_SET_INTERVAL) && set->automerge)
                return set_error(ctx, set, "auto-merge only works with interval sets");
@@ -2833,7 +2833,7 @@ static int flowtable_evaluate(struct eval_ctx *ctx, struct flowtable *ft)
        table = table_lookup_global(ctx);
        if (table == NULL)
                return cmd_error(ctx, "Could not process rule: Table '%s' does not exist",
-                                ctx->cmd->handle.table);
+                                ctx->cmd->handle.table.name);
 
        ft->hooknum = str2hooknum(NFPROTO_NETDEV, ft->hookstr);
        if (ft->hooknum == NF_INET_NUMHOOKS)
@@ -2925,7 +2925,7 @@ static int chain_evaluate(struct eval_ctx *ctx, struct chain *chain)
        table = table_lookup_global(ctx);
        if (table == NULL)
                return cmd_error(ctx, "Could not process rule: Table '%s' does not exist",
-                                ctx->cmd->handle.table);
+                                ctx->cmd->handle.table.name);
 
        if (chain == NULL) {
                if (chain_lookup(table, &ctx->cmd->handle) == NULL) {
@@ -3089,7 +3089,7 @@ static int cmd_evaluate_get(struct eval_ctx *ctx, struct cmd *cmd)
                table = table_lookup(&cmd->handle, ctx->cache);
                if (table == NULL)
                        return cmd_error(ctx, "Could not process rule: Table '%s' does not exist",
-                                        cmd->handle.table);
+                                        cmd->handle.table.name);
                set = set_lookup(table, cmd->handle.set);
                if (set == NULL || set->flags & (NFT_SET_MAP | NFT_SET_EVAL))
                        return cmd_error(ctx, "Could not process rule: Set '%s' does not exist",
@@ -3112,7 +3112,7 @@ static int cmd_evaluate_list_obj(struct eval_ctx *ctx, const struct cmd *cmd,
        table = table_lookup(&cmd->handle, ctx->cache);
        if (table == NULL)
                return cmd_error(ctx, "Could not process rule: Table '%s' does not exist",
-                                cmd->handle.table);
+                                cmd->handle.table.name);
        if (obj_lookup(table, cmd->handle.obj, obj_type) == NULL)
                return cmd_error(ctx, "Could not process rule: Object '%s' does not exist",
                                         cmd->handle.obj);
@@ -3132,19 +3132,19 @@ static int cmd_evaluate_list(struct eval_ctx *ctx, struct cmd *cmd)
 
        switch (cmd->obj) {
        case CMD_OBJ_TABLE:
-               if (cmd->handle.table == NULL)
+               if (cmd->handle.table.name == NULL)
                        return 0;
 
                table = table_lookup(&cmd->handle, ctx->cache);
                if (table == NULL)
                        return cmd_error(ctx, "Could not process rule: Table '%s' does not exist",
-                                        cmd->handle.table);
+                                        cmd->handle.table.name);
                return 0;
        case CMD_OBJ_SET:
                table = table_lookup(&cmd->handle, ctx->cache);
                if (table == NULL)
                        return cmd_error(ctx, "Could not process rule: Table '%s' does not exist",
-                                        cmd->handle.table);
+                                        cmd->handle.table.name);
                set = set_lookup(table, cmd->handle.set);
                if (set == NULL || set->flags & (NFT_SET_MAP | NFT_SET_EVAL))
                        return cmd_error(ctx, "Could not process rule: Set '%s' does not exist",
@@ -3154,7 +3154,7 @@ static int cmd_evaluate_list(struct eval_ctx *ctx, struct cmd *cmd)
                table = table_lookup(&cmd->handle, ctx->cache);
                if (table == NULL)
                        return cmd_error(ctx, "Could not process rule: Table '%s' does not exist",
-                                        cmd->handle.table);
+                                        cmd->handle.table.name);
                set = set_lookup(table, cmd->handle.set);
                if (set == NULL || !(set->flags & NFT_SET_EVAL))
                        return cmd_error(ctx, "Could not process rule: Meter '%s' does not exist",
@@ -3164,7 +3164,7 @@ static int cmd_evaluate_list(struct eval_ctx *ctx, struct cmd *cmd)
                table = table_lookup(&cmd->handle, ctx->cache);
                if (table == NULL)
                        return cmd_error(ctx, "Could not process rule: Table '%s' does not exist",
-                                        cmd->handle.table);
+                                        cmd->handle.table.name);
                set = set_lookup(table, cmd->handle.set);
                if (set == NULL || !(set->flags & NFT_SET_MAP))
                        return cmd_error(ctx, "Could not process rule: Map '%s' does not exist",
@@ -3174,7 +3174,7 @@ static int cmd_evaluate_list(struct eval_ctx *ctx, struct cmd *cmd)
                table = table_lookup(&cmd->handle, ctx->cache);
                if (table == NULL)
                        return cmd_error(ctx, "Could not process rule: Table '%s' does not exist",
-                                        cmd->handle.table);
+                                        cmd->handle.table.name);
                if (chain_lookup(table, &cmd->handle) == NULL)
                        return cmd_error(ctx, "Could not process rule: Chain '%s' does not exist",
                                         cmd->handle.chain);
@@ -3193,11 +3193,11 @@ static int cmd_evaluate_list(struct eval_ctx *ctx, struct cmd *cmd)
        case CMD_OBJ_LIMITS:
        case CMD_OBJ_SETS:
        case CMD_OBJ_FLOWTABLES:
-               if (cmd->handle.table == NULL)
+               if (cmd->handle.table.name == NULL)
                        return 0;
                if (table_lookup(&cmd->handle, ctx->cache) == NULL)
                        return cmd_error(ctx, "Could not process rule: Table '%s' does not exist",
-                                        cmd->handle.table);
+                                        cmd->handle.table.name);
                return 0;
        case CMD_OBJ_CHAINS:
        case CMD_OBJ_RULESET:
@@ -3223,11 +3223,11 @@ static int cmd_evaluate_reset(struct eval_ctx *ctx, struct cmd *cmd)
        case CMD_OBJ_QUOTA:
        case CMD_OBJ_COUNTERS:
        case CMD_OBJ_QUOTAS:
-               if (cmd->handle.table == NULL)
+               if (cmd->handle.table.name == NULL)
                        return 0;
                if (table_lookup(&cmd->handle, ctx->cache) == NULL)
                        return cmd_error(ctx, "Could not process rule: Table '%s' does not exist",
-                                        cmd->handle.table);
+                                        cmd->handle.table.name);
                return 0;
        default:
                BUG("invalid command object type %u\n", cmd->obj);
@@ -3260,7 +3260,7 @@ static int cmd_evaluate_flush(struct eval_ctx *ctx, struct cmd *cmd)
                table = table_lookup(&cmd->handle, ctx->cache);
                if (table == NULL)
                        return cmd_error(ctx, "Could not process rule: Table '%s' does not exist",
-                                        cmd->handle.table);
+                                        cmd->handle.table.name);
                set = set_lookup(table, cmd->handle.set);
                if (set == NULL || set->flags & (NFT_SET_MAP | NFT_SET_EVAL))
                        return cmd_error(ctx, "Could not process rule: Set '%s' does not exist",
@@ -3275,7 +3275,7 @@ static int cmd_evaluate_flush(struct eval_ctx *ctx, struct cmd *cmd)
                table = table_lookup(&cmd->handle, ctx->cache);
                if (table == NULL)
                        return cmd_error(ctx, "Could not process rule: Table '%s' does not exist",
-                                        cmd->handle.table);
+                                        cmd->handle.table.name);
                set = set_lookup(table, cmd->handle.set);
                if (set == NULL || !(set->flags & NFT_SET_MAP))
                        return cmd_error(ctx, "Could not process rule: Map '%s' does not exist",
@@ -3290,7 +3290,7 @@ static int cmd_evaluate_flush(struct eval_ctx *ctx, struct cmd *cmd)
                table = table_lookup(&cmd->handle, ctx->cache);
                if (table == NULL)
                        return cmd_error(ctx, "Could not process rule: Table '%s' does not exist",
-                                        cmd->handle.table);
+                                        cmd->handle.table.name);
                set = set_lookup(table, cmd->handle.set);
                if (set == NULL || !(set->flags & NFT_SET_EVAL))
                        return cmd_error(ctx, "Could not process rule: Meter '%s' does not exist",
@@ -3317,7 +3317,7 @@ static int cmd_evaluate_rename(struct eval_ctx *ctx, struct cmd *cmd)
                table = table_lookup(&ctx->cmd->handle, ctx->cache);
                if (table == NULL)
                        return cmd_error(ctx, "Could not process rule: Table '%s' does not exist",
-                                        ctx->cmd->handle.table);
+                                        ctx->cmd->handle.table.name);
                if (chain_lookup(table, &ctx->cmd->handle) == NULL)
                        return cmd_error(ctx, "Could not process rule: Chain '%s' does not exist",
                                         ctx->cmd->handle.chain);
index 9249a21cfc0be602d1242d880b1e78c49135c3af..4310c3b8dc434ba7bf8fa3f986f4dc4eaa71d8af 100644 (file)
@@ -576,7 +576,7 @@ static void netlink_events_cache_deltable(struct netlink_mon_handler *monh,
 
        nlt      = netlink_table_alloc(nlh);
        h.family = nftnl_table_get_u32(nlt, NFTNL_TABLE_FAMILY);
-       h.table  = nftnl_table_get_str(nlt, NFTNL_TABLE_NAME);
+       h.table.name  = nftnl_table_get_str(nlt, NFTNL_TABLE_NAME);
 
        t = table_lookup(&h, monh->cache);
        if (t == NULL)
@@ -722,7 +722,7 @@ static void netlink_events_cache_delobj(struct netlink_mon_handler *monh,
 
        nlo      = netlink_obj_alloc(nlh);
        h.family = nftnl_obj_get_u32(nlo, NFTNL_OBJ_FAMILY);
-       h.table  = nftnl_obj_get_str(nlo, NFTNL_OBJ_TABLE);
+       h.table.name  = nftnl_obj_get_str(nlo, NFTNL_OBJ_TABLE);
 
        name     = nftnl_obj_get_str(nlo, NFTNL_OBJ_NAME);
        type     = nftnl_obj_get_u32(nlo, NFTNL_OBJ_TYPE);
index 5fb42074d9007427ca324329126c9c8f21aee007..0c078d6433447b2197c94ced615a8d202dbed259 100644 (file)
@@ -125,8 +125,8 @@ struct nftnl_table *alloc_nftnl_table(const struct handle *h)
                memory_allocation_error();
 
        nftnl_table_set_u32(nlt, NFTNL_TABLE_FAMILY, h->family);
-       if (h->table != NULL)
-               nftnl_table_set(nlt, NFTNL_TABLE_NAME, h->table);
+       if (h->table.name != NULL)
+               nftnl_table_set(nlt, NFTNL_TABLE_NAME, h->table.name);
        if (h->handle.id)
                nftnl_table_set_u64(nlt, NFTNL_TABLE_HANDLE, h->handle.id);
 
@@ -142,7 +142,7 @@ struct nftnl_chain *alloc_nftnl_chain(const struct handle *h)
                memory_allocation_error();
 
        nftnl_chain_set_u32(nlc, NFTNL_CHAIN_FAMILY, h->family);
-       nftnl_chain_set_str(nlc, NFTNL_CHAIN_TABLE, h->table);
+       nftnl_chain_set_str(nlc, NFTNL_CHAIN_TABLE, h->table.name);
        if (h->handle.id)
                nftnl_chain_set_u64(nlc, NFTNL_CHAIN_HANDLE, h->handle.id);
        if (h->chain != NULL)
@@ -160,7 +160,7 @@ struct nftnl_rule *alloc_nftnl_rule(const struct handle *h)
                memory_allocation_error();
 
        nftnl_rule_set_u32(nlr, NFTNL_RULE_FAMILY, h->family);
-       nftnl_rule_set_str(nlr, NFTNL_RULE_TABLE, h->table);
+       nftnl_rule_set_str(nlr, NFTNL_RULE_TABLE, h->table.name);
        if (h->chain != NULL)
                nftnl_rule_set_str(nlr, NFTNL_RULE_CHAIN, h->chain);
        if (h->handle.id)
@@ -191,7 +191,7 @@ struct nftnl_set *alloc_nftnl_set(const struct handle *h)
                memory_allocation_error();
 
        nftnl_set_set_u32(nls, NFTNL_SET_FAMILY, h->family);
-       nftnl_set_set_str(nls, NFTNL_SET_TABLE, h->table);
+       nftnl_set_set_str(nls, NFTNL_SET_TABLE, h->table.name);
        if (h->set != NULL)
                nftnl_set_set_str(nls, NFTNL_SET_NAME, h->set);
        if (h->set_id)
@@ -292,7 +292,7 @@ __alloc_nftnl_obj(const struct handle *h, uint32_t type)
                memory_allocation_error();
 
        nftnl_obj_set_u32(nlo, NFTNL_OBJ_FAMILY, h->family);
-       nftnl_obj_set_str(nlo, NFTNL_OBJ_TABLE, h->table);
+       nftnl_obj_set_str(nlo, NFTNL_OBJ_TABLE, h->table.name);
        if (h->obj != NULL)
                nftnl_obj_set_str(nlo, NFTNL_OBJ_NAME, h->obj);
 
@@ -539,7 +539,7 @@ static int list_rule_cb(struct nftnl_rule *nlr, void *arg)
        chain  = nftnl_rule_get_str(nlr, NFTNL_RULE_CHAIN);
 
        if (h->family != family ||
-           strcmp(table, h->table) != 0 ||
+           strcmp(table, h->table.name) != 0 ||
            (h->chain && strcmp(chain, h->chain) != 0))
                return 0;
 
@@ -653,7 +653,7 @@ struct chain *netlink_delinearize_chain(struct netlink_ctx *ctx,
        chain = chain_alloc(nftnl_chain_get_str(nlc, NFTNL_CHAIN_NAME));
        chain->handle.family =
                nftnl_chain_get_u32(nlc, NFTNL_CHAIN_FAMILY);
-       chain->handle.table  =
+       chain->handle.table.name  =
                xstrdup(nftnl_chain_get_str(nlc, NFTNL_CHAIN_TABLE));
        chain->handle.handle.id =
                nftnl_chain_get_u64(nlc, NFTNL_CHAIN_HANDLE);
@@ -695,7 +695,7 @@ static int list_chain_cb(struct nftnl_chain *nlc, void *arg)
        name   = nftnl_chain_get_str(nlc, NFTNL_CHAIN_NAME);
        family = nftnl_chain_get_u32(nlc, NFTNL_CHAIN_FAMILY);
 
-       if (h->family != family || strcmp(table, h->table) != 0)
+       if (h->family != family || strcmp(table, h->table.name) != 0)
                return 0;
        if (h->chain && strcmp(name, h->chain) != 0)
                return 0;
@@ -767,7 +767,7 @@ struct table *netlink_delinearize_table(struct netlink_ctx *ctx,
 
        table = table_alloc();
        table->handle.family = nftnl_table_get_u32(nlt, NFTNL_TABLE_FAMILY);
-       table->handle.table  = xstrdup(nftnl_table_get_str(nlt, NFTNL_TABLE_NAME));
+       table->handle.table.name = xstrdup(nftnl_table_get_str(nlt, NFTNL_TABLE_NAME));
        table->flags         = nftnl_table_get_u32(nlt, NFTNL_TABLE_FLAGS);
        table->handle.handle.id = nftnl_table_get_u64(nlt, NFTNL_TABLE_HANDLE);
 
@@ -925,7 +925,7 @@ struct set *netlink_delinearize_set(struct netlink_ctx *ctx,
 
        set = set_alloc(&netlink_location);
        set->handle.family = nftnl_set_get_u32(nls, NFTNL_SET_FAMILY);
-       set->handle.table  = xstrdup(nftnl_set_get_str(nls, NFTNL_SET_TABLE));
+       set->handle.table.name = xstrdup(nftnl_set_get_str(nls, NFTNL_SET_TABLE));
        set->handle.set    = xstrdup(nftnl_set_get_str(nls, NFTNL_SET_NAME));
        set->automerge     = automerge;
 
@@ -1062,7 +1062,7 @@ int netlink_list_sets(struct netlink_ctx *ctx, const struct handle *h)
        struct nftnl_set_list *set_cache;
        int err;
 
-       set_cache = mnl_nft_set_dump(ctx, h->family, h->table);
+       set_cache = mnl_nft_set_dump(ctx, h->family, h->table.name);
        if (set_cache == NULL) {
                if (errno == EINTR)
                        return -1;
@@ -1408,7 +1408,7 @@ struct obj *netlink_delinearize_obj(struct netlink_ctx *ctx,
 
        obj = obj_alloc(&netlink_location);
        obj->handle.family = nftnl_obj_get_u32(nlo, NFTNL_OBJ_FAMILY);
-       obj->handle.table =
+       obj->handle.table.name =
                xstrdup(nftnl_obj_get_str(nlo, NFTNL_OBJ_TABLE));
        obj->handle.obj =
                xstrdup(nftnl_obj_get_str(nlo, NFTNL_OBJ_NAME));
@@ -1465,7 +1465,7 @@ static struct nftnl_flowtable *alloc_nftnl_flowtable(const struct handle *h,
                memory_allocation_error();
 
        nftnl_flowtable_set_u32(flo, NFTNL_FLOWTABLE_FAMILY, h->family);
-       nftnl_flowtable_set_str(flo, NFTNL_FLOWTABLE_TABLE, h->table);
+       nftnl_flowtable_set_str(flo, NFTNL_FLOWTABLE_TABLE, h->table.name);
        if (h->flowtable != NULL)
                nftnl_flowtable_set_str(flo, NFTNL_FLOWTABLE_NAME, h->flowtable);
 
@@ -1543,7 +1543,7 @@ int netlink_list_objs(struct netlink_ctx *ctx, const struct handle *h)
        int err;
 
        obj_cache = mnl_nft_obj_dump(ctx, h->family,
-                                    h->table, NULL, 0, true, false);
+                                    h->table.name, NULL, 0, true, false);
        if (obj_cache == NULL) {
                if (errno == EINTR)
                        return -1;
@@ -1564,7 +1564,7 @@ int netlink_reset_objs(struct netlink_ctx *ctx, const struct cmd *cmd,
        int err;
 
        obj_cache = mnl_nft_obj_dump(ctx, h->family,
-                                    h->table, h->obj, type, dump, true);
+                                    h->table.name, h->obj, type, dump, true);
        if (obj_cache == NULL)
                return -1;
 
@@ -1584,7 +1584,7 @@ netlink_delinearize_flowtable(struct netlink_ctx *ctx,
        flowtable = flowtable_alloc(&netlink_location);
        flowtable->handle.family =
                nftnl_flowtable_get_u32(nlo, NFTNL_FLOWTABLE_FAMILY);
-       flowtable->handle.table =
+       flowtable->handle.table.name =
                xstrdup(nftnl_flowtable_get_str(nlo, NFTNL_FLOWTABLE_TABLE));
        flowtable->handle.flowtable =
                xstrdup(nftnl_flowtable_get_str(nlo, NFTNL_FLOWTABLE_NAME));
@@ -1623,7 +1623,7 @@ int netlink_list_flowtables(struct netlink_ctx *ctx, const struct handle *h)
        struct nftnl_flowtable_list *flowtable_cache;
        int err;
 
-       flowtable_cache = mnl_nft_flowtable_dump(ctx, h->family, h->table);
+       flowtable_cache = mnl_nft_flowtable_dump(ctx, h->family, h->table.name);
        if (flowtable_cache == NULL) {
                if (errno == EINTR)
                        return -1;
@@ -1719,10 +1719,10 @@ static void trace_print_rule(const struct nftnl_trace *nlt,
        struct handle h;
 
        h.family = nftnl_trace_get_u32(nlt, NFTNL_TRACE_FAMILY);
-       h.table  = nftnl_trace_get_str(nlt, NFTNL_TRACE_TABLE);
+       h.table.name  = nftnl_trace_get_str(nlt, NFTNL_TRACE_TABLE);
        h.chain  = nftnl_trace_get_str(nlt, NFTNL_TRACE_CHAIN);
 
-       if (!h.table)
+       if (!h.table.name)
                return;
 
        table = table_lookup(&h, cache);
index 10b3e8cb1c1be428ffa2366300d3cedb5a1f2bd8..6a082ad15fc81dcda69cb476fb4454eb32dd8797 100644 (file)
@@ -2445,7 +2445,7 @@ struct rule *netlink_delinearize_rule(struct netlink_ctx *ctx,
 
        memset(&h, 0, sizeof(h));
        h.family = nftnl_rule_get_u32(nlr, NFTNL_RULE_FAMILY);
-       h.table  = xstrdup(nftnl_rule_get_str(nlr, NFTNL_RULE_TABLE));
+       h.table.name  = xstrdup(nftnl_rule_get_str(nlr, NFTNL_RULE_TABLE));
        h.chain  = xstrdup(nftnl_rule_get_str(nlr, NFTNL_RULE_CHAIN));
        h.handle.id = nftnl_rule_get_u64(nlr, NFTNL_RULE_HANDLE);
 
index dcd468357ebcc00c91422600b8a092ec84f47af7..95a42d3e9f89b64491526f6b2644f75e64fde681 100644 (file)
@@ -1844,7 +1844,8 @@ table_spec                :       family_spec     identifier
                        {
                                memset(&$$, 0, sizeof($$));
                                $$.family       = $1;
-                               $$.table        = $2;
+                               $$.table.location = @2;
+                               $$.table.name   = $2;
                        }
                        ;
 
index 5693888c31db97dbe619afa7350e5f8c6310bf42..6c2b4eea7c24df9b43f3624019140da8a4937728 100644 (file)
@@ -30,7 +30,7 @@
 
 void handle_free(struct handle *h)
 {
-       xfree(h->table);
+       xfree(h->table.name);
        xfree(h->chain);
        xfree(h->set);
        xfree(h->flowtable);
@@ -40,8 +40,8 @@ void handle_merge(struct handle *dst, const struct handle *src)
 {
        if (dst->family == 0)
                dst->family = src->family;
-       if (dst->table == NULL && src->table != NULL)
-               dst->table = xstrdup(src->table);
+       if (dst->table.name == NULL && src->table.name != NULL)
+               dst->table.name = xstrdup(src->table.name);
        if (dst->chain == NULL && src->chain != NULL)
                dst->chain = xstrdup(src->chain);
        if (dst->set == NULL && src->set != NULL)
@@ -270,7 +270,7 @@ struct set *set_lookup_global(uint32_t family, const char *table,
        struct table *t;
 
        h.family = family;
-       h.table = table;
+       h.table.name = table;
 
        t = table_lookup(&h, cache);
        if (t == NULL)
@@ -418,7 +418,7 @@ void set_print_plain(const struct set *s, struct output_ctx *octx)
        struct print_fmt_options opts = {
                .tab            = "",
                .nl             = " ",
-               .table          = s->handle.table,
+               .table          = s->handle.table.name,
                .family         = family2str(s->handle.family),
                .stmt_separator = "; ",
        };
@@ -777,7 +777,7 @@ static void chain_print(const struct chain *chain, struct output_ctx *octx)
 void chain_print_plain(const struct chain *chain, struct output_ctx *octx)
 {
        nft_print(octx, "chain %s %s %s", family2str(chain->handle.family),
-                 chain->handle.table, chain->handle.chain);
+                 chain->handle.table.name, chain->handle.chain);
 
        if (chain->flags & CHAIN_F_BASECHAIN) {
                nft_print(octx, " { type %s hook %s priority %d; policy %s; }",
@@ -842,7 +842,7 @@ struct table *table_lookup(const struct handle *h,
 
        list_for_each_entry(table, &cache->list, list) {
                if (table->handle.family == h->family &&
-                   !strcmp(table->handle.table, h->table))
+                   !strcmp(table->handle.table.name, h->table.name))
                        return table;
        }
        return NULL;
@@ -884,7 +884,7 @@ static void table_print(const struct table *table, struct output_ctx *octx)
        const char *delim = "";
        const char *family = family2str(table->handle.family);
 
-       nft_print(octx, "table %s %s {", family, table->handle.table);
+       nft_print(octx, "table %s %s {", family, table->handle.table.name);
        if (octx->handle > 0)
                nft_print(octx, " # handle %" PRIu64, table->handle.handle.id);
        nft_print(octx, "\n");
@@ -1318,7 +1318,7 @@ static int do_list_sets(struct netlink_ctx *ctx, struct cmd *cmd)
 
                nft_print(ctx->octx, "table %s %s {\n",
                          family2str(table->handle.family),
-                         table->handle.table);
+                         table->handle.table.name);
 
                list_for_each_entry(set, &table->sets, list) {
                        if (cmd->obj == CMD_OBJ_SETS &&
@@ -1543,7 +1543,7 @@ void obj_print_plain(const struct obj *obj, struct output_ctx *octx)
        struct print_fmt_options opts = {
                .tab            = "",
                .nl             = " ",
-               .table          = obj->handle.table,
+               .table          = obj->handle.table.name,
                .family         = family2str(obj->handle.family),
        };
 
@@ -1567,10 +1567,10 @@ static int do_list_obj(struct netlink_ctx *ctx, struct cmd *cmd, uint32_t type)
 
                nft_print(ctx->octx, "table %s %s {\n",
                          family2str(table->handle.family),
-                         table->handle.table);
+                         table->handle.table.name);
 
-               if (cmd->handle.table != NULL &&
-                   strcmp(cmd->handle.table, table->handle.table)) {
+               if (cmd->handle.table.name != NULL &&
+                   strcmp(cmd->handle.table.name, table->handle.table.name)) {
                        nft_print(ctx->octx, "}\n");
                        continue;
                }
@@ -1686,7 +1686,7 @@ static int do_list_flowtables(struct netlink_ctx *ctx, struct cmd *cmd)
 
                nft_print(ctx->octx, "table %s %s {\n",
                          family2str(table->handle.family),
-                         table->handle.table);
+                         table->handle.table.name);
 
                list_for_each_entry(flowtable, &table->flowtables, list) {
                        flowtable_print_declaration(flowtable, &opts, ctx->octx);
@@ -1709,13 +1709,13 @@ static int do_list_ruleset(struct netlink_ctx *ctx, struct cmd *cmd)
                        continue;
 
                cmd->handle.family = table->handle.family;
-               cmd->handle.table = table->handle.table;
+               cmd->handle.table.name = table->handle.table.name;
 
                if (do_list_table(ctx, cmd, table) < 0)
                        return -1;
        }
 
-       cmd->handle.table = NULL;
+       cmd->handle.table.name = NULL;
 
        return 0;
 }
@@ -1731,7 +1731,7 @@ static int do_list_tables(struct netlink_ctx *ctx, struct cmd *cmd)
 
                nft_print(ctx->octx, "table %s %s\n",
                          family2str(table->handle.family),
-                         table->handle.table);
+                         table->handle.table.name);
        }
 
        return 0;
@@ -1742,7 +1742,7 @@ static void table_print_declaration(struct table *table,
 {
        nft_print(octx, "table %s %s {\n",
                  family2str(table->handle.family),
-                 table->handle.table);
+                 table->handle.table.name);
 }
 
 static int do_list_chain(struct netlink_ctx *ctx, struct cmd *cmd,
@@ -1813,12 +1813,12 @@ static int do_command_list(struct netlink_ctx *ctx, struct cmd *cmd)
 {
        struct table *table = NULL;
 
-       if (cmd->handle.table != NULL)
+       if (cmd->handle.table.name != NULL)
                table = table_lookup(&cmd->handle, ctx->cache);
 
        switch (cmd->obj) {
        case CMD_OBJ_TABLE:
-               if (!cmd->handle.table)
+               if (!cmd->handle.table.name)
                        return do_list_tables(ctx, cmd);
                return do_list_table(ctx, cmd, table);
        case CMD_OBJ_CHAIN:
@@ -1897,7 +1897,7 @@ static int do_command_get(struct netlink_ctx *ctx, struct cmd *cmd)
 {
        struct table *table = NULL;
 
-       if (cmd->handle.table != NULL)
+       if (cmd->handle.table.name != NULL)
                table = table_lookup(&cmd->handle, ctx->cache);
 
        switch (cmd->obj) {