aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/src/peer.c
diff options
context:
space:
mode:
authorJason A. Donenfeld <Jason@zx2c4.com>2017-09-28 17:49:13 +0200
committerJason A. Donenfeld <Jason@zx2c4.com>2017-10-02 02:45:53 +0200
commit4dff6b0e7a74939bc442210b7e5bf38cdfecf890 (patch)
tree794a134b22f1010eedff340ef6bbd7af308d94ee /src/peer.c
parenttimers: ensure safe timer removal (diff)
downloadwireguard-monolithic-historical-4dff6b0e7a74939bc442210b7e5bf38cdfecf890.tar.xz
wireguard-monolithic-historical-4dff6b0e7a74939bc442210b7e5bf38cdfecf890.zip
peer: remove from RCU lists when the kref is zero
Diffstat (limited to 'src/peer.c')
-rw-r--r--src/peer.c9
1 files changed, 5 insertions, 4 deletions
diff --git a/src/peer.c b/src/peer.c
index d5fbdb8..403c608 100644
--- a/src/peer.c
+++ b/src/peer.c
@@ -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);
}