const struct nft_expr *expr);
        void                            (*destroy)(const struct nft_ctx *ctx,
                                                   const struct nft_expr *expr);
+       void                            (*destroy_clone)(const struct nft_ctx *ctx,
+                                                        const struct nft_expr *expr);
        int                             (*dump)(struct sk_buff *skb,
                                                const struct nft_expr *expr);
        int                             (*validate)(const struct nft_ctx *ctx,
 
        nft_data_release(nft_set_ext_key(ext), NFT_DATA_VALUE);
        if (nft_set_ext_exists(ext, NFT_SET_EXT_DATA))
                nft_data_release(nft_set_ext_data(ext), set->dtype);
-       if (destroy_expr && nft_set_ext_exists(ext, NFT_SET_EXT_EXPR))
-               nf_tables_expr_destroy(&ctx, nft_set_ext_expr(ext));
+       if (destroy_expr && nft_set_ext_exists(ext, NFT_SET_EXT_EXPR)) {
+               struct nft_expr *expr = nft_set_ext_expr(ext);
+
+               if (expr->ops->destroy_clone) {
+                       expr->ops->destroy_clone(&ctx, expr);
+                       module_put(expr->ops->type->owner);
+               } else {
+                       nf_tables_expr_destroy(&ctx, expr);
+               }
+       }
        if (nft_set_ext_exists(ext, NFT_SET_EXT_OBJREF))
                (*nft_set_ext_obj(ext))->use--;
        kfree(elem);
 
        .eval           = nft_counter_eval,
        .init           = nft_counter_init,
        .destroy        = nft_counter_destroy,
+       .destroy_clone  = nft_counter_destroy,
        .dump           = nft_counter_dump,
        .clone          = nft_counter_clone,
 };