@@ -5817,10 +5817,6 @@ static int nf_tables_dump_set(struct sk_buff *skb, struct netlink_callback *cb)
58175817 nla_nest_end (skb , nest );
58185818 nlmsg_end (skb , nlh );
58195819
5820- if (dump_ctx -> reset && args .iter .count > args .iter .skip )
5821- audit_log_nft_set_reset (table , cb -> seq ,
5822- args .iter .count - args .iter .skip );
5823-
58245820 rcu_read_unlock ();
58255821
58265822 if (args .iter .err && args .iter .err != - EMSGSIZE )
@@ -5836,6 +5832,26 @@ static int nf_tables_dump_set(struct sk_buff *skb, struct netlink_callback *cb)
58365832 return - ENOSPC ;
58375833}
58385834
5835+ static int nf_tables_dumpreset_set (struct sk_buff * skb ,
5836+ struct netlink_callback * cb )
5837+ {
5838+ struct nftables_pernet * nft_net = nft_pernet (sock_net (skb -> sk ));
5839+ struct nft_set_dump_ctx * dump_ctx = cb -> data ;
5840+ int ret , skip = cb -> args [0 ];
5841+
5842+ mutex_lock (& nft_net -> commit_mutex );
5843+
5844+ ret = nf_tables_dump_set (skb , cb );
5845+
5846+ if (cb -> args [0 ] > skip )
5847+ audit_log_nft_set_reset (dump_ctx -> ctx .table , cb -> seq ,
5848+ cb -> args [0 ] - skip );
5849+
5850+ mutex_unlock (& nft_net -> commit_mutex );
5851+
5852+ return ret ;
5853+ }
5854+
58395855static int nf_tables_dump_set_start (struct netlink_callback * cb )
58405856{
58415857 struct nft_set_dump_ctx * dump_ctx = cb -> data ;
@@ -6079,13 +6095,8 @@ static int nf_tables_getsetelem(struct sk_buff *skb,
60796095{
60806096 struct netlink_ext_ack * extack = info -> extack ;
60816097 struct nft_set_dump_ctx dump_ctx ;
6082- int rem , err = 0 , nelems = 0 ;
6083- struct net * net = info -> net ;
60846098 struct nlattr * attr ;
6085- bool reset = false;
6086-
6087- if (NFNL_MSG_TYPE (info -> nlh -> nlmsg_type ) == NFT_MSG_GETSETELEM_RESET )
6088- reset = true;
6099+ int rem , err = 0 ;
60896100
60906101 if (info -> nlh -> nlmsg_flags & NLM_F_DUMP ) {
60916102 struct netlink_dump_control c = {
@@ -6095,7 +6106,7 @@ static int nf_tables_getsetelem(struct sk_buff *skb,
60956106 .module = THIS_MODULE ,
60966107 };
60976108
6098- err = nft_set_dump_ctx_init (& dump_ctx , skb , info , nla , reset );
6109+ err = nft_set_dump_ctx_init (& dump_ctx , skb , info , nla , false );
60996110 if (err )
61006111 return err ;
61016112
@@ -6106,22 +6117,75 @@ static int nf_tables_getsetelem(struct sk_buff *skb,
61066117 if (!nla [NFTA_SET_ELEM_LIST_ELEMENTS ])
61076118 return - EINVAL ;
61086119
6109- err = nft_set_dump_ctx_init (& dump_ctx , skb , info , nla , reset );
6120+ err = nft_set_dump_ctx_init (& dump_ctx , skb , info , nla , false );
61106121 if (err )
61116122 return err ;
61126123
61136124 nla_for_each_nested (attr , nla [NFTA_SET_ELEM_LIST_ELEMENTS ], rem ) {
6114- err = nft_get_set_elem (& dump_ctx .ctx , dump_ctx .set , attr , reset );
6125+ err = nft_get_set_elem (& dump_ctx .ctx , dump_ctx .set , attr , false);
6126+ if (err < 0 ) {
6127+ NL_SET_BAD_ATTR (extack , attr );
6128+ break ;
6129+ }
6130+ }
6131+
6132+ return err ;
6133+ }
6134+
6135+ static int nf_tables_getsetelem_reset (struct sk_buff * skb ,
6136+ const struct nfnl_info * info ,
6137+ const struct nlattr * const nla [])
6138+ {
6139+ struct nftables_pernet * nft_net = nft_pernet (info -> net );
6140+ struct netlink_ext_ack * extack = info -> extack ;
6141+ struct nft_set_dump_ctx dump_ctx ;
6142+ int rem , err = 0 , nelems = 0 ;
6143+ struct nlattr * attr ;
6144+
6145+ if (info -> nlh -> nlmsg_flags & NLM_F_DUMP ) {
6146+ struct netlink_dump_control c = {
6147+ .start = nf_tables_dump_set_start ,
6148+ .dump = nf_tables_dumpreset_set ,
6149+ .done = nf_tables_dump_set_done ,
6150+ .module = THIS_MODULE ,
6151+ };
6152+
6153+ err = nft_set_dump_ctx_init (& dump_ctx , skb , info , nla , true);
6154+ if (err )
6155+ return err ;
6156+
6157+ c .data = & dump_ctx ;
6158+ return nft_netlink_dump_start_rcu (info -> sk , skb , info -> nlh , & c );
6159+ }
6160+
6161+ if (!nla [NFTA_SET_ELEM_LIST_ELEMENTS ])
6162+ return - EINVAL ;
6163+
6164+ if (!try_module_get (THIS_MODULE ))
6165+ return - EINVAL ;
6166+ rcu_read_unlock ();
6167+ mutex_lock (& nft_net -> commit_mutex );
6168+ rcu_read_lock ();
6169+
6170+ err = nft_set_dump_ctx_init (& dump_ctx , skb , info , nla , true);
6171+ if (err )
6172+ goto out_unlock ;
6173+
6174+ nla_for_each_nested (attr , nla [NFTA_SET_ELEM_LIST_ELEMENTS ], rem ) {
6175+ err = nft_get_set_elem (& dump_ctx .ctx , dump_ctx .set , attr , true);
61156176 if (err < 0 ) {
61166177 NL_SET_BAD_ATTR (extack , attr );
61176178 break ;
61186179 }
61196180 nelems ++ ;
61206181 }
6182+ audit_log_nft_set_reset (dump_ctx .ctx .table , nft_net -> base_seq , nelems );
61216183
6122- if (reset )
6123- audit_log_nft_set_reset (dump_ctx .ctx .table , nft_pernet (net )-> base_seq ,
6124- nelems );
6184+ out_unlock :
6185+ rcu_read_unlock ();
6186+ mutex_unlock (& nft_net -> commit_mutex );
6187+ rcu_read_lock ();
6188+ module_put (THIS_MODULE );
61256189
61266190 return err ;
61276191}
@@ -9095,7 +9159,7 @@ static const struct nfnl_callback nf_tables_cb[NFT_MSG_MAX] = {
90959159 .policy = nft_set_elem_list_policy ,
90969160 },
90979161 [NFT_MSG_GETSETELEM_RESET ] = {
9098- .call = nf_tables_getsetelem ,
9162+ .call = nf_tables_getsetelem_reset ,
90999163 .type = NFNL_CB_RCU ,
91009164 .attr_count = NFTA_SET_ELEM_LIST_MAX ,
91019165 .policy = nft_set_elem_list_policy ,
0 commit comments