git: f2ab91608440 - main - [vlan + lagg] add IFNET_EVENT_UPDATE_BAUDRATE event

From: Wojciech Macek <wma_at_FreeBSD.org>
Date: Fri, 20 May 2022 04:39:40 UTC
The branch main has been updated by wma:

URL: https://cgit.FreeBSD.org/src/commit/?id=f2ab91608440338e5574eff098ad4f69e4541a1d

commit f2ab91608440338e5574eff098ad4f69e4541a1d
Author:     Andrey V. Elsukov <ae@FreeBSD.org>
AuthorDate: 2022-05-19 06:02:27 +0000
Commit:     Wojciech Macek <wma@FreeBSD.org>
CommitDate: 2022-05-20 04:38:43 +0000

    [vlan + lagg] add IFNET_EVENT_UPDATE_BAUDRATE event
    
    use it to update if_baudrate for vlan interfaces created on the LACP lagg.
    
    Differential revision:  https://reviews.freebsd.org/D33405
---
 sys/net/ieee8023ad_lacp.c |  2 ++
 sys/net/if_var.h          |  1 +
 sys/net/if_vlan.c         | 35 +++++++++++++++++++++++++++++++++++
 3 files changed, 38 insertions(+)

diff --git a/sys/net/ieee8023ad_lacp.c b/sys/net/ieee8023ad_lacp.c
index 1e2e638fcdf5..6656ebb2b400 100644
--- a/sys/net/ieee8023ad_lacp.c
+++ b/sys/net/ieee8023ad_lacp.c
@@ -1090,6 +1090,8 @@ lacp_update_portmap(struct lacp_softc *lsc)
 		speed = lacp_aggregator_bandwidth(la);
 	}
 	sc->sc_ifp->if_baudrate = speed;
+	EVENTHANDLER_INVOKE(ifnet_event, sc->sc_ifp,
+	    IFNET_EVENT_UPDATE_BAUDRATE);
 
 	/* switch the active portmap over */
 	atomic_store_rel_int(&lsc->lsc_activemap, newmap);
diff --git a/sys/net/if_var.h b/sys/net/if_var.h
index e054c613e9e6..2c09795c6b36 100644
--- a/sys/net/if_var.h
+++ b/sys/net/if_var.h
@@ -515,6 +515,7 @@ EVENTHANDLER_DECLARE(ifnet_link_event, ifnet_link_event_handler_t);
 #define IFNET_EVENT_UP		0
 #define IFNET_EVENT_DOWN	1
 #define IFNET_EVENT_PCP		2	/* priority code point, PCP */
+#define	IFNET_EVENT_UPDATE_BAUDRATE	3
 
 typedef void (*ifnet_event_fn)(void *, struct ifnet *ifp, int event);
 EVENTHANDLER_DECLARE(ifnet_event, ifnet_event_fn);
diff --git a/sys/net/if_vlan.c b/sys/net/if_vlan.c
index 2bb5284c2129..dc7a5fcb0c73 100644
--- a/sys/net/if_vlan.c
+++ b/sys/net/if_vlan.c
@@ -221,6 +221,7 @@ static MALLOC_DEFINE(M_VLAN, vlanname, "802.1Q Virtual LAN Interface");
 
 static eventhandler_tag ifdetach_tag;
 static eventhandler_tag iflladdr_tag;
+static eventhandler_tag ifevent_tag;
 
 /*
  * if_vlan uses two module-level synchronizations primitives to allow concurrent
@@ -327,6 +328,7 @@ static	int vlan_clone_destroy(struct if_clone *, struct ifnet *);
 
 static	void vlan_ifdetach(void *arg, struct ifnet *ifp);
 static  void vlan_iflladdr(void *arg, struct ifnet *ifp);
+static  void vlan_ifevent(void *arg, struct ifnet *ifp, int event);
 
 static  void vlan_lladdr_fn(void *arg, int pending);
 
@@ -673,6 +675,34 @@ vlan_setmulti(struct ifnet *ifp)
 	return (0);
 }
 
+/*
+ * A handler for interface ifnet events.
+ */
+static void
+vlan_ifevent(void *arg __unused, struct ifnet *ifp, int event)
+{
+	struct epoch_tracker et;
+	struct ifvlan *ifv;
+	struct ifvlantrunk *trunk;
+
+	if (event != IFNET_EVENT_UPDATE_BAUDRATE)
+		return;
+
+	NET_EPOCH_ENTER(et);
+	trunk = ifp->if_vlantrunk;
+	if (trunk == NULL) {
+		NET_EPOCH_EXIT(et);
+		return;
+	}
+
+	TRUNK_WLOCK(trunk);
+	VLAN_FOREACH(ifv, trunk) {
+		ifv->ifv_ifp->if_baudrate = ifp->if_baudrate;
+	}
+	TRUNK_WUNLOCK(trunk);
+	NET_EPOCH_EXIT(et);
+}
+
 /*
  * A handler for parent interface link layer address changes.
  * If the parent interface link layer address is changed we
@@ -886,6 +916,10 @@ vlan_modevent(module_t mod, int type, void *data)
 		    vlan_iflladdr, NULL, EVENTHANDLER_PRI_ANY);
 		if (iflladdr_tag == NULL)
 			return (ENOMEM);
+		ifevent_tag = EVENTHANDLER_REGISTER(ifnet_event,
+		    vlan_ifevent, NULL, EVENTHANDLER_PRI_ANY);
+		if (ifevent_tag == NULL)
+			return (ENOMEM);
 		VLAN_LOCKING_INIT();
 		vlan_input_p = vlan_input;
 		vlan_link_state_p = vlan_link_state;
@@ -916,6 +950,7 @@ vlan_modevent(module_t mod, int type, void *data)
 #endif
 		EVENTHANDLER_DEREGISTER(ifnet_departure_event, ifdetach_tag);
 		EVENTHANDLER_DEREGISTER(iflladdr_event, iflladdr_tag);
+		EVENTHANDLER_DEREGISTER(ifnet_event, ifevent_tag);
 		vlan_input_p = NULL;
 		vlan_link_state_p = NULL;
 		vlan_trunk_cap_p = NULL;