Skip to content

Commit 4c5daea

Browse files
committed
netfilter: nf_tables: consolidate timeout extension for elements
Expiration and timeout are stored in separated set element extensions, but they are tightly coupled. Consolidate them in a single extension to simplify and prepare for set element updates. Signed-off-by: Pablo Neira Ayuso <[email protected]>
1 parent 73d3c04 commit 4c5daea

File tree

3 files changed

+30
-44
lines changed

3 files changed

+30
-44
lines changed

include/net/netfilter/nf_tables.h

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -687,7 +687,6 @@ void nf_tables_destroy_set(const struct nft_ctx *ctx, struct nft_set *set);
687687
* @NFT_SET_EXT_DATA: mapping data
688688
* @NFT_SET_EXT_FLAGS: element flags
689689
* @NFT_SET_EXT_TIMEOUT: element timeout
690-
* @NFT_SET_EXT_EXPIRATION: element expiration time
691690
* @NFT_SET_EXT_USERDATA: user data associated with the element
692691
* @NFT_SET_EXT_EXPRESSIONS: expressions associated with the element
693692
* @NFT_SET_EXT_OBJREF: stateful object reference associated with element
@@ -699,7 +698,6 @@ enum nft_set_extensions {
699698
NFT_SET_EXT_DATA,
700699
NFT_SET_EXT_FLAGS,
701700
NFT_SET_EXT_TIMEOUT,
702-
NFT_SET_EXT_EXPIRATION,
703701
NFT_SET_EXT_USERDATA,
704702
NFT_SET_EXT_EXPRESSIONS,
705703
NFT_SET_EXT_OBJREF,
@@ -811,14 +809,14 @@ static inline u8 *nft_set_ext_flags(const struct nft_set_ext *ext)
811809
return nft_set_ext(ext, NFT_SET_EXT_FLAGS);
812810
}
813811

814-
static inline u64 *nft_set_ext_timeout(const struct nft_set_ext *ext)
815-
{
816-
return nft_set_ext(ext, NFT_SET_EXT_TIMEOUT);
817-
}
812+
struct nft_timeout {
813+
u64 timeout;
814+
u64 expiration;
815+
};
818816

819-
static inline u64 *nft_set_ext_expiration(const struct nft_set_ext *ext)
817+
static inline struct nft_timeout *nft_set_ext_timeout(const struct nft_set_ext *ext)
820818
{
821-
return nft_set_ext(ext, NFT_SET_EXT_EXPIRATION);
819+
return nft_set_ext(ext, NFT_SET_EXT_TIMEOUT);
822820
}
823821

