aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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 */