[Midnightbsd-cvs] src: sys/netipsec: Sync with FreeBSD 7 enhancements.

laffer1 at midnightbsd.org laffer1 at midnightbsd.org
Mon Sep 15 20:25:01 EDT 2008


Log Message:
-----------
Sync with FreeBSD 7 enhancements.

Modified Files:
--------------
    src/sys/netipsec:
        ipsec.c (r1.1.1.1 -> r1.2)
        ipsec.h (r1.2 -> r1.3)
        ipsec6.h (r1.1.1.1 -> r1.2)
        ipsec_input.c (r1.1.1.1 -> r1.2)
        ipsec_mbuf.c (r1.2 -> r1.3)
        ipsec_osdep.h (r1.1.1.1 -> r1.2)
        ipsec_output.c (r1.1.1.1 -> r1.2)
        key.c (r1.1.1.1 -> r1.2)
        key_debug.c (r1.1.1.1 -> r1.2)
        key_var.h (r1.1.1.1 -> r1.2)
        keydb.h (r1.1.1.1 -> r1.2)
        keysock.c (r1.1.1.2 -> r1.2)
        keysock.h (r1.1.1.2 -> r1.2)
        xform.h (r1.2 -> r1.3)
        xform_ah.c (r1.2 -> r1.3)
        xform_esp.c (r1.3 -> r1.4)
        xform_ipcomp.c (r1.2 -> r1.3)
        xform_ipip.c (r1.2 -> r1.3)
        xform_tcp.c (r1.1.1.1 -> r1.2)

-------------- next part --------------
Index: key.c
===================================================================
RCS file: /home/cvs/src/sys/netipsec/key.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/netipsec/key.c -L sys/netipsec/key.c -u -r1.1.1.1 -r1.2
--- sys/netipsec/key.c
+++ sys/netipsec/key.c
@@ -1,4 +1,4 @@
-/*	$FreeBSD: src/sys/netipsec/key.c,v 1.20 2005/01/07 01:45:46 imp Exp $	*/
+/*	$FreeBSD: src/sys/netipsec/key.c,v 1.28 2007/07/01 11:38:29 gnn Exp $	*/
 /*	$KAME: key.c,v 1.191 2001/06/27 10:46:49 sakane Exp $	*/
 
 /*-
@@ -54,6 +54,7 @@
 #include <sys/errno.h>
 #include <sys/proc.h>
 #include <sys/queue.h>
+#include <sys/refcount.h>
 #include <sys/syslog.h>
 
 #include <net/if.h>
@@ -420,7 +421,10 @@
 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_dup(const void *, u_int, struct malloc_type *);
+static struct seckey *key_dup_keymsg(const struct sadb_key *, u_int, 
+				     struct malloc_type *);
+static struct seclifetime *key_dup_lifemsg(const struct sadb_lifetime *src,
+					    struct malloc_type *type);
 #ifdef INET6
 static int key_ismyaddr6 __P((struct sockaddr_in6 *));
 #endif
@@ -488,6 +492,10 @@
 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 mbuf *key_setlifetime(struct seclifetime *src, 
+				     u_int16_t exttype);
+static struct mbuf *key_setkey(struct seckey *src, u_int16_t exttype);
+
 #if 0
 static const char *key_getfqdn __P((void));
 static const char *key_getuserfqdn __P((void));
@@ -495,14 +503,26 @@
 static void key_sa_chgstate __P((struct secasvar *, u_int8_t));
 static struct mbuf *key_alloc_mbuf __P((int));
 
-#define	SA_ADDREF(p) do {						\
-	(p)->refcnt++;							\
-	IPSEC_ASSERT((p)->refcnt != 0, ("SA refcnt overflow"));		\
-} while (0)
-#define	SA_DELREF(p) do {						\
-	IPSEC_ASSERT((p)->refcnt > 0, ("SA refcnt underflow"));		\
-	(p)->refcnt--;							\
-} while (0)
+static __inline void
+sa_initref(struct secasvar *sav)
+{
+
+	refcount_init(&sav->refcnt, 1);
+}
+static __inline void
+sa_addref(struct secasvar *sav)
+{
+
+	refcount_acquire(&sav->refcnt);
+	IPSEC_ASSERT(sav->refcnt != 0, ("SA refcnt overflow"));
+}
+static __inline int
+sa_delref(struct secasvar *sav)
+{
+
+	IPSEC_ASSERT(sav->refcnt > 0, ("SA refcnt underflow"));
+	return (refcount_release(&sav->refcnt));
+}
 
 #define	SP_ADDREF(p) do {						\
 	(p)->refcnt++;							\
@@ -909,8 +929,8 @@
 
 		/* What the best method is to compare ? */
 		if (key_preferred_oldsa) {
-			if (candidate->lft_c->sadb_lifetime_addtime >
-					sav->lft_c->sadb_lifetime_addtime) {
+			if (candidate->lft_c->addtime >
+					sav->lft_c->addtime) {
 				candidate = sav;
 			}
 			continue;
@@ -918,8 +938,8 @@
 		}
 
 		/* preferred new sa rather than old sa */
-		if (candidate->lft_c->sadb_lifetime_addtime <
-				sav->lft_c->sadb_lifetime_addtime) {
+		if (candidate->lft_c->addtime <
+				sav->lft_c->addtime) {
 			d = candidate;
 			candidate = sav;
 		} else
@@ -930,7 +950,7 @@
 		 * suitable candidate and the lifetime of the SA is not
 		 * permanent.
 		 */
-		if (d->lft_c->sadb_lifetime_addtime != 0) {
+		if (d->lft_c->addtime != 0) {
 			struct mbuf *m, *result;
 			u_int8_t satype;
 
@@ -993,7 +1013,7 @@
 		}
 	}
 	if (candidate) {
-		SA_ADDREF(candidate);
+		sa_addref(candidate);
 		KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
 			printf("DP %s cause refcnt++:%d SA:%p\n",
 				__func__, candidate->refcnt, candidate));
@@ -1072,7 +1092,7 @@
 				/* check dst address */
 				if (key_sockaddrcmp(&dst->sa, &sav->sah->saidx.dst.sa, 0) != 0)
 					continue;
-				SA_ADDREF(sav);
+				sa_addref(sav);
 				goto done;
 			}
 		}
@@ -1191,16 +1211,16 @@
 
 	IPSEC_ASSERT(sav != NULL, ("null sav"));
 
-	/* XXX unguarded? */
-	SA_DELREF(sav);
-
-	KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
-		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) {
+	if (sa_delref(sav)) {
+		KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
+			printf("DP %s SA:%p (SPI %u) from %s:%u; refcnt now %u\n",
+				__func__, sav, ntohl(sav->spi), where, tag, sav->refcnt));
 		*psav = NULL;
 		key_delsav(sav);
+	} else {
+		KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
+			printf("DP %s SA:%p (SPI %u) from %s:%u; refcnt now %u\n",
+				__func__, sav, ntohl(sav->spi), where, tag, sav->refcnt));
 	}
 }
 
@@ -2103,8 +2123,7 @@
 	if (mhp->ext[SADB_X_EXT_POLICY] == NULL ||
 	    mhp->extlen[SADB_X_EXT_POLICY] < sizeof(struct sadb_x_policy)) {
 		ipseclog((LOG_DEBUG, "%s: invalid message is passed.\n", __func__));
-		key_senderror(so, m, EINVAL);
-		return 0;
+		return key_senderror(so, m, EINVAL);
 	}
 
 	id = ((struct sadb_x_policy *)mhp->ext[SADB_X_EXT_POLICY])->sadb_x_policy_id;
@@ -2112,7 +2131,7 @@
 	/* Is there SP in SPD ? */
 	if ((sp = key_getspbyid(id)) == NULL) {
 		ipseclog((LOG_DEBUG, "%s: no SP found id:%u.\n", __func__, id));
-		key_senderror(so, m, EINVAL);
+		return key_senderror(so, m, EINVAL);
 	}
 
 	sp->state = IPSEC_SPSTATE_DEAD;
@@ -2126,8 +2145,6 @@
 	/* create new sadb_msg to reply. */
 	len = PFKEY_ALIGN8(sizeof(struct sadb_msg));
 
-	if (len > MCLBYTES)
-		return key_senderror(so, m, ENOBUFS);
 	MGETHDR(n, M_DONTWAIT, MT_DATA);
 	if (n && len > MHLEN) {
 		MCLGET(n, M_DONTWAIT);
@@ -2240,7 +2257,6 @@
 {
 	struct mbuf *result = NULL, *m;
 	struct secspacq *newspacq;
-	int error;
 
 	IPSEC_ASSERT(sp != NULL, ("null secpolicy"));
 	IPSEC_ASSERT(sp->req == NULL, ("policy exists"));
@@ -2268,10 +2284,9 @@
 
 	/* create new sadb_msg to reply. */
 	m = key_setsadbmsg(SADB_X_SPDACQUIRE, 0, 0, 0, 0, 0);
-	if (!m) {
-		error = ENOBUFS;
-		goto fail;
-	}
+	if (!m)
+		return ENOBUFS;
+
 	result = m;
 
 	result->m_pkthdr.len = 0;
@@ -2282,11 +2297,6 @@
 	    PFKEY_UNIT64(result->m_pkthdr.len);
 
 	return key_sendup_mbuf(NULL, m, KEY_SENDUP_REGISTERED);
-
-fail:
-	if (result)
-		m_freem(result);
-	return error;
 }
 
 /*
@@ -2757,7 +2767,7 @@
 
 	/* add to satree */
 	newsav->sah = sah;
-	newsav->refcnt = 1;
+	sa_initref(newsav);
 	newsav->state = SADB_SASTATE_LARVAL;
 
 	/* XXX locking??? */
@@ -2787,15 +2797,19 @@
 	} else {
 		KASSERT(sav->iv == NULL, ("iv but no xform"));
 		if (sav->key_auth != NULL)
-			bzero(_KEYBUF(sav->key_auth), _KEYLEN(sav->key_auth));
+			bzero(sav->key_auth->key_data, _KEYLEN(sav->key_auth));
 		if (sav->key_enc != NULL)
-			bzero(_KEYBUF(sav->key_enc), _KEYLEN(sav->key_enc));
+			bzero(sav->key_enc->key_data, _KEYLEN(sav->key_enc));
 	}
 	if (sav->key_auth != NULL) {
+		if (sav->key_auth->key_data != NULL)
+			free(sav->key_auth->key_data, M_IPSEC_MISC);
 		free(sav->key_auth, M_IPSEC_MISC);
 		sav->key_auth = NULL;
 	}
 	if (sav->key_enc != NULL) {
+		if (sav->key_enc->key_data != NULL)
+			free(sav->key_enc->key_data, M_IPSEC_MISC);
 		free(sav->key_enc, M_IPSEC_MISC);
 		sav->key_enc = NULL;
 	}
@@ -3038,9 +3052,11 @@
 			goto fail;
 		}
 
-		sav->key_auth = key_dup(key0, len, M_IPSEC_MISC);
-		if (sav->key_auth == NULL) {
-			ipseclog((LOG_DEBUG, "%s: No more memory.\n",__func__));
+		sav->key_auth = (struct seckey *)key_dup_keymsg(key0, len,
+								M_IPSEC_MISC);
+		if (sav->key_auth == NULL ) {
+			ipseclog((LOG_DEBUG, "%s: No more memory.\n",
+				  __func__));
 			error = ENOBUFS;
 			goto fail;
 		}
@@ -3066,7 +3082,9 @@
 				error = EINVAL;
 				break;
 			}
-			sav->key_enc = key_dup(key0, len, M_IPSEC_MISC);
+			sav->key_enc = (struct seckey *)key_dup_keymsg(key0,
+								       len,
+								       M_IPSEC_MISC);
 			if (sav->key_enc == NULL) {
 				ipseclog((LOG_DEBUG, "%s: No more memory.\n",
 					__func__));
@@ -3126,13 +3144,10 @@
 		goto fail;
 	}
 
-	sav->lft_c->sadb_lifetime_len =
-	    PFKEY_UNIT64(sizeof(struct sadb_lifetime));
-	sav->lft_c->sadb_lifetime_exttype = SADB_EXT_LIFETIME_CURRENT;
-	sav->lft_c->sadb_lifetime_allocations = 0;
-	sav->lft_c->sadb_lifetime_bytes = 0;
-	sav->lft_c->sadb_lifetime_addtime = time_second;
-	sav->lft_c->sadb_lifetime_usetime = 0;
+	sav->lft_c->allocations = 0;
+	sav->lft_c->bytes = 0;
+	sav->lft_c->addtime = time_second;
+	sav->lft_c->usetime = 0;
 
 	/* lifetimes for HARD and SOFT */
     {
@@ -3144,7 +3159,7 @@
 			error = EINVAL;
 			goto fail;
 		}
