summaryrefslogtreecommitdiffstats
path: root/freebsd/sys/net/if_vlan.c
diff options
context:
space:
mode:
Diffstat (limited to 'freebsd/sys/net/if_vlan.c')
-rw-r--r--freebsd/sys/net/if_vlan.c36
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: