MFC: sys/netipsec/key.c
sys/netipsec/xform_ah.c sys/netipsec/xform_esp.c sys/netipsec/xform_ipcomp.c - Allow to use fast_ipsec(4) on debug.mpsafenet=0 and INVARIANTS-enabled systems. Without the change it will panic on assertions. - Update the code after opencrypto changes.
This commit is contained in:
parent
f276329193
commit
1d18621829
@ -54,6 +54,7 @@
|
||||
#include <sys/errno.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/queue.h>
|
||||
#include <sys/refcount.h>
|
||||
#include <sys/syslog.h>
|
||||
|
||||
#include <net/if.h>
|
||||
@ -495,14 +496,26 @@ static const char *key_getuserfqdn __P((void));
|
||||
static void key_sa_chgstate __P((struct secasvar *, u_int8_t));
|
||||
static struct mbuf *key_alloc_mbuf __P((int));
|
||||
|
||||
#define SA_ADDREF(p) do { \
|
||||
(p)->refcnt++; \
|
||||
IPSEC_ASSERT((p)->refcnt != 0, ("SA refcnt overflow")); \
|
||||
} while (0)
|
||||
#define SA_DELREF(p) do { \
|
||||
IPSEC_ASSERT((p)->refcnt > 0, ("SA refcnt underflow")); \
|
||||
(p)->refcnt--; \
|
||||
} while (0)
|
||||
static __inline void
|
||||
sa_initref(struct secasvar *sav)
|
||||
{
|
||||
|
||||
refcount_init(&sav->refcnt, 1);
|
||||
}
|
||||
static __inline void
|
||||
sa_addref(struct secasvar *sav)
|
||||
{
|
||||
|
||||
refcount_acquire(&sav->refcnt);
|
||||
IPSEC_ASSERT(sav->refcnt != 0, ("SA refcnt overflow"));
|
||||
}
|
||||
static __inline int
|
||||
sa_delref(struct secasvar *sav)
|
||||
{
|
||||
|
||||
IPSEC_ASSERT(sav->refcnt > 0, ("SA refcnt underflow"));
|
||||
return (refcount_release(&sav->refcnt));
|
||||
}
|
||||
|
||||
#define SP_ADDREF(p) do { \
|
||||
(p)->refcnt++; \
|
||||
@ -993,7 +1006,7 @@ key_do_allocsa_policy(struct secashead *sah, u_int state)
|
||||
}
|
||||
}
|
||||
if (candidate) {
|
||||
SA_ADDREF(candidate);
|
||||
sa_addref(candidate);
|
||||
KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
|
||||
printf("DP %s cause refcnt++:%d SA:%p\n",
|
||||
__func__, candidate->refcnt, candidate));
|
||||
@ -1072,7 +1085,7 @@ key_allocsa(
|
||||
/* check dst address */
|
||||
if (key_sockaddrcmp(&dst->sa, &sav->sah->saidx.dst.sa, 0) != 0)
|
||||
continue;
|
||||
SA_ADDREF(sav);
|
||||
sa_addref(sav);
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
@ -1191,16 +1204,16 @@ key_freesav(struct secasvar **psav, const char* where, int tag)
|
||||
|
||||
IPSEC_ASSERT(sav != NULL, ("null sav"));
|
||||
|
||||
/* XXX unguarded? */
|
||||
SA_DELREF(sav);
|
||||
|
||||
KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
|
||||
printf("DP %s SA:%p (SPI %u) from %s:%u; refcnt now %u\n",
|
||||
__func__, sav, ntohl(sav->spi), where, tag, sav->refcnt));
|
||||
|
||||
if (sav->refcnt == 0) {
|
||||
if (sa_delref(sav)) {
|
||||
KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
|
||||
printf("DP %s SA:%p (SPI %u) from %s:%u; refcnt now %u\n",
|
||||
__func__, sav, ntohl(sav->spi), where, tag, sav->refcnt));
|
||||
*psav = NULL;
|
||||
key_delsav(sav);
|
||||
} else {
|
||||
KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
|
||||
printf("DP %s SA:%p (SPI %u) from %s:%u; refcnt now %u\n",
|
||||
__func__, sav, ntohl(sav->spi), where, tag, sav->refcnt));
|
||||
}
|
||||
}
|
||||
|
||||
@ -2757,7 +2770,7 @@ key_newsav(m, mhp, sah, errp, where, tag)
|
||||
|
||||
/* add to satree */
|
||||
newsav->sah = sah;
|
||||
newsav->refcnt = 1;
|
||||
sa_initref(newsav);
|
||||
newsav->state = SADB_SASTATE_LARVAL;
|
||||
|
||||
/* XXX locking??? */
|
||||
@ -4776,7 +4789,7 @@ key_getsavbyseq(sah, seq)
|
||||
KEY_CHKSASTATE(state, sav->state, __func__);
|
||||
|
||||
if (sav->seq == seq) {
|
||||
SA_ADDREF(sav);
|
||||
sa_addref(sav);
|
||||
KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
|
||||
printf("DP %s cause refcnt++:%d SA:%p\n",
|
||||
__func__, sav->refcnt, sav));
|
||||
|
@ -81,11 +81,11 @@
|
||||
sizeof (struct ah) : sizeof (struct ah) + sizeof (u_int32_t))
|
||||
/*
|
||||
* Return authenticator size in bytes. The old protocol is known
|
||||
* to use a fixed 16-byte authenticator. The new algorithm gets
|
||||
* this size from the xform but is (currently) always 12.
|
||||
* to use a fixed 16-byte authenticator. The new algorithm use 12-byte
|
||||
* authenticator.
|
||||
*/
|
||||
#define AUTHSIZE(sav) \
|
||||
((sav->flags & SADB_X_EXT_OLD) ? 16 : (sav)->tdb_authalgxform->authsize)
|
||||
((sav->flags & SADB_X_EXT_OLD) ? 16 : AH_HMAC_HASHLEN)
|
||||
|
||||
int ah_enable = 1; /* control flow of packets with AH */
|
||||
int ah_cleartos = 1; /* clear ip_tos when doing AH calc */
|
||||
@ -116,11 +116,11 @@ ah_algorithm_lookup(int alg)
|
||||
case SADB_X_AALG_NULL:
|
||||
return &auth_hash_null;
|
||||
case SADB_AALG_MD5HMAC:
|
||||
return &auth_hash_hmac_md5_96;
|
||||
return &auth_hash_hmac_md5;
|
||||
case SADB_AALG_SHA1HMAC:
|
||||
return &auth_hash_hmac_sha1_96;
|
||||
return &auth_hash_hmac_sha1;
|
||||
case SADB_X_AALG_RIPEMD160HMAC:
|
||||
return &auth_hash_hmac_ripemd_160_96;
|
||||
return &auth_hash_hmac_ripemd_160;
|
||||
case SADB_X_AALG_MD5:
|
||||
return &auth_hash_key_md5;
|
||||
case SADB_X_AALG_SHA:
|
||||
@ -202,6 +202,7 @@ ah_init0(struct secasvar *sav, struct xformsw *xsp, struct cryptoini *cria)
|
||||
cria->cri_alg = sav->tdb_authalgxform->type;
|
||||
cria->cri_klen = _KEYBITS(sav->key_auth);
|
||||
cria->cri_key = _KEYBUF(sav->key_auth);
|
||||
cria->cri_mlen = AUTHSIZE(sav);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -734,6 +735,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 +767,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 +863,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 +874,7 @@ bad:
|
||||
free(tc, M_XDATA);
|
||||
if (crp != NULL)
|
||||
crypto_freereq(crp);
|
||||
NET_UNLOCK_GIANT();
|
||||
return error;
|
||||
}
|
||||
|
||||
@ -1114,6 +1121,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 +1149,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 +1183,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 +1193,7 @@ bad:
|
||||
m_freem(m);
|
||||
free(tc, M_XDATA);
|
||||
crypto_freereq(crp);
|
||||
NET_UNLOCK_GIANT();
|
||||
return error;
|
||||
}
|
||||
|
||||
|
@ -329,7 +329,7 @@ esp_input(struct mbuf *m, struct secasvar *sav, int skip, int protoff)
|
||||
}
|
||||
|
||||
/* Update the counters */
|
||||
espstat.esps_ibytes += m->m_pkthdr.len - skip - hlen - alen;
|
||||
espstat.esps_ibytes += m->m_pkthdr.len - (skip + hlen + alen);
|
||||
|
||||
/* Find out if we've already done crypto */
|
||||
for (mtag = m_tag_find(m, PACKET_TAG_IPSEC_IN_CRYPTO_DONE, NULL);
|
||||
@ -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++;
|
||||
@ -524,13 +528,13 @@ esp_input_cb(struct cryptop *crp)
|
||||
ahstat.ahs_hist[sav->alg_auth]++;
|
||||
if (mtag == NULL) {
|
||||
/* 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 - AH_HMAC_HASHLEN,
|
||||
AH_HMAC_HASHLEN, aalg);
|
||||
|
||||
ptr = (caddr_t) (tc + 1);
|
||||
|
||||
/* Verify authenticator */
|
||||
if (bcmp(ptr, aalg, esph->authsize) != 0) {
|
||||
if (bcmp(ptr, aalg, AH_HMAC_HASHLEN) != 0) {
|
||||
DPRINTF(("%s: "
|
||||
"authentication hash mismatch for packet in SA %s/%08lx\n",
|
||||
__func__,
|
||||
@ -543,7 +547,7 @@ esp_input_cb(struct cryptop *crp)
|
||||
}
|
||||
|
||||
/* Remove trailing authenticator */
|
||||
m_adj(m, -(esph->authsize));
|
||||
m_adj(m, -AH_HMAC_HASHLEN);
|
||||
}
|
||||
|
||||
/* Release the crypto descriptors */
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user