@@ -1131,11 +1131,14 @@ nf_tables_chain_type_lookup(struct net *net, const struct nlattr *nla,
11311131 return ERR_PTR (- ENOENT );
11321132}
11331133
1134- static __be16 nft_base_seq (const struct net * net )
1134+ static unsigned int nft_base_seq (const struct net * net )
11351135{
1136- struct nftables_pernet * nft_net = nft_pernet (net );
1136+ return READ_ONCE (net -> nft .base_seq );
1137+ }
11371138
1138- return htons (nft_net -> base_seq & 0xffff );
1139+ static __be16 nft_base_seq_be16 (const struct net * net )
1140+ {
1141+ return htons (nft_base_seq (net ) & 0xffff );
11391142}
11401143
11411144static const struct nla_policy nft_table_policy [NFTA_TABLE_MAX + 1 ] = {
@@ -1155,7 +1158,7 @@ static int nf_tables_fill_table_info(struct sk_buff *skb, struct net *net,
11551158
11561159 nlh = nfnl_msg_put (skb , portid , seq ,
11571160 nfnl_msg_type (NFNL_SUBSYS_NFTABLES , event ),
1158- flags , family , NFNETLINK_V0 , nft_base_seq (net ));
1161+ flags , family , NFNETLINK_V0 , nft_base_seq_be16 (net ));
11591162 if (!nlh )
11601163 goto nla_put_failure ;
11611164
@@ -1248,7 +1251,7 @@ static int nf_tables_dump_tables(struct sk_buff *skb,
12481251
12491252 rcu_read_lock ();
12501253 nft_net = nft_pernet (net );
1251- cb -> seq = READ_ONCE ( nft_net -> base_seq );
1254+ cb -> seq = nft_base_seq ( net );
12521255
12531256 list_for_each_entry_rcu (table , & nft_net -> tables , list ) {
12541257 if (family != NFPROTO_UNSPEC && family != table -> family )
@@ -2030,7 +2033,7 @@ static int nf_tables_fill_chain_info(struct sk_buff *skb, struct net *net,
20302033
20312034 nlh = nfnl_msg_put (skb , portid , seq ,
20322035 nfnl_msg_type (NFNL_SUBSYS_NFTABLES , event ),
2033- flags , family , NFNETLINK_V0 , nft_base_seq (net ));
2036+ flags , family , NFNETLINK_V0 , nft_base_seq_be16 (net ));
20342037 if (!nlh )
20352038 goto nla_put_failure ;
20362039
@@ -2133,7 +2136,7 @@ static int nf_tables_dump_chains(struct sk_buff *skb,
21332136
21342137 rcu_read_lock ();
21352138 nft_net = nft_pernet (net );
2136- cb -> seq = READ_ONCE ( nft_net -> base_seq );
2139+ cb -> seq = nft_base_seq ( net );
21372140
21382141 list_for_each_entry_rcu (table , & nft_net -> tables , list ) {
21392142 if (family != NFPROTO_UNSPEC && family != table -> family )
@@ -3671,7 +3674,7 @@ static int nf_tables_fill_rule_info(struct sk_buff *skb, struct net *net,
36713674 u16 type = nfnl_msg_type (NFNL_SUBSYS_NFTABLES , event );
36723675
36733676 nlh = nfnl_msg_put (skb , portid , seq , type , flags , family , NFNETLINK_V0 ,
3674- nft_base_seq (net ));
3677+ nft_base_seq_be16 (net ));
36753678 if (!nlh )
36763679 goto nla_put_failure ;
36773680
@@ -3839,7 +3842,7 @@ static int nf_tables_dump_rules(struct sk_buff *skb,
38393842
38403843 rcu_read_lock ();
38413844 nft_net = nft_pernet (net );
3842- cb -> seq = READ_ONCE ( nft_net -> base_seq );
3845+ cb -> seq = nft_base_seq ( net );
38433846
38443847 list_for_each_entry_rcu (table , & nft_net -> tables , list ) {
38453848 if (family != NFPROTO_UNSPEC && family != table -> family )
@@ -4050,7 +4053,7 @@ static int nf_tables_getrule_reset(struct sk_buff *skb,
40504053 buf = kasprintf (GFP_ATOMIC , "%.*s:%u" ,
40514054 nla_len (nla [NFTA_RULE_TABLE ]),
40524055 (char * )nla_data (nla [NFTA_RULE_TABLE ]),
4053- nft_net -> base_seq );
4056+ nft_base_seq ( net ) );
40544057 audit_log_nfcfg (buf , info -> nfmsg -> nfgen_family , 1 ,
40554058 AUDIT_NFT_OP_RULE_RESET , GFP_ATOMIC );
40564059 kfree (buf );
@@ -4887,7 +4890,7 @@ static int nf_tables_fill_set(struct sk_buff *skb, const struct nft_ctx *ctx,
48874890 nlh = nfnl_msg_put (skb , portid , seq ,
48884891 nfnl_msg_type (NFNL_SUBSYS_NFTABLES , event ),
48894892 flags , ctx -> family , NFNETLINK_V0 ,
4890- nft_base_seq (ctx -> net ));
4893+ nft_base_seq_be16 (ctx -> net ));
48914894 if (!nlh )
48924895 goto nla_put_failure ;
48934896
@@ -5032,7 +5035,7 @@ static int nf_tables_dump_sets(struct sk_buff *skb, struct netlink_callback *cb)
50325035
50335036 rcu_read_lock ();
50345037 nft_net = nft_pernet (net );
5035- cb -> seq = READ_ONCE ( nft_net -> base_seq );
5038+ cb -> seq = nft_base_seq ( net );
50365039
50375040 list_for_each_entry_rcu (table , & nft_net -> tables , list ) {
50385041 if (ctx -> family != NFPROTO_UNSPEC &&
@@ -6209,7 +6212,7 @@ static int nf_tables_dump_set(struct sk_buff *skb, struct netlink_callback *cb)
62096212
62106213 rcu_read_lock ();
62116214 nft_net = nft_pernet (net );
6212- cb -> seq = READ_ONCE ( nft_net -> base_seq );
6215+ cb -> seq = nft_base_seq ( net );
62136216
62146217 list_for_each_entry_rcu (table , & nft_net -> tables , list ) {
62156218 if (dump_ctx -> ctx .family != NFPROTO_UNSPEC &&
@@ -6238,7 +6241,7 @@ static int nf_tables_dump_set(struct sk_buff *skb, struct netlink_callback *cb)
62386241 seq = cb -> nlh -> nlmsg_seq ;
62396242
62406243 nlh = nfnl_msg_put (skb , portid , seq , event , NLM_F_MULTI ,
6241- table -> family , NFNETLINK_V0 , nft_base_seq (net ));
6244+ table -> family , NFNETLINK_V0 , nft_base_seq_be16 (net ));
62426245 if (!nlh )
62436246 goto nla_put_failure ;
62446247
@@ -6331,7 +6334,7 @@ static int nf_tables_fill_setelem_info(struct sk_buff *skb,
63316334
63326335 event = nfnl_msg_type (NFNL_SUBSYS_NFTABLES , event );
63336336 nlh = nfnl_msg_put (skb , portid , seq , event , flags , ctx -> family ,
6334- NFNETLINK_V0 , nft_base_seq (ctx -> net ));
6337+ NFNETLINK_V0 , nft_base_seq_be16 (ctx -> net ));
63356338 if (!nlh )
63366339 goto nla_put_failure ;
63376340
@@ -6630,7 +6633,7 @@ static int nf_tables_getsetelem_reset(struct sk_buff *skb,
66306633 }
66316634 nelems ++ ;
66326635 }
6633- audit_log_nft_set_reset (dump_ctx .ctx .table , nft_net -> base_seq , nelems );
6636+ audit_log_nft_set_reset (dump_ctx .ctx .table , nft_base_seq ( info -> net ) , nelems );
66346637
66356638out_unlock :
66366639 rcu_read_unlock ();
@@ -8381,7 +8384,7 @@ static int nf_tables_fill_obj_info(struct sk_buff *skb, struct net *net,
83818384
83828385 nlh = nfnl_msg_put (skb , portid , seq ,
83838386 nfnl_msg_type (NFNL_SUBSYS_NFTABLES , event ),
8384- flags , family , NFNETLINK_V0 , nft_base_seq (net ));
8387+ flags , family , NFNETLINK_V0 , nft_base_seq_be16 (net ));
83858388 if (!nlh )
83868389 goto nla_put_failure ;
83878390
@@ -8446,7 +8449,7 @@ static int nf_tables_dump_obj(struct sk_buff *skb, struct netlink_callback *cb)
84468449
84478450 rcu_read_lock ();
84488451 nft_net = nft_pernet (net );
8449- cb -> seq = READ_ONCE ( nft_net -> base_seq );
8452+ cb -> seq = nft_base_seq ( net );
84508453
84518454 list_for_each_entry_rcu (table , & nft_net -> tables , list ) {
84528455 if (family != NFPROTO_UNSPEC && family != table -> family )
@@ -8480,7 +8483,7 @@ static int nf_tables_dump_obj(struct sk_buff *skb, struct netlink_callback *cb)
84808483 idx ++ ;
84818484 }
84828485 if (ctx -> reset && entries )
8483- audit_log_obj_reset (table , nft_net -> base_seq , entries );
8486+ audit_log_obj_reset (table , nft_base_seq ( net ) , entries );
84848487 if (rc < 0 )
84858488 break ;
84868489 }
@@ -8649,7 +8652,7 @@ static int nf_tables_getobj_reset(struct sk_buff *skb,
86498652 buf = kasprintf (GFP_ATOMIC , "%.*s:%u" ,
86508653 nla_len (nla [NFTA_OBJ_TABLE ]),
86518654 (char * )nla_data (nla [NFTA_OBJ_TABLE ]),
8652- nft_net -> base_seq );
8655+ nft_base_seq ( net ) );
86538656 audit_log_nfcfg (buf , info -> nfmsg -> nfgen_family , 1 ,
86548657 AUDIT_NFT_OP_OBJ_RESET , GFP_ATOMIC );
86558658 kfree (buf );
@@ -8754,9 +8757,8 @@ void nft_obj_notify(struct net *net, const struct nft_table *table,
87548757 struct nft_object * obj , u32 portid , u32 seq , int event ,
87558758 u16 flags , int family , int report , gfp_t gfp )
87568759{
8757- struct nftables_pernet * nft_net = nft_pernet (net );
87588760 char * buf = kasprintf (gfp , "%s:%u" ,
8759- table -> name , nft_net -> base_seq );
8761+ table -> name , nft_base_seq ( net ) );
87608762
87618763 audit_log_nfcfg (buf ,
87628764 family ,
@@ -9442,7 +9444,7 @@ static int nf_tables_fill_flowtable_info(struct sk_buff *skb, struct net *net,
94429444
94439445 nlh = nfnl_msg_put (skb , portid , seq ,
94449446 nfnl_msg_type (NFNL_SUBSYS_NFTABLES , event ),
9445- flags , family , NFNETLINK_V0 , nft_base_seq (net ));
9447+ flags , family , NFNETLINK_V0 , nft_base_seq_be16 (net ));
94469448 if (!nlh )
94479449 goto nla_put_failure ;
94489450
@@ -9511,7 +9513,7 @@ static int nf_tables_dump_flowtable(struct sk_buff *skb,
95119513
95129514 rcu_read_lock ();
95139515 nft_net = nft_pernet (net );
9514- cb -> seq = READ_ONCE ( nft_net -> base_seq );
9516+ cb -> seq = nft_base_seq ( net );
95159517
95169518 list_for_each_entry_rcu (table , & nft_net -> tables , list ) {
95179519 if (family != NFPROTO_UNSPEC && family != table -> family )
@@ -9696,17 +9698,16 @@ static void nf_tables_flowtable_destroy(struct nft_flowtable *flowtable)
96969698static int nf_tables_fill_gen_info (struct sk_buff * skb , struct net * net ,
96979699 u32 portid , u32 seq )
96989700{
9699- struct nftables_pernet * nft_net = nft_pernet (net );
97009701 struct nlmsghdr * nlh ;
97019702 char buf [TASK_COMM_LEN ];
97029703 int event = nfnl_msg_type (NFNL_SUBSYS_NFTABLES , NFT_MSG_NEWGEN );
97039704
97049705 nlh = nfnl_msg_put (skb , portid , seq , event , 0 , AF_UNSPEC ,
9705- NFNETLINK_V0 , nft_base_seq (net ));
9706+ NFNETLINK_V0 , nft_base_seq_be16 (net ));
97069707 if (!nlh )
97079708 goto nla_put_failure ;
97089709
9709- if (nla_put_be32 (skb , NFTA_GEN_ID , htonl (nft_net -> base_seq )) ||
9710+ if (nla_put_be32 (skb , NFTA_GEN_ID , htonl (nft_base_seq ( net ) )) ||
97109711 nla_put_be32 (skb , NFTA_GEN_PROC_PID , htonl (task_pid_nr (current ))) ||
97119712 nla_put_string (skb , NFTA_GEN_PROC_NAME , get_task_comm (buf , current )))
97129713 goto nla_put_failure ;
@@ -10968,11 +10969,12 @@ static int nf_tables_commit(struct net *net, struct sk_buff *skb)
1096810969 * Bump generation counter, invalidate any dump in progress.
1096910970 * Cannot fail after this point.
1097010971 */
10971- base_seq = READ_ONCE ( nft_net -> base_seq );
10972+ base_seq = nft_base_seq ( net );
1097210973 while (++ base_seq == 0 )
1097310974 ;
1097410975
10975- WRITE_ONCE (nft_net -> base_seq , base_seq );
10976+ /* pairs with smp_load_acquire in nft_lookup_eval */
10977+ smp_store_release (& net -> nft .base_seq , base_seq );
1097610978
1097710979 gc_seq = nft_gc_seq_begin (nft_net );
1097810980
@@ -11181,7 +11183,7 @@ static int nf_tables_commit(struct net *net, struct sk_buff *skb)
1118111183
1118211184 nft_commit_notify (net , NETLINK_CB (skb ).portid );
1118311185 nf_tables_gen_notify (net , skb , NFT_MSG_NEWGEN );
11184- nf_tables_commit_audit_log (& adl , nft_net -> base_seq );
11186+ nf_tables_commit_audit_log (& adl , nft_base_seq ( net ) );
1118511187
1118611188 nft_gc_seq_end (nft_net , gc_seq );
1118711189 nft_net -> validate_state = NFT_VALIDATE_SKIP ;
@@ -11506,7 +11508,7 @@ static bool nf_tables_valid_genid(struct net *net, u32 genid)
1150611508 mutex_lock (& nft_net -> commit_mutex );
1150711509 nft_net -> tstamp = get_jiffies_64 ();
1150811510
11509- genid_ok = genid == 0 || nft_net -> base_seq == genid ;
11511+ genid_ok = genid == 0 || nft_base_seq ( net ) == genid ;
1151011512 if (!genid_ok )
1151111513 mutex_unlock (& nft_net -> commit_mutex );
1151211514
@@ -12143,7 +12145,7 @@ static int __net_init nf_tables_init_net(struct net *net)
1214312145 INIT_LIST_HEAD (& nft_net -> module_list );
1214412146 INIT_LIST_HEAD (& nft_net -> notify_list );
1214512147 mutex_init (& nft_net -> commit_mutex );
12146- nft_net -> base_seq = 1 ;
12148+ net -> nft . base_seq = 1 ;
1214712149 nft_net -> gc_seq = 0 ;
1214812150 nft_net -> validate_state = NFT_VALIDATE_SKIP ;
1214912151 INIT_WORK (& nft_net -> destroy_work , nf_tables_trans_destroy_work );
0 commit comments