Skip to content

Commit d3f3e6a

Browse files
committed
Merge branch 'wireguard-fixes'
Jason A. Donenfeld says: ==================== wireguard fixes for 5.7-rc5 With Ubuntu and Debian having backported this into their kernels, we're finally seeing testing from places we hadn't seen prior, which is nice. With that comes more fixes: 1) The CI for PPC64 was running with extremely small stacks for 64-bit, causing spurious crashes in surprising places. 2) There's was an old leftover routing loop restriction, which no longer makes sense given the queueing architecture, and was causing problems for people who really did want nested routing. 3) Not yielding our kthread on CONFIG_PREEMPT_VOLUNTARY systems caused RCU stalls and other issues, reported by Wang Jian, with the fix suggested by Sultan Alsawaf. 4) Clang spewed warnings in a selftest for CONFIG_IPV6=n, reported by Arnd Bergmann. 5) A complicated if statement was simplified to an assignment while also making the likely/unlikely hinting more correct and simple, and increasing readability, suggested by Sultan. Patches (2) and (3) have Fixes: lines and are probably good candidates for stable. ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents 6f5c27f + 243f214 commit d3f3e6a

File tree

6 files changed

+72
-33
lines changed

6 files changed

+72
-33
lines changed

drivers/net/wireguard/receive.c

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -226,21 +226,20 @@ void wg_packet_handshake_receive_worker(struct work_struct *work)
226226
static void keep_key_fresh(struct wg_peer *peer)
227227
{
228228
struct noise_keypair *keypair;
229-
bool send = false;
229+
bool send;
230230

231231
if (peer->sent_lastminute_handshake)
232232
return;
233233

234234
rcu_read_lock_bh();
235235
keypair = rcu_dereference_bh(peer->keypairs.current_keypair);
236-
if (likely(keypair && READ_ONCE(keypair->sending.is_valid)) &&
237-
keypair->i_am_the_initiator &&
238-
unlikely(wg_birthdate_has_expired(keypair->sending.birthdate,
239-
REJECT_AFTER_TIME - KEEPALIVE_TIMEOUT - REKEY_TIMEOUT)))
240-
send = true;
236+
send = keypair && READ_ONCE(keypair->sending.is_valid) &&
237+
keypair->i_am_the_initiator &&
238+
wg_birthdate_has_expired(keypair->sending.birthdate,
239+
REJECT_AFTER_TIME - KEEPALIVE_TIMEOUT - REKEY_TIMEOUT);
241240
rcu_read_unlock_bh();
242241

243-
if (send) {
242+
if (unlikely(send)) {
244243
peer->sent_lastminute_handshake = true;
245244
wg_packet_send_queued_handshake_initiation(peer, false);
246245
}
@@ -516,6 +515,8 @@ void wg_packet_decrypt_worker(struct work_struct *work)
516515
&PACKET_CB(skb)->keypair->receiving)) ?
517516
PACKET_STATE_CRYPTED : PACKET_STATE_DEAD;
518517
wg_queue_enqueue_per_peer_napi(skb, state);
518+
if (need_resched())
519+
cond_resched();
519520
}
520521
}
521522

drivers/net/wireguard/selftest/ratelimiter.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -120,9 +120,9 @@ bool __init wg_ratelimiter_selftest(void)
120120
enum { TRIALS_BEFORE_GIVING_UP = 5000 };
121121
bool success = false;
122122
int test = 0, trials;
123-
struct sk_buff *skb4, *skb6;
123+
struct sk_buff *skb4, *skb6 = NULL;
124124
struct iphdr *hdr4;
125-
struct ipv6hdr *hdr6;
125+
struct ipv6hdr *hdr6 = NULL;
126126

127127
if (IS_ENABLED(CONFIG_KASAN) || IS_ENABLED(CONFIG_UBSAN))
128128
return true;

