diff options
author | Richard Scheffenegger <rscheff@FreeBSD.org> | 2024-01-25 22:21:07 +0000 |
---|---|---|
committer | Richard Scheffenegger <rscheff@FreeBSD.org> | 2024-01-25 23:16:22 +0000 |
commit | fc262fd3dc0a111f42d34cff4012912db906549a (patch) | |
tree | 040ae74477c39ba12f225e826c112aa7501f8404 | |
parent | 0932fb565a08e6e13dd9843e7a60dae311911d0d (diff) | |
download | src-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.c | 71 | ||||
-rw-r--r-- | 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 */ |