summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNiels Provos <provos@cvs.openbsd.org>2001-06-23 03:10:22 +0000
committerNiels Provos <provos@cvs.openbsd.org>2001-06-23 03:10:22 +0000
commitf13e0c71f1aae8d4d488fcfdd478d86e9ce198f1 (patch)
treea8ae9862a393a032c28597319705cd3172bcdf84
parentea586daa1510e3d7de6d07245280f201186df118 (diff)
fix up mtu for routes and ongoing tcp connection when if mtu changes
from FreeBSD; fixes pr/1878
-rw-r--r--sys/netinet/ip_output.c14
-rw-r--r--sys/netinet/tcp_output.c12
2 files changed, 24 insertions, 2 deletions
diff --git a/sys/netinet/ip_output.c b/sys/netinet/ip_output.c
index c6ca2c6e493..dfd4cc19d63 100644
--- a/sys/netinet/ip_output.c
+++ b/sys/netinet/ip_output.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_output.c,v 1.105 2001/06/23 02:27:10 angelos Exp $ */
+/* $OpenBSD: ip_output.c,v 1.106 2001/06/23 03:10:21 provos Exp $ */
/* $NetBSD: ip_output.c,v 1.28 1996/02/13 23:43:07 christos Exp $ */
/*
@@ -621,6 +621,18 @@ sendit:
*/
if (ip->ip_off & IP_DF) {
error = EMSGSIZE;
+ /*
+ * This case can happen if the user changed the MTU
+ * of an interface after enabling IP on it. Because
+ * most netifs don't keep track of routes pointing to
+ * them, there is no way for one to update all its
+ * routes when the MTU is changed.
+ */
+ if ((ro->ro_rt->rt_flags & (RTF_UP | RTF_HOST))
+ && !(ro->ro_rt->rt_rmx.rmx_locks & RTV_MTU)
+ && (ro->ro_rt->rt_rmx.rmx_mtu > ifp->if_mtu)) {
+ ro->ro_rt->rt_rmx.rmx_mtu = ifp->if_mtu;
+ }
ipstat.ips_cantfrag++;
goto bad;
}
diff --git a/sys/netinet/tcp_output.c b/sys/netinet/tcp_output.c
index a694cc0886d..37c2419b1ca 100644
--- a/sys/netinet/tcp_output.c
+++ b/sys/netinet/tcp_output.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: tcp_output.c,v 1.37 2001/06/08 03:53:46 angelos Exp $ */
+/* $OpenBSD: tcp_output.c,v 1.38 2001/06/23 03:10:21 provos Exp $ */
/* $NetBSD: tcp_output.c,v 1.16 1997/06/03 16:17:09 kml Exp $ */
/*
@@ -1102,6 +1102,16 @@ out:
tcp_quench(tp->t_inpcb, 0);
return (0);
}
+ if (error == EMSGSIZE) {
+ /*
+ * ip_output() will have already fixed the route
+ * for us. tcp_mtudisc() will, as its last action,
+ * initiate retransmission, so it is important to
+ * not do so here.
+ */
+ tcp_mtudisc(tp->t_inpcb, 0);
+ return (0);
+ }
if ((error == EHOSTUNREACH || error == ENETDOWN)
&& TCPS_HAVERCVDSYN(tp->t_state)) {
tp->t_softerror = error;