Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F114446193
D506.id1666.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
6 KB
Referenced Files
None
Subscribers
None
D506.id1666.diff
View Options
Index: sys/netinet/tcp_output.c
===================================================================
--- sys/netinet/tcp_output.c
+++ sys/netinet/tcp_output.c
@@ -675,6 +675,12 @@
send:
SOCKBUF_LOCK_ASSERT(&so->so_snd);
+ if (len > 0) {
+ if (len >= tp->t_maxseg)
+ tp->t_pmtud_flags |= PLPMTU_MAXSEGSNT;
+ else
+ tp->t_pmtud_flags &= ~PLPMTU_MAXSEGSNT;
+ }
/*
* Before ESTABLISHED, force sending of initial options
* unless TCP set not to do any options.
@@ -1219,8 +1225,12 @@
*
* NB: Don't set DF on small MTU/MSS to have a safe fallback.
*/
- if (V_path_mtu_discovery && tp->t_maxopd > V_tcp_minmss)
+ if (V_path_mtu_discovery && tp->t_maxopd > V_tcp_minmss) {
ip->ip_off |= htons(IP_DF);
+ tp->t_pmtud_flags |= PLPMTU_PMTUD;
+ } else {
+ tp->t_pmtud_flags &= ~PLPMTU_PMTUD;
+ }
if (tp->t_state == TCPS_SYN_SENT)
TCP_PROBE5(connect__request, NULL, tp, ip, tp, th);
Index: sys/netinet/tcp_timer.c
===================================================================
--- sys/netinet/tcp_timer.c
+++ sys/netinet/tcp_timer.c
@@ -66,6 +66,9 @@
#include <netinet/tcp_fsm.h>
#include <netinet/tcp_timer.h>
#include <netinet/tcp_var.h>
+#ifdef INET6
+#include <netinet6/tcp6_var.h>
+#endif
#include <netinet/tcpip.h>
#ifdef TCPDEBUG
#include <netinet/tcp_debug.h>
@@ -127,6 +130,35 @@
&tcp_rexmit_drop_options, 0,
"Drop TCP options from 3rd and later retransmitted SYN");
+
+VNET_DECLARE(int, tcp_pmtud_black_hole_detect);
+#define V_tcp_pmtud_black_hole_detect VNET(tcp_pmtud_black_hole_detect)
+
+VNET_DEFINE(int, tcp_pmtud_black_hole_detect) = 0;
+SYSCTL_VNET_INT(_net_inet_tcp, OID_AUTO, pmtud_blackhole_detection,
+ CTLTYPE_INT|CTLFLAG_RW, &VNET_NAME(tcp_pmtud_black_hole_detect), 0,
+ "Path MTU Discovery Black Hole Detection");
+
+#ifdef INET
+VNET_DECLARE(int, tcp_pmtud_black_hole_mss);
+#define V_tcp_pmtud_black_hole_mss VNET(tcp_pmtud_black_hole_mss)
+
+VNET_DEFINE(int, tcp_pmtud_black_hole_mss) = 536;
+SYSCTL_INT(_net_inet_tcp, OID_AUTO, pmtud_blackhole_mss,
+ CTLTYPE_INT|CTLFLAG_RW, &VNET_NAME(tcp_pmtud_black_hole_mss), 0,
+ "Path MTU Discovery Black Hole Detection lowered MSS");
+#endif
+
+#ifdef INET6
+VNET_DECLARE(int, tcp_v6pmtud_black_hole_mss);
+#define V_tcp_v6pmtud_black_hole_mss VNET(tcp_v6pmtud_black_hole_mss)
+
+VNET_DEFINE(int, tcp_v6pmtud_black_hole_mss) = 1220;
+SYSCTL_INT(_net_inet_tcp, OID_AUTO, v6pmtud_blackhole_mss,
+ CTLTYPE_INT|CTLFLAG_RW, &VNET_NAME(tcp_v6pmtud_black_hole_mss), 0,
+ "Path MTU Discovery IPv6 Black Hole Detection lowered MSS");
+#endif
+
#ifdef RSS
static int per_cpu_timers = 1;
#else
@@ -539,6 +571,10 @@
ostate = tp->t_state;
#endif
+#if defined(INET6) && defined(INET)
+ int isipv6;
+#endif
+
INP_INFO_RLOCK(&V_tcbinfo);
inp = tp->t_inpcb;
/*
@@ -640,6 +676,89 @@
rexmt = TCP_REXMTVAL(tp) * tcp_backoff[tp->t_rxtshift];
TCPT_RANGESET(tp->t_rxtcur, rexmt,
tp->t_rttmin, TCPTV_REXMTMAX);
+
+ if (V_tcp_pmtud_black_hole_detect && (tp->t_state == TCPS_ESTABLISHED)) {
+ int optlen = 0;
+ if (((tp->t_pmtud_flags & (PLPMTU_PMTUD|PLPMTU_MAXSEGSNT)) ==
+ (PLPMTU_PMTUD|PLPMTU_MAXSEGSNT)) &&
+ (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.
+ */
+ /* Disable Path MTU Discovery for now */
+ tp->t_pmtud_flags &= ~PLPMTU_PMTUD;
+ /* Record that we may have found a black hole */
+ tp->t_pmtud_flags |= PLPMTU_BLACKHOLE;
+ optlen = tp->t_maxopd - tp->t_maxseg;
+ /* Keep track of previous MSS */
+ tp->t_pmtud_saved_maxopd = tp->t_maxopd;
+
+#if defined(INET6) && defined(INET)
+ isipv6 = (tp->t_inpcb->inp_vflag & INP_IPV6) ? 1 : 0;
+
+ /* Reduce the MSS to intermediary value */
+ if (ispiv6)
+#endif
+#if defined(INET6)
+ if (tp->t_maxopd > V_tcp_pmtud_black_hole_mss) {
+#elif defined (INET)
+ if (tp->t_maxopd > V_tcp_pmtud_black_hole_mss) {
+#endif
+ /* use the sysctl tuneable blackhole MSS */
+ tp->t_maxopd =
+#if defined(INET6) && defined(INET)
+ isipv6 ? V_tcp_v6pmtud_black_hole_mss :
+ V_tcp_pmtud_black_hole_mss;
+#elif defined (INET6)
+ V_tcp_v6pmtud_black_hole_mss;
+#elif defined (INET)
+ V_tcp_pmtud_black_hole_mss;
+#endif /* INET6 vs INET checks */
+ } else {
+ /* use the default MSS */
+ tp->t_maxopd =
+#if defined(INET6) && defined(INET)
+ isipv6 ? V_tcp_v6mssdflt :
+ V_tcp_mssdflt;
+#elif defined (INET6)
+ V_tcp_v6mssdflt;
+#elif defined (INET)
+ V_tcp_mssdflt;
+#endif /* INET6 */
+ }
+ tp->t_maxseg = tp->t_maxopd - optlen;
+ /*
+ * Reset the slow-start flight size
+ * as it may depend on the new MSS
+ */
+ if (CC_ALGO(tp)->conn_init != NULL)
+ CC_ALGO(tp)->conn_init(tp->ccv);
+ } else {
+ /*
+ * 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.
+ */
+ if ((tp->t_pmtud_flags & PLPMTU_BLACKHOLE) &&
+ (tp->t_rxtshift > 4)) {
+ tp->t_pmtud_flags |= PLPMTU_PMTUD;
+ tp->t_pmtud_flags &= ~PLPMTU_BLACKHOLE;
+ optlen = tp->t_maxopd - tp->t_maxseg;
+ tp->t_maxopd = tp->t_pmtud_saved_maxopd;
+ tp->t_maxseg = tp->t_maxopd - optlen;
+ /*
+ * Reset the slow-start flight size as it
+ * may depend on the new MSS.
+ */
+ if (CC_ALGO(tp)->conn_init != NULL)
+ CC_ALGO(tp)->conn_init(tp->ccv);
+ }
+ }
+ }
+
/*
* Disable RFC1323 and SACK if we haven't got any response to
* our third SYN to work-around some broken terminal servers
Index: sys/netinet/tcp_var.h
===================================================================
--- sys/netinet/tcp_var.h
+++ sys/netinet/tcp_var.h
@@ -200,6 +200,8 @@
u_int t_keepcnt; /* number of keepalives before close */
u_int t_tsomax; /* tso burst length limit */
+ u_int t_pmtud_saved_maxopd; /* pre-blackhole MSS */
+ u_int t_pmtud_flags; /* PLPMTU flags */
uint32_t t_ispare[8]; /* 5 UTO, 3 TBD */
void *t_pspare2[4]; /* 1 TCP_SIGNATURE, 3 TBD */
@@ -275,6 +277,13 @@
#endif /* TCP_SIGNATURE */
/*
+ * Flags for PLPMTU handling, t_pmtu_flags
+ */
+#define PLPMTU_BLACKHOLE 0x00000001 /* possible PLPMTUD Black Hole */
+#define PLPMTU_PMTUD 0x00000002 /* allowed to attempt PLPMTUD */
+#define PLPMTU_MAXSEGSNT 0x00000004 /* last segment sent was full seg */
+
+/*
* Structure to hold TCP options that are only used during segment
* processing (in tcp_input), but not held in the tcpcb.
* It's basically used to reduce the number of parameters
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sun, Apr 13, 3:40 PM (6 h, 14 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
17500528
Default Alt Text
D506.id1666.diff (6 KB)
Attached To
Mode
D506: Merge PLPMTU blackhole detection from xnu.
Attached
Detach File
Event Timeline
Log In to Comment