/* can only be invoked when all peer references have been dropped (i.e. RCU *releaseroutine)
*/ void ovpn_crypto_state_release(struct ovpn_crypto_state *cs)
{ struct ovpn_crypto_key_slot *ks;
ks = rcu_access_pointer(cs->slots[0]); if (ks) {
RCU_INIT_POINTER(cs->slots[0], NULL);
ovpn_crypto_key_slot_put(ks);
}
/* removes the key matching the specified id from the crypto context */ bool ovpn_crypto_kill_key(struct ovpn_crypto_state *cs, u8 key_id)
{ struct ovpn_crypto_key_slot *ks = NULL;
/* let the caller know if a key was actually killed */ return ks;
}
/* Reset the ovpn_crypto_state object in a way that is atomic *toRCUreaders.
*/ int ovpn_crypto_state_reset(struct ovpn_crypto_state *cs, conststruct ovpn_peer_key_reset *pkr)
{ struct ovpn_crypto_key_slot *old = NULL, *new;
u8 idx;
if (pkr->slot != OVPN_KEY_SLOT_PRIMARY &&
pkr->slot != OVPN_KEY_SLOT_SECONDARY) return -EINVAL;
new = ovpn_aead_crypto_key_slot_new(&pkr->key); if (IS_ERR(new)) return PTR_ERR(new);
spin_lock_bh(&cs->lock);
idx = cs->primary_idx; switch (pkr->slot) { case OVPN_KEY_SLOT_PRIMARY:
old = rcu_replace_pointer(cs->slots[idx], new,
lockdep_is_held(&cs->lock)); break; case OVPN_KEY_SLOT_SECONDARY:
old = rcu_replace_pointer(cs->slots[!idx], new,
lockdep_is_held(&cs->lock)); break;
}
spin_unlock_bh(&cs->lock);
spin_lock_bh(&cs->lock);
idx = cs->primary_idx;
old_primary = rcu_dereference_protected(cs->slots[idx],
lockdep_is_held(&cs->lock));
old_secondary = rcu_dereference_protected(cs->slots[!idx],
lockdep_is_held(&cs->lock)); /* perform real swap by switching the index of the primary key */
WRITE_ONCE(cs->primary_idx, !cs->primary_idx);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.