Commit a7fc9368 authored by Pablo Neira Ayuso's avatar Pablo Neira Ayuso
Browse files

netfilter: nf_tables: add nft_set_elem_expr_alloc()



Add helper function to create stateful expression.

Signed-off-by: default avatarPablo Neira Ayuso <pablo@netfilter.org>
parent eb16933a
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -666,6 +666,10 @@ static inline struct nft_object **nft_set_ext_obj(const struct nft_set_ext *ext)
	return nft_set_ext(ext, NFT_SET_EXT_OBJREF);
}

struct nft_expr *nft_set_elem_expr_alloc(const struct nft_ctx *ctx,
					 const struct nft_set *set,
					 const struct nlattr *attr);

void *nft_set_elem_init(const struct nft_set *set,
			const struct nft_set_ext_tmpl *tmpl,
			const u32 *key, const u32 *key_end, const u32 *data,
+30 −0
Original line number Diff line number Diff line
@@ -4779,6 +4779,36 @@ static struct nft_trans *nft_trans_elem_alloc(struct nft_ctx *ctx,
	return trans;
}

struct nft_expr *nft_set_elem_expr_alloc(const struct nft_ctx *ctx,
					 const struct nft_set *set,
					 const struct nlattr *attr)
{
	struct nft_expr *expr;
	int err;

	expr = nft_expr_init(ctx, attr);
	if (IS_ERR(expr))
		return expr;

	err = -EOPNOTSUPP;
	if (!(expr->ops->type->flags & NFT_EXPR_STATEFUL))
		goto err_set_elem_expr;

	if (expr->ops->type->flags & NFT_EXPR_GC) {
		if (set->flags & NFT_SET_TIMEOUT)
			goto err_set_elem_expr;
		if (!set->ops->gc_init)
			goto err_set_elem_expr;
		set->ops->gc_init(set);
	}

	return expr;

err_set_elem_expr:
	nft_expr_destroy(ctx, expr);
	return ERR_PTR(err);
}

void *nft_set_elem_init(const struct nft_set *set,
			const struct nft_set_ext_tmpl *tmpl,
			const u32 *key, const u32 *key_end,
+2 −13
Original line number Diff line number Diff line
@@ -206,21 +206,10 @@ static int nft_dynset_init(const struct nft_ctx *ctx,
		if (!(set->flags & NFT_SET_EVAL))
			return -EINVAL;

		priv->expr = nft_expr_init(ctx, tb[NFTA_DYNSET_EXPR]);
		priv->expr = nft_set_elem_expr_alloc(ctx, set,
						     tb[NFTA_DYNSET_EXPR]);
		if (IS_ERR(priv->expr))
			return PTR_ERR(priv->expr);

		err = -EOPNOTSUPP;
		if (!(priv->expr->ops->type->flags & NFT_EXPR_STATEFUL))
			goto err1;

		if (priv->expr->ops->type->flags & NFT_EXPR_GC) {
			if (set->flags & NFT_SET_TIMEOUT)
				goto err1;
			if (!set->ops->gc_init)
				goto err1;
			set->ops->gc_init(set);
		}
	}

	nft_set_ext_prepare(&priv->tmpl);