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: Pablo Neira Ayuso <pablo@netfilter.org>
This commit is contained in:
parent
0e9091d686
commit
3971ca1435
|
@ -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,
|
||||||
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,
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
elem.priv = set->ops->deactivate(set, &elem);
|
|
||||||
if (elem.priv == NULL) {
|
|
||||||
err = -ENOENT;
|
|
||||||
goto err3;
|
goto err3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
priv = set->ops->deactivate(set, &elem);
|
||||||
|
if (priv == NULL) {
|
||||||
|
err = -ENOENT;
|
||||||
|
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:
|
||||||
|
|
Loading…
Reference in New Issue