lagg0.2 style vlans on lagg(4) interface
Niki Denev
nike_d at cytexbg.com
Wed May 21 21:22:53 UTC 2008
On Thu, May 22, 2008 at 12:05 AM, Max Laier <max at love2party.net> wrote:
> Looks good, though I'd probably move up the _INVOKE to before the ARPs are
> sent out. Probably between twiddling the hardware and sending ARPs
> (though that needs an else-case if the interface is still down). In fact
> the ARPs could be sent from an event hook, too. This would get rid of
> INET specific code in the LL-interface code.
>
I thought about moving it up too, but in this case isn't it going to
be called only if the interface is up (IFF_UP)?
Here is an updated version that makes vlan_lladdr_update() check if
ifp->if_vlantrunk exists,
because otherwise we get a panic if there is a change of the link
layer address on different interface that
does not have vlan children.
diff -ur /usr/src/.zfs/snapshot/orig/sys/net/if.c /usr/src/sys/net/if.c
--- /usr/src/.zfs/snapshot/orig/sys/net/if.c 2008-04-29 23:43:08.000000000 +0300
+++ /usr/src/sys/net/if.c 2008-05-21 23:48:59.621157217 +0300
@@ -2647,6 +2647,12 @@
}
#endif
}
+ /*
+ * Notify interested parties (clonable children like if_vlan(4))
+ * about the link layer address change
+ */
+ EVENTHANDLER_INVOKE(ifaddr_event, ifp);
+
return (0);
}
diff -ur /usr/src/.zfs/snapshot/orig/sys/net/if_vlan.c
/usr/src/sys/net/if_vlan.c
--- /usr/src/.zfs/snapshot/orig/sys/net/if_vlan.c 2007-10-28
18:24:16.000000000 +0200
+++ /usr/src/sys/net/if_vlan.c 2008-05-22 00:18:57.128613715 +0300
@@ -137,6 +137,7 @@
static MALLOC_DEFINE(M_VLAN, VLANNAME, "802.1Q Virtual LAN Interface");
static eventhandler_tag ifdetach_tag;
+static eventhandler_tag ifaddr_tag;
/*
* We have a global mutex, that is used to serialize configuration
@@ -518,6 +519,35 @@
/* For if_link_state_change() eyes only... */
extern void (*vlan_link_state_p)(struct ifnet *, int);
+/*
+ * Update vlan interface link layer address on
+ * parent interface link layer address change.
+ */
+static int
+vlan_lladdr_update(void *arg __unused, struct ifnet *ifp)
+{
+ struct ifvlantrunk *trunk = ifp->if_vlantrunk;
+ struct ifvlan *ifv;
+ int i;
+
+ if (trunk) {
+ TRUNK_LOCK(trunk);
+#ifdef VLAN_ARRAY
+ for (i = 0; i < VLAN_ARRAY_SIZE; i++)
+ if (trunk->vlans[i] != NULL) {
+ ifv = trunk->vlans[i];
+#else
+ for (i = 0; i < (1 << trunk->hwidth); i++) {
+ LIST_FOREACH(ifv, &trunk->hash[i], ifv_list)
+#endif
+ bcopy(IF_LLADDR(ifp), IF_LLADDR(ifv->ifv_ifp),
+ ETHER_ADDR_LEN);
+ }
+ TRUNK_UNLOCK(trunk);
+ }
+ return (0);
+}
+
static int
vlan_modevent(module_t mod, int type, void *data)
{
@@ -528,6 +558,10 @@
vlan_ifdetach, NULL, EVENTHANDLER_PRI_ANY);
if (ifdetach_tag == NULL)
return (ENOMEM);
+ ifaddr_tag = EVENTHANDLER_REGISTER(ifaddr_event,
+ vlan_lladdr_update, NULL, EVENTHANDLER_PRI_ANY);
+ if (ifaddr_tag == NULL)
+ return (ENOMEM);
VLAN_LOCK_INIT();
vlan_input_p = vlan_input;
vlan_link_state_p = vlan_link_state;
@@ -546,6 +580,7 @@
case MOD_UNLOAD:
if_clone_detach(&vlan_cloner);
EVENTHANDLER_DEREGISTER(ifnet_departure_event, ifdetach_tag);
+ EVENTHANDLER_DEREGISTER(ifaddr_event, ifaddr_tag);
vlan_input_p = NULL;
vlan_link_state_p = NULL;
vlan_trunk_cap_p = NULL;
More information about the freebsd-net
mailing list