diff --git a/share/man/man4/cc_dctcp.4 b/share/man/man4/cc_dctcp.4 --- a/share/man/man4/cc_dctcp.4 +++ b/share/man/man4/cc_dctcp.4 @@ -28,7 +28,7 @@ .\" .\" $FreeBSD$ .\" -.Dd May 13, 2021 +.Dd November 8, 2022 .Dt CC_DCTCP 4 .Os .Sh NAME @@ -91,6 +91,11 @@ .It Va slowstart A flag if the congestion window should be reduced by one half after slow start. Valid settings 0 and 1, default 0. +.It Va ect1 +Controls if a DCTCP session should use IP ECT(0) marking when sending out +segments (default), or ECT(1) marking making use of L4S infrastructure. +Changes to this setting will only affect new sessions, existing sessions will +retain their previous marking value. .El .Sh SEE ALSO .Xr cc_cdg 4 , diff --git a/sys/netinet/cc/cc_dctcp.c b/sys/netinet/cc/cc_dctcp.c --- a/sys/netinet/cc/cc_dctcp.c +++ b/sys/netinet/cc/cc_dctcp.c @@ -68,6 +68,8 @@ #define V_dctcp_shift_g VNET(dctcp_shift_g) VNET_DEFINE_STATIC(uint32_t, dctcp_slowstart) = 0; #define V_dctcp_slowstart VNET(dctcp_slowstart) +VNET_DEFINE_STATIC(uint32_t, dctcp_ect1) = 0; +#define V_dctcp_ect1 VNET(dctcp_ect1) struct dctcp { uint32_t bytes_ecn; /* # of marked bytes during a RTT */ @@ -313,8 +315,11 @@ dctcp_data = ccv->cc_data; - if (CCV(ccv, t_flags2) & TF2_ECN_PERMIT) + if (CCV(ccv, t_flags2) & TF2_ECN_PERMIT) { dctcp_data->save_sndnxt = CCV(ccv, snd_nxt); + if (V_dctcp_ect1) + CCV(ccv, t_flags2) |= TF2_ECN_USE_ECT1; + } } /* @@ -478,5 +483,10 @@ &VNET_NAME(dctcp_slowstart), 0, &dctcp_slowstart_handler, "IU", "half CWND reduction after the first slow start"); +SYSCTL_UINT(_net_inet_tcp_cc_dctcp, OID_AUTO, ect1, + CTLFLAG_VNET | CTLFLAG_RW | CTLFLAG_NEEDGIANT, + &VNET_NAME(dctcp_ect1), 0, + "Send DCTCP segments with ÍP ECT(0) or ECT(1)"); + DECLARE_CC_MODULE(dctcp, &dctcp_cc_algo); MODULE_VERSION(dctcp, 2); diff --git a/sys/netinet/tcp_ecn.c b/sys/netinet/tcp_ecn.c --- a/sys/netinet/tcp_ecn.c +++ b/sys/netinet/tcp_ecn.c @@ -411,8 +411,13 @@ !((tp->t_flags & TF_FORCEDATA) && len == 1)); /* RFC3168 ECN marking, only new data segments */ if (newdata) { - ipecn = IPTOS_ECN_ECT0; - TCPSTAT_INC(tcps_ecn_ect0); + if (tp->t_flags2 & TF2_ECN_USE_ECT1) { + ipecn = IPTOS_ECN_ECT1; + TCPSTAT_INC(tcps_ecn_ect1); + } else { + ipecn = IPTOS_ECN_ECT0; + TCPSTAT_INC(tcps_ecn_ect0); + } } /* * Reply with proper ECN notifications. diff --git a/sys/netinet/tcp_var.h b/sys/netinet/tcp_var.h --- a/sys/netinet/tcp_var.h +++ b/sys/netinet/tcp_var.h @@ -577,7 +577,9 @@ #define TF2_ECN_SND_CWR 0x00000040 /* ECN CWR in queue */ #define TF2_ECN_SND_ECE 0x00000080 /* ECN ECE in queue */ #define TF2_ACE_PERMIT 0x00000100 /* Accurate ECN mode */ -#define TF2_FBYTES_COMPLETE 0x00000400 /* We have first bytes in and out */ +#define TF2_FBYTES_COMPLETE 0x00000400 /* We have first bytes in and out */ +#define TF2_ECN_USE_ECT1 0x00000800 /* Use ECT(1) marking on session */ + /* * Structure to hold TCP options that are only used during segment * processing (in tcp_input), but not held in the tcpcb.