 +static void expired_retransmit_handshake(unsigned long ptr)
 +{
 +	peer_get_from_ptr(ptr);
-+	pr_debug("Handshake for peer %Lu (%pISpfsc) did not complete after %d seconds, retrying\n", peer->internal_id, &peer->endpoint.addr, REKEY_TIMEOUT / HZ);
 +	if (peer->timer_handshake_attempts > MAX_TIMER_HANDSHAKES) {
++		pr_debug("%s: Handshake for peer %Lu (%pISpfsc) did not complete after %d attempts, giving up\n", netdev_pub(peer->device)->name, peer->internal_id, &peer->endpoint.addr, MAX_TIMER_HANDSHAKES + 2);
++
 +		del_timer(&peer->timer_send_keepalive);
 +		/* We remove all existing packets and don't try again,
 +		 * if we try unsuccessfully for too long to make a handshake. */
 +		skb_queue_purge(&peer->tx_packet_queue);
 +		/* We set a timer for destroying any residue that might be left
 +		 * of a partial exchange. */
-+		if (likely(peer->timers_enabled))
++		if (likely(peer->timers_enabled) && !timer_pending(&peer->timer_kill_ephemerals))
 +			mod_timer(&peer->timer_kill_ephemerals, jiffies + (REJECT_AFTER_TIME * 3));
-+		goto out;
++	} else {
++		++peer->timer_handshake_attempts;
++		pr_debug("%s: Handshake for peer %Lu (%pISpfsc) did not complete after %d seconds, retrying (try %d)\n", netdev_pub(peer->device)->name, peer->internal_id, &peer->endpoint.addr, REKEY_TIMEOUT / HZ, peer->timer_handshake_attempts + 1);
++
++		/* We clear the endpoint address src address, in case this is the cause of trouble. */
++		socket_clear_peer_endpoint_src(peer);
++
++		packet_queue_handshake_initiation(peer, true);
 +	}
-+
-+	/* We clear the endpoint address src address, in case this is the cause of trouble. */
-+	socket_clear_peer_endpoint_src(peer);
-+
-+	packet_queue_handshake_initiation(peer);
-+	++peer->timer_handshake_attempts;
-+out:
 +	peer_put(peer);
 +}
 +

+	v0 ^= second;
+	POSTAMBLE
+}
+EXPORT_SYMBOL(siphash_2u64);
+
+/**
+ * siphash_3u64 - compute 64-bit siphash PRF value of 3 u64

+
+static const char constant[16] = "expand 32-byte k";
+
+static void hchacha20_generic(u8 derived_key[CHACHA20POLY1305_KEYLEN], const u8 nonce[16], const u8 key[CHACHA20POLY1305_KEYLEN])
+{
+	u32 x[CHACHA20_BLOCK_SIZE / sizeof(u32)];
+	__le32 *out = (__force __le32 *)derived_key;
