git: 0bd0c3295ac0 - main - ng_ether: refactor to use interface EVENTHANDLER(9)s
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Mon, 22 Dec 2025 02:23:49 UTC
The branch main has been updated by glebius:
URL: https://cgit.FreeBSD.org/src/commit/?id=0bd0c3295ac09f759f2816b73cbd2d950e3bef7e
commit 0bd0c3295ac09f759f2816b73cbd2d950e3bef7e
Author: Gleb Smirnoff <glebius@FreeBSD.org>
AuthorDate: 2025-12-21 22:13:58 +0000
Commit: Gleb Smirnoff <glebius@FreeBSD.org>
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);