Index: sys/net/if_tun.c =================================================================== --- sys/net/if_tun.c +++ sys/net/if_tun.c @@ -131,6 +131,15 @@ static int tun_clone_create(struct if_clone *, int, caddr_t); static void tun_clone_destroy(struct ifnet *); + +#ifdef INET6 +/* + * XXX: declare here to avoid to include many inet6 related files.. + * should be more generalized? + */ +extern void nd6_setmtu(struct ifnet *); +#endif + static struct if_clone *tun_cloner; static d_open_t tunopen; @@ -665,13 +674,15 @@ int error; struct tun_softc *tp = dev->si_drv1; struct tuninfo *tunp; + u_long oldmtu; switch (cmd) { case TUNSIFINFO: tunp = (struct tuninfo *)data; if (tunp->mtu < IF_MINMTU) return (EINVAL); - if (TUN2IFP(tp)->if_mtu != tunp->mtu) { + oldmtu = TUN2IFP(tp)->if_mtu; + if (oldmtu != tunp->mtu) { error = priv_check(td, PRIV_NET_SETIFMTU); if (error) return (error); @@ -682,6 +693,19 @@ TUN2IFP(tp)->if_mtu = tunp->mtu; TUN2IFP(tp)->if_baudrate = tunp->baudrate; mtx_unlock(&tp->tun_mtx); + getmicrotime(&TUN2IFP(tp)->if_lastchange); + CURVNET_SET(TUN2IFP(tp)->if_vnet); + rt_ifmsg(TUN2IFP(tp)); + /* + * If the link MTU changed, do network layer specific procedure. + */ + if (TUN2IFP(tp)->if_mtu != oldmtu) { +#ifdef INET6 + nd6_setmtu(TUN2IFP(tp)); +#endif + rt_updatemtu(TUN2IFP(tp)); + } + CURVNET_RESTORE(); break; case TUNGIFINFO: tunp = (struct tuninfo *)data;