diff options
author | Jason A. Donenfeld <Jason@zx2c4.com> | 2017-09-28 17:49:13 +0200 |
---|---|---|
committer | Jason A. Donenfeld <Jason@zx2c4.com> | 2017-10-02 02:45:53 +0200 |
commit | 5275f47a0d0d6fe9f6ee39e47f4bd7d8627b016c (patch) | |
tree | 165686a1ce8bebd9d812c1f6fefaabf20a7f1f93 /src/peer.c | |
parent | 2f3c1fcb41fe878694e6cd32708a4e2032b93fc4 (diff) |
peer: remove from RCU lists when the kref is zero
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
Diffstat (limited to 'src/peer.c')
-rw-r--r-- | src/peer.c | 9 |
1 files changed, 5 insertions, 4 deletions
@@ -78,13 +78,13 @@ void peer_remove(struct wireguard_peer *peer) if (unlikely(!peer)) return; lockdep_assert_held(&peer->device->device_update_lock); + routing_table_remove_by_peer(&peer->device->peer_routing_table, peer); + pubkey_hashtable_remove(&peer->device->peer_hashtable, peer); + skb_queue_purge(&peer->staged_packet_queue); noise_handshake_clear(&peer->handshake); noise_keypairs_clear(&peer->keypairs); list_del_init(&peer->peer_list); timers_stop(peer); - routing_table_remove_by_peer(&peer->device->peer_routing_table, peer); - pubkey_hashtable_remove(&peer->device->peer_hashtable, peer); - skb_queue_purge(&peer->staged_packet_queue); flush_workqueue(peer->device->packet_crypt_wq); /* The first flush is for encrypt/decrypt step. */ flush_workqueue(peer->device->packet_crypt_wq); /* The second flush is for send/receive step. */ flush_workqueue(peer->device->handshake_send_wq); @@ -95,7 +95,6 @@ static void rcu_release(struct rcu_head *rcu) { struct wireguard_peer *peer = container_of(rcu, struct wireguard_peer, rcu); pr_debug("%s: Peer %Lu (%pISpfsc) destroyed\n", peer->device->dev->name, peer->internal_id, &peer->endpoint.addr); - skb_queue_purge(&peer->staged_packet_queue); dst_cache_destroy(&peer->endpoint_cache); kzfree(peer); } @@ -103,6 +102,8 @@ static void rcu_release(struct rcu_head *rcu) static void kref_release(struct kref *refcount) { struct wireguard_peer *peer = container_of(refcount, struct wireguard_peer, refcount); + index_hashtable_remove(&peer->device->index_hashtable, &peer->handshake.entry); + skb_queue_purge(&peer->staged_packet_queue); call_rcu_bh(&peer->rcu, rcu_release); } |