Date: Mon, 14 Jun 2010 09:32:11 +0900 From: Arifumi Matsumoto <a@arifumi.net> To: bug-followup@FreeBSD.org, freebsd-net@freebsd.org Subject: Re: kern/143666: [ip6] [request] PMTU black hole detection not implemented Message-ID: <AANLkTikRI9hzTIn80qAEoKiHOjo0aeCZz5TJsgXUe-6-@mail.gmail.com>
index | next in thread | raw e-mail
[-- Attachment #1 --]
Hi,
I made a patch for 8.0 release to fix this issue of path-mtu blackhole
detection.
This was mostly derived from macosx, which is APSL and BSD
dual-licensed code base,
and slightly modified so that it should not affect ipv4 path mtu detection.
I tested it on 8.0 release only.
I'm guessing this can be applied for CURRENT also, as the related code does not
seem to be changed that much.
Best regards,
[-- Attachment #2 --]
diff -c netinet.org/tcp_timer.c netinet/tcp_timer.c
*** netinet.org/tcp_timer.c Sun Oct 25 01:10:29 2009
--- netinet/tcp_timer.c Mon Jun 14 03:17:33 2010
***************
*** 61,66 ****
--- 61,67 ----
#include <netinet/tcp_fsm.h>
#include <netinet/tcp_timer.h>
#include <netinet/tcp_var.h>
+ #include <netinet6/tcp6_var.h>
#include <netinet/tcpip.h>
#ifdef TCPDEBUG
#include <netinet/tcp_debug.h>
***************
*** 110,115 ****
--- 111,123 ----
SYSCTL_PROC(_net_inet_tcp, OID_AUTO, finwait2_timeout, CTLTYPE_INT|CTLFLAG_RW,
&tcp_finwait2_timeout, 0, sysctl_msec_to_ticks, "I", "FIN-WAIT2 timeout");
+ int tcp_pmtud_black_hole_detect = 1 ;
+ SYSCTL_INT(_net_inet_tcp, OID_AUTO, pmtud_blackhole_detection, CTLFLAG_RW,
+ &tcp_pmtud_black_hole_detect, 0, "Path MTU Discovery Black Hole Detection");
+
+ int tcp_pmtud_black_hole_mss = 1200 ;
+ SYSCTL_INT(_net_inet_tcp, OID_AUTO, pmtud_blackhole_mss, CTLFLAG_RW,
+ &tcp_pmtud_black_hole_mss, 0, "Path MTU Discovery Black Hole Detection lowered MSS");
static int tcp_keepcnt = TCPTV_KEEPCNT;
/* max idle probes */
***************
*** 442,447 ****
--- 450,458 ----
int rexmt;
int headlocked;
struct inpcb *inp;
+ #ifdef INET6
+ int optlen = 0;
+ #endif
#ifdef TCPDEBUG
int ostate;
***************
*** 513,518 ****
--- 524,570 ----
rexmt = TCP_REXMTVAL(tp) * tcp_backoff[tp->t_rxtshift];
TCPT_RANGESET(tp->t_rxtcur, rexmt,
tp->t_rttmin, TCPTV_REXMTMAX);
+
+ /*
+ * Check for potential Path MTU Discovery Black Hole
+ */
+
+ #if INET6
+ if ((tp->t_inpcb->inp_vflag & INP_IPV6) != 0 && tcp_pmtud_black_hole_detect && (tp->t_state == TCPS_ESTABLISHED)) {
+ if (tp->t_rxtshift == 2) {
+ /*
+ * Enter Path MTU Black-hole Detection mechanism:
+ * - Disable Path MTU Discovery (IP "DF" bit).
+ * - Reduce MTU to lower value than what we negociated with peer.
+ */
+
+ tp->t_flags |= TF_BLACKHOLE; /* Record that we may have found a black hole */
+ optlen = tp->t_maxopd - tp->t_maxseg;
+ tp->t_pmtud_saved_maxopd = tp->t_maxopd; /* Keep track of previous MSS */
+ if (tp->t_maxopd > tcp_pmtud_black_hole_mss)
+ tp->t_maxopd = tcp_pmtud_black_hole_mss; /* Reduce the MSS to intermediary value */
+ else {
+ tp->t_maxopd = V_tcp_v6mssdflt;
+ }
+ tp->t_maxseg = tp->t_maxopd - optlen;
+ }
+ /*
+ * If further retransmissions are still unsuccessful with a lowered MTU,
+ * maybe this isn't a Black Hole and we restore the previous MSS and
+ * blackhole detection flags.
+ */
+ else {
+
+ if ((tp->t_flags & TF_BLACKHOLE) && (tp->t_rxtshift > 4)) {
+ tp->t_flags &= ~TF_BLACKHOLE;
+ optlen = tp->t_maxopd - tp->t_maxseg;
+ tp->t_maxopd = tp->t_pmtud_saved_maxopd;
+ tp->t_maxseg = tp->t_maxopd - optlen;
+ }
+ }
+ }
+ #endif
+
/*
* Disable rfc1323 if we havn't got any response to
* our third SYN to work-around some broken terminal servers
diff -c netinet.org/tcp_var.h netinet/tcp_var.h
*** netinet.org/tcp_var.h Sun Oct 25 01:10:29 2009
--- netinet/tcp_var.h Mon Jun 14 09:21:25 2010
***************
*** 203,208 ****
--- 203,209 ----
int t_ispare; /* explicit pad for 64bit alignment */
void *t_pspare2[6]; /* 2 CC / 4 TBD */
uint64_t _pad[12]; /* 7 UTO, 5 TBD (1-2 CC/RTT?) */
+ u_int t_pmtud_saved_maxopd; /* MSS saved before performing PMTU-D BlackHole detection */
};
/*
***************
*** 234,239 ****
--- 235,241 ----
#define TF_ECN_PERMIT 0x4000000 /* connection ECN-ready */
#define TF_ECN_SND_CWR 0x8000000 /* ECN CWR in queue */
#define TF_ECN_SND_ECE 0x10000000 /* ECN ECE in queue */
+ #define TF_BLACKHOLE 0x20000000 /* Path MTU Discovery Black Hole detection */
#define IN_FASTRECOVERY(tp) (tp->t_flags & TF_FASTRECOVERY)
#define ENTER_FASTRECOVERY(tp) tp->t_flags |= TF_FASTRECOVERY
help
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?AANLkTikRI9hzTIn80qAEoKiHOjo0aeCZz5TJsgXUe-6->
