]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
tcp: accecn: retransmit downgraded SYN in AccECN negotiation
authorChia-Yu Chang <chia-yu.chang@nokia-bell-labs.com>
Sat, 31 Jan 2026 22:25:07 +0000 (23:25 +0100)
committerPaolo Abeni <pabeni@redhat.com>
Tue, 3 Feb 2026 14:13:24 +0000 (15:13 +0100)
Based on AccECN spec (RFC9768) Section 3.1.4.1, if the sender of an
AccECN SYN (the TCP Client) times out before receiving the SYN/ACK, it
SHOULD attempt to negotiate the use of AccECN at least one more time
by continuing to set all three TCP ECN flags (AE,CWR,ECE) = (1,1,1) on
the first retransmitted SYN (using the usual retransmission time-outs).

If this first retransmission also fails to be acknowledged, in
deployment scenarios where AccECN path traversal might be problematic,
the TCP Client SHOULD send subsequent retransmissions of the SYN with
the three TCP-ECN flags cleared (AE,CWR,ECE) = (0,0,0).

Signed-off-by: Chia-Yu Chang <chia-yu.chang@nokia-bell-labs.com>
Acked-by: Paolo Abeni <pabeni@redhat.com>
Reviewed-by: Eric Dumazet <edumazet@google.com>
Link: https://patch.msgid.link/20260131222515.8485-8-chia-yu.chang@nokia-bell-labs.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
net/ipv4/tcp_output.c

index 597e888af36d8697cd696964077b423e79fdb83e..b28596655d73d6a49bbc45f6b449beaae7dc9429 100644 (file)
@@ -3606,12 +3606,15 @@ start:
                        tcp_retrans_try_collapse(sk, skb, avail_wnd);
        }
 
-       /* RFC3168, section 6.1.1.1. ECN fallback
-        * As AccECN uses the same SYN flags (+ AE), this check covers both
-        * cases.
-        */
-       if ((TCP_SKB_CB(skb)->tcp_flags & TCPHDR_SYN_ECN) == TCPHDR_SYN_ECN)
-               tcp_ecn_clear_syn(sk, skb);
+       if (!tcp_ecn_mode_pending(tp) || icsk->icsk_retransmits > 1) {
+               /* RFC3168, section 6.1.1.1. ECN fallback
+                * As AccECN uses the same SYN flags (+ AE), this check
+                * covers both cases.
+                */
+               if ((TCP_SKB_CB(skb)->tcp_flags & TCPHDR_SYN_ECN) ==
+                   TCPHDR_SYN_ECN)
+                       tcp_ecn_clear_syn(sk, skb);
+       }
 
        /* Update global and local TCP statistics. */
        segs = tcp_skb_pcount(skb);