@@ -5080,7 +5080,8 @@ static const struct nla_policy nft_set_elem_list_policy[NFTA_SET_ELEM_LIST_MAX +
50805080
50815081static int nft_set_elem_expr_dump (struct sk_buff * skb ,
50825082 const struct nft_set * set ,
5083- const struct nft_set_ext * ext )
5083+ const struct nft_set_ext * ext ,
5084+ bool reset )
50845085{
50855086 struct nft_set_elem_expr * elem_expr ;
50865087 u32 size , num_exprs = 0 ;
@@ -5093,7 +5094,7 @@ static int nft_set_elem_expr_dump(struct sk_buff *skb,
50935094
50945095 if (num_exprs == 1 ) {
50955096 expr = nft_setelem_expr_at (elem_expr , 0 );
5096- if (nft_expr_dump (skb , NFTA_SET_ELEM_EXPR , expr , false ) < 0 )
5097+ if (nft_expr_dump (skb , NFTA_SET_ELEM_EXPR , expr , reset ) < 0 )
50975098 return -1 ;
50985099
50995100 return 0 ;
@@ -5104,7 +5105,7 @@ static int nft_set_elem_expr_dump(struct sk_buff *skb,
51045105
51055106 nft_setelem_expr_foreach (expr , elem_expr , size ) {
51065107 expr = nft_setelem_expr_at (elem_expr , size );
5107- if (nft_expr_dump (skb , NFTA_LIST_ELEM , expr , false ) < 0 )
5108+ if (nft_expr_dump (skb , NFTA_LIST_ELEM , expr , reset ) < 0 )
51085109 goto nla_put_failure ;
51095110 }
51105111 nla_nest_end (skb , nest );
@@ -5117,11 +5118,13 @@ static int nft_set_elem_expr_dump(struct sk_buff *skb,
51175118
51185119static int nf_tables_fill_setelem (struct sk_buff * skb ,
51195120 const struct nft_set * set ,
5120- const struct nft_set_elem * elem )
5121+ const struct nft_set_elem * elem ,
5122+ bool reset )
51215123{
51225124 const struct nft_set_ext * ext = nft_set_elem_ext (set , elem -> priv );
51235125 unsigned char * b = skb_tail_pointer (skb );
51245126 struct nlattr * nest ;
5127+ u64 timeout = 0 ;
51255128
51265129 nest = nla_nest_start_noflag (skb , NFTA_LIST_ELEM );
51275130 if (nest == NULL )
@@ -5144,7 +5147,7 @@ static int nf_tables_fill_setelem(struct sk_buff *skb,
51445147 goto nla_put_failure ;
51455148
51465149 if (nft_set_ext_exists (ext , NFT_SET_EXT_EXPRESSIONS ) &&
5147- nft_set_elem_expr_dump (skb , set , ext ))
5150+ nft_set_elem_expr_dump (skb , set , ext , reset ))
51485151 goto nla_put_failure ;
51495152
51505153 if (nft_set_ext_exists (ext , NFT_SET_EXT_OBJREF ) &&
@@ -5157,11 +5160,15 @@ static int nf_tables_fill_setelem(struct sk_buff *skb,
51575160 htonl (* nft_set_ext_flags (ext ))))
51585161 goto nla_put_failure ;
51595162
5160- if (nft_set_ext_exists (ext , NFT_SET_EXT_TIMEOUT ) &&
5161- nla_put_be64 (skb , NFTA_SET_ELEM_TIMEOUT ,
5162- nf_jiffies64_to_msecs (* nft_set_ext_timeout (ext )),
5163- NFTA_SET_ELEM_PAD ))
5164- goto nla_put_failure ;
5163+ if (nft_set_ext_exists (ext , NFT_SET_EXT_TIMEOUT )) {
5164+ timeout = * nft_set_ext_timeout (ext );
5165+ if (nla_put_be64 (skb , NFTA_SET_ELEM_TIMEOUT ,
5166+ nf_jiffies64_to_msecs (timeout ),
5167+ NFTA_SET_ELEM_PAD ))
5168+ goto nla_put_failure ;
5169+ } else if (set -> flags & NFT_SET_TIMEOUT ) {
5170+ timeout = READ_ONCE (set -> timeout );
5171+ }
51655172
51665173 if (nft_set_ext_exists (ext , NFT_SET_EXT_EXPIRATION )) {
51675174 u64 expires , now = get_jiffies_64 ();
@@ -5176,6 +5183,9 @@ static int nf_tables_fill_setelem(struct sk_buff *skb,
51765183 nf_jiffies64_to_msecs (expires ),
51775184 NFTA_SET_ELEM_PAD ))
51785185 goto nla_put_failure ;
5186+
5187+ if (reset )
5188+ * nft_set_ext_expiration (ext ) = now + timeout ;
51795189 }
51805190
51815191 if (nft_set_ext_exists (ext , NFT_SET_EXT_USERDATA )) {
@@ -5199,6 +5209,7 @@ struct nft_set_dump_args {
51995209 const struct netlink_callback * cb ;
52005210 struct nft_set_iter iter ;
52015211 struct sk_buff * skb ;
5212+ bool reset ;
52025213};
52035214
52045215static int nf_tables_dump_setelem (const struct nft_ctx * ctx ,
@@ -5209,7 +5220,7 @@ static int nf_tables_dump_setelem(const struct nft_ctx *ctx,
52095220 struct nft_set_dump_args * args ;
52105221
52115222 args = container_of (iter , struct nft_set_dump_args , iter );
5212- return nf_tables_fill_setelem (args -> skb , set , elem );
5223+ return nf_tables_fill_setelem (args -> skb , set , elem , args -> reset );
52135224}
52145225
52155226struct nft_set_dump_ctx {
@@ -5218,7 +5229,7 @@ struct nft_set_dump_ctx {
52185229};
52195230
52205231static int nft_set_catchall_dump (struct net * net , struct sk_buff * skb ,
5221- const struct nft_set * set )
5232+ const struct nft_set * set , bool reset )
52225233{
52235234 struct nft_set_elem_catchall * catchall ;
52245235 u8 genmask = nft_genmask_cur (net );
@@ -5233,7 +5244,7 @@ static int nft_set_catchall_dump(struct net *net, struct sk_buff *skb,
52335244 continue ;
52345245
52355246 elem .priv = catchall -> elem ;
5236- ret = nf_tables_fill_setelem (skb , set , & elem );
5247+ ret = nf_tables_fill_setelem (skb , set , & elem , reset );
52375248 break ;
52385249 }
52395250
@@ -5251,6 +5262,7 @@ static int nf_tables_dump_set(struct sk_buff *skb, struct netlink_callback *cb)
52515262 bool set_found = false;
52525263 struct nlmsghdr * nlh ;
52535264 struct nlattr * nest ;
5265+ bool reset = false;
52545266 u32 portid , seq ;
52555267 int event ;
52565268
@@ -5298,8 +5310,12 @@ static int nf_tables_dump_set(struct sk_buff *skb, struct netlink_callback *cb)
52985310 if (nest == NULL )
52995311 goto nla_put_failure ;
53005312
5313+ if (NFNL_MSG_TYPE (cb -> nlh -> nlmsg_type ) == NFT_MSG_GETSETELEM_RESET )
5314+ reset = true;
5315+
53015316 args .cb = cb ;
53025317 args .skb = skb ;
5318+ args .reset = reset ;
53035319 args .iter .genmask = nft_genmask_cur (net );
53045320 args .iter .skip = cb -> args [0 ];
53055321 args .iter .count = 0 ;
@@ -5308,7 +5324,7 @@ static int nf_tables_dump_set(struct sk_buff *skb, struct netlink_callback *cb)
53085324 set -> ops -> walk (& dump_ctx -> ctx , set , & args .iter );
53095325
53105326 if (!args .iter .err && args .iter .count == cb -> args [0 ])
5311- args .iter .err = nft_set_catchall_dump (net , skb , set );
5327+ args .iter .err = nft_set_catchall_dump (net , skb , set , reset );
53125328 rcu_read_unlock ();
53135329
53145330 nla_nest_end (skb , nest );
@@ -5346,7 +5362,8 @@ static int nf_tables_fill_setelem_info(struct sk_buff *skb,
53465362 const struct nft_ctx * ctx , u32 seq ,
53475363 u32 portid , int event , u16 flags ,
53485364 const struct nft_set * set ,
5349- const struct nft_set_elem * elem )
5365+ const struct nft_set_elem * elem ,
5366+ bool reset )
53505367{
53515368 struct nlmsghdr * nlh ;
53525369 struct nlattr * nest ;
@@ -5367,7 +5384,7 @@ static int nf_tables_fill_setelem_info(struct sk_buff *skb,
53675384 if (nest == NULL )
53685385 goto nla_put_failure ;
53695386
5370- err = nf_tables_fill_setelem (skb , set , elem );
5387+ err = nf_tables_fill_setelem (skb , set , elem , reset );
53715388 if (err < 0 )
53725389 goto nla_put_failure ;
53735390
@@ -5487,7 +5504,7 @@ static int nft_setelem_get(struct nft_ctx *ctx, struct nft_set *set,
54875504}
54885505
54895506static int nft_get_set_elem (struct nft_ctx * ctx , struct nft_set * set ,
5490- const struct nlattr * attr )
5507+ const struct nlattr * attr , bool reset )
54915508{
54925509 struct nlattr * nla [NFTA_SET_ELEM_MAX + 1 ];
54935510 struct nft_set_elem elem ;
@@ -5531,7 +5548,8 @@ static int nft_get_set_elem(struct nft_ctx *ctx, struct nft_set *set,
55315548 return err ;
55325549
55335550 err = nf_tables_fill_setelem_info (skb , ctx , ctx -> seq , ctx -> portid ,
5534- NFT_MSG_NEWSETELEM , 0 , set , & elem );
5551+ NFT_MSG_NEWSETELEM , 0 , set , & elem ,
5552+ reset );
55355553 if (err < 0 )
55365554 goto err_fill_setelem ;
55375555
@@ -5555,6 +5573,7 @@ static int nf_tables_getsetelem(struct sk_buff *skb,
55555573 struct nft_set * set ;
55565574 struct nlattr * attr ;
55575575 struct nft_ctx ctx ;
5576+ bool reset = false;
55585577 int rem , err = 0 ;
55595578
55605579 table = nft_table_lookup (net , nla [NFTA_SET_ELEM_LIST_TABLE ], family ,
@@ -5589,8 +5608,11 @@ static int nf_tables_getsetelem(struct sk_buff *skb,
55895608 if (!nla [NFTA_SET_ELEM_LIST_ELEMENTS ])
55905609 return - EINVAL ;
55915610
5611+ if (NFNL_MSG_TYPE (info -> nlh -> nlmsg_type ) == NFT_MSG_GETSETELEM_RESET )
5612+ reset = true;
5613+
55925614 nla_for_each_nested (attr , nla [NFTA_SET_ELEM_LIST_ELEMENTS ], rem ) {
5593- err = nft_get_set_elem (& ctx , set , attr );
5615+ err = nft_get_set_elem (& ctx , set , attr , reset );
55945616 if (err < 0 ) {
55955617 NL_SET_BAD_ATTR (extack , attr );
55965618 break ;
@@ -5623,7 +5645,7 @@ static void nf_tables_setelem_notify(const struct nft_ctx *ctx,
56235645 flags |= ctx -> flags & (NLM_F_CREATE | NLM_F_EXCL );
56245646
56255647 err = nf_tables_fill_setelem_info (skb , ctx , 0 , portid , event , flags ,
5626- set , elem );
5648+ set , elem , false );
56275649 if (err < 0 ) {
56285650 kfree_skb (skb );
56295651 goto err ;
@@ -8490,6 +8512,12 @@ static const struct nfnl_callback nf_tables_cb[NFT_MSG_MAX] = {
84908512 .attr_count = NFTA_SET_ELEM_LIST_MAX ,
84918513 .policy = nft_set_elem_list_policy ,
84928514 },
8515+ [NFT_MSG_GETSETELEM_RESET ] = {
8516+ .call = nf_tables_getsetelem ,
8517+ .type = NFNL_CB_RCU ,
8518+ .attr_count = NFTA_SET_ELEM_LIST_MAX ,
8519+ .policy = nft_set_elem_list_policy ,
8520+ },
84938521 [NFT_MSG_DELSETELEM ] = {
84948522 .call = nf_tables_delsetelem ,
84958523 .type = NFNL_CB_BATCH ,
0 commit comments