git: f026275e26d0 - main - tcp: set IP ECN header codepoint properly

From: Richard Scheffenegger <rscheff_at_FreeBSD.org>
Date: Thu, 03 Feb 2022 15:54:34 UTC
The branch main has been updated by rscheff:

URL: https://cgit.FreeBSD.org/src/commit/?id=f026275e26d0071ac3dee98526e8b9bcad58f0fa

commit f026275e26d0071ac3dee98526e8b9bcad58f0fa
Author:     Richard Scheffenegger <rscheff@FreeBSD.org>
AuthorDate: 2022-02-03 15:47:50 +0000
Commit:     Richard Scheffenegger <rscheff@FreeBSD.org>
CommitDate: 2022-02-03 15:53:41 +0000

    tcp: set IP ECN header codepoint properly
    
    TCP RACK can cache the IP header while preparing
    a new TCP packet for transmission. Thus all the
    IP ECN codepoint bits need to be assigned, without
    assuming a clear field beforehand.
    
    Reviewed By: tuexen, kbowling, #transport
    MFC after:   3 days
    Sponsored by:        NetApp, Inc.
    Differential Revision: https://reviews.freebsd.org/D34148
---
 sys/netinet/tcp_output.c      |  7 ++++++-
 sys/netinet/tcp_stacks/rack.c | 14 ++++++++++++--
 2 files changed, 18 insertions(+), 3 deletions(-)

diff --git a/sys/netinet/tcp_output.c b/sys/netinet/tcp_output.c
index dc512c8aad39..ce6d9b86e73f 100644
--- a/sys/netinet/tcp_output.c
+++ b/sys/netinet/tcp_output.c
@@ -1223,11 +1223,16 @@ send:
 		    !((tp->t_flags & TF_FORCEDATA) && len == 1 &&
 		    SEQ_LT(tp->snd_una, tp->snd_max))) {
 #ifdef INET6
-			if (isipv6)
+			if (isipv6) {
+				ip6->ip6_flow &= ~htonl(IPTOS_ECN_MASK << 20);
 				ip6->ip6_flow |= htonl(IPTOS_ECN_ECT0 << 20);
+			}
 			else
 #endif
+			{
+				ip->ip_tos &= ~IPTOS_ECN_MASK;
 				ip->ip_tos |= IPTOS_ECN_ECT0;
+			}
 			TCPSTAT_INC(tcps_ecn_ect0);
 			/*
 			 * Reply with proper ECN notifications.
diff --git a/sys/netinet/tcp_stacks/rack.c b/sys/netinet/tcp_stacks/rack.c
index 7983c18620e2..22164c0d5cf4 100644
--- a/sys/netinet/tcp_stacks/rack.c
+++ b/sys/netinet/tcp_stacks/rack.c
@@ -16537,11 +16537,16 @@ again:
 		 */
 		if (len > 0 && SEQ_GEQ(tp->snd_nxt, tp->snd_max)) {
 #ifdef INET6
-			if (rack->r_is_v6)
+			if (rack->r_is_v6) {
+				ip6->ip6_flow &= ~htonl(IPTOS_ECN_MASK << 20);
 				ip6->ip6_flow |= htonl(IPTOS_ECN_ECT0 << 20);
+			}
 			else
 #endif
+			{
+				ip->ip_tos &= ~IPTOS_ECN_MASK;
 				ip->ip_tos |= IPTOS_ECN_ECT0;
+			}
 			KMOD_TCPSTAT_INC(tcps_ecn_ect0);
 			/*
 			 * Reply with proper ECN notifications.
@@ -18614,11 +18619,16 @@ send:
 		if (len > 0 && SEQ_GEQ(tp->snd_nxt, tp->snd_max) &&
 		    (sack_rxmit == 0)) {
 #ifdef INET6
-			if (isipv6)
+			if (isipv6) {
+				ip6->ip6_flow &= ~htonl(IPTOS_ECN_MASK << 20);
 				ip6->ip6_flow |= htonl(IPTOS_ECN_ECT0 << 20);
+			}
 			else
 #endif
+			{
+				ip->ip_tos &= IPTOS_ECN_MASK;
 				ip->ip_tos |= IPTOS_ECN_ECT0;
+			}
 			KMOD_TCPSTAT_INC(tcps_ecn_ect0);
 			/*
 			 * Reply with proper ECN notifications.