@@ -52,16 +52,17 @@ tcp_timewait_check_oow_rate_limit(struct inet_timewait_sock *tw,
5252 return TCP_TW_SUCCESS ;
5353}
5454
55- static void twsk_rcv_nxt_update (struct tcp_timewait_sock * tcptw , u32 seq )
55+ static void twsk_rcv_nxt_update (struct tcp_timewait_sock * tcptw , u32 seq ,
56+ u32 rcv_nxt )
5657{
5758#ifdef CONFIG_TCP_AO
5859 struct tcp_ao_info * ao ;
5960
6061 ao = rcu_dereference (tcptw -> ao_info );
61- if (unlikely (ao && seq < tcptw -> tw_rcv_nxt ))
62+ if (unlikely (ao && seq < rcv_nxt ))
6263 WRITE_ONCE (ao -> rcv_sne , ao -> rcv_sne + 1 );
6364#endif
64- tcptw -> tw_rcv_nxt = seq ;
65+ WRITE_ONCE ( tcptw -> tw_rcv_nxt , seq ) ;
6566}
6667
6768/*
@@ -98,8 +99,9 @@ enum tcp_tw_status
9899tcp_timewait_state_process (struct inet_timewait_sock * tw , struct sk_buff * skb ,
99100 const struct tcphdr * th , u32 * tw_isn )
100101{
101- struct tcp_options_received tmp_opt ;
102102 struct tcp_timewait_sock * tcptw = tcp_twsk ((struct sock * )tw );
103+ u32 rcv_nxt = READ_ONCE (tcptw -> tw_rcv_nxt );
104+ struct tcp_options_received tmp_opt ;
103105 bool paws_reject = false;
104106 int ts_recent_stamp ;
105107
@@ -117,26 +119,26 @@ tcp_timewait_state_process(struct inet_timewait_sock *tw, struct sk_buff *skb,
117119 }
118120 }
119121
120- if (tw -> tw_substate == TCP_FIN_WAIT2 ) {
122+ if (READ_ONCE ( tw -> tw_substate ) == TCP_FIN_WAIT2 ) {
121123 /* Just repeat all the checks of tcp_rcv_state_process() */
122124
123125 /* Out of window, send ACK */
124126 if (paws_reject ||
125127 !tcp_in_window (TCP_SKB_CB (skb )-> seq , TCP_SKB_CB (skb )-> end_seq ,
126- tcptw -> tw_rcv_nxt ,
127- tcptw -> tw_rcv_nxt + tcptw -> tw_rcv_wnd ))
128+ rcv_nxt ,
129+ rcv_nxt + tcptw -> tw_rcv_wnd ))
128130 return tcp_timewait_check_oow_rate_limit (
129131 tw , skb , LINUX_MIB_TCPACKSKIPPEDFINWAIT2 );
130132
131133 if (th -> rst )
132134 goto kill ;
133135
134- if (th -> syn && !before (TCP_SKB_CB (skb )-> seq , tcptw -> tw_rcv_nxt ))
136+ if (th -> syn && !before (TCP_SKB_CB (skb )-> seq , rcv_nxt ))
135137 return TCP_TW_RST ;
136138
137139 /* Dup ACK? */
138140 if (!th -> ack ||
139- !after (TCP_SKB_CB (skb )-> end_seq , tcptw -> tw_rcv_nxt ) ||
141+ !after (TCP_SKB_CB (skb )-> end_seq , rcv_nxt ) ||
140142 TCP_SKB_CB (skb )-> end_seq == TCP_SKB_CB (skb )-> seq ) {
141143 inet_twsk_put (tw );
142144 return TCP_TW_SUCCESS ;
@@ -146,12 +148,13 @@ tcp_timewait_state_process(struct inet_timewait_sock *tw, struct sk_buff *skb,
146148 * reset.
147149 */
148150 if (!th -> fin ||
149- TCP_SKB_CB (skb )-> end_seq != tcptw -> tw_rcv_nxt + 1 )
151+ TCP_SKB_CB (skb )-> end_seq != rcv_nxt + 1 )
150152 return TCP_TW_RST ;
151153
152154 /* FIN arrived, enter true time-wait state. */
153- tw -> tw_substate = TCP_TIME_WAIT ;
154- twsk_rcv_nxt_update (tcptw , TCP_SKB_CB (skb )-> end_seq );
155+ WRITE_ONCE (tw -> tw_substate , TCP_TIME_WAIT );
156+ twsk_rcv_nxt_update (tcptw , TCP_SKB_CB (skb )-> end_seq ,
157+ rcv_nxt );
155158
156159 if (tmp_opt .saw_tstamp ) {
157160 WRITE_ONCE (tcptw -> tw_ts_recent_stamp ,
@@ -182,7 +185,7 @@ tcp_timewait_state_process(struct inet_timewait_sock *tw, struct sk_buff *skb,
182185 */
183186
184187 if (!paws_reject &&
185- (TCP_SKB_CB (skb )-> seq == tcptw -> tw_rcv_nxt &&
188+ (TCP_SKB_CB (skb )-> seq == rcv_nxt &&
186189 (TCP_SKB_CB (skb )-> seq == TCP_SKB_CB (skb )-> end_seq || th -> rst ))) {
187190 /* In window segment, it may be only reset or bare ack. */
188191
@@ -229,7 +232,7 @@ tcp_timewait_state_process(struct inet_timewait_sock *tw, struct sk_buff *skb,
229232 */
230233
231234 if (th -> syn && !th -> rst && !th -> ack && !paws_reject &&
232- (after (TCP_SKB_CB (skb )-> seq , tcptw -> tw_rcv_nxt ) ||
235+ (after (TCP_SKB_CB (skb )-> seq , rcv_nxt ) ||
233236 (tmp_opt .saw_tstamp &&
234237 (s32 )(READ_ONCE (tcptw -> tw_ts_recent ) - tmp_opt .rcv_tsval ) < 0 ))) {
235238 u32 isn = tcptw -> tw_snd_nxt + 65535 + 2 ;
0 commit comments