Mon Jun 6 16:48:35 2011 UTC ()
remove a limitation that inner and outer IP version must be equal
for an ESP tunnel, and add some fixes which make v4-in-v6 work
(v6 as inner protocol isn't ready, even v6-in-v6 can never have worked)

being here, fix a statistics counter and kill an unused variable


(drochner)
diff -r1.32 -r1.33 src/sys/netipsec/ipsec_output.c
diff -r1.71 -r1.72 src/sys/netipsec/key.c
diff -r1.26 -r1.27 src/sys/netipsec/xform_ipip.c

cvs diff -r1.32 -r1.33 src/sys/netipsec/ipsec_output.c (expand / switch to context diff)
--- src/sys/netipsec/ipsec_output.c 2011/02/18 16:12:26 1.32
+++ src/sys/netipsec/ipsec_output.c 2011/06/06 16:48:35 1.33
@@ -1,4 +1,4 @@
-/*	$NetBSD: ipsec_output.c,v 1.32 2011/02/18 16:12:26 drochner Exp $	*/
+/*	$NetBSD: ipsec_output.c,v 1.33 2011/06/06 16:48:35 drochner Exp $	*/
 
 /*-
  * Copyright (c) 2002, 2003 Sam Leffler, Errno Consulting
@@ -29,7 +29,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ipsec_output.c,v 1.32 2011/02/18 16:12:26 drochner Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ipsec_output.c,v 1.33 2011/06/06 16:48:35 drochner Exp $");
 
 /*
  * IPsec output processing.
@@ -608,9 +608,15 @@
 	 *     for reclaiming their resources.
 	 */
 	if (sav->tdb_xform->xf_type != XF_IP4) {
-		ip = mtod(m, struct ip *);
-		i = ip->ip_hl << 2;
-		off = offsetof(struct ip, ip_p);
+		union sockaddr_union *dst = &sav->sah->saidx.dst;
+		if (dst->sa.sa_family == AF_INET) {
+			ip = mtod(m, struct ip *);
+			i = ip->ip_hl << 2;
+			off = offsetof(struct ip, ip_p);
+		} else {
+			i = sizeof(struct ip6_hdr);
+			off = offsetof(struct ip6_hdr, ip6_nxt);
+		}
 		error = (*sav->tdb_xform->xf_output)(m, isr, NULL, i, off);
 	} else {
 		error = ipsec_process_done(m, isr);

cvs diff -r1.71 -r1.72 src/sys/netipsec/key.c (expand / switch to context diff)
--- src/sys/netipsec/key.c 2011/05/23 15:17:25 1.71
+++ src/sys/netipsec/key.c 2011/06/06 16:48:35 1.72
@@ -1,4 +1,4 @@
-/*	$NetBSD: key.c,v 1.71 2011/05/23 15:17:25 drochner Exp $	*/
+/*	$NetBSD: key.c,v 1.72 2011/06/06 16:48:35 drochner Exp $	*/
 /*	$FreeBSD: src/sys/netipsec/key.c,v 1.3.2.3 2004/02/14 22:23:23 bms Exp $	*/
 /*	$KAME: key.c,v 1.191 2001/06/27 10:46:49 sakane Exp $	*/
 	
@@ -32,7 +32,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: key.c,v 1.71 2011/05/23 15:17:25 drochner Exp $");
+__KERNEL_RCSID(0, "$NetBSD: key.c,v 1.72 2011/06/06 16:48:35 drochner Exp $");
 
 /*
  * This code is referd to RFC 2367
@@ -1942,24 +1942,6 @@
 		KFREE(newsp);
 		return key_senderror(so, m, EINVAL);
 	}
-#if 1
-	if (newsp->req && newsp->req->saidx.src.sa.sa_family) {
-		struct sockaddr *sa;
-		sa = (struct sockaddr *)(src0 + 1);
-		if (sa->sa_family != newsp->req->saidx.src.sa.sa_family) {
-			KFREE(newsp);
-			return key_senderror(so, m, EINVAL);
-		}
-	}
-	if (newsp->req && newsp->req->saidx.dst.sa.sa_family) {
-		struct sockaddr *sa;
-		sa = (struct sockaddr *)(dst0 + 1);
-		if (sa->sa_family != newsp->req->saidx.dst.sa.sa_family) {
-			KFREE(newsp);
-			return key_senderror(so, m, EINVAL);
-		}
-	}
-#endif
 
 	newsp->created = time_uptime;
 	newsp->lastused = newsp->created;

cvs diff -r1.26 -r1.27 src/sys/netipsec/xform_ipip.c (expand / switch to context diff)
--- src/sys/netipsec/xform_ipip.c 2011/02/18 20:40:58 1.26
+++ src/sys/netipsec/xform_ipip.c 2011/06/06 16:48:35 1.27
@@ -1,4 +1,4 @@
-/*	$NetBSD: xform_ipip.c,v 1.26 2011/02/18 20:40:58 drochner Exp $	*/
+/*	$NetBSD: xform_ipip.c,v 1.27 2011/06/06 16:48:35 drochner Exp $	*/
 /*	$FreeBSD: src/sys/netipsec/xform_ipip.c,v 1.3.2.1 2003/01/24 05:11:36 sam Exp $	*/
 /*	$OpenBSD: ip_ipip.c,v 1.25 2002/06/10 18:04:55 itojun Exp $ */
 
@@ -39,7 +39,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: xform_ipip.c,v 1.26 2011/02/18 20:40:58 drochner Exp $");
+__KERNEL_RCSID(0, "$NetBSD: xform_ipip.c,v 1.27 2011/06/06 16:48:35 drochner Exp $");
 
 /*
  * IP-inside-IP processing
@@ -203,7 +203,6 @@
 	struct ip6_hdr *ip6 = NULL;
 	u_int8_t itos;
 #endif
-	u_int8_t nxt;
 	int isr;
 	u_int8_t otos;
 	u_int8_t v;
@@ -322,14 +321,12 @@
 #ifdef INET
     	case 4:
                 ipo = mtod(m, struct ip *);
-                nxt = ipo->ip_p;
 		ip_ecn_egress(ip4_ipsec_ecn, &otos, &ipo->ip_tos);
                 break;
 #endif /* INET */
 #ifdef INET6
     	case 6:
                 ip6 = (struct ip6_hdr *) ipo;
-                nxt = ip6->ip6_nxt;
 		itos = (ntohl(ip6->ip6_flow) >> 20) & 0xff;
 		ip_ecn_egress(ip6_ipsec_ecn, &otos, &itos);
 		ip6->ip6_flow &= ~htonl(0xff << 20);
@@ -549,12 +546,14 @@
 			goto bad;
 		}
 
-		/* scoped address handling */
-		ip6 = mtod(m, struct ip6_hdr *);
-		if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_src))
-			ip6->ip6_src.s6_addr16[1] = 0;
-		if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_dst))
-			ip6->ip6_dst.s6_addr16[1] = 0;
+		if (tp == (IPV6_VERSION >> 4)) {
+			/* scoped address handling */
+			ip6 = mtod(m, struct ip6_hdr *);
+			if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_src))
+				ip6->ip6_src.s6_addr16[1] = 0;
+			if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_dst))
+				ip6->ip6_dst.s6_addr16[1] = 0;
+		}
 
 		M_PREPEND(m, sizeof(struct ip6_hdr), M_DONTWAIT);
 		if (m == 0) {
@@ -573,6 +572,10 @@
 		ip6o->ip6_hlim = ip_defttl;
 		ip6o->ip6_dst = saidx->dst.sin6.sin6_addr;
 		ip6o->ip6_src = saidx->src.sin6.sin6_addr;
+		if (IN6_IS_SCOPE_LINKLOCAL(&ip6o->ip6_dst))
+			ip6o->ip6_dst.s6_addr16[1] = htons(saidx->dst.sin6.sin6_scope_id);
+		if (IN6_IS_SCOPE_LINKLOCAL(&ip6o->ip6_src))
+			ip6o->ip6_src.s6_addr16[1] = htons(saidx->src.sin6.sin6_scope_id);
 
 #ifdef INET
 		if (tp == IPVERSION) {
@@ -636,7 +639,7 @@
 			tdb->tdb_cur_bytes +=
 			    m->m_pkthdr.len - sizeof(struct ip6_hdr);
 #endif
-		IPIP_STATADD(IPIP_STAT_IBYTES,
+		IPIP_STATADD(IPIP_STAT_OBYTES,
 		    m->m_pkthdr.len - sizeof(struct ip6_hdr));
 	}
 #endif /* INET6 */