netfilter: nf_tables: add nft_set_elem_expr_alloc()
authorPablo Neira Ayuso <pablo@netfilter.org>
Wed, 11 Mar 2020 14:30:12 +0000 (15:30 +0100)
committerPablo Neira Ayuso <pablo@netfilter.org>
Sun, 15 Mar 2020 14:27:47 +0000 (15:27 +0100)
Add helper function to create stateful expression.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
include/net/netfilter/nf_tables.h
net/netfilter/nf_tables_api.c
net/netfilter/nft_dynset.c

index 01f48b5..52b872a 100644 (file)
@@ -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,
index 7187b0d..1605a72 100644 (file)
@@ -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,
index 6837852..e106cf1 100644 (file)
@@ -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);