Index: sys/netinet6/ip6_output.c =================================================================== --- sys/netinet6/ip6_output.c +++ sys/netinet6/ip6_output.c @@ -1302,6 +1302,7 @@ uint32_t scopeid; struct sockaddr_in6 *sa6_dst; u_long mtu; + u_int32_t ifmtu; mtu = 0; if (do_lookup) { @@ -1330,8 +1331,24 @@ mtu = ro_pmtu->ro_mtu; } - if (ro_pmtu->ro_rt) + if (ro_pmtu->ro_rt) { + if (ifp == NULL) + ifp = ro_pmtu->ro_rt->rt_ifp; + ifmtu = IN6_LINKMTU(ifp); mtu = ro_pmtu->ro_rt->rt_mtu; + /* + * The MTU on the route is larger than the MTU on + * the interface! This shouldn't happen, unless the + * MTU of the interface has been changed after the + * interface was brought up. Change the MTU in the + * route to match the interface MTU (as long as the + * field isn't locked). + */ + if (ifmtu < mtu) { + mtu = ifmtu; + ro_pmtu->ro_rt->rt_mtu = mtu; + } + } return (ip6_calcmtu(ifp, dst, mtu, mtup, alwaysfragp, proto)); }