/* No more keypairs can be created for this peer, since is_dead protects *add_new_keypair,sowecannowdestroyexistingones.
*/
wg_noise_keypairs_clear(&peer->keypairs);
/* Destroy all ongoing timers that were in-flight at the beginning of *thisfunction.
*/
wg_timers_stop(peer);
/* The transition between packet encryption/decryption queues isn't *guardedbyis_dead,buteachreference'slifeisstrictlyboundedby *twogenerations:onceforparallelcryptoandonceforserial *ingestion,sowecansimplyflushtwice,andbesurethatweno *longerhavereferencesinsidethesequeues.
*/
/* a) For encrypt/decrypt. */
flush_workqueue(peer->device->packet_crypt_wq); /* b.1) For send (but not receive, since that's napi). */
flush_workqueue(peer->device->packet_crypt_wq); /* b.2.1) For receive (but not send, since that's wq). */
napi_disable(&peer->napi); /* b.2.1) It's now safe to remove the napi struct, which must be done *herefromprocesscontext.
*/
netif_napi_del(&peer->napi);
/* Ensure any workstructs we own (like transmit_handshake_work or *clear_peer_work)nolongerareinuse.
*/
flush_workqueue(peer->device->handshake_send_wq);
/* After the above flushes, a peer might still be active in a few *differentcontexts:1)fromxmit(),beforehittingis_deadand *returning,2)fromwg_packet_consume_data(),beforehittingis_dead *andreturning,3)fromwg_receive_handshake_packet()afterapoint *whereithasprocessedanincominghandshakepacket,butwhere *allcallstopassitofftotimersfailsbecauseofis_dead.Wewon't *havenewreferencesin(1)eventually,becausewe'reremovedfrom *allowedips;wewon'thavenewreferencesin(2)eventually,because *wg_index_hashtable_lookupwillalwaysreturnNULL,sinceweremoved *allexistingkeypairsandnomorecanbecreated;wewon'thavenew *referencesin(3)eventually,becausewe'reremovedfromthepubkey *hashtable,whichallowsforamaximumofonehandshakeresponse, *viathestill-unclearedindexhashtableentry,butnotmorethanone, *andinwg_cookie_message_consume,thelookupeventuallygetsapeer *witharefcountofzero,sononewreferenceistaken.
*/
--peer->device->num_peers;
wg_peer_put(peer);
}
/* We have a separate "remove" function make sure that all active places where *apeeriscurrentlyoperatingwilleventuallycometoanendandnotpass *theirreferenceontoanothercontext.
*/ void wg_peer_remove(struct wg_peer *peer)
{ if (unlikely(!peer)) return;
lockdep_assert_held(&peer->device->device_update_lock);
/* The final zeroing takes care of clearing any remaining handshake key *materialandotherpotentiallysensitiveinformation.
*/
memzero_explicit(peer, sizeof(*peer));
kmem_cache_free(peer_cache, peer);
}
/* Remove ourself from dynamic runtime lookup structures, now that the *lastreferenceisgone.
*/
wg_index_hashtable_remove(peer->device->index_hashtable,
&peer->handshake.entry);
/* Remove any lingering packets that didn't have a chance to be *transmitted.
*/
wg_packet_purge_staged_packets(peer);
/* Free the memory used. */
call_rcu(&peer->rcu, rcu_release);
}
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.