Move the cloned interface list management in to if_clone. For some drivers the
softc lists and associated mutex are now unused so these have been removed. Calling if_clone_detach() will now destroy all the cloned interfaces for the driver and in most cases is all thats needed to unload. Idea by: brooks Reviewed by: brooks
This commit is contained in:
parent
2a522eb9d3
commit
4e7e0183e1
@ -369,9 +369,6 @@ pflog_modevent(module_t mod, int type, void *data)
|
||||
|
||||
case MOD_UNLOAD:
|
||||
if_clone_detach(&pflog_cloner);
|
||||
while (!LIST_EMPTY(&pflog_list))
|
||||
ifc_simple_destroy(&pflog_cloner,
|
||||
SCP2IFP(LIST_FIRST(&pflog_list)));
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -1851,9 +1851,6 @@ pfsync_modevent(module_t mod, int type, void *data)
|
||||
|
||||
case MOD_UNLOAD:
|
||||
if_clone_detach(&pfsync_cloner);
|
||||
while (!LIST_EMPTY(&pfsync_list))
|
||||
ifc_simple_destroy(&pfsync_cloner,
|
||||
SCP2IFP(LIST_FIRST(&pfsync_list)));
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -170,8 +170,6 @@ __FBSDID("$FreeBSD$");
|
||||
#define BRIDGE_RTABLE_PRUNE_PERIOD (5 * 60)
|
||||
#endif
|
||||
|
||||
static struct mtx bridge_list_mtx;
|
||||
|
||||
int bridge_rtable_prune_period = BRIDGE_RTABLE_PRUNE_PERIOD;
|
||||
|
||||
uma_zone_t bridge_rtnode_zone;
|
||||
@ -339,8 +337,6 @@ const int bridge_control_table_size =
|
||||
static const u_char etherbroadcastaddr[ETHER_ADDR_LEN] =
|
||||
{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
|
||||
|
||||
LIST_HEAD(, bridge_softc) bridge_list;
|
||||
|
||||
IFC_SIMPLE_DECLARE(bridge, 0);
|
||||
|
||||
static int
|
||||
@ -349,12 +345,10 @@ bridge_modevent(module_t mod, int type, void *data)
|
||||
|
||||
switch (type) {
|
||||
case MOD_LOAD:
|
||||
mtx_init(&bridge_list_mtx, "if_bridge list", NULL, MTX_DEF);
|
||||
if_clone_attach(&bridge_cloner);
|
||||
bridge_rtnode_zone = uma_zcreate("bridge_rtnode",
|
||||
sizeof(struct bridge_rtnode), NULL, NULL, NULL, NULL,
|
||||
UMA_ALIGN_PTR, 0);
|
||||
LIST_INIT(&bridge_list);
|
||||
bridge_input_p = bridge_input;
|
||||
bridge_output_p = bridge_output;
|
||||
bridge_dn_p = bridge_dummynet;
|
||||
@ -363,16 +357,12 @@ bridge_modevent(module_t mod, int type, void *data)
|
||||
break;
|
||||
case MOD_UNLOAD:
|
||||
if_clone_detach(&bridge_cloner);
|
||||
while (!LIST_EMPTY(&bridge_list))
|
||||
ifc_simple_destroy(&bridge_cloner,
|
||||
LIST_FIRST(&bridge_list)->sc_ifp);
|
||||
uma_zdestroy(bridge_rtnode_zone);
|
||||
bridge_input_p = NULL;
|
||||
bridge_output_p = NULL;
|
||||
bridge_dn_p = NULL;
|
||||
bridge_detach_p = NULL;
|
||||
bstp_linkstate_p = NULL;
|
||||
mtx_destroy(&bridge_list_mtx);
|
||||
break;
|
||||
default:
|
||||
return EOPNOTSUPP;
|
||||
@ -482,10 +472,6 @@ bridge_clone_create(struct if_clone *ifc, int unit)
|
||||
ifp->if_baudrate = 0;
|
||||
ifp->if_type = IFT_BRIDGE;
|
||||
|
||||
mtx_lock(&bridge_list_mtx);
|
||||
LIST_INSERT_HEAD(&bridge_list, sc, sc_list);
|
||||
mtx_unlock(&bridge_list_mtx);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -513,10 +499,6 @@ bridge_clone_destroy(struct ifnet *ifp)
|
||||
callout_drain(&sc->sc_brcallout);
|
||||
callout_drain(&sc->sc_bstpcallout);
|
||||
|
||||
mtx_lock(&bridge_list_mtx);
|
||||
LIST_REMOVE(sc, sc_list);
|
||||
mtx_unlock(&bridge_list_mtx);
|
||||
|
||||
ether_ifdetach(ifp);
|
||||
if_free_type(ifp, IFT_ETHER);
|
||||
|
||||
|
@ -264,7 +264,6 @@ struct bridge_rtnode {
|
||||
*/
|
||||
struct bridge_softc {
|
||||
struct ifnet *sc_ifp; /* make this an interface */
|
||||
LIST_ENTRY(bridge_softc) sc_list;
|
||||
struct mtx sc_mtx;
|
||||
struct cv sc_cv;
|
||||
uint64_t sc_designated_root;
|
||||
|
@ -49,7 +49,9 @@
|
||||
#include <net/radix.h>
|
||||
#include <net/route.h>
|
||||
|
||||
static void if_clone_free(struct if_clone *ifc);
|
||||
static void if_clone_free(struct if_clone *ifc);
|
||||
static int if_clone_createif(struct if_clone *ifc, char *name, size_t len);
|
||||
static int if_clone_destroyif(struct if_clone *ifc, struct ifnet *ifp);
|
||||
|
||||
static struct mtx if_cloners_mtx;
|
||||
static int if_cloners_count;
|
||||
@ -100,6 +102,11 @@ LIST_HEAD(, if_clone) if_cloners = LIST_HEAD_INITIALIZER(if_cloners);
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define IFC_IFLIST_INSERT(_ifc, _ifp) \
|
||||
LIST_INSERT_HEAD(&_ifc->ifc_iflist, _ifp, if_clones)
|
||||
#define IFC_IFLIST_REMOVE(_ifc, _ifp) \
|
||||
LIST_REMOVE(_ifp, if_clones)
|
||||
|
||||
static MALLOC_DEFINE(M_CLONE, "clone", "interface cloning framework");
|
||||
|
||||
void
|
||||
@ -109,17 +116,13 @@ if_clone_init(void)
|
||||
}
|
||||
|
||||
/*
|
||||
* Create a clone network interface.
|
||||
* Lookup and create a clone network interface.
|
||||
*/
|
||||
int
|
||||
if_clone_create(char *name, size_t len)
|
||||
{
|
||||
int err;
|
||||
struct if_clone *ifc;
|
||||
|
||||
if (ifunit(name) != NULL)
|
||||
return (EEXIST);
|
||||
|
||||
/* Try to find an applicable cloner for this request */
|
||||
IF_CLONERS_LOCK();
|
||||
LIST_FOREACH(ifc, &if_cloners, ifc_list) {
|
||||
@ -132,17 +135,42 @@ if_clone_create(char *name, size_t len)
|
||||
if (ifc == NULL)
|
||||
return (EINVAL);
|
||||
|
||||
return (if_clone_createif(ifc, name, len));
|
||||
}
|
||||
|
||||
/*
|
||||
* Create a clone network interface.
|
||||
*/
|
||||
static int
|
||||
if_clone_createif(struct if_clone *ifc, char *name, size_t len)
|
||||
{
|
||||
int err;
|
||||
struct ifnet *ifp;
|
||||
|
||||
if (ifunit(name) != NULL)
|
||||
return (EEXIST);
|
||||
|
||||
err = (*ifc->ifc_create)(ifc, name, len);
|
||||
|
||||
if (!err) {
|
||||
ifp = ifunit(name);
|
||||
if (ifp == NULL)
|
||||
panic("%s: lookup failed for %s", __func__, name);
|
||||
|
||||
IF_CLONE_LOCK(ifc);
|
||||
IFC_IFLIST_INSERT(ifc, ifp);
|
||||
IF_CLONE_UNLOCK(ifc);
|
||||
}
|
||||
|
||||
return (err);
|
||||
}
|
||||
|
||||
/*
|
||||
* Destroy a clone network interface.
|
||||
* Lookup and destroy a clone network interface.
|
||||
*/
|
||||
int
|
||||
if_clone_destroy(const char *name)
|
||||
{
|
||||
int err;
|
||||
struct if_clone *ifc;
|
||||
struct ifnet *ifp;
|
||||
|
||||
@ -161,6 +189,21 @@ if_clone_destroy(const char *name)
|
||||
if (ifc == NULL)
|
||||
return (EINVAL);
|
||||
|
||||
return (if_clone_destroyif(ifc, ifp));
|
||||
}
|
||||
|
||||
/*
|
||||
* Destroy a clone network interface.
|
||||
*/
|
||||
static int
|
||||
if_clone_destroyif(struct if_clone *ifc, struct ifnet *ifp)
|
||||
{
|
||||
int err;
|
||||
|
||||
IF_CLONE_LOCK(ifc);
|
||||
IFC_IFLIST_REMOVE(ifc, ifp);
|
||||
IF_CLONE_UNLOCK(ifc);
|
||||
|
||||
if (ifc->ifc_destroy == NULL) {
|
||||
err = EOPNOTSUPP;
|
||||
goto done;
|
||||
@ -197,6 +240,8 @@ if_clone_attach(struct if_clone *ifc)
|
||||
if_cloners_count++;
|
||||
IF_CLONERS_UNLOCK();
|
||||
|
||||
LIST_INIT(&ifc->ifc_iflist);
|
||||
|
||||
if (ifc->ifc_attach != NULL)
|
||||
(*ifc->ifc_attach)(ifc);
|
||||
EVENTHANDLER_INVOKE(if_clone_event, ifc);
|
||||
@ -219,6 +264,10 @@ if_clone_detach(struct if_clone *ifc)
|
||||
if (ifc->ifc_attach == ifc_simple_attach)
|
||||
ifcs->ifcs_minifs = 0;
|
||||
|
||||
/* destroy all interfaces for this cloner */
|
||||
while (!LIST_EMPTY(&ifc->ifc_iflist))
|
||||
if_clone_destroyif(ifc, LIST_FIRST(&ifc->ifc_iflist));
|
||||
|
||||
IF_CLONE_REMREF(ifc);
|
||||
}
|
||||
|
||||
@ -230,6 +279,9 @@ if_clone_free(struct if_clone *ifc)
|
||||
("ifc_units[%d] is not empty", bytoff));
|
||||
}
|
||||
|
||||
KASSERT(LIST_EMPTY(&ifc->ifc_iflist),
|
||||
("%s: ifc_iflist not empty", __func__));
|
||||
|
||||
IF_CLONE_LOCK_DESTROY(ifc);
|
||||
free(ifc->ifc_units, M_CLONE);
|
||||
}
|
||||
@ -401,7 +453,7 @@ ifc_simple_attach(struct if_clone *ifc)
|
||||
|
||||
for (unit = 0; unit < ifcs->ifcs_minifs; unit++) {
|
||||
snprintf(name, IFNAMSIZ, "%s%d", ifc->ifc_name, unit);
|
||||
err = (*ifc->ifc_create)(ifc, name, IFNAMSIZ);
|
||||
err = if_clone_createif(ifc, name, IFNAMSIZ);
|
||||
KASSERT(err == 0,
|
||||
("%s: failed to create required interface %s",
|
||||
__func__, name));
|
||||
|
@ -66,6 +66,7 @@ struct if_clone {
|
||||
|
||||
long ifc_refcnt; /* (i) Refrence count. */
|
||||
struct mtx ifc_mtx; /* Muted to protect members. */
|
||||
LIST_HEAD(, ifnet) ifc_iflist; /* (i) List of cloned interfaces */
|
||||
};
|
||||
|
||||
void if_clone_init(void);
|
||||
|
@ -63,7 +63,6 @@
|
||||
|
||||
struct disc_softc {
|
||||
struct ifnet *sc_ifp; /* must be first */
|
||||
LIST_ENTRY(disc_softc) sc_list;
|
||||
};
|
||||
|
||||
static int discoutput(struct ifnet *, struct mbuf *,
|
||||
@ -73,9 +72,7 @@ static int discioctl(struct ifnet *, u_long, caddr_t);
|
||||
static int disc_clone_create(struct if_clone *, int);
|
||||
static void disc_clone_destroy(struct ifnet *);
|
||||
|
||||
static struct mtx disc_mtx;
|
||||
static MALLOC_DEFINE(M_DISC, DISCNAME, "Discard interface");
|
||||
static LIST_HEAD(, disc_softc) disc_softc_list;
|
||||
|
||||
IFC_SIMPLE_DECLARE(disc, 0);
|
||||
|
||||
@ -103,9 +100,6 @@ disc_clone_create(struct if_clone *ifc, int unit)
|
||||
ifp->if_snd.ifq_maxlen = 20;
|
||||
if_attach(ifp);
|
||||
bpfattach(ifp, DLT_NULL, sizeof(u_int32_t));
|
||||
mtx_lock(&disc_mtx);
|
||||
LIST_INSERT_HEAD(&disc_softc_list, sc, sc_list);
|
||||
mtx_unlock(&disc_mtx);
|
||||
|
||||
return (0);
|
||||
}
|
||||
@ -116,9 +110,6 @@ disc_clone_destroy(struct ifnet *ifp)
|
||||
struct disc_softc *sc;
|
||||
|
||||
sc = ifp->if_softc;
|
||||
mtx_lock(&disc_mtx);
|
||||
LIST_REMOVE(sc, sc_list);
|
||||
mtx_unlock(&disc_mtx);
|
||||
|
||||
bpfdetach(ifp);
|
||||
if_detach(ifp);
|
||||
@ -130,25 +121,13 @@ disc_clone_destroy(struct ifnet *ifp)
|
||||
static int
|
||||
disc_modevent(module_t mod, int type, void *data)
|
||||
{
|
||||
struct disc_softc *sc;
|
||||
|
||||
switch (type) {
|
||||
case MOD_LOAD:
|
||||
mtx_init(&disc_mtx, "disc_mtx", NULL, MTX_DEF);
|
||||
LIST_INIT(&disc_softc_list);
|
||||
if_clone_attach(&disc_cloner);
|
||||
break;
|
||||
case MOD_UNLOAD:
|
||||
if_clone_detach(&disc_cloner);
|
||||
|
||||
mtx_lock(&disc_mtx);
|
||||
while ((sc = LIST_FIRST(&disc_softc_list)) != NULL) {
|
||||
mtx_unlock(&disc_mtx);
|
||||
ifc_simple_destroy(&disc_cloner, sc->sc_ifp);
|
||||
mtx_lock(&disc_mtx);
|
||||
}
|
||||
mtx_unlock(&disc_mtx);
|
||||
mtx_destroy(&disc_mtx);
|
||||
break;
|
||||
default:
|
||||
return (EOPNOTSUPP);
|
||||
|
@ -84,7 +84,6 @@
|
||||
|
||||
struct faith_softc {
|
||||
struct ifnet *sc_ifp;
|
||||
LIST_ENTRY(faith_softc) sc_list;
|
||||
};
|
||||
|
||||
static int faithioctl(struct ifnet *, u_long, caddr_t);
|
||||
@ -97,9 +96,7 @@ static int faithprefix(struct in6_addr *);
|
||||
|
||||
static int faithmodevent(module_t, int, void *);
|
||||
|
||||
static struct mtx faith_mtx;
|
||||
static MALLOC_DEFINE(M_FAITH, FAITHNAME, "Firewall Assisted Tunnel Interface");
|
||||
static LIST_HEAD(, faith_softc) faith_softc_list;
|
||||
|
||||
static int faith_clone_create(struct if_clone *, int);
|
||||
static void faith_clone_destroy(struct ifnet *);
|
||||
@ -114,12 +111,9 @@ faithmodevent(mod, type, data)
|
||||
int type;
|
||||
void *data;
|
||||
{
|
||||
struct faith_softc *sc;
|
||||
|
||||
switch (type) {
|
||||
case MOD_LOAD:
|
||||
mtx_init(&faith_mtx, "faith_mtx", NULL, MTX_DEF);
|
||||
LIST_INIT(&faith_softc_list);
|
||||
if_clone_attach(&faith_cloner);
|
||||
|
||||
#ifdef INET6
|
||||
@ -133,15 +127,6 @@ faithmodevent(mod, type, data)
|
||||
#endif
|
||||
|
||||
if_clone_detach(&faith_cloner);
|
||||
|
||||
mtx_lock(&faith_mtx);
|
||||
while ((sc = LIST_FIRST(&faith_softc_list)) != NULL) {
|
||||
mtx_unlock(&faith_mtx);
|
||||
ifc_simple_destroy(&faith_cloner, sc->sc_ifp);
|
||||
mtx_lock(&faith_mtx);
|
||||
}
|
||||
mtx_unlock(&faith_mtx);
|
||||
mtx_destroy(&faith_mtx);
|
||||
break;
|
||||
default:
|
||||
return EOPNOTSUPP;
|
||||
@ -186,9 +171,6 @@ faith_clone_create(ifc, unit)
|
||||
ifp->if_snd.ifq_maxlen = ifqmaxlen;
|
||||
if_attach(ifp);
|
||||
bpfattach(ifp, DLT_NULL, sizeof(u_int32_t));
|
||||
mtx_lock(&faith_mtx);
|
||||
LIST_INSERT_HEAD(&faith_softc_list, sc, sc_list);
|
||||
mtx_unlock(&faith_mtx);
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -198,10 +180,6 @@ faith_clone_destroy(ifp)
|
||||
{
|
||||
struct faith_softc *sc = ifp->if_softc;
|
||||
|
||||
mtx_lock(&faith_mtx);
|
||||
LIST_REMOVE(sc, sc_list);
|
||||
mtx_unlock(&faith_mtx);
|
||||
|
||||
bpfdetach(ifp);
|
||||
if_detach(ifp);
|
||||
if_free(ifp);
|
||||
|
@ -225,7 +225,6 @@ gifmodevent(mod, type, data)
|
||||
int type;
|
||||
void *data;
|
||||
{
|
||||
struct gif_softc *sc;
|
||||
|
||||
switch (type) {
|
||||
case MOD_LOAD:
|
||||
@ -240,14 +239,6 @@ gifmodevent(mod, type, data)
|
||||
break;
|
||||
case MOD_UNLOAD:
|
||||
if_clone_detach(&gif_cloner);
|
||||
|
||||
mtx_lock(&gif_mtx);
|
||||
while ((sc = LIST_FIRST(&gif_softc_list)) != NULL) {
|
||||
mtx_unlock(&gif_mtx);
|
||||
ifc_simple_destroy(&gif_cloner, GIF2IFP(sc));
|
||||
mtx_lock(&gif_mtx);
|
||||
}
|
||||
mtx_unlock(&gif_mtx);
|
||||
mtx_destroy(&gif_mtx);
|
||||
#ifdef INET6
|
||||
ip6_gif_hlim = 0;
|
||||
|
@ -774,7 +774,6 @@ gre_in_cksum(u_int16_t *p, u_int len)
|
||||
static int
|
||||
gremodevent(module_t mod, int type, void *data)
|
||||
{
|
||||
struct gre_softc *sc;
|
||||
|
||||
switch (type) {
|
||||
case MOD_LOAD:
|
||||
@ -782,14 +781,6 @@ gremodevent(module_t mod, int type, void *data)
|
||||
break;
|
||||
case MOD_UNLOAD:
|
||||
if_clone_detach(&gre_cloner);
|
||||
|
||||
mtx_lock(&gre_mtx);
|
||||
while ((sc = LIST_FIRST(&gre_softc_list)) != NULL) {
|
||||
mtx_unlock(&gre_mtx);
|
||||
ifc_simple_destroy(&gre_cloner, GRE2IFP(sc));
|
||||
mtx_lock(&gre_mtx);
|
||||
}
|
||||
mtx_unlock(&gre_mtx);
|
||||
mtx_destroy(&gre_mtx);
|
||||
break;
|
||||
default:
|
||||
|
@ -263,7 +263,6 @@ ppp_clone_destroy(struct ifnet *ifp)
|
||||
static int
|
||||
ppp_modevent(module_t mod, int type, void *data)
|
||||
{
|
||||
struct ppp_softc *sc;
|
||||
|
||||
switch (type) {
|
||||
case MOD_LOAD:
|
||||
@ -285,13 +284,6 @@ ppp_modevent(module_t mod, int type, void *data)
|
||||
netisr_unregister(NETISR_PPP);
|
||||
|
||||
if_clone_detach(&ppp_cloner);
|
||||
|
||||
PPP_LIST_LOCK();
|
||||
while ((sc = LIST_FIRST(&ppp_softc_list)) != NULL) {
|
||||
PPP_LIST_UNLOCK();
|
||||
ifc_simple_destroy(&ppp_cloner, PPP2IFP(sc));
|
||||
PPP_LIST_LOCK();
|
||||
}
|
||||
PPP_LIST_LOCK_DESTROY();
|
||||
break;
|
||||
default:
|
||||
|
@ -138,19 +138,14 @@ struct stf_softc {
|
||||
} __sc_ro46;
|
||||
#define sc_ro __sc_ro46.__sc_ro4
|
||||
const struct encaptab *encap_cookie;
|
||||
LIST_ENTRY(stf_softc) sc_list; /* all stf's are linked */
|
||||
};
|
||||
#define STF2IFP(sc) ((sc)->sc_ifp)
|
||||
|
||||
/*
|
||||
* All mutable global variables in if_stf.c are protected by stf_mtx.
|
||||
* XXXRW: Note that mutable fields in the softc are not currently locked:
|
||||
* in particular, sc_ro needs to be protected from concurrent entrance
|
||||
* of stf_output().
|
||||
*/
|
||||
static struct mtx stf_mtx;
|
||||
static LIST_HEAD(, stf_softc) stf_softc_list;
|
||||
|
||||
static MALLOC_DEFINE(M_STF, STFNAME, "6to4 Tunnel Interface");
|
||||
static const int ip_stf_ttl = 40;
|
||||
|
||||
@ -246,9 +241,6 @@ stf_clone_create(struct if_clone *ifc, char *name, size_t len)
|
||||
ifp->if_snd.ifq_maxlen = IFQ_MAXLEN;
|
||||
if_attach(ifp);
|
||||
bpfattach(ifp, DLT_NULL, sizeof(u_int32_t));
|
||||
mtx_lock(&stf_mtx);
|
||||
LIST_INSERT_HEAD(&stf_softc_list, sc, sc_list);
|
||||
mtx_unlock(&stf_mtx);
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -258,10 +250,6 @@ stf_clone_destroy(struct if_clone *ifc, struct ifnet *ifp)
|
||||
struct stf_softc *sc = ifp->if_softc;
|
||||
int err;
|
||||
|
||||
mtx_lock(&stf_mtx);
|
||||
LIST_REMOVE(sc, sc_list);
|
||||
mtx_unlock(&stf_mtx);
|
||||
|
||||
err = encap_detach(sc->encap_cookie);
|
||||
KASSERT(err == 0, ("Unexpected error detaching encap_cookie"));
|
||||
bpfdetach(ifp);
|
||||
@ -280,26 +268,13 @@ stfmodevent(mod, type, data)
|
||||
int type;
|
||||
void *data;
|
||||
{
|
||||
struct stf_softc *sc;
|
||||
|
||||
switch (type) {
|
||||
case MOD_LOAD:
|
||||
mtx_init(&stf_mtx, "stf_mtx", NULL, MTX_DEF);
|
||||
LIST_INIT(&stf_softc_list);
|
||||
if_clone_attach(&stf_cloner);
|
||||
|
||||
break;
|
||||
case MOD_UNLOAD:
|
||||
if_clone_detach(&stf_cloner);
|
||||
|
||||
mtx_lock(&stf_mtx);
|
||||
while ((sc = LIST_FIRST(&stf_softc_list)) != NULL) {
|
||||
mtx_unlock(&stf_mtx);
|
||||
stf_clone_destroy(&stf_cloner, STF2IFP(sc));
|
||||
mtx_lock(&stf_mtx);
|
||||
}
|
||||
mtx_unlock(&stf_mtx);
|
||||
mtx_destroy(&stf_mtx);
|
||||
break;
|
||||
default:
|
||||
return (EOPNOTSUPP);
|
||||
|
@ -180,6 +180,7 @@ struct ifnet {
|
||||
struct task if_starttask; /* task for IFF_NEEDSGIANT */
|
||||
struct task if_linktask; /* task for link change events */
|
||||
struct mtx if_addr_mtx; /* mutex to protect address lists */
|
||||
LIST_ENTRY(ifnet) if_clones; /* interfaces of a cloner */
|
||||
};
|
||||
|
||||
typedef void if_init_f_t(void *);
|
||||
|
@ -251,9 +251,6 @@ vlan_modevent(module_t mod, int type, void *data)
|
||||
if_clone_detach(&vlan_cloner);
|
||||
vlan_input_p = NULL;
|
||||
vlan_link_state_p = NULL;
|
||||
while (!LIST_EMPTY(&ifv_list))
|
||||
vlan_clone_destroy(&vlan_cloner,
|
||||
LIST_FIRST(&ifv_list)->ifv_ifp);
|
||||
VLAN_LOCK_DESTROY();
|
||||
break;
|
||||
default:
|
||||
|
@ -2143,9 +2143,6 @@ carp_modevent(module_t mod, int type, void *data)
|
||||
|
||||
case MOD_UNLOAD:
|
||||
if_clone_detach(&carp_cloner);
|
||||
while (!LIST_EMPTY(&carpif_list))
|
||||
ifc_simple_destroy(&carp_cloner,
|
||||
SC2IFP(LIST_FIRST(&carpif_list)));
|
||||
mtx_destroy(&carp_mtx);
|
||||
break;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user