| @@ -3873,6 +3873,7 @@ static const struct nla_policy nft_set_elem_policy[NFTA_SET_ELEM_MAX + 1] = { · 3872 unmodified lines |
| 3873 | [NFTA_SET_ELEM_DATA] = { .type = NLA_NESTED }, | 3873 | [NFTA_SET_ELEM_DATA] = { .type = NLA_NESTED }, |
| 3874 | [NFTA_SET_ELEM_FLAGS] = { .type = NLA_U32 }, | 3874 | [NFTA_SET_ELEM_FLAGS] = { .type = NLA_U32 }, |
| 3875 | [NFTA_SET_ELEM_TIMEOUT] = { .type = NLA_U64 }, | 3875 | [NFTA_SET_ELEM_TIMEOUT] = { .type = NLA_U64 }, |
| | 3876 | [NFTA_SET_ELEM_EXPIRATION] = { .type = NLA_U64 }, |
| 3876 | [NFTA_SET_ELEM_USERDATA] = { .type = NLA_BINARY, | 3877 | [NFTA_SET_ELEM_USERDATA] = { .type = NLA_BINARY, |
| 3877 | .len = NFT_USERDATA_MAXLEN }, | 3878 | .len = NFT_USERDATA_MAXLEN }, |
| 3878 | [NFTA_SET_ELEM_EXPR] = { .type = NLA_NESTED }, | 3879 | [NFTA_SET_ELEM_EXPR] = { .type = NLA_NESTED }, |
| @@ -4326,7 +4327,7 @@ static struct nft_trans *nft_trans_elem_alloc(struct nft_ctx *ctx, · 447 unmodified lines |
| 4326 | void *nft_set_elem_init(const struct nft_set *set, | 4327 | void *nft_set_elem_init(const struct nft_set *set, |
| 4327 | const struct nft_set_ext_tmpl *tmpl, | 4328 | const struct nft_set_ext_tmpl *tmpl, |
| 4328 | const u32 *key, const u32 *data, | 4329 | const u32 *key, const u32 *data, |
| 4329 | u64 timeout, gfp_t gfp) | 4330 | u64 timeout, u64 expiration, gfp_t gfp) |
| 4330 | { | 4331 | { |
| 4331 | struct nft_set_ext *ext; | 4332 | struct nft_set_ext *ext; |
| 4332 | void *elem; | 4333 | void *elem; |
| @@ -4341,9 +4342,11 @@ void *nft_set_elem_init(const struct nft_set *set, · 8 unmodified lines |
| 4341 | memcpy(nft_set_ext_key(ext), key, set->klen); | 4342 | memcpy(nft_set_ext_key(ext), key, set->klen); |
| 4342 | if (nft_set_ext_exists(ext, NFT_SET_EXT_DATA)) | 4343 | if (nft_set_ext_exists(ext, NFT_SET_EXT_DATA)) |
| 4343 | memcpy(nft_set_ext_data(ext), data, set->dlen); | 4344 | memcpy(nft_set_ext_data(ext), data, set->dlen); |
| 4344 | if (nft_set_ext_exists(ext, NFT_SET_EXT_EXPIRATION)) | 4345 | if (nft_set_ext_exists(ext, NFT_SET_EXT_EXPIRATION)) { |
| 4345 | *nft_set_ext_expiration(ext) = | 4346 | *nft_set_ext_expiration(ext) = get_jiffies_64() + expiration; |
| 4346 | get_jiffies_64() + timeout; | 4347 | if (expiration == 0) |
| | 4348 | *nft_set_ext_expiration(ext) += timeout; |
| | 4349 | } |
| 4347 | if (nft_set_ext_exists(ext, NFT_SET_EXT_TIMEOUT)) | 4350 | if (nft_set_ext_exists(ext, NFT_SET_EXT_TIMEOUT)) |
| 4348 | *nft_set_ext_timeout(ext) = timeout; | 4351 | *nft_set_ext_timeout(ext) = timeout; |
| 4349 | | 4352 | |
| @@ -4408,6 +4411,7 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set, · 58 unmodified lines |
| 4408 | struct nft_trans *trans; | 4411 | struct nft_trans *trans; |
| 4409 | u32 flags = 0; | 4412 | u32 flags = 0; |
| 4410 | u64 timeout; | 4413 | u64 timeout; |
| | 4414 | u64 expiration; |
| 4411 | u8 ulen; | 4415 | u8 ulen; |
| 4412 | int err; | 4416 | int err; |
| 4413 | | 4417 | |
| @@ -4451,6 +4455,16 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set, · 37 unmodified lines |
| 4451 | timeout = set->timeout; | 4455 | timeout = set->timeout; |
| 4452 | } | 4456 | } |
| 4453 | | 4457 | |
| | 4458 | expiration = 0; |
| | 4459 | if (nla[NFTA_SET_ELEM_EXPIRATION] != NULL) { |
| | 4460 | if (!(set->flags & NFT_SET_TIMEOUT)) |
| | 4461 | return -EINVAL; |
| | 4462 | err = nf_msecs_to_jiffies64(nla[NFTA_SET_ELEM_EXPIRATION], |
| | 4463 | &expiration); |
| | 4464 | if (err) |
| | 4465 | return err; |
| | 4466 | } |
| | 4467 | |
| 4454 | err = nft_data_init(ctx, &elem.key.val, sizeof(elem.key), &d1, | 4468 | err = nft_data_init(ctx, &elem.key.val, sizeof(elem.key), &d1, |
| 4455 | nla[NFTA_SET_ELEM_KEY]); | 4469 | nla[NFTA_SET_ELEM_KEY]); |
| 4456 | if (err < 0) | 4470 | if (err < 0) |
| @@ -4533,7 +4547,7 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set, · 76 unmodified lines |
| 4533 | | 4547 | |
| 4534 | err = -ENOMEM; | 4548 | err = -ENOMEM; |
| 4535 | elem.priv = nft_set_elem_init(set, &tmpl, elem.key.val.data, data.data, | 4549 | elem.priv = nft_set_elem_init(set, &tmpl, elem.key.val.data, data.data, |
| 4536 | timeout, GFP_KERNEL); | 4550 | timeout, expiration, GFP_KERNEL); |
| 4537 | if (elem.priv == NULL) | 4551 | if (elem.priv == NULL) |
| 4538 | goto err3; | 4552 | goto err3; |
| 4539 | | 4553 | |
| @@ -4735,7 +4749,7 @@ static int nft_del_setelem(struct nft_ctx *ctx, struct nft_set *set, · 195 unmodified lines |
| 4735 | | 4749 | |
| 4736 | err = -ENOMEM; | 4750 | err = -ENOMEM; |
| 4737 | elem.priv = nft_set_elem_init(set, &tmpl, elem.key.val.data, NULL, 0, | 4751 | elem.priv = nft_set_elem_init(set, &tmpl, elem.key.val.data, NULL, 0, |
| 4738 | GFP_KERNEL); | 4752 | 0, GFP_KERNEL); |
| 4739 | if (elem.priv == NULL) | 4753 | if (elem.priv == NULL) |
| 4740 | goto err2; | 4754 | goto err2; |
| 4741 | | 4755 | |