Page MenuHomeFreeBSD

D23230.id75613.diff
No OneTemporary

D23230.id75613.diff

Index: share/man/man4/tcp.4
===================================================================
--- share/man/man4/tcp.4
+++ share/man/man4/tcp.4
@@ -34,7 +34,7 @@
.\" From: @(#)tcp.4 8.1 (Berkeley) 6/5/93
.\" $FreeBSD$
.\"
-.Dd July 23, 2020
+.Dd August 8, 2020
.Dt TCP 4
.Os
.Sh NAME
@@ -665,6 +665,20 @@
specific connection.
This is needed to help with connection establishment
when a broken firewall is in the network path.
+.It Va ecn.plusplus
+Enable sending of SYN/ACK or all control segments and retransmissions as
+ECN capable transport.
+Settings:
+.Bl -tag -compact
+.It 0
+Regular RFC3168 operation. Send only data segements as ECN capable
+transport.
+.It 1
+Support ECN+ (RFC5562), send SYN/ACK packets as ECN capable transport.
+.It 2
+Support ECN++ (Generalized ECN), all segments of an ECN-enabled session
+are sent as ECN capable transport.
+.El
.It Va pmtud_blackhole_detection
Enable automatic path MTU blackhole detection.
In case of retransmits of MSS sized segments,
Index: sys/netinet/tcp_input.c
===================================================================
--- sys/netinet/tcp_input.c
+++ sys/netinet/tcp_input.c
@@ -202,6 +202,11 @@
&VNET_NAME(tcp_ecn_maxretries), 0,
"Max retries before giving up on ECN");
+VNET_DEFINE(int, tcp_ecn_plusplus) = 0;
+SYSCTL_INT(_net_inet_tcp_ecn, OID_AUTO, plusplus, CTLFLAG_VNET | CTLFLAG_RW,
+ &VNET_NAME(tcp_ecn_plusplus), 0,
+ "Send SYN,ACK and control packets as ECT");
+
VNET_DEFINE(int, tcp_insecure_syn) = 0;
SYSCTL_INT(_net_inet_tcp, OID_AUTO, insecure_syn, CTLFLAG_VNET | CTLFLAG_RW,
&VNET_NAME(tcp_insecure_syn), 0,
Index: sys/netinet/tcp_output.c
===================================================================
--- sys/netinet/tcp_output.c
+++ sys/netinet/tcp_output.c
@@ -1165,17 +1165,32 @@
tp->t_flags2 &= ~TF2_ECN_SND_ECE;
}
- if (tp->t_state == TCPS_ESTABLISHED &&
- (tp->t_flags2 & TF2_ECN_PERMIT)) {
+ if (((tp->t_state == TCPS_ESTABLISHED) &&
+ (tp->t_flags2 & TF2_ECN_PERMIT)) ||
+ ((tp->t_state > TCPS_ESTABLISHED) &&
+ (tp->t_flags2 & TF2_ECN_PERMIT) &&
+ (V_tcp_ecn_plusplus == 2)) ||
+ /*
+ * Note that a passive open SYN,ACK
+ * is actually sent from tcp_syncache
+ */
+ (((flags & (TH_SYN|TH_ACK)) == (TH_SYN)) &&
+ ((flags & (TH_ECE|TH_CWR)) == (TH_ECE|TH_CWR)) &&
+ (V_tcp_ecn_plusplus == 2)) ||
+ (((flags & (TH_SYN|TH_ACK)) == (TH_SYN|TH_ACK)) &&
+ (flags & (TH_CWR|TH_ECE)) &&
+ (V_tcp_ecn_plusplus))) {
/*
* If the peer has ECN, mark data packets with
* ECN capable transmission (ECT).
* Ignore pure ack packets, retransmissions and window probes.
*/
- if (len > 0 && SEQ_GEQ(tp->snd_nxt, tp->snd_max) &&
+ if ((V_tcp_ecn_plusplus == 2) ||
+ (V_tcp_ecn_plusplus && tp->t_state < TCPS_ESTABLISHED) ||
+ ((len > 0 && SEQ_GEQ(tp->snd_nxt, tp->snd_max) &&
(sack_rxmit == 0) &&
!((tp->t_flags & TF_FORCEDATA) && len == 1 &&
- SEQ_LT(tp->snd_una, tp->snd_max))) {
+ SEQ_LT(tp->snd_una, tp->snd_max))))) {
#ifdef INET6
if (isipv6)
ip6->ip6_flow |= htonl(IPTOS_ECN_ECT0 << 20);
Index: sys/netinet/tcp_stacks/rack.c
===================================================================
--- sys/netinet/tcp_stacks/rack.c
+++ sys/netinet/tcp_stacks/rack.c
@@ -13576,15 +13576,30 @@
flags |= TH_ECE;
tp->t_flags2 &= ~TF2_ECN_SND_ECE;
}
- if (tp->t_state == TCPS_ESTABLISHED &&
- (tp->t_flags2 & TF2_ECN_PERMIT)) {
+ if ((tp->t_state == TCPS_ESTABLISHED &&
+ (tp->t_flags2 & TF2_ECN_PERMIT)) ||
+ ((tp->t_state > TCPS_ESTABLISHED) &&
+ (tp->t_flags2 & TF2_ECN_PERMIT) &&
+ (V_tcp_ecn_plusplus == 2)) ||
+ /*
+ * Note that a passive open SYN,ACK
+ * is actually sent from tcp_syncache
+ */
+ (((flags & (TH_SYN|TH_ACK)) == (TH_SYN)) &&
+ ((flags & (TH_ECE|TH_CWR)) == (TH_ECE|TH_CWR)) &&
+ (V_tcp_ecn_plusplus == 2)) ||
+ (((flags & (TH_SYN|TH_ACK)) == (TH_SYN|TH_ACK)) &&
+ (flags & (TH_CWR|TH_ECE)) &&
+ (V_tcp_ecn_plusplus))) {
/*
* If the peer has ECN, mark data packets with ECN capable
* transmission (ECT). Ignore pure ack packets,
* retransmissions.
*/
- if (len > 0 && SEQ_GEQ(tp->snd_nxt, tp->snd_max) &&
- (sack_rxmit == 0)) {
+ if ((V_tcp_ecn_plusplus == 2) ||
+ (V_tcp_ecn_plusplus && tp->t_state < TCPS_ESTABLISHED) ||
+ ((len > 0 && SEQ_GEQ(tp->snd_nxt, tp->snd_max) &&
+ (sack_rxmit == 0)))) {
#ifdef INET6
if (isipv6)
ip6->ip6_flow |= htonl(IPTOS_ECN_ECT0 << 20);
Index: sys/netinet/tcp_syncache.c
===================================================================
--- sys/netinet/tcp_syncache.c
+++ sys/netinet/tcp_syncache.c
@@ -1849,6 +1849,22 @@
if ((flags & TH_SYN) && (sc->sc_flags & SCF_ECN)) {
th->th_flags |= TH_ECE;
TCPSTAT_INC(tcps_ecn_shs);
+
+ if ((V_tcp_ecn_plusplus == 2) ||
+ ((V_tcp_ecn_plusplus) &&
+ (flags & TH_ACK))) {
+#ifdef INET6
+ if (sc->sc_inc.inc_flags & INC_ISIPV6)
+ ip6->ip6_flow |= htonl(IPTOS_ECN_ECT0 << 20);
+#endif
+#if defined(INET6) && defined(INET)
+ else
+#endif
+#ifdef INET
+ ip->ip_tos |= IPTOS_ECN_ECT0;
+#endif
+ TCPSTAT_INC(tcps_ecn_ect0);
+ }
}
/* Tack on the TCP options. */
Index: sys/netinet/tcp_var.h
===================================================================
--- sys/netinet/tcp_var.h
+++ sys/netinet/tcp_var.h
@@ -838,6 +838,7 @@
VNET_DECLARE(int, tcp_do_sack);
VNET_DECLARE(int, tcp_do_tso);
VNET_DECLARE(int, tcp_ecn_maxretries);
+VNET_DECLARE(int, tcp_ecn_plusplus);
VNET_DECLARE(int, tcp_initcwnd_segments);
VNET_DECLARE(int, tcp_insecure_rst);
VNET_DECLARE(int, tcp_insecure_syn);
@@ -880,6 +881,7 @@
#define V_tcp_do_sack VNET(tcp_do_sack)
#define V_tcp_do_tso VNET(tcp_do_tso)
#define V_tcp_ecn_maxretries VNET(tcp_ecn_maxretries)
+#define V_tcp_ecn_plusplus VNET(tcp_ecn_plusplus)
#define V_tcp_initcwnd_segments VNET(tcp_initcwnd_segments)
#define V_tcp_insecure_rst VNET(tcp_insecure_rst)
#define V_tcp_insecure_syn VNET(tcp_insecure_syn)

File Metadata

Mime Type
text/plain
Expires
Thu, Feb 6, 3:31 AM (12 h, 35 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
16486170
Default Alt Text
D23230.id75613.diff (5 KB)

Event Timeline