X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/b7266188b87f3620ec3f9f717e57194a7dd989fe..d1ecb069dfe24481e4a83f44cb5217a2b06746d7:/bsd/net/if_pflog.c?ds=inline diff --git a/bsd/net/if_pflog.c b/bsd/net/if_pflog.c index 278a7b198..8e7480911 100644 --- a/bsd/net/if_pflog.c +++ b/bsd/net/if_pflog.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008 Apple Inc. All rights reserved. + * Copyright (c) 2007-2010 Apple Inc. All rights reserved. * * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ * @@ -70,6 +70,7 @@ #include #include +#include #include #include #include @@ -100,7 +101,8 @@ #define DPRINTF(x) #endif -static int pflog_create_dev(void); +static int pflog_clone_create(struct if_clone *, u_int32_t, void *); +static int pflog_clone_destroy(struct ifnet *); static errno_t pflogoutput(struct ifnet *, struct mbuf *); static errno_t pflogioctl(struct ifnet *, unsigned long, void *); static errno_t pflogdemux(struct ifnet *, struct mbuf *, char *, @@ -108,50 +110,43 @@ static errno_t pflogdemux(struct ifnet *, struct mbuf *, char *, static errno_t pflogaddproto(struct ifnet *, protocol_family_t, const struct ifnet_demux_desc *, u_int32_t); static errno_t pflogdelproto(struct ifnet *, protocol_family_t); +static void pflogfree(struct ifnet *); static LIST_HEAD(, pflog_softc) pflogif_list; +static struct if_clone pflog_cloner = + IF_CLONE_INITIALIZER(PFLOGNAME, pflog_clone_create, pflog_clone_destroy, + 0, (PFLOGIFS_MAX - 1)); struct ifnet *pflogifs[PFLOGIFS_MAX]; /* for fast access */ -static int npflog; -static lck_attr_t *pflog_lock_attr; -static lck_grp_t *pflog_lock_grp; -static lck_grp_attr_t *pflog_lock_grp_attr; -static lck_mtx_t *pflog_lock; void pfloginit(void) { int i; - if (pflog_lock != NULL) - return; - - pflog_lock_grp_attr = lck_grp_attr_alloc_init(); - pflog_lock_grp = lck_grp_alloc_init("pflog", pflog_lock_grp_attr); - pflog_lock_attr = lck_attr_alloc_init(); - pflog_lock = lck_mtx_alloc_init(pflog_lock_grp, pflog_lock_attr); - if (pflog_lock == NULL) { - panic("%s: unable to allocate lock", __func__); + if (pf_perim_lock == NULL || pf_lock == NULL) { + panic("%s: called before PF is initialized", __func__); /* NOTREACHED */ } LIST_INIT(&pflogif_list); for (i = 0; i < PFLOGIFS_MAX; i++) pflogifs[i] = NULL; - pflog_create_dev(); + (void) if_clone_attach(&pflog_cloner); } static int -pflog_create_dev(void) +pflog_clone_create(struct if_clone *ifc, u_int32_t unit, __unused void *params) { struct pflog_softc *pflogif; struct ifnet_init_params pf_init; int error = 0; - lck_mtx_lock(pflog_lock); - if (npflog >= PFLOGIFS_MAX) { - error = EINVAL; - goto done; + if (unit >= PFLOGIFS_MAX) { + /* Either the interface cloner or our initializer is broken */ + panic("%s: unit (%d) exceeds max (%d)", __func__, unit, + PFLOGIFS_MAX); + /* NOTREACHED */ } if ((pflogif = _MALLOC(sizeof (*pflogif), @@ -161,8 +156,8 @@ pflog_create_dev(void) } bzero(&pf_init, sizeof (pf_init)); - pf_init.name = PFLOGNAME; - pf_init.unit = npflog; + pf_init.name = ifc->ifc_name; + pf_init.unit = unit; pf_init.type = IFT_PFLOG; pf_init.family = IFNET_FAMILY_LOOPBACK; pf_init.output = pflogoutput; @@ -171,9 +166,10 @@ pflog_create_dev(void) pf_init.del_proto = pflogdelproto; pf_init.softc = pflogif; pf_init.ioctl = pflogioctl; + pf_init.detach = pflogfree; bzero(pflogif, sizeof (*pflogif)); - pflogif->sc_unit = npflog; + pflogif->sc_unit = unit; error = ifnet_allocate(&pf_init, &pflogif->sc_if); if (error != 0) { @@ -197,34 +193,34 @@ pflog_create_dev(void) bpfattach(pflogif->sc_if, DLT_PFLOG, PFLOG_HDRLEN); #endif + lck_rw_lock_shared(pf_perim_lock); + lck_mtx_lock(pf_lock); LIST_INSERT_HEAD(&pflogif_list, pflogif, sc_list); - pflogifs[npflog] = pflogif->sc_if; - ++npflog; -done: - lck_mtx_unlock(pflog_lock); + pflogifs[unit] = pflogif->sc_if; + lck_mtx_unlock(pf_lock); + lck_rw_done(pf_perim_lock); +done: return (error); } -#if 0 -int -pflog_destroy_dev(struct ifnet *ifp) +static int +pflog_clone_destroy(struct ifnet *ifp) { - struct pflog_softc *pflogif = ifp->if_softc; + struct pflog_softc *pflogif = ifp->if_softc; - lck_mtx_lock(pflog_lock); + lck_rw_lock_shared(pf_perim_lock); + lck_mtx_lock(pf_lock); pflogifs[pflogif->sc_unit] = NULL; LIST_REMOVE(pflogif, sc_list); - lck_mtx_unlock(pflog_lock); + lck_mtx_unlock(pf_lock); + lck_rw_done(pf_perim_lock); -#if NBPFILTER > 0 - bpfdetach(ifp); -#endif - if_detach(ifp); - _FREE(pflogif, M_DEVBUF); - return (0); + /* bpfdetach() is taken care of as part of interface detach */ + (void) ifnet_detach(ifp); + + return 0; } -#endif static errno_t pflogoutput(struct ifnet *ifp, struct mbuf *m) @@ -281,6 +277,14 @@ pflogdelproto(struct ifnet *ifp, protocol_family_t pf) return (0); } +static void +pflogfree(struct ifnet *ifp) +{ + _FREE(ifp->if_softc, M_DEVBUF); + ifp->if_softc = NULL; + (void) ifnet_release(ifp); +} + int pflog_packet(struct pfi_kif *kif, struct mbuf *m, sa_family_t af, u_int8_t dir, u_int8_t reason, struct pf_rule *rm, struct pf_rule *am, @@ -290,6 +294,8 @@ pflog_packet(struct pfi_kif *kif, struct mbuf *m, sa_family_t af, u_int8_t dir, struct ifnet *ifn; struct pfloghdr hdr; + lck_mtx_assert(pf_lock, LCK_MTX_ASSERT_OWNED); + if (kif == NULL || m == NULL || rm == NULL || pd == NULL) return (-1);