-		sav->lft_h = key_dup(lft0, sizeof(*lft0), M_IPSEC_MISC);
+		sav->lft_h = key_dup_lifemsg(lft0, M_IPSEC_MISC);
 		if (sav->lft_h == NULL) {
 			ipseclog((LOG_DEBUG, "%s: No more memory.\n",__func__));
 			error = ENOBUFS;
@@ -3159,7 +3174,7 @@
 			error = EINVAL;
 			goto fail;
 		}
-		sav->lft_s = key_dup(lft0, sizeof(*lft0), M_IPSEC_MISC);
+		sav->lft_s = key_dup_lifemsg(lft0, M_IPSEC_MISC);
 		if (sav->lft_s == NULL) {
 			ipseclog((LOG_DEBUG, "%s: No more memory.\n",__func__));
 			error = ENOBUFS;
@@ -3192,7 +3207,12 @@
 	switch (sav->sah->saidx.proto) {
 	case IPPROTO_ESP:
 	case IPPROTO_AH:
-		if (ntohl(sav->spi) >= 0 && ntohl(sav->spi) <= 255) {
+		/*
+		 * RFC 4302, 2.4. Security Parameters Index (SPI), SPI values
+		 * 1-255 reserved by IANA for future use,
+		 * 0 for implementation specific, local use.
+		 */
+		if (ntohl(sav->spi) <= 255) {
 			ipseclog((LOG_DEBUG, "%s: illegal range of SPI %u.\n",
 			    __func__, (u_int32_t)ntohl(sav->spi)));
 			return EINVAL;
@@ -3271,9 +3291,7 @@
 	u_int32_t seq, pid;
 {
 	struct mbuf *result = NULL, *tres = NULL, *m;
-	int l = 0;
 	int i;
-	void *p;
 	int dumporder[] = {
 		SADB_EXT_SA, SADB_X_EXT_SA2,
 		SADB_EXT_LIFETIME_HARD, SADB_EXT_LIFETIME_SOFT,
@@ -3290,7 +3308,6 @@
 
 	for (i = sizeof(dumporder)/sizeof(dumporder[0]) - 1; i >= 0; i--) {
 		m = NULL;
-		p = NULL;
 		switch (dumporder[i]) {
 		case SADB_EXT_SA:
 			m = key_setsadbsa(sav);
@@ -3325,36 +3342,45 @@
 		case SADB_EXT_KEY_AUTH:
 			if (!sav->key_auth)
 				continue;
-			l = PFKEY_UNUNIT64(sav->key_auth->sadb_key_len);
-			p = sav->key_auth;
+			m = key_setkey(sav->key_auth, SADB_EXT_KEY_AUTH);
+			if (!m)
+				goto fail;
 			break;
 
 		case SADB_EXT_KEY_ENCRYPT:
 			if (!sav->key_enc)
 				continue;
-			l = PFKEY_UNUNIT64(sav->key_enc->sadb_key_len);
-			p = sav->key_enc;
+			m = key_setkey(sav->key_enc, SADB_EXT_KEY_ENCRYPT);
+			if (!m)
+				goto fail;
 			break;
 
 		case SADB_EXT_LIFETIME_CURRENT:
 			if (!sav->lft_c)
 				continue;
-			l = PFKEY_UNUNIT64(((struct sadb_ext *)sav->lft_c)->sadb_ext_len);
-			p = sav->lft_c;
+			m = key_setlifetime(sav->lft_c, 
+					    SADB_EXT_LIFETIME_CURRENT);
+			if (!m)
+				goto fail;
 			break;
 
 		case SADB_EXT_LIFETIME_HARD:
 			if (!sav->lft_h)
 				continue;
-			l = PFKEY_UNUNIT64(((struct sadb_ext *)sav->lft_h)->sadb_ext_len);
-			p = sav->lft_h;
+			m = key_setlifetime(sav->lft_h, 
+					    SADB_EXT_LIFETIME_HARD);
+			if (!m)
+				goto fail;
 			break;
 
 		case SADB_EXT_LIFETIME_SOFT:
 			if (!sav->lft_s)
 				continue;
-			l = PFKEY_UNUNIT64(((struct sadb_ext *)sav->lft_s)->sadb_ext_len);
-			p = sav->lft_s;
+			m = key_setlifetime(sav->lft_h, 
+					    SADB_EXT_LIFETIME_SOFT);
+
+			if (!m)
+				goto fail;
 			break;
 
 		case SADB_EXT_ADDRESS_PROXY:
@@ -3366,29 +3392,15 @@
 			continue;
 		}
 
-		if ((!m && !p) || (m && p))
+		if (!m)
 			goto fail;
-		if (p && tres) {
-			M_PREPEND(tres, l, M_DONTWAIT);
-			if (!tres)
-				goto fail;
-			bcopy(p, mtod(tres, caddr_t), l);
-			continue;
-		}
-		if (p) {
-			m = key_alloc_mbuf(l);
-			if (!m)
-				goto fail;
-			m_copyback(m, 0, l, p);
-		}
-
 		if (tres)
 			m_cat(m, tres);
 		tres = m;
+		  
 	}
 
 	m_cat(result, tres);
-
 	if (result->m_len < sizeof(struct sadb_msg)) {
 		result = m_pullup(result, sizeof(struct sadb_msg));
 		if (result == NULL)
@@ -3609,21 +3621,63 @@
 }
 
 /* %%% utilities */
-/*
- * copy a buffer into the new buffer allocated.
+/* Take a key message (sadb_key) from the socket and turn it into one
+ * of the kernel's key structures (seckey).
+ *
+ * IN: pointer to the src
+ * OUT: NULL no more memory
  */
-static void *
-key_dup(const void *src, u_int len, struct malloc_type *type)
+struct seckey *
+key_dup_keymsg(const struct sadb_key *src, u_int len,
+	       struct malloc_type *type)
+{
+	struct seckey *dst;
+	dst = (struct seckey *)malloc(sizeof(struct seckey), type, M_NOWAIT);
+	if (dst != NULL) {
+		dst->bits = src->sadb_key_bits;
+		dst->key_data = (char *)malloc(len, type, M_NOWAIT);
+		if (dst->key_data != NULL) {
+			bcopy((const char *)src + sizeof(struct sadb_key), 
+			      dst->key_data, len);
+		} else {
+			ipseclog((LOG_DEBUG, "%s: No more memory.\n", 
+				  __func__));
+			free(dst, type);
+			dst = NULL;
+		}
+	} else {
+		ipseclog((LOG_DEBUG, "%s: No more memory.\n", 
+			  __func__));
+
+	}
+	return dst;
+}
+
+/* Take a lifetime message (sadb_lifetime) passed in on a socket and
+ * turn it into one of the kernel's lifetime structures (seclifetime).
+ *
+ * IN: pointer to the destination, source and malloc type
+ * OUT: NULL, no more memory
+ */
+
+static struct seclifetime *
+key_dup_lifemsg(const struct sadb_lifetime *src,
+		 struct malloc_type *type)
 {
-	void *copy;
+	struct seclifetime *dst = NULL;
 
-	copy = malloc(len, type, M_NOWAIT);
-	if (copy == NULL) {
+	dst = (struct seclifetime *)malloc(sizeof(struct seclifetime), 
+					   type, M_NOWAIT);
+	if (dst == NULL) {
 		/* XXX counter */
 		ipseclog((LOG_DEBUG, "%s: No more memory.\n", __func__));
-	} else
-		bcopy(src, copy, len);
-	return copy;
+	} else {
+		dst->allocations = src->sadb_lifetime_allocations;
+		dst->bytes = src->sadb_lifetime_bytes;
+		dst->addtime = src->sadb_lifetime_addtime;
+		dst->usetime = src->sadb_lifetime_usetime;
+	}
+	return dst;
 }
 
 /* compare my own address
@@ -3948,6 +4002,7 @@
 		    satosin6(sa1)->sin6_port != satosin6(sa2)->sin6_port) {
 			return 1;
 		}
+		break;
 	default:
 		if (bcmp(sa1, sa2, sa1->sa_len) != 0)
 			return 1;
@@ -4071,13 +4126,13 @@
 			}
 
 			/* check SOFT lifetime */
-			if (sav->lft_s->sadb_lifetime_addtime != 0 &&
-			    now - sav->created > sav->lft_s->sadb_lifetime_addtime) {
+			if (sav->lft_s->addtime != 0 &&
+			    now - sav->created > sav->lft_s->addtime) {
 				/*
 				 * check SA to be used whether or not.
 				 * when SA hasn't been used, delete it.
 				 */
-				if (sav->lft_c->sadb_lifetime_usetime == 0) {
+				if (sav->lft_c->usetime == 0) {
 					key_sa_chgstate(sav, SADB_SASTATE_DEAD);
 					KEY_FREESAV(&sav);
 				} else {
@@ -4096,8 +4151,8 @@
 			 * 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->bytes != 0 &&
+			    sav->lft_s->bytes < sav->lft_c->bytes) {
 
 				key_sa_chgstate(sav, SADB_SASTATE_DYING);
 				/*
@@ -4122,15 +4177,15 @@
 				continue;
 			}
 
-			if (sav->lft_h->sadb_lifetime_addtime != 0 &&
-			    now - sav->created > sav->lft_h->sadb_lifetime_addtime) {
+			if (sav->lft_h->addtime != 0 &&
+			    now - sav->created > sav->lft_h->addtime) {
 				key_sa_chgstate(sav, SADB_SASTATE_DEAD);
 				KEY_FREESAV(&sav);
 			}
 #if 0	/* XXX Should we keep to send expire message until HARD lifetime ? */
 			else if (sav->lft_s != NULL
-			      && sav->lft_s->sadb_lifetime_addtime != 0
-			      && now - sav->created > sav->lft_s->sadb_lifetime_addtime) {
+			      && sav->lft_s->addtime != 0
+			      && now - sav->created > sav->lft_s->addtime) {
 				/*
 				 * XXX: should be checked to be
 				 * installed the valid SA.
@@ -4144,8 +4199,8 @@
 			}
 #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->bytes != 0 &&
+			    sav->lft_h->bytes < sav->lft_c->bytes) {
 				key_sa_chgstate(sav, SADB_SASTATE_DEAD);
 				KEY_FREESAV(&sav);
 			}
@@ -4461,8 +4516,6 @@
 	/* create new sadb_msg to reply. */
 	len = PFKEY_ALIGN8(sizeof(struct sadb_msg)) +
 	    PFKEY_ALIGN8(sizeof(struct sadb_sa));
-	if (len > MCLBYTES)
-		return key_senderror(so, m, ENOBUFS);
 
 	MGETHDR(n, M_DONTWAIT, MT_DATA);
 	if (len > MHLEN) {
@@ -4776,7 +4829,7 @@
 		KEY_CHKSASTATE(state, sav->state, __func__);
 
 		if (sav->seq == seq) {
-			SA_ADDREF(sav);
+			sa_addref(sav);
 			KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
 				printf("DP %s cause refcnt++:%d SA:%p\n",
 					__func__, sav->refcnt, sav));
@@ -4977,20 +5030,23 @@
 	}
 
 	/* make structure */
-	sah->idents = malloc(idsrclen, M_IPSEC_MISC, M_NOWAIT);
+	sah->idents = malloc(sizeof(struct secident), M_IPSEC_MISC, M_NOWAIT);
 	if (sah->idents == NULL) {
 		ipseclog((LOG_DEBUG, "%s: No more memory.\n", __func__));
 		return ENOBUFS;
 	}
-	sah->identd = malloc(iddstlen, M_IPSEC_MISC, M_NOWAIT);
+	sah->identd = malloc(sizeof(struct secident), M_IPSEC_MISC, M_NOWAIT);
 	if (sah->identd == NULL) {
 		free(sah->idents, M_IPSEC_MISC);
 		sah->idents = NULL;
 		ipseclog((LOG_DEBUG, "%s: No more memory.\n", __func__));
 		return ENOBUFS;
 	}
-	bcopy(idsrc, sah->idents, idsrclen);
-	bcopy(iddst, sah->identd, iddstlen);
+	sah->idents->type = idsrc->sadb_ident_type;
+	sah->idents->id = idsrc->sadb_ident_id;
+
+	sah->identd->type = iddst->sadb_ident_type;
+	sah->identd->id = iddst->sadb_ident_id;
 
 	return 0;
 }
@@ -6262,10 +6318,10 @@
 	lt = mtod(m, struct sadb_lifetime *);
 	lt->sadb_lifetime_len = PFKEY_UNIT64(sizeof(struct sadb_lifetime));
 	lt->sadb_lifetime_exttype = SADB_EXT_LIFETIME_CURRENT;
-	lt->sadb_lifetime_allocations = sav->lft_c->sadb_lifetime_allocations;
-	lt->sadb_lifetime_bytes = sav->lft_c->sadb_lifetime_bytes;
-	lt->sadb_lifetime_addtime = sav->lft_c->sadb_lifetime_addtime;
-	lt->sadb_lifetime_usetime = sav->lft_c->sadb_lifetime_usetime;
+	lt->sadb_lifetime_allocations = sav->lft_c->allocations;
+	lt->sadb_lifetime_bytes = sav->lft_c->bytes;
+	lt->sadb_lifetime_addtime = sav->lft_c->addtime;
+	lt->sadb_lifetime_usetime = sav->lft_c->usetime;
 	lt = (struct sadb_lifetime *)(mtod(m, caddr_t) + len / 2);
 	bcopy(sav->lft_s, lt, sizeof(*lt));
 	m_cat(result, m);
@@ -7103,21 +7159,21 @@
 	 * XXX Currently, there is a difference of bytes size
 	 * between inbound and outbound processing.
 	 */
-	sav->lft_c->sadb_lifetime_bytes += m->m_pkthdr.len;
+	sav->lft_c->bytes += m->m_pkthdr.len;
 	/* to check bytes lifetime is done in key_timehandler(). */
 
 	/*
 	 * We use the number of packets as the unit of
-	 * sadb_lifetime_allocations.  We increment the variable
+	 * allocations.  We increment the variable
 	 * whenever {esp,ah}_{in,out}put is called.
 	 */
-	sav->lft_c->sadb_lifetime_allocations++;
+	sav->lft_c->allocations++;
 	/* XXX check for expires? */
 
 	/*
-	 * NOTE: We record CURRENT sadb_lifetime_usetime by using wall clock,
+	 * NOTE: We record CURRENT usetime by using wall clock,
 	 * in seconds.  HARD and SOFT lifetime are measured by the time
-	 * difference (again in seconds) from sadb_lifetime_usetime.
+	 * difference (again in seconds) from usetime.
 	 *
 	 *	usetime
 	 *	v     expire   expire
@@ -7125,7 +7181,7 @@
 	 *	<--------------> HARD
 	 *	<-----> SOFT
 	 */
-	sav->lft_c->sadb_lifetime_usetime = time_second;
+	sav->lft_c->usetime = time_second;
 	/* XXX check for expires? */
 
 	return;
@@ -7214,3 +7270,81 @@
 
 	return m;
 }
+
+/*
+ * Take one of the kernel's security keys and convert it into a PF_KEY
+ * structure within an mbuf, suitable for sending up to a waiting
+ * application in user land.
+ * 
+ * IN: 
+ *    src: A pointer to a kernel security key.
+ *    exttype: Which type of key this is. Refer to the PF_KEY data structures.
+ * OUT:
+ *    a valid mbuf or NULL indicating an error
+ *
+ */
+
+static struct mbuf *
+key_setkey(struct seckey *src, u_int16_t exttype) 
+{
+	struct mbuf *m;
+	struct sadb_key *p;
+	int len;
+
+	if (src == NULL)
+		return NULL;
+
+	len = PFKEY_ALIGN8(sizeof(struct sadb_key) + _KEYLEN(src));
+	m = key_alloc_mbuf(len);
+	if (m == NULL)
+		return NULL;
+	p = mtod(m, struct sadb_key *);
+	bzero(p, len);
+	p->sadb_key_len = PFKEY_UNIT64(len);
+	p->sadb_key_exttype = exttype;
+	p->sadb_key_bits = src->bits;
+	bcopy(src->key_data, _KEYBUF(p), _KEYLEN(src));
+
+	return m;
+}
+
+/*
+ * Take one of the kernel's lifetime data structures and convert it
+ * into a PF_KEY structure within an mbuf, suitable for sending up to
+ * a waiting application in user land.
+ * 
+ * IN: 
+ *    src: A pointer to a kernel lifetime structure.
+ *    exttype: Which type of lifetime this is. Refer to the PF_KEY 
+ *             data structures for more information.
+ * OUT:
+ *    a valid mbuf or NULL indicating an error
+ *
+ */
+
+static struct mbuf *
+key_setlifetime(struct seclifetime *src, u_int16_t exttype)
+{
+	struct mbuf *m = NULL;
+	struct sadb_lifetime *p;
+	int len = PFKEY_ALIGN8(sizeof(struct sadb_lifetime));
+
+	if (src == NULL)
+		return NULL;
+
+	m = key_alloc_mbuf(len);
+	if (m == NULL)
+		return m;
+	p = mtod(m, struct sadb_lifetime *);
+
+	bzero(p, len);
+	p->sadb_lifetime_len = PFKEY_UNIT64(len);
+	p->sadb_lifetime_exttype = exttype;
+	p->sadb_lifetime_allocations = src->allocations;
+	p->sadb_lifetime_bytes = src->bytes;
+	p->sadb_lifetime_addtime = src->addtime;
+	p->sadb_lifetime_usetime = src->usetime;
+	
+	return m;
+
+}
Index: ipsec_input.c
===================================================================
RCS file: /home/cvs/src/sys/netipsec/ipsec_input.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/netipsec/ipsec_input.c -L sys/netipsec/ipsec_input.c -u -r1.1.1.1 -r1.2
--- sys/netipsec/ipsec_input.c
+++ sys/netipsec/ipsec_input.c
@@ -1,4 +1,4 @@
-/*	$FreeBSD: src/sys/netipsec/ipsec_input.c,v 1.9 2005/01/07 01:45:46 imp Exp $	*/
+/*	$FreeBSD: src/sys/netipsec/ipsec_input.c,v 1.19 2007/09/12 05:54:53 gnn Exp $	*/
 /*	$OpenBSD: ipsec_input.c,v 1.63 2003/02/20 18:35:43 deraadt Exp $	*/
 /*-
  * The authors of this code are John Ioannidis (ji at tla.org),
@@ -43,6 +43,7 @@
 #include "opt_inet.h"
 #include "opt_inet6.h"
 #include "opt_ipsec.h"
+#include "opt_enc.h"
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -55,6 +56,7 @@
 #include <sys/syslog.h>
 
 #include <net/if.h>
+#include <net/pfil.h>
 #include <net/route.h>
 #include <net/netisr.h>
 
@@ -99,7 +101,7 @@
 /*
  * ipsec_common_input gets called when an IPsec-protected packet
  * is received by IPv4 or IPv6.  It's job is to find the right SA
- # and call the appropriate transform.  The transform callback
+ * and call the appropriate transform.  The transform callback
  * takes care of further processing (like ingress filtering).
  */
 static int
@@ -115,6 +117,10 @@
 
 	IPSEC_ASSERT(m != NULL, ("null packet"));
 
+	IPSEC_ASSERT(sproto == IPPROTO_ESP || sproto == IPPROTO_AH ||
+		sproto == IPPROTO_IPCOMP,
+		("unexpected security protocol %u", sproto));
+
 	if ((sproto == IPPROTO_ESP && !esp_enable) ||
 	    (sproto == IPPROTO_AH && !ah_enable) ||
 	    (sproto == IPPROTO_IPCOMP && !ipcomp_enable)) {
@@ -276,6 +282,11 @@
 	struct tdb_ident *tdbi;
 	struct secasindex *saidx;
 	int error;
+#ifdef INET6
+#ifdef notyet
+	char ip6buf[INET6_ADDRSTRLEN];
+#endif
+#endif
 
 	IPSEC_SPLASSERT_SOFTNET(__func__);
 
@@ -321,6 +332,7 @@
 	}
 	prot = ip->ip_p;
 
+#ifdef notyet
 	/* IP-in-IP encapsulation */
 	if (prot == IPPROTO_IPIP) {
 		struct ip ipn;
@@ -336,7 +348,6 @@
 		m_copydata(m, ip->ip_hl << 2, sizeof(struct ip),
 		    (caddr_t) &ipn);
 
-#ifdef notyet
 		/* XXX PROXY address isn't recorded in SAH */
 		/*
 		 * Check that the inner source address is the same as
@@ -364,9 +375,8 @@
 			error = EACCES;
 			goto bad;
 		}
-#endif /*XXX*/
 	}
-#if INET6
+#ifdef INET6
 	/* IPv6-in-IP encapsulation. */
 	if (prot == IPPROTO_IPV6) {
 		struct ip6_hdr ip6n;
@@ -382,7 +392,6 @@
 		m_copydata(m, ip->ip_hl << 2, sizeof(struct ip6_hdr),
 		    (caddr_t) &ip6n);
 
-#ifdef notyet
 		/*
 		 * Check that the inner source address is the same as
 		 * the proxy address, if available.
@@ -397,7 +406,7 @@
 			DPRINTF(("%s: inner source address %s doesn't "
 			    "correspond to expected proxy source %s, "
 			    "SA %s/%08lx\n", __func__,
-			    ip6_sprintf(&ip6n.ip6_src),
+			    ip6_sprintf(ip6buf, &ip6n.ip6_src),
 			    ipsec_address(&saidx->proxy),
 			    ipsec_address(&saidx->dst),
 			    (u_long) ntohl(sav->spi)));
@@ -408,9 +417,9 @@
 			error = EACCES;
 			goto bad;
 		}
-#endif /*XXX*/
 	}
 #endif /* INET6 */
+#endif /*XXX*/
 
 	/*
 	 * Record what we've done to the packet (under what SA it was
@@ -437,13 +446,25 @@
 		tdbi->spi = sav->spi;
 
 		m_tag_prepend(m, mtag);
-	} else {
+	} else if (mt != NULL) {
 		mt->m_tag_id = PACKET_TAG_IPSEC_IN_DONE;
 		/* XXX do we need to mark m_flags??? */
 	}
 
 	key_sa_recordxfer(sav, m);		/* record data transfer */
 
+#ifdef DEV_ENC
+	/*
+	 * Pass the mbuf to enc0 for bpf and pfil. We will filter the IPIP
+	 * packet later after it has been decapsulated.
+	 */
+	ipsec_bpf(m, sav, AF_INET);
+
+	if (prot != IPPROTO_IPIP)
+		if ((error = ipsec_filter(&m, PFIL_IN)) != 0)
+			return (error);
+#endif
+
 	/*
 	 * Re-dispatch via software interrupt.
 	 */
@@ -531,6 +552,9 @@
 	int nxt;
 	u_int8_t nxt8;
 	int error, nest;
+#ifdef notyet
+	char ip6buf[INET6_ADDRSTRLEN];
+#endif
 
 	IPSEC_ASSERT(m != NULL, ("null mbuf"));
 	IPSEC_ASSERT(sav != NULL, ("null SA"));
@@ -572,6 +596,7 @@
 	/* Save protocol */
 	m_copydata(m, protoff, 1, (unsigned char *) &prot);
 
+#ifdef notyet
 #ifdef INET
 	/* IP-in-IP encapsulation */
 	if (prot == IPPROTO_IPIP) {
@@ -587,7 +612,6 @@
 		/* ipn will now contain the inner IPv4 header */
 		m_copydata(m, skip, sizeof(struct ip), (caddr_t) &ipn);
 
-#ifdef notyet
 		/*
 		 * Check that the inner source address is the same as
 		 * the proxy address, if available.
@@ -611,7 +635,6 @@
 			error = EACCES;
 			goto bad;
 		}
-#endif /*XXX*/
 	}
 #endif /* INET */
 
@@ -630,7 +653,6 @@
 		m_copydata(m, skip, sizeof(struct ip6_hdr),
 		    (caddr_t) &ip6n);
 
-#ifdef notyet
 		/*
 		 * Check that the inner source address is the same as
 		 * the proxy address, if available.
@@ -645,7 +667,7 @@
 			DPRINTF(("%s: inner source address %s doesn't "
 			    "correspond to expected proxy source %s, "
 			    "SA %s/%08lx\n", __func__,
-			    ip6_sprintf(&ip6n.ip6_src),
+			    ip6_sprintf(ip6buf, &ip6n.ip6_src),
 			    ipsec_address(&saidx->proxy),
 			    ipsec_address(&saidx->dst),
 			    (u_long) ntohl(sav->spi)));
@@ -655,8 +677,8 @@
 			error = EACCES;
 			goto bad;
 		}
-#endif /*XXX*/
 	}
+#endif /*XXX*/
 
 	/*
 	 * Record what we've done to the packet (under what SA it was
@@ -739,6 +761,11 @@
 void
 esp6_ctlinput(int cmd, struct sockaddr *sa, void *d)
 {
+	struct ip6ctlparam *ip6cp = NULL;
+	struct mbuf *m = NULL;
+	struct ip6_hdr *ip6;
+	int off;
+
 	if (sa->sa_family != AF_INET6 ||
 	    sa->sa_len != sizeof(struct sockaddr_in6))
 		return;
@@ -746,10 +773,18 @@
 		return;
 
 	/* if the parameter is from icmp6, decode it. */
-	if (d !=  NULL) {
-		struct ip6ctlparam *ip6cp = (struct ip6ctlparam *)d;
-		struct mbuf *m = ip6cp->ip6c_m;
-		int off = ip6cp->ip6c_off;
+	if (d != NULL) {
+		ip6cp = (struct ip6ctlparam *)d;
+		m = ip6cp->ip6c_m;
+		ip6 = ip6cp->ip6c_ip6;
+		off = ip6cp->ip6c_off;
+	} else {
+		m = NULL;
+		ip6 = NULL;
+		off = 0;	/* calm gcc */
+	}
+
+	if (ip6 != NULL) {
 
 		struct ip6ctlparam ip6cp1;
 
Index: xform_ipip.c
===================================================================
RCS file: /home/cvs/src/sys/netipsec/xform_ipip.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -L sys/netipsec/xform_ipip.c -L sys/netipsec/xform_ipip.c -u -r1.2 -r1.3
--- sys/netipsec/xform_ipip.c
+++ sys/netipsec/xform_ipip.c
@@ -1,4 +1,4 @@
-/*	$FreeBSD: src/sys/netipsec/xform_ipip.c,v 1.11.2.1 2006/04/01 15:22:44 bz Exp $	*/
+/*	$FreeBSD: src/sys/netipsec/xform_ipip.c,v 1.15 2007/07/19 09:57:54 bz Exp $	*/
 /*	$OpenBSD: ip_ipip.c,v 1.25 2002/06/10 18:04:55 itojun Exp $ */
 /*-
  * The authors of this code are John Ioannidis (ji at tla.org),
@@ -41,6 +41,7 @@
  */
 #include "opt_inet.h"
 #include "opt_inet6.h"
+#include "opt_enc.h"
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -51,6 +52,7 @@
 #include <sys/sysctl.h>
 
 #include <net/if.h>
+#include <net/pfil.h>
 #include <net/route.h>
 #include <net/netisr.h>
 
@@ -345,6 +347,12 @@
 	/* Statistics */
 	ipipstat.ipips_ibytes += m->m_pkthdr.len - iphlen;
 
+#ifdef DEV_ENC
+	/* pass the mbuf to enc0 for packet filtering */
+	if (ipsec_filter(&m, PFIL_IN) != 0)
+		return;
+#endif
+
 	/*
 	 * Interface pointer stays the same; if no IPsec processing has
 	 * been done (or will be done), this will point to a normal
@@ -599,7 +607,7 @@
 	return (error);
 }
 
-#ifdef FAST_IPSEC
+#ifdef IPSEC
 static int
 ipe4_init(struct secasvar *sav, struct xformsw *xsp)
 {
@@ -678,4 +686,4 @@
 #endif
 }
 SYSINIT(ipe4_xform_init, SI_SUB_PROTO_DOMAIN, SI_ORDER_MIDDLE, ipe4_attach, NULL);
-#endif	/* FAST_IPSEC */
+#endif	/* IPSEC */
Index: ipsec.c
===================================================================
RCS file: /home/cvs/src/sys/netipsec/ipsec.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/netipsec/ipsec.c -L sys/netipsec/ipsec.c -u -r1.1.1.1 -r1.2
--- sys/netipsec/ipsec.c
+++ sys/netipsec/ipsec.c
@@ -1,4 +1,4 @@
-/*	$FreeBSD: src/sys/netipsec/ipsec.c,v 1.12 2005/06/02 23:56:10 hmp Exp $	*/
+/*	$FreeBSD: src/sys/netipsec/ipsec.c,v 1.24 2007/07/01 11:38:29 gnn Exp $	*/
 /*	$KAME: ipsec.c,v 1.103 2001/05/24 07:14:18 sakane Exp $	*/
 
 /*-
@@ -43,6 +43,7 @@
 #include <sys/malloc.h>
 #include <sys/mbuf.h>
 #include <sys/domain.h>
+#include <sys/priv.h>
 #include <sys/protosw.h>
 #include <sys/socket.h>
 #include <sys/socketvar.h>
@@ -75,6 +76,7 @@
 #include <netinet/icmp6.h>
 #endif
 
+#include <sys/types.h>
 #include <netipsec/ipsec.h>
 #ifdef INET6
 #include <netipsec/ipsec6.h>
@@ -92,6 +94,8 @@
 
 #include <machine/in_cksum.h>
 
+#include <opencrypto/cryptodev.h>
+
 #ifdef IPSEC_DEBUG
 int ipsec_debug = 1;
 #else
@@ -99,7 +103,7 @@
 #endif
 
 /* NB: name changed so netstat doesn't use it */
-struct newipsecstat newipsecstat;
+struct ipsecstat ipsec4stat;
 int ip4_ah_offsetmask = 0;	/* maybe IP_DF? */
 int ip4_ipsec_dfbit = 0;	/* DF bit on encap. 0: clear 1: set 2: copy */
 int ip4_esp_trans_deflev = IPSEC_LEVEL_USE;
@@ -116,7 +120,7 @@
  * -1	require software support
  *  0	take anything
  */
-int	crypto_support = 0;
+int	crypto_support = CRYPTOCAP_F_HARDWARE | CRYPTOCAP_F_SOFTWARE;
 
 SYSCTL_DECL(_net_inet_ipsec);
 
@@ -146,9 +150,27 @@
 SYSCTL_INT(_net_inet_ipsec, OID_AUTO,
 	crypto_support,	CTLFLAG_RW,	&crypto_support,0, "");
 SYSCTL_STRUCT(_net_inet_ipsec, OID_AUTO,
-	ipsecstats,	CTLFLAG_RD,	&newipsecstat,	newipsecstat, "");
+	ipsecstats,	CTLFLAG_RD,	&ipsec4stat, ipsecstat, "");
 
-#ifdef INET6
+#ifdef REGRESSION
+/*
+ * When set to 1, IPsec will send packets with the same sequence number.
+ * This allows to verify if the other side has proper replay attacks detection.
+ */
+int ipsec_replay = 0;
+SYSCTL_INT(_net_inet_ipsec, OID_AUTO, test_replay, CTLFLAG_RW, &ipsec_replay, 0,
+    "Emulate replay attack");
+/*
+ * When set 1, IPsec will send packets with corrupted HMAC.
+ * This allows to verify if the other side properly detects modified packets.
+ */
+int ipsec_integrity = 0;
+SYSCTL_INT(_net_inet_ipsec, OID_AUTO, test_integrity, CTLFLAG_RW,
+    &ipsec_integrity, 0, "Emulate man-in-the-middle attack");
+#endif
+
+#ifdef INET6 
+struct ipsecstat ipsec6stat;
 int ip6_esp_trans_deflev = IPSEC_LEVEL_USE;
 int ip6_esp_net_deflev = IPSEC_LEVEL_USE;
 int ip6_ah_trans_deflev = IPSEC_LEVEL_USE;
@@ -179,6 +201,8 @@
 	debug, CTLFLAG_RW,	&ipsec_debug,	0, "");
 SYSCTL_INT(_net_inet6_ipsec6, IPSECCTL_ESP_RANDPAD,
 	esp_randpad, CTLFLAG_RW,	&ip6_esp_randpad,	0, "");
+SYSCTL_STRUCT(_net_inet6_ipsec6, IPSECCTL_STATS,
+	ipsecstats, CTLFLAG_RD, &ipsec6stat, ipsecstat, "");
 #endif /* INET6 */
 
 static int ipsec4_setspidx_inpcb __P((struct mbuf *, struct inpcb *pcb));
@@ -431,7 +455,7 @@
 		sp = ipsec_getpolicybysock(m, dir, inp, error);
 	if (sp == NULL) {
 		IPSEC_ASSERT(*error != 0, ("getpolicy failed w/o error"));
-		newipsecstat.ips_out_inval++;
+		ipsec4stat.ips_out_inval++;
 		return NULL;
 	}
 	IPSEC_ASSERT(*error == 0, ("sp w/ error set to %u", *error));
@@ -441,7 +465,7 @@
 		printf("%s: invalid policy %u\n", __func__, sp->policy);
 		/* fall thru... */
 	case IPSEC_POLICY_DISCARD:
-		newipsecstat.ips_out_polvio++;
+		ipsec4stat.ips_out_polvio++;
 		*error = -EINVAL;	/* packet is discarded by caller */
 		break;
 	case IPSEC_POLICY_BYPASS:
@@ -732,6 +756,7 @@
 	int off, nxt;
 	struct tcphdr th;
 	struct udphdr uh;
+	struct icmp6_hdr ih;
 
 	/* sanity check */
 	if (m == NULL)
@@ -772,6 +797,15 @@
 		((struct sockaddr_in6 *)&spidx->dst)->sin6_port = uh.uh_dport;
 		break;
 	case IPPROTO_ICMPV6:
+		spidx->ul_proto = nxt;
+		if (off + sizeof(struct icmp6_hdr) > m->m_pkthdr.len)
+			break;
+		m_copydata(m, off, sizeof(ih), (caddr_t)&ih);
+		((struct sockaddr_in6 *)&spidx->src)->sin6_port =
+		    htons((uint16_t)ih.icmp6_type);
+		((struct sockaddr_in6 *)&spidx->dst)->sin6_port =
+		    htons((uint16_t)ih.icmp6_code);
+		break;
 	default:
 		/* XXX intermediate headers??? */
 		spidx->ul_proto = nxt;
@@ -1432,7 +1466,7 @@
 	if (sp != NULL) {
 		result = ipsec_in_reject(sp, m);
 		if (result)
-			newipsecstat.ips_in_polvio++;
+			ipsec4stat.ips_in_polvio++;
 		KEY_FREESP(&sp);
 	} else {
 		result = 0;	/* XXX should be panic ?
@@ -1472,7 +1506,7 @@
 	if (sp != NULL) {
 		result = ipsec_in_reject(sp, m);
 		if (result)
-			newipsecstat.ips_in_polvio++;
+			ipsec6stat.ips_in_polvio++;
 		KEY_FREESP(&sp);
 	} else {
 		result = 0;
@@ -1814,6 +1848,7 @@
 	unsigned char *ucp = (unsigned char *) &ina;
 	static int i = 3;
 
+	/* XXX-BZ returns static buffer. */
 	i = (i + 1) % 4;
 	sprintf(buf[i], "%d.%d.%d.%d", ucp[0] & 0xff, ucp[1] & 0xff,
 	    ucp[2] & 0xff, ucp[3] & 0xff);
@@ -1824,15 +1859,18 @@
 char *
 ipsec_address(union sockaddr_union* sa)
 {
+#ifdef INET6
+	char ip6buf[INET6_ADDRSTRLEN];
+#endif
 	switch (sa->sa.sa_family) {
-#if INET
+#ifdef INET
 	case AF_INET:
 		return inet_ntoa4(sa->sin.sin_addr);
 #endif /* INET */
 
-#if INET6
+#ifdef INET6
 	case AF_INET6:
-		return ip6_sprintf(&sa->sin6.sin6_addr);
+		return ip6_sprintf(ip6buf, &sa->sin6.sin6_addr);
 #endif /* INET6 */
 
 	default:
Index: ipsec6.h
===================================================================
RCS file: /home/cvs/src/sys/netipsec/ipsec6.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/netipsec/ipsec6.h -L sys/netipsec/ipsec6.h -u -r1.1.1.1 -r1.2
--- sys/netipsec/ipsec6.h
+++ sys/netipsec/ipsec6.h
@@ -1,4 +1,4 @@
-/*	$FreeBSD: src/sys/netipsec/ipsec6.h,v 1.2 2005/01/07 01:45:46 imp Exp $	*/
+/*	$FreeBSD: src/sys/netipsec/ipsec6.h,v 1.3 2007/07/01 11:38:29 gnn Exp $	*/
 /*	$KAME: ipsec.h,v 1.44 2001/03/23 08:08:47 itojun Exp $	*/
 
 /*-
@@ -41,6 +41,7 @@
 #include <netipsec/keydb.h>
 
 #ifdef _KERNEL
+extern struct ipsecstat ipsec6stat;
 extern int ip6_esp_trans_deflev;
 extern int ip6_esp_net_deflev;
 extern int ip6_ah_trans_deflev;
@@ -50,15 +51,6 @@
 
 struct inpcb;
 
-/* KAME compatibility shims */
-#define	ipsec6_getpolicybyaddr	ipsec_getpolicybyaddr
-#define	ipsec6_getpolicybysock	ipsec_getpolicybysock
-#define	ipsec6stat		newipsecstat
-#define	out_inval		ips_out_inval
-#define	in_polvio		ips_in_polvio
-#define	out_polvio		ips_out_polvio
-#define	key_freesp(_x)		KEY_FREESP(&_x)
-
 extern int ipsec6_delete_pcbpolicy __P((struct inpcb *));
 extern int ipsec6_set_policy __P((struct inpcb *inp, int optname,
 	caddr_t request, size_t len, int priv));
Index: key_debug.c
===================================================================
RCS file: /home/cvs/src/sys/netipsec/key_debug.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/netipsec/key_debug.c -L sys/netipsec/key_debug.c -u -r1.1.1.1 -r1.2
--- sys/netipsec/key_debug.c
+++ sys/netipsec/key_debug.c
@@ -1,4 +1,4 @@
-/*	$FreeBSD: src/sys/netipsec/key_debug.c,v 1.3 2005/01/07 01:45:46 imp Exp $	*/
+/*	$FreeBSD: src/sys/netipsec/key_debug.c,v 1.5 2007/07/01 11:38:29 gnn Exp $	*/
 /*	$KAME: key_debug.c,v 1.26 2001/06/27 10:46:50 sakane Exp $	*/
 
 /*-
@@ -73,7 +73,7 @@
 #endif
 
 #ifndef _KERNEL
-#define panic(param)	{ printf(param); exit(-1); }
+#define panic(fmt, ...)	{ printf(fmt, ## __VA_ARGS__); exit(-1); }
 #endif
 
 /* NOTE: host byte order */
@@ -588,7 +588,7 @@
 	if (sav->lft_s != NULL)
 		kdebug_sadb_lifetime((struct sadb_ext *)sav->lft_s);
 
-#if notyet
+#ifdef notyet
 	/* XXX: misc[123] ? */
 #endif
 
Index: xform_ah.c
===================================================================
RCS file: /home/cvs/src/sys/netipsec/xform_ah.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -L sys/netipsec/xform_ah.c -L sys/netipsec/xform_ah.c -u -r1.2 -r1.3
--- sys/netipsec/xform_ah.c
+++ sys/netipsec/xform_ah.c
@@ -1,4 +1,4 @@
-/*	$FreeBSD: src/sys/netipsec/xform_ah.c,v 1.7.2.1 2006/03/23 23:24:33 sam Exp $	*/
+/*	$FreeBSD: src/sys/netipsec/xform_ah.c,v 1.15 2007/08/06 14:26:02 rwatson Exp $	*/
 /*	$OpenBSD: ip_ah.c,v 1.63 2001/06/26 06:18:58 angelos Exp $ */
 /*-
  * The authors of this code are John Ioannidis (ji at tla.org),
@@ -81,11 +81,11 @@
 		sizeof (struct ah) : sizeof (struct ah) + sizeof (u_int32_t))
 /* 
  * Return authenticator size in bytes.  The old protocol is known
- * to use a fixed 16-byte authenticator.  The new algorithm gets
- * this size from the xform but is (currently) always 12.
+ * to use a fixed 16-byte authenticator.  The new algorithm use 12-byte
+ * authenticator.
  */
 #define	AUTHSIZE(sav) \
-	((sav->flags & SADB_X_EXT_OLD) ? 16 : (sav)->tdb_authalgxform->authsize)
+	((sav->flags & SADB_X_EXT_OLD) ? 16 : AH_HMAC_HASHLEN)
 
 int	ah_enable = 1;			/* control flow of packets with AH */
 int	ah_cleartos = 1;		/* clear ip_tos when doing AH calc */
@@ -110,17 +110,17 @@
 struct auth_hash *
 ah_algorithm_lookup(int alg)
 {
-	if (alg >= AH_ALG_MAX)
+	if (alg > SADB_AALG_MAX)
 		return NULL;
 	switch (alg) {
 	case SADB_X_AALG_NULL:
 		return &auth_hash_null;
 	case SADB_AALG_MD5HMAC:
-		return &auth_hash_hmac_md5_96;
+		return &auth_hash_hmac_md5;
 	case SADB_AALG_SHA1HMAC:
-		return &auth_hash_hmac_sha1_96;
+		return &auth_hash_hmac_sha1;
 	case SADB_X_AALG_RIPEMD160HMAC:
-		return &auth_hash_hmac_ripemd_160_96;
+		return &auth_hash_hmac_ripemd_160;
 	case SADB_X_AALG_MD5:
 		return &auth_hash_key_md5;
 	case SADB_X_AALG_SHA:
@@ -201,7 +201,8 @@
 	bzero(cria, sizeof (*cria));
 	cria->cri_alg = sav->tdb_authalgxform->type;
 	cria->cri_klen = _KEYBITS(sav->key_auth);
-	cria->cri_key = _KEYBUF(sav->key_auth);
+	cria->cri_key = sav->key_auth->key_data;
+	cria->cri_mlen = AUTHSIZE(sav);
 
 	return 0;
 }
@@ -231,7 +232,7 @@
 	int err;
 
 	if (sav->key_auth)
-		bzero(_KEYBUF(sav->key_auth), _KEYLEN(sav->key_auth));
+		bzero(sav->key_auth->key_data, _KEYLEN(sav->key_auth));
 
 	err = crypto_freesession(sav->tdb_cryptoid);
 	sav->tdb_cryptoid = 0;
@@ -622,8 +623,8 @@
 
 	/* Authentication operation. */
 	crda->crd_alg = ahx->type;
-	crda->crd_key = _KEYBUF(sav->key_auth);
 	crda->crd_klen = _KEYBITS(sav->key_auth);
+	crda->crd_key = sav->key_auth->key_data;
 
 	/* Find out if we've already done crypto. */
 	for (mtag = m_tag_find(m, PACKET_TAG_IPSEC_IN_CRYPTO_DONE, NULL);
@@ -764,8 +765,10 @@
 		if (sav->tdb_cryptoid != 0)
 			sav->tdb_cryptoid = crp->crp_sid;
 
-		if (crp->crp_etype == EAGAIN)
-			return crypto_dispatch(crp);
+		if (crp->crp_etype == EAGAIN) {
+			error = crypto_dispatch(crp);
+			return error;
+		}
 
 		ahstat.ahs_noxform++;
 		DPRINTF(("%s: crypto error %d\n", __func__, crp->crp_etype));
@@ -857,7 +860,6 @@
 	IPSEC_COMMON_INPUT_CB(m, sav, skip, protoff, mtag);
 
 	KEY_FREESAV(&sav);
-
 	return error;
 bad:
 	if (sav)
@@ -992,7 +994,11 @@
 			error = EINVAL;
 			goto bad;
 		}
-		sav->replay->count++;
+#ifdef REGRESSION
+		/* Emulate replay attack when ipsec_replay is TRUE. */
+		if (!ipsec_replay)
+#endif
+			sav->replay->count++;
 		ah->ah_seq = htonl(sav->replay->count);
 	}
 
@@ -1014,7 +1020,7 @@
 
 	/* Authentication operation. */
 	crda->crd_alg = ahx->type;
-	crda->crd_key = _KEYBUF(sav->key_auth);
+	crda->crd_key = sav->key_auth->key_data;
 	crda->crd_klen = _KEYBITS(sav->key_auth);
 
 	/* Allocate IPsec-specific opaque crypto info. */
@@ -1140,7 +1146,8 @@
 		if (crp->crp_etype == EAGAIN) {
 			KEY_FREESAV(&sav);
 			IPSECREQUEST_UNLOCK(isr);
-			return crypto_dispatch(crp);
+			error = crypto_dispatch(crp);
+			return error;
 		}
 
 		ahstat.ahs_noxform++;
@@ -1168,11 +1175,24 @@
 	free(tc, M_XDATA);
 	crypto_freereq(crp);
 
+#ifdef REGRESSION
+	/* Emulate man-in-the-middle attack when ipsec_integrity is TRUE. */
+	if (ipsec_integrity) {
+		int alen;
+
+		/*
+		 * Corrupt HMAC if we want to test integrity verification of
+		 * the other side.
+		 */
+		alen = AUTHSIZE(sav);
+		m_copyback(m, m->m_pkthdr.len - alen, alen, ipseczeroes);
+	}
+#endif
+
 	/* NB: m is reclaimed by ipsec_process_done. */
 	err = ipsec_process_done(m, isr);
 	KEY_FREESAV(&sav);
 	IPSECREQUEST_UNLOCK(isr);
-
 	return err;
 bad:
 	if (sav)
Index: ipsec_mbuf.c
===================================================================
RCS file: /home/cvs/src/sys/netipsec/ipsec_mbuf.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -L sys/netipsec/ipsec_mbuf.c -L sys/netipsec/ipsec_mbuf.c -u -r1.2 -r1.3
--- sys/netipsec/ipsec_mbuf.c
+++ sys/netipsec/ipsec_mbuf.c
@@ -23,7 +23,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/sys/netipsec/ipsec_mbuf.c,v 1.10.8.1 2006/03/23 23:24:32 sam Exp $
+ * $FreeBSD: src/sys/netipsec/ipsec_mbuf.c,v 1.13 2007/07/01 11:38:29 gnn Exp $
  */
 
 /*
@@ -88,7 +88,7 @@
 			return (NULL);
 		n->m_next = m->m_next;		/* splice new mbuf */
 		m->m_next = n;
-		newipsecstat.ips_mbinserted++;
+		ipsec4stat.ips_mbinserted++;
 		if (hlen <= M_TRAILINGSPACE(m) + remain) {
 			/*
 			 * New header fits in the old mbuf if we copy
@@ -122,7 +122,7 @@
 				/* splice in second mbuf */
 				n2->m_next = n->m_next;
 				n->m_next = n2;
-				newipsecstat.ips_mbinserted++;
+				ipsec4stat.ips_mbinserted++;
 			} else {
 				memcpy(mtod(n, caddr_t) + hlen,
 				       mtod(m, caddr_t) + skip, remain);
@@ -238,7 +238,7 @@
 	/* Remove the header and associated data from the mbuf. */
 	if (roff == 0) {
 		/* The header was at the beginning of the mbuf */
-		newipsecstat.ips_input_front++;
+		ipsec4stat.ips_input_front++;
 		m_adj(m1, hlen);
 		if ((m1->m_flags & M_PKTHDR) == 0)
 			m->m_pkthdr.len -= hlen;
@@ -250,7 +250,7 @@
 		 * so first let's remove the remainder of the header from
 		 * the beginning of the remainder of the mbuf chain, if any.
 		 */
-		newipsecstat.ips_input_end++;
+		ipsec4stat.ips_input_end++;
 		if (roff + hlen > m1->m_len) {
 			/* Adjust the next mbuf by the remainder */
 			m_adj(m1->m_next, roff + hlen - m1->m_len);
@@ -275,7 +275,7 @@
 		 * The header lies in the "middle" of the mbuf; copy
 		 * the remainder of the mbuf down over the header.
 		 */
-		newipsecstat.ips_input_middle++;
+		ipsec4stat.ips_input_middle++;
 		bcopy(mtod(m1, u_char *) + roff + hlen,
 		      mtod(m1, u_char *) + roff,
 		      m1->m_len - (roff + hlen));
Index: keysock.c
===================================================================
RCS file: /home/cvs/src/sys/netipsec/keysock.c,v
retrieving revision 1.1.1.2
retrieving revision 1.2
diff -L sys/netipsec/keysock.c -L sys/netipsec/keysock.c -u -r1.1.1.2 -r1.2
--- sys/netipsec/keysock.c
+++ sys/netipsec/keysock.c
@@ -1,4 +1,4 @@
-/*	$FreeBSD: src/sys/netipsec/keysock.c,v 1.10.2.2 2006/01/27 21:50:11 bz Exp $	*/
+/*	$FreeBSD: src/sys/netipsec/keysock.c,v 1.18.2.2 2007/11/20 09:35:15 bz Exp $	*/
 /*	$KAME: keysock.c,v 1.25 2001/08/13 20:07:41 itojun Exp $	*/
 
 /*-
@@ -43,6 +43,7 @@
 #include <sys/malloc.h>
 #include <sys/mbuf.h>
 #include <sys/mutex.h>
+#include <sys/priv.h>
 #include <sys/protosw.h>
 #include <sys/signalvar.h>
 #include <sys/socket.h>
@@ -81,7 +82,6 @@
 {
 	struct sadb_msg *msg;
 	int len, error = 0;
-	int s;
 
 	if (m == 0)
 		panic("%s: NULL pointer was passed.\n", __func__);
@@ -116,11 +116,8 @@
 		goto end;
 	}
 
-	/*XXX giant lock*/
-	s = splnet();
 	error = key_parse(m, so);
 	m = NULL;
-	splx(s);
 end:
 	if (m)
 		m_freem(m);
@@ -213,15 +210,19 @@
 	while (tlen > 0) {
 		if (tlen == len) {
 			MGETHDR(n, M_DONTWAIT, MT_DATA);
+			if (n == NULL) {
+				pfkeystat.in_nomem++;
+				return ENOBUFS;
+			}
 			n->m_len = MHLEN;
 		} else {
 			MGET(n, M_DONTWAIT, MT_DATA);
+			if (n == NULL) {
+				pfkeystat.in_nomem++;
+				return ENOBUFS;
+			}
 			n->m_len = MLEN;
 		}
-		if (!n) {
-			pfkeystat.in_nomem++;
-			return ENOBUFS;
-		}
 		if (tlen >= MCLBYTES) {	/*XXX better threshold? */
 			MCLGET(n, M_DONTWAIT);
 			if ((n->m_flags & M_EXT) == 0) {
@@ -278,22 +279,18 @@
 	pfkeystat.in_total++;
 	pfkeystat.in_bytes += m->m_pkthdr.len;
 	if (m->m_len < sizeof(struct sadb_msg)) {
-#if 1
 		m = m_pullup(m, sizeof(struct sadb_msg));
 		if (m == NULL) {
 			pfkeystat.in_nomem++;
 			return ENOBUFS;
 		}
-#else
-		/* don't bother pulling it up just for stats */
-#endif
 	}
 	if (m->m_len >= sizeof(struct sadb_msg)) {
 		struct sadb_msg *msg;
 		msg = mtod(m, struct sadb_msg *);
 		pfkeystat.in_msgtype[msg->sadb_msg_type]++;
 	}
-
+	mtx_lock(&rawcb_mtx);
 	LIST_FOREACH(rp, &rawcb_list, list)
 	{
 		if (rp->rcb_proto.sp_family != PF_KEY)
@@ -344,11 +341,13 @@
 		if ((n = m_copy(m, 0, (int)M_COPYALL)) == NULL) {
 			m_freem(m);
 			pfkeystat.in_nomem++;
+			mtx_unlock(&rawcb_mtx);
 			return ENOBUFS;
 		}
 
 		if ((error = key_sendup0(rp, n, 0)) != 0) {
 			m_freem(m);
+			mtx_unlock(&rawcb_mtx);
 			return error;
 		}
 
@@ -362,6 +361,7 @@
 		error = 0;
 		m_freem(m);
 	}
+	mtx_unlock(&rawcb_mtx);
 	return error;
 }
 
@@ -369,14 +369,10 @@
  * key_abort()
  * derived from net/rtsock.c:rts_abort()
  */
-static int
+static void
 key_abort(struct socket *so)
 {
-	int s, error;
-	s = splnet();
-	error = raw_usrreqs.pru_abort(so);
-	splx(s);
-	return error;
+	raw_usrreqs.pru_abort(so);
 }
 
 /*
@@ -387,29 +383,27 @@
 key_attach(struct socket *so, int proto, struct thread *td)
 {
 	struct keycb *kp;
-	int s, error;
+	int error;
+
+	KASSERT(so->so_pcb == NULL, ("key_attach: so_pcb != NULL"));
 
-	if (sotorawcb(so) != 0)
-		return EISCONN;	/* XXX panic? */
-	kp = (struct keycb *)malloc(sizeof *kp, M_PCB, M_WAITOK|M_ZERO); /* XXX */
+	if (td != NULL) {
+		error = priv_check(td, PRIV_NET_RAW);
+		if (error)
+			return error;
+	}
+
+	/* XXX */
+	MALLOC(kp, struct keycb *, sizeof *kp, M_PCB, M_WAITOK | M_ZERO); 
 	if (kp == 0)
 		return ENOBUFS;
 
-	/*
-	 * The splnet() is necessary to block protocols from sending
-	 * error notifications (like RTM_REDIRECT or RTM_LOSING) while
-	 * this PCB is extant but incompletely initialized.
-	 * Probably we should try to do more of this work beforehand and
-	 * eliminate the spl.
-	 */
-	s = splnet();
 	so->so_pcb = (caddr_t)kp;
-	error = raw_usrreqs.pru_attach(so, proto, td);
+	error = raw_attach(so, proto);
 	kp = (struct keycb *)sotorawcb(so);
 	if (error) {
 		free(kp, M_PCB);
 		so->so_pcb = (caddr_t) 0;
-		splx(s);
 		return error;
 	}
 
@@ -423,7 +417,6 @@
 	soisconnected(so);
 	so->so_options |= SO_USELOOPBACK;
 
-	splx(s);
 	return 0;
 }
 
@@ -434,11 +427,18 @@
 static int
 key_bind(struct socket *so, struct sockaddr *nam, struct thread *td)
 {
-	int s, error;
-	s = splnet();
-	error = raw_usrreqs.pru_bind(so, nam, td); /* xxx just EINVAL */
-	splx(s);
-	return error;
+  return EINVAL;
+}
+
+/*
+ * key_close()
+ * derived from net/rtsock.c:rts_close().
+ */
+static void
+key_close(struct socket *so)
+{
+
+	raw_usrreqs.pru_close(so);
 }
 
 /*
@@ -448,35 +448,26 @@
 static int
 key_connect(struct socket *so, struct sockaddr *nam, struct thread *td)
 {
-	int s, error;
-	s = splnet();
-	error = raw_usrreqs.pru_connect(so, nam, td); /* XXX just EINVAL */
-	splx(s);
-	return error;
+	return EINVAL;
 }
 
 /*
  * key_detach()
  * derived from net/rtsock.c:rts_detach()
  */
-static int
+static void
 key_detach(struct socket *so)
 {
 	struct keycb *kp = (struct keycb *)sotorawcb(so);
-	int s, error;
 
-	s = splnet();
-	if (kp != 0) {
-		if (kp->kp_raw.rcb_proto.sp_protocol
-		    == PF_KEY) /* XXX: AF_KEY */
-			key_cb.key_count--;
-		key_cb.any_count--;
+	KASSERT(kp != NULL, ("key_detach: kp == NULL"));
+	if (kp->kp_raw.rcb_proto.sp_protocol
+	    == PF_KEY) /* XXX: AF_KEY */
+		key_cb.key_count--;
+	key_cb.any_count--;
 
-		key_freereg(so);
-	}
-	error = raw_usrreqs.pru_detach(so);
-	splx(s);
-	return error;
+	key_freereg(so);
+	raw_usrreqs.pru_detach(so);
 }
 
 /*
@@ -486,11 +477,7 @@
 static int
 key_disconnect(struct socket *so)
 {
-	int s, error;
-	s = splnet();
-	error = raw_usrreqs.pru_disconnect(so);
-	splx(s);
-	return error;
+	return(raw_usrreqs.pru_disconnect(so));
 }
 
 /*
@@ -500,11 +487,7 @@
 static int
 key_peeraddr(struct socket *so, struct sockaddr **nam)
 {
-	int s, error;
-	s = splnet();
-	error = raw_usrreqs.pru_peeraddr(so, nam);
-	splx(s);
-	return error;
+	return(raw_usrreqs.pru_peeraddr(so, nam));
 }
 
 /*
@@ -515,11 +498,7 @@
 key_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *nam,
 	 struct mbuf *control, struct thread *td)
 {
-	int s, error;
-	s = splnet();
-	error = raw_usrreqs.pru_send(so, flags, m, nam, control, td);
-	splx(s);
-	return error;
+	return(raw_usrreqs.pru_send(so, flags, m, nam, control, td));
 }
 
 /*
@@ -529,11 +508,7 @@
 static int
 key_shutdown(struct socket *so)
 {
-	int s, error;
-	s = splnet();
-	error = raw_usrreqs.pru_shutdown(so);
-	splx(s);
-	return error;
+	return(raw_usrreqs.pru_shutdown(so));
 }
 
 /*
@@ -543,11 +518,7 @@
 static int
 key_sockaddr(struct socket *so, struct sockaddr **nam)
 {
-	int s, error;
-	s = splnet();
-	error = raw_usrreqs.pru_sockaddr(so, nam);
-	splx(s);
-	return error;
+	return(raw_usrreqs.pru_sockaddr(so, nam));
 }
 
 struct pr_usrreqs key_usrreqs = {
@@ -561,6 +532,7 @@
 	.pru_send =		key_send,
 	.pru_shutdown =		key_shutdown,
 	.pru_sockaddr =		key_sockaddr,
+	.pru_close =		key_close,
 };
 
 /* sysctl */
Index: keysock.h
===================================================================
RCS file: /home/cvs/src/sys/netipsec/keysock.h,v
retrieving revision 1.1.1.2
retrieving revision 1.2
diff -L sys/netipsec/keysock.h -L sys/netipsec/keysock.h -u -r1.1.1.2 -r1.2
--- sys/netipsec/keysock.h
+++ sys/netipsec/keysock.h
@@ -1,4 +1,4 @@
-/*	$FreeBSD: src/sys/netipsec/keysock.h,v 1.2.2.1 2006/01/27 21:50:11 bz Exp $	*/
+/*	$FreeBSD: src/sys/netipsec/keysock.h,v 1.3 2006/01/21 10:44:34 bz Exp $	*/
 /*	$KAME: keysock.h,v 1.8 2000/03/27 05:11:06 sumikawa Exp $	*/
 
 /*-
Index: xform.h
===================================================================
RCS file: /home/cvs/src/sys/netipsec/xform.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -L sys/netipsec/xform.h -L sys/netipsec/xform.h -u -r1.2 -r1.3
--- sys/netipsec/xform.h
+++ sys/netipsec/xform.h
@@ -1,4 +1,4 @@
-/*	$FreeBSD: src/sys/netipsec/xform.h,v 1.2.2.1 2006/04/01 15:22:44 bz Exp $	*/
+/*	$FreeBSD: src/sys/netipsec/xform.h,v 1.3 2006/03/30 18:57:04 bz Exp $	*/
 /*	$OpenBSD: ip_ipsp.h,v 1.119 2002/03/14 01:27:11 millert Exp $	*/
 /*-
  * The authors of this code are John Ioannidis (ji at tla.org),
Index: xform_tcp.c
===================================================================
RCS file: /home/cvs/src/sys/netipsec/xform_tcp.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/netipsec/xform_tcp.c -L sys/netipsec/xform_tcp.c -u -r1.1.1.1 -r1.2
--- sys/netipsec/xform_tcp.c
+++ sys/netipsec/xform_tcp.c
@@ -1,4 +1,4 @@
-/*	$FreeBSD: src/sys/netipsec/xform_tcp.c,v 1.4 2005/01/07 01:45:46 imp Exp $ */
+/*	$FreeBSD: src/sys/netipsec/xform_tcp.c,v 1.5 2006/03/25 13:38:52 gnn Exp $ */
 
 /*-
  * Copyright (c) 2003 Bruce M. Simpson <bms at spc.org>
@@ -117,7 +117,7 @@
 {
 
 	if (sav->key_auth)
-		bzero(_KEYBUF(sav->key_auth), _KEYLEN(sav->key_auth));
+		bzero(sav->key_auth->key_data, _KEYLEN(sav->key_auth));
 
 	sav->tdb_cryptoid = 0;
 	sav->tdb_authalgxform = NULL;
Index: xform_esp.c
===================================================================
RCS file: /home/cvs/src/sys/netipsec/xform_esp.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -L sys/netipsec/xform_esp.c -L sys/netipsec/xform_esp.c -u -r1.3 -r1.4
--- sys/netipsec/xform_esp.c
+++ sys/netipsec/xform_esp.c
@@ -1,4 +1,4 @@
-/*	$FreeBSD: src/sys/netipsec/xform_esp.c,v 1.10 2005/01/07 01:45:46 imp Exp $	*/
+/*	$FreeBSD: src/sys/netipsec/xform_esp.c,v 1.20 2007/08/06 14:26:02 rwatson Exp $	*/
 /*	$OpenBSD: ip_esp.c,v 1.69 2001/06/26 06:18:59 angelos Exp $ */
 /*-
  * The authors of this code are John Ioannidis (ji at tla.org),
@@ -113,6 +113,8 @@
 		return &enc_xform_skipjack;
 	case SADB_EALG_NULL:
 		return &enc_xform_null;
+	case SADB_X_EALG_CAMELLIACBC:
+		return &enc_xform_camellia;
 	}
 	return NULL;
 }
@@ -215,7 +217,7 @@
 	bzero(&crie, sizeof (crie));
 	crie.cri_alg = sav->tdb_encalgxform->type;
 	crie.cri_klen = _KEYBITS(sav->key_enc);
-	crie.cri_key = _KEYBUF(sav->key_enc);
+	crie.cri_key = sav->key_enc->key_data;
 	/* XXX Rounds ? */
 
 	if (sav->tdb_authalgxform && sav->tdb_encalgxform) {
@@ -248,7 +250,7 @@
 	int error = ah_zeroize(sav);
 
 	if (sav->key_enc)
-		bzero(_KEYBUF(sav->key_enc), _KEYLEN(sav->key_enc));
+		bzero(sav->key_enc->key_data, _KEYLEN(sav->key_enc));
 	if (sav->iv) {
 		free(sav->iv, M_XDATA);
 		sav->iv = NULL;
@@ -329,7 +331,7 @@
 	}
 
 	/* Update the counters */
-	espstat.esps_ibytes += m->m_pkthdr.len - skip - hlen - alen;
+	espstat.esps_ibytes += m->m_pkthdr.len - (skip + hlen + alen);
 
 	/* Find out if we've already done crypto */
 	for (mtag = m_tag_find(m, PACKET_TAG_IPSEC_IN_CRYPTO_DONE, NULL);
@@ -381,7 +383,7 @@
 		crda->crd_inject = m->m_pkthdr.len - alen;
 
 		crda->crd_alg = esph->type;
-		crda->crd_key = _KEYBUF(sav->key_auth);
+		crda->crd_key = sav->key_auth->key_data;
 		crda->crd_klen = _KEYBITS(sav->key_auth);
 
 		/* Copy the authenticator */
@@ -418,7 +420,7 @@
 		crde->crd_inject = skip + hlen - sav->ivlen;
 
 		crde->crd_alg = espx->type;
-		crde->crd_key = _KEYBUF(sav->key_enc);
+		crde->crd_key = sav->key_enc->key_data;
 		crde->crd_klen = _KEYBITS(sav->key_enc);
 		/* XXX Rounds ? */
 	}
@@ -496,7 +498,8 @@
 
 		if (crp->crp_etype == EAGAIN) {
 			KEY_FREESAV(&sav);
-			return crypto_dispatch(crp);
+			error = crypto_dispatch(crp);
+			return error;
 		}
 
 		espstat.esps_noxform++;
@@ -524,13 +527,13 @@
 		ahstat.ahs_hist[sav->alg_auth]++;
 		if (mtag == NULL) {
 			/* Copy the authenticator from the packet */
-			m_copydata(m, m->m_pkthdr.len - esph->authsize,
-				esph->authsize, aalg);
+			m_copydata(m, m->m_pkthdr.len - AH_HMAC_HASHLEN,
+				AH_HMAC_HASHLEN, aalg);
 
 			ptr = (caddr_t) (tc + 1);
 
 			/* Verify authenticator */
-			if (bcmp(ptr, aalg, esph->authsize) != 0) {
+			if (bcmp(ptr, aalg, AH_HMAC_HASHLEN) != 0) {
 				DPRINTF(("%s: "
 		    "authentication hash mismatch for packet in SA %s/%08lx\n",
 				    __func__,
@@ -543,7 +546,7 @@
 		}
 
 		/* Remove trailing authenticator */
-		m_adj(m, -(esph->authsize));
+		m_adj(m, -AH_HMAC_HASHLEN);
 	}
 
 	/* Release the crypto descriptors */
@@ -753,7 +756,14 @@
 	/* Initialize ESP header. */
 	bcopy((caddr_t) &sav->spi, mtod(mo, caddr_t) + roff, sizeof(u_int32_t));
 	if (sav->replay) {
-		u_int32_t replay = htonl(++(sav->replay->count));
+		u_int32_t replay;
+
+#ifdef REGRESSION
+		/* Emulate replay attack when ipsec_replay is TRUE. */
+		if (!ipsec_replay)
+#endif
+			sav->replay->count++;
+		replay = htonl(sav->replay->count);
 		bcopy((caddr_t) &replay,
 		    mtod(mo, caddr_t) + roff + sizeof(u_int32_t),
 		    sizeof(u_int32_t));
@@ -819,7 +829,7 @@
 
 		/* Encryption operation. */
 		crde->crd_alg = espx->type;
-		crde->crd_key = _KEYBUF(sav->key_enc);
+		crde->crd_key = sav->key_enc->key_data;
 		crde->crd_klen = _KEYBITS(sav->key_enc);
 		/* XXX Rounds ? */
 	} else
@@ -858,7 +868,7 @@
 
 		/* Authentication operation. */
 		crda->crd_alg = esph->type;
-		crda->crd_key = _KEYBUF(sav->key_auth);
+		crda->crd_key = sav->key_auth->key_data;
 		crda->crd_klen = _KEYBITS(sav->key_auth);
 	}
 
@@ -908,7 +918,8 @@
 		if (crp->crp_etype == EAGAIN) {
 			KEY_FREESAV(&sav);
 			IPSECREQUEST_UNLOCK(isr);
-			return crypto_dispatch(crp);
+			error = crypto_dispatch(crp);
+			return error;
 		}
 
 		espstat.esps_noxform++;
@@ -932,11 +943,28 @@
 	free(tc, M_XDATA);
 	crypto_freereq(crp);
 
+#ifdef REGRESSION
+	/* Emulate man-in-the-middle attack when ipsec_integrity is TRUE. */
+	if (ipsec_integrity) {
+		static unsigned char ipseczeroes[AH_HMAC_HASHLEN];
+		struct auth_hash *esph;
+
+		/*
+		 * Corrupt HMAC if we want to test integrity verification of
+		 * the other side.
+		 */
+		esph = sav->tdb_authalgxform;
+		if (esph !=  NULL) {
+			m_copyback(m, m->m_pkthdr.len - AH_HMAC_HASHLEN,
+			    AH_HMAC_HASHLEN, ipseczeroes);
+		}
+	}
+#endif
+
 	/* NB: m is reclaimed by ipsec_process_done. */
 	err = ipsec_process_done(m, isr);
 	KEY_FREESAV(&sav);
 	IPSECREQUEST_UNLOCK(isr);
-
 	return err;
 bad:
 	if (sav)
@@ -970,6 +998,7 @@
 	MAXIV(enc_xform_cast5);		/* SADB_X_EALG_CAST128CBC */
 	MAXIV(enc_xform_skipjack);	/* SADB_X_EALG_SKIPJACK */
 	MAXIV(enc_xform_null);		/* SADB_EALG_NULL */
+	MAXIV(enc_xform_camellia);	/* SADB_X_EALG_CAMELLIACBC */
 
 	xform_register(&esp_xformsw);
 #undef MAXIV
Index: xform_ipcomp.c
===================================================================
RCS file: /home/cvs/src/sys/netipsec/xform_ipcomp.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -L sys/netipsec/xform_ipcomp.c -L sys/netipsec/xform_ipcomp.c -u -r1.2 -r1.3
--- sys/netipsec/xform_ipcomp.c
+++ sys/netipsec/xform_ipcomp.c
@@ -1,4 +1,4 @@
-/*	$FreeBSD: src/sys/netipsec/xform_ipcomp.c,v 1.8.2.1 2006/03/23 23:24:33 sam Exp $	*/
+/*	$FreeBSD: src/sys/netipsec/xform_ipcomp.c,v 1.11 2007/08/06 14:26:02 rwatson Exp $	*/
 /* $OpenBSD: ip_ipcomp.c,v 1.1 2001/07/05 12:08:52 jjbg Exp $ */
 
 /*-
@@ -249,7 +249,8 @@
 
 		if (crp->crp_etype == EAGAIN) {
 			KEY_FREESAV(&sav);
-			return crypto_dispatch(crp);
+			error = crypto_dispatch(crp);
+			return error;
 		}
 
 		ipcompstat.ipcomps_noxform++;
@@ -519,7 +520,8 @@
 		if (crp->crp_etype == EAGAIN) {
 			KEY_FREESAV(&sav);
 			IPSECREQUEST_UNLOCK(isr);
-			return crypto_dispatch(crp);
+			error = crypto_dispatch(crp);
+			return error;
 		}
 		ipcompstat.ipcomps_noxform++;
 		DPRINTF(("%s: crypto error %d\n", __func__, crp->crp_etype));
@@ -572,7 +574,6 @@
 	error = ipsec_process_done(m, isr);
 	KEY_FREESAV(&sav);
 	IPSECREQUEST_UNLOCK(isr);
-
 	return error;
 bad:
 	if (sav)
Index: ipsec.h
===================================================================
RCS file: /home/cvs/src/sys/netipsec/ipsec.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -L sys/netipsec/ipsec.h -L sys/netipsec/ipsec.h -u -r1.2 -r1.3
--- sys/netipsec/ipsec.h
+++ sys/netipsec/ipsec.h
@@ -1,4 +1,4 @@
-/*	$FreeBSD: src/sys/netipsec/ipsec.h,v 1.8.2.1 2006/03/23 23:24:32 sam Exp $	*/
+/*	$FreeBSD: src/sys/netipsec/ipsec.h,v 1.13 2007/07/01 11:38:29 gnn Exp $	*/
 /*	$KAME: ipsec.h,v 1.53 2001/11/20 08:32:38 itojun Exp $	*/
 
 /*-
@@ -205,7 +205,7 @@
 				 */
 #define IPSEC_REPLAYWSIZE  32
 
-/* old statistics for ipsec processing */
+/* statistics for ipsec processing */
 struct ipsecstat {
 	u_quad_t in_success;  /* succeeded inbound process */
 	u_quad_t in_polvio;
@@ -236,10 +236,7 @@
 
 	u_quad_t spdcachelookup;
 	u_quad_t spdcachemiss;
-};
 
-/* statistics for ipsec processing */
-struct newipsecstat {
 	u_int32_t ips_in_polvio;	/* input: sec policy violation */
 	u_int32_t ips_out_polvio;	/* output: sec policy violation */
 	u_int32_t ips_out_nosa;		/* output: SA unavailable  */
@@ -330,8 +327,12 @@
 };
 
 extern int ipsec_debug;
+#ifdef REGRESSION
+extern int ipsec_replay;
+extern int ipsec_integrity;
+#endif
 
-extern struct newipsecstat newipsecstat;
+extern struct ipsecstat ipsec4stat;
 extern struct secpolicy ip4_def_policy;
 extern int ip4_esp_trans_deflev;
 extern int ip4_esp_net_deflev;
@@ -348,10 +349,6 @@
 /* for openbsd compatibility */
 #define	DPRINTF(x)	do { if (ipsec_debug) printf x; } while (0)
 
-/* XXX for KAME code compatibility */
-#define ipsec_pcbconn(_x)
-#define	ipsec_pcbdisconn(_x)
-
 extern	struct ipsecrequest *ipsec_newisr(void);
 extern	void ipsec_delisr(struct ipsecrequest *);
 
@@ -413,6 +410,8 @@
 extern	struct mbuf *m_makespace(struct mbuf *m0, int skip, int hlen, int *off);
 extern	caddr_t m_pad(struct mbuf *m, int n);
 extern	int m_striphdr(struct mbuf *m, int skip, int hlen);
+extern	int ipsec_filter(struct mbuf **, int);
+extern	void ipsec_bpf(struct mbuf *, struct secasvar *, int);
 #endif /* _KERNEL */
 
 #ifndef _KERNEL
Index: ipsec_osdep.h
===================================================================
RCS file: /home/cvs/src/sys/netipsec/ipsec_osdep.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/netipsec/ipsec_osdep.h -L sys/netipsec/ipsec_osdep.h -u -r1.1.1.1 -r1.2
--- sys/netipsec/ipsec_osdep.h
+++ sys/netipsec/ipsec_osdep.h
@@ -1,4 +1,4 @@
-/*	$FreeBSD: src/sys/netipsec/ipsec_osdep.h,v 1.2 2005/01/07 01:45:46 imp Exp $	*/
+/*	$FreeBSD: src/sys/netipsec/ipsec_osdep.h,v 1.6 2007/06/12 00:12:00 rwatson Exp $	*/
 /*	$NetBSD: ipsec_osdep.h,v 1.1 2003/08/13 20:06:51 jonathan Exp $	*/
 
 /*-
@@ -211,14 +211,16 @@
 
 /*
  * 8. Test for "privileged" socket opened by superuser.
- * FreeBSD tests  ((so)->so_cred && (so)->so_cred.cr_uid == 0), 
+ * FreeBSD tests  ((so)->so_cred != NULL && priv_check_cred((so)->so_cred,
+ * PRIV_NETINET_IPSEC, 0) == 0).
  * NetBSD (1.6N) tests (so)->so_uid == 0).
  * This difference is wrapped inside  the IPSEC_PRIVILEGED_SO() macro.
- *
  */
 #ifdef __FreeBSD__ 
 #define IPSEC_IS_PRIVILEGED_SO(_so) \
-	((_so)->so_cred && (_so)->so_cred->cr_uid == 0)
+	((_so)->so_cred != NULL && \
+	 priv_check_cred((_so)->so_cred, PRIV_NETINET_IPSEC, 0) \
+	 == 0)
 #endif	/* __FreeBSD__ */
 
 #ifdef __NetBSD__
Index: key_var.h
===================================================================
RCS file: /home/cvs/src/sys/netipsec/key_var.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/netipsec/key_var.h -L sys/netipsec/key_var.h -u -r1.1.1.1 -r1.2
--- sys/netipsec/key_var.h
+++ sys/netipsec/key_var.h
@@ -1,4 +1,4 @@
-/*	$FreeBSD: src/sys/netipsec/key_var.h,v 1.2 2005/01/07 01:45:46 imp Exp $	*/
+/*	$FreeBSD: src/sys/netipsec/key_var.h,v 1.3 2006/03/25 13:38:52 gnn Exp $	*/
 /*	$KAME: key_var.h,v 1.11 2001/09/12 23:05:07 sakane Exp $	*/
 
 /*-
@@ -66,8 +66,8 @@
 
 #ifdef _KERNEL
 #define _ARRAYLEN(p) (sizeof(p)/sizeof(p[0]))
-#define _KEYLEN(key) ((u_int)((key)->sadb_key_bits >> 3))
-#define _KEYBITS(key) ((u_int)((key)->sadb_key_bits))
+#define _KEYLEN(key) ((u_int)((key)->bits >> 3))
+#define _KEYBITS(key) ((u_int)((key)->bits))
 #define _KEYBUF(key) ((caddr_t)((caddr_t)(key) + sizeof(struct sadb_key)))
 #endif /*_KERNEL*/
 
Index: ipsec_output.c
===================================================================
RCS file: /home/cvs/src/sys/netipsec/ipsec_output.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/netipsec/ipsec_output.c -L sys/netipsec/ipsec_output.c -u -r1.1.1.1 -r1.2
--- sys/netipsec/ipsec_output.c
+++ sys/netipsec/ipsec_output.c
@@ -23,7 +23,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/sys/netipsec/ipsec_output.c,v 1.10 2004/01/20 22:45:10 sam Exp $
+ * $FreeBSD: src/sys/netipsec/ipsec_output.c,v 1.16 2007/07/19 09:57:54 bz Exp $
  */
 
 /*
@@ -32,6 +32,7 @@
 #include "opt_inet.h"
 #include "opt_inet6.h"
 #include "opt_ipsec.h"
+#include "opt_enc.h"
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -43,6 +44,7 @@
 #include <sys/syslog.h>
 
 #include <net/if.h>
+#include <net/pfil.h>
 #include <net/route.h>
 
 #include <netinet/in.h>
@@ -154,7 +156,7 @@
 	 * doing further processing.
 	 */
 	if (isr->next) {
-		newipsecstat.ips_out_bundlesa++;
+		ipsec4stat.ips_out_bundlesa++;
 		return ipsec4_process_packet(m, isr->next, 0, 0);
 	}
 	key_sa_recordxfer(sav, m);		/* record data transfer */
@@ -280,7 +282,7 @@
 		 * this packet because it is responsibility for
 		 * upper layer to retransmit the packet.
 		 */
-		newipsecstat.ips_out_nosa++;
+		ipsec4stat.ips_out_nosa++;
 		goto bad;
 	}
 	sav = isr->sav;
@@ -358,6 +360,13 @@
 		goto bad;
 
 	sav = isr->sav;
+
+#ifdef DEV_ENC
+	/* pass the mbuf to enc0 for packet filtering */
+	if ((error = ipsec_filter(&m, PFIL_OUT)) != 0)
+		goto bad;
+#endif
+
 	if (!tunalready) {
 		union sockaddr_union *dst = &sav->sah->saidx.dst;
 		int setdf;
@@ -455,6 +464,11 @@
 		}
 	}
 
+#ifdef DEV_ENC
+	/* pass the mbuf to enc0 for bpf processing */
+	ipsec_bpf(m, sav, AF_INET);
+#endif
+
 	/*
 	 * Dispatch to the appropriate IPsec transform logic.  The
 	 * packet will be returned for transmission after crypto
@@ -500,7 +514,7 @@
 	ip6 = mtod(m, struct ip6_hdr *);
 	hlen = sizeof(struct ip6_hdr);
 	if (m->m_len > hlen) {
-		MGETHDR(mh, M_DONTWAIT, MT_HEADER);
+		MGETHDR(mh, M_DONTWAIT, MT_DATA);
 		if (!mh) {
 			m_freem(m);
 			return NULL;
@@ -546,7 +560,7 @@
 	IPSEC_ASSERT(tun != NULL, ("null tun"));
 
 	KEYDEBUG(KEYDEBUG_IPSEC_DATA,
-		printf("%s: applyed SP\n", __func__);
+		printf("%s: applied SP\n", __func__);
 		kdebug_secpolicy(sp));
 
 	isr = sp->req;
@@ -559,6 +573,7 @@
 	*tun = 0;
 	m = state->m;
 
+	IPSECREQUEST_LOCK(isr);		/* insure SA contents don't change */
 	isr = ipsec_nextisr(m, isr, AF_INET6, &saidx, &error);
 	if (isr == NULL) {
 #ifdef notdef
@@ -578,10 +593,15 @@
 		goto bad;
 	}
 
-	return (*isr->sav->tdb_xform->xf_output)(m, isr, NULL,
-		sizeof (struct ip6_hdr),
-		offsetof(struct ip6_hdr, ip6_nxt));
+	error = (*isr->sav->tdb_xform->xf_output)(m, isr, NULL,
+						  sizeof (struct ip6_hdr),
+						  offsetof(struct ip6_hdr, 
+							   ip6_nxt));
+	IPSECREQUEST_UNLOCK(isr);
+	return error;
 bad:
+	if (isr)
+		IPSECREQUEST_UNLOCK(isr);
 	if (m)
 		m_freem(m);
 	state->m = NULL;
@@ -601,7 +621,7 @@
 		m_freem(m);
 		return EINVAL;
 	}
-	IPSEC_ASSERT(m->m_len != sizeof (struct ip6_hdr),
+	IPSEC_ASSERT(m->m_len == sizeof (struct ip6_hdr),
 		("mbuf wrong size; len %u", m->m_len));
 
 
@@ -645,8 +665,8 @@
 		/* ip6->ip6_plen will be updated in ip6_output() */
 	}
 	ip6->ip6_nxt = IPPROTO_IPV6;
-	sav->sah->saidx.src.sin6.sin6_addr = ip6->ip6_src;
-	sav->sah->saidx.dst.sin6.sin6_addr = ip6->ip6_dst;
+	ip6->ip6_src = sav->sah->saidx.src.sin6.sin6_addr;
+	ip6->ip6_dst = sav->sah->saidx.dst.sin6.sin6_addr;
 	ip6->ip6_hlim = IPV6_DEFHLIM;
 
 	/* XXX Should ip6_src be updated later ? */
@@ -672,7 +692,7 @@
 	IPSEC_ASSERT(sp != NULL, ("null sp"));
 
 	KEYDEBUG(KEYDEBUG_IPSEC_DATA,
-		printf("%s: applyed SP\n", __func__);
+		printf("%s: applied SP\n", __func__);
 		kdebug_secpolicy(sp));
 
 	m = state->m;
@@ -684,6 +704,8 @@
 		if (isr->saidx.mode == IPSEC_MODE_TUNNEL)
 			break;
 	}
+
+	IPSECREQUEST_LOCK(isr);		/* insure SA contents don't change */
 	isr = ipsec_nextisr(m, isr, AF_INET6, &saidx, &error);
 	if (isr == NULL)
 		goto bad;
@@ -701,14 +723,14 @@
 			ipseclog((LOG_ERR, "%s: family mismatched between "
 			    "inner and outer, spi=%u\n", __func__,
 			    ntohl(isr->sav->spi)));
-			newipsecstat.ips_out_inval++;
+			ipsec6stat.ips_out_inval++;
 			error = EAFNOSUPPORT;
 			goto bad;
 		}
 
 		m = ipsec6_splithdr(m);
 		if (!m) {
-			newipsecstat.ips_out_nomem++;
+			ipsec6stat.ips_out_nomem++;
 			error = ENOMEM;
 			goto bad;
 		}
@@ -737,7 +759,7 @@
 		}
 		if (state->ro->ro_rt == 0) {
 			ip6stat.ip6s_noroute++;
-			newipsecstat.ips_out_noroute++;
+			ipsec6stat.ips_out_noroute++;
 			error = EHOSTUNREACH;
 			goto bad;
 		}
@@ -751,15 +773,19 @@
 
 	m = ipsec6_splithdr(m);
 	if (!m) {
-		newipsecstat.ips_out_nomem++;
+		ipsec6stat.ips_out_nomem++;
 		error = ENOMEM;
 		goto bad;
 	}
 	ip6 = mtod(m, struct ip6_hdr *);
-	return (*isr->sav->tdb_xform->xf_output)(m, isr, NULL,
+	error = (*isr->sav->tdb_xform->xf_output)(m, isr, NULL,
 		sizeof (struct ip6_hdr),
 		offsetof(struct ip6_hdr, ip6_nxt));
+	IPSECREQUEST_UNLOCK(isr);
+	return error;
 bad:
+	if (isr)
+		IPSECREQUEST_UNLOCK(isr);
 	if (m)
 		m_freem(m);
 	state->m = NULL;
Index: keydb.h
===================================================================
RCS file: /home/cvs/src/sys/netipsec/keydb.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/netipsec/keydb.h -L sys/netipsec/keydb.h -u -r1.1.1.1 -r1.2
--- sys/netipsec/keydb.h
+++ sys/netipsec/keydb.h
@@ -1,4 +1,4 @@
-/*	$FreeBSD: src/sys/netipsec/keydb.h,v 1.5 2005/01/07 01:45:46 imp Exp $	*/
+/*	$FreeBSD: src/sys/netipsec/keydb.h,v 1.6 2006/03/25 13:38:52 gnn Exp $	*/
 /*	$KAME: keydb.h,v 1.14 2000/08/02 17:58:26 sakane Exp $	*/
 
 /*-
@@ -60,14 +60,39 @@
 					/* see IPSEC_MANUAL_REQID_MAX. */
 };
 
+/* 
+ * In order to split out the keydb implementation from that of the
+ * PF_KEY sockets we need to define a few structures that while they
+ * may seem common are likely to diverge over time. 
+ */
+
+/* sadb_identity */
+struct secident {
+	u_int16_t type;
+	u_int64_t id;
+};
+
+/* sadb_key */
+struct seckey {
+	u_int16_t bits;
+	char *key_data;
+};
+
+struct seclifetime {
+	u_int32_t allocations;
+	u_int64_t bytes;
+	u_int64_t addtime;
+	u_int64_t usetime;
+};
+
 /* Security Association Data Base */
 struct secashead {
 	LIST_ENTRY(secashead) chain;
 
 	struct secasindex saidx;
 
-	struct sadb_ident *idents;	/* source identity */
-	struct sadb_ident *identd;	/* destination identity */
+	struct secident *idents;	/* source identity */
+	struct secident *identd;	/* destination identity */
 					/* XXX I don't know how to use them. */
 
 	u_int8_t state;			/* MATURE or DEAD. */
@@ -97,8 +122,8 @@
 	u_int32_t spi;			/* SPI Value, network byte order */
 	u_int32_t flags;		/* holder for SADB_KEY_FLAGS */
 
-	struct sadb_key *key_auth;	/* Key for Authentication */
-	struct sadb_key *key_enc;	/* Key for Encryption */
+	struct seckey *key_auth;	/* Key for Authentication */
+	struct seckey *key_enc;	        /* Key for Encryption */
 	caddr_t iv;			/* Initilization Vector */
 	u_int ivlen;			/* length of IV */
 	void *sched;			/* intermediate encryption key */
@@ -107,9 +132,9 @@
 	struct secreplay *replay;	/* replay prevention */
 	time_t created;			/* for lifetime */
 
-	struct sadb_lifetime *lft_c;	/* CURRENT lifetime, it's constant. */
-	struct sadb_lifetime *lft_h;	/* HARD lifetime */
-	struct sadb_lifetime *lft_s;	/* SOFT lifetime */
+	struct seclifetime *lft_c;	/* CURRENT lifetime, it's constant. */
+	struct seclifetime *lft_h;	/* HARD lifetime */
+	struct seclifetime *lft_s;	/* SOFT lifetime */
 
 	u_int32_t seq;			/* sequence number */
 	pid_t pid;			/* message's pid */


More information about the Midnightbsd-cvs mailing list