• Denis Kirjanov's avatar
    tcp: don't ignore ECN CWR on pure ACK · 25702840
    Denis Kirjanov authored
    there is a problem with the CWR flag set in an incoming ACK segment
    and it leads to the situation when the ECE flag is latched forever
    
    the following packetdrill script shows what happens:
    
    // Stack receives incoming segments with CE set
    +0.1 <[ect0]  . 11001:12001(1000) ack 1001 win 65535
    +0.0 <[ce]    . 12001:13001(1000) ack 1001 win 65535
    +0.0 <[ect0] P. 13001:14001(1000) ack 1001 win 65535
    
    // Stack repsonds with ECN ECHO
    +0.0 >[noecn]  . 1001:1001(0) ack 12001
    +0.0 >[noecn] E. 1001:1001(0) ack 13001
    +0.0 >[noecn] E. 1001:1001(0) ack 14001
    
    // Write a packet
    +0.1 write(3, ..., 1000) = 1000
    +0.0 >[ect0] PE. 1001:2001(1000) ack 14001
    
    // Pure ACK received
    +0.01 <[noecn] W. 14001:14001(0) ack 2001 win 65535
    
    // Since CWR was sent, this packet should NOT have ECE set
    
    +0.1 write(3, ..., 1000) = 1000
    +0.0 >[ect0]  P. 2001:3001(1000) ack 14001
    // but Linux will still keep ECE latched here, with packetdrill
    // flagging a missing ECE flag, expecting
    // >[ect0] PE. 2001:3001(1000) ack 14001
    // in the script
    
    In the situation above we will continue to send ECN ECHO packets
    and trigger the peer to reduce the congestion window. To avoid that
    we can check CWR on pure ACKs received.
    
    v3:
    - Add a sequence check to avoid sending an ACK to an ACK
    
    v2:
    - Adjusted the comment
    - move CWR check before checking for unacknowledged packets
    Signed-off-by: default avatarDenis Kirjanov <denis.kirjanov@suse.com>
    Acked-by: default avatarNeal Cardwell <ncardwell@google.com>
    Signed-off-by: default avatarEric Dumazet <edumazet@google.com>
    Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
    25702840
tcp_input.c 192 KB