@@ -9739,6 +9739,22 @@ static void nft_set_commit_update(struct list_head *set_update_list)
9739
9739
}
9740
9740
}
9741
9741
9742
+ static unsigned int nft_gc_seq_begin (struct nftables_pernet * nft_net )
9743
+ {
9744
+ unsigned int gc_seq ;
9745
+
9746
+ /* Bump gc counter, it becomes odd, this is the busy mark. */
9747
+ gc_seq = READ_ONCE (nft_net -> gc_seq );
9748
+ WRITE_ONCE (nft_net -> gc_seq , ++ gc_seq );
9749
+
9750
+ return gc_seq ;
9751
+ }
9752
+
9753
+ static void nft_gc_seq_end (struct nftables_pernet * nft_net , unsigned int gc_seq )
9754
+ {
9755
+ WRITE_ONCE (nft_net -> gc_seq , ++ gc_seq );
9756
+ }
9757
+
9742
9758
static int nf_tables_commit (struct net * net , struct sk_buff * skb )
9743
9759
{
9744
9760
struct nftables_pernet * nft_net = nft_pernet (net );
@@ -9824,9 +9840,7 @@ static int nf_tables_commit(struct net *net, struct sk_buff *skb)
9824
9840
9825
9841
WRITE_ONCE (nft_net -> base_seq , base_seq );
9826
9842
9827
- /* Bump gc counter, it becomes odd, this is the busy mark. */
9828
- gc_seq = READ_ONCE (nft_net -> gc_seq );
9829
- WRITE_ONCE (nft_net -> gc_seq , ++ gc_seq );
9843
+ gc_seq = nft_gc_seq_begin (nft_net );
9830
9844
9831
9845
/* step 3. Start new generation, rules_gen_X now in use. */
9832
9846
net -> nft .gencursor = nft_gencursor_next (net );
@@ -10039,7 +10053,7 @@ static int nf_tables_commit(struct net *net, struct sk_buff *skb)
10039
10053
nf_tables_gen_notify (net , skb , NFT_MSG_NEWGEN );
10040
10054
nf_tables_commit_audit_log (& adl , nft_net -> base_seq );
10041
10055
10042
- WRITE_ONCE (nft_net -> gc_seq , ++ gc_seq );
10056
+ nft_gc_seq_end (nft_net , gc_seq );
10043
10057
nf_tables_commit_release (net );
10044
10058
10045
10059
return 0 ;
@@ -11040,13 +11054,17 @@ static int nft_rcv_nl_event(struct notifier_block *this, unsigned long event,
11040
11054
struct net * net = n -> net ;
11041
11055
unsigned int deleted ;
11042
11056
bool restart = false;
11057
+ unsigned int gc_seq ;
11043
11058
11044
11059
if (event != NETLINK_URELEASE || n -> protocol != NETLINK_NETFILTER )
11045
11060
return NOTIFY_DONE ;
11046
11061
11047
11062
nft_net = nft_pernet (net );
11048
11063
deleted = 0 ;
11049
11064
mutex_lock (& nft_net -> commit_mutex );
11065
+
11066
+ gc_seq = nft_gc_seq_begin (nft_net );
11067
+
11050
11068
if (!list_empty (& nf_tables_destroy_list ))
11051
11069
rcu_barrier ();
11052
11070
again :
@@ -11069,6 +11087,8 @@ static int nft_rcv_nl_event(struct notifier_block *this, unsigned long event,
11069
11087
if (restart )
11070
11088
goto again ;
11071
11089
}
11090
+ nft_gc_seq_end (nft_net , gc_seq );
11091
+
11072
11092
mutex_unlock (& nft_net -> commit_mutex );
11073
11093
11074
11094
return NOTIFY_DONE ;
@@ -11106,12 +11126,20 @@ static void __net_exit nf_tables_pre_exit_net(struct net *net)
11106
11126
static void __net_exit nf_tables_exit_net (struct net * net )
11107
11127
{
11108
11128
struct nftables_pernet * nft_net = nft_pernet (net );
11129
+ unsigned int gc_seq ;
11109
11130
11110
11131
mutex_lock (& nft_net -> commit_mutex );
11132
+
11133
+ gc_seq = nft_gc_seq_begin (nft_net );
11134
+
11111
11135
if (!list_empty (& nft_net -> commit_list ) ||
11112
11136
!list_empty (& nft_net -> module_list ))
11113
11137
__nf_tables_abort (net , NFNL_ABORT_NONE );
11138
+
11114
11139
__nft_release_tables (net );
11140
+
11141
+ nft_gc_seq_end (nft_net , gc_seq );
11142
+
11115
11143
mutex_unlock (& nft_net -> commit_mutex );
11116
11144
WARN_ON_ONCE (!list_empty (& nft_net -> tables ));
11117
11145
WARN_ON_ONCE (!list_empty (& nft_net -> module_list ));
0 commit comments