Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'accecn-protocol-case-handling-series'

Chia-Yu Chang says:

====================
AccECN protocol case handling series

Plesae find the v13 AccECN case handling patch series, which covers
several excpetional case handling of Accurate ECN spec (RFC9768),
adds new identifiers to be used by CC modules, adds ecn_delta into
rate_sample, and keeps the ACE counter for computation, etc.

This patch series is part of the full AccECN patch series, which is at
https://github.com/L4STeam/linux-net-next/commits/upstream_l4steam/
---
Chia-Yu Chang (13):
selftests/net: gro: add self-test for TCP CWR flag
tcp: ECT_1_NEGOTIATION and NEEDS_ACCECN identifiers
tcp: disable RFC3168 fallback identifier for CC modules
tcp: accecn: handle unexpected AccECN negotiation feedback
tcp: accecn: retransmit downgraded SYN in AccECN negotiation
tcp: add TCP_SYNACK_RETRANS synack_type
tcp: accecn: retransmit SYN/ACK without AccECN option or non-AccECN
SYN/ACK
tcp: accecn: unset ECT if receive or send ACE=0 in AccECN negotiaion
tcp: accecn: fallback outgoing half link to non-AccECN
tcp: accecn: detect loss ACK w/ AccECN option and add
TCP_ACCECN_OPTION_PERSIST
tcp: accecn: add tcpi_ecn_mode and tcpi_option2 in tcp_info
tcp: accecn: enable AccECN
selftests/net: packetdrill: add TCP Accurate ECN cases

Ilpo Järvinen (2):
tcp: try to avoid safer when ACKs are thinned
gro: flushing when CWR is set negatively affects AccECN

Documentation/networking/ip-sysctl.rst | 4 +-
.../networking/net_cachelines/tcp_sock.rst | 1 +
include/linux/tcp.h | 4 +-
include/net/inet_ecn.h | 20 +++-
include/net/tcp.h | 32 +++++-
include/net/tcp_ecn.h | 103 ++++++++++++------
include/uapi/linux/tcp.h | 26 ++++-
net/ipv4/inet_connection_sock.c | 3 +
net/ipv4/sysctl_net_ipv4.c | 4 +-
net/ipv4/tcp.c | 10 ++
net/ipv4/tcp_cong.c | 5 +-
net/ipv4/tcp_input.c | 40 ++++++-
net/ipv4/tcp_minisocks.c | 43 +++++---
net/ipv4/tcp_offload.c | 3 +-
net/ipv4/tcp_output.c | 34 ++++--
net/ipv4/tcp_timer.c | 3 +
tools/testing/selftests/drivers/net/gro.c | 81 ++++++++++----
tools/testing/selftests/drivers/net/gro.py | 3 +-
.../tcp_accecn_2nd_data_as_first.pkt | 24 ++++
.../tcp_accecn_2nd_data_as_first_connect.pkt | 30 +++++
.../tcp_accecn_3rd_ack_after_synack_rxmt.pkt | 19 ++++
..._accecn_3rd_ack_ce_updates_received_ce.pkt | 18 +++
.../tcp_accecn_3rd_ack_lost_data_ce.pkt | 22 ++++
.../net/packetdrill/tcp_accecn_3rd_dups.pkt | 26 +++++
.../tcp_accecn_acc_ecn_disabled.pkt | 13 +++
.../tcp_accecn_accecn_then_notecn_syn.pkt | 28 +++++
.../tcp_accecn_accecn_to_rfc3168.pkt | 18 +++
.../tcp_accecn_client_accecn_options_drop.pkt | 34 ++++++
.../tcp_accecn_client_accecn_options_lost.pkt | 38 +++++++
.../tcp_accecn_clientside_disabled.pkt | 12 ++
...cecn_close_local_close_then_remote_fin.pkt | 25 +++++
.../tcp_accecn_delivered_2ndlargeack.pkt | 25 +++++
..._accecn_delivered_falseoverflow_detect.pkt | 31 ++++++
.../tcp_accecn_delivered_largeack.pkt | 24 ++++
.../tcp_accecn_delivered_largeack2.pkt | 25 +++++
.../tcp_accecn_delivered_maxack.pkt | 25 +++++
.../tcp_accecn_delivered_updates.pkt | 70 ++++++++++++
.../net/packetdrill/tcp_accecn_ecn3.pkt | 12 ++
.../tcp_accecn_ecn_field_updates_opt.pkt | 35 ++++++
.../packetdrill/tcp_accecn_ipflags_drop.pkt | 14 +++
.../tcp_accecn_listen_opt_drop.pkt | 16 +++
.../tcp_accecn_multiple_syn_ack_drop.pkt | 28 +++++
.../tcp_accecn_multiple_syn_drop.pkt | 18 +++
.../tcp_accecn_negotiation_bleach.pkt | 23 ++++
.../tcp_accecn_negotiation_connect.pkt | 23 ++++
.../tcp_accecn_negotiation_listen.pkt | 26 +++++
.../tcp_accecn_negotiation_noopt_connect.pkt | 23 ++++
.../tcp_accecn_negotiation_optenable.pkt | 23 ++++
.../tcp_accecn_no_ecn_after_accecn.pkt | 20 ++++
.../net/packetdrill/tcp_accecn_noopt.pkt | 27 +++++
.../net/packetdrill/tcp_accecn_noprogress.pkt | 27 +++++
.../tcp_accecn_notecn_then_accecn_syn.pkt | 28 +++++
.../tcp_accecn_rfc3168_to_fallback.pkt | 18 +++
.../tcp_accecn_rfc3168_to_rfc3168.pkt | 18 +++
.../tcp_accecn_sack_space_grab.pkt | 28 +++++
.../tcp_accecn_sack_space_grab_with_ts.pkt | 39 +++++++
...tcp_accecn_serverside_accecn_disabled1.pkt | 20 ++++
...tcp_accecn_serverside_accecn_disabled2.pkt | 20 ++++
.../tcp_accecn_serverside_broken.pkt | 19 ++++
.../tcp_accecn_serverside_ecn_disabled.pkt | 19 ++++
.../tcp_accecn_serverside_only.pkt | 18 +++
...n_syn_ace_flags_acked_after_retransmit.pkt | 18 +++
.../tcp_accecn_syn_ace_flags_drop.pkt | 16 +++
...n_ack_ace_flags_acked_after_retransmit.pkt | 27 +++++
.../tcp_accecn_syn_ack_ace_flags_drop.pkt | 26 +++++
.../net/packetdrill/tcp_accecn_syn_ce.pkt | 13 +++
.../net/packetdrill/tcp_accecn_syn_ect0.pkt | 13 +++
.../net/packetdrill/tcp_accecn_syn_ect1.pkt | 13 +++
.../net/packetdrill/tcp_accecn_synack_ce.pkt | 27 +++++
..._accecn_synack_ce_updates_delivered_ce.pkt | 22 ++++
.../packetdrill/tcp_accecn_synack_ect0.pkt | 24 ++++
.../packetdrill/tcp_accecn_synack_ect1.pkt | 24 ++++
.../packetdrill/tcp_accecn_synack_rexmit.pkt | 15 +++
.../packetdrill/tcp_accecn_synack_rxmt.pkt | 25 +++++
.../packetdrill/tcp_accecn_tsnoprogress.pkt | 26 +++++
.../net/packetdrill/tcp_accecn_tsprogress.pkt | 25 +++++
76 files changed, 1680 insertions(+), 102 deletions(-)
create mode 100644 tools/testing/selftests/net/packetdrill/tcp_accecn_2nd_data_as_first.pkt
create mode 100644 tools/testing/selftests/net/packetdrill/tcp_accecn_2nd_data_as_first_connect.pkt
create mode 100644 tools/testing/selftests/net/packetdrill/tcp_accecn_3rd_ack_after_synack_rxmt.pkt
create mode 100644 tools/testing/selftests/net/packetdrill/tcp_accecn_3rd_ack_ce_updates_received_ce.pkt
create mode 100644 tools/testing/selftests/net/packetdrill/tcp_accecn_3rd_ack_lost_data_ce.pkt
create mode 100644 tools/testing/selftests/net/packetdrill/tcp_accecn_3rd_dups.pkt
create mode 100644 tools/testing/selftests/net/packetdrill/tcp_accecn_acc_ecn_disabled.pkt
create mode 100644 tools/testing/selftests/net/packetdrill/tcp_accecn_accecn_then_notecn_syn.pkt
create mode 100644 tools/testing/selftests/net/packetdrill/tcp_accecn_accecn_to_rfc3168.pkt
create mode 100644 tools/testing/selftests/net/packetdrill/tcp_accecn_client_accecn_options_drop.pkt
create mode 100644 tools/testing/selftests/net/packetdrill/tcp_accecn_client_accecn_options_lost.pkt
create mode 100644 tools/testing/selftests/net/packetdrill/tcp_accecn_clientside_disabled.pkt
create mode 100644 tools/testing/selftests/net/packetdrill/tcp_accecn_close_local_close_then_remote_fin.pkt
create mode 100644 tools/testing/selftests/net/packetdrill/tcp_accecn_delivered_2ndlargeack.pkt
create mode 100644 tools/testing/selftests/net/packetdrill/tcp_accecn_delivered_falseoverflow_detect.pkt
create mode 100644 tools/testing/selftests/net/packetdrill/tcp_accecn_delivered_largeack.pkt
create mode 100644 tools/testing/selftests/net/packetdrill/tcp_accecn_delivered_largeack2.pkt
create mode 100644 tools/testing/selftests/net/packetdrill/tcp_accecn_delivered_maxack.pkt
create mode 100644 tools/testing/selftests/net/packetdrill/tcp_accecn_delivered_updates.pkt
create mode 100644 tools/testing/selftests/net/packetdrill/tcp_accecn_ecn3.pkt
create mode 100644 tools/testing/selftests/net/packetdrill/tcp_accecn_ecn_field_updates_opt.pkt
create mode 100644 tools/testing/selftests/net/packetdrill/tcp_accecn_ipflags_drop.pkt
create mode 100644 tools/testing/selftests/net/packetdrill/tcp_accecn_listen_opt_drop.pkt
create mode 100644 tools/testing/selftests/net/packetdrill/tcp_accecn_multiple_syn_ack_drop.pkt
create mode 100644 tools/testing/selftests/net/packetdrill/tcp_accecn_multiple_syn_drop.pkt
create mode 100644 tools/testing/selftests/net/packetdrill/tcp_accecn_negotiation_bleach.pkt
create mode 100644 tools/testing/selftests/net/packetdrill/tcp_accecn_negotiation_connect.pkt
create mode 100644 tools/testing/selftests/net/packetdrill/tcp_accecn_negotiation_listen.pkt
create mode 100644 tools/testing/selftests/net/packetdrill/tcp_accecn_negotiation_noopt_connect.pkt
create mode 100644 tools/testing/selftests/net/packetdrill/tcp_accecn_negotiation_optenable.pkt
create mode 100644 tools/testing/selftests/net/packetdrill/tcp_accecn_no_ecn_after_accecn.pkt
create mode 100644 tools/testing/selftests/net/packetdrill/tcp_accecn_noopt.pkt
create mode 100644 tools/testing/selftests/net/packetdrill/tcp_accecn_noprogress.pkt
create mode 100644 tools/testing/selftests/net/packetdrill/tcp_accecn_notecn_then_accecn_syn.pkt
create mode 100644 tools/testing/selftests/net/packetdrill/tcp_accecn_rfc3168_to_fallback.pkt
create mode 100644 tools/testing/selftests/net/packetdrill/tcp_accecn_rfc3168_to_rfc3168.pkt
create mode 100644 tools/testing/selftests/net/packetdrill/tcp_accecn_sack_space_grab.pkt
create mode 100644 tools/testing/selftests/net/packetdrill/tcp_accecn_sack_space_grab_with_ts.pkt
create mode 100644 tools/testing/selftests/net/packetdrill/tcp_accecn_serverside_accecn_disabled1.pkt
create mode 100644 tools/testing/selftests/net/packetdrill/tcp_accecn_serverside_accecn_disabled2.pkt
create mode 100644 tools/testing/selftests/net/packetdrill/tcp_accecn_serverside_broken.pkt
create mode 100644 tools/testing/selftests/net/packetdrill/tcp_accecn_serverside_ecn_disabled.pkt
create mode 100644 tools/testing/selftests/net/packetdrill/tcp_accecn_serverside_only.pkt
create mode 100644 tools/testing/selftests/net/packetdrill/tcp_accecn_syn_ace_flags_acked_after_retransmit.pkt
create mode 100644 tools/testing/selftests/net/packetdrill/tcp_accecn_syn_ace_flags_drop.pkt
create mode 100644 tools/testing/selftests/net/packetdrill/tcp_accecn_syn_ack_ace_flags_acked_after_retransmit.pkt
create mode 100644 tools/testing/selftests/net/packetdrill/tcp_accecn_syn_ack_ace_flags_drop.pkt
create mode 100644 tools/testing/selftests/net/packetdrill/tcp_accecn_syn_ce.pkt
create mode 100644 tools/testing/selftests/net/packetdrill/tcp_accecn_syn_ect0.pkt
create mode 100644 tools/testing/selftests/net/packetdrill/tcp_accecn_syn_ect1.pkt
create mode 100644 tools/testing/selftests/net/packetdrill/tcp_accecn_synack_ce.pkt
create mode 100644 tools/testing/selftests/net/packetdrill/tcp_accecn_synack_ce_updates_delivered_ce.pkt
create mode 100644 tools/testing/selftests/net/packetdrill/tcp_accecn_synack_ect0.pkt
create mode 100644 tools/testing/selftests/net/packetdrill/tcp_accecn_synack_ect1.pkt
create mode 100644 tools/testing/selftests/net/packetdrill/tcp_accecn_synack_rexmit.pkt
create mode 100644 tools/testing/selftests/net/packetdrill/tcp_accecn_synack_rxmt.pkt
create mode 100644 tools/testing/selftests/net/packetdrill/tcp_accecn_tsnoprogress.pkt
create mode 100644 tools/testing/selftests/net/packetdrill/tcp_accecn_tsprogress.pkt
====================

Link: https://patch.msgid.link/20260131222515.8485-1-chia-yu.chang@nokia-bell-labs.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>

