summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/contrib/pf/net/if_pflog.c3
-rw-r--r--sys/contrib/pf/net/if_pfsync.c3
-rw-r--r--sys/net/if_bridge.c18
-rw-r--r--sys/net/if_bridgevar.h1
-rw-r--r--sys/net/if_clone.c70
-rw-r--r--sys/net/if_clone.h1
-rw-r--r--sys/net/if_disc.c21
-rw-r--r--sys/net/if_faith.c22
-rw-r--r--sys/net/if_gif.c9
-rw-r--r--sys/net/if_gre.c9
-rw-r--r--sys/net/if_ppp.c8
-rw-r--r--sys/net/if_stf.c25
-rw-r--r--sys/net/if_var.h1
-rw-r--r--sys/net/if_vlan.c3
-rw-r--r--sys/netinet/ip_carp.c3
15 files changed, 63 insertions, 134 deletions
diff --git a/sys/contrib/pf/net/if_pflog.c b/sys/contrib/pf/net/if_pflog.c
index 2497a94..1466ec2 100644
--- a/sys/contrib/pf/net/if_pflog.c
+++ b/sys/contrib/pf/net/if_pflog.c
@@ -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:
diff --git a/sys/contrib/pf/net/if_pfsync.c b/sys/contrib/pf/net/if_pfsync.c
index 5f0e8a6..e7f80e2 100644
--- a/sys/contrib/pf/net/if_pfsync.c
+++ b/sys/contrib/pf/net/if_pfsync.c
@@ -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:
diff --git a/sys/net/if_bridge.c b/sys/net/if_bridge.c
index 0b2bd752..7090a6b 100644
--- a/sys/net/if_bridge.c
+++ b/sys/net/if_bridge.c
@@ -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);
diff --git a/sys/net/if_bridgevar.h b/sys/net/if_bridgevar.h
index 7c6b9c2..98dfcda 100644
--- a/sys/net/if_bridgevar.h
+++ b/sys/net/if_bridgevar.h
@@ -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;
diff --git a/sys/net/if_clone.c b/sys/net/if_clone.c
index 746f08f..859ece2 100644
--- a/sys/net/if_clone.c
+++ b/sys/net/if_clone.c
@@ -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));
diff --git a/sys/net/if_clone.h b/sys/net/if_clone.h
index d84b47e..38a0959 100644
--- a/sys/net/if_clone.h
+++ b/sys/net/if_clone.h
@@ -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);
diff --git a/sys/net/if_disc.c b/sys/net/if_disc.c
index 3b0804e..0a138df 100644
--- a/sys/net/if_disc.c
+++ b/sys/net/if_disc.c
@@ -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);
diff --git a/sys/net/if_faith.c b/sys/net/if_faith.c
index 677e1b2..71b8c35 100644
--- a/sys/net/if_faith.c
+++ b/sys/net/if_faith.c
@@ -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);
diff --git a/sys/net/if_gif.c b/sys/net/if_gif.c
index da611cc..c946a1c 100644
--- a/sys/net/if_gif.c
+++ b/sys/net/if_gif.c
@@ -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;
diff --git a/sys/net/if_gre.c b/sys/net/if_gre.c
index 53639f6..22ceba5 100644
--- a/sys/net/if_gre.c
+++ b/sys/net/if_gre.c
@@ -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:
diff --git a/sys/net/if_ppp.c b/sys/net/if_ppp.c
index 45915c6..3d5cd13 100644
--- a/sys/net/if_ppp.c
+++ b/sys/net/if_ppp.c
@@ -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:
diff --git a/sys/net/if_stf.c b/sys/net/if_stf.c
index e779b17..a08291a 100644
--- a/sys/net/if_stf.c
+++ b/sys/net/if_stf.c
@@ -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);
diff --git a/sys/net/if_var.h b/sys/net/if_var.h
index 783ddd8..b09319f 100644
--- a/sys/net/if_var.h
+++ b/sys/net/if_var.h
@@ -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 *);
diff --git a/sys/net/if_vlan.c b/sys/net/if_vlan.c
index 15a2a79..b8b0703 100644
--- a/sys/net/if_vlan.c
+++ b/sys/net/if_vlan.c
@@ -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:
diff --git a/sys/netinet/ip_carp.c b/sys/netinet/ip_carp.c
index 5fe4577..44157b4 100644
--- a/sys/netinet/ip_carp.c
+++ b/sys/netinet/ip_carp.c
@@ -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;
OpenPOWER on IntegriCloud