git: fc262fd3dc0a - main - tcp: AccECN access ACE field by shifting bits

From: Richard Scheffenegger <rscheff_at_FreeBSD.org>
Date: Thu, 25 Jan 2024 23:17:57 UTC
The branch main has been updated by rscheff:

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

commit fc262fd3dc0a111f42d34cff4012912db906549a
Author:     Richard Scheffenegger <rscheff@FreeBSD.org>
AuthorDate: 2024-01-25 22:21:07 +0000
Commit:     Richard Scheffenegger <rscheff@FreeBSD.org>
CommitDate: 2024-01-25 23:16:22 +0000

    tcp: AccECN access ACE field by shifting bits
    
    Shifting bits is quicker than checking header flag bits
    one by one. Also improve readability by the use of switch
    statements.
    
    No change in behaviour.
    
    Reviewed By:           glebius, tuexen, #transport
    Sponsored by:          NetApp, Inc.
    Differential Revision: https://reviews.freebsd.org/D43560
---
 sys/netinet/tcp_ecn.c | 71 ++++++++++++++++++++++++---------------------------
 sys/netinet/tcp_ecn.h |  3 ++-
 2 files changed, 36 insertions(+), 38 deletions(-)

diff --git a/sys/netinet/tcp_ecn.c b/sys/netinet/tcp_ecn.c
index 43c23f8118f4..34ecfe1c83c0 100644
--- a/sys/netinet/tcp_ecn.c
+++ b/sys/netinet/tcp_ecn.c
@@ -96,6 +96,9 @@
 #include <netinet/tcpip.h>
 #include <netinet/tcp_ecn.h>
 
+static inline int  tcp_ecn_get_ace(uint16_t);
+static inline void tcp_ecn_set_ace(uint16_t *, uint32_t);
+
 static SYSCTL_NODE(_net_inet_tcp, OID_AUTO, ecn,
     CTLFLAG_RW | CTLFLAG_MPSAFE, 0,
     "TCP ECN");
@@ -116,22 +119,24 @@ SYSCTL_INT(_net_inet_tcp_ecn, OID_AUTO, maxretries,
 void
 tcp_ecn_input_syn_sent(struct tcpcb *tp, uint16_t thflags, int iptos)
 {
-
-	if (V_tcp_do_ecn == 0)
+	switch (V_tcp_do_ecn) {
+	case 0:
 		return;
-	if ((V_tcp_do_ecn == 1) ||
-	    (V_tcp_do_ecn == 2)) {
+	case 1:
+		/* FALLTHROUGH */
+	case 2:
 		/* RFC3168 ECN handling */
 		if ((thflags & (TH_CWR | TH_ECE)) == (0 | TH_ECE)) {
 			tp->t_flags2 |= TF2_ECN_PERMIT;
 			tp->t_flags2 &= ~TF2_ACE_PERMIT;
 			TCPSTAT_INC(tcps_ecn_shs);
 		}
-	} else
-	/* decoding Accurate ECN according to table in section 3.1.1 */
-	if ((V_tcp_do_ecn == 3) ||
-	    (V_tcp_do_ecn == 4)) {
-		/*
+		break;
+	case 3:
+		/* FALLTHROUGH */
+	case 4:
+		/* decoding Accurate ECN according to
+		 * table in section 3.1.1
 		 * on the SYN,ACK, process the AccECN
 		 * flags indicating the state the SYN
 		 * was delivered.
@@ -208,6 +213,7 @@ tcp_ecn_input_syn_sent(struct tcpcb *tp, uint16_t thflags, int iptos)
 			tp->t_rcep = 0b110;
 			break;
 		}
+		break;
 	}
 }
 
@@ -219,10 +225,12 @@ tcp_ecn_input_parallel_syn(struct tcpcb *tp, uint16_t thflags, int iptos)
 {
 	if (thflags & TH_ACK)
 		return;
-	if (V_tcp_do_ecn == 0)
+	switch (V_tcp_do_ecn) {
+	case 0:
 		return;
-	if ((V_tcp_do_ecn == 1) ||
-	    (V_tcp_do_ecn == 2)) {
+	case 1:
+		/* FALLTHROUGH */
+	case 2:
 		/* RFC3168 ECN handling */
 		if ((thflags & (TH_CWR | TH_ECE)) == (TH_CWR | TH_ECE)) {
 			tp->t_flags2 |= TF2_ECN_PERMIT;
@@ -230,9 +238,10 @@ tcp_ecn_input_parallel_syn(struct tcpcb *tp, uint16_t thflags, int iptos)
 			tp->t_flags2 |= TF2_ECN_SND_ECE;
 			TCPSTAT_INC(tcps_ecn_shs);
 		}
-	} else
-	if ((V_tcp_do_ecn == 3) ||
-	    (V_tcp_do_ecn == 4)) {
+		break;
+	case 3:
+		/* FALLTHROUGH */
+	case 4:
 		/* AccECN handling */
 		switch (thflags & (TH_AE | TH_CWR | TH_ECE)) {
 		default:
@@ -272,6 +281,7 @@ tcp_ecn_input_parallel_syn(struct tcpcb *tp, uint16_t thflags, int iptos)
 			}
 			break;
 		}
+		break;
 	}
 }
 
@@ -418,13 +428,7 @@ tcp_ecn_output_established(struct tcpcb *tp, uint16_t *thflags, int len, bool rx
 	 * Reply with proper ECN notifications.
 	 */
 	if (tp->t_flags2 & TF2_ACE_PERMIT) {
-		*thflags &= ~(TH_AE|TH_CWR|TH_ECE);
-		if (tp->t_rcep & 0x01)
-			*thflags |= TH_ECE;
-		if (tp->t_rcep & 0x02)
-			*thflags |= TH_CWR;
-		if (tp->t_rcep & 0x04)
-			*thflags |= TH_AE;
+		tcp_ecn_set_ace(thflags, tp->t_rcep);
 		if (!(tp->t_flags2 & TF2_ECN_PERMIT)) {
 			/*
 			 * here we process the final
@@ -476,9 +480,6 @@ tcp_ecn_syncache_socket(struct tcpcb *tp, struct syncache *sc)
 			tp->t_scep = 6;
 			tp->t_rcep = 6;
 			break;
-		/* undefined SCF codepoint */
-		default:
-			break;
 		}
 	}
 }
@@ -591,24 +592,20 @@ tcp_ecn_syncache_respond(uint16_t thflags, struct syncache *sc)
 			TCPSTAT_INC(tcps_ecn_shs);
 			TCPSTAT_INC(tcps_ace_ce);
 			break;
-		/* undefined SCF codepoint */
-		default:
-			break;
 		}
 	}
 	return thflags;
 }
 
