*     @name: name of the chain
  *     @udlen: user data length
  *     @udata: user data in the chain
+ *     @rcu_head: rcu head for deferred release
  *     @blob_next: rule blob pointer to the next in the chain
  */
 struct nft_chain {
        char                            *name;
        u16                             udlen;
        u8                              *udata;
+       struct rcu_head                 rcu_head;
 
        /* Only used during control plane commit phase: */
        struct nft_rule_blob            *blob_next;
  *     @sets: sets in the table
  *     @objects: stateful objects in the table
  *     @flowtables: flow tables in the table
+ *     @net: netnamespace this table belongs to
  *     @hgenerator: handle generator state
  *     @handle: table handle
  *     @use: number of chain references to this table
        struct list_head                sets;
        struct list_head                objects;
        struct list_head                flowtables;
+       possible_net_t                  net;
        u64                             hgenerator;
        u64                             handle;
        u32                             use;
 
        INIT_LIST_HEAD(&table->sets);
        INIT_LIST_HEAD(&table->objects);
        INIT_LIST_HEAD(&table->flowtables);
+       write_pnet(&table->net, net);
        table->family = family;
        table->flags = flags;
        table->handle = ++nft_net->table_handle;
 }
 EXPORT_SYMBOL_GPL(nft_data_dump);
 
-int __nft_release_basechain(struct nft_ctx *ctx)
+static void __nft_release_basechain_now(struct nft_ctx *ctx)
 {
        struct nft_rule *rule, *nr;
 
-       if (WARN_ON(!nft_is_base_chain(ctx->chain)))
-               return 0;
-
-       nf_tables_unregister_hook(ctx->net, ctx->chain->table, ctx->chain);
        list_for_each_entry_safe(rule, nr, &ctx->chain->rules, list) {
                list_del(&rule->list);
-               nft_use_dec(&ctx->chain->use);
                nf_tables_rule_release(ctx, rule);
        }
+       nf_tables_chain_destroy(ctx->chain);
+}
+
+static void nft_release_basechain_rcu(struct rcu_head *head)
+{
+       struct nft_chain *chain = container_of(head, struct nft_chain, rcu_head);
+       struct nft_ctx ctx = {
+               .family = chain->table->family,
+               .chain  = chain,
+               .net    = read_pnet(&chain->table->net),
+       };
+
+       __nft_release_basechain_now(&ctx);
+       put_net(ctx.net);
+}
+
+int __nft_release_basechain(struct nft_ctx *ctx)
+{
+       struct nft_rule *rule;
+
+       if (WARN_ON_ONCE(!nft_is_base_chain(ctx->chain)))
+               return 0;
+
+       nf_tables_unregister_hook(ctx->net, ctx->chain->table, ctx->chain);
+       list_for_each_entry(rule, &ctx->chain->rules, list)
+               nft_use_dec(&ctx->chain->use);
+
        nft_chain_del(ctx->chain);
        nft_use_dec(&ctx->table->use);
-       nf_tables_chain_destroy(ctx->chain);
+
+       if (maybe_get_net(ctx->net))
+               call_rcu(&ctx->chain->rcu_head, nft_release_basechain_rcu);
+       else
+               __nft_release_basechain_now(ctx);
 
        return 0;
 }