svn commit: r274755 - in stable/10/sys: netinet6 netipsec

Andrey V. Elsukov ae at FreeBSD.org
Thu Nov 20 18:49:13 UTC 2014


Author: ae
Date: Thu Nov 20 18:49:11 2014
New Revision: 274755
URL: https://svnweb.freebsd.org/changeset/base/274755

Log:
  MFC r274434:
    Fix ips_out_nosa errors accounting.
  
  MFC r274454:
    ipsec6_process_packet is called before ip6_output fixes ip6_plen.
    Update ip6_plen before bpf processing to be able see correct value.
  
  MFC r274455:
    We don't return sp pointer, thus NULL assignment isn't needed.
    And reference to sp will be freed at the end.
  
  MFC r274465:
    Remove redundant ip6_plen initialization.
  
  MFC r274466:
    Strip IP header only when we act in tunnel mode.
  
  MFC r274467:
    Count statistics for the specific address family.
  
  Sponsored by:	Yandex LLC

Modified:
  stable/10/sys/netinet6/ip6_ipsec.c
  stable/10/sys/netipsec/ipsec_input.c
  stable/10/sys/netipsec/ipsec_output.c
  stable/10/sys/netipsec/xform_ipip.c
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/sys/netinet6/ip6_ipsec.c
==============================================================================
--- stable/10/sys/netinet6/ip6_ipsec.c	Thu Nov 20 17:36:25 2014	(r274754)
+++ stable/10/sys/netinet6/ip6_ipsec.c	Thu Nov 20 18:49:11 2014	(r274755)
@@ -272,11 +272,7 @@ ip6_ipsec_output(struct mbuf **m, struct
 				/*
 				 * No IPsec processing is needed, free
 				 * reference to SP.
-				 *
-				 * NB: null pointer to avoid free at
-				 *     done: below.
 				 */
-				KEY_FREESP(&sp), sp = NULL;
 				goto done;
 			}
 		}

Modified: stable/10/sys/netipsec/ipsec_input.c
==============================================================================
--- stable/10/sys/netipsec/ipsec_input.c	Thu Nov 20 17:36:25 2014	(r274754)
+++ stable/10/sys/netipsec/ipsec_input.c	Thu Nov 20 18:49:11 2014	(r274755)
@@ -650,8 +650,8 @@ ipsec6_common_input_cb(struct mbuf *m, s
 	ip6->ip6_plen = htons(m->m_pkthdr.len - sizeof(struct ip6_hdr));
 
 	/* Save protocol */
-	prot = 0;
-	m_copydata(m, protoff, 1, (unsigned char *) &prot);
+	m_copydata(m, protoff, 1, &nxt8);
+	prot = nxt8;
 
 #ifdef DEV_ENC
 	encif->if_ipackets++;
@@ -669,32 +669,33 @@ ipsec6_common_input_cb(struct mbuf *m, s
 			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)));
@@ -705,33 +706,33 @@ ipsec6_common_input_cb(struct mbuf *m, s
 		}
 #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)));
@@ -742,6 +743,10 @@ ipsec6_common_input_cb(struct mbuf *m, s
 		}
 #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
@@ -792,10 +797,6 @@ ipsec6_common_input_cb(struct mbuf *m, s
 	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

Modified: stable/10/sys/netipsec/ipsec_output.c
==============================================================================
--- stable/10/sys/netipsec/ipsec_output.c	Thu Nov 20 17:36:25 2014	(r274754)
+++ stable/10/sys/netipsec/ipsec_output.c	Thu Nov 20 18:49:11 2014	(r274755)
@@ -164,11 +164,11 @@ ipsec_process_done(struct mbuf *m, struc
 	 * doing further processing.
 	 */
 	if (isr->next) {
-		IPSECSTAT_INC(ips_out_bundlesa);
 		/* XXX-BZ currently only support same AF bundles. */
 		switch (saidx->dst.sa.sa_family) {
 #ifdef INET
 		case AF_INET:
+			IPSECSTAT_INC(ips_out_bundlesa);
 			return ipsec4_process_packet(m, isr->next, 0, 0);
 			/* NOTREACHED */
 #endif
@@ -176,6 +176,7 @@ ipsec_process_done(struct mbuf *m, struc
 #ifdef INET6
 		case AF_INET6:
 			/* XXX */
+			IPSEC6STAT_INC(ips_out_bundlesa);
 			return ipsec6_process_packet(m, isr->next);
 			/* NOTREACHED */
 #endif /* INET6 */
@@ -357,7 +358,16 @@ again:
 		 * this packet because it is responsibility for
 		 * upper layer to retransmit the packet.
 		 */
-		IPSECSTAT_INC(ips_out_nosa);
+		switch(af) {
+		case AF_INET:
+			IPSECSTAT_INC(ips_out_nosa);
+			break;
+#ifdef INET6
+		case AF_INET6:
+			IPSEC6STAT_INC(ips_out_nosa);
+			break;
+#endif
+		}
 		goto bad;
 	}
 	sav = isr->sav;
@@ -639,6 +649,8 @@ ipsec6_process_packet(
 	sav = isr->sav;
 	dst = &sav->sah->saidx.dst;
 
+	ip6 = mtod(m, struct ip6_hdr *);
+	ip6->ip6_plen = htons(m->m_pkthdr.len - sizeof(*ip6));
 #ifdef DEV_ENC
 	encif->if_opackets++;
 	encif->if_obytes += m->m_pkthdr.len;
@@ -650,8 +662,6 @@ ipsec6_process_packet(
 		goto bad;
 #endif /* DEV_ENC */
 
-	ip6 = mtod(m, struct ip6_hdr *); /* XXX */
-
 	/* Do the appropriate encapsulation, if necessary */
 	if (isr->saidx.mode == IPSEC_MODE_TUNNEL || /* Tunnel requ'd */
 	    dst->sa.sa_family != AF_INET6 ||        /* PF mismatch */
@@ -674,9 +684,6 @@ ipsec6_process_packet(
 			goto bad;
 		}
 
-		ip6 = mtod(m, struct ip6_hdr *);
-		ip6->ip6_plen = htons(m->m_pkthdr.len - sizeof(*ip6));
-
 		/* Encapsulate the packet */
 		error = ipip_output(m, isr, &mp, 0, 0);
 		if (mp == NULL && !error) {

Modified: stable/10/sys/netipsec/xform_ipip.c
==============================================================================
--- stable/10/sys/netipsec/xform_ipip.c	Thu Nov 20 17:36:25 2014	(r274754)
+++ stable/10/sys/netipsec/xform_ipip.c	Thu Nov 20 18:49:11 2014	(r274755)
@@ -486,12 +486,9 @@ ipip_output(
 		ip6o->ip6_flow = 0;
 		ip6o->ip6_vfc &= ~IPV6_VERSION_MASK;
 		ip6o->ip6_vfc |= IPV6_VERSION;
-		ip6o->ip6_plen = htons(m->m_pkthdr.len);
 		ip6o->ip6_hlim = IPV6_DEFHLIM;
 		ip6o->ip6_dst = saidx->dst.sin6.sin6_addr;
 		ip6o->ip6_src = saidx->src.sin6.sin6_addr;
-
-		/* Fix payload length */
 		ip6o->ip6_plen = htons(m->m_pkthdr.len - sizeof(*ip6));
 
 		switch (tp) {


More information about the svn-src-stable-10 mailing list