From: Chia-Yu Chang <[email protected]>

When connection is initialized after ECN negotiation, this patch
enables CA to control whether ECT(0) or ECT(1) should be used.
A new identiifer (TCP_CONG_ECT_1_ESTABLISH) defines the expected
ECT value in the IP header.

Signed-off-by: Chia-Yu Chang <[email protected]>
---
 include/net/tcp.h     | 1 +
 include/net/tcp_ecn.h | 6 ++++++
 net/ipv4/tcp_cong.c   | 4 +++-
 net/ipv4/tcp_output.c | 2 +-
 4 files changed, 11 insertions(+), 2 deletions(-)

diff --git a/include/net/tcp.h b/include/net/tcp.h
index 1838389a9d8a..b9def462479d 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -428,6 +428,7 @@ static inline void tcp_dec_quickack_mode(struct sock *sk)
 #define        TCP_ECN_DEMAND_CWR      BIT(2)
 #define        TCP_ECN_SEEN            BIT(3)
 #define        TCP_ECN_MODE_ACCECN     BIT(4)
+#define        TCP_ECN_ECT_1_ESTABLISH BIT(5)
 
 #define        TCP_ECN_DISABLED        0
 #define        TCP_ECN_MODE_PENDING    (TCP_ECN_MODE_RFC3168 | 
TCP_ECN_MODE_ACCECN)
diff --git a/include/net/tcp_ecn.h b/include/net/tcp_ecn.h
index 865d5c5a7718..210ec63538f8 100644
--- a/include/net/tcp_ecn.h
+++ b/include/net/tcp_ecn.h
@@ -38,6 +38,12 @@ static inline void INET_ECN_xmit_ect_1_negotiation(struct 
sock *sk)
        __INET_ECN_xmit(sk, tcp_ca_ect_1_negotiation(sk));
 }
 
+/* Apply either ECT(0) or ECT(1) based on TCP_CONG_ECT_1_ESTABLISH flag */
+static inline void INET_ECN_xmit_ect_1_establish(struct sock *sk)
+{
+       __INET_ECN_xmit(sk, tcp_sk(sk)->ecn_flags & TCP_ECN_ECT_1_ESTABLISH);
+}
+
 static inline void tcp_ecn_queue_cwr(struct tcp_sock *tp)
 {
        /* Do not set CWR if in AccECN mode! */
diff --git a/net/ipv4/tcp_cong.c b/net/ipv4/tcp_cong.c
index 8e83ef81fc18..8da2a9a34b29 100644
--- a/net/ipv4/tcp_cong.c
+++ b/net/ipv4/tcp_cong.c
@@ -240,7 +240,9 @@ void tcp_init_congestion_control(struct sock *sk)
        tcp_sk(sk)->prior_ssthresh = 0;
        if (icsk->icsk_ca_ops->init)
                icsk->icsk_ca_ops->init(sk);
-       if (tcp_ca_needs_ecn(sk))
+       if (tcp_ca_needs_accecn(sk))
+               INET_ECN_xmit_ect_1_establish(sk);
+       else if (tcp_ca_needs_ecn(sk))
                INET_ECN_xmit(sk);
        else
                INET_ECN_dontxmit(sk);
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index c8865205cdc8..3248f3895b15 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -350,7 +350,7 @@ static void tcp_ecn_send(struct sock *sk, struct sk_buff 
*skb,
        if (tcp_ecn_mode_accecn(tp)) {
                if (!tcp_accecn_ace_fail_recv(tp) &&
                    !tcp_accecn_ace_fail_send(tp))
-                       INET_ECN_xmit(sk);
+                       INET_ECN_xmit_ect_1_establish(sk);
                else
                        INET_ECN_dontxmit(sk);
                tcp_accecn_set_ace(tp, skb, th);
-- 
2.34.1


Reply via email to