drivers/net/wireguard/send.c

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -124,20 +124,17 @@ void wg_packet_send_handshake_cookie(struct wg_device *wg,
124124
static void keep_key_fresh(struct wg_peer *peer)
125125
{
126126
struct noise_keypair *keypair;
127-
bool send = false;
127+
bool send;
128128

129129
rcu_read_lock_bh();
130130
keypair = rcu_dereference_bh(peer->keypairs.current_keypair);
131-
if (likely(keypair && READ_ONCE(keypair->sending.is_valid)) &&
132-
(unlikely(atomic64_read(&keypair->sending.counter.counter) >
133-
REKEY_AFTER_MESSAGES) ||
134-
(keypair->i_am_the_initiator &&
135-
unlikely(wg_birthdate_has_expired(keypair->sending.birthdate,
136-
REKEY_AFTER_TIME)))))
137-
send = true;
131+
send = keypair && READ_ONCE(keypair->sending.is_valid) &&
132+
(atomic64_read(&keypair->sending.counter.counter) > REKEY_AFTER_MESSAGES ||
133+
(keypair->i_am_the_initiator &&
134+
wg_birthdate_has_expired(keypair->sending.birthdate, REKEY_AFTER_TIME)));
138135
rcu_read_unlock_bh();
139136

140-
if (send)
137+
if (unlikely(send))
141138
wg_packet_send_queued_handshake_initiation(peer, false);
142139
}
143140

@@ -281,6 +278,8 @@ void wg_packet_tx_worker(struct work_struct *work)
281278

282279
wg_noise_keypair_put(keypair, false);
283280
wg_peer_put(peer);
281+
if (need_resched())
282+
cond_resched();
284283
}
285284
}
286285

@@ -304,6 +303,8 @@ void wg_packet_encrypt_worker(struct work_struct *work)
304303
}
305304
wg_queue_enqueue_per_peer(&PACKET_PEER(first)->tx_queue, first,
306305
state);
306+
if (need_resched())
307+
cond_resched();
307308
}
308309
}
309310

drivers/net/wireguard/socket.c

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -76,12 +76,6 @@ static int send4(struct wg_device *wg, struct sk_buff *skb,
7676
net_dbg_ratelimited("%s: No route to %pISpfsc, error %d\n",
7777
wg->dev->name, &endpoint->addr, ret);
7878
goto err;
79-
} else if (unlikely(rt->dst.dev == skb->dev)) {
80-
ip_rt_put(rt);
81-
ret = -ELOOP;
82-
net_dbg_ratelimited("%s: Avoiding routing loop to %pISpfsc\n",
83-
wg->dev->name, &endpoint->addr);
84-
goto err;
8579
}
8680
if (cache)
8781
dst_cache_set_ip4(cache, &rt->dst, fl.saddr);
@@ -149,12 +143,6 @@ static int send6(struct wg_device *wg, struct sk_buff *skb,
149143
net_dbg_ratelimited("%s: No route to %pISpfsc, error %d\n",
150144
wg->dev->name, &endpoint->addr, ret);
151145
goto err;
152-
} else if (unlikely(dst->dev == skb->dev)) {
153-
dst_release(dst);
154-
ret = -ELOOP;
155-
net_dbg_ratelimited("%s: Avoiding routing loop to %pISpfsc\n",
156-
wg->dev->name, &endpoint->addr);
157-
goto err;
158146
}
159147
if (cache)
160148
dst_cache_set_ip6(cache, dst, &fl.saddr);

tools/testing/selftests/wireguard/netns.sh

