Date: Fri, 3 Aug 2007 22:01:20 GMT From: Marko Zec <zec@FreeBSD.org> To: Perforce Change Reviews <perforce@FreeBSD.org> Subject: PERFORCE change 124613 for review Message-ID: <200708032201.l73M1KSG080580@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=124613 Change 124613 by zec@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_ */
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200708032201.l73M1KSG080580>