Commit b8e20400 authored by Pablo Neira Ayuso's avatar Pablo Neira Ayuso

netfilter: nft_compat: use .release_ops and remove list of extension

Add .release_ops, that is called in case of error at a later stage in
the expression initialization path, ie. .select_ops() has been already
set up operations and that needs to be undone. This allows us to unwind
.select_ops from the error path, ie. release the dynamic operations for
this extension.

Moreover, allocate one single operation instead of recycling them, this
comes at the cost of consuming a bit more memory per rule, but it
simplifies the infrastructure.
Signed-off-by: default avatarPablo Neira Ayuso <pablo@netfilter.org>
parent ff8285f8
...@@ -690,10 +690,12 @@ static inline void nft_set_gc_batch_add(struct nft_set_gc_batch *gcb, ...@@ -690,10 +690,12 @@ static inline void nft_set_gc_batch_add(struct nft_set_gc_batch *gcb,
gcb->elems[gcb->head.cnt++] = elem; gcb->elems[gcb->head.cnt++] = elem;
} }
struct nft_expr_ops;
/** /**
* struct nft_expr_type - nf_tables expression type * struct nft_expr_type - nf_tables expression type
* *
* @select_ops: function to select nft_expr_ops * @select_ops: function to select nft_expr_ops
* @release_ops: release nft_expr_ops
* @ops: default ops, used when no select_ops functions is present * @ops: default ops, used when no select_ops functions is present
* @list: used internally * @list: used internally
* @name: Identifier * @name: Identifier
...@@ -706,6 +708,7 @@ static inline void nft_set_gc_batch_add(struct nft_set_gc_batch *gcb, ...@@ -706,6 +708,7 @@ static inline void nft_set_gc_batch_add(struct nft_set_gc_batch *gcb,
struct nft_expr_type { struct nft_expr_type {
const struct nft_expr_ops *(*select_ops)(const struct nft_ctx *, const struct nft_expr_ops *(*select_ops)(const struct nft_ctx *,
const struct nlattr * const tb[]); const struct nlattr * const tb[]);
void (*release_ops)(const struct nft_expr_ops *ops);
const struct nft_expr_ops *ops; const struct nft_expr_ops *ops;
struct list_head list; struct list_head list;
const char *name; const char *name;
......
...@@ -2172,6 +2172,7 @@ struct nft_expr *nft_expr_init(const struct nft_ctx *ctx, ...@@ -2172,6 +2172,7 @@ struct nft_expr *nft_expr_init(const struct nft_ctx *ctx,
{ {
struct nft_expr_info info; struct nft_expr_info info;
struct nft_expr *expr; struct nft_expr *expr;
struct module *owner;
int err; int err;
err = nf_tables_expr_parse(ctx, nla, &info); err = nf_tables_expr_parse(ctx, nla, &info);
...@@ -2191,7 +2192,11 @@ struct nft_expr *nft_expr_init(const struct nft_ctx *ctx, ...@@ -2191,7 +2192,11 @@ struct nft_expr *nft_expr_init(const struct nft_ctx *ctx,
err3: err3:
kfree(expr); kfree(expr);
err2: err2:
module_put(info.ops->type->owner); owner = info.ops->type->owner;
if (info.ops->type->release_ops)
info.ops->type->release_ops(info.ops);
module_put(owner);
err1: err1:
return ERR_PTR(err); return ERR_PTR(err);
} }
......
This diff is collapsed.
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