@@ -2261,7 +2261,16 @@ static int nft_chain_parse_hook(struct net *net,
2261
2261
return - EOPNOTSUPP ;
2262
2262
}
2263
2263
2264
- type = basechain -> type ;
2264
+ if (nla [NFTA_CHAIN_TYPE ]) {
2265
+ type = __nf_tables_chain_type_lookup (nla [NFTA_CHAIN_TYPE ],
2266
+ family );
2267
+ if (!type ) {
2268
+ NL_SET_BAD_ATTR (extack , nla [NFTA_CHAIN_TYPE ]);
2269
+ return - ENOENT ;
2270
+ }
2271
+ } else {
2272
+ type = basechain -> type ;
2273
+ }
2265
2274
}
2266
2275
2267
2276
if (!try_module_get (type -> owner )) {
@@ -5817,10 +5826,6 @@ static int nf_tables_dump_set(struct sk_buff *skb, struct netlink_callback *cb)
5817
5826
nla_nest_end (skb , nest );
5818
5827
nlmsg_end (skb , nlh );
5819
5828
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
-
5824
5829
rcu_read_unlock ();
5825
5830
5826
5831
if (args .iter .err && args .iter .err != - EMSGSIZE )
@@ -5836,6 +5841,26 @@ static int nf_tables_dump_set(struct sk_buff *skb, struct netlink_callback *cb)
5836
5841
return - ENOSPC ;
5837
5842
}
5838
5843
5844
+ static int nf_tables_dumpreset_set (struct sk_buff * skb ,
5845
+ struct netlink_callback * cb )
5846
+ {
5847
+ struct nftables_pernet * nft_net = nft_pernet (sock_net (skb -> sk ));
5848
+ struct nft_set_dump_ctx * dump_ctx = cb -> data ;
5849
+ int ret , skip = cb -> args [0 ];
5850
+
5851
+ mutex_lock (& nft_net -> commit_mutex );
5852
+
5853
+ ret = nf_tables_dump_set (skb , cb );
5854
+
5855
+ if (cb -> args [0 ] > skip )
5856
+ audit_log_nft_set_reset (dump_ctx -> ctx .table , cb -> seq ,
5857
+ cb -> args [0 ] - skip );
5858
+
5859
+ mutex_unlock (& nft_net -> commit_mutex );
5860
+
5861
+ return ret ;
5862
+ }
5863
+
5839
5864
static int nf_tables_dump_set_start (struct netlink_callback * cb )
5840
5865
{
5841
5866
struct nft_set_dump_ctx * dump_ctx = cb -> data ;
@@ -5910,7 +5935,7 @@ static int nft_setelem_parse_flags(const struct nft_set *set,
5910
5935
return 0 ;
5911
5936
}
5912
5937
5913
- static int nft_setelem_parse_key (struct nft_ctx * ctx , struct nft_set * set ,
5938
+ static int nft_setelem_parse_key (struct nft_ctx * ctx , const struct nft_set * set ,
5914
5939
struct nft_data * key , struct nlattr * attr )
5915
5940
{
5916
5941
struct nft_data_desc desc = {
@@ -5963,7 +5988,7 @@ static void *nft_setelem_catchall_get(const struct net *net,
5963
5988
return priv ;
5964
5989
}
5965
5990
5966
- static int nft_setelem_get (struct nft_ctx * ctx , struct nft_set * set ,
5991
+ static int nft_setelem_get (struct nft_ctx * ctx , const struct nft_set * set ,
5967
5992
struct nft_set_elem * elem , u32 flags )
5968
5993
{
5969
5994
void * priv ;
@@ -5982,7 +6007,7 @@ static int nft_setelem_get(struct nft_ctx *ctx, struct nft_set *set,
5982
6007
return 0 ;
5983
6008
}
5984
6009
5985
- static int nft_get_set_elem (struct nft_ctx * ctx , struct nft_set * set ,
6010
+ static int nft_get_set_elem (struct nft_ctx * ctx , const struct nft_set * set ,
5986
6011
const struct nlattr * attr , bool reset )
5987
6012
{
5988
6013
struct nlattr * nla [NFTA_SET_ELEM_MAX + 1 ];
@@ -6039,21 +6064,18 @@ static int nft_get_set_elem(struct nft_ctx *ctx, struct nft_set *set,
6039
6064
return err ;
6040
6065
}
6041
6066
6042
- /* called with rcu_read_lock held */
6043
- static int nf_tables_getsetelem (struct sk_buff * skb ,
6044
- const struct nfnl_info * info ,
6045
- const struct nlattr * const nla [])
6067
+ static int nft_set_dump_ctx_init (struct nft_set_dump_ctx * dump_ctx ,
6068
+ const struct sk_buff * skb ,
6069
+ const struct nfnl_info * info ,
6070
+ const struct nlattr * const nla [],
6071
+ bool reset )
6046
6072
{
6047
6073
struct netlink_ext_ack * extack = info -> extack ;
6048
6074
u8 genmask = nft_genmask_cur (info -> net );
6049
6075
u8 family = info -> nfmsg -> nfgen_family ;
6050
- int rem , err = 0 , nelems = 0 ;
6051
6076
struct net * net = info -> net ;
6052
6077
struct nft_table * table ;
6053
6078
struct nft_set * set ;
6054
- struct nlattr * attr ;
6055
- struct nft_ctx ctx ;
6056
- bool reset = false;
6057
6079
6058
6080
table = nft_table_lookup (net , nla [NFTA_SET_ELEM_LIST_TABLE ], family ,
6059
6081
genmask , 0 );
@@ -6068,10 +6090,22 @@ static int nf_tables_getsetelem(struct sk_buff *skb,
6068
6090
return PTR_ERR (set );
6069
6091
}
6070
6092
6071
- nft_ctx_init (& ctx , net , skb , info -> nlh , family , table , NULL , nla );
6093
+ nft_ctx_init (& dump_ctx -> ctx , net , skb ,
6094
+ info -> nlh , family , table , NULL , nla );
6095
+ dump_ctx -> set = set ;
6096
+ dump_ctx -> reset = reset ;
6097
+ return 0 ;
6098
+ }
6072
6099
6073
- if (NFNL_MSG_TYPE (info -> nlh -> nlmsg_type ) == NFT_MSG_GETSETELEM_RESET )
6074
- reset = true;
6100
+ /* called with rcu_read_lock held */
6101
+ static int nf_tables_getsetelem (struct sk_buff * skb ,
6102
+ const struct nfnl_info * info ,
6103
+ const struct nlattr * const nla [])
6104
+ {
6105
+ struct netlink_ext_ack * extack = info -> extack ;
6106
+ struct nft_set_dump_ctx dump_ctx ;
6107
+ struct nlattr * attr ;
6108
+ int rem , err = 0 ;
6075
6109
6076
6110
if (info -> nlh -> nlmsg_flags & NLM_F_DUMP ) {
6077
6111
struct netlink_dump_control c = {
@@ -6080,31 +6114,87 @@ static int nf_tables_getsetelem(struct sk_buff *skb,
6080
6114
.done = nf_tables_dump_set_done ,
6081
6115
.module = THIS_MODULE ,
6082
6116
};
6083
- struct nft_set_dump_ctx dump_ctx = {
6084
- .set = set ,
6085
- .ctx = ctx ,
6086
- .reset = reset ,
6117
+
6118
+ err = nft_set_dump_ctx_init (& dump_ctx , skb , info , nla , false);
6119
+ if (err )
6120
+ return err ;
6121
+
6122
+ c .data = & dump_ctx ;
6123
+ return nft_netlink_dump_start_rcu (info -> sk , skb , info -> nlh , & c );
6124
+ }
6125
+
6126
+ if (!nla [NFTA_SET_ELEM_LIST_ELEMENTS ])
6127
+ return - EINVAL ;
6128
+
6129
+ err = nft_set_dump_ctx_init (& dump_ctx , skb , info , nla , false);
6130
+ if (err )
6131
+ return err ;
6132
+
6133
+ nla_for_each_nested (attr , nla [NFTA_SET_ELEM_LIST_ELEMENTS ], rem ) {
6134
+ err = nft_get_set_elem (& dump_ctx .ctx , dump_ctx .set , attr , false);
6135
+ if (err < 0 ) {
6136
+ NL_SET_BAD_ATTR (extack , attr );
6137
+ break ;
6138
+ }
6139
+ }
6140
+
6141
+ return err ;
6142
+ }
6143
+
6144
+ static int nf_tables_getsetelem_reset (struct sk_buff * skb ,
6145
+ const struct nfnl_info * info ,
6146
+ const struct nlattr * const nla [])
6147
+ {
6148
+ struct nftables_pernet * nft_net = nft_pernet (info -> net );
6149
+ struct netlink_ext_ack * extack = info -> extack ;
6150
+ struct nft_set_dump_ctx dump_ctx ;
6151
+ int rem , err = 0 , nelems = 0 ;
6152
+ struct nlattr * attr ;
6153
+
6154
+ if (info -> nlh -> nlmsg_flags & NLM_F_DUMP ) {
6155
+ struct netlink_dump_control c = {
6156
+ .start = nf_tables_dump_set_start ,
6157
+ .dump = nf_tables_dumpreset_set ,
6158
+ .done = nf_tables_dump_set_done ,
6159
+ .module = THIS_MODULE ,
6087
6160
};
6088
6161
6162
+ err = nft_set_dump_ctx_init (& dump_ctx , skb , info , nla , true);
6163
+ if (err )
6164
+ return err ;
6165
+
6089
6166
c .data = & dump_ctx ;
6090
6167
return nft_netlink_dump_start_rcu (info -> sk , skb , info -> nlh , & c );
6091
6168
}
6092
6169
6093
6170
if (!nla [NFTA_SET_ELEM_LIST_ELEMENTS ])
6094
6171
return - EINVAL ;
6095
6172
6173
+ if (!try_module_get (THIS_MODULE ))
6174
+ return - EINVAL ;
6175
+ rcu_read_unlock ();
6176
+ mutex_lock (& nft_net -> commit_mutex );
6177
+ rcu_read_lock ();
6178
+
6179
+ err = nft_set_dump_ctx_init (& dump_ctx , skb , info , nla , true);
6180
+ if (err )
6181
+ goto out_unlock ;
6182
+
6096
6183
nla_for_each_nested (attr , nla [NFTA_SET_ELEM_LIST_ELEMENTS ], rem ) {
6097
- err = nft_get_set_elem (& ctx , set , attr , reset );
6184
+ err = nft_get_set_elem (& dump_ctx . ctx , dump_ctx . set , attr , true );
6098
6185
if (err < 0 ) {
6099
6186
NL_SET_BAD_ATTR (extack , attr );
6100
6187
break ;
6101
6188
}
6102
6189
nelems ++ ;
6103
6190
}
6191
+ audit_log_nft_set_reset (dump_ctx .ctx .table , nft_net -> base_seq , nelems );
6104
6192
6105
- if (reset )
6106
- audit_log_nft_set_reset (table , nft_pernet (net )-> base_seq ,
6107
- nelems );
6193
+ out_unlock :
6194
+ rcu_read_unlock ();
6195
+ mutex_unlock (& nft_net -> commit_mutex );
6196
+ rcu_read_lock ();
6197
+ module_put (THIS_MODULE );
6108
6198
6109
6199
return err ;
6110
6200
}
@@ -9078,7 +9168,7 @@ static const struct nfnl_callback nf_tables_cb[NFT_MSG_MAX] = {
9078
9168
.policy = nft_set_elem_list_policy ,
9079
9169
},
9080
9170
[NFT_MSG_GETSETELEM_RESET ] = {
9081
- .call = nf_tables_getsetelem ,
9171
+ .call = nf_tables_getsetelem_reset ,
9082
9172
.type = NFNL_CB_RCU ,
9083
9173
.attr_count = NFTA_SET_ELEM_LIST_MAX ,
9084
9174
.policy = nft_set_elem_list_policy ,
@@ -10383,6 +10473,7 @@ static int __nf_tables_abort(struct net *net, enum nfnl_abort_action action)
10383
10473
nft_trans_destroy (trans );
10384
10474
break ;
10385
10475
}
10476
+ nft_trans_set (trans )-> dead = 1 ;
10386
10477
list_del_rcu (& nft_trans_set (trans )-> list );
10387
10478
break ;
10388
10479
case NFT_MSG_DELSET :
0 commit comments