Merge remote-tracking branch 'torvalds/master' into perf/core
[linux-2.6-microblaze.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:${3:-5201} pid $2"; while [[ $(ss -N "$1" -tlpH "sport = ${3:-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         # TCP over IPv4, in parallel
146         for max in 4 5 50; do
147                 local pids=( )
148                 for ((i=0; i < max; ++i)) do
149                         n2 iperf3 -p $(( 5200 + i )) -s -1 -B 192.168.241.2 &
150                         pids+=( $! ); waitiperf $netns2 $! $(( 5200 + i ))
151                 done
152                 for ((i=0; i < max; ++i)) do
153                         n1 iperf3 -Z -t 3 -p $(( 5200 + i )) -c 192.168.241.2 &
154                 done
155                 wait "${pids[@]}"
156         done
157 }
158
159 [[ $(ip1 link show dev wg0) =~ mtu\ ([0-9]+) ]] && orig_mtu="${BASH_REMATCH[1]}"
160 big_mtu=$(( 34816 - 1500 + $orig_mtu ))
161
162 # Test using IPv4 as outer transport
163 n1 wg set wg0 peer "$pub2" endpoint 127.0.0.1:2
164 n2 wg set wg0 peer "$pub1" endpoint 127.0.0.1:1
165 # Before calling tests, we first make sure that the stats counters and timestamper are working
166 n2 ping -c 10 -f -W 1 192.168.241.1
167 { read _; read _; read _; read rx_bytes _; read _; read tx_bytes _; } < <(ip2 -stats link show dev wg0)
168 (( rx_bytes == 1372 && (tx_bytes == 1428 || tx_bytes == 1460) ))
169 { read _; read _; read _; read rx_bytes _; read _; read tx_bytes _; } < <(ip1 -stats link show dev wg0)
170 (( tx_bytes == 1372 && (rx_bytes == 1428 || rx_bytes == 1460) ))
171 read _ rx_bytes tx_bytes < <(n2 wg show wg0 transfer)
172 (( rx_bytes == 1372 && (tx_bytes == 1428 || tx_bytes == 1460) ))
173 read _ rx_bytes tx_bytes < <(n1 wg show wg0 transfer)
174 (( tx_bytes == 1372 && (rx_bytes == 1428 || rx_bytes == 1460) ))
175 read _ timestamp < <(n1 wg show wg0 latest-handshakes)
176 (( timestamp != 0 ))
177
178 tests
179 ip1 link set wg0 mtu $big_mtu
180 ip2 link set wg0 mtu $big_mtu
181 tests
182
183 ip1 link set wg0 mtu $orig_mtu
184 ip2 link set wg0 mtu $orig_mtu
185
186 # Test using IPv6 as outer transport
187 n1 wg set wg0 peer "$pub2" endpoint [::1]:2
188 n2 wg set wg0 peer "$pub1" endpoint [::1]:1
189 tests
190 ip1 link set wg0 mtu $big_mtu
191 ip2 link set wg0 mtu $big_mtu
192 tests
193
194 # Test that route MTUs work with the padding
195 ip1 link set wg0 mtu 1300
196 ip2 link set wg0 mtu 1300
197 n1 wg set wg0 peer "$pub2" endpoint 127.0.0.1:2
198 n2 wg set wg0 peer "$pub1" endpoint 127.0.0.1:1
199 n0 iptables -A INPUT -m length --length 1360 -j DROP
200 n1 ip route add 192.168.241.2/32 dev wg0 mtu 1299
201 n2 ip route add 192.168.241.1/32 dev wg0 mtu 1299
202 n2 ping -c 1 -W 1 -s 1269 192.168.241.1
203 n2 ip route delete 192.168.241.1/32 dev wg0 mtu 1299
204 n1 ip route delete 192.168.241.2/32 dev wg0 mtu 1299
205 n0 iptables -F INPUT
206
207 ip1 link set wg0 mtu $orig_mtu
208 ip2 link set wg0 mtu $orig_mtu
209
210 # Test using IPv4 that roaming works
211 ip0 -4 addr del 127.0.0.1/8 dev lo
212 ip0 -4 addr add 127.212.121.99/8 dev lo
213 n1 wg set wg0 listen-port 9999
214 n1 wg set wg0 peer "$pub2" endpoint 127.0.0.1:2
215 n1 ping6 -W 1 -c 1 fd00::2
216 [[ $(n2 wg show wg0 endpoints) == "$pub1        127.212.121.99:9999" ]]
217
218 # Test using IPv6 that roaming works
219 n1 wg set wg0 listen-port 9998
220 n1 wg set wg0 peer "$pub2" endpoint [::1]:2
221 n1 ping -W 1 -c 1 192.168.241.2
222 [[ $(n2 wg show wg0 endpoints) == "$pub1        [::1]:9998" ]]
223
224 # Test that crypto-RP filter works
225 n1 wg set wg0 peer "$pub2" allowed-ips 192.168.241.0/24
226 exec 4< <(n1 ncat -l -u -p 1111)
227 ncat_pid=$!
228 waitncatudp $netns1 $ncat_pid
229 n2 ncat -u 192.168.241.1 1111 <<<"X"
230 read -r -N 1 -t 1 out <&4 && [[ $out == "X" ]]
231 kill $ncat_pid
232 more_specific_key="$(pp wg genkey | pp wg pubkey)"
233 n1 wg set wg0 peer "$more_specific_key" allowed-ips 192.168.241.2/32
234 n2 wg set wg0 listen-port 9997
235 exec 4< <(n1 ncat -l -u -p 1111)
236 ncat_pid=$!
237 waitncatudp $netns1 $ncat_pid
238 n2 ncat -u 192.168.241.1 1111 <<<"X"
239 ! read -r -N 1 -t 1 out <&4 || false
240 kill $ncat_pid
241 n1 wg set wg0 peer "$more_specific_key" remove
242 [[ $(n1 wg show wg0 endpoints) == "$pub2        [::1]:9997" ]]
243
244 # Test that we can change private keys keys and immediately handshake
245 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
246 n2 wg set wg0 private-key <(echo "$key2") listen-port 2 peer "$pub1" preshared-key <(echo "$psk") allowed-ips 192.168.241.1/32
247 n1 ping -W 1 -c 1 192.168.241.2
248 n1 wg set wg0 private-key <(echo "$key3")
249 n2 wg set wg0 peer "$pub3" preshared-key <(echo "$psk") allowed-ips 192.168.241.1/32 peer "$pub1" remove
250 n1 ping -W 1 -c 1 192.168.241.2
251 n2 wg set wg0 peer "$pub3" remove
252
253 # Test that we can route wg through wg
254 ip1 addr flush dev wg0
255 ip2 addr flush dev wg0
256 ip1 addr add fd00::5:1/112 dev wg0
257 ip2 addr add fd00::5:2/112 dev wg0
258 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
259 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
260 ip1 link add wg1 type wireguard
261 ip2 link add wg1 type wireguard
262 ip1 addr add 192.168.241.1/24 dev wg1
263 ip1 addr add fd00::1/112 dev wg1
264 ip2 addr add 192.168.241.2/24 dev wg1
265 ip2 addr add fd00::2/112 dev wg1
266 ip1 link set mtu 1340 up dev wg1
267 ip2 link set mtu 1340 up dev wg1
268 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
269 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
270 tests
271 # Try to set up a routing loop between the two namespaces
272 ip1 link set netns $netns0 dev wg1
273 ip0 addr add 192.168.241.1/24 dev wg1
274 ip0 link set up dev wg1
275 n0 ping -W 1 -c 1 192.168.241.2
276 n1 wg set wg0 peer "$pub2" endpoint 192.168.241.2:7
277 ip2 link del wg0
278 ip2 link del wg1
279 ! n0 ping -W 1 -c 10 -f 192.168.241.2 || false # Should not crash kernel
280
281 ip0 link del wg1
282 ip1 link del wg0
283
284 # Test using NAT. We now change the topology to this:
285 # ┌────────────────────────────────────────┐    ┌────────────────────────────────────────────────┐     ┌────────────────────────────────────────┐
286 # │             $ns1 namespace             │    │                 $ns0 namespace                 │     │             $ns2 namespace             │
287 # │                                        │    │                                                │     │                                        │
288 # │  ┌─────┐             ┌─────┐           │    │    ┌──────┐              ┌──────┐              │     │  ┌─────┐            ┌─────┐            │
289 # │  │ wg0 │─────────────│vethc│───────────┼────┼────│vethrc│              │vethrs│──────────────┼─────┼──│veths│────────────│ wg0 │            │
290 # │  ├─────┴──────────┐  ├─────┴──────────┐│    │    ├──────┴─────────┐    ├──────┴────────────┐ │     │  ├─────┴──────────┐ ├─────┴──────────┐ │
291 # │  │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│ │
292 # │  │fd00::1/24      │  │                ││    │    │                │    │SNAT:192.168.1.0/24│ │     │  │                │ │fd00::2/24      │ │
293 # │  └────────────────┘  └────────────────┘│    │    └────────────────┘    └───────────────────┘ │     │  └────────────────┘ └────────────────┘ │
294 # └────────────────────────────────────────┘    └────────────────────────────────────────────────┘     └────────────────────────────────────────┘
295
296 ip1 link add dev wg0 type wireguard
297 ip2 link add dev wg0 type wireguard
298 configure_peers
299
300 ip0 link add vethrc type veth peer name vethc
301 ip0 link add vethrs type veth peer name veths
302 ip0 link set vethc netns $netns1
303 ip0 link set veths netns $netns2
304 ip0 link set vethrc up
305 ip0 link set vethrs up
306 ip0 addr add 192.168.1.1/24 dev vethrc
307 ip0 addr add 10.0.0.1/24 dev vethrs
308 ip1 addr add 192.168.1.100/24 dev vethc
309 ip1 link set vethc up
310 ip1 route add default via 192.168.1.1
311 ip2 addr add 10.0.0.100/24 dev veths
312 ip2 link set veths up
313 waitiface $netns0 vethrc
314 waitiface $netns0 vethrs
315 waitiface $netns1 vethc
316 waitiface $netns2 veths
317
318 n0 bash -c 'printf 1 > /proc/sys/net/ipv4/ip_forward'
319 n0 bash -c 'printf 2 > /proc/sys/net/netfilter/nf_conntrack_udp_timeout'
320 n0 bash -c 'printf 2 > /proc/sys/net/netfilter/nf_conntrack_udp_timeout_stream'
321 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
322
323 n1 wg set wg0 peer "$pub2" endpoint 10.0.0.100:2 persistent-keepalive 1
324 n1 ping -W 1 -c 1 192.168.241.2
325 n2 ping -W 1 -c 1 192.168.241.1
326 [[ $(n2 wg show wg0 endpoints) == "$pub1        10.0.0.1:1" ]]
327 # Demonstrate n2 can still send packets to n1, since persistent-keepalive will prevent connection tracking entry from expiring (to see entries: `n0 conntrack -L`).
328 pp sleep 3
329 n2 ping -W 1 -c 1 192.168.241.1
330 n1 wg set wg0 peer "$pub2" persistent-keepalive 0
331
332 # Test that sk_bound_dev_if works
333 n1 ping -I wg0 -c 1 -W 1 192.168.241.2
334 # What about when the mark changes and the packet must be rerouted?
335 n1 iptables -t mangle -I OUTPUT -j MARK --set-xmark 1
336 n1 ping -c 1 -W 1 192.168.241.2 # First the boring case
337 n1 ping -I wg0 -c 1 -W 1 192.168.241.2 # Then the sk_bound_dev_if case
338 n1 iptables -t mangle -D OUTPUT -j MARK --set-xmark 1
339
340 # Test that onion routing works, even when it loops
341 n1 wg set wg0 peer "$pub3" allowed-ips 192.168.242.2/32 endpoint 192.168.241.2:5
342 ip1 addr add 192.168.242.1/24 dev wg0
343 ip2 link add wg1 type wireguard
344 ip2 addr add 192.168.242.2/24 dev wg1
345 n2 wg set wg1 private-key <(echo "$key3") listen-port 5 peer "$pub1" allowed-ips 192.168.242.1/32
346 ip2 link set wg1 up
347 n1 ping -W 1 -c 1 192.168.242.2
348 ip2 link del wg1
349 n1 wg set wg0 peer "$pub3" endpoint 192.168.242.2:5
350 ! n1 ping -W 1 -c 1 192.168.242.2 || false # Should not crash kernel
351 n1 wg set wg0 peer "$pub3" remove
352 ip1 addr del 192.168.242.1/24 dev wg0
353
354 # Do a wg-quick(8)-style policy routing for the default route, making sure vethc has a v6 address to tease out bugs.
355 ip1 -6 addr add fc00::9/96 dev vethc
356 ip1 -6 route add default via fc00::1
357 ip2 -4 addr add 192.168.99.7/32 dev wg0
358 ip2 -6 addr add abab::1111/128 dev wg0
359 n1 wg set wg0 fwmark 51820 peer "$pub2" allowed-ips 192.168.99.7,abab::1111
360 ip1 -6 route add default dev wg0 table 51820
361 ip1 -6 rule add not fwmark 51820 table 51820
362 ip1 -6 rule add table main suppress_prefixlength 0
363 ip1 -4 route add default dev wg0 table 51820
364 ip1 -4 rule add not fwmark 51820 table 51820
365 ip1 -4 rule add table main suppress_prefixlength 0
366 n1 bash -c 'printf 0 > /proc/sys/net/ipv4/conf/vethc/rp_filter'
367 # Flood the pings instead of sending just one, to trigger routing table reference counting bugs.
368 n1 ping -W 1 -c 100 -f 192.168.99.7
369 n1 ping -W 1 -c 100 -f abab::1111
370
371 # Have ns2 NAT into wg0 packets from ns0, but return an icmp error along the right route.
372 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
373 n0 iptables -t filter -A INPUT \! -s 10.0.0.0/24 -i vethrs -j DROP # Manual rpfilter just to be explicit.
374 n2 bash -c 'printf 1 > /proc/sys/net/ipv4/ip_forward'
375 ip0 -4 route add 192.168.241.1 via 10.0.0.100
376 n2 wg set wg0 peer "$pub1" remove
377 [[ $(! n0 ping -W 1 -c 1 192.168.241.1 || false) == *"From 10.0.0.100 icmp_seq=1 Destination Host Unreachable"* ]]
378
379 n0 iptables -t nat -F
380 n0 iptables -t filter -F
381 n2 iptables -t nat -F
382 ip0 link del vethrc
383 ip0 link del vethrs
384 ip1 link del wg0
385 ip2 link del wg0
386
387 # Test that saddr routing is sticky but not too sticky, changing to this topology:
388 # ┌────────────────────────────────────────┐    ┌────────────────────────────────────────┐
389 # │             $ns1 namespace             │    │             $ns2 namespace             │
390 # │                                        │    │                                        │
391 # │  ┌─────┐             ┌─────┐           │    │  ┌─────┐            ┌─────┐            │
392 # │  │ wg0 │─────────────│veth1│───────────┼────┼──│veth2│────────────│ wg0 │            │
393 # │  ├─────┴──────────┐  ├─────┴──────────┐│    │  ├─────┴──────────┐ ├─────┴──────────┐ │
394 # │  │192.168.241.1/24│  │10.0.0.1/24     ││    │  │10.0.0.2/24     │ │192.168.241.2/24│ │
395 # │  │fd00::1/24      │  │fd00:aa::1/96   ││    │  │fd00:aa::2/96   │ │fd00::2/24      │ │
396 # │  └────────────────┘  └────────────────┘│    │  └────────────────┘ └────────────────┘ │
397 # └────────────────────────────────────────┘    └────────────────────────────────────────┘
398
399 ip1 link add dev wg0 type wireguard
400 ip2 link add dev wg0 type wireguard
401 configure_peers
402 ip1 link add veth1 type veth peer name veth2
403 ip1 link set veth2 netns $netns2
404 n1 bash -c 'printf 0 > /proc/sys/net/ipv6/conf/all/accept_dad'
405 n2 bash -c 'printf 0 > /proc/sys/net/ipv6/conf/all/accept_dad'
406 n1 bash -c 'printf 0 > /proc/sys/net/ipv6/conf/veth1/accept_dad'
407 n2 bash -c 'printf 0 > /proc/sys/net/ipv6/conf/veth2/accept_dad'
408 n1 bash -c 'printf 1 > /proc/sys/net/ipv4/conf/veth1/promote_secondaries'
409
410 # First we check that we aren't overly sticky and can fall over to new IPs when old ones are removed
411 ip1 addr add 10.0.0.1/24 dev veth1
412 ip1 addr add fd00:aa::1/96 dev veth1
413 ip2 addr add 10.0.0.2/24 dev veth2
414 ip2 addr add fd00:aa::2/96 dev veth2
415 ip1 link set veth1 up
416 ip2 link set veth2 up
417 waitiface $netns1 veth1
418 waitiface $netns2 veth2
419 n1 wg set wg0 peer "$pub2" endpoint 10.0.0.2:2
420 n1 ping -W 1 -c 1 192.168.241.2
421 ip1 addr add 10.0.0.10/24 dev veth1
422 ip1 addr del 10.0.0.1/24 dev veth1
423 n1 ping -W 1 -c 1 192.168.241.2
424 n1 wg set wg0 peer "$pub2" endpoint [fd00:aa::2]:2
425 n1 ping -W 1 -c 1 192.168.241.2
426 ip1 addr add fd00:aa::10/96 dev veth1
427 ip1 addr del fd00:aa::1/96 dev veth1
428 n1 ping -W 1 -c 1 192.168.241.2
429
430 # Now we show that we can successfully do reply to sender routing
431 ip1 link set veth1 down
432 ip2 link set veth2 down
433 ip1 addr flush dev veth1
434 ip2 addr flush dev veth2
435 ip1 addr add 10.0.0.1/24 dev veth1
436 ip1 addr add 10.0.0.2/24 dev veth1
437 ip1 addr add fd00:aa::1/96 dev veth1
438 ip1 addr add fd00:aa::2/96 dev veth1
439 ip2 addr add 10.0.0.3/24 dev veth2
440 ip2 addr add fd00:aa::3/96 dev veth2
441 ip1 link set veth1 up
442 ip2 link set veth2 up
443 waitiface $netns1 veth1
444 waitiface $netns2 veth2
445 n2 wg set wg0 peer "$pub1" endpoint 10.0.0.1:1
446 n2 ping -W 1 -c 1 192.168.241.1
447 [[ $(n2 wg show wg0 endpoints) == "$pub1        10.0.0.1:1" ]]
448 n2 wg set wg0 peer "$pub1" endpoint [fd00:aa::1]:1
449 n2 ping -W 1 -c 1 192.168.241.1
450 [[ $(n2 wg show wg0 endpoints) == "$pub1        [fd00:aa::1]:1" ]]
451 n2 wg set wg0 peer "$pub1" endpoint 10.0.0.2:1
452 n2 ping -W 1 -c 1 192.168.241.1
453 [[ $(n2 wg show wg0 endpoints) == "$pub1        10.0.0.2:1" ]]
454 n2 wg set wg0 peer "$pub1" endpoint [fd00:aa::2]:1
455 n2 ping -W 1 -c 1 192.168.241.1
456 [[ $(n2 wg show wg0 endpoints) == "$pub1        [fd00:aa::2]:1" ]]
457
458 # What happens if the inbound destination address belongs to a different interface as the default route?
459 ip1 link add dummy0 type dummy
460 ip1 addr add 10.50.0.1/24 dev dummy0
461 ip1 link set dummy0 up
462 ip2 route add 10.50.0.0/24 dev veth2
463 n2 wg set wg0 peer "$pub1" endpoint 10.50.0.1:1
464 n2 ping -W 1 -c 1 192.168.241.1
465 [[ $(n2 wg show wg0 endpoints) == "$pub1        10.50.0.1:1" ]]
466
467 ip1 link del dummy0
468 ip1 addr flush dev veth1
469 ip2 addr flush dev veth2
470 ip1 route flush dev veth1
471 ip2 route flush dev veth2
472
473 # Now we see what happens if another interface route takes precedence over an ongoing one
474 ip1 link add veth3 type veth peer name veth4
475 ip1 link set veth4 netns $netns2
476 ip1 addr add 10.0.0.1/24 dev veth1
477 ip2 addr add 10.0.0.2/24 dev veth2
478 ip1 addr add 10.0.0.3/24 dev veth3
479 ip1 link set veth1 up
480 ip2 link set veth2 up
481 ip1 link set veth3 up
482 ip2 link set veth4 up
483 waitiface $netns1 veth1
484 waitiface $netns2 veth2
485 waitiface $netns1 veth3
486 waitiface $netns2 veth4
487 ip1 route flush dev veth1
488 ip1 route flush dev veth3
489 ip1 route add 10.0.0.0/24 dev veth1 src 10.0.0.1 metric 2
490 n1 wg set wg0 peer "$pub2" endpoint 10.0.0.2:2
491 n1 ping -W 1 -c 1 192.168.241.2
492 [[ $(n2 wg show wg0 endpoints) == "$pub1        10.0.0.1:1" ]]
493 ip1 route add 10.0.0.0/24 dev veth3 src 10.0.0.3 metric 1
494 n1 bash -c 'printf 0 > /proc/sys/net/ipv4/conf/veth1/rp_filter'
495 n2 bash -c 'printf 0 > /proc/sys/net/ipv4/conf/veth4/rp_filter'
496 n1 bash -c 'printf 0 > /proc/sys/net/ipv4/conf/all/rp_filter'
497 n2 bash -c 'printf 0 > /proc/sys/net/ipv4/conf/all/rp_filter'
498 n1 ping -W 1 -c 1 192.168.241.2
499 [[ $(n2 wg show wg0 endpoints) == "$pub1        10.0.0.3:1" ]]
500
501 ip1 link del veth1
502 ip1 link del veth3
503 ip1 link del wg0
504 ip2 link del wg0
505
506 # We test that Netlink/IPC is working properly by doing things that usually cause split responses
507 ip0 link add dev wg0 type wireguard
508 config=( "[Interface]" "PrivateKey=$(wg genkey)" "[Peer]" "PublicKey=$(wg genkey)" )
509 for a in {1..255}; do
510         for b in {0..255}; do
511                 config+=( "AllowedIPs=$a.$b.0.0/16,$a::$b/128" )
512         done
513 done
514 n0 wg setconf wg0 <(printf '%s\n' "${config[@]}")
515 i=0
516 for ip in $(n0 wg show wg0 allowed-ips); do
517         ((++i))
518 done
519 ((i == 255*256*2+1))
520 ip0 link del wg0
521 ip0 link add dev wg0 type wireguard
522 config=( "[Interface]" "PrivateKey=$(wg genkey)" )
523 for a in {1..40}; do
524         config+=( "[Peer]" "PublicKey=$(wg genkey)" )
525         for b in {1..52}; do
526                 config+=( "AllowedIPs=$a.$b.0.0/16" )
527         done
528 done
529 n0 wg setconf wg0 <(printf '%s\n' "${config[@]}")
530 i=0
531 while read -r line; do
532         j=0
533         for ip in $line; do
534                 ((++j))
535         done
536         ((j == 53))
537         ((++i))
538 done < <(n0 wg show wg0 allowed-ips)
539 ((i == 40))
540 ip0 link del wg0
541 ip0 link add wg0 type wireguard
542 config=( )
543 for i in {1..29}; do
544         config+=( "[Peer]" "PublicKey=$(wg genkey)" )
545 done
546 config+=( "[Peer]" "PublicKey=$(wg genkey)" "AllowedIPs=255.2.3.4/32,abcd::255/128" )
547 n0 wg setconf wg0 <(printf '%s\n' "${config[@]}")
548 n0 wg showconf wg0 > /dev/null
549 ip0 link del wg0
550
551 allowedips=( )
552 for i in {1..197}; do
553         allowedips+=( abcd::$i )
554 done
555 saved_ifs="$IFS"
556 IFS=,
557 allowedips="${allowedips[*]}"
558 IFS="$saved_ifs"
559 ip0 link add wg0 type wireguard
560 n0 wg set wg0 peer "$pub1"
561 n0 wg set wg0 peer "$pub2" allowed-ips "$allowedips"
562 {
563         read -r pub allowedips
564         [[ $pub == "$pub1" && $allowedips == "(none)" ]]
565         read -r pub allowedips
566         [[ $pub == "$pub2" ]]
567         i=0
568         for _ in $allowedips; do
569                 ((++i))
570         done
571         ((i == 197))
572 } < <(n0 wg show wg0 allowed-ips)
573 ip0 link del wg0
574
575 ! n0 wg show doesnotexist || false
576
577 ip0 link add wg0 type wireguard
578 n0 wg set wg0 private-key <(echo "$key1") peer "$pub2" preshared-key <(echo "$psk")
579 [[ $(n0 wg show wg0 private-key) == "$key1" ]]
580 [[ $(n0 wg show wg0 preshared-keys) == "$pub2   $psk" ]]
581 n0 wg set wg0 private-key /dev/null peer "$pub2" preshared-key /dev/null
582 [[ $(n0 wg show wg0 private-key) == "(none)" ]]
583 [[ $(n0 wg show wg0 preshared-keys) == "$pub2   (none)" ]]
584 n0 wg set wg0 peer "$pub2"
585 n0 wg set wg0 private-key <(echo "$key2")
586 [[ $(n0 wg show wg0 public-key) == "$pub2" ]]
587 [[ -z $(n0 wg show wg0 peers) ]]
588 n0 wg set wg0 peer "$pub2"
589 [[ -z $(n0 wg show wg0 peers) ]]
590 n0 wg set wg0 private-key <(echo "$key1")
591 n0 wg set wg0 peer "$pub2"
592 [[ $(n0 wg show wg0 peers) == "$pub2" ]]
593 n0 wg set wg0 private-key <(echo "/${key1:1}")
594 [[ $(n0 wg show wg0 private-key) == "+${key1:1}" ]]
595 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
596 n0 wg set wg0 peer "$pub2" allowed-ips 0.0.0.0/0
597 n0 wg set wg0 peer "$pub2" allowed-ips ::/0,1700::/111,5000::/4,e000::/37,9000::/75
598 n0 wg set wg0 peer "$pub2" allowed-ips ::/0
599 n0 wg set wg0 peer "$pub2" remove
600 for low_order_point in AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= 4Ot6fDtBuK4WVuP68Z/EatoJjeucMrH9hmIFFl9JuAA= X5yVvKNQjCSx0LFVnIPvWwREXMRYHI6G2CJO3dCfEVc= 7P///////////////////////////////////////38= 7f///////////////////////////////////////38= 7v///////////////////////////////////////38=; do
601         n0 wg set wg0 peer "$low_order_point" persistent-keepalive 1 endpoint 127.0.0.1:1111
602 done
603 [[ -n $(n0 wg show wg0 peers) ]]
604 exec 4< <(n0 ncat -l -u -p 1111)
605 ncat_pid=$!
606 waitncatudp $netns0 $ncat_pid
607 ip0 link set wg0 up
608 ! read -r -n 1 -t 2 <&4 || false
609 kill $ncat_pid
610 ip0 link del wg0
611
612 # Ensure there aren't circular reference loops
613 ip1 link add wg1 type wireguard
614 ip2 link add wg2 type wireguard
615 ip1 link set wg1 netns $netns2
616 ip2 link set wg2 netns $netns1
617 pp ip netns delete $netns1
618 pp ip netns delete $netns2
619 pp ip netns add $netns1
620 pp ip netns add $netns2
621
622 sleep 2 # Wait for cleanup and grace periods
623 declare -A objects
624 while read -t 0.1 -r line 2>/dev/null || [[ $? -ne 142 ]]; do
625         [[ $line =~ .*(wg[0-9]+:\ [A-Z][a-z]+\ ?[0-9]*)\ .*(created|destroyed).* ]] || continue
626         objects["${BASH_REMATCH[1]}"]+="${BASH_REMATCH[2]}"
627 done < /dev/kmsg
628 alldeleted=1
629 for object in "${!objects[@]}"; do
630         if [[ ${objects["$object"]} != *createddestroyed ]]; then
631                 echo "Error: $object: merely ${objects["$object"]}" >&3
632                 alldeleted=0
633         fi
634 done
635 [[ $alldeleted -eq 1 ]]
636 pretty "" "Objects that were created were also destroyed."