aboutsummaryrefslogtreecommitdiff
path: root/sys/netipsec/xform_esp.c
diff options
context:
space:
mode:
authorJohn Baldwin <jhb@FreeBSD.org>2018-03-20 17:05:23 +0000
committerJohn Baldwin <jhb@FreeBSD.org>2018-03-20 17:05:23 +0000
commitfd40ecf3d4d2be5ca9c25c66fe572002214c65dd (patch)
tree8840319e930d0fd8024bfe07422c0746935452e7 /sys/netipsec/xform_esp.c
parent79e9552ebb62388d003c95e58c2aa1ce50ac6f0f (diff)
downloadsrc-fd40ecf3d4d2be5ca9c25c66fe572002214c65dd.tar.gz
src-fd40ecf3d4d2be5ca9c25c66fe572002214c65dd.zip
Set the proper vnet in IPsec callback functions.
When using hardware crypto engines, the callback functions used to handle an IPsec packet after it has been encrypted or decrypted can be invoked asynchronously from a worker thread that is not associated with a vnet. Extend 'struct xform_data' to include a vnet pointer and save the current vnet in this new member when queueing crypto requests in IPsec. In the IPsec callback routines, use the new member to set the current vnet while processing the modified packet. This fixes a panic when using hardware offload such as ccr(4) with IPsec after VIMAGE was enabled in GENERIC. Reported by: Sony Arpita Das and Harsh Jain @ Chelsio Reviewed by: bz MFC after: 1 week Sponsored by: Chelsio Communications Differential Revision: https://reviews.freebsd.org/D14763
Notes
Notes: svn path=/head/; revision=331248
Diffstat (limited to 'sys/netipsec/xform_esp.c')
-rw-r--r--sys/netipsec/xform_esp.c10
1 files changed, 10 insertions, 0 deletions
diff --git a/sys/netipsec/xform_esp.c b/sys/netipsec/xform_esp.c
index 7eaaab6ae3cb..c6212e41a82e 100644
--- a/sys/netipsec/xform_esp.c
+++ b/sys/netipsec/xform_esp.c
@@ -397,6 +397,7 @@ esp_input(struct mbuf *m, struct secasvar *sav, int skip, int protoff)
xd->protoff = protoff;
xd->skip = skip;
xd->cryptoid = cryptoid;
+ xd->vnet = curvnet;
/* Decryption descriptor */
IPSEC_ASSERT(crde != NULL, ("null esp crypto descriptor"));
@@ -455,6 +456,7 @@ esp_input_cb(struct cryptop *crp)
m = (struct mbuf *) crp->crp_buf;
xd = (struct xform_data *) crp->crp_opaque;
+ CURVNET_SET(xd->vnet);
sav = xd->sav;
skip = xd->skip;
protoff = xd->protoff;
@@ -469,6 +471,7 @@ esp_input_cb(struct cryptop *crp)
if (ipsec_updateid(sav, &crp->crp_sid, &cryptoid) != 0)
crypto_freesession(cryptoid);
xd->cryptoid = crp->crp_sid;
+ CURVNET_RESTORE();
return (crypto_dispatch(crp));
}
ESPSTAT_INC(esps_noxform);
@@ -603,8 +606,10 @@ esp_input_cb(struct cryptop *crp)
panic("%s: Unexpected address family: %d saidx=%p", __func__,
saidx->dst.sa.sa_family, saidx);
}
+ CURVNET_RESTORE();
return error;
bad:
+ CURVNET_RESTORE();
if (sav != NULL)
key_freesav(&sav);
if (m != NULL)
@@ -837,6 +842,7 @@ esp_output(struct mbuf *m, struct secpolicy *sp, struct secasvar *sav,
xd->sav = sav;
xd->idx = idx;
xd->cryptoid = cryptoid;
+ xd->vnet = curvnet;
/* Crypto operation descriptor. */
crp->crp_ilen = m->m_pkthdr.len; /* Total input length. */
@@ -882,6 +888,7 @@ esp_output_cb(struct cryptop *crp)
int error;
xd = (struct xform_data *) crp->crp_opaque;
+ CURVNET_SET(xd->vnet);
m = (struct mbuf *) crp->crp_buf;
sp = xd->sp;
sav = xd->sav;
@@ -895,6 +902,7 @@ esp_output_cb(struct cryptop *crp)
if (ipsec_updateid(sav, &crp->crp_sid, &cryptoid) != 0)
crypto_freesession(cryptoid);
xd->cryptoid = crp->crp_sid;
+ CURVNET_RESTORE();
return (crypto_dispatch(crp));
}
ESPSTAT_INC(esps_noxform);
@@ -940,8 +948,10 @@ esp_output_cb(struct cryptop *crp)
/* NB: m is reclaimed by ipsec_process_done. */
error = ipsec_process_done(m, sp, sav, idx);
+ CURVNET_RESTORE();
return (error);
bad:
+ CURVNET_RESTORE();
free(xd, M_XDATA);
crypto_freereq(crp);
key_freesav(&sav);