Skip to content

Commit 84349af

Browse files
committed
receive: drop handshakes if queue lock is contended
If we're being delivered packets from multiple CPUs so quickly that the ring lock is contended for CPU tries, then it's safe to assume that the queue is near capacity anyway, so just drop the packet rather than spinning. This helps deal with multicore DoS that can interfere with data path performance. It _still_ does not completely fix the issue, but it again chips away at it. Reported-by: Streun Fabio <fstreun@student.ethz.ch> Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
1 parent 79c7da9 commit 84349af

File tree

1 file changed

+13
-3
lines changed

1 file changed

+13
-3
lines changed

src/receive.c

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -563,9 +563,19 @@ void wg_packet_receive(struct wg_device *wg, struct sk_buff *skb)
563563
case cpu_to_le32(MESSAGE_HANDSHAKE_INITIATION):
564564
case cpu_to_le32(MESSAGE_HANDSHAKE_RESPONSE):
565565
case cpu_to_le32(MESSAGE_HANDSHAKE_COOKIE): {
566-
int cpu;
567-
if (unlikely(!rng_is_initialized() ||
568-
ptr_ring_produce_bh(&wg->handshake_queue.ring, skb))) {
566+
int cpu, ret = -EBUSY;
567+
568+
if (unlikely(!rng_is_initialized()))
569+
goto drop;
570+
if (atomic_read(&wg->handshake_queue_len) > MAX_QUEUED_INCOMING_HANDSHAKES / 2) {
571+
if (spin_trylock_bh(&wg->handshake_queue.ring.producer_lock)) {
572+
ret = __ptr_ring_produce(&wg->handshake_queue.ring, skb);
573+
spin_unlock_bh(&wg->handshake_queue.ring.producer_lock);
574+
}
575+
} else
576+
ret = ptr_ring_produce_bh(&wg->handshake_queue.ring, skb);
577+
if (ret) {
578+
drop:
569579
net_dbg_skb_ratelimited("%s: Dropping handshake packet from %pISpfsc\n",
570580
wg->dev->name, skb);
571581
goto err;

0 commit comments

Comments
 (0)