netfilter: nft_dynset: honor stateful expressions in set definition
authorPablo Neira Ayuso <pablo@netfilter.org>
Sat, 16 Jan 2021 11:26:46 +0000 (12:26 +0100)
committerPablo Neira Ayuso <pablo@netfilter.org>
Sat, 16 Jan 2021 17:57:26 +0000 (18:57 +0100)
If the set definition contains stateful expressions, allocate them for
the newly added entries from the packet path.

Fixes: 65038428b2c6 ("netfilter: nf_tables: allow to specify stateful expression in set definition")
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 f4af836..4b6ecf5 100644 (file)
@@ -721,6 +721,8 @@ 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,
                        u64 timeout, u64 expiration, gfp_t gfp);
+int nft_set_elem_expr_clone(const struct nft_ctx *ctx, struct nft_set *set,
+                           struct nft_expr *expr_array[]);
 void nft_set_elem_destroy(const struct nft_set *set, void *elem,
                          bool destroy_expr);
 
index 15c467f..8d3aa97 100644 (file)
@@ -5235,9 +5235,8 @@ static void nf_tables_set_elem_destroy(const struct nft_ctx *ctx,
        kfree(elem);
 }
 
-static int nft_set_elem_expr_clone(const struct nft_ctx *ctx,
-                                  struct nft_set *set,
-                                  struct nft_expr *expr_array[])
+int nft_set_elem_expr_clone(const struct nft_ctx *ctx, struct nft_set *set,
+                           struct nft_expr *expr_array[])
 {
        struct nft_expr *expr;
        int err, i, k;
index 0b053f7..8620474 100644 (file)
@@ -295,6 +295,12 @@ static int nft_dynset_init(const struct nft_ctx *ctx,
                        err = -EOPNOTSUPP;
                        goto err_expr_free;
                }
+       } else if (set->num_exprs > 0) {
+               err = nft_set_elem_expr_clone(ctx, set, priv->expr_array);
+               if (err < 0)
+                       return err;
+
+               priv->num_exprs = set->num_exprs;
        }
 
        nft_set_ext_prepare(&priv->tmpl);