static const struct nla_policy nft_table_policy[NFTA_TABLE_MAX + 1] = {
        [NFTA_TABLE_NAME]       = { .type = NLA_STRING },
+       [NFTA_TABLE_FLAGS]      = { .type = NLA_U32 },
 };
 
 static int nf_tables_fill_table_info(struct sk_buff *skb, u32 portid, u32 seq,
        nfmsg->version          = NFNETLINK_V0;
        nfmsg->res_id           = 0;
 
-       if (nla_put_string(skb, NFTA_TABLE_NAME, table->name))
+       if (nla_put_string(skb, NFTA_TABLE_NAME, table->name) ||
+           nla_put_be32(skb, NFTA_TABLE_FLAGS, htonl(table->flags)))
                goto nla_put_failure;
 
        return nlmsg_end(skb, nlh);
        return err;
 }
 
+static int nf_tables_table_enable(struct nft_table *table)
+{
+       struct nft_chain *chain;
+       int err, i = 0;
+
+       list_for_each_entry(chain, &table->chains, list) {
+               err = nf_register_hook(&nft_base_chain(chain)->ops);
+               if (err < 0)
+                       goto err;
+
+               i++;
+       }
+       return 0;
+err:
+       list_for_each_entry(chain, &table->chains, list) {
+               if (i-- <= 0)
+                       break;
+
+               nf_unregister_hook(&nft_base_chain(chain)->ops);
+       }
+       return err;
+}
+
+static int nf_tables_table_disable(struct nft_table *table)
+{
+       struct nft_chain *chain;
+
+       list_for_each_entry(chain, &table->chains, list)
+               nf_unregister_hook(&nft_base_chain(chain)->ops);
+
+       return 0;
+}
+
+static int nf_tables_updtable(struct sock *nlsk, struct sk_buff *skb,
+                             const struct nlmsghdr *nlh,
+                             const struct nlattr * const nla[],
+                             struct nft_af_info *afi, struct nft_table *table)
+{
+       const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
+       int family = nfmsg->nfgen_family, ret = 0;
+
+       if (nla[NFTA_TABLE_FLAGS]) {
+               __be32 flags;
+
+               flags = ntohl(nla_get_be32(nla[NFTA_TABLE_FLAGS]));
+               if (flags & ~NFT_TABLE_F_DORMANT)
+                       return -EINVAL;
+
+               if ((flags & NFT_TABLE_F_DORMANT) &&
+                   !(table->flags & NFT_TABLE_F_DORMANT)) {
+                       ret = nf_tables_table_disable(table);
+                       if (ret >= 0)
+                               table->flags |= NFT_TABLE_F_DORMANT;
+               } else if (!(flags & NFT_TABLE_F_DORMANT) &&
+                          table->flags & NFT_TABLE_F_DORMANT) {
+                       ret = nf_tables_table_enable(table);
+                       if (ret >= 0)
+                               table->flags &= ~NFT_TABLE_F_DORMANT;
+               }
+               if (ret < 0)
+                       goto err;
+       }
+
+       nf_tables_table_notify(skb, nlh, table, NFT_MSG_NEWTABLE, family);
+err:
+       return ret;
+}
+
 static int nf_tables_newtable(struct sock *nlsk, struct sk_buff *skb,
                              const struct nlmsghdr *nlh,
                              const struct nlattr * const nla[])
                        return -EEXIST;
                if (nlh->nlmsg_flags & NLM_F_REPLACE)
                        return -EOPNOTSUPP;
-               return 0;
+               return nf_tables_updtable(nlsk, skb, nlh, nla, afi, table);
        }
 
        table = kzalloc(sizeof(*table) + nla_len(name), GFP_KERNEL);
        INIT_LIST_HEAD(&table->chains);
        INIT_LIST_HEAD(&table->sets);
 
+       if (nla[NFTA_TABLE_FLAGS]) {
+               __be32 flags;
+
+               flags = ntohl(nla_get_be32(nla[NFTA_TABLE_FLAGS]));
+               if (flags & ~NFT_TABLE_F_DORMANT) {
+                       kfree(table);
+                       return -EINVAL;
+               }
+
+               table->flags |= flags;
+       }
+
        list_add_tail(&table->list, &afi->tables);
        nf_tables_table_notify(skb, nlh, table, NFT_MSG_NEWTABLE, family);
        return 0;
        chain->handle = nf_tables_alloc_handle(table);
        nla_strlcpy(chain->name, name, NFT_CHAIN_MAXNAMELEN);
 
-       list_add_tail(&chain->list, &table->chains);
-       table->use++;
-
-       if (chain->flags & NFT_BASE_CHAIN) {
+       if (!(table->flags & NFT_TABLE_F_DORMANT) &&
+           chain->flags & NFT_BASE_CHAIN) {
                err = nf_register_hook(&nft_base_chain(chain)->ops);
                if (err < 0) {
                        free_percpu(basechain->stats);
                        return err;
                }
        }
+       list_add_tail(&chain->list, &table->chains);
+       table->use++;
 notify:
        nf_tables_chain_notify(skb, nlh, table, chain, NFT_MSG_NEWCHAIN,
                               family);
        list_del(&chain->list);
        table->use--;
 
-       if (chain->flags & NFT_BASE_CHAIN)
+       if (!(table->flags & NFT_TABLE_F_DORMANT) &&
+           chain->flags & NFT_BASE_CHAIN)
                nf_unregister_hook(&nft_base_chain(chain)->ops);
 
        nf_tables_chain_notify(skb, nlh, table, chain, NFT_MSG_DELCHAIN,