Allow the TCP backhole detection to be disabled at all, enabled only

for IPv4, enabled only for IPv6, and enabled for IPv4 and IPv6.
The current blackhole detection might classify a temporary outage as
an MTU issue and reduces permanently the MSS. Since the consequences of
such a reduction due to a misclassification are much more drastically
for IPv4 than for IPv6, allow the administrator to enable it for IPv6 only.

Reviewed by:		bcr@ (man page), Richard Scheffenegger
Sponsored by:		Netflix, Inc.
Differential Revision:	https://reviews.freebsd.org/D24219
This commit is contained in:
Michael Tuexen 2020-03-31 15:54:54 +00:00
parent 11c7efe3a4
commit 413c3db101
4 changed files with 44 additions and 19 deletions

View File

@ -34,7 +34,7 @@
.\" From: @(#)tcp.4 8.1 (Berkeley) 6/5/93
.\" $FreeBSD$
.\"
.Dd March 29, 2020
.Dd March 31, 2020
.Dt TCP 4
.Os
.Sh NAME
@ -628,21 +628,31 @@ specific connection.
This is needed to help with connection establishment
when a broken firewall is in the network path.
.It Va pmtud_blackhole_detection
Turn on automatic path MTU blackhole detection.
In case of retransmits OS will
lower the MSS to check if it's MTU problem.
If current MSS is greater than
configured value to try
Enable automatic path MTU blackhole detection.
In case of retransmits of MSS sized segments,
the OS will lower the MSS to check if it's an MTU problem.
If the current MSS is greater than the configured value to try
.Po Va net.inet.tcp.pmtud_blackhole_mss
and
.Va net.inet.tcp.v6pmtud_blackhole_mss
.Pc ,
it will be set to this value, otherwise,
MSS will be set to default values
the MSS will be set to the default values
.Po Va net.inet.tcp.mssdflt
and
.Va net.inet.tcp.v6mssdflt
.Pc .
Settings:
.Bl -tag -compact
.It 0
Disable path MTU blackhole detection.
.It 1
Enable path MTU blackhole detection for IPv4 and IPv6.
.It 2
Enable path MTU blackhole detection only for IPv4.
.It 3
Enable path MTU blackhole detection only for IPv6.
.El
.It Va pmtud_blackhole_mss
MSS to try for IPv4 if PMTU blackhole detection is turned on.
.It Va v6pmtud_blackhole_mss

View File

@ -5041,6 +5041,7 @@ bbr_timeout_rxt(struct tcpcb *tp, struct tcp_bbr *bbr, uint32_t cts)
{
int32_t rexmt;
int32_t retval = 0;
bool isipv6;
bbr->r_ctl.rc_hpts_flags &= ~PACE_TMR_RXT;
if (bbr->rc_all_timers_stopped) {
@ -5127,11 +5128,16 @@ bbr_timeout_rxt(struct tcpcb *tp, struct tcp_bbr *bbr, uint32_t cts)
* of packets and process straight to FIN. In that case we won't
* catch ESTABLISHED state.
*/
if (V_tcp_pmtud_blackhole_detect && (((tp->t_state == TCPS_ESTABLISHED))
|| (tp->t_state == TCPS_FIN_WAIT_1))) {
#ifdef INET6
int32_t isipv6;
isipv6 = (tp->t_inpcb->inp_vflag & INP_IPV6) ? true : false;
#else
isipv6 = false;
#endif
if (((V_tcp_pmtud_blackhole_detect == 1) ||
(V_tcp_pmtud_blackhole_detect == 2 && !isipv6) ||
(V_tcp_pmtud_blackhole_detect == 3 && isipv6)) &&
((tp->t_state == TCPS_ESTABLISHED) ||
(tp->t_state == TCPS_FIN_WAIT_1))) {
/*
* Idea here is that at each stage of mtu probe (usually,

View File

@ -3123,6 +3123,7 @@ rack_timeout_rxt(struct tcpcb *tp, struct tcp_rack *rack, uint32_t cts)
int32_t rexmt;
struct inpcb *inp;
int32_t retval = 0;
bool isipv6;
inp = tp->t_inpcb;
if (tp->t_timers->tt_flags & TT_STOPPED) {
@ -3209,11 +3210,16 @@ rack_timeout_rxt(struct tcpcb *tp, struct tcp_rack *rack, uint32_t cts)
* of packets and process straight to FIN. In that case we won't
* catch ESTABLISHED state.
*/
if (V_tcp_pmtud_blackhole_detect && (((tp->t_state == TCPS_ESTABLISHED))
|| (tp->t_state == TCPS_FIN_WAIT_1))) {
#ifdef INET6
int32_t isipv6;
isipv6 = (tp->t_inpcb->inp_vflag & INP_IPV6) ? true : false;
#else
isipv6 = false;
#endif
if (((V_tcp_pmtud_blackhole_detect == 1) ||
(V_tcp_pmtud_blackhole_detect == 2 && !isipv6) ||
(V_tcp_pmtud_blackhole_detect == 3 && isipv6)) &&
((tp->t_state == TCPS_ESTABLISHED) ||
(tp->t_state == TCPS_FIN_WAIT_1))) {
/*
* Idea here is that at each stage of mtu probe (usually,
@ -3243,7 +3249,6 @@ rack_timeout_rxt(struct tcpcb *tp, struct tcp_rack *rack, uint32_t cts)
* default in an attempt to retransmit.
*/
#ifdef INET6
isipv6 = (tp->t_inpcb->inp_vflag & INP_IPV6) ? 1 : 0;
if (isipv6 &&
tp->t_maxseg > V_tcp_v6pmtud_blackhole_mss) {
/* Use the sysctl tuneable blackhole MSS. */

View File

@ -614,6 +614,7 @@ tcp_timer_rexmt(void * xtp)
int rexmt;
struct inpcb *inp;
struct epoch_tracker et;
bool isipv6;
#ifdef TCPDEBUG
int ostate;
@ -712,12 +713,16 @@ tcp_timer_rexmt(void * xtp)
* packets and process straight to FIN. In that case we won't catch
* ESTABLISHED state.
*/
if (V_tcp_pmtud_blackhole_detect && (((tp->t_state == TCPS_ESTABLISHED))
|| (tp->t_state == TCPS_FIN_WAIT_1))) {
#ifdef INET6
int isipv6;
isipv6 = (tp->t_inpcb->inp_vflag & INP_IPV6) ? true : false;
#else
isipv6 = false;
#endif
if (((V_tcp_pmtud_blackhole_detect == 1) ||
(V_tcp_pmtud_blackhole_detect == 2 && !isipv6) ||
(V_tcp_pmtud_blackhole_detect == 3 && isipv6)) &&
((tp->t_state == TCPS_ESTABLISHED) ||
(tp->t_state == TCPS_FIN_WAIT_1))) {
/*
* Idea here is that at each stage of mtu probe (usually, 1448
* -> 1188 -> 524) should be given 2 chances to recover before
@ -746,7 +751,6 @@ tcp_timer_rexmt(void * xtp)
* in an attempt to retransmit.
*/
#ifdef INET6
isipv6 = (tp->t_inpcb->inp_vflag & INP_IPV6) ? 1 : 0;
if (isipv6 &&
tp->t_maxseg > V_tcp_v6pmtud_blackhole_mss) {
/* Use the sysctl tuneable blackhole MSS. */