diff --git a/sys/net/if_bridge.c b/sys/net/if_bridge.c index f884c039b52..c40928f75af 100644 --- a/sys/net/if_bridge.c +++ b/sys/net/if_bridge.c @@ -135,6 +135,14 @@ __FBSDID("$FreeBSD$"); #include +#ifdef INET6 +/* + * XXX: declare here to avoid to include many inet6 related files.. + * should be more generalized? + */ +extern void nd6_setmtu(struct ifnet *); +#endif + /* * Size of the route hash table. Must be a power of two. */ @@ -772,7 +780,7 @@ bridge_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) } args; struct ifdrv *ifd = (struct ifdrv *) data; const struct bridge_control *bc; - int error = 0; + int error = 0, oldmtu; switch (cmd) { @@ -818,12 +826,24 @@ bridge_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) break; } + oldmtu = ifp->if_mtu; BRIDGE_LOCK(sc); error = (*bc->bc_func)(sc, &args); BRIDGE_UNLOCK(sc); if (error) break; + /* + * Bridge MTU may change during addition of the first port. + * If it did, do network layer specific procedure. + */ + if (ifp->if_mtu != oldmtu) { +#ifdef INET6 + nd6_setmtu(ifp); +#endif + rt_updatemtu(ifp); + } + if (bc->bc_flags & BC_F_COPYOUT) error = copyout(&args, ifd->ifd_data, ifd->ifd_len); diff --git a/sys/net/if_lagg.c b/sys/net/if_lagg.c index 174fd4479d8..d38f772f689 100644 --- a/sys/net/if_lagg.c +++ b/sys/net/if_lagg.c @@ -53,6 +53,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #if defined(INET) || defined(INET6) @@ -74,6 +75,14 @@ __FBSDID("$FreeBSD$"); #include #include +#ifdef INET6 +/* + * XXX: declare here to avoid to include many inet6 related files.. + * should be more generalized? + */ +extern void nd6_setmtu(struct ifnet *); +#endif + #define LAGG_RLOCK() struct epoch_tracker lagg_et; epoch_enter_preempt(net_epoch_preempt, &lagg_et) #define LAGG_RUNLOCK() epoch_exit_preempt(net_epoch_preempt, &lagg_et) #define LAGG_RLOCK_ASSERT() NET_EPOCH_ASSERT() @@ -1178,7 +1187,7 @@ lagg_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) struct ifnet *tpif; struct thread *td = curthread; char *buf, *outbuf; - int count, buflen, len, error = 0; + int count, buflen, len, error = 0, oldmtu; bzero(&rpbuf, sizeof(rpbuf)); @@ -1453,10 +1462,23 @@ lagg_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) tpif->if_xname); } #endif + oldmtu = ifp->if_mtu; LAGG_XLOCK(sc); error = lagg_port_create(sc, tpif); LAGG_XUNLOCK(sc); if_rele(tpif); + + /* + * LAGG MTU may change during addition of the first port. + * If it did, do network layer specific procedure. + */ + if (ifp->if_mtu != oldmtu) { +#ifdef INET6 + nd6_setmtu(ifp); +#endif + rt_updatemtu(ifp); + } + VLAN_CAPABILITIES(ifp); break; case SIOCSLAGGDELPORT: diff --git a/sys/net/if_vlan.c b/sys/net/if_vlan.c index 88844b0e848..a9ab3f85018 100644 --- a/sys/net/if_vlan.c +++ b/sys/net/if_vlan.c @@ -46,6 +46,7 @@ __FBSDID("$FreeBSD$"); #include "opt_inet.h" +#include "opt_inet6.h" #include "opt_kern_tls.h" #include "opt_vlan.h" #include "opt_ratelimit.h" @@ -75,6 +76,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #ifdef INET @@ -82,6 +84,14 @@ __FBSDID("$FreeBSD$"); #include #endif +#ifdef INET6 +/* + * XXX: declare here to avoid to include many inet6 related files.. + * should be more generalized? + */ +extern void nd6_setmtu(struct ifnet *); +#endif + #define VLAN_DEF_HWIDTH 4 #define VLAN_IFFLAGS (IFF_BROADCAST | IFF_MULTICAST) @@ -1807,7 +1817,7 @@ vlan_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) struct ifvlan *ifv; struct ifvlantrunk *trunk; struct vlanreq vlr; - int error = 0; + int error = 0, oldmtu; ifr = (struct ifreq *)data; ifa = (struct ifaddr *) data; @@ -1901,8 +1911,20 @@ vlan_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) error = ENOENT; break; } + oldmtu = ifp->if_mtu; error = vlan_config(ifv, p, vlr.vlr_tag); if_rele(p); + + /* + * VLAN MTU may change during addition of the vlandev. + * If it did, do network layer specific procedure. + */ + if (ifp->if_mtu != oldmtu) { +#ifdef INET6 + nd6_setmtu(ifp); +#endif + rt_updatemtu(ifp); + } break; case SIOCGETVLAN: