From 86e85007b500fe54023f94dad0fd3f5d566fc2ba Mon Sep 17 00:00:00 2001 From: Niels Provos Date: Mon, 11 Dec 2000 19:12:23 +0000 Subject: turn off path mtu when icmp needfrag messages get blocked, okay itojun@ --- sys/netinet/tcp_timer.c | 50 ++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 43 insertions(+), 7 deletions(-) (limited to 'sys/netinet/tcp_timer.c') diff --git a/sys/netinet/tcp_timer.c b/sys/netinet/tcp_timer.c index 4f7b1726439..c1e08b91f27 100644 --- a/sys/netinet/tcp_timer.c +++ b/sys/netinet/tcp_timer.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tcp_timer.c,v 1.17 2000/09/18 22:06:38 provos Exp $ */ +/* $OpenBSD: tcp_timer.c,v 1.18 2000/12/11 19:12:22 provos Exp $ */ /* $NetBSD: tcp_timer.c,v 1.14 1996/02/13 23:44:09 christos Exp $ */ /* @@ -60,6 +60,7 @@ #include #include #include +#include #include int tcp_keepidle = TCPTV_KEEP_IDLE; @@ -236,7 +237,7 @@ tcp_timers(tp, timer) rto * tcp_backoff[tp->t_rxtshift], tp->t_rttmin, TCPTV_REXMTMAX); tp->t_timer[TCPT_REXMT] = tp->t_rxtcur; -#if 0 + /* * If we are losing and we are trying path MTU discovery, * try turning it off. This will avoid black holes in @@ -245,15 +246,50 @@ tcp_timers(tp, timer) * lots more sophisticated searching to find the right * value here... */ - if (ip_mtudisc && tp->t_rxtshift > TCP_MAXRXTSHIFT / 6) { + if (ip_mtudisc && tp->t_inpcb && + tp->t_rxtshift > TCP_MAXRXTSHIFT / 6) { + struct inpcb *inp = tp->t_inpcb; struct rtentry *rt = NULL; + struct sockaddr_in sin; - if (tp->t_inpcb) - rt = in_pcbrtentry(tp->t_inpcb); - /* XXX: Black hole recovery code goes here */ - } + rt = in_pcbrtentry(inp); + /* Check if path MTU discovery is disabled already */ + if (rt && (rt->rt_flags & RTF_HOST) && + (rt->rt_rmx.rmx_locks & RTV_MTU)) + goto out; + + rt = NULL; + switch(tp->pf) { +#ifdef INET6 + case PF_INET6: + /* + * We can not turn off path MTU for IPv6. + * Do nothing for now, maybe lower to + * minimum MTU. + */ + break; #endif + case PF_INET: + bzero(&sin, sizeof(struct sockaddr_in)); + sin.sin_family = AF_INET; + sin.sin_len = sizeof(struct sockaddr_in); + sin.sin_addr = inp->inp_faddr; + rt = icmp_mtudisc_clone(sintosa(&sin)); + break; + } + if (rt != NULL) { + /* Disable path MTU discovery */ + if ((rt->rt_rmx.rmx_locks & RTV_MTU) == 0) { + rt->rt_rmx.rmx_locks |= RTV_MTU; + in_rtchange(inp, 0); + } + + rtfree(rt); + } + out: + } + /* * If losing, let the lower level know and try for * a better route. Also, if we backed off this far, -- cgit v1.2.3