aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Scheffenegger <rscheff@FreeBSD.org>2024-01-25 22:21:07 +0000
committerRichard Scheffenegger <rscheff@FreeBSD.org>2024-01-25 23:16:22 +0000
commitfc262fd3dc0a111f42d34cff4012912db906549a (patch)
tree040ae74477c39ba12f225e826c112aa7501f8404
parent0932fb565a08e6e13dd9843e7a60dae311911d0d (diff)
downloadsrc-fc262fd3dc0a111f42d34cff4012912db906549a.tar.gz
src-fc262fd3dc0a111f42d34cff4012912db906549a.zip
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
-rw-r--r--sys/netinet/tcp_ecn.c71
-rw-r--r--sys/netinet/tcp_ecn.h3
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 */