The branch main has been updated by glebius:

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

commit 0bd0c3295ac09f759f2816b73cbd2d950e3bef7e
Author:     Gleb Smirnoff <[email protected]>
AuthorDate: 2025-12-21 22:13:58 +0000
Commit:     Gleb Smirnoff <[email protected]>
CommitDate: 2025-12-22 02:23:14 +0000

    ng_ether: refactor to use interface EVENTHANDLER(9)s
---
 sys/net/ethernet.h      |   4 --
 sys/net/if.c            |   5 --
 sys/net/if_bridge.c     |   2 -
 sys/net/if_ethersubr.c  |  32 -----------
 sys/netgraph/ng_ether.c | 141 ++++++++++++++++++++++--------------------------
 5 files changed, 64 insertions(+), 120 deletions(-)

diff --git a/sys/net/ethernet.h b/sys/net/ethernet.h
index 01485cf26e06..85e0ddb74144 100644
--- a/sys/net/ethernet.h
+++ b/sys/net/ethernet.h
@@ -460,10 +460,6 @@ extern     uint32_t ether_crc32_be(const uint8_t *, 
size_t);
 extern void ether_demux(struct ifnet *, struct mbuf *);
 extern void ether_ifattach(struct ifnet *, const u_int8_t *);
 extern void ether_ifdetach(struct ifnet *);
-#ifdef VIMAGE
-struct vnet;
-extern void ether_reassign(struct ifnet *, struct vnet *, char *);
-#endif
 extern int  ether_ioctl(struct ifnet *, u_long, caddr_t);
 extern int  ether_output(struct ifnet *, struct mbuf *,
            const struct sockaddr *, struct route *);
diff --git a/sys/net/if.c b/sys/net/if.c
index 1dea00da3cf2..4ddf8a69b3f0 100644
--- a/sys/net/if.c
+++ b/sys/net/if.c
@@ -239,7 +239,6 @@ static MALLOC_DEFINE(M_IFDESCR, "ifdescr", "ifnet 
descriptions");
 static struct sx ifdescr_sx;
 SX_SYSINIT(ifdescr_sx, &ifdescr_sx, "ifnet descr");
 
-void   (*ng_ether_link_state_p)(struct ifnet *ifp, int state);
 void   (*lagg_linkstate_p)(struct ifnet *ifp, int state);
 /* These are external hooks for CARP. */
 void   (*carp_linkstate_p)(struct ifnet *ifp);
@@ -2031,10 +2030,6 @@ do_link_state_change(void *arg, int pending)
        rt_ifmsg(ifp, 0);
        if (ifp->if_vlantrunk != NULL)
                (*vlan_link_state_p)(ifp);
-
-       if ((ifp->if_type == IFT_ETHER || ifp->if_type == IFT_L2VLAN) &&
-           ifp->if_l2com != NULL)
-               (*ng_ether_link_state_p)(ifp, link_state);
        if (ifp->if_carp)
                (*carp_linkstate_p)(ifp);
        if (ifp->if_bridge)
diff --git a/sys/net/if_bridge.c b/sys/net/if_bridge.c
index d7911a348d87..9a468a8eb462 100644
--- a/sys/net/if_bridge.c
+++ b/sys/net/if_bridge.c
@@ -801,8 +801,6 @@ bridge_reassign(struct ifnet *ifp, struct vnet *newvnet, 
char *arg)
        }
 
        BRIDGE_UNLOCK(sc);
-
-       ether_reassign(ifp, newvnet, arg);
 }
 #endif
 
diff --git a/sys/net/if_ethersubr.c b/sys/net/if_ethersubr.c
index 9c157bf3d3c2..da9264aa4a23 100644
--- a/sys/net/if_ethersubr.c
+++ b/sys/net/if_ethersubr.c
@@ -98,8 +98,6 @@ VNET_DEFINE(pfil_head_t, link_pfil_head);     /* Packet 
filter hooks */
 void   (*ng_ether_input_p)(struct ifnet *ifp, struct mbuf **mp);
 void   (*ng_ether_input_orphan_p)(struct ifnet *ifp, struct mbuf *m);
 int    (*ng_ether_output_p)(struct ifnet *ifp, struct mbuf **mp);
