From 7d617251ccf3bd1070412da64297d4297326750f Mon Sep 17 00:00:00 2001
From: pjd <pjd@FreeBSD.org>
Date: Thu, 23 Mar 2006 23:26:34 +0000
Subject: [PATCH] Allow to use fast_ipsec(4) on debug.mpsafenet=0 and
 INVARIANTS-enabled systems. Without the change it will panic on assertions.

MFC after:	2 weeks
---
 sys/netipsec/xform_ah.c     | 21 ++++++++++++++++-----
 sys/netipsec/xform_esp.c    | 17 ++++++++++++++---
 sys/netipsec/xform_ipcomp.c | 17 ++++++++++++++---
 3 files changed, 44 insertions(+), 11 deletions(-)

diff --git a/sys/netipsec/xform_ah.c b/sys/netipsec/xform_ah.c
index 3b1f66538fb1..862134f78fa2 100644
--- a/sys/netipsec/xform_ah.c
+++ b/sys/netipsec/xform_ah.c
@@ -734,6 +734,8 @@ ah_input_cb(struct cryptop *crp)
 	caddr_t ptr;
 	int authsize;
 
+	NET_LOCK_GIANT();
+
 	crd = crp->crp_desc;
 
 	tc = (struct tdb_crypto *) crp->crp_opaque;
@@ -764,8 +766,11 @@ ah_input_cb(struct cryptop *crp)
 		if (sav->tdb_cryptoid != 0)
 			sav->tdb_cryptoid = crp->crp_sid;
 
-		if (crp->crp_etype == EAGAIN)
-			return crypto_dispatch(crp);
+		if (crp->crp_etype == EAGAIN) {
+			error = crypto_dispatch(crp);
+			NET_UNLOCK_GIANT();
+			return error;
+		}
 
 		ahstat.ahs_noxform++;
 		DPRINTF(("%s: crypto error %d\n", __func__, crp->crp_etype));
@@ -857,7 +862,7 @@ ah_input_cb(struct cryptop *crp)
 	IPSEC_COMMON_INPUT_CB(m, sav, skip, protoff, mtag);
 
 	KEY_FREESAV(&sav);
-
+	NET_UNLOCK_GIANT();
 	return error;
 bad:
 	if (sav)
@@ -868,6 +873,7 @@ bad:
 		free(tc, M_XDATA);
 	if (crp != NULL)
 		crypto_freereq(crp);
+	NET_UNLOCK_GIANT();
 	return error;
 }
 
@@ -1114,6 +1120,8 @@ ah_output_cb(struct cryptop *crp)
 	caddr_t ptr;
 	int err;
 
+	NET_LOCK_GIANT();
+
 	tc = (struct tdb_crypto *) crp->crp_opaque;
 	IPSEC_ASSERT(tc != NULL, ("null opaque data area!"));
 	skip = tc->tc_skip;
@@ -1140,7 +1148,9 @@ ah_output_cb(struct cryptop *crp)
 		if (crp->crp_etype == EAGAIN) {
 			KEY_FREESAV(&sav);
 			IPSECREQUEST_UNLOCK(isr);
-			return crypto_dispatch(crp);
+			error = crypto_dispatch(crp);
+			NET_UNLOCK_GIANT();
+			return error;
 		}
 
 		ahstat.ahs_noxform++;
@@ -1172,7 +1182,7 @@ ah_output_cb(struct cryptop *crp)
 	err = ipsec_process_done(m, isr);
 	KEY_FREESAV(&sav);
 	IPSECREQUEST_UNLOCK(isr);
-
+	NET_UNLOCK_GIANT();
 	return err;
 bad:
 	if (sav)
@@ -1182,6 +1192,7 @@ bad:
 		m_freem(m);
 	free(tc, M_XDATA);
 	crypto_freereq(crp);
+	NET_UNLOCK_GIANT();
 	return error;
 }
 
diff --git a/sys/netipsec/xform_esp.c b/sys/netipsec/xform_esp.c
index d9c013b70f7a..107dccf3443f 100644
--- a/sys/netipsec/xform_esp.c
+++ b/sys/netipsec/xform_esp.c
@@ -460,6 +460,8 @@ esp_input_cb(struct cryptop *crp)
 	struct secasindex *saidx;
 	caddr_t ptr;
 
+	NET_LOCK_GIANT();
+
 	crd = crp->crp_desc;
 	IPSEC_ASSERT(crd != NULL, ("null crypto descriptor!"));
 
@@ -496,7 +498,9 @@ esp_input_cb(struct cryptop *crp)
 
 		if (crp->crp_etype == EAGAIN) {
 			KEY_FREESAV(&sav);
-			return crypto_dispatch(crp);
+			error = crypto_dispatch(crp);
+			NET_UNLOCK_GIANT();
+			return error;
 		}
 
 		espstat.esps_noxform++;
