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>
*** 245,257 ****
netstack_rele(ns);
return (-1);
}
ekp = (ah_kstats_t *)kp->ks_data;
! mutex_enter(&ipss->ipsec_alg_lock);
ekp->ah_stat_num_aalgs.value.ui64 = ipss->ipsec_nalgs[IPSEC_ALG_AUTH];
! mutex_exit(&ipss->ipsec_alg_lock);
netstack_rele(ns);
return (0);
}
--- 246,258 ----
netstack_rele(ns);
return (-1);
}
ekp = (ah_kstats_t *)kp->ks_data;
! rw_enter(&ipss->ipsec_alg_lock, RW_READER);
ekp->ah_stat_num_aalgs.value.ui64 = ipss->ipsec_nalgs[IPSEC_ALG_AUTH];
! rw_exit(&ipss->ipsec_alg_lock);
netstack_rele(ns);
return (0);
}
*** 571,581 ****
* Allocate the PF_KEY message that follows KEYSOCK_OUT.
* The alg reader lock needs to be held while allocating
* the variable part (i.e. the algorithms) of the message.
*/
! mutex_enter(&ipss->ipsec_alg_lock);
/*
* Return only valid algorithms, so the number of algorithms
* to send up may be less than the number of algorithm entries
* in the table.
--- 572,582 ----
* Allocate the PF_KEY message that follows KEYSOCK_OUT.
* The alg reader lock needs to be held while allocating
* the variable part (i.e. the algorithms) of the message.
*/
! rw_enter(&ipss->ipsec_alg_lock, RW_READER);
/*
* Return only valid algorithms, so the number of algorithms
* to send up may be less than the number of algorithm entries
* in the table.
*** 593,603 ****
allocsize += (num_aalgs * sizeof (*saalg));
allocsize += sizeof (*sasupp);
}
mp->b_cont = allocb(allocsize, BPRI_HI);
if (mp->b_cont == NULL) {
! mutex_exit(&ipss->ipsec_alg_lock);
freemsg(mp);
return (B_FALSE);
}
mp->b_cont->b_wptr += allocsize;
--- 594,604 ----
allocsize += (num_aalgs * sizeof (*saalg));
allocsize += sizeof (*sasupp);
}
mp->b_cont = allocb(allocsize, BPRI_HI);
if (mp->b_cont == NULL) {
! rw_exit(&ipss->ipsec_alg_lock);
freemsg(mp);
return (B_FALSE);
}
mp->b_cont->b_wptr += allocsize;
*** 640,650 ****
"ah_register_out()! Missed #%d.\n", i);
#endif /* DEBUG */
nextext = (sadb_ext_t *)saalg;
}
! mutex_exit(&ipss->ipsec_alg_lock);
if (sens_tsl != NULL) {
sens = (sadb_sens_t *)nextext;
sadb_sens_from_label(sens, SADB_EXT_SENSITIVITY,
sens_tsl, sens_len);
--- 641,651 ----
"ah_register_out()! Missed #%d.\n", i);
#endif /* DEBUG */
nextext = (sadb_ext_t *)saalg;
}
! rw_exit(&ipss->ipsec_alg_lock);
if (sens_tsl != NULL) {
sens = (sadb_sens_t *)nextext;
sadb_sens_from_label(sens, SADB_EXT_SENSITIVITY,
sens_tsl, sens_len);
*** 1121,1156 ****
* if I did, I'd do them here, before I sent the weak key
* check up to the algorithm.
*/
/* verify that there is a mapping for the specified algorithm */
! mutex_enter(&ipss->ipsec_alg_lock);
aalg = ipss->ipsec_alglists[IPSEC_ALG_AUTH][assoc->sadb_sa_auth];
if (aalg == NULL || !ALG_VALID(aalg)) {
! mutex_exit(&ipss->ipsec_alg_lock);
ah1dbg(ahstack, ("Couldn't find auth alg #%d.\n",
assoc->sadb_sa_auth));
*diagnostic = SADB_X_DIAGNOSTIC_BAD_AALG;
return (EINVAL);
}
ASSERT(aalg->alg_mech_type != CRYPTO_MECHANISM_INVALID);
/* sanity check key sizes */
if (!ipsec_valid_key_size(key->sadb_key_bits, aalg)) {
! mutex_exit(&ipss->ipsec_alg_lock);
*diagnostic = SADB_X_DIAGNOSTIC_BAD_AKEYBITS;
return (EINVAL);
}
/* check key and fix parity if needed */
if (ipsec_check_key(aalg->alg_mech_type, key, B_TRUE,
diagnostic) != 0) {
! mutex_exit(&ipss->ipsec_alg_lock);
return (EINVAL);
}
! mutex_exit(&ipss->ipsec_alg_lock);
return (ah_add_sa_finish(mp, (sadb_msg_t *)mp->b_cont->b_rptr, ksi,
diagnostic, ahstack));
}
--- 1122,1157 ----
* if I did, I'd do them here, before I sent the weak key
* check up to the algorithm.
*/
/* verify that there is a mapping for the specified algorithm */
! rw_enter(&ipss->ipsec_alg_lock, RW_READER);
aalg = ipss->ipsec_alglists[IPSEC_ALG_AUTH][assoc->sadb_sa_auth];
if (aalg == NULL || !ALG_VALID(aalg)) {
! rw_exit(&ipss->ipsec_alg_lock);
ah1dbg(ahstack, ("Couldn't find auth alg #%d.\n",
assoc->sadb_sa_auth));
*diagnostic = SADB_X_DIAGNOSTIC_BAD_AALG;
return (EINVAL);
}
ASSERT(aalg->alg_mech_type != CRYPTO_MECHANISM_INVALID);
/* sanity check key sizes */
if (!ipsec_valid_key_size(key->sadb_key_bits, aalg)) {
! rw_exit(&ipss->ipsec_alg_lock);
*diagnostic = SADB_X_DIAGNOSTIC_BAD_AKEYBITS;
return (EINVAL);
}
/* check key and fix parity if needed */
if (ipsec_check_key(aalg->alg_mech_type, key, B_TRUE,
diagnostic) != 0) {
! rw_exit(&ipss->ipsec_alg_lock);
return (EINVAL);
}
! rw_exit(&ipss->ipsec_alg_lock);
return (ah_add_sa_finish(mp, (sadb_msg_t *)mp->b_cont->b_rptr, ksi,
diagnostic, ahstack));
}
*** 1747,1757 ****
ipsec_action_t *ap;
ipsec_prot_t *prot;
ipsecah_stack_t *ahstack = ns->netstack_ipsecah;
ipsec_stack_t *ipss = ns->netstack_ipsec;
! ASSERT(MUTEX_HELD(&ipss->ipsec_alg_lock));
prop->sadb_prop_exttype = SADB_EXT_PROPOSAL;
prop->sadb_prop_len = SADB_8TO64(sizeof (sadb_prop_t));
*(uint32_t *)(&prop->sadb_prop_replay) = 0; /* Quick zero-out! */
--- 1748,1758 ----
ipsec_action_t *ap;
ipsec_prot_t *prot;
ipsecah_stack_t *ahstack = ns->netstack_ipsecah;
ipsec_stack_t *ipss = ns->netstack_ipsec;
! ASSERT(RW_READ_HELD(&ipss->ipsec_alg_lock));
prop->sadb_prop_exttype = SADB_EXT_PROPOSAL;
prop->sadb_prop_len = SADB_8TO64(sizeof (sadb_prop_t));
*(uint32_t *)(&prop->sadb_prop_replay) = 0; /* Quick zero-out! */
*** 1859,1869 ****
if (pfkeymp == NULL) {
ah0dbg(("sadb_setup_acquire failed.\n"));
mutex_exit(&acqrec->ipsacq_lock);
return;
}
! ASSERT(MUTEX_HELD(&ipss->ipsec_alg_lock));
combs = ipss->ipsec_nalgs[IPSEC_ALG_AUTH];
msgmp = pfkeymp->b_cont;
samsg = (sadb_msg_t *)(msgmp->b_rptr);
/* Insert proposal here. */
--- 1860,1870 ----
if (pfkeymp == NULL) {
ah0dbg(("sadb_setup_acquire failed.\n"));
mutex_exit(&acqrec->ipsacq_lock);
return;
}
! ASSERT(RW_READ_HELD(&ipss->ipsec_alg_lock));
combs = ipss->ipsec_nalgs[IPSEC_ALG_AUTH];
msgmp = pfkeymp->b_cont;
samsg = (sadb_msg_t *)(msgmp->b_rptr);
/* Insert proposal here. */
*** 1871,1881 ****
prop = (sadb_prop_t *)(((uint64_t *)samsg) + samsg->sadb_msg_len);
ah_insert_prop(prop, acqrec, combs, ns);
samsg->sadb_msg_len += prop->sadb_prop_len;
msgmp->b_wptr += SADB_64TO8(samsg->sadb_msg_len);
! mutex_exit(&ipss->ipsec_alg_lock);
/*
* Must mutex_exit() before sending PF_KEY message up, in
* order to avoid recursive mutex_enter() if there are no registered
* listeners.
--- 1872,1882 ----
prop = (sadb_prop_t *)(((uint64_t *)samsg) + samsg->sadb_msg_len);
ah_insert_prop(prop, acqrec, combs, ns);
samsg->sadb_msg_len += prop->sadb_prop_len;
msgmp->b_wptr += SADB_64TO8(samsg->sadb_msg_len);
! rw_exit(&ipss->ipsec_alg_lock);
/*
* Must mutex_exit() before sending PF_KEY message up, in
* order to avoid recursive mutex_enter() if there are no registered
* listeners.