Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 18 Dec 2025 19:16:02 +0000
From:      Gleb Smirnoff <glebius@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: 713b57c414b7 - main - net: split ifnet_arrival_event into two events
Message-ID:  <694452f2.346f3.4214bebb@gitrepo.freebsd.org>

index | next in thread | raw e-mail

The branch main has been updated by glebius:

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

commit 713b57c414b789fd6c3eb2ce7ecb682b6cb4ba30
Author:     Gleb Smirnoff <glebius@FreeBSD.org>
AuthorDate: 2025-12-18 16:47:31 +0000
Commit:     Gleb Smirnoff <glebius@FreeBSD.org>
CommitDate: 2025-12-18 19:15:53 +0000

    net: split ifnet_arrival_event into two events
    
    Run the original ifnet_arrival_event before linking the interface.
    Otherwise there is a race window when interface is already visible, but
    not all of the protocols have completed their attach. Provide a new event
    handler ifnet_attached_event, that is executed when the inteface is fully
    visible.  Use it in route(4) socket and netlink(4) to announce new
    interface to the userland. Properly document the ifnet events in if_var.h.
    
    Reviewed by:            zlei, melifaro
    Differential Revision:  https://reviews.freebsd.org/D54085
---
 sys/net/if.c              |  5 ++---
 sys/net/if_var.h          | 23 +++++++++++++++++------
 sys/net/rtsock.c          |  4 ++--
 sys/netlink/route/iface.c |  2 +-
 4 files changed, 22 insertions(+), 12 deletions(-)

diff --git a/sys/net/if.c b/sys/net/if.c
index d7c6b22821e2..b603c72bd106 100644
--- a/sys/net/if.c
+++ b/sys/net/if.c
@@ -932,10 +932,9 @@ if_attach_internal(struct ifnet *ifp, bool vmove)
 
 	if (domain_init_status >= 2)
 		if_attachdomain1(ifp);
-
-	if_link_ifnet(ifp);
-
 	EVENTHANDLER_INVOKE(ifnet_arrival_event, ifp);
+	if_link_ifnet(ifp);
+	EVENTHANDLER_INVOKE(ifnet_attached_event, ifp);
 	if (IS_DEFAULT_VNET(curvnet))
 		devctl_notify("IFNET", ifp->if_xname, "ATTACH", NULL);
 }
diff --git a/sys/net/if_var.h b/sys/net/if_var.h
index b717e879815b..cbc4969918ba 100644
--- a/sys/net/if_var.h
+++ b/sys/net/if_var.h
@@ -358,12 +358,23 @@ typedef void (*ifaddr_event_ext_handler_t)(void *, if_t, struct ifaddr *, int);
 EVENTHANDLER_DECLARE(ifaddr_event_ext, ifaddr_event_ext_handler_t);
 #define	IFADDR_EVENT_ADD	0
 #define	IFADDR_EVENT_DEL	1
-/* new interface arrival event */
-typedef void (*ifnet_arrival_event_handler_t)(void *, if_t);
-EVENTHANDLER_DECLARE(ifnet_arrival_event, ifnet_arrival_event_handler_t);
-/* interface departure event */
-typedef void (*ifnet_departure_event_handler_t)(void *, if_t);
-EVENTHANDLER_DECLARE(ifnet_departure_event, ifnet_departure_event_handler_t);
+
+/*
+ * Interface arrival & departure events.
+ * The ifnet_arrival_event is executed before the is yet globally visible.
+ * Protocols shall use this event to attach themselves.  Protocols shall not
+ * expect other protocols to be fully attached.
+ * The ifnet_attached_event is executed after the interface is attached to all
+ * protocols, is globally visible and fully functional.
+ * The ifnet_departure_event is complementary to ifnet_arrival_event.  The
+ * interface is no longer globally visible, protocols may detach.
+ * XXXGL: immediate memory reclamation may not be safe in ifnet_departure_event.
+ */
+typedef void (*ifnet_event_handler_t)(void *, if_t);
+EVENTHANDLER_DECLARE(ifnet_arrival_event, ifnet_event_handler_t);
+EVENTHANDLER_DECLARE(ifnet_attached_event, ifnet_event_handler_t);
+EVENTHANDLER_DECLARE(ifnet_departure_event, ifnet_event_handler_t);
+
 /* Interface link state change event */
 typedef void (*ifnet_link_event_handler_t)(void *, if_t, int);
 EVENTHANDLER_DECLARE(ifnet_link_event, ifnet_link_event_handler_t);
diff --git a/sys/net/rtsock.c b/sys/net/rtsock.c
index be858428bb3e..82af92545b79 100644
--- a/sys/net/rtsock.c
+++ b/sys/net/rtsock.c
@@ -317,11 +317,11 @@ rtsock_init(void *dummy __unused)
 SYSINIT(rtsock_init, SI_SUB_PROTO_DOMAIN, SI_ORDER_THIRD, rtsock_init, NULL);
 
 static void
-rts_handle_ifnet_arrival(void *arg __unused, struct ifnet *ifp)
+rts_ifnet_attached(void *arg __unused, struct ifnet *ifp)
 {
 	rt_ifannouncemsg(ifp, IFAN_ARRIVAL);
 }
-EVENTHANDLER_DEFINE(ifnet_arrival_event, rts_handle_ifnet_arrival, NULL, 0);
+EVENTHANDLER_DEFINE(ifnet_attached_event, rts_ifnet_attached, NULL, 0);
 
 static void
 rts_handle_ifnet_departure(void *arg __unused, struct ifnet *ifp)
diff --git a/sys/netlink/route/iface.c b/sys/netlink/route/iface.c
index 70ec5e688c57..29a9a89fd20c 100644
--- a/sys/netlink/route/iface.c
+++ b/sys/netlink/route/iface.c
@@ -1508,7 +1508,7 @@ void
 rtnl_ifaces_init(void)
 {
 	ifattach_event = EVENTHANDLER_REGISTER(
-	    ifnet_arrival_event, rtnl_handle_ifattach, NULL,
+	    ifnet_attached_event, rtnl_handle_ifattach, NULL,
 	    EVENTHANDLER_PRI_ANY);
 	ifdetach_event = EVENTHANDLER_REGISTER(
 	    ifnet_departure_event, rtnl_handle_ifdetach, NULL,


help

Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?694452f2.346f3.4214bebb>