Index: sys/net/if_tap.c =================================================================== --- sys/net/if_tap.c +++ sys/net/if_tap.c @@ -38,6 +38,7 @@ */ #include "opt_inet.h" +#include "opt_inet6.h" #include #include @@ -103,6 +104,15 @@ static struct if_clone *tap_cloner; static int vmnet_clone_create(struct if_clone *, int, caddr_t); static void vmnet_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 *vmnet_cloner; /* character device */ @@ -726,6 +736,8 @@ struct tap_softc *tp = dev->si_drv1; struct ifnet *ifp = tp->tap_ifp; struct tapinfo *tapp = NULL; + u_long oldmtu; + int error; int f; #if defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD5) || \ defined(COMPAT_FREEBSD4) @@ -735,12 +747,34 @@ switch (cmd) { case TAPSIFINFO: tapp = (struct tapinfo *)data; + if (tapp->mtu < IF_MINMTU) + return (EINVAL); + oldmtu = ifp->if_mtu; + if (oldmtu != tapp->mtu) { + error = priv_check(td, PRIV_NET_SETIFMTU); + if (error) + return (error); + } if (ifp->if_type != tapp->type) return (EPROTOTYPE); mtx_lock(&tp->tap_mtx); ifp->if_mtu = tapp->mtu; ifp->if_baudrate = tapp->baudrate; mtx_unlock(&tp->tap_mtx); + getmicrotime(&ifp->if_lastchange); + CURVNET_SET(ifp->if_vnet); + rt_ifmsg(ifp); + /* + * If the link MTU changed, do network layer specific + * procedure. + */ + if (ifp->if_mtu != oldmtu) { +#ifdef INET6 + nd6_setmtu(ifp); +#endif + rt_updatemtu(ifp); + } + CURVNET_RESTORE(); break; case TAPGIFINFO: 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;