@@ -625,6 +629,7 @@ esp_input_cb(struct cryptop *crp)
 	IPSEC_COMMON_INPUT_CB(m, sav, skip, protoff, mtag);
 
 	KEY_FREESAV(&sav);
+	NET_UNLOCK_GIANT();
 	return error;
 bad:
 	if (sav)
@@ -635,6 +640,7 @@ bad:
 		free(tc, M_XDATA);
 	if (crp != NULL)
 		crypto_freereq(crp);
+	NET_UNLOCK_GIANT();
 	return error;
 }
 
@@ -881,6 +887,8 @@ esp_output_cb(struct cryptop *crp)
 	struct mbuf *m;
 	int err, error;
 
+	NET_LOCK_GIANT();
+
 	tc = (struct tdb_crypto *) crp->crp_opaque;
 	IPSEC_ASSERT(tc != NULL, ("null opaque data area!"));
 	m = (struct mbuf *) crp->crp_buf;
@@ -908,7 +916,9 @@ esp_output_cb(struct cryptop *crp)
 		if (crp->crp_etype == EAGAIN) {
 			KEY_FREESAV(&sav);
 			IPSECREQUEST_UNLOCK(isr);
-			return crypto_dispatch(crp);
+			error = crypto_dispatch(crp);
+			NET_UNLOCK_GIANT();
+			return error;
 		}
 
 		espstat.esps_noxform++;
@@ -936,7 +946,7 @@ esp_output_cb(struct cryptop *crp)
 	err = ipsec_process_done(m, isr);
 	KEY_FREESAV(&sav);
 	IPSECREQUEST_UNLOCK(isr);
-
+	NET_UNLOCK_GIANT();
 	return err;
 bad:
 	if (sav)
@@ -946,6 +956,7 @@ bad:
 		m_freem(m);
 	free(tc, M_XDATA);
 	crypto_freereq(crp);
+	NET_UNLOCK_GIANT();
 	return error;
 }
 
diff --git a/sys/netipsec/xform_ipcomp.c b/sys/netipsec/xform_ipcomp.c
index 1ad6c492eb62..6885584b5f98 100644
--- a/sys/netipsec/xform_ipcomp.c
+++ b/sys/netipsec/xform_ipcomp.c
@@ -219,6 +219,8 @@ ipcomp_input_cb(struct cryptop *crp)
 	u_int8_t nproto;
 	caddr_t addr;
 
+	NET_LOCK_GIANT();
+
 	crd = crp->crp_desc;
 
 	tc = (struct tdb_crypto *) crp->crp_opaque;
@@ -249,7 +251,9 @@ ipcomp_input_cb(struct cryptop *crp)
 
 		if (crp->crp_etype == EAGAIN) {
 			KEY_FREESAV(&sav);
-			return crypto_dispatch(crp);
+			error = crypto_dispatch(crp);
+			NET_UNLOCK_GIANT();
+			return error;
 		}
 
 		ipcompstat.ipcomps_noxform++;
@@ -302,6 +306,7 @@ ipcomp_input_cb(struct cryptop *crp)
 	IPSEC_COMMON_INPUT_CB(m, sav, skip, protoff, NULL);
 
 	KEY_FREESAV(&sav);
+	NET_UNLOCK_GIANT();
 	return error;
 bad:
 	if (sav)
@@ -312,6 +317,7 @@ bad:
 		free(tc, M_XDATA);
 	if (crp)
 		crypto_freereq(crp);
+	NET_UNLOCK_GIANT();
 	return error;
 }
 
@@ -493,6 +499,8 @@ ipcomp_output_cb(struct cryptop *crp)
 	struct mbuf *m;
 	int error, skip, rlen;
 
+	NET_LOCK_GIANT();
+
 	tc = (struct tdb_crypto *) crp->crp_opaque;
 	IPSEC_ASSERT(tc != NULL, ("null opaque data area!"));
 	m = (struct mbuf *) crp->crp_buf;
@@ -519,7 +527,9 @@ ipcomp_output_cb(struct cryptop *crp)
 		if (crp->crp_etype == EAGAIN) {
 			KEY_FREESAV(&sav);
 			IPSECREQUEST_UNLOCK(isr);
-			return crypto_dispatch(crp);
+			error = crypto_dispatch(crp);
+			NET_UNLOCK_GIANT();
+			return error;
 		}
 		ipcompstat.ipcomps_noxform++;
 		DPRINTF(("%s: crypto error %d\n", __func__, crp->crp_etype));
@@ -572,7 +582,7 @@ ipcomp_output_cb(struct cryptop *crp)
 	error = ipsec_process_done(m, isr);
 	KEY_FREESAV(&sav);
 	IPSECREQUEST_UNLOCK(isr);
-
+	NET_UNLOCK_GIANT();
 	return error;
 bad:
 	if (sav)
@@ -582,6 +592,7 @@ bad:
 		m_freem(m);
 	free(tc, M_XDATA);
 	crypto_freereq(crp);
+	NET_UNLOCK_GIANT();
 	return error;
 }