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)
This commit is contained in:
Marko Zec 2009-04-26 07:14:50 +00:00
parent c13b951ef9
commit aef8f3445b
5 changed files with 159 additions and 15 deletions

View File

@ -1123,6 +1123,7 @@ hook_p ng_findhook(node_p node, const char *name);
struct ng_type *ng_findtype(const char *type);
int ng_make_node_common(struct ng_type *typep, node_p *nodep);
int ng_name_node(node_p node, const char *name);
node_p ng_name2noderef(node_p node, const char *name);
int ng_newtype(struct ng_type *tp);
ng_ID_t ng_node2ID(node_p node);
item_p ng_package_data(struct mbuf *m, int flags);

View File

@ -84,6 +84,8 @@ struct vnet_netgraph vnet_netgraph_0;
/* Mutex to protect topology events. */
static struct mtx ng_topo_mtx;
static vnet_attach_fn vnet_netgraph_iattach;
#ifdef NETGRAPH_DEBUG
static struct mtx ng_nodelist_mtx; /* protects global node/hook lists */
static struct mtx ngq_mtx; /* protects the queue item list */
@ -227,7 +229,6 @@ static int ng_mkpeer(node_p node, const char *name,
/* Imported, these used to be externally visible, some may go back. */
void ng_destroy_hook(hook_p hook);
node_p ng_name2noderef(node_p node, const char *name);
int ng_path2noderef(node_p here, const char *path,
node_p *dest, hook_p *lasthook);
int ng_make_node(const char *type, node_p *nodepp);
@ -3068,6 +3069,27 @@ ng_mod_event(module_t mod, int event, void *data)
return (error);
}
#ifndef VIMAGE_GLOBALS
static const vnet_modinfo_t vnet_netgraph_modinfo = {
.vmi_id = VNET_MOD_NETGRAPH,
.vmi_name = "netgraph",
#ifdef VIMAGE
.vmi_size = sizeof(struct vnet_netgraph),
#endif
.vmi_iattach = vnet_netgraph_iattach
};
#endif
static int
vnet_netgraph_iattach(const void *arg __unused)
{
INIT_VNET_NETGRAPH(curvnet);
V_nextID = 1;
return (0);
}
/*
* Handle loading and unloading for this code.
* The only thing we need to link into is the NETISR strucure.
@ -3082,7 +3104,11 @@ ngb_mod_event(module_t mod, int event, void *data)
switch (event) {
case MOD_LOAD:
/* Initialize everything. */
V_nextID = 1;
#ifndef VIMAGE_GLOBALS
vnet_mod_register(&vnet_netgraph_modinfo);
#else
vnet_netgraph_iattach(NULL);
#endif
NG_WORKLIST_LOCK_INIT();
mtx_init(&ng_typelist_mtx, "netgraph types mutex", NULL,
MTX_DEF);

View File

@ -113,10 +113,23 @@ static struct ng_type typestruct = {
};
NETGRAPH_INIT(eiface, &typestruct);
static vnet_attach_fn ng_eiface_iattach;
static vnet_detach_fn ng_eiface_idetach;
#ifdef VIMAGE_GLOBALS
static struct unrhdr *ng_eiface_unit;
#endif
#ifndef VIMAGE_GLOBALS
static vnet_modinfo_t vnet_ng_eiface_modinfo = {
.vmi_id = VNET_MOD_NG_EIFACE,
.vmi_name = "ng_eiface",
.vmi_dependson = VNET_MOD_NETGRAPH,
.vmi_iattach = ng_eiface_iattach,
.vmi_idetach = ng_eiface_idetach
};
#endif
/************************************************************************
INTERFACE STUFF
************************************************************************/
@ -590,10 +603,18 @@ ng_eiface_mod_event(module_t mod, int event, void *data)
switch (event) {
case MOD_LOAD:
V_ng_eiface_unit = new_unrhdr(0, 0xffff, NULL);
#ifndef VIMAGE_GLOBALS
vnet_mod_register(&vnet_ng_eiface_modinfo);
#else
ng_eiface_iattach(NULL);
#endif
break;
case MOD_UNLOAD:
delete_unrhdr(V_ng_eiface_unit);
#ifndef VIMAGE_GLOBALS
vnet_mod_deregister(&vnet_ng_eiface_modinfo);
#else
ng_eiface_idetach(NULL);
#endif
break;
default:
error = EOPNOTSUPP;
@ -601,3 +622,21 @@ ng_eiface_mod_event(module_t mod, int event, void *data)
}
return (error);
}
static int ng_eiface_iattach(const void *unused)
{
INIT_VNET_NETGRAPH(curvnet);
V_ng_eiface_unit = new_unrhdr(0, 0xffff, NULL);
return (0);
}
static int ng_eiface_idetach(const void *unused)
{
INIT_VNET_NETGRAPH(curvnet);
delete_unrhdr(V_ng_eiface_unit);
return (0);
}

View File

@ -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);
}

View File

@ -209,10 +209,23 @@ static struct ng_type typestruct = {
};
NETGRAPH_INIT(iface, &typestruct);
static vnet_attach_fn ng_iface_iattach;
static vnet_detach_fn ng_iface_idetach;
#ifdef VIMAGE_GLOBALS
static struct unrhdr *ng_iface_unit;
#endif
#ifndef VIMAGE_GLOBALS
static vnet_modinfo_t vnet_ng_iface_modinfo = {
.vmi_id = VNET_MOD_NG_IFACE,
.vmi_name = "ng_iface",
.vmi_dependson = VNET_MOD_NETGRAPH,
.vmi_iattach = ng_iface_iattach,
.vmi_idetach = ng_iface_idetach
};
#endif
/************************************************************************
HELPER STUFF
************************************************************************/
@ -836,10 +849,18 @@ ng_iface_mod_event(module_t mod, int event, void *data)
switch (event) {
case MOD_LOAD:
V_ng_iface_unit = new_unrhdr(0, 0xffff, NULL);
#ifndef VIMAGE_GLOBALS
vnet_mod_register(&vnet_ng_iface_modinfo);
#else
ng_iface_iattach(NULL);
#endif
break;
case MOD_UNLOAD:
delete_unrhdr(V_ng_iface_unit);
#ifndef VIMAGE_GLOBALS
vnet_mod_deregister(&vnet_ng_iface_modinfo);
#else
ng_iface_idetach(NULL);
#endif
break;
default:
error = EOPNOTSUPP;
@ -847,3 +868,21 @@ ng_iface_mod_event(module_t mod, int event, void *data)
}
return (error);
}
static int ng_iface_iattach(const void *unused)
{
INIT_VNET_NETGRAPH(curvnet);
V_ng_iface_unit = new_unrhdr(0, 0xffff, NULL);
return (0);
}
static int ng_iface_idetach(const void *unused)
{
INIT_VNET_NETGRAPH(curvnet);
delete_unrhdr(V_ng_iface_unit);
return (0);
}