Skip to content

Commit d9157f6

Browse files
ws-yangpckuba-moo
authored andcommitted
tcp: fix F-RTO may not work correctly when receiving DSACK
Currently DSACK is regarded as a dupack, which may cause F-RTO to incorrectly enter "loss was real" when receiving DSACK. Packetdrill to demonstrate: // Enable F-RTO and TLP 0 `sysctl -q net.ipv4.tcp_frto=2` 0 `sysctl -q net.ipv4.tcp_early_retrans=3` 0 `sysctl -q net.ipv4.tcp_congestion_control=cubic` // Establish a connection +0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3 +0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0 +0 bind(3, ..., ...) = 0 +0 listen(3, 1) = 0 // RTT 10ms, RTO 210ms +.1 < S 0:0(0) win 32792 <mss 1000,sackOK,nop,nop,nop,wscale 7> +0 > S. 0:0(0) ack 1 <...> +.01 < . 1:1(0) ack 1 win 257 +0 accept(3, ..., ...) = 4 // Send 2 data segments +0 write(4, ..., 2000) = 2000 +0 > P. 1:2001(2000) ack 1 // TLP +.022 > P. 1001:2001(1000) ack 1 // Continue to send 8 data segments +0 write(4, ..., 10000) = 10000 +0 > P. 2001:10001(8000) ack 1 // RTO +.188 > . 1:1001(1000) ack 1 // The original data is acked and new data is sent(F-RTO step 2.b) +0 < . 1:1(0) ack 2001 win 257 +0 > P. 10001:12001(2000) ack 1 // D-SACK caused by TLP is regarded as a dupack, this results in // the incorrect judgment of "loss was real"(F-RTO step 3.a) +.022 < . 1:1(0) ack 2001 win 257 <sack 1001:2001,nop,nop> // Never-retransmitted data(3001:4001) are acked and // expect to switch to open state(F-RTO step 3.b) +0 < . 1:1(0) ack 4001 win 257 +0 %{ assert tcpi_ca_state == 0, tcpi_ca_state }% Fixes: e33099f ("tcp: implement RFC5682 F-RTO") Signed-off-by: Pengcheng Yang <[email protected]> Acked-by: Neal Cardwell <[email protected]> Tested-by: Neal Cardwell <[email protected]> Reviewed-by: Eric Dumazet <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
1 parent c26d0d9 commit d9157f6

File tree

1 file changed

+2
-1
lines changed

1 file changed

+2
-1
lines changed

net/ipv4/tcp_input.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3867,7 +3867,8 @@ static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag)
38673867
tcp_process_tlp_ack(sk, ack, flag);
38683868

38693869
if (tcp_ack_is_dubious(sk, flag)) {
3870-
if (!(flag & (FLAG_SND_UNA_ADVANCED | FLAG_NOT_DUP))) {
3870+
if (!(flag & (FLAG_SND_UNA_ADVANCED |
3871+
FLAG_NOT_DUP | FLAG_DSACKING_ACK))) {
38713872
num_dupack = 1;
38723873
/* Consider if pure acks were aggregated in tcp_add_backlog() */
38733874
if (!(flag & FLAG_DATA))

0 commit comments

Comments
 (0)