summaryrefslogtreecommitdiff
path: root/sys/netinet
diff options
context:
space:
mode:
authorAngelos D. Keromytis <angelos@cvs.openbsd.org>2000-06-06 04:49:30 +0000
committerAngelos D. Keromytis <angelos@cvs.openbsd.org>2000-06-06 04:49:30 +0000
commitee1d7cfceb2f06d438e37aca407be87faa58f4b4 (patch)
treed71518fa3ec86c889d2a68d9949a68c7d49f4cc1 /sys/netinet
parent28e7560d28b82c0a7c3e0c52c53482b4eb8ab322 (diff)
Get rid of tdb_ref, keep indirect pointer to TDB.
Diffstat (limited to 'sys/netinet')
-rw-r--r--sys/netinet/ip_ah.c167
-rw-r--r--sys/netinet/ip_esp.c127
-rw-r--r--sys/netinet/ip_ipsp.c13
-rw-r--r--sys/netinet/ip_ipsp.h12
4 files changed, 173 insertions, 146 deletions
diff --git a/sys/netinet/ip_ah.c b/sys/netinet/ip_ah.c
index 5fdbf4aef42..149b9d78ac1 100644
--- a/sys/netinet/ip_ah.c
+++ b/sys/netinet/ip_ah.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_ah.c,v 1.38 2000/06/01 05:40:41 angelos Exp $ */
+/* $OpenBSD: ip_ah.c,v 1.39 2000/06/06 04:49:29 angelos Exp $ */
/*
* The authors of this code are John Ioannidis (ji@tla.org),
@@ -471,6 +471,7 @@ int
ah_input(struct mbuf *m, struct tdb *tdb, int skip, int protoff)
{
struct auth_hash *ahx = (struct auth_hash *) tdb->tdb_authalgxform;
+ struct tdb_crypto *tc;
u_int32_t btsx;
u_int8_t hl;
int rplen;
@@ -573,15 +574,28 @@ ah_input(struct mbuf *m, struct tdb *tdb, int skip, int protoff)
crda->crd_key = tdb->tdb_amxkey;
crda->crd_klen = tdb->tdb_amxkeylen * 8;
+ /* Allocate IPsec-specific opaque crypto info */
+ MALLOC(tc, struct tdb_crypto *, sizeof(struct tdb_crypto),
+ M_XDATA, M_DONTWAIT);
+ if (tc == NULL)
+ {
+ m_freem(m);
+ crypto_freereq(crp);
+ DPRINTF(("ah_input(): failed to allocate tdb_crypto\n"));
+ ahstat.ahs_crypto++;
+ return ENOBUFS;
+ }
+
/*
* Save the authenticator, the skipped portion of the packet, and the
* AH header.
*/
- MALLOC(crp->crp_opaque4, caddr_t, skip + rplen + ahx->authsize,
+ MALLOC(tc->tc_ptr, caddr_t, skip + rplen + ahx->authsize,
M_XDATA, M_DONTWAIT);
- if (crp->crp_opaque4 == 0)
+ if (tc->tc_ptr == 0)
{
m_freem(m);
+ FREE(tc, M_XDATA);
crypto_freereq(crp);
DPRINTF(("ah_input(): failed to allocate auth array\n"));
ahstat.ahs_crypto++;
@@ -589,7 +603,7 @@ ah_input(struct mbuf *m, struct tdb *tdb, int skip, int protoff)
}
/* Save data */
- m_copydata(m, 0, skip + rplen + ahx->authsize, crp->crp_opaque4);
+ m_copydata(m, 0, skip + rplen + ahx->authsize, tc->tc_ptr);
/* Zeroize the authenticator on the packet */
m_copyback(m, skip + rplen, ahx->authsize, ipseczeroes);
@@ -599,25 +613,26 @@ ah_input(struct mbuf *m, struct tdb *tdb, int skip, int protoff)
skip, ahx->type, 0)) != 0)
{
/* mbuf will be free'd by callee */
- FREE(crp->crp_opaque4, M_XDATA);
-
+ FREE(tc->tc_ptr, M_XDATA);
+ FREE(tc, M_XDATA);
crypto_freereq(crp);
return btsx;
}
- tdb->tdb_ref++;
-
/* Crypto operation descriptor */
crp->crp_ilen = m->m_pkthdr.len; /* Total input length */
crp->crp_flags = CRYPTO_F_IMBUF;
crp->crp_buf = (caddr_t) m;
crp->crp_callback = (int (*) (struct cryptop *)) ah_input_cb;
crp->crp_sid = tdb->tdb_cryptoid;
+ crp->crp_opaque = (caddr_t) tc;
/* These are passed as-is to the callback */
- crp->crp_opaque1 = (caddr_t) tdb;
- (long) crp->crp_opaque2 = skip;
- (long) crp->crp_opaque3 = protoff;
+ tc->tc_skip = skip;
+ tc->tc_protoff = protoff;
+ tc->tc_spi = tdb->tdb_spi;
+ tc->tc_proto = tdb->tdb_sproto;
+ bcopy(&tdb->tdb_dst, &tc->tc_dst, sizeof(union sockaddr_union));
return crypto_dispatch(crp);
}
@@ -633,33 +648,30 @@ ah_input_cb(void *op)
struct mbuf *m1, *m0, *m;
struct cryptodesc *crd;
struct auth_hash *ahx;
+ struct tdb_crypto *tc;
struct cryptop *crp;
struct tdb *tdb;
+ caddr_t ptr = 0;
crp = (struct cryptop *) op;
crd = crp->crp_desc;
- tdb = (struct tdb *) crp->crp_opaque1;
- ahx = (struct auth_hash *) tdb->tdb_authalgxform;
- skip = (long) crp->crp_opaque2;
- protoff = (long) crp->crp_opaque3;
+
+ tc = (struct tdb_crypto *) crp->crp_opaque;
+ skip = tc->tc_skip;
+ protoff = tc->tc_protoff;
+ ptr = tc->tc_ptr;
m = (struct mbuf *) crp->crp_buf;
- /*
- * Check that the TDB is still valid -- not really an error, but
- * we need to handle it as such. It may happen if the TDB expired
- * or was deleted while there was a pending request in the crypto
- * queue.
- */
- if (tdb->tdb_flags & TDBF_INVALID)
+ tdb = gettdb(tc->tc_spi, &tc->tc_dst, tc->tc_proto);
+ FREE(tc, M_XDATA);
+ if (tdb == NULL)
{
- ahstat.ahs_invalid++;
- tdb_delete(tdb, 0, 0);
- error = ENXIO;
- DPRINTF(("ah_input_cb(): TDB expired while processing crypto\n"));
+ ahstat.ahs_notdb++;
+ DPRINTF(("ah_input_cb(): TDB is expired while in crypto"));
goto baddone;
}
- else
- tdb->tdb_ref--;
+
+ ahx = (struct auth_hash *) tdb->tdb_authalgxform;
/* Check for crypto errors */
if (crp->crp_etype)
@@ -668,10 +680,7 @@ ah_input_cb(void *op)
tdb->tdb_cryptoid = crp->crp_sid;
if (crp->crp_etype == EAGAIN)
- {
- tdb->tdb_ref++;
- return crypto_dispatch(crp);
- }
+ return crypto_dispatch(crp);
ahstat.ahs_noxform++;
DPRINTF(("ah_input_cb(): crypto error %d\n", crp->crp_etype));
@@ -697,7 +706,7 @@ ah_input_cb(void *op)
m_copydata(m, skip + rplen, ahx->authsize, calc);
/* Verify authenticator */
- if (bcmp(crp->crp_opaque4 + skip + rplen, calc, ahx->authsize))
+ if (bcmp(ptr + skip + rplen, calc, ahx->authsize))
{
DPRINTF(("ah_input(): authentication failed for packet in SA %s/%08x\n", ipsp_address(tdb->tdb_dst), ntohl(tdb->tdb_spi)));
ahstat.ahs_badauth++;
@@ -706,14 +715,14 @@ ah_input_cb(void *op)
}
/* Fix the Next Protocol field */
- ((u_int8_t *) crp->crp_opaque4)[protoff] =
- ((u_int8_t *) crp->crp_opaque4)[skip];
+ ((u_int8_t *) ptr)[protoff] =
+ ((u_int8_t *) ptr)[skip];
/* Copyback the saved (uncooked) network headers */
- m_copyback(m, 0, skip, crp->crp_opaque4);
+ m_copyback(m, 0, skip, ptr);
/* No longer needed */
- FREE(crp->crp_opaque4, M_XDATA);
+ FREE(ptr, M_XDATA);
crypto_freereq(crp);
/* Record the beginning of the AH header */
@@ -785,8 +794,8 @@ ah_input_cb(void *op)
m_freem(m);
/* We have to free this manually */
- if (crp && crp->crp_opaque4)
- FREE(crp->crp_opaque4, M_XDATA);
+ if (ptr)
+ FREE(ptr, M_XDATA);
crypto_freereq(crp);
@@ -802,6 +811,7 @@ ah_output(struct mbuf *m, struct tdb *tdb, struct mbuf **mp, int skip,
{
struct auth_hash *ahx = (struct auth_hash *) tdb->tdb_authalgxform;
struct cryptodesc *crda;
+ struct tdb_crypto *tc;
struct mbuf *mo, *mi;
struct cryptop *crp;
u_int16_t iplen;
@@ -996,10 +1006,23 @@ ah_output(struct mbuf *m, struct tdb *tdb, struct mbuf **mp, int skip,
crda->crd_key = tdb->tdb_amxkey;
crda->crd_klen = tdb->tdb_amxkeylen * 8;
+ /* Allocate IPsec-specific opaque crypto info */
+ MALLOC(tc, struct tdb_crypto *, sizeof(struct tdb_crypto), M_XDATA,
+ M_DONTWAIT);
+ if (tc == NULL)
+ {
+ m_freem(m);
+ crypto_freereq(crp);
+ DPRINTF(("ah_output(): failed to allocate tdb_crypto\n"));
+ ahstat.ahs_crypto++;
+ return ENOBUFS;
+ }
+
/* Save the skipped portion of the packet */
- MALLOC(crp->crp_opaque4, caddr_t, skip, M_XDATA, M_DONTWAIT);
- if (crp->crp_opaque4 == 0)
+ MALLOC(tc->tc_ptr, caddr_t, skip, M_XDATA, M_DONTWAIT);
+ if (tc->tc_ptr == 0)
{
+ FREE(tc, M_XDATA);
m_freem(m);
crypto_freereq(crp);
DPRINTF(("ah_output(): failed to allocate auth array\n"));
@@ -1007,7 +1030,7 @@ ah_output(struct mbuf *m, struct tdb *tdb, struct mbuf **mp, int skip,
return ENOBUFS;
}
else
- m_copydata(m, 0, skip, crp->crp_opaque4);
+ m_copydata(m, 0, skip, tc->tc_ptr);
/*
* Fix IP header length on the header used for authentication. We don't
@@ -1018,7 +1041,7 @@ ah_output(struct mbuf *m, struct tdb *tdb, struct mbuf **mp, int skip,
{
#ifdef INET
case AF_INET:
- bcopy(crp->crp_opaque4 + offsetof(struct ip, ip_len),
+ bcopy(tc->tc_ptr + offsetof(struct ip, ip_len),
(caddr_t) &iplen, sizeof(u_int16_t));
iplen = htons(ntohs(iplen) + rplen + ahx->authsize);
m_copyback(m, offsetof(struct ip, ip_len), sizeof(u_int16_t),
@@ -1028,7 +1051,7 @@ ah_output(struct mbuf *m, struct tdb *tdb, struct mbuf **mp, int skip,
#ifdef INET6
case AF_INET6:
- bcopy(crp->crp_opaque4 + offsetof(struct ip6_hdr, ip6_plen),
+ bcopy(tc->tc_ptr + offsetof(struct ip6_hdr, ip6_plen),
(caddr_t) &iplen, sizeof(u_int16_t));
iplen = htons(ntohs(iplen) + rplen + ahx->authsize);
m_copyback(m, offsetof(struct ip6_hdr, ip6_plen),
@@ -1037,19 +1060,18 @@ ah_output(struct mbuf *m, struct tdb *tdb, struct mbuf **mp, int skip,
#endif /* INET6 */
}
- tdb->tdb_ref++;
-
/* Update the Next Protocol field in the IP header and the saved data */
prot = IPPROTO_AH;
m_copyback(m, protoff, sizeof(u_int8_t), (caddr_t) &prot);
- ((u_int8_t *) crp->crp_opaque4)[protoff] = IPPROTO_AH;
+ ((u_int8_t *) tc->tc_ptr)[protoff] = IPPROTO_AH;
/* "Massage" the packet headers for crypto processing */
if ((len = ah_massage_headers(&m, tdb->tdb_dst.sa.sa_family,
skip, ahx->type, 1)) != 0)
{
/* mbuf will be free'd by callee */
- FREE(crp->crp_opaque4, M_XDATA);
+ FREE(tc->tc_ptr, M_XDATA);
+ FREE(tc, M_XDATA);
crypto_freereq(crp);
return len;
}
@@ -1060,11 +1082,14 @@ ah_output(struct mbuf *m, struct tdb *tdb, struct mbuf **mp, int skip,
crp->crp_buf = (caddr_t) m;
crp->crp_callback = (int (*) (struct cryptop *)) ah_output_cb;
crp->crp_sid = tdb->tdb_cryptoid;
+ crp->crp_opaque = (caddr_t) tc;
/* These are passed as-is to the callback */
- crp->crp_opaque1 = (caddr_t) tdb;
- (long) crp->crp_opaque2 = skip;
- (long) crp->crp_opaque3 = protoff;
+ tc->tc_skip = skip;
+ tc->tc_protoff = protoff;
+ tc->tc_spi = tdb->tdb_spi;
+ tc->tc_proto = tdb->tdb_sproto;
+ bcopy(&tdb->tdb_dst, &tc->tc_dst, sizeof(union sockaddr_union));
return crypto_dispatch(crp);
}
@@ -1076,32 +1101,27 @@ int
ah_output_cb(void *op)
{
int skip, protoff, error;
+ struct tdb_crypto *tc;
struct cryptop *crp;
struct tdb *tdb;
+ caddr_t ptr = 0;
struct mbuf *m;
crp = (struct cryptop *) op;
- tdb = (struct tdb *) crp->crp_opaque1;
- skip = (long) crp->crp_opaque2;
- protoff = (long) crp->crp_opaque3;
+ tc = (struct tdb_crypto *) crp->crp_opaque;
+ skip = tc->tc_skip;
+ protoff = tc->tc_protoff;
+ ptr = tc->tc_ptr;
m = (struct mbuf *) crp->crp_buf;
- /*
- * Check that the TDB is still valid -- not really an error, but
- * we need to handle it as such. It may happen if the TDB expired
- * or was deleted while there was a pending request in the crypto
- * queue.
- */
- if (tdb->tdb_flags & TDBF_INVALID)
+ tdb = gettdb(tc->tc_spi, &tc->tc_dst, tc->tc_proto);
+ FREE(tc, M_XDATA);
+ if (tdb == NULL)
{
- ahstat.ahs_invalid++;
- tdb_delete(tdb, 0, 0);
- error = ENXIO;
- DPRINTF(("ah_output_cb(): TDB expired while processing crypto\n"));
+ ahstat.ahs_notdb++;
+ DPRINTF(("ah_output_cb(): TDB is expired while in crypto\n"));
goto baddone;
}
- else
- tdb->tdb_ref--;
/* Check for crypto errors */
if (crp->crp_etype)
@@ -1110,10 +1130,7 @@ ah_output_cb(void *op)
tdb->tdb_cryptoid = crp->crp_sid;
if (crp->crp_etype == EAGAIN)
- {
- tdb->tdb_ref++;
- return crypto_dispatch(crp);
- }
+ return crypto_dispatch(crp);
ahstat.ahs_noxform++;
DPRINTF(("ah_output_cb(): crypto error %d\n", crp->crp_etype));
@@ -1131,10 +1148,10 @@ ah_output_cb(void *op)
}
/* Copy original headers (with the new protocol number) back in place */
- m_copyback(m, 0, skip, crp->crp_opaque4);
+ m_copyback(m, 0, skip, ptr);
/* No longer needed */
- FREE(crp->crp_opaque4, M_XDATA);
+ FREE(ptr, M_XDATA);
crypto_freereq(crp);
return ipsp_process_done(m, tdb);
@@ -1144,8 +1161,8 @@ ah_output_cb(void *op)
m_freem(m);
/* We have to free this manually */
- if (crp && crp->crp_opaque4)
- FREE(crp->crp_opaque4, M_XDATA);
+ if (ptr)
+ FREE(ptr, M_XDATA);
crypto_freereq(crp);
diff --git a/sys/netinet/ip_esp.c b/sys/netinet/ip_esp.c
index 2dde3a96d35..14901be6254 100644
--- a/sys/netinet/ip_esp.c
+++ b/sys/netinet/ip_esp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_esp.c,v 1.43 2000/06/01 05:40:41 angelos Exp $ */
+/* $OpenBSD: ip_esp.c,v 1.44 2000/06/06 04:49:29 angelos Exp $ */
/*
* The authors of this code are John Ioannidis (ji@tla.org),
@@ -278,6 +278,7 @@ esp_input(struct mbuf *m, struct tdb *tdb, int skip, int protoff)
{
struct auth_hash *esph = (struct auth_hash *) tdb->tdb_authalgxform;
struct enc_xform *espx = (struct enc_xform *) tdb->tdb_encalgxform;
+ struct tdb_crypto *tc;
int plen, alen, hlen;
u_int32_t btsx;
@@ -377,6 +378,18 @@ esp_input(struct mbuf *m, struct tdb *tdb, int skip, int protoff)
return ENOBUFS;
}
+ /* Get IPsec-specific opaque pointer */
+ MALLOC(tc, struct tdb_crypto *, sizeof(struct tdb_crypto),
+ M_XDATA, M_DONTWAIT);
+ if (tc == NULL)
+ {
+ m_freem(m);
+ crypto_freereq(crp);
+ DPRINTF(("esp_input(): failed to allocate tdb_crypto\n"));
+ espstat.esps_crypto++;
+ return ENOBUFS;
+ }
+
if (esph)
{
crda = crp->crp_desc;
@@ -392,9 +405,10 @@ esp_input(struct mbuf *m, struct tdb *tdb, int skip, int protoff)
crda->crd_klen = tdb->tdb_amxkeylen * 8;
/* Keep a copy of the authenticator */
- MALLOC(crp->crp_opaque4, caddr_t, alen, M_XDATA, M_DONTWAIT);
- if (crp->crp_opaque4 == 0)
+ MALLOC(tc->tc_ptr, caddr_t, alen, M_XDATA, M_DONTWAIT);
+ if (tc->tc_ptr == 0)
{
+ FREE(tc, M_XDATA);
m_freem(m);
crypto_freereq(crp);
DPRINTF(("esp_input(): failed to allocate auth array\n"));
@@ -403,24 +417,25 @@ esp_input(struct mbuf *m, struct tdb *tdb, int skip, int protoff)
}
/* Copy the authenticator */
- m_copydata(m, m->m_pkthdr.len - alen, alen, crp->crp_opaque4);
+ m_copydata(m, m->m_pkthdr.len - alen, alen, tc->tc_ptr);
}
else
crde = crp->crp_desc;
- tdb->tdb_ref++;
-
/* Crypto operation descriptor */
crp->crp_ilen = m->m_pkthdr.len; /* Total input length */
crp->crp_flags = CRYPTO_F_IMBUF;
crp->crp_buf = (caddr_t) m;
crp->crp_callback = (int (*) (struct cryptop *)) esp_input_cb;
crp->crp_sid = tdb->tdb_cryptoid;
+ crp->crp_opaque = (caddr_t) tc;
/* These are passed as-is to the callback */
- crp->crp_opaque1 = (caddr_t) tdb;
- (long) crp->crp_opaque2 = skip;
- (long) crp->crp_opaque3 = protoff;
+ tc->tc_skip = skip;
+ tc->tc_protoff = protoff;
+ tc->tc_spi = tdb->tdb_spi;
+ tc->tc_proto = tdb->tdb_sproto;
+ bcopy(&tdb->tdb_dst, &tc->tc_dst, sizeof(union sockaddr_union));
/* Decryption descriptor */
if (espx)
@@ -462,34 +477,31 @@ esp_input_cb(void *op)
struct cryptodesc *crd;
struct auth_hash *esph;
struct enc_xform *espx;
+ struct tdb_crypto *tc;
struct cryptop *crp;
struct tdb *tdb;
+ caddr_t ptr = 0;
crp = (struct cryptop *) op;
crd = crp->crp_desc;
- tdb = (struct tdb *) crp->crp_opaque1;
- esph = (struct auth_hash *) tdb->tdb_authalgxform;
- espx = (struct enc_xform *) tdb->tdb_encalgxform;
- skip = (long) crp->crp_opaque2;
- protoff = (long) crp->crp_opaque3;
+
+ tc = (struct tdb_crypto *) crp->crp_opaque;
+ skip = tc->tc_skip;
+ protoff = tc->tc_protoff;
+ ptr = tc->tc_ptr;
m = (struct mbuf *) crp->crp_buf;
- /*
- * Check that the TDB is still valid -- not really an error, but
- * we need to handle it as such. It may happen if the TDB expired
- * or was deleted while there was a pending request in the crypto
- * queue.
- */
- if (tdb->tdb_flags & TDBF_INVALID)
+ tdb = gettdb(tc->tc_spi, &tc->tc_dst, tc->tc_proto);
+ FREE(tc, M_XDATA);
+ if (tdb == NULL)
{
- espstat.esps_invalid++;
- tdb_delete(tdb, 0, 0);
- error = ENXIO;
- DPRINTF(("esp_input_cb(): TDB expired while processing crypto\n"));
+ espstat.esps_notdb++;
+ DPRINTF(("esp_input_cb(): TDB is expired while in crypto"));
goto baddone;
}
- else
- tdb->tdb_ref--;
+
+ esph = (struct auth_hash *) tdb->tdb_authalgxform;
+ espx = (struct enc_xform *) tdb->tdb_encalgxform;
/* Check for crypto errors */
if (crp->crp_etype)
@@ -499,10 +511,7 @@ esp_input_cb(void *op)
tdb->tdb_cryptoid = crp->crp_sid;
if (crp->crp_etype == EAGAIN)
- {
- tdb->tdb_ref++;
- return crypto_dispatch(crp);
- }
+ return crypto_dispatch(crp);
espstat.esps_noxform++;
DPRINTF(("esp_input_cb(): crypto error %d\n", crp->crp_etype));
@@ -523,11 +532,10 @@ esp_input_cb(void *op)
if (esph)
{
/* Copy the authenticator from the packet */
- m_copydata(m, m->m_pkthdr.len - esph->authsize,
- esph->authsize, aalg);
+ m_copydata(m, m->m_pkthdr.len - esph->authsize, esph->authsize, aalg);
/* Verify authenticator */
- if (bcmp(crp->crp_opaque4, aalg, esph->authsize))
+ if (bcmp(ptr, aalg, esph->authsize))
{
DPRINTF(("esp_input_cb(): authentication failed for packet in SA %s/%08x\n", ipsp_address(tdb->tdb_dst), ntohl(tdb->tdb_spi)));
espstat.esps_badauth++;
@@ -539,7 +547,7 @@ esp_input_cb(void *op)
m_adj(m, -(esph->authsize));
/* We have to manually free this */
- FREE(crp->crp_opaque4, M_XDATA);
+ FREE(ptr, M_XDATA);
}
/* Release the crypto descriptors */
@@ -650,8 +658,8 @@ esp_input_cb(void *op)
m_freem(m);
/* We have to manually free this */
- if (crp && crp->crp_opaque4)
- FREE(crp->crp_opaque4, M_XDATA);
+ if (ptr)
+ FREE(ptr, M_XDATA);
crypto_freereq(crp);
@@ -669,6 +677,7 @@ esp_output(struct mbuf *m, struct tdb *tdb, struct mbuf **mp, int skip,
struct auth_hash *esph = (struct auth_hash *) tdb->tdb_authalgxform;
int ilen, hlen, rlen, plen, padding, blks, alen;
struct mbuf *mi, *mo = (struct mbuf *) NULL;
+ struct tdb_crypto *tc;
unsigned char *pad;
u_int8_t prot;
@@ -920,14 +929,28 @@ esp_output(struct mbuf *m, struct tdb *tdb, struct mbuf **mp, int skip,
else
crda = crp->crp_desc;
- tdb->tdb_ref++;
+ /* IPsec-specific opaque crypto info */
+ MALLOC(tc, struct tdb_crypto *, sizeof(struct tdb_crypto),
+ M_XDATA, M_DONTWAIT);
+ if (tc == NULL)
+ {
+ m_freem(m);
+ crypto_freereq(crp);
+ DPRINTF(("esp_output(): failed to allocate tdb_crypto\n"));
+ espstat.esps_crypto++;
+ return ENOBUFS;
+ }
+
+ tc->tc_spi = tdb->tdb_spi;
+ tc->tc_proto = tdb->tdb_sproto;
+ bcopy(&tdb->tdb_dst, &tc->tc_dst, sizeof(union sockaddr_union));
/* Crypto operation descriptor */
crp->crp_ilen = m->m_pkthdr.len; /* Total input length */
crp->crp_flags = CRYPTO_F_IMBUF;
crp->crp_buf = (caddr_t) m;
crp->crp_callback = (int (*) (struct cryptop *)) esp_output_cb;
- crp->crp_opaque1 = (caddr_t) tdb;
+ crp->crp_opaque = (caddr_t) tc;
crp->crp_sid = tdb->tdb_cryptoid;
if (esph)
@@ -953,29 +976,22 @@ int
esp_output_cb(void *op)
{
struct cryptop *crp = (struct cryptop *) op;
+ struct tdb_crypto *tc;
struct tdb *tdb;
struct mbuf *m;
int error;
- tdb = (struct tdb *) crp->crp_opaque1;
+ tc = (struct tdb_crypto *) crp->crp_opaque;
m = (struct mbuf *) crp->crp_buf;
- /*
- * Check that the TDB is still valid -- not really an error, but
- * we need to handle it as such. It may happen if the TDB expired
- * or was deleted while there was a pending request in the crypto
- * queue.
- */
- if (tdb->tdb_flags & TDBF_INVALID)
+ tdb = gettdb(tc->tc_spi, &tc->tc_dst, tc->tc_proto);
+ FREE(tc, M_XDATA);
+ if (tdb == NULL)
{
- espstat.esps_invalid++;
- tdb_delete(tdb, 0, 0);
- error = ENXIO;
- DPRINTF(("esp_output_cb(): TDB expired while processing crypto\n"));
+ espstat.esps_notdb++;
+ DPRINTF(("esp_output_cb(): TDB is expired while in crypto\n"));
goto baddone;
}
- else
- tdb->tdb_ref--;
/* Check for crypto errors */
if (crp->crp_etype)
@@ -985,10 +1001,7 @@ esp_output_cb(void *op)
tdb->tdb_cryptoid = crp->crp_sid;
if (crp->crp_etype == EAGAIN)
- {
- tdb->tdb_ref++;
- return crypto_dispatch(crp);
- }
+ return crypto_dispatch(crp);
espstat.esps_noxform++;
DPRINTF(("esp_output_cb(): crypto error %d\n", crp->crp_etype));
diff --git a/sys/netinet/ip_ipsp.c b/sys/netinet/ip_ipsp.c
index f017aaf594c..dbd61455750 100644
--- a/sys/netinet/ip_ipsp.c
+++ b/sys/netinet/ip_ipsp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_ipsp.c,v 1.90 2000/06/01 06:11:08 angelos Exp $ */
+/* $OpenBSD: ip_ipsp.c,v 1.91 2000/06/06 04:49:29 angelos Exp $ */
/*
* The authors of this code are John Ioannidis (ji@tla.org),
@@ -1045,7 +1045,6 @@ puttdb(struct tdb *tdbp)
}
tdbp->tdb_hnext = tdbh[hashval];
tdbh[hashval] = tdbp;
- tdbp->tdb_ref++;
tdb_count++;
splx(s);
}
@@ -1112,13 +1111,6 @@ tdb_delete(struct tdb *tdbp, int delchain, int expflags)
u_int32_t hashval = tdbp->tdb_sproto + tdbp->tdb_spi;
int s;
- /* If it's still referenced, go on */
- if (--tdbp->tdb_ref > 0)
- {
- tdbp->tdb_flags |= TDBF_INVALID;
- return;
- }
-
/* When deleting the bypass tdb, skip the hash table code. */
if (tdbp == tdb_bypass && tdbp != NULL)
{
@@ -1473,9 +1465,6 @@ ipsp_kern(int off, char **bufp, int len)
l += sprintf(buffer + l, "\tCrypto ID: %qu\n", tdb->tdb_cryptoid);
- l += sprintf(buffer + l, "\tCurrently referenced %d time%s\n",
- tdb->tdb_ref, tdb->tdb_ref == 1 ? "" : "s");
-
if (tdb->tdb_xform)
l += sprintf(buffer + l, "\txform = <%s>\n",
tdb->tdb_xform->xf_name);
diff --git a/sys/netinet/ip_ipsp.h b/sys/netinet/ip_ipsp.h
index 1b090276788..effc3dfef65 100644
--- a/sys/netinet/ip_ipsp.h
+++ b/sys/netinet/ip_ipsp.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_ipsp.h,v 1.66 2000/06/01 04:24:26 angelos Exp $ */
+/* $OpenBSD: ip_ipsp.h,v 1.67 2000/06/06 04:49:29 angelos Exp $ */
/*
* The authors of this code are John Ioannidis (ji@tla.org),
@@ -271,7 +271,6 @@ struct tdb /* tunnel descriptor block */
* tdb_exp_first_use <= curtime */
u_int64_t tdb_cryptoid; /* Crypto session ID */
- int32_t tdb_ref; /* References */
u_int32_t tdb_spi; /* SPI */
u_int16_t tdb_amxkeylen; /* Raw authentication key length */
u_int16_t tdb_emxkeylen; /* Raw encryption key length */
@@ -317,6 +316,15 @@ struct tdb_ident {
u_int8_t proto;
};
+struct tdb_crypto {
+ u_int32_t tc_spi;
+ union sockaddr_union tc_dst;
+ u_int8_t tc_proto;
+ int tc_protoff;
+ int tc_skip;
+ caddr_t tc_ptr;
+};
+
struct ipsecinit
{
u_int8_t *ii_enckey;