+1678 -100
+3 -1
Documentation/networking/ip-sysctl.rst
··· 482 482 1 Send AccECN option sparingly according to the minimum option 483 483 rules outlined in draft-ietf-tcpm-accurate-ecn. 484 484 2 Send AccECN option on every packet whenever it fits into TCP 485 - option space. 485 + option space except when AccECN fallback is triggered. 486 + 3 Send AccECN option on every packet whenever it fits into TCP 487 + option space even when AccECN fallback is triggered. 486 488 = ============================================================ 487 489 488 490 Default: 2
+1
Documentation/networking/net_cachelines/tcp_sock.rst
··· 105 105 u32[3] received_ecn_bytes read_mostly read_write 106 106 u8:4 received_ce_pending read_mostly read_write 107 107 u32[3] delivered_ecn_bytes read_write 108 + u16 pkts_acked_ewma read_write 108 109 u8:2 syn_ect_snt write_mostly read_write 109 110 u8:2 syn_ect_rcv read_mostly read_write 110 111 u8:2 accecn_minlen write_mostly read_write
+3 -1
include/linux/tcp.h
··· 291 291 u8 nonagle : 4,/* Disable Nagle algorithm? */ 292 292 rate_app_limited:1; /* rate_{delivered,interval_us} limited? */ 293 293 u8 received_ce_pending:4, /* Not yet transmit cnt of received_ce */ 294 - unused2:4; 294 + accecn_opt_sent_w_dsack:1,/* Sent ACCECN opt in previous ACK w/ D-SACK */ 295 + unused2:3; 295 296 u8 accecn_minlen:2,/* Minimum length of AccECN option sent */ 296 297 est_ecnfield:2,/* ECN field for AccECN delivered estimates */ 297 298 accecn_opt_demand:2,/* Demand AccECN option for n next ACKs */ ··· 343 342 u32 rate_interval_us; /* saved rate sample: time elapsed */ 344 343 u32 rcv_rtt_last_tsecr; 345 344 u32 delivered_ecn_bytes[3]; 345 + u16 pkts_acked_ewma;/* Pkts acked EWMA for AccECN cep heuristic */ 346 346 u64 first_tx_mstamp; /* start of window send phase */ 347 347 u64 delivered_mstamp; /* time we reached "delivered" */ 348 348 u64 bytes_acked; /* RFC4898 tcpEStatsAppHCThruOctetsAcked
+17 -3
include/net/inet_ecn.h
··· 51 51 return outer; 52 52 } 53 53 54 + /* Apply either ECT(0) or ECT(1) */ 55 + static inline void __INET_ECN_xmit(struct sock *sk, bool use_ect_1) 56 + { 57 + __u8 ect = use_ect_1 ? INET_ECN_ECT_1 : INET_ECN_ECT_0; 58 + 59 + /* Mask the complete byte in case the connection alternates between 60 + * ECT(0) and ECT(1). 61 + */ 62 + inet_sk(sk)->tos &= ~INET_ECN_MASK; 63 + inet_sk(sk)->tos |= ect; 64 + if (inet6_sk(sk)) { 65 + inet6_sk(sk)->tclass &= ~INET_ECN_MASK; 66 + inet6_sk(sk)->tclass |= ect; 67 + } 68 + } 69 + 54 70 static inline void INET_ECN_xmit(struct sock *sk) 55 71 { 56 - inet_sk(sk)->tos |= INET_ECN_ECT_0; 57 - if (inet6_sk(sk) != NULL) 58 - inet6_sk(sk)->tclass |= INET_ECN_ECT_0; 72 + __INET_ECN_xmit(sk, false); 59 73 } 60 74 61 75 static inline void INET_ECN_dontxmit(struct sock *sk)
+31 -1
include/net/tcp.h
··· 552 552 TCP_SYNACK_NORMAL, 553 553 TCP_SYNACK_FASTOPEN, 554 554 TCP_SYNACK_COOKIE, 555 + TCP_SYNACK_RETRANS, 555 556 }; 556 557 struct sk_buff *tcp_make_synack(const struct sock *sk, struct dst_entry *dst, 557 558 struct request_sock *req, ··· 1216 1215 #define TCP_CONG_NON_RESTRICTED BIT(0) 1217 1216 /* Requires ECN/ECT set on all packets */ 1218 1217 #define TCP_CONG_NEEDS_ECN BIT(1) 1219 - #define TCP_CONG_MASK (TCP_CONG_NON_RESTRICTED | TCP_CONG_NEEDS_ECN) 1218 + /* Require successfully negotiated AccECN capability */ 1219 + #define TCP_CONG_NEEDS_ACCECN BIT(2) 1220 + /* Use ECT(1) instead of ECT(0) while the CA is uninitialized */ 1221 + #define TCP_CONG_ECT_1_NEGOTIATION BIT(3) 1222 + /* Cannot fallback to RFC3168 during AccECN negotiation */ 1223 + #define TCP_CONG_NO_FALLBACK_RFC3168 BIT(4) 1224 + #define TCP_CONG_MASK (TCP_CONG_NON_RESTRICTED | TCP_CONG_NEEDS_ECN | \ 1225 + TCP_CONG_NEEDS_ACCECN | TCP_CONG_ECT_1_NEGOTIATION | \ 1226 + TCP_CONG_NO_FALLBACK_RFC3168) 1220 1227 1221 1228 union tcp_cc_info; 1222 1229 ··· 1363 1354 const struct inet_connection_sock *icsk = inet_csk(sk); 1364 1355 1365 1356 return icsk->icsk_ca_ops->flags & TCP_CONG_NEEDS_ECN; 1357 + } 1358 + 1359 + static inline bool tcp_ca_needs_accecn(const struct sock *sk) 1360 + { 1361 + const struct inet_connection_sock *icsk = inet_csk(sk); 1362 + 1363 + return icsk->icsk_ca_ops->flags & TCP_CONG_NEEDS_ACCECN; 1364 + } 1365 + 1366 + static inline bool tcp_ca_ect_1_negotiation(const struct sock *sk) 1367 + { 1368 + const struct inet_connection_sock *icsk = inet_csk(sk); 1369 + 1370 + return icsk->icsk_ca_ops->flags & TCP_CONG_ECT_1_NEGOTIATION; 1371 + } 1372 + 1373 + static inline bool tcp_ca_no_fallback_rfc3168(const struct sock *sk) 1374 + { 1375 + const struct inet_connection_sock *icsk = inet_csk(sk); 1376 + 1377 + return icsk->icsk_ca_ops->flags & TCP_CONG_NO_FALLBACK_RFC3168; 1366 1378 } 1367 1379 1368 1380 static inline void tcp_ca_event(struct sock *sk, const enum tcp_ca_event event)
+68 -35
include/net/tcp_ecn.h
··· 29 29 TCP_ACCECN_OPTION_DISABLED = 0, 30 30 TCP_ACCECN_OPTION_MINIMUM = 1, 31 31 TCP_ACCECN_OPTION_FULL = 2, 32 + TCP_ACCECN_OPTION_PERSIST = 3, 32 33 }; 34 + 35 + /* Apply either ECT(0) or ECT(1) based on TCP_CONG_ECT_1_NEGOTIATION flag */ 36 + static inline void INET_ECN_xmit_ect_1_negotiation(struct sock *sk) 37 + { 38 + __INET_ECN_xmit(sk, tcp_ca_ect_1_negotiation(sk)); 39 + } 33 40 34 41 static inline void tcp_ecn_queue_cwr(struct tcp_sock *tp) 35 42 { ··· 67 60 tp->ecn_flags &= ~TCP_ECN_QUEUE_CWR; 68 61 } 69 62 70 - /* tp->accecn_fail_mode */ 71 - #define TCP_ACCECN_ACE_FAIL_SEND BIT(0) 72 - #define TCP_ACCECN_ACE_FAIL_RECV BIT(1) 73 - #define TCP_ACCECN_OPT_FAIL_SEND BIT(2) 74 - #define TCP_ACCECN_OPT_FAIL_RECV BIT(3) 75 - 76 63 static inline bool tcp_accecn_ace_fail_send(const struct tcp_sock *tp) 77 64 { 78 65 return tp->accecn_fail_mode & TCP_ACCECN_ACE_FAIL_SEND; ··· 91 90 { 92 91 tp->accecn_fail_mode |= mode; 93 92 } 94 - 95 - #define TCP_ACCECN_OPT_NOT_SEEN 0x0 96 - #define TCP_ACCECN_OPT_EMPTY_SEEN 0x1 97 - #define TCP_ACCECN_OPT_COUNTER_SEEN 0x2 98 - #define TCP_ACCECN_OPT_FAIL_SEEN 0x3 99 93 100 94 static inline u8 tcp_accecn_ace(const struct tcphdr *th) 101 95 { ··· 165 169 switch (ace) { 166 170 case 0x0: 167 171 /* Invalid value */ 168 - tcp_accecn_fail_mode_set(tp, TCP_ACCECN_ACE_FAIL_RECV); 172 + if (!TCP_SKB_CB(skb)->sacked) 173 + tcp_accecn_fail_mode_set(tp, TCP_ACCECN_ACE_FAIL_RECV | 174 + TCP_ACCECN_OPT_FAIL_RECV); 169 175 break; 170 176 case 0x7: 171 177 case 0x5: ··· 396 398 tp->received_ce_pending = 0; 397 399 __tcp_accecn_init_bytes_counters(tp->received_ecn_bytes); 398 400 __tcp_accecn_init_bytes_counters(tp->delivered_ecn_bytes); 401 + tp->accecn_opt_sent_w_dsack = 0; 399 402 tp->accecn_minlen = 0; 400 403 tp->accecn_opt_demand = 0; 401 404 tp->est_ecnfield = 0; ··· 466 467 return TCP_ACCECN_OPT_COUNTER_SEEN; 467 468 } 468 469 470 + static inline void tcp_ecn_rcv_synack_accecn(struct sock *sk, 471 + const struct sk_buff *skb, u8 dsf) 472 + { 473 + struct tcp_sock *tp = tcp_sk(sk); 474 + 475 + tcp_ecn_mode_set(tp, TCP_ECN_MODE_ACCECN); 476 + tp->syn_ect_rcv = dsf & INET_ECN_MASK; 477 + /* Demand Accurate ECN option in response to the SYN on the SYN/ACK 478 + * and the TCP server will try to send one more packet with an AccECN 479 + * Option at a later point during the connection. 480 + */ 481 + if (tp->rx_opt.accecn && 482 + tp->saw_accecn_opt < TCP_ACCECN_OPT_COUNTER_SEEN) { 483 + u8 saw_opt = tcp_accecn_option_init(skb, tp->rx_opt.accecn); 484 + 485 + tcp_accecn_saw_opt_fail_recv(tp, saw_opt); 486 + tp->accecn_opt_demand = 2; 487 + } 488 + } 489 + 469 490 /* See Table 2 of the AccECN draft */ 470 491 static inline void tcp_ecn_rcv_synack(struct sock *sk, const struct sk_buff *skb, 471 492 const struct tcphdr *th, u8 ip_dsfield) ··· 508 489 tcp_ecn_mode_set(tp, TCP_ECN_DISABLED); 509 490 break; 510 491 case 0x1: 511 - case 0x5: 512 492 /* +========+========+============+=============+ 513 493 * | A | B | SYN/ACK | Feedback | 514 494 * | | | B->A | Mode of A | 515 495 * | | | AE CWR ECE | | 516 496 * +========+========+============+=============+ 517 - * | AccECN | Nonce | 1 0 1 | (Reserved) | 518 497 * | AccECN | ECN | 0 0 1 | Classic ECN | 519 498 * | Nonce | AccECN | 0 0 1 | Classic ECN | 520 499 * | ECN | AccECN | 0 0 1 | Classic ECN | 521 500 * +========+========+============+=============+ 522 501 */ 523 - if (tcp_ecn_mode_pending(tp)) 524 - /* Downgrade from AccECN, or requested initially */ 502 + if (tcp_ca_no_fallback_rfc3168(sk)) 503 + tcp_ecn_mode_set(tp, TCP_ECN_DISABLED); 504 + else 525 505 tcp_ecn_mode_set(tp, TCP_ECN_MODE_RFC3168); 526 506 break; 527 - default: 528 - tcp_ecn_mode_set(tp, TCP_ECN_MODE_ACCECN); 529 - tp->syn_ect_rcv = ip_dsfield & INET_ECN_MASK; 530 - if (tp->rx_opt.accecn && 531 - tp->saw_accecn_opt < TCP_ACCECN_OPT_COUNTER_SEEN) { 532 - u8 saw_opt = tcp_accecn_option_init(skb, tp->rx_opt.accecn); 533 - 534 - tcp_accecn_saw_opt_fail_recv(tp, saw_opt); 535 - tp->accecn_opt_demand = 2; 507 + case 0x5: 508 + if (tcp_ecn_mode_pending(tp)) { 509 + tcp_ecn_rcv_synack_accecn(sk, skb, ip_dsfield); 510 + if (INET_ECN_is_ce(ip_dsfield)) { 511 + tp->received_ce++; 512 + tp->received_ce_pending++; 513 + } 536 514 } 515 + break; 516 + default: 517 + tcp_ecn_rcv_synack_accecn(sk, skb, ip_dsfield); 537 518 if (INET_ECN_is_ce(ip_dsfield) && 538 519 tcp_accecn_validate_syn_feedback(sk, ace, 539 520 tp->syn_ect_snt)) { ··· 544 525 } 545 526 } 546 527 547 - static inline void tcp_ecn_rcv_syn(struct tcp_sock *tp, const struct tcphdr *th, 528 + static inline void tcp_ecn_rcv_syn(struct sock *sk, const struct tcphdr *th, 548 529 const struct sk_buff *skb) 549 530 { 531 + struct tcp_sock *tp = tcp_sk(sk); 532 + 550 533 if (tcp_ecn_mode_pending(tp)) { 551 534 if (!tcp_accecn_syn_requested(th)) { 552 535 /* Downgrade to classic ECN feedback */ ··· 560 539 tcp_ecn_mode_set(tp, TCP_ECN_MODE_ACCECN); 561 540 } 562 541 } 563 - if (tcp_ecn_mode_rfc3168(tp) && (!th->ece || !th->cwr)) 542 + if (tcp_ecn_mode_rfc3168(tp) && 543 + (!th->ece || !th->cwr || tcp_ca_no_fallback_rfc3168(sk))) 564 544 tcp_ecn_mode_set(tp, TCP_ECN_DISABLED); 565 545 } 566 546 ··· 583 561 TCP_SKB_CB(skb)->tcp_flags &= ~TCPHDR_ECE; 584 562 else if (tcp_ca_needs_ecn(sk) || 585 563 tcp_bpf_ca_needs_ecn(sk)) 586 - INET_ECN_xmit(sk); 564 + INET_ECN_xmit_ect_1_negotiation(sk); 587 565 588 566 if (tp->ecn_flags & TCP_ECN_MODE_ACCECN) { 589 567 TCP_SKB_CB(skb)->tcp_flags &= ~TCPHDR_ACE; ··· 601 579 bool use_ecn, use_accecn; 602 580 u8 tcp_ecn = READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_ecn); 603 581 604 - use_accecn = tcp_ecn == TCP_ECN_IN_ACCECN_OUT_ACCECN; 582 + use_accecn = tcp_ecn == TCP_ECN_IN_ACCECN_OUT_ACCECN || 583 + tcp_ca_needs_accecn(sk); 605 584 use_ecn = tcp_ecn == TCP_ECN_IN_ECN_OUT_ECN || 606 585 tcp_ecn == TCP_ECN_IN_ACCECN_OUT_ECN || 607 586 tcp_ca_needs_ecn(sk) || bpf_needs_ecn || use_accecn; ··· 618 595 619 596 if (use_ecn) { 620 597 if (tcp_ca_needs_ecn(sk) || bpf_needs_ecn) 621 - INET_ECN_xmit(sk); 598 + INET_ECN_xmit_ect_1_negotiation(sk); 622 599 623 600 TCP_SKB_CB(skb)->tcp_flags |= TCPHDR_ECE | TCPHDR_CWR; 624 601 if (use_accecn) { ··· 642 619 } 643 620 644 621 static inline void 645 - tcp_ecn_make_synack(const struct request_sock *req, struct tcphdr *th) 622 + tcp_ecn_make_synack(const struct request_sock *req, struct tcphdr *th, 623 + enum tcp_synack_type synack_type) 646 624 { 647 - if (tcp_rsk(req)->accecn_ok) 648 - tcp_accecn_echo_syn_ect(th, tcp_rsk(req)->syn_ect_rcv); 649 - else if (inet_rsk(req)->ecn_ok) 650 - th->ece = 1; 625 + /* Accurate ECN shall retransmit SYN/ACK with ACE=0 if the 626 + * previously retransmitted SYN/ACK also times out. 627 + */ 628 + if (!req->num_timeout || synack_type != TCP_SYNACK_RETRANS) { 629 + if (tcp_rsk(req)->accecn_ok) 630 + tcp_accecn_echo_syn_ect(th, tcp_rsk(req)->syn_ect_rcv); 631 + else if (inet_rsk(req)->ecn_ok) 632 + th->ece = 1; 633 + } else if (tcp_rsk(req)->accecn_ok) { 634 + th->ae = 0; 635 + th->cwr = 0; 636 + th->ece = 0; 637 + } 651 638 } 652 639 653 640 static inline bool tcp_accecn_option_beacon_check(const struct sock *sk)
+23 -3
include/uapi/linux/tcp.h
··· 226 226 #define TCPF_CA_Loss (1<<TCP_CA_Loss) 227 227 }; 228 228 229 + /* Values for tcpi_ecn_mode after negotiation */ 230 + #define TCPI_ECN_MODE_DISABLED 0x0 231 + #define TCPI_ECN_MODE_RFC3168 0x1 232 + #define TCPI_ECN_MODE_ACCECN 0x2 233 + #define TCPI_ECN_MODE_PENDING 0x3 234 + 235 + /* Values for accecn_opt_seen */ 236 + #define TCP_ACCECN_OPT_NOT_SEEN 0x0 237 + #define TCP_ACCECN_OPT_EMPTY_SEEN 0x1 238 + #define TCP_ACCECN_OPT_COUNTER_SEEN 0x2 239 + #define TCP_ACCECN_OPT_FAIL_SEEN 0x3 240 + 241 + /* Values for accecn_fail_mode */ 242 + #define TCP_ACCECN_ACE_FAIL_SEND BIT(0) 243 + #define TCP_ACCECN_ACE_FAIL_RECV BIT(1) 244 + #define TCP_ACCECN_OPT_FAIL_SEND BIT(2) 245 + #define TCP_ACCECN_OPT_FAIL_RECV BIT(3) 246 + 229 247 struct tcp_info { 230 248 __u8 tcpi_state; 231 249 __u8 tcpi_ca_state; ··· 334 316 * in milliseconds, including any 335 317 * unfinished recovery. 336 318 */ 337 - __u32 tcpi_received_ce; /* # of CE marks received */ 319 + __u32 tcpi_received_ce; /* # of CE marked segments received */ 338 320 __u32 tcpi_delivered_e1_bytes; /* Accurate ECN byte counters */ 339 321 __u32 tcpi_delivered_e0_bytes; 340 322 __u32 tcpi_delivered_ce_bytes; 341 323 __u32 tcpi_received_e1_bytes; 342 324 __u32 tcpi_received_e0_bytes; 343 325 __u32 tcpi_received_ce_bytes; 344 - __u16 tcpi_accecn_fail_mode; 345 - __u16 tcpi_accecn_opt_seen; 326 + __u32 tcpi_ecn_mode:2, 327 + tcpi_accecn_opt_seen:2, 328 + tcpi_accecn_fail_mode:4, 329 + tcpi_options2:24; 346 330 }; 347 331 348 332 /* netlink attributes types for SCM_TIMESTAMPING_OPT_STATS */
+3
net/ipv4/inet_connection_sock.c
··· 20 20 #include <net/tcp_states.h> 21 21 #include <net/xfrm.h> 22 22 #include <net/tcp.h> 23 + #include <net/tcp_ecn.h> 23 24 #include <net/sock_reuseport.h> 24 25 #include <net/addrconf.h> 25 26 ··· 1104 1103 (!resend || 1105 1104 !tcp_rtx_synack(sk_listener, req) || 1106 1105 inet_rsk(req)->acked)) { 1106 + if (req->num_retrans > 1 && tcp_rsk(req)->accecn_ok) 1107 + tcp_rsk(req)->accecn_fail_mode |= TCP_ACCECN_ACE_FAIL_SEND; 1107 1108 if (req->num_timeout++ == 0) 1108 1109 atomic_dec(&queue->young); 1109 1110 mod_timer(&req->rsk_timer, jiffies + tcp_reqsk_timeout(req));
+2 -2
net/ipv4/sysctl_net_ipv4.c
··· 47 47 static int tcp_plb_max_rounds = 31; 48 48 static int tcp_plb_max_cong_thresh = 256; 49 49 static unsigned int tcp_tw_reuse_delay_max = TCP_PAWS_MSL * MSEC_PER_SEC; 50 - static int tcp_ecn_mode_max = 2; 50 + static int tcp_ecn_mode_max = 5; 51 51 static u32 icmp_errors_extension_mask_all = 52 52 GENMASK_U8(ICMP_ERR_EXT_COUNT - 1, 0); 53 53 ··· 749 749 .mode = 0644, 750 750 .proc_handler = proc_dou8vec_minmax, 751 751 .extra1 = SYSCTL_ZERO, 752 - .extra2 = SYSCTL_TWO, 752 + .extra2 = SYSCTL_THREE, 753 753 }, 754 754 { 755 755 .procname = "tcp_ecn_option_beacon",
+10
net/ipv4/tcp.c
··· 3470 3470 tcp_accecn_init_counters(tp); 3471 3471 tp->prev_ecnfield = 0; 3472 3472 tp->accecn_opt_tstamp = 0; 3473 + tp->pkts_acked_ewma = 0; 3473 3474 if (icsk->icsk_ca_initialized && icsk->icsk_ca_ops->release) 3474 3475 icsk->icsk_ca_ops->release(sk); 3475 3476 memset(icsk->icsk_ca_priv, 0, sizeof(icsk->icsk_ca_priv)); ··· 4373 4372 if (tp->rto_stamp) 4374 4373 info->tcpi_total_rto_time += tcp_clock_ms() - tp->rto_stamp; 4375 4374 4375 + if (tcp_ecn_disabled(tp)) 4376 + info->tcpi_ecn_mode = TCPI_ECN_MODE_DISABLED; 4377 + else if (tcp_ecn_mode_rfc3168(tp)) 4378 + info->tcpi_ecn_mode = TCPI_ECN_MODE_RFC3168; 4379 + else if (tcp_ecn_mode_accecn(tp)) 4380 + info->tcpi_ecn_mode = TCPI_ECN_MODE_ACCECN; 4381 + else if (tcp_ecn_mode_pending(tp)) 4382 + info->tcpi_ecn_mode = TCPI_ECN_MODE_PENDING; 4376 4383 info->tcpi_accecn_fail_mode = tp->accecn_fail_mode; 4377 4384 info->tcpi_accecn_opt_seen = tp->saw_accecn_opt; 4378 4385 info->tcpi_received_ce = tp->received_ce; ··· 5252 5243 CACHELINE_ASSERT_GROUP_MEMBER(struct tcp_sock, tcp_sock_write_rx, rate_interval_us); 5253 5244 CACHELINE_ASSERT_GROUP_MEMBER(struct tcp_sock, tcp_sock_write_rx, rcv_rtt_last_tsecr); 5254 5245 CACHELINE_ASSERT_GROUP_MEMBER(struct tcp_sock, tcp_sock_write_rx, delivered_ecn_bytes); 5246 + CACHELINE_ASSERT_GROUP_MEMBER(struct tcp_sock, tcp_sock_write_rx, pkts_acked_ewma); 5255 5247 CACHELINE_ASSERT_GROUP_MEMBER(struct tcp_sock, tcp_sock_write_rx, first_tx_mstamp); 5256 5248 CACHELINE_ASSERT_GROUP_MEMBER(struct tcp_sock, tcp_sock_write_rx, delivered_mstamp); 5257 5249 CACHELINE_ASSERT_GROUP_MEMBER(struct tcp_sock, tcp_sock_write_rx, bytes_acked);
+3 -2
net/ipv4/tcp_cong.c
··· 16 16 #include <linux/gfp.h> 17 17 #include <linux/jhash.h> 18 18 #include <net/tcp.h> 19 + #include <net/tcp_ecn.h> 19 20 #include <trace/events/tcp.h> 20 21 21 22 static DEFINE_SPINLOCK(tcp_cong_list_lock); ··· 228 227 229 228 memset(icsk->icsk_ca_priv, 0, sizeof(icsk->icsk_ca_priv)); 230 229 if (ca->flags & TCP_CONG_NEEDS_ECN) 231 - INET_ECN_xmit(sk); 230 + INET_ECN_xmit_ect_1_negotiation(sk); 232 231 else 233 232 INET_ECN_dontxmit(sk); 234 233 } ··· 258 257 memset(icsk->icsk_ca_priv, 0, sizeof(icsk->icsk_ca_priv)); 259 258 260 259 if (ca->flags & TCP_CONG_NEEDS_ECN) 261 - INET_ECN_xmit(sk); 260 + INET_ECN_xmit_ect_1_negotiation(sk); 262 261 else 263 262 INET_ECN_dontxmit(sk); 264 263
+36 -4
net/ipv4/tcp_input.c
··· 488 488 tcp_count_delivered_ce(tp, delivered); 489 489 } 490 490 491 + #define PKTS_ACKED_WEIGHT 6 492 + #define PKTS_ACKED_PREC 6 493 + #define ACK_COMP_THRESH 4 494 + 491 495 /* Returns the ECN CE delta */ 492 496 static u32 __tcp_accecn_process(struct sock *sk, const struct sk_buff *skb, 493 497 u32 delivered_pkts, u32 delivered_bytes, ··· 503 499 u32 delta, safe_delta, d_ceb; 504 500 bool opt_deltas_valid; 505 501 u32 corrected_ace; 502 + u32 ewma; 506 503 507 504 /* Reordered ACK or uncertain due to lack of data to send and ts */ 508 505 if (!(flag & (FLAG_FORWARD_PROGRESS | FLAG_TS_PROGRESS))) ··· 511 506 512 507 opt_deltas_valid = tcp_accecn_process_option(tp, skb, 513 508 delivered_bytes, flag); 509 + 510 + if (delivered_pkts) { 511 + if (!tp->pkts_acked_ewma) { 512 + ewma = delivered_pkts << PKTS_ACKED_PREC; 513 + } else { 514 + ewma = tp->pkts_acked_ewma; 515 + ewma = (((ewma << PKTS_ACKED_WEIGHT) - ewma) + 516 + (delivered_pkts << PKTS_ACKED_PREC)) >> 517 + PKTS_ACKED_WEIGHT; 518 + } 519 + tp->pkts_acked_ewma = min_t(u32, ewma, 0xFFFFU); 520 + } 514 521 515 522 if (!(flag & FLAG_SLOWPATH)) { 516 523 /* AccECN counter might overflow on large ACKs */ ··· 572 555 if (d_ceb < 573 556 safe_delta * tp->mss_cache >> TCP_ACCECN_SAFETY_SHIFT) 574 557 return delta; 575 - } 558 + } else if (tp->pkts_acked_ewma > (ACK_COMP_THRESH << PKTS_ACKED_PREC)) 559 + return delta; 576 560 577 561 return safe_delta; 578 562 } ··· 5046 5028 tcp_sack_extend(tp->duplicate_sack, seq, end_seq); 5047 5029 } 5048 5030 5049 - static void tcp_rcv_spurious_retrans(struct sock *sk, const struct sk_buff *skb) 5031 + static void tcp_rcv_spurious_retrans(struct sock *sk, 5032 + const struct sk_buff *skb) 5050 5033 { 5034 + struct tcp_sock *tp = tcp_sk(sk); 5035 + 5051 5036 /* When the ACK path fails or drops most ACKs, the sender would 5052 5037 * timeout and spuriously retransmit the same segment repeatedly. 5053 5038 * If it seems our ACKs are not reaching the other side, ··· 5070 5049 /* Save last flowlabel after a spurious retrans. */ 5071 5050 tcp_save_lrcv_flowlabel(sk, skb); 5072 5051 #endif 5052 + /* Check DSACK info to detect that the previous ACK carrying the 5053 + * AccECN option was lost after the second retransmision, and then 5054 + * stop sending AccECN option in all subsequent ACKs. 5055 + */ 5056 + if (tcp_ecn_mode_accecn(tp) && 5057 + tp->accecn_opt_sent_w_dsack && 5058 + TCP_SKB_CB(skb)->seq == tp->duplicate_sack[0].start_seq) 5059 + tcp_accecn_fail_mode_set(tp, TCP_ACCECN_OPT_FAIL_SEND); 5073 5060 } 5074 5061 5075 5062 static void tcp_send_dupack(struct sock *sk, const struct sk_buff *skb) ··· 6480 6451 if (th->syn) { 6481 6452 if (tcp_ecn_mode_accecn(tp)) { 6482 6453 accecn_reflector = true; 6454 + tp->syn_ect_rcv = TCP_SKB_CB(skb)->ip_dsfield & 6455 + INET_ECN_MASK; 6483 6456 if (tp->rx_opt.accecn && 6484 6457 tp->saw_accecn_opt < TCP_ACCECN_OPT_COUNTER_SEEN) { 6485 6458 u8 saw_opt = tcp_accecn_option_init(skb, tp->rx_opt.accecn); ··· 7103 7072 tp->snd_wl1 = TCP_SKB_CB(skb)->seq; 7104 7073 tp->max_window = tp->snd_wnd; 7105 7074 7106 - tcp_ecn_rcv_syn(tp, th, skb); 7075 + tcp_ecn_rcv_syn(sk, th, skb); 7107 7076 7108 7077 tcp_mtup_init(sk); 7109 7078 tcp_sync_mss(sk, icsk->icsk_pmtu_cookie); ··· 7508 7477 u32 ecn_ok_dst; 7509 7478 7510 7479 if (tcp_accecn_syn_requested(th) && 7511 - READ_ONCE(net->ipv4.sysctl_tcp_ecn) >= 3) { 7480 + (READ_ONCE(net->ipv4.sysctl_tcp_ecn) >= 3 || 7481 + tcp_ca_needs_accecn(listen_sk))) { 7512 7482 inet_rsk(req)->ecn_ok = 1; 7513 7483 tcp_rsk(req)->accecn_ok = 1; 7514 7484 tcp_rsk(req)->syn_ect_rcv = TCP_SKB_CB(skb)->ip_dsfield &
+28 -11
net/ipv4/tcp_minisocks.c
··· 481 481 tp->syn_ect_snt = treq->syn_ect_snt; 482 482 tcp_accecn_third_ack(sk, skb, treq->syn_ect_snt); 483 483 tp->saw_accecn_opt = treq->saw_accecn_opt; 484 + if (treq->accecn_fail_mode & TCP_ACCECN_ACE_FAIL_SEND) 485 + tcp_accecn_fail_mode_set(tp, TCP_ACCECN_ACE_FAIL_SEND); 486 + if (treq->accecn_fail_mode & TCP_ACCECN_ACE_FAIL_RECV) 487 + tcp_accecn_fail_mode_set(tp, TCP_ACCECN_ACE_FAIL_RECV); 484 488 tp->prev_ecnfield = treq->syn_ect_rcv; 485 489 tp->accecn_opt_demand = 1; 486 490 tcp_ecn_received_counters_payload(sk, skb); 487 491 } else { 488 - tcp_ecn_mode_set(tp, inet_rsk(req)->ecn_ok ? 489 - TCP_ECN_MODE_RFC3168 : 490 - TCP_ECN_DISABLED); 492 + if (inet_rsk(req)->ecn_ok && !tcp_ca_no_fallback_rfc3168(sk)) 493 + tcp_ecn_mode_set(tp, TCP_ECN_MODE_RFC3168); 494 + else 495 + tcp_ecn_mode_set(tp, TCP_ECN_DISABLED); 491 496 } 492 497 } 493 498 ··· 753 748 */ 754 749 if (!tcp_oow_rate_limited(sock_net(sk), skb, 755 750 LINUX_MIB_TCPACKSKIPPEDSYNRECV, 756 - &tcp_rsk(req)->last_oow_ack_time) && 751 + &tcp_rsk(req)->last_oow_ack_time)) { 752 + if (tcp_rsk(req)->accecn_ok) { 753 + u8 ect_rcv = TCP_SKB_CB(skb)->ip_dsfield & 754 + INET_ECN_MASK; 757 755 758 - !tcp_rtx_synack(sk, req)) { 759 - unsigned long expires = jiffies; 756 + tcp_rsk(req)->syn_ect_rcv = ect_rcv; 757 + if (tcp_accecn_ace(tcp_hdr(skb)) == 0x0) 758 + tcp_rsk(req)->accecn_fail_mode |= TCP_ACCECN_ACE_FAIL_RECV; 759 + } 760 + if (!tcp_rtx_synack(sk, req)) { 761 + unsigned long expires = jiffies; 760 762 761 - expires += tcp_reqsk_timeout(req); 762 - if (!fastopen) 763 - mod_timer_pending(&req->rsk_timer, expires); 764 - else 765 - req->rsk_timer.expires = expires; 763 + if (req->num_retrans > 1 && tcp_rsk(req)->accecn_ok) 764 + tcp_rsk(req)->accecn_fail_mode |= TCP_ACCECN_ACE_FAIL_SEND; 765 + 766 + expires += tcp_reqsk_timeout(req); 767 + if (!fastopen) 768 + mod_timer_pending(&req->rsk_timer, 769 + expires); 770 + else 771 + req->rsk_timer.expires = expires; 772 + } 766 773 } 767 774 return NULL; 768 775 }
+1 -2
net/ipv4/tcp_offload.c
··· 304 304 goto out_check_final; 305 305 306 306 th2 = tcp_hdr(p); 307 - flush = (__force int)(flags & TCP_FLAG_CWR); 308 - flush |= (__force int)((flags ^ tcp_flag_word(th2)) & 307 + flush = (__force int)((flags ^ tcp_flag_word(th2)) & 309 308 ~(TCP_FLAG_FIN | TCP_FLAG_PSH)); 310 309 flush |= (__force int)(th->ack_seq ^ th2->ack_seq); 311 310 for (i = sizeof(*th); i < thlen; i += 4)
+23 -11
net/ipv4/tcp_output.c
··· 334 334 return; 335 335 336 336 if (tcp_ecn_mode_accecn(tp)) { 337 - if (!tcp_accecn_ace_fail_recv(tp)) 337 + if (!tcp_accecn_ace_fail_recv(tp) && 338 + !tcp_accecn_ace_fail_send(tp)) 338 339 INET_ECN_xmit(sk); 340 + else 341 + INET_ECN_dontxmit(sk); 339 342 tcp_accecn_set_ace(tp, skb, th); 340 343 skb_shinfo(skb)->gso_type |= SKB_GSO_TCP_ACCECN; 341 344 } else { ··· 715 712 if (tp) { 716 713 tp->accecn_minlen = 0; 717 714 tp->accecn_opt_tstamp = tp->tcp_mstamp; 715 + tp->accecn_opt_sent_w_dsack = tp->rx_opt.dsack; 718 716 if (tp->accecn_opt_demand) 719 717 tp->accecn_opt_demand--; 720 718 } 719 + } else if (tp) { 720 + tp->accecn_opt_sent_w_dsack = 0; 721 721 } 722 722 723 723 if (unlikely(OPTION_SACK_ADVERTISE & options)) { ··· 1112 1106 1113 1107 if (treq->accecn_ok && 1114 1108 READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_ecn_option) && 1115 - req->num_timeout < 1 && remaining >= TCPOLEN_ACCECN_BASE) { 1109 + synack_type != TCP_SYNACK_RETRANS && remaining >= TCPOLEN_ACCECN_BASE) { 1116 1110 opts->use_synack_ecn_bytes = 1; 1117 1111 remaining -= tcp_options_fit_accecn(opts, 0, remaining); 1118 1112 } ··· 1192 1186 if (tcp_ecn_mode_accecn(tp)) { 1193 1187 int ecn_opt = READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_ecn_option); 1194 1188 1195 - if (ecn_opt && tp->saw_accecn_opt && !tcp_accecn_opt_fail_send(tp) && 1189 + if (ecn_opt && tp->saw_accecn_opt && 1190 + (ecn_opt >= TCP_ACCECN_OPTION_PERSIST || 1191 + !tcp_accecn_opt_fail_send(tp)) && 1196 1192 (ecn_opt >= TCP_ACCECN_OPTION_FULL || tp->accecn_opt_demand || 1197 1193 tcp_accecn_option_beacon_check(sk))) { 1198 1194 opts->use_synack_ecn_bytes = 0; ··· 3614 3606 tcp_retrans_try_collapse(sk, skb, avail_wnd); 3615 3607 } 3616 3608 3617 - /* RFC3168, section 6.1.1.1. ECN fallback 3618 - * As AccECN uses the same SYN flags (+ AE), this check covers both 3619 - * cases. 3620 - */ 3621 - if ((TCP_SKB_CB(skb)->tcp_flags & TCPHDR_SYN_ECN) == TCPHDR_SYN_ECN) 3622 - tcp_ecn_clear_syn(sk, skb); 3609 + if (!tcp_ecn_mode_pending(tp) || icsk->icsk_retransmits > 1) { 3610 + /* RFC3168, section 6.1.1.1. ECN fallback 3611 + * As AccECN uses the same SYN flags (+ AE), this check 3612 + * covers both cases. 3613 + */ 3614 + if ((TCP_SKB_CB(skb)->tcp_flags & TCPHDR_SYN_ECN) == 3615 + TCPHDR_SYN_ECN) 3616 + tcp_ecn_clear_syn(sk, skb); 3617 + } 3623 3618 3624 3619 /* Update global and local TCP statistics. */ 3625 3620 segs = tcp_skb_pcount(skb); ··· 3937 3926 3938 3927 switch (synack_type) { 3939 3928 case TCP_SYNACK_NORMAL: 3929 + case TCP_SYNACK_RETRANS: 3940 3930 skb_set_owner_edemux(skb, req_to_sk(req)); 3941 3931 break; 3942 3932 case TCP_SYNACK_COOKIE: ··· 4020 4008 memset(th, 0, sizeof(struct tcphdr)); 4021 4009 th->syn = 1; 4022 4010 th->ack = 1; 4023 - tcp_ecn_make_synack(req, th); 4011 + tcp_ecn_make_synack(req, th, synack_type); 4024 4012 th->source = htons(ireq->ir_num); 4025 4013 th->dest = ireq->ir_rmt_port; 4026 4014 skb->mark = ireq->ir_mark; ··· 4623 4611 /* Paired with WRITE_ONCE() in sock_setsockopt() */ 4624 4612 if (READ_ONCE(sk->sk_txrehash) == SOCK_TXREHASH_ENABLED) 4625 4613 WRITE_ONCE(tcp_rsk(req)->txhash, net_tx_rndhash()); 4626 - res = af_ops->send_synack(sk, NULL, &fl, req, NULL, TCP_SYNACK_NORMAL, 4614 + res = af_ops->send_synack(sk, NULL, &fl, req, NULL, TCP_SYNACK_RETRANS, 4627 4615 NULL); 4628 4616 if (!res) { 4629 4617 TCP_INC_STATS(sock_net(sk), TCP_MIB_RETRANSSEGS);
+3
net/ipv4/tcp_timer.c
··· 22 22 #include <linux/module.h> 23 23 #include <linux/gfp.h> 24 24 #include <net/tcp.h> 25 + #include <net/tcp_ecn.h> 25 26 #include <net/rstreason.h> 26 27 27 28 static u32 tcp_clamp_rto_to_user_timeout(const struct sock *sk) ··· 480 479 * it's not good to give up too easily. 481 480 */ 482 481 tcp_rtx_synack(sk, req); 482 + if (req->num_retrans > 1 && tcp_rsk(req)->accecn_ok) 483 + tcp_rsk(req)->accecn_fail_mode |= TCP_ACCECN_ACE_FAIL_SEND; 483 484 req->num_timeout++; 484 485 tcp_update_rto_stats(sk); 485 486 if (!tp->retrans_stamp)
+58 -23
tools/testing/selftests/drivers/net/gro.c
··· 17 17 * Pure ACK does not coalesce. 18 18 * 19 19 * flags_*: 20 - * No packets with PSH, SYN, URG, RST set will be coalesced. 21 - * - flags_psh, flags_syn, flags_rst, flags_urg 20 + * No packets with PSH, SYN, URG, RST, CWR set will be coalesced. 21 + * - flags_psh, flags_syn, flags_rst, flags_urg, flags_cwr 22 22 * 23 23 * tcp_*: 24 24 * Packets with incorrect checksum, non-consecutive seqno and ··· 360 360 fill_datalinklayer(buf); 361 361 } 362 362 363 - /* send one extra flag, not first and not last pkt */ 364 - static void send_flags(int fd, struct sockaddr_ll *daddr, int psh, int syn, 365 - int rst, int urg) 363 + #ifndef TH_CWR 364 + #define TH_CWR 0x80 365 + #endif 366 + static void set_flags(struct tcphdr *tcph, int payload_len, int psh, int syn, 367 + int rst, int urg, int cwr) 366 368 { 367 - static char flag_buf[MAX_HDR_LEN + PAYLOAD_LEN]; 368 - static char buf[MAX_HDR_LEN + PAYLOAD_LEN]; 369 - int payload_len, pkt_size, flag, i; 370 - struct tcphdr *tcph; 371 - 372 - payload_len = PAYLOAD_LEN * psh; 373 - pkt_size = total_hdr_len + payload_len; 374 - flag = NUM_PACKETS / 2; 375 - 376 - create_packet(flag_buf, flag * payload_len, 0, payload_len, 0); 377 - 378 - tcph = (struct tcphdr *)(flag_buf + tcp_offset); 379 369 tcph->psh = psh; 380 370 tcph->syn = syn; 381 371 tcph->rst = rst; 382 372 tcph->urg = urg; 373 + if (cwr) 374 + tcph->th_flags |= TH_CWR; 375 + else 376 + tcph->th_flags &= ~TH_CWR; 383 377 tcph->check = 0; 384 378 tcph->check = tcp_checksum(tcph, payload_len); 379 + } 380 + 381 + /* send extra flags of the (NUM_PACKETS / 2) and (NUM_PACKETS / 2 - 1) 382 + * pkts, not first and not last pkt 383 + */ 384 + static void send_flags(int fd, struct sockaddr_ll *daddr, int psh, int syn, 385 + int rst, int urg, int cwr) 386 + { 387 + static char flag_buf[2][MAX_HDR_LEN + PAYLOAD_LEN]; 388 + static char buf[MAX_HDR_LEN + PAYLOAD_LEN]; 389 + int payload_len, pkt_size, i; 390 + struct tcphdr *tcph; 391 + int flag[2]; 392 + 393 + payload_len = PAYLOAD_LEN * (psh || cwr); 394 + pkt_size = total_hdr_len + payload_len; 395 + flag[0] = NUM_PACKETS / 2; 396 + flag[1] = NUM_PACKETS / 2 - 1; 397 + 398 + /* Create and configure packets with flags 399 + */ 400 + for (i = 0; i < 2; i++) { 401 + if (flag[i] > 0) { 402 + create_packet(flag_buf[i], flag[i] * payload_len, 0, 403 + payload_len, 0); 404 + tcph = (struct tcphdr *)(flag_buf[i] + tcp_offset); 405 + set_flags(tcph, payload_len, psh, syn, rst, urg, cwr); 406 + } 407 + } 385 408 386 409 for (i = 0; i < NUM_PACKETS + 1; i++) { 387 - if (i == flag) { 388 - write_packet(fd, flag_buf, pkt_size, daddr); 410 + if (i == flag[0]) { 411 + write_packet(fd, flag_buf[0], pkt_size, daddr); 412 + continue; 413 + } else if (i == flag[1] && cwr) { 414 + write_packet(fd, flag_buf[1], pkt_size, daddr); 389 415 continue; 390 416 } 391 417 create_packet(buf, i * PAYLOAD_LEN, 0, PAYLOAD_LEN, 0); ··· 1094 1068 1095 1069 /* flags sub-tests */ 1096 1070 } else if (strcmp(testname, "flags_psh") == 0) { 1097 - send_flags(txfd, &daddr, 1, 0, 0, 0); 1071 + send_flags(txfd, &daddr, 1, 0, 0, 0, 0); 1098 1072 write_packet(txfd, fin_pkt, total_hdr_len, &daddr); 1099 1073 } else if (strcmp(testname, "flags_syn") == 0) { 1100 - send_flags(txfd, &daddr, 0, 1, 0, 0); 1074 + send_flags(txfd, &daddr, 0, 1, 0, 0, 0); 1101 1075 write_packet(txfd, fin_pkt, total_hdr_len, &daddr); 1102 1076 } else if (strcmp(testname, "flags_rst") == 0) { 1103 - send_flags(txfd, &daddr, 0, 0, 1, 0); 1077 + send_flags(txfd, &daddr, 0, 0, 1, 0, 0); 1104 1078 write_packet(txfd, fin_pkt, total_hdr_len, &daddr); 1105 1079 } else if (strcmp(testname, "flags_urg") == 0) { 1106 - send_flags(txfd, &daddr, 0, 0, 0, 1); 1080 + send_flags(txfd, &daddr, 0, 0, 0, 1, 0); 1081 + write_packet(txfd, fin_pkt, total_hdr_len, &daddr); 1082 + } else if (strcmp(testname, "flags_cwr") == 0) { 1083 + send_flags(txfd, &daddr, 0, 0, 0, 0, 1); 1107 1084 write_packet(txfd, fin_pkt, total_hdr_len, &daddr); 1108 1085 1109 1086 /* tcp sub-tests */ ··· 1267 1238 correct_payload[1] = 0; 1268 1239 correct_payload[2] = PAYLOAD_LEN * 2; 1269 1240 printf("urg flag ends coalescing: "); 1241 + check_recv_pkts(rxfd, correct_payload, 3); 1242 + } else if (strcmp(testname, "flags_cwr") == 0) { 1243 + correct_payload[0] = PAYLOAD_LEN; 1244 + correct_payload[1] = PAYLOAD_LEN * 2; 1245 + correct_payload[2] = PAYLOAD_LEN * 2; 1246 + printf("cwr flag ends coalescing: "); 1270 1247 check_recv_pkts(rxfd, correct_payload, 3); 1271 1248 1272 1249 /* tcp sub-tests */
+2 -1
tools/testing/selftests/drivers/net/gro.py
··· 17 17 - flags_syn: Packets with SYN flag don't coalesce 18 18 - flags_rst: Packets with RST flag don't coalesce 19 19 - flags_urg: Packets with URG flag don't coalesce 20 + - flags_cwr: Packets with CWR flag don't coalesce 20 21 - tcp_csum: Packets with incorrect checksum don't coalesce 21 22 - tcp_seq: Packets with non-consecutive seqno don't coalesce 22 23 - tcp_ts: Packets with different timestamp options don't coalesce ··· 192 191 common_tests = [ 193 192 "data_same", "data_lrg_sml", "data_sml_lrg", 194 193 "ack", 195 - "flags_psh", "flags_syn", "flags_rst", "flags_urg", 194 + "flags_psh", "flags_syn", "flags_rst", "flags_urg", "flags_cwr", 196 195 "tcp_csum", "tcp_seq", "tcp_ts", "tcp_opt", 197 196 "ip_ecn", "ip_tos", 198 197 "large_max", "large_rem",
+24
tools/testing/selftests/net/packetdrill/tcp_accecn_2nd_data_as_first.pkt
··· 1 + // 3rd ACK + 1st data segment lost, data segments with ce 2 + 3 + `./defaults.sh 4 + sysctl -q net.ipv4.tcp_ecn=3 5 + ` 6 + 7 + 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3 8 + +0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0 9 + +0 bind(3, ..., ...) = 0 10 + +0 listen(3, 1) = 0 11 + 12 + +0.05 < SEWA 0:0(0) win 32767 <mss 1460,nop,nop,sackOK,nop,wscale 8> 13 + +.002 > SW. 0:0(0) ack 1 <mss 1460,ECN e1b 1 ceb 0 e0b 1,nop,nop,nop,sackOK,nop,wscale 8> 14 + // 3rd ACK lost 15 + // 1st data segment lost 16 + +0.05 < [ce] EAP. 1001:2001(1000) ack 1 win 264 <ECN e0b 1 ceb 0 e1b 1,nop> 17 + +.002 > [ect0] WA. 1:1(0) ack 1 <ECN e1b 1 ceb 1000 e0b 1,nop,nop,nop,sack 1001:2001> 18 + +.002 accept(3, ..., ...) = 4 19 + 20 + +0.2 < [ce] EAP. 1:1001(1000) ack 1 win 264 <ECN e0b 1 ceb 0 e1b 1,nop> 21 + +.001 > [ect0] EWA. 1:1(0) ack 2001 <ECN e1b 1 ceb 2000 e0b 1,nop> 22 + 23 + +0.05 < [ce] EAP. 2001:3001(1000) ack 1 win 264 24 + +.001 > [ect0] . 1:1(0) ack 3001 <ECN e1b 1 ceb 3000 e0b 1,nop>
+30
tools/testing/selftests/net/packetdrill/tcp_accecn_2nd_data_as_first_connect.pkt
··· 1 + // 3rd ACK + 1st data segment lost, 2nd data segments with ce 2 + 3 + `./defaults.sh 4 + sysctl -q net.ipv4.tcp_ecn=3 5 + ` 6 + 7 + 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 4 8 + +.002 ... 0.052 connect(4, ..., ...) = 0 9 + 10 + +.002 > [noecn] SEWA 0:0(0) <mss 1460,sackOK,TS val 100 ecr 0,nop,wscale 8> 11 + +0.05 < [noecn] SW. 0:0(0) ack 1 win 32767 <mss 1016,ECN e0b 1 ceb 0 e1b 1,nop,nop,nop,sackOK,nop,wscale 8> 12 + // 3rd ACK lost 13 + +.002 > [ect0] W. 1:1(0) ack 1 <ECN e1b 1 ceb 0 e0b 1,nop> 14 + 15 + +0.01 write(4, ..., 2000) = 2000 16 + // 1st data segment lost + 2nd gets CE 17 + +.002 > [ect0] .5 1:1005(1004) ack 1 <ECN e1b 1 ceb 0 e0b 1,nop> 18 + +.000 > [ect0] P.5 1005:2001(996) ack 1 <ECN e1b 1 ceb 0 e0b 1, nop> 19 + +0.05 < [ect0] .6 1:1(0) ack 1 win 264 <ECN e0b 1 ceb 996 e1b 1,nop,nop,nop,sack 1005:2001> 20 + 21 + +0.01 %{ assert tcpi_delivered_ce == 1, tcpi_delivered_ce }% 22 + 23 + +0.002~+0.1 > [ect0] .5 1:1005(1004) ack 1 <ECN e1b 1 ceb 0 e0b 1,nop> 24 + +.05 < [ect0] .6 1:1(0) ack 2001 win 264 <ECN e0b 1005 ceb 996 e1b 1,nop> 25 + 26 + +0.01 write(4, ..., 1000) = 1000 27 + +0~+0.002 > [ect0] P.5 2001:3001(1000) ack 1 <ECN e1b 1 ceb 0 e0b 1,nop> 28 + 29 + +0.1 < [ect0] .5 1:1001(1000) ack 3001 win 264 <ECN e0b 1 ceb 0 e1b 1,nop> 30 + +0~+0.01 > [ect0] .5 3001:3001(0) ack 1001 <ECN e1b 1 ceb 0 e0b 1001,nop>
+19
tools/testing/selftests/net/packetdrill/tcp_accecn_3rd_ack_after_synack_rxmt.pkt
··· 1 + // Test 3rd ACK flags when SYN-ACK is rexmitted 2 + 3 + `./defaults.sh 4 + sysctl -q net.ipv4.tcp_ecn=3 5 + ` 6 + 7 + 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 4 8 + +.002 ... 0.052 connect(4, ..., ...) = 0 9 + 10 + +.002 > [noecn] SEWA 0:0(0) <mss 1460,sackOK,TS val 100 ecr 0,nop,wscale 8> 11 + +0.05 < [noecn] SW. 0:0(0) ack 1 win 32767 <mss 1460,ECN e0b 1 ceb 0 e1b 1,nop,nop,nop,sackOK,nop,wscale 8> 12 + +.002 > [ect0] W. 1:1(0) ack 1 <ECN e1b 1 ceb 0 e0b 1,nop> 13 + 14 + +0.1 < [ect0] S. 0:0(0) ack 1 win 32767 <mss 1460,nop,nop,sackOK,nop,wscale 8> 15 + 16 + // Our code currently sends a challenge ACK 17 + // when it receives a SYN in ESTABLISHED state 18 + // based on the latest SYN 19 + +.002 > [ect0] A. 1:1(0) ack 1 <ECN e1b 1 ceb 0 e0b 1,nop>
+18
tools/testing/selftests/net/packetdrill/tcp_accecn_3rd_ack_ce_updates_received_ce.pkt
··· 1 + // Third ACK CE increases r.cep 2 + 3 + `./defaults.sh 4 + sysctl -q net.ipv4.tcp_ecn=3 5 + ` 6 + 7 + 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3 8 + +0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0 9 + +0 bind(3, ..., ...) = 0 10 + +0 listen(3, 1) = 0 11 + 12 + +0.05 < SEWA 0:0(0) win 32767 <mss 1050,nop,nop,sackOK,nop,wscale 8> 13 + +.002 > SW. 0:0(0) ack 1 <mss 1460,ECN e1b 1 ceb 0 e0b 1,nop,nop,nop,sackOK,nop,wscale 8> 14 + +0.05 < [ce] W. 1:1(0) ack 1 win 264 <ECN e0b 1 ceb 0 e1b 1,nop> 15 + +.002 accept(3, ..., ...) = 4 16 + 17 + +0.01 write(4, ..., 1000) = 1000 18 + +.002 > [ect0] WAP. 1:1001(1000) ack 1 <ECN e1b 1 ceb 0 e0b 1,nop>
+22
tools/testing/selftests/net/packetdrill/tcp_accecn_3rd_ack_lost_data_ce.pkt
··· 1 + // 3rd ACK lost, CE for the first data segment 2 + 3 + `./defaults.sh 4 + sysctl -q net.ipv4.tcp_ecn=3 5 + ` 6 + 7 + 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3 8 + +0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0 9 + +0 bind(3, ..., ...) = 0 10 + +0 listen(3, 1) = 0 11 + 12 + +0.05 < SEWA 0:0(0) win 32767 <mss 1050,nop,nop,sackOK,nop,wscale 8> 13 + +.002 > SW. 0:0(0) ack 1 <mss 1460,ECN e1b 1 ceb 0 e0b 1,nop,nop,nop,sackOK,nop,wscale 8> 14 + // 3rd ACK lost 15 + +0.05 < [ce] EAP. 1:1001(1000) ack 1 win 264 <ECN e0b 1 ceb 0 e1b 1,nop> 16 + +.002 > [ect0] WA. 1:1(0) ack 1001 <ECN e1b 1 ceb 1000 e0b 1,nop> 17 + +.002 accept(3, ..., ...) = 4 18 + 19 + +0.01 %{ assert tcpi_delivered_ce == 0, tcpi_delivered_ce }% 20 + 21 + +0.05 < [ce] EAP. 1001:2001(1000) ack 1 win 264 <ECN e0b 1 ceb 0 e1b 1,nop> 22 + +.001 > [ect0] EWA. 1:1(0) ack 2001 <ECN e1b 1 ceb 2000 e0b 1 ,nop>
+26
tools/testing/selftests/net/packetdrill/tcp_accecn_3rd_dups.pkt
··· 1 + // Test SYN/ACK rexmit triggered 3rd ACK duplicate + CE on first data seg 2 + 3 + `./defaults.sh 4 + sysctl -q net.ipv4.tcp_ecn=3 5 + ` 6 + 7 + 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3 8 + +0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0 9 + +0 bind(3, ..., ...) = 0 10 + +0 listen(3, 1) = 0 11 + 12 + +0 < SEWA 0:0(0) win 32792 <mss 1050,nop,nop,sackOK,nop,wscale 8> 13 + +.002 > SW. 0:0(0) ack 1 <mss 1460,ECN e1b 1 ceb 0 e0b 1,nop,nop,nop,sackOK,nop,wscale 8> 14 + 15 + // SYN/ACK rexmitted => two 3rd ACKs in-flight 16 + +1.0~+1.1 > SW. 0:0(0) ack 1 <mss 1460,nop,nop,sackOK,nop,wscale 8> 17 + // Delivered 1st 3rd ACK 18 + +0.05 < [ect0] W. 1:1(0) ack 1 win 257 <ECN e0b 1 ceb 0 e1b 1,nop> 19 + +.002 accept(3, ..., ...) = 4 20 + 21 + // Duplicate 3rd ACK delivered 22 + +1.05 < [ect0] W. 1:1(0) ack 1 win 257 <ECN e0b 1 ceb 0 e1b 1,nop> 23 + 24 + +0.05 < [ce] EAP. 1:1001(1000) ack 1 win 257 <ECN e0b 1 ceb 0 e1b 1,nop> 25 + +.002 > [ect0] WA. 1:1(0) ack 1001 <ECN e1b 1 ceb 1000 e0b 1,nop> 26 + +0 read(4, ..., 1000) = 1000
+13
tools/testing/selftests/net/packetdrill/tcp_accecn_acc_ecn_disabled.pkt
··· 1 + // Test that when accurate ECN is disabled, 2 + // client uses RFC3168 ECN for SYN 3 + 4 + `./defaults.sh 5 + sysctl -q net.ipv4.tcp_ecn=1 6 + ` 7 + 8 + 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 4 9 + +.002 ... 0.052 connect(4, ..., ...) = 0 10 + 11 + +.002 > [noecn] SEW 0:0(0) <mss 1460,sackOK,TS val 100 ecr 0,nop,wscale 8> 12 + +0.05 < [noecn] S. 0:0(0) ack 1 win 32767 <mss 1460,sackOK,nop,nop,nop,wscale 8> 13 + +.002 > [noecn] . 1:1(0) ack 1
+28
tools/testing/selftests/net/packetdrill/tcp_accecn_accecn_then_notecn_syn.pkt
··· 1 + // Test that SYN-ACK with ACE flags and without 2 + // ACE flags got dropped. Although we disable ECN, 3 + // we shouldn't consider this as blackholed as 4 + // these are dropped due to congestion 5 + 6 + `./defaults.sh 7 + sysctl -q net.ipv4.tcp_ecn=3 8 + sysctl -q net.ipv4.tcp_ecn_option=2 9 + ` 10 + 11 + +0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3 12 + +0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0 13 + +0 bind(3, ..., ...) = 0 14 + +0 listen(3, 1) = 0 15 + 16 + +0 < [ect0] SEWA 0:0(0) win 32792 <mss 1460,nop,nop,sackOK,nop,wscale 8> 17 + +.002 > [noecn] SA. 0:0(0) ack 1 <mss 1460,ECN e1b 1 ceb 0 e0b 1,nop,nop,nop,sackOK,nop,wscale 8> 18 + 19 + // Retransmit SYN 20 + +0.1 < [noecn] S 0:0(0) win 32792 <mss 1460,nop,nop,sackOK,nop,wscale 8> 21 + +.002 > [noecn] SW. 0:0(0) ack 1 <mss 1460,nop,nop,sackOK,nop,wscale 8> 22 + 23 + +0.1 < [noecn] W. 1:1(0) ack 1 win 320 <ECN e0b 1 ceb 0 e1b 1,nop> 24 + +.002 accept(3, ..., ...) = 4 25 + 26 + // Write with AccECN option but with ip-noecn since we received one SYN with ACE=0 27 + +0.01 write(4, ..., 100) = 100 28 + +.002 > [noecn] P5. 1:101(100) ack 1 <ECN e1b 1 ceb 0 e0b 1,nop>
+18
tools/testing/selftests/net/packetdrill/tcp_accecn_accecn_to_rfc3168.pkt
··· 1 + // Test AccECN -> RFC3168 fallback when sysctl asks for RFC3168 ECN 2 + 3 + `./defaults.sh 4 + sysctl -q net.ipv4.tcp_ecn=1 5 + ` 6 + 7 + 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3 8 + +0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0 9 + +0 bind(3, ..., ...) = 0 10 + +0 listen(3, 1) = 0 11 + 12 + +0 < SEWA 0:0(0) win 32792 <mss 1050,nop,nop,sackOK,nop,wscale 8> 13 + +.002 > SE. 0:0(0) ack 1 <mss 1460,nop,nop,sackOK,nop,wscale 8> 14 + +0.05 < . 1:1(0) ack 1 win 320 15 + +.002 accept(3, ..., ...) = 4 16 + 17 + +0.01 write(4, ..., 1000) = 1000 18 + +.002 > [ect0] P. 1:1001(1000) ack 1
+34
tools/testing/selftests/net/packetdrill/tcp_accecn_client_accecn_options_drop.pkt
··· 1 + // Client negotiates AccECN and starts sending 2 + // AccECN option in last ACK and data segments 3 + // Middlebox drops AccECN option and client 4 + // reverts to ACE flags only 5 + 6 + `./defaults.sh 7 + sysctl -q net.ipv4.tcp_ecn=3 8 + sysctl -q net.ipv4.tcp_ecn_option=2 9 + sysctl -q net.ipv4.tcp_ecn_option_beacon=1 10 + ` 11 + 12 + 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3 13 + +0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0 14 + +0 bind(3, ..., ...) = 0 15 + +0 listen(3, 1) = 0 16 + 17 + +0 < SEWA 0:0(0) win 32792 <mss 1050,nop,nop,sackOK,nop,wscale 8> 18 + +.002 > SW. 0:0(0) ack 1 <mss 1460,ECN e1b 1 ceb 0 e0b 1,nop,nop,nop,sackOK,nop,wscale 8> 19 + +0.05 < [ect0] W. 1:1(0) ack 1 win 257 <ECN e0b 1 ceb 0 e1b 1,nop> 20 + +.002 accept(3, ..., ...) = 4 21 + 22 + +0.05 < [ect0] EAP. 1:1001(1000) ack 1 win 257 <ECN e0b 1 ceb 0 e1b 1,nop> 23 + +.002 > [ect0] EA. 1:1(0) ack 1001 <ECN e1b 1 ceb 0 e0b 1001,nop> 24 + +0 read(4, ..., 1000) = 1000 25 + 26 + +0.05 < [ect0] EAP. 1:1001(1000) ack 1 win 257 <ECN e0b 1 ceb 0 e1b 1,nop> 27 + +.002 > [ect0] EA. 1:1(0) ack 1001 <ECN e1b 1 ceb 0 e0b 2001,nop,nop,nop,sack 1:1001> 28 + 29 + +0.05 < [ect0] EAP. 1:1001(1000) ack 1 win 257 <ECN e0b 1 ceb 0 e1b 1,nop> 30 + +.002 > [ect0] EA. 1:1(0) ack 1001 <nop,nop,sack 1:1001> 31 + 32 + +0.05 < [ect0] EAP. 1001:2001(1000) ack 1 win 257 <ECN e0b 1 ceb 0 e1b 1,nop> 33 + +.002 > [ect0] EA. 1:1(0) ack 2001 34 + +0 read(4, ..., 1000) = 1000
+38
tools/testing/selftests/net/packetdrill/tcp_accecn_client_accecn_options_lost.pkt
··· 1 + // Client negotiates AccECN and starts sending 2 + // AccECN option in last ACK and data segments 3 + // Middlebox accepts AccECN option but some packets 4 + // are lost due to congestion. Client should 5 + // continue to send AccECN option 6 + 7 + `./defaults.sh 8 + sysctl -q net.ipv4.tcp_ecn=3 9 + sysctl -q net.ipv4.tcp_ecn_option=2 10 + ` 11 + 12 + +0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 4 13 + +.002 ... 0.102 connect(4, ..., ...) = 0 14 + 15 + +.002 > [noecn] SEWA 0:0(0) <mss 1460,sackOK,TS val 100 ecr 0,nop,wscale 8> 16 + +0.1 < [ect0] SW. 0:0(0) ack 1 win 32767 <mss 1024,ECN e0b 1 ceb 0 e1b 1,nop,nop,nop,sackOK,nop,wscale 8> 17 + +.002 > [ect0] A. 1:1(0) ack 1 <ECN e1b 1 ceb 0 e0b 1,nop> 18 + 19 + // Send 20 + +0.01 write(4, ..., 3000) = 3000 21 + +.002 > [ect0] .5 1:1013(1012) ack 1 <ECN e1b 1 ceb 0 e0b 1,nop> 22 + +.002 > [ect0] P.5 1013:2025(1012) ack 1 <ECN e1b 1 ceb 0 e0b 1,nop> 23 + +.002 > [ect0] P.5 2025:3001(976) ack 1 <ECN e1b 1 ceb 0 e0b 1,nop> 24 + 25 + // First two segments were lost due to congestion as SACK was 26 + // received acknowledging 3rd segment 27 + +0.1 < [ect0] .5 1:1(0) ack 1 win 264 <ECN e1b 1 ceb 0 e0b 977,nop,nop,nop,sack 2025:3001> 28 + 29 + // Since data with option was SACKed, we can 30 + // continue to use AccECN option for the rest of 31 + // the connection. This one is a rexmt 32 + +.02~+0.5 > [ect0] .5 1:1013(1012) ack 1 <ECN e1b 1 ceb 0 e0b 1,nop> 33 + +0.1 < [ect0] .5 1:1(0) ack 3001 win 264 <ECN e1b 1 ceb 0 e0b 3000,nop> 34 + 35 + // Send new data, it should contain AccECN option 36 + +0.01 write(4, ..., 2000) = 2000 37 + +.002 > [ect0] .5 3001:4013(1012) ack 1 <ECN e1b 1 ceb 0 e0b 1,nop> 38 + +.002 > [ect0] P.5 4013:5001(988) ack 1 <ECN e1b 1 ceb 0 e0b 1,nop>
+12
tools/testing/selftests/net/packetdrill/tcp_accecn_clientside_disabled.pkt
··· 1 + // AccECN sysctl server-side only, no ECN/AccECN 2 + 3 + `./defaults.sh 4 + sysctl -q net.ipv4.tcp_ecn=5 5 + ` 6 + 7 + 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 4 8 + +.002 ... 0.052 connect(4, ..., ...) = 0 9 + 10 + +.002 > S 0:0(0) <mss 1460,sackOK,TS val 100 ecr 0,nop,wscale 8> 11 + +0.05 < S. 0:0(0) ack 1 win 32767 <mss 1460,sackOK,nop,nop,nop,wscale 8> 12 + +.002 > . 1:1(0) ack 1
+25
tools/testing/selftests/net/packetdrill/tcp_accecn_close_local_close_then_remote_fin.pkt
··· 1 + // Test basic connection teardown where local process closes first: 2 + // the local process calls close() first, so we send a FIN, and receive an ACK. 3 + // Then we receive a FIN and ACK it. 4 + 5 + `./defaults.sh 6 + sysctl -q net.ipv4.tcp_ecn=3 7 + sysctl -q net.ipv4.tcp_ecn_option=0 8 + ` 9 + 10 + 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3 11 + +.01...0.011 connect(3, ..., ...) = 0 12 + +0 > [noecn] SEWA 0:0(0) <...> 13 + +0 < [ect1] SW. 0:0(0) ack 1 win 32768 <mss 1000,nop,wscale 6,nop,nop,sackOK> 14 + +0 > [ect0] EW. 1:1(0) ack 1 15 + 16 + +0 write(3, ..., 1000) = 1000 17 + +0 > [ect0] P5. 1:1001(1000) ack 1 18 + +0 < [ect0] .5 1:1(0) ack 1001 win 257 19 + 20 + +0 close(3) = 0 21 + +0 > [ect0] F5. 1001:1001(0) ack 1 22 + +0 < [ect0] .5 1:1(0) ack 1002 win 257 23 + 24 + +0 < [ect0] F5. 1:1(0) ack 1002 win 257 25 + +0 > [ect0] . 1002:1002(0) ack 2
+25
tools/testing/selftests/net/packetdrill/tcp_accecn_delivered_2ndlargeack.pkt
··· 1 + // Test a large ACK (> ACE field max) 2 + 3 + `./defaults.sh 4 + sysctl -q net.ipv4.tcp_ecn=3 5 + sysctl -q net.ipv4.tcp_ecn_option=0 6 + ` 7 + 8 + 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3 9 + +0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0 10 + +0 bind(3, ..., ...) = 0 11 + +0 listen(3, 1) = 0 12 + 13 + +0 < SEWA 0:0(0) win 32792 <mss 1460,nop,nop,sackOK,nop,wscale 8> 14 + +.002 > SW. 0:0(0) ack 1 <mss 1460,nop,nop,sackOK,nop,wscale 8> 15 + +0.05 < [ect0] W. 1:1(0) ack 1 win 264 16 + +.002 accept(3, ..., ...) = 4 17 + 18 + +0.01 %{ assert tcpi_delivered_ce == 0, tcpi_delivered_ce }% 19 + 20 + +0.01 write(4, ..., 14600) = 14600 21 + +.002 > [ect0] P.5 1:14601(14600) ack 1 22 + +0.05 < [ect0] .5 1:1(0) ack 1461 win 264 23 + +0.05 < [ect0] .5 1:1(0) ack 14601 win 264 24 + 25 + +0.01 %{ assert tcpi_delivered_ce == 8, tcpi_delivered_ce }%
+31
tools/testing/selftests/net/packetdrill/tcp_accecn_delivered_falseoverflow_detect.pkt
··· 1 + // Test false overflow detection with option used to rule out overflow 2 + 3 + `./defaults.sh 4 + sysctl -q net.ipv4.tcp_ecn=3 5 + ` 6 + 7 + 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3 8 + +0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0 9 + +0 bind(3, ..., ...) = 0 10 + +0 listen(3, 1) = 0 11 + 12 + +0 < SEWA 0:0(0) win 32792 <mss 1460,nop,nop,sackOK,nop,wscale 8> 13 + +.002 > SW. 0:0(0) ack 1 <mss 1460,ECN e1b 1 ceb 0 e0b 1,nop,nop,nop,sackOK,nop,wscale 8> 14 + +0.05 < [ect0] W. 1:1(0) ack 1 win 264 <ECN e0b 1 ceb 0 e1b 1,nop> 15 + +.002 accept(3, ..., ...) = 4 16 + 17 + +0.01 %{ assert tcpi_delivered_ce == 0, tcpi_delivered_ce }% 18 + 19 + // Stop sending option to allow easier testing 20 + +0 `sysctl -q net.ipv4.tcp_ecn_option=0` 21 + 22 + +0.002 write(4, ..., 14600) = 14600 23 + +.002 > [ect0] P.5 1:14601(14600) ack 1 24 + 25 + +0.05 < [ect0] .5 1:1(0) ack 1460 win 264 <ECN e0b 1461 ceb 0 e1b 1,nop> 26 + +0.05 < [ect0] .5 1:1(0) ack 14601 win 264 <ECN e0b 14601 ceb 0 e1b 1,nop> 27 + 28 + +0.01 %{ 29 + assert tcpi_delivered_ce == 0, tcpi_delivered_ce 30 + assert tcpi_delivered_e0_bytes == 14600, tcpi_delivered_e0_bytes 31 + }%
+24
tools/testing/selftests/net/packetdrill/tcp_accecn_delivered_largeack.pkt
··· 1 + // Test a large ACK (> ACE field max) 2 + 3 + `./defaults.sh 4 + sysctl -q net.ipv4.tcp_ecn=3 5 + sysctl -q net.ipv4.tcp_ecn_option=0 6 + ` 7 + 8 + 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3 9 + +0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0 10 + +0 bind(3, ..., ...) = 0 11 + +0 listen(3, 1) = 0 12 + 13 + +0 < SEWA 0:0(0) win 32792 <mss 1460,nop,nop,sackOK,nop,wscale 8> 14 + +.002 > SW. 0:0(0) ack 1 <mss 1460,nop,nop,sackOK,nop,wscale 8> 15 + +0.05 < [ect0] W. 1:1(0) ack 1 win 264 16 + +.002 accept(3, ..., ...) = 4 17 + 18 + +0.01 %{ assert tcpi_delivered_ce == 0, tcpi_delivered_ce }% 19 + 20 + +0.01 write(4, ..., 14600) = 14600 21 + +.002 > [ect0] P.5 1:14601(14600) ack 1 22 + +0.05 < [ect0] .5 1:1(0) ack 14601 win 264 23 + 24 + +0.01 %{ assert tcpi_delivered_ce == 0, tcpi_delivered_ce }%
+25
tools/testing/selftests/net/packetdrill/tcp_accecn_delivered_largeack2.pkt
··· 1 + // Test a large ACK (> ACE field max) 2 + 3 + `./defaults.sh 4 + sysctl -q net.ipv4.tcp_ecn=3 5 + sysctl -q net.ipv4.tcp_ecn_option=0 6 + ` 7 + 8 + 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3 9 + +0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0 10 + +0 bind(3, ..., ...) = 0 11 + +0 listen(3, 1) = 0 12 + 13 + +0 < SEWA 0:0(0) win 32792 <mss 1460,nop,nop,sackOK,nop,wscale 8> 14 + +.002 > SW. 0:0(0) ack 1 <mss 1460,nop,nop,sackOK,nop,wscale 8> 15 + +0.05 < [ect0] W. 1:1(0) ack 1 win 264 16 + +.002 accept(3, ..., ...) = 4 17 + 18 + +0.01 %{ assert tcpi_delivered_ce == 0, tcpi_delivered_ce }% 19 + 20 + +0.01 write(4, ..., 14600) = 14600 21 + +.002 > [ect0] P.5 1:14601(14600) ack 1 22 + // Fake CE 23 + +0.05 < [ect0] .6 1:1(0) ack 14601 win 264 24 + 25 + +0.01 %{ assert tcpi_delivered_ce == 1, tcpi_delivered_ce }%
+25
tools/testing/selftests/net/packetdrill/tcp_accecn_delivered_maxack.pkt
··· 1 + // Test a large ACK (at ACE field max delta) 2 + 3 + `./defaults.sh 4 + sysctl -q net.ipv4.tcp_ecn=3 5 + sysctl -q net.ipv4.tcp_ecn_option=0 6 + ` 7 + 8 + 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3 9 + +0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0 10 + +0 bind(3, ..., ...) = 0 11 + +0 listen(3, 1) = 0 12 + 13 + +0 < SEWA 0:0(0) win 32792 <mss 1460,nop,nop,sackOK,nop,wscale 8> 14 + +.002 > SW. 0:0(0) ack 1 <mss 1460,nop,nop,sackOK,nop,wscale 8> 15 + +0.05 < [ect0] W. 1:1(0) ack 1 win 264 16 + +.002 accept(3, ..., ...) = 4 17 + 18 + +0.01 %{ assert tcpi_delivered_ce == 0, tcpi_delivered_ce }% 19 + 20 + +0.01 write(4, ..., 14600) = 14600 21 + +.002 > [ect0] P.5 1:14601(14600) ack 1 22 + // Fake CE 23 + +0.05 < [ect0] .4 1:1(0) ack 14601 win 264 24 + 25 + +0.01 %{ assert tcpi_delivered_ce == 7, tcpi_delivered_ce }%
+70
tools/testing/selftests/net/packetdrill/tcp_accecn_delivered_updates.pkt
··· 1 + // Test basic AccECN CEP/CEB/E0B/E1B functionality & CEP wrapping 2 + 3 + `./defaults.sh 4 + sysctl -q net.ipv4.tcp_ecn=3 5 + ` 6 + 7 + 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3 8 + +0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0 9 + +0 bind(3, ..., ...) = 0 10 + +0 listen(3, 1) = 0 11 + 12 + +0 < SEWA 0:0(0) win 32792 <mss 1050,nop,nop,sackOK,nop,wscale 8> 13 + +.002 > SW. 0:0(0) ack 1 <mss 1460,ECN e1b 1 ceb 0 e0b 1,nop,nop,nop,sackOK,nop,wscale 8> 14 + +0.05 < [ect0] W. 1:1(0) ack 1 win 264 <ECN e0b 1 ceb 0 e1b 1,nop> 15 + +.002 accept(3, ..., ...) = 4 16 + 17 + +0.01 %{ 18 + assert tcpi_delivered_ce == 0, tcpi_delivered_ce 19 + assert tcpi_delivered_ce_bytes == 0, tcpi_delivered_ce_bytes 20 + }% 21 + 22 + +0.01 write(4, ..., 1000) = 1000 23 + +.002 > [ect0] EAP. 1:1001(1000) ack 1 <ECN e1b 1 ceb 0 e0b 1,nop> 24 + // Fake CE 25 + +0.05 < [ect0] WA. 1:1(0) ack 1001 win 264 <ECN e0b 1 ceb 1000 e1b 1,nop> 26 + 27 + +0.01 %{ 28 + assert tcpi_delivered_ce == 1, tcpi_delivered_ce 29 + assert tcpi_delivered_ce_bytes == 1000, tcpi_delivered_ce_bytes 30 + }% 31 + 32 + +0.01 write(4, ..., 1000) = 1000 33 + +.002 > [ect0] EAP. 1001:2001(1000) ack 1 <ECN e1b 1 ceb 0 e0b 1,nop> 34 + // Fake ect0 35 + +0.05 < [ect0] WA. 1:1(0) ack 2001 win 264 <ECN e0b 1001 ceb 1000 e1b 1,nop> 36 + 37 + +0.01 %{ 38 + assert tcpi_delivered_ce == 1, tcpi_delivered_ce 39 + assert tcpi_delivered_e0_bytes == 1000, tcpi_delivered_e0_bytes 40 + }% 41 + 42 + +0.01 write(4, ..., 1000) = 1000 43 + +.002 > [ect0] EAP. 2001:3001(1000) ack 1 <ECN e1b 1 ceb 0 e0b 1,nop> 44 + // Fake ce 45 + +0.05 < [ect0] EWA. 1:1(0) ack 3001 win 264 <ECN e0b 1001 ceb 2000 e1b 1,nop> 46 + 47 + +0.01 %{ 48 + assert tcpi_delivered_ce == 2, tcpi_delivered_ce 49 + assert tcpi_delivered_ce_bytes == 2000, tcpi_delivered_ce_bytes 50 + }% 51 + 52 + +0.01 write(4, ..., 1000) = 1000 53 + +.002 > [ect0] EAP. 3001:4001(1000) ack 1 <ECN e1b 1 ceb 0 e0b 1,nop> 54 + // Fake ect1 55 + +0.05 < [ect0] EWA. 1:1(0) ack 4001 win 264 <ECN e0b 1001 ceb 2000 e1b 1001,nop> 56 + 57 + +0.01 %{ 58 + assert tcpi_delivered_ce == 2, tcpi_delivered_ce 59 + assert tcpi_delivered_e1_bytes == 1000, tcpi_delivered_e1_bytes 60 + }% 61 + 62 + +0.01 write(4, ..., 1000) = 1000 63 + +.002 > [ect0] EAP. 4001:5001(1000) ack 1 <ECN e1b 1 ceb 0 e0b 1,nop> 64 + // Fake ce 65 + +0.05 < [ect0] . 1:1(0) ack 5001 win 264 <ECN e0b 1001 ceb 3000 e1b 1001,nop> 66 + 67 + +0.01 %{ 68 + assert tcpi_delivered_ce == 3, tcpi_delivered_ce 69 + assert tcpi_delivered_ce_bytes == 3000, tcpi_delivered_ce_bytes 70 + }%
+12
tools/testing/selftests/net/packetdrill/tcp_accecn_ecn3.pkt
··· 1 + // Test that tcp_ecn=4 uses RFC3168 ECN for SYN 2 + 3 + `./defaults.sh 4 + sysctl -q net.ipv4.tcp_ecn=4 5 + ` 6 + 7 + 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 4 8 + +.002 ... 0.05 connect(4, ..., ...) = 0 9 + 10 + +.002 > SEW 0:0(0) <mss 1460,sackOK,TS val 100 ecr 0,nop,wscale 8> 11 + +0.05 < S. 0:0(0) ack 1 win 32767 <mss 1460,nop,nop,sackOK,nop,wscale 8> 12 + +.002 > . 1:1(0) ack 1
+35
tools/testing/selftests/net/packetdrill/tcp_accecn_ecn_field_updates_opt.pkt
··· 1 + // Test basic AccECN CEP/CEB/E0B/E1B functionality & CEP wrapping 2 + 3 + `./defaults.sh 4 + sysctl -q net.ipv4.tcp_ecn=3 5 + ` 6 + 7 + 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3 8 + +0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0 9 + +0 bind(3, ..., ...) = 0 10 + +0 listen(3, 1) = 0 11 + 12 + +0 < SEWA 0:0(0) win 32792 <mss 1050,nop,nop,sackOK,nop,wscale 8> 13 + +.002 > SW. 0:0(0) ack 1 <mss 1460,ECN e1b 1 ceb 0 e0b 1,nop,nop,nop,sackOK,nop,wscale 8> 14 + +0.05 < [ect0] W. 1:1(0) ack 1 win 257 <ECN e0b 1 ceb 0 e1b 1,nop> 15 + +.002 accept(3, ..., ...) = 4 16 + 17 + +0.05 < [ce] EAP. 1:1001(1000) ack 1 win 257 <ECN e0b 1 ceb 0 e1b 1,nop> 18 + +.002 > [ect0] WA. 1:1(0) ack 1001 <ECN e1b 1 ceb 1000 e0b 1,nop> 19 + +0 read(4, ..., 1000) = 1000 20 + 21 + +0.05 < [ect0] EAP. 1001:2001(1000) ack 1 win 257 <ECN e0b 1 ceb 0 e1b 1,nop> 22 + +.002 > [ect0] WA. 1:1(0) ack 2001 <ECN e1b 1 ceb 1000 e0b 1001,nop> 23 + +0 read(4, ..., 1000) = 1000 24 + 25 + +0.05 < [ce] EAP. 2001:3001(1000) ack 1 win 257 <ECN e0b 1 ceb 0 e1b 1,nop> 26 + +.002 > [ect0] EWA. 1:1(0) ack 3001 <ECN e1b 1 ceb 2000 e0b 1001,nop> 27 + +0 read(4, ..., 1000) = 1000 28 + 29 + +0.05 < [ect1] EAP. 3001:4001(1000) ack 1 win 257 <ECN e0b 1 ceb 0 e1b 1,nop> 30 + +.002 > [ect0] EWA. 1:1(0) ack 4001 <ECN e1b 1001 ceb 2000 e0b 1001,nop> 31 + +0 read(4, ..., 1000) = 1000 32 + 33 + +0.05 < [ce] EAP. 4001:5001(1000) ack 1 win 257 <ECN e0b 1 ceb 0 e1b 1,nop> 34 + +.002 > [ect0] . 1:1(0) ack 5001 <ECN e1b 1001 ceb 3000 e0b 1001,nop> 35 + +0 read(4, ..., 1000) = 1000
+14
tools/testing/selftests/net/packetdrill/tcp_accecn_ipflags_drop.pkt
··· 1 + // Test IP flags drop 2 + --tolerance_usecs=50000 3 + 4 + `./defaults.sh 5 + sysctl -q net.ipv4.tcp_ecn=3 6 + ` 7 + 8 + 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 4 9 + +.002 ... 1.1 connect(4, ..., ...) = 0 10 + 11 + +.002 > SEWA 0:0(0) <mss 1460,sackOK,TS val 100 ecr 0,nop,wscale 8> 12 + +.02 ~ +1.1 > SEWA 0:0(0) <mss 1460,sackOK,TS val 100 ecr 0,nop,wscale 8> 13 + +0.05 < S. 0:0(0) ack 1 win 32767 <mss 1460,nop,nop,sackOK,nop,wscale 8> 14 + +.002 > [noecn] . 1:1(0) ack 1
+16
tools/testing/selftests/net/packetdrill/tcp_accecn_listen_opt_drop.pkt
··· 1 + // SYN/ACK option drop test 2 + 3 + `./defaults.sh 4 + sysctl -q net.ipv4.tcp_ecn=3 5 + ` 6 + 7 + 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3 8 + +0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0 9 + +0 bind(3, ..., ...) = 0 10 + +0 listen(3, 1) = 0 11 + 12 + +0 < SEWA 0:0(0) win 32792 <mss 1050,nop,nop,sackOK,nop,wscale 8> 13 + +.002 > SW. 0:0(0) ack 1 <mss 1460,ECN e1b 1 ceb 0 e0b 1,nop,nop,nop,sackOK,nop,wscale 8> 14 + +.02 ~+2 > SW. 0:0(0) ack 1 <mss 1460,nop,nop,sackOK,nop,wscale 8> 15 + +.02 ~+5 > S. 0:0(0) ack 1 <mss 1460,nop,nop,sackOK,nop,wscale 8> 16 + +.02 ~+8 > S. 0:0(0) ack 1 <mss 1460,nop,nop,sackOK,nop,wscale 8>
+28
tools/testing/selftests/net/packetdrill/tcp_accecn_multiple_syn_ack_drop.pkt
··· 1 + // Test that SYN-ACK with ACE flags and without 2 + // ACE flags got dropped. Although we disable ECN, 3 + // we shouldn't consider this as blackholed as 4 + // these are dropped due to congestion 5 + 6 + `./defaults.sh 7 + sysctl -q net.ipv4.tcp_ecn=3 8 + sysctl -q net.ipv4.tcp_ecn_option=2 9 + ` 10 + 11 + +0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3 12 + +0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0 13 + +0 bind(3, ..., ...) = 0 14 + +0 listen(3, 1) = 0 15 + 16 + +0 < [noecn] SEWA 0:0(0) win 32792 <mss 1460,nop,nop,sackOK,nop,wscale 8> 17 + +.002 > [noecn] SW. 0:0(0) ack 1 <mss 1460,ECN e1b 1 ceb 0 e0b 1,nop,nop,nop,sackOK,nop,wscale 8> 18 + 19 + // Retransmit SYN-ACK without option 20 + +1~+1.1 > [noecn] SW. 0:0(0) ack 1 <mss 1460,nop,nop,sackOK,nop,wscale 8> 21 + 22 + // SYN-ACK maybe getting blackholed, disable ECN 23 + +2~+2.2 > [noecn] S. 0:0(0) ack 1 <mss 1460,nop,nop,sackOK,nop,wscale 8> 24 + +4~+4.4 > [noecn] S. 0:0(0) ack 1 <mss 1460,nop,nop,sackOK,nop,wscale 8> 25 + 26 + // Received an ACK after sending 3rd retransmission, not a blackhole 27 + +0.1 < [noecn] . 1:1(0) ack 1 win 320 28 + +.002 accept(3, ..., ...) = 4
+18
tools/testing/selftests/net/packetdrill/tcp_accecn_multiple_syn_drop.pkt
··· 1 + // Test that SYN with ACE flags and without 2 + // ACE flags got dropped. Although we disable 3 + // ECN, we shouldn't consider this as blackholed 4 + // as these are dropped due to congestion 5 + 6 + `./defaults.sh 7 + sysctl -q net.ipv4.tcp_ecn=3 8 + ` 9 + 10 + 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 4 11 + +.002 ... 3.1 connect(4, ..., ...) = 0 12 + 13 + +.002 > [noecn] SEWA 0:0(0) <mss 1460,sackOK,TS val 100 ecr 0,nop,wscale 8> 14 + +.02~+1.1 > [noecn] SEWA 0:0(0) <mss 1460,sackOK,TS val 100 ecr 0,nop,wscale 8> 15 + +.02~+1.1 > [noecn] S 0:0(0) <mss 1460,sackOK,TS val 100 ecr 0,nop,wscale 8> 16 + +.02~+1.1 > [noecn] S 0:0(0) <mss 1460,sackOK,TS val 100 ecr 0,nop,wscale 8> 17 + +0.1 < [noecn] S. 0:0(0) ack 1 win 32767 <mss 1460,nop,nop,sackOK,nop,wscale 8> 18 + +0~+0.01 > [noecn] . 1:1(0) ack 1
+23
tools/testing/selftests/net/packetdrill/tcp_accecn_negotiation_bleach.pkt
··· 1 + // Test AccECN flags bleach 2 + 3 + `./defaults.sh 4 + sysctl -q net.ipv4.tcp_ecn=3 5 + ` 6 + 7 + 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3 8 + +0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0 9 + +0 bind(3, ..., ...) = 0 10 + +0 listen(3, 1) = 0 11 + 12 + +0 < SEWA 0:0(0) win 32792 <mss 1050,nop,nop,sackOK,nop,wscale 8> 13 + +.002 > SW. 0:0(0) ack 1 <mss 1460,ECN e1b 1 ceb 0 e0b 1,nop,nop,nop,sackOK,nop,wscale 8> 14 + +0.05 < [ect0] . 1:1(0) ack 1 win 320 <ECN e0b 1 ceb 0 e1b 1,nop> 15 + +.002 accept(3, ..., ...) = 4 16 + 17 + +0.01 %{ assert tcpi_delivered_ce == 0, tcpi_delivered_ce }% 18 + 19 + +0.01 write(4, ..., 1000) = 1000 20 + +.002 > [noecn] EAP. 1:1001(1000) ack 1 <ECN e1b 1 ceb 0 e0b 1,nop> 21 + +0.05 < [ect0] EAP. 1:1(0) ack 1001 win 320 22 + 23 + +0.01 %{ assert tcpi_delivered_ce == 0, tcpi_delivered_ce }%
+23
tools/testing/selftests/net/packetdrill/tcp_accecn_negotiation_connect.pkt
··· 1 + // Test basic AccECN negotiation 2 + 3 + `./defaults.sh 4 + sysctl -q net.ipv4.tcp_ecn=3 5 + ` 6 + 7 + 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 4 8 + +.002 ... 0.052 connect(4, ..., ...) = 0 9 + 10 + +.002 > SEWA 0:0(0) <mss 1460,sackOK,TS val 100 ecr 0,nop,wscale 8> 11 + +0.05 < SW. 0:0(0) ack 1 win 32767 <mss 1460,ECN e0b 1 ceb 0 e1b 1,nop,nop,nop,sackOK,nop,wscale 8> 12 + +.002 > [ect0] W. 1:1(0) ack 1 <ECN e1b 1 ceb 0 e0b 1,nop> 13 + 14 + +0.01 write(4, ..., 1000) = 1000 15 + +.002 > [ect0] EAP. 1:1001(1000) ack 1 <ECN e1b 1 ceb 0 e0b 1,nop> 16 + +.05 < [ect0] EAP. 1:1(0) ack 1001 win 256 <ECN e0b 1001 ceb 0 e1b 0,nop> 17 + 18 + +0.01 %{ assert tcpi_delivered_ce == 0, tcpi_delivered_ce }% 19 + 20 + +0.01 write(4, ..., 1000) = 1000 21 + +.002 > [ect0] EAP. 1001:2001(1000) ack 1 <ECN e1b 1 ceb 0 e0b 1,nop> 22 + 23 + +0.01 %{ assert tcpi_delivered_ce == 0, tcpi_delivered_ce }%
+26
tools/testing/selftests/net/packetdrill/tcp_accecn_negotiation_listen.pkt
··· 1 + // Test basic AccECN negotiation 2 + 3 + `./defaults.sh 4 + sysctl -q net.ipv4.tcp_ecn=3 5 + ` 6 + 7 + 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3 8 + +0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0 9 + +0 bind(3, ..., ...) = 0 10 + +0 listen(3, 1) = 0 11 + 12 + +0 < SEWA 0:0(0) win 32792 <mss 1050,nop,nop,sackOK,nop,wscale 8> 13 + +.002 > SW. 0:0(0) ack 1 <mss 1460,ECN e1b 1 ceb 0 e0b 1,nop,nop,nop,sackOK,nop,wscale 8> 14 + +0.05 < [ect0] W. 1:1(0) ack 1 win 320 <ECN e0b 1 ceb 0 e1b 1,nop> 15 + +.002 accept(3, ..., ...) = 4 16 + 17 + +0.01 %{ assert tcpi_delivered_ce == 0, tcpi_delivered_ce }% 18 + 19 + +0.01 write(4, ..., 1000) = 1000 20 + +.002 > [ect0] EAP. 1:1001(1000) ack 1 <ECN e1b 1 ceb 0 e0b 1,nop> 21 + +0.05 < [ect0] EAP. 1:1(0) ack 1001 win 320 22 + 23 + +0.01 %{ assert tcpi_delivered_ce == 0, tcpi_delivered_ce }% 24 + 25 + +0.01 write(4, ..., 1000) = 1000 26 + +.002 > [ect0] EAP. 1001:2001(1000) ack 1 <ECN e1b 1 ceb 0 e0b 1,nop>
+23
tools/testing/selftests/net/packetdrill/tcp_accecn_negotiation_noopt_connect.pkt
··· 1 + // Test basic AccECN negotiation without option 2 + 3 + `./defaults.sh 4 + sysctl -q net.ipv4.tcp_ecn=3 5 + ` 6 + 7 + 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 4 8 + +.002 ... 0.052 connect(4, ..., ...) = 0 9 + 10 + +.002 > SEWA 0:0(0) <mss 1460,sackOK,TS val 100 ecr 0,nop,wscale 8> 11 + +0.05 < SW. 0:0(0) ack 1 win 32767 <mss 1460,nop,nop,sackOK,nop,wscale 8> 12 + +.002 > [ect0] W. 1:1(0) ack 1 13 + 14 + +0.01 write(4, ..., 1000) = 1000 15 + +.002 > [ect0] EAP. 1:1001(1000) ack 1 16 + +.05 < [ect0] EAP. 1:1(0) ack 1001 win 256 17 + 18 + +0.01 %{ assert tcpi_delivered_ce == 0, tcpi_delivered_ce }% 19 + 20 + +0.01 write(4, ..., 1000) = 1000 21 + +.002 > [ect0] EAP. 1001:2001(1000) ack 1 22 + 23 + +0.01 %{ assert tcpi_delivered_ce == 0, tcpi_delivered_ce }%
+23
tools/testing/selftests/net/packetdrill/tcp_accecn_negotiation_optenable.pkt
··· 1 + // Test basic AccECN negotiation, late option enable 2 + 3 + `./defaults.sh 4 + sysctl -q net.ipv4.tcp_ecn=3 5 + ` 6 + 7 + 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 4 8 + +.002 ... 0.052 connect(4, ..., ...) = 0 9 + 10 + +.002 > SEWA 0:0(0) <mss 1460,sackOK,TS val 100 ecr 0,nop,wscale 8> 11 + +0.05 < SW. 0:0(0) ack 1 win 32767 <mss 1460,nop,nop,sackOK,nop,wscale 8> 12 + +.002 > [ect0] W. 1:1(0) ack 1 13 + 14 + +0.01 write(4, ..., 1000) = 1000 15 + +.002 > [ect0] EAP. 1:1001(1000) ack 1 16 + +.05 < [ect0] EAP. 1:1(0) ack 1001 win 256 <ECN e0b 1001 ceb 0 e1b 1,nop> 17 + 18 + +0.01 %{ assert tcpi_delivered_ce == 0, tcpi_delivered_ce }% 19 + 20 + +0.01 write(4, ..., 1000) = 1000 21 + +.002 > [ect0] EAP. 1001:2001(1000) ack 1 <ECN e1b 1 ceb 0 e0b 1,nop> 22 + 23 + +0.01 %{ assert tcpi_delivered_ce == 0, tcpi_delivered_ce }%
+20
tools/testing/selftests/net/packetdrill/tcp_accecn_no_ecn_after_accecn.pkt
··· 1 + // Test client behavior on receiving a non ECN SYN-ACK 2 + // after receiving an AccECN SYN-ACK and moving to 3 + // ESTABLISHED state 4 + 5 + `./defaults.sh 6 + sysctl -q net.ipv4.tcp_ecn=3 7 + sysctl -q net.ipv4.tcp_ecn_option=2 8 + ` 9 + 10 + 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 4 11 + +.002 ... 0.052 connect(4, ..., ...) = 0 12 + 13 + +.002 > [noecn] SEWA 0:0(0) <mss 1460,sackOK,TS val 100 ecr 0,nop,wscale 8> 14 + // Receive an AccECN SYN-ACK and move to ESTABLISHED 15 + +0.05 < [noecn] SW. 0:0(0) ack 1 win 32767 <mss 1460,ECN e0b 1 ceb 0 e1b 1,nop,nop,nop,sackOK,nop,wscale 8> 16 + +.002 > [ect0] W. 1:1(0) ack 1 <ECN e1b 1 ceb 0 e0b 1,nop> 17 + 18 + // Receive a non ECN SYN-ACK and send a challenge ACK with ACE feedback 19 + +0.1 < [noecn] S. 0:0(0) ack 1 win 32767 <mss 1460,nop,nop,sackOK,nop,wscale 8> 20 + +.002 > [ect0] W. 1:1(0) ack 1 <ECN e1b 1 ceb 0 e0b 1,nop>
+27
tools/testing/selftests/net/packetdrill/tcp_accecn_noopt.pkt
··· 1 + // Test basic AccECN negotiation with option off using sysctl 2 + 3 + `./defaults.sh 4 + sysctl -q net.ipv4.tcp_ecn=3 5 + sysctl -q net.ipv4.tcp_ecn_option=0 6 + ` 7 + 8 + 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3 9 + +0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0 10 + +0 bind(3, ..., ...) = 0 11 + +0 listen(3, 1) = 0 12 + 13 + +0 < SEWA 0:0(0) win 32792 <mss 1050,nop,nop,sackOK,nop,wscale 8> 14 + +.002 > SW. 0:0(0) ack 1 <mss 1460,nop,nop,sackOK,nop,wscale 8> 15 + +0.05 < [ect0] W. 1:1(0) ack 1 win 320 <ECN e0b 1 ceb 0 e1b 1,nop> 16 + +.002 accept(3, ..., ...) = 4 17 + 18 + +0.01 %{ assert tcpi_delivered_ce == 0, tcpi_delivered_ce }% 19 + 20 + +0.01 write(4, ..., 1000) = 1000 21 + +.002 > [ect0] EAP. 1:1001(1000) ack 1 22 + +0.05 < [ect0] EAP. 1:1(0) ack 1001 win 320 23 + 24 + +0.01 %{ assert tcpi_delivered_ce == 0, tcpi_delivered_ce }% 25 + 26 + +0.01 write(4, ..., 1000) = 1000 27 + +.002 > [ect0] EAP. 1001:2001(1000) ack 1
+27
tools/testing/selftests/net/packetdrill/tcp_accecn_noprogress.pkt
··· 1 + // Test no progress filtering 2 + 3 + `./defaults.sh 4 + sysctl -q net.ipv4.tcp_ecn=3 5 + ` 6 + 7 + 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3 8 + +0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0 9 + +0 bind(3, ..., ...) = 0 10 + +0 listen(3, 1) = 0 11 + 12 + +0 < SEWA 0:0(0) win 32792 <mss 1050,nop,nop,sackOK,nop,wscale 8> 13 + +.002 > SW. 0:0(0) ack 1 <mss 1460,ECN e1b 1 ceb 0 e0b 1,nop,nop,nop,sackOK,nop,wscale 8> 14 + +0.05 < [ect0] W. 1:1(0) ack 1 win 264 <ECN e0b 1 ceb 0 e1b 1,nop> 15 + +.002 accept(3, ..., ...) = 4 16 + 17 + +0.01 %{ assert tcpi_delivered_ce == 0, tcpi_delivered_ce }% 18 + 19 + +0.01 write(4, ..., 1000) = 1000 20 + +.002 > [ect0] EAP. 1:1001(1000) ack 1 <ECN e1b 1 ceb 0 e0b 1,nop> 21 + // Fake CE and claim no progress 22 + +0.05 < [ect0] WA. 1:1(0) ack 1 win 264 <ECN e0b 1 ceb 1000 e1b 1,nop> 23 + 24 + +0.01 %{ 25 + assert tcpi_delivered_ce == 0, tcpi_delivered_ce 26 + assert tcpi_delivered_ce_bytes == 0, tcpi_delivered_ce_bytes 27 + }%
+28
tools/testing/selftests/net/packetdrill/tcp_accecn_notecn_then_accecn_syn.pkt
··· 1 + // Test that SYN-ACK with ACE flags and without 2 + // ACE flags got dropped. Although we disable ECN, 3 + // we shouldn't consider this as blackholed as 4 + // these are dropped due to congestion 5 + 6 + `./defaults.sh 7 + sysctl -q net.ipv4.tcp_ecn=3 8 + sysctl -q net.ipv4.tcp_ecn_option=2 9 + ` 10 + 11 + +0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3 12 + +0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0 13 + +0 bind(3, ..., ...) = 0 14 + +0 listen(3, 1) = 0 15 + 16 + +0 < [noecn] S 0:0(0) win 32792 <mss 1460,nop,nop,sackOK,nop,wscale 8> 17 + +.002 > [noecn] S. 0:0(0) ack 1 <mss 1460,nop,nop,sackOK,nop,wscale 8> 18 + 19 + // Retransmit SYN 20 + +0.1 < [ect0] SEWA 0:0(0) win 32792 <mss 1460,nop,nop,sackOK,nop,wscale 8> 21 + +.002 > [noecn] S. 0:0(0) ack 1 <mss 1460,nop,nop,sackOK,nop,wscale 8> 22 + 23 + +0.1 < [noecn] . 1:1(0) ack 1 win 320 24 + +.002 accept(3, ..., ...) = 4 25 + 26 + // Write with AccECN option but with ip-noecn since we received one SYN with ACE=0 27 + +0.01 write(4, ..., 100) = 100 28 + +.002 > [noecn] P. 1:101(100) ack 1
+18
tools/testing/selftests/net/packetdrill/tcp_accecn_rfc3168_to_fallback.pkt
··· 1 + // Test RFC3168 fallback when sysctl asks for AccECN 2 + 3 + `./defaults.sh 4 + sysctl -q net.ipv4.tcp_ecn=3 5 + ` 6 + 7 + 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3 8 + +0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0 9 + +0 bind(3, ..., ...) = 0 10 + +0 listen(3, 1) = 0 11 + 12 + +0 < SEW 0:0(0) win 32792 <mss 1050,nop,nop,sackOK,nop,wscale 8> 13 + +.002 > SE. 0:0(0) ack 1 <mss 1460,nop,nop,sackOK,nop,wscale 8> 14 + +0.05 < . 1:1(0) ack 1 win 320 15 + +.002 accept(3, ..., ...) = 4 16 + 17 + +0.01 write(4, ..., 1000) = 1000 18 + +.002 > [ect0] P. 1:1001(1000) ack 1
+18
tools/testing/selftests/net/packetdrill/tcp_accecn_rfc3168_to_rfc3168.pkt
··· 1 + // Test RFC3168 ECN when sysctl asks for RFC3168 ECN 2 + 3 + `./defaults.sh 4 + sysctl -q net.ipv4.tcp_ecn=1 5 + ` 6 + 7 + 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3 8 + +0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0 9 + +0 bind(3, ..., ...) = 0 10 + +0 listen(3, 1) = 0 11 + 12 + +0 < SEW 0:0(0) win 32792 <mss 1050,nop,nop,sackOK,nop,wscale 8> 13 + +.002 > SE. 0:0(0) ack 1 <mss 1460,nop,nop,sackOK,nop,wscale 8> 14 + +0.05 < . 1:1(0) ack 1 win 320 15 + +.002 accept(3, ..., ...) = 4 16 + 17 + +0.01 write(4, ..., 1000) = 1000 18 + +.002 > [ect0] P. 1:1001(1000) ack 1
+28
tools/testing/selftests/net/packetdrill/tcp_accecn_sack_space_grab.pkt
··· 1 + // Test SACK space grab to fit AccECN option 2 + --tcp_ts_tick_usecs=1000 3 + 4 + `./defaults.sh 5 + sysctl -q net.ipv4.tcp_ecn=3 6 + ` 7 + 8 + 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3 9 + +0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0 10 + +0 bind(3, ..., ...) = 0 11 + +0 listen(3, 1) = 0 12 + 13 + +0 < SEWA 0:0(0) win 32792 <mss 1050,nop,nop,sackOK,nop,wscale 8> 14 + +.002 > SW. 0:0(0) ack 1 <mss 1460,ECN e1b 1 ceb 0 e0b 1,nop,nop,nop,sackOK,nop,wscale 8> 15 + +0.05 < [ect0] W. 1:1(0) ack 1 win 264 <ECN e0b 1 ceb 0 e1b 1,nop> 16 + +.002 accept(3, ..., ...) = 4 17 + 18 + +.01 < [ect1] EAP. 1001:2001(1000) ack 1 win 264 19 + +0.002 > [ect0] EA. 1:1(0) ack 1 <ECN e1b 1001 ceb 0 e0b 1,nop,nop,nop,sack 1001:2001> 20 + +.01 < [ect0] EAP. 3001:4001(1000) ack 1 win 264 21 + +0.002 > [ect0] EA. 1:1(0) ack 1 <ECN e1b 1001 ceb 0 e0b 1001,nop,nop,nop,sack 3001:4001 1001:2001> 22 + +.01 < [ce] EAP. 5001:6001(1000) ack 1 win 264 23 + +0.002 > [ect0] WA. 1:1(0) ack 1 <ECN e1b 1001 ceb 1000 e0b 1001,nop,nop,nop,sack 5001:6001 3001:4001 1001:2001> 24 + // DSACK works? 25 + +.01 < [ect0] EAP. 5001:6001(1000) ack 1 win 264 26 + +0.002 > [ect0] WA. 1:1(0) ack 1 <ECN e1b 1001 ceb 1000 e0b 2001,nop,nop,nop,sack 5001:6001 5001:6001 3001:4001> 27 + +.01 < [ect1] EAP. 6001:7001(1000) ack 1 win 264 28 + +0.002 > [ect0] WA. 1:1(0) ack 1 <ECN e1b 2001 ceb 1000 e0b 2001,nop,nop,nop,sack 5001:7001 3001:4001 1001:2001>
+39
tools/testing/selftests/net/packetdrill/tcp_accecn_sack_space_grab_with_ts.pkt
··· 1 + // Test SACK space grab to fit AccECN option 2 + --tcp_ts_tick_usecs=1000 3 + 4 + `./defaults.sh 5 + sysctl -q net.ipv4.tcp_ecn=3 6 + ` 7 + 8 + 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3 9 + +0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0 10 + +0 bind(3, ..., ...) = 0 11 + +0 listen(3, 1) = 0 12 + 13 + +0 < SEWA 0:0(0) win 32792 <mss 1050,sackOK,TS val 1 ecr 0,nop,wscale 8> 14 + +.002 > SW. 0:0(0) ack 1 <mss 1460,sackOK,TS val 100 ecr 1,ECN e1b 1 ceb 0 e0b 1,nop,nop,wscale 8> 15 + +0.05 < [ect0] W. 1:1(0) ack 1 win 264 <nop,nop,TS val 2 ecr 100,ECN e0b 1 ceb 0 e1b 1,nop> 16 + +.002 accept(3, ..., ...) = 4 17 + 18 + // One SACK block should allow all 3 AccECN fields: 19 + +.01 < [ect1] EAP. 1001:2001(1000) ack 1 win 264 <nop,nop,TS val 3 ecr 100> 20 + +0.002 > [ect0] EA. 1:1(0) ack 1 <nop,nop,TS val 160 ecr 2,ECN e1b 1001 ceb 0 e0b 1,nop,nop,nop,sack 1001:2001> 21 + 22 + // Two SACK blocks should fit w/ AccECN if we only need to use 2 AccECN fields: check ect1 arriving. 23 + +.01 < [ect1] EAP. 3001:4001(1000) ack 1 win 264 <nop,nop,TS val 4 ecr 100> 24 + +0.002 > [ect0] EA. 1:1(0) ack 1 <nop,nop,TS val 172 ecr 2,ECN e1b 2001 ceb 0,nop,nop,sack 3001:4001 1001:2001> 25 + 26 + // Two SACK blocks should fit w/ AccECN if we only need to use 2 AccECN fields: check CE arriving. 27 + +.01 < [ce] EAP. 5001:6001(1000) ack 1 win 264 <nop,nop,TS val 5 ecr 100> 28 + +0.002 > [ect0] WA. 1:1(0) ack 1 <nop,nop,TS val 184 ecr 2,ECN e1b 2001 ceb 1000,nop,nop,sack 5001:6001 3001:4001> 29 + 30 + // Check that DSACK works, using 2 SACK blocks in total, if we only need to use 2 AccECN fields: check ect1 arriving. 31 + +.01 < [ect1] EAP. 5001:6001(1000) ack 1 win 264 <nop,nop,TS val 5 ecr 100> 32 + +0.002 > [ect0] WA. 1:1(0) ack 1 <nop,nop,TS val 196 ecr 2,ECN e1b 3001 ceb 1000,nop,nop,sack 5001:6001 5001:6001> 33 + 34 + // Check the case where the AccECN option doesn't fit, because sending ect0 35 + // with order 1 would rquire 3 AccECN fields, 36 + // and TS (12 bytes) + 2 SACK blocks (20 bytes) + 3 AccECN fields (2 + 3*3 bytes) > 40 bytes. 37 + // That's OK; Linux TCP AccECN is optimized for the ECT1 case, not ECT0. 38 + +.01 < [ect0] EAP. 6001:7001(1000) ack 1 win 264 <nop,nop,TS val 5 ecr 100> 39 + +0.002 > [ect0] WA. 1:1(0) ack 1 <nop,nop,TS val 204 ecr 2,nop,nop,sack 5001:7001 3001:4001 1001:2001>
+20
tools/testing/selftests/net/packetdrill/tcp_accecn_serverside_accecn_disabled1.pkt
··· 1 + // Test against classic ECN server 2 + // Not-ECT on SYN and server sets 1|0|1 (AE is unused for classic ECN) 3 + 4 + `./defaults.sh 5 + sysctl -q net.ipv4.tcp_ecn=3 6 + ` 7 + 8 + 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 4 9 + +.002 ... 0.052 connect(4, ..., ...) = 0 10 + 11 + +.002 > [noecn] SEWA 0:0(0) <mss 1460,sackOK,TS val 100 ecr 0,nop,wscale 8> 12 + +0.05 < [noecn] SEA. 0:0(0) ack 1 win 32767 <mss 1460,sackOK,TS val 700 ecr 100,nop,wscale 8> 13 + +.002 > [ect0] W. 1:1(0) ack 1 <nop, nop, TS val 200 ecr 700> 14 + 15 + +0 write(4, ..., 100) = 100 16 + +.002 > [ect0] P.5 1:101(100) ack 1 <nop,nop,TS val 300 ecr 700> 17 + +0 close(4) = 0 18 + 19 + +.002 > [ect0] F.5 101:101(0) ack 1 <nop,nop,TS val 400 ecr 700> 20 + +0.1 < [noecn] R. 1:1(0) ack 102 win 4242
+20
tools/testing/selftests/net/packetdrill/tcp_accecn_serverside_accecn_disabled2.pkt
··· 1 + // Test against classic ECN server 2 + // Not-ECT on SYN and server sets 0|0|1 3 + 4 + `./defaults.sh 5 + sysctl -q net.ipv4.tcp_ecn=3 6 + ` 7 + 8 + 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 4 9 + +.002 ... 0.052 connect(4, ..., ...) = 0 10 + 11 + +.002 > [noecn] SEWA 0:0(0) <mss 1460,sackOK,TS val 100 ecr 0,nop,wscale 8> 12 + +0.05 < [noecn] SE. 0:0(0) ack 1 win 32767 <mss 1460,sackOK,TS val 700 ecr 100,nop,wscale 8> 13 + +.002 > [noecn] . 1:1(0) ack 1 <nop, nop, TS val 200 ecr 700> 14 + 15 + +0 write(4, ..., 100) = 100 16 + +.002 > [ect0] P. 1:101(100) ack 1 <nop,nop,TS val 300 ecr 700> 17 + +0 close(4) = 0 18 + 19 + +0 > [noecn] F. 101:101(0) ack 1 <...> 20 + +0.1 < R. 1:1(0) ack 102 win 4242
+19
tools/testing/selftests/net/packetdrill/tcp_accecn_serverside_broken.pkt
··· 1 + // Test against broken server (1|1|1) 2 + 3 + `./defaults.sh 4 + sysctl -q net.ipv4.tcp_ecn=3 5 + ` 6 + 7 + 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 4 8 + +.002 ... 0.052 connect(4, ..., ...) = 0 9 + 10 + +.002 > [noecn] SEWA 0:0(0) <mss 1460,sackOK,TS val 100 ecr 0,nop,wscale 8> 11 + +0.05 < [noecn] SEWA. 0:0(0) ack 1 win 32767 <mss 1460,sackOK,TS val 700 ecr 100,nop,wscale 8> 12 + +.002 > [noecn] . 1:1(0) ack 1 <nop, nop, TS val 200 ecr 700> 13 + 14 + +0 write(4, ..., 100) = 100 15 + +.002 > [noecn] P. 1:101(100) ack 1 <nop,nop,TS val 300 ecr 700> 16 + +0 close(4) = 0 17 + 18 + +.002 > [noecn] F. 101:101(0) ack 1 <...> 19 + +0.1 < [noecn] R. 1:1(0) ack 102 win 4242
+19
tools/testing/selftests/net/packetdrill/tcp_accecn_serverside_ecn_disabled.pkt
··· 1 + // Test against Non ECN server (0|0|0) 2 + 3 + `./defaults.sh 4 + sysctl -q net.ipv4.tcp_ecn=3 5 + ` 6 + 7 + 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 4 8 + +.002 ... 0.052 connect(4, ..., ...) = 0 9 + 10 + +.002 > [noecn] SEWA 0:0(0) <mss 1460,sackOK,TS val 100 ecr 0,nop,wscale 8> 11 + +0.05 < [noecn] S. 0:0(0) ack 1 win 32767 <mss 1460,sackOK,TS val 700 ecr 100,nop,wscale 8> 12 + +.002 > [noecn] . 1:1(0) ack 1 <nop, nop, TS val 200 ecr 700> 13 + 14 + +0 write(4, ..., 100) = 100 15 + +.002 > [noecn] P. 1:101(100) ack 1 <nop,nop,TS val 300 ecr 700> 16 + +0 close(4) = 0 17 + 18 + +.002 > [noecn] F. 101:101(0) ack 1 <nop,nop,TS val 400 ecr 700> 19 + +0.1 < [noecn] R. 1:1(0) ack 102 win 4242
+18
tools/testing/selftests/net/packetdrill/tcp_accecn_serverside_only.pkt
··· 1 + // Test AccECN with sysctl set to server-side only 2 + 3 + `./defaults.sh 4 + sysctl -q net.ipv4.tcp_ecn=5 5 + ` 6 + 7 + 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3 8 + +0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0 9 + +0 bind(3, ..., ...) = 0 10 + +0 listen(3, 1) = 0 11 + 12 + +0 < SEWA 0:0(0) win 32792 <mss 1050,nop,nop,sackOK,nop,wscale 8> 13 + +.002 > SW. 0:0(0) ack 1 <mss 1460,ECN e1b 1 ceb 0 e0b 1,nop,nop,nop,sackOK,nop,wscale 8> 14 + +0.05 < [ect0] W. 1:1(0) ack 1 win 320 <ECN e0b 1 ceb 0 e1b 1,nop> 15 + +.002 accept(3, ..., ...) = 4 16 + 17 + +0.01 write(4, ..., 1000) = 1000 18 + +.002 > [ect0] EAP. 1:1001(1000) ack 1 <ECN e1b 1 ceb 0 e0b 1,nop>
+18
tools/testing/selftests/net/packetdrill/tcp_accecn_syn_ace_flags_acked_after_retransmit.pkt
··· 1 + // Test that SYN with ACE flags was Acked 2 + // after 2nd retransmission. In this case, 3 + // since we got SYN-ACK that supports Accurate 4 + // ECN, we consider this as successful negotiation 5 + 6 + `./defaults.sh 7 + sysctl -q net.ipv4.tcp_ecn=3 8 + ` 9 + 10 + 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 4 11 + +.002 ... 2.1 connect(4, ..., ...) = 0 12 + 13 + +.002 > [noecn] SEWA 0:0(0) <mss 1460,sackOK,TS val 100 ecr 0,nop,wscale 8> 14 + +1~+1.1 > [noecn] SEWA 0:0(0) <mss 1460,sackOK,TS val 100 ecr 0,nop,wscale 8> 15 + +1~+1.1 > [noecn] S 0:0(0) <mss 1460,sackOK,TS val 100 ecr 0,nop,wscale 8> 16 + 17 + +0.1 < [noecn] SW. 0:0(0) ack 1 win 32767 <mss 1016,ECN e0b 1 ceb 0 e1b 1,nop,nop,nop,sackOK,nop,wscale 8> 18 + +0~+0.01 > [ect0] W. 1:1(0) ack 1 <ECN e1b 1 ceb 0 e0b 1,nop>
+16
tools/testing/selftests/net/packetdrill/tcp_accecn_syn_ace_flags_drop.pkt
··· 1 + // Test that SYN with ACE flags got dropped 2 + // We retry one more time with ACE and then 3 + // fallback to disabled ECN 4 + 5 + `./defaults.sh 6 + sysctl -q net.ipv4.tcp_ecn=3 7 + ` 8 + 9 + 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 4 10 + +.002 ... 2.1 connect(4, ..., ...) = 0 11 + 12 + +.002 > [noecn] SEWA 0:0(0) <mss 1460,sackOK,TS val 100 ecr 0,nop,wscale 8> 13 + +1~+1.1 > [noecn] SEWA 0:0(0) <mss 1460,sackOK,TS val 100 ecr 0,nop,wscale 8> 14 + +1~+1.1 > [noecn] S 0:0(0) <mss 1460,sackOK,TS val 100 ecr 0,nop,wscale 8> 15 + +0.1 < [noecn] S. 0:0(0) ack 1 win 32767 <mss 1460,nop,nop,sackOK,nop,wscale 8> 16 + +0~+0.01 > [noecn] . 1:1(0) ack 1
+27
tools/testing/selftests/net/packetdrill/tcp_accecn_syn_ack_ace_flags_acked_after_retransmit.pkt
··· 1 + // Test that SYN-ACK with ACE flags was Acked 2 + // after 2nd retransmission. In this case, 3 + // since we got the last ACK that supports Accurate 4 + // ECN, we consider this as successful negotiation 5 + 6 + `./defaults.sh 7 + sysctl -q net.ipv4.tcp_ecn=3 8 + sysctl -q net.ipv4.tcp_ecn_option=2 9 + ` 10 + 11 + +0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3 12 + +0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0 13 + +0 bind(3, ..., ...) = 0 14 + +0 listen(3, 1) = 0 15 + 16 + +0 < [noecn] SEWA 0:0(0) win 32792 <mss 1460,nop,nop,sackOK,nop,wscale 8> 17 + +.002 > [noecn] SW. 0:0(0) ack 1 <mss 1460,ECN e1b 1 ceb 0 e0b 1,nop,nop,nop,sackOK,nop,wscale 8> 18 + 19 + // Retransmit SYN-ACK without option 20 + +1~+1.1 > [noecn] SW. 0:0(0) ack 1 <mss 1460,nop,nop,sackOK,nop,wscale 8> 21 + 22 + // SYN-ACK maybe getting blackholed, disable ECN 23 + +2~+2.2 > [noecn] S. 0:0(0) ack 1 <mss 1460,nop,nop,sackOK,nop,wscale 8> 24 + 25 + // Received an ACK with ACE flags, state should be set to negotiation succeeded 26 + +0.1 < [noecn] W. 1:1(0) ack 1 win 320 <ECN e0b 1 ceb 0 e1b 1,nop> 27 + +.002 accept(3, ..., ...) = 4
+26
tools/testing/selftests/net/packetdrill/tcp_accecn_syn_ack_ace_flags_drop.pkt
··· 1 + // Test that SYN-ACK with ACE flags got dropped 2 + // We retry one more time with ACE and then 3 + // fallback to disabled ECN 4 + 5 + `./defaults.sh 6 + sysctl -q net.ipv4.tcp_ecn=3 7 + sysctl -q net.ipv4.tcp_ecn_option=2 8 + ` 9 + 10 + +0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3 11 + +0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0 12 + +0 bind(3, ..., ...) = 0 13 + +0 listen(3, 1) = 0 14 + 15 + +0 < [noecn] SEWA 0:0(0) win 32792 <mss 1460,nop,nop,sackOK,nop,wscale 8> 16 + +.002 > [noecn] SW. 0:0(0) ack 1 <mss 1460,ECN e1b 1 ceb 0 e0b 1,nop,nop,nop,sackOK,nop,wscale 8> 17 + 18 + // Retransmit SYN-ACK without option 19 + +1~+1.1 > [noecn] SW. 0:0(0) ack 1 <mss 1460,nop,nop,sackOK,nop,wscale 8> 20 + 21 + // SYN-ACK maybe getting blackholed, disable ECN 22 + +2~+2.2 > [noecn] S. 0:0(0) ack 1 <mss 1460,nop,nop,sackOK,nop,wscale 8> 23 + 24 + // Received an ACK with no ACE flags, state should be set to blackholed 25 + +0.1 < [noecn] . 1:1(0) ack 1 win 320 26 + +0 accept(3, ..., ...) = 4
+13
tools/testing/selftests/net/packetdrill/tcp_accecn_syn_ce.pkt
··· 1 + // Test AccECN ECN field reflector in SYNACK 2 + 3 + `./defaults.sh 4 + sysctl -q net.ipv4.tcp_ecn=3 5 + ` 6 + 7 + 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3 8 + +0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0 9 + +0 bind(3, ..., ...) = 0 10 + +0 listen(3, 1) = 0 11 + 12 + +0 < [ce] SEWA 0:0(0) win 32792 <mss 1050,nop,nop,sackOK,nop,wscale 8> 13 + +.002 > SWA. 0:0(0) ack 1 <mss 1460,ECN e1b 1 ceb 0 e0b 1,nop,nop,nop,sackOK,nop,wscale 8>
+13
tools/testing/selftests/net/packetdrill/tcp_accecn_syn_ect0.pkt
··· 1 + // Test AccECN ECN field reflector in SYNACK 2 + 3 + `./defaults.sh 4 + sysctl -q net.ipv4.tcp_ecn=3 5 + ` 6 + 7 + 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3 8 + +0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0 9 + +0 bind(3, ..., ...) = 0 10 + +0 listen(3, 1) = 0 11 + 12 + +0 < [ect0] SEWA 0:0(0) win 32792 <mss 1050,nop,nop,sackOK,nop,wscale 8> 13 + +.002 > SA. 0:0(0) ack 1 <mss 1460,ECN e1b 1 ceb 0 e0b 1,nop,nop,nop,sackOK,nop,wscale 8>
+13
tools/testing/selftests/net/packetdrill/tcp_accecn_syn_ect1.pkt
··· 1 + // Test AccECN ECN field reflector in SYNACK 2 + 3 + `./defaults.sh 4 + sysctl -q net.ipv4.tcp_ecn=3 5 + ` 6 + 7 + 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3 8 + +0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0 9 + +0 bind(3, ..., ...) = 0 10 + +0 listen(3, 1) = 0 11 + 12 + +0 < [ect1] SEWA 0:0(0) win 32792 <mss 1050,nop,nop,sackOK,nop,wscale 8> 13 + +.002 > SEW. 0:0(0) ack 1 <mss 1460,ECN e1b 1 ceb 0 e0b 1,nop,nop,nop,sackOK,nop,wscale 8>
+27
tools/testing/selftests/net/packetdrill/tcp_accecn_synack_ce.pkt
··· 1 + // Test SYNACK CE & received_ce update 2 + 3 + `./defaults.sh 4 + sysctl -q net.ipv4.tcp_ecn=3 5 + sysctl -q net.ipv4.tcp_ecn_option=2 6 + ` 7 + 8 + 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 4 9 + +.002 ... 0.052 connect(4, ..., ...) = 0 10 + 11 + +.002 > [noecn] SEWA 0:0(0) <mss 1460,sackOK,TS val 100 ecr 0,nop,wscale 8> 12 + +0.05 < [ce] SW. 0:0(0) ack 1 win 32767 <mss 1460,ECN e0b 1 ceb 0 e1b 1,nop,nop,nop,sackOK,nop,wscale 8> 13 + +.002 > [ect0] WA. 1:1(0) ack 1 <ECN e1b 1 ceb 0 e0b 1,nop> 14 + 15 + +0.01 write(4, ..., 100) = 100 16 + +.002 > [ect0] P.6 1:101(100) ack 1 <ECN e1b 1 ceb 0 e0b 1,nop> 17 + +0.05 < [ect0] P.5 1:101(100) ack 101 win 256 <ECN e0b 101 ceb 0 e1b 1,nop> 18 + +.002 > [ect0] .6 101:101(0) ack 101 <ECN e1b 1 ceb 0 e0b 101,nop> 19 + 20 + +0.01 write(4, ..., 100) = 100 21 + +.002 > [ect0] P.6 101:201(100) ack 101 <ECN e1b 1 ceb 0 e0b 101,nop> 22 + 23 + +0.1 < [ect1] P.5 201:301(100) ack 201 win 256 <ECN e0b 101 ceb 0 e1b 1,nop> 24 + +.002 > [ect0] .6 201:201(0) ack 101 <ECN e1b 101 ceb 0 e0b 101,nop,nop,nop,sack 201:301> 25 + 26 + +0.01 < [ce] .6 401:501(100) ack 201 win 256 <ECN e0b 101 ceb 0 e1b 1,nop> 27 + +.002 > [ect0] .7 201:201(0) ack 101 <ECN e1b 101 ceb 100 e0b 101,nop,nop,nop,sack 401:501 201:301>
+22
tools/testing/selftests/net/packetdrill/tcp_accecn_synack_ce_updates_delivered_ce.pkt
··· 1 + // Reflected SYNACK CE mark increases delivered_ce 2 + 3 + `./defaults.sh 4 + sysctl -q net.ipv4.tcp_ecn=3 5 + sysctl -q net.ipv4.tcp_ecn_fallback=0 6 + ` 7 + 8 + 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3 9 + +0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0 10 + +0 bind(3, ..., ...) = 0 11 + +0 listen(3, 1) = 0 12 + 13 + +0.05 < SEWA 0:0(0) win 32767 <mss 1050,nop,nop,sackOK,nop,wscale 8> 14 + +.002 > SW. 0:0(0) ack 1 <mss 1460,ECN e1b 1 ceb 0 e0b 1,nop,nop,nop,sackOK,nop,wscale 8> 15 + // Fake ce for prev, ECT validator must be disabled for this to work 16 + +0.05 < [ect0] WA. 1:1(0) ack 1 win 264 <ECN e0b 1 ceb 0 e1b 1,nop> 17 + +.002 accept(3, ..., ...) = 4 18 + 19 + +0.01 %{ assert tcpi_delivered_ce == 1, tcpi_delivered_ce }% 20 + 21 + +0.01 write(4, ..., 1000) = 1000 22 + +.002 > [ect0] EAP. 1:1001(1000) ack 1 <ECN e1b 1 ceb 0 e0b 1,nop>
+24
tools/testing/selftests/net/packetdrill/tcp_accecn_synack_ect0.pkt
··· 1 + // Test SYN=0 reflector 2 + 3 + `./defaults.sh 4 + sysctl -q net.ipv4.tcp_ecn=3 5 + ` 6 + 7 + 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 4 8 + +.002 ... 0.052 connect(4, ..., ...) = 0 9 + 10 + +.002 > SEWA 0:0(0) <mss 1460,sackOK,TS val 100 ecr 0,nop,wscale 8> 11 + +0.05 < [ect0] SW. 0:0(0) ack 1 win 32767 <mss 1460,ECN e0b 1 ceb 0 e1b 1,nop,nop,nop,sackOK,nop,wscale 8> 12 + +.002 > [ect0] A. 1:1(0) ack 1 <ECN e1b 1 ceb 0 e0b 1,nop> 13 + 14 + +0.01 write(4, ..., 100) = 100 15 + +.002 > [ect0] P.5 1:101(100) ack 1 <ECN e1b 1 ceb 0 e0b 1,nop> 16 + +0.05 < [ect0] P.5 1:1(0) ack 101 win 256 <ECN e0b 101 ceb 0 e1b 1,nop> 17 + 18 + +0.01 < [ect0] P.5 1:101(100) ack 101 win 256 <ECN e0b 1 ceb 0 e1b 1,nop> 19 + +.002 > [ect0] .5 101:101(0) ack 101 <ECN e1b 1 ceb 0 e0b 101,nop> 20 + +0 read(4, ..., 100) = 100 21 + 22 + +0 close(4) = 0 23 + +0 > F.5 101:101(0) ack 101 <...> 24 + +0.1 < R. 101:101(0) ack 102 win 4242
+24
tools/testing/selftests/net/packetdrill/tcp_accecn_synack_ect1.pkt
··· 1 + // Test SYN=0 reflector 2 + 3 + `./defaults.sh 4 + sysctl -q net.ipv4.tcp_ecn=3 5 + ` 6 + 7 + 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 4 8 + +.002 ... 0.052 connect(4, ..., ...) = 0 9 + 10 + +.002 > SEWA 0:0(0) <mss 1460,sackOK,TS val 100 ecr 0,nop,wscale 8> 11 + +0.05 < [ect1] SW. 0:0(0) ack 1 win 32767 <mss 1460,ECN e0b 1 ceb 0 e1b 1,nop,nop,nop,sackOK,nop,wscale 8> 12 + +.002 > [ect0] EW. 1:1(0) ack 1 <ECN e1b 1 ceb 0 e0b 1,nop> 13 + 14 + +0.01 write(4, ..., 100) = 100 15 + +.002 > [ect0] P.5 1:101(100) ack 1 <ECN e1b 1 ceb 0 e0b 1,nop> 16 + +0.05 < [ect1] P.5 1:1(0) ack 101 win 256 <ECN e0b 101 ceb 0 e1b 1,nop> 17 + 18 + +0.01 < [ect1] P.5 1:101(100) ack 101 win 256 <ECN e0b 1 ceb 0 e1b 1,nop> 19 + +.002 > [ect0] .5 101:101(0) ack 101 <ECN e1b 101 ceb 0 e0b 1,nop> 20 + +0 read(4, ..., 100) = 100 21 + 22 + +0 close(4) = 0 23 + +0 > F5. 101:101(0) ack 101 <...> 24 + +0.1 < R. 101:101(0) ack 102 win 4242
+15
tools/testing/selftests/net/packetdrill/tcp_accecn_synack_rexmit.pkt
··· 1 + // Test 3rd ACK flags when SYN-ACK is rexmitted 2 + 3 + `./defaults.sh 4 + sysctl -q net.ipv4.tcp_ecn=3 5 + ` 6 + 7 + 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 4 8 + +.002 ... 0.052 connect(4, ..., ...) = 0 9 + 10 + +.002 > SEWA 0:0(0) <mss 1460,sackOK,TS val 100 ecr 0,nop,wscale 8> 11 + +0.05 < SW. 0:0(0) ack 1 win 32767 <mss 1460,ECN e0b 1 ceb 0 e1b 1,nop,nop,nop,sackOK,nop,wscale 8> 12 + +.002 > [ect0] W. 1:1(0) ack 1 <ECN e1b 1 ceb 0 e0b 1,nop> 13 + 14 + +0.05 < SW. 0:0(0) ack 1 win 32767 <mss 1460,ECN e0b 1 ceb 0 e1b 1,nop,nop,nop,sackOK,nop,wscale 8> 15 + +.002 > [ect0] W. 1:1(0) ack 1 <ECN e1b 1 ceb 0 e0b 1,nop>
+25
tools/testing/selftests/net/packetdrill/tcp_accecn_synack_rxmt.pkt
··· 1 + // Test that we retransmit SYN-ACK with ACE and without 2 + // AccECN options after 3 + // SYN-ACK was lost and TCP moved to TCPS_SYN_RECEIVED 4 + 5 + `./defaults.sh 6 + sysctl -q net.ipv4.tcp_ecn=3 7 + sysctl -q net.ipv4.tcp_ecn_option=2 8 + ` 9 + 10 + +0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3 11 + +0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0 12 + +0 bind(3, ..., ...) = 0 13 + +0 listen(3, 1) = 0 14 + 15 + +0 < [noecn] SEWA 0:0(0) win 32792 <mss 1460,nop,nop,sackOK,nop,wscale 8> 16 + +.002 > [noecn] SW. 0:0(0) ack 1 <mss 1460,ECN e1b 1 ceb 0 e0b 1,nop,nop,nop,sackOK,nop,wscale 8> 17 + 18 + // Retransmit SYN-ACK without option 19 + +1~+1.1 > [noecn] SW. 0:0(0) ack 1 <mss 1460,nop,nop,sackOK,nop,wscale 8> 20 + +0.1 < [noecn] W. 1:1(0) ack 1 win 320 <ECN e0b 1 ceb 0 e1b 1,nop> 21 + +.002 accept(3, ..., ...) = 4 22 + 23 + // We try to write with AccECN option 24 + +0.01 write(4, ..., 100) = 100 25 + +.002 > [ect0] P5. 1:101(100) ack 1 <ECN e1b 1 ceb 0 e0b 1,nop>
+26
tools/testing/selftests/net/packetdrill/tcp_accecn_tsnoprogress.pkt
··· 1 + // Test TS progress filtering 2 + --tcp_ts_tick_usecs=1000 3 + --tolerance_usecs=7000 4 + 5 + `./defaults.sh 6 + sysctl -q net.ipv4.tcp_ecn=3 7 + ` 8 + 9 + 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3 10 + +0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0 11 + +0 bind(3, ..., ...) = 0 12 + +0 listen(3, 1) = 0 13 + 14 + +0 < SEWA 0:0(0) win 32792 <mss 1050,sackOK,TS val 1 ecr 0,nop,wscale 8> 15 + +.002 > SW. 0:0(0) ack 1 <mss 1460,sackOK,TS val 10 ecr 1,ECN e1b 1 ceb 0 e0b 1,nop,nop,wscale 8> 16 + +0.05 < [ect0] W. 1:1(0) ack 1 win 264 <nop,nop,TS val 2 ecr 10> 17 + +.002 accept(3, ..., ...) = 4 18 + 19 + +0.01 %{ assert tcpi_delivered_ce == 0, tcpi_delivered_ce }% 20 + 21 + +0.01 write(4, ..., 1000) = 1000 22 + +.002 > [ect0] EAP. 1:1001(1000) ack 1 <nop,nop,TS val 83 ecr 2> 23 + // Fake CE and claim no progress 24 + +0.05 < [ect0] WA. 1:1(0) ack 1 win 264 <nop,nop,TS val 2 ecr 83> 25 + 26 + +0.01 %{ assert tcpi_delivered_ce == 0, tcpi_delivered_ce }%
+25
tools/testing/selftests/net/packetdrill/tcp_accecn_tsprogress.pkt
··· 1 + // Test TS progress filtering 2 + --tcp_ts_tick_usecs=1000 3 + 4 + `./defaults.sh 5 + sysctl -q net.ipv4.tcp_ecn=3 6 + ` 7 + 8 + 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3 9 + +0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0 10 + +0 bind(3, ..., ...) = 0 11 + +0 listen(3, 1) = 0 12 + 13 + +0 < SEWA 0:0(0) win 32792 <mss 1050,sackOK,TS val 1 ecr 0,nop,wscale 8> 14 + +.002 > SW. 0:0(0) ack 1 <mss 1460,sackOK,TS val 10 ecr 1,ECN e1b 1 ceb 0 e0b 1,nop,nop,wscale 8> 15 + +0.05 < [ect0] W. 1:1(0) ack 1 win 264 <nop,nop,TS val 2 ecr 10> 16 + +.002 accept(3, ..., ...) = 4 17 + 18 + +0.01 %{ assert tcpi_delivered_ce == 0, tcpi_delivered_ce }% 19 + 20 + +0.01 write(4, ..., 1000) = 1000 21 + +.002 > [ect0] EAP. 1:1001(1000) ack 1 <nop,nop,TS val 83 ecr 2> 22 + // Fake CE and claim no progress 23 + +0.05 < [ect0] WA. 1:1(0) ack 1 win 264 <nop,nop,TS val 3 ecr 83> 24 + 25 + +0.01 %{ assert tcpi_delivered_ce == 1, tcpi_delivered_ce }%