Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 23 Nov 2016 12:20:38 +0000 (UTC)
From:      "Andrey V. Elsukov" <ae@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r309056 - projects/ipsec/sys/netipsec
Message-ID:  <201611231220.uANCKcrZ014712@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: ae
Date: Wed Nov 23 12:20:38 2016
New Revision: 309056
URL: https://svnweb.freebsd.org/changeset/base/309056

Log:
  Update inbound IPsec packet processing for IPv4/IPv6.
  
  Use new xform_history structure to save information about used SA.
  Keep reference to SA until xform callback is not finished.
  If xform_input fails to queue crypto request, release reference.
  Otherwise xform callback will release it after sending mbuf to netisr.

Modified:
  projects/ipsec/sys/netipsec/ipsec_input.c

Modified: projects/ipsec/sys/netipsec/ipsec_input.c
==============================================================================
--- projects/ipsec/sys/netipsec/ipsec_input.c	Wed Nov 23 11:56:22 2016	(r309055)
+++ projects/ipsec/sys/netipsec/ipsec_input.c	Wed Nov 23 12:20:38 2016	(r309056)
@@ -209,7 +209,7 @@ ipsec_common_input(struct mbuf *m, int s
 	}
 
 	/* NB: only pass dst since key_allocsa follows RFC2401 */
