Commit 371ebcbb authored by Pablo Neira Ayuso's avatar Pablo Neira Ayuso

netfilter: nf_tables: add destroy_clone expression

Before this patch, cloned expressions are released via ->destroy. This
is a problem for the new connlimit expression since the ->destroy path
drop a reference on the conntrack modules and it unregisters hooks. The
new ->destroy_clone provides context that this expression is being
released from the packet path, so it is mirroring ->clone(), where
neither module reference is dropped nor hooks need to be unregistered -
because this done from the control plane path from the ->init() path.
Signed-off-by: default avatarPablo Neira Ayuso <pablo@netfilter.org>
parent 79b174ad
...@@ -745,6 +745,8 @@ struct nft_expr_ops { ...@@ -745,6 +745,8 @@ struct nft_expr_ops {
const struct nft_expr *expr); const struct nft_expr *expr);
void (*destroy)(const struct nft_ctx *ctx, void (*destroy)(const struct nft_ctx *ctx,
const struct nft_expr *expr); const struct nft_expr *expr);
void (*destroy_clone)(const struct nft_ctx *ctx,
const struct nft_expr *expr);
int (*dump)(struct sk_buff *skb, int (*dump)(struct sk_buff *skb,
const struct nft_expr *expr); const struct nft_expr *expr);
int (*validate)(const struct nft_ctx *ctx, int (*validate)(const struct nft_ctx *ctx,
......
...@@ -4046,8 +4046,16 @@ void nft_set_elem_destroy(const struct nft_set *set, void *elem, ...@@ -4046,8 +4046,16 @@ void nft_set_elem_destroy(const struct nft_set *set, void *elem,
nft_data_release(nft_set_ext_key(ext), NFT_DATA_VALUE); nft_data_release(nft_set_ext_key(ext), NFT_DATA_VALUE);
if (nft_set_ext_exists(ext, NFT_SET_EXT_DATA)) if (nft_set_ext_exists(ext, NFT_SET_EXT_DATA))
nft_data_release(nft_set_ext_data(ext), set->dtype); nft_data_release(nft_set_ext_data(ext), set->dtype);
if (destroy_expr && nft_set_ext_exists(ext, NFT_SET_EXT_EXPR)) if (destroy_expr && nft_set_ext_exists(ext, NFT_SET_EXT_EXPR)) {
nf_tables_expr_destroy(&ctx, nft_set_ext_expr(ext)); 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)) if (nft_set_ext_exists(ext, NFT_SET_EXT_OBJREF))
(*nft_set_ext_obj(ext))->use--; (*nft_set_ext_obj(ext))->use--;
kfree(elem); kfree(elem);
......
...@@ -258,6 +258,7 @@ static const struct nft_expr_ops nft_counter_ops = { ...@@ -258,6 +258,7 @@ static const struct nft_expr_ops nft_counter_ops = {
.eval = nft_counter_eval, .eval = nft_counter_eval,
.init = nft_counter_init, .init = nft_counter_init,
.destroy = nft_counter_destroy, .destroy = nft_counter_destroy,
.destroy_clone = nft_counter_destroy,
.dump = nft_counter_dump, .dump = nft_counter_dump,
.clone = nft_counter_clone, .clone = nft_counter_clone,
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment