Commit 3971ca14 authored by Pablo Neira Ayuso's avatar Pablo Neira Ayuso

netfilter: nf_tables: parse element flags from nft_del_setelem()

Parse flags and pass them to the set via ->deactivate() to check if we
remove the right element from the intervals.
Signed-off-by: default avatarPablo Neira Ayuso <pablo@netfilter.org>
parent 0e9091d6
...@@ -3592,9 +3592,13 @@ static int nft_del_setelem(struct nft_ctx *ctx, struct nft_set *set, ...@@ -3592,9 +3592,13 @@ static int nft_del_setelem(struct nft_ctx *ctx, struct nft_set *set,
const struct nlattr *attr) const struct nlattr *attr)
{ {
struct nlattr *nla[NFTA_SET_ELEM_MAX + 1]; struct nlattr *nla[NFTA_SET_ELEM_MAX + 1];
struct nft_set_ext_tmpl tmpl;
struct nft_data_desc desc; struct nft_data_desc desc;
struct nft_set_elem elem; struct nft_set_elem elem;
struct nft_set_ext *ext;
struct nft_trans *trans; struct nft_trans *trans;
u32 flags = 0;
void *priv;
int err; int err;
err = nla_parse_nested(nla, NFTA_SET_ELEM_MAX, attr, err = nla_parse_nested(nla, NFTA_SET_ELEM_MAX, attr,
...@@ -3606,6 +3610,14 @@ static int nft_del_setelem(struct nft_ctx *ctx, struct nft_set *set, ...@@ -3606,6 +3610,14 @@ static int nft_del_setelem(struct nft_ctx *ctx, struct nft_set *set,
if (nla[NFTA_SET_ELEM_KEY] == NULL) if (nla[NFTA_SET_ELEM_KEY] == NULL)
goto err1; goto err1;
nft_set_ext_prepare(&tmpl);
err = nft_setelem_parse_flags(set, nla[NFTA_SET_ELEM_FLAGS], &flags);
if (err < 0)
return err;
if (flags != 0)
nft_set_ext_add(&tmpl, NFT_SET_EXT_FLAGS);
err = nft_data_init(ctx, &elem.key.val, sizeof(elem.key), &desc, err = nft_data_init(ctx, &elem.key.val, sizeof(elem.key), &desc,
nla[NFTA_SET_ELEM_KEY]); nla[NFTA_SET_ELEM_KEY]);
if (err < 0) if (err < 0)
...@@ -3615,24 +3627,40 @@ static int nft_del_setelem(struct nft_ctx *ctx, struct nft_set *set, ...@@ -3615,24 +3627,40 @@ static int nft_del_setelem(struct nft_ctx *ctx, struct nft_set *set,
if (desc.type != NFT_DATA_VALUE || desc.len != set->klen) if (desc.type != NFT_DATA_VALUE || desc.len != set->klen)
goto err2; goto err2;
nft_set_ext_add_length(&tmpl, NFT_SET_EXT_KEY, desc.len);
err = -ENOMEM;
elem.priv = nft_set_elem_init(set, &tmpl, elem.key.val.data, NULL, 0,
GFP_KERNEL);
if (elem.priv == NULL)
goto err2;
ext = nft_set_elem_ext(set, elem.priv);
if (flags)
*nft_set_ext_flags(ext) = flags;
trans = nft_trans_elem_alloc(ctx, NFT_MSG_DELSETELEM, set); trans = nft_trans_elem_alloc(ctx, NFT_MSG_DELSETELEM, set);
if (trans == NULL) { if (trans == NULL) {
err = -ENOMEM; err = -ENOMEM;
goto err2; goto err3;
} }
elem.priv = set->ops->deactivate(set, &elem); priv = set->ops->deactivate(set, &elem);
if (elem.priv == NULL) { if (priv == NULL) {
err = -ENOENT; err = -ENOENT;
goto err3; goto err4;
} }
kfree(elem.priv);
elem.priv = priv;
nft_trans_elem(trans) = elem; nft_trans_elem(trans) = elem;
list_add_tail(&trans->list, &ctx->net->nft.commit_list); list_add_tail(&trans->list, &ctx->net->nft.commit_list);
return 0; return 0;
err3: err4:
kfree(trans); kfree(trans);
err3:
kfree(elem.priv);
err2: err2:
nft_data_uninit(&elem.key.val, desc.type); nft_data_uninit(&elem.key.val, desc.type);
err1: err1:
......
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