824822
static inline struct nft_userdata *nft_set_ext_userdata(const struct nft_set_ext *ext)
@@ -834,8 +832,8 @@ static inline struct nft_set_elem_expr *nft_set_ext_expr(const struct nft_set_ex
834832
static inline bool __nft_set_elem_expired(const struct nft_set_ext *ext,
835833
u64 tstamp)
836834
{
837-
return nft_set_ext_exists(ext, NFT_SET_EXT_EXPIRATION) &&
838-
time_after_eq64(tstamp, READ_ONCE(*nft_set_ext_expiration(ext)));
835+
return nft_set_ext_exists(ext, NFT_SET_EXT_TIMEOUT) &&
836+
time_after_eq64(tstamp, READ_ONCE(nft_set_ext_timeout(ext)->expiration));
839837
}
840838

841839
static inline bool nft_set_elem_expired(const struct nft_set_ext *ext)

net/netfilter/nf_tables_api.c

Lines changed: 17 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -5694,12 +5694,8 @@ const struct nft_set_ext_type nft_set_ext_types[] = {
56945694
.align = __alignof__(u8),
56955695
},
56965696
[NFT_SET_EXT_TIMEOUT] = {
5697-
.len = sizeof(u64),
5698-
.align = __alignof__(u64),
5699-
},
5700-
[NFT_SET_EXT_EXPIRATION] = {
5701-
.len = sizeof(u64),
5702-
.align = __alignof__(u64),
5697+
.len = sizeof(struct nft_timeout),
5698+
.align = __alignof__(struct nft_timeout),
57035699
},
57045700
[NFT_SET_EXT_USERDATA] = {
57055701
.len = sizeof(struct nft_userdata),
@@ -5818,16 +5814,16 @@ static int nf_tables_fill_setelem(struct sk_buff *skb,
58185814
htonl(*nft_set_ext_flags(ext))))
58195815
goto nla_put_failure;
58205816

5821-
if (nft_set_ext_exists(ext, NFT_SET_EXT_TIMEOUT) &&
5822-
nla_put_be64(skb, NFTA_SET_ELEM_TIMEOUT,
5823-
nf_jiffies64_to_msecs(*nft_set_ext_timeout(ext)),
5824-
NFTA_SET_ELEM_PAD))
5825-
goto nla_put_failure;
5826-
5827-
if (nft_set_ext_exists(ext, NFT_SET_EXT_EXPIRATION)) {
5817+
if (nft_set_ext_exists(ext, NFT_SET_EXT_TIMEOUT)) {
58285818
u64 expires, now = get_jiffies_64();
58295819

5830-
expires = READ_ONCE(*nft_set_ext_expiration(ext));
5820+
if (nft_set_ext_timeout(ext)->timeout != READ_ONCE(set->timeout) &&
5821+
nla_put_be64(skb, NFTA_SET_ELEM_TIMEOUT,
5822+
nf_jiffies64_to_msecs(nft_set_ext_timeout(ext)->timeout),
5823+
NFTA_SET_ELEM_PAD))
5824+
goto nla_put_failure;
5825+
5826+
expires = READ_ONCE(nft_set_ext_timeout(ext)->expiration);
58315827
if (time_before64(now, expires))
58325828
expires -= now;
58335829
else
@@ -6499,13 +6495,14 @@ struct nft_elem_priv *nft_set_elem_init(const struct nft_set *set,
64996495
nft_set_ext_data(ext), data, set->dlen) < 0)
65006496
goto err_ext_check;
65016497

6502-
if (nft_set_ext_exists(ext, NFT_SET_EXT_EXPIRATION)) {
6503-
*nft_set_ext_expiration(ext) = get_jiffies_64() + expiration;
6498+
if (nft_set_ext_exists(ext, NFT_SET_EXT_TIMEOUT)) {
6499+
nft_set_ext_timeout(ext)->timeout = timeout;
6500+
65046501
if (expiration == 0)
6505-
*nft_set_ext_expiration(ext) += timeout;
6502+
expiration = timeout;
6503+
6504+
nft_set_ext_timeout(ext)->expiration = get_jiffies_64() + expiration;
65066505
}
6507-
if (nft_set_ext_exists(ext, NFT_SET_EXT_TIMEOUT))
6508-
*nft_set_ext_timeout(ext) = timeout;
65096506

65106507
return elem;
65116508

@@ -7019,15 +7016,9 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
70197016
}
70207017

70217018
if (timeout > 0) {
7022-
err = nft_set_ext_add(&tmpl, NFT_SET_EXT_EXPIRATION);
7019+
err = nft_set_ext_add(&tmpl, NFT_SET_EXT_TIMEOUT);
70237020
if (err < 0)
70247021
goto err_parse_key_end;
7025-
7026-
if (timeout != set->timeout) {
7027-
err = nft_set_ext_add(&tmpl, NFT_SET_EXT_TIMEOUT);
7028-
if (err < 0)
7029-
goto err_parse_key_end;
7030-
}
70317022
}
70327023

70337024
if (num_exprs) {

net/netfilter/nft_dynset.c

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -94,9 +94,9 @@ void nft_dynset_eval(const struct nft_expr *expr,
9494
if (set->ops->update(set, &regs->data[priv->sreg_key], nft_dynset_new,
9595
expr, regs, &ext)) {
9696
if (priv->op == NFT_DYNSET_OP_UPDATE &&
97-
nft_set_ext_exists(ext, NFT_SET_EXT_EXPIRATION)) {
97+
nft_set_ext_exists(ext, NFT_SET_EXT_TIMEOUT)) {
9898
timeout = priv->timeout ? : READ_ONCE(set->timeout);
99-
WRITE_ONCE(*nft_set_ext_expiration(ext), get_jiffies_64() + timeout);
99+
WRITE_ONCE(nft_set_ext_timeout(ext)->expiration, get_jiffies_64() + timeout);
100100
}
101101

102102
nft_set_elem_update_expr(ext, regs, pkt);
@@ -312,12 +312,9 @@ static int nft_dynset_init(const struct nft_ctx *ctx,
312312
if (priv->num_exprs)
313313
nft_dynset_ext_add_expr(priv);
314314

315-
if (set->flags & NFT_SET_TIMEOUT) {
316-
if (timeout || READ_ONCE(set->timeout)) {
317-
nft_set_ext_add(&priv->tmpl, NFT_SET_EXT_TIMEOUT);
318-
nft_set_ext_add(&priv->tmpl, NFT_SET_EXT_EXPIRATION);
319-
}
320-
}
315+
if (set->flags & NFT_SET_TIMEOUT &&
316+
(timeout || READ_ONCE(set->timeout)))
317+
nft_set_ext_add(&priv->tmpl, NFT_SET_EXT_TIMEOUT);
321318

322319
priv->timeout = timeout;
323320

0 commit comments

Comments
 (0)