Index: sys/netinet/tcp_input.c =================================================================== --- sys/netinet/tcp_input.c +++ sys/netinet/tcp_input.c @@ -157,6 +157,11 @@ &VNET_NAME(tcp_do_rfc6675_pipe), 0, "Use calculated pipe/in-flight bytes per RFC 6675"); +VNET_DEFINE(int, tcp_do_rfc6675_cwnd) = 0; +SYSCTL_INT(_net_inet_tcp, OID_AUTO, rfc6675_cwnd, CTLFLAG_VNET | CTLFLAG_RW, + &VNET_NAME(tcp_do_rfc6675_cwnd), 0, + "Follow RFC 6675 for cwnd and sshthresh calculations"); + VNET_DEFINE(int, tcp_do_rfc3042) = 1; #define V_tcp_do_rfc3042 VNET(tcp_do_rfc3042) SYSCTL_INT(_net_inet_tcp, OID_AUTO, rfc3042, CTLFLAG_VNET | CTLFLAG_RW, @@ -2582,7 +2587,8 @@ * we have less than 1/2 the original window's * worth of data in flight. */ - if (V_tcp_do_rfc6675_pipe) + if (V_tcp_do_rfc6675_pipe || + V_tcp_do_rfc6675_cwnd) awnd = tcp_compute_pipe(tp); else awnd = (tp->snd_nxt - tp->snd_fack) + @@ -2628,7 +2634,18 @@ TCPSTAT_INC( tcps_sack_recovery_episode); tp->sack_newdata = tp->snd_nxt; - tp->snd_cwnd = maxseg; + /* + * As per RFC6675, + * ssthresh = cwnd = pipe / 2 + */ + if (V_tcp_do_rfc6675_cwnd) { + int pipe; + pipe = tcp_compute_pipe(tp); + tp->snd_ssthresh = + tp->snd_cwnd = pipe / 2; + } else + tp->snd_cwnd = maxseg; + (void) tp->t_fb->tfb_tcp_output(tp); goto drop; } Index: sys/netinet/tcp_var.h =================================================================== --- sys/netinet/tcp_var.h +++ sys/netinet/tcp_var.h @@ -730,6 +730,9 @@ VNET_DECLARE(int, tcp_do_rfc6675_pipe); #define V_tcp_do_rfc6675_pipe VNET(tcp_do_rfc6675_pipe) +VNET_DECLARE(int, tcp_do_rfc6675_cwnd); +#define V_tcp_do_rfc6675_cwnd VNET(tcp_do_rfc6675_cwnd) + int tcp_addoptions(struct tcpopt *, u_char *); int tcp_ccalgounload(struct cc_algo *unload_algo); struct tcpcb *