summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorrwatson <rwatson@FreeBSD.org>2004-03-09 19:23:06 +0000
committerrwatson <rwatson@FreeBSD.org>2004-03-09 19:23:06 +0000
commit63f793ca249823f0c3812457a8342dd6702d0548 (patch)
tree5743f3bb6cfced802b5012a83e5038bc924598bd /sys
parent696d0d4e7fdd6d7c8ef68038b94148e516ab1a1d (diff)
downloadFreeBSD-src-63f793ca249823f0c3812457a8342dd6702d0548.zip
FreeBSD-src-63f793ca249823f0c3812457a8342dd6702d0548.tar.gz
Introduce faith_mtx to protect the if_faith global softc list.
Push if_faith softc destruction logic into faith_destroy() so that it can be called after softc list removal in both the clone destroy and module unload paths.
Diffstat (limited to 'sys')
-rw-r--r--sys/net/if_faith.c34
1 files changed, 27 insertions, 7 deletions
diff --git a/sys/net/if_faith.c b/sys/net/if_faith.c
index 06e60cd..6a46e86 100644
--- a/sys/net/if_faith.c
+++ b/sys/net/if_faith.c
@@ -99,11 +99,13 @@ 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;
int faith_clone_create(struct if_clone *, int);
void faith_clone_destroy(struct ifnet *);
+static void faith_destroy(struct faith_softc *);
struct if_clone faith_cloner = IF_CLONE_INITIALIZER(FAITHNAME,
faith_clone_create, faith_clone_destroy, 0, IF_MAXUNIT);
@@ -116,9 +118,11 @@ 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);
@@ -134,10 +138,15 @@ faithmodevent(mod, type, data)
if_clone_detach(&faith_cloner);
- while (!LIST_EMPTY(&faith_softc_list))
- faith_clone_destroy(
- &LIST_FIRST(&faith_softc_list)->sc_if);
-
+ mtx_lock(&faith_mtx);
+ while ((sc = LIST_FIRST(&faith_softc_list)) != NULL) {
+ LIST_REMOVE(sc, sc_list);
+ mtx_unlock(&faith_mtx);
+ faith_destroy(sc);
+ mtx_lock(&faith_mtx);
+ }
+ mtx_unlock(&faith_mtx);
+ mtx_destroy(&faith_mtx);
break;
}
return 0;
@@ -176,21 +185,32 @@ faith_clone_create(ifc, unit)
sc->sc_if.if_snd.ifq_maxlen = ifqmaxlen;
if_attach(&sc->sc_if);
bpfattach(&sc->sc_if, DLT_NULL, sizeof(u_int));
+ mtx_lock(&faith_mtx);
LIST_INSERT_HEAD(&faith_softc_list, sc, sc_list);
+ mtx_unlock(&faith_mtx);
return (0);
}
+static void
+faith_destroy(struct faith_softc *sc)
+{
+
+ bpfdetach(&sc->sc_if);
+ if_detach(&sc->sc_if);
+ free(sc, M_FAITH);
+}
+
void
faith_clone_destroy(ifp)
struct ifnet *ifp;
{
struct faith_softc *sc = (void *) ifp;
+ mtx_lock(&faith_mtx);
LIST_REMOVE(sc, sc_list);
- bpfdetach(ifp);
- if_detach(ifp);
+ mtx_unlock(&faith_mtx);
- free(sc, M_FAITH);
+ faith_destroy(sc);
}
int
OpenPOWER on IntegriCloud