lagg0.2 style vlans on lagg(4) interface

Niki Denev nike_d at cytexbg.com
Wed May 21 20:44:43 UTC 2008


On Wed, May 21, 2008 at 8:44 PM, Max Laier <max at love2party.net> wrote:
>> It doesn't (and shouldn't have to).  I'd simply add an
>> EVENTHANDLER_INVOKE(ifaddr_event, ifp) to if_setlladdr() - we do that for
>> INET[6] address already.  Then vlan (and any other device interested in
>> LLaddress changes) can simply register to that eventhandler and resync.
>>

Hi,
Does this look like a reasonable solution?
It passes my limited testing.

Niki

diff -ur /usr/src/sys/net/if.c
/usr/src/.zfs/snapshot/vlan_lladdr_patch/sys/net/if.c
--- /usr/src/sys/net/if.c       2008-04-29 23:43:08.000000000 +0300
+++ /usr/src/.zfs/snapshot/vlan_lladdr_patch/sys/net/if.c
2008-05-21 22:12:33.989318352 +0300
@@ -2647,6 +2647,11 @@
                }
 #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/sys/net/if_vlan.c
/usr/src/.zfs/snapshot/vlan_lladdr_patch/sys/net/if_vlan.c
--- /usr/src/sys/net/if_vlan.c  2007-10-28 18:24:16.000000000 +0200
+++ /usr/src/.zfs/snapshot/vlan_lladdr_patch/sys/net/if_vlan.c
2008-05-21 23:24:13.322156460 +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,33 @@
 /* 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;
+
+       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 +556,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 +578,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