summaryrefslogtreecommitdiffstats
path: root/sys/net/if_stf.c
diff options
context:
space:
mode:
authorthompsa <thompsa@FreeBSD.org>2005-10-12 19:52:16 +0000
committerthompsa <thompsa@FreeBSD.org>2005-10-12 19:52:16 +0000
commitd6130a47038460d2093bdc0fcdadd546393cc823 (patch)
treee685414c2d4a9a0e96a99f9d18fa6ce3780a6fbe /sys/net/if_stf.c
parent1917bf7b66cadbb6cbcc022f50fb4252b6996ff7 (diff)
downloadFreeBSD-src-d6130a47038460d2093bdc0fcdadd546393cc823.zip
FreeBSD-src-d6130a47038460d2093bdc0fcdadd546393cc823.tar.gz
Change the reference counting to count the number of cloned interfaces for each
cloner. This ensures that ifc->ifc_units is not prematurely freed in if_clone_detach() before the clones are destroyed, resulting in memory modified after free. This could be triggered with if_vlan. Assert that all cloners have been destroyed when freeing the memory. Change all simple cloners to destroy their clones with ifc_simple_destroy() on module unload so the reference count is properly updated. This also cleans up the interface destroy routines and allows future optimisation. Discussed with: brooks, pjd, -current Reviewed by: brooks
Diffstat (limited to 'sys/net/if_stf.c')
-rw-r--r--sys/net/if_stf.c26
1 files changed, 9 insertions, 17 deletions
diff --git a/sys/net/if_stf.c b/sys/net/if_stf.c
index 3ba3343..e779b17 100644
--- a/sys/net/if_stf.c
+++ b/sys/net/if_stf.c
@@ -252,30 +252,23 @@ stf_clone_create(struct if_clone *ifc, char *name, size_t len)
return (0);
}
-static void
-stf_destroy(struct stf_softc *sc)
-{
- int err;
-
- err = encap_detach(sc->encap_cookie);
- KASSERT(err == 0, ("Unexpected error detaching encap_cookie"));
- bpfdetach(STF2IFP(sc));
- if_detach(STF2IFP(sc));
- if_free(STF2IFP(sc));
-
- free(sc, M_STF);
-}
-
static int
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);
- stf_destroy(sc);
+ err = encap_detach(sc->encap_cookie);
+ KASSERT(err == 0, ("Unexpected error detaching encap_cookie"));
+ bpfdetach(ifp);
+ if_detach(ifp);
+ if_free(ifp);
+
+ free(sc, M_STF);
ifc_free_unit(ifc, STFUNIT);
return (0);
@@ -301,9 +294,8 @@ stfmodevent(mod, type, data)
mtx_lock(&stf_mtx);
while ((sc = LIST_FIRST(&stf_softc_list)) != NULL) {
- LIST_REMOVE(sc, sc_list);
mtx_unlock(&stf_mtx);
- stf_destroy(sc);
+ stf_clone_destroy(&stf_cloner, STF2IFP(sc));
mtx_lock(&stf_mtx);
}
mtx_unlock(&stf_mtx);
OpenPOWER on IntegriCloud