Separating the kernel and user land versions of PF_KEY.

gnn at freebsd.org gnn at freebsd.org
Sat Feb 11 05:37:16 PST 2006


Hi Folks,

The attached patch makes it so that the user land and kernel land
versions of the pf_key structures are different and therefore no
longer dependent.  This is one step in moving us away from the place
we're in now where changes to one side require changes in the
other. At some point soon a more full overhaul of the code will take
place, likely along the lines of the code found in OpenBSD (look at
net/pfkey*.[ch] there).  Please send feedback etc. on this patch along
to me.

BTW Although this patch contains a lot of p4 cruft it applies cleanly
against HEAD, at least as of a few days ago and passes the CT test
suite ipsec4 which is available by installing the ct port.

Thanks,
George

Change 89716 by gnn at gnn_devbox_fast_ipsec on 2006/01/15 02:41:52

	First cut at removing PF_KEY data structures from the keydb.  This code
	does not work completely yet but needs to be saved.

Affected files ...

... //depot/projects/gnn_fast_ipsec/src/sys/netipsec/ipsec.c#2 edit
... //depot/projects/gnn_fast_ipsec/src/sys/netipsec/key.c#2 edit
... //depot/projects/gnn_fast_ipsec/src/sys/netipsec/key_var.h#2 edit
... //depot/projects/gnn_fast_ipsec/src/sys/netipsec/keydb.h#2 edit
... //depot/projects/gnn_fast_ipsec/src/sys/netipsec/xform_ah.c#2 edit
... //depot/projects/gnn_fast_ipsec/src/sys/netipsec/xform_esp.c#2 edit
... //depot/projects/gnn_fast_ipsec/src/sys/netipsec/xform_tcp.c#2 edit

Differences ...

==== //depot/projects/gnn_fast_ipsec/src/sys/netipsec/ipsec.c#2 (text+ko) ====
Index: sys/netipsec/ipsec.c
--- sys/netipsec/ipsec.c.~1~	Sun Feb  5 15:06:16 2006
+++ sys/netipsec/ipsec.c	Sun Feb  5 15:06:16 2006
@@ -92,6 +92,7 @@
 
 #include <machine/in_cksum.h>
 
+#define IPSEC_DEBUG
 #ifdef IPSEC_DEBUG
 int ipsec_debug = 1;
 #else

==== //depot/projects/gnn_fast_ipsec/src/sys/netipsec/key.c#2 (text+ko) ====
Index: sys/netipsec/key.c
--- sys/netipsec/key.c.~1~	Sun Feb  5 15:06:16 2006
+++ sys/netipsec/key.c	Sun Feb  5 15:06:16 2006
@@ -420,7 +420,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 +491,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));
@@ -909,8 +916,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 +925,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 +937,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;
 
@@ -2787,9 +2794,9 @@
 	} 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) {
 		free(sav->key_auth, M_IPSEC_MISC);
@@ -3038,9 +3045,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;
 		}
@@ -3061,12 +3070,15 @@
 		}
 		switch (mhp->msg->sadb_msg_satype) {
 		case SADB_SATYPE_ESP:
+		  /* XXX FIX ME */
 			if (len == PFKEY_ALIGN8(sizeof(struct sadb_key)) &&
 			    sav->alg_enc != SADB_EALG_NULL) {
 				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 +3138,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 +3153,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 +3168,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;
@@ -3271,9 +3280,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 +3297,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 +3331,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 +3381,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 +3610,67 @@
 }
 
 /* %%% 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
+ */
+struct seckey *
+key_dup_keymsg(const struct sadb_key *src, u_int len,
+	       struct malloc_type *type)
+{
+	struct seckey *dst = NULL;
+	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(src + sizeof(struct sadb_key), 
+			      dst->key_data, len);
+			ipseclog((LOG_DEBUG, "%s: source bits %p\n", __func__,
+				  src + sizeof(struct sadb_key)));
+			ipseclog((LOG_DEBUG, "%s: dst bits %p\n", __func__,
+				  dst->key_data));
+		} 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 void *
-key_dup(const void *src, u_int len, struct malloc_type *type)
+
+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
@@ -4071,13 +4118,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 +4143,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 +4169,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 +4191,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);
 			}
@@ -4977,20 +5024,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 +6312,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 +7153,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 +7175,7 @@
 	 *	<--------------> HARD
 	 *	<-----> SOFT
 	 */
-	sav->lft_c->sadb_lifetime_usetime = time_second;
+	sav->lft_c->usetime = time_second;
 	/* XXX check for expires? */
 
 	return;
@@ -7214,3 +7264,55 @@
 
 	return m;
 }
+
+static struct mbuf *
+key_setkey(struct seckey *src, u_int16_t exttype) 
+{
+	struct mbuf *m;
+	struct sadb_key *p;
+	int len = PFKEY_ALIGN8(sizeof(struct sadb_key));
+
+	if (src == NULL)
+		return NULL;
+
+	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;
+	ipseclog((LOG_DEBUG, "%s: setting key data %s\n", 
+			   __func__, src->key_data));
+	bcopy(src->key_data, _KEYBUF(p), len);
+
+	return m;
+}
+
+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;
+
+}