-void   (*ng_ether_attach_p)(struct ifnet *ifp);
-void   (*ng_ether_detach_p)(struct ifnet *ifp);
 
 /* if_bridge(4) support */
 void   (*bridge_dn_p)(struct mbuf *, struct ifnet *);
@@ -988,9 +986,6 @@ ether_ifattach(struct ifnet *ifp, const u_int8_t *lla)
        ifp->if_input = ether_input;
        ifp->if_resolvemulti = ether_resolvemulti;
        ifp->if_requestencap = ether_requestencap;
-#ifdef VIMAGE
-       ifp->if_reassign = ether_reassign;
-#endif
        if (ifp->if_baudrate == 0)
                ifp->if_baudrate = IF_Mbps(10);         /* just a default */
        ifp->if_broadcastaddr = etherbroadcastaddr;
@@ -1006,8 +1001,6 @@ ether_ifattach(struct ifnet *ifp, const u_int8_t *lla)
                bcopy(lla, ifp->if_hw_addr, ifp->if_addrlen);
 
        bpfattach(ifp, DLT_EN10MB, ETHER_HDR_LEN);
-       if (ng_ether_attach_p != NULL)
-               (*ng_ether_attach_p)(ifp);
 
        /* Announce Ethernet MAC address if non-zero. */
        for (i = 0; i < ifp->if_addrlen; i++)
@@ -1035,35 +1028,10 @@ ether_ifdetach(struct ifnet *ifp)
        sdl = (struct sockaddr_dl *)(ifp->if_addr->ifa_addr);
        uuid_ether_del(LLADDR(sdl));
 
-       if (ifp->if_l2com != NULL) {
-               KASSERT(ng_ether_detach_p != NULL,
-                   ("ng_ether_detach_p is NULL"));
-               (*ng_ether_detach_p)(ifp);
-       }
-
        bpfdetach(ifp);
        if_detach(ifp);
 }
 
-#ifdef VIMAGE
-void
-ether_reassign(struct ifnet *ifp, struct vnet *new_vnet, char *unused __unused)
-{
-
-       if (ifp->if_l2com != NULL) {
-               KASSERT(ng_ether_detach_p != NULL,
-                   ("ng_ether_detach_p is NULL"));
-               (*ng_ether_detach_p)(ifp);
-       }
-
-       if (ng_ether_attach_p != NULL) {
-               CURVNET_SET_QUIET(new_vnet);
-               (*ng_ether_attach_p)(ifp);
-               CURVNET_RESTORE();
-       }
-}
-#endif
-
 SYSCTL_DECL(_net_link);
 SYSCTL_NODE(_net_link, IFT_ETHER, ether, CTLFLAG_RW | CTLFLAG_MPSAFE, 0,
     "Ethernet");
diff --git a/sys/netgraph/ng_ether.c b/sys/netgraph/ng_ether.c
index 80a0d3411ee8..fc388c6cdd70 100644
--- a/sys/netgraph/ng_ether.c
+++ b/sys/netgraph/ng_ether.c
@@ -92,17 +92,11 @@ typedef struct private *priv_p;
 extern void    (*ng_ether_input_p)(struct ifnet *ifp, struct mbuf **mp);
 extern void    (*ng_ether_input_orphan_p)(struct ifnet *ifp, struct mbuf *m);
 extern int     (*ng_ether_output_p)(struct ifnet *ifp, struct mbuf **mp);
