From ae3f31df5722995bbf717fd4ffe7bfa9c2e80826 Mon Sep 17 00:00:00 2001 From: Chia-Yu Date: Fri, 19 Jan 2024 15:11:58 +0100 Subject: [PATCH 01/24] Modification for ACCECN draft --- net/ipv4/tcp_minisocks.c | 39 +++++++++++++++++---------------------- net/ipv4/tcp_output.c | 6 ------ 2 files changed, 17 insertions(+), 28 deletions(-) diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c index 8450748d6873..75b919d850c2 100644 --- a/net/ipv4/tcp_minisocks.c +++ b/net/ipv4/tcp_minisocks.c @@ -414,7 +414,11 @@ bool tcp_accecn_third_ack(struct sock *sk, const struct sk_buff *skb, if (!TCP_SKB_CB(skb)->sacked) { inet_rsk(req)->ecn_ok = 0; tcp_rsk(req)->accecn_ok = 0; + tcp_ecn_mode_set(tp, TCP_ECN_DISABLED); + tp->prev_ecnfield = treq->syn_ect_rcv; + tp->accecn_opt_demand = 1; + tcp_ecn_received_counters(sk, skb, skb->len - th->doff * 4); verify_ace = false; } break; @@ -447,24 +451,20 @@ static void tcp_ecn_openreq_child(struct sock *sk, // [CY] 3.1.5. Implications of AccECN Mode - A TCP Server in AccECN mode: MUST NOT set ECT on // any packet for the rest of the connection, if it has received or sent at least one valid // SYN or Acceptable SYN/ACK with (AE,CWR,ECE) = (0,0,0) during the handshake. - if (treq->noect) { - tcp_ecn_mode_set(tp, TCP_ECN_DISABLED); - } else { - if (treq->accecn_ok) { - const struct tcphdr *th = (const struct tcphdr *)skb->data; - if (tcp_accecn_third_ack(sk, skb, req, treq->syn_ect_snt)) { - tcp_ecn_mode_set(tp, TCP_ECN_MODE_ACCECN); - tp->syn_ect_snt = treq->syn_ect_snt; - tp->saw_accecn_opt = treq->saw_accecn_opt; - tp->prev_ecnfield = treq->syn_ect_rcv; - tp->accecn_opt_demand = 1; - tcp_ecn_received_counters(sk, skb, skb->len - th->doff * 4); - } - } else { - tcp_ecn_mode_set(tp, inet_rsk(req)->ecn_ok && !tcp_ca_no_fallback_rfc3168(sk) ? - TCP_ECN_MODE_RFC3168 : - TCP_ECN_DISABLED); + if (treq->accecn_ok) { + const struct tcphdr *th = (const struct tcphdr *)skb->data; + if (tcp_accecn_third_ack(sk, skb, req, treq->syn_ect_snt)) { + tcp_ecn_mode_set(tp, TCP_ECN_MODE_ACCECN); + tp->syn_ect_snt = treq->syn_ect_snt; + tp->saw_accecn_opt = treq->saw_accecn_opt; + tp->prev_ecnfield = treq->syn_ect_rcv; + tp->accecn_opt_demand = 1; + tcp_ecn_received_counters(sk, skb, skb->len - th->doff * 4); } + } else { + tcp_ecn_mode_set(tp, inet_rsk(req)->ecn_ok && !tcp_ca_no_fallback_rfc3168(sk) ? + TCP_ECN_MODE_RFC3168 : + TCP_ECN_DISABLED); } } @@ -723,11 +723,6 @@ struct sock *tcp_check_req(struct sock *sk, struct sk_buff *skb, // the appropriate combination of TCP-ECN flags to feed back the IP-ECN field of this latest SYN) tcp_sk(sk)->syn_ect_rcv = TCP_SKB_CB(skb)->ip_dsfield & INET_ECN_MASK; - // [CY] 3.1.5. Implications of AccECN Mode - A TCP Server in AccECN mode: MUST NOT set ECT on - // any packet for the rest of the connection, if it has received or sent at least one valid - // SYN or Acceptable SYN/ACK with (AE,CWR,ECE) = (0,0,0) during the handshake. - tcp_rsk(req)->noect = 1; - INET_ECN_dontxmit(sk); } } diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 99ae746753eb..c884210b21cc 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -392,12 +392,6 @@ tcp_ecn_make_synack(struct sock *sk, struct request_sock *req, struct tcphdr *th th->ae = 0; th->cwr = 0; th->ece = 0; - - // [CY] 3.1.5. Implications of AccECN Mode - A TCP Server in AccECN mode: MUST NOT set ECT on - // any packet for the rest of the connection, if it has received or sent at least one valid - // SYN or Acceptable SYN/ACK with (AE,CWR,ECE) = (0,0,0) during the handshake. - tcp_rsk(req)->noect = 1; - INET_ECN_dontxmit(sk); } } From bb25bcf7350fae2b174666c7c1572ae9ea836460 Mon Sep 17 00:00:00 2001 From: Chia-Yu Chang <125277758+minuscat@users.noreply.github.com> Date: Fri, 19 Jan 2024 15:23:54 +0100 Subject: [PATCH 02/24] Update kernel.yml --- .github/workflows/kernel.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/kernel.yml b/.github/workflows/kernel.yml index 1c6d3320a606..4c81b75c797e 100644 --- a/.github/workflows/kernel.yml +++ b/.github/workflows/kernel.yml @@ -63,7 +63,7 @@ jobs: runs-on: ubuntu-20.04 needs: build permissions: write-all - if: ${{ github.ref == 'refs/heads/testing' || github.ref == 'refs/heads/ratebase' || github.ref == 'refs/heads/AccECN-2023'}} + if: ${{ github.ref == 'refs/heads/testing' || github.ref == 'refs/heads/ratebase' || github.ref == 'refs/heads/AccECN-2023' || github.ref == 'refs/heads/AccECN-2024'}} steps: - name: Get artifact uses: actions/download-artifact@v3 From 12a84bc0a1b5996a20e4e1a627530d0181ca5393 Mon Sep 17 00:00:00 2001 From: Chia-Yu Chang <125277758+minuscat@users.noreply.github.com> Date: Fri, 19 Jan 2024 15:25:24 +0100 Subject: [PATCH 03/24] Update tcp_minisocks.c --- net/ipv4/tcp_minisocks.c | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c index 75b919d850c2..f78c540f13f2 100644 --- a/net/ipv4/tcp_minisocks.c +++ b/net/ipv4/tcp_minisocks.c @@ -407,20 +407,6 @@ bool tcp_accecn_third_ack(struct sock *sk, const struct sk_buff *skb, switch (ace) { case 0x0: tp->ecn_fail = 1; - // [CY] 3.2.2.1. ACE Field on the ACK of the SYN/ACK - If the Server is in AccECN mode and in SYN-RCVD - // state, and if it receives a value of zero on a pure ACK with SYN=0 and no SACK blocks, for the rest - // of the connection the Server MUST NOT set ECT on outgoing packets and MUST NOT respond to AccECN - // feedback. Nonetheless, as a Data Receiver it MUST NOT disable AccECN feedback. - if (!TCP_SKB_CB(skb)->sacked) { - inet_rsk(req)->ecn_ok = 0; - tcp_rsk(req)->accecn_ok = 0; - - tcp_ecn_mode_set(tp, TCP_ECN_DISABLED); - tp->prev_ecnfield = treq->syn_ect_rcv; - tp->accecn_opt_demand = 1; - tcp_ecn_received_counters(sk, skb, skb->len - th->doff * 4); - verify_ace = false; - } break; case 0x7: case 0x5: From 230e7ae791293db96b0696a9e4ac79b839097f4e Mon Sep 17 00:00:00 2001 From: Chia-Yu Date: Fri, 19 Jan 2024 18:09:50 +0100 Subject: [PATCH 04/24] Modification for ACCECN draft --- net/ipv4/tcp_input.c | 33 +++++++++++++++++---------------- net/ipv4/tcp_minisocks.c | 2 +- net/ipv4/tcp_output.c | 6 +++--- 3 files changed, 21 insertions(+), 20 deletions(-) diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index fdd58702b736..820330e81eba 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -444,6 +444,7 @@ static void tcp_ecn_rcv_synack(struct sock *sk, const struct sk_buff *skb, tcp_ecn_mode_set(tp, TCP_ECN_DISABLED); break; case 0x1: + case 0x5: if (tcp_ca_no_fallback_rfc3168(sk)) tcp_ecn_mode_set(tp, TCP_ECN_DISABLED); else @@ -454,22 +455,22 @@ static void tcp_ecn_rcv_synack(struct sock *sk, const struct sk_buff *skb, // = (1,0,1) but it does not have logic specific to such a combination, the Client MUST enable AccECN // mode as if the SYN/ACK confirmed that the Server supported AccECN and as if it fed back that the // IP-ECN field on the SYN had arrived unchanged. - case 0x5: - if (tcp_ecn_mode_pending(tp)) { - tcp_ecn_mode_set(tp, TCP_ECN_MODE_ACCECN); - tp->syn_ect_rcv = ip_dsfield & INET_ECN_MASK; - if (tp->rx_opt.accecn && - tp->saw_accecn_opt < TCP_ACCECN_OPT_COUNTER_SEEN) { - tp->saw_accecn_opt = tcp_accecn_option_init(skb, - tp->rx_opt.accecn); - tp->accecn_opt_demand = 2; - } - if (INET_ECN_is_ce(ip_dsfield)) { - tp->received_ce++; - tp->received_ce_pending++; - } - } - break; + //case 0x5: + // if (tcp_ecn_mode_pending(tp)) { + // tcp_ecn_mode_set(tp, TCP_ECN_MODE_ACCECN); + // tp->syn_ect_rcv = ip_dsfield & INET_ECN_MASK; + // if (tp->rx_opt.accecn && + // tp->saw_accecn_opt < TCP_ACCECN_OPT_COUNTER_SEEN) { + // tp->saw_accecn_opt = tcp_accecn_option_init(skb, + // tp->rx_opt.accecn); + // tp->accecn_opt_demand = 2; + // } + // if (INET_ECN_is_ce(ip_dsfield)) { + // tp->received_ce++; + // tp->received_ce_pending++; + // } + // } + // break; default: tcp_ecn_mode_set(tp, TCP_ECN_MODE_ACCECN); tp->syn_ect_rcv = ip_dsfield & INET_ECN_MASK; diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c index f78c540f13f2..deacdb22aab3 100644 --- a/net/ipv4/tcp_minisocks.c +++ b/net/ipv4/tcp_minisocks.c @@ -707,7 +707,7 @@ struct sock *tcp_check_req(struct sock *sk, struct sk_buff *skb, // [CY] 3.1.5. Implications of AccECN Mode - A TCP Server already in AccECN mode: SHOULD // acknowledge a valid SYN arriving with (AE,CWR,ECE) =(0,0,0) by emitting an AccECN SYN/ACK (with // the appropriate combination of TCP-ECN flags to feed back the IP-ECN field of this latest SYN) - tcp_sk(sk)->syn_ect_rcv = TCP_SKB_CB(skb)->ip_dsfield & INET_ECN_MASK; + //tcp_sk(sk)->syn_ect_rcv = TCP_SKB_CB(skb)->ip_dsfield & INET_ECN_MASK; } } diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index c884210b21cc..9237c9f7a4ef 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -389,9 +389,9 @@ tcp_ecn_make_synack(struct sock *sk, struct request_sock *req, struct tcphdr *th // [CY] 3.2.3.2.2. Testing for Loss of Packets Carrying the AccECN Option - If this retransmission times out, // to expedite connection setup, the TCP Server SHOULD retransmit the SYN/ACK with (AE,CWR,ECE) = (0,0,0) and // no AccECN Option, but it remains in AccECN feedback mode - th->ae = 0; - th->cwr = 0; - th->ece = 0; + //th->ae = 0; + //th->cwr = 0; + //th->ece = 0; } } From 472b228b6effa285a9064dfd4bc8df596f723f93 Mon Sep 17 00:00:00 2001 From: Chia-Yu Date: Sat, 20 Jan 2024 11:04:29 +0100 Subject: [PATCH 05/24] Revert "Modification for ACCECN draft" This reverts commit 230e7ae791293db96b0696a9e4ac79b839097f4e. --- net/ipv4/tcp_input.c | 33 ++++++++++++++++----------------- net/ipv4/tcp_minisocks.c | 2 +- net/ipv4/tcp_output.c | 6 +++--- 3 files changed, 20 insertions(+), 21 deletions(-) diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 820330e81eba..fdd58702b736 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -444,7 +444,6 @@ static void tcp_ecn_rcv_synack(struct sock *sk, const struct sk_buff *skb, tcp_ecn_mode_set(tp, TCP_ECN_DISABLED); break; case 0x1: - case 0x5: if (tcp_ca_no_fallback_rfc3168(sk)) tcp_ecn_mode_set(tp, TCP_ECN_DISABLED); else @@ -455,22 +454,22 @@ static void tcp_ecn_rcv_synack(struct sock *sk, const struct sk_buff *skb, // = (1,0,1) but it does not have logic specific to such a combination, the Client MUST enable AccECN // mode as if the SYN/ACK confirmed that the Server supported AccECN and as if it fed back that the // IP-ECN field on the SYN had arrived unchanged. - //case 0x5: - // if (tcp_ecn_mode_pending(tp)) { - // tcp_ecn_mode_set(tp, TCP_ECN_MODE_ACCECN); - // tp->syn_ect_rcv = ip_dsfield & INET_ECN_MASK; - // if (tp->rx_opt.accecn && - // tp->saw_accecn_opt < TCP_ACCECN_OPT_COUNTER_SEEN) { - // tp->saw_accecn_opt = tcp_accecn_option_init(skb, - // tp->rx_opt.accecn); - // tp->accecn_opt_demand = 2; - // } - // if (INET_ECN_is_ce(ip_dsfield)) { - // tp->received_ce++; - // tp->received_ce_pending++; - // } - // } - // break; + case 0x5: + if (tcp_ecn_mode_pending(tp)) { + tcp_ecn_mode_set(tp, TCP_ECN_MODE_ACCECN); + tp->syn_ect_rcv = ip_dsfield & INET_ECN_MASK; + if (tp->rx_opt.accecn && + tp->saw_accecn_opt < TCP_ACCECN_OPT_COUNTER_SEEN) { + tp->saw_accecn_opt = tcp_accecn_option_init(skb, + tp->rx_opt.accecn); + tp->accecn_opt_demand = 2; + } + if (INET_ECN_is_ce(ip_dsfield)) { + tp->received_ce++; + tp->received_ce_pending++; + } + } + break; default: tcp_ecn_mode_set(tp, TCP_ECN_MODE_ACCECN); tp->syn_ect_rcv = ip_dsfield & INET_ECN_MASK; diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c index deacdb22aab3..f78c540f13f2 100644 --- a/net/ipv4/tcp_minisocks.c +++ b/net/ipv4/tcp_minisocks.c @@ -707,7 +707,7 @@ struct sock *tcp_check_req(struct sock *sk, struct sk_buff *skb, // [CY] 3.1.5. Implications of AccECN Mode - A TCP Server already in AccECN mode: SHOULD // acknowledge a valid SYN arriving with (AE,CWR,ECE) =(0,0,0) by emitting an AccECN SYN/ACK (with // the appropriate combination of TCP-ECN flags to feed back the IP-ECN field of this latest SYN) - //tcp_sk(sk)->syn_ect_rcv = TCP_SKB_CB(skb)->ip_dsfield & INET_ECN_MASK; + tcp_sk(sk)->syn_ect_rcv = TCP_SKB_CB(skb)->ip_dsfield & INET_ECN_MASK; } } diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 9237c9f7a4ef..c884210b21cc 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -389,9 +389,9 @@ tcp_ecn_make_synack(struct sock *sk, struct request_sock *req, struct tcphdr *th // [CY] 3.2.3.2.2. Testing for Loss of Packets Carrying the AccECN Option - If this retransmission times out, // to expedite connection setup, the TCP Server SHOULD retransmit the SYN/ACK with (AE,CWR,ECE) = (0,0,0) and // no AccECN Option, but it remains in AccECN feedback mode - //th->ae = 0; - //th->cwr = 0; - //th->ece = 0; + th->ae = 0; + th->cwr = 0; + th->ece = 0; } } From 2fc01fe6844a2f364600f919b25d09c1e4a6df99 Mon Sep 17 00:00:00 2001 From: Chia-Yu Date: Sat, 20 Jan 2024 11:33:05 +0100 Subject: [PATCH 06/24] Modification for ACCECN draft --- net/ipv4/tcp_minisocks.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c index f78c540f13f2..149e12d5c6f6 100644 --- a/net/ipv4/tcp_minisocks.c +++ b/net/ipv4/tcp_minisocks.c @@ -407,6 +407,16 @@ bool tcp_accecn_third_ack(struct sock *sk, const struct sk_buff *skb, switch (ace) { case 0x0: tp->ecn_fail = 1; + // [CY] 3.2.2.1. ACE Field on the ACK of the SYN/ACK - If the Server is in AccECN mode and in SYN-RCVD + // state, and if it receives a value of zero on a pure ACK with SYN=0 and no SACK blocks, for the rest + // of the connection the Server MUST NOT set ECT on outgoing packets and MUST NOT respond to AccECN + // feedback. Nonetheless, as a Data Receiver it MUST NOT disable AccECN feedback. + if (!TCP_SKB_CB(skb)->sacked) { + inet_rsk(req)->ecn_ok = 0; + tcp_rsk(req)->accecn_ok = 0; + tcp_ecn_mode_set(tp, TCP_ECN_DISABLED); + verify_ace = false; + } break; case 0x7: case 0x5: @@ -443,10 +453,10 @@ static void tcp_ecn_openreq_child(struct sock *sk, tcp_ecn_mode_set(tp, TCP_ECN_MODE_ACCECN); tp->syn_ect_snt = treq->syn_ect_snt; tp->saw_accecn_opt = treq->saw_accecn_opt; - tp->prev_ecnfield = treq->syn_ect_rcv; - tp->accecn_opt_demand = 1; - tcp_ecn_received_counters(sk, skb, skb->len - th->doff * 4); } + tp->prev_ecnfield = treq->syn_ect_rcv; + tp->accecn_opt_demand = 1; + tcp_ecn_received_counters(sk, skb, skb->len - th->doff * 4); } else { tcp_ecn_mode_set(tp, inet_rsk(req)->ecn_ok && !tcp_ca_no_fallback_rfc3168(sk) ? TCP_ECN_MODE_RFC3168 : From 04b6c9851681024aaa26cc203d0c6a115a9f4285 Mon Sep 17 00:00:00 2001 From: Chia-Yu Date: Sat, 20 Jan 2024 16:58:40 +0100 Subject: [PATCH 07/24] Modification for ACCECN draft --- net/ipv4/tcp_minisocks.c | 11 ++++++++--- net/ipv4/tcp_output.c | 5 +++++ 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c index 149e12d5c6f6..47623c7bc3e8 100644 --- a/net/ipv4/tcp_minisocks.c +++ b/net/ipv4/tcp_minisocks.c @@ -412,8 +412,6 @@ bool tcp_accecn_third_ack(struct sock *sk, const struct sk_buff *skb, // of the connection the Server MUST NOT set ECT on outgoing packets and MUST NOT respond to AccECN // feedback. Nonetheless, as a Data Receiver it MUST NOT disable AccECN feedback. if (!TCP_SKB_CB(skb)->sacked) { - inet_rsk(req)->ecn_ok = 0; - tcp_rsk(req)->accecn_ok = 0; tcp_ecn_mode_set(tp, TCP_ECN_DISABLED); verify_ace = false; } @@ -451,9 +449,11 @@ static void tcp_ecn_openreq_child(struct sock *sk, const struct tcphdr *th = (const struct tcphdr *)skb->data; if (tcp_accecn_third_ack(sk, skb, req, treq->syn_ect_snt)) { tcp_ecn_mode_set(tp, TCP_ECN_MODE_ACCECN); - tp->syn_ect_snt = treq->syn_ect_snt; tp->saw_accecn_opt = treq->saw_accecn_opt; + } else { + tp->saw_accecn_opt = TCP_ACCECN_OPT_FAIL; } + tp->syn_ect_snt = treq->syn_ect_snt; tp->prev_ecnfield = treq->syn_ect_rcv; tp->accecn_opt_demand = 1; tcp_ecn_received_counters(sk, skb, skb->len - th->doff * 4); @@ -719,6 +719,11 @@ struct sock *tcp_check_req(struct sock *sk, struct sk_buff *skb, // the appropriate combination of TCP-ECN flags to feed back the IP-ECN field of this latest SYN) tcp_sk(sk)->syn_ect_rcv = TCP_SKB_CB(skb)->ip_dsfield & INET_ECN_MASK; + // [CY] 3.1.5. Implications of AccECN Mode - A TCP Server in AccECN mode: MUST NOT set ECT on + // any packet for the rest of the connection, if it has received or sent at least one valid + // SYN or Acceptable SYN/ACK with (AE,CWR,ECE) = (0,0,0) during the handshake + tcp_sk(sk)->ecn_fail = 1; + INET_ECN_dontxmit(sk); } } diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index c884210b21cc..5bf109464f6b 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -392,6 +392,11 @@ tcp_ecn_make_synack(struct sock *sk, struct request_sock *req, struct tcphdr *th th->ae = 0; th->cwr = 0; th->ece = 0; + // [CY] 3.1.5. Implications of AccECN Mode - A TCP Server in AccECN mode: MUST NOT set ECT on + // any packet for the rest of the connection, if it has received or sent at least one valid + // SYN or Acceptable SYN/ACK with (AE,CWR,ECE) = (0,0,0) during the handshake. + tcp_sk(sk)->ecn_fail = 1; + INET_ECN_dontxmit(sk); } } From a449debb5c81f55cb04b5fe07e903563294bc581 Mon Sep 17 00:00:00 2001 From: Chia-Yu Date: Sun, 21 Jan 2024 03:37:15 +0100 Subject: [PATCH 08/24] Modification for ACCECN draft --- include/linux/tcp.h | 4 ++-- net/ipv4/tcp.c | 1 + net/ipv4/tcp_input.c | 5 ++--- net/ipv4/tcp_minisocks.c | 33 +++++++++++++++------------------ net/ipv4/tcp_output.c | 2 +- 5 files changed, 21 insertions(+), 24 deletions(-) diff --git a/include/linux/tcp.h b/include/linux/tcp.h index 1557cf0241c8..50f036db09bf 100644 --- a/include/linux/tcp.h +++ b/include/linux/tcp.h @@ -126,8 +126,7 @@ struct tcp_request_sock { #if IS_ENABLED(CONFIG_MPTCP) bool drop_req; #endif - u8 noect : 1, - accecn_ok : 1, + u8 accecn_ok : 1, saw_accecn_opt : 2, syn_ect_snt: 2, syn_ect_rcv: 2; @@ -234,6 +233,7 @@ struct tcp_sock { syn_ect_snt:2, /* AccECN ECT memory, only */ syn_ect_rcv:2, /* ... needed durign 3WHS + first seqno */ ecn_fail:1; /* ECN reflector detected path mangling */ + u8 accecn_no_process:1; /* AccECN no response on feedback */ u8 saw_accecn_opt:2, /* An AccECN option was seen */ fast_ack_mode:2, /* which fast ack mode ? */ unused:4; diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 9721d7f0db9b..a9ccb83a8548 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -3033,6 +3033,7 @@ int tcp_disconnect(struct sock *sk, int flags) tp->delivered_ce = 0; tp->saw_accecn_opt = 0; tp->ecn_fail = 0; + tp->accecn_no_preocess = 0; tcp_accecn_init_counters(tp); tp->prev_ecnfield = 0; tp->accecn_opt_tstamp = 0; diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index fdd58702b736..56d2a9a454fd 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -595,7 +595,7 @@ static bool tcp_accecn_process_option(struct tcp_sock *tp, bool order1, res; unsigned int i; - if (tp->saw_accecn_opt == TCP_ACCECN_OPT_FAIL) + if (tp->saw_accecn_opt == TCP_ACCECN_OPT_FAIL || tp->accecn_no_process) return false; if (!(flag & FLAG_SLOWPATH) || !tp->rx_opt.accecn) { @@ -7017,7 +7017,7 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb) tcp_initialize_rcv_mss(sk); if (tcp_ecn_mode_accecn(tp)) - tcp_accecn_third_ack(sk, skb, req, tp->syn_ect_snt); + tcp_accecn_third_ack(sk, skb, tp->syn_ect_snt); tcp_fast_path_on(tp); break; @@ -7218,7 +7218,6 @@ static void tcp_openreq_init(struct request_sock *req, tcp_rsk(req)->rcv_nxt = TCP_SKB_CB(skb)->seq + 1; tcp_rsk(req)->snt_synack = 0; tcp_rsk(req)->last_oow_ack_time = 0; - tcp_rsk(req)->noect = 0; tcp_rsk(req)->accecn_ok = 0; tcp_rsk(req)->saw_accecn_opt = 0; tcp_rsk(req)->syn_ect_rcv = 0; diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c index 47623c7bc3e8..c0a448571ae7 100644 --- a/net/ipv4/tcp_minisocks.c +++ b/net/ipv4/tcp_minisocks.c @@ -397,24 +397,25 @@ void tcp_openreq_init_rwin(struct request_sock *req, } EXPORT_SYMBOL(tcp_openreq_init_rwin); -bool tcp_accecn_third_ack(struct sock *sk, const struct sk_buff *skb, - struct request_sock *req, u8 syn_ect_snt) +void tcp_accecn_third_ack(struct sock *sk, const struct sk_buff *skb, + u8 syn_ect_snt) { u8 ace = tcp_accecn_ace(tcp_hdr(skb)); struct tcp_sock *tp = tcp_sk(sk); - bool verify_ace = true; switch (ace) { case 0x0: - tp->ecn_fail = 1; // [CY] 3.2.2.1. ACE Field on the ACK of the SYN/ACK - If the Server is in AccECN mode and in SYN-RCVD // state, and if it receives a value of zero on a pure ACK with SYN=0 and no SACK blocks, for the rest // of the connection the Server MUST NOT set ECT on outgoing packets and MUST NOT respond to AccECN // feedback. Nonetheless, as a Data Receiver it MUST NOT disable AccECN feedback. - if (!TCP_SKB_CB(skb)->sacked) { - tcp_ecn_mode_set(tp, TCP_ECN_DISABLED); - verify_ace = false; - } + tp->ecn_fail = 1; + tp->accecn_no_process = 1; + //INET_ECN_dontxmit(sk); + //if (!TCP_SKB_CB(skb)->sacked) { + // tcp_ecn_mode_set(tp, TCP_ECN_DISABLED); + // verify_ace = false; + //} break; case 0x7: case 0x5: @@ -432,14 +433,13 @@ bool tcp_accecn_third_ack(struct sock *sk, const struct sk_buff *skb, } break; } - return verify_ace; } static void tcp_ecn_openreq_child(struct sock *sk, - struct request_sock *req, + const struct request_sock *req, const struct sk_buff *skb) { - struct tcp_request_sock *treq = tcp_rsk(req); + const struct tcp_request_sock *treq = tcp_rsk(req); struct tcp_sock *tp = tcp_sk(sk); // [CY] 3.1.5. Implications of AccECN Mode - A TCP Server in AccECN mode: MUST NOT set ECT on @@ -447,13 +447,10 @@ static void tcp_ecn_openreq_child(struct sock *sk, // SYN or Acceptable SYN/ACK with (AE,CWR,ECE) = (0,0,0) during the handshake. if (treq->accecn_ok) { const struct tcphdr *th = (const struct tcphdr *)skb->data; - if (tcp_accecn_third_ack(sk, skb, req, treq->syn_ect_snt)) { - tcp_ecn_mode_set(tp, TCP_ECN_MODE_ACCECN); - tp->saw_accecn_opt = treq->saw_accecn_opt; - } else { - tp->saw_accecn_opt = TCP_ACCECN_OPT_FAIL; - } + tcp_ecn_mode_set(tp, TCP_ECN_MODE_ACCECN); tp->syn_ect_snt = treq->syn_ect_snt; + tcp_accecn_third_ack(sk, skb, treq->syn_ect_snt); + tp->saw_accecn_opt = treq->saw_accecn_opt; tp->prev_ecnfield = treq->syn_ect_rcv; tp->accecn_opt_demand = 1; tcp_ecn_received_counters(sk, skb, skb->len - th->doff * 4); @@ -723,7 +720,7 @@ struct sock *tcp_check_req(struct sock *sk, struct sk_buff *skb, // any packet for the rest of the connection, if it has received or sent at least one valid // SYN or Acceptable SYN/ACK with (AE,CWR,ECE) = (0,0,0) during the handshake tcp_sk(sk)->ecn_fail = 1; - INET_ECN_dontxmit(sk); + //INET_ECN_dontxmit(sk); } } diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 5bf109464f6b..04313da0783d 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -396,7 +396,7 @@ tcp_ecn_make_synack(struct sock *sk, struct request_sock *req, struct tcphdr *th // any packet for the rest of the connection, if it has received or sent at least one valid // SYN or Acceptable SYN/ACK with (AE,CWR,ECE) = (0,0,0) during the handshake. tcp_sk(sk)->ecn_fail = 1; - INET_ECN_dontxmit(sk); + //INET_ECN_dontxmit(sk); } } From 0e900e57ac8f015b44f226ef53f78c48586b09a4 Mon Sep 17 00:00:00 2001 From: Chia-Yu Date: Sun, 21 Jan 2024 08:44:50 +0100 Subject: [PATCH 09/24] Modification for ACCECN draft --- Documentation/networking/ip-sysctl.rst | 4 ++-- include/net/tcp.h | 4 ++-- net/ipv4/tcp_minisocks.c | 24 ++++++++++++------------ net/ipv4/tcp_output.c | 2 +- 4 files changed, 17 insertions(+), 17 deletions(-) diff --git a/Documentation/networking/ip-sysctl.rst b/Documentation/networking/ip-sysctl.rst index dbe87fe8cc56..88c315841f3d 100644 --- a/Documentation/networking/ip-sysctl.rst +++ b/Documentation/networking/ip-sysctl.rst @@ -433,9 +433,9 @@ tcp_ecn_option - INTEGER tcp_ecn_option_beacon - INTEGER Control Accurate ECN (AccECN) option sending frequency per RTT and it - take effect only when tcp_ecn_option is set to 2. + takes effect only when tcp_ecn_option is set to 2. - Default: 3 (AccECN will be send at least 3 times per RTT) + Default: 1 (AccECN will be send at least 1 time per RTT) tcp_ecn_fallback - BOOLEAN If the kernel detects that ECN connection misbehaves, enable fall diff --git a/include/net/tcp.h b/include/net/tcp.h index f26a931d2ae2..6745b64ca705 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -432,8 +432,8 @@ static inline int tcp_accecn_extract_syn_ect(u8 ace) } bool tcp_accecn_validate_syn_feedback(struct sock *sk, u8 ace, u8 sent_ect); -bool tcp_accecn_third_ack(struct sock *sk, const struct sk_buff *skb, - struct request_sock *req, u8 syn_ect_snt); +void tcp_accecn_third_ack(struct sock *sk, const struct sk_buff *skb, + u8 syn_ect_snt); u8 tcp_accecn_option_init(const struct sk_buff *skb, u8 opt_offset); void tcp_ecn_received_counters(struct sock *sk, const struct sk_buff *skb, u32 payload_len); diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c index c0a448571ae7..95a4bfdb189e 100644 --- a/net/ipv4/tcp_minisocks.c +++ b/net/ipv4/tcp_minisocks.c @@ -398,7 +398,7 @@ void tcp_openreq_init_rwin(struct request_sock *req, EXPORT_SYMBOL(tcp_openreq_init_rwin); void tcp_accecn_third_ack(struct sock *sk, const struct sk_buff *skb, - u8 syn_ect_snt) + u8 syn_ect_snt) { u8 ace = tcp_accecn_ace(tcp_hdr(skb)); struct tcp_sock *tp = tcp_sk(sk); @@ -446,18 +446,18 @@ static void tcp_ecn_openreq_child(struct sock *sk, // any packet for the rest of the connection, if it has received or sent at least one valid // SYN or Acceptable SYN/ACK with (AE,CWR,ECE) = (0,0,0) during the handshake. if (treq->accecn_ok) { - const struct tcphdr *th = (const struct tcphdr *)skb->data; - tcp_ecn_mode_set(tp, TCP_ECN_MODE_ACCECN); - tp->syn_ect_snt = treq->syn_ect_snt; - tcp_accecn_third_ack(sk, skb, treq->syn_ect_snt); - tp->saw_accecn_opt = treq->saw_accecn_opt; - tp->prev_ecnfield = treq->syn_ect_rcv; - tp->accecn_opt_demand = 1; - tcp_ecn_received_counters(sk, skb, skb->len - th->doff * 4); + const struct tcphdr *th = (const struct tcphdr *)skb->data; + tcp_ecn_mode_set(tp, TCP_ECN_MODE_ACCECN); + tp->syn_ect_snt = treq->syn_ect_snt; + tcp_accecn_third_ack(sk, skb, treq->syn_ect_snt); + tp->saw_accecn_opt = treq->saw_accecn_opt; + tp->prev_ecnfield = treq->syn_ect_rcv; + tp->accecn_opt_demand = 1; + tcp_ecn_received_counters(sk, skb, skb->len - th->doff * 4); } else { - tcp_ecn_mode_set(tp, inet_rsk(req)->ecn_ok && !tcp_ca_no_fallback_rfc3168(sk) ? - TCP_ECN_MODE_RFC3168 : - TCP_ECN_DISABLED); + tcp_ecn_mode_set(tp, inet_rsk(req)->ecn_ok && !tcp_ca_no_fallback_rfc3168(sk) ? + TCP_ECN_MODE_RFC3168 : + TCP_ECN_DISABLED); } } diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 04313da0783d..e0987c3e7ed4 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -378,7 +378,7 @@ static void tcp_accecn_echo_syn_ect(struct tcphdr *th, u8 ect) } static void -tcp_ecn_make_synack(struct sock *sk, struct request_sock *req, struct tcphdr *th) +tcp_ecn_make_synack(struct sock *sk, const struct request_sock *req, struct tcphdr *th) { if (req->num_timeout < 2) { if (tcp_rsk(req)->accecn_ok) From 24da58c05a036e69f364fd84e7ed65c0b699f947 Mon Sep 17 00:00:00 2001 From: Chia-Yu Date: Sun, 21 Jan 2024 11:44:16 +0100 Subject: [PATCH 10/24] Fix typo in tcp.c --- net/ipv4/tcp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index a9ccb83a8548..a2058babe9d8 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -3033,7 +3033,7 @@ int tcp_disconnect(struct sock *sk, int flags) tp->delivered_ce = 0; tp->saw_accecn_opt = 0; tp->ecn_fail = 0; - tp->accecn_no_preocess = 0; + tp->accecn_no_process = 0; tcp_accecn_init_counters(tp); tp->prev_ecnfield = 0; tp->accecn_opt_tstamp = 0; From 7a6a4eeac615f43353f9bd58958d201d8cb4d15c Mon Sep 17 00:00:00 2001 From: Chia-Yu Date: Sun, 21 Jan 2024 17:40:49 +0100 Subject: [PATCH 11/24] Update retx counter for synack --- net/ipv4/tcp_timer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c index e873a768f9e8..46d40b967a68 100644 --- a/net/ipv4/tcp_timer.c +++ b/net/ipv4/tcp_timer.c @@ -428,8 +428,8 @@ static void tcp_fastopen_synack_timer(struct sock *sk, struct request_sock *req) * regular retransmit because if the child socket has been accepted * it's not good to give up too easily. */ - inet_rtx_syn_ack(sk, req); req->num_timeout++; + inet_rtx_syn_ack(sk, req); icsk->icsk_retransmits++; if (!tp->retrans_stamp) tp->retrans_stamp = tcp_time_stamp(tp); From 3941f6d878415bc54058720aa733bfbb5ae3c6ca Mon Sep 17 00:00:00 2001 From: Chia-Yu Date: Sun, 21 Jan 2024 23:47:45 +0100 Subject: [PATCH 12/24] Add is_rtx flag --- include/net/request_sock.h | 4 +++- net/ipv4/inet_connection_sock.c | 1 + net/ipv4/tcp_output.c | 4 ++-- net/ipv4/tcp_timer.c | 2 +- 4 files changed, 7 insertions(+), 4 deletions(-) diff --git a/include/net/request_sock.h b/include/net/request_sock.h index 29e41ff3ec93..d382e540f329 100644 --- a/include/net/request_sock.h +++ b/include/net/request_sock.h @@ -62,7 +62,8 @@ struct request_sock { u16 mss; u8 num_retrans; /* number of retransmits */ u8 syncookie:1; /* syncookie: encode tcpopts in timestamp */ - u8 num_timeout:7; /* number of timeouts */ + u8 num_timeout:7, + is_rtx:1; /* number of timeouts */ u32 ts_recent; struct timer_list rsk_timer; const struct request_sock_ops *rsk_ops; @@ -105,6 +106,7 @@ reqsk_alloc(const struct request_sock_ops *ops, struct sock *sk_listener, sk_tx_queue_clear(req_to_sk(req)); req->saved_syn = NULL; req->num_timeout = 0; + req->is_rtx = 0; req->num_retrans = 0; req->sk = NULL; refcount_set(&req->rsk_refcnt, 0); diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c index a53f9bf7886f..9d20f2456cf2 100644 --- a/net/ipv4/inet_connection_sock.c +++ b/net/ipv4/inet_connection_sock.c @@ -688,6 +688,7 @@ static void syn_ack_recalc(struct request_sock *req, int inet_rtx_syn_ack(const struct sock *parent, struct request_sock *req) { + req->is_rtx = 1; int err = req->rsk_ops->rtx_syn_ack(parent, req); if (!err) diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index e0987c3e7ed4..6f2a4ff81a58 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -380,7 +380,7 @@ static void tcp_accecn_echo_syn_ect(struct tcphdr *th, u8 ect) static void tcp_ecn_make_synack(struct sock *sk, const struct request_sock *req, struct tcphdr *th) { - if (req->num_timeout < 2) { + if (!req->is_rtx || req->num_timeout < 1) { if (tcp_rsk(req)->accecn_ok) tcp_accecn_echo_syn_ect(th, tcp_rsk(req)->syn_ect_rcv); else if (inet_rsk(req)->ecn_ok) @@ -1107,7 +1107,7 @@ static unsigned int tcp_synack_options(const struct sock *sk, // [CY] 3.2.3.2.2. Testing for Loss of Packets Carrying the AccECN Option - TCP Server SHOULD retransmit the // SYN/ACK, but with no AccECN Option if (treq->accecn_ok && sock_net(sk)->ipv4.sysctl_tcp_ecn_option && - req->num_timeout < 1 && (remaining >= TCPOLEN_ACCECN_BASE)) { + !req->is_rtx && (remaining >= TCPOLEN_ACCECN_BASE)) { opts->ecn_bytes = synack_ecn_bytes; remaining -= tcp_options_fit_accecn(opts, 0, remaining, tcp_synack_options_combine_saving(opts)); diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c index 46d40b967a68..e873a768f9e8 100644 --- a/net/ipv4/tcp_timer.c +++ b/net/ipv4/tcp_timer.c @@ -428,8 +428,8 @@ static void tcp_fastopen_synack_timer(struct sock *sk, struct request_sock *req) * regular retransmit because if the child socket has been accepted * it's not good to give up too easily. */ - req->num_timeout++; inet_rtx_syn_ack(sk, req); + req->num_timeout++; icsk->icsk_retransmits++; if (!tp->retrans_stamp) tp->retrans_stamp = tcp_time_stamp(tp); From 3ff07b9511a5e49eb428f160455535f849e81309 Mon Sep 17 00:00:00 2001 From: Chia-Yu Date: Mon, 22 Jan 2024 10:40:59 +0100 Subject: [PATCH 13/24] Fix missing SYN retx in AccECN draft --- net/ipv4/tcp_output.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 6f2a4ff81a58..695b437ff06d 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -3451,12 +3451,20 @@ int __tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb, int segs) 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. + /* [CY] 3.1.4.1. Retransmitted SYNs - 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). */ - 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); From 15a3b7ce1ab461d76c7d2bf58ae4bdd8932e18a7 Mon Sep 17 00:00:00 2001 From: Chia-Yu Date: Mon, 22 Jan 2024 16:44:19 +0100 Subject: [PATCH 14/24] Update syn_ack_rcv for challenge ack --- net/ipv4/tcp_input.c | 5 +++++ net/ipv4/tcp_minisocks.c | 6 ------ net/ipv4/tcp_output.c | 1 - 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 56d2a9a454fd..bfa026e76638 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -6235,6 +6235,11 @@ static bool tcp_validate_incoming(struct sock *sk, struct sk_buff *skb, if (th->syn) { if (tcp_ecn_mode_accecn(tp)) { send_accecn_reflector = true; + /* [CY] 3.1.5. Implications of AccECN Mode - A host in AccECN mode that is feeding back the IP-ECN + * field on a SYN or SYN/ACK: MUST feed back the IP-ECN field on the latest valid SYN or acceptable + * SYN/ACK to arrive.” + */ + tp->syn_ect_rcv = TCP_SKB_CB(skb)->ip_dsfield & INET_ECN_MASK; if (tp->rx_opt.accecn && tp->saw_accecn_opt < TCP_ACCECN_OPT_COUNTER_SEEN) { tp->saw_accecn_opt = tcp_accecn_option_init(skb, diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c index 95a4bfdb189e..acf58f2c224b 100644 --- a/net/ipv4/tcp_minisocks.c +++ b/net/ipv4/tcp_minisocks.c @@ -411,11 +411,6 @@ void tcp_accecn_third_ack(struct sock *sk, const struct sk_buff *skb, // feedback. Nonetheless, as a Data Receiver it MUST NOT disable AccECN feedback. tp->ecn_fail = 1; tp->accecn_no_process = 1; - //INET_ECN_dontxmit(sk); - //if (!TCP_SKB_CB(skb)->sacked) { - // tcp_ecn_mode_set(tp, TCP_ECN_DISABLED); - // verify_ace = false; - //} break; case 0x7: case 0x5: @@ -720,7 +715,6 @@ struct sock *tcp_check_req(struct sock *sk, struct sk_buff *skb, // any packet for the rest of the connection, if it has received or sent at least one valid // SYN or Acceptable SYN/ACK with (AE,CWR,ECE) = (0,0,0) during the handshake tcp_sk(sk)->ecn_fail = 1; - //INET_ECN_dontxmit(sk); } } diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 695b437ff06d..ddc5f1c4d06c 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -396,7 +396,6 @@ tcp_ecn_make_synack(struct sock *sk, const struct request_sock *req, struct tcph // any packet for the rest of the connection, if it has received or sent at least one valid // SYN or Acceptable SYN/ACK with (AE,CWR,ECE) = (0,0,0) during the handshake. tcp_sk(sk)->ecn_fail = 1; - //INET_ECN_dontxmit(sk); } } From 08367ec3369f82259117c01b26eb17fe351f5b85 Mon Sep 17 00:00:00 2001 From: Chia-Yu Date: Tue, 23 Jan 2024 01:40:28 +0100 Subject: [PATCH 15/24] Update syn_ect_rcv for retx SYN --- net/ipv4/tcp_minisocks.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c index acf58f2c224b..4054fcbf12da 100644 --- a/net/ipv4/tcp_minisocks.c +++ b/net/ipv4/tcp_minisocks.c @@ -709,7 +709,7 @@ struct sock *tcp_check_req(struct sock *sk, struct sk_buff *skb, // [CY] 3.1.5. Implications of AccECN Mode - A TCP Server already in AccECN mode: SHOULD // acknowledge a valid SYN arriving with (AE,CWR,ECE) =(0,0,0) by emitting an AccECN SYN/ACK (with // the appropriate combination of TCP-ECN flags to feed back the IP-ECN field of this latest SYN) - tcp_sk(sk)->syn_ect_rcv = TCP_SKB_CB(skb)->ip_dsfield & INET_ECN_MASK; + tcp_rsk(req)->syn_ect_rcv = TCP_SKB_CB(skb)->ip_dsfield & INET_ECN_MASK; // [CY] 3.1.5. Implications of AccECN Mode - A TCP Server in AccECN mode: MUST NOT set ECT on // any packet for the rest of the connection, if it has received or sent at least one valid From b9fd5d0bfa39704b371927b79fc16ecac406020c Mon Sep 17 00:00:00 2001 From: Chia-Yu Date: Tue, 23 Jan 2024 11:18:27 +0100 Subject: [PATCH 16/24] Modification for ACCECN draft --- net/ipv4/tcp_minisocks.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c index 4054fcbf12da..5d661a5c3180 100644 --- a/net/ipv4/tcp_minisocks.c +++ b/net/ipv4/tcp_minisocks.c @@ -705,15 +705,16 @@ struct sock *tcp_check_req(struct sock *sk, struct sk_buff *skb, &tcp_rsk(req)->last_oow_ack_time)) { if (tcp_rsk(req)->accecn_ok) { + /* [CY] 3.1.5 Implications of AccECN Mode - A host in AccECN mode that is feeding back the IP-ECN + * field on a SYN or SYN/ACK: MUST feed back the IP-ECN field on the latest valid SYN or acceptable + * SYN/ACK to arrive. + */ + tcp_rsk(req)->syn_ect_rcv = TCP_SKB_CB(skb)->ip_dsfield & INET_ECN_MASK; if (tcp_accecn_ace(tcp_hdr(skb)) == 0x0) { - // [CY] 3.1.5. Implications of AccECN Mode - A TCP Server already in AccECN mode: SHOULD - // acknowledge a valid SYN arriving with (AE,CWR,ECE) =(0,0,0) by emitting an AccECN SYN/ACK (with - // the appropriate combination of TCP-ECN flags to feed back the IP-ECN field of this latest SYN) - tcp_rsk(req)->syn_ect_rcv = TCP_SKB_CB(skb)->ip_dsfield & INET_ECN_MASK; - - // [CY] 3.1.5. Implications of AccECN Mode - A TCP Server in AccECN mode: MUST NOT set ECT on - // any packet for the rest of the connection, if it has received or sent at least one valid - // SYN or Acceptable SYN/ACK with (AE,CWR,ECE) = (0,0,0) during the handshake + /* [CY] 3.1.5. Implications of AccECN Mode - A TCP Server in AccECN mode: MUST NOT set ECT on + * any packet for the rest of the connection, if it has received or sent at least one valid + * SYN or Acceptable SYN/ACK with (AE,CWR,ECE) = (0,0,0) during the handshake + */ tcp_sk(sk)->ecn_fail = 1; } } From 8780b899edb517ce6dbea01514368f953603e5e1 Mon Sep 17 00:00:00 2001 From: Chia-Yu Date: Thu, 25 Jan 2024 16:00:58 +0100 Subject: [PATCH 17/24] Include the case of 3.2.3.2.2. for packet loss carrying AccECN option --- include/linux/tcp.h | 3 ++- net/ipv4/tcp.c | 1 + net/ipv4/tcp_input.c | 29 ++++++++++++++++++++--------- net/ipv4/tcp_minisocks.c | 16 ++++++++-------- net/ipv4/tcp_output.c | 21 ++++++++++++--------- 5 files changed, 43 insertions(+), 27 deletions(-) diff --git a/include/linux/tcp.h b/include/linux/tcp.h index 50f036db09bf..cc1013374a96 100644 --- a/include/linux/tcp.h +++ b/include/linux/tcp.h @@ -233,7 +233,8 @@ struct tcp_sock { syn_ect_snt:2, /* AccECN ECT memory, only */ syn_ect_rcv:2, /* ... needed durign 3WHS + first seqno */ ecn_fail:1; /* ECN reflector detected path mangling */ - u8 accecn_no_process:1; /* AccECN no response on feedback */ + u8 accecn_no_process:1, /* AccECN no response on feedback */ + accecn_no_options:1; u8 saw_accecn_opt:2, /* An AccECN option was seen */ fast_ack_mode:2, /* which fast ack mode ? */ unused:4; diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index a2058babe9d8..8b4fce6fef4c 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -3034,6 +3034,7 @@ int tcp_disconnect(struct sock *sk, int flags) tp->saw_accecn_opt = 0; tp->ecn_fail = 0; tp->accecn_no_process = 0; + tp->accecn_no_options = 0; tcp_accecn_init_counters(tp); tp->prev_ecnfield = 0; tp->accecn_opt_tstamp = 0; diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index bfa026e76638..94aed08fd16e 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -449,11 +449,11 @@ static void tcp_ecn_rcv_synack(struct sock *sk, const struct sk_buff *skb, else tcp_ecn_mode_set(tp, TCP_ECN_MODE_RFC3168); break; - // [CY] 3.1.2. Backward Compatibility - If a TCP Client has sent a SYN requesting AccECN feedback with - // (AE,CWR,ECE) = (1,1,1) then receives a SYN/ACK with the currently reserved combination (AE,CWR,ECE) - // = (1,0,1) but it does not have logic specific to such a combination, the Client MUST enable AccECN - // mode as if the SYN/ACK confirmed that the Server supported AccECN and as if it fed back that the - // IP-ECN field on the SYN had arrived unchanged. + /* [CY] 3.1.2. Backward Compatibility - If a TCP Client has sent a SYN requesting AccECN feedback with (AE,CWR,ECE) = + * (1,1,1) then receives a SYN/ACK with the currently reserved combination (AE,CWR,ECE) = (1,0,1) but it does not + * have logic specific to such a combination, the Client MUST enable AccECN mode as if the SYN/ACK confirmed that the + * Server supported AccECN and as if it fed back that the IP-ECN field on the SYN had arrived unchanged. + */ case 0x5: if (tcp_ecn_mode_pending(tp)) { tcp_ecn_mode_set(tp, TCP_ECN_MODE_ACCECN); @@ -595,7 +595,7 @@ static bool tcp_accecn_process_option(struct tcp_sock *tp, bool order1, res; unsigned int i; - if (tp->saw_accecn_opt == TCP_ACCECN_OPT_FAIL || tp->accecn_no_process) + if (tp->saw_accecn_opt == TCP_ACCECN_OPT_FAIL || tp->accecn_no_response) return false; if (!(flag & FLAG_SLOWPATH) || !tp->rx_opt.accecn) { @@ -4893,8 +4893,19 @@ static void tcp_rcv_spurious_retrans(struct sock *sk, const struct sk_buff *skb) * DSACK state and change the txhash to re-route speculatively. */ if (TCP_SKB_CB(skb)->seq == tcp_sk(sk)->duplicate_sack[0].start_seq && - sk_rethink_txhash(sk)) + sk_rethink_txhash(sk)) { NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPDUPLICATEDATAREHASH); + /* [CY] 3.2.3.2.2. Testing for Loss of Packets Carrying the AccECN Option - If a middlebox is dropping + * packets with options it does not recognize, a host that is sending little or no data but mostly pure + * ACKs will not inherently detect such losses. Such a host MAY detect loss of ACKs carrying the AccECN + * Option by detecting whether the acknowledged data always reappears as a retransmission. In such cases, + * the host SHOULD disable the sending of the AccECN Option for this half-connection. + */ + if (tcp_ecn_mode_accecn(tp)) + tcp_sock(sk)->accecn_no_options = 1; + } + + } } static void tcp_send_dupack(struct sock *sk, const struct sk_buff *skb) @@ -6235,8 +6246,8 @@ static bool tcp_validate_incoming(struct sock *sk, struct sk_buff *skb, if (th->syn) { if (tcp_ecn_mode_accecn(tp)) { send_accecn_reflector = true; - /* [CY] 3.1.5. Implications of AccECN Mode - A host in AccECN mode that is feeding back the IP-ECN - * field on a SYN or SYN/ACK: MUST feed back the IP-ECN field on the latest valid SYN or acceptable + /* [CY] 3.1.5. Implications of AccECN Mode - A host in AccECN mode that is feeding back the IP-ECN + * field on a SYN or SYN/ACK: MUST feed back the IP-ECN field on the latest valid SYN or acceptable * SYN/ACK to arrive.” */ tp->syn_ect_rcv = TCP_SKB_CB(skb)->ip_dsfield & INET_ECN_MASK; diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c index 5d661a5c3180..2066097415f2 100644 --- a/net/ipv4/tcp_minisocks.c +++ b/net/ipv4/tcp_minisocks.c @@ -405,12 +405,12 @@ void tcp_accecn_third_ack(struct sock *sk, const struct sk_buff *skb, switch (ace) { case 0x0: - // [CY] 3.2.2.1. ACE Field on the ACK of the SYN/ACK - If the Server is in AccECN mode and in SYN-RCVD + // [CY] 3.2.2.1. ACE Field on the ACK of the SYN/ACK - If the Server is in AccECN mode and in SYN-RCVD // state, and if it receives a value of zero on a pure ACK with SYN=0 and no SACK blocks, for the rest - // of the connection the Server MUST NOT set ECT on outgoing packets and MUST NOT respond to AccECN + // of the connection the Server MUST NOT set ECT on outgoing packets and MUST NOT respond to AccECN // feedback. Nonetheless, as a Data Receiver it MUST NOT disable AccECN feedback. tp->ecn_fail = 1; - tp->accecn_no_process = 1; + tp->accecn_no_response = 1; break; case 0x7: case 0x5: @@ -437,8 +437,8 @@ static void tcp_ecn_openreq_child(struct sock *sk, const struct tcp_request_sock *treq = tcp_rsk(req); struct tcp_sock *tp = tcp_sk(sk); - // [CY] 3.1.5. Implications of AccECN Mode - A TCP Server in AccECN mode: MUST NOT set ECT on - // any packet for the rest of the connection, if it has received or sent at least one valid + // [CY] 3.1.5. Implications of AccECN Mode - A TCP Server in AccECN mode: MUST NOT set ECT on + // any packet for the rest of the connection, if it has received or sent at least one valid // SYN or Acceptable SYN/ACK with (AE,CWR,ECE) = (0,0,0) during the handshake. if (treq->accecn_ok) { const struct tcphdr *th = (const struct tcphdr *)skb->data; @@ -706,13 +706,13 @@ struct sock *tcp_check_req(struct sock *sk, struct sk_buff *skb, if (tcp_rsk(req)->accecn_ok) { /* [CY] 3.1.5 Implications of AccECN Mode - A host in AccECN mode that is feeding back the IP-ECN - * field on a SYN or SYN/ACK: MUST feed back the IP-ECN field on the latest valid SYN or acceptable + * field on a SYN or SYN/ACK: MUST feed back the IP-ECN field on the latest valid SYN or acceptable * SYN/ACK to arrive. */ tcp_rsk(req)->syn_ect_rcv = TCP_SKB_CB(skb)->ip_dsfield & INET_ECN_MASK; if (tcp_accecn_ace(tcp_hdr(skb)) == 0x0) { - /* [CY] 3.1.5. Implications of AccECN Mode - A TCP Server in AccECN mode: MUST NOT set ECT on - * any packet for the rest of the connection, if it has received or sent at least one valid + /* [CY] 3.1.5. Implications of AccECN Mode - A TCP Server in AccECN mode: MUST NOT set ECT on + * any packet for the rest of the connection, if it has received or sent at least one valid * SYN or Acceptable SYN/ACK with (AE,CWR,ECE) = (0,0,0) during the handshake */ tcp_sk(sk)->ecn_fail = 1; diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index ddc5f1c4d06c..4806686bcb49 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -386,15 +386,17 @@ tcp_ecn_make_synack(struct sock *sk, const struct request_sock *req, struct tcph else if (inet_rsk(req)->ecn_ok) th->ece = 1; } else if (tcp_rsk(req)->accecn_ok) { - // [CY] 3.2.3.2.2. Testing for Loss of Packets Carrying the AccECN Option - If this retransmission times out, - // to expedite connection setup, the TCP Server SHOULD retransmit the SYN/ACK with (AE,CWR,ECE) = (0,0,0) and - // no AccECN Option, but it remains in AccECN feedback mode + /* [CY] 3.2.3.2.2. Testing for Loss of Packets Carrying the AccECN Option - If this retransmission times out, + * to expedite connection setup, the TCP Server SHOULD retransmit the SYN/ACK with (AE,CWR,ECE) = (0,0,0) and + * no AccECN Option, but it remains in AccECN feedback mode + */ th->ae = 0; th->cwr = 0; th->ece = 0; - // [CY] 3.1.5. Implications of AccECN Mode - A TCP Server in AccECN mode: MUST NOT set ECT on - // any packet for the rest of the connection, if it has received or sent at least one valid - // SYN or Acceptable SYN/ACK with (AE,CWR,ECE) = (0,0,0) during the handshake. + /* [CY] 3.1.5. Implications of AccECN Mode - A TCP Server in AccECN mode: MUST NOT set ECT on any packet for + * the rest of the connection, if it has received or sent at least one valid SYN or Acceptable SYN/ACK with + * (AE,CWR,ECE) = (0,0,0) during the handshake. + */ tcp_sk(sk)->ecn_fail = 1; } } @@ -1103,8 +1105,9 @@ static unsigned int tcp_synack_options(const struct sock *sk, smc_set_option_cond(tcp_sk(sk), ireq, opts, &remaining); - // [CY] 3.2.3.2.2. Testing for Loss of Packets Carrying the AccECN Option - TCP Server SHOULD retransmit the - // SYN/ACK, but with no AccECN Option + /* [CY] 3.2.3.2.2. Testing for Loss of Packets Carrying the AccECN Option - TCP Server SHOULD retransmit the + * SYN/ACK, but with no AccECN Option + */ if (treq->accecn_ok && sock_net(sk)->ipv4.sysctl_tcp_ecn_option && !req->is_rtx && (remaining >= TCPOLEN_ACCECN_BASE)) { opts->ecn_bytes = synack_ecn_bytes; @@ -1186,7 +1189,7 @@ static unsigned int tcp_established_options(struct sock *sk, struct sk_buff *skb if (tcp_ecn_mode_accecn(tp) && sock_net(sk)->ipv4.sysctl_tcp_ecn_option && - (tp->saw_accecn_opt && tp->saw_accecn_opt != TCP_ACCECN_OPT_FAIL)) { + (tp->saw_accecn_opt && tp->saw_accecn_opt != TCP_ACCECN_OPT_FAIL && !tp->accecn_no_options)) { if (sock_net(sk)->ipv4.sysctl_tcp_ecn_option >= 2 || tp->accecn_opt_demand || tcp_accecn_option_beacon_check(sk)) { From 821d92cc77deac49a46cd514676266a122ef799e Mon Sep 17 00:00:00 2001 From: Chia-Yu Date: Thu, 25 Jan 2024 17:28:55 +0100 Subject: [PATCH 18/24] Fix typo --- include/linux/tcp.h | 4 ++-- net/ipv4/tcp.c | 2 +- net/ipv4/tcp_input.c | 2 +- net/ipv4/tcp_minisocks.c | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/include/linux/tcp.h b/include/linux/tcp.h index cc1013374a96..ee11ba9a1f1d 100644 --- a/include/linux/tcp.h +++ b/include/linux/tcp.h @@ -233,8 +233,8 @@ struct tcp_sock { syn_ect_snt:2, /* AccECN ECT memory, only */ syn_ect_rcv:2, /* ... needed durign 3WHS + first seqno */ ecn_fail:1; /* ECN reflector detected path mangling */ - u8 accecn_no_process:1, /* AccECN no response on feedback */ - accecn_no_options:1; + u8 accecn_no_respond:1, /* AccECN no response on feedback */ + accecn_no_options:1; /* AccECN no options send out */ u8 saw_accecn_opt:2, /* An AccECN option was seen */ fast_ack_mode:2, /* which fast ack mode ? */ unused:4; diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 8b4fce6fef4c..ad66e0cd8c01 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -3033,7 +3033,7 @@ int tcp_disconnect(struct sock *sk, int flags) tp->delivered_ce = 0; tp->saw_accecn_opt = 0; tp->ecn_fail = 0; - tp->accecn_no_process = 0; + tp->accecn_no_respond = 0; tp->accecn_no_options = 0; tcp_accecn_init_counters(tp); tp->prev_ecnfield = 0; diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 94aed08fd16e..3e019e324c46 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -595,7 +595,7 @@ static bool tcp_accecn_process_option(struct tcp_sock *tp, bool order1, res; unsigned int i; - if (tp->saw_accecn_opt == TCP_ACCECN_OPT_FAIL || tp->accecn_no_response) + if (tp->saw_accecn_opt == TCP_ACCECN_OPT_FAIL || tp->accecn_no_respond) return false; if (!(flag & FLAG_SLOWPATH) || !tp->rx_opt.accecn) { diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c index 2066097415f2..7318de84a6c8 100644 --- a/net/ipv4/tcp_minisocks.c +++ b/net/ipv4/tcp_minisocks.c @@ -410,7 +410,7 @@ void tcp_accecn_third_ack(struct sock *sk, const struct sk_buff *skb, // of the connection the Server MUST NOT set ECT on outgoing packets and MUST NOT respond to AccECN // feedback. Nonetheless, as a Data Receiver it MUST NOT disable AccECN feedback. tp->ecn_fail = 1; - tp->accecn_no_response = 1; + tp->accecn_no_respond = 1; break; case 0x7: case 0x5: From 08b1f990ee1f55e95fc2ad4ea6979bdcd2db4f0d Mon Sep 17 00:00:00 2001 From: Chia-Yu Date: Tue, 30 Jan 2024 17:20:30 +0100 Subject: [PATCH 19/24] Fix typo and comments --- net/ipv4/tcp_input.c | 1 - net/ipv4/tcp_minisocks.c | 16 +++++++++------- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 3e019e324c46..760e69e593c6 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -4903,7 +4903,6 @@ static void tcp_rcv_spurious_retrans(struct sock *sk, const struct sk_buff *skb) */ if (tcp_ecn_mode_accecn(tp)) tcp_sock(sk)->accecn_no_options = 1; - } } } diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c index 7318de84a6c8..8aeeca7423dc 100644 --- a/net/ipv4/tcp_minisocks.c +++ b/net/ipv4/tcp_minisocks.c @@ -405,10 +405,11 @@ void tcp_accecn_third_ack(struct sock *sk, const struct sk_buff *skb, switch (ace) { case 0x0: - // [CY] 3.2.2.1. ACE Field on the ACK of the SYN/ACK - If the Server is in AccECN mode and in SYN-RCVD - // state, and if it receives a value of zero on a pure ACK with SYN=0 and no SACK blocks, for the rest - // of the connection the Server MUST NOT set ECT on outgoing packets and MUST NOT respond to AccECN - // feedback. Nonetheless, as a Data Receiver it MUST NOT disable AccECN feedback. + /* [CY] 3.2.2.1. ACE Field on the ACK of the SYN/ACK - If the Server is in AccECN mode and in SYN-RCVD + * state, and if it receives a value of zero on a pure ACK with SYN=0 and no SACK blocks, for the rest + * of the connection the Server MUST NOT set ECT on outgoing packets and MUST NOT respond to AccECN + * feedback. Nonetheless, as a Data Receiver it MUST NOT disable AccECN feedback. + */ tp->ecn_fail = 1; tp->accecn_no_respond = 1; break; @@ -437,9 +438,10 @@ static void tcp_ecn_openreq_child(struct sock *sk, const struct tcp_request_sock *treq = tcp_rsk(req); struct tcp_sock *tp = tcp_sk(sk); - // [CY] 3.1.5. Implications of AccECN Mode - A TCP Server in AccECN mode: MUST NOT set ECT on - // any packet for the rest of the connection, if it has received or sent at least one valid - // SYN or Acceptable SYN/ACK with (AE,CWR,ECE) = (0,0,0) during the handshake. + /* [CY] 3.1.5. Implications of AccECN Mode - A TCP Server in AccECN mode: MUST NOT set ECT oni + * any packet for the rest of the connection, if it has received or sent at least one valid + * SYN or Acceptable SYN/ACK with (AE,CWR,ECE) = (0,0,0) during the handshake. + */ if (treq->accecn_ok) { const struct tcphdr *th = (const struct tcphdr *)skb->data; tcp_ecn_mode_set(tp, TCP_ECN_MODE_ACCECN); From 4538174db72a276736f9c5e517b43926be79cc67 Mon Sep 17 00:00:00 2001 From: Chia-Yu Date: Tue, 30 Jan 2024 18:21:17 +0100 Subject: [PATCH 20/24] Fix typo --- net/ipv4/tcp_input.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 760e69e593c6..4eeba5e3bfe0 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -4901,7 +4901,7 @@ static void tcp_rcv_spurious_retrans(struct sock *sk, const struct sk_buff *skb) * Option by detecting whether the acknowledged data always reappears as a retransmission. In such cases, * the host SHOULD disable the sending of the AccECN Option for this half-connection. */ - if (tcp_ecn_mode_accecn(tp)) + if (tcp_ecn_mode_accecn(tcp_sock(sk))) tcp_sock(sk)->accecn_no_options = 1; } From bde09fefe1e049e25a745b6860d2b5e99c034ac7 Mon Sep 17 00:00:00 2001 From: Chia-Yu Date: Tue, 30 Jan 2024 19:23:54 +0100 Subject: [PATCH 21/24] Fix typo --- net/ipv4/tcp_input.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 4eeba5e3bfe0..68835c3010a4 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -4901,8 +4901,8 @@ static void tcp_rcv_spurious_retrans(struct sock *sk, const struct sk_buff *skb) * Option by detecting whether the acknowledged data always reappears as a retransmission. In such cases, * the host SHOULD disable the sending of the AccECN Option for this half-connection. */ - if (tcp_ecn_mode_accecn(tcp_sock(sk))) - tcp_sock(sk)->accecn_no_options = 1; + if (tcp_ecn_mode_accecn(tcp_sk(sk))) + tcp_sk(sk)->accecn_no_options = 1; } } From 5d809aaa59df0fc2f484a3d614f6c8ce798d3812 Mon Sep 17 00:00:00 2001 From: Chia-Yu Date: Sat, 3 Feb 2024 15:33:06 +0100 Subject: [PATCH 22/24] Add ACE check on first data ACK --- include/linux/tcp.h | 3 ++- net/ipv4/tcp.c | 1 + net/ipv4/tcp_input.c | 15 +++++++++++++++ net/ipv4/tcp_minisocks.c | 2 +- 4 files changed, 19 insertions(+), 2 deletions(-) diff --git a/include/linux/tcp.h b/include/linux/tcp.h index ee11ba9a1f1d..73ab3e9c7942 100644 --- a/include/linux/tcp.h +++ b/include/linux/tcp.h @@ -234,7 +234,8 @@ struct tcp_sock { syn_ect_rcv:2, /* ... needed durign 3WHS + first seqno */ ecn_fail:1; /* ECN reflector detected path mangling */ u8 accecn_no_respond:1, /* AccECN no response on feedback */ - accecn_no_options:1; /* AccECN no options send out */ + accecn_no_options:1, /* AccECN no options send out */ + first_data_ack:1; /* Check for first data ack */ u8 saw_accecn_opt:2, /* An AccECN option was seen */ fast_ack_mode:2, /* which fast ack mode ? */ unused:4; diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index ad66e0cd8c01..3f7a83eb6fae 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -3035,6 +3035,7 @@ int tcp_disconnect(struct sock *sk, int flags) tp->ecn_fail = 0; tp->accecn_no_respond = 0; tp->accecn_no_options = 0; + tp->first_data_ack = 0; tcp_accecn_init_counters(tp); tp->prev_ecnfield = 0; tp->accecn_opt_tstamp = 0; diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 68835c3010a4..dee1e31d9b8a 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -703,6 +703,21 @@ static u32 __tcp_accecn_process(struct sock *sk, const struct sk_buff *skb, if (flag & FLAG_SYN_ACKED) return 0; + /* [CY] 3.2.2.4. Testing for Zeroing of the ACE Field - If AccECN has been successfully negotiated, the Data Sender + * MAY check the value of the ACE counter in the first feedback packet (with or without data) that arrives after the + * 3-way handshake. If the value of this ACE field is found to be zero (0b000), for the remainder of the half- + * connection the Data Sender ought to send non-ECN-capable packets and it is advised not to respond to any feedback + * of CE markings. + */ + if (!tp->first_data_ack) { + tp->first_data_ack = 1; + if (!tcp_accecn_ace(tcp_hdr(skb))) { + tp->ecn_fail = 1; + tp->accecn_no_respond = 1; + return 0; + } + } + if (tp->received_ce_pending >= TCP_ACCECN_ACE_MAX_DELTA) inet_csk(sk)->icsk_ack.pending |= ICSK_ACK_NOW; diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c index 8aeeca7423dc..ba104fb82c7d 100644 --- a/net/ipv4/tcp_minisocks.c +++ b/net/ipv4/tcp_minisocks.c @@ -438,7 +438,7 @@ static void tcp_ecn_openreq_child(struct sock *sk, const struct tcp_request_sock *treq = tcp_rsk(req); struct tcp_sock *tp = tcp_sk(sk); - /* [CY] 3.1.5. Implications of AccECN Mode - A TCP Server in AccECN mode: MUST NOT set ECT oni + /* [CY] 3.1.5. Implications of AccECN Mode - A TCP Server in AccECN mode: MUST NOT set ECT on * any packet for the rest of the connection, if it has received or sent at least one valid * SYN or Acceptable SYN/ACK with (AE,CWR,ECE) = (0,0,0) during the handshake. */ From ebae93fe595af2c517daa156df765b7c4ba97c83 Mon Sep 17 00:00:00 2001 From: Chia-Yu Date: Mon, 5 Feb 2024 22:11:12 +0100 Subject: [PATCH 23/24] Add ACE check on first data ACK --- net/ipv4/tcp_input.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index dee1e31d9b8a..c2c72a2688ef 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -711,8 +711,9 @@ static u32 __tcp_accecn_process(struct sock *sk, const struct sk_buff *skb, */ if (!tp->first_data_ack) { tp->first_data_ack = 1; - if (!tcp_accecn_ace(tcp_hdr(skb))) { + if (tcp_accecn_ace(tcp_hdr(skb)) == 0x0) { tp->ecn_fail = 1; + INET_ECN_dontxmit(sk); tp->accecn_no_respond = 1; return 0; } From 623cd470dd64fcf2522b7246fdf5a4bafbe45495 Mon Sep 17 00:00:00 2001 From: Chia-Yu Chang <125277758+minuscat@users.noreply.github.com> Date: Wed, 7 Feb 2024 13:07:17 +0100 Subject: [PATCH 24/24] Update kernel.yml --- .github/workflows/kernel.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/kernel.yml b/.github/workflows/kernel.yml index 4c81b75c797e..1c6d3320a606 100644 --- a/.github/workflows/kernel.yml +++ b/.github/workflows/kernel.yml @@ -63,7 +63,7 @@ jobs: runs-on: ubuntu-20.04 needs: build permissions: write-all - if: ${{ github.ref == 'refs/heads/testing' || github.ref == 'refs/heads/ratebase' || github.ref == 'refs/heads/AccECN-2023' || github.ref == 'refs/heads/AccECN-2024'}} + if: ${{ github.ref == 'refs/heads/testing' || github.ref == 'refs/heads/ratebase' || github.ref == 'refs/heads/AccECN-2023'}} steps: - name: Get artifact uses: actions/download-artifact@v3