-	sav = KEY_ALLOCSA(&dst_address, sproto, spi);
+	sav = key_allocsa(&dst_address, sproto, spi);
 	if (sav == NULL) {
 		DPRINTF(("%s: no key association found for SA %s/%08lx/%u\n",
 		    __func__, ipsec_address(&dst_address, buf, sizeof(buf)),
@@ -234,8 +234,9 @@ ipsec_common_input(struct mbuf *m, int s
 	 * everything else.
 	 */
 	error = (*sav->tdb_xform->xf_input)(m, sav, skip, protoff);
-	KEY_FREESAV(&sav);
-	return error;
+	if (error != 0)
+		key_freesav(&sav);
+	return (error);
 }
 
 #ifdef INET
@@ -309,21 +310,19 @@ int
 ipsec4_common_input_cb(struct mbuf *m, struct secasvar *sav, int skip,
     int protoff)
 {
-	char buf[INET6_ADDRSTRLEN];
+	char buf[IPSEC_ADDRSTRLEN];
 	struct ipsec_ctx_data ctx;
-	int prot, af, sproto, isr_prot;
-	struct ip *ip;
-	struct m_tag *mtag;
-	struct tdb_ident *tdbi;
+	struct xform_history *xh;
 	struct secasindex *saidx;
-	int error;
+	struct m_tag *mtag;
+	struct ip *ip;
+	int error, prot, af, sproto, isr_prot;
 #ifdef INET6
 #ifdef notyet
-	char ip6buf[INET6_ADDRSTRLEN];
+	char ip6buf[IPSEC_ADDRSTRLEN];
 #endif
 #endif
 
-	IPSEC_ASSERT(m != NULL, ("null mbuf"));
 	IPSEC_ASSERT(sav != NULL, ("null SA"));
 	IPSEC_ASSERT(sav->sah != NULL, ("null SAH"));
 	saidx = &sav->sah->saidx;
@@ -360,7 +359,7 @@ ipsec4_common_input_cb(struct mbuf *m, s
 	IPSEC_INIT_CTX(&ctx, &m, sav, AF_INET, IPSEC_ENC_BEFORE);
 	if ((error = ipsec_run_hhooks(&ctx, HHOOK_TYPE_IPSEC_IN)) != 0)
 		goto bad;
-	ip = mtod(m, struct ip *);
+	ip = mtod(m, struct ip *);	/* update pointer */
 
 	/* IP-in-IP encapsulation */
 	if (prot == IPPROTO_IPIP &&
@@ -445,8 +444,8 @@ ipsec4_common_input_cb(struct mbuf *m, s
 		/*
 		 * 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.
+		 * In other cases we assume transport mode. Set prot to
+		 * correctly choose netisr.
 		 */
 		prot = IPPROTO_IPIP;
 	}
@@ -457,7 +456,7 @@ ipsec4_common_input_cb(struct mbuf *m, s
 	 */
 	if (sproto != IPPROTO_IPCOMP) {
 		mtag = m_tag_get(PACKET_TAG_IPSEC_IN_DONE,
-		    sizeof(struct tdb_ident), M_NOWAIT);
+		    sizeof(struct xform_history), M_NOWAIT);
 		if (mtag == NULL) {
 			DPRINTF(("%s: failed to get tag\n", __func__));
 			IPSEC_ISTAT(sproto, hdrops);
@@ -465,14 +464,11 @@ ipsec4_common_input_cb(struct mbuf *m, s
 			goto bad;
 		}
 
-		tdbi = (struct tdb_ident *)(mtag + 1);
-		bcopy(&saidx->dst, &tdbi->dst, saidx->dst.sa.sa_len);
-		tdbi->proto = sproto;
-		tdbi->spi = sav->spi;
-		/* Cache those two for enc(4) in xform_ipip. */
-		tdbi->alg_auth = sav->alg_auth;
-		tdbi->alg_enc = sav->alg_enc;
-
+		xh = (struct xform_history *)(mtag + 1);
+		bcopy(&saidx->dst, &xh->dst, saidx->dst.sa.sa_len);
+		xh->spi = sav->spi;
+		xh->proto = sproto;
+		xh->mode = saidx->mode;
 		m_tag_prepend(m, mtag);
 	}
 
@@ -509,17 +505,20 @@ ipsec4_common_input_cb(struct mbuf *m, s
 	IPSEC_INIT_CTX(&ctx, &m, sav, af, IPSEC_ENC_AFTER);
 	if ((error = ipsec_run_hhooks(&ctx, HHOOK_TYPE_IPSEC_IN)) != 0)
 		goto bad;
+
 	error = netisr_queue_src(isr_prot, (uintptr_t)sav->spi, m);
+	key_freesav(&sav);
 	if (error) {
 		IPSEC_ISTAT(sproto, qfull);
 		DPRINTF(("%s: queue full; proto %u packet dropped\n",
 			__func__, sproto));
-		return error;
 	}
-	return 0;
+	return (error);
 bad:
-	m_freem(m);
-	return error;
+	key_freesav(&sav);
+	if (m != NULL)
+		m_freem(m);
+	return (error);
 }
 
 void
@@ -582,21 +581,20 @@ int
 ipsec6_common_input_cb(struct mbuf *m, struct secasvar *sav, int skip,
     int protoff)
 {
-	char buf[INET6_ADDRSTRLEN];
+	char buf[IPSEC_ADDRSTRLEN];
 	struct ipsec_ctx_data ctx;
-	int prot, af, sproto;
+	struct xform_history *xh;
+	struct secasindex *saidx;
 	struct ip6_hdr *ip6;
 	struct m_tag *mtag;
-	struct tdb_ident *tdbi;
-	struct secasindex *saidx;
+	int prot, af, sproto;
 	int nxt, isr_prot;
-	u_int8_t nxt8;
 	int error, nest;
+	uint8_t nxt8;
 #ifdef notyet
-	char ip6buf[INET6_ADDRSTRLEN];
+	char ip6buf[IPSEC_ADDRSTRLEN];
 #endif
 
-	IPSEC_ASSERT(m != NULL, ("null mbuf"));
 	IPSEC_ASSERT(sav != NULL, ("null SA"));
 	IPSEC_ASSERT(sav->sah != NULL, ("null SAH"));
 	saidx = &sav->sah->saidx;
@@ -620,12 +618,13 @@ ipsec6_common_input_cb(struct mbuf *m, s
 		goto bad;
 	}
 
-	ip6 = mtod(m, struct ip6_hdr *);
-	ip6->ip6_plen = htons(m->m_pkthdr.len - sizeof(struct ip6_hdr));
-
 	IPSEC_INIT_CTX(&ctx, &m, sav, af, IPSEC_ENC_BEFORE);
 	if ((error = ipsec_run_hhooks(&ctx, HHOOK_TYPE_IPSEC_IN)) != 0)
 		goto bad;
+
+	ip6 = mtod(m, struct ip6_hdr *);
+	ip6->ip6_plen = htons(m->m_pkthdr.len - sizeof(struct ip6_hdr));
+
 	/* Save protocol */
 	m_copydata(m, protoff, 1, &nxt8);
 	prot = nxt8;
@@ -715,7 +714,7 @@ ipsec6_common_input_cb(struct mbuf *m, s
 	 */
 	if (sproto != IPPROTO_IPCOMP) {
 		mtag = m_tag_get(PACKET_TAG_IPSEC_IN_DONE,
-		    sizeof(struct tdb_ident), M_NOWAIT);
+		    sizeof(struct xform_history), M_NOWAIT);
 		if (mtag == NULL) {
 			DPRINTF(("%s: failed to get tag\n", __func__));
 			IPSEC_ISTAT(sproto, hdrops);
@@ -723,20 +722,16 @@ ipsec6_common_input_cb(struct mbuf *m, s
 			goto bad;
 		}
 
-		tdbi = (struct tdb_ident *)(mtag + 1);
-		bcopy(&saidx->dst, &tdbi->dst, sizeof(union sockaddr_union));
-		tdbi->proto = sproto;
-		tdbi->spi = sav->spi;
-		/* Cache those two for enc(4) in xform_ipip. */
-		tdbi->alg_auth = sav->alg_auth;
-		tdbi->alg_enc = sav->alg_enc;
-
+		xh = (struct xform_history *)(mtag + 1);
+		bcopy(&saidx->dst, &xh->dst, saidx->dst.sa.sa_len);
+		xh->spi = sav->spi;
+		xh->proto = sproto;
+		xh->mode = saidx->mode;
 		m_tag_prepend(m, mtag);
 	}
 
 	key_sa_recordxfer(sav, m);
 
-
 #ifdef INET
 	if (prot == IPPROTO_IPIP)
 		af = AF_INET;
@@ -768,6 +763,7 @@ ipsec6_common_input_cb(struct mbuf *m, s
 			goto bad;
 		}
 		error = netisr_queue_src(isr_prot, (uintptr_t)sav->spi, m);
+		key_freesav(&sav);
 		if (error) {
 			IPSEC_ISTAT(sproto, qfull);
 			DPRINTF(("%s: queue full; proto %u packet dropped\n",
@@ -810,13 +806,14 @@ ipsec6_common_input_cb(struct mbuf *m, s
 		}
 		nxt = (*inet6sw[ip6_protox[nxt]].pr_input)(&m, &skip, nxt);
 	}
-	return 0;
+	key_freesav(&sav);
+	return (0);
 bad:
+	key_freesav(&sav);
 	if (m)
 		m_freem(m);
-	return error;
+	return (error);
 }
-
 void
 esp6_ctlinput(int cmd, struct sockaddr *sa, void *d)
 {
@@ -884,11 +881,11 @@ esp6_ctlinput(int cmd, struct sockaddr *
 			 * Check to see if we have a valid SA corresponding to
 			 * the address in the ICMP message payload.
 			 */
-			sav = KEY_ALLOCSA((union sockaddr_union *)sa,
+			sav = key_allocsa((union sockaddr_union *)sa,
 					IPPROTO_ESP, spi);
 			valid = (sav != NULL);
 			if (sav)
-				KEY_FREESAV(&sav);
+				key_freesav(&sav);
 
 			/* XXX Further validation? */
 



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