Print this page
8381 Convert ipsec_alg_lock from mutex to rwlock
*** 19,28 ****
--- 19,29 ----
* CDDL HEADER END
*/
/*
* Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
+ * Copyright (c) 2012 Nexenta Systems, Inc. All rights reserved.
*/
#include <sys/types.h>
#include <sys/stream.h>
#include <sys/stropts.h>
*** 3196,3206 ****
*/
newbie->ipsa_kcfauthkey.ck_format = CRYPTO_KEY_RAW;
newbie->ipsa_kcfauthkey.ck_length = newbie->ipsa_authkeybits;
newbie->ipsa_kcfauthkey.ck_data = newbie->ipsa_authkey;
! mutex_enter(&ipss->ipsec_alg_lock);
alg = ipss->ipsec_alglists[IPSEC_ALG_AUTH]
[newbie->ipsa_auth_alg];
if (alg != NULL && ALG_VALID(alg)) {
newbie->ipsa_amech.cm_type = alg->alg_mech_type;
newbie->ipsa_amech.cm_param =
--- 3197,3207 ----
*/
newbie->ipsa_kcfauthkey.ck_format = CRYPTO_KEY_RAW;
newbie->ipsa_kcfauthkey.ck_length = newbie->ipsa_authkeybits;
newbie->ipsa_kcfauthkey.ck_data = newbie->ipsa_authkey;
! rw_enter(&ipss->ipsec_alg_lock, RW_READER);
alg = ipss->ipsec_alglists[IPSEC_ALG_AUTH]
[newbie->ipsa_auth_alg];
if (alg != NULL && ALG_VALID(alg)) {
newbie->ipsa_amech.cm_type = alg->alg_mech_type;
newbie->ipsa_amech.cm_param =
*** 3209,3219 ****
newbie->ipsa_mac_len = (size_t)alg->alg_datalen;
} else {
newbie->ipsa_amech.cm_type = CRYPTO_MECHANISM_INVALID;
}
error = ipsec_create_ctx_tmpl(newbie, IPSEC_ALG_AUTH);
! mutex_exit(&ipss->ipsec_alg_lock);
if (error != 0) {
mutex_exit(&newbie->ipsa_lock);
/*
* An error here indicates that alg is the wrong type
* (IE: not authentication) or its not in the alg tables
--- 3210,3220 ----
newbie->ipsa_mac_len = (size_t)alg->alg_datalen;
} else {
newbie->ipsa_amech.cm_type = CRYPTO_MECHANISM_INVALID;
}
error = ipsec_create_ctx_tmpl(newbie, IPSEC_ALG_AUTH);
! rw_exit(&ipss->ipsec_alg_lock);
if (error != 0) {
mutex_exit(&newbie->ipsa_lock);
/*
* An error here indicates that alg is the wrong type
* (IE: not authentication) or its not in the alg tables
*** 3226,3236 ****
goto error;
}
}
if (ekey != NULL) {
! mutex_enter(&ipss->ipsec_alg_lock);
async = async || (ipss->ipsec_algs_exec_mode[IPSEC_ALG_ENCR] ==
IPSEC_ALGS_EXEC_ASYNC);
alg = ipss->ipsec_alglists[IPSEC_ALG_ENCR]
[newbie->ipsa_encr_alg];
--- 3227,3237 ----
goto error;
}
}
if (ekey != NULL) {
! rw_enter(&ipss->ipsec_alg_lock, RW_READER);
async = async || (ipss->ipsec_algs_exec_mode[IPSEC_ALG_ENCR] ==
IPSEC_ALGS_EXEC_ASYNC);
alg = ipss->ipsec_alglists[IPSEC_ALG_ENCR]
[newbie->ipsa_encr_alg];
*** 3259,3269 ****
newbie->ipsa_emech.cm_param = NULL;
newbie->ipsa_emech.cm_param_len = 0;
} else {
newbie->ipsa_emech.cm_type = CRYPTO_MECHANISM_INVALID;
}
! mutex_exit(&ipss->ipsec_alg_lock);
/*
* The byte stream following the sadb_key_t is made up of:
* key bytes, [salt bytes], [IV initial value]
* All of these have variable length. The IV is typically
--- 3260,3270 ----
newbie->ipsa_emech.cm_param = NULL;
newbie->ipsa_emech.cm_param_len = 0;
} else {
newbie->ipsa_emech.cm_type = CRYPTO_MECHANISM_INVALID;
}
! rw_exit(&ipss->ipsec_alg_lock);
/*
* The byte stream following the sadb_key_t is made up of:
* key bytes, [salt bytes], [IV initial value]
* All of these have variable length. The IV is typically
*** 3371,3383 ****
*/
newbie->ipsa_kcfencrkey.ck_format = CRYPTO_KEY_RAW;
newbie->ipsa_kcfencrkey.ck_length = newbie->ipsa_encrkeybits;
newbie->ipsa_kcfencrkey.ck_data = newbie->ipsa_encrkey;
! mutex_enter(&ipss->ipsec_alg_lock);
error = ipsec_create_ctx_tmpl(newbie, IPSEC_ALG_ENCR);
! mutex_exit(&ipss->ipsec_alg_lock);
if (error != 0) {
mutex_exit(&newbie->ipsa_lock);
/* See above for error explanation. */
*diagnostic = SADB_X_DIAGNOSTIC_BAD_CTX;
goto error;
--- 3372,3384 ----
*/
newbie->ipsa_kcfencrkey.ck_format = CRYPTO_KEY_RAW;
newbie->ipsa_kcfencrkey.ck_length = newbie->ipsa_encrkeybits;
newbie->ipsa_kcfencrkey.ck_data = newbie->ipsa_encrkey;
! rw_enter(&ipss->ipsec_alg_lock, RW_READER);
error = ipsec_create_ctx_tmpl(newbie, IPSEC_ALG_ENCR);
! rw_exit(&ipss->ipsec_alg_lock);
if (error != 0) {
mutex_exit(&newbie->ipsa_lock);
/* See above for error explanation. */
*diagnostic = SADB_X_DIAGNOSTIC_BAD_CTX;
goto error;
*** 5279,5300 ****
/*
* Normalize vs. crypto framework's limits. This way, you can specify
* a stronger policy, and when the framework loads a stronger version,
* you can just keep plowing w/o rewhacking your SPD.
*/
! mutex_enter(&ipss->ipsec_alg_lock);
algp = ipss->ipsec_alglists[(algtype == SADB_X_ALGTYPE_AUTH) ?
IPSEC_ALG_AUTH : IPSEC_ALG_ENCR][alg];
if (algp == NULL) {
! mutex_exit(&ipss->ipsec_alg_lock);
return (NULL); /* Algorithm doesn't exist. Fail gracefully. */
}
if (minbits < algp->alg_ef_minbits)
minbits = algp->alg_ef_minbits;
if (maxbits > algp->alg_ef_maxbits)
maxbits = algp->alg_ef_maxbits;
! mutex_exit(&ipss->ipsec_alg_lock);
algdesc->sadb_x_algdesc_reserved = SADB_8TO1(algp->alg_saltlen);
algdesc->sadb_x_algdesc_satype = satype;
algdesc->sadb_x_algdesc_algtype = algtype;
algdesc->sadb_x_algdesc_alg = alg;
--- 5280,5301 ----
/*
* Normalize vs. crypto framework's limits. This way, you can specify
* a stronger policy, and when the framework loads a stronger version,
* you can just keep plowing w/o rewhacking your SPD.
*/
! rw_enter(&ipss->ipsec_alg_lock, RW_READER);
algp = ipss->ipsec_alglists[(algtype == SADB_X_ALGTYPE_AUTH) ?
IPSEC_ALG_AUTH : IPSEC_ALG_ENCR][alg];
if (algp == NULL) {
! rw_exit(&ipss->ipsec_alg_lock);
return (NULL); /* Algorithm doesn't exist. Fail gracefully. */
}
if (minbits < algp->alg_ef_minbits)
minbits = algp->alg_ef_minbits;
if (maxbits > algp->alg_ef_maxbits)
maxbits = algp->alg_ef_maxbits;
! rw_exit(&ipss->ipsec_alg_lock);
algdesc->sadb_x_algdesc_reserved = SADB_8TO1(algp->alg_saltlen);
algdesc->sadb_x_algdesc_satype = satype;
algdesc->sadb_x_algdesc_algtype = algtype;
algdesc->sadb_x_algdesc_alg = alg;
*** 5772,5782 ****
sizeof (sadb_address_t) + sizeof (sadb_prop_t);
/* Make sure there's enough to cover both AF_INET and AF_INET6. */
allocsize += 2 * sizeof (struct sockaddr_in6);
! mutex_enter(&ipss->ipsec_alg_lock);
/* NOTE: The lock is now held through to this function's return. */
allocsize += ipss->ipsec_nalgs[IPSEC_ALG_AUTH] *
ipss->ipsec_nalgs[IPSEC_ALG_ENCR] * sizeof (sadb_comb_t);
if (tunnel_mode) {
--- 5773,5783 ----
sizeof (sadb_address_t) + sizeof (sadb_prop_t);
/* Make sure there's enough to cover both AF_INET and AF_INET6. */
allocsize += 2 * sizeof (struct sockaddr_in6);
! rw_enter(&ipss->ipsec_alg_lock, RW_READER);
/* NOTE: The lock is now held through to this function's return. */
allocsize += ipss->ipsec_nalgs[IPSEC_ALG_AUTH] *
ipss->ipsec_nalgs[IPSEC_ALG_ENCR] * sizeof (sadb_comb_t);
if (tunnel_mode) {
*** 5787,5797 ****
}
msgmp = allocb(allocsize, BPRI_HI);
if (msgmp == NULL) {
freeb(pfkeymp);
! mutex_exit(&ipss->ipsec_alg_lock);
return (NULL);
}
pfkeymp->b_cont = msgmp;
cur = msgmp->b_rptr;
--- 5788,5798 ----
}
msgmp = allocb(allocsize, BPRI_HI);
if (msgmp == NULL) {
freeb(pfkeymp);
! rw_exit(&ipss->ipsec_alg_lock);
return (NULL);
}
pfkeymp->b_cont = msgmp;
cur = msgmp->b_rptr;
*** 5810,5820 ****
default:
/* This should never happen unless we have kernel bugs. */
cmn_err(CE_WARN,
"sadb_setup_acquire: corrupt ACQUIRE record.\n");
ASSERT(0);
! mutex_exit(&ipss->ipsec_alg_lock);
return (NULL);
}
samsg->sadb_msg_version = PF_KEY_V2;
samsg->sadb_msg_type = SADB_ACQUIRE;
--- 5811,5821 ----
default:
/* This should never happen unless we have kernel bugs. */
cmn_err(CE_WARN,
"sadb_setup_acquire: corrupt ACQUIRE record.\n");
ASSERT(0);
! rw_exit(&ipss->ipsec_alg_lock);
return (NULL);
}
samsg->sadb_msg_version = PF_KEY_V2;
samsg->sadb_msg_type = SADB_ACQUIRE;
*** 5857,5867 ****
/* XXXMLS Insert sensitivity information here. */
if (cur != NULL)
samsg->sadb_msg_len = SADB_8TO64(cur - msgmp->b_rptr);
else
! mutex_exit(&ipss->ipsec_alg_lock);
return (pfkeymp);
}
/*
--- 5858,5868 ----
/* XXXMLS Insert sensitivity information here. */
if (cur != NULL)
samsg->sadb_msg_len = SADB_8TO64(cur - msgmp->b_rptr);
else
! rw_exit(&ipss->ipsec_alg_lock);
return (pfkeymp);
}
/*
*** 7188,7198 ****
crypto_key_t *key;
crypto_ctx_template_t *sa_tmpl;
int rv;
ipsec_stack_t *ipss = sa->ipsa_netstack->netstack_ipsec;
! ASSERT(MUTEX_HELD(&ipss->ipsec_alg_lock));
ASSERT(MUTEX_HELD(&sa->ipsa_lock));
/* get pointers to the algorithm info, context template, and key */
switch (alg_type) {
case IPSEC_ALG_AUTH:
--- 7189,7199 ----
crypto_key_t *key;
crypto_ctx_template_t *sa_tmpl;
int rv;
ipsec_stack_t *ipss = sa->ipsa_netstack->netstack_ipsec;
! ASSERT(RW_READ_HELD(&ipss->ipsec_alg_lock));
ASSERT(MUTEX_HELD(&sa->ipsa_lock));
/* get pointers to the algorithm info, context template, and key */
switch (alg_type) {
case IPSEC_ALG_AUTH: