Changeset View
Changeset View
Standalone View
Standalone View
sys/netinet/tcp_input.c
Show First 20 Lines • Show All 157 Lines • ▼ Show 20 Lines | SYSCTL_INT(_net_inet_tcp, OID_AUTO, rfc6675_pipe, CTLFLAG_VNET | CTLFLAG_RW, | ||||
"Use calculated pipe/in-flight bytes per RFC 6675"); | "Use calculated pipe/in-flight bytes per RFC 6675"); | ||||
VNET_DEFINE(int, tcp_do_rfc3042) = 1; | VNET_DEFINE(int, tcp_do_rfc3042) = 1; | ||||
#define V_tcp_do_rfc3042 VNET(tcp_do_rfc3042) | #define V_tcp_do_rfc3042 VNET(tcp_do_rfc3042) | ||||
SYSCTL_INT(_net_inet_tcp, OID_AUTO, rfc3042, CTLFLAG_VNET | CTLFLAG_RW, | SYSCTL_INT(_net_inet_tcp, OID_AUTO, rfc3042, CTLFLAG_VNET | CTLFLAG_RW, | ||||
&VNET_NAME(tcp_do_rfc3042), 0, | &VNET_NAME(tcp_do_rfc3042), 0, | ||||
"Enable RFC 3042 (Limited Transmit)"); | "Enable RFC 3042 (Limited Transmit)"); | ||||
VNET_DEFINE(int, tcp_do_rfc3390) = 1; | VNET_DEFINE(int, tcp_do_rfc3390); | ||||
SYSCTL_INT(_net_inet_tcp, OID_AUTO, rfc3390, CTLFLAG_VNET | CTLFLAG_RW, | static int tcp_sysctl_rfc3390_handler(SYSCTL_HANDLER_ARGS); | ||||
&VNET_NAME(tcp_do_rfc3390), 0, | SYSCTL_PROC(_net_inet_tcp, OID_AUTO, rfc3390, | ||||
CTLFLAG_VNET | CTLTYPE_INT | CTLFLAG_RW, | |||||
&VNET_NAME(tcp_do_rfc3390), 0, &tcp_sysctl_rfc3390_handler, "I", | |||||
"Enable RFC 3390 (Increasing TCP's Initial Congestion Window)"); | "Enable RFC 3390 (Increasing TCP's Initial Congestion Window)"); | ||||
VNET_DEFINE(int, tcp_do_rfc6928); | |||||
static int tcp_sysctl_rfc6928_handler(SYSCTL_HANDLER_ARGS); | |||||
SYSCTL_PROC(_net_inet_tcp, OID_AUTO, rfc6928, | |||||
CTLFLAG_VNET | CTLTYPE_INT | CTLFLAG_RW, | |||||
&VNET_NAME(tcp_do_rfc6928), 0, &tcp_sysctl_rfc6928_handler, "I", | |||||
"Enable RFC 6928 (Increasing TCP's Initial Congestion Window)"); | |||||
VNET_DEFINE(int, tcp_initcwnd_segments) = 10; | VNET_DEFINE(int, tcp_initcwnd_segments) = 10; | ||||
SYSCTL_INT(_net_inet_tcp, OID_AUTO, initcwnd_segments, | SYSCTL_INT(_net_inet_tcp, OID_AUTO, initcwnd_segments, | ||||
CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(tcp_initcwnd_segments), 0, | CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(tcp_initcwnd_segments), 0, | ||||
"Slow-start flight size (initial congestion window) in number of segments"); | "Slow-start flight size (initial congestion window) in number of segments"); | ||||
VNET_DEFINE(int, tcp_initcwnd_bytes) = 14600; | |||||
SYSCTL_INT(_net_inet_tcp, OID_AUTO, initcwnd_bytes, | |||||
CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(tcp_initcwnd_bytes), 0, | |||||
"Slow-start flight size (initial congestion window) in number of bytes"); | |||||
VNET_DEFINE(int, tcp_do_rfc3465) = 1; | VNET_DEFINE(int, tcp_do_rfc3465) = 1; | ||||
SYSCTL_INT(_net_inet_tcp, OID_AUTO, rfc3465, CTLFLAG_VNET | CTLFLAG_RW, | SYSCTL_INT(_net_inet_tcp, OID_AUTO, rfc3465, CTLFLAG_VNET | CTLFLAG_RW, | ||||
&VNET_NAME(tcp_do_rfc3465), 0, | &VNET_NAME(tcp_do_rfc3465), 0, | ||||
"Enable RFC 3465 (Appropriate Byte Counting)"); | "Enable RFC 3465 (Appropriate Byte Counting)"); | ||||
VNET_DEFINE(int, tcp_abc_l_var) = 2; | VNET_DEFINE(int, tcp_abc_l_var) = 2; | ||||
SYSCTL_INT(_net_inet_tcp, OID_AUTO, abc_l_var, CTLFLAG_VNET | CTLFLAG_RW, | SYSCTL_INT(_net_inet_tcp, OID_AUTO, abc_l_var, CTLFLAG_VNET | CTLFLAG_RW, | ||||
&VNET_NAME(tcp_abc_l_var), 2, | &VNET_NAME(tcp_abc_l_var), 2, | ||||
▲ Show 20 Lines • Show All 160 Lines • ▼ Show 20 Lines | if (metrics.rmx_ssthresh) { | ||||
* buffer limit on the path. Use this to set | * buffer limit on the path. Use this to set | ||||
* the slow start threshhold, but set the | * the slow start threshhold, but set the | ||||
* threshold to no less than 2*mss. | * threshold to no less than 2*mss. | ||||
*/ | */ | ||||
tp->snd_ssthresh = max(2 * maxseg, metrics.rmx_ssthresh); | tp->snd_ssthresh = max(2 * maxseg, metrics.rmx_ssthresh); | ||||
TCPSTAT_INC(tcps_usedssthresh); | TCPSTAT_INC(tcps_usedssthresh); | ||||
} | } | ||||
/* | /* Determine the initial congestion window */ | ||||
* Set the initial slow-start flight size. | tp->snd_cwnd = tcp_initcwnd(tp, maxseg); | ||||
* | |||||
* RFC5681 Section 3.1 specifies the default conservative values. | |||||
* RFC3390 specifies slightly more aggressive values. | |||||
* RFC6928 increases it to ten segments. | |||||
* Support for user specified value for initial flight size. | |||||
* | |||||
* If a SYN or SYN/ACK was lost and retransmitted, we have to | |||||
* reduce the initial CWND to one segment as congestion is likely | |||||
* requiring us to be cautious. | |||||
*/ | |||||
if (tp->snd_cwnd == 1) | |||||
tp->snd_cwnd = maxseg; /* SYN(-ACK) lost */ | |||||
else if (V_tcp_initcwnd_segments) | |||||
tp->snd_cwnd = min(V_tcp_initcwnd_segments * maxseg, | |||||
max(2 * maxseg, V_tcp_initcwnd_segments * 1460)); | |||||
else if (V_tcp_do_rfc3390) | |||||
tp->snd_cwnd = min(4 * maxseg, max(2 * maxseg, 4380)); | |||||
else { | |||||
/* Per RFC5681 Section 3.1 */ | |||||
if (maxseg > 2190) | |||||
tp->snd_cwnd = 2 * maxseg; | |||||
else if (maxseg > 1095) | |||||
tp->snd_cwnd = 3 * maxseg; | |||||
else | |||||
tp->snd_cwnd = 4 * maxseg; | |||||
} | |||||
if (CC_ALGO(tp)->conn_init != NULL) | if (CC_ALGO(tp)->conn_init != NULL) | ||||
CC_ALGO(tp)->conn_init(tp->ccv); | CC_ALGO(tp)->conn_init(tp->ccv); | ||||
} | } | ||||
void inline | void inline | ||||
cc_cong_signal(struct tcpcb *tp, struct tcphdr *th, uint32_t type) | cc_cong_signal(struct tcpcb *tp, struct tcphdr *th, uint32_t type) | ||||
{ | { | ||||
▲ Show 20 Lines • Show All 3,432 Lines • ▼ Show 20 Lines | |||||
} | } | ||||
int | int | ||||
tcp_compute_pipe(struct tcpcb *tp) | tcp_compute_pipe(struct tcpcb *tp) | ||||
{ | { | ||||
return (tp->snd_max - tp->snd_una + | return (tp->snd_max - tp->snd_una + | ||||
tp->sackhint.sack_bytes_rexmit - | tp->sackhint.sack_bytes_rexmit - | ||||
tp->sackhint.sacked_bytes); | tp->sackhint.sacked_bytes); | ||||
} | |||||
/* | |||||
* Set the initial slow-start flight size. | |||||
* | |||||
* Support for user specified value for initial flight size. | |||||
* RFC6928 increases it to ten segments. | |||||
* RFC3390 specifies slightly more aggressive values. | |||||
* RFC5681 Section 3.1 specifies the default conservative values. | |||||
* | |||||
* If a SYN or SYN/ACK was lost and retransmitted, we have to | |||||
* reduce the initial CWND to one segment as congestion is likely | |||||
* requiring us to be cautious. | |||||
* | |||||
* RFC3390: min (4*MSS, max (2*MSS, 4380)) | |||||
* RFC6928: min (10*MSS, max (2*MSS, 14600)) | |||||
* code: max(2*MSS, min(initcwnd_segments * MSS, initcwnd_bytes)) | |||||
*/ | |||||
u_long | |||||
tcp_initcwnd(struct tcpcb *tp, u_int maxseg) | |||||
{ | |||||
u_long initcwnd; | |||||
if (tp->snd_cwnd == 1) | |||||
initcwnd = maxseg; /* SYN(-ACK) lost */ | |||||
else if (V_tcp_initcwnd_bytes >= 4380) | |||||
initcwnd = max(2 * maxseg, | |||||
min(V_tcp_initcwnd_segments * maxseg, | |||||
V_tcp_initcwnd_bytes)); | |||||
else { | |||||
/* Per RFC5681 Section 3.1 */ | |||||
if (maxseg > 2190) | |||||
initcwnd = 2 * maxseg; | |||||
else if (maxseg > 1095) | |||||
initcwnd = 3 * maxseg; | |||||
else | |||||
initcwnd = 4 * maxseg; | |||||
} | |||||
return (initcwnd); | |||||
} | |||||
static int | |||||
tcp_sysctl_rfc3390_handler(SYSCTL_HANDLER_ARGS) | |||||
{ | |||||
int error, new; | |||||
new = V_tcp_do_rfc3390; | |||||
error = sysctl_handle_int(oidp, &new, 0, req); | |||||
if (error == 0 && req->newptr && new == 1) { | |||||
V_tcp_initcwnd_segments = 4; | |||||
V_tcp_initcwnd_bytes = 4380; | |||||
V_tcp_do_rfc3390 = new; | |||||
} | |||||
return (error); | |||||
} | |||||
static int | |||||
tcp_sysctl_rfc6928_handler(SYSCTL_HANDLER_ARGS) | |||||
{ | |||||
int error, new; | |||||
new = V_tcp_do_rfc6928; | |||||
error = sysctl_handle_int(oidp, &new, 0, req); | |||||
if (error == 0 && req->newptr && new == 1) { | |||||
V_tcp_initcwnd_segments = 10; | |||||
V_tcp_initcwnd_bytes = 14600; | |||||
V_tcp_do_rfc6928 = new; | |||||
} | |||||
return (error); | |||||
} | } |