Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 22 May 2008 00:22:52 +0300
From:      "Niki Denev" <nike_d@cytexbg.com>
To:        "Max Laier" <max@love2party.net>
Cc:        freebsd-net@freebsd.org
Subject:   Re: lagg0.2 style vlans on lagg(4) interface
Message-ID:  <2e77fc10805211422q75603d54h5709ed3e5be37d0a@mail.gmail.com>
In-Reply-To: <200805212305.58235.max@love2party.net>
References:  <2e77fc10805211031n6c42ffd2u3dee28164094b83b@mail.gmail.com> <2e77fc10805211223l7fd69e4cwdd488bada0dc7b95@mail.gmail.com> <2e77fc10805211344m606886f9pd45ff7b001bc8da0@mail.gmail.com> <200805212305.58235.max@love2party.net>

next in thread | previous in thread | raw e-mail | index | archive | help
On Thu, May 22, 2008 at 12:05 AM, Max Laier <max@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;



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?2e77fc10805211422q75603d54h5709ed3e5be37d0a>