return 0;
 }
 
-/* Internal set flag */
-#define NFT_SET_INACTIVE       (1 << 15)
-
 static int nft_trans_set_add(struct nft_ctx *ctx, int msg_type,
                             struct nft_set *set)
 {
        if (msg_type == NFT_MSG_NEWSET && ctx->nla[NFTA_SET_ID] != NULL) {
                nft_trans_set_id(trans) =
                        ntohl(nla_get_be32(ctx->nla[NFTA_SET_ID]));
-               set->flags |= NFT_SET_INACTIVE;
+               nft_activate_next(ctx->net, set);
        }
        nft_trans_set(trans) = set;
        list_add_tail(&trans->list, &ctx->net->nft.commit_list);
        if (err < 0)
                return err;
 
-       list_del_rcu(&set->list);
+       nft_deactivate_next(ctx->net, set);
        ctx->table->use--;
 
        return err;
        }
 
        list_for_each_entry_safe(set, ns, &ctx->table->sets, list) {
+               if (!nft_is_active_next(ctx->net, set))
+                       continue;
+
                if (set->flags & NFT_SET_ANONYMOUS &&
                    !list_empty(&set->bindings))
                        continue;
 }
 
 struct nft_set *nf_tables_set_lookup(const struct nft_table *table,
-                                    const struct nlattr *nla)
+                                    const struct nlattr *nla, u8 genmask)
 {
        struct nft_set *set;
 
                return ERR_PTR(-EINVAL);
 
        list_for_each_entry(set, &table->sets, list) {
-               if (!nla_strcmp(nla, set->name))
+               if (!nla_strcmp(nla, set->name) &&
+                   nft_active_genmask(set, genmask))
                        return set;
        }
        return ERR_PTR(-ENOENT);
 }
 
 struct nft_set *nf_tables_set_lookup_byid(const struct net *net,
-                                         const struct nlattr *nla)
+                                         const struct nlattr *nla,
+                                         u8 genmask)
 {
        struct nft_trans *trans;
        u32 id = ntohl(nla_get_be32(nla));
 
        list_for_each_entry(trans, &net->nft.commit_list, list) {
+               struct nft_set *set = nft_trans_set(trans);
+
                if (trans->msg_type == NFT_MSG_NEWSET &&
-                   id == nft_trans_set_id(trans))
-                       return nft_trans_set(trans);
+                   id == nft_trans_set_id(trans) &&
+                   nft_active_genmask(set, genmask))
+                       return set;
        }
        return ERR_PTR(-ENOENT);
 }
                list_for_each_entry(i, &ctx->table->sets, list) {
                        int tmp;
 
+                       if (!nft_is_active_next(ctx->net, set))
+                               continue;
                        if (!sscanf(i->name, name, &tmp))
                                continue;
                        if (tmp < min || tmp >= min + BITS_PER_BYTE * PAGE_SIZE)
 
        snprintf(set->name, sizeof(set->name), name, min + n);
        list_for_each_entry(i, &ctx->table->sets, list) {
+               if (!nft_is_active_next(ctx->net, i))
+                       continue;
                if (!strcmp(set->name, i->name))
                        return -ENFILE;
        }
                        list_for_each_entry_rcu(set, &table->sets, list) {
                                if (idx < s_idx)
                                        goto cont;
+                               if (!nft_is_active(net, set))
+                                       goto cont;
 
                                ctx_set = *ctx;
                                ctx_set.table = table;
        if (nfmsg->nfgen_family == NFPROTO_UNSPEC)
                return -EAFNOSUPPORT;
 
-       set = nf_tables_set_lookup(ctx.table, nla[NFTA_SET_NAME]);
+       set = nf_tables_set_lookup(ctx.table, nla[NFTA_SET_NAME], genmask);
        if (IS_ERR(set))
                return PTR_ERR(set);
-       if (set->flags & NFT_SET_INACTIVE)
-               return -ENOENT;
 
        skb2 = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
        if (skb2 == NULL)
 
        nft_ctx_init(&ctx, net, skb, nlh, afi, table, NULL, nla);
 
-       set = nf_tables_set_lookup(table, nla[NFTA_SET_NAME]);
+       set = nf_tables_set_lookup(table, nla[NFTA_SET_NAME], genmask);
        if (IS_ERR(set)) {
                if (PTR_ERR(set) != -ENOENT)
                        return PTR_ERR(set);
        if (err < 0)
                return err;
 
-       set = nf_tables_set_lookup(ctx.table, nla[NFTA_SET_NAME]);
+       set = nf_tables_set_lookup(ctx.table, nla[NFTA_SET_NAME], genmask);
        if (IS_ERR(set))
                return PTR_ERR(set);
        if (!list_empty(&set->bindings))
        list_del_rcu(&binding->list);
 
        if (list_empty(&set->bindings) && set->flags & NFT_SET_ANONYMOUS &&
-           !(set->flags & NFT_SET_INACTIVE))
+           nft_is_active(ctx->net, set))
                nf_tables_set_destroy(ctx, set);
 }
 
        if (err < 0)
                return err;
 
-       set = nf_tables_set_lookup(ctx.table, nla[NFTA_SET_ELEM_LIST_SET]);
+       set = nf_tables_set_lookup(ctx.table, nla[NFTA_SET_ELEM_LIST_SET],
+                                  genmask);
        if (IS_ERR(set))
                return PTR_ERR(set);
-       if (set->flags & NFT_SET_INACTIVE)
-               return -ENOENT;
 
        event  = NFT_MSG_NEWSETELEM;
        event |= NFNL_SUBSYS_NFTABLES << 8;
        if (err < 0)
                return err;
 
-       set = nf_tables_set_lookup(ctx.table, nla[NFTA_SET_ELEM_LIST_SET]);
+       set = nf_tables_set_lookup(ctx.table, nla[NFTA_SET_ELEM_LIST_SET],
+                                  genmask);
        if (IS_ERR(set))
                return PTR_ERR(set);
-       if (set->flags & NFT_SET_INACTIVE)
-               return -ENOENT;
 
        if (nlh->nlmsg_flags & NLM_F_DUMP) {
                struct netlink_dump_control c = {
        if (err < 0)
                return err;
 
-       set = nf_tables_set_lookup(ctx.table, nla[NFTA_SET_ELEM_LIST_SET]);
+       set = nf_tables_set_lookup(ctx.table, nla[NFTA_SET_ELEM_LIST_SET],
+                                  genmask);
        if (IS_ERR(set)) {
                if (nla[NFTA_SET_ELEM_LIST_SET_ID]) {
                        set = nf_tables_set_lookup_byid(net,
-                                       nla[NFTA_SET_ELEM_LIST_SET_ID]);
+                                       nla[NFTA_SET_ELEM_LIST_SET_ID],
+                                       genmask);
                }
                if (IS_ERR(set))
                        return PTR_ERR(set);
        if (err < 0)
                return err;
 
-       set = nf_tables_set_lookup(ctx.table, nla[NFTA_SET_ELEM_LIST_SET]);
+       set = nf_tables_set_lookup(ctx.table, nla[NFTA_SET_ELEM_LIST_SET],
+                                  genmask);
        if (IS_ERR(set))
                return PTR_ERR(set);
        if (!list_empty(&set->bindings) && set->flags & NFT_SET_CONSTANT)
                                              NFT_MSG_DELRULE);
                        break;
                case NFT_MSG_NEWSET:
-                       nft_trans_set(trans)->flags &= ~NFT_SET_INACTIVE;
+                       nft_clear(net, nft_trans_set(trans));
                        /* This avoids hitting -EBUSY when deleting the table
                         * from the transaction.
                         */
                        nft_trans_destroy(trans);
                        break;
                case NFT_MSG_DELSET:
+                       list_del_rcu(&nft_trans_set(trans)->list);
                        nf_tables_set_notify(&trans->ctx, nft_trans_set(trans),
                                             NFT_MSG_DELSET, GFP_KERNEL);
                        break;
                        break;
                case NFT_MSG_DELSET:
                        trans->ctx.table->use++;
-                       list_add_tail_rcu(&nft_trans_set(trans)->list,
-                                         &trans->ctx.table->sets);
+                       nft_clear(trans->ctx.net, nft_trans_set(trans));
                        nft_trans_destroy(trans);
                        break;
                case NFT_MSG_NEWSETELEM:
        }
 
        list_for_each_entry(set, &ctx->table->sets, list) {
+               if (!nft_is_active_next(ctx->net, set))
+                       continue;
                if (!(set->flags & NFT_SET_MAP) ||
                    set->dtype != NFT_DATA_VERDICT)
                        continue;