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: