@@ -278,6 +278,8 @@ static int nf_tables_dump_tables(struct sk_buff *skb,
278
278
int family = nfmsg -> nfgen_family ;
279
279
280
280
rcu_read_lock ();
281
+ cb -> seq = net -> nft .base_seq ;
282
+
281
283
list_for_each_entry_rcu (afi , & net -> nft .af_info , list ) {
282
284
if (family != NFPROTO_UNSPEC && family != afi -> family )
283
285
continue ;
@@ -295,6 +297,8 @@ static int nf_tables_dump_tables(struct sk_buff *skb,
295
297
NLM_F_MULTI ,
296
298
afi -> family , table ) < 0 )
297
299
goto done ;
300
+
301
+ nl_dump_check_consistent (cb , nlmsg_hdr (skb ));
298
302
cont :
299
303
idx ++ ;
300
304
}
@@ -767,6 +771,8 @@ static int nf_tables_dump_chains(struct sk_buff *skb,
767
771
int family = nfmsg -> nfgen_family ;
768
772
769
773
rcu_read_lock ();
774
+ cb -> seq = net -> nft .base_seq ;
775
+
770
776
list_for_each_entry_rcu (afi , & net -> nft .af_info , list ) {
771
777
if (family != NFPROTO_UNSPEC && family != afi -> family )
772
778
continue ;
@@ -784,6 +790,8 @@ static int nf_tables_dump_chains(struct sk_buff *skb,
784
790
NLM_F_MULTI ,
785
791
afi -> family , table , chain ) < 0 )
786
792
goto done ;
793
+
794
+ nl_dump_check_consistent (cb , nlmsg_hdr (skb ));
787
795
cont :
788
796
idx ++ ;
789
797
}
@@ -1555,10 +1563,10 @@ static int nf_tables_dump_rules(struct sk_buff *skb,
1555
1563
unsigned int idx = 0 , s_idx = cb -> args [0 ];
1556
1564
struct net * net = sock_net (skb -> sk );
1557
1565
int family = nfmsg -> nfgen_family ;
1558
- u8 genctr = ACCESS_ONCE (net -> nft .genctr );
1559
- u8 gencursor = ACCESS_ONCE (net -> nft .gencursor );
1560
1566
1561
1567
rcu_read_lock ();
1568
+ cb -> seq = net -> nft .base_seq ;
1569
+
1562
1570
list_for_each_entry_rcu (afi , & net -> nft .af_info , list ) {
1563
1571
if (family != NFPROTO_UNSPEC && family != afi -> family )
1564
1572
continue ;
@@ -1579,6 +1587,8 @@ static int nf_tables_dump_rules(struct sk_buff *skb,
1579
1587
NLM_F_MULTI | NLM_F_APPEND ,
1580
1588
afi -> family , table , chain , rule ) < 0 )
1581
1589
goto done ;
1590
+
1591
+ nl_dump_check_consistent (cb , nlmsg_hdr (skb ));
1582
1592
cont :
1583
1593
idx ++ ;
1584
1594
}
@@ -1588,10 +1598,6 @@ static int nf_tables_dump_rules(struct sk_buff *skb,
1588
1598
done :
1589
1599
rcu_read_unlock ();
1590
1600
1591
- /* Invalidate this dump, a transition to the new generation happened */
1592
- if (gencursor != net -> nft .gencursor || genctr != net -> nft .genctr )
1593
- return - EBUSY ;
1594
-
1595
1601
cb -> args [0 ] = idx ;
1596
1602
return skb -> len ;
1597
1603
}
@@ -2244,6 +2250,8 @@ static int nf_tables_dump_sets_table(struct nft_ctx *ctx, struct sk_buff *skb,
2244
2250
return skb -> len ;
2245
2251
2246
2252
rcu_read_lock ();
2253
+ cb -> seq = ctx -> net -> nft .base_seq ;
2254
+
2247
2255
list_for_each_entry_rcu (set , & ctx -> table -> sets , list ) {
2248
2256
if (idx < s_idx )
2249
2257
goto cont ;
@@ -2252,6 +2260,7 @@ static int nf_tables_dump_sets_table(struct nft_ctx *ctx, struct sk_buff *skb,
2252
2260
cb -> args [0 ] = idx ;
2253
2261
goto done ;
2254
2262
}
2263
+ nl_dump_check_consistent (cb , nlmsg_hdr (skb ));
2255
2264
cont :
2256
2265
idx ++ ;
2257
2266
}
@@ -2272,6 +2281,8 @@ static int nf_tables_dump_sets_family(struct nft_ctx *ctx, struct sk_buff *skb,
2272
2281
return skb -> len ;
2273
2282
2274
2283
rcu_read_lock ();
2284
+ cb -> seq = ctx -> net -> nft .base_seq ;
2285
+
2275
2286
list_for_each_entry_rcu (table , & ctx -> afi -> tables , list ) {
2276
2287
if (cur_table ) {
2277
2288
if (cur_table != table )
@@ -2290,6 +2301,7 @@ static int nf_tables_dump_sets_family(struct nft_ctx *ctx, struct sk_buff *skb,
2290
2301
cb -> args [2 ] = (unsigned long ) table ;
2291
2302
goto done ;
2292
2303
}
2304
+ nl_dump_check_consistent (cb , nlmsg_hdr (skb ));
2293
2305
cont :
2294
2306
idx ++ ;
2295
2307
}
@@ -2314,6 +2326,8 @@ static int nf_tables_dump_sets_all(struct nft_ctx *ctx, struct sk_buff *skb,
2314
2326
return skb -> len ;
2315
2327
2316
2328
rcu_read_lock ();
2329
+ cb -> seq = net -> nft .base_seq ;
2330
+
2317
2331
list_for_each_entry_rcu (afi , & net -> nft .af_info , list ) {
2318
2332
if (cur_family ) {
2319
2333
if (afi -> family != cur_family )
@@ -2344,6 +2358,7 @@ static int nf_tables_dump_sets_all(struct nft_ctx *ctx, struct sk_buff *skb,
2344
2358
cb -> args [3 ] = afi -> family ;
2345
2359
goto done ;
2346
2360
}
2361
+ nl_dump_check_consistent (cb , nlmsg_hdr (skb ));
2347
2362
cont :
2348
2363
idx ++ ;
2349
2364
}
@@ -3361,7 +3376,7 @@ static int nf_tables_commit(struct sk_buff *skb)
3361
3376
struct nft_set * set ;
3362
3377
3363
3378
/* Bump generation counter, invalidate any dump in progress */
3364
- net -> nft .genctr ++ ;
3379
+ while ( ++ net -> nft .base_seq == 0 ) ;
3365
3380
3366
3381
/* A new generation has just started */
3367
3382
net -> nft .gencursor = gencursor_next (net );
@@ -3966,6 +3981,7 @@ static int nf_tables_init_net(struct net *net)
3966
3981
{
3967
3982
INIT_LIST_HEAD (& net -> nft .af_info );
3968
3983
INIT_LIST_HEAD (& net -> nft .commit_list );
3984
+ net -> nft .base_seq = 1 ;
3969
3985
return 0 ;
3970
3986
}
3971
3987
0 commit comments