@@ -1106,11 +1106,14 @@ nf_tables_chain_type_lookup(struct net *net, const struct nlattr *nla,
11061106 return ERR_PTR (- ENOENT );
11071107}
11081108
1109- static __be16 nft_base_seq (const struct net * net )
1109+ static unsigned int nft_base_seq (const struct net * net )
11101110{
1111- struct nftables_pernet * nft_net = nft_pernet (net );
1111+ return READ_ONCE (net -> nft .base_seq );
1112+ }
11121113
1113- return htons (nft_net -> base_seq & 0xffff );
1114+ static __be16 nft_base_seq_be16 (const struct net * net )
1115+ {
1116+ return htons (nft_base_seq (net ) & 0xffff );
11141117}
11151118
11161119static const struct nla_policy nft_table_policy [NFTA_TABLE_MAX + 1 ] = {
@@ -1130,7 +1133,7 @@ static int nf_tables_fill_table_info(struct sk_buff *skb, struct net *net,
11301133
11311134 event = nfnl_msg_type (NFNL_SUBSYS_NFTABLES , event );
11321135 nlh = nfnl_msg_put (skb , portid , seq , event , flags , family ,
1133- NFNETLINK_V0 , nft_base_seq (net ));
1136+ NFNETLINK_V0 , nft_base_seq_be16 (net ));
11341137 if (!nlh )
11351138 goto nla_put_failure ;
11361139
@@ -1222,7 +1225,7 @@ static int nf_tables_dump_tables(struct sk_buff *skb,
12221225
12231226 rcu_read_lock ();
12241227 nft_net = nft_pernet (net );
1225- cb -> seq = READ_ONCE ( nft_net -> base_seq );
1228+ cb -> seq = nft_base_seq ( net );
12261229
12271230 list_for_each_entry_rcu (table , & nft_net -> tables , list ) {
12281231 if (family != NFPROTO_UNSPEC && family != table -> family )
@@ -1992,7 +1995,7 @@ static int nf_tables_fill_chain_info(struct sk_buff *skb, struct net *net,
19921995
19931996 event = nfnl_msg_type (NFNL_SUBSYS_NFTABLES , event );
19941997 nlh = nfnl_msg_put (skb , portid , seq , event , flags , family ,
1995- NFNETLINK_V0 , nft_base_seq (net ));
1998+ NFNETLINK_V0 , nft_base_seq_be16 (net ));
19961999 if (!nlh )
19972000 goto nla_put_failure ;
19982001
@@ -2093,7 +2096,7 @@ static int nf_tables_dump_chains(struct sk_buff *skb,
20932096
20942097 rcu_read_lock ();
20952098 nft_net = nft_pernet (net );
2096- cb -> seq = READ_ONCE ( nft_net -> base_seq );
2099+ cb -> seq = nft_base_seq ( net );
20972100
20982101 list_for_each_entry_rcu (table , & nft_net -> tables , list ) {
20992102 if (family != NFPROTO_UNSPEC && family != table -> family )
@@ -3604,7 +3607,7 @@ static int nf_tables_fill_rule_info(struct sk_buff *skb, struct net *net,
36043607 u16 type = nfnl_msg_type (NFNL_SUBSYS_NFTABLES , event );
36053608
36063609 nlh = nfnl_msg_put (skb , portid , seq , type , flags , family , NFNETLINK_V0 ,
3607- nft_base_seq (net ));
3610+ nft_base_seq_be16 (net ));
36083611 if (!nlh )
36093612 goto nla_put_failure ;
36103613
@@ -3772,7 +3775,7 @@ static int nf_tables_dump_rules(struct sk_buff *skb,
37723775
37733776 rcu_read_lock ();
37743777 nft_net = nft_pernet (net );
3775- cb -> seq = READ_ONCE ( nft_net -> base_seq );
3778+ cb -> seq = nft_base_seq ( net );
37763779
37773780 list_for_each_entry_rcu (table , & nft_net -> tables , list ) {
37783781 if (family != NFPROTO_UNSPEC && family != table -> family )
@@ -3983,7 +3986,7 @@ static int nf_tables_getrule_reset(struct sk_buff *skb,
39833986 buf = kasprintf (GFP_ATOMIC , "%.*s:%u" ,
39843987 nla_len (nla [NFTA_RULE_TABLE ]),
39853988 (char * )nla_data (nla [NFTA_RULE_TABLE ]),
3986- nft_net -> base_seq );
3989+ nft_base_seq ( net ) );
39873990 audit_log_nfcfg (buf , info -> nfmsg -> nfgen_family , 1 ,
39883991 AUDIT_NFT_OP_RULE_RESET , GFP_ATOMIC );
39893992 kfree (buf );
@@ -4819,7 +4822,7 @@ static int nf_tables_fill_set(struct sk_buff *skb, const struct nft_ctx *ctx,
48194822
48204823 event = nfnl_msg_type (NFNL_SUBSYS_NFTABLES , event );
48214824 nlh = nfnl_msg_put (skb , portid , seq , event , flags , ctx -> family ,
4822- NFNETLINK_V0 , nft_base_seq (ctx -> net ));
4825+ NFNETLINK_V0 , nft_base_seq_be16 (ctx -> net ));
48234826 if (!nlh )
48244827 goto nla_put_failure ;
48254828
@@ -4963,7 +4966,7 @@ static int nf_tables_dump_sets(struct sk_buff *skb, struct netlink_callback *cb)
49634966
49644967 rcu_read_lock ();
49654968 nft_net = nft_pernet (net );
4966- cb -> seq = READ_ONCE ( nft_net -> base_seq );
4969+ cb -> seq = nft_base_seq ( net );
49674970
49684971 list_for_each_entry_rcu (table , & nft_net -> tables , list ) {
49694972 if (ctx -> family != NFPROTO_UNSPEC &&
@@ -6140,7 +6143,7 @@ static int nf_tables_dump_set(struct sk_buff *skb, struct netlink_callback *cb)
61406143
61416144 rcu_read_lock ();
61426145 nft_net = nft_pernet (net );
6143- cb -> seq = READ_ONCE ( nft_net -> base_seq );
6146+ cb -> seq = nft_base_seq ( net );
61446147
61456148 list_for_each_entry_rcu (table , & nft_net -> tables , list ) {
61466149 if (dump_ctx -> ctx .family != NFPROTO_UNSPEC &&
@@ -6169,7 +6172,7 @@ static int nf_tables_dump_set(struct sk_buff *skb, struct netlink_callback *cb)
61696172 seq = cb -> nlh -> nlmsg_seq ;
61706173
61716174 nlh = nfnl_msg_put (skb , portid , seq , event , NLM_F_MULTI ,
6172- table -> family , NFNETLINK_V0 , nft_base_seq (net ));
6175+ table -> family , NFNETLINK_V0 , nft_base_seq_be16 (net ));
61736176 if (!nlh )
61746177 goto nla_put_failure ;
61756178
@@ -6262,7 +6265,7 @@ static int nf_tables_fill_setelem_info(struct sk_buff *skb,
62626265
62636266 event = nfnl_msg_type (NFNL_SUBSYS_NFTABLES , event );
62646267 nlh = nfnl_msg_put (skb , portid , seq , event , flags , ctx -> family ,
6265- NFNETLINK_V0 , nft_base_seq (ctx -> net ));
6268+ NFNETLINK_V0 , nft_base_seq_be16 (ctx -> net ));
62666269 if (!nlh )
62676270 goto nla_put_failure ;
62686271
@@ -6561,7 +6564,7 @@ static int nf_tables_getsetelem_reset(struct sk_buff *skb,
65616564 }
65626565 nelems ++ ;
65636566 }
6564- audit_log_nft_set_reset (dump_ctx .ctx .table , nft_net -> base_seq , nelems );
6567+ audit_log_nft_set_reset (dump_ctx .ctx .table , nft_base_seq ( info -> net ) , nelems );
65656568
65666569out_unlock :
65676570 rcu_read_unlock ();
@@ -8312,7 +8315,7 @@ static int nf_tables_fill_obj_info(struct sk_buff *skb, struct net *net,
83128315
83138316 event = nfnl_msg_type (NFNL_SUBSYS_NFTABLES , event );
83148317 nlh = nfnl_msg_put (skb , portid , seq , event , flags , family ,
8315- NFNETLINK_V0 , nft_base_seq (net ));
8318+ NFNETLINK_V0 , nft_base_seq_be16 (net ));
83168319 if (!nlh )
83178320 goto nla_put_failure ;
83188321
@@ -8376,7 +8379,7 @@ static int nf_tables_dump_obj(struct sk_buff *skb, struct netlink_callback *cb)
83768379
83778380 rcu_read_lock ();
83788381 nft_net = nft_pernet (net );
8379- cb -> seq = READ_ONCE ( nft_net -> base_seq );
8382+ cb -> seq = nft_base_seq ( net );
83808383
83818384 list_for_each_entry_rcu (table , & nft_net -> tables , list ) {
83828385 if (family != NFPROTO_UNSPEC && family != table -> family )
@@ -8410,7 +8413,7 @@ static int nf_tables_dump_obj(struct sk_buff *skb, struct netlink_callback *cb)
84108413 idx ++ ;
84118414 }
84128415 if (ctx -> reset && entries )
8413- audit_log_obj_reset (table , nft_net -> base_seq , entries );
8416+ audit_log_obj_reset (table , nft_base_seq ( net ) , entries );
84148417 if (rc < 0 )
84158418 break ;
84168419 }
@@ -8579,7 +8582,7 @@ static int nf_tables_getobj_reset(struct sk_buff *skb,
85798582 buf = kasprintf (GFP_ATOMIC , "%.*s:%u" ,
85808583 nla_len (nla [NFTA_OBJ_TABLE ]),
85818584 (char * )nla_data (nla [NFTA_OBJ_TABLE ]),
8582- nft_net -> base_seq );
8585+ nft_base_seq ( net ) );
85838586 audit_log_nfcfg (buf , info -> nfmsg -> nfgen_family , 1 ,
85848587 AUDIT_NFT_OP_OBJ_RESET , GFP_ATOMIC );
85858588 kfree (buf );
@@ -8684,9 +8687,8 @@ void nft_obj_notify(struct net *net, const struct nft_table *table,
86848687 struct nft_object * obj , u32 portid , u32 seq , int event ,
86858688 u16 flags , int family , int report , gfp_t gfp )
86868689{
8687- struct nftables_pernet * nft_net = nft_pernet (net );
86888690 char * buf = kasprintf (gfp , "%s:%u" ,
8689- table -> name , nft_net -> base_seq );
8691+ table -> name , nft_base_seq ( net ) );
86908692
86918693 audit_log_nfcfg (buf ,
86928694 family ,
@@ -9352,7 +9354,7 @@ static int nf_tables_fill_flowtable_info(struct sk_buff *skb, struct net *net,
93529354
93539355 event = nfnl_msg_type (NFNL_SUBSYS_NFTABLES , event );
93549356 nlh = nfnl_msg_put (skb , portid , seq , event , flags , family ,
9355- NFNETLINK_V0 , nft_base_seq (net ));
9357+ NFNETLINK_V0 , nft_base_seq_be16 (net ));
93569358 if (!nlh )
93579359 goto nla_put_failure ;
93589360
@@ -9419,7 +9421,7 @@ static int nf_tables_dump_flowtable(struct sk_buff *skb,
94199421
94209422 rcu_read_lock ();
94219423 nft_net = nft_pernet (net );
9422- cb -> seq = READ_ONCE ( nft_net -> base_seq );
9424+ cb -> seq = nft_base_seq ( net );
94239425
94249426 list_for_each_entry_rcu (table , & nft_net -> tables , list ) {
94259427 if (family != NFPROTO_UNSPEC && family != table -> family )
@@ -9604,17 +9606,16 @@ static void nf_tables_flowtable_destroy(struct nft_flowtable *flowtable)
96049606static int nf_tables_fill_gen_info (struct sk_buff * skb , struct net * net ,
96059607 u32 portid , u32 seq )
96069608{
9607- struct nftables_pernet * nft_net = nft_pernet (net );
96089609 struct nlmsghdr * nlh ;
96099610 char buf [TASK_COMM_LEN ];
96109611 int event = nfnl_msg_type (NFNL_SUBSYS_NFTABLES , NFT_MSG_NEWGEN );
96119612
96129613 nlh = nfnl_msg_put (skb , portid , seq , event , 0 , AF_UNSPEC ,
9613- NFNETLINK_V0 , nft_base_seq (net ));
9614+ NFNETLINK_V0 , nft_base_seq_be16 (net ));
96149615 if (!nlh )
96159616 goto nla_put_failure ;
96169617
9617- if (nla_put_be32 (skb , NFTA_GEN_ID , htonl (nft_net -> base_seq )) ||
9618+ if (nla_put_be32 (skb , NFTA_GEN_ID , htonl (nft_base_seq ( net ) )) ||
96189619 nla_put_be32 (skb , NFTA_GEN_PROC_PID , htonl (task_pid_nr (current ))) ||
96199620 nla_put_string (skb , NFTA_GEN_PROC_NAME , get_task_comm (buf , current )))
96209621 goto nla_put_failure ;
@@ -10790,11 +10791,12 @@ static int nf_tables_commit(struct net *net, struct sk_buff *skb)
1079010791 * Bump generation counter, invalidate any dump in progress.
1079110792 * Cannot fail after this point.
1079210793 */
10793- base_seq = READ_ONCE ( nft_net -> base_seq );
10794+ base_seq = nft_base_seq ( net );
1079410795 while (++ base_seq == 0 )
1079510796 ;
1079610797
10797- WRITE_ONCE (nft_net -> base_seq , base_seq );
10798+ /* pairs with smp_load_acquire in nft_lookup_eval */
10799+ smp_store_release (& net -> nft .base_seq , base_seq );
1079810800
1079910801 gc_seq = nft_gc_seq_begin (nft_net );
1080010802
@@ -11003,7 +11005,7 @@ static int nf_tables_commit(struct net *net, struct sk_buff *skb)
1100311005
1100411006 nft_commit_notify (net , NETLINK_CB (skb ).portid );
1100511007 nf_tables_gen_notify (net , skb , NFT_MSG_NEWGEN );
11006- nf_tables_commit_audit_log (& adl , nft_net -> base_seq );
11008+ nf_tables_commit_audit_log (& adl , nft_base_seq ( net ) );
1100711009
1100811010 nft_gc_seq_end (nft_net , gc_seq );
1100911011 nft_net -> validate_state = NFT_VALIDATE_SKIP ;
@@ -11328,7 +11330,7 @@ static bool nf_tables_valid_genid(struct net *net, u32 genid)
1132811330 mutex_lock (& nft_net -> commit_mutex );
1132911331 nft_net -> tstamp = get_jiffies_64 ();
1133011332
11331- genid_ok = genid == 0 || nft_net -> base_seq == genid ;
11333+ genid_ok = genid == 0 || nft_base_seq ( net ) == genid ;
1133211334 if (!genid_ok )
1133311335 mutex_unlock (& nft_net -> commit_mutex );
1133411336
@@ -12006,7 +12008,7 @@ static int __net_init nf_tables_init_net(struct net *net)
1200612008 INIT_LIST_HEAD (& nft_net -> module_list );
1200712009 INIT_LIST_HEAD (& nft_net -> notify_list );
1200812010 mutex_init (& nft_net -> commit_mutex );
12009- nft_net -> base_seq = 1 ;
12011+ net -> nft . base_seq = 1 ;
1201012012 nft_net -> gc_seq = 0 ;
1201112013 nft_net -> validate_state = NFT_VALIDATE_SKIP ;
1201212014 INIT_WORK (& nft_net -> destroy_work , nf_tables_trans_destroy_work );
0 commit comments