aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorJason A. Donenfeld <Jason@zx2c4.com>2016-07-25 14:17:11 +0200
committerJason A. Donenfeld <Jason@zx2c4.com>2016-08-08 15:44:42 +0200
commit0a2052846089300000ad2607097acd71d368ee3d (patch)
treeaa109df28e0d9c79ec4c195b150b70296d786552
parentpersistent-keepalive: change range to [1,65535] (diff)
downloadwireguard-monolithic-historical-0a2052846089300000ad2607097acd71d368ee3d.tar.xz
wireguard-monolithic-historical-0a2052846089300000ad2607097acd71d368ee3d.zip
tests: use makefile and expand greatly
-rw-r--r--.gitignore2
-rw-r--r--src/tests/debug.mk7
-rwxr-xr-xsrc/tests/guest-init.sh15
-rwxr-xr-xsrc/tests/netns.sh252
-rwxr-xr-xsrc/tests/qemu.sh132
-rw-r--r--src/tests/qemu/Makefile196
-rw-r--r--src/tests/qemu/debug.config64
-rw-r--r--src/tests/qemu/init.c110
-rw-r--r--src/tests/qemu/kernel.config68
9 files changed, 609 insertions, 237 deletions
diff --git a/.gitignore b/.gitignore
index 7a4b600..7e37082 100644
--- a/.gitignore
+++ b/.gitignore
@@ -8,3 +8,5 @@ Module.symvers
*.swp
modules.order
modules.builtin
+src/tests/qemu/build/
+src/tests/qemu/distfiles/
diff --git a/src/tests/debug.mk b/src/tests/debug.mk
index a013c97..1b298a7 100644
--- a/src/tests/debug.mk
+++ b/src/tests/debug.mk
@@ -21,7 +21,12 @@ test: debug
-sudo modprobe x_tables
-sudo modprobe ipv6
-sudo modprobe xt_hashlimit
- ./tests/netns.sh
+ -sudo rmmod wireguard
+ -sudo insmod wireguard.ko
+ sudo PATH="$(shell pwd)/tools:$$PATH:/usr/sbin:/sbin:/usr/bin:/bin:/usr/local/sbin:/usr/local/bin" ./tests/netns.sh
+
+test-qemu:
+ $(MAKE) -C tests/qemu
remote-test:
ssh $(SSH_OPTS1) -Nf $(REMOTE_HOST1)
diff --git a/src/tests/guest-init.sh b/src/tests/guest-init.sh
deleted file mode 100755
index 676bbb0..0000000
--- a/src/tests/guest-init.sh
+++ /dev/null
@@ -1,15 +0,0 @@
-#!/bin/bash
-export PATH="/tools:/sbin:/bin"
-/bin/busybox ln -sf / /usr
-/bin/busybox --install -s
-mkdir /run /proc /tmp /sys /var /dev
-ln -s /run /var/run
-mount -t tmpfs none /run
-mount -t tmpfs none /tmp
-mount -t sysfs none /sys
-mount -t proc none /proc
-mount -t devtmpfs none /dev
-ln -s /proc/self/fd /dev/fd
-/wireguard/tests/netns.sh --no-module-insert && touch /wg-netns-success
-echo o > /proc/sysrq-trigger
-sleep 10000000000
diff --git a/src/tests/netns.sh b/src/tests/netns.sh
index 901ec36..eb5ed43 100755
--- a/src/tests/netns.sh
+++ b/src/tests/netns.sh
@@ -1,100 +1,104 @@
#!/bin/bash
-# This is a simple test suite for WireGuard. At some point it might be
-# nice to transition this to Sharness, like git, cgit, and pass, but
-# it's possible that kernel upstream won't like the bulkiness of that
-# very much. So for now we'll leave it to a single simple file like
-# this one here.
+# This script tests the below topology:
#
-# The exit code is 0 when this is successful.
-
-[[ $UID != 0 ]] && exec sudo bash "$(readlink -f "$0")" "$@"
-[[ $1 == --no-module-insert ]] && no_module=1 || no_module=0
-set -ex
-date
-cd "$(dirname "$(readlink -f "$0")")/.."
-
-unset netns0 netns1 netns2
-while [[ $netns1 == "$netns2" || $netns0 == "$netns1" || $netns0 == "$netns2" ]]; do
- netns0="wgtestns$RANDOM"
- netns1="wgtestns$RANDOM"
- netns2="wgtestns$RANDOM"
-done
-
-n0() { ip netns exec $netns0 "$@"; }
-n1() { ip netns exec $netns1 "$@"; }
-n2() { ip netns exec $netns2 "$@"; }
-ip0() { ip -n $netns0 "$@"; }
-ip1() { ip -n $netns1 "$@"; }
-ip2() { ip -n $netns2 "$@"; }
+# ┌─────────────────────┐ ┌──────────────────────────────────┐ ┌─────────────────────┐
+# │ $ns1 namespace │ │ $ns0 namespace │ │ $ns2 namespace │
+# │ │ │ │ │ │
+# │┌────────┐ │ │ ┌────────┐ │ │ ┌────────┐│
+# ││ wg0 │───────────┼───┼────────────│ lo │────────────┼───┼───────────│ wg0 ││
+# │├────────┴──────────┐│ │ ┌───────┴────────┴────────┐ │ │┌──────────┴────────┤│
+# ││192.168.241.1/24 ││ │ │(ns1) (ns2) │ │ ││192.168.241.2/24 ││
+# ││abcd::1/24 ││ │ │127.0.0.1:1 127.0.0.1:2│ │ ││abcd::2/24 ││
+# │└───────────────────┘│ │ │[::]:1 [::]:2 │ │ │└───────────────────┘│
+# └─────────────────────┘ │ └─────────────────────────┘ │ └─────────────────────┘
+# └──────────────────────────────────┘
+#
+# After the topology is prepared we run a series of TCP/UDP iperf3 tests between the
+# wireguard peers in $ns1 and $ns2. Note that $ns0 is the endpoint for the wg0
+# interfaces in $ns1 and $ns2. See https://www.wireguard.io/netns/ for further
+# details on how this is accomplished.
+set -e
+
+exec 3>&1
+export WG_HIDE_KEYS=never
+netns0="wg-test-$$-0"
+netns1="wg-test-$$-1"
+netns2="wg-test-$$-2"
+pretty() { echo -e "\x1b[32m\x1b[1m[+] ${1:+NS$1: }${2}\x1b[0m" >&3; }
+pp() { pretty "" "$*"; "$@"; }
+n0() { pretty 0 "$*"; ip netns exec $netns0 "$@"; }
+n1() { pretty 1 "$*"; ip netns exec $netns1 "$@"; }
+n2() { pretty 2 "$*"; ip netns exec $netns2 "$@"; }
+ip0() { pretty 0 "ip $*"; ip -n $netns0 "$@"; }
+ip1() { pretty 1 "ip $*"; ip -n $netns1 "$@"; }
+ip2() { pretty 2 "ip $*"; ip -n $netns2 "$@"; }
+sleep() { read -t "$1" -N 0 || true; }
+waitiperf() { pretty "${1//*-}" "wait for iperf:5201"; while [[ $(ss -N "$1" -tlp 'sport = 5201') != *iperf3* ]]; do sleep 0.1; done; }
cleanup() {
set +e
+ exec 2>/dev/null
ip0 link del dev wg0
ip1 link del dev wg0
ip2 link del dev wg0
- [[ $no_module -ne 1 ]] && rmmod wireguard
- killall iperf3
- ip netns del $netns1
- ip netns del $netns2
- ip netns del $netns0
+ pp ip netns del $netns1
+ pp ip netns del $netns2
+ pp ip netns del $netns0
+ kill -- -$$
exit
}
trap cleanup EXIT
-if [[ $no_module -ne 1 ]]; then
- rmmod wireguard 2>/dev/null || true
- # We consider insertion part of the tests because when compiled in debug mode,
- # the module will fail to insert if the internal kernel self-tests fail.
- insmod wireguard.ko
-fi
-
ip netns del $netns0 2>/dev/null || true
ip netns del $netns1 2>/dev/null || true
ip netns del $netns2 2>/dev/null || true
-ip netns add $netns0
-ip netns add $netns1
-ip netns add $netns2
-
+pp ip netns add $netns0
+pp ip netns add $netns1
+pp ip netns add $netns2
ip0 link set up dev lo
+
ip0 link add dev wg0 type wireguard
ip0 link set wg0 netns $netns1
ip0 link add dev wg0 type wireguard
ip0 link set wg0 netns $netns2
-
-ip1 addr add 192.168.241.1/24 dev wg0
-ip1 addr add abcd::1/24 dev wg0
-ip2 addr add 192.168.241.2/24 dev wg0
-ip2 addr add abcd::2/24 dev wg0
-
-key1="$(tools/wg genkey)"
-key2="$(tools/wg genkey)"
-pub1="$(tools/wg pubkey <<<"$key1")"
-pub2="$(tools/wg pubkey <<<"$key2")"
-psk="$(tools/wg genpsk)"
+key1="$(pp wg genkey)"
+key2="$(pp wg genkey)"
+pub1="$(pp wg pubkey <<<"$key1")"
+pub2="$(pp wg pubkey <<<"$key2")"
+psk="$(pp wg genpsk)"
[[ -n $key1 && -n $key2 && -n $psk ]]
-n1 tools/wg set wg0 \
- private-key <(echo "$key1") \
- preshared-key <(echo "$psk") \
- listen-port 1 \
- peer "$pub2" \
- allowed-ips 192.168.241.2/32,abcd::2/128
-n2 tools/wg set wg0 \
- private-key <(echo "$key2") \
- preshared-key <(echo "$psk") \
- listen-port 2 \
- peer "$pub1" \
- allowed-ips 192.168.241.1/32,abcd::1/128
-
-ip1 link set up dev wg0
-ip2 link set up dev wg0
+configure_peers() {
+ ip1 addr add 192.168.241.1/24 dev wg0
+ ip1 addr add abcd::1/24 dev wg0
+
+ ip2 addr add 192.168.241.2/24 dev wg0
+ ip2 addr add abcd::2/24 dev wg0
+
+ n1 wg set wg0 \
+ private-key <(echo "$key1") \
+ preshared-key <(echo "$psk") \
+ listen-port 1 \
+ peer "$pub2" \
+ allowed-ips 192.168.241.2/32,abcd::2/128
+ n2 wg set wg0 \
+ private-key <(echo "$key2") \
+ preshared-key <(echo "$psk") \
+ listen-port 2 \
+ peer "$pub1" \
+ allowed-ips 192.168.241.1/32,abcd::1/128
+
+ ip1 link set up dev wg0
+ ip2 link set up dev wg0
+}
+configure_peers
tests() {
# Status before
- n1 tools/wg
- n2 tools/wg
+ n1 wg
+ n2 wg
# Ping over IPv4
n2 ping -c 10 -f -W 1 192.168.241.1
@@ -105,38 +109,108 @@ tests() {
n1 ping6 -c 10 -f -W 1 abcd::2
# TCP over IPv4
- n2 iperf3 -s -D -B 192.168.241.2
- while ! ss -N $netns2 -tlp 'sport = 5201' | grep -q iperf3; do sleep 0.1; done
- n1 iperf3 -Z -i 1 -n 1G "$@" -c 192.168.241.2
+ n2 iperf3 -s -1 -B 192.168.241.2 &
+ waitiperf $netns2
+ n1 iperf3 -Z -i 1 -n 500M "$@" -c 192.168.241.2
# TCP over IPv6
- n1 iperf3 -s -D -B abcd::1
- while ! ss -N $netns1 -tlp 'sport = 5201' | grep -q iperf3; do sleep 0.1; done
- n2 iperf3 -Z -i 1 -n 1G "$@" -c abcd::1
+ n1 iperf3 -s -1 -B abcd::1 &
+ waitiperf $netns1
+ n2 iperf3 -Z -i 1 -n 500M "$@" -c abcd::1
# UDP over IPv4
- n1 iperf3 -s -D -B 192.168.241.1
- while ! ss -N $netns1 -tlp 'sport = 5201' | grep -q iperf3; do sleep 0.1; done
- n2 iperf3 -Z -i 1 -n 1G "$@" -b 0 -u -c 192.168.241.1
+ n1 iperf3 -s -1 -B 192.168.241.1 &
+ waitiperf $netns1
+ n2 iperf3 -Z -i 1 -n 500M "$@" -b 0 -u -c 192.168.241.1
# UDP over IPv6
- n2 iperf3 -s -D -B abcd::2
- while ! ss -N $netns2 -tlp 'sport = 5201' | grep -q iperf3; do sleep 0.1; done
- n1 iperf3 -Z -i 1 -n 1G "$@" -b 0 -u -c abcd::2
+ n2 iperf3 -s -1 -B abcd::2 &
+ waitiperf $netns2
+ n1 iperf3 -Z -i 1 -n 500M "$@" -b 0 -u -c abcd::2
# Status after
- n1 tools/wg
- n2 tools/wg
+ n1 wg
+ n2 wg
}
# Test using IPv4 as outer transport
-n1 tools/wg set wg0 peer "$pub2" endpoint 127.0.0.1:2
-n2 tools/wg set wg0 peer "$pub1" endpoint 127.0.0.1:1
+n1 wg set wg0 peer "$pub2" endpoint 127.0.0.1:2
+n2 wg set wg0 peer "$pub1" endpoint 127.0.0.1:1
tests
# Test using IPv6 as outer transport
-n1 tools/wg set wg0 peer "$pub2" endpoint [::1]:2
-n2 tools/wg set wg0 peer "$pub1" endpoint [::1]:1
+n1 wg set wg0 peer "$pub2" endpoint [::1]:2
+n2 wg set wg0 peer "$pub1" endpoint [::1]:1
tests
-date
+# Test using IPv4 that roaming works
+ip0 -4 addr del 127.0.0.1/8 dev lo
+ip0 -4 addr add 127.212.121.99/8 dev lo
+n1 wg set wg0 listen-port 9999
+n1 wg set wg0 peer "$pub2" endpoint 127.0.0.1:2
+n1 ping6 -W 1 -c 1 abcd::2
+[[ $(n2 wg show wg0 endpoints) == "$pub1 127.212.121.99:9999" ]]
+n1 wg
+n2 wg
+
+# Test using IPv6 that roaming works
+n1 wg set wg0 listen-port 9998
+n1 wg set wg0 peer "$pub2" endpoint [::1]:2
+n1 ping -W 1 -c 1 192.168.241.2
+[[ $(n2 wg show wg0 endpoints) == "$pub1 [::1]:9998" ]]
+n1 wg
+n2 wg
+
+# Test using NAT. We now change the topology to this:
+# ┌────────────────────────────────────────┐ ┌────────────────────────────────────────────────┐ ┌────────────────────────────────────────┐
+# │ $ns1 namespace │ │ $ns0 namespace │ │ $ns2 namespace │
+# │ │ │ │ │ │
+# │ │ │ │ │ │
+# │ ┌─────┐ ┌─────┐ │ │ ┌──────┐ ┌──────┐ │ │ ┌─────┐ ┌─────┐ │
+# │ │ wg0 │─────────────│vethc│───────────┼────┼────│vethrc│ │vethrs│──────────────┼─────┼──│veths│────────────│ wg0 │ │
+# │ ├─────┴──────────┐ ├─────┴──────────┐│ │ ├──────┴─────────┐ ├──────┴────────────┐ │ │ ├─────┴──────────┐ ├─────┴──────────┐ │
+# │ │192.168.241.1/24│ │192.168.1.100/24││ │ │192.168.1.100/24│ │10.0.0.1/24 │ │ │ │10.0.0.100/24 │ │192.168.241.2/24│ │
+# │ │abcd::1/24 │ │ ││ │ │ │ │SNAT:192.168.1.0/24│ │ │ │ │ │abcd::2/24 │ │
+# │ └────────────────┘ └────────────────┘│ │ └────────────────┘ └───────────────────┘ │ │ └────────────────┘ └────────────────┘ │
+# │ │ │ │ │ │
+# │ │ │ │ │ │
+# │ │ │ │ │ │
+# └────────────────────────────────────────┘ └────────────────────────────────────────────────┘ └────────────────────────────────────────┘
+
+ip1 link del wg0
+ip2 link del wg0
+ip1 link add dev wg0 type wireguard
+ip2 link add dev wg0 type wireguard
+configure_peers
+
+ip0 link add vethrc type veth peer name vethc
+ip0 link add vethrs type veth peer name veths
+ip0 link set vethc netns $netns1
+ip0 link set veths netns $netns2
+ip0 link set vethrc up
+ip0 link set vethrs up
+ip0 addr add 192.168.1.1/24 dev vethrc
+ip0 addr add 10.0.0.1/24 dev vethrs
+ip1 addr add 192.168.1.100/24 dev vethc
+ip1 link set vethc up
+ip1 route add default via 192.168.1.1
+ip2 addr add 10.0.0.100/24 dev veths
+ip2 link set veths up
+
+n0 bash -c 'echo 1 > /proc/sys/kernel/sysctl_writes_strict'
+n0 bash -c 'echo 1 > /proc/sys/net/ipv4/ip_forward'
+n0 bash -c 'echo 2 > /proc/sys/net/netfilter/nf_conntrack_udp_timeout'
+n0 bash -c 'echo 2 > /proc/sys/net/netfilter/nf_conntrack_udp_timeout_stream'
+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
+
+n1 wg set wg0 peer "$pub2" endpoint 10.0.0.100:2 persistent-keepalive 1
+n1 wg
+n2 wg
+n1 ping -W 1 -c 1 192.168.241.2
+n2 ping -W 1 -c 1 192.168.241.1
+n1 wg
+n2 wg
+[[ $(n2 wg show wg0 endpoints) == "$pub1 10.0.0.1:1" ]]
+# Demonstrate n2 can still send packets to n1, since persistent-keepalive will prevent connection tracking entry from expiring (to see entries: `n0 conntrack -L`).
+pp sleep 3
+n2 ping -W 1 -c 1 192.168.241.1
diff --git a/src/tests/qemu.sh b/src/tests/qemu.sh
deleted file mode 100755
index 8bd5026..0000000
--- a/src/tests/qemu.sh
+++ /dev/null
@@ -1,132 +0,0 @@
-#!/bin/bash
-# This compiles a kernel, creates a rootfs, and then starts up
-# QEMU to run the netns.sh test.
-#
-# The exit code is 0 when this is successful.
-
-set -ex
-cleanup() {
- set +e
- [[ -d $scratch_dir ]] || exit
- cd /
- rm -rf "$scratch_dir"
-}
-trap cleanup EXIT
-wireguard_dir="$(readlink -f "$(dirname "$(readlink -f "$0")")/..")"
-scratch_dir="$(mktemp -d)"
-cd "$scratch_dir"
-mkdir -p root/tools
-root_dir="$(readlink -f root)"
-wget https://cdn.kernel.org/pub/linux/kernel/v4.x/linux-4.6.4.tar.xz
-tar xf linux-*.tar.xz
-cd linux-*
-make x86_64_defconfig
-sed -i "/^if NET\$/a source \"$wireguard_dir/Kconfig\"" net/Kconfig
-echo "obj-y += ../../../../../../../../../../../../../../../../../../../../../..$wireguard_dir/" >> net/Makefile
-cat >> .config <<_EOF
-CONFIG_NET=y
-CONFIG_INET=y
-CONFIG_NETFILTER=y
-CONFIG_NETFILTER_XTABLES=y
-CONFIG_NETFILTER_ADVANCED=y
-CONFIG_NF_CONNTRACK=y
-CONFIG_IP6_NF_IPTABLES=y
-CONFIG_IPV6=y
-CONFIG_NET_UDP_TUNNEL=y
-CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=y
-CONFIG_CRYPTO_MANAGER=y
-CONFIG_WIREGUARD=y
-CONFIG_WIREGUARD_DEBUG=y
-CONFIG_WIREGUARD_PARALLEL=y
-CONFIG_HW_RANDOM_VIRTIO=y
-_EOF
-make kvmconfig
-make -j$(nproc)
-make INSTALL_HDR_PATH="$root_dir" headers_install
-cd ..
-
-wget https://www.musl-libc.org/releases/musl-1.1.15.tar.gz
-tar xf musl-*.tar.gz
-cd musl-*
-unset CC
-./configure --prefix="$root_dir"
-make -j$(nproc)
-make install
-export CC="$root_dir/bin/musl-gcc"
-export CFLAGS="-static -O2"
-cd ..
-wget http://ftp.gnu.org/gnu/bash/bash-4.3.tar.gz
-tar xf bash-*.tar.gz
-cd bash-*
-for i in {1..43}; do
- wget -O - http://ftp.gnu.org/gnu/bash/bash-4.3-patches/bash43-$(printf '%03d' $i) | patch -p0
-done
-./configure --prefix="$root_dir" --without-bash-malloc
-make -j$(nproc)
-make install
-cd ..
-wget https://busybox.net/downloads/busybox-1.25.0.tar.bz2
-tar xf busybox-*.tar.bz2
-cd busybox-*
-make defconfig
-make -j$(nproc)
-cp busybox "$root_dir/bin/"
-cd ..
-wget http://ftp.netfilter.org/pub/libmnl/libmnl-1.0.4.tar.bz2
-tar xf libmnl-*.tar.bz2
-cd libmnl-*
-./configure --prefix="$root_dir" --enable-static --disable-shared
-make -j$(nproc)
-make install
-cd ..
-wget https://www.kernel.org/pub/linux/utils/net/iproute2/iproute2-4.3.0.tar.xz
-tar xf iproute2-*.tar.xz
-cd iproute2-*
-sed -i 's/-O2/-O2 -static/' Makefile
-sed -i '/ARPD/d' Makefile
-sed -i 's/arpd.8//' man/man8/Makefile
-sed -i 's/m_ipt.o//' tc/Makefile
-sed -i 's/[^ ]*_bpf.o//' tc/Makefile
-echo -e "TC_CONFIG_XT=n\nTC_CONFIG_ATM=n\nTC_CONFIG_IPSET=n\nIP_CONFIG_SETNS=y" > Config
-wget -O - https://cgit.gentoo.org/proj/musl.git/plain/sys-apps/iproute2/files/iproute2-4.3.0-musl.patch | patch -p1
-make -j$(nproc) PREFIX="$root_dir" CC="$CC" LDFLAGS=-static
-cp ip/ip misc/ss "$root_dir/tools"
-cd ..
-wget http://downloads.es.net/pub/iperf/iperf-3.1.3.tar.gz
-tar xf iperf-*.tar.gz
-cd iperf-*
-wget -O - https://github.com/esnet/iperf/commit/1fe02385b60c9dcd8a04b8bd3ff5cff120ec35a6.diff | patch -p1
-sed -i 's/-pg//;s/-g//' src/Makefile*
-LDFLAGS=-static CFLAGS="-static -O2 -D_GNU_SOURCE" ./configure --prefix="$root_dir" --disable-shared --enable-static
-make -j$(nprocs)
-rm src/iperf3
-sed -i 's/iperf3_CFLAGS =/iperf3_CFLAGS = -all-static/' src/Makefile
-make
-cp src/iperf3 "$root_dir/tools"
-wget https://github.com/iputils/iputils/archive/s20160308.tar.gz -O iputils-s20160308.tar.gz
-tar xf iputils-*.tar.gz
-cd iputils-*
-LDFLAGS=-static make CC="$CC" USE_IDN=no USE_CAP=no USE_CRYPTO=no USE_GCRYPT=no USE_NETTLE=no ping -j$(nproc)
-cp ping $root_dir/tools/ping
-cp ping $root_dir/tools/ping6
-cd ..
-cp -r "$wireguard_dir" "$root_dir/wireguard"
-cd "$root_dir/wireguard/tools"
-make clean
-LDFLAGS=-static PKG_CONFIG_SYSROOT_DIR="$root_dir" PKG_CONFIG_PATH="$root_dir/lib/pkgconfig" PKG_CONFIG_LIBDIR="$root_dir/lib/pkgconfig" PREFIX="$root_dir" make -j$(nproc)
-cd "$root_dir/.."
-
-qemu-system-x86_64 \
- -enable-kvm \
- -cpu host \
- -smp 2 \
- -m 64M \
- -nographic \
- -object rng-random,id=rng0,filename=/dev/urandom \
- -device virtio-rng-pci,rng=rng0 \
- -kernel linux-*/arch/x86/boot/bzImage \
- -fsdev local,path="$root_dir",security_model=none,id=root \
- -device virtio-9p-pci,fsdev=root,mount_tag=/dev/root \
- -append "root=/dev/root rw rootfstype=9p rootflags=trans=virtio console=ttyS0 init=/wireguard/tests/guest-init.sh"
-
-[[ -e $root_dir/wg-netns-success ]]
diff --git a/src/tests/qemu/Makefile b/src/tests/qemu/Makefile
new file mode 100644
index 0000000..1474734
--- /dev/null
+++ b/src/tests/qemu/Makefile
@@ -0,0 +1,196 @@
+PWD := $(shell pwd)
+
+# Set these from the environment to override
+KERNEL_VERSION ?= 4.7
+BUILD_PATH ?= $(PWD)/build
+DISTFILES_PATH ?= $(PWD)/distfiles
+DEBUG_KERNEL ?= no
+NR_CPUS ?= 2
+
+
+DOWNLOAD := wget -O
+# DOWNLOAD := curl -f -o
+
+MIRROR := https://download.wireguard.io/qemu-test/distfiles/
+
+CHOST := x86_64-pc-linux-gnu
+WIREGUARD_SOURCES := $(wildcard ../../*.c ../../*.h ../../selftest/*.h ../../crypto/*.c ../../crypto/*.h ../../crypto/*.S)
+TOOLS_SOURCES := $(wildcard ../../tools/*.c ../../tools*.h ../../uapi.h)
+
+default: qemu
+
+# variable name, tarball project name, version, tarball extension, default URI base
+define tar_download =
+$(1)_VERSION := $(3)
+$(1)_NAME := $(2)-$$($(1)_VERSION)
+$(1)_TAR := $(DISTFILES_PATH)/$$($(1)_NAME)$(4)
+$(1)_PATH := $(BUILD_PATH)/$$($(1)_NAME)
+$(call file_download,$$($(1)_NAME)$(4),$(5))
+endef
+
+define file_download =
+$(DISTFILES_PATH)/$(1):
+ mkdir -p $(DISTFILES_PATH)
+ [ -n "$(MIRROR)" ] && $(DOWNLOAD) $$@ $(MIRROR)/$(1) || $(DOWNLOAD) $$@ $(2)/$(1)
+endef
+
+$(eval $(call tar_download,KERNEL,linux,$(KERNEL_VERSION),.tar.xz,https://www.kernel.org/pub/linux/kernel/v4.x/))
+KERNEL_BZIMAGE := $(KERNEL_PATH)/arch/x86/boot/bzImage
+$(eval $(call tar_download,MUSL,musl,1.1.15,.tar.gz,https://www.musl-libc.org/releases/))
+$(eval $(call tar_download,LIBMNL,libmnl,1.0.4,.tar.bz2,http://ftp.netfilter.org/pub/libmnl/))
+$(eval $(call tar_download,IPERF,iperf,3.1.3,.tar.gz,http://downloads.es.net/pub/iperf/))
+$(eval $(call tar_download,BASH,bash,30a978b7d808c067219c95be88c4979b6a7aa251,.tar.gz,http://git.savannah.gnu.org/cgit/bash.git/snapshot/))
+$(eval $(call tar_download,IPROUTE2,iproute2,4.3.0,.tar.gz,http://www.kernel.org/pub/linux/utils/net/iproute2/))
+$(eval $(call tar_download,IPTABLES,iptables,1.6.0,.tar.bz2,http://ftp.netfilter.org/pub/iptables/))
+
+IPUTILS_VERSION := s20160308
+IPUTILS_TAR := $(DISTFILES_PATH)/$(IPUTILS_VERSION).tar.gz
+IPUTILS_PATH := $(BUILD_PATH)/iputils-$(IPUTILS_VERSION)
+$(eval $(call file_download,$(IPUTILS_VERSION).tar.gz,https://github.com/iputils/iputils/archive/))
+
+CFLAGS ?= -O3 -march=native -pipe
+CPPFLAGS := -I$(BUILD_PATH)/include
+
+MUSL_CC := $(BUILD_PATH)/musl-gcc
+
+qemu: $(KERNEL_BZIMAGE)
+ rm -f $(BUILD_PATH)/result
+ qemu-system-x86_64 \
+ -nodefaults \
+ -nographic \
+ -machine q35,accel=kvm \
+ -cpu host \
+ -smp $(NR_CPUS) \
+ -m 64M \
+ -object rng-random,id=rng0,filename=/dev/urandom \
+ -device virtio-rng-pci,rng=rng0 \
+ -device virtio-serial,max_ports=2 \
+ -chardev stdio,id=stdio \
+ -device virtconsole,chardev=stdio \
+ -chardev file,id=status,path=$(BUILD_PATH)/result \
+ -device virtserialport,chardev=status \
+ -monitor none \
+ -kernel $< \
+ -append "console=hvc0"
+ grep -Fq success $(BUILD_PATH)/result
+
+$(BUILD_PATH)/init-cpio-spec.txt:
+ mkdir -p $(BUILD_PATH)
+ echo "file /init $(BUILD_PATH)/init 755 0 0" > $@
+ echo "file /init.sh $(PWD)/../netns.sh 755 0 0" >> $@
+ echo "dir /dev 755 0 0" >> $@
+ echo "nod /dev/console 644 0 0 c 5 1" >> $@
+ echo "dir /bin 755 0 0" >> $@
+ echo "file /bin/iperf3 $(IPERF_PATH)/src/iperf3 755 0 0" >> $@
+ echo "file /bin/wg $(BUILD_PATH)/tools/wg 755 0 0" >> $@
+ echo "file /bin/bash $(BASH_PATH)/bash 755 0 0" >> $@
+ echo "file /bin/ip $(IPROUTE2_PATH)/ip/ip 755 0 0" >> $@
+ echo "file /bin/ss $(IPROUTE2_PATH)/misc/ss 755 0 0" >> $@
+ echo "file /bin/ping $(IPUTILS_PATH)/ping 755 0 0" >> $@
+ echo "file /bin/xtables-multi $(IPTABLES_PATH)/iptables/xtables-multi 755 0 0" >> $@
+ echo "slink /bin/iptables xtables-multi 777 0 0" >> $@
+ echo "slink /bin/ping6 ping 777 0 0" >> $@
+ echo "dir /lib 755 0 0" >> $@
+ echo "file /lib/libc.so $(MUSL_PATH)/lib/libc.so 755 0 0" >> $@
+ echo "slink /lib/ld-linux.so.1 libc.so 777 0 0" >> $@
+
+$(KERNEL_PATH): $(KERNEL_TAR)
+ mkdir -p $(BUILD_PATH)
+ tar -C $(BUILD_PATH) -xf $<
+ sed -i "/^if INET\$$/a source \"net/wireguard/Kconfig\"" $(KERNEL_PATH)/net/Kconfig
+ sed -i "/^obj-\$$(CONFIG_NET).*:=/a obj-\$$(CONFIG_WIREGUARD) += wireguard/" $(KERNEL_PATH)/net/Makefile
+ ln -sf $(shell readlink -f ../..) $(KERNEL_PATH)/net/wireguard
+
+$(KERNEL_PATH)/.config: kernel.config | $(KERNEL_PATH)
+ cp kernel.config $(KERNEL_PATH)/minimal.config
+ printf 'CONFIG_NR_CPUS=$(NR_CPUS)\nCONFIG_INITRAMFS_SOURCE="$(BUILD_PATH)/init-cpio-spec.txt"\n' >> $(KERNEL_PATH)/minimal.config
+ $(MAKE) -C $(KERNEL_PATH) ARCH=x86_64 tinyconfig
+ cd $(KERNEL_PATH) && scripts/kconfig/merge_config.sh -n .config minimal.config
+ -[ "$(DEBUG_KERNEL)" = "yes" ] && ( cd $(KERNEL_PATH) && scripts/kconfig/merge_config.sh -n .config $(PWD)/debug.config )
+
+$(KERNEL_BZIMAGE): $(KERNEL_PATH) $(KERNEL_PATH)/.config $(BUILD_PATH)/init-cpio-spec.txt $(MUSL_PATH)/lib/libc.so $(IPERF_PATH)/src/iperf3 $(BUILD_PATH)/tools/wg $(IPUTILS_PATH)/ping $(BASH_PATH)/bash $(IPROUTE2_PATH)/ip/ip $(IPTABLES_PATH)/iptables/xtables-multi $(BUILD_PATH)/init ../netns.sh $(WIREGUARD_SOURCES) $(TOOLS_SOURCES)
+ $(MAKE) -C $(KERNEL_PATH)
+
+$(BUILD_PATH)/include/linux: | $(KERNEL_PATH)
+ $(MAKE) -C $(KERNEL_PATH) INSTALL_HDR_PATH=$(BUILD_PATH) headers_install
+
+$(MUSL_PATH)/lib/libc.so: $(MUSL_TAR) | $(BUILD_PATH)/include/linux
+ tar -C $(BUILD_PATH) -xf $<
+ cd $(MUSL_PATH) && ./configure --prefix=/ --disable-static CFLAGS="$(CFLAGS)"
+ $(MAKE) -C $(MUSL_PATH)
+ strip -s $@
+
+$(MUSL_CC): $(MUSL_PATH)/lib/libc.so
+ $(MAKE) -C $(MUSL_PATH) DESTDIR=$(BUILD_PATH) install-headers
+ sh $(MUSL_PATH)/tools/musl-gcc.specs.sh $(BUILD_PATH)/include $(MUSL_PATH)/lib /lib/ld-linux.so.1 > $(BUILD_PATH)/musl-gcc.specs
+ printf '#!/bin/sh\nexec "$(CC)" "$$@" -specs "$(BUILD_PATH)/musl-gcc.specs"\n' > $(BUILD_PATH)/musl-gcc
+ chmod +x $(BUILD_PATH)/musl-gcc
+
+$(IPERF_PATH): $(IPERF_TAR)
+ tar -C $(BUILD_PATH) -xf $<
+ sed -i '1s/^/#include <stdint.h>/' $(IPERF_PATH)/src/cjson.h $(IPERF_PATH)/src/timer.h
+ sed -i -r 's/-p?g//g' $(IPERF_PATH)/src/Makefile*
+
+$(IPERF_PATH)/src/iperf3: $(IPERF_PATH) $(MUSL_CC)
+ cd $(IPERF_PATH) && CC="$(MUSL_CC)" CFLAGS="$(CFLAGS) -D_GNU_SOURCE" ./configure --prefix=/ --host=$(CHOST) --enable-static --disable-shared
+ $(MAKE) -C $(IPERF_PATH)
+ strip -s $@
+
+$(LIBMNL_PATH): $(LIBMNL_TAR)
+ tar -C $(BUILD_PATH) -xf $<
+
+$(LIBMNL_PATH)/src/.libs/libmnl.a: $(LIBMNL_PATH) $(MUSL_CC)
+ cd $(LIBMNL_PATH) && CC="$(MUSL_CC)" CFLAGS="$(CFLAGS)" ./configure --prefix=/ --host=$(CHOST) --enable-static --disable-shared
+ $(MAKE) -C $(LIBMNL_PATH)
+
+$(BUILD_PATH)/tools/wg: $(MUSL_CC) $(TOOLS_SOURCES) $(LIBMNL_PATH)/src/.libs/libmnl.a | $(BUILD_PATH)/include/linux
+ cp -pr ../../uapi.h ../../tools $(BUILD_PATH)/
+ $(MAKE) -C $(BUILD_PATH)/tools clean
+ CC="$(MUSL_CC)" CFLAGS="$(CFLAGS)" LDFLAGS="$(LDFLAGS) -L$(LIBMNL_PATH)/src/.libs" $(MAKE) -C $(BUILD_PATH)/tools LIBMNL_CFLAGS="-I$(LIBMNL_PATH)/include" LIBMNL_LDLIBS="-lmnl" wg
+ strip -s $@
+
+$(BUILD_PATH)/init: init.c $(MUSL_CC)
+ $(MUSL_CC) -o $@ $<
+ strip -s $@
+
+$(IPUTILS_PATH): $(IPUTILS_TAR)
+ tar -C $(BUILD_PATH) -xf $<
+
+$(IPUTILS_PATH)/ping: $(IPUTILS_PATH) $(MUSL_CC) | $(BUILD_PATH)/include/linux
+ $(MAKE) -C $(IPUTILS_PATH) CC="$(MUSL_CC)" USE_CAP=no USE_IDN=no USE_NETTLE=no USE_CRYPTO=no ping
+ strip -s $@
+
+$(BASH_PATH): $(BASH_TAR)
+ tar -C $(BUILD_PATH) -xf $<
+
+$(BASH_PATH)/bash: $(BASH_PATH) $(MUSL_CC) | $(BUILD_PATH)/include/linux
+ cd $(BASH_PATH) && CC="$(MUSL_CC)" CFLAGS="$(CFLAGS)" ./configure --prefix=/ --host=$(CHOST) --without-bash-malloc --disable-debugger --disable-help-builtin --disable-history --disable-multibyte --disable-progcomp --disable-readline --disable-mem-scramble
+ $(MAKE) -C $(BASH_PATH)
+ strip -s $@
+
+$(IPROUTE2_PATH): $(IPROUTE2_TAR)
+ tar -C $(BUILD_PATH) -xf $<
+ sed -i '/ARPD/d' $(IPROUTE2_PATH)/Makefile
+ sed -i 's/arpd.8//' $(IPROUTE2_PATH)/man/man8/Makefile
+ sed -i 's/m_ipt.o//;s/[^ ]*_bpf.o//' $(IPROUTE2_PATH)/tc/Makefile
+ sed -i '/#include <linux\/in\.h>/d;/#include <linux\/in6\.h>/d' $(IPROUTE2_PATH)/include/libiptc/ipt_kernel_headers.h $(IPROUTE2_PATH)/include/linux/if_bridge.h $(IPROUTE2_PATH)/include/linux/netfilter.h $(IPROUTE2_PATH)/include/linux/xfrm.h
+ printf 'TC_CONFIG_XT=n\nTC_CONFIG_ATM=n\nTC_CONFIG_IPSET=n\nIP_CONFIG_SETNS=y\n' > $(IPROUTE2_PATH)/Config
+
+$(IPROUTE2_PATH)/ip/ip: $(IPROUTE2_PATH) $(MUSL_CC) | $(BUILD_PATH)/include/linux
+ CFLAGS="$(CFLAGS)" $(MAKE) -C $(IPROUTE2_PATH) PREFIX=/ CC="$(MUSL_CC)"
+ strip -s $(IPROUTE2_PATH)/ip/ip $(IPROUTE2_PATH)/misc/ss
+
+$(IPTABLES_PATH): $(IPTABLES_TAR)
+ tar -C $(BUILD_PATH) -xf $<
+ rm -f $(IPTABLES_PATH)/include/linux/{kernel,types}.h
+ sed -i -e "/nfnetlink=[01]/s:=[01]:=0:" -e "/nfconntrack=[01]/s:=[01]:=0:" $(IPTABLES_PATH)/configure
+
+$(IPTABLES_PATH)/iptables/xtables-multi: $(IPTABLES_PATH) $(MUSL_CC) $(LIBMNL_PATH)/src/.libs/libmnl.a | $(KERNEL_PATH)
+ cd $(IPTABLES_PATH) && PKG_CONFIG_LIBDIR="$(LIBMNL_PATH)" CC="$(MUSL_CC)" CFLAGS="$(CFLAGS)" ./configure --prefix=/ --host=$(CHOST) --enable-static --disable-shared --disable-nftables --disable-bpf-compiler --disable-nfsynproxy --disable-libipq --with-kernel=$(KERNEL_PATH)
+ $(MAKE) -C $(IPTABLES_PATH)
+
+clean:
+ rm -rf $(BUILD_PATH)
+
+distclean: clean
+ rm -rf $(DISTFILES_PATH)
diff --git a/src/tests/qemu/debug.config b/src/tests/qemu/debug.config
new file mode 100644
index 0000000..2298959
--- /dev/null
+++ b/src/tests/qemu/debug.config
@@ -0,0 +1,64 @@
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_POINTER=y
+CONFIG_STACK_VALIDATION=y
+CONFIG_DEBUG_KERNEL=y
+CONFIG_PAGE_EXTENSION=y
+CONFIG_PAGE_POISONING=y
+CONFIG_DEBUG_OBJECTS=y
+CONFIG_DEBUG_OBJECTS_FREE=y
+CONFIG_DEBUG_OBJECTS_TIMERS=y
+CONFIG_DEBUG_OBJECTS_WORK=y
+CONFIG_DEBUG_OBJECTS_RCU_HEAD=y
+CONFIG_DEBUG_OBJECTS_PERCPU_COUNTER=y
+CONFIG_DEBUG_OBJECTS_ENABLE_DEFAULT=1
+CONFIG_SLUB_DEBUG_ON=y
+CONFIG_DEBUG_VM=y
+CONFIG_DEBUG_MEMORY_INIT=y
+CONFIG_HAVE_DEBUG_STACKOVERFLOW=y
+CONFIG_DEBUG_STACKOVERFLOW=y
+CONFIG_HAVE_ARCH_KMEMCHECK=y
+CONFIG_HAVE_ARCH_KASAN=y
+CONFIG_KASAN=y
+CONFIG_KASAN_INLINE=y
+CONFIG_ARCH_HAS_KCOV=y
+CONFIG_KCOV=y
+CONFIG_DEBUG_SHIRQ=y
+CONFIG_LOCKUP_DETECTOR=y
+CONFIG_HARDLOCKUP_DETECTOR=y
+CONFIG_BOOTPARAM_HARDLOCKUP_PANIC_VALUE=0
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_DETECT_HUNG_TASK=y
+CONFIG_DEFAULT_HUNG_TASK_TIMEOUT=120
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
+CONFIG_WQ_WATCHDOG=y
+CONFIG_PANIC_ON_OOPS_VALUE=0
+CONFIG_PANIC_TIMEOUT=0
+CONFIG_SCHED_DEBUG=y
+CONFIG_SCHED_INFO=y
+CONFIG_SCHEDSTATS=y
+CONFIG_SCHED_STACK_END_CHECK=y
+CONFIG_DEBUG_TIMEKEEPING=y
+CONFIG_TIMER_STATS=y
+CONFIG_DEBUG_PREEMPT=y
+CONFIG_DEBUG_RT_MUTEXES=y
+CONFIG_DEBUG_SPINLOCK=y
+CONFIG_DEBUG_MUTEXES=y
+CONFIG_DEBUG_LOCK_ALLOC=y
+CONFIG_PROVE_LOCKING=y
+CONFIG_LOCKDEP=y
+CONFIG_DEBUG_ATOMIC_SLEEP=y
+CONFIG_TRACE_IRQFLAGS=y
+CONFIG_STACKTRACE=y
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_LIST=y
+CONFIG_DEBUG_PI_LIST=y
+CONFIG_PROVE_RCU=y
+CONFIG_SPARSE_RCU_POINTER=y
+CONFIG_RCU_CPU_STALL_TIMEOUT=21
+CONFIG_RCU_TRACE=y
+CONFIG_RCU_EQS_DEBUG=y
+CONFIG_ARCH_HAS_DEBUG_STRICT_USER_COPY_CHECKS=y
+CONFIG_USER_STACKTRACE_SUPPORT=y
+CONFIG_X86_VERBOSE_BOOTUP=y
+CONFIG_EARLY_PRINTK=y
diff --git a/src/tests/qemu/init.c b/src/tests/qemu/init.c
new file mode 100644
index 0000000..310f34b
--- /dev/null
+++ b/src/tests/qemu/init.c
@@ -0,0 +1,110 @@
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <sys/wait.h>
+#include <sys/mount.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/io.h>
+#include <sys/ioctl.h>
+#include <linux/random.h>
+
+ __attribute__((noreturn)) static void poweroff(void)
+{
+ ioperm(0x604, 2, 1);
+ outw(1 << 13, 0x604);
+ sleep(30);
+ fprintf(stderr, "\x1b[37m\x1b[41m\x1b[1mFailed to power off!!!\x1b[0m\n");
+ exit(1);
+}
+
+static void panic(const char *what)
+{
+ fprintf(stderr, "\n\n\x1b[37m\x1b[41m\x1b[1mSOMETHING WENT HORRIBLY WRONG\x1b[0m\n\n \x1b[31m\x1b[1m%s: %s\x1b[0m\n\n\x1b[37m\x1b[44m\x1b[1mPower off...\x1b[0m\n\n", what, strerror(errno));
+ poweroff();
+}
+
+#define pretty_message(msg) puts("\x1b[32m\x1b[1m" msg "\x1b[0m")
+
+int main(int argc, char *argv[])
+{
+ int status, fd1, fd2, i;
+ struct {
+ int entropy_count;
+ int buffer_size;
+ unsigned char buffer[128];
+ } entropy = {
+ .entropy_count = 128,
+ .buffer_size = 128
+ };
+ pretty_message("[+] Mounting filesystems...");
+ mkdir("/dev", 0755);
+ mkdir("/proc", 0755);
+ mkdir("/sys", 0755);
+ mkdir("/tmp", 0755);
+ mkdir("/run", 0755);
+ mkdir("/var", 0755);
+ if (mount("none", "/dev", "devtmpfs", 0, NULL))
+ panic("devtmpfs mount");
+ if (mount("none", "/proc", "proc", 0, NULL))
+ panic("procfs mount");
+ if (mount("none", "/sys", "sysfs", 0, NULL))
+ panic("sysfs mount");
+ if (mount("none", "/tmp", "tmpfs", 0, NULL))
+ panic("tmpfs mount");
+ if (mount("none", "/run", "tmpfs", 0, NULL))
+ panic("tmpfs mount");
+ if (symlink("/run", "/var/run"))
+ panic("run symlink");
+ if (symlink("/proc/self/fd", "/dev/fd"))
+ panic("fd symlink");
+ pretty_message("[+] Enabling logging...");
+ fd1 = open("/proc/sys/kernel/printk", O_WRONLY);
+ if (fd1 < 0)
+ panic("open(printk)");
+ if (write(fd1, "9\n", 2) != 2)
+ panic("write(printk)");
+ close(fd1);
+ pretty_message("[+] Ensuring RNG entropy...");
+ fd1 = open("/dev/hwrng", O_RDONLY);
+ fd2 = open("/dev/urandom", O_WRONLY);
+ if (fd1 < 0 || fd2 < 0)
+ panic("open(hwrng,urandom)");
+ for (i = 0; i < 4096; ++i) {
+ if (read(fd1, entropy.buffer, 128) != 128)
+ panic("read(hwrng)");
+ if (ioctl(fd2, RNDADDENTROPY, &entropy) < 0)
+ panic("ioctl(urandom)");
+ }
+ close(fd1);
+ close(fd2);
+
+ pretty_message("[+] Launching tests...");
+ switch (fork()) {
+ case -1:
+ panic("fork");
+ break;
+ case 0:
+ execl("/init.sh", "init", NULL);
+ panic("exec");
+ break;
+ }
+ if (wait(&status) < 0)
+ panic("wait");
+ if (WIFEXITED(status) && WEXITSTATUS(status) == 0) {
+ pretty_message("[+] Tests successful! :-)");
+ fd1 = open("/dev/vport1p1", O_WRONLY);
+ if (fd1 < 0)
+ panic("open(vport1p1)");
+ if (write(fd1, "success\n", 8) != 8)
+ panic("write(success)");
+ close(fd1);
+ } else
+ puts("\x1b[31m\x1b[1m[-] Tests failed! :-(\x1b[0m");
+ poweroff();
+ return 1;
+}
diff --git a/src/tests/qemu/kernel.config b/src/tests/qemu/kernel.config
new file mode 100644
index 0000000..e1bf4d6
--- /dev/null
+++ b/src/tests/qemu/kernel.config
@@ -0,0 +1,68 @@
+CONFIG_NET=y
+CONFIG_NETDEVICES=y
+CONFIG_NET_CORE=y
+CONFIG_VETH=y
+CONFIG_MULTIUSER=y
+CONFIG_NAMESPACES=y
+CONFIG_NET_NS=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IPV6=y
+CONFIG_NF_CONNTRACK=y
+CONFIG_NF_NAT=y
+CONFIG_NETFILTER_XTABLES=y
+CONFIG_NETFILTER_XT_NAT=y
+CONFIG_NF_CONNTRACK_IPV4=y
+CONFIG_NF_NAT_IPV4=y
+CONFIG_IP_NF_IPTABLES=y
+CONFIG_IP_NF_NAT=y
+CONFIG_TTY=y
+CONFIG_BINFMT_ELF=y
+CONFIG_BINFMT_SCRIPT=y
+CONFIG_PCI=y
+CONFIG_PCI_MSI=y
+CONFIG_VIRTUALIZATION=y
+CONFIG_HYPERVISOR_GUEST=y
+CONFIG_PARAVIRT=y
+CONFIG_KVM_GUEST=y
+CONFIG_PARAVIRT_SPINLOCKS=y
+CONFIG_VIRTIO=y
+CONFIG_VIRTIO_PCI=y
+CONFIG_VIRTIO_CONSOLE=y
+CONFIG_VIRTIO_PCI_LEGACY=y
+CONFIG_HW_RANDOM=y
+CONFIG_HW_RANDOM_VIRTIO=y
+CONFIG_PRINTK=y
+CONFIG_KALLSYMS=y
+CONFIG_BUG=y
+CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE=y
+CONFIG_EMBEDDED=n
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_SHMEM=y
+CONFIG_SLUB=y
+CONFIG_SMP=y
+CONFIG_SCHED_SMT=y
+CONFIG_SCHED_MC=y
+CONFIG_NUMA=y
+CONFIG_PREEMPT=y
+CONFIG_NO_HZ=y
+CONFIG_NO_HZ_IDLE=y
+CONFIG_NO_HZ_FULL=n
+CONFIG_HZ_PERIODIC=n
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_ARCH_RANDOM=y
+CONFIG_FILE_LOCKING=y
+CONFIG_DEVTMPFS=y
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+CONFIG_MESSAGE_LOGLEVEL_DEFAULT=7
+CONFIG_PRINTK_TIME=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_LEGACY_VSYSCALL_NONE=y
+CONFIG_KERNEL_GZIP=y
+CONFIG_WIREGUARD=y
+CONFIG_WIREGUARD_PARALLEL=y
+CONFIG_WIREGUARD_DEBUG=y