]> git.ipfire.org Git - thirdparty/linux.git/blob - tools/testing/selftests/wireguard/netns.sh
Merge tag 'io_uring-5.7-2020-05-22' of git://git.kernel.dk/linux-block
[thirdparty/linux.git] / tools / testing / selftests / wireguard / netns.sh
1 #!/bin/bash
2 # SPDX-License-Identifier: GPL-2.0
3 #
4 # Copyright (C) 2015-2019 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
5 #
6 # This script tests the below topology:
7 #
8 # ┌─────────────────────┐ ┌──────────────────────────────────┐ ┌─────────────────────┐
9 # │ $ns1 namespace │ │ $ns0 namespace │ │ $ns2 namespace │
10 # │ │ │ │ │ │
11 # │┌────────┐ │ │ ┌────────┐ │ │ ┌────────┐│
12 # ││ wg0 │───────────┼───┼────────────│ lo │────────────┼───┼───────────│ wg0 ││
13 # │├────────┴──────────┐│ │ ┌───────┴────────┴────────┐ │ │┌──────────┴────────┤│
14 # ││192.168.241.1/24 ││ │ │(ns1) (ns2) │ │ ││192.168.241.2/24 ││
15 # ││fd00::1/24 ││ │ │127.0.0.1:1 127.0.0.1:2│ │ ││fd00::2/24 ││
16 # │└───────────────────┘│ │ │[::]:1 [::]:2 │ │ │└───────────────────┘│
17 # └─────────────────────┘ │ └─────────────────────────┘ │ └─────────────────────┘
18 # └──────────────────────────────────┘
19 #
20 # After the topology is prepared we run a series of TCP/UDP iperf3 tests between the
21 # wireguard peers in $ns1 and $ns2. Note that $ns0 is the endpoint for the wg0
22 # interfaces in $ns1 and $ns2. See https://www.wireguard.com/netns/ for further
23 # details on how this is accomplished.
24 set -e
25
26 exec 3>&1
27 export LANG=C
28 export WG_HIDE_KEYS=never
29 netns0="wg-test-$$-0"
30 netns1="wg-test-$$-1"
31 netns2="wg-test-$$-2"
32 pretty() { echo -e "\x1b[32m\x1b[1m[+] ${1:+NS$1: }${2}\x1b[0m" >&3; }
33 pp() { pretty "" "$*"; "$@"; }
34 maybe_exec() { if [[ $BASHPID -eq $$ ]]; then "$@"; else exec "$@"; fi; }
35 n0() { pretty 0 "$*"; maybe_exec ip netns exec $netns0 "$@"; }
36 n1() { pretty 1 "$*"; maybe_exec ip netns exec $netns1 "$@"; }
37 n2() { pretty 2 "$*"; maybe_exec ip netns exec $netns2 "$@"; }
38 ip0() { pretty 0 "ip $*"; ip -n $netns0 "$@"; }
39 ip1() { pretty 1 "ip $*"; ip -n $netns1 "$@"; }
40 ip2() { pretty 2 "ip $*"; ip -n $netns2 "$@"; }
41 sleep() { read -t "$1" -N 1 || true; }
42 waitiperf() { pretty "${1//*-}" "wait for iperf:5201 pid $2"; while [[ $(ss -N "$1" -tlpH 'sport = 5201') != *\"iperf3\",pid=$2,fd=* ]]; do sleep 0.1; done; }
43 waitncatudp() { pretty "${1//*-}" "wait for udp:1111 pid $2"; while [[ $(ss -N "$1" -ulpH 'sport = 1111') != *\"ncat\",pid=$2,fd=* ]]; do sleep 0.1; done; }
44 waitiface() { pretty "${1//*-}" "wait for $2 to come up"; ip netns exec "$1" bash -c "while [[ \$(< \"/sys/class/net/$2/operstate\") != up ]]; do read -t .1 -N 0 || true; done;"; }
45
46 cleanup() {
47 set +e
48 exec 2>/dev/null
49 printf "$orig_message_cost" > /proc/sys/net/core/message_cost
50 ip0 link del dev wg0
51 ip0 link del dev wg1
52 ip1 link del dev wg0
53 ip1 link del dev wg1
54 ip2 link del dev wg0
55 ip2 link del dev wg1
56 local to_kill="$(ip netns pids $netns0) $(ip netns pids $netns1) $(ip netns pids $netns2)"
57 [[ -n $to_kill ]] && kill $to_kill
58 pp ip netns del $netns1
59 pp ip netns del $netns2
60 pp ip netns del $netns0
61 exit
62 }
63
64 orig_message_cost="$(< /proc/sys/net/core/message_cost)"
65 trap cleanup EXIT
66 printf 0 > /proc/sys/net/core/message_cost
67
68 ip netns del $netns0 2>/dev/null || true
69 ip netns del $netns1 2>/dev/null || true
70 ip netns del $netns2 2>/dev/null || true
71 pp ip netns add $netns0
72 pp ip netns add $netns1
73 pp ip netns add $netns2
74 ip0 link set up dev lo
75
76 ip0 link add dev wg0 type wireguard
77 ip0 link set wg0 netns $netns1
78 ip0 link add dev wg0 type wireguard
79 ip0 link set wg0 netns $netns2
80 key1="$(pp wg genkey)"
81 key2="$(pp wg genkey)"
82 key3="$(pp wg genkey)"
83 key4="$(pp wg genkey)"
84 pub1="$(pp wg pubkey <<<"$key1")"
85 pub2="$(pp wg pubkey <<<"$key2")"
86 pub3="$(pp wg pubkey <<<"$key3")"
87 pub4="$(pp wg pubkey <<<"$key4")"
88 psk="$(pp wg genpsk)"
89 [[ -n $key1 && -n $key2 && -n $psk ]]
90
91 configure_peers() {
92 ip1 addr add 192.168.241.1/24 dev wg0
93 ip1 addr add fd00::1/112 dev wg0
94
95 ip2 addr add 192.168.241.2/24 dev wg0
96 ip2 addr add fd00::2/112 dev wg0
97
98 n1 wg set wg0 \
99 private-key <(echo "$key1") \
100 listen-port 1 \
101 peer "$pub2" \
102 preshared-key <(echo "$psk") \
103 allowed-ips 192.168.241.2/32,fd00::2/128
104 n2 wg set wg0 \
105 private-key <(echo "$key2") \
106 listen-port 2 \
107 peer "$pub1" \
108 preshared-key <(echo "$psk") \
109 allowed-ips 192.168.241.1/32,fd00::1/128
110
111 ip1 link set up dev wg0
112 ip2 link set up dev wg0
113 }
114 configure_peers
115
116 tests() {
117 # Ping over IPv4
118 n2 ping -c 10 -f -W 1 192.168.241.1
119 n1 ping -c 10 -f -W 1 192.168.241.2
120
121 # Ping over IPv6
122 n2 ping6 -c 10 -f -W 1 fd00::1
123 n1 ping6 -c 10 -f -W 1 fd00::2
124
125 # TCP over IPv4
126 n2 iperf3 -s -1 -B 192.168.241.2 &
127 waitiperf $netns2 $!
128 n1 iperf3 -Z -t 3 -c 192.168.241.2
129
130 # TCP over IPv6
131 n1 iperf3 -s -1 -B fd00::1 &
132 waitiperf $netns1 $!
133 n2 iperf3 -Z -t 3 -c fd00::1
134
135 # UDP over IPv4
136 n1 iperf3 -s -1 -B 192.168.241.1 &
137 waitiperf $netns1 $!
138 n2 iperf3 -Z -t 3 -b 0 -u -c 192.168.241.1
139
140 # UDP over IPv6
141 n2 iperf3 -s -1 -B fd00::2 &
142 waitiperf $netns2 $!
143 n1 iperf3 -Z -t 3 -b 0 -u -c fd00::2
144 }
145
146 [[ $(ip1 link show dev wg0) =~ mtu\ ([0-9]+) ]] && orig_mtu="${BASH_REMATCH[1]}"
147 big_mtu=$(( 34816 - 1500 + $orig_mtu ))
148
149 # Test using IPv4 as outer transport
150 n1 wg set wg0 peer "$pub2" endpoint 127.0.0.1:2
151 n2 wg set wg0 peer "$pub1" endpoint 127.0.0.1:1
152 # Before calling tests, we first make sure that the stats counters and timestamper are working
153 n2 ping -c 10 -f -W 1 192.168.241.1
154 { read _; read _; read _; read rx_bytes _; read _; read tx_bytes _; } < <(ip2 -stats link show dev wg0)
155 (( rx_bytes == 1372 && (tx_bytes == 1428 || tx_bytes == 1460) ))
156 { read _; read _; read _; read rx_bytes _; read _; read tx_bytes _; } < <(ip1 -stats link show dev wg0)
157 (( tx_bytes == 1372 && (rx_bytes == 1428 || rx_bytes == 1460) ))
158 read _ rx_bytes tx_bytes < <(n2 wg show wg0 transfer)
159 (( rx_bytes == 1372 && (tx_bytes == 1428 || tx_bytes == 1460) ))
160 read _ rx_bytes tx_bytes < <(n1 wg show wg0 transfer)
161 (( tx_bytes == 1372 && (rx_bytes == 1428 || rx_bytes == 1460) ))
162 read _ timestamp < <(n1 wg show wg0 latest-handshakes)
163 (( timestamp != 0 ))
164
165 tests
166 ip1 link set wg0 mtu $big_mtu
167 ip2 link set wg0 mtu $big_mtu
168 tests
169
170 ip1 link set wg0 mtu $orig_mtu
171 ip2 link set wg0 mtu $orig_mtu
172
173 # Test using IPv6 as outer transport
174 n1 wg set wg0 peer "$pub2" endpoint [::1]:2
175 n2 wg set wg0 peer "$pub1" endpoint [::1]:1
176 tests
177 ip1 link set wg0 mtu $big_mtu
178 ip2 link set wg0 mtu $big_mtu
179 tests
180
181 # Test that route MTUs work with the padding
182 ip1 link set wg0 mtu 1300
183 ip2 link set wg0 mtu 1300
184 n1 wg set wg0 peer "$pub2" endpoint 127.0.0.1:2
185 n2 wg set wg0 peer "$pub1" endpoint 127.0.0.1:1
186 n0 iptables -A INPUT -m length --length 1360 -j DROP
187 n1 ip route add 192.168.241.2/32 dev wg0 mtu 1299
188 n2 ip route add 192.168.241.1/32 dev wg0 mtu 1299
189 n2 ping -c 1 -W 1 -s 1269 192.168.241.1
190 n2 ip route delete 192.168.241.1/32 dev wg0 mtu 1299
191 n1 ip route delete 192.168.241.2/32 dev wg0 mtu 1299
192 n0 iptables -F INPUT
193
194 ip1 link set wg0 mtu $orig_mtu
195 ip2 link set wg0 mtu $orig_mtu
196
197 # Test using IPv4 that roaming works
198 ip0 -4 addr del 127.0.0.1/8 dev lo
199 ip0 -4 addr add 127.212.121.99/8 dev lo
200 n1 wg set wg0 listen-port 9999
201 n1 wg set wg0 peer "$pub2" endpoint 127.0.0.1:2
202 n1 ping6 -W 1 -c 1 fd00::2
203 [[ $(n2 wg show wg0 endpoints) == "$pub1 127.212.121.99:9999" ]]
204
205 # Test using IPv6 that roaming works
206 n1 wg set wg0 listen-port 9998
207 n1 wg set wg0 peer "$pub2" endpoint [::1]:2
208 n1 ping -W 1 -c 1 192.168.241.2
209 [[ $(n2 wg show wg0 endpoints) == "$pub1 [::1]:9998" ]]
210
211 # Test that crypto-RP filter works
212 n1 wg set wg0 peer "$pub2" allowed-ips 192.168.241.0/24
213 exec 4< <(n1 ncat -l -u -p 1111)
214 ncat_pid=$!
215 waitncatudp $netns1 $ncat_pid
216 n2 ncat -u 192.168.241.1 1111 <<<"X"
217 read -r -N 1 -t 1 out <&4 && [[ $out == "X" ]]
218 kill $ncat_pid
219 more_specific_key="$(pp wg genkey | pp wg pubkey)"
220 n1 wg set wg0 peer "$more_specific_key" allowed-ips 192.168.241.2/32
221 n2 wg set wg0 listen-port 9997
222 exec 4< <(n1 ncat -l -u -p 1111)
223 ncat_pid=$!
224 waitncatudp $netns1 $ncat_pid
225 n2 ncat -u 192.168.241.1 1111 <<<"X"
226 ! read -r -N 1 -t 1 out <&4 || false
227 kill $ncat_pid
228 n1 wg set wg0 peer "$more_specific_key" remove
229 [[ $(n1 wg show wg0 endpoints) == "$pub2 [::1]:9997" ]]
230
231 # Test that we can change private keys keys and immediately handshake
232 n1 wg set wg0 private-key <(echo "$key1") peer "$pub2" preshared-key <(echo "$psk") allowed-ips 192.168.241.2/32 endpoint 127.0.0.1:2
233 n2 wg set wg0 private-key <(echo "$key2") listen-port 2 peer "$pub1" preshared-key <(echo "$psk") allowed-ips 192.168.241.1/32
234 n1 ping -W 1 -c 1 192.168.241.2
235 n1 wg set wg0 private-key <(echo "$key3")
236 n2 wg set wg0 peer "$pub3" preshared-key <(echo "$psk") allowed-ips 192.168.241.1/32 peer "$pub1" remove
237 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
267
268 ip0 link del wg1
269 ip1 link del wg0
270
271 # Test using NAT. We now change the topology to this:
272 # ┌────────────────────────────────────────┐ ┌────────────────────────────────────────────────┐ ┌────────────────────────────────────────┐
273 # │ $ns1 namespace │ │ $ns0 namespace │ │ $ns2 namespace │
274 # │ │ │ │ │ │
275 # │ ┌─────┐ ┌─────┐ │ │ ┌──────┐ ┌──────┐ │ │ ┌─────┐ ┌─────┐ │
276 # │ │ wg0 │─────────────│vethc│───────────┼────┼────│vethrc│ │vethrs│──────────────┼─────┼──│veths│────────────│ wg0 │ │
277 # │ ├─────┴──────────┐ ├─────┴──────────┐│ │ ├──────┴─────────┐ ├──────┴────────────┐ │ │ ├─────┴──────────┐ ├─────┴──────────┐ │
278 # │ │192.168.241.1/24│ │192.168.1.100/24││ │ │192.168.1.1/24 │ │10.0.0.1/24 │ │ │ │10.0.0.100/24 │ │192.168.241.2/24│ │
279 # │ │fd00::1/24 │ │ ││ │ │ │ │SNAT:192.168.1.0/24│ │ │ │ │ │fd00::2/24 │ │
280 # │ └────────────────┘ └────────────────┘│ │ └────────────────┘ └───────────────────┘ │ │ └────────────────┘ └────────────────┘ │
281 # └────────────────────────────────────────┘ └────────────────────────────────────────────────┘ └────────────────────────────────────────┘
282
283 ip1 link add dev wg0 type wireguard
284 ip2 link add dev wg0 type wireguard
285 configure_peers
286
287 ip0 link add vethrc type veth peer name vethc
288 ip0 link add vethrs type veth peer name veths
289 ip0 link set vethc netns $netns1
290 ip0 link set veths netns $netns2
291 ip0 link set vethrc up
292 ip0 link set vethrs up
293 ip0 addr add 192.168.1.1/24 dev vethrc
294 ip0 addr add 10.0.0.1/24 dev vethrs
295 ip1 addr add 192.168.1.100/24 dev vethc
296 ip1 link set vethc up
297 ip1 route add default via 192.168.1.1
298 ip2 addr add 10.0.0.100/24 dev veths
299 ip2 link set veths up
300 waitiface $netns0 vethrc
301 waitiface $netns0 vethrs
302 waitiface $netns1 vethc
303 waitiface $netns2 veths
304
305 n0 bash -c 'printf 1 > /proc/sys/net/ipv4/ip_forward'
306 n0 bash -c 'printf 2 > /proc/sys/net/netfilter/nf_conntrack_udp_timeout'
307 n0 bash -c 'printf 2 > /proc/sys/net/netfilter/nf_conntrack_udp_timeout_stream'
308 n0 iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -d 10.0.0.0/24 -j SNAT --to 10.0.0.1
309
310 n1 wg set wg0 peer "$pub2" endpoint 10.0.0.100:2 persistent-keepalive 1
311 n1 ping -W 1 -c 1 192.168.241.2
312 n2 ping -W 1 -c 1 192.168.241.1
313 [[ $(n2 wg show wg0 endpoints) == "$pub1 10.0.0.1:1" ]]
314 # Demonstrate n2 can still send packets to n1, since persistent-keepalive will prevent connection tracking entry from expiring (to see entries: `n0 conntrack -L`).
315 pp sleep 3
316 n2 ping -W 1 -c 1 192.168.241.1
317 n1 wg set wg0 peer "$pub2" persistent-keepalive 0
318
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
333 # Do a wg-quick(8)-style policy routing for the default route, making sure vethc has a v6 address to tease out bugs.
334 ip1 -6 addr add fc00::9/96 dev vethc
335 ip1 -6 route add default via fc00::1
336 ip2 -4 addr add 192.168.99.7/32 dev wg0
337 ip2 -6 addr add abab::1111/128 dev wg0
338 n1 wg set wg0 fwmark 51820 peer "$pub2" allowed-ips 192.168.99.7,abab::1111
339 ip1 -6 route add default dev wg0 table 51820
340 ip1 -6 rule add not fwmark 51820 table 51820
341 ip1 -6 rule add table main suppress_prefixlength 0
342 ip1 -4 route add default dev wg0 table 51820
343 ip1 -4 rule add not fwmark 51820 table 51820
344 ip1 -4 rule add table main suppress_prefixlength 0
345 # Flood the pings instead of sending just one, to trigger routing table reference counting bugs.
346 n1 ping -W 1 -c 100 -f 192.168.99.7
347 n1 ping -W 1 -c 100 -f abab::1111
348
349 # Have ns2 NAT into wg0 packets from ns0, but return an icmp error along the right route.
350 n2 iptables -t nat -A POSTROUTING -s 10.0.0.0/24 -d 192.168.241.0/24 -j SNAT --to 192.168.241.2
351 n0 iptables -t filter -A INPUT \! -s 10.0.0.0/24 -i vethrs -j DROP # Manual rpfilter just to be explicit.
352 n2 bash -c 'printf 1 > /proc/sys/net/ipv4/ip_forward'
353 ip0 -4 route add 192.168.241.1 via 10.0.0.100
354 n2 wg set wg0 peer "$pub1" remove
355 [[ $(! n0 ping -W 1 -c 1 192.168.241.1 || false) == *"From 10.0.0.100 icmp_seq=1 Destination Host Unreachable"* ]]
356
357 n0 iptables -t nat -F
358 n0 iptables -t filter -F
359 n2 iptables -t nat -F
360 ip0 link del vethrc
361 ip0 link del vethrs
362 ip1 link del wg0
363 ip2 link del wg0
364
365 # Test that saddr routing is sticky but not too sticky, changing to this topology:
366 # ┌────────────────────────────────────────┐ ┌────────────────────────────────────────┐
367 # │ $ns1 namespace │ │ $ns2 namespace │
368 # │ │ │ │
369 # │ ┌─────┐ ┌─────┐ │ │ ┌─────┐ ┌─────┐ │
370 # │ │ wg0 │─────────────│veth1│───────────┼────┼──│veth2│────────────│ wg0 │ │
371 # │ ├─────┴──────────┐ ├─────┴──────────┐│ │ ├─────┴──────────┐ ├─────┴──────────┐ │
372 # │ │192.168.241.1/24│ │10.0.0.1/24 ││ │ │10.0.0.2/24 │ │192.168.241.2/24│ │
373 # │ │fd00::1/24 │ │fd00:aa::1/96 ││ │ │fd00:aa::2/96 │ │fd00::2/24 │ │
374 # │ └────────────────┘ └────────────────┘│ │ └────────────────┘ └────────────────┘ │
375 # └────────────────────────────────────────┘ └────────────────────────────────────────┘
376
377 ip1 link add dev wg0 type wireguard
378 ip2 link add dev wg0 type wireguard
379 configure_peers
380 ip1 link add veth1 type veth peer name veth2
381 ip1 link set veth2 netns $netns2
382 n1 bash -c 'printf 0 > /proc/sys/net/ipv6/conf/all/accept_dad'
383 n2 bash -c 'printf 0 > /proc/sys/net/ipv6/conf/all/accept_dad'
384 n1 bash -c 'printf 0 > /proc/sys/net/ipv6/conf/veth1/accept_dad'
385 n2 bash -c 'printf 0 > /proc/sys/net/ipv6/conf/veth2/accept_dad'
386 n1 bash -c 'printf 1 > /proc/sys/net/ipv4/conf/veth1/promote_secondaries'
387
388 # First we check that we aren't overly sticky and can fall over to new IPs when old ones are removed
389 ip1 addr add 10.0.0.1/24 dev veth1
390 ip1 addr add fd00:aa::1/96 dev veth1
391 ip2 addr add 10.0.0.2/24 dev veth2
392 ip2 addr add fd00:aa::2/96 dev veth2
393 ip1 link set veth1 up
394 ip2 link set veth2 up
395 waitiface $netns1 veth1
396 waitiface $netns2 veth2
397 n1 wg set wg0 peer "$pub2" endpoint 10.0.0.2:2
398 n1 ping -W 1 -c 1 192.168.241.2
399 ip1 addr add 10.0.0.10/24 dev veth1
400 ip1 addr del 10.0.0.1/24 dev veth1
401 n1 ping -W 1 -c 1 192.168.241.2
402 n1 wg set wg0 peer "$pub2" endpoint [fd00:aa::2]:2
403 n1 ping -W 1 -c 1 192.168.241.2
404 ip1 addr add fd00:aa::10/96 dev veth1
405 ip1 addr del fd00:aa::1/96 dev veth1
406 n1 ping -W 1 -c 1 192.168.241.2
407
408 # Now we show that we can successfully do reply to sender routing
409 ip1 link set veth1 down
410 ip2 link set veth2 down
411 ip1 addr flush dev veth1
412 ip2 addr flush dev veth2
413 ip1 addr add 10.0.0.1/24 dev veth1
414 ip1 addr add 10.0.0.2/24 dev veth1
415 ip1 addr add fd00:aa::1/96 dev veth1
416 ip1 addr add fd00:aa::2/96 dev veth1
417 ip2 addr add 10.0.0.3/24 dev veth2
418 ip2 addr add fd00:aa::3/96 dev veth2
419 ip1 link set veth1 up
420 ip2 link set veth2 up
421 waitiface $netns1 veth1
422 waitiface $netns2 veth2
423 n2 wg set wg0 peer "$pub1" endpoint 10.0.0.1:1
424 n2 ping -W 1 -c 1 192.168.241.1
425 [[ $(n2 wg show wg0 endpoints) == "$pub1 10.0.0.1:1" ]]
426 n2 wg set wg0 peer "$pub1" endpoint [fd00:aa::1]:1
427 n2 ping -W 1 -c 1 192.168.241.1
428 [[ $(n2 wg show wg0 endpoints) == "$pub1 [fd00:aa::1]:1" ]]
429 n2 wg set wg0 peer "$pub1" endpoint 10.0.0.2:1
430 n2 ping -W 1 -c 1 192.168.241.1
431 [[ $(n2 wg show wg0 endpoints) == "$pub1 10.0.0.2:1" ]]
432 n2 wg set wg0 peer "$pub1" endpoint [fd00:aa::2]:1
433 n2 ping -W 1 -c 1 192.168.241.1
434 [[ $(n2 wg show wg0 endpoints) == "$pub1 [fd00:aa::2]:1" ]]
435
436 # What happens if the inbound destination address belongs to a different interface as the default route?
437 ip1 link add dummy0 type dummy
438 ip1 addr add 10.50.0.1/24 dev dummy0
439 ip1 link set dummy0 up
440 ip2 route add 10.50.0.0/24 dev veth2
441 n2 wg set wg0 peer "$pub1" endpoint 10.50.0.1:1
442 n2 ping -W 1 -c 1 192.168.241.1
443 [[ $(n2 wg show wg0 endpoints) == "$pub1 10.50.0.1:1" ]]
444
445 ip1 link del dummy0
446 ip1 addr flush dev veth1
447 ip2 addr flush dev veth2
448 ip1 route flush dev veth1
449 ip2 route flush dev veth2
450
451 # Now we see what happens if another interface route takes precedence over an ongoing one
452 ip1 link add veth3 type veth peer name veth4
453 ip1 link set veth4 netns $netns2
454 ip1 addr add 10.0.0.1/24 dev veth1
455 ip2 addr add 10.0.0.2/24 dev veth2
456 ip1 addr add 10.0.0.3/24 dev veth3
457 ip1 link set veth1 up
458 ip2 link set veth2 up
459 ip1 link set veth3 up
460 ip2 link set veth4 up
461 waitiface $netns1 veth1
462 waitiface $netns2 veth2
463 waitiface $netns1 veth3
464 waitiface $netns2 veth4
465 ip1 route flush dev veth1
466 ip1 route flush dev veth3
467 ip1 route add 10.0.0.0/24 dev veth1 src 10.0.0.1 metric 2
468 n1 wg set wg0 peer "$pub2" endpoint 10.0.0.2:2
469 n1 ping -W 1 -c 1 192.168.241.2
470 [[ $(n2 wg show wg0 endpoints) == "$pub1 10.0.0.1:1" ]]
471 ip1 route add 10.0.0.0/24 dev veth3 src 10.0.0.3 metric 1
472 n1 bash -c 'printf 0 > /proc/sys/net/ipv4/conf/veth1/rp_filter'
473 n2 bash -c 'printf 0 > /proc/sys/net/ipv4/conf/veth4/rp_filter'
474 n1 bash -c 'printf 0 > /proc/sys/net/ipv4/conf/all/rp_filter'
475 n2 bash -c 'printf 0 > /proc/sys/net/ipv4/conf/all/rp_filter'
476 n1 ping -W 1 -c 1 192.168.241.2
477 [[ $(n2 wg show wg0 endpoints) == "$pub1 10.0.0.3:1" ]]
478
479 ip1 link del veth1
480 ip1 link del veth3
481 ip1 link del wg0
482 ip2 link del wg0
483
484 # We test that Netlink/IPC is working properly by doing things that usually cause split responses
485 ip0 link add dev wg0 type wireguard
486 config=( "[Interface]" "PrivateKey=$(wg genkey)" "[Peer]" "PublicKey=$(wg genkey)" )
487 for a in {1..255}; do
488 for b in {0..255}; do
489 config+=( "AllowedIPs=$a.$b.0.0/16,$a::$b/128" )
490 done
491 done
492 n0 wg setconf wg0 <(printf '%s\n' "${config[@]}")
493 i=0
494 for ip in $(n0 wg show wg0 allowed-ips); do
495 ((++i))
496 done
497 ((i == 255*256*2+1))
498 ip0 link del wg0
499 ip0 link add dev wg0 type wireguard
500 config=( "[Interface]" "PrivateKey=$(wg genkey)" )
501 for a in {1..40}; do
502 config+=( "[Peer]" "PublicKey=$(wg genkey)" )
503 for b in {1..52}; do
504 config+=( "AllowedIPs=$a.$b.0.0/16" )
505 done
506 done
507 n0 wg setconf wg0 <(printf '%s\n' "${config[@]}")
508 i=0
509 while read -r line; do
510 j=0
511 for ip in $line; do
512 ((++j))
513 done
514 ((j == 53))
515 ((++i))
516 done < <(n0 wg show wg0 allowed-ips)
517 ((i == 40))
518 ip0 link del wg0
519 ip0 link add wg0 type wireguard
520 config=( )
521 for i in {1..29}; do
522 config+=( "[Peer]" "PublicKey=$(wg genkey)" )
523 done
524 config+=( "[Peer]" "PublicKey=$(wg genkey)" "AllowedIPs=255.2.3.4/32,abcd::255/128" )
525 n0 wg setconf wg0 <(printf '%s\n' "${config[@]}")
526 n0 wg showconf wg0 > /dev/null
527 ip0 link del wg0
528
529 allowedips=( )
530 for i in {1..197}; do
531 allowedips+=( abcd::$i )
532 done
533 saved_ifs="$IFS"
534 IFS=,
535 allowedips="${allowedips[*]}"
536 IFS="$saved_ifs"
537 ip0 link add wg0 type wireguard
538 n0 wg set wg0 peer "$pub1"
539 n0 wg set wg0 peer "$pub2" allowed-ips "$allowedips"
540 {
541 read -r pub allowedips
542 [[ $pub == "$pub1" && $allowedips == "(none)" ]]
543 read -r pub allowedips
544 [[ $pub == "$pub2" ]]
545 i=0
546 for _ in $allowedips; do
547 ((++i))
548 done
549 ((i == 197))
550 } < <(n0 wg show wg0 allowed-ips)
551 ip0 link del wg0
552
553 ! n0 wg show doesnotexist || false
554
555 ip0 link add wg0 type wireguard
556 n0 wg set wg0 private-key <(echo "$key1") peer "$pub2" preshared-key <(echo "$psk")
557 [[ $(n0 wg show wg0 private-key) == "$key1" ]]
558 [[ $(n0 wg show wg0 preshared-keys) == "$pub2 $psk" ]]
559 n0 wg set wg0 private-key /dev/null peer "$pub2" preshared-key /dev/null
560 [[ $(n0 wg show wg0 private-key) == "(none)" ]]
561 [[ $(n0 wg show wg0 preshared-keys) == "$pub2 (none)" ]]
562 n0 wg set wg0 peer "$pub2"
563 n0 wg set wg0 private-key <(echo "$key2")
564 [[ $(n0 wg show wg0 public-key) == "$pub2" ]]
565 [[ -z $(n0 wg show wg0 peers) ]]
566 n0 wg set wg0 peer "$pub2"
567 [[ -z $(n0 wg show wg0 peers) ]]
568 n0 wg set wg0 private-key <(echo "$key1")
569 n0 wg set wg0 peer "$pub2"
570 [[ $(n0 wg show wg0 peers) == "$pub2" ]]
571 n0 wg set wg0 private-key <(echo "/${key1:1}")
572 [[ $(n0 wg show wg0 private-key) == "+${key1:1}" ]]
573 n0 wg set wg0 peer "$pub2" allowed-ips 0.0.0.0/0,10.0.0.0/8,100.0.0.0/10,172.16.0.0/12,192.168.0.0/16
574 n0 wg set wg0 peer "$pub2" allowed-ips 0.0.0.0/0
575 n0 wg set wg0 peer "$pub2" allowed-ips ::/0,1700::/111,5000::/4,e000::/37,9000::/75
576 n0 wg set wg0 peer "$pub2" allowed-ips ::/0
577 n0 wg set wg0 peer "$pub2" remove
578 for low_order_point in AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= 4Ot6fDtBuK4WVuP68Z/EatoJjeucMrH9hmIFFl9JuAA= X5yVvKNQjCSx0LFVnIPvWwREXMRYHI6G2CJO3dCfEVc= 7P///////////////////////////////////////38= 7f///////////////////////////////////////38= 7v///////////////////////////////////////38=; do
579 n0 wg set wg0 peer "$low_order_point" persistent-keepalive 1 endpoint 127.0.0.1:1111
580 done
581 [[ -n $(n0 wg show wg0 peers) ]]
582 exec 4< <(n0 ncat -l -u -p 1111)
583 ncat_pid=$!
584 waitncatudp $netns0 $ncat_pid
585 ip0 link set wg0 up
586 ! read -r -n 1 -t 2 <&4 || false
587 kill $ncat_pid
588 ip0 link del wg0
589
590 declare -A objects
591 while read -t 0.1 -r line 2>/dev/null || [[ $? -ne 142 ]]; do
592 [[ $line =~ .*(wg[0-9]+:\ [A-Z][a-z]+\ [0-9]+)\ .*(created|destroyed).* ]] || continue
593 objects["${BASH_REMATCH[1]}"]+="${BASH_REMATCH[2]}"
594 done < /dev/kmsg
595 alldeleted=1
596 for object in "${!objects[@]}"; do
597 if [[ ${objects["$object"]} != *createddestroyed ]]; then
598 echo "Error: $object: merely ${objects["$object"]}" >&3
599 alldeleted=0
600 fi
601 done
602 [[ $alldeleted -eq 1 ]]
603 pretty "" "Objects that were created were also destroyed."