Changeset View
Changeset View
Standalone View
Standalone View
sys/netinet/tcp_ecn.c
Show First 20 Lines • Show All 96 Lines • ▼ Show 20 Lines | |||||
#include <netinet/tcp_seq.h> | #include <netinet/tcp_seq.h> | ||||
#include <netinet/tcp_var.h> | #include <netinet/tcp_var.h> | ||||
#include <netinet/tcp_syncache.h> | #include <netinet/tcp_syncache.h> | ||||
#include <netinet/tcp_timer.h> | #include <netinet/tcp_timer.h> | ||||
#include <netinet6/tcp6_var.h> | #include <netinet6/tcp6_var.h> | ||||
#include <netinet/tcpip.h> | #include <netinet/tcpip.h> | ||||
#include <netinet/tcp_ecn.h> | #include <netinet/tcp_ecn.h> | ||||
static SYSCTL_NODE(_net_inet_tcp, OID_AUTO, ecn, | |||||
CTLFLAG_RW | CTLFLAG_MPSAFE, 0, | |||||
"TCP ECN"); | |||||
VNET_DEFINE(int, tcp_do_ecn) = 2; | |||||
SYSCTL_INT(_net_inet_tcp_ecn, OID_AUTO, enable, | |||||
CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(tcp_do_ecn), 0, | |||||
"TCP ECN support"); | |||||
VNET_DEFINE(int, tcp_ecn_maxretries) = 1; | |||||
SYSCTL_INT(_net_inet_tcp_ecn, OID_AUTO, maxretries, | |||||
CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(tcp_ecn_maxretries), 0, | |||||
"Max retries before giving up on ECN"); | |||||
VNET_DEFINE(int, tcp_ecn_option) = 0; | |||||
SYSCTL_INT(_net_inet_tcp_ecn, OID_AUTO, option, | |||||
CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(tcp_ecn_option), 0, | |||||
"Use AccECN TCP option"); | |||||
/* | /* | ||||
* Process incoming SYN,ACK packet | * Process incoming SYN,ACK packet | ||||
*/ | */ | ||||
void | void | ||||
tcp_ecn_input_syn_sent(struct tcpcb *tp, uint16_t thflags, int iptos) | tcp_ecn_input_syn_sent(struct tcpcb *tp, uint16_t thflags, int iptos) | ||||
{ | { | ||||
if (V_tcp_do_ecn == 0) | if (V_tcp_do_ecn == 0) | ||||
return; | return; | ||||
if ((V_tcp_do_ecn == 1) || | if ((V_tcp_do_ecn == 1) || | ||||
(V_tcp_do_ecn == 2)) { | (V_tcp_do_ecn == 2)) { | ||||
/* RFC3168 ECN handling */ | /* RFC3168 ECN handling */ | ||||
if ((thflags & (TH_CWR | TH_ECE)) == (0 | TH_ECE)) { | if ((thflags & (TH_CWR | TH_ECE)) == (0 | TH_ECE)) { | ||||
tp->t_flags2 |= TF2_ECN_PERMIT; | tp->t_flags2 |= TF2_ECN_PERMIT; | ||||
TCPSTAT_INC(tcps_ecn_shs); | TCPSTAT_INC(tcps_ecn_shs); | ||||
▲ Show 20 Lines • Show All 135 Lines • ▼ Show 20 Lines | if ((V_tcp_do_ecn == 3) || | ||||
} | } | ||||
} | } | ||||
} | } | ||||
/* | /* | ||||
* TCP ECN processing. | * TCP ECN processing. | ||||
*/ | */ | ||||
int | int | ||||
tcp_ecn_input_segment(struct tcpcb *tp, uint16_t thflags, int iptos) | tcp_ecn_input_segment(struct tcpcb *tp, uint16_t thflags, int tlen, int iptos) | ||||
{ | { | ||||
int delta_ace = 0; | int delta_ace = 0; | ||||
if (tp->t_flags2 & (TF2_ECN_PERMIT | TF2_ACE_PERMIT)) { | if (tp->t_flags2 & (TF2_ECN_PERMIT | TF2_ACE_PERMIT)) { | ||||
switch (iptos & IPTOS_ECN_MASK) { | switch (iptos & IPTOS_ECN_MASK) { | ||||
case IPTOS_ECN_CE: | case IPTOS_ECN_CE: | ||||
tp->t_flags2 |= TF2_ACO_CE; | |||||
tp->t_rceb += tlen; | |||||
TCPSTAT_INC(tcps_ecn_ce); | TCPSTAT_INC(tcps_ecn_ce); | ||||
break; | break; | ||||
case IPTOS_ECN_ECT0: | case IPTOS_ECN_ECT0: | ||||
tp->t_flags2 |= TF2_ACO_E0; | |||||
tp->t_re0b += tlen; | |||||
TCPSTAT_INC(tcps_ecn_ect0); | TCPSTAT_INC(tcps_ecn_ect0); | ||||
break; | break; | ||||
case IPTOS_ECN_ECT1: | case IPTOS_ECN_ECT1: | ||||
tp->t_flags2 |= TF2_ACO_E1; | |||||
tp->t_re1b += tlen; | |||||
TCPSTAT_INC(tcps_ecn_ect1); | TCPSTAT_INC(tcps_ecn_ect1); | ||||
break; | break; | ||||
} | } | ||||
if (tp->t_flags2 & TF2_ACE_PERMIT) { | if (tp->t_flags2 & TF2_ACE_PERMIT) { | ||||
if ((iptos & IPTOS_ECN_MASK) == IPTOS_ECN_CE) | if ((iptos & IPTOS_ECN_MASK) == IPTOS_ECN_CE) | ||||
tp->t_rcep += 1; | tp->t_rcep += 1; | ||||
if (tp->t_flags2 & TF2_ECN_PERMIT) { | if (tp->t_flags2 & TF2_ECN_PERMIT) { | ||||
▲ Show 20 Lines • Show All 290 Lines • Show Last 20 Lines |