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