On Sat, Oct 23, 2021 at 03:08:29PM +0200, Tobias Heider wrote: > Now that we have removed all the legacy crypto offloading drivers we can > simplify the crypto framework API by ripping out the async callbacks. > > The diff below removes crypto_dispatch() and crypto_done() and replaces > them with crypto_invoke() which is blocking and only returns after the > operation has completed or an error occured. > The former callback functions are invoked directly by the consumer > (e.g. IPsec and softraid) instead of the crypto driver. > > The plan is to clean up the callers in a follow-up diff to remove > the callback functions alltogether. > > ok?
OK bluhm@ > diff --git a/sys/arch/amd64/amd64/aesni.c b/sys/arch/amd64/amd64/aesni.c > index 12ed40b37a8..86b3b1947ed 100644 > --- a/sys/arch/amd64/amd64/aesni.c > +++ b/sys/arch/amd64/amd64/aesni.c > @@ -699,7 +699,6 @@ aesni_process(struct cryptop *crp) > out: > smr_read_leave(); > crp->crp_etype = err; > - crypto_done(crp); > return (err); > } > > diff --git a/sys/arch/amd64/amd64/via.c b/sys/arch/amd64/amd64/via.c > index d6f04c3a88c..bb677399e01 100644 > --- a/sys/arch/amd64/amd64/via.c > +++ b/sys/arch/amd64/amd64/via.c > @@ -460,7 +460,6 @@ viac3_crypto_process(struct cryptop *crp) > } > out: > crp->crp_etype = err; > - crypto_done(crp); > return (err); > } > > diff --git a/sys/arch/arm64/arm64/cryptox.c b/sys/arch/arm64/arm64/cryptox.c > index 0b4ff183f04..82def0b8702 100644 > --- a/sys/arch/arm64/arm64/cryptox.c > +++ b/sys/arch/arm64/arm64/cryptox.c > @@ -486,6 +486,5 @@ cryptox_process(struct cryptop *crp) > out: > smr_read_leave(); > crp->crp_etype = err; > - crypto_done(crp); > return (err); > } > diff --git a/sys/arch/i386/i386/via.c b/sys/arch/i386/i386/via.c > index 9822bec8519..a627c9cb19c 100644 > --- a/sys/arch/i386/i386/via.c > +++ b/sys/arch/i386/i386/via.c > @@ -468,7 +468,6 @@ viac3_crypto_process(struct cryptop *crp) > } > out: > crp->crp_etype = err; > - crypto_done(crp); > return (err); > } > > diff --git a/sys/arch/i386/pci/glxsb.c b/sys/arch/i386/pci/glxsb.c > index 2dca0de55fb..212a343ecc2 100644 > --- a/sys/arch/i386/pci/glxsb.c > +++ b/sys/arch/i386/pci/glxsb.c > @@ -825,7 +825,6 @@ glxsb_crypto_process(struct cryptop *crp) > > out: > crp->crp_etype = err; > - crypto_done(crp); > splx(s); > return (err); > } > diff --git a/sys/arch/octeon/dev/octcrypto.c b/sys/arch/octeon/dev/octcrypto.c > index 26449679790..dbfdc2a0ac1 100644 > --- a/sys/arch/octeon/dev/octcrypto.c > +++ b/sys/arch/octeon/dev/octcrypto.c > @@ -658,7 +658,6 @@ out: > smr_read_leave(); > > crp->crp_etype = error; > - crypto_done(crp); > return error; > } > > diff --git a/sys/crypto/crypto.c b/sys/crypto/crypto.c > index c4bc6064a9b..dc1a34f0c38 100644 > --- a/sys/crypto/crypto.c > +++ b/sys/crypto/crypto.c > @@ -376,33 +376,6 @@ crypto_unregister(u_int32_t driverid, int alg) > return 0; > } > > -/* > - * Add crypto request to a queue, to be processed by a kernel thread. > - */ > -void > -crypto_dispatch(struct cryptop *crp) > -{ > - int lock = 1, s; > - u_int32_t hid; > - > - s = splvm(); > - hid = (crp->crp_sid >> 32) & 0xffffffff; > - if (hid < crypto_drivers_num) { > - if (crypto_drivers[hid].cc_flags & CRYPTOCAP_F_MPSAFE) > - lock = 0; > - } > - splx(s); > - > - /* XXXSMP crypto_invoke() is not MP safe */ > - lock = 1; > - > - if (lock) > - KERNEL_LOCK(); > - crypto_invoke(crp); > - if (lock) > - KERNEL_UNLOCK(); > -} > - > /* > * Dispatch a crypto request to the appropriate crypto devices. > */ > @@ -416,7 +389,6 @@ crypto_invoke(struct cryptop *crp) > > /* Sanity checks. */ > KASSERT(crp != NULL); > - KASSERT(crp->crp_callback != NULL); > > KERNEL_ASSERT_LOCKED(); > > @@ -466,7 +438,6 @@ crypto_invoke(struct cryptop *crp) > > crp->crp_etype = EAGAIN; > done: > - crypto_done(crp); > splx(s); > } > > @@ -518,14 +489,3 @@ crypto_init(void) > pool_init(&cryptop_pool, sizeof(struct cryptop), 0, IPL_VM, 0, > "cryptop", NULL); > } > - > -/* > - * Invoke the callback on behalf of the driver. > - */ > -void > -crypto_done(struct cryptop *crp) > -{ > - crp->crp_flags |= CRYPTO_F_DONE; > - > - crp->crp_callback(crp); > -} > diff --git a/sys/crypto/cryptodev.h b/sys/crypto/cryptodev.h > index 5caa5125a46..7a7b6ed78ca 100644 > --- a/sys/crypto/cryptodev.h > +++ b/sys/crypto/cryptodev.h > @@ -169,18 +169,14 @@ struct cryptop { > #define CRYPTO_F_IMBUF 0x0001 /* Input/output are mbuf chains, > otherwise contig */ > #define CRYPTO_F_IOV 0x0002 /* Input/output are uio */ > #define CRYPTO_F_MPSAFE 0x0004 /* Do not use kernel lock for callback > */ > -#define CRYPTO_F_DONE 0x0010 /* request completed */ > > void *crp_buf; /* Data to be processed */ > - void *crp_opaque; /* Opaque pointer, passed along */ > > struct cryptodesc *crp_desc; /* List of processing descriptors */ > struct cryptodesc crp_sdesc[2]; /* Static array for small ops */ > int crp_ndesc; /* Amount of descriptors to use */ > int crp_ndescalloc;/* Amount of descriptors allocated */ > > - void (*crp_callback)(struct cryptop *); /* Callback function */ > - > caddr_t crp_mac; > }; > > @@ -214,14 +210,12 @@ void crypto_init(void); > > int crypto_newsession(u_int64_t *, struct cryptoini *, int); > int crypto_freesession(u_int64_t); > -void crypto_dispatch(struct cryptop *); > int crypto_register(u_int32_t, int *, > int (*)(u_int32_t *, struct cryptoini *), int (*)(u_int64_t), > int (*)(struct cryptop *)); > int crypto_unregister(u_int32_t, int); > int32_t crypto_get_driverid(u_int8_t); > void crypto_invoke(struct cryptop *); > -void crypto_done(struct cryptop *); > > void cuio_copydata(struct uio *, int, int, caddr_t); > void cuio_copyback(struct uio *, int, int, const void *); > diff --git a/sys/crypto/cryptosoft.c b/sys/crypto/cryptosoft.c > index 3fc7e3ca8f0..fe60a1b5da2 100644 > --- a/sys/crypto/cryptosoft.c > +++ b/sys/crypto/cryptosoft.c > @@ -1129,7 +1129,6 @@ swcr_process(struct cryptop *crp) > } > > done: > - crypto_done(crp); > return 0; > } > > diff --git a/sys/dev/softraid_crypto.c b/sys/dev/softraid_crypto.c > index 867e9f61df5..1bded7b9ffb 100644 > --- a/sys/dev/softraid_crypto.c > +++ b/sys/dev/softraid_crypto.c > @@ -87,13 +87,13 @@ int > sr_crypto_meta_opt_handler_internal(struct sr_discipline *, > struct sr_crypto *, struct sr_meta_opt_hdr *); > int sr_crypto_meta_opt_handler(struct sr_discipline *, > struct sr_meta_opt_hdr *); > -void sr_crypto_write(struct cryptop *); > +void sr_crypto_write(struct sr_crypto_wu *); > int sr_crypto_rw(struct sr_workunit *); > int sr_crypto_dev_rw(struct sr_workunit *, struct sr_crypto_wu *); > void sr_crypto_done_internal(struct sr_workunit *, > struct sr_crypto *); > void sr_crypto_done(struct sr_workunit *); > -void sr_crypto_read(struct cryptop *); > +void sr_crypto_read(struct sr_crypto_wu *); > void sr_crypto_calculate_check_hmac_sha1(u_int8_t *, int, > u_int8_t *, int, u_char *); > void sr_crypto_hotplug(struct sr_discipline *, struct disk *, int); > @@ -322,7 +322,6 @@ sr_crypto_prepare(struct sr_workunit *wu, struct > sr_crypto *mdd_crypto, > keyndx = blkno >> SR_CRYPTO_KEY_BLKSHIFT; > crwu->cr_crp->crp_sid = mdd_crypto->scr_sid[keyndx]; > > - crwu->cr_crp->crp_opaque = crwu; > crwu->cr_crp->crp_ilen = xs->datalen; > crwu->cr_crp->crp_alloctype = M_DEVBUF; > crwu->cr_crp->crp_flags = CRYPTO_F_IOV; > @@ -1168,8 +1167,10 @@ sr_crypto_rw(struct sr_workunit *wu) > if (wu->swu_xs->flags & SCSI_DATA_OUT) { > mdd_crypto = &wu->swu_dis->mds.mdd_crypto; > crwu = sr_crypto_prepare(wu, mdd_crypto, 1); > - crwu->cr_crp->crp_callback = sr_crypto_write; > - crypto_dispatch(crwu->cr_crp); > + KERNEL_LOCK(); > + crypto_invoke(crwu->cr_crp); > + KERNEL_UNLOCK(); > + sr_crypto_write(crwu); > rv = crwu->cr_crp->crp_etype; > } else > rv = sr_crypto_dev_rw(wu, NULL); > @@ -1178,16 +1179,15 @@ sr_crypto_rw(struct sr_workunit *wu) > } > > void > -sr_crypto_write(struct cryptop *crp) > +sr_crypto_write(struct sr_crypto_wu *crwu) > { > - struct sr_crypto_wu *crwu = crp->crp_opaque; > struct sr_workunit *wu = &crwu->cr_wu; > int s; > > DNPRINTF(SR_D_INTR, "%s: sr_crypto_write: wu %p xs: %p\n", > DEVNAME(wu->swu_dis->sd_sc), wu, wu->swu_xs); > > - if (crp->crp_etype) { > + if (crwu->cr_crp->crp_etype) { > /* fail io */ > wu->swu_xs->error = XS_DRIVER_STUFFUP; > s = splbio(); > @@ -1246,10 +1246,12 @@ sr_crypto_done_internal(struct sr_workunit *wu, > struct sr_crypto *mdd_crypto) > /* If this was a successful read, initiate decryption of the data. */ > if (ISSET(xs->flags, SCSI_DATA_IN) && xs->error == XS_NOERROR) { > crwu = sr_crypto_prepare(wu, mdd_crypto, 0); > - crwu->cr_crp->crp_callback = sr_crypto_read; > - DNPRINTF(SR_D_INTR, "%s: sr_crypto_done: crypto_dispatch %p\n", > + DNPRINTF(SR_D_INTR, "%s: sr_crypto_done: crypto_invoke %p\n", > DEVNAME(wu->swu_dis->sd_sc), crwu->cr_crp); > - crypto_dispatch(crwu->cr_crp); > + KERNEL_LOCK(); > + crypto_invoke(crwu->cr_crp); > + KERNEL_UNLOCK(); > + sr_crypto_read(crwu); > return; > } > > @@ -1266,16 +1268,15 @@ sr_crypto_done(struct sr_workunit *wu) > } > > void > -sr_crypto_read(struct cryptop *crp) > +sr_crypto_read(struct sr_crypto_wu *crwu) > { > - struct sr_crypto_wu *crwu = crp->crp_opaque; > struct sr_workunit *wu = &crwu->cr_wu; > int s; > > DNPRINTF(SR_D_INTR, "%s: sr_crypto_read: wu %p xs: %p\n", > DEVNAME(wu->swu_dis->sd_sc), wu, wu->swu_xs); > > - if (crp->crp_etype) > + if (crwu->cr_crp->crp_etype) > wu->swu_xs->error = XS_DRIVER_STUFFUP; > > s = splbio(); > diff --git a/sys/dev/softraid_raid1c.c b/sys/dev/softraid_raid1c.c > index d23323bc5e4..77b2f1142b2 100644 > --- a/sys/dev/softraid_raid1c.c > +++ b/sys/dev/softraid_raid1c.c > @@ -58,7 +58,7 @@ void sr_raid1c_free_resources(struct sr_discipline > *sd); > int sr_raid1c_ioctl(struct sr_discipline *sd, struct bioc_discipline *bd); > int sr_raid1c_meta_opt_handler(struct sr_discipline *, > struct sr_meta_opt_hdr *); > -void sr_raid1c_write(struct cryptop *); > +void sr_raid1c_write(struct sr_crypto_wu *); > int sr_raid1c_rw(struct sr_workunit *); > int sr_raid1c_dev_rw(struct sr_workunit *, struct sr_crypto_wu *); > void sr_raid1c_done(struct sr_workunit *wu); > @@ -312,16 +312,15 @@ bad: > } > > void > -sr_raid1c_write(struct cryptop *crp) > +sr_raid1c_write(struct sr_crypto_wu *crwu) > { > - struct sr_crypto_wu *crwu = crp->crp_opaque; > struct sr_workunit *wu = &crwu->cr_wu; > int s; > > DNPRINTF(SR_D_INTR, "%s: sr_raid1c_write: wu %p xs: %p\n", > DEVNAME(wu->swu_dis->sd_sc), wu, wu->swu_xs); > > - if (crp->crp_etype) { > + if (crwu->cr_crp->crp_etype) { > /* fail io */ > wu->swu_xs->error = XS_DRIVER_STUFFUP; > s = splbio(); > @@ -358,8 +357,10 @@ sr_raid1c_rw(struct sr_workunit *wu) > !ISSET(wu->swu_flags, SR_WUF_REBUILD)) { > mdd_raid1c = &wu->swu_dis->mds.mdd_raid1c; > crwu = sr_crypto_prepare(wu, &mdd_raid1c->sr1c_crypto, 1); > - crwu->cr_crp->crp_callback = sr_raid1c_write; > - crypto_dispatch(crwu->cr_crp); > + KERNEL_LOCK(); > + crypto_invoke(crwu->cr_crp); > + KERNEL_UNLOCK(); > + sr_raid1c_write(crwu); > rv = crwu->cr_crp->crp_etype; > } else > rv = sr_raid1c_dev_rw(wu, NULL); > diff --git a/sys/netinet/ip_ah.c b/sys/netinet/ip_ah.c > index a10c2a7b7ba..7ce83a9730e 100644 > --- a/sys/netinet/ip_ah.c > +++ b/sys/netinet/ip_ah.c > @@ -531,7 +531,7 @@ ah_input(struct mbuf *m, struct tdb *tdb, int skip, int > protoff) > struct tdb_crypto *tc = NULL; > u_int32_t btsx, esn; > u_int8_t hl; > - int error, rplen; > + int error, rplen, clen; > u_int64_t ibytes; > #ifdef ENCDEBUG > char buf[INET6_ADDRSTRLEN]; > @@ -686,9 +686,7 @@ ah_input(struct mbuf *m, struct tdb *tdb, int skip, int > protoff) > crp->crp_ilen = m->m_pkthdr.len; /* Total input length. */ > crp->crp_flags = CRYPTO_F_IMBUF | CRYPTO_F_MPSAFE; > crp->crp_buf = (caddr_t)m; > - crp->crp_callback = ipsec_input_cb; > crp->crp_sid = tdb->tdb_cryptoid; > - crp->crp_opaque = (caddr_t)tc; > > /* These are passed as-is to the callback. */ > tc->tc_skip = skip; > @@ -699,7 +697,36 @@ ah_input(struct mbuf *m, struct tdb *tdb, int skip, int > protoff) > memcpy(&tc->tc_dst, &tdb->tdb_dst, sizeof(union sockaddr_union)); > tc->tc_rpl = tdb->tdb_rpl; > > - crypto_dispatch(crp); > + KERNEL_LOCK(); > + crypto_invoke(crp); > + while (crp->crp_etype == EAGAIN) { > + /* Reset the session ID */ > + if (tdb->tdb_cryptoid != 0) > + tdb->tdb_cryptoid = crp->crp_sid; > + crypto_invoke(crp); > + } > + KERNEL_UNLOCK(); > + if (crp->crp_etype) { > + DPRINTF("crypto error %d", crp->crp_etype); > + ipsecstat_inc(ipsec_noxform); > + ipsecstat_inc(ipsec_idrops); > + tdb->tdb_idrops++; > + error = crp->crp_etype; > + goto drop; > + } > + > + /* Length of data after processing */ > + clen = crp->crp_olen; > + > + /* Release the crypto descriptors */ > + crypto_freereq(crp); > + > + error = ah_input_cb(tdb, tc, m, clen); > + if (error) { > + ipsecstat_inc(ipsec_idrops); > + tdb->tdb_idrops++; > + } > + > return 0; > > drop: > @@ -893,7 +920,7 @@ ah_output(struct mbuf *m, struct tdb *tdb, int skip, int > protoff) > struct cryptop *crp = NULL; > u_int64_t replay64; > u_int16_t iplen; > - int error, rplen, roff; > + int error, rplen, roff, ilen, olen; > u_int8_t prot; > struct ah *ah; > #if NBPFILTER > 0 > @@ -1133,9 +1160,7 @@ ah_output(struct mbuf *m, struct tdb *tdb, int skip, > int protoff) > crp->crp_ilen = m->m_pkthdr.len; /* Total input length. */ > crp->crp_flags = CRYPTO_F_IMBUF | CRYPTO_F_MPSAFE; > crp->crp_buf = (caddr_t)m; > - crp->crp_callback = ipsec_output_cb; > crp->crp_sid = tdb->tdb_cryptoid; > - crp->crp_opaque = (caddr_t)tc; > > /* These are passed as-is to the callback. */ > tc->tc_skip = skip; > @@ -1145,7 +1170,36 @@ ah_output(struct mbuf *m, struct tdb *tdb, int skip, > int protoff) > tc->tc_rdomain = tdb->tdb_rdomain; > memcpy(&tc->tc_dst, &tdb->tdb_dst, sizeof(union sockaddr_union)); > > - crypto_dispatch(crp); > + KERNEL_LOCK(); > + crypto_invoke(crp); > + while (crp->crp_etype == EAGAIN) { > + /* Reset the session ID */ > + if (tdb->tdb_cryptoid != 0) > + tdb->tdb_cryptoid = crp->crp_sid; > + crypto_invoke(crp); > + } > + KERNEL_UNLOCK(); > + if (crp->crp_etype) { > + DPRINTF("crypto error %d", crp->crp_etype); > + ipsecstat_inc(ipsec_noxform); > + ipsecstat_inc(ipsec_odrops); > + tdb->tdb_odrops++; > + error = crp->crp_etype; > + goto drop; > + } > + > + ilen = crp->crp_ilen; > + olen = crp->crp_olen; > + > + /* Release the crypto descriptors */ > + crypto_freereq(crp); > + > + error = ah_output_cb(tdb, tc, m, ilen, olen); > + if (error) { > + ipsecstat_inc(ipsec_odrops); > + tdb->tdb_odrops++; > + } > + > return 0; > > drop: > diff --git a/sys/netinet/ip_esp.c b/sys/netinet/ip_esp.c > index 1b96a2b942d..1e4cfaafdcf 100644 > --- a/sys/netinet/ip_esp.c > +++ b/sys/netinet/ip_esp.c > @@ -347,7 +347,7 @@ esp_input(struct mbuf *m, struct tdb *tdb, int skip, int > protoff) > struct cryptodesc *crde = NULL, *crda = NULL; > struct cryptop *crp = NULL; > struct tdb_crypto *tc = NULL; > - int plen, alen, hlen, error; > + int plen, alen, hlen, error, clen; > u_int32_t btsx, esn; > #ifdef ENCDEBUG > char buf[INET6_ADDRSTRLEN]; > @@ -498,9 +498,7 @@ esp_input(struct mbuf *m, struct tdb *tdb, int skip, int > protoff) > crp->crp_ilen = m->m_pkthdr.len; /* Total input length */ > crp->crp_flags = CRYPTO_F_IMBUF | CRYPTO_F_MPSAFE; > crp->crp_buf = (caddr_t)m; > - crp->crp_callback = ipsec_input_cb; > crp->crp_sid = tdb->tdb_cryptoid; > - crp->crp_opaque = (caddr_t)tc; > > /* These are passed as-is to the callback */ > tc->tc_skip = skip; > @@ -526,7 +524,35 @@ esp_input(struct mbuf *m, struct tdb *tdb, int skip, int > protoff) > crde->crd_len = m->m_pkthdr.len - (skip + hlen + alen); > } > > - crypto_dispatch(crp); > + KERNEL_LOCK(); > + crypto_invoke(crp); > + while (crp->crp_etype == EAGAIN) { > + /* Reset the session ID */ > + if (tdb->tdb_cryptoid != 0) > + tdb->tdb_cryptoid = crp->crp_sid; > + crypto_invoke(crp); > + } > + KERNEL_UNLOCK(); > + if (crp->crp_etype) { > + DPRINTF("crypto error %d", crp->crp_etype); > + ipsecstat_inc(ipsec_noxform); > + ipsecstat_inc(ipsec_idrops); > + tdb->tdb_idrops++; > + error = crp->crp_etype; > + goto drop; > + } > + > + clen = crp->crp_olen; > + > + /* Release the crypto descriptors */ > + crypto_freereq(crp); > + > + error = esp_input_cb(tdb, tc, m, clen); > + if (error) { > + ipsecstat_inc(ipsec_idrops); > + tdb->tdb_idrops++; > + } > + > return 0; > > drop: > @@ -742,7 +768,7 @@ esp_output(struct mbuf *m, struct tdb *tdb, int skip, int > protoff) > { > const struct enc_xform *espx = tdb->tdb_encalgxform; > const struct auth_hash *esph = tdb->tdb_authalgxform; > - int ilen, hlen, rlen, padding, blks, alen, roff, error; > + int ilen, olen, hlen, rlen, padding, blks, alen, roff, error; > u_int64_t replay64; > u_int32_t replay; > struct mbuf *mi, *mo = (struct mbuf *) NULL; > @@ -980,8 +1006,6 @@ esp_output(struct mbuf *m, struct tdb *tdb, int skip, > int protoff) > crp->crp_ilen = m->m_pkthdr.len; /* Total input length. */ > crp->crp_flags = CRYPTO_F_IMBUF | CRYPTO_F_MPSAFE; > crp->crp_buf = (caddr_t)m; > - crp->crp_callback = ipsec_output_cb; > - crp->crp_opaque = (caddr_t)tc; > crp->crp_sid = tdb->tdb_cryptoid; > > if (esph) { > @@ -1010,7 +1034,36 @@ esp_output(struct mbuf *m, struct tdb *tdb, int skip, > int protoff) > crda->crd_len = m->m_pkthdr.len - (skip + alen); > } > > - crypto_dispatch(crp); > + KERNEL_LOCK(); > + crypto_invoke(crp); > + while (crp->crp_etype == EAGAIN) { > + /* Reset the session ID */ > + if (tdb->tdb_cryptoid != 0) > + tdb->tdb_cryptoid = crp->crp_sid; > + crypto_invoke(crp); > + } > + KERNEL_UNLOCK(); > + if (crp->crp_etype) { > + DPRINTF("crypto error %d", crp->crp_etype); > + ipsecstat_inc(ipsec_noxform); > + ipsecstat_inc(ipsec_odrops); > + tdb->tdb_odrops++; > + error = crp->crp_etype; > + goto drop; > + } > + > + ilen = crp->crp_ilen; > + olen = crp->crp_olen; > + > + /* Release the crypto descriptors */ > + crypto_freereq(crp); > + > + error = esp_output_cb(tdb, tc, m, ilen, olen); > + if (error) { > + ipsecstat_inc(ipsec_odrops); > + tdb->tdb_odrops++; > + } > + > return 0; > > drop: > diff --git a/sys/netinet/ip_ipcomp.c b/sys/netinet/ip_ipcomp.c > index 902955c9d6e..4837429fee6 100644 > --- a/sys/netinet/ip_ipcomp.c > +++ b/sys/netinet/ip_ipcomp.c > @@ -135,7 +135,7 @@ ipcomp_input(struct mbuf *m, struct tdb *tdb, int skip, > int protoff) > { > const struct comp_algo *ipcompx = tdb->tdb_compalgxform; > struct tdb_crypto *tc; > - int hlen; > + int hlen, error, clen; > > struct cryptodesc *crdc = NULL; > struct cryptop *crp; > @@ -172,9 +172,7 @@ ipcomp_input(struct mbuf *m, struct tdb *tdb, int skip, > int protoff) > crp->crp_ilen = m->m_pkthdr.len - (skip + hlen); > crp->crp_flags = CRYPTO_F_IMBUF | CRYPTO_F_MPSAFE; > crp->crp_buf = (caddr_t)m; > - crp->crp_callback = ipsec_input_cb; > crp->crp_sid = tdb->tdb_cryptoid; > - crp->crp_opaque = (caddr_t)tc; > > /* These are passed as-is to the callback */ > tc->tc_skip = skip; > @@ -184,7 +182,37 @@ ipcomp_input(struct mbuf *m, struct tdb *tdb, int skip, > int protoff) > tc->tc_rdomain = tdb->tdb_rdomain; > tc->tc_dst = tdb->tdb_dst; > > - crypto_dispatch(crp); > + KERNEL_LOCK(); > + crypto_invoke(crp); > + while (crp->crp_etype == EAGAIN) { > + /* Reset the session ID */ > + if (tdb->tdb_cryptoid != 0) > + tdb->tdb_cryptoid = crp->crp_sid; > + crypto_invoke(crp); > + } > + KERNEL_UNLOCK(); > + if (crp->crp_etype) { > + DPRINTF("crypto error %d", crp->crp_etype); > + ipsecstat_inc(ipsec_noxform); > + ipsecstat_inc(ipsec_idrops); > + tdb->tdb_idrops++; > + free(tc, M_XDATA, 0); > + m_freem(m); > + crypto_freereq(crp); > + return crp->crp_etype; > + } > + > + clen = crp->crp_olen; > + > + /* Release the crypto descriptors */ > + crypto_freereq(crp); > + > + error = ipcomp_input_cb(tdb, tc, m, clen); > + if (error) { > + ipsecstat_inc(ipsec_idrops); > + tdb->tdb_idrops++; > + } > + > return 0; > } > > @@ -319,7 +347,7 @@ int > ipcomp_output(struct mbuf *m, struct tdb *tdb, int skip, int protoff) > { > const struct comp_algo *ipcompx = tdb->tdb_compalgxform; > - int error, hlen; > + int error, hlen, ilen, olen; > struct cryptodesc *crdc = NULL; > struct cryptop *crp = NULL; > struct tdb_crypto *tc; > @@ -474,11 +502,40 @@ ipcomp_output(struct mbuf *m, struct tdb *tdb, int > skip, int protoff) > crp->crp_ilen = m->m_pkthdr.len; /* Total input length */ > crp->crp_flags = CRYPTO_F_IMBUF | CRYPTO_F_MPSAFE; > crp->crp_buf = (caddr_t)m; > - crp->crp_callback = ipsec_output_cb; > - crp->crp_opaque = (caddr_t)tc; > crp->crp_sid = tdb->tdb_cryptoid; > > - crypto_dispatch(crp); > + KERNEL_LOCK(); > + crypto_invoke(crp); > + while (crp->crp_etype == EAGAIN) { > + /* Reset the session ID */ > + if (tdb->tdb_cryptoid != 0) > + tdb->tdb_cryptoid = crp->crp_sid; > + crypto_invoke(crp); > + } > + KERNEL_UNLOCK(); > + if (crp->crp_etype) { > + DPRINTF("crypto error %d", crp->crp_etype); > + ipsecstat_inc(ipsec_noxform); > + ipsecstat_inc(ipsec_odrops); > + free(tc, M_XDATA, 0); > + tdb->tdb_odrops++; > + m_freem(m); > + crypto_freereq(crp); > + return crp->crp_etype; > + } > + > + ilen = crp->crp_ilen; > + olen = crp->crp_olen; > + > + /* Release the crypto descriptors */ > + crypto_freereq(crp); > + > + error = ipcomp_output_cb(tdb, tc, m, crp->crp_ilen, crp->crp_olen); > + if (error) { > + ipsecstat_inc(ipsec_odrops); > + tdb->tdb_odrops++; > + } > + > return 0; > > drop: > diff --git a/sys/netinet/ip_ipsp.h b/sys/netinet/ip_ipsp.h > index 9bb39465b57..63aea100e5d 100644 > --- a/sys/netinet/ip_ipsp.h > +++ b/sys/netinet/ip_ipsp.h > @@ -648,8 +648,6 @@ void ipsp_init(void); > void ipsec_init(void); > int ipsec_sysctl(int *, u_int, void *, size_t *, void *, size_t); > int ipsec_common_input(struct mbuf *, int, int, int, int, int); > -void ipsec_input_cb(struct cryptop *); > -void ipsec_output_cb(struct cryptop *); > int ipsec_common_input_cb(struct mbuf *, struct tdb *, int, int); > int ipsec_delete_policy(struct ipsec_policy *); > ssize_t ipsec_hdrsz(struct tdb *); > diff --git a/sys/netinet/ipsec_input.c b/sys/netinet/ipsec_input.c > index 2a9a378bde7..6fda85f24b7 100644 > --- a/sys/netinet/ipsec_input.c > +++ b/sys/netinet/ipsec_input.c > @@ -366,78 +366,6 @@ ipsec_common_input(struct mbuf *m, int skip, int > protoff, int af, int sproto, > return error; > } > > -void > -ipsec_input_cb(struct cryptop *crp) > -{ > - struct tdb_crypto *tc = (struct tdb_crypto *) crp->crp_opaque; > - struct mbuf *m = (struct mbuf *) crp->crp_buf; > - struct tdb *tdb = NULL; > - int clen, error; > - > - NET_ASSERT_LOCKED(); > - > - if (m == NULL) { > - DPRINTF("bogus returned buffer from crypto"); > - ipsecstat_inc(ipsec_crypto); > - goto drop; > - } > - > - tdb = gettdb(tc->tc_rdomain, tc->tc_spi, &tc->tc_dst, tc->tc_proto); > - if (tdb == NULL) { > - DPRINTF("TDB is expired while in crypto"); > - ipsecstat_inc(ipsec_notdb); > - goto drop; > - } > - > - /* Check for crypto errors */ > - if (crp->crp_etype) { > - if (crp->crp_etype == EAGAIN) { > - /* Reset the session ID */ > - if (tdb->tdb_cryptoid != 0) > - tdb->tdb_cryptoid = crp->crp_sid; > - crypto_dispatch(crp); > - return; > - } > - DPRINTF("crypto error %d", crp->crp_etype); > - ipsecstat_inc(ipsec_noxform); > - goto drop; > - } > - > - /* Length of data after processing */ > - clen = crp->crp_olen; > - > - /* Release the crypto descriptors */ > - crypto_freereq(crp); > - > - switch (tdb->tdb_sproto) { > - case IPPROTO_ESP: > - error = esp_input_cb(tdb, tc, m, clen); > - break; > - case IPPROTO_AH: > - error = ah_input_cb(tdb, tc, m, clen); > - break; > - case IPPROTO_IPCOMP: > - error = ipcomp_input_cb(tdb, tc, m, clen); > - break; > - default: > - panic("%s: unknown/unsupported security protocol %d", > - __func__, tdb->tdb_sproto); > - } > - if (error) { > - ipsecstat_inc(ipsec_idrops); > - tdb->tdb_idrops++; > - } > - return; > - > - drop: > - m_freem(m); > - free(tc, M_XDATA, 0); > - crypto_freereq(crp); > - ipsecstat_inc(ipsec_idrops); > - if (tdb != NULL) > - tdb->tdb_idrops++; > -} > - > /* > * IPsec input callback, called by the transform callback. Takes care of > * filtering and other sanity checks on the processed packet. > diff --git a/sys/netinet/ipsec_output.c b/sys/netinet/ipsec_output.c > index ed11171b543..9962e521dad 100644 > --- a/sys/netinet/ipsec_output.c > +++ b/sys/netinet/ipsec_output.c > @@ -377,81 +377,6 @@ ipsp_process_packet(struct mbuf *m, struct tdb *tdb, int > af, int tunalready) > return error; > } > > -/* > - * IPsec output callback, called directly by the crypto driver. > - */ > -void > -ipsec_output_cb(struct cryptop *crp) > -{ > - struct tdb_crypto *tc = (struct tdb_crypto *) crp->crp_opaque; > - struct mbuf *m = (struct mbuf *) crp->crp_buf; > - struct tdb *tdb = NULL; > - int error, ilen, olen; > - > - NET_ASSERT_LOCKED(); > - > - if (m == NULL) { > - DPRINTF("bogus returned buffer from crypto"); > - ipsecstat_inc(ipsec_crypto); > - goto drop; > - } > - > - tdb = gettdb(tc->tc_rdomain, tc->tc_spi, &tc->tc_dst, tc->tc_proto); > - if (tdb == NULL) { > - DPRINTF("TDB is expired while in crypto"); > - ipsecstat_inc(ipsec_notdb); > - goto drop; > - } > - > - /* Check for crypto errors. */ > - if (crp->crp_etype) { > - if (crp->crp_etype == EAGAIN) { > - /* Reset the session ID */ > - if (tdb->tdb_cryptoid != 0) > - tdb->tdb_cryptoid = crp->crp_sid; > - crypto_dispatch(crp); > - return; > - } > - DPRINTF("crypto error %d", crp->crp_etype); > - ipsecstat_inc(ipsec_noxform); > - goto drop; > - } > - > - olen = crp->crp_olen; > - ilen = crp->crp_ilen; > - > - /* Release crypto descriptors. */ > - crypto_freereq(crp); > - > - switch (tdb->tdb_sproto) { > - case IPPROTO_ESP: > - error = esp_output_cb(tdb, tc, m, ilen, olen); > - break; > - case IPPROTO_AH: > - error = ah_output_cb(tdb, tc, m, ilen, olen); > - break; > - case IPPROTO_IPCOMP: > - error = ipcomp_output_cb(tdb, tc, m, ilen, olen); > - break; > - default: > - panic("%s: unhandled security protocol %d", > - __func__, tdb->tdb_sproto); > - } > - if (error) { > - ipsecstat_inc(ipsec_odrops); > - tdb->tdb_odrops++; > - } > - return; > - > - drop: > - m_freem(m); > - free(tc, M_XDATA, 0); > - crypto_freereq(crp); > - ipsecstat_inc(ipsec_odrops); > - if (tdb != NULL) > - tdb->tdb_odrops++; > -} > - > /* > * Called by the IPsec output transform callbacks, to transmit the packet > * or do further processing, as necessary.