28
28
29
29
#define NFT_MODULE_AUTOLOAD_LIMIT (MODULE_NAME_LEN - sizeof("nft-expr-255-"))
30
30
31
+ unsigned int nf_tables_net_id __read_mostly ;
32
+ EXPORT_SYMBOL_GPL (nf_tables_net_id );
33
+
31
34
static LIST_HEAD (nf_tables_expressions );
32
35
static LIST_HEAD (nf_tables_objects );
33
36
static LIST_HEAD (nf_tables_flowtables );
@@ -3593,8 +3596,8 @@ static struct nft_set *nft_set_lookup_byid(const struct net *net,
3593
3596
const struct nft_table * table ,
3594
3597
const struct nlattr * nla , u8 genmask )
3595
3598
{
3596
- struct nft_trans * trans ;
3597
3599
u32 id = ntohl (nla_get_be32 (nla ));
3600
+ struct nft_trans * trans ;
3598
3601
3599
3602
list_for_each_entry (trans , & net -> nft .commit_list , list ) {
3600
3603
if (trans -> msg_type == NFT_MSG_NEWSET ) {
@@ -3837,8 +3840,8 @@ static void nf_tables_set_notify(const struct nft_ctx *ctx,
3837
3840
const struct nft_set * set , int event ,
3838
3841
gfp_t gfp_flags )
3839
3842
{
3840
- u32 portid = ctx -> portid ;
3841
3843
struct sk_buff * skb ;
3844
+ u32 portid = ctx -> portid ;
3842
3845
u16 flags = 0 ;
3843
3846
int err ;
3844
3847
@@ -4783,7 +4786,7 @@ static int nf_tables_dump_set(struct sk_buff *skb, struct netlink_callback *cb)
4783
4786
rcu_read_lock ();
4784
4787
cb -> seq = READ_ONCE (net -> nft .base_seq );
4785
4788
4786
- list_for_each_entry_rcu (table , & net -> nft .tables , list ) {
4789
+ list_for_each_entry_rcu (table , & net -> nft .tables , list ) {
4787
4790
if (dump_ctx -> ctx .family != NFPROTO_UNSPEC &&
4788
4791
dump_ctx -> ctx .family != table -> family )
4789
4792
continue ;
@@ -7957,14 +7960,31 @@ static void nft_set_commit_update(struct list_head *set_update_list)
7957
7960
}
7958
7961
}
7959
7962
7963
+ static unsigned int nft_gc_seq_begin (struct nftables_pernet * nft_net )
7964
+ {
7965
+ unsigned int gc_seq ;
7966
+
7967
+ /* Bump gc counter, it becomes odd, this is the busy mark. */
7968
+ gc_seq = READ_ONCE (nft_net -> gc_seq );
7969
+ WRITE_ONCE (nft_net -> gc_seq , ++ gc_seq );
7970
+
7971
+ return gc_seq ;
7972
+ }
7973
+
7974
+ static void nft_gc_seq_end (struct nftables_pernet * nft_net , unsigned int gc_seq )
7975
+ {
7976
+ WRITE_ONCE (nft_net -> gc_seq , ++ gc_seq );
7977
+ }
7978
+
7960
7979
static int nf_tables_commit (struct net * net , struct sk_buff * skb )
7961
7980
{
7981
+ struct nftables_pernet * nft_net = nft_pernet (net );
7962
7982
struct nft_trans * trans , * next ;
7983
+ unsigned int base_seq , gc_seq ;
7963
7984
LIST_HEAD (set_update_list );
7964
7985
struct nft_trans_elem * te ;
7965
7986
struct nft_chain * chain ;
7966
7987
struct nft_table * table ;
7967
- unsigned int base_seq ;
7968
7988
LIST_HEAD (adl );
7969
7989
int err ;
7970
7990
@@ -8015,6 +8035,8 @@ static int nf_tables_commit(struct net *net, struct sk_buff *skb)
8015
8035
8016
8036
WRITE_ONCE (net -> nft .base_seq , base_seq );
8017
8037
8038
+ gc_seq = nft_gc_seq_begin (nft_net );
8039
+
8018
8040
/* step 3. Start new generation, rules_gen_X now in use. */
8019
8041
net -> nft .gencursor = nft_gencursor_next (net );
8020
8042
@@ -8393,18 +8415,25 @@ static void nf_tables_cleanup(struct net *net)
8393
8415
static int nf_tables_abort (struct net * net , struct sk_buff * skb ,
8394
8416
enum nfnl_abort_action action )
8395
8417
{
8396
- int ret = __nf_tables_abort (net , action );
8418
+ struct nftables_pernet * nft_net = nft_pernet (net );
8419
+ unsigned int gc_seq ;
8420
+ int ret ;
8397
8421
8422
+ gc_seq = nft_gc_seq_begin (nft_net );
8423
+ ret = __nf_tables_abort (net , action );
8424
+ nft_gc_seq_end (nft_net , gc_seq );
8398
8425
mutex_unlock (& net -> nft_commit_mutex );
8399
8426
8400
8427
return ret ;
8401
8428
}
8402
8429
8403
8430
static bool nf_tables_valid_genid (struct net * net , u32 genid )
8404
8431
{
8432
+ struct nftables_pernet * nft_net = nft_pernet (net );
8405
8433
bool genid_ok ;
8406
8434
8407
8435
mutex_lock (& net -> nft_commit_mutex );
8436
+ nft_net -> tstamp = get_jiffies_64 ();
8408
8437
8409
8438
genid_ok = genid == 0 || net -> nft .base_seq == genid ;
8410
8439
if (!genid_ok )
@@ -9014,13 +9043,16 @@ static void __nft_release_tables(struct net *net)
9014
9043
9015
9044
static int __net_init nf_tables_init_net (struct net * net )
9016
9045
{
9046
+ struct nftables_pernet * nft_net = nft_pernet (net );
9047
+
9017
9048
INIT_LIST_HEAD (& net -> nft .tables );
9018
9049
INIT_LIST_HEAD (& net -> nft .commit_list );
9019
9050
INIT_LIST_HEAD (& net -> nft_module_list );
9020
9051
INIT_LIST_HEAD (& net -> nft_notify_list );
9021
9052
mutex_init (& net -> nft_commit_mutex );
9022
9053
net -> nft .base_seq = 1 ;
9023
9054
net -> nft .validate_state = NFT_VALIDATE_SKIP ;
9055
+ nft_net -> gc_seq = 0 ;
9024
9056
9025
9057
return 0 ;
9026
9058
}
@@ -9034,11 +9066,21 @@ static void __net_exit nf_tables_pre_exit_net(struct net *net)
9034
9066
9035
9067
static void __net_exit nf_tables_exit_net (struct net * net )
9036
9068
{
9069
+ struct nftables_pernet * nft_net = nft_pernet (net );
9070
+ unsigned int gc_seq ;
9071
+
9037
9072
mutex_lock (& net -> nft_commit_mutex );
9073
+
9074
+ gc_seq = nft_gc_seq_begin (nft_net );
9075
+
9038
9076
if (!list_empty (& net -> nft .commit_list ) ||
9039
9077
!list_empty (& net -> nft_module_list ))
9040
9078
__nf_tables_abort (net , NFNL_ABORT_NONE );
9079
+
9041
9080
__nft_release_tables (net );
9081
+
9082
+ nft_gc_seq_end (nft_net , gc_seq );
9083
+
9042
9084
mutex_unlock (& net -> nft_commit_mutex );
9043
9085
WARN_ON_ONCE (!list_empty (& net -> nft .tables ));
9044
9086
WARN_ON_ONCE (!list_empty (& net -> nft_module_list ));
0 commit comments