PERFORCE change 124613 for review
Marko Zec
zec at FreeBSD.org
Fri Aug 3 15:01:21 PDT 2007
http://perforce.freebsd.org/chv.cgi?CH=124613
Change 124613 by zec at zec_tpx32 on 2007/08/03 22:01:03
Promote ng_ether to a vnet module in order to ensure it doesn't
begin to attach to existing ethernet ifnets before netgraph
vnet module is registered.
In ng_ether_attach() drop a reference to other node, if found
when searching for conflicts with ng_eiface over the same ifnet.
Affected files ...
.. //depot/projects/vimage/src/sys/netgraph/ng_ether.c#8 edit
.. //depot/projects/vimage/src/sys/netgraph/vnetgraph.h#4 edit
Differences ...
==== //depot/projects/vimage/src/sys/netgraph/ng_ether.c#8 (text+ko) ====
@@ -74,6 +74,12 @@
#define IFP2NG(ifp) (IFP2AC((ifp))->ac_netgraph)
+static vnet_attach_fn ng_ether_iattach;
+static vnet_detach_fn ng_ether_idetach;
+
+VNET_MOD_DECLARE_STATELESS(NG_ETHER, ng_ether, ng_ether_iattach,
+ ng_ether_idetach, NETGRAPH)
+
/* Per-node private data */
struct private {
struct ifnet *ifp; /* associated interface */
@@ -292,8 +298,10 @@
* This should prevent ether nodes to be attached to
* eiface nodes in the same vnet, which is pointless.
*/
- if (ng_name2noderef(node, ifp->if_xname) != NULL)
+ if ((node = ng_name2noderef(NULL, ifp->if_xname)) != NULL) {
+ NG_NODE_UNREF(node);
return;
+ }
/* Create node */
KASSERT(!IFP2NG(ifp), ("%s: node already exists?", __func__));
@@ -743,56 +751,25 @@
static int
ng_ether_mod_event(module_t mod, int event, void *data)
{
- struct ifnet *ifp;
int error = 0;
int s;
s = splnet();
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;
-
- /* Create nodes for any already-existing Ethernet interfaces */
- IFNET_RLOCK();
- VNET_ITERLOOP_BEGIN();
- INIT_VNET_NET(vnet_iter);
- TAILQ_FOREACH(ifp, &V_ifnet, if_link) {
- if (ifp->if_type == IFT_ETHER
- || ifp->if_type == IFT_L2VLAN)
- ng_ether_attach(ifp);
- }
- VNET_ITERLOOP_END();
- IFNET_RUNLOCK();
+#ifdef VIMAGE
+ vnet_mod_register(&vnet_ng_ether_modinfo);
+#else
+ error = ng_ether_iattach(NULL);
+#endif
break;
case MOD_UNLOAD:
-
- /*
- * Note that the base code won't try to unload us until
- * all nodes have been removed, and that can't happen
- * until all Ethernet interfaces are removed. In any
- * case, we know there are no nodes left if the action
- * is MOD_UNLOAD, so there's no need to detach any nodes.
- */
-
- /* 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;
+#ifdef VIMAGE
+ vnet_mod_deregister(&vnet_ng_ether_modinfo);
+#else
+ ng_ether_idetach(NULL);
+#endif
break;
default:
@@ -803,3 +780,60 @@
return (error);
}
+static int ng_ether_iattach(const void *unused)
+{
+ INIT_VNET_NET(curvnet);
+ struct ifnet *ifp;
+
+#ifdef VIMAGE
+ if (IS_VNET_0(curvnet)){
+#endif
+ /* Register function hooks */
+ if (ng_ether_attach_p != NULL)
+ return(EEXIST);
+ 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;
+#ifdef VIMAGE
+ }
+#endif
+
+ /* 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;
+}
+
+static int ng_ether_idetach(const void *unused)
+{
+ /*
+ * Note that the base code won't try to unload us until
+ * all nodes have been removed, and that can't happen
+ * until all Ethernet interfaces are removed. In any
+ * case, we know there are no nodes left if the action
+ * is MOD_UNLOAD, so there's no need to detach any nodes.
+ */
+
+ if (!IS_VNET_0(curvnet))
+ return(0);
+
+ /* 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;
+
+ return 0;
+}
+
==== //depot/projects/vimage/src/sys/netgraph/vnetgraph.h#4 (text+ko) ====
@@ -37,35 +37,24 @@
#define INIT_VNET_NETGRAPH(vnet) \
INIT_FROM_VNET(vnet, VNET_MOD_NETGRAPH, \
- struct vnet_netgraph, vnet_netgraph)
+ struct vnet_netgraph, vnet_netgraph)
#define VNET_NETGRAPH(sym) VSYM(vnet_netgraph, sym)
#ifdef VIMAGE
struct vnet_netgraph {
- struct vnet *parent_vnet;
-
LIST_HEAD(, ng_node) _ng_nodelist;
- SLIST_HEAD(, ng_node) _ng_allnodes;
- LIST_HEAD(, ng_node) _ng_freenodes;
- SLIST_HEAD(, ng_hook) _ng_allhooks;
- LIST_HEAD(, ng_hook) _ng_freehooks;
+ struct unrhdr *_ng_iface_unit;
+ struct unrhdr *_ng_eiface_unit;
};
-
-extern struct vnet_netgraph vnet_netgraph_0;
#endif
-/*
- * Symbol translation macros
- */
-
+/* Symbol translation macros */
#define V_ng_nodelist VNET_NETGRAPH(ng_nodelist)
-#define V_ng_allnodes VNET_NETGRAPH(ng_allnodes)
-#define V_ng_freenodes VNET_NETGRAPH(ng_freenodes)
-#define V_ng_allhooks VNET_NETGRAPH(ng_allhooks)
-#define V_ng_freehooks VNET_NETGRAPH(ng_freehoks)
+#define V_ng_iface_unit VNET_NETGRAPH(ng_iface_unit)
+#define V_ng_eiface_unit VNET_NETGRAPH(ng_eiface_unit)
#endif /* !_NETGRAPH_VNETGRAPH_H_ */
More information about the p4-projects
mailing list