From 0a6c1d4242d4d23328bf77b152fe0864e2db7f35 Mon Sep 17 00:00:00 2001 From: sam Date: Mon, 29 Sep 2003 22:57:43 +0000 Subject: MFp4: portability work, general cleanup, locking fixes change 38496 o add ipsec_osdep.h that holds os-specific definitions for portability o s/KASSERT/IPSEC_ASSERT/ for portability o s/SPLASSERT/IPSEC_SPLASSERT/ for portability o remove function names from ASSERT strings since line#+file pinpints the location o use __func__ uniformly to reduce string storage o convert some random #ifdef DIAGNOSTIC code to assertions o remove some debuggging assertions no longer needed change 38498 o replace numerous bogus panic's with equally bogus assertions that at least go away on a production system change 38502 + 38530 o change explicit mtx operations to #defines to simplify future changes to a different lock type change 38531 o hookup ipv4 ctlinput paths to a noop routine; we should be handling path mtu changes at least o correct potential null pointer deref in ipsec4_common_input_cb chnage 38685 o fix locking for bundled SA's and for when key exchange is required change 38770 o eliminate recursion on the SAHTREE lock change 38804 o cleanup some types: long -> time_t o remove refrence to dead #define change 38805 o correct some types: long -> time_t o add scan generation # to secpolicy to deal with locking issues change 38806 o use LIST_FOREACH_SAFE instead of handrolled code o change key_flush_spd to drop the sptree lock before purging an entry to avoid lock recursion and to avoid holding the lock over a long-running operation o misc cleanups of tangled and twisty code There is still much to do here but for now things look to be working again. Supported by: FreeBSD Foundation --- sys/netipsec/key.c | 1136 ++++++++++++++++++++++++++-------------------------- 1 file changed, 574 insertions(+), 562 deletions(-) (limited to 'sys/netipsec/key.c') diff --git a/sys/netipsec/key.c b/sys/netipsec/key.c index 622a091..b8bad88 100644 --- a/sys/netipsec/key.c +++ b/sys/netipsec/key.c @@ -96,8 +96,6 @@ /* randomness */ #include -#include - #define FULLMASK 0xff #define _BITS(bytes) ((bytes) << 3) @@ -127,15 +125,52 @@ static u_int32_t acq_seq = 0; static LIST_HEAD(_sptree, secpolicy) sptree[IPSEC_DIR_MAX]; /* SPD */ static struct mtx sptree_lock; +#define SPTREE_LOCK_INIT() \ + mtx_init(&sptree_lock, "sptree", \ + "fast ipsec security policy database", MTX_DEF) +#define SPTREE_LOCK_DESTROY() mtx_destroy(&sptree_lock) +#define SPTREE_LOCK() mtx_lock(&sptree_lock) +#define SPTREE_UNLOCK() mtx_unlock(&sptree_lock) +#define SPTREE_LOCK_ASSERT() mtx_assert(&sptree_lock, MA_OWNED) + static LIST_HEAD(_sahtree, secashead) sahtree; /* SAD */ static struct mtx sahtree_lock; +#define SAHTREE_LOCK_INIT() \ + mtx_init(&sahtree_lock, "sahtree", \ + "fast ipsec security association database", MTX_DEF) +#define SAHTREE_LOCK_DESTROY() mtx_destroy(&sahtree_lock) +#define SAHTREE_LOCK() mtx_lock(&sahtree_lock) +#define SAHTREE_UNLOCK() mtx_unlock(&sahtree_lock) +#define SAHTREE_LOCK_ASSERT() mtx_assert(&sahtree_lock, MA_OWNED) + /* registed list */ static LIST_HEAD(_regtree, secreg) regtree[SADB_SATYPE_MAX + 1]; static struct mtx regtree_lock; +#define REGTREE_LOCK_INIT() \ + mtx_init(®tree_lock, "regtree", "fast ipsec regtree", MTX_DEF) +#define REGTREE_LOCK_DESTROY() mtx_destroy(®tree_lock) +#define REGTREE_LOCK() mtx_lock(®tree_lock) +#define REGTREE_UNLOCK() mtx_unlock(®tree_lock) +#define REGTREE_LOCK_ASSERT() mtx_assert(®tree_lock, MA_OWNED) + static LIST_HEAD(_acqtree, secacq) acqtree; /* acquiring list */ static struct mtx acq_lock; +#define ACQ_LOCK_INIT() \ + mtx_init(&acq_lock, "acqtree", "fast ipsec acquire list", MTX_DEF) +#define ACQ_LOCK_DESTROY() mtx_destroy(&acq_lock) +#define ACQ_LOCK() mtx_lock(&acq_lock) +#define ACQ_UNLOCK() mtx_unlock(&acq_lock) +#define ACQ_LOCK_ASSERT() mtx_assert(&acq_lock, MA_OWNED) + static LIST_HEAD(_spacqtree, secspacq) spacqtree; /* SP acquiring list */ static struct mtx spacq_lock; +#define SPACQ_LOCK_INIT() \ + mtx_init(&spacq_lock, "spacqtree", \ + "fast ipsec security policy acquire list", MTX_DEF) +#define SPACQ_LOCK_DESTROY() mtx_destroy(&spacq_lock) +#define SPACQ_LOCK() mtx_lock(&spacq_lock) +#define SPACQ_UNLOCK() mtx_unlock(&spacq_lock) +#define SPACQ_LOCK_ASSERT() mtx_assert(&spacq_lock, MA_OWNED) /* search order for SAs */ static u_int saorder_state_valid[] = { @@ -254,10 +289,6 @@ SYSCTL_INT(_net_key, KEYCTL_AH_KEYMIN, ah_keymin, CTLFLAG_RW, \ SYSCTL_INT(_net_key, KEYCTL_PREFERED_OLDSA, prefered_oldsa, CTLFLAG_RW,\ &key_prefered_oldsa, 0, ""); -#ifndef LIST_FOREACH -#define LIST_FOREACH(elm, head, field) \ - for (elm = LIST_FIRST(head); elm; elm = LIST_NEXT(elm, field)) -#endif #define __LIST_CHAINED(elm) \ (!((elm)->chain.le_next == NULL && (elm)->chain.le_prev == NULL)) #define LIST_INSERT_TAIL(head, elm, type, field) \ @@ -467,23 +498,19 @@ static struct mbuf *key_alloc_mbuf __P((int)); #define SA_ADDREF(p) do { \ (p)->refcnt++; \ - KASSERT((p)->refcnt != 0, \ - ("SA refcnt overflow at %s:%u", __FILE__, __LINE__)); \ + IPSEC_ASSERT((p)->refcnt != 0, ("SA refcnt overflow")); \ } while (0) #define SA_DELREF(p) do { \ - KASSERT((p)->refcnt > 0, \ - ("SA refcnt underflow at %s:%u", __FILE__, __LINE__)); \ + IPSEC_ASSERT((p)->refcnt > 0, ("SA refcnt underflow")); \ (p)->refcnt--; \ } while (0) #define SP_ADDREF(p) do { \ (p)->refcnt++; \ - KASSERT((p)->refcnt != 0, \ - ("SP refcnt overflow at %s:%u", __FILE__, __LINE__)); \ + IPSEC_ASSERT((p)->refcnt != 0, ("SP refcnt overflow")); \ } while (0) #define SP_DELREF(p) do { \ - KASSERT((p)->refcnt > 0, \ - ("SP refcnt underflow at %s:%u", __FILE__, __LINE__)); \ + IPSEC_ASSERT((p)->refcnt > 0, ("SP refcnt underflow")); \ (p)->refcnt--; \ } while (0) @@ -511,19 +538,19 @@ key_allocsp(struct secpolicyindex *spidx, u_int dir, const char* where, int tag) { struct secpolicy *sp; - KASSERT(spidx != NULL, ("key_allocsp: null spidx")); - KASSERT(dir == IPSEC_DIR_INBOUND || dir == IPSEC_DIR_OUTBOUND, - ("key_allocsp: invalid direction %u", dir)); + IPSEC_ASSERT(spidx != NULL, ("null spidx")); + IPSEC_ASSERT(dir == IPSEC_DIR_INBOUND || dir == IPSEC_DIR_OUTBOUND, + ("invalid direction %u", dir)); KEYDEBUG(KEYDEBUG_IPSEC_STAMP, - printf("DP key_allocsp from %s:%u\n", where, tag)); + printf("DP %s from %s:%u\n", __func__, where, tag)); /* get a SP entry */ KEYDEBUG(KEYDEBUG_IPSEC_DATA, printf("*** objects\n"); kdebug_secpolicyindex(spidx)); - mtx_lock(&sptree_lock); + SPTREE_LOCK(); LIST_FOREACH(sp, &sptree[dir], chain) { KEYDEBUG(KEYDEBUG_IPSEC_DATA, printf("*** in SPD\n"); @@ -538,16 +565,16 @@ key_allocsp(struct secpolicyindex *spidx, u_int dir, const char* where, int tag) found: if (sp) { /* sanity check */ - KEY_CHKSPDIR(sp->spidx.dir, dir, "key_allocsp"); + KEY_CHKSPDIR(sp->spidx.dir, dir, __func__); /* found a SPD entry */ sp->lastused = time_second; SP_ADDREF(sp); } - mtx_unlock(&sptree_lock); + SPTREE_UNLOCK(); KEYDEBUG(KEYDEBUG_IPSEC_STAMP, - printf("DP key_allocsp return SP:%p (ID=%u) refcnt %u\n", + printf("DP %s return SP:%p (ID=%u) refcnt %u\n", __func__, sp, sp ? sp->id : 0, sp ? sp->refcnt : 0)); return sp; } @@ -567,12 +594,12 @@ key_allocsp2(u_int32_t spi, { struct secpolicy *sp; - KASSERT(dst != NULL, ("key_allocsp2: null dst")); - KASSERT(dir == IPSEC_DIR_INBOUND || dir == IPSEC_DIR_OUTBOUND, - ("key_allocsp2: invalid direction %u", dir)); + IPSEC_ASSERT(dst != NULL, ("null dst")); + IPSEC_ASSERT(dir == IPSEC_DIR_INBOUND || dir == IPSEC_DIR_OUTBOUND, + ("invalid direction %u", dir)); KEYDEBUG(KEYDEBUG_IPSEC_STAMP, - printf("DP key_allocsp2 from %s:%u\n", where, tag)); + printf("DP %s from %s:%u\n", __func__, where, tag)); /* get a SP entry */ KEYDEBUG(KEYDEBUG_IPSEC_DATA, @@ -580,7 +607,7 @@ key_allocsp2(u_int32_t spi, printf("spi %u proto %u dir %u\n", spi, proto, dir); kdebug_sockaddr(&dst->sa)); - mtx_lock(&sptree_lock); + SPTREE_LOCK(); LIST_FOREACH(sp, &sptree[dir], chain) { KEYDEBUG(KEYDEBUG_IPSEC_DATA, printf("*** in SPD\n"); @@ -601,16 +628,16 @@ key_allocsp2(u_int32_t spi, found: if (sp) { /* sanity check */ - KEY_CHKSPDIR(sp->spidx.dir, dir, "key_allocsp2"); + KEY_CHKSPDIR(sp->spidx.dir, dir, __func__); /* found a SPD entry */ sp->lastused = time_second; SP_ADDREF(sp); } - mtx_unlock(&sptree_lock); + SPTREE_UNLOCK(); KEYDEBUG(KEYDEBUG_IPSEC_STAMP, - printf("DP key_allocsp2 return SP:%p (ID=%u) refcnt %u\n", + printf("DP %s return SP:%p (ID=%u) refcnt %u\n", __func__, sp, sp ? sp->id : 0, sp ? sp->refcnt : 0)); return sp; } @@ -632,16 +659,16 @@ key_gettunnel(const struct sockaddr *osrc, struct secpolicyindex spidx; KEYDEBUG(KEYDEBUG_IPSEC_STAMP, - printf("DP key_gettunnel from %s:%u\n", where, tag)); + printf("DP %s from %s:%u\n", __func__, where, tag)); if (isrc->sa_family != idst->sa_family) { - ipseclog((LOG_ERR, "protocol family mismatched %d != %d\n.", - isrc->sa_family, idst->sa_family)); + ipseclog((LOG_ERR, "%s: protocol family mismatched %d != %d\n.", + __func__, isrc->sa_family, idst->sa_family)); sp = NULL; goto done; } - mtx_lock(&sptree_lock); + SPTREE_LOCK(); LIST_FOREACH(sp, &sptree[dir], chain) { if (sp->state == IPSEC_SPSTATE_DEAD) continue; @@ -683,10 +710,10 @@ found: sp->lastused = time_second; SP_ADDREF(sp); } - mtx_unlock(&sptree_lock); + SPTREE_UNLOCK(); done: KEYDEBUG(KEYDEBUG_IPSEC_STAMP, - printf("DP key_gettunnel return SP:%p (ID=%u) refcnt %u\n", + printf("DP %s return SP:%p (ID=%u) refcnt %u\n", __func__, sp, sp ? sp->id : 0, sp ? sp->refcnt : 0)); return sp; } @@ -703,11 +730,11 @@ key_checkrequest(struct ipsecrequest *isr, const struct secasindex *saidx) u_int level; int error; - KASSERT(isr != NULL, ("key_checkrequest: null isr")); - KASSERT(saidx != NULL, ("key_checkrequest: null saidx")); - KASSERT(saidx->mode == IPSEC_MODE_TRANSPORT || + IPSEC_ASSERT(isr != NULL, ("null isr")); + IPSEC_ASSERT(saidx != NULL, ("null saidx")); + IPSEC_ASSERT(saidx->mode == IPSEC_MODE_TRANSPORT || saidx->mode == IPSEC_MODE_TUNNEL, - ("key_checkrequest: unexpected policy %u", saidx->mode)); + ("unexpected policy %u", saidx->mode)); /* * XXX guard against protocol callbacks from the crypto @@ -715,7 +742,7 @@ key_checkrequest(struct ipsecrequest *isr, const struct secasindex *saidx) * temporarily null out below. Need to rethink how we * handle bundled SA's in the callback thread. */ - mtx_assert(&isr->lock, MA_OWNED); + IPSECREQUEST_LOCK_ASSERT(isr); /* get current level */ level = ipsec_get_reqlevel(isr); @@ -726,7 +753,7 @@ key_checkrequest(struct ipsecrequest *isr, const struct secasindex *saidx) */ if (isr->sav != NULL) { if (isr->sav->sah == NULL) - panic("key_checkrequest: sah is null.\n"); + panic("%s: sah is null.\n", __func__); if (isr->sav == (struct secasvar *)LIST_FIRST( &isr->sav->sah->savtree[SADB_SASTATE_DEAD])) { KEY_FREESAV(&isr->sav); @@ -771,14 +798,14 @@ key_checkrequest(struct ipsecrequest *isr, const struct secasindex *saidx) error = key_acquire(saidx, isr->sp); if (error != 0) { /* XXX What should I do ? */ - ipseclog((LOG_DEBUG, "key_checkrequest: error %d returned " - "from key_acquire.\n", error)); + ipseclog((LOG_DEBUG, "%s: error %d returned from key_acquire\n", + __func__, error)); return error; } if (level != IPSEC_LEVEL_REQUIRE) { /* XXX sigh, the interface to this routine is botched */ - KASSERT(isr->sav == NULL, ("key_checkrequest: unexpected SA")); + IPSEC_ASSERT(isr->sav == NULL, ("unexpected SA")); return 0; } else { return ENOENT; @@ -798,16 +825,16 @@ key_allocsa_policy(const struct secasindex *saidx) struct secasvar *sav; u_int stateidx, state; - mtx_lock(&sahtree_lock); + SAHTREE_LOCK(); LIST_FOREACH(sah, &sahtree, chain) { if (sah->state == SADB_SASTATE_DEAD) continue; if (key_cmpsaidx(&sah->saidx, saidx, CMP_MODE_REQID)) { - mtx_unlock(&sahtree_lock); /* XXX??? */ + SAHTREE_UNLOCK(); goto found; } } - mtx_unlock(&sahtree_lock); + SAHTREE_UNLOCK(); return NULL; @@ -843,7 +870,7 @@ key_do_allocsa_policy(struct secashead *sah, u_int state) /* initilize */ candidate = NULL; - mtx_lock(&sahtree_lock); + SAHTREE_LOCK(); for (sav = LIST_FIRST(&sah->savtree[state]); sav != NULL; sav = nextsav) { @@ -851,7 +878,7 @@ key_do_allocsa_policy(struct secashead *sah, u_int state) nextsav = LIST_NEXT(sav, chain); /* sanity check */ - KEY_CHKSASTATE(sav->state, state, "key_do_allocsa_policy"); + KEY_CHKSASTATE(sav->state, state, __func__); /* initialize */ if (candidate == NULL) { @@ -861,10 +888,9 @@ key_do_allocsa_policy(struct secashead *sah, u_int state) /* Which SA is the better ? */ - /* sanity check 2 */ - if (candidate->lft_c == NULL || sav->lft_c == NULL) - panic("key_do_allocsa_policy: " - "lifetime_current is NULL.\n"); + IPSEC_ASSERT(candidate->lft_c != NULL, + ("null candidate lifetime")); + IPSEC_ASSERT(sav->lft_c != NULL, ("null sav lifetime")); /* What the best method is to compare ? */ if (key_prefered_oldsa) { @@ -894,8 +920,7 @@ key_do_allocsa_policy(struct secashead *sah, u_int state) key_sa_chgstate(d, SADB_SASTATE_DEAD); - KASSERT(d->refcnt > 0, - ("key_do_allocsa_policy: bogus ref count")); + IPSEC_ASSERT(d->refcnt > 0, ("bogus ref count")); m = key_setsadbmsg(SADB_DELETE, 0, d->sah->saidx.proto, 0, 0, d->refcnt - 1); if (!m) @@ -949,11 +974,10 @@ key_do_allocsa_policy(struct secashead *sah, u_int state) if (candidate) { SA_ADDREF(candidate); KEYDEBUG(KEYDEBUG_IPSEC_STAMP, - printf("DP allocsa_policy cause " - "refcnt++:%d SA:%p\n", - candidate->refcnt, candidate)); + printf("DP %s cause refcnt++:%d SA:%p\n", + __func__, candidate->refcnt, candidate)); } - mtx_unlock(&sahtree_lock); + SAHTREE_UNLOCK(); return candidate; } @@ -984,10 +1008,10 @@ key_allocsa( struct secasvar *sav; u_int stateidx, state; - KASSERT(dst != NULL, ("key_allocsa: null dst address")); + IPSEC_ASSERT(dst != NULL, ("null dst address")); KEYDEBUG(KEYDEBUG_IPSEC_STAMP, - printf("DP key_allocsa from %s:%u\n", where, tag)); + printf("DP %s from %s:%u\n", __func__, where, tag)); /* * searching SAD. @@ -995,7 +1019,7 @@ key_allocsa( * IPsec tunnel packet is received. But ESP tunnel mode is * encrypted so we can't check internal IP header. */ - mtx_lock(&sahtree_lock); + SAHTREE_LOCK(); LIST_FOREACH(sah, &sahtree, chain) { /* search valid state */ for (stateidx = 0; @@ -1004,7 +1028,7 @@ key_allocsa( state = saorder_state_valid[stateidx]; LIST_FOREACH(sav, &sah->savtree[state], chain) { /* sanity check */ - KEY_CHKSASTATE(sav->state, state, "key_allocsav"); + KEY_CHKSASTATE(sav->state, state, __func__); /* do not return entries w/ unusable state */ if (sav->state != SADB_SASTATE_MATURE && sav->state != SADB_SASTATE_DYING) @@ -1028,10 +1052,10 @@ key_allocsa( } sav = NULL; done: - mtx_unlock(&sahtree_lock); + SAHTREE_UNLOCK(); KEYDEBUG(KEYDEBUG_IPSEC_STAMP, - printf("DP key_allocsa return SA:%p; refcnt %u\n", + printf("DP %s return SA:%p; refcnt %u\n", __func__, sav, sav ? sav->refcnt : 0)); return sav; } @@ -1045,20 +1069,20 @@ _key_freesp(struct secpolicy **spp, const char* where, int tag) { struct secpolicy *sp = *spp; - KASSERT(sp != NULL, ("key_freesp: null sp")); + IPSEC_ASSERT(sp != NULL, ("null sp")); - mtx_lock(&sptree_lock); + SPTREE_LOCK(); SP_DELREF(sp); KEYDEBUG(KEYDEBUG_IPSEC_STAMP, - printf("DP key_freesp SP:%p (ID=%u) from %s:%u; refcnt now %u\n", - sp, sp->id, where, tag, sp->refcnt)); + printf("DP %s SP:%p (ID=%u) from %s:%u; refcnt now %u\n", + __func__, sp, sp->id, where, tag, sp->refcnt)); if (sp->refcnt == 0) { *spp = NULL; key_delsp(sp); } - mtx_unlock(&sptree_lock); + SPTREE_UNLOCK(); } /* @@ -1068,8 +1092,7 @@ _key_freesp(struct secpolicy **spp, const char* where, int tag) void key_freeso(struct socket *so) { - /* sanity check */ - KASSERT(so != NULL, ("key_freeso: null so")); + IPSEC_ASSERT(so != NULL, ("null so")); switch (so->so_proto->pr_domain->dom_family) { #ifdef INET @@ -1109,8 +1132,8 @@ key_freeso(struct socket *so) break; #endif /* INET6 */ default: - ipseclog((LOG_DEBUG, "key_freeso: unknown address family=%d.\n", - so->so_proto->pr_domain->dom_family)); + ipseclog((LOG_DEBUG, "%s: unknown address family=%d.\n", + __func__, so->so_proto->pr_domain->dom_family)); return; } } @@ -1118,14 +1141,14 @@ key_freeso(struct socket *so) static void key_freesp_so(struct secpolicy **sp) { - KASSERT(sp != NULL && *sp != NULL, ("key_freesp_so: null sp")); + IPSEC_ASSERT(sp != NULL && *sp != NULL, ("null sp")); if ((*sp)->policy == IPSEC_POLICY_ENTRUST || (*sp)->policy == IPSEC_POLICY_BYPASS) return; - KASSERT((*sp)->policy == IPSEC_POLICY_IPSEC, - ("key_freesp_so: invalid policy %u", (*sp)->policy)); + IPSEC_ASSERT((*sp)->policy == IPSEC_POLICY_IPSEC, + ("invalid policy %u", (*sp)->policy)); KEY_FREESP(sp); } @@ -1139,13 +1162,14 @@ key_freesav(struct secasvar **psav, const char* where, int tag) { struct secasvar *sav = *psav; - KASSERT(sav != NULL, ("key_freesav: null sav")); + IPSEC_ASSERT(sav != NULL, ("null sav")); + /* XXX unguarded? */ SA_DELREF(sav); KEYDEBUG(KEYDEBUG_IPSEC_STAMP, - printf("DP key_freesav SA:%p (SPI %u) from %s:%u; refcnt now %u\n", - sav, ntohl(sav->spi), where, tag, sav->refcnt)); + printf("DP %s SA:%p (SPI %u) from %s:%u; refcnt now %u\n", + __func__, sav, ntohl(sav->spi), where, tag, sav->refcnt)); if (sav->refcnt == 0) { *psav = NULL; @@ -1162,14 +1186,13 @@ key_delsp(struct secpolicy *sp) { struct ipsecrequest *isr, *nextisr; - KASSERT(sp != NULL, ("key_delsp: null sp")); - mtx_assert(&sptree_lock, MA_OWNED); + IPSEC_ASSERT(sp != NULL, ("null sp")); + SPTREE_LOCK_ASSERT(); sp->state = IPSEC_SPSTATE_DEAD; - KASSERT(sp->refcnt == 0, - ("key_delsp: SP with references deleted (refcnt %u)", - sp->refcnt)); + IPSEC_ASSERT(sp->refcnt == 0, + ("SP with references deleted (refcnt %u)", sp->refcnt)); /* remove from SP index */ if (__LIST_CHAINED(sp)) @@ -1197,9 +1220,9 @@ key_getsp(struct secpolicyindex *spidx) { struct secpolicy *sp; - KASSERT(spidx != NULL, ("key_getsp: null spidx")); + IPSEC_ASSERT(spidx != NULL, ("null spidx")); - mtx_lock(&sptree_lock); + SPTREE_LOCK(); LIST_FOREACH(sp, &sptree[spidx->dir], chain) { if (sp->state == IPSEC_SPSTATE_DEAD) continue; @@ -1208,7 +1231,7 @@ key_getsp(struct secpolicyindex *spidx) break; } } - mtx_unlock(&sptree_lock); + SPTREE_UNLOCK(); return sp; } @@ -1223,7 +1246,7 @@ key_getspbyid(u_int32_t id) { struct secpolicy *sp; - mtx_lock(&sptree_lock); + SPTREE_LOCK(); LIST_FOREACH(sp, &sptree[IPSEC_DIR_INBOUND], chain) { if (sp->state == IPSEC_SPSTATE_DEAD) continue; @@ -1242,7 +1265,7 @@ key_getspbyid(u_int32_t id) } } done: - mtx_unlock(&sptree_lock); + SPTREE_UNLOCK(); return sp; } @@ -1255,13 +1278,13 @@ key_newsp(const char* where, int tag) newsp = (struct secpolicy *) malloc(sizeof(struct secpolicy), M_IPSEC_SP, M_NOWAIT|M_ZERO); if (newsp) { - mtx_init(&newsp->lock, "ipsec policy", NULL, MTX_DEF); + SECPOLICY_LOCK_INIT(newsp); newsp->refcnt = 1; newsp->req = NULL; } KEYDEBUG(KEYDEBUG_IPSEC_STAMP, - printf("DP key_newsp from %s:%u return SP:%p\n", + printf("DP %s from %s:%u return SP:%p\n", __func__, where, tag, newsp)); return newsp; } @@ -1269,7 +1292,7 @@ key_newsp(const char* where, int tag) static void _key_delsp(struct secpolicy *sp) { - mtx_destroy(&sp->lock); + SECPOLICY_LOCK_DESTROY(sp); free(sp, M_IPSEC_SP); } @@ -1286,13 +1309,11 @@ key_msg2sp(xpl0, len, error) { struct secpolicy *newsp; - /* sanity check */ - if (xpl0 == NULL) - panic("key_msg2sp: NULL pointer was passed.\n"); - if (len < sizeof(*xpl0)) - panic("key_msg2sp: invalid length.\n"); + IPSEC_ASSERT(xpl0 != NULL, ("null xpl0")); + IPSEC_ASSERT(len >= sizeof(*xpl0), ("policy too short: %u", len)); + if (len != PFKEY_EXTLEN(xpl0)) { - ipseclog((LOG_DEBUG, "key_msg2sp: Invalid msg length.\n")); + ipseclog((LOG_DEBUG, "%s: Invalid msg length.\n", __func__)); *error = EINVAL; return NULL; } @@ -1322,8 +1343,8 @@ key_msg2sp(xpl0, len, error) /* validity check */ if (PFKEY_EXTLEN(xpl0) < sizeof(*xpl0)) { - ipseclog((LOG_DEBUG, - "key_msg2sp: Invalid msg length.\n")); + ipseclog((LOG_DEBUG, "%s: Invalid msg length.\n", + __func__)); KEY_FREESP(&newsp); *error = EINVAL; return NULL; @@ -1335,8 +1356,8 @@ key_msg2sp(xpl0, len, error) while (tlen > 0) { /* length check */ if (xisr->sadb_x_ipsecrequest_len < sizeof(*xisr)) { - ipseclog((LOG_DEBUG, "key_msg2sp: " - "invalid ipsecrequest length.\n")); + ipseclog((LOG_DEBUG, "%s: invalid ipsecrequest " + "length.\n", __func__)); KEY_FREESP(&newsp); *error = EINVAL; return NULL; @@ -1347,7 +1368,7 @@ key_msg2sp(xpl0, len, error) *p_isr = ipsec_newisr(); if ((*p_isr) == NULL) { ipseclog((LOG_DEBUG, - "key_msg2sp: No more memory.\n")); + "%s: No more memory.\n", __func__)); KEY_FREESP(&newsp); *error = ENOBUFS; return NULL; @@ -1361,7 +1382,7 @@ key_msg2sp(xpl0, len, error) break; default: ipseclog((LOG_DEBUG, - "key_msg2sp: invalid proto type=%u\n", + "%s: invalid proto type=%u\n", __func__, xisr->sadb_x_ipsecrequest_proto)); KEY_FREESP(&newsp); *error = EPROTONOSUPPORT; @@ -1376,7 +1397,7 @@ key_msg2sp(xpl0, len, error) case IPSEC_MODE_ANY: default: ipseclog((LOG_DEBUG, - "key_msg2sp: invalid mode=%u\n", + "%s: invalid mode=%u\n", __func__, xisr->sadb_x_ipsecrequest_mode)); KEY_FREESP(&newsp); *error = EINVAL; @@ -1398,8 +1419,9 @@ key_msg2sp(xpl0, len, error) if (xisr->sadb_x_ipsecrequest_reqid > IPSEC_MANUAL_REQID_MAX) { ipseclog((LOG_DEBUG, - "key_msg2sp: reqid=%d range " + "%s: reqid=%d range " "violation, updated by kernel.\n", + __func__, xisr->sadb_x_ipsecrequest_reqid)); xisr->sadb_x_ipsecrequest_reqid = 0; } @@ -1422,7 +1444,8 @@ key_msg2sp(xpl0, len, error) break; default: - ipseclog((LOG_DEBUG, "key_msg2sp: invalid level=%u\n", + ipseclog((LOG_DEBUG, "%s: invalid level=%u\n", + __func__, xisr->sadb_x_ipsecrequest_level)); KEY_FREESP(&newsp); *error = EINVAL; @@ -1439,8 +1462,9 @@ key_msg2sp(xpl0, len, error) /* validity check */ if (paddr->sa_len > sizeof((*p_isr)->saidx.src)) { - ipseclog((LOG_DEBUG, "key_msg2sp: invalid request " - "address length.\n")); + ipseclog((LOG_DEBUG, "%s: invalid " + "request address length.\n", + __func__)); KEY_FREESP(&newsp); *error = EINVAL; return NULL; @@ -1454,8 +1478,9 @@ key_msg2sp(xpl0, len, error) /* validity check */ if (paddr->sa_len > sizeof((*p_isr)->saidx.dst)) { - ipseclog((LOG_DEBUG, "key_msg2sp: invalid request " - "address length.\n")); + ipseclog((LOG_DEBUG, "%s: invalid " + "request address length.\n", + __func__)); KEY_FREESP(&newsp); *error = EINVAL; return NULL; @@ -1472,7 +1497,8 @@ key_msg2sp(xpl0, len, error) /* validity check */ if (tlen < 0) { - ipseclog((LOG_DEBUG, "key_msg2sp: becoming tlen < 0.\n")); + ipseclog((LOG_DEBUG, "%s: becoming tlen < 0.\n", + __func__)); KEY_FREESP(&newsp); *error = EINVAL; return NULL; @@ -1484,7 +1510,7 @@ key_msg2sp(xpl0, len, error) } break; default: - ipseclog((LOG_DEBUG, "key_msg2sp: invalid policy type.\n")); + ipseclog((LOG_DEBUG, "%s: invalid policy type.\n", __func__)); KEY_FREESP(&newsp); *error = EINVAL; return NULL; @@ -1519,9 +1545,7 @@ key_sp2msg(sp) caddr_t p; struct mbuf *m; - /* sanity check. */ - if (sp == NULL) - panic("key_sp2msg: NULL pointer was passed.\n"); + IPSEC_ASSERT(sp != NULL, ("null policy")); tlen = key_getspreqmsglen(sp); @@ -1594,8 +1618,8 @@ key_gather_mbuf(m, mhp, ndeep, nitem, va_alist) struct mbuf *result = NULL, *n; int len; - if (m == NULL || mhp == NULL) - panic("null pointer passed to key_gather"); + IPSEC_ASSERT(m != NULL, ("null mbuf")); + IPSEC_ASSERT(mhp != NULL, ("null msghdr")); va_start(ap, nitem); for (i = 0; i < nitem; i++) { @@ -1611,10 +1635,9 @@ key_gather_mbuf(m, mhp, ndeep, nitem, va_alist) if (idx == SADB_EXT_RESERVED) { len = PFKEY_ALIGN8(sizeof(struct sadb_msg)); -#ifdef DIAGNOSTIC - if (len > MHLEN) - panic("assumption failed"); -#endif + + IPSEC_ASSERT(len <= MHLEN, ("header too big %u", len)); + MGETHDR(n, M_DONTWAIT, MT_DATA); if (!n) goto fail; @@ -1688,9 +1711,10 @@ key_spdadd(so, m, mhp) struct secpolicy *newsp; int error; - /* sanity check */ - if (so == NULL || m == NULL || mhp == NULL || mhp->msg == NULL) - panic("key_spdadd: NULL pointer is passed.\n"); + IPSEC_ASSERT(so != NULL, ("null socket")); + IPSEC_ASSERT(m != NULL, ("null mbuf")); + IPSEC_ASSERT(mhp != NULL, ("null msghdr")); + IPSEC_ASSERT(mhp->msg != NULL, ("null msg")); if (mhp->ext[SADB_EXT_ADDRESS_SRC] == NULL || mhp->ext[SADB_EXT_ADDRESS_DST] == NULL || @@ -1701,13 +1725,15 @@ key_spdadd(so, m, mhp) if (mhp->extlen[SADB_EXT_ADDRESS_SRC] < sizeof(struct sadb_address) || mhp->extlen[SADB_EXT_ADDRESS_DST] < sizeof(struct sadb_address) || mhp->extlen[SADB_X_EXT_POLICY] < sizeof(struct sadb_x_policy)) { - ipseclog((LOG_DEBUG, "key_spdadd: invalid message is passed.\n")); + ipseclog((LOG_DEBUG, "%s: invalid message is passed.\n", + __func__)); return key_senderror(so, m, EINVAL); } if (mhp->ext[SADB_EXT_LIFETIME_HARD] != NULL) { if (mhp->extlen[SADB_EXT_LIFETIME_HARD] < sizeof(struct sadb_lifetime)) { - ipseclog((LOG_DEBUG, "key_spdadd: invalid message is passed.\n")); + ipseclog((LOG_DEBUG, "%s: invalid message is passed.\n", + __func__)); return key_senderror(so, m, EINVAL); } lft = (struct sadb_lifetime *)mhp->ext[SADB_EXT_LIFETIME_HARD]; @@ -1733,7 +1759,7 @@ key_spdadd(so, m, mhp) case IPSEC_DIR_OUTBOUND: break; default: - ipseclog((LOG_DEBUG, "key_spdadd: Invalid SP direction.\n")); + ipseclog((LOG_DEBUG, "%s: Invalid SP direction.\n", __func__)); mhp->msg->sadb_msg_errno = EINVAL; return 0; } @@ -1742,7 +1768,7 @@ key_spdadd(so, m, mhp) /* key_spdadd() accepts DISCARD, NONE and IPSEC. */ if (xpl0->sadb_x_policy_type == IPSEC_POLICY_ENTRUST || xpl0->sadb_x_policy_type == IPSEC_POLICY_BYPASS) { - ipseclog((LOG_DEBUG, "key_spdadd: Invalid policy type.\n")); + ipseclog((LOG_DEBUG, "%s: Invalid policy type.\n", __func__)); return key_senderror(so, m, EINVAL); } @@ -1750,7 +1776,8 @@ key_spdadd(so, m, mhp) if (mhp->msg->sadb_msg_type != SADB_X_SPDSETIDX && xpl0->sadb_x_policy_type == IPSEC_POLICY_IPSEC && mhp->extlen[SADB_X_EXT_POLICY] <= sizeof(*xpl0)) { - ipseclog((LOG_DEBUG, "key_spdadd: some policy requests part required.\n")); + ipseclog((LOG_DEBUG, "%s: some policy requests part required\n", + __func__)); return key_senderror(so, m, EINVAL); } @@ -1769,7 +1796,8 @@ key_spdadd(so, m, mhp) } else { if (newsp != NULL) { KEY_FREESP(&newsp); - ipseclog((LOG_DEBUG, "key_spdadd: a SP entry exists already.\n")); + ipseclog((LOG_DEBUG, "%s: a SP entry exists already.\n", + __func__)); return key_senderror(so, m, EEXIST); } } @@ -1839,7 +1867,7 @@ key_spdadd(so, m, mhp) /* reset counter in order to deletion by timehandler. */ spacq->created = time_second; spacq->count = 0; - mtx_unlock(&spacq_lock); + SPACQ_UNLOCK(); } } @@ -1913,7 +1941,8 @@ key_getnewspid() } if (count == 0 || newid == 0) { - ipseclog((LOG_DEBUG, "key_getnewspid: to allocate policy id is failed.\n")); + ipseclog((LOG_DEBUG, "%s: to allocate policy id is failed.\n", + __func__)); return 0; } @@ -1943,20 +1972,23 @@ key_spddelete(so, m, mhp) struct secpolicyindex spidx; struct secpolicy *sp; - /* sanity check */ - if (so == NULL || m == NULL || mhp == NULL || mhp->msg == NULL) - panic("key_spddelete: NULL pointer is passed.\n"); + IPSEC_ASSERT(so != NULL, ("null so")); + IPSEC_ASSERT(m != NULL, ("null mbuf")); + IPSEC_ASSERT(mhp != NULL, ("null msghdr")); + IPSEC_ASSERT(mhp->msg != NULL, ("null msg")); if (mhp->ext[SADB_EXT_ADDRESS_SRC] == NULL || mhp->ext[SADB_EXT_ADDRESS_DST] == NULL || mhp->ext[SADB_X_EXT_POLICY] == NULL) { - ipseclog((LOG_DEBUG, "key_spddelete: invalid message is passed.\n")); + ipseclog((LOG_DEBUG, "%s: invalid message is passed.\n", + __func__)); return key_senderror(so, m, EINVAL); } if (mhp->extlen[SADB_EXT_ADDRESS_SRC] < sizeof(struct sadb_address) || mhp->extlen[SADB_EXT_ADDRESS_DST] < sizeof(struct sadb_address) || mhp->extlen[SADB_X_EXT_POLICY] < sizeof(struct sadb_x_policy)) { - ipseclog((LOG_DEBUG, "key_spddelete: invalid message is passed.\n")); + ipseclog((LOG_DEBUG, "%s: invalid message is passed.\n", + __func__)); return key_senderror(so, m, EINVAL); } @@ -1980,13 +2012,13 @@ key_spddelete(so, m, mhp) case IPSEC_DIR_OUTBOUND: break; default: - ipseclog((LOG_DEBUG, "key_spddelete: Invalid SP direction.\n")); + ipseclog((LOG_DEBUG, "%s: Invalid SP direction.\n", __func__)); return key_senderror(so, m, EINVAL); } /* Is there SP in SPD ? */ if ((sp = key_getsp(&spidx)) == NULL) { - ipseclog((LOG_DEBUG, "key_spddelete: no SP found.\n")); + ipseclog((LOG_DEBUG, "%s: no SP found.\n", __func__)); return key_senderror(so, m, EINVAL); } @@ -1994,7 +2026,7 @@ key_spddelete(so, m, mhp) xpl0->sadb_x_policy_id = sp->id; sp->state = IPSEC_SPSTATE_DEAD; - mtx_destroy(&sp->lock); + SECPOLICY_LOCK_DESTROY(sp); KEY_FREESP(&sp); { @@ -2037,13 +2069,14 @@ key_spddelete2(so, m, mhp) u_int32_t id; struct secpolicy *sp; - /* sanity check */ - if (so == NULL || m == NULL || mhp == NULL || mhp->msg == NULL) - panic("key_spddelete2: NULL pointer is passed.\n"); + IPSEC_ASSERT(so != NULL, ("null socket")); + IPSEC_ASSERT(m != NULL, ("null mbuf")); + IPSEC_ASSERT(mhp != NULL, ("null msghdr")); + IPSEC_ASSERT(mhp->msg != NULL, ("null msg")); if (mhp->ext[SADB_X_EXT_POLICY] == NULL || mhp->extlen[SADB_X_EXT_POLICY] < sizeof(struct sadb_x_policy)) { - ipseclog((LOG_DEBUG, "key_spddelete2: invalid message is passed.\n")); + ipseclog((LOG_DEBUG, "%s: invalid message is passed.\n", __func__)); key_senderror(so, m, EINVAL); return 0; } @@ -2052,12 +2085,12 @@ key_spddelete2(so, m, mhp) /* Is there SP in SPD ? */ if ((sp = key_getspbyid(id)) == NULL) { - ipseclog((LOG_DEBUG, "key_spddelete2: no SP found id:%u.\n", id)); + ipseclog((LOG_DEBUG, "%s: no SP found id:%u.\n", __func__, id)); key_senderror(so, m, EINVAL); } sp->state = IPSEC_SPSTATE_DEAD; - mtx_destroy(&sp->lock); + SECPOLICY_LOCK_DESTROY(sp); KEY_FREESP(&sp); { @@ -2088,10 +2121,8 @@ key_spddelete2(so, m, mhp) m_copydata(m, 0, sizeof(struct sadb_msg), mtod(n, caddr_t) + off); off += PFKEY_ALIGN8(sizeof(struct sadb_msg)); -#ifdef DIAGNOSTIC - if (off != len) - panic("length inconsistency in key_spddelete2"); -#endif + IPSEC_ASSERT(off == len, ("length inconsistency (off %u len %u)", + off, len)); n->m_next = m_copym(m, mhp->extoff[SADB_X_EXT_POLICY], mhp->extlen[SADB_X_EXT_POLICY], M_DONTWAIT); @@ -2135,13 +2166,15 @@ key_spdget(so, m, mhp) struct secpolicy *sp; struct mbuf *n; - /* sanity check */ - if (so == NULL || m == NULL || mhp == NULL || mhp->msg == NULL) - panic("key_spdget: NULL pointer is passed.\n"); + IPSEC_ASSERT(so != NULL, ("null socket")); + IPSEC_ASSERT(m != NULL, ("null mbuf")); + IPSEC_ASSERT(mhp != NULL, ("null msghdr")); + IPSEC_ASSERT(mhp->msg != NULL, ("null msg")); if (mhp->ext[SADB_X_EXT_POLICY] == NULL || mhp->extlen[SADB_X_EXT_POLICY] < sizeof(struct sadb_x_policy)) { - ipseclog((LOG_DEBUG, "key_spdget: invalid message is passed.\n")); + ipseclog((LOG_DEBUG, "%s: invalid message is passed.\n", + __func__)); return key_senderror(so, m, EINVAL); } @@ -2149,7 +2182,7 @@ key_spdget(so, m, mhp) /* Is there SP in SPD ? */ if ((sp = key_getspbyid(id)) == NULL) { - ipseclog((LOG_DEBUG, "key_spdget: no SP found id:%u.\n", id)); + ipseclog((LOG_DEBUG, "%s: no SP found id:%u.\n", __func__, id)); return key_senderror(so, m, ENOENT); } @@ -2184,13 +2217,10 @@ key_spdacquire(sp) struct secspacq *newspacq; int error; - /* sanity check */ - if (sp == NULL) - panic("key_spdacquire: NULL pointer is passed.\n"); - if (sp->req != NULL) - panic("key_spdacquire: called but there is request.\n"); - if (sp->policy != IPSEC_POLICY_IPSEC) - panic("key_spdacquire: policy mismathed. IPsec is expected.\n"); + IPSEC_ASSERT(sp != NULL, ("null secpolicy")); + IPSEC_ASSERT(sp->req == NULL, ("policy exists")); + IPSEC_ASSERT(sp->policy == IPSEC_POLICY_IPSEC, + ("policy not IPSEC %u", sp->policy)); /* Get an entry to check whether sent message or not. */ newspacq = key_getspacq(&sp->spidx); @@ -2203,7 +2233,7 @@ key_spdacquire(sp) newspacq->count++; return 0; } - mtx_unlock(&spacq_lock); + SPACQ_UNLOCK(); } else { /* make new entry for blocking to send SADB_ACQUIRE. */ newspacq = key_newspacq(&sp->spidx); @@ -2256,21 +2286,23 @@ key_spdflush(so, m, mhp) struct secpolicy *sp; u_int dir; - /* sanity check */ - if (so == NULL || m == NULL || mhp == NULL || mhp->msg == NULL) - panic("key_spdflush: NULL pointer is passed.\n"); + IPSEC_ASSERT(so != NULL, ("null socket")); + IPSEC_ASSERT(m != NULL, ("null mbuf")); + IPSEC_ASSERT(mhp != NULL, ("null msghdr")); + IPSEC_ASSERT(mhp->msg != NULL, ("null msg")); if (m->m_len != PFKEY_ALIGN8(sizeof(struct sadb_msg))) return key_senderror(so, m, EINVAL); for (dir = 0; dir < IPSEC_DIR_MAX; dir++) { - LIST_FOREACH(sp, &sptree[dir], chain) { + SPTREE_LOCK(); + LIST_FOREACH(sp, &sptree[dir], chain) sp->state = IPSEC_SPSTATE_DEAD; - } + SPTREE_UNLOCK(); } if (sizeof(struct sadb_msg) > m->m_len + M_TRAILINGSPACE(m)) { - ipseclog((LOG_DEBUG, "key_spdflush: No more memory.\n")); + ipseclog((LOG_DEBUG, "%s: No more memory.\n", __func__)); return key_senderror(so, m, ENOBUFS); } @@ -2307,9 +2339,10 @@ key_spddump(so, m, mhp) u_int dir; struct mbuf *n; - /* sanity check */ - if (so == NULL || m == NULL || mhp == NULL || mhp->msg == NULL) - panic("key_spddump: NULL pointer is passed.\n"); + IPSEC_ASSERT(so != NULL, ("null socket")); + IPSEC_ASSERT(m != NULL, ("null mbuf")); + IPSEC_ASSERT(mhp != NULL, ("null msghdr")); + IPSEC_ASSERT(mhp->msg != NULL, ("null msg")); /* search SPD entry and get buffer size. */ cnt = 0; @@ -2444,9 +2477,7 @@ key_spdexpire(sp) /* XXX: Why do we lock ? */ - /* sanity check */ - if (sp == NULL) - panic("key_spdexpire: NULL pointer is passed.\n"); + IPSEC_ASSERT(sp != NULL, ("null secpolicy")); /* set msg header */ m = key_setsadbmsg(SADB_X_SPDEXPIRE, 0, 0, 0, 0, 0); @@ -2550,7 +2581,7 @@ key_newsah(saidx) { struct secashead *newsah; - KASSERT(saidx != NULL, ("key_newsaidx: null saidx")); + IPSEC_ASSERT(saidx != NULL, ("null saidx")); newsah = malloc(sizeof(struct secashead), M_IPSEC_SAH, M_NOWAIT|M_ZERO); if (newsah != NULL) { @@ -2562,9 +2593,9 @@ key_newsah(saidx) /* add to saidxtree */ newsah->state = SADB_SASTATE_MATURE; - mtx_lock(&sahtree_lock); + SAHTREE_LOCK(); LIST_INSERT_HEAD(&sahtree, newsah, chain); - mtx_unlock(&sahtree_lock); + SAHTREE_UNLOCK(); } return(newsah); } @@ -2577,28 +2608,21 @@ key_delsah(sah) struct secashead *sah; { struct secasvar *sav, *nextsav; - u_int stateidx, state; + u_int stateidx; int zombie = 0; - /* sanity check */ - KASSERT(sah != NULL, ("key_delsah: NULL sah")); - mtx_assert(&sahtree_lock, MA_OWNED); + IPSEC_ASSERT(sah != NULL, ("NULL sah")); + SAHTREE_LOCK_ASSERT(); /* searching all SA registerd in the secindex. */ for (stateidx = 0; stateidx < _ARRAYLEN(saorder_state_any); stateidx++) { - - state = saorder_state_any[stateidx]; - for (sav = (struct secasvar *)LIST_FIRST(&sah->savtree[state]); - sav != NULL; - sav = nextsav) { - - nextsav = LIST_NEXT(sav, chain); - + u_int state = saorder_state_any[stateidx]; + LIST_FOREACH_SAFE(sav, &sah->savtree[state], chain, nextsav) { if (sav->refcnt == 0) { /* sanity check */ - KEY_CHKSASTATE(state, sav->state, "key_delsah"); + KEY_CHKSASTATE(state, sav->state, __func__); KEY_FREESAV(&sav); } else { /* give up to delete this sa */ @@ -2606,20 +2630,16 @@ key_delsah(sah) } } } - /* remove from tree of SA index */ - if (!zombie && __LIST_CHAINED(sah)) - LIST_REMOVE(sah, chain); - - /* don't delete sah only if there are savs. */ - if (zombie) - return; - - if (sah->sa_route.ro_rt) { - RTFREE(sah->sa_route.ro_rt); - sah->sa_route.ro_rt = (struct rtentry *)NULL; + if (!zombie) { /* delete only if there are savs */ + /* remove from tree of SA index */ + if (__LIST_CHAINED(sah)) + LIST_REMOVE(sah, chain); + if (sah->sa_route.ro_rt) { + RTFREE(sah->sa_route.ro_rt); + sah->sa_route.ro_rt = (struct rtentry *)NULL; + } + free(sah, M_IPSEC_SAH); } - - free(sah, M_IPSEC_SAH); } /* @@ -2646,13 +2666,14 @@ key_newsav(m, mhp, sah, errp, where, tag) struct secasvar *newsav; const struct sadb_sa *xsa; - /* sanity check */ - if (m == NULL || mhp == NULL || mhp->msg == NULL || sah == NULL) - panic("key_newsa: NULL pointer is passed.\n"); + IPSEC_ASSERT(m != NULL, ("null mbuf")); + IPSEC_ASSERT(mhp != NULL, ("null msghdr")); + IPSEC_ASSERT(mhp->msg != NULL, ("null msg")); + IPSEC_ASSERT(sah != NULL, ("null secashead")); newsav = malloc(sizeof(struct secasvar), M_IPSEC_SA, M_NOWAIT|M_ZERO); if (newsav == NULL) { - ipseclog((LOG_DEBUG, "key_newsa: No more memory.\n")); + ipseclog((LOG_DEBUG, "%s: No more memory.\n", __func__)); *errp = ENOBUFS; goto done; } @@ -2676,7 +2697,8 @@ key_newsav(m, mhp, sah, errp, where, tag) if (mhp->ext[SADB_EXT_SA] == NULL) { free(newsav, M_IPSEC_SA); newsav = NULL; - ipseclog((LOG_DEBUG, "key_newsa: invalid message is passed.\n")); + ipseclog((LOG_DEBUG, "%s: invalid message is passed.\n", + __func__)); *errp = EINVAL; goto done; } @@ -2702,7 +2724,7 @@ key_newsav(m, mhp, sah, errp, where, tag) } } - mtx_init(&newsav->lock, "ipsec sa", NULL, MTX_DEF); + SECASVAR_LOCK_INIT(newsav); /* reset created */ newsav->created = time_second; @@ -2718,7 +2740,7 @@ key_newsav(m, mhp, sah, errp, where, tag) secasvar, chain); done: KEYDEBUG(KEYDEBUG_IPSEC_STAMP, - printf("DP key_newsav from %s:%u return SP:%p\n", + printf("DP %s from %s:%u return SP:%p\n", __func__, where, tag, newsav)); return newsav; @@ -2738,6 +2760,7 @@ key_cleansav(struct secasvar *sav) sav->tdb_xform->xf_zeroize(sav); sav->tdb_xform = NULL; } else { + KASSERT(sav->iv == NULL, ("iv but no xform")); if (sav->key_auth != NULL) bzero(_KEYBUF(sav->key_auth), _KEYLEN(sav->key_auth)); if (sav->key_enc != NULL) @@ -2772,10 +2795,6 @@ key_cleansav(struct secasvar *sav) free(sav->lft_s, M_IPSEC_MISC); sav->lft_s = NULL; } - if (sav->iv != NULL) { - free(sav->iv, M_IPSEC_MISC); - sav->iv = NULL; - } } /* @@ -2785,15 +2804,14 @@ static void key_delsav(sav) struct secasvar *sav; { - KASSERT(sav != NULL, ("key_delsav: null sav")); - KASSERT(sav->refcnt == 0, - ("key_delsav: reference count %u > 0", sav->refcnt)); + IPSEC_ASSERT(sav != NULL, ("null sav")); + IPSEC_ASSERT(sav->refcnt == 0, ("reference count %u > 0", sav->refcnt)); /* remove from SA header */ if (__LIST_CHAINED(sav)) LIST_REMOVE(sav, chain); key_cleansav(sav); - mtx_destroy(&sav->lock); + SECASVAR_LOCK_DESTROY(sav); free(sav, M_IPSEC_SA); } @@ -2809,14 +2827,14 @@ key_getsah(saidx) { struct secashead *sah; - mtx_lock(&sahtree_lock); + SAHTREE_LOCK(); LIST_FOREACH(sah, &sahtree, chain) { if (sah->state == SADB_SASTATE_DEAD) continue; if (key_cmpsaidx(&sah->saidx, saidx, CMP_REQID)) break; } - mtx_unlock(&sahtree_lock); + SAHTREE_UNLOCK(); return sah; } @@ -2838,13 +2856,14 @@ key_checkspidup(saidx, spi) /* check address family */ if (saidx->src.sa.sa_family != saidx->dst.sa.sa_family) { - ipseclog((LOG_DEBUG, "key_checkspidup: address family mismatched.\n")); + ipseclog((LOG_DEBUG, "%s: address family mismatched.\n", + __func__)); return NULL; } sav = NULL; /* check all SAD */ - mtx_lock(&sahtree_lock); + SAHTREE_LOCK(); LIST_FOREACH(sah, &sahtree, chain) { if (!key_ismyaddr((struct sockaddr *)&sah->saidx.dst)) continue; @@ -2852,7 +2871,7 @@ key_checkspidup(saidx, spi) if (sav != NULL) break; } - mtx_unlock(&sahtree_lock); + SAHTREE_UNLOCK(); return sav; } @@ -2872,7 +2891,7 @@ key_getsavbyspi(sah, spi) u_int stateidx, state; sav = NULL; - mtx_lock(&sahtree_lock); + SAHTREE_LOCK_ASSERT(); /* search all status */ for (stateidx = 0; stateidx < _ARRAYLEN(saorder_state_alive); @@ -2883,9 +2902,9 @@ key_getsavbyspi(sah, spi) /* sanity check */ if (sav->state != state) { - ipseclog((LOG_DEBUG, "key_getsavbyspi: " + ipseclog((LOG_DEBUG, "%s: " "invalid sav->state (queue: %d SA: %d)\n", - state, sav->state)); + __func__, state, sav->state)); continue; } @@ -2893,7 +2912,6 @@ key_getsavbyspi(sah, spi) break; } } - mtx_unlock(&sahtree_lock); return sav; } @@ -2914,9 +2932,9 @@ key_setsaval(sav, m, mhp) { int error = 0; - /* sanity check */ - if (m == NULL || mhp == NULL || mhp->msg == NULL) - panic("key_setsaval: NULL pointer is passed.\n"); + IPSEC_ASSERT(m != NULL, ("null mbuf")); + IPSEC_ASSERT(mhp != NULL, ("null msghdr")); + IPSEC_ASSERT(mhp->msg != NULL, ("null msg")); /* initialization */ sav->replay = NULL; @@ -2952,7 +2970,8 @@ key_setsaval(sav, m, mhp) sav->replay = (struct secreplay *) malloc(sizeof(struct secreplay)+sa0->sadb_sa_replay, M_IPSEC_MISC, M_NOWAIT|M_ZERO); if (sav->replay == NULL) { - ipseclog((LOG_DEBUG, "key_setsaval: No more memory.\n")); + ipseclog((LOG_DEBUG, "%s: No more memory.\n", + __func__)); error = ENOBUFS; goto fail; } @@ -2988,13 +3007,14 @@ key_setsaval(sav, m, mhp) break; } if (error) { - ipseclog((LOG_DEBUG, "key_setsaval: invalid key_auth values.\n")); + ipseclog((LOG_DEBUG, "%s: invalid key_auth values.\n", + __func__)); goto fail; } sav->key_auth = key_dup(key0, len, M_IPSEC_MISC); if (sav->key_auth == NULL) { - ipseclog((LOG_DEBUG, "key_setsaval: No more memory.\n")); + ipseclog((LOG_DEBUG, "%s: No more memory.\n",__func__)); error = ENOBUFS; goto fail; } @@ -3022,7 +3042,8 @@ key_setsaval(sav, m, mhp) } sav->key_enc = key_dup(key0, len, M_IPSEC_MISC); if (sav->key_enc == NULL) { - ipseclog((LOG_DEBUG, "key_setsaval: No more memory.\n")); + ipseclog((LOG_DEBUG, "%s: No more memory.\n", + __func__)); error = ENOBUFS; goto fail; } @@ -3038,7 +3059,8 @@ key_setsaval(sav, m, mhp) break; } if (error) { - ipseclog((LOG_DEBUG, "key_setsatval: invalid key_enc value.\n")); + ipseclog((LOG_DEBUG, "%s: invalid key_enc value.\n", + __func__)); goto fail; } } @@ -3058,9 +3080,8 @@ key_setsaval(sav, m, mhp) break; } if (error) { - ipseclog((LOG_DEBUG, - "key_setsaval: unable to initialize SA type %u.\n", - mhp->msg->sadb_msg_satype)); + ipseclog((LOG_DEBUG, "%s: unable to initialize SA type %u.\n", + __func__, mhp->msg->sadb_msg_satype)); goto fail; } @@ -3070,7 +3091,7 @@ key_setsaval(sav, m, mhp) /* make lifetime for CURRENT */ sav->lft_c = malloc(sizeof(struct sadb_lifetime), M_IPSEC_MISC, M_NOWAIT); if (sav->lft_c == NULL) { - ipseclog((LOG_DEBUG, "key_setsaval: No more memory.\n")); + ipseclog((LOG_DEBUG, "%s: No more memory.\n", __func__)); error = ENOBUFS; goto fail; } @@ -3095,7 +3116,7 @@ key_setsaval(sav, m, mhp) } sav->lft_h = key_dup(lft0, sizeof(*lft0), M_IPSEC_MISC); if (sav->lft_h == NULL) { - ipseclog((LOG_DEBUG, "key_setsaval: No more memory.\n")); + ipseclog((LOG_DEBUG, "%s: No more memory.\n",__func__)); error = ENOBUFS; goto fail; } @@ -3110,7 +3131,7 @@ key_setsaval(sav, m, mhp) } sav->lft_s = key_dup(lft0, sizeof(*lft0), M_IPSEC_MISC); if (sav->lft_s == NULL) { - ipseclog((LOG_DEBUG, "key_setsaval: No more memory.\n")); + ipseclog((LOG_DEBUG, "%s: No more memory.\n",__func__)); error = ENOBUFS; goto fail; } @@ -3142,9 +3163,8 @@ key_mature(struct secasvar *sav) case IPPROTO_ESP: case IPPROTO_AH: if (ntohl(sav->spi) >= 0 && ntohl(sav->spi) <= 255) { - ipseclog((LOG_DEBUG, - "key_mature: illegal range of SPI %u.\n", - (u_int32_t)ntohl(sav->spi))); + ipseclog((LOG_DEBUG, "%s: illegal range of SPI %u.\n", + __func__, (u_int32_t)ntohl(sav->spi))); return EINVAL; } break; @@ -3156,8 +3176,8 @@ key_mature(struct secasvar *sav) /* check flags */ if ((sav->flags & (SADB_X_EXT_OLD|SADB_X_EXT_DERIV)) == (SADB_X_EXT_OLD|SADB_X_EXT_DERIV)) { - ipseclog((LOG_DEBUG, "key_mature: " - "invalid flag (derived) given to old-esp.\n")); + ipseclog((LOG_DEBUG, "%s: invalid flag (derived) " + "given to old-esp.\n", __func__)); return EINVAL; } error = xform_init(sav, XF_ESP); @@ -3165,39 +3185,40 @@ key_mature(struct secasvar *sav) case IPPROTO_AH: /* check flags */ if (sav->flags & SADB_X_EXT_DERIV) { - ipseclog((LOG_DEBUG, "key_mature: " - "invalid flag (derived) given to AH SA.\n")); + ipseclog((LOG_DEBUG, "%s: invalid flag (derived) " + "given to AH SA.\n", __func__)); return EINVAL; } if (sav->alg_enc != SADB_EALG_NONE) { - ipseclog((LOG_DEBUG, "key_mature: " - "protocol and algorithm mismated.\n")); + ipseclog((LOG_DEBUG, "%s: protocol and algorithm " + "mismated.\n", __func__)); return(EINVAL); } error = xform_init(sav, XF_AH); break; case IPPROTO_IPCOMP: if (sav->alg_auth != SADB_AALG_NONE) { - ipseclog((LOG_DEBUG, "key_mature: " - "protocol and algorithm mismated.\n")); + ipseclog((LOG_DEBUG, "%s: protocol and algorithm " + "mismated.\n", __func__)); return(EINVAL); } if ((sav->flags & SADB_X_EXT_RAWCPI) == 0 && ntohl(sav->spi) >= 0x10000) { - ipseclog((LOG_DEBUG, "key_mature: invalid cpi for IPComp.\n")); + ipseclog((LOG_DEBUG, "%s: invalid cpi for IPComp.\n", + __func__)); return(EINVAL); } error = xform_init(sav, XF_IPCOMP); break; default: - ipseclog((LOG_DEBUG, "key_mature: Invalid satype.\n")); + ipseclog((LOG_DEBUG, "%s: Invalid satype.\n", __func__)); error = EPROTONOSUPPORT; break; } if (error == 0) { - mtx_lock(&sahtree_lock); + SAHTREE_LOCK(); key_sa_chgstate(sav, SADB_SASTATE_MATURE); - mtx_unlock(&sahtree_lock); + SAHTREE_UNLOCK(); } return (error); } @@ -3561,7 +3582,7 @@ key_dup(const void *src, u_int len, struct malloc_type *type) copy = malloc(len, type, M_NOWAIT); if (copy == NULL) { /* XXX counter */ - ipseclog((LOG_DEBUG, "key_dup: No more memory.\n")); + ipseclog((LOG_DEBUG, "%s: No more memory.\n", __func__)); } else bcopy(src, copy, len); return copy; @@ -3580,9 +3601,7 @@ key_ismyaddr(sa) struct in_ifaddr *ia; #endif - /* sanity check */ - if (sa == NULL) - panic("key_ismyaddr: NULL pointer is passed.\n"); + IPSEC_ASSERT(sa != NULL, ("null sockaddr")); switch (sa->sa_family) { #ifdef INET @@ -3942,35 +3961,37 @@ key_bbcmp(const void *a1, const void *a2, u_int bits) static void key_flush_spd(time_t now) { - struct secpolicy *sp, *nextsp; + static u_int16_t sptree_scangen = 0; + u_int16_t gen = sptree_scangen++; + struct secpolicy *sp; u_int dir; /* SPD */ for (dir = 0; dir < IPSEC_DIR_MAX; dir++) { - mtx_lock(&sptree_lock); - for (sp = LIST_FIRST(&sptree[dir]); - sp != NULL; - sp = nextsp) { - - nextsp = LIST_NEXT(sp, chain); - +restart: + SPTREE_LOCK(); + LIST_FOREACH(sp, &sptree[dir], chain) { + if (sp->scangen == gen) /* previously handled */ + continue; + sp->scangen = gen; if (sp->state == IPSEC_SPSTATE_DEAD) { + /* NB: clean entries created by key_spdflush */ + SPTREE_UNLOCK(); KEY_FREESP(&sp); - continue; + goto restart; } - if (sp->lifetime == 0 && sp->validtime == 0) continue; - - /* the deletion will occur next time */ if ((sp->lifetime && now - sp->created > sp->lifetime) || (sp->validtime && now - sp->lastused > sp->validtime)) { sp->state = IPSEC_SPSTATE_DEAD; + SPTREE_UNLOCK(); key_spdexpire(sp); - continue; + KEY_FREESP(&sp); + goto restart; } } - mtx_unlock(&sptree_lock); + SPTREE_UNLOCK(); } } @@ -3981,13 +4002,8 @@ key_flush_sad(time_t now) struct secasvar *sav, *nextsav; /* SAD */ - mtx_lock(&sahtree_lock); - for (sah = LIST_FIRST(&sahtree); - sah != NULL; - sah = nextsah) { - - nextsah = LIST_NEXT(sah, chain); - + SAHTREE_LOCK(); + LIST_FOREACH_SAFE(sah, &sahtree, chain, nextsah) { /* if sah has been dead, then delete it and process next sah. */ if (sah->state == SADB_SASTATE_DEAD) { key_delsah(sah); @@ -3995,41 +4011,30 @@ key_flush_sad(time_t now) } /* if LARVAL entry doesn't become MATURE, delete it. */ - for (sav = LIST_FIRST(&sah->savtree[SADB_SASTATE_LARVAL]); - sav != NULL; - sav = nextsav) { - - nextsav = LIST_NEXT(sav, chain); - - if (now - sav->created > key_larval_lifetime) { + LIST_FOREACH_SAFE(sav, &sah->savtree[SADB_SASTATE_LARVAL], chain, nextsav) { + if (now - sav->created > key_larval_lifetime) KEY_FREESAV(&sav); - } } /* * check MATURE entry to start to send expire message * whether or not. */ - for (sav = LIST_FIRST(&sah->savtree[SADB_SASTATE_MATURE]); - sav != NULL; - sav = nextsav) { - - nextsav = LIST_NEXT(sav, chain); - + LIST_FOREACH_SAFE(sav, &sah->savtree[SADB_SASTATE_MATURE], chain, nextsav) { /* we don't need to check. */ if (sav->lft_s == NULL) continue; /* sanity check */ if (sav->lft_c == NULL) { - ipseclog((LOG_DEBUG,"key_timehandler: " - "There is no CURRENT time, why?\n")); + ipseclog((LOG_DEBUG,"%s: there is no CURRENT " + "time, why?\n", __func__)); continue; } /* check SOFT lifetime */ - if (sav->lft_s->sadb_lifetime_addtime != 0 - && now - sav->created > sav->lft_s->sadb_lifetime_addtime) { + if (sav->lft_s->sadb_lifetime_addtime != 0 && + now - sav->created > sav->lft_s->sadb_lifetime_addtime) { /* * check SA to be used whether or not. * when SA hasn't been used, delete it. @@ -4053,8 +4058,8 @@ key_flush_sad(time_t now) * when new SA is installed. Caution when it's * installed too big lifetime by time. */ - else if (sav->lft_s->sadb_lifetime_bytes != 0 - && sav->lft_s->sadb_lifetime_bytes < sav->lft_c->sadb_lifetime_bytes) { + else if (sav->lft_s->sadb_lifetime_bytes != 0 && + sav->lft_s->sadb_lifetime_bytes < sav->lft_c->sadb_lifetime_bytes) { key_sa_chgstate(sav, SADB_SASTATE_DYING); /* @@ -4067,25 +4072,20 @@ key_flush_sad(time_t now) } /* check DYING entry to change status to DEAD. */ - for (sav = LIST_FIRST(&sah->savtree[SADB_SASTATE_DYING]); - sav != NULL; - sav = nextsav) { - - nextsav = LIST_NEXT(sav, chain); - + LIST_FOREACH_SAFE(sav, &sah->savtree[SADB_SASTATE_DYING], chain, nextsav) { /* we don't need to check. */ if (sav->lft_h == NULL) continue; /* sanity check */ if (sav->lft_c == NULL) { - ipseclog((LOG_DEBUG, "key_timehandler: " - "There is no CURRENT time, why?\n")); + ipseclog((LOG_DEBUG, "%s: there is no CURRENT " + "time, why?\n", __func__)); continue; } - if (sav->lft_h->sadb_lifetime_addtime != 0 - && now - sav->created > sav->lft_h->sadb_lifetime_addtime) { + if (sav->lft_h->sadb_lifetime_addtime != 0 && + now - sav->created > sav->lft_h->sadb_lifetime_addtime) { key_sa_chgstate(sav, SADB_SASTATE_DEAD); KEY_FREESAV(&sav); } @@ -4106,29 +4106,22 @@ key_flush_sad(time_t now) } #endif /* check HARD lifetime by bytes */ - else if (sav->lft_h->sadb_lifetime_bytes != 0 - && sav->lft_h->sadb_lifetime_bytes < sav->lft_c->sadb_lifetime_bytes) { + else if (sav->lft_h->sadb_lifetime_bytes != 0 && + sav->lft_h->sadb_lifetime_bytes < sav->lft_c->sadb_lifetime_bytes) { key_sa_chgstate(sav, SADB_SASTATE_DEAD); KEY_FREESAV(&sav); } } /* delete entry in DEAD */ - for (sav = LIST_FIRST(&sah->savtree[SADB_SASTATE_DEAD]); - sav != NULL; - sav = nextsav) { - - nextsav = LIST_NEXT(sav, chain); - + LIST_FOREACH_SAFE(sav, &sah->savtree[SADB_SASTATE_DEAD], chain, nextsav) { /* sanity check */ if (sav->state != SADB_SASTATE_DEAD) { - ipseclog((LOG_DEBUG, "key_timehandler: " - "invalid sav->state " - "(queue: %d SA: %d): " - "kill it anyway\n", + ipseclog((LOG_DEBUG, "%s: invalid sav->state " + "(queue: %d SA: %d): kill it anyway\n", + __func__, SADB_SASTATE_DEAD, sav->state)); } - /* * do not call key_freesav() here. * sav should already be freed, and sav->refcnt @@ -4137,7 +4130,7 @@ key_flush_sad(time_t now) */ } } - mtx_unlock(&sahtree_lock); + SAHTREE_UNLOCK(); } static void @@ -4146,7 +4139,7 @@ key_flush_acq(time_t now) struct secacq *acq, *nextacq; /* ACQ tree */ - mtx_lock(&acq_lock); + ACQ_LOCK(); for (acq = LIST_FIRST(&acqtree); acq != NULL; acq = nextacq) { nextacq = LIST_NEXT(acq, chain); if (now - acq->created > key_blockacq_lifetime @@ -4155,7 +4148,7 @@ key_flush_acq(time_t now) free(acq, M_IPSEC_SAQ); } } - mtx_unlock(&acq_lock); + ACQ_UNLOCK(); } static void @@ -4164,7 +4157,7 @@ key_flush_spacq(time_t now) struct secspacq *acq, *nextacq; /* SP ACQ tree */ - mtx_lock(&spacq_lock); + SPACQ_LOCK(); for (acq = LIST_FIRST(&spacqtree); acq != NULL; acq = nextacq) { nextacq = LIST_NEXT(acq, chain); if (now - acq->created > key_blockacq_lifetime @@ -4173,7 +4166,7 @@ key_flush_spacq(time_t now) free(acq, M_IPSEC_SAQ); } } - mtx_unlock(&spacq_lock); + SPACQ_UNLOCK(); } /* @@ -4309,18 +4302,21 @@ key_getspi(so, m, mhp) u_int32_t reqid; int error; - /* sanity check */ - if (so == NULL || m == NULL || mhp == NULL || mhp->msg == NULL) - panic("key_getspi: NULL pointer is passed.\n"); + IPSEC_ASSERT(so != NULL, ("null socket")); + IPSEC_ASSERT(m != NULL, ("null mbuf")); + IPSEC_ASSERT(mhp != NULL, ("null msghdr")); + IPSEC_ASSERT(mhp->msg != NULL, ("null msg")); if (mhp->ext[SADB_EXT_ADDRESS_SRC] == NULL || mhp->ext[SADB_EXT_ADDRESS_DST] == NULL) { - ipseclog((LOG_DEBUG, "key_getspi: invalid message is passed.\n")); + ipseclog((LOG_DEBUG, "%s: invalid message is passed.\n", + __func__)); return key_senderror(so, m, EINVAL); } if (mhp->extlen[SADB_EXT_ADDRESS_SRC] < sizeof(struct sadb_address) || mhp->extlen[SADB_EXT_ADDRESS_DST] < sizeof(struct sadb_address)) { - ipseclog((LOG_DEBUG, "key_getspi: invalid message is passed.\n")); + ipseclog((LOG_DEBUG, "%s: invalid message is passed.\n", + __func__)); return key_senderror(so, m, EINVAL); } if (mhp->ext[SADB_X_EXT_SA2] != NULL) { @@ -4336,7 +4332,8 @@ key_getspi(so, m, mhp) /* map satype to proto */ if ((proto = key_satype2proto(mhp->msg->sadb_msg_satype)) == 0) { - ipseclog((LOG_DEBUG, "key_getspi: invalid satype is passed.\n")); + ipseclog((LOG_DEBUG, "%s: invalid satype is passed.\n", + __func__)); return key_senderror(so, m, EINVAL); } @@ -4387,7 +4384,7 @@ key_getspi(so, m, mhp) if ((newsah = key_getsah(&saidx)) == NULL) { /* create a new SA index */ if ((newsah = key_newsah(&saidx)) == NULL) { - ipseclog((LOG_DEBUG, "key_getspi: No more memory.\n")); + ipseclog((LOG_DEBUG, "%s: No more memory.\n",__func__)); return key_senderror(so, m, ENOBUFS); } } @@ -4449,10 +4446,8 @@ key_getspi(so, m, mhp) m_sa->sadb_sa_spi = htonl(spi); off += PFKEY_ALIGN8(sizeof(struct sadb_sa)); -#ifdef DIAGNOSTIC - if (off != len) - panic("length inconsistency in key_getspi"); -#endif + IPSEC_ASSERT(off == len, + ("length inconsistency (off %u len %u)", off, len)); n->m_next = key_gather_mbuf(m, mhp, 0, 2, SADB_EXT_ADDRESS_SRC, SADB_EXT_ADDRESS_DST); @@ -4519,7 +4514,8 @@ key_do_getnewspi(spirange, saidx) if (min == max) { if (key_checkspidup(saidx, min) != NULL) { - ipseclog((LOG_DEBUG, "key_do_getnewspi: SPI %u exists already.\n", min)); + ipseclog((LOG_DEBUG, "%s: SPI %u exists already.\n", + __func__, min)); return 0; } @@ -4541,7 +4537,8 @@ key_do_getnewspi(spirange, saidx) } if (count == 0 || newspi == 0) { - ipseclog((LOG_DEBUG, "key_do_getnewspi: to allocate spi is failed.\n")); + ipseclog((LOG_DEBUG, "%s: to allocate spi is failed.\n", + __func__)); return 0; } } @@ -4582,13 +4579,15 @@ key_update(so, m, mhp) u_int32_t reqid; int error; - /* sanity check */ - if (so == NULL || m == NULL || mhp == NULL || mhp->msg == NULL) - panic("key_update: NULL pointer is passed.\n"); + IPSEC_ASSERT(so != NULL, ("null socket")); + IPSEC_ASSERT(m != NULL, ("null mbuf")); + IPSEC_ASSERT(mhp != NULL, ("null msghdr")); + IPSEC_ASSERT(mhp->msg != NULL, ("null msg")); /* map satype to proto */ if ((proto = key_satype2proto(mhp->msg->sadb_msg_satype)) == 0) { - ipseclog((LOG_DEBUG, "key_update: invalid satype is passed.\n")); + ipseclog((LOG_DEBUG, "%s: invalid satype is passed.\n", + __func__)); return key_senderror(so, m, EINVAL); } @@ -4603,13 +4602,15 @@ key_update(so, m, mhp) mhp->ext[SADB_EXT_LIFETIME_SOFT] == NULL) || (mhp->ext[SADB_EXT_LIFETIME_HARD] == NULL && mhp->ext[SADB_EXT_LIFETIME_SOFT] != NULL)) { - ipseclog((LOG_DEBUG, "key_update: invalid message is passed.\n")); + ipseclog((LOG_DEBUG, "%s: invalid message is passed.\n", + __func__)); return key_senderror(so, m, EINVAL); } if (mhp->extlen[SADB_EXT_SA] < sizeof(struct sadb_sa) || mhp->extlen[SADB_EXT_ADDRESS_SRC] < sizeof(struct sadb_address) || mhp->extlen[SADB_EXT_ADDRESS_DST] < sizeof(struct sadb_address)) { - ipseclog((LOG_DEBUG, "key_update: invalid message is passed.\n")); + ipseclog((LOG_DEBUG, "%s: invalid message is passed.\n", + __func__)); return key_senderror(so, m, EINVAL); } if (mhp->ext[SADB_X_EXT_SA2] != NULL) { @@ -4630,7 +4631,7 @@ key_update(so, m, mhp) /* get a SA header */ if ((sah = key_getsah(&saidx)) == NULL) { - ipseclog((LOG_DEBUG, "key_update: no SA index found.\n")); + ipseclog((LOG_DEBUG, "%s: no SA index found.\n", __func__)); return key_senderror(so, m, ENOENT); } @@ -4644,40 +4645,40 @@ key_update(so, m, mhp) #ifdef IPSEC_DOSEQCHECK if (mhp->msg->sadb_msg_seq != 0 && (sav = key_getsavbyseq(sah, mhp->msg->sadb_msg_seq)) == NULL) { - ipseclog((LOG_DEBUG, - "key_update: no larval SA with sequence %u exists.\n", - mhp->msg->sadb_msg_seq)); + ipseclog((LOG_DEBUG, "%s: no larval SA with sequence %u " + "exists.\n", __func__, mhp->msg->sadb_msg_seq)); return key_senderror(so, m, ENOENT); } #else - if ((sav = key_getsavbyspi(sah, sa0->sadb_sa_spi)) == NULL) { - ipseclog((LOG_DEBUG, - "key_update: no such a SA found (spi:%u)\n", - (u_int32_t)ntohl(sa0->sadb_sa_spi))); + SAHTREE_LOCK(); + sav = key_getsavbyspi(sah, sa0->sadb_sa_spi); + SAHTREE_UNLOCK(); + if (sav == NULL) { + ipseclog((LOG_DEBUG, "%s: no such a SA found (spi:%u)\n", + __func__, (u_int32_t)ntohl(sa0->sadb_sa_spi))); return key_senderror(so, m, EINVAL); } #endif /* validity check */ if (sav->sah->saidx.proto != proto) { - ipseclog((LOG_DEBUG, - "key_update: protocol mismatched (DB=%u param=%u)\n", - sav->sah->saidx.proto, proto)); + ipseclog((LOG_DEBUG, "%s: protocol mismatched " + "(DB=%u param=%u)\n", __func__, + sav->sah->saidx.proto, proto)); return key_senderror(so, m, EINVAL); } #ifdef IPSEC_DOSEQCHECK if (sav->spi != sa0->sadb_sa_spi) { - ipseclog((LOG_DEBUG, - "key_update: SPI mismatched (DB:%u param:%u)\n", + ipseclog((LOG_DEBUG, "%s: SPI mismatched (DB:%u param:%u)\n", + __func__, (u_int32_t)ntohl(sav->spi), (u_int32_t)ntohl(sa0->sadb_sa_spi))); return key_senderror(so, m, EINVAL); } #endif if (sav->pid != mhp->msg->sadb_msg_pid) { - ipseclog((LOG_DEBUG, - "key_update: pid mismatched (DB:%u param:%u)\n", - sav->pid, mhp->msg->sadb_msg_pid)); + ipseclog((LOG_DEBUG, "%s: pid mismatched (DB:%u param:%u)\n", + __func__, sav->pid, mhp->msg->sadb_msg_pid)); return key_senderror(so, m, EINVAL); } @@ -4700,7 +4701,7 @@ key_update(so, m, mhp) /* set msg buf from mhp */ n = key_getmsgbuf_x1(m, mhp); if (n == NULL) { - ipseclog((LOG_DEBUG, "key_update: No more memory.\n")); + ipseclog((LOG_DEBUG, "%s: No more memory.\n", __func__)); return key_senderror(so, m, ENOBUFS); } @@ -4730,14 +4731,13 @@ key_getsavbyseq(sah, seq) /* search SAD with sequence number ? */ LIST_FOREACH(sav, &sah->savtree[state], chain) { - KEY_CHKSASTATE(state, sav->state, "key_getsabyseq"); + KEY_CHKSASTATE(state, sav->state, __func__); if (sav->seq == seq) { SA_ADDREF(sav); KEYDEBUG(KEYDEBUG_IPSEC_STAMP, - printf("DP key_getsavbyseq cause " - "refcnt++:%d SA:%p\n", - sav->refcnt, sav)); + printf("DP %s cause refcnt++:%d SA:%p\n", + __func__, sav->refcnt, sav)); return sav; } } @@ -4777,13 +4777,15 @@ key_add(so, m, mhp) u_int32_t reqid; int error; - /* sanity check */ - if (so == NULL || m == NULL || mhp == NULL || mhp->msg == NULL) - panic("key_add: NULL pointer is passed.\n"); + IPSEC_ASSERT(so != NULL, ("null socket")); + IPSEC_ASSERT(m != NULL, ("null mbuf")); + IPSEC_ASSERT(mhp != NULL, ("null msghdr")); + IPSEC_ASSERT(mhp->msg != NULL, ("null msg")); /* map satype to proto */ if ((proto = key_satype2proto(mhp->msg->sadb_msg_satype)) == 0) { - ipseclog((LOG_DEBUG, "key_add: invalid satype is passed.\n")); + ipseclog((LOG_DEBUG, "%s: invalid satype is passed.\n", + __func__)); return key_senderror(so, m, EINVAL); } @@ -4798,14 +4800,16 @@ key_add(so, m, mhp) mhp->ext[SADB_EXT_LIFETIME_SOFT] == NULL) || (mhp->ext[SADB_EXT_LIFETIME_HARD] == NULL && mhp->ext[SADB_EXT_LIFETIME_SOFT] != NULL)) { - ipseclog((LOG_DEBUG, "key_add: invalid message is passed.\n")); + ipseclog((LOG_DEBUG, "%s: invalid message is passed.\n", + __func__)); return key_senderror(so, m, EINVAL); } if (mhp->extlen[SADB_EXT_SA] < sizeof(struct sadb_sa) || mhp->extlen[SADB_EXT_ADDRESS_SRC] < sizeof(struct sadb_address) || mhp->extlen[SADB_EXT_ADDRESS_DST] < sizeof(struct sadb_address)) { /* XXX need more */ - ipseclog((LOG_DEBUG, "key_add: invalid message is passed.\n")); + ipseclog((LOG_DEBUG, "%s: invalid message is passed.\n", + __func__)); return key_senderror(so, m, EINVAL); } if (mhp->ext[SADB_X_EXT_SA2] != NULL) { @@ -4827,7 +4831,7 @@ key_add(so, m, mhp) if ((newsah = key_getsah(&saidx)) == NULL) { /* create a new SA header */ if ((newsah = key_newsah(&saidx)) == NULL) { - ipseclog((LOG_DEBUG, "key_add: No more memory.\n")); + ipseclog((LOG_DEBUG, "%s: No more memory.\n",__func__)); return key_senderror(so, m, ENOBUFS); } } @@ -4841,8 +4845,11 @@ key_add(so, m, mhp) /* create new SA entry. */ /* We can create new SA only if SPI is differenct. */ - if (key_getsavbyspi(newsah, sa0->sadb_sa_spi)) { - ipseclog((LOG_DEBUG, "key_add: SA already exists.\n")); + SAHTREE_LOCK(); + newsav = key_getsavbyspi(newsah, sa0->sadb_sa_spi); + SAHTREE_UNLOCK(); + if (newsav != NULL) { + ipseclog((LOG_DEBUG, "%s: SA already exists.\n", __func__)); return key_senderror(so, m, EEXIST); } newsav = KEY_NEWSAV(m, mhp, newsah, &error); @@ -4867,7 +4874,7 @@ key_add(so, m, mhp) /* set msg buf from mhp */ n = key_getmsgbuf_x1(m, mhp); if (n == NULL) { - ipseclog((LOG_DEBUG, "key_update: No more memory.\n")); + ipseclog((LOG_DEBUG, "%s: No more memory.\n", __func__)); return key_senderror(so, m, ENOBUFS); } @@ -4886,9 +4893,10 @@ key_setident(sah, m, mhp) const struct sadb_ident *idsrc, *iddst; int idsrclen, iddstlen; - /* sanity check */ - if (sah == NULL || m == NULL || mhp == NULL || mhp->msg == NULL) - panic("key_setident: NULL pointer is passed.\n"); + IPSEC_ASSERT(sah != NULL, ("null secashead")); + IPSEC_ASSERT(m != NULL, ("null mbuf")); + IPSEC_ASSERT(mhp != NULL, ("null msghdr")); + IPSEC_ASSERT(mhp->msg != NULL, ("null msg")); /* don't make buffer if not there */ if (mhp->ext[SADB_EXT_IDENTITY_SRC] == NULL && @@ -4900,7 +4908,7 @@ key_setident(sah, m, mhp) if (mhp->ext[SADB_EXT_IDENTITY_SRC] == NULL || mhp->ext[SADB_EXT_IDENTITY_DST] == NULL) { - ipseclog((LOG_DEBUG, "key_setident: invalid identity.\n")); + ipseclog((LOG_DEBUG, "%s: invalid identity.\n", __func__)); return EINVAL; } @@ -4911,7 +4919,7 @@ key_setident(sah, m, mhp) /* validity check */ if (idsrc->sadb_ident_type != iddst->sadb_ident_type) { - ipseclog((LOG_DEBUG, "key_setident: ident type mismatch.\n")); + ipseclog((LOG_DEBUG, "%s: ident type mismatch.\n", __func__)); return EINVAL; } @@ -4929,14 +4937,14 @@ key_setident(sah, m, mhp) /* make structure */ sah->idents = malloc(idsrclen, M_IPSEC_MISC, M_NOWAIT); if (sah->idents == NULL) { - ipseclog((LOG_DEBUG, "key_setident: No more memory.\n")); + ipseclog((LOG_DEBUG, "%s: No more memory.\n", __func__)); return ENOBUFS; } sah->identd = malloc(iddstlen, M_IPSEC_MISC, M_NOWAIT); if (sah->identd == NULL) { free(sah->idents, M_IPSEC_MISC); sah->idents = NULL; - ipseclog((LOG_DEBUG, "key_setident: No more memory.\n")); + ipseclog((LOG_DEBUG, "%s: No more memory.\n", __func__)); return ENOBUFS; } bcopy(idsrc, sah->idents, idsrclen); @@ -4956,9 +4964,9 @@ key_getmsgbuf_x1(m, mhp) { struct mbuf *n; - /* sanity check */ - if (m == NULL || mhp == NULL || mhp->msg == NULL) - panic("key_getmsgbuf_x1: NULL pointer is passed.\n"); + IPSEC_ASSERT(m != NULL, ("null mbuf")); + IPSEC_ASSERT(mhp != NULL, ("null msghdr")); + IPSEC_ASSERT(mhp->msg != NULL, ("null msg")); /* create new sadb_msg to reply. */ n = key_gather_mbuf(m, mhp, 1, 9, SADB_EXT_RESERVED, @@ -5008,25 +5016,29 @@ key_delete(so, m, mhp) struct secasvar *sav = NULL; u_int16_t proto; - /* sanity check */ - if (so == NULL || m == NULL || mhp == NULL || mhp->msg == NULL) - panic("key_delete: NULL pointer is passed.\n"); + IPSEC_ASSERT(so != NULL, ("null socket")); + IPSEC_ASSERT(m != NULL, ("null mbuf")); + IPSEC_ASSERT(mhp != NULL, ("null msghdr")); + IPSEC_ASSERT(mhp->msg != NULL, ("null msg")); /* map satype to proto */ if ((proto = key_satype2proto(mhp->msg->sadb_msg_satype)) == 0) { - ipseclog((LOG_DEBUG, "key_delete: invalid satype is passed.\n")); + ipseclog((LOG_DEBUG, "%s: invalid satype is passed.\n", + __func__)); return key_senderror(so, m, EINVAL); } if (mhp->ext[SADB_EXT_ADDRESS_SRC] == NULL || mhp->ext[SADB_EXT_ADDRESS_DST] == NULL) { - ipseclog((LOG_DEBUG, "key_delete: invalid message is passed.\n")); + ipseclog((LOG_DEBUG, "%s: invalid message is passed.\n", + __func__)); return key_senderror(so, m, EINVAL); } if (mhp->extlen[SADB_EXT_ADDRESS_SRC] < sizeof(struct sadb_address) || mhp->extlen[SADB_EXT_ADDRESS_DST] < sizeof(struct sadb_address)) { - ipseclog((LOG_DEBUG, "key_delete: invalid message is passed.\n")); + ipseclog((LOG_DEBUG, "%s: invalid message is passed.\n", + __func__)); return key_senderror(so, m, EINVAL); } @@ -5036,10 +5048,11 @@ key_delete(so, m, mhp) * that match the src/dst. This is used during * IKE INITIAL-CONTACT. */ - ipseclog((LOG_DEBUG, "key_delete: doing delete all.\n")); + ipseclog((LOG_DEBUG, "%s: doing delete all.\n", __func__)); return key_delete_all(so, m, mhp, proto); } else if (mhp->extlen[SADB_EXT_SA] < sizeof(struct sadb_sa)) { - ipseclog((LOG_DEBUG, "key_delete: invalid message is passed.\n")); + ipseclog((LOG_DEBUG, "%s: invalid message is passed.\n", + __func__)); return key_senderror(so, m, EINVAL); } @@ -5051,7 +5064,7 @@ key_delete(so, m, mhp) KEY_SETSECASIDX(proto, IPSEC_MODE_ANY, 0, src0 + 1, dst0 + 1, &saidx); /* get a SA header */ - mtx_lock(&sahtree_lock); + SAHTREE_LOCK(); LIST_FOREACH(sah, &sahtree, chain) { if (sah->state == SADB_SASTATE_DEAD) continue; @@ -5064,13 +5077,13 @@ key_delete(so, m, mhp) break; } if (sah == NULL) { - mtx_unlock(&sahtree_lock); - ipseclog((LOG_DEBUG, "key_delete: no SA found.\n")); + SAHTREE_UNLOCK(); + ipseclog((LOG_DEBUG, "%s: no SA found.\n", __func__)); return key_senderror(so, m, ENOENT); } key_sa_chgstate(sav, SADB_SASTATE_DEAD); - mtx_unlock(&sahtree_lock); + SAHTREE_UNLOCK(); KEY_FREESAV(&sav); { @@ -5119,7 +5132,7 @@ key_delete_all(so, m, mhp, proto) /* XXX boundary check against sa_len */ KEY_SETSECASIDX(proto, IPSEC_MODE_ANY, 0, src0 + 1, dst0 + 1, &saidx); - mtx_lock(&sahtree_lock); + SAHTREE_LOCK(); LIST_FOREACH(sah, &sahtree, chain) { if (sah->state == SADB_SASTATE_DEAD) continue; @@ -5138,10 +5151,9 @@ key_delete_all(so, m, mhp, proto) nextsav = LIST_NEXT(sav, chain); /* sanity check */ if (sav->state != state) { - ipseclog((LOG_DEBUG, "key_delete_all: " - "invalid sav->state " - "(queue: %d SA: %d)\n", - state, sav->state)); + ipseclog((LOG_DEBUG, "%s: invalid " + "sav->state (queue %d SA %d)\n", + __func__, state, sav->state)); continue; } @@ -5150,7 +5162,7 @@ key_delete_all(so, m, mhp, proto) } } } - mtx_unlock(&sahtree_lock); + SAHTREE_UNLOCK(); { struct mbuf *n; struct sadb_msg *newmsg; @@ -5200,26 +5212,30 @@ key_get(so, m, mhp) struct secasvar *sav = NULL; u_int16_t proto; - /* sanity check */ - if (so == NULL || m == NULL || mhp == NULL || mhp->msg == NULL) - panic("key_get: NULL pointer is passed.\n"); + IPSEC_ASSERT(so != NULL, ("null socket")); + IPSEC_ASSERT(m != NULL, ("null mbuf")); + IPSEC_ASSERT(mhp != NULL, ("null msghdr")); + IPSEC_ASSERT(mhp->msg != NULL, ("null msg")); /* map satype to proto */ if ((proto = key_satype2proto(mhp->msg->sadb_msg_satype)) == 0) { - ipseclog((LOG_DEBUG, "key_get: invalid satype is passed.\n")); + ipseclog((LOG_DEBUG, "%s: invalid satype is passed.\n", + __func__)); return key_senderror(so, m, EINVAL); } if (mhp->ext[SADB_EXT_SA] == NULL || mhp->ext[SADB_EXT_ADDRESS_SRC] == NULL || mhp->ext[SADB_EXT_ADDRESS_DST] == NULL) { - ipseclog((LOG_DEBUG, "key_get: invalid message is passed.\n")); + ipseclog((LOG_DEBUG, "%s: invalid message is passed.\n", + __func__)); return key_senderror(so, m, EINVAL); } if (mhp->extlen[SADB_EXT_SA] < sizeof(struct sadb_sa) || mhp->extlen[SADB_EXT_ADDRESS_SRC] < sizeof(struct sadb_address) || mhp->extlen[SADB_EXT_ADDRESS_DST] < sizeof(struct sadb_address)) { - ipseclog((LOG_DEBUG, "key_get: invalid message is passed.\n")); + ipseclog((LOG_DEBUG, "%s: invalid message is passed.\n", + __func__)); return key_senderror(so, m, EINVAL); } @@ -5231,7 +5247,7 @@ key_get(so, m, mhp) KEY_SETSECASIDX(proto, IPSEC_MODE_ANY, 0, src0 + 1, dst0 + 1, &saidx); /* get a SA header */ - mtx_lock(&sahtree_lock); + SAHTREE_LOCK(); LIST_FOREACH(sah, &sahtree, chain) { if (sah->state == SADB_SASTATE_DEAD) continue; @@ -5243,9 +5259,9 @@ key_get(so, m, mhp) if (sav) break; } - mtx_unlock(&sahtree_lock); + SAHTREE_UNLOCK(); if (sah == NULL) { - ipseclog((LOG_DEBUG, "key_get: no SA found.\n")); + ipseclog((LOG_DEBUG, "%s: no SA found.\n", __func__)); return key_senderror(so, m, ENOENT); } @@ -5255,7 +5271,8 @@ key_get(so, m, mhp) /* map proto to satype */ if ((satype = key_proto2satype(sah->saidx.proto)) == 0) { - ipseclog((LOG_DEBUG, "key_get: there was invalid proto in SAD.\n")); + ipseclog((LOG_DEBUG, "%s: there was invalid proto in SAD.\n", + __func__)); return key_senderror(so, m, EINVAL); } @@ -5318,9 +5335,8 @@ key_getcomb_esp() if (ipsec_esp_auth) m = key_getcomb_ah(); else { - KASSERT(l <= MLEN, - ("key_getcomb_esp: l=%u > MLEN=%lu", - l, (u_long) MLEN)); + IPSEC_ASSERT(l <= MLEN, + ("l=%u > MLEN=%lu", l, (u_long) MLEN)); MGET(m, M_DONTWAIT, MT_DATA); if (m) { M_ALIGN(m, l); @@ -5335,8 +5351,7 @@ key_getcomb_esp() totlen = 0; for (n = m; n; n = n->m_next) totlen += n->m_len; - KASSERT((totlen % l) == 0, - ("key_getcomb_esp: totlen=%u, l=%u", totlen, l)); + IPSEC_ASSERT((totlen % l) == 0, ("totlen=%u, l=%u", totlen, l)); for (off = 0; off < totlen; off += l) { n = m_pulldown(m, off, l, &o); @@ -5384,8 +5399,8 @@ key_getsizes_ah( case SADB_X_AALG_SHA: *min = *max = 20; break; case SADB_X_AALG_NULL: *min = 1; *max = 256; break; default: - DPRINTF(("key_getsizes_ah: unknown AH algorithm %u\n", - alg)); + DPRINTF(("%s: unknown AH algorithm %u\n", + __func__, alg)); break; } } @@ -5420,9 +5435,8 @@ key_getcomb_ah() continue; if (!m) { - KASSERT(l <= MLEN, - ("key_getcomb_ah: l=%u > MLEN=%lu", - l, (u_long) MLEN)); + IPSEC_ASSERT(l <= MLEN, + ("l=%u > MLEN=%lu", l, (u_long) MLEN)); MGET(m, M_DONTWAIT, MT_DATA); if (m) { M_ALIGN(m, l); @@ -5465,9 +5479,8 @@ key_getcomb_ipcomp() continue; if (!m) { - KASSERT(l <= MLEN, - ("key_getcomb_ipcomp: l=%u > MLEN=%lu", - l, (u_long) MLEN)); + IPSEC_ASSERT(l <= MLEN, + ("l=%u > MLEN=%lu", l, (u_long) MLEN)); MGET(m, M_DONTWAIT, MT_DATA); if (m) { M_ALIGN(m, l); @@ -5565,11 +5578,9 @@ key_acquire(const struct secasindex *saidx, struct secpolicy *sp) int error = -1; u_int32_t seq; - /* sanity check */ - KASSERT(saidx != NULL, ("key_acquire: null saidx")); + IPSEC_ASSERT(saidx != NULL, ("null saidx")); satype = key_proto2satype(saidx->proto); - KASSERT(satype != 0, - ("key_acquire: null satype, protocol %u", saidx->proto)); + IPSEC_ASSERT(satype != 0, ("null satype, protocol %u", saidx->proto)); /* * We never do anything about acquirng SA. There is anather @@ -5731,7 +5742,7 @@ key_newacq(const struct secasindex *saidx) /* get new entry */ newacq = malloc(sizeof(struct secacq), M_IPSEC_SAQ, M_NOWAIT|M_ZERO); if (newacq == NULL) { - ipseclog((LOG_DEBUG, "key_newacq: No more memory.\n")); + ipseclog((LOG_DEBUG, "%s: No more memory.\n", __func__)); return NULL; } @@ -5742,9 +5753,9 @@ key_newacq(const struct secasindex *saidx) newacq->count = 0; /* add to acqtree */ - mtx_lock(&acq_lock); + ACQ_LOCK(); LIST_INSERT_HEAD(&acqtree, newacq, chain); - mtx_unlock(&acq_lock); + ACQ_UNLOCK(); return newacq; } @@ -5754,12 +5765,12 @@ key_getacq(const struct secasindex *saidx) { struct secacq *acq; - mtx_lock(&acq_lock); + ACQ_LOCK(); LIST_FOREACH(acq, &acqtree, chain) { if (key_cmpsaidx(saidx, &acq->saidx, CMP_EXACTLY)) break; } - mtx_unlock(&acq_lock); + ACQ_UNLOCK(); return acq; } @@ -5770,12 +5781,12 @@ key_getacqbyseq(seq) { struct secacq *acq; - mtx_lock(&acq_lock); + ACQ_LOCK(); LIST_FOREACH(acq, &acqtree, chain) { if (acq->seq == seq) break; } - mtx_unlock(&acq_lock); + ACQ_UNLOCK(); return acq; } @@ -5789,7 +5800,7 @@ key_newspacq(spidx) /* get new entry */ acq = malloc(sizeof(struct secspacq), M_IPSEC_SAQ, M_NOWAIT|M_ZERO); if (acq == NULL) { - ipseclog((LOG_DEBUG, "key_newspacq: No more memory.\n")); + ipseclog((LOG_DEBUG, "%s: No more memory.\n", __func__)); return NULL; } @@ -5799,9 +5810,9 @@ key_newspacq(spidx) acq->count = 0; /* add to spacqtree */ - mtx_lock(&spacq_lock); + SPACQ_LOCK(); LIST_INSERT_HEAD(&spacqtree, acq, chain); - mtx_unlock(&spacq_lock); + SPACQ_UNLOCK(); return acq; } @@ -5812,14 +5823,14 @@ key_getspacq(spidx) { struct secspacq *acq; - mtx_lock(&spacq_lock); + SPACQ_LOCK(); LIST_FOREACH(acq, &spacqtree, chain) { if (key_cmpspidx_exactly(spidx, &acq->spidx)) { /* NB: return holding spacq_lock */ return acq; } } - mtx_unlock(&spacq_lock); + SPACQ_UNLOCK(); return NULL; } @@ -5850,9 +5861,10 @@ key_acquire2(so, m, mhp) u_int16_t proto; int error; - /* sanity check */ - if (so == NULL || m == NULL || mhp == NULL || mhp->msg == NULL) - panic("key_acquire2: NULL pointer is passed.\n"); + IPSEC_ASSERT(so != NULL, ("null socket")); + IPSEC_ASSERT(m != NULL, ("null mbuf")); + IPSEC_ASSERT(mhp != NULL, ("null msghdr")); + IPSEC_ASSERT(mhp->msg != NULL, ("null msg")); /* * Error message from KMd. @@ -5865,7 +5877,8 @@ key_acquire2(so, m, mhp) /* check sequence number */ if (mhp->msg->sadb_msg_seq == 0) { - ipseclog((LOG_DEBUG, "key_acquire2: must specify sequence number.\n")); + ipseclog((LOG_DEBUG, "%s: must specify sequence " + "number.\n", __func__)); m_freem(m); return 0; } @@ -5892,7 +5905,8 @@ key_acquire2(so, m, mhp) /* map satype to proto */ if ((proto = key_satype2proto(mhp->msg->sadb_msg_satype)) == 0) { - ipseclog((LOG_DEBUG, "key_acquire2: invalid satype is passed.\n")); + ipseclog((LOG_DEBUG, "%s: invalid satype is passed.\n", + __func__)); return key_senderror(so, m, EINVAL); } @@ -5900,14 +5914,16 @@ key_acquire2(so, m, mhp) mhp->ext[SADB_EXT_ADDRESS_DST] == NULL || mhp->ext[SADB_EXT_PROPOSAL] == NULL) { /* error */ - ipseclog((LOG_DEBUG, "key_acquire2: invalid message is passed.\n")); + ipseclog((LOG_DEBUG, "%s: invalid message is passed.\n", + __func__)); return key_senderror(so, m, EINVAL); } if (mhp->extlen[SADB_EXT_ADDRESS_SRC] < sizeof(struct sadb_address) || mhp->extlen[SADB_EXT_ADDRESS_DST] < sizeof(struct sadb_address) || mhp->extlen[SADB_EXT_PROPOSAL] < sizeof(struct sadb_prop)) { /* error */ - ipseclog((LOG_DEBUG, "key_acquire2: invalid message is passed.\n")); + ipseclog((LOG_DEBUG, "%s: invalid message is passed.\n", + __func__)); return key_senderror(so, m, EINVAL); } @@ -5918,23 +5934,23 @@ key_acquire2(so, m, mhp) KEY_SETSECASIDX(proto, IPSEC_MODE_ANY, 0, src0 + 1, dst0 + 1, &saidx); /* get a SA index */ - mtx_lock(&sahtree_lock); + SAHTREE_LOCK(); LIST_FOREACH(sah, &sahtree, chain) { if (sah->state == SADB_SASTATE_DEAD) continue; if (key_cmpsaidx(&sah->saidx, &saidx, CMP_MODE_REQID)) break; } - mtx_unlock(&sahtree_lock); + SAHTREE_UNLOCK(); if (sah != NULL) { - ipseclog((LOG_DEBUG, "key_acquire2: a SA exists already.\n")); + ipseclog((LOG_DEBUG, "%s: a SA exists already.\n", __func__)); return key_senderror(so, m, EEXIST); } error = key_acquire(&saidx, NULL); if (error != 0) { - ipseclog((LOG_DEBUG, "key_acquire2: error %d returned " - "from key_acquire.\n", mhp->msg->sadb_msg_errno)); + ipseclog((LOG_DEBUG, "%s: error %d returned from key_acquire\n", + __func__, mhp->msg->sadb_msg_errno)); return key_senderror(so, m, error); } @@ -5962,9 +5978,10 @@ key_register(so, m, mhp) { struct secreg *reg, *newreg = 0; - /* sanity check */ - if (so == NULL || m == NULL || mhp == NULL || mhp->msg == NULL) - panic("key_register: NULL pointer is passed.\n"); + IPSEC_ASSERT(so != NULL, ("null socket")); + IPSEC_ASSERT(m != NULL, ("null mbuf")); + IPSEC_ASSERT(mhp != NULL, ("null msghdr")); + IPSEC_ASSERT(mhp->msg != NULL, ("null msg")); /* check for invalid register message */ if (mhp->msg->sadb_msg_satype >= sizeof(regtree)/sizeof(regtree[0])) @@ -5975,11 +5992,12 @@ key_register(so, m, mhp) goto setmsg; /* check whether existing or not */ - mtx_lock(®tree_lock); + REGTREE_LOCK(); LIST_FOREACH(reg, ®tree[mhp->msg->sadb_msg_satype], chain) { if (reg->so == so) { - mtx_unlock(®tree_lock); - ipseclog((LOG_DEBUG, "key_register: socket exists already.\n")); + REGTREE_UNLOCK(); + ipseclog((LOG_DEBUG, "%s: socket exists already.\n", + __func__)); return key_senderror(so, m, EEXIST); } } @@ -5987,8 +6005,8 @@ key_register(so, m, mhp) /* create regnode */ newreg = malloc(sizeof(struct secreg), M_IPSEC_SAR, M_NOWAIT|M_ZERO); if (newreg == NULL) { - mtx_unlock(®tree_lock); - ipseclog((LOG_DEBUG, "key_register: No more memory.\n")); + REGTREE_UNLOCK(); + ipseclog((LOG_DEBUG, "%s: No more memory.\n", __func__)); return key_senderror(so, m, ENOBUFS); } @@ -5997,7 +6015,7 @@ key_register(so, m, mhp) /* add regnode to regtree. */ LIST_INSERT_HEAD(®tree[mhp->msg->sadb_msg_satype], newreg, chain); - mtx_unlock(®tree_lock); + REGTREE_UNLOCK(); setmsg: { @@ -6097,10 +6115,8 @@ key_register(so, m, mhp) } } -#ifdef DIGAGNOSTIC - if (off != len) - panic("length assumption failed in key_register"); -#endif + IPSEC_ASSERT(off == len, + ("length assumption failed (off %u len %u)", off, len)); m_freem(m); return key_sendup_mbuf(so, n, KEY_SENDUP_REGISTERED); @@ -6117,15 +6133,14 @@ key_freereg(struct socket *so) struct secreg *reg; int i; - /* sanity check */ - KASSERT(so != NULL, ("key_freereg: NULL so")); + IPSEC_ASSERT(so != NULL, ("NULL so")); /* * check whether existing or not. * check all type of SA, because there is a potential that * one socket is registered to multiple type of SA. */ - mtx_lock(®tree_lock); + REGTREE_LOCK(); for (i = 0; i <= SADB_SATYPE_MAX; i++) { LIST_FOREACH(reg, ®tree[i], chain) { if (reg->so == so && __LIST_CHAINED(reg)) { @@ -6135,7 +6150,7 @@ key_freereg(struct socket *so) } } } - mtx_unlock(®tree_lock); + REGTREE_UNLOCK(); } /* @@ -6161,15 +6176,12 @@ key_expire(struct secasvar *sav) /* XXX: Why do we lock ? */ s = splnet(); /*called from softclock()*/ - /* sanity check */ - if (sav == NULL) - panic("key_expire: NULL pointer is passed.\n"); - if (sav->sah == NULL) - panic("key_expire: Why was SA index in SA NULL.\n"); - if ((satype = key_proto2satype(sav->sah->saidx.proto)) == 0) - panic("key_expire: invalid proto is passed.\n"); + IPSEC_ASSERT (sav != NULL, ("null sav")); + IPSEC_ASSERT (sav->sah != NULL, ("null sa header")); /* set msg header */ + satype = key_proto2satype(sav->sah->saidx.proto); + IPSEC_ASSERT(satype != 0, ("invalid proto, satype %u", satype)); m = key_setsadbmsg(SADB_EXPIRE, 0, satype, sav->seq, 0, sav->refcnt); if (!m) { error = ENOBUFS; @@ -6291,18 +6303,19 @@ key_flush(so, m, mhp) u_int8_t state; u_int stateidx; - /* sanity check */ - if (so == NULL || mhp == NULL || mhp->msg == NULL) - panic("key_flush: NULL pointer is passed.\n"); + IPSEC_ASSERT(so != NULL, ("null socket")); + IPSEC_ASSERT(mhp != NULL, ("null msghdr")); + IPSEC_ASSERT(mhp->msg != NULL, ("null msg")); /* map satype to proto */ if ((proto = key_satype2proto(mhp->msg->sadb_msg_satype)) == 0) { - ipseclog((LOG_DEBUG, "key_flush: invalid satype is passed.\n")); + ipseclog((LOG_DEBUG, "%s: invalid satype is passed.\n", + __func__)); return key_senderror(so, m, EINVAL); } /* no SATYPE specified, i.e. flushing all SA. */ - mtx_lock(&sahtree_lock); + SAHTREE_LOCK(); for (sah = LIST_FIRST(&sahtree); sah != NULL; sah = nextsah) { @@ -6329,11 +6342,11 @@ key_flush(so, m, mhp) sah->state = SADB_SASTATE_DEAD; } - mtx_unlock(&sahtree_lock); + SAHTREE_UNLOCK(); if (m->m_len < sizeof(struct sadb_msg) || sizeof(struct sadb_msg) > m->m_len + M_TRAILINGSPACE(m)) { - ipseclog((LOG_DEBUG, "key_flush: No more memory.\n")); + ipseclog((LOG_DEBUG, "%s: No more memory.\n", __func__)); return key_senderror(so, m, ENOBUFS); } @@ -6376,19 +6389,21 @@ key_dump(so, m, mhp) struct sadb_msg *newmsg; struct mbuf *n; - /* sanity check */ - if (so == NULL || m == NULL || mhp == NULL || mhp->msg == NULL) - panic("key_dump: NULL pointer is passed.\n"); + IPSEC_ASSERT(so != NULL, ("null socket")); + IPSEC_ASSERT(m != NULL, ("null mbuf")); + IPSEC_ASSERT(mhp != NULL, ("null msghdr")); + IPSEC_ASSERT(mhp->msg != NULL, ("null msg")); /* map satype to proto */ if ((proto = key_satype2proto(mhp->msg->sadb_msg_satype)) == 0) { - ipseclog((LOG_DEBUG, "key_dump: invalid satype is passed.\n")); + ipseclog((LOG_DEBUG, "%s: invalid satype is passed.\n", + __func__)); return key_senderror(so, m, EINVAL); } /* count sav entries to be sent to the userland. */ cnt = 0; - mtx_lock(&sahtree_lock); + SAHTREE_LOCK(); LIST_FOREACH(sah, &sahtree, chain) { if (mhp->msg->sadb_msg_satype != SADB_SATYPE_UNSPEC && proto != sah->saidx.proto) @@ -6405,7 +6420,7 @@ key_dump(so, m, mhp) } if (cnt == 0) { - mtx_unlock(&sahtree_lock); + SAHTREE_UNLOCK(); return key_senderror(so, m, ENOENT); } @@ -6418,8 +6433,9 @@ key_dump(so, m, mhp) /* map proto to satype */ if ((satype = key_proto2satype(sah->saidx.proto)) == 0) { - mtx_unlock(&sahtree_lock); - ipseclog((LOG_DEBUG, "key_dump: there was invalid proto in SAD.\n")); + SAHTREE_UNLOCK(); + ipseclog((LOG_DEBUG, "%s: there was invalid proto in " + "SAD.\n", __func__)); return key_senderror(so, m, EINVAL); } @@ -6431,14 +6447,14 @@ key_dump(so, m, mhp) n = key_setdumpsa(sav, SADB_DUMP, satype, --cnt, mhp->msg->sadb_msg_pid); if (!n) { - mtx_unlock(&sahtree_lock); + SAHTREE_UNLOCK(); return key_senderror(so, m, ENOBUFS); } key_sendup_mbuf(so, n, KEY_SENDUP_ONE); } } } - mtx_unlock(&sahtree_lock); + SAHTREE_UNLOCK(); m_freem(m); return 0; @@ -6457,9 +6473,10 @@ key_promisc(so, m, mhp) { int olen; - /* sanity check */ - if (so == NULL || m == NULL || mhp == NULL || mhp->msg == NULL) - panic("key_promisc: NULL pointer is passed.\n"); + IPSEC_ASSERT(so != NULL, ("null socket")); + IPSEC_ASSERT(m != NULL, ("null mbuf")); + IPSEC_ASSERT(mhp != NULL, ("null msghdr")); + IPSEC_ASSERT(mhp->msg != NULL, ("null msg")); olen = PFKEY_UNUNIT64(mhp->msg->sadb_msg_len); @@ -6548,13 +6565,12 @@ key_parse(m, so) int error; int target; - /* sanity check */ - if (m == NULL || so == NULL) - panic("key_parse: NULL pointer is passed.\n"); + IPSEC_ASSERT(so != NULL, ("null socket")); + IPSEC_ASSERT(m != NULL, ("null mbuf")); #if 0 /*kdebug_sadb assumes msg in linear buffer*/ KEYDEBUG(KEYDEBUG_KEY_DUMP, - ipseclog((LOG_DEBUG, "key_parse: passed sadb_msg\n")); + ipseclog((LOG_DEBUG, "%s: passed sadb_msg\n", __func__)); kdebug_sadb(msg)); #endif @@ -6569,24 +6585,23 @@ key_parse(m, so) if ((m->m_flags & M_PKTHDR) == 0 || m->m_pkthdr.len != m->m_pkthdr.len) { - ipseclog((LOG_DEBUG, "key_parse: invalid message length.\n")); + ipseclog((LOG_DEBUG, "%s: invalid message length.\n",__func__)); pfkeystat.out_invlen++; error = EINVAL; goto senderror; } if (msg->sadb_msg_version != PF_KEY_V2) { - ipseclog((LOG_DEBUG, - "key_parse: PF_KEY version %u is mismatched.\n", - msg->sadb_msg_version)); + ipseclog((LOG_DEBUG, "%s: PF_KEY version %u is mismatched.\n", + __func__, msg->sadb_msg_version)); pfkeystat.out_invver++; error = EINVAL; goto senderror; } if (msg->sadb_msg_type > SADB_MAX) { - ipseclog((LOG_DEBUG, "key_parse: invalid type %u is passed.\n", - msg->sadb_msg_type)); + ipseclog((LOG_DEBUG, "%s: invalid type %u is passed.\n", + __func__, msg->sadb_msg_type)); pfkeystat.out_invmsgtype++; error = EINVAL; goto senderror; @@ -6642,8 +6657,9 @@ key_parse(m, so) case SADB_GET: case SADB_ACQUIRE: case SADB_EXPIRE: - ipseclog((LOG_DEBUG, "key_parse: must specify satype " - "when msg type=%u.\n", msg->sadb_msg_type)); + ipseclog((LOG_DEBUG, "%s: must specify satype " + "when msg type=%u.\n", __func__, + msg->sadb_msg_type)); pfkeystat.out_invsatype++; error = EINVAL; goto senderror; @@ -6661,8 +6677,8 @@ key_parse(m, so) case SADB_X_SPDSETIDX: case SADB_X_SPDUPDATE: case SADB_X_SPDDELETE2: - ipseclog((LOG_DEBUG, "key_parse: illegal satype=%u\n", - msg->sadb_msg_type)); + ipseclog((LOG_DEBUG, "%s: illegal satype=%u\n", + __func__, msg->sadb_msg_type)); pfkeystat.out_invsatype++; error = EINVAL; goto senderror; @@ -6672,8 +6688,8 @@ key_parse(m, so) case SADB_SATYPE_OSPFV2: case SADB_SATYPE_RIPV2: case SADB_SATYPE_MIP: - ipseclog((LOG_DEBUG, "key_parse: type %u isn't supported.\n", - msg->sadb_msg_satype)); + ipseclog((LOG_DEBUG, "%s: type %u isn't supported.\n", + __func__, msg->sadb_msg_satype)); pfkeystat.out_invsatype++; error = EOPNOTSUPP; goto senderror; @@ -6682,8 +6698,8 @@ key_parse(m, so) break; /*FALLTHROUGH*/ default: - ipseclog((LOG_DEBUG, "key_parse: invalid type %u is passed.\n", - msg->sadb_msg_satype)); + ipseclog((LOG_DEBUG, "%s: invalid type %u is passed.\n", + __func__, msg->sadb_msg_satype)); pfkeystat.out_invsatype++; error = EINVAL; goto senderror; @@ -6700,7 +6716,8 @@ key_parse(m, so) /* check upper layer protocol */ if (src0->sadb_address_proto != dst0->sadb_address_proto) { - ipseclog((LOG_DEBUG, "key_parse: upper layer protocol mismatched.\n")); + ipseclog((LOG_DEBUG, "%s: upper layer protocol " + "mismatched.\n", __func__)); pfkeystat.out_invaddr++; error = EINVAL; goto senderror; @@ -6709,15 +6726,16 @@ key_parse(m, so) /* check family */ if (PFKEY_ADDR_SADDR(src0)->sa_family != PFKEY_ADDR_SADDR(dst0)->sa_family) { - ipseclog((LOG_DEBUG, "key_parse: address family mismatched.\n")); + ipseclog((LOG_DEBUG, "%s: address family mismatched.\n", + __func__)); pfkeystat.out_invaddr++; error = EINVAL; goto senderror; } if (PFKEY_ADDR_SADDR(src0)->sa_len != PFKEY_ADDR_SADDR(dst0)->sa_len) { - ipseclog((LOG_DEBUG, - "key_parse: address struct size mismatched.\n")); + ipseclog((LOG_DEBUG, "%s: address struct size " + "mismatched.\n", __func__)); pfkeystat.out_invaddr++; error = EINVAL; goto senderror; @@ -6741,8 +6759,8 @@ key_parse(m, so) } break; default: - ipseclog((LOG_DEBUG, - "key_parse: unsupported address family.\n")); + ipseclog((LOG_DEBUG, "%s: unsupported address family\n", + __func__)); pfkeystat.out_invaddr++; error = EAFNOSUPPORT; goto senderror; @@ -6763,8 +6781,8 @@ key_parse(m, so) /* check max prefix length */ if (src0->sadb_address_prefixlen > plen || dst0->sadb_address_prefixlen > plen) { - ipseclog((LOG_DEBUG, - "key_parse: illegal prefixlen.\n")); + ipseclog((LOG_DEBUG, "%s: illegal prefixlen.\n", + __func__)); pfkeystat.out_invaddr++; error = EINVAL; goto senderror; @@ -6798,8 +6816,8 @@ key_senderror(so, m, code) { struct sadb_msg *msg; - if (m->m_len < sizeof(struct sadb_msg)) - panic("invalid mbuf passed to key_senderror"); + IPSEC_ASSERT(m->m_len >= sizeof(struct sadb_msg), + ("mbuf too small, len %u", m->m_len)); msg = mtod(m, struct sadb_msg *); msg->sadb_msg_errno = code; @@ -6822,11 +6840,10 @@ key_align(m, mhp) int extlen; int toff; - /* sanity check */ - if (m == NULL || mhp == NULL) - panic("key_align: NULL pointer is passed.\n"); - if (m->m_len < sizeof(struct sadb_msg)) - panic("invalid mbuf passed to key_align"); + IPSEC_ASSERT(m != NULL, ("null mbuf")); + IPSEC_ASSERT(mhp != NULL, ("null msghdr")); + IPSEC_ASSERT(m->m_len >= sizeof(struct sadb_msg), + ("mbuf too small, len %u", m->m_len)); /* initialize */ bzero(mhp, sizeof(*mhp)); @@ -6870,18 +6887,16 @@ key_align(m, mhp) * KEY_AUTH or KEY_ENCRYPT ? */ if (mhp->ext[ext->sadb_ext_type] != NULL) { - ipseclog((LOG_DEBUG, - "key_align: duplicate ext_type %u " - "is passed.\n", ext->sadb_ext_type)); + ipseclog((LOG_DEBUG, "%s: duplicate ext_type " + "%u\n", __func__, ext->sadb_ext_type)); m_freem(m); pfkeystat.out_dupext++; return EINVAL; } break; default: - ipseclog((LOG_DEBUG, - "key_align: invalid ext_type %u is passed.\n", - ext->sadb_ext_type)); + ipseclog((LOG_DEBUG, "%s: invalid ext_type %u\n", + __func__, ext->sadb_ext_type)); m_freem(m); pfkeystat.out_invexttype++; return EINVAL; @@ -6980,11 +6995,11 @@ key_init() { int i; - mtx_init(&sptree_lock, "sptree lock", "fast ipsec sadb", MTX_DEF); - mtx_init(®tree_lock, "regtree lock", "fast ipsec sadb", MTX_DEF); - mtx_init(&sahtree_lock, "sahtree lock", "fast ipsec sadb", MTX_DEF); - mtx_init(&acq_lock, "acqtree lock", "fast ipsec sadb", MTX_DEF); - mtx_init(&spacq_lock, "spacqtree lock", "fast ipsec sadb", MTX_DEF); + SPTREE_LOCK_INIT(); + REGTREE_LOCK_INIT(); + SAHTREE_LOCK_INIT(); + ACQ_LOCK_INIT(); + SPACQ_LOCK_INIT(); for (i = 0; i < IPSEC_DIR_MAX; i++) LIST_INIT(&sptree[i]); @@ -7008,7 +7023,7 @@ key_init() /* initialize key statistics */ keystat.getspi_count = 1; - printf("IPsec: Initialized Security Association Processing.\n"); + printf("Fast IPsec: Initialized Security Association Processing.\n"); return; } @@ -7028,9 +7043,7 @@ key_checktunnelsanity(sav, family, src, dst) caddr_t src; caddr_t dst; { - /* sanity check */ - if (sav->sah == NULL) - panic("sav->sah == NULL at key_checktunnelsanity"); + IPSEC_ASSERT(sav->sah != NULL, ("null SA header")); /* XXX: check inner IP header */ @@ -7043,8 +7056,8 @@ key_sa_recordxfer(sav, m) struct secasvar *sav; struct mbuf *m; { - KASSERT(sav != NULL, ("key_sa_recordxfer: Null secasvar")); - KASSERT(m != NULL, ("key_sa_recordxfer: Null mbuf")); + IPSEC_ASSERT(sav != NULL, ("Null secasvar")); + IPSEC_ASSERT(m != NULL, ("Null mbuf")); if (!sav->lft_c) return; @@ -7088,7 +7101,7 @@ key_sa_routechange(dst) struct secashead *sah; struct route *ro; - mtx_lock(&sahtree_lock); + SAHTREE_LOCK(); LIST_FOREACH(sah, &sahtree, chain) { ro = &sah->sa_route; if (ro->ro_rt && dst->sa_len == ro->ro_dst.sa_len @@ -7097,7 +7110,7 @@ key_sa_routechange(dst) ro->ro_rt = (struct rtentry *)NULL; } } - mtx_unlock(&sahtree_lock); + SAHTREE_UNLOCK(); } static void @@ -7105,8 +7118,8 @@ key_sa_chgstate(sav, state) struct secasvar *sav; u_int8_t state; { - KASSERT(sav != NULL, ("key_sa_chgstate: NULL sav")); - mtx_assert(&sahtree_lock, MA_OWNED); + IPSEC_ASSERT(sav != NULL, ("NULL sav")); + SAHTREE_LOCK_ASSERT(); if (sav->state != state) { if (__LIST_CHAINED(sav)) @@ -7121,8 +7134,7 @@ key_sa_stir_iv(sav) struct secasvar *sav; { - if (!sav->iv) - panic("key_sa_stir_iv called with sav == NULL"); + IPSEC_ASSERT(sav->iv != NULL, ("null IV")); key_randomfill(sav->iv, sav->ivlen); } -- cgit v1.1