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: Pablo Neira Ayuso <pablo@netfilter.org>
This commit is contained in:
Родитель
79b174ade1
Коммит
371ebcbb9e
|
@ -745,6 +745,8 @@ struct nft_expr_ops {
|
|||
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,
|
||||
|
|
|
@ -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);
|
||||
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);
|
||||
|
|
|
@ -258,6 +258,7 @@ static const struct nft_expr_ops nft_counter_ops = {
|
|||
.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,
|
||||
};
|
||||
|
|
Загрузка…
Ссылка в новой задаче