Lines changed: 51 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,11 @@ cleanup() {
4848
exec 2>/dev/null
4949
printf "$orig_message_cost" > /proc/sys/net/core/message_cost
5050
ip0 link del dev wg0
51+
ip0 link del dev wg1
5152
ip1 link del dev wg0
53+
ip1 link del dev wg1
5254
ip2 link del dev wg0
55+
ip2 link del dev wg1
5356
local to_kill="$(ip netns pids $netns0) $(ip netns pids $netns1) $(ip netns pids $netns2)"
5457
[[ -n $to_kill ]] && kill $to_kill
5558
pp ip netns del $netns1
@@ -77,18 +80,20 @@ ip0 link set wg0 netns $netns2
7780
key1="$(pp wg genkey)"
7881
key2="$(pp wg genkey)"
7982
key3="$(pp wg genkey)"
83+
key4="$(pp wg genkey)"
8084
pub1="$(pp wg pubkey <<<"$key1")"
8185
pub2="$(pp wg pubkey <<<"$key2")"
8286
pub3="$(pp wg pubkey <<<"$key3")"
87+
pub4="$(pp wg pubkey <<<"$key4")"
8388
psk="$(pp wg genpsk)"
8489
[[ -n $key1 && -n $key2 && -n $psk ]]
8590

8691
configure_peers() {
8792
ip1 addr add 192.168.241.1/24 dev wg0
88-
ip1 addr add fd00::1/24 dev wg0
93+
ip1 addr add fd00::1/112 dev wg0
8994

9095
ip2 addr add 192.168.241.2/24 dev wg0
91-
ip2 addr add fd00::2/24 dev wg0
96+
ip2 addr add fd00::2/112 dev wg0
9297

9398
n1 wg set wg0 \
9499
private-key <(echo "$key1") \
@@ -230,9 +235,38 @@ n1 ping -W 1 -c 1 192.168.241.2
230235
n1 wg set wg0 private-key <(echo "$key3")
231236
n2 wg set wg0 peer "$pub3" preshared-key <(echo "$psk") allowed-ips 192.168.241.1/32 peer "$pub1" remove
232237
n1 ping -W 1 -c 1 192.168.241.2
238+
n2 wg set wg0 peer "$pub3" remove
239+
240+
# Test that we can route wg through wg
241+
ip1 addr flush dev wg0
242+
ip2 addr flush dev wg0
243+
ip1 addr add fd00::5:1/112 dev wg0
244+
ip2 addr add fd00::5:2/112 dev wg0
245+
n1 wg set wg0 private-key <(echo "$key1") peer "$pub2" preshared-key <(echo "$psk") allowed-ips fd00::5:2/128 endpoint 127.0.0.1:2
246+
n2 wg set wg0 private-key <(echo "$key2") listen-port 2 peer "$pub1" preshared-key <(echo "$psk") allowed-ips fd00::5:1/128 endpoint 127.212.121.99:9998
247+
ip1 link add wg1 type wireguard
248+
ip2 link add wg1 type wireguard
249+
ip1 addr add 192.168.241.1/24 dev wg1
250+
ip1 addr add fd00::1/112 dev wg1
251+
ip2 addr add 192.168.241.2/24 dev wg1
252+
ip2 addr add fd00::2/112 dev wg1
253+
ip1 link set mtu 1340 up dev wg1
254+
ip2 link set mtu 1340 up dev wg1
255+
n1 wg set wg1 listen-port 5 private-key <(echo "$key3") peer "$pub4" allowed-ips 192.168.241.2/32,fd00::2/128 endpoint [fd00::5:2]:5
256+
n2 wg set wg1 listen-port 5 private-key <(echo "$key4") peer "$pub3" allowed-ips 192.168.241.1/32,fd00::1/128 endpoint [fd00::5:1]:5
257+
tests
258+
# Try to set up a routing loop between the two namespaces
259+
ip1 link set netns $netns0 dev wg1
260+
ip0 addr add 192.168.241.1/24 dev wg1
261+
ip0 link set up dev wg1
262+
n0 ping -W 1 -c 1 192.168.241.2
263+
n1 wg set wg0 peer "$pub2" endpoint 192.168.241.2:7
264+
ip2 link del wg0
265+
ip2 link del wg1
266+
! n0 ping -W 1 -c 10 -f 192.168.241.2 || false # Should not crash kernel
233267

268+
ip0 link del wg1
234269
ip1 link del wg0
235-
ip2 link del wg0
236270

237271
# Test using NAT. We now change the topology to this:
238272
# ┌────────────────────────────────────────┐ ┌────────────────────────────────────────────────┐ ┌────────────────────────────────────────┐
@@ -282,6 +316,20 @@ pp sleep 3
282316
n2 ping -W 1 -c 1 192.168.241.1
283317
n1 wg set wg0 peer "$pub2" persistent-keepalive 0
284318

319+
# Test that onion routing works, even when it loops
320+
n1 wg set wg0 peer "$pub3" allowed-ips 192.168.242.2/32 endpoint 192.168.241.2:5
321+
ip1 addr add 192.168.242.1/24 dev wg0
322+
ip2 link add wg1 type wireguard
323+
ip2 addr add 192.168.242.2/24 dev wg1
324+
n2 wg set wg1 private-key <(echo "$key3") listen-port 5 peer "$pub1" allowed-ips 192.168.242.1/32
325+
ip2 link set wg1 up
326+
n1 ping -W 1 -c 1 192.168.242.2
327+
ip2 link del wg1
328+
n1 wg set wg0 peer "$pub3" endpoint 192.168.242.2:5
329+
! n1 ping -W 1 -c 1 192.168.242.2 || false # Should not crash kernel
330+
n1 wg set wg0 peer "$pub3" remove
331+
ip1 addr del 192.168.242.1/24 dev wg0
332+
285333
# Do a wg-quick(8)-style policy routing for the default route, making sure vethc has a v6 address to tease out bugs.
286334
ip1 -6 addr add fc00::9/96 dev vethc
287335
ip1 -6 route add default via fc00::1

tools/testing/selftests/wireguard/qemu/arch/powerpc64le.config

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,4 @@ CONFIG_CMDLINE_BOOL=y
1010
CONFIG_CMDLINE="console=hvc0 wg.success=hvc1"
1111
CONFIG_SECTION_MISMATCH_WARN_ONLY=y
1212
CONFIG_FRAME_WARN=1280
13+
CONFIG_THREAD_SHIFT=14

0 commit comments

Comments
 (0)