#include <sys/queue.h>
#include <sys/syslog.h>
+#include <kern/locks.h>
+
#include <net/if.h>
#include <net/route.h>
#include <net/raw_cb.h>
#define FULLMASK 0xff
+lck_grp_t *sadb_mutex_grp;
+lck_grp_attr_t *sadb_mutex_grp_attr;
+lck_attr_t *sadb_mutex_attr;
+lck_mtx_t *sadb_mutex;
+extern lck_mtx_t *nd6_mutex;
+
/*
* Note on SA reference counting:
* - SAs that are not in DEAD state will have (total external reference + 1)
static int key_blockacq_count = 10; /* counter for blocking SADB_ACQUIRE.*/
static int key_blockacq_lifetime = 20; /* lifetime for blocking SADB_ACQUIRE.*/
static int key_preferred_oldsa = 0; /* preferred old sa rather than new sa.*/
-static int natt_keepalive_interval = 29; /* interval between natt keepalives.*/
+static int natt_keepalive_interval = 20; /* interval between natt keepalives.*/
static u_int32_t acq_seq = 0;
static int key_tick_init_random = 0;
static LIST_HEAD(_sahtree, secashead) sahtree; /* SAD */
static LIST_HEAD(_regtree, secreg) regtree[SADB_SATYPE_MAX + 1];
/* registed list */
+
+#define SPIHASHSIZE 128
+#define SPIHASH(x) (((x) ^ ((x) >> 16)) % SPIHASHSIZE)
+static LIST_HEAD(_spihash, secasvar) spihash[SPIHASHSIZE];
+
#ifndef IPSEC_NONBLOCK_ACQUIRE
static LIST_HEAD(_acqtree, secacq) acqtree; /* acquiring list */
#endif
SYSCTL_INT(_net_key, KEYCTL_NATT_KEEPALIVE_INTERVAL, natt_keepalive_interval, CTLFLAG_RW,\
&natt_keepalive_interval, 0, "");
+/* PF_KEY statistics */
+SYSCTL_STRUCT(_net_key, KEYCTL_PFKEYSTAT, pfkeystat, CTLFLAG_RD,\
+ &pfkeystat, pfkeystat, "");
+
#ifndef LIST_FOREACH
#define LIST_FOREACH(elm, head, field) \
for (elm = LIST_FIRST(head); elm; elm = LIST_NEXT(elm, field))
int extlen[SADB_EXT_MAX + 1];
};
-static struct secasvar *key_allocsa_policy __P((struct secasindex *));
-static void key_freesp_so __P((struct secpolicy **));
-static struct secasvar *key_do_allocsa_policy __P((struct secashead *, u_int));
-static void key_delsp __P((struct secpolicy *));
-static struct secpolicy *key_getsp __P((struct secpolicyindex *));
-static struct secpolicy *key_getspbyid __P((u_int32_t));
-static u_int32_t key_newreqid __P((void));
-static struct mbuf *key_gather_mbuf __P((struct mbuf *,
- const struct sadb_msghdr *, int, int, int *));
-static int key_spdadd __P((struct socket *, struct mbuf *,
- const struct sadb_msghdr *));
-static u_int32_t key_getnewspid __P((void));
-static int key_spddelete __P((struct socket *, struct mbuf *,
- const struct sadb_msghdr *));
-static int key_spddelete2 __P((struct socket *, struct mbuf *,
- const struct sadb_msghdr *));
-static int key_spdget __P((struct socket *, struct mbuf *,
- const struct sadb_msghdr *));
-static int key_spdflush __P((struct socket *, struct mbuf *,
- const struct sadb_msghdr *));
-static int key_spddump __P((struct socket *, struct mbuf *,
- const struct sadb_msghdr *));
-static struct mbuf *key_setdumpsp __P((struct secpolicy *,
- u_int8_t, u_int32_t, u_int32_t));
-static u_int key_getspreqmsglen __P((struct secpolicy *));
-static int key_spdexpire __P((struct secpolicy *));
-static struct secashead *key_newsah __P((struct secasindex *));
-static void key_delsah __P((struct secashead *));
-static struct secasvar *key_newsav __P((struct mbuf *,
- const struct sadb_msghdr *, struct secashead *, int *));
-static void key_delsav __P((struct secasvar *));
-static struct secashead *key_getsah __P((struct secasindex *));
-static struct secasvar *key_checkspidup __P((struct secasindex *, u_int32_t));
-static struct secasvar *key_getsavbyspi __P((struct secashead *, u_int32_t));
-static int key_setsaval __P((struct secasvar *, struct mbuf *,
- const struct sadb_msghdr *));
-static int key_mature __P((struct secasvar *));
-static struct mbuf *key_setdumpsa __P((struct secasvar *, u_int8_t,
- u_int8_t, u_int32_t, u_int32_t));
-static struct mbuf *key_setsadbmsg __P((u_int8_t, u_int16_t, u_int8_t,
- u_int32_t, pid_t, u_int16_t));
-static struct mbuf *key_setsadbsa __P((struct secasvar *));
-static struct mbuf *key_setsadbaddr __P((u_int16_t,
- struct sockaddr *, u_int8_t, u_int16_t));
+static struct secasvar *key_allocsa_policy(struct secasindex *);
+static void key_freesp_so(struct secpolicy **);
+static struct secasvar *key_do_allocsa_policy(struct secashead *, u_int);
+static void key_delsp(struct secpolicy *);
+static struct secpolicy *key_getsp(struct secpolicyindex *);
+static struct secpolicy *key_getspbyid(u_int32_t);
+static u_int32_t key_newreqid(void);
+static struct mbuf *key_gather_mbuf(struct mbuf *,
+ const struct sadb_msghdr *, int, int, int *);
+static int key_spdadd(struct socket *, struct mbuf *,
+ const struct sadb_msghdr *);
+static u_int32_t key_getnewspid(void);
+static int key_spddelete(struct socket *, struct mbuf *,
+ const struct sadb_msghdr *);
+static int key_spddelete2(struct socket *, struct mbuf *,
+ const struct sadb_msghdr *);
+static int key_spdget(struct socket *, struct mbuf *,
+ const struct sadb_msghdr *);
+static int key_spdflush(struct socket *, struct mbuf *,
+ const struct sadb_msghdr *);
+static int key_spddump(struct socket *, struct mbuf *,
+ const struct sadb_msghdr *);
+static struct mbuf *key_setdumpsp(struct secpolicy *,
+ u_int8_t, u_int32_t, u_int32_t);
+static u_int key_getspreqmsglen(struct secpolicy *);
+static int key_spdexpire(struct secpolicy *);
+static struct secashead *key_newsah(struct secasindex *);
+static void key_delsah(struct secashead *);
+static struct secasvar *key_newsav(struct mbuf *,
+ const struct sadb_msghdr *, struct secashead *, int *);
+static void key_delsav(struct secasvar *);
+static struct secashead *key_getsah(struct secasindex *);
+static struct secasvar *key_checkspidup(struct secasindex *, u_int32_t);
+static void key_setspi __P((struct secasvar *, u_int32_t));
+static struct secasvar *key_getsavbyspi(struct secashead *, u_int32_t);
+static int key_setsaval(struct secasvar *, struct mbuf *,
+ const struct sadb_msghdr *);
+static int key_mature(struct secasvar *);
+static struct mbuf *key_setdumpsa(struct secasvar *, u_int8_t,
+ u_int8_t, u_int32_t, u_int32_t);
+static struct mbuf *key_setsadbmsg(u_int8_t, u_int16_t, u_int8_t,
+ u_int32_t, pid_t, u_int16_t);
+static struct mbuf *key_setsadbsa(struct secasvar *);
+static struct mbuf *key_setsadbaddr(u_int16_t,
+ struct sockaddr *, u_int8_t, u_int16_t);
#if 0
-static struct mbuf *key_setsadbident __P((u_int16_t, u_int16_t, caddr_t,
- int, u_int64_t));
+static struct mbuf *key_setsadbident(u_int16_t, u_int16_t, caddr_t,
+ int, u_int64_t);
#endif
-static struct mbuf *key_setsadbxsa2 __P((u_int8_t, u_int32_t, u_int32_t));
-static struct mbuf *key_setsadbxpolicy __P((u_int16_t, u_int8_t,
- u_int32_t));
-static void *key_newbuf __P((const void *, u_int));
+static struct mbuf *key_setsadbxsa2(u_int8_t, u_int32_t, u_int32_t);
+static struct mbuf *key_setsadbxpolicy(u_int16_t, u_int8_t,
+ u_int32_t);
+static void *key_newbuf(const void *, u_int);
#if INET6
-static int key_ismyaddr6 __P((struct sockaddr_in6 *));
+static int key_ismyaddr6(struct sockaddr_in6 *);
#endif
/* flags for key_cmpsaidx() */
#define CMP_MODE_REQID 2 /* additionally HEAD, reqid, mode. */
#define CMP_REQID 3 /* additionally HEAD, reaid. */
#define CMP_EXACTLY 4 /* all elements. */
-static int key_cmpsaidx
- __P((struct secasindex *, struct secasindex *, int));
-
-static int key_cmpspidx_exactly
- __P((struct secpolicyindex *, struct secpolicyindex *));
-static int key_cmpspidx_withmask
- __P((struct secpolicyindex *, struct secpolicyindex *));
-static int key_sockaddrcmp __P((struct sockaddr *, struct sockaddr *, int));
-static int key_bbcmp __P((caddr_t, caddr_t, u_int));
-static void key_srandom __P((void));
-static u_int16_t key_satype2proto __P((u_int8_t));
-static u_int8_t key_proto2satype __P((u_int16_t));
-
-static int key_getspi __P((struct socket *, struct mbuf *,
- const struct sadb_msghdr *));
-static u_int32_t key_do_getnewspi __P((struct sadb_spirange *,
- struct secasindex *));
-static int key_update __P((struct socket *, struct mbuf *,
- const struct sadb_msghdr *));
+static int key_cmpsaidx(struct secasindex *, struct secasindex *, int);
+
+static int key_cmpspidx_exactly(struct secpolicyindex *,
+ struct secpolicyindex *);
+static int key_cmpspidx_withmask(struct secpolicyindex *,
+ struct secpolicyindex *);
+static int key_sockaddrcmp(struct sockaddr *, struct sockaddr *, int);
+static int key_bbcmp(caddr_t, caddr_t, u_int);
+static void key_srandom(void);
+static u_int16_t key_satype2proto(u_int8_t);
+static u_int8_t key_proto2satype(u_int16_t);
+
+static int key_getspi(struct socket *, struct mbuf *,
+ const struct sadb_msghdr *);
+static u_int32_t key_do_getnewspi(struct sadb_spirange *, struct secasindex *);
+static int key_update(struct socket *, struct mbuf *,
+ const struct sadb_msghdr *);
#if IPSEC_DOSEQCHECK
-static struct secasvar *key_getsavbyseq __P((struct secashead *, u_int32_t));
+static struct secasvar *key_getsavbyseq(struct secashead *, u_int32_t);
#endif
-static int key_add __P((struct socket *, struct mbuf *,
- const struct sadb_msghdr *));
-static int key_setident __P((struct secashead *, struct mbuf *,
- const struct sadb_msghdr *));
-static struct mbuf *key_getmsgbuf_x1 __P((struct mbuf *,
- const struct sadb_msghdr *));
-static int key_delete __P((struct socket *, struct mbuf *,
- const struct sadb_msghdr *));
-static int key_get __P((struct socket *, struct mbuf *,
- const struct sadb_msghdr *));
-
-static void key_getcomb_setlifetime __P((struct sadb_comb *));
+static int key_add(struct socket *, struct mbuf *, const struct sadb_msghdr *);
+static int key_setident(struct secashead *, struct mbuf *,
+ const struct sadb_msghdr *);
+static struct mbuf *key_getmsgbuf_x1(struct mbuf *, const struct sadb_msghdr *);
+static int key_delete(struct socket *, struct mbuf *,
+ const struct sadb_msghdr *);
+static int key_get(struct socket *, struct mbuf *, const struct sadb_msghdr *);
+
+static void key_getcomb_setlifetime(struct sadb_comb *);
#if IPSEC_ESP
-static struct mbuf *key_getcomb_esp __P((void));
+static struct mbuf *key_getcomb_esp(void);
#endif
-static struct mbuf *key_getcomb_ah __P((void));
-static struct mbuf *key_getcomb_ipcomp __P((void));
-static struct mbuf *key_getprop __P((const struct secasindex *));
+static struct mbuf *key_getcomb_ah(void);
+static struct mbuf *key_getcomb_ipcomp(void);
+static struct mbuf *key_getprop(const struct secasindex *);
-static int key_acquire __P((struct secasindex *, struct secpolicy *));
+static int key_acquire(struct secasindex *, struct secpolicy *);
#ifndef IPSEC_NONBLOCK_ACQUIRE
-static struct secacq *key_newacq __P((struct secasindex *));
-static struct secacq *key_getacq __P((struct secasindex *));
-static struct secacq *key_getacqbyseq __P((u_int32_t));
+static struct secacq *key_newacq(struct secasindex *);
+static struct secacq *key_getacq(struct secasindex *);
+static struct secacq *key_getacqbyseq(u_int32_t);
#endif
-static struct secspacq *key_newspacq __P((struct secpolicyindex *));
-static struct secspacq *key_getspacq __P((struct secpolicyindex *));
-static int key_acquire2 __P((struct socket *, struct mbuf *,
- const struct sadb_msghdr *));
-static int key_register __P((struct socket *, struct mbuf *,
- const struct sadb_msghdr *));
-static int key_expire __P((struct secasvar *));
-static int key_flush __P((struct socket *, struct mbuf *,
- const struct sadb_msghdr *));
-static int key_dump __P((struct socket *, struct mbuf *,
- const struct sadb_msghdr *));
-static int key_promisc __P((struct socket *, struct mbuf *,
- const struct sadb_msghdr *));
-static int key_senderror __P((struct socket *, struct mbuf *, int));
-static int key_validate_ext __P((const struct sadb_ext *, int));
-static int key_align __P((struct mbuf *, struct sadb_msghdr *));
+static struct secspacq *key_newspacq(struct secpolicyindex *);
+static struct secspacq *key_getspacq(struct secpolicyindex *);
+static int key_acquire2(struct socket *, struct mbuf *,
+ const struct sadb_msghdr *);
+static int key_register(struct socket *, struct mbuf *,
+ const struct sadb_msghdr *);
+static int key_expire(struct secasvar *);
+static int key_flush(struct socket *, struct mbuf *,
+ const struct sadb_msghdr *);
+static int key_dump(struct socket *, struct mbuf *, const struct sadb_msghdr *);
+static int key_promisc(struct socket *, struct mbuf *,
+ const struct sadb_msghdr *);
+static int key_senderror(struct socket *, struct mbuf *, int);
+static int key_validate_ext(const struct sadb_ext *, int);
+static int key_align(struct mbuf *, struct sadb_msghdr *);
#if 0
-static const char *key_getfqdn __P((void));
-static const char *key_getuserfqdn __P((void));
+static const char *key_getfqdn(void);
+static const char *key_getuserfqdn(void);
#endif
-static void key_sa_chgstate __P((struct secasvar *, u_int8_t));
-static struct mbuf *key_alloc_mbuf __P((int));
+static void key_sa_chgstate(struct secasvar *, u_int8_t);
+static struct mbuf *key_alloc_mbuf(int);
extern int ipsec_bypass;
void ipsec_send_natt_keepalive(struct secasvar *sav);
+
+/*
+ * PF_KEY init
+ * setup locks and call raw_init()
+ *
+ */
+void
+key_init(void)
+{
+
+ int i;
+
+ sadb_mutex_grp_attr = lck_grp_attr_alloc_init();
+ sadb_mutex_grp = lck_grp_alloc_init("sadb", sadb_mutex_grp_attr);
+ sadb_mutex_attr = lck_attr_alloc_init();
+
+ if ((sadb_mutex = lck_mtx_alloc_init(sadb_mutex_grp, sadb_mutex_attr)) == NULL) {
+ printf("key_init: can't alloc sadb_mutex\n");
+ return;
+ }
+
+ for (i = 0; i < SPIHASHSIZE; i++)
+ LIST_INIT(&spihash[i]);
+
+ raw_init();
+}
+
+
/* %%% IPsec policy management */
/*
* allocating a SP for OUTBOUND or INBOUND packet.
struct timeval tv;
int s;
+ lck_mtx_assert(sadb_mutex, LCK_MTX_ASSERT_OWNED);
/* sanity check */
if (spidx == NULL)
panic("key_allocsp: NULL pointer is passed.\n");
}
/* get a SP entry */
- s = splnet(); /*called from softclock()*/
KEYDEBUG(KEYDEBUG_IPSEC_DATA,
printf("*** objects\n");
kdebug_secpolicyindex(spidx));
goto found;
}
- splx(s);
return NULL;
found:
microtime(&tv);
sp->lastused = tv.tv_sec;
sp->refcnt++;
- splx(s);
KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
printf("DP key_allocsp cause refcnt++:%d SP:%p\n",
sp->refcnt, sp));
struct sockaddr *os, *od, *is, *id;
struct secpolicyindex spidx;
+ lck_mtx_assert(sadb_mutex, LCK_MTX_ASSERT_OWNED);
+
if (isrc->sa_family != idst->sa_family) {
ipseclog((LOG_ERR, "protocol family mismatched %d != %d\n.",
isrc->sa_family, idst->sa_family));
return NULL;
}
- s = splnet(); /*called from softclock()*/
LIST_FOREACH(sp, &sptree[dir], chain) {
if (sp->state == IPSEC_SPSTATE_DEAD)
continue;
goto found;
}
}
- splx(s);
+
return NULL;
found:
microtime(&tv);
sp->lastused = tv.tv_sec;
sp->refcnt++;
- splx(s);
return sp;
}
u_int level;
int error;
+ lck_mtx_assert(sadb_mutex, LCK_MTX_ASSERT_OWNED);
+
/* sanity check */
if (isr == NULL || saidx == NULL)
panic("key_checkrequest: NULL pointer is passed.\n");
const u_int *saorder_state_valid;
int arraysize;
+ lck_mtx_assert(sadb_mutex, LCK_MTX_ASSERT_OWNED);
+
LIST_FOREACH(sah, &sahtree, chain) {
if (sah->state == SADB_SASTATE_DEAD)
continue;
{
struct secasvar *sav, *nextsav, *candidate, *d;
+ lck_mtx_assert(sadb_mutex, LCK_MTX_ASSERT_OWNED);
+
/* initilize */
candidate = NULL;
* allocating a SA entry for a *INBOUND* packet.
* Must call key_freesav() later.
* OUT: positive: pointer to a sav.
- * NULL: not found, or error occured.
+ * NULL: not found, or error occurred.
*
* In the comparison, source address will be ignored for RFC2401 conformance.
* To quote, from section 4.1:
caddr_t src, dst;
u_int32_t spi;
{
- struct secashead *sah;
- struct secasvar *sav;
- u_int stateidx, state;
+ struct secasvar *sav, *match;
+ u_int stateidx, state, tmpidx, matchidx;
struct sockaddr_in sin;
struct sockaddr_in6 sin6;
int s;
const u_int *saorder_state_valid;
int arraysize;
+ lck_mtx_assert(sadb_mutex, LCK_MTX_ASSERT_OWNED);
+
/* sanity check */
if (src == NULL || dst == NULL)
panic("key_allocsa: NULL pointer is passed.\n");
* IPsec tunnel packet is received. But ESP tunnel mode is
* encrypted so we can't check internal IP header.
*/
- s = splnet(); /*called from softclock()*/
- LIST_FOREACH(sah, &sahtree, chain) {
- /*
- * search a valid state list for inbound packet.
- * the search order is not important.
- */
- for (stateidx = 0; stateidx < arraysize; stateidx++) {
+ /*
+ * search a valid state list for inbound packet.
+ * the search order is not important.
+ */
+ match = NULL;
+ matchidx = arraysize;
+ LIST_FOREACH(sav, &spihash[SPIHASH(spi)], spihash) {
+ if (sav->spi != spi)
+ continue;
+ if (proto != sav->sah->saidx.proto)
+ continue;
+ if (family != sav->sah->saidx.src.ss_family ||
+ family != sav->sah->saidx.dst.ss_family)
+ continue;
+ tmpidx = arraysize;
+ for (stateidx = 0; stateidx < matchidx; stateidx++) {
state = saorder_state_valid[stateidx];
- LIST_FOREACH(sav, &sah->savtree[state], chain) {
- /* sanity check */
- KEY_CHKSASTATE(sav->state, state, "key_allocsav");
- if (proto != sav->sah->saidx.proto)
- continue;
- if (spi != sav->spi)
- continue;
- if (family != sav->sah->saidx.src.ss_family ||
- family != sav->sah->saidx.dst.ss_family)
- continue;
+ if (sav->state == state) {
+ tmpidx = stateidx;
+ break;
+ }
+ }
+ if (tmpidx >= matchidx)
+ continue;
#if 0 /* don't check src */
- /* check src address */
- switch (family) {
- case AF_INET:
- bzero(&sin, sizeof(sin));
- sin.sin_family = AF_INET;
- sin.sin_len = sizeof(sin);
- bcopy(src, &sin.sin_addr,
- sizeof(sin.sin_addr));
- if (key_sockaddrcmp((struct sockaddr*)&sin,
- (struct sockaddr *)&sav->sah->saidx.src, 0) != 0)
- continue;
-
- break;
- case AF_INET6:
- bzero(&sin6, sizeof(sin6));
- sin6.sin6_family = AF_INET6;
- sin6.sin6_len = sizeof(sin6);
- bcopy(src, &sin6.sin6_addr,
- sizeof(sin6.sin6_addr));
- if (IN6_IS_SCOPE_LINKLOCAL(&sin6.sin6_addr)) {
- /* kame fake scopeid */
- sin6.sin6_scope_id =
- ntohs(sin6.sin6_addr.s6_addr16[1]);
- sin6.sin6_addr.s6_addr16[1] = 0;
- }
- if (key_sockaddrcmp((struct sockaddr*)&sin6,
- (struct sockaddr *)&sav->sah->saidx.src, 0) != 0)
- continue;
- break;
- default:
- ipseclog((LOG_DEBUG, "key_allocsa: "
- "unknown address family=%d.\n",
- family));
- continue;
- }
+ /* check src address */
+ switch (family) {
+ case AF_INET:
+ bzero(&sin, sizeof(sin));
+ sin.sin_family = AF_INET;
+ sin.sin_len = sizeof(sin);
+ bcopy(src, &sin.sin_addr,
+ sizeof(sin.sin_addr));
+ if (key_sockaddrcmp((struct sockaddr*)&sin,
+ (struct sockaddr *)&sav->sah->saidx.src, 0) != 0)
+ continue;
+ break;
+ case AF_INET6:
+ bzero(&sin6, sizeof(sin6));
+ sin6.sin6_family = AF_INET6;
+ sin6.sin6_len = sizeof(sin6);
+ bcopy(src, &sin6.sin6_addr,
+ sizeof(sin6.sin6_addr));
+ if (IN6_IS_SCOPE_LINKLOCAL(&sin6.sin6_addr)) {
+ /* kame fake scopeid */
+ sin6.sin6_scope_id =
+ ntohs(sin6.sin6_addr.s6_addr16[1]);
+ sin6.sin6_addr.s6_addr16[1] = 0;
+ }
+ if (key_sockaddrcmp((struct sockaddr*)&sin6,
+ (struct sockaddr *)&sav->sah->saidx.src, 0) != 0)
+ continue;
+ break;
+ default:
+ ipseclog((LOG_DEBUG, "key_allocsa: "
+ "unknown address family=%d.\n",
+ family));
+ continue;
+ }
#endif
- /* check dst address */
- switch (family) {
- case AF_INET:
- bzero(&sin, sizeof(sin));
- sin.sin_family = AF_INET;
- sin.sin_len = sizeof(sin);
- bcopy(dst, &sin.sin_addr,
- sizeof(sin.sin_addr));
- if (key_sockaddrcmp((struct sockaddr*)&sin,
- (struct sockaddr *)&sav->sah->saidx.dst, 0) != 0)
- continue;
-
- break;
- case AF_INET6:
- bzero(&sin6, sizeof(sin6));
- sin6.sin6_family = AF_INET6;
- sin6.sin6_len = sizeof(sin6);
- bcopy(dst, &sin6.sin6_addr,
- sizeof(sin6.sin6_addr));
- if (IN6_IS_SCOPE_LINKLOCAL(&sin6.sin6_addr)) {
- /* kame fake scopeid */
- sin6.sin6_scope_id =
- ntohs(sin6.sin6_addr.s6_addr16[1]);
- sin6.sin6_addr.s6_addr16[1] = 0;
- }
- if (key_sockaddrcmp((struct sockaddr*)&sin6,
- (struct sockaddr *)&sav->sah->saidx.dst, 0) != 0)
- continue;
- break;
- default:
- ipseclog((LOG_DEBUG, "key_allocsa: "
- "unknown address family=%d.\n",
- family));
- continue;
- }
+ /* check dst address */
+ switch (family) {
+ case AF_INET:
+ bzero(&sin, sizeof(sin));
+ sin.sin_family = AF_INET;
+ sin.sin_len = sizeof(sin);
+ bcopy(dst, &sin.sin_addr,
+ sizeof(sin.sin_addr));
+ if (key_sockaddrcmp((struct sockaddr*)&sin,
+ (struct sockaddr *)&sav->sah->saidx.dst, 0) != 0)
+ continue;
- goto found;
- }
+ break;
+ case AF_INET6:
+ bzero(&sin6, sizeof(sin6));
+ sin6.sin6_family = AF_INET6;
+ sin6.sin6_len = sizeof(sin6);
+ bcopy(dst, &sin6.sin6_addr,
+ sizeof(sin6.sin6_addr));
+ if (IN6_IS_SCOPE_LINKLOCAL(&sin6.sin6_addr)) {
+ /* kame fake scopeid */
+ sin6.sin6_scope_id =
+ ntohs(sin6.sin6_addr.s6_addr16[1]);
+ sin6.sin6_addr.s6_addr16[1] = 0;
+ }
+ if (key_sockaddrcmp((struct sockaddr*)&sin6,
+ (struct sockaddr *)&sav->sah->saidx.dst, 0) != 0)
+ continue;
+ break;
+ default:
+ ipseclog((LOG_DEBUG, "key_allocsa: "
+ "unknown address family=%d.\n", family));
+ continue;
}
+
+ match = sav;
+ matchidx = tmpidx;
}
+ if (match)
+ goto found;
/* not found */
- splx(s);
return NULL;
found:
- sav->refcnt++;
- splx(s);
+ match->refcnt++;
KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
printf("DP allocsa cause refcnt++:%d SA:%p\n",
- sav->refcnt, sav));
- return sav;
+ match->refcnt, match));
+ return match;
}
/*
key_freesp(sp)
struct secpolicy *sp;
{
+ lck_mtx_assert(sadb_mutex, LCK_MTX_ASSERT_OWNED);
+
/* sanity check */
if (sp == NULL)
panic("key_freesp: NULL pointer is passed.\n");
return;
}
+#if 0
/*
* Must be called after calling key_allocsp().
* For the packet with socket.
key_freeso(so)
struct socket *so;
{
+ lck_mtx_assert(sadb_mutex, LCK_MTX_ASSERT_OWNED);
+
/* sanity check */
if (so == NULL)
panic("key_freeso: NULL pointer is passed.\n");
return;
}
+#endif
static void
key_freesp_so(sp)
struct secpolicy **sp;
{
+
+ lck_mtx_assert(sadb_mutex, LCK_MTX_ASSERT_OWNED);
+
/* sanity check */
if (sp == NULL || *sp == NULL)
panic("key_freesp_so: sp == NULL\n");
key_freesav(sav)
struct secasvar *sav;
{
+ lck_mtx_assert(sadb_mutex, LCK_MTX_ASSERT_OWNED);
+
/* sanity check */
if (sav == NULL)
panic("key_freesav: NULL pointer is passed.\n");
{
int s;
+ lck_mtx_assert(sadb_mutex, LCK_MTX_ASSERT_OWNED);
+
/* sanity check */
if (sp == NULL)
panic("key_delsp: NULL pointer is passed.\n");
{
struct secpolicy *sp;
+ lck_mtx_assert(sadb_mutex, LCK_MTX_ASSERT_OWNED);
+
/* sanity check */
if (spidx == NULL)
panic("key_getsp: NULL pointer is passed.\n");
{
struct secpolicy *sp;
+ lck_mtx_assert(sadb_mutex, LCK_MTX_ASSERT_OWNED);
+
LIST_FOREACH(sp, &sptree[IPSEC_DIR_INBOUND], chain) {
if (sp->state == IPSEC_SPSTATE_DEAD)
continue;
{
struct secpolicy *newsp;
+ lck_mtx_assert(sadb_mutex, LCK_MTX_ASSERT_OWNED);
+
/* sanity check */
if (xpl0 == NULL)
panic("key_msg2sp: NULL pointer was passed.\n");
{
static u_int32_t auto_reqid = IPSEC_MANUAL_REQID_MAX + 1;
+ lck_mtx_assert(sadb_mutex, LCK_MTX_ASSERT_OWNED);
+
auto_reqid = (auto_reqid == ~0
? IPSEC_MANUAL_REQID_MAX + 1 : auto_reqid + 1);
caddr_t p;
struct mbuf *m;
+ lck_mtx_assert(sadb_mutex, LCK_MTX_ASSERT_OWNED);
+
/* sanity check. */
if (sp == NULL)
panic("key_sp2msg: NULL pointer was passed.\n");
struct timeval tv;
int error;
+ lck_mtx_assert(sadb_mutex, LCK_MTX_ASSERT_OWNED);
+
/* sanity check */
if (so == NULL || m == NULL || mhp == NULL || mhp->msg == NULL)
panic("key_spdadd: NULL pointer is passed.\n");
int count = key_spi_trycnt; /* XXX */
struct secpolicy *sp;
+ lck_mtx_assert(sadb_mutex, LCK_MTX_ASSERT_OWNED);
+
/* when requesting to allocate spi ranged */
while (count--) {
newid = (policy_id = (policy_id == ~0 ? 1 : policy_id + 1));
struct secpolicyindex spidx;
struct secpolicy *sp;
+ lck_mtx_assert(sadb_mutex, LCK_MTX_ASSERT_OWNED);
+
/* sanity check */
if (so == NULL || m == NULL || mhp == NULL || mhp->msg == NULL)
panic("key_spddelete: NULL pointer is passed.\n");
u_int32_t id;
struct secpolicy *sp;
+ lck_mtx_assert(sadb_mutex, LCK_MTX_ASSERT_OWNED);
+
/* sanity check */
if (so == NULL || m == NULL || mhp == NULL || mhp->msg == NULL)
panic("key_spddelete2: NULL pointer is passed.\n");
struct secpolicy *sp;
struct mbuf *n;
+ lck_mtx_assert(sadb_mutex, LCK_MTX_ASSERT_OWNED);
+
/* sanity check */
if (so == NULL || m == NULL || mhp == NULL || mhp->msg == NULL)
panic("key_spdget: NULL pointer is passed.\n");
* send
* <base, policy(*)>
* to KMD, and expect to receive
- * <base> with SADB_X_SPDACQUIRE if error occured,
+ * <base> with SADB_X_SPDACQUIRE if error occurred,
* or
* <base, policy>
* with SADB_X_SPDUPDATE from KMD by PF_KEY.
struct secspacq *newspacq;
int error;
+ lck_mtx_assert(sadb_mutex, LCK_MTX_ASSERT_OWNED);
+
/* sanity check */
if (sp == NULL)
panic("key_spdacquire: NULL pointer is passed.\n");
struct secpolicy *sp;
u_int dir;
+ lck_mtx_assert(sadb_mutex, LCK_MTX_ASSERT_OWNED);
+
/* sanity check */
if (so == NULL || m == NULL || mhp == NULL || mhp->msg == NULL)
panic("key_spdflush: NULL pointer is passed.\n");
u_int dir;
struct mbuf *n;
+ lck_mtx_assert(sadb_mutex, LCK_MTX_ASSERT_OWNED);
+
/* sanity check */
if (so == NULL || m == NULL || mhp == NULL || mhp->msg == NULL)
panic("key_spddump: NULL pointer is passed.\n");
{
struct mbuf *result = NULL, *m;
+ lck_mtx_assert(sadb_mutex, LCK_MTX_ASSERT_OWNED);
+
m = key_setsadbmsg(type, 0, SADB_SATYPE_UNSPEC, seq, pid, sp->refcnt);
if (!m)
goto fail;
{
u_int tlen;
+ lck_mtx_assert(sadb_mutex, LCK_MTX_ASSERT_OWNED);
+
tlen = sizeof(struct sadb_x_policy);
/* if is the policy for ipsec ? */
int error = -1;
struct sadb_lifetime *lt;
- /* XXX: Why do we lock ? */
- s = splnet(); /*called from softclock()*/
+ lck_mtx_assert(sadb_mutex, LCK_MTX_ASSERT_OWNED);
/* sanity check */
if (sp == NULL)
fail:
if (result)
m_freem(result);
- splx(s);
return error;
}
{
struct secashead *newsah;
+ lck_mtx_assert(sadb_mutex, LCK_MTX_ASSERT_OWNED);
+
/* sanity check */
if (saidx == NULL)
panic("key_newsaidx: NULL pointer is passed.\n");
int s;
int zombie = 0;
+ lck_mtx_assert(sadb_mutex, LCK_MTX_ASSERT_OWNED);
+
/* sanity check */
if (sah == NULL)
panic("key_delsah: NULL pointer is passed.\n");
struct secasvar *newsav;
const struct sadb_sa *xsa;
+ lck_mtx_assert(sadb_mutex, LCK_MTX_ASSERT_OWNED);
+
/* sanity check */
if (m == NULL || mhp == NULL || mhp->msg == NULL || sah == NULL)
panic("key_newsa: NULL pointer is passed.\n");
switch (mhp->msg->sadb_msg_type) {
case SADB_GETSPI:
- newsav->spi = 0;
+ key_setspi(newsav, 0);
#if IPSEC_DOSEQCHECK
/* sync sequence number */
return NULL;
}
xsa = (const struct sadb_sa *)mhp->ext[SADB_EXT_SA];
- newsav->spi = xsa->sadb_sa_spi;
+ key_setspi(newsav, xsa->sadb_sa_spi);
newsav->seq = mhp->msg->sadb_msg_seq;
break;
default:
if (mhp->msg->sadb_msg_type != SADB_GETSPI) {
*errp = key_setsaval(newsav, m, mhp);
if (*errp) {
+ if (newsav->spihash.le_prev || newsav->spihash.le_next)
+ LIST_REMOVE(newsav, spihash);
KFREE(newsav);
return NULL;
}
key_delsav(sav)
struct secasvar *sav;
{
+ lck_mtx_assert(sadb_mutex, LCK_MTX_ASSERT_OWNED);
+
/* sanity check */
if (sav == NULL)
panic("key_delsav: NULL pointer is passed.\n");
/* remove from SA header */
if (__LIST_CHAINED(sav))
LIST_REMOVE(sav, chain);
+
+ if (sav->spihash.le_prev || sav->spihash.le_next)
+ LIST_REMOVE(sav, spihash);
if (sav->key_auth != NULL) {
bzero(_KEYBUF(sav->key_auth), _KEYLEN(sav->key_auth));
{
struct secashead *sah;
+ lck_mtx_assert(sadb_mutex, LCK_MTX_ASSERT_OWNED);
+
LIST_FOREACH(sah, &sahtree, chain) {
if (sah->state == SADB_SASTATE_DEAD)
continue;
struct secasindex *saidx;
u_int32_t spi;
{
- struct secashead *sah;
struct secasvar *sav;
+ u_int stateidx, state;
+
+ lck_mtx_assert(sadb_mutex, LCK_MTX_ASSERT_OWNED);
/* check address family */
if (saidx->src.ss_family != saidx->dst.ss_family) {
}
/* check all SAD */
- LIST_FOREACH(sah, &sahtree, chain) {
- if (!key_ismyaddr((struct sockaddr *)&sah->saidx.dst))
+ LIST_FOREACH(sav, &spihash[SPIHASH(spi)], spihash) {
+ if (sav->spi != spi)
continue;
- sav = key_getsavbyspi(sah, spi);
- if (sav != NULL)
- return sav;
+ for (stateidx = 0;
+ stateidx < _ARRAYLEN(saorder_state_alive);
+ stateidx++) {
+ state = saorder_state_alive[stateidx];
+ if (sav->state == state &&
+ key_ismyaddr((struct sockaddr *)&sav->sah->saidx.dst))
+ return sav;
+ }
}
return NULL;
}
+static void
+key_setspi(sav, spi)
+ struct secasvar *sav;
+ u_int32_t spi;
+{
+
+ sav->spi = spi;
+ if (sav->spihash.le_prev || sav->spihash.le_next)
+ LIST_REMOVE(sav, spihash);
+ LIST_INSERT_HEAD(&spihash[SPIHASH(spi)], sav, spihash);
+}
+
+
/*
* search SAD litmited alive SA, protocol, SPI.
* OUT:
struct secashead *sah;
u_int32_t spi;
{
- struct secasvar *sav;
- u_int stateidx, state;
-
- /* search all status */
- for (stateidx = 0;
- stateidx < _ARRAYLEN(saorder_state_alive);
- stateidx++) {
-
- state = saorder_state_alive[stateidx];
- LIST_FOREACH(sav, &sah->savtree[state], chain) {
-
- /* sanity check */
- if (sav->state != state) {
- ipseclog((LOG_DEBUG, "key_getsavbyspi: "
- "invalid sav->state (queue: %d SA: %d)\n",
- state, sav->state));
- continue;
+ struct secasvar *sav, *match;
+ u_int stateidx, state, matchidx;
+
+ match = NULL;
+ matchidx = _ARRAYLEN(saorder_state_alive);
+ LIST_FOREACH(sav, &spihash[SPIHASH(spi)], spihash) {
+ if (sav->spi != spi)
+ continue;
+ if (sav->sah != sah)
+ continue;
+ for (stateidx = 0; stateidx < matchidx; stateidx++) {
+ state = saorder_state_alive[stateidx];
+ if (sav->state == state) {
+ match = sav;
+ matchidx = stateidx;
+ break;
}
-
- if (sav->spi == spi)
- return sav;
}
}
- return NULL;
+ return match;
}
/*
int error = 0;
struct timeval tv;
+ lck_mtx_assert(sadb_mutex, LCK_MTX_ASSERT_OWNED);
+
/* sanity check */
if (m == NULL || mhp == NULL || mhp->msg == NULL)
panic("key_setsaval: NULL pointer is passed.\n");
sa0 = (const struct sadb_sa *)mhp->ext[SADB_EXT_SA];
if (mhp->extlen[SADB_EXT_SA] < sizeof(*sa0)) {
+ ipseclog((LOG_DEBUG, "key_setsaval: invalid message size.\n"));
error = EINVAL;
goto fail;
}
if ((sav->flags & SADB_X_EXT_NATT) != 0) {
if (mhp->extlen[SADB_EXT_SA] < sizeof(struct sadb_sa_2) ||
((struct sadb_sa_2*)(sa0))->sadb_sa_natt_port == 0) {
+ ipseclog((LOG_DEBUG, "key_setsaval: natt port not set.\n"));
error = EINVAL;
goto fail;
}
error = 0;
if (len < sizeof(*key0)) {
+ ipseclog((LOG_DEBUG, "key_setsaval: invalid auth key ext len. len = %d\n", len));
error = EINVAL;
goto fail;
}
error = 0;
if (len < sizeof(*key0)) {
+ ipseclog((LOG_DEBUG, "key_setsaval: invalid encryption key ext len. len = %d\n", len));
error = EINVAL;
goto fail;
}
case SADB_SATYPE_ESP:
if (len == PFKEY_ALIGN8(sizeof(struct sadb_key)) &&
sav->alg_enc != SADB_EALG_NULL) {
+ ipseclog((LOG_DEBUG, "key_setsaval: invalid ESP algorithm.\n"));
error = EINVAL;
break;
}
break;
}
if (error) {
- ipseclog((LOG_DEBUG, "key_setsatval: invalid key_enc value.\n"));
+ ipseclog((LOG_DEBUG, "key_setsaval: invalid key_enc value.\n"));
goto fail;
}
}
lft0 = (struct sadb_lifetime *)mhp->ext[SADB_EXT_LIFETIME_HARD];
if (lft0 != NULL) {
if (mhp->extlen[SADB_EXT_LIFETIME_HARD] < sizeof(*lft0)) {
+ ipseclog((LOG_DEBUG, "key_setsaval: invalid hard lifetime ext len.\n"));
error = EINVAL;
goto fail;
}
lft0 = (struct sadb_lifetime *)mhp->ext[SADB_EXT_LIFETIME_SOFT];
if (lft0 != NULL) {
if (mhp->extlen[SADB_EXT_LIFETIME_SOFT] < sizeof(*lft0)) {
+ ipseclog((LOG_DEBUG, "key_setsaval: invalid soft lifetime ext len.\n"));
error = EINVAL;
goto fail;
}
mature = 0;
+ lck_mtx_assert(sadb_mutex, LCK_MTX_ASSERT_OWNED);
+
/* check SPI value */
switch (sav->sah->saidx.proto) {
case IPPROTO_ESP:
SADB_EXT_IDENTITY_DST, SADB_EXT_SENSITIVITY,
};
+ lck_mtx_assert(sadb_mutex, LCK_MTX_ASSERT_OWNED);
+
m = key_setsadbmsg(type, 0, satype, seq, pid, sav->refcnt);
if (m == NULL)
goto fail;
switch (sa->sa_family) {
#if INET
case AF_INET:
+ lck_mtx_lock(rt_mtx);
sin = (struct sockaddr_in *)sa;
for (ia = in_ifaddrhead.tqh_first; ia;
ia = ia->ia_link.tqe_next)
sin->sin_len == ia->ia_addr.sin_len &&
sin->sin_addr.s_addr == ia->ia_addr.sin_addr.s_addr)
{
+ lck_mtx_unlock(rt_mtx);
return 1;
}
}
+ lck_mtx_unlock(rt_mtx);
break;
#endif
#if INET6
struct in6_ifaddr *ia;
struct in6_multi *in6m;
- for (ia = in6_ifaddr; ia; ia = ia->ia_next) {
+ lck_mtx_lock(nd6_mutex);
+ for (ia = in6_ifaddrs; ia; ia = ia->ia_next) {
if (key_sockaddrcmp((struct sockaddr *)&sin6,
- (struct sockaddr *)&ia->ia_addr, 0) == 0)
+ (struct sockaddr *)&ia->ia_addr, 0) == 0) {
+ lck_mtx_unlock(nd6_mutex);
return 1;
+ }
/*
* XXX Multicast
*/
in6m = NULL;
IN6_LOOKUP_MULTI(sin6->sin6_addr, ia->ia_ifp, in6m);
- if (in6m)
+ if (in6m) {
+ lck_mtx_unlock(nd6_mutex);
return 1;
+ }
}
+ lck_mtx_unlock(nd6_mutex);
/* loopback, just for safety */
if (IN6_IS_ADDR_LOOPBACK(&sin6->sin6_addr))
* and do to remove or to expire.
* XXX: year 2038 problem may remain.
*/
-void
-key_timehandler_funnel(void)
-{
-#ifdef __APPLE__
- boolean_t funnel_state;
- funnel_state = thread_funnel_set(network_flock, TRUE);
-#endif
- key_timehandler();
-#ifdef __APPLE__
- (void) thread_funnel_set(network_flock, FALSE);
-#endif
-}
void
key_timehandler(void)
microtime(&tv);
- s = splnet(); /*called from softclock()*/
-
+ lck_mtx_lock(sadb_mutex);
/* SPD */
{
struct secpolicy *sp, *nextsp;
natt_now++;
+ lck_mtx_unlock(sadb_mutex);
#ifndef IPSEC_DEBUG2
/* do exchange to tick time !! */
- (void)timeout((void *)key_timehandler_funnel, (void *)0, hz);
+ (void)timeout((void *)key_timehandler, (void *)0, hz);
#endif /* IPSEC_DEBUG2 */
- splx(s);
return;
}
u_int32_t reqid;
int error;
+ lck_mtx_assert(sadb_mutex, LCK_MTX_ASSERT_OWNED);
+
/* sanity check */
if (so == NULL || m == NULL || mhp == NULL || mhp->msg == NULL)
panic("key_getspi: NULL pointer is passed.\n");
}
/* set spi */
- newsav->spi = htonl(spi);
+ key_setspi(newsav, htonl(spi));
#ifndef IPSEC_NONBLOCK_ACQUIRE
/* delete the entry in acqtree */
u_int32_t min, max;
int count = key_spi_trycnt;
+ lck_mtx_assert(sadb_mutex, LCK_MTX_ASSERT_OWNED);
+
/* set spi range to allocate */
if (spirange != NULL) {
min = spirange->sadb_spirange_min;
u_int32_t reqid;
int error;
+ lck_mtx_assert(sadb_mutex, LCK_MTX_ASSERT_OWNED);
+
/* sanity check */
if (so == NULL || m == NULL || mhp == NULL || mhp->msg == NULL)
panic("key_update: NULL pointer is passed.\n");
}
/* check SA values to be mature. */
- if ((mhp->msg->sadb_msg_errno = key_mature(sav)) != 0) {
+ if ((error = key_mature(sav)) != 0) {
key_freesav(sav);
- return key_senderror(so, m, 0);
+ return key_senderror(so, m, error);
}
{
struct secasvar *sav;
u_int state;
+ lck_mtx_assert(sadb_mutex, LCK_MTX_ASSERT_OWNED);
+
state = SADB_SASTATE_LARVAL;
/* search SAD with sequence number ? */
u_int32_t reqid;
int error;
+ lck_mtx_assert(sadb_mutex, LCK_MTX_ASSERT_OWNED);
+
/* sanity check */
if (so == NULL || m == NULL || mhp == NULL || mhp->msg == NULL)
panic("key_add: NULL pointer is passed.\n");
const struct sadb_ident *idsrc, *iddst;
int idsrclen, iddstlen;
+ lck_mtx_assert(sadb_mutex, LCK_MTX_ASSERT_OWNED);
+
/* sanity check */
if (sah == NULL || m == NULL || mhp == NULL || mhp->msg == NULL)
panic("key_setident: NULL pointer is passed.\n");
return n;
}
-static int key_delete_all __P((struct socket *, struct mbuf *,
- const struct sadb_msghdr *, u_int16_t));
+static int key_delete_all(struct socket *, struct mbuf *,
+ const struct sadb_msghdr *, u_int16_t);
/*
* SADB_DELETE processing
struct secasvar *sav = NULL;
u_int16_t proto;
+ lck_mtx_assert(sadb_mutex, LCK_MTX_ASSERT_OWNED);
+
/* sanity check */
if (so == NULL || m == NULL || mhp == NULL || mhp->msg == NULL)
panic("key_delete: NULL pointer is passed.\n");
struct secasvar *sav, *nextsav;
u_int stateidx, state;
+ lck_mtx_assert(sadb_mutex, LCK_MTX_ASSERT_OWNED);
+
src0 = (struct sadb_address *)(mhp->ext[SADB_EXT_ADDRESS_SRC]);
dst0 = (struct sadb_address *)(mhp->ext[SADB_EXT_ADDRESS_DST]);
struct secasvar *sav = NULL;
u_int16_t proto;
+ lck_mtx_assert(sadb_mutex, LCK_MTX_ASSERT_OWNED);
+
/* sanity check */
if (so == NULL || m == NULL || mhp == NULL || mhp->msg == NULL)
panic("key_get: NULL pointer is passed.\n");
* <base, SA, address(SD), (address(P)), x_policy,
* (identity(SD),) (sensitivity,) proposal>
* to KMD, and expect to receive
- * <base> with SADB_ACQUIRE if error occured,
+ * <base> with SADB_ACQUIRE if error occurred,
* or
* <base, src address, dst address, (SPI range)> with SADB_GETSPI
* from KMD by PF_KEY.
int error = -1;
u_int32_t seq;
+ lck_mtx_assert(sadb_mutex, LCK_MTX_ASSERT_OWNED);
+
/* sanity check */
if (saidx == NULL)
panic("key_acquire: NULL pointer is passed.\n");
{
struct secacq *acq;
+ lck_mtx_assert(sadb_mutex, LCK_MTX_ASSERT_OWNED);
+
LIST_FOREACH(acq, &acqtree, chain) {
if (key_cmpsaidx(saidx, &acq->saidx, CMP_EXACTLY))
return acq;
{
struct secacq *acq;
+ lck_mtx_assert(sadb_mutex, LCK_MTX_ASSERT_OWNED);
+
LIST_FOREACH(acq, &acqtree, chain) {
if (acq->seq == seq)
return acq;
{
struct secspacq *acq;
+ lck_mtx_assert(sadb_mutex, LCK_MTX_ASSERT_OWNED);
+
LIST_FOREACH(acq, &spacqtree, chain) {
if (key_cmpspidx_exactly(spidx, &acq->spidx))
return acq;
u_int16_t proto;
int error;
+ lck_mtx_assert(sadb_mutex, LCK_MTX_ASSERT_OWNED);
+
/* sanity check */
if (so == NULL || m == NULL || mhp == NULL || mhp->msg == NULL)
panic("key_acquire2: NULL pointer is passed.\n");
/*
* Error message from KMd.
- * We assume that if error was occured in IKEd, the length of PFKEY
+ * We assume that if error was occurred in IKEd, the length of PFKEY
* message is equal to the size of sadb_msg structure.
- * We do not raise error even if error occured in this function.
+ * We do not raise error even if error occurred in this function.
*/
if (mhp->msg->sadb_msg_len == PFKEY_UNIT64(sizeof(struct sadb_msg))) {
#ifndef IPSEC_NONBLOCK_ACQUIRE
{
struct secreg *reg, *newreg = 0;
+ lck_mtx_assert(sadb_mutex, LCK_MTX_ASSERT_OWNED);
+
/* sanity check */
if (so == NULL || m == NULL || mhp == NULL || mhp->msg == NULL)
panic("key_register: NULL pointer is passed.\n");
}
bzero((caddr_t)newreg, sizeof(*newreg));
+ socket_lock(so, 1);
newreg->so = so;
((struct keycb *)sotorawcb(so))->kp_registered++;
+ socket_unlock(so, 1);
/* add regnode to regtree. */
LIST_INSERT_HEAD(®tree[mhp->msg->sadb_msg_satype], newreg, chain);
struct secreg *reg;
int i;
+ lck_mtx_assert(sadb_mutex, LCK_MTX_ASSERT_OWNED);
+
/* sanity check */
if (so == NULL)
panic("key_freereg: NULL pointer is passed.\n");
int error = -1;
struct sadb_lifetime *lt;
- /* XXX: Why do we lock ? */
- s = splnet(); /*called from softclock()*/
+ lck_mtx_assert(sadb_mutex, LCK_MTX_ASSERT_OWNED);
/* sanity check */
if (sav == NULL)
u_int8_t state;
u_int stateidx;
+ lck_mtx_assert(sadb_mutex, LCK_MTX_ASSERT_OWNED);
+
/* sanity check */
if (so == NULL || mhp == NULL || mhp->msg == NULL)
panic("key_flush: NULL pointer is passed.\n");
struct sadb_msg *newmsg;
struct mbuf *n;
+ lck_mtx_assert(sadb_mutex, LCK_MTX_ASSERT_OWNED);
+
/* sanity check */
if (so == NULL || m == NULL || mhp == NULL || mhp->msg == NULL)
panic("key_dump: NULL pointer is passed.\n");
{
int olen;
+ lck_mtx_assert(sadb_mutex, LCK_MTX_ASSERT_OWNED);
+
/* sanity check */
if (so == NULL || m == NULL || mhp == NULL || mhp->msg == NULL)
panic("key_promisc: NULL pointer is passed.\n");
} else if (olen == sizeof(struct sadb_msg)) {
/* enable/disable promisc mode */
struct keycb *kp;
-
+
+ socket_lock(so, 1);
if ((kp = (struct keycb *)sotorawcb(so)) == NULL)
return key_senderror(so, m, EINVAL);
mhp->msg->sadb_msg_errno = 0;
kp->kp_promisc = mhp->msg->sadb_msg_satype;
break;
default:
+ socket_unlock(so, 1);
return key_senderror(so, m, EINVAL);
}
+ socket_unlock(so, 1);
/* send the original message back to everyone */
mhp->msg->sadb_msg_errno = 0;
}
}
-static int (*key_typesw[]) __P((struct socket *, struct mbuf *,
- const struct sadb_msghdr *)) = {
+static int (*key_typesw[])(struct socket *, struct mbuf *,
+ const struct sadb_msghdr *) = {
NULL, /* SADB_RESERVED */
key_getspi, /* SADB_GETSPI */
key_update, /* SADB_UPDATE */
int error;
int target;
+ lck_mtx_assert(sadb_mutex, LCK_MTX_ASSERT_OWNED);
+
/* sanity check */
if (m == NULL || so == NULL)
panic("key_parse: NULL pointer is passed.\n");
{
struct sadb_msg *msg;
+ lck_mtx_assert(sadb_mutex, LCK_MTX_ASSERT_OWNED);
+
if (m->m_len < sizeof(struct sadb_msg))
panic("invalid mbuf passed to key_senderror");
}
void
-key_init()
+key_domain_init()
{
int i;
#endif
#ifndef IPSEC_DEBUG2
- timeout((void *)key_timehandler_funnel, (void *)0, hz);
+ timeout((void *)key_timehandler, (void *)0, hz);
#endif /*IPSEC_DEBUG2*/
/* initialize key statistics */
caddr_t src;
caddr_t dst;
{
+ lck_mtx_assert(sadb_mutex, LCK_MTX_ASSERT_OWNED);
+
/* sanity check */
if (sav->sah == NULL)
panic("sav->sah == NULL at key_checktunnelsanity");
struct secasvar *sav;
struct mbuf *m;
{
+ lck_mtx_assert(sadb_mutex, LCK_MTX_ASSERT_OWNED);
+
if (!sav)
panic("key_sa_recordxfer called with sav == NULL");
if (!m)
struct secashead *sah;
struct route *ro;
+ lck_mtx_lock(sadb_mutex);
LIST_FOREACH(sah, &sahtree, chain) {
ro = &sah->sa_route;
if (ro->ro_rt && dst->sa_len == ro->ro_dst.sa_len
ro->ro_rt = (struct rtentry *)NULL;
}
}
+ lck_mtx_unlock(sadb_mutex);
return;
}
struct secasvar *sav;
u_int8_t state;
{
+ lck_mtx_assert(sadb_mutex, LCK_MTX_ASSERT_OWNED);
+
if (sav == NULL)
panic("key_sa_chgstate called with sav == NULL");
struct secasvar *sav;
{
+ lck_mtx_assert(sadb_mutex, LCK_MTX_ASSERT_OWNED);
+
if (!sav->iv)
panic("key_sa_stir_iv called with sav == NULL");
key_randomfill(sav->iv, sav->ivlen);