@@ -211,7 +211,7 @@ static int nft_trans_chain_add(struct nft_ctx *ctx, int msg_type)
211
211
return - ENOMEM ;
212
212
213
213
if (msg_type == NFT_MSG_NEWCHAIN )
214
- ctx -> chain -> flags |= NFT_CHAIN_INACTIVE ;
214
+ nft_activate_next ( ctx -> net , ctx -> chain ) ;
215
215
216
216
list_add_tail (& trans -> list , & ctx -> net -> nft .commit_list );
217
217
return 0 ;
@@ -226,7 +226,7 @@ static int nft_delchain(struct nft_ctx *ctx)
226
226
return err ;
227
227
228
228
ctx -> table -> use -- ;
229
- list_del_rcu ( & ctx -> chain -> list );
229
+ nft_deactivate_next ( ctx -> net , ctx -> chain );
230
230
231
231
return err ;
232
232
}
@@ -559,13 +559,16 @@ static int nf_tables_gettable(struct net *net, struct sock *nlsk,
559
559
return err ;
560
560
}
561
561
562
- static int nf_tables_table_enable (const struct nft_af_info * afi ,
562
+ static int nf_tables_table_enable (struct net * net ,
563
+ const struct nft_af_info * afi ,
563
564
struct nft_table * table )
564
565
{
565
566
struct nft_chain * chain ;
566
567
int err , i = 0 ;
567
568
568
569
list_for_each_entry (chain , & table -> chains , list ) {
570
+ if (!nft_is_active_next (net , chain ))
571
+ continue ;
569
572
if (!(chain -> flags & NFT_BASE_CHAIN ))
570
573
continue ;
571
574
@@ -578,6 +581,8 @@ static int nf_tables_table_enable(const struct nft_af_info *afi,
578
581
return 0 ;
579
582
err :
580
583
list_for_each_entry (chain , & table -> chains , list ) {
584
+ if (!nft_is_active_next (net , chain ))
585
+ continue ;
581
586
if (!(chain -> flags & NFT_BASE_CHAIN ))
582
587
continue ;
583
588
@@ -589,12 +594,15 @@ static int nf_tables_table_enable(const struct nft_af_info *afi,
589
594
return err ;
590
595
}
591
596
592
- static void nf_tables_table_disable (const struct nft_af_info * afi ,
597
+ static void nf_tables_table_disable (struct net * net ,
598
+ const struct nft_af_info * afi ,
593
599
struct nft_table * table )
594
600
{
595
601
struct nft_chain * chain ;
596
602
597
603
list_for_each_entry (chain , & table -> chains , list ) {
604
+ if (!nft_is_active_next (net , chain ))
605
+ continue ;
598
606
if (chain -> flags & NFT_BASE_CHAIN )
599
607
nft_unregister_basechain (nft_base_chain (chain ),
600
608
afi -> nops );
@@ -627,7 +635,7 @@ static int nf_tables_updtable(struct nft_ctx *ctx)
627
635
nft_trans_table_enable (trans ) = false;
628
636
} else if (!(flags & NFT_TABLE_F_DORMANT ) &&
629
637
ctx -> table -> flags & NFT_TABLE_F_DORMANT ) {
630
- ret = nf_tables_table_enable (ctx -> afi , ctx -> table );
638
+ ret = nf_tables_table_enable (ctx -> net , ctx -> afi , ctx -> table );
631
639
if (ret >= 0 ) {
632
640
ctx -> table -> flags &= ~NFT_TABLE_F_DORMANT ;
633
641
nft_trans_table_enable (trans ) = true;
@@ -722,6 +730,9 @@ static int nft_flush_table(struct nft_ctx *ctx)
722
730
struct nft_set * set , * ns ;
723
731
724
732
list_for_each_entry (chain , & ctx -> table -> chains , list ) {
733
+ if (!nft_is_active_next (ctx -> net , chain ))
734
+ continue ;
735
+
725
736
ctx -> chain = chain ;
726
737
727
738
err = nft_delrule_by_chain (ctx );
@@ -740,6 +751,9 @@ static int nft_flush_table(struct nft_ctx *ctx)
740
751
}
741
752
742
753
list_for_each_entry_safe (chain , nc , & ctx -> table -> chains , list ) {
754
+ if (!nft_is_active_next (ctx -> net , chain ))
755
+ continue ;
756
+
743
757
ctx -> chain = chain ;
744
758
745
759
err = nft_delchain (ctx );
@@ -849,28 +863,32 @@ EXPORT_SYMBOL_GPL(nft_unregister_chain_type);
849
863
*/
850
864
851
865
static struct nft_chain *
852
- nf_tables_chain_lookup_byhandle (const struct nft_table * table , u64 handle )
866
+ nf_tables_chain_lookup_byhandle (const struct nft_table * table , u64 handle ,
867
+ u8 genmask )
853
868
{
854
869
struct nft_chain * chain ;
855
870
856
871
list_for_each_entry (chain , & table -> chains , list ) {
857
- if (chain -> handle == handle )
872
+ if (chain -> handle == handle &&
873
+ nft_active_genmask (chain , genmask ))
858
874
return chain ;
859
875
}
860
876
861
877
return ERR_PTR (- ENOENT );
862
878
}
863
879
864
880
static struct nft_chain * nf_tables_chain_lookup (const struct nft_table * table ,
865
- const struct nlattr * nla )
881
+ const struct nlattr * nla ,
882
+ u8 genmask )
866
883
{
867
884
struct nft_chain * chain ;
868
885
869
886
if (nla == NULL )
870
887
return ERR_PTR (- EINVAL );
871
888
872
889
list_for_each_entry (chain , & table -> chains , list ) {
873
- if (!nla_strcmp (nla , chain -> name ))
890
+ if (!nla_strcmp (nla , chain -> name ) &&
891
+ nft_active_genmask (chain , genmask ))
874
892
return chain ;
875
893
}
876
894
@@ -1053,6 +1071,8 @@ static int nf_tables_dump_chains(struct sk_buff *skb,
1053
1071
if (idx > s_idx )
1054
1072
memset (& cb -> args [1 ], 0 ,
1055
1073
sizeof (cb -> args ) - sizeof (cb -> args [0 ]));
1074
+ if (!nft_is_active (net , chain ))
1075
+ continue ;
1056
1076
if (nf_tables_fill_chain_info (skb , net ,
1057
1077
NETLINK_CB (cb -> skb ).portid ,
1058
1078
cb -> nlh -> nlmsg_seq ,
@@ -1101,11 +1121,9 @@ static int nf_tables_getchain(struct net *net, struct sock *nlsk,
1101
1121
if (IS_ERR (table ))
1102
1122
return PTR_ERR (table );
1103
1123
1104
- chain = nf_tables_chain_lookup (table , nla [NFTA_CHAIN_NAME ]);
1124
+ chain = nf_tables_chain_lookup (table , nla [NFTA_CHAIN_NAME ], genmask );
1105
1125
if (IS_ERR (chain ))
1106
1126
return PTR_ERR (chain );
1107
- if (chain -> flags & NFT_CHAIN_INACTIVE )
1108
- return - ENOENT ;
1109
1127
1110
1128
skb2 = alloc_skb (NLMSG_GOODSIZE , GFP_KERNEL );
1111
1129
if (!skb2 )
@@ -1230,11 +1248,11 @@ static int nf_tables_newchain(struct net *net, struct sock *nlsk,
1230
1248
1231
1249
if (nla [NFTA_CHAIN_HANDLE ]) {
1232
1250
handle = be64_to_cpu (nla_get_be64 (nla [NFTA_CHAIN_HANDLE ]));
1233
- chain = nf_tables_chain_lookup_byhandle (table , handle );
1251
+ chain = nf_tables_chain_lookup_byhandle (table , handle , genmask );
1234
1252
if (IS_ERR (chain ))
1235
1253
return PTR_ERR (chain );
1236
1254
} else {
1237
- chain = nf_tables_chain_lookup (table , name );
1255
+ chain = nf_tables_chain_lookup (table , name , genmask );
1238
1256
if (IS_ERR (chain )) {
1239
1257
if (PTR_ERR (chain ) != - ENOENT )
1240
1258
return PTR_ERR (chain );
@@ -1265,16 +1283,20 @@ static int nf_tables_newchain(struct net *net, struct sock *nlsk,
1265
1283
struct nft_stats * stats = NULL ;
1266
1284
struct nft_trans * trans ;
1267
1285
1268
- if (chain -> flags & NFT_CHAIN_INACTIVE )
1269
- return - ENOENT ;
1270
1286
if (nlh -> nlmsg_flags & NLM_F_EXCL )
1271
1287
return - EEXIST ;
1272
1288
if (nlh -> nlmsg_flags & NLM_F_REPLACE )
1273
1289
return - EOPNOTSUPP ;
1274
1290
1275
- if (nla [NFTA_CHAIN_HANDLE ] && name &&
1276
- !IS_ERR (nf_tables_chain_lookup (table , nla [NFTA_CHAIN_NAME ])))
1277
- return - EEXIST ;
1291
+ if (nla [NFTA_CHAIN_HANDLE ] && name ) {
1292
+ struct nft_chain * chain2 ;
1293
+
1294
+ chain2 = nf_tables_chain_lookup (table ,
1295
+ nla [NFTA_CHAIN_NAME ],
1296
+ genmask );
1297
+ if (IS_ERR (chain2 ))
1298
+ return PTR_ERR (chain2 );
1299
+ }
1278
1300
1279
1301
if (nla [NFTA_CHAIN_COUNTERS ]) {
1280
1302
if (!(chain -> flags & NFT_BASE_CHAIN ))
@@ -1468,7 +1490,7 @@ static int nf_tables_delchain(struct net *net, struct sock *nlsk,
1468
1490
if (IS_ERR (table ))
1469
1491
return PTR_ERR (table );
1470
1492
1471
- chain = nf_tables_chain_lookup (table , nla [NFTA_CHAIN_NAME ]);
1493
+ chain = nf_tables_chain_lookup (table , nla [NFTA_CHAIN_NAME ], genmask );
1472
1494
if (IS_ERR (chain ))
1473
1495
return PTR_ERR (chain );
1474
1496
if (chain -> use > 0 )
@@ -1930,11 +1952,9 @@ static int nf_tables_getrule(struct net *net, struct sock *nlsk,
1930
1952
if (IS_ERR (table ))
1931
1953
return PTR_ERR (table );
1932
1954
1933
- chain = nf_tables_chain_lookup (table , nla [NFTA_RULE_CHAIN ]);
1955
+ chain = nf_tables_chain_lookup (table , nla [NFTA_RULE_CHAIN ], genmask );
1934
1956
if (IS_ERR (chain ))
1935
1957
return PTR_ERR (chain );
1936
- if (chain -> flags & NFT_CHAIN_INACTIVE )
1937
- return - ENOENT ;
1938
1958
1939
1959
rule = nf_tables_rule_lookup (chain , nla [NFTA_RULE_HANDLE ]);
1940
1960
if (IS_ERR (rule ))
@@ -2008,7 +2028,7 @@ static int nf_tables_newrule(struct net *net, struct sock *nlsk,
2008
2028
if (IS_ERR (table ))
2009
2029
return PTR_ERR (table );
2010
2030
2011
- chain = nf_tables_chain_lookup (table , nla [NFTA_RULE_CHAIN ]);
2031
+ chain = nf_tables_chain_lookup (table , nla [NFTA_RULE_CHAIN ], genmask );
2012
2032
if (IS_ERR (chain ))
2013
2033
return PTR_ERR (chain );
2014
2034
@@ -2166,7 +2186,8 @@ static int nf_tables_delrule(struct net *net, struct sock *nlsk,
2166
2186
return PTR_ERR (table );
2167
2187
2168
2188
if (nla [NFTA_RULE_CHAIN ]) {
2169
- chain = nf_tables_chain_lookup (table , nla [NFTA_RULE_CHAIN ]);
2189
+ chain = nf_tables_chain_lookup (table , nla [NFTA_RULE_CHAIN ],
2190
+ genmask );
2170
2191
if (IS_ERR (chain ))
2171
2192
return PTR_ERR (chain );
2172
2193
}
@@ -2186,6 +2207,9 @@ static int nf_tables_delrule(struct net *net, struct sock *nlsk,
2186
2207
}
2187
2208
} else {
2188
2209
list_for_each_entry (chain , & table -> chains , list ) {
2210
+ if (!nft_is_active_next (net , chain ))
2211
+ continue ;
2212
+
2189
2213
ctx .chain = chain ;
2190
2214
err = nft_delrule_by_chain (& ctx );
2191
2215
if (err < 0 )
@@ -3934,7 +3958,8 @@ static int nf_tables_commit(struct net *net, struct sk_buff *skb)
3934
3958
case NFT_MSG_NEWTABLE :
3935
3959
if (nft_trans_table_update (trans )) {
3936
3960
if (!nft_trans_table_enable (trans )) {
3937
- nf_tables_table_disable (trans -> ctx .afi ,
3961
+ nf_tables_table_disable (net ,
3962
+ trans -> ctx .afi ,
3938
3963
trans -> ctx .table );
3939
3964
trans -> ctx .table -> flags |= NFT_TABLE_F_DORMANT ;
3940
3965
}
@@ -3952,12 +3977,13 @@ static int nf_tables_commit(struct net *net, struct sk_buff *skb)
3952
3977
if (nft_trans_chain_update (trans ))
3953
3978
nft_chain_commit_update (trans );
3954
3979
else
3955
- trans -> ctx .chain -> flags &= ~ NFT_CHAIN_INACTIVE ;
3980
+ nft_clear ( net , trans -> ctx .chain ) ;
3956
3981
3957
3982
nf_tables_chain_notify (& trans -> ctx , NFT_MSG_NEWCHAIN );
3958
3983
nft_trans_destroy (trans );
3959
3984
break ;
3960
3985
case NFT_MSG_DELCHAIN :
3986
+ list_del_rcu (& trans -> ctx .chain -> list );
3961
3987
nf_tables_chain_notify (& trans -> ctx , NFT_MSG_DELCHAIN );
3962
3988
nf_tables_unregister_hooks (trans -> ctx .table ,
3963
3989
trans -> ctx .chain ,
@@ -4061,7 +4087,8 @@ static int nf_tables_abort(struct net *net, struct sk_buff *skb)
4061
4087
case NFT_MSG_NEWTABLE :
4062
4088
if (nft_trans_table_update (trans )) {
4063
4089
if (nft_trans_table_enable (trans )) {
4064
- nf_tables_table_disable (trans -> ctx .afi ,
4090
+ nf_tables_table_disable (net ,
4091
+ trans -> ctx .afi ,
4065
4092
trans -> ctx .table );
4066
4093
trans -> ctx .table -> flags |= NFT_TABLE_F_DORMANT ;
4067
4094
}
@@ -4089,8 +4116,7 @@ static int nf_tables_abort(struct net *net, struct sk_buff *skb)
4089
4116
break ;
4090
4117
case NFT_MSG_DELCHAIN :
4091
4118
trans -> ctx .table -> use ++ ;
4092
- list_add_tail_rcu (& trans -> ctx .chain -> list ,
4093
- & trans -> ctx .table -> chains );
4119
+ nft_clear (trans -> ctx .net , trans -> ctx .chain );
4094
4120
nft_trans_destroy (trans );
4095
4121
break ;
4096
4122
case NFT_MSG_NEWRULE :
@@ -4413,6 +4439,7 @@ static const struct nla_policy nft_verdict_policy[NFTA_VERDICT_MAX + 1] = {
4413
4439
static int nft_verdict_init (const struct nft_ctx * ctx , struct nft_data * data ,
4414
4440
struct nft_data_desc * desc , const struct nlattr * nla )
4415
4441
{
4442
+ u8 genmask = nft_genmask_next (ctx -> net );
4416
4443
struct nlattr * tb [NFTA_VERDICT_MAX + 1 ];
4417
4444
struct nft_chain * chain ;
4418
4445
int err ;
@@ -4445,7 +4472,7 @@ static int nft_verdict_init(const struct nft_ctx *ctx, struct nft_data *data,
4445
4472
if (!tb [NFTA_VERDICT_CHAIN ])
4446
4473
return - EINVAL ;
4447
4474
chain = nf_tables_chain_lookup (ctx -> table ,
4448
- tb [NFTA_VERDICT_CHAIN ]);
4475
+ tb [NFTA_VERDICT_CHAIN ], genmask );
4449
4476
if (IS_ERR (chain ))
4450
4477
return PTR_ERR (chain );
4451
4478
if (chain -> flags & NFT_BASE_CHAIN )
0 commit comments