Merge git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf

Pablo Neira Ayuso says:

====================
Netfilter fixes for net

1) Honor stateful expressions defined in the set from the dynset
   extension. The set definition provides a stateful expression
   that must be used by the dynset expression in case it is specified.

2) Missing timeout extension in the set element in the dynset
   extension leads to inconsistent ruleset listing, not allowing
   the user to restore timeout and expiration on ruleset reload.

3) Do not dump the stateful expression from the dynset extension
   if it coming from the set definition.

* git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf:
  netfilter: nft_dynset: dump expressions when set definition contains no expressions
  netfilter: nft_dynset: add timeout extension to template
  netfilter: nft_dynset: honor stateful expressions in set definition
====================

Link: https://lore.kernel.org/r/20210127132512.5472-1-pablo@netfilter.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Jakub Kicinski 2021-01-27 17:53:45 -08:00
commit 0f764eec3e
3 changed files with 30 additions and 18 deletions

View 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);

View 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;

View 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);
@ -306,8 +312,10 @@ static int nft_dynset_init(const struct nft_ctx *ctx,
nft_dynset_ext_add_expr(priv);
if (set->flags & NFT_SET_TIMEOUT) {
if (timeout || set->timeout)
if (timeout || set->timeout) {
nft_set_ext_add(&priv->tmpl, NFT_SET_EXT_TIMEOUT);
nft_set_ext_add(&priv->tmpl, NFT_SET_EXT_EXPIRATION);
}
}
priv->timeout = timeout;
@ -376,22 +384,25 @@ static int nft_dynset_dump(struct sk_buff *skb, const struct nft_expr *expr)
nf_jiffies64_to_msecs(priv->timeout),
NFTA_DYNSET_PAD))
goto nla_put_failure;
if (priv->num_exprs == 1) {
if (nft_expr_dump(skb, NFTA_DYNSET_EXPR, priv->expr_array[0]))
goto nla_put_failure;
} else if (priv->num_exprs > 1) {
struct nlattr *nest;
nest = nla_nest_start_noflag(skb, NFTA_DYNSET_EXPRESSIONS);
if (!nest)
goto nla_put_failure;
for (i = 0; i < priv->num_exprs; i++) {
if (nft_expr_dump(skb, NFTA_LIST_ELEM,
priv->expr_array[i]))
if (priv->set->num_exprs == 0) {
if (priv->num_exprs == 1) {
if (nft_expr_dump(skb, NFTA_DYNSET_EXPR,
priv->expr_array[0]))
goto nla_put_failure;
} else if (priv->num_exprs > 1) {
struct nlattr *nest;
nest = nla_nest_start_noflag(skb, NFTA_DYNSET_EXPRESSIONS);
if (!nest)
goto nla_put_failure;
for (i = 0; i < priv->num_exprs; i++) {
if (nft_expr_dump(skb, NFTA_LIST_ELEM,
priv->expr_array[i]))
goto nla_put_failure;
}
nla_nest_end(skb, nest);
}
nla_nest_end(skb, nest);
}
if (nla_put_be32(skb, NFTA_DYNSET_FLAGS, htonl(flags)))
goto nla_put_failure;