diff options
author | rwatson <rwatson@FreeBSD.org> | 2004-03-22 16:04:43 +0000 |
---|---|---|
committer | rwatson <rwatson@FreeBSD.org> | 2004-03-22 16:04:43 +0000 |
commit | aaf338640edc5b97817ed043864912e3193b5c72 (patch) | |
tree | 57de7b111e737beb9dc79a5c406c2c378993a50d /sys/netinet/ip_gre.c | |
parent | 2f3c5b96fbd42a5b2ad28a77e6cb4ceaa6d76832 (diff) | |
download | FreeBSD-src-aaf338640edc5b97817ed043864912e3193b5c72.zip FreeBSD-src-aaf338640edc5b97817ed043864912e3193b5c72.tar.gz |
Lock down global variables in if_gre:
- Add gre_mtx to protect global softc list.
- Hold gre_mtx over various list operations (insert, delete).
- Centralize if_gre interface teardown in gre_destroy(), and call this
from modevent unload and gre_clone_destroy().
- Export gre_mtx to ip_gre.c, which walks the gre list to look up gre
interfaces during encapsulation. Add a wonking comment on how we need
some sort of drain/reference count mechanism to keep gre references
alive while in use and simultaneous destroy.
This commit does not lockdown softc data, which follows in a future
commit.
Diffstat (limited to 'sys/netinet/ip_gre.c')
-rw-r--r-- | sys/netinet/ip_gre.c | 13 |
1 files changed, 12 insertions, 1 deletions
diff --git a/sys/netinet/ip_gre.c b/sys/netinet/ip_gre.c index 960b8a8..c11317d 100644 --- a/sys/netinet/ip_gre.c +++ b/sys/netinet/ip_gre.c @@ -314,6 +314,13 @@ gre_mobile_input(m, va_alist) /* * Find the gre interface associated with our src/dst/proto set. + * + * XXXRW: Need some sort of drain/refcount mechanism so that the softc + * reference remains valid after it's returned from gre_lookup(). Right + * now, I'm thinking it should be reference-counted with a gre_dropref() + * when the caller is done with the softc. This is complicated by how + * to handle destroying the gre softc; probably using a gre_drain() in + * in_gre.c during destroy. */ static struct gre_softc * gre_lookup(m, proto) @@ -323,14 +330,18 @@ gre_lookup(m, proto) struct ip *ip = mtod(m, struct ip *); struct gre_softc *sc; + mtx_lock(&gre_mtx); for (sc = LIST_FIRST(&gre_softc_list); sc != NULL; sc = LIST_NEXT(sc, sc_list)) { if ((sc->g_dst.s_addr == ip->ip_src.s_addr) && (sc->g_src.s_addr == ip->ip_dst.s_addr) && (sc->g_proto == proto) && - ((sc->sc_if.if_flags & IFF_UP) != 0)) + ((sc->sc_if.if_flags & IFF_UP) != 0)) { + mtx_unlock(&gre_mtx); return (sc); + } } + mtx_unlock(&gre_mtx); return (NULL); } |