Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 14 Nov 2014 18:20:09 GMT
From:      John-Mark Gurney <jmg@FreeBSD.org>
To:        Perforce Change Reviews <perforce@FreeBSD.org>
Subject:   PERFORCE change 1202823 for review
Message-ID:  <201411141820.sAEIK90l091870@skunkworks.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://p4web.freebsd.org/@@1202823?ac=10

Change 1202823 by jmg@jmg_carbon2 on 2014/11/14 18:19:46

	fix from ae for fixing IPv6 transport ICMP...

Affected files ...

.. //depot/projects/opencrypto/sys/netipsec/ipsec_input.c#4 edit

Differences ...

==== //depot/projects/opencrypto/sys/netipsec/ipsec_input.c#4 (text+ko) ====

@@ -432,7 +432,7 @@
 	}
 #ifdef INET6
 	/* IPv6-in-IP encapsulation. */
-	if (prot == IPPROTO_IPV6 &&
+	else if (prot == IPPROTO_IPV6 &&
 	    saidx->mode != IPSEC_MODE_TRANSPORT) {
 
 		if (m->m_pkthdr.len - skip < sizeof(struct ip6_hdr)) {
@@ -469,6 +469,15 @@
 #endif /* notyet */
 	}
 #endif /* INET6 */
+	else if (prot != IPPROTO_IPV6 && saidx->mode == IPSEC_MODE_ANY) {
+		/*
+		 * When mode is wildcard, inner protocol is IPv6 and
+		 * we have no INET6 support - drop this packet a bit later.
+		 * In other cases we assume transport mode and outer
+		 * header was already stripped in xform_xxx_cb.
+		 */
+		prot = IPPROTO_IPIP;
+	}
 
 	/*
 	 * Record what we've done to the packet (under what SA it was
@@ -664,11 +673,11 @@
 	}
 
 	ip6 = mtod(m, struct ip6_hdr *);
-	ip6->ip6_plen = htons(m->m_pkthdr.len - sizeof(struct ip6_hdr));
+	ip6->ip6_plen = htons(m->m_pkthdr.len);
 
 	/* Save protocol */
-	prot = 0;
-	m_copydata(m, protoff, 1, (unsigned char *) &prot);
+	m_copydata(m, protoff, 1, &nxt8);
+	prot = nxt8;
 
 #ifdef DEV_ENC
 	if_inc_counter(encif, IFCOUNTER_IPACKETS, 1);
@@ -686,32 +695,33 @@
 			return (error);
 #endif /* DEV_ENC */
 
-#ifdef INET
-	/* IP-in-IP encapsulation */
-	if (prot == IPPROTO_IPIP) {
-		if (m->m_pkthdr.len - skip < sizeof(struct ip)) {
+	/* IPv6-in-IP encapsulation */
+	if (prot == IPPROTO_IPV6 &&
+	    saidx->mode != IPSEC_MODE_TRANSPORT) {
+		if (m->m_pkthdr.len - skip < sizeof(struct ip6_hdr)) {
 			IPSEC_ISTAT(sproto, hdrops);
 			error = EINVAL;
 			goto bad;
 		}
-		/* ipn will now contain the inner IPv4 header */
-	 	m_striphdr(m, 0, skip);
+		/* ip6n will now contain the inner IPv6 header. */
+		m_striphdr(m, 0, skip);
 		skip = 0;
 #ifdef notyet
 		/*
 		 * Check that the inner source address is the same as
 		 * the proxy address, if available.
 		 */
-		if ((saidx->proxy.sa.sa_family == AF_INET &&
-		    saidx->proxy.sin.sin_addr.s_addr != INADDR_ANY &&
-		    ipn.ip_src.s_addr != saidx->proxy.sin.sin_addr.s_addr) ||
-		    (saidx->proxy.sa.sa_family != AF_INET &&
+		if ((saidx->proxy.sa.sa_family == AF_INET6 &&
+		    !IN6_IS_ADDR_UNSPECIFIED(&saidx->proxy.sin6.sin6_addr) &&
+		    !IN6_ARE_ADDR_EQUAL(&ip6n.ip6_src,
+			&saidx->proxy.sin6.sin6_addr)) ||
+		    (saidx->proxy.sa.sa_family != AF_INET6 &&
 			saidx->proxy.sa.sa_family != 0)) {
 
 			DPRINTF(("%s: inner source address %s doesn't "
 			    "correspond to expected proxy source %s, "
 			    "SA %s/%08lx\n", __func__,
-			    inet_ntoa4(ipn.ip_src),
+			    ip6_sprintf(ip6buf, &ip6n.ip6_src),
 			    ipsec_address(&saidx->proxy),
 			    ipsec_address(&saidx->dst),
 			    (u_long) ntohl(sav->spi)));
@@ -722,33 +732,33 @@
 		}
 #endif /* notyet */
 	}
-#endif /* INET */
-	/* IPv6-in-IP encapsulation */
-	if (prot == IPPROTO_IPV6) {
-		if (m->m_pkthdr.len - skip < sizeof(struct ip6_hdr)) {
+#ifdef INET
+	/* IP-in-IP encapsulation */
+	else if (prot == IPPROTO_IPIP &&
+	    saidx->mode != IPSEC_MODE_TRANSPORT) {
+		if (m->m_pkthdr.len - skip < sizeof(struct ip)) {
 			IPSEC_ISTAT(sproto, hdrops);
 			error = EINVAL;
 			goto bad;
 		}
-		/* ip6n will now contain the inner IPv6 header. */
-		m_striphdr(m, 0, skip);
+		/* ipn will now contain the inner IPv4 header */
+	 	m_striphdr(m, 0, skip);
 		skip = 0;
 #ifdef notyet
 		/*
 		 * Check that the inner source address is the same as
 		 * the proxy address, if available.
 		 */
-		if ((saidx->proxy.sa.sa_family == AF_INET6 &&
-		    !IN6_IS_ADDR_UNSPECIFIED(&saidx->proxy.sin6.sin6_addr) &&
-		    !IN6_ARE_ADDR_EQUAL(&ip6n.ip6_src,
-			&saidx->proxy.sin6.sin6_addr)) ||
-		    (saidx->proxy.sa.sa_family != AF_INET6 &&
+		if ((saidx->proxy.sa.sa_family == AF_INET &&
+		    saidx->proxy.sin.sin_addr.s_addr != INADDR_ANY &&
+		    ipn.ip_src.s_addr != saidx->proxy.sin.sin_addr.s_addr) ||
+		    (saidx->proxy.sa.sa_family != AF_INET &&
 			saidx->proxy.sa.sa_family != 0)) {
 
 			DPRINTF(("%s: inner source address %s doesn't "
 			    "correspond to expected proxy source %s, "
 			    "SA %s/%08lx\n", __func__,
-			    ip6_sprintf(ip6buf, &ip6n.ip6_src),
+			    inet_ntoa4(ipn.ip_src),
 			    ipsec_address(&saidx->proxy),
 			    ipsec_address(&saidx->dst),
 			    (u_long) ntohl(sav->spi)));
@@ -759,6 +769,10 @@
 		}
 #endif /* notyet */
 	}
+#endif /* INET */
+	else {
+		prot = IPPROTO_IPV6; /* for correct BPF processing */
+	}
 
 	/*
 	 * Record what we've done to the packet (under what SA it was
@@ -809,10 +823,6 @@
 	if ((error = ipsec_filter(&m, PFIL_IN, ENC_IN|ENC_AFTER)) != 0)
 		return (error);
 #endif /* DEV_ENC */
-	/* Retrieve new protocol */
-	/* We have stripped the IP6 header from the mbuf, we have to use the backuped proto value instead */
-	nxt8 = prot;
-
 	/*
 	 * See the end of ip6_input for this logic.
 	 * IPPROTO_IPV[46] case will be processed just like other ones



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201411141820.sAEIK90l091870>