From owner-svn-src-head@FreeBSD.ORG Tue Nov 29 13:55:09 2011 Return-Path: Delivered-To: svn-src-head@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id D46BB1065673; Tue, 29 Nov 2011 13:55:08 +0000 (UTC) (envelope-from glebius@FreeBSD.org) Received: from cell.glebius.int.ru (glebius.int.ru [81.19.64.117]) by mx1.freebsd.org (Postfix) with ESMTP id E56288FC0C; Tue, 29 Nov 2011 13:55:07 +0000 (UTC) Received: from cell.glebius.int.ru (localhost [127.0.0.1]) by cell.glebius.int.ru (8.14.5/8.14.5) with ESMTP id pATDt68n077016; Tue, 29 Nov 2011 17:55:06 +0400 (MSK) (envelope-from glebius@FreeBSD.org) Received: (from glebius@localhost) by cell.glebius.int.ru (8.14.5/8.14.5/Submit) id pATDt6Bv077015; Tue, 29 Nov 2011 17:55:06 +0400 (MSK) (envelope-from glebius@FreeBSD.org) X-Authentication-Warning: cell.glebius.int.ru: glebius set sender to glebius@FreeBSD.org using -f Date: Tue, 29 Nov 2011 17:55:06 +0400 From: Gleb Smirnoff To: "Bjoern A. Zeeb" Message-ID: <20111129135506.GB44498@FreeBSD.org> References: <201111281444.pASEixdO095604@svn.freebsd.org> <20111129093550.GZ44498@FreeBSD.org> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="KN5l+BnMqAQyZLvT" Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.5.21 (2010-09-15) Cc: svn-src-head@FreeBSD.org, svn-src-all@FreeBSD.org, src-committers@FreeBSD.org Subject: Re: svn commit: r228071 - head/sys/net X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 29 Nov 2011 13:55:09 -0000 --KN5l+BnMqAQyZLvT Content-Type: text/plain; charset=koi8-r Content-Disposition: inline On Tue, Nov 29, 2011 at 09:43:37AM +0000, Bjoern A. Zeeb wrote: B> On Tue, 29 Nov 2011, Gleb Smirnoff wrote: B> > btw, I don't like the static initializer of cloners, since it require re-compile of B> > dependencies. B> > B> > What about making an API change: remove the static initializer and make an initializer B> > function. Modules should have only a pointer to opaque structure. We will bump B> > __FreeBSD_version for that. But later with any change to the if_clone struct, we B> > won't have ABI change. If everyone agrees, I can go for that. B> B> I have some fairly intrusive changes to cloners sitting in p4 for the B> V_irtualization but it could make my life easier; I'll be happy to B> look at the patch. Okay, here is what I am suggesting: - make struct if_clone opaque, and remove if from if_clone.h - IF_CLONE_INITIALIZER and IFC_SIMPLE_DECLARE substituted with if_clone_advanced() and if_clone_simple() Now, with all our guts obscure to the callers, we can simplify things: - kill ifc_data, that was an old attempt to support simple & advanced cloners w/o changes to the struct ifclone - make union that stores either simple or advanced methods and data - kill ifc_attach, that was used only for simple callers, embed it into if_clone_simple() Modifications to the callers are quite simple: - substitute static initializer to 'static struct if_clone *fooclone;'; - substitite if_clone_attach() to either if_clone_advanced() or if_clone_simple() - fix argument for if_clone_detach() - if module reads ifc_name, substitute it to some locally stored name Attached patch includes the core changes, changes to lo(4) - a simple cloner, vlan(4) - advanced one, and epair(4) - API abuser :) All three work, so I think converting others won't be a problem. I am only not 100% sure that I've put correct code under VIMAGE ifdefs. Can you review this part thoroughly? If you agree with suggested changes, I can proceed to converting other callers and commit. -- Totus tuus, Glebius. --KN5l+BnMqAQyZLvT Content-Type: text/x-diff; charset=koi8-r Content-Disposition: attachment; filename="if_clone.diff" Index: if_clone.c =================================================================== --- if_clone.c (revision 228129) +++ if_clone.c (working copy) @@ -1,4 +1,5 @@ /*- + * Copyright (c) 2011 Gleb Smirnoff * Copyright (c) 1980, 1986, 1993 * The Regents of the University of California. All rights reserved. * @@ -42,19 +43,64 @@ #include #include -#if 0 -#include -#endif -#include #include #include #include #include +/* Current IF_MAXUNIT expands maximum to 5 characters. */ +#define IFCLOSIZ (IFNAMSIZ - 5) + +/* + * Structure describing a `cloning' interface. + * + * List of locks + * (c) const until freeing + * (d) driver specific data, may need external protection. + * (e) locked by if_cloners_mtx + * (i) locked by ifc_mtx mtx + */ +struct if_clone { + char ifc_name[IFCLOSIZ]; /* (c) Name of device, e.g. `gif' */ + struct unrhdr *ifc_unrhdr; /* (c) alloc_unr(9) header */ + long ifc_refcnt; /* (i) Reference count. */ + LIST_HEAD(, ifnet) ifc_iflist; /* (i) List of cloned interfaces */ + struct mtx ifc_mtx; /* Mutex to protect members. */ + + enum { SIMPLE, ADVANCED } ifc_type; /* (c) */ + + /* (c) Driver specific cloning functions. Called with no locks held. */ + union { + struct { /* advanced cloner */ + ifc_match_t *_ifc_match; + ifc_create_t *_ifc_create; + ifc_destroy_t *_ifc_destroy; + } A; + struct { /* simple cloner */ + ifcs_create_t *_ifcs_create; + ifcs_destroy_t *_ifcs_destroy; + int _ifcs_minifs; /* minimum ifs */ + + } S; + } U; +#define ifc_match U.A._ifc_match +#define ifc_create U.A._ifc_create +#define ifc_destroy U.A._ifc_destroy +#define ifcs_create U.S._ifcs_create +#define ifcs_destroy U.S._ifcs_destroy +#define ifcs_minifs U.S._ifcs_minifs + + LIST_ENTRY(if_clone) ifc_list; /* (e) On list of cloners */ +}; + static void if_clone_free(struct if_clone *ifc); static int if_clone_createif(struct if_clone *ifc, char *name, size_t len, caddr_t params); +static int ifc_simple_match(struct if_clone *, const char *); +static int ifc_simple_create(struct if_clone *, char *, size_t, caddr_t); +static int ifc_simple_destroy(struct if_clone *, struct ifnet *); + static struct mtx if_cloners_mtx; static VNET_DEFINE(int, if_cloners_count); VNET_DEFINE(LIST_HEAD(, if_clone), if_cloners); @@ -138,18 +184,25 @@ /* Try to find an applicable cloner for this request */ IF_CLONERS_LOCK(); - LIST_FOREACH(ifc, &V_if_cloners, ifc_list) { - if (ifc->ifc_match(ifc, name)) { - break; + LIST_FOREACH(ifc, &V_if_cloners, ifc_list) + if (ifc->ifc_type == SIMPLE) { + if (ifc_simple_match(ifc, name)) + break; + } else { + if (ifc->ifc_match(ifc, name)) + break; } - } #ifdef VIMAGE if (ifc == NULL && !IS_DEFAULT_VNET(curvnet)) { CURVNET_SET_QUIET(vnet0); - LIST_FOREACH(ifc, &V_if_cloners, ifc_list) { - if (ifc->ifc_match(ifc, name)) - break; - } + LIST_FOREACH(ifc, &V_if_cloners, ifc_list) + if (ifc->ifc_type == SIMPLE) { + if (ifc_simple_match(ifc, name)) + break; + } else { + if (ifc->ifc_match(ifc, name)) + break; + } CURVNET_RESTORE(); } #endif @@ -173,7 +226,10 @@ if (ifunit(name) != NULL) return (EEXIST); - err = (*ifc->ifc_create)(ifc, name, len, params); + if (ifc->ifc_type == SIMPLE) + err = ifc_simple_create(ifc, name, len, params); + else + err = (*ifc->ifc_create)(ifc, name, len, params); if (!err) { ifp = ifunit(name); @@ -214,10 +270,14 @@ #ifdef VIMAGE if (ifc == NULL && !IS_DEFAULT_VNET(curvnet)) { CURVNET_SET_QUIET(vnet0); - LIST_FOREACH(ifc, &V_if_cloners, ifc_list) { - if (ifc->ifc_match(ifc, name)) - break; - } + LIST_FOREACH(ifc, &V_if_cloners, ifc_list) + if (ifc->type == SIMPLE) { + if (ifc_simple_match(ifc, name)) + break; + } else { + if (ifc->ifc_match(ifc, name)) + break; + } CURVNET_RESTORE(); } #endif @@ -241,7 +301,7 @@ int err; struct ifnet *ifcifp; - if (ifc->ifc_destroy == NULL) + if (ifc->ifc_type == ADVANCED && ifc->ifc_destroy == NULL) return(EOPNOTSUPP); /* @@ -266,7 +326,10 @@ if_delgroup(ifp, ifc->ifc_name); - err = (*ifc->ifc_destroy)(ifc, ifp); + if (ifc->ifc_type == SIMPLE) + err = ifc_simple_destroy(ifc, ifp); + else + err = (*ifc->ifc_destroy)(ifc, ifp); if (err != 0) { if_addgroup(ifp, ifc->ifc_name); @@ -279,21 +342,29 @@ return (err); } -/* - * Register a network interface cloner. - */ -int -if_clone_attach(struct if_clone *ifc) +static struct if_clone * +if_clone_alloc(const char *name, int maxunit) { - struct if_clone *ifc1; + struct if_clone *ifc; - KASSERT(ifc->ifc_name != NULL, ("%s: no name\n", __func__)); + KASSERT(name != NULL, ("%s: no name\n", __func__)); + ifc = malloc(sizeof(struct if_clone), M_CLONE, M_WAITOK | M_ZERO); + strncpy(ifc->ifc_name, name, IFCLOSIZ-1); IF_CLONE_LOCK_INIT(ifc); IF_CLONE_ADDREF(ifc); - ifc->ifc_unrhdr = new_unrhdr(0, ifc->ifc_maxunit, &ifc->ifc_mtx); + ifc->ifc_unrhdr = new_unrhdr(0, (maxunit ? maxunit : IF_MAXUNIT), + &ifc->ifc_mtx); LIST_INIT(&ifc->ifc_iflist); + return (ifc); +} + +static int +if_clone_attach(struct if_clone *ifc) +{ + struct if_clone *ifc1; + IF_CLONERS_LOCK(); LIST_FOREACH(ifc1, &V_if_cloners, ifc_list) if (strcmp(ifc->ifc_name, ifc1->ifc_name) == 0) { @@ -305,20 +376,67 @@ V_if_cloners_count++; IF_CLONERS_UNLOCK(); - if (ifc->ifc_attach != NULL) - (*ifc->ifc_attach)(ifc); + return (0); +} + +struct if_clone * +if_clone_advanced(const char *name, u_int maxunit, ifc_match_t match, + ifc_create_t create, ifc_destroy_t destroy) +{ + struct if_clone *ifc; + + ifc = if_clone_alloc(name, maxunit); + ifc->ifc_type = ADVANCED; + ifc->ifc_match = match; + ifc->ifc_create = create; + ifc->ifc_destroy = destroy; + + if (if_clone_attach(ifc) != 0) + return (NULL); + EVENTHANDLER_INVOKE(if_clone_event, ifc); - return (0); + return (ifc); } +struct if_clone * +if_clone_simple(const char *name, ifcs_create_t create, ifcs_destroy_t destroy, + u_int minifs) +{ + struct if_clone *ifc; + u_int unit; + + ifc = if_clone_alloc(name, 0); + ifc->ifc_type = SIMPLE; + ifc->ifcs_create = create; + ifc->ifcs_destroy = destroy; + ifc->ifcs_minifs = minifs; + + if (if_clone_attach(ifc) != 0) + return (NULL); + + for (unit = 0; unit < minifs; unit++) { + char name[IFNAMSIZ]; + int error; + + snprintf(name, IFNAMSIZ, "%s%d", ifc->ifc_name, unit); + error = if_clone_createif(ifc, name, IFNAMSIZ, NULL); + KASSERT(error == 0, + ("%s: failed to create required interface %s", + __func__, name)); + } + + EVENTHANDLER_INVOKE(if_clone_event, ifc); + + return (ifc); +} + /* * Unregister a network interface cloner. */ void if_clone_detach(struct if_clone *ifc) { - struct ifc_simple_data *ifcs = ifc->ifc_data; IF_CLONERS_LOCK(); LIST_REMOVE(ifc, ifc_list); @@ -326,8 +444,8 @@ IF_CLONERS_UNLOCK(); /* Allow all simples to be destroyed */ - if (ifc->ifc_attach == ifc_simple_attach) - ifcs->ifcs_minifs = 0; + if (ifc->ifc_type == SIMPLE) + ifc->ifcs_minifs = 0; /* destroy all interfaces for this cloner */ while (!LIST_EMPTY(&ifc->ifc_iflist)) @@ -345,6 +463,7 @@ IF_CLONE_LOCK_DESTROY(ifc); delete_unrhdr(ifc->ifc_unrhdr); + free(ifc, M_CLONE); } /* @@ -474,29 +593,7 @@ IF_CLONE_REMREF(ifc); } -void -ifc_simple_attach(struct if_clone *ifc) -{ - int err; - int unit; - char name[IFNAMSIZ]; - struct ifc_simple_data *ifcs = ifc->ifc_data; - - KASSERT(ifcs->ifcs_minifs - 1 <= ifc->ifc_maxunit, - ("%s: %s requested more units than allowed (%d > %d)", - __func__, ifc->ifc_name, ifcs->ifcs_minifs, - ifc->ifc_maxunit + 1)); - - for (unit = 0; unit < ifcs->ifcs_minifs; unit++) { - snprintf(name, IFNAMSIZ, "%s%d", ifc->ifc_name, unit); - err = if_clone_createif(ifc, name, IFNAMSIZ, NULL); - KASSERT(err == 0, - ("%s: failed to create required interface %s", - __func__, name)); - } -} - -int +static int ifc_simple_match(struct if_clone *ifc, const char *name) { const char *cp; @@ -517,14 +614,13 @@ return (1); } -int +static int ifc_simple_create(struct if_clone *ifc, char *name, size_t len, caddr_t params) { char *dp; int wildcard; int unit; int err; - struct ifc_simple_data *ifcs = ifc->ifc_data; err = ifc_name2unit(name, &unit); if (err != 0) @@ -536,7 +632,7 @@ if (err != 0) return (err); - err = ifcs->ifcs_create(ifc, unit, params); + err = ifc->ifcs_create(ifc, unit, params); if (err != 0) { ifc_free_unit(ifc, unit); return (err); @@ -560,18 +656,17 @@ return (0); } -int +static int ifc_simple_destroy(struct if_clone *ifc, struct ifnet *ifp) { int unit; - struct ifc_simple_data *ifcs = ifc->ifc_data; unit = ifp->if_dunit; - if (unit < ifcs->ifcs_minifs) + if (unit < ifc->ifcs_minifs) return (EINVAL); - ifcs->ifcs_destroy(ifp); + ifc->ifcs_destroy(ifp); ifc_free_unit(ifc, unit); Index: if_clone.h =================================================================== --- if_clone.h (revision 228129) +++ if_clone.h (working copy) @@ -35,87 +35,42 @@ #ifdef _KERNEL -#define IFC_CLONE_INITIALIZER(name, data, maxunit, \ - attach, match, create, destroy) \ - { \ - .ifc_name = name, \ - .ifc_maxunit = maxunit, \ - .ifc_data = data, \ - .ifc_attach = attach, \ - .ifc_match = match, \ - .ifc_create = create, \ - .ifc_destroy = destroy, \ - } +struct if_clone; -/* - * Structure describing a `cloning' interface. - * - * List of locks - * (c) const until freeing - * (d) driver specific data, may need external protection. - * (e) locked by if_cloners_mtx - * (i) locked by ifc_mtx mtx - */ -struct if_clone { - LIST_ENTRY(if_clone) ifc_list; /* (e) On list of cloners */ - const char *ifc_name; /* (c) Name of device, e.g. `gif' */ - int ifc_maxunit; /* (c) Maximum unit number */ - struct unrhdr *ifc_unrhdr; /* (c) alloc_unr(9) header */ - void *ifc_data; /* (*) Data for ifc_* functions. */ +/* Methods. */ +typedef int ifc_match_t(struct if_clone *, const char *); +typedef int ifc_create_t(struct if_clone *, char *, size_t, caddr_t); +typedef int ifc_destroy_t(struct if_clone *, struct ifnet *); - /* (c) Driver specific cloning functions. Called with no locks held. */ - void (*ifc_attach)(struct if_clone *); - int (*ifc_match)(struct if_clone *, const char *); - int (*ifc_create)(struct if_clone *, char *, size_t, caddr_t); - int (*ifc_destroy)(struct if_clone *, struct ifnet *); +typedef int ifcs_create_t(struct if_clone *, int, caddr_t); +typedef void ifcs_destroy_t(struct ifnet *); - long ifc_refcnt; /* (i) Refrence count. */ - struct mtx ifc_mtx; /* Mutex to protect members. */ - LIST_HEAD(, ifnet) ifc_iflist; /* (i) List of cloned interfaces */ -}; - -void if_clone_init(void); -int if_clone_attach(struct if_clone *); +/* Interface cloner (de)allocating functions. */ +struct if_clone * + if_clone_advanced(const char *, u_int, ifc_match_t, ifc_create_t, + ifc_destroy_t); +struct if_clone * + if_clone_simple(const char *, ifcs_create_t, ifcs_destroy_t, u_int); void if_clone_detach(struct if_clone *); -void vnet_if_clone_init(void); -int if_clone_create(char *, size_t, caddr_t); -int if_clone_destroy(const char *); -int if_clone_destroyif(struct if_clone *, struct ifnet *); -int if_clone_list(struct if_clonereq *); - +/* Unit (de)allocating fucntions. */ int ifc_name2unit(const char *name, int *unit); int ifc_alloc_unit(struct if_clone *, int *); void ifc_free_unit(struct if_clone *, int); -/* - * The ifc_simple functions, structures, and macros implement basic - * cloning as in 5.[012]. - */ - -struct ifc_simple_data { - int ifcs_minifs; /* minimum number of interfaces */ - - int (*ifcs_create)(struct if_clone *, int, caddr_t); - void (*ifcs_destroy)(struct ifnet *); -}; - -/* interface clone event */ +/* Interface clone event. */ typedef void (*if_clone_event_handler_t)(void *, struct if_clone *); EVENTHANDLER_DECLARE(if_clone_event, if_clone_event_handler_t); -#define IFC_SIMPLE_DECLARE(name, minifs) \ -struct ifc_simple_data name##_cloner_data = \ - {minifs, name##_clone_create, name##_clone_destroy}; \ -struct if_clone name##_cloner = \ - IFC_CLONE_INITIALIZER(#name, &name##_cloner_data, IF_MAXUNIT, \ - ifc_simple_attach, ifc_simple_match, ifc_simple_create, ifc_simple_destroy) +/* The below interfaces used only by net/if.c. */ +void if_clone_init(void); +void vnet_if_clone_init(void); +int if_clone_create(char *, size_t, caddr_t); +int if_clone_destroy(const char *); +int if_clone_list(struct if_clonereq *); -void ifc_simple_attach(struct if_clone *); -int ifc_simple_match(struct if_clone *, const char *); -int ifc_simple_create(struct if_clone *, char *, size_t, caddr_t); -int ifc_simple_destroy(struct if_clone *, struct ifnet *); +/* The below interface used only by epair(4). */ +int if_clone_destroyif(struct if_clone *, struct ifnet *); #endif /* _KERNEL */ - #endif /* !_NET_IF_CLONE_H_ */ Index: if_vlan.c =================================================================== --- if_vlan.c (revision 228129) +++ if_vlan.c (working copy) @@ -207,11 +207,10 @@ static void vlan_ifdetach(void *arg, struct ifnet *ifp); static void vlan_iflladdr(void *arg, struct ifnet *ifp); -static struct if_clone vlan_cloner = IFC_CLONE_INITIALIZER(VLANNAME, NULL, - IF_MAXUNIT, NULL, vlan_clone_match, vlan_clone_create, vlan_clone_destroy); +static struct if_clone *vlan_cloner; #ifdef VIMAGE -static VNET_DEFINE(struct if_clone, vlan_cloner); +static VNET_DEFINE(struct if_clone *, vlan_cloner); #define V_vlan_cloner VNET(vlan_cloner) #endif @@ -719,7 +718,8 @@ vlan_tag_p = vlan_tag; vlan_devat_p = vlan_devat; #ifndef VIMAGE - if_clone_attach(&vlan_cloner); + vlan_cloner = if_clone_advanced(VLANNAME, 0, vlan_clone_match, + vlan_clone_create, vlan_clone_destroy); #endif if (bootverbose) printf("vlan: initialized, using " @@ -733,7 +733,7 @@ break; case MOD_UNLOAD: #ifndef VIMAGE - if_clone_detach(&vlan_cloner); + if_clone_detach(vlan_cloner); #endif EVENTHANDLER_DEREGISTER(ifnet_departure_event, ifdetach_tag); EVENTHANDLER_DEREGISTER(iflladdr_event, iflladdr_tag); @@ -769,8 +769,9 @@ vnet_vlan_init(const void *unused __unused) { + vlan_cloner = if_clone_advanced(VLANNAME, 0, vlan_clone_match, + vlan_clone_create, vlan_clone_destroy); V_vlan_cloner = vlan_cloner; - if_clone_attach(&V_vlan_cloner); } VNET_SYSINIT(vnet_vlan_init, SI_SUB_PROTO_IFATTACHDOMAIN, SI_ORDER_ANY, vnet_vlan_init, NULL); @@ -779,7 +780,7 @@ vnet_vlan_uninit(const void *unused __unused) { - if_clone_detach(&V_vlan_cloner); + if_clone_detach(V_vlan_cloner); } VNET_SYSUNINIT(vnet_vlan_uninit, SI_SUB_PROTO_IFATTACHDOMAIN, SI_ORDER_FIRST, vnet_vlan_uninit, NULL); @@ -936,7 +937,7 @@ * we don't conform to the default naming convention for interfaces. */ strlcpy(ifp->if_xname, name, IFNAMSIZ); - ifp->if_dname = ifc->ifc_name; + ifp->if_dname = VLANNAME; ifp->if_dunit = unit; /* NB: flags are not set here */ ifp->if_linkmib = &ifv->ifv_mib; Index: if_loop.c =================================================================== --- if_loop.c (revision 228129) +++ if_loop.c (working copy) @@ -106,13 +106,12 @@ VNET_DEFINE(struct ifnet *, loif); /* Used externally */ #ifdef VIMAGE -static VNET_DEFINE(struct ifc_simple_data, lo_cloner_data); -static VNET_DEFINE(struct if_clone, lo_cloner); -#define V_lo_cloner_data VNET(lo_cloner_data) +static VNET_DEFINE(struct if_clone *, lo_cloner); #define V_lo_cloner VNET(lo_cloner) #endif -IFC_SIMPLE_DECLARE(lo, 1); +static struct if_clone *lo_cloner; +static const char *loname = "lo"; static void lo_clone_destroy(struct ifnet *ifp) @@ -137,7 +136,7 @@ if (ifp == NULL) return (ENOSPC); - if_initname(ifp, ifc->ifc_name, unit); + if_initname(ifp, loname, unit); ifp->if_mtu = LOMTU; ifp->if_flags = IFF_LOOPBACK | IFF_MULTICAST; ifp->if_ioctl = loioctl; @@ -158,12 +157,12 @@ { #ifdef VIMAGE + lo_cloner = if_clone_simple(loname, lo_clone_create, lo_clone_destroy, + 1); V_lo_cloner = lo_cloner; - V_lo_cloner_data = lo_cloner_data; - V_lo_cloner.ifc_data = &V_lo_cloner_data; - if_clone_attach(&V_lo_cloner); #else - if_clone_attach(&lo_cloner); + lo_cloner = if_clone_simple(loname, lo_clone_create, lo_clone_destroy, + 1); #endif } VNET_SYSINIT(vnet_loif_init, SI_SUB_PROTO_IFATTACHDOMAIN, SI_ORDER_ANY, @@ -174,7 +173,7 @@ vnet_loif_uninit(const void *unused __unused) { - if_clone_detach(&V_lo_cloner); + if_clone_detach(V_lo_cloner); V_loif = NULL; } VNET_SYSUNINIT(vnet_loif_uninit, SI_SUB_PROTO_IFATTACHDOMAIN, SI_ORDER_ANY, Index: if_epair.c =================================================================== --- if_epair.c (revision 228129) +++ if_epair.c (working copy) @@ -171,9 +171,7 @@ static MALLOC_DEFINE(M_EPAIR, EPAIRNAME, "Pair of virtual cross-over connected Ethernet-like interfaces"); -static struct if_clone epair_cloner = IFC_CLONE_INITIALIZER( - EPAIRNAME, NULL, IF_MAXUNIT, - NULL, epair_clone_match, epair_clone_create, epair_clone_destroy); +static struct if_clone *epair_cloner; /* * DPCPU area and functions. @@ -714,7 +712,7 @@ /* * We are abusing params to create our second interface. - * Actually we already created it and called if_clone_createif() + * Actually we already created it and called if_clone_create() * for it to do the official insertion procedure the moment we knew * it cannot fail anymore. So just do attach it here. */ @@ -807,7 +805,7 @@ ifp = sca->ifp; ifp->if_softc = sca; strlcpy(ifp->if_xname, name, IFNAMSIZ); - ifp->if_dname = ifc->ifc_name; + ifp->if_dname = EPAIRNAME; ifp->if_dunit = unit; ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; ifp->if_capabilities = IFCAP_VLAN_MTU; @@ -833,7 +831,7 @@ ifp = scb->ifp; ifp->if_softc = scb; strlcpy(ifp->if_xname, name, IFNAMSIZ); - ifp->if_dname = ifc->ifc_name; + ifp->if_dname = EPAIRNAME; ifp->if_dunit = unit; ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; ifp->if_capabilities = IFCAP_VLAN_MTU; @@ -846,7 +844,7 @@ strlcpy(name, EPAIRNAME, len); error = if_clone_create(name, len, (caddr_t)scb); if (error) - panic("%s: if_clone_createif() for our 2nd iface failed: %d", + panic("%s: if_clone_create() for our 2nd iface failed: %d", __func__, error); scb->if_qflush = ifp->if_qflush; ifp->if_qflush = epair_qflush; @@ -956,12 +954,13 @@ if (TUNABLE_INT_FETCH("net.link.epair.netisr_maxqlen", &qlimit)) epair_nh.nh_qlimit = qlimit; netisr_register(&epair_nh); - if_clone_attach(&epair_cloner); + epair_cloner = if_clone_advanced(EPAIRNAME, 0, + epair_clone_match, epair_clone_create, epair_clone_destroy); if (bootverbose) printf("%s initialized.\n", EPAIRNAME); break; case MOD_UNLOAD: - if_clone_detach(&epair_cloner); + if_clone_detach(epair_cloner); netisr_unregister(&epair_nh); epair_dpcpu_detach(); if (bootverbose) --KN5l+BnMqAQyZLvT--