Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 24 May 2020 17:51:14 +0000 (UTC)
From:      Richard Scheffenegger <rscheff@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org
Subject:   svn commit: r361436 - stable/11/sys/netinet
Message-ID:  <202005241751.04OHpEUT044542@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: rscheff
Date: Sun May 24 17:51:14 2020
New Revision: 361436
URL: https://svnweb.freebsd.org/changeset/base/361436

Log:
  MFC r361347: With RFC3168 ECN, CWR SHOULD only be sent with new data
  
  Overly conservative data receivers may ignore the CWR flag on other
  packets, and keep ECE latched. This can result in continous reduction
  of the congestion window, and very poor performance when ECN is
  enabled.
  
  This does NOT contain the merge of the change to RACK since at this
  time that code does not exist in stable/11, and there is no plan to
  merge RACK to stable/11.
  
  PR:		243590
  Reviewed by:	rgrimes (mentor), rrs
  Approved by:	rgrimes (mentor), tuexen (mentor)
  MFC after:	3 days
  Sponsored by:	NetApp, Inc.
  Differential Revision:	https://reviews.freebsd.org/D23364

Modified:
  stable/11/sys/netinet/tcp_input.c
  stable/11/sys/netinet/tcp_output.c
Directory Properties:
  stable/11/   (props changed)

Modified: stable/11/sys/netinet/tcp_input.c
==============================================================================
--- stable/11/sys/netinet/tcp_input.c	Sun May 24 16:47:27 2020	(r361435)
+++ stable/11/sys/netinet/tcp_input.c	Sun May 24 17:51:14 2020	(r361436)
@@ -417,9 +417,15 @@ cc_cong_signal(struct tcpcb *tp, struct tcphdr *th, ui
 		}
 		break;
 	case CC_ECN:
-		if (!IN_CONGRECOVERY(tp->t_flags)) {
+		if (!IN_CONGRECOVERY(tp->t_flags) ||
+		    /*
+		     * Allow ECN reaction on ACK to CWR, if
+		     * that data segment was also CE marked.
+		     */
+		    SEQ_GEQ(th->th_ack, tp->snd_recover)) {
+			EXIT_CONGRECOVERY(tp->t_flags);
 			TCPSTAT_INC(tcps_ecn_rcwnd);
-			tp->snd_recover = tp->snd_max;
+			tp->snd_recover = tp->snd_max + 1;
 			if (tp->t_flags & TF_ECN_PERMIT)
 				tp->t_flags |= TF_ECN_SND_CWR;
 		}

Modified: stable/11/sys/netinet/tcp_output.c
==============================================================================
--- stable/11/sys/netinet/tcp_output.c	Sun May 24 16:47:27 2020	(r361435)
+++ stable/11/sys/netinet/tcp_output.c	Sun May 24 17:51:14 2020	(r361436)
@@ -1161,7 +1161,8 @@ send:
 		 * Ignore pure ack packets, retransmissions and window probes.
 		 */
 		if (len > 0 && SEQ_GEQ(tp->snd_nxt, tp->snd_max) &&
-		    !((tp->t_flags & TF_FORCEDATA) && len == 1)) {
+		    !((tp->t_flags & TF_FORCEDATA) && len == 1 &&
+		    SEQ_LT(tp->snd_una, tp->snd_max))) {
 #ifdef INET6
 			if (isipv6)
 				ip6->ip6_flow |= htonl(IPTOS_ECN_ECT0 << 20);
@@ -1169,15 +1170,15 @@ send:
 #endif
 				ip->ip_tos |= IPTOS_ECN_ECT0;
 			TCPSTAT_INC(tcps_ecn_ect0);
+			/*
+			 * Reply with proper ECN notifications.
+			 * Only set CWR on new data segments.
+			 */
+			if (tp->t_flags & TF_ECN_SND_CWR) {
+				flags |= TH_CWR;
+				tp->t_flags &= ~TF_ECN_SND_CWR;
+			}
 		}
-		
-		/*
-		 * Reply with proper ECN notifications.
-		 */
-		if (tp->t_flags & TF_ECN_SND_CWR) {
-			flags |= TH_CWR;
-			tp->t_flags &= ~TF_ECN_SND_CWR;
-		} 
 		if (tp->t_flags & TF_ECN_SND_ECE)
 			flags |= TH_ECE;
 	}



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202005241751.04OHpEUT044542>