-int
+static inline int
 tcp_ecn_get_ace(uint16_t thflags)
 {
-	int ace = 0;
+	return ((thflags & (TH_AE|TH_CWR|TH_ECE)) >> TH_ACE_SHIFT);
+}
 
-	if (thflags & TH_ECE)
-		ace += 1;
-	if (thflags & TH_CWR)
-		ace += 2;
-	if (thflags & TH_AE)
-		ace += 4;
-	return ace;
+static inline void
+tcp_ecn_set_ace(uint16_t *thflags, uint32_t t_rcep)
+{
+	*thflags &= ~(TH_AE|TH_CWR|TH_ECE);
+	*thflags |= ((t_rcep << TH_ACE_SHIFT) & (TH_AE|TH_CWR|TH_ECE));
 }
diff --git a/sys/netinet/tcp_ecn.h b/sys/netinet/tcp_ecn.h
index db5c71d64cab..89ee157361ab 100644
--- a/sys/netinet/tcp_ecn.h
+++ b/sys/netinet/tcp_ecn.h
@@ -38,6 +38,8 @@
 #include <netinet/tcp_var.h>
 #include <netinet/tcp_syncache.h>
 
+#define TH_ACE_SHIFT 6
+
 void	 tcp_ecn_input_syn_sent(struct tcpcb *, uint16_t, int);
 void	 tcp_ecn_input_parallel_syn(struct tcpcb *, uint16_t, int);
 int	 tcp_ecn_input_segment(struct tcpcb *, uint16_t, int, int, int);
@@ -46,7 +48,6 @@ int	 tcp_ecn_output_established(struct tcpcb *, uint16_t *, int, bool);
 void	 tcp_ecn_syncache_socket(struct tcpcb *, struct syncache *);
 int	 tcp_ecn_syncache_add(uint16_t, int);
 uint16_t tcp_ecn_syncache_respond(uint16_t, struct syncache *);
-int	 tcp_ecn_get_ace(uint16_t);
 
 #endif /* _KERNEL */