-extern void    (*ng_ether_attach_p)(struct ifnet *ifp);
-extern void    (*ng_ether_detach_p)(struct ifnet *ifp);
-extern void    (*ng_ether_link_state_p)(struct ifnet *ifp, int state);
 
 /* Functional hooks called from if_ethersubr.c */
 static void    ng_ether_input(struct ifnet *ifp, struct mbuf **mp);
 static void    ng_ether_input_orphan(struct ifnet *ifp, struct mbuf *m);
 static int     ng_ether_output(struct ifnet *ifp, struct mbuf **mp);
-static void    ng_ether_attach(struct ifnet *ifp);
-static void    ng_ether_detach(struct ifnet *ifp); 
-static void    ng_ether_link_state(struct ifnet *ifp, int state); 
 
 /* Other functions */
 static int     ng_ether_rcv_lower(hook_p node, item_p item);
@@ -117,7 +111,8 @@ static ng_rcvdata_t ng_ether_rcvdata;
 static ng_disconnect_t ng_ether_disconnect;
 static int             ng_ether_mod_event(module_t mod, int event, void *data);
 
-static eventhandler_tag        ng_ether_ifnet_arrival_cookie;
+static eventhandler_tag        ifnet_arrival_tag, ifnet_departure_tag,
+    ifnet_rename_tag, ifnet_linkstate_tag;
 
 /* List of commands and how to convert arguments to/from ASCII */
 static const struct ng_cmdlist ng_ether_cmdlist[] = {
@@ -299,13 +294,19 @@ ng_ether_output(struct ifnet *ifp, struct mbuf **mp)
  * A new Ethernet interface has been attached.
  * Create a new node for it, etc.
  */
-static void
-ng_ether_attach(struct ifnet *ifp)
+static int
+ng_ether_attach(struct ifnet *ifp, void *arg __unused)
 {
        char name[IFNAMSIZ];
        priv_p priv;
        node_p node;
 
+       if ((ifp)->if_type != IFT_ETHER &&
+           (ifp)->if_type != IFT_L2VLAN &&
+           (ifp)->if_type != IFT_BRIDGE)
+               return (0);
+       MPASS(IFP2NG(ifp) == NULL);
+
        /*
         * Do not create / attach an ether node to this ifnet if
         * a netgraph node with the same name already exists.
@@ -316,25 +317,17 @@ ng_ether_attach(struct ifnet *ifp)
        ng_ether_sanitize_ifname(ifp->if_xname, name);
        if ((node = ng_name2noderef(NULL, name)) != NULL) {
                NG_NODE_UNREF(node);
-               return;
+               return (0);
        }
 
-       /* Create node */
-       KASSERT(!IFP2NG(ifp), ("%s: node already exists?", __func__));
        if (ng_make_node_common(&ng_ether_typestruct, &node) != 0) {
                log(LOG_ERR, "%s: can't %s for %s\n",
                    __func__, "create node", ifp->if_xname);
-               return;
+               return (0);
        }
 
        /* Allocate private data */
-       priv = malloc(sizeof(*priv), M_NETGRAPH, M_NOWAIT | M_ZERO);
-       if (priv == NULL) {
-               log(LOG_ERR, "%s: can't %s for %s\n",
-                   __func__, "allocate memory", ifp->if_xname);
-               NG_NODE_UNREF(node);
-               return;
-       }
+       priv = malloc(sizeof(*priv), M_NETGRAPH, M_WAITOK | M_ZERO);
        NG_NODE_SET_PRIVATE(node, priv);
        priv->ifp = ifp;
        IFP2NG(ifp) = node;
@@ -343,17 +336,38 @@ ng_ether_attach(struct ifnet *ifp)
        /* Try to give the node the same name as the interface */
        if (ng_name_node(node, name) != 0)
                log(LOG_WARNING, "%s: can't name node %s\n", __func__, name);
+
+       return (0);
 }
 
+static void
+ng_ether_arrival(void *arg __unused, struct ifnet *ifp)
+{
+       (void)ng_ether_attach(ifp, NULL);
+}
+
+#define        RETURN_IF_NOT_ETHERNET_OR_DETACHED(ifp) do {                    
\
+       if ((ifp)->if_type != IFT_ETHER &&                              \
+           (ifp)->if_type != IFT_L2VLAN &&                             \
+           (ifp)->if_type != IFT_BRIDGE)                               \
+               return;                                                 \
+       if (IFP2NG(ifp) == NULL)                                        \
+               return;                                                 \
+} while (0)
+
 /*
  * An Ethernet interface is being detached.
  * REALLY Destroy its node.
  */
 static void
