@@ -5229,7 +5229,8 @@ static const struct nla_policy nft_set_elem_list_policy[NFTA_SET_ELEM_LIST_MAX +
52295229
52305230static int nft_set_elem_expr_dump (struct sk_buff * skb ,
52315231 const struct nft_set * set ,
5232- const struct nft_set_ext * ext )
5232+ const struct nft_set_ext * ext ,
5233+ bool reset )
52335234{
52345235 struct nft_set_elem_expr * elem_expr ;
52355236 u32 size , num_exprs = 0 ;
@@ -5242,7 +5243,7 @@ static int nft_set_elem_expr_dump(struct sk_buff *skb,
52425243
52435244 if (num_exprs == 1 ) {
52445245 expr = nft_setelem_expr_at (elem_expr , 0 );
5245- if (nft_expr_dump (skb , NFTA_SET_ELEM_EXPR , expr , false ) < 0 )
5246+ if (nft_expr_dump (skb , NFTA_SET_ELEM_EXPR , expr , reset ) < 0 )
52465247 return -1 ;
52475248
52485249 return 0 ;
@@ -5253,7 +5254,7 @@ static int nft_set_elem_expr_dump(struct sk_buff *skb,
52535254
52545255 nft_setelem_expr_foreach (expr , elem_expr , size ) {
52555256 expr = nft_setelem_expr_at (elem_expr , size );
5256- if (nft_expr_dump (skb , NFTA_LIST_ELEM , expr , false ) < 0 )
5257+ if (nft_expr_dump (skb , NFTA_LIST_ELEM , expr , reset ) < 0 )
52575258 goto nla_put_failure ;
52585259 }
52595260 nla_nest_end (skb , nest );
@@ -5266,11 +5267,13 @@ static int nft_set_elem_expr_dump(struct sk_buff *skb,
52665267
52675268static int nf_tables_fill_setelem (struct sk_buff * skb ,
52685269 const struct nft_set * set ,
5269- const struct nft_set_elem * elem )
5270+ const struct nft_set_elem * elem ,
5271+ bool reset )
52705272{
52715273 const struct nft_set_ext * ext = nft_set_elem_ext (set , elem -> priv );
52725274 unsigned char * b = skb_tail_pointer (skb );
52735275 struct nlattr * nest ;
5276+ u64 timeout = 0 ;
52745277
52755278 nest = nla_nest_start_noflag (skb , NFTA_LIST_ELEM );
52765279 if (nest == NULL )
@@ -5293,7 +5296,7 @@ static int nf_tables_fill_setelem(struct sk_buff *skb,
52935296 goto nla_put_failure ;
52945297
52955298 if (nft_set_ext_exists (ext , NFT_SET_EXT_EXPRESSIONS ) &&
5296- nft_set_elem_expr_dump (skb , set , ext ))
5299+ nft_set_elem_expr_dump (skb , set , ext , reset ))
52975300 goto nla_put_failure ;
52985301
52995302 if (nft_set_ext_exists (ext , NFT_SET_EXT_OBJREF ) &&
@@ -5306,11 +5309,15 @@ static int nf_tables_fill_setelem(struct sk_buff *skb,
53065309 htonl (* nft_set_ext_flags (ext ))))
53075310 goto nla_put_failure ;
53085311
5309- if (nft_set_ext_exists (ext , NFT_SET_EXT_TIMEOUT ) &&
5310- nla_put_be64 (skb , NFTA_SET_ELEM_TIMEOUT ,
5311- nf_jiffies64_to_msecs (* nft_set_ext_timeout (ext )),
5312- NFTA_SET_ELEM_PAD ))
5313- goto nla_put_failure ;
5312+ if (nft_set_ext_exists (ext , NFT_SET_EXT_TIMEOUT )) {
5313+ timeout = * nft_set_ext_timeout (ext );
5314+ if (nla_put_be64 (skb , NFTA_SET_ELEM_TIMEOUT ,
5315+ nf_jiffies64_to_msecs (timeout ),
5316+ NFTA_SET_ELEM_PAD ))
5317+ goto nla_put_failure ;
5318+ } else if (set -> flags & NFT_SET_TIMEOUT ) {
5319+ timeout = READ_ONCE (set -> timeout );
5320+ }
53145321
53155322 if (nft_set_ext_exists (ext , NFT_SET_EXT_EXPIRATION )) {
53165323 u64 expires , now = get_jiffies_64 ();
@@ -5325,6 +5332,9 @@ static int nf_tables_fill_setelem(struct sk_buff *skb,
53255332 nf_jiffies64_to_msecs (expires ),
53265333 NFTA_SET_ELEM_PAD ))
53275334 goto nla_put_failure ;
5335+
5336+ if (reset )
5337+ * nft_set_ext_expiration (ext ) = now + timeout ;
53285338 }
53295339
53305340 if (nft_set_ext_exists (ext , NFT_SET_EXT_USERDATA )) {
@@ -5348,6 +5358,7 @@ struct nft_set_dump_args {
53485358 const struct netlink_callback * cb ;
53495359 struct nft_set_iter iter ;
53505360 struct sk_buff * skb ;
5361+ bool reset ;
53515362};
53525363
53535364static int nf_tables_dump_setelem (const struct nft_ctx * ctx ,
@@ -5358,7 +5369,7 @@ static int nf_tables_dump_setelem(const struct nft_ctx *ctx,
53585369 struct nft_set_dump_args * args ;
53595370
53605371 args = container_of (iter , struct nft_set_dump_args , iter );
5361- return nf_tables_fill_setelem (args -> skb , set , elem );
5372+ return nf_tables_fill_setelem (args -> skb , set , elem , args -> reset );
53625373}
53635374
53645375struct nft_set_dump_ctx {
@@ -5367,7 +5378,7 @@ struct nft_set_dump_ctx {
53675378};
53685379
53695380static int nft_set_catchall_dump (struct net * net , struct sk_buff * skb ,
5370- const struct nft_set * set )
5381+ const struct nft_set * set , bool reset )
53715382{
53725383 struct nft_set_elem_catchall * catchall ;
53735384 u8 genmask = nft_genmask_cur (net );
@@ -5382,7 +5393,7 @@ static int nft_set_catchall_dump(struct net *net, struct sk_buff *skb,
53825393 continue ;
53835394
53845395 elem .priv = catchall -> elem ;
5385- ret = nf_tables_fill_setelem (skb , set , & elem );
5396+ ret = nf_tables_fill_setelem (skb , set , & elem , reset );
53865397 break ;
53875398 }
53885399
@@ -5400,6 +5411,7 @@ static int nf_tables_dump_set(struct sk_buff *skb, struct netlink_callback *cb)
54005411 bool set_found = false;
54015412 struct nlmsghdr * nlh ;
54025413 struct nlattr * nest ;
5414+ bool reset = false;
54035415 u32 portid , seq ;
54045416 int event ;
54055417
@@ -5447,8 +5459,12 @@ static int nf_tables_dump_set(struct sk_buff *skb, struct netlink_callback *cb)
54475459 if (nest == NULL )
54485460 goto nla_put_failure ;
54495461
5462+ if (NFNL_MSG_TYPE (cb -> nlh -> nlmsg_type ) == NFT_MSG_GETSETELEM_RESET )
5463+ reset = true;
5464+
54505465 args .cb = cb ;
54515466 args .skb = skb ;
5467+ args .reset = reset ;
54525468 args .iter .genmask = nft_genmask_cur (net );
54535469 args .iter .skip = cb -> args [0 ];
54545470 args .iter .count = 0 ;
@@ -5457,7 +5473,7 @@ static int nf_tables_dump_set(struct sk_buff *skb, struct netlink_callback *cb)
54575473 set -> ops -> walk (& dump_ctx -> ctx , set , & args .iter );
54585474
54595475 if (!args .iter .err && args .iter .count == cb -> args [0 ])
5460- args .iter .err = nft_set_catchall_dump (net , skb , set );
5476+ args .iter .err = nft_set_catchall_dump (net , skb , set , reset );
54615477 rcu_read_unlock ();
54625478
54635479 nla_nest_end (skb , nest );
@@ -5495,7 +5511,8 @@ static int nf_tables_fill_setelem_info(struct sk_buff *skb,
54955511 const struct nft_ctx * ctx , u32 seq ,
54965512 u32 portid , int event , u16 flags ,
54975513 const struct nft_set * set ,
5498- const struct nft_set_elem * elem )
5514+ const struct nft_set_elem * elem ,
5515+ bool reset )
54995516{
55005517 struct nlmsghdr * nlh ;
55015518 struct nlattr * nest ;
@@ -5516,7 +5533,7 @@ static int nf_tables_fill_setelem_info(struct sk_buff *skb,
55165533 if (nest == NULL )
55175534 goto nla_put_failure ;
55185535
5519- err = nf_tables_fill_setelem (skb , set , elem );
5536+ err = nf_tables_fill_setelem (skb , set , elem , reset );
55205537 if (err < 0 )
55215538 goto nla_put_failure ;
55225539
@@ -5622,7 +5639,7 @@ static int nft_setelem_get(struct nft_ctx *ctx, struct nft_set *set,
56225639}
56235640
56245641static int nft_get_set_elem (struct nft_ctx * ctx , struct nft_set * set ,
5625- const struct nlattr * attr )
5642+ const struct nlattr * attr , bool reset )
56265643{
56275644 struct nlattr * nla [NFTA_SET_ELEM_MAX + 1 ];
56285645 struct nft_set_elem elem ;
@@ -5666,7 +5683,8 @@ static int nft_get_set_elem(struct nft_ctx *ctx, struct nft_set *set,
56665683 return err ;
56675684
56685685 err = nf_tables_fill_setelem_info (skb , ctx , ctx -> seq , ctx -> portid ,
5669- NFT_MSG_NEWSETELEM , 0 , set , & elem );
5686+ NFT_MSG_NEWSETELEM , 0 , set , & elem ,
5687+ reset );
56705688 if (err < 0 )
56715689 goto err_fill_setelem ;
56725690
@@ -5690,6 +5708,7 @@ static int nf_tables_getsetelem(struct sk_buff *skb,
56905708 struct nft_set * set ;
56915709 struct nlattr * attr ;
56925710 struct nft_ctx ctx ;
5711+ bool reset = false;
56935712 int rem , err = 0 ;
56945713
56955714 table = nft_table_lookup (net , nla [NFTA_SET_ELEM_LIST_TABLE ], family ,
@@ -5724,8 +5743,11 @@ static int nf_tables_getsetelem(struct sk_buff *skb,
57245743 if (!nla [NFTA_SET_ELEM_LIST_ELEMENTS ])
57255744 return - EINVAL ;
57265745
5746+ if (NFNL_MSG_TYPE (info -> nlh -> nlmsg_type ) == NFT_MSG_GETSETELEM_RESET )
5747+ reset = true;
5748+
57275749 nla_for_each_nested (attr , nla [NFTA_SET_ELEM_LIST_ELEMENTS ], rem ) {
5728- err = nft_get_set_elem (& ctx , set , attr );
5750+ err = nft_get_set_elem (& ctx , set , attr , reset );
57295751 if (err < 0 ) {
57305752 NL_SET_BAD_ATTR (extack , attr );
57315753 break ;
@@ -5758,7 +5780,7 @@ static void nf_tables_setelem_notify(const struct nft_ctx *ctx,
57585780 flags |= ctx -> flags & (NLM_F_CREATE | NLM_F_EXCL );
57595781
57605782 err = nf_tables_fill_setelem_info (skb , ctx , 0 , portid , event , flags ,
5761- set , elem );
5783+ set , elem , false );
57625784 if (err < 0 ) {
57635785 kfree_skb (skb );
57645786 goto err ;
@@ -8715,6 +8737,12 @@ static const struct nfnl_callback nf_tables_cb[NFT_MSG_MAX] = {
87158737 .attr_count = NFTA_SET_ELEM_LIST_MAX ,
87168738 .policy = nft_set_elem_list_policy ,
87178739 },
8740+ [NFT_MSG_GETSETELEM_RESET ] = {
8741+ .call = nf_tables_getsetelem ,
8742+ .type = NFNL_CB_RCU ,
8743+ .attr_count = NFTA_SET_ELEM_LIST_MAX ,
8744+ .policy = nft_set_elem_list_policy ,
8745+ },
87188746 [NFT_MSG_DELSETELEM ] = {
87198747 .call = nf_tables_delsetelem ,
87208748 .type = NFNL_CB_BATCH ,
0 commit comments