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

netfilter: nf_tables: add elements with stateful expressions

Update nft_add_set_elem() to handle the NFTA_SET_ELEM_EXPR netlink
attribute. This patch allows users to to add elements with stateful
expressions.
Signed-off-by: default avatarPablo Neira Ayuso <pablo@netfilter.org>
parent 795a6d6b
...@@ -4891,6 +4891,7 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set, ...@@ -4891,6 +4891,7 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
struct nft_set_elem elem; struct nft_set_elem elem;
struct nft_set_binding *binding; struct nft_set_binding *binding;
struct nft_object *obj = NULL; struct nft_object *obj = NULL;
struct nft_expr *expr = NULL;
struct nft_userdata *udata; struct nft_userdata *udata;
struct nft_data_desc desc; struct nft_data_desc desc;
struct nft_data data; struct nft_data data;
...@@ -4958,10 +4959,17 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set, ...@@ -4958,10 +4959,17 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
return err; return err;
} }
if (nla[NFTA_SET_ELEM_EXPR] != NULL) {
expr = nft_set_elem_expr_alloc(ctx, set,
nla[NFTA_SET_ELEM_EXPR]);
if (IS_ERR(expr))
return PTR_ERR(expr);
}
err = nft_setelem_parse_key(ctx, set, &elem.key.val, err = nft_setelem_parse_key(ctx, set, &elem.key.val,
nla[NFTA_SET_ELEM_KEY]); nla[NFTA_SET_ELEM_KEY]);
if (err < 0) if (err < 0)
return err; goto err_set_elem_expr;
nft_set_ext_add_length(&tmpl, NFT_SET_EXT_KEY, set->klen); nft_set_ext_add_length(&tmpl, NFT_SET_EXT_KEY, set->klen);
...@@ -4980,6 +4988,10 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set, ...@@ -4980,6 +4988,10 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
nft_set_ext_add(&tmpl, NFT_SET_EXT_TIMEOUT); nft_set_ext_add(&tmpl, NFT_SET_EXT_TIMEOUT);
} }
if (expr)
nft_set_ext_add_length(&tmpl, NFT_SET_EXT_EXPR,
expr->ops->size);
if (nla[NFTA_SET_ELEM_OBJREF] != NULL) { if (nla[NFTA_SET_ELEM_OBJREF] != NULL) {
if (!(set->flags & NFT_SET_OBJECT)) { if (!(set->flags & NFT_SET_OBJECT)) {
err = -EINVAL; err = -EINVAL;
...@@ -5064,6 +5076,10 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set, ...@@ -5064,6 +5076,10 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
*nft_set_ext_obj(ext) = obj; *nft_set_ext_obj(ext) = obj;
obj->use++; obj->use++;
} }
if (expr) {
memcpy(nft_set_ext_expr(ext), expr, expr->ops->size);
kfree(expr);
}
trans = nft_trans_elem_alloc(ctx, NFT_MSG_NEWSETELEM, set); trans = nft_trans_elem_alloc(ctx, NFT_MSG_NEWSETELEM, set);
if (trans == NULL) if (trans == NULL)
...@@ -5119,6 +5135,9 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set, ...@@ -5119,6 +5135,9 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
nft_data_release(&elem.key_end.val, NFT_DATA_VALUE); nft_data_release(&elem.key_end.val, NFT_DATA_VALUE);
err_parse_key: err_parse_key:
nft_data_release(&elem.key.val, NFT_DATA_VALUE); nft_data_release(&elem.key.val, NFT_DATA_VALUE);
err_set_elem_expr:
if (expr != NULL)
nft_expr_destroy(ctx, expr);
return err; return err;
} }
......
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