diff options
Diffstat (limited to 'freebsd/sys/net/if_vlan.c')
-rw-r--r-- | freebsd/sys/net/if_vlan.c | 36 |
1 files changed, 33 insertions, 3 deletions
diff --git a/freebsd/sys/net/if_vlan.c b/freebsd/sys/net/if_vlan.c index 8f108b9d..2b5b3488 100644 --- a/freebsd/sys/net/if_vlan.c +++ b/freebsd/sys/net/if_vlan.c @@ -48,6 +48,7 @@ __FBSDID("$FreeBSD$"); #include <rtems/bsd/local/opt_inet.h> +#include <rtems/bsd/local/opt_inet6.h> #include <rtems/bsd/local/opt_vlan.h> #include <rtems/bsd/local/opt_ratelimit.h> @@ -76,6 +77,7 @@ __FBSDID("$FreeBSD$"); #include <net/if_dl.h> #include <net/if_types.h> #include <net/if_vlan_var.h> +#include <net/route.h> #include <net/vnet.h> #ifdef INET @@ -83,6 +85,14 @@ __FBSDID("$FreeBSD$"); #include <netinet/if_ether.h> #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) @@ -1410,11 +1420,19 @@ vlan_config(struct ifvlan *ifv, struct ifnet *p, uint16_t vid) * Set up our interface address to reflect the underlying * physical interface's. */ - bcopy(IF_LLADDR(p), IF_LLADDR(ifp), p->if_addrlen); + TASK_INIT(&ifv->lladdr_task, 0, vlan_lladdr_fn, ifv); ((struct sockaddr_dl *)ifp->if_addr->ifa_addr)->sdl_alen = p->if_addrlen; - TASK_INIT(&ifv->lladdr_task, 0, vlan_lladdr_fn, ifv); + /* + * Do not schedule link address update if it was the same + * as previous parent's. This helps avoid updating for each + * associated llentry. + */ + if (memcmp(IF_LLADDR(p), IF_LLADDR(ifp), p->if_addrlen) != 0) { + bcopy(IF_LLADDR(p), IF_LLADDR(ifp), p->if_addrlen); + taskqueue_enqueue(taskqueue_thread, &ifv->lladdr_task); + } /* We are ready for operation now. */ ifp->if_drv_flags |= IFF_DRV_RUNNING; @@ -1725,7 +1743,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; @@ -1819,8 +1837,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: |