==== //depot/projects/gnn_fast_ipsec/src/sys/netipsec/key_var.h#2 (text+ko) ====
Index: sys/netipsec/key_var.h
--- sys/netipsec/key_var.h.~1~	Sun Feb  5 15:06:16 2006
+++ sys/netipsec/key_var.h	Sun Feb  5 15:06:16 2006
@@ -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*/
 

==== //depot/projects/gnn_fast_ipsec/src/sys/netipsec/keydb.h#2 (text+ko) ====
Index: sys/netipsec/keydb.h
--- sys/netipsec/keydb.h.~1~	Sun Feb  5 15:06:16 2006
+++ sys/netipsec/keydb.h	Sun Feb  5 15:06:16 2006
@@ -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 */

==== //depot/projects/gnn_fast_ipsec/src/sys/netipsec/xform_ah.c#2 (text+ko) ====
Index: sys/netipsec/xform_ah.c
--- sys/netipsec/xform_ah.c.~1~	Sun Feb  5 15:06:16 2006
+++ sys/netipsec/xform_ah.c	Sun Feb  5 15:06:16 2006
@@ -201,7 +201,7 @@
 	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;
 
 	return 0;
 }
@@ -231,7 +231,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 +622,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);
@@ -1014,7 +1014,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. */

==== //depot/projects/gnn_fast_ipsec/src/sys/netipsec/xform_esp.c#2 (text+ko) ====
Index: sys/netipsec/xform_esp.c
--- sys/netipsec/xform_esp.c.~1~	Sun Feb  5 15:06:16 2006
+++ sys/netipsec/xform_esp.c	Sun Feb  5 15:06:16 2006
@@ -215,7 +215,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 +248,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;
@@ -381,7 +381,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 +418,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 ? */
 	}
@@ -802,7 +802,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
@@ -841,7 +841,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);
 	}
 

==== //depot/projects/gnn_fast_ipsec/src/sys/netipsec/xform_tcp.c#2 (text+ko) ====
Index: sys/netipsec/xform_tcp.c
--- sys/netipsec/xform_tcp.c.~1~	Sun Feb  5 15:06:16 2006
+++ sys/netipsec/xform_tcp.c	Sun Feb  5 15:06:16 2006
@@ -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;
End of Patch.
Change 90069 by gnn at gnn_tahi_fast_ipsec on 2006/01/21 13:06:06

	Fix pointer arithmetic so that we actually put the key in the database
	and not random garbage.  
	
	First working version with new structures.

Affected files ...

... //depot/projects/gnn_fast_ipsec/src/sys/netipsec/key.c#3 edit

Differences ...

==== //depot/projects/gnn_fast_ipsec/src/sys/netipsec/key.c#3 (text+ko) ====
Index: sys/netipsec/key.c
--- sys/netipsec/key.c.~1~	Sun Feb  5 15:06:27 2006
+++ sys/netipsec/key.c	Sun Feb  5 15:06:27 2006
@@ -2799,10 +2799,14 @@
 			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;
 	}
@@ -3070,7 +3074,6 @@
 		}
 		switch (mhp->msg->sadb_msg_satype) {
 		case SADB_SATYPE_ESP:
-		  /* XXX FIX ME */
 			if (len == PFKEY_ALIGN8(sizeof(struct sadb_key)) &&
 			    sav->alg_enc != SADB_EALG_NULL) {
 				error = EINVAL;
@@ -3620,18 +3623,14 @@
 key_dup_keymsg(const struct sadb_key *src, u_int len,
 	       struct malloc_type *type)
 {
-	struct seckey *dst = NULL;
+	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(src + sizeof(struct sadb_key), 
+			bcopy((const char *)src + sizeof(struct sadb_key), 
 			      dst->key_data, len);
-			ipseclog((LOG_DEBUG, "%s: source bits %p\n", __func__,
-				  src + sizeof(struct sadb_key)));
-			ipseclog((LOG_DEBUG, "%s: dst bits %p\n", __func__,
-				  dst->key_data));
 		} else {
 			ipseclog((LOG_DEBUG, "%s: No more memory.\n", 
 				  __func__));
@@ -7265,12 +7264,25 @@
 	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 = PFKEY_ALIGN8(sizeof(struct sadb_key));
+	int len = PFKEY_ALIGN8(sizeof(struct sadb_key) + _KEYLEN(src));
 
 	if (src == NULL)
 		return NULL;
@@ -7285,11 +7297,25 @@
 	p->sadb_key_bits = src->bits;
 	ipseclog((LOG_DEBUG, "%s: setting key data %s\n", 
 			   __func__, src->key_data));
-	bcopy(src->key_data, _KEYBUF(p), len);
+	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)
 {
End of Patch.


More information about the freebsd-net mailing list