-ng_ether_detach(struct ifnet *ifp)
+ng_ether_detach(void *arg __unused, struct ifnet *ifp)
 {
        const node_p node = IFP2NG(ifp);
-       const priv_p priv = NG_NODE_PRIVATE(node);
+       priv_p priv;
+
+       RETURN_IF_NOT_ETHERNET_OR_DETACHED(ifp);
+
+       priv = NG_NODE_PRIVATE(node);
 
        taskqueue_drain(taskqueue_swi, &ifp->if_linktask);
        NG_NODE_REALLY_DIE(node);       /* Force real removal of node */
@@ -372,13 +386,17 @@ ng_ether_detach(struct ifnet *ifp)
  * if_link_state_change() has already checked that the state has changed.
  */
 static void
-ng_ether_link_state(struct ifnet *ifp, int state)
+ng_ether_link_state(void *arg __unused, struct ifnet *ifp, int state)
 {
        const node_p node = IFP2NG(ifp);
-       const priv_p priv = NG_NODE_PRIVATE(node);
+       priv_p priv;
        struct ng_mesg *msg;
        int cmd, dummy_error = 0;
 
+       RETURN_IF_NOT_ETHERNET_OR_DETACHED(ifp);
+
+       priv = NG_NODE_PRIVATE(node);
+
        if (state == LINK_STATE_UP)
                cmd = NGM_LINK_IS_UP;
        else if (state == LINK_STATE_DOWN)
@@ -399,31 +417,17 @@ ng_ether_link_state(struct ifnet *ifp, int state)
 }
 
 /*
- * Interface arrival notification handler.
- * The notification is produced in two cases:
- *  o a new interface arrives
- *  o an existing interface got renamed
- * Currently the first case is handled by ng_ether_attach via special
- * hook ng_ether_attach_p.
+ * Interface has been renamed.
  */
 static void
-ng_ether_ifnet_arrival_event(void *arg __unused, struct ifnet *ifp)
+ng_ether_rename(void *arg __unused, struct ifnet *ifp)
 {
        char name[IFNAMSIZ];
        node_p node;
 
-       /* Only ethernet interfaces are of interest. */
-       if (ifp->if_type != IFT_ETHER &&
-           ifp->if_type != IFT_L2VLAN &&
-           ifp->if_type != IFT_BRIDGE)
-               return;
+       RETURN_IF_NOT_ETHERNET_OR_DETACHED(ifp);
 
-       /*
-        * Just return if it's a new interface without an ng_ether companion.
-        */
        node = IFP2NG(ifp);
-       if (node == NULL)
-               return;
 
        /* Try to give the node the same name as the new interface name */
        ng_ether_sanitize_ifname(ifp->if_xname, name);
@@ -629,7 +633,7 @@ ng_ether_rcvmsg(node_p node, item_p item, hook_p lasthook)
                        break;
                    }
                case NGM_ETHER_DETACH:
-                       ng_ether_detach(priv->ifp);
+                       ng_ether_detach(NULL, priv->ifp);
                        break;
                default:
                        error = EINVAL;
@@ -810,22 +814,19 @@ ng_ether_mod_event(module_t mod, int event, void *data)
 
        switch (event) {
        case MOD_LOAD:
-
-               /* Register function hooks */
-               if (ng_ether_attach_p != NULL) {
-                       error = EEXIST;
-                       break;
-               }
-               ng_ether_attach_p = ng_ether_attach;
-               ng_ether_detach_p = ng_ether_detach;
                ng_ether_output_p = ng_ether_output;
                ng_ether_input_p = ng_ether_input;
                ng_ether_input_orphan_p = ng_ether_input_orphan;
-               ng_ether_link_state_p = ng_ether_link_state;
 
-               ng_ether_ifnet_arrival_cookie =
-                   EVENTHANDLER_REGISTER(ifnet_arrival_event,
-                   ng_ether_ifnet_arrival_event, NULL, EVENTHANDLER_PRI_ANY);
+               ifnet_arrival_tag = EVENTHANDLER_REGISTER(ifnet_arrival_event,
+                   ng_ether_arrival, NULL, EVENTHANDLER_PRI_ANY);
+               ifnet_departure_tag =
+                   EVENTHANDLER_REGISTER(ifnet_departure_event,
+                   ng_ether_detach, NULL, EVENTHANDLER_PRI_ANY);
+               ifnet_rename_tag = EVENTHANDLER_REGISTER(ifnet_rename_event,
+                   ng_ether_rename, NULL, EVENTHANDLER_PRI_ANY);
+               ifnet_linkstate_tag = EVENTHANDLER_REGISTER(ifnet_link_event,
+                   ng_ether_link_state, NULL, EVENTHANDLER_PRI_ANY);
                break;
 
        case MOD_UNLOAD:
@@ -838,16 +839,16 @@ ng_ether_mod_event(module_t mod, int event, void *data)
                 * is MOD_UNLOAD, so there's no need to detach any nodes.
                 */
 
-               EVENTHANDLER_DEREGISTER(ifnet_arrival_event,
-                   ng_ether_ifnet_arrival_cookie);
+               EVENTHANDLER_DEREGISTER(ifnet_arrival_event, ifnet_arrival_tag);
+               EVENTHANDLER_DEREGISTER(ifnet_departure_event,
+                   ifnet_departure_tag);
+               EVENTHANDLER_DEREGISTER(ifnet_rename_event, ifnet_rename_tag);
+               EVENTHANDLER_DEREGISTER(ifnet_link_event, ifnet_linkstate_tag);
 
                /* Unregister function hooks */
-               ng_ether_attach_p = NULL;
-               ng_ether_detach_p = NULL;
                ng_ether_output_p = NULL;
                ng_ether_input_p = NULL;
                ng_ether_input_orphan_p = NULL;
-               ng_ether_link_state_p = NULL;
                break;
 
        default:
@@ -858,23 +859,9 @@ ng_ether_mod_event(module_t mod, int event, void *data)
 }
 
 static void
-vnet_ng_ether_init(const void *unused)
+ng_ether_vnet_init(void *arg __unused)
 {
-       struct ifnet *ifp;
-
-       /* If module load was rejected, don't attach to vnets. */
-       if (ng_ether_attach_p != ng_ether_attach)
-               return;
-
-       /* Create nodes for any already-existing Ethernet interfaces. */
-       IFNET_RLOCK();
-       CK_STAILQ_FOREACH(ifp, &V_ifnet, if_link) {
-               if (ifp->if_type == IFT_ETHER ||
-                   ifp->if_type == IFT_L2VLAN ||
-                   ifp->if_type == IFT_BRIDGE)
-                       ng_ether_attach(ifp);
-       }
-       IFNET_RUNLOCK();
+       if_foreach_sleep(NULL, NULL, ng_ether_attach, NULL);
 }
-VNET_SYSINIT(vnet_ng_ether_init, SI_SUB_PSEUDO, SI_ORDER_ANY,
-    vnet_ng_ether_init, NULL);
+VNET_SYSINIT(ng_ether_vnet_init, SI_SUB_PROTO_IF, SI_ORDER_ANY,
+    ng_ether_vnet_init, NULL);

Reply via email to