@@ -1199,7 +1199,8 @@ static int nf_tables_fill_chain_info(struct sk_buff *skb, struct net *net,
1199
1199
if (nla_put_string (skb , NFTA_CHAIN_TYPE , basechain -> type -> name ))
1200
1200
goto nla_put_failure ;
1201
1201
1202
- if (basechain -> stats && nft_dump_stats (skb , basechain -> stats ))
1202
+ if (rcu_access_pointer (basechain -> stats ) &&
1203
+ nft_dump_stats (skb , rcu_dereference (basechain -> stats )))
1203
1204
goto nla_put_failure ;
1204
1205
}
1205
1206
@@ -1375,16 +1376,18 @@ static struct nft_stats __percpu *nft_stats_alloc(const struct nlattr *attr)
1375
1376
return newstats ;
1376
1377
}
1377
1378
1378
- static void nft_chain_stats_replace (struct nft_base_chain * chain ,
1379
+ static void nft_chain_stats_replace (struct net * net ,
1380
+ struct nft_base_chain * chain ,
1379
1381
struct nft_stats __percpu * newstats )
1380
1382
{
1381
1383
struct nft_stats __percpu * oldstats ;
1382
1384
1383
1385
if (newstats == NULL )
1384
1386
return ;
1385
1387
1386
- if (chain -> stats ) {
1387
- oldstats = nfnl_dereference (chain -> stats , NFNL_SUBSYS_NFTABLES );
1388
+ if (rcu_access_pointer (chain -> stats )) {
1389
+ oldstats = rcu_dereference_protected (chain -> stats ,
1390
+ lockdep_commit_lock_is_held (net ));
1388
1391
rcu_assign_pointer (chain -> stats , newstats );
1389
1392
synchronize_rcu ();
1390
1393
free_percpu (oldstats );
@@ -1421,9 +1424,10 @@ static void nf_tables_chain_destroy(struct nft_ctx *ctx)
1421
1424
struct nft_base_chain * basechain = nft_base_chain (chain );
1422
1425
1423
1426
module_put (basechain -> type -> owner );
1424
- free_percpu (basechain -> stats );
1425
- if (basechain -> stats )
1427
+ if (rcu_access_pointer (basechain -> stats )) {
1426
1428
static_branch_dec (& nft_counters_enabled );
1429
+ free_percpu (rcu_dereference_raw (basechain -> stats ));
1430
+ }
1427
1431
kfree (chain -> name );
1428
1432
kfree (basechain );
1429
1433
} else {
@@ -1572,7 +1576,7 @@ static int nf_tables_addchain(struct nft_ctx *ctx, u8 family, u8 genmask,
1572
1576
kfree (basechain );
1573
1577
return PTR_ERR (stats );
1574
1578
}
1575
- basechain -> stats = stats ;
1579
+ rcu_assign_pointer ( basechain -> stats , stats ) ;
1576
1580
static_branch_inc (& nft_counters_enabled );
1577
1581
}
1578
1582
@@ -6145,7 +6149,8 @@ static void nft_chain_commit_update(struct nft_trans *trans)
6145
6149
return ;
6146
6150
6147
6151
basechain = nft_base_chain (trans -> ctx .chain );
6148
- nft_chain_stats_replace (basechain , nft_trans_chain_stats (trans ));
6152
+ nft_chain_stats_replace (trans -> ctx .net , basechain ,
6153
+ nft_trans_chain_stats (trans ));
6149
6154
6150
6155
switch (nft_trans_chain_policy (trans )) {
6151
6156
case NF_DROP :
0 commit comments