diff options
author | zec <zec@FreeBSD.org> | 2009-04-26 07:14:50 +0000 |
---|---|---|
committer | zec <zec@FreeBSD.org> | 2009-04-26 07:14:50 +0000 |
commit | c269cc664ea0bb95561b14b109212e8640c8d53a (patch) | |
tree | a1175fbb0223247a55badf8c425bc6113277d52f /sys/netgraph/ng_ether.c | |
parent | 712d9928291fa1fa1a011adcfd08c48ac1a6adc7 (diff) | |
download | FreeBSD-src-c269cc664ea0bb95561b14b109212e8640c8d53a.zip FreeBSD-src-c269cc664ea0bb95561b14b109212e8640c8d53a.tar.gz |
In preparation to make options VIMAGE operational, where needed,
initialize / release netgraph related state in iattach() / idetach()
functions called via the vnet module registration / initialization
framework, instead of initialization / cleanups being done in
mod_event handlers.
While here, introduce a crude hack aimed at preventing ng_ether to
autoattach to ng_eiface ifnets, which are also netgraph nodes already.
Reviewed by: bz
Approved by: julian (mentor)
Diffstat (limited to 'sys/netgraph/ng_ether.c')
-rw-r--r-- | sys/netgraph/ng_ether.c | 57 |
1 files changed, 48 insertions, 9 deletions
diff --git a/sys/netgraph/ng_ether.c b/sys/netgraph/ng_ether.c index aaf4372..b26aea2 100644 --- a/sys/netgraph/ng_ether.c +++ b/sys/netgraph/ng_ether.c @@ -75,6 +75,17 @@ #define IFP2NG(ifp) (IFP2AC((ifp))->ac_netgraph) +static vnet_attach_fn ng_ether_iattach; + +#ifndef VIMAGE_GLOBALS +static vnet_modinfo_t vnet_ng_ether_modinfo = { + .vmi_id = VNET_MOD_NG_ETHER, + .vmi_name = "ng_ether", + .vmi_dependson = VNET_MOD_NETGRAPH, + .vmi_iattach = ng_ether_iattach, +}; +#endif + /* Per-node private data */ struct private { struct ifnet *ifp; /* associated interface */ @@ -287,6 +298,18 @@ ng_ether_attach(struct ifnet *ifp) priv_p priv; node_p node; + /* + * Do not create / attach an ether node to this ifnet if + * a netgraph node with the same name already exists. + * This should prevent ether nodes to become attached to + * eiface nodes, which may be problematic due to naming + * clashes. + */ + if ((node = ng_name2noderef(NULL, ifp->if_xname)) != NULL) { + NG_NODE_UNREF(node); + return; + } + /* Create node */ KASSERT(!IFP2NG(ifp), ("%s: node already exists?", __func__)); if (ng_make_node_common(&ng_ether_typestruct, &node) != 0) { @@ -741,7 +764,6 @@ ng_ether_disconnect(hook_p hook) static int ng_ether_mod_event(module_t mod, int event, void *data) { - struct ifnet *ifp; int error = 0; int s; @@ -761,14 +783,11 @@ ng_ether_mod_event(module_t mod, int event, void *data) ng_ether_input_orphan_p = ng_ether_input_orphan; ng_ether_link_state_p = ng_ether_link_state; - /* Create nodes for any already-existing Ethernet interfaces */ - IFNET_RLOCK(); - TAILQ_FOREACH(ifp, &V_ifnet, if_link) { - if (ifp->if_type == IFT_ETHER - || ifp->if_type == IFT_L2VLAN) - ng_ether_attach(ifp); - } - IFNET_RUNLOCK(); +#ifndef VIMAGE_GLOBALS + vnet_mod_register(&vnet_ng_ether_modinfo); +#else + error = ng_ether_iattach(NULL); +#endif break; case MOD_UNLOAD: @@ -781,6 +800,10 @@ ng_ether_mod_event(module_t mod, int event, void *data) * is MOD_UNLOAD, so there's no need to detach any nodes. */ +#ifndef VIMAGE_GLOBALS + vnet_mod_deregister(&vnet_ng_ether_modinfo); +#endif + /* Unregister function hooks */ ng_ether_attach_p = NULL; ng_ether_detach_p = NULL; @@ -798,3 +821,19 @@ ng_ether_mod_event(module_t mod, int event, void *data) return (error); } +static int ng_ether_iattach(const void *unused) +{ + INIT_VNET_NET(curvnet); + struct ifnet *ifp; + + /* Create nodes for any already-existing Ethernet interfaces. */ + IFNET_RLOCK(); + TAILQ_FOREACH(ifp, &V_ifnet, if_link) { + if (ifp->if_type == IFT_ETHER + || ifp->if_type == IFT_L2VLAN) + ng_ether_attach(ifp); + } + IFNET_RUNLOCK(); + + return (0); +} |