summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorFelipe Sateler <fsateler@debian.org>2019-02-20 21:24:33 -0300
committerFelipe Sateler <fsateler@debian.org>2019-02-20 21:24:33 -0300
commit7c20daf69c4411979b7f8902f3601d1cdc56cc07 (patch)
treed59b9989ce55ed23693e80974d94c856f1c2c8b1 /test
parent6e866b331d7cd4a5e0759dd160dea6edabd3678e (diff)
downloadsystemd-7c20daf69c4411979b7f8902f3601d1cdc56cc07.tar.gz
New upstream version 241upstream/241
Diffstat (limited to 'test')
-rwxr-xr-xtest/TEST-01-BASIC/test.sh11
-rwxr-xr-xtest/TEST-10-ISSUE-2467/test.sh6
-rwxr-xr-xtest/TEST-19-DELEGATE/testsuite.sh2
-rwxr-xr-xtest/TEST-22-TMPFILES/test-02.sh31
-rw-r--r--test/TEST-28-PERCENTJ-WANTEDBY/Makefile9
-rwxr-xr-xtest/TEST-28-PERCENTJ-WANTEDBY/test.sh68
-rw-r--r--test/fuzz/fuzz-udev-rules/oss-fuzz-129801
-rw-r--r--test/meson.build3
-rwxr-xr-xtest/rule-syntax-check.py5
-rw-r--r--test/test-execute/exec-privatenetwork-yes.service2
-rw-r--r--test/test-functions82
-rw-r--r--test/test-network/conf/24-search-domain.network2
-rw-r--r--test/test-network/conf/25-address-section.network7
-rw-r--r--test/test-network/conf/25-link-local-addressing-no.network5
-rw-r--r--test/test-network/conf/25-link-local-addressing-yes.network5
-rw-r--r--test/test-network/conf/25-route-ipv6-src.network16
-rw-r--r--test/test-network/conf/25-wireguard-23-peers.netdev148
-rw-r--r--test/test-network/conf/25-wireguard-23-peers.network97
-rw-r--r--test/test-network/conf/25-wireguard.netdev3
-rw-r--r--test/test-network/conf/dhcp-server-veth-peer.network2
-rw-r--r--test/test-network/conf/dhcp-v4-server-veth-peer.network4
-rwxr-xr-xtest/test-network/systemd-networkd-tests.py251
22 files changed, 682 insertions, 78 deletions
diff --git a/test/TEST-01-BASIC/test.sh b/test/TEST-01-BASIC/test.sh
index 1d2f833478..1c64017aaa 100755
--- a/test/TEST-01-BASIC/test.sh
+++ b/test/TEST-01-BASIC/test.sh
@@ -3,7 +3,7 @@
# ex: ts=8 sw=4 sts=4 et filetype=sh
set -e
TEST_DESCRIPTION="Basic systemd setup"
-RUN_IN_UNPRIVILEGED_CONTAINER=yes
+RUN_IN_UNPRIVILEGED_CONTAINER=${RUN_IN_UNPRIVILEGED_CONTAINER:-yes}
. $TEST_BASE_DIR/test-functions
@@ -26,7 +26,7 @@ Description=Testsuite service
After=multi-user.target
[Service]
-ExecStart=/bin/sh -x -c 'systemctl --state=failed --no-legend --no-pager > /failed ; echo OK > /testok'
+ExecStart=/bin/sh -x -c 'systemctl --state=failed --no-legend --no-pager > /failed ; systemctl daemon-reload ; echo OK > /testok'
Type=oneshot
EOF
@@ -34,13 +34,6 @@ EOF
) || return 1
setup_nspawn_root
- # mask some services that we do not want to run in these tests
- ln -s /dev/null $initdir/etc/systemd/system/systemd-hwdb-update.service
- ln -s /dev/null $initdir/etc/systemd/system/systemd-journal-catalog-update.service
- ln -s /dev/null $initdir/etc/systemd/system/systemd-networkd.service
- ln -s /dev/null $initdir/etc/systemd/system/systemd-networkd.socket
- ln -s /dev/null $initdir/etc/systemd/system/systemd-resolved.service
-
ddebug "umount $TESTDIR/root"
umount $TESTDIR/root
}
diff --git a/test/TEST-10-ISSUE-2467/test.sh b/test/TEST-10-ISSUE-2467/test.sh
index d8959187a1..c85433d7d3 100755
--- a/test/TEST-10-ISSUE-2467/test.sh
+++ b/test/TEST-10-ISSUE-2467/test.sh
@@ -17,7 +17,7 @@ test_setup() {
eval $(udevadm info --export --query=env --name=${LOOPDEV}p2)
setup_basic_environment
- dracut_install true rm
+ dracut_install true rm socat
# setup the testsuite service
cat >$initdir/etc/systemd/system/testsuite.service <<'EOF'
@@ -28,13 +28,13 @@ Description=Testsuite service
Type=oneshot
StandardOutput=tty
StandardError=tty
-ExecStart=/bin/sh -e -x -c 'rm -f /tmp/nonexistent; systemctl start test.socket; echo > /run/test.ctl; >/testok'
+ExecStart=/bin/sh -e -x -c 'rm -f /tmp/nonexistent; systemctl start test.socket; printf x > test.file; socat -t20 OPEN:test.file UNIX-CONNECT:/run/test.ctl; >/testok'
TimeoutStartSec=10s
EOF
cat >$initdir/etc/systemd/system/test.socket <<'EOF'
[Socket]
-ListenFIFO=/run/test.ctl
+ListenStream=/run/test.ctl
EOF
cat > $initdir/etc/systemd/system/test.service <<'EOF'
diff --git a/test/TEST-19-DELEGATE/testsuite.sh b/test/TEST-19-DELEGATE/testsuite.sh
index abfcee3cd2..fdfab950b1 100755
--- a/test/TEST-19-DELEGATE/testsuite.sh
+++ b/test/TEST-19-DELEGATE/testsuite.sh
@@ -33,7 +33,7 @@ if grep -q cgroup2 /proc/filesystems ; then
# And now check again, "io" should have vanished
grep -qv io /sys/fs/cgroup/system.slice/cgroup.controllers
else
- echo "Skipping TEST-19-DELEGATE, as the kernel doesn't actually support cgroupsv2" >&2
+ echo "Skipping TEST-19-DELEGATE, as the kernel doesn't actually support cgroup v2" >&2
fi
echo OK > /testok
diff --git a/test/TEST-22-TMPFILES/test-02.sh b/test/TEST-22-TMPFILES/test-02.sh
index fe8b903298..d1bf1ea04b 100755
--- a/test/TEST-22-TMPFILES/test-02.sh
+++ b/test/TEST-22-TMPFILES/test-02.sh
@@ -6,8 +6,8 @@
set -e
set -x
-rm -fr /tmp/{d,D,e}
-mkdir /tmp/{d,D,e}
+rm -fr /tmp/{C,d,D,e}
+mkdir /tmp/{C,d,D,e}
#
# 'd'
@@ -93,3 +93,30 @@ test $(stat -c %U:%G:%a /tmp/e/3/d2) = "daemon:daemon:755"
test -f /tmp/e/3/f1
test $(stat -c %U:%G:%a /tmp/e/3/f1) = "root:root:644"
+
+#
+# 'C'
+#
+
+mkdir /tmp/C/{1,2,3}-origin
+touch /tmp/C/{1,2,3}-origin/f1
+chmod 755 /tmp/C/{1,2,3}-origin/f1
+
+mkdir /tmp/C/{2,3}
+touch /tmp/C/3/f1
+
+systemd-tmpfiles --create - <<EOF
+C /tmp/C/1 0755 daemon daemon - /tmp/C/1-origin
+C /tmp/C/2 0755 daemon daemon - /tmp/C/2-origin
+EOF
+
+test -d /tmp/C/1
+test $(stat -c %U:%G:%a /tmp/C/1/f1) = "daemon:daemon:755"
+test -d /tmp/C/2
+test $(stat -c %U:%G:%a /tmp/C/2/f1) = "daemon:daemon:755"
+
+! systemd-tmpfiles --create - <<EOF
+C /tmp/C/3 0755 daemon daemon - /tmp/C/3-origin
+EOF
+
+test $(stat -c %U:%G:%a /tmp/C/3/f1) = "root:root:644"
diff --git a/test/TEST-28-PERCENTJ-WANTEDBY/Makefile b/test/TEST-28-PERCENTJ-WANTEDBY/Makefile
new file mode 100644
index 0000000000..45e9bfc67c
--- /dev/null
+++ b/test/TEST-28-PERCENTJ-WANTEDBY/Makefile
@@ -0,0 +1,9 @@
+BUILD_DIR=$(shell ../../tools/find-build-dir.sh)
+
+all setup run:
+ @basedir=../.. TEST_BASE_DIR=../ BUILD_DIR=$(BUILD_DIR) ./test.sh --$@
+
+clean clean-again:
+ @basedir=../.. TEST_BASE_DIR=../ BUILD_DIR=$(BUILD_DIR) ./test.sh --clean
+
+.PHONY: all setup run clean clean-again
diff --git a/test/TEST-28-PERCENTJ-WANTEDBY/test.sh b/test/TEST-28-PERCENTJ-WANTEDBY/test.sh
new file mode 100755
index 0000000000..68935d0da0
--- /dev/null
+++ b/test/TEST-28-PERCENTJ-WANTEDBY/test.sh
@@ -0,0 +1,68 @@
+#!/bin/bash
+# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
+# ex: ts=8 sw=4 sts=4 et filetype=sh
+set -e
+TEST_DESCRIPTION="Ensure %j Wants directives work"
+RUN_IN_UNPRIVILEGED_CONTAINER=yes
+
+. $TEST_BASE_DIR/test-functions
+
+test_setup() {
+ create_empty_image
+ mkdir -p $TESTDIR/root
+ mount ${LOOPDEV}p1 $TESTDIR/root
+
+ # Create what will eventually be our root filesystem onto an overlay
+ (
+ LOG_LEVEL=5
+ eval $(udevadm info --export --query=env --name=${LOOPDEV}p2)
+
+ setup_basic_environment
+
+ # Set up the services.
+ cat >$initdir/etc/systemd/system/specifier-j-wants.service << EOF
+[Unit]
+Description=Wants with percent-j specifier
+Wants=specifier-j-depends-%j.service
+After=specifier-j-depends-%j.service
+
+[Service]
+Type=oneshot
+ExecStart=test -f /tmp/test-specifier-j-%j
+ExecStart=/bin/sh -c 'echo OK > /testok'
+EOF
+ cat >$initdir/etc/systemd/system/specifier-j-depends-wants.service << EOF
+[Unit]
+Description=Dependent service for percent-j specifier
+
+[Service]
+Type=oneshot
+ExecStart=touch /tmp/test-specifier-j-wants
+EOF
+ cat >$initdir/etc/systemd/system/testsuite.service << EOF
+[Unit]
+Description=Testsuite: Ensure %j Wants directives work
+Wants=specifier-j-wants.service
+After=specifier-j-wants.service
+
+[Service]
+Type=oneshot
+ExecStart=/bin/true
+EOF
+
+ setup_testsuite
+ ) || return 1
+ setup_nspawn_root
+
+ # mask some services that we do not want to run in these tests
+ ln -s /dev/null $initdir/etc/systemd/system/systemd-hwdb-update.service
+ ln -s /dev/null $initdir/etc/systemd/system/systemd-journal-catalog-update.service
+ ln -s /dev/null $initdir/etc/systemd/system/systemd-networkd.service
+ ln -s /dev/null $initdir/etc/systemd/system/systemd-networkd.socket
+ ln -s /dev/null $initdir/etc/systemd/system/systemd-resolved.service
+
+ ddebug "umount $TESTDIR/root"
+ umount $TESTDIR/root
+}
+
+do_test "$@"
diff --git a/test/fuzz/fuzz-udev-rules/oss-fuzz-12980 b/test/fuzz/fuzz-udev-rules/oss-fuzz-12980
new file mode 100644
index 0000000000..37846f42fa
--- /dev/null
+++ b/test/fuzz/fuzz-udev-rules/oss-fuzz-12980
@@ -0,0 +1 @@
+ SUBSYSTEM==" " KERNEL==" " GROUP=" " KERNEL==" " GROUP=" " MODE =" " KERNEL==" " GROUP=" " KERNEL==" " GROUP=" " MODE =" " KERNEL==" " GROUP=" " MODE=" " GROUP=" " KERNEL==" " GROUP=" " KERNEL==" "GROUP=" " KERNEL==" " GROUP=" " MODE =" "KERNEL==" " GROUP=" " KERNEL==" " GROUP=" "MODE =" " KERNEL==" " KERNEL==" " GROUP=" " MODE =" " KERNEL==" " GROUP=" " KERNEL==" " GROUP=" " MODE =" " KERNEL==" " GROUP=" " MODE=" " GROUP=" " KERNEL==" " GROUP=" " KERNEL==" " GROUP=" " KERNEL==" " GROUP=" " MODE =" " KERNEL==" " GROUP=" " MODE="" MODE =" " KERNEL==" " GROUP=" " KERNEL==" " GROUP=" " MODE =" " KERNEL=="" GROUP=" " KERNEL==" " GROUP=" " MODE =" " KERNEL==" " KERNEL==" " OPTIONS =" string_escape=replace watch " \ No newline at end of file
diff --git a/test/meson.build b/test/meson.build
index d98bfb80d2..94903934a5 100644
--- a/test/meson.build
+++ b/test/meson.build
@@ -252,7 +252,8 @@ if perl.found()
udev_test_pl = find_program('udev-test.pl')
if want_tests != 'false'
test('udev-test',
- udev_test_pl)
+ udev_test_pl,
+ timeout : 180)
endif
else
message('Skipping udev-test because perl is not available')
diff --git a/test/rule-syntax-check.py b/test/rule-syntax-check.py
index dfb06d9ed9..8b26c988ab 100755
--- a/test/rule-syntax-check.py
+++ b/test/rule-syntax-check.py
@@ -17,6 +17,8 @@ if not rules_files:
quoted_string_re = r'"(?:[^\\"]|\\.)*"'
no_args_tests = re.compile(r'(ACTION|DEVPATH|KERNELS?|NAME|SYMLINK|SUBSYSTEMS?|DRIVERS?|TAG|PROGRAM|RESULT|TEST)\s*(?:=|!)=\s*' + quoted_string_re + '$')
+# PROGRAM can also be specified as an assignment.
+program_assign = re.compile(r'PROGRAM\s*=\s*' + quoted_string_re + '$')
args_tests = re.compile(r'(ATTRS?|ENV|TEST){([a-zA-Z0-9/_.*%-]+)}\s*(?:=|!)=\s*' + quoted_string_re + '$')
no_args_assign = re.compile(r'(NAME|SYMLINK|OWNER|GROUP|MODE|TAG|RUN|LABEL|GOTO|OPTIONS|IMPORT)\s*(?:\+=|:=|=)\s*' + quoted_string_re + '$')
args_assign = re.compile(r'(ATTR|ENV|IMPORT|RUN){([a-zA-Z0-9/_.*%-]+)}\s*(=|\+=)\s*' + quoted_string_re + '$')
@@ -51,7 +53,8 @@ for path in rules_files:
for clause_match in comma_separated_group_re.finditer(line):
clause = clause_match.group().strip()
if not (no_args_tests.match(clause) or args_tests.match(clause) or
- no_args_assign.match(clause) or args_assign.match(clause)):
+ no_args_assign.match(clause) or args_assign.match(clause) or
+ program_assign.match(clause)):
print('Invalid line {}:{}: {}'.format(path, lineno, line))
print(' clause:', clause)
diff --git a/test/test-execute/exec-privatenetwork-yes.service b/test/test-execute/exec-privatenetwork-yes.service
index ded8d55126..8f5cbadf04 100644
--- a/test/test-execute/exec-privatenetwork-yes.service
+++ b/test/test-execute/exec-privatenetwork-yes.service
@@ -2,6 +2,6 @@
Description=Test for PrivateNetwork
[Service]
-ExecStart=/bin/sh -x -c '! ip link | grep ": " | grep -Ev ": (lo|(sit0|ip6tnl0|ip6gre0)@.*):"'
+ExecStart=/bin/sh -x -c '! ip link | grep -E "^[0-9]+: " | grep -Ev ": (lo|(erspan|gre|gretap|ip_vti|ip6_vti|ip6gre|ip6tnl|sit|tunl)0@.*):"'
Type=oneshot
PrivateNetwork=yes
diff --git a/test/test-functions b/test/test-functions
index 37069396b7..a936202e4a 100644
--- a/test/test-functions
+++ b/test/test-functions
@@ -15,6 +15,7 @@ TIMED_OUT= # will be 1 after run_* if *_TIMEOUT is set and test timed out
[[ "$LOOKS_LIKE_SUSE" ]] && FSTYPE="${FSTYPE:-btrfs}" || FSTYPE="${FSTYPE:-ext4}"
UNIFIED_CGROUP_HIERARCHY="${UNIFIED_CGROUP_HIERARCHY:-default}"
EFI_MOUNT="$(bootctl -p 2>/dev/null || echo /boot)"
+QEMU_MEM="${QEMU_MEM:-512M}"
if ! ROOTLIBDIR=$(pkg-config --variable=systemdutildir systemd); then
echo "WARNING! Cannot determine rootlibdir from pkg-config, assuming /usr/lib/systemd" >&2
@@ -37,7 +38,7 @@ is_built_with_asan() {
fi
# Borrowed from https://github.com/google/oss-fuzz/blob/cd9acd02f9d3f6e80011cc1e9549be526ce5f270/infra/base-images/base-runner/bad_build_check#L182
- local _asan_calls=$(objdump -dC $BUILD_DIR/systemd | egrep "callq\s+[0-9a-f]+\s+<__asan" -c)
+ local _asan_calls=$(objdump -dC $BUILD_DIR/systemd-journald | egrep "callq\s+[0-9a-f]+\s+<__asan" -c)
if (( $_asan_calls < 1000 )); then
return 1
else
@@ -51,6 +52,8 @@ if [[ "$IS_BUILT_WITH_ASAN" = "yes" ]]; then
STRIP_BINARIES=no
SKIP_INITRD=yes
PATH_TO_INIT=$ROOTLIBDIR/systemd-under-asan
+ QEMU_MEM="1536M"
+ QEMU_SMP=4
fi
function find_qemu_bin() {
@@ -96,17 +99,28 @@ run_qemu() {
&& KERNEL_BIN="$EFI_MOUNT/$MACHINE_ID/$KERNEL_VER/linux"
fi
+ CONSOLE=ttyS0
+
if [[ ! "$KERNEL_BIN" ]]; then
if [[ "$LOOKS_LIKE_ARCH" ]]; then
KERNEL_BIN=/boot/vmlinuz-linux
else
- KERNEL_BIN=/boot/vmlinuz-$KERNEL_VER
+ [ "$ARCH" ] || ARCH=$(uname -m)
+ case $ARCH in
+ ppc64*)
+ KERNEL_BIN=/boot/vmlinux-$KERNEL_VER
+ CONSOLE=hvc0
+ ;;
+ *)
+ KERNEL_BIN=/boot/vmlinuz-$KERNEL_VER
+ ;;
+ esac
fi
fi
default_fedora_initrd=/boot/initramfs-${KERNEL_VER}.img
default_debian_initrd=/boot/initrd.img-${KERNEL_VER}
- default_arch_initrd=/boot/initramfs-linux.img
+ default_arch_initrd=/boot/initramfs-linux-fallback.img
default_suse_initrd=/boot/initrd-${KERNEL_VER}
if [[ ! "$INITRD" ]]; then
if [[ -e "$default_fedora_initrd" ]]; then
@@ -147,7 +161,7 @@ root=/dev/sda1 \
raid=noautodetect \
loglevel=2 \
init=$PATH_TO_INIT \
-console=ttyS0 \
+console=$CONSOLE \
selinux=0 \
printk.devkmsg=on \
$_cgroup_args \
@@ -156,7 +170,7 @@ $KERNEL_APPEND \
QEMU_OPTIONS="-smp $QEMU_SMP \
-net none \
--m 512M \
+-m $QEMU_MEM \
-nographic \
-kernel $KERNEL_BIN \
-drive format=raw,cache=unsafe,file=${TESTDIR}/rootdisk.img \
@@ -330,8 +344,8 @@ create_asan_wrapper() {
set -x
DEFAULT_ASAN_OPTIONS=strict_string_checks=1:detect_stack_use_after_return=1:check_initialization_order=1:strict_init_order=1
-DEFAULT_UBSAN_OPTIONS=print_stacktrace=1:print_summary=1
-DEFAULT_ENVIRONMENT="ASAN_OPTIONS=\$DEFAULT_ASAN_OPTIONS UBSAN_OPTIONS=\$DEFAULT_UBSAN_OPTIONS:halt_on_error=1"
+DEFAULT_UBSAN_OPTIONS=print_stacktrace=1:print_summary=1:halt_on_error=1
+DEFAULT_ENVIRONMENT="ASAN_OPTIONS=\$DEFAULT_ASAN_OPTIONS UBSAN_OPTIONS=\$DEFAULT_UBSAN_OPTIONS"
mount -t proc proc /proc
mount -t sysfs sysfs /sys
@@ -344,6 +358,7 @@ if [[ "\$PATH_TO_ASAN" ]]; then
DEFAULT_ENVIRONMENT="\$DEFAULT_ENVIRONMENT LD_PRELOAD=\$PATH_TO_ASAN"
fi
echo DefaultEnvironment=\$DEFAULT_ENVIRONMENT >>/etc/systemd/system.conf
+echo DefaultTimeoutStartSec=180s >>/etc/systemd/system.conf
# ASAN and syscall filters aren't compatible with each other.
find / -name '*.service' -type f | xargs sed -i 's/^\\(MemoryDeny\\|SystemCall\\)/#\\1/'
@@ -354,6 +369,12 @@ JOURNALD_CONF_DIR=/etc/systemd/system/systemd-journald.service.d
mkdir -p "\$JOURNALD_CONF_DIR"
printf "[Service]\nEnvironment=ASAN_OPTIONS=\$DEFAULT_ASAN_OPTIONS:log_path=/systemd-journald.asan.log\n" >"\$JOURNALD_CONF_DIR/env.conf"
+# 90s isn't enough for some services to finish when literally everything is run
+# under ASan+UBSan in containers, which, in turn, are run in VMs.
+# Let's limit which environments such services should be executed in.
+mkdir -p /etc/systemd/system/systemd-hwdb-update.service.d
+printf "[Unit]\nConditionVirtualization=container\n\n[Service]\nTimeoutSec=180s\n" >/etc/systemd/system/systemd-hwdb-update.service.d/env-override.conf
+
export ASAN_OPTIONS=\$DEFAULT_ASAN_OPTIONS:log_path=/systemd.asan.log UBSAN_OPTIONS=\$DEFAULT_UBSAN_OPTIONS
exec $ROOTLIBDIR/systemd "\$@"
EOF
@@ -453,8 +474,47 @@ EOF
fi
}
+check_asan_reports() {
+ local ret=0
+ local root="$1"
+
+ if [[ "$IS_BUILT_WITH_ASAN" = "yes" ]]; then
+ ls -l "$root"
+ if [[ -e "$root/systemd.asan.log.1" ]]; then
+ cat "$root/systemd.asan.log.1"
+ ret=$(($ret+1))
+ fi
+
+ journald_report=$(find "$root" -name "systemd-journald.asan.log*" -exec cat {} \;)
+ if [[ ! -z "$journald_report" ]]; then
+ printf "%s" "$journald_report"
+ ret=$(($ret+1))
+ fi
+
+ pids=$(
+ "$BUILD_DIR/journalctl" -D "$root/var/log/journal" | perl -alne '
+ BEGIN {
+ %services_to_ignore = (
+ "dbus-daemon" => undef,
+ );
+ }
+ print $2 if /\s(\S*)\[(\d+)\]:\s*SUMMARY:\s+\w+Sanitizer/ && !exists $services_to_ignore{$1}'
+ )
+ if [[ ! -z "$pids" ]]; then
+ ret=$(($ret+1))
+ for pid in $pids; do
+ "$BUILD_DIR/journalctl" -D "$root/var/log/journal" _PID=$pid --no-pager
+ done
+ fi
+ fi
+
+ return $ret
+}
+
check_result_nspawn() {
local ret=1
+ local journald_report=""
+ local pids=""
[[ -e $TESTDIR/$1/testok ]] && ret=0
[[ -f $TESTDIR/$1/failed ]] && cp -a $TESTDIR/$1/failed $TESTDIR
cp -a $TESTDIR/$1/var/log/journal $TESTDIR
@@ -462,6 +522,7 @@ check_result_nspawn() {
ls -l $TESTDIR/journal/*/*.journal
test -s $TESTDIR/failed && ret=$(($ret+1))
[ -n "$TIMED_OUT" ] && ret=$(($ret+1))
+ check_asan_reports "$TESTDIR/$1" || ret=$(($ret+1))
return $ret
}
@@ -473,6 +534,7 @@ check_result_qemu() {
[[ -e $TESTDIR/root/testok ]] && ret=0
[[ -f $TESTDIR/root/failed ]] && cp -a $TESTDIR/root/failed $TESTDIR
cp -a $TESTDIR/root/var/log/journal $TESTDIR
+ check_asan_reports "$TESTDIR/root" || ret=$(($ret+1))
umount $TESTDIR/root
[[ -f $TESTDIR/failed ]] && cat $TESTDIR/failed
ls -l $TESTDIR/journal/*/*.journal
@@ -508,7 +570,9 @@ install_execs() {
sed -r -n 's|^Exec[a-zA-Z]*=[@+!-]*([^ ]+).*|\1|gp' $initdir/{$systemdsystemunitdir,$systemduserunitdir}/*.service \
| sort -u | while read i; do
# some {rc,halt}.local scripts and programs are okay to not exist, the rest should
- inst $i || [ "${i%.local}" != "$i" ] || [ "${i%systemd-update-done}" != "$i" ]
+ # also, plymouth is pulled in by rescue.service, but even there the exit code
+ # is ignored; as it's not present on some distros, don't fail if it doesn't exist
+ inst $i || [ "${i%.local}" != "$i" ] || [ "${i%systemd-update-done}" != "$i" ] || [ "/bin/plymouth" == "$i" ]
done
)
}
@@ -1526,7 +1590,7 @@ test_run() {
else
dwarn "can't run systemd-nspawn, skipping"
fi
- fi
+ fi
fi
return 0
}
diff --git a/test/test-network/conf/24-search-domain.network b/test/test-network/conf/24-search-domain.network
index 970b130ab0..124af438a3 100644
--- a/test/test-network/conf/24-search-domain.network
+++ b/test/test-network/conf/24-search-domain.network
@@ -2,6 +2,6 @@
Name=dummy98
[Network]
-Address=192.168.42.100
+Address=192.168.42.100/24
DNS=192.168.42.1
Domains= one two three four five six seven eight nine ten
diff --git a/test/test-network/conf/25-address-section.network b/test/test-network/conf/25-address-section.network
index d0fae69361..3904953443 100644
--- a/test/test-network/conf/25-address-section.network
+++ b/test/test-network/conf/25-address-section.network
@@ -1,6 +1,9 @@
[Match]
Name=dummy98
+[Network]
+IPv6AcceptRA=no
+
[Address]
Address=10.2.3.4/16
Peer=10.2.3.5/16
@@ -9,3 +12,7 @@ Label=32
[Address]
Address=10.6.7.8/16
Label=33
+
+[Address]
+Address=2001:db8::20
+Peer=2001:db8::10/128
diff --git a/test/test-network/conf/25-link-local-addressing-no.network b/test/test-network/conf/25-link-local-addressing-no.network
new file mode 100644
index 0000000000..8320414d9e
--- /dev/null
+++ b/test/test-network/conf/25-link-local-addressing-no.network
@@ -0,0 +1,5 @@
+[Match]
+Name=dummy98
+
+[Network]
+LinkLocalAddressing=no
diff --git a/test/test-network/conf/25-link-local-addressing-yes.network b/test/test-network/conf/25-link-local-addressing-yes.network
new file mode 100644
index 0000000000..dcf2f2f7b1
--- /dev/null
+++ b/test/test-network/conf/25-link-local-addressing-yes.network
@@ -0,0 +1,5 @@
+[Match]
+Name=test1
+
+[Network]
+LinkLocalAddressing=yes
diff --git a/test/test-network/conf/25-route-ipv6-src.network b/test/test-network/conf/25-route-ipv6-src.network
new file mode 100644
index 0000000000..4e551c024a
--- /dev/null
+++ b/test/test-network/conf/25-route-ipv6-src.network
@@ -0,0 +1,16 @@
+# This test cannot use a dummy interface: IPv6 addresses
+# are added without having to go through tentative state
+
+[Match]
+Name=bond199
+
+[Network]
+LinkLocalAddressing=ipv6
+Address=2001:1234:56:8f63::1/64
+Address=2001:1234:56:8f63::2/64
+IPv6AcceptRA=no
+
+[Route]
+Destination=abcd::/16
+Gateway=2001:1234:56:8f63::1:1
+PreferredSource=2001:1234:56:8f63::2
diff --git a/test/test-network/conf/25-wireguard-23-peers.netdev b/test/test-network/conf/25-wireguard-23-peers.netdev
new file mode 100644
index 0000000000..7f77dc1743
--- /dev/null
+++ b/test/test-network/conf/25-wireguard-23-peers.netdev
@@ -0,0 +1,148 @@
+[NetDev]
+Name=wg98
+Kind=wireguard
+Description=For issue #11404
+# Generated by the script https://launchpadlibrarian.net/405947185/systemd-wg
+
+[WireGuard]
+# 51820 is common port for Wireguard, 4500 is IPSec/UDP
+ListenPort=4500
+PrivateKey=CJQUtcS9emY2fLYqDlpSZiE/QJyHkPWr+WHtZLZ90FU=
+
+# peer 1
+[WireGuardPeer]
+PublicKey=TxVmU/YJ2R3G3cbGKUiIx02y6CgcKlElVGAkzrwJuXg=
+AllowedIPs=fd8d:4d6d:3ccb:0500:0c79:2339:edce:ece1/128
+AllowedIPs=fd8d:4d6d:3ccb:0c79:2339:edce::/96
+
+# peer 2
+[WireGuardPeer]
+PublicKey=coGr5lLn1RsCeh1RWBXn1GvcDqKSQ82HSeN0GrUugHg=
+AllowedIPs=fd8d:4d6d:3ccb:0500:a072:80da:de4f:add1/128
+AllowedIPs=fd8d:4d6d:3ccb:a072:80da:de4f::/96
+
+# peer 3
+[WireGuardPeer]
+PublicKey=PeiULTZjyfjqg/OOqnzKtLSWnrU+ipinqMsMw0hY+1w=
+AllowedIPs=fd8d:4d6d:3ccb:0500:f349:c4f0:10c1:06b4/128
+AllowedIPs=fd8d:4d6d:3ccb:f349:c4f0:10c1::/96
+
+# peer 4
+[WireGuardPeer]
+PublicKey=PjdC8+BmQPdgheY7gle9s3gvM7r07L6A+gMBe5bOZXk=
+AllowedIPs=fd8d:4d6d:3ccb:0500:b684:4f81:2e3e:132e/128
+AllowedIPs=fd8d:4d6d:3ccb:b684:4f81:2e3e::/96
+
+# peer 5
+[WireGuardPeer]
+PublicKey=1MGQurlRaQIAgdH/sd0qDNamDKAepMy/+pzZUx9oEDI=
+AllowedIPs=fd8d:4d6d:3ccb:0500:c624:6bf7:4c09:3b59/128
+AllowedIPs=fd8d:4d6d:3ccb:c624:6bf7:4c09::/96
+
+# peer 6
+[WireGuardPeer]
+PublicKey=+FgzhoGfPIzNBvtIZfBwNtWls2FSGt/6Kve3M9Z1ZlE=
+AllowedIPs=fd8d:4d6d:3ccb:0500:9c11:d820:2e96:9be0/128
+AllowedIPs=fd8d:4d6d:3ccb:9c11:d820:2e96::/96
+
+# peer 7
+[WireGuardPeer]
+PublicKey=Kb2ozFhzg9huKmV4miLlWgh05ToP+xVqd2N0e7Ebmyc=
+AllowedIPs=fd8d:4d6d:3ccb:0500:bad5:495d:8e9c:3427/128
+AllowedIPs=fd8d:4d6d:3ccb:bad5:495d:8e9c::/96
+
+# peer 8
+[WireGuardPeer]
+PublicKey=p2kY786d4vFO/PpstaQrn7UPuakoHRABUHmcDKzXVi4=
+AllowedIPs=fd8d:4d6d:3ccb:0500:1e54:1415:35d0:a47c/128
+AllowedIPs=fd8d:4d6d:3ccb:1e54:1415:35d0::/96
+
+# peer 9
+[WireGuardPeer]
+PublicKey=FNiQqmeizNXTmd9jEU/gvNkuEs1MoWovNp8IpPkoqz4=
+AllowedIPs=fd8d:4d6d:3ccb:0500:1dbf:ca8a:32d3:dd81/128
+AllowedIPs=fd8d:4d6d:3ccb:1dbf:ca8a:32d3::/96
+
+# peer 10
+[WireGuardPeer]
+PublicKey=wAwyAuLSQTO7lwQnUQHTumrMgkwigIExGR26AthWTU8=
+AllowedIPs=fd8d:4d6d:3ccb:0500:dcdd:d33b:90c9:6088/128
+AllowedIPs=fd8d:4d6d:3ccb:dcdd:d33b:90c9::/96
+
+# peer 11
+[WireGuardPeer]
+PublicKey=8gRYdXRyhgjiMSbqk3sj5kzXGsQqkZ4defvK2ONqHA0=
+AllowedIPs=fd8d:4d6d:3ccb:0500:6f2e:6888:c6fd:dfb9/128
+AllowedIPs=fd8d:4d6d:3ccb:6f2e:6888:c6fd::/96
+
+# peer 12
+[WireGuardPeer]
+PublicKey=4Bj9Dalwnq2Trf5Bl7iJCpSOaxC83YEbxgrgBl0ljQk=
+AllowedIPs=fd8d:4d6d:3ccb:0500:d4f9:05dc:9296:0a1a/128
+AllowedIPs=fd8d:4d6d:3ccb:d4f9:05dc:9296::/96
+
+# peer 13
+[WireGuardPeer]
+PublicKey=BOTxUDlPSIzYucVmML4IYcTIaX0TiqC7DOnfLUI7RRg=
+AllowedIPs=fd8d:4d6d:3ccb:0500:b39c:9cdc:755a:ead3/128
+AllowedIPs=fd8d:4d6d:3ccb:b39c:9cdc:755a::/96
+
+# peer 14
+[WireGuardPeer]
+PublicKey=PiqEvBzow5vElGD2uOtRtZG6G60tM82kmjbyJP02mFQ=
+AllowedIPs=fd8d:4d6d:3ccb:0500:bfe5:c3c3:5d77:0fcb/128
+AllowedIPs=fd8d:4d6d:3ccb:bfe5:c3c3:5d77::/96
+
+# peer 15
+[WireGuardPeer]
+PublicKey=Eor9QBsIoUG6C3ZKsKdqm4Vkt0n2N7qpSh2LzphQeho=
+AllowedIPs=fd8d:4d6d:3ccb:0500:900c:d437:ec27:8822/128
+AllowedIPs=fd8d:4d6d:3ccb:900c:d437:ec27::/96
+
+# peer 16
+[WireGuardPeer]
+PublicKey=acXPW0Ar+TiTOqKuUDpop9AVLuPNdzqf0l+V8k5t7CM=
+AllowedIPs=fd8d:4d6d:3ccb:0500:270d:b5dd:4a3f:8909/128
+AllowedIPs=fd8d:4d6d:3ccb:270d:b5dd:4a3f::/96
+
+# peer 17
+[WireGuardPeer]
+PublicKey=+0g/5jzbitHyfhB4gbJnWrhSMsSjCcOE2rftWTDEW3E=
+AllowedIPs=fd8d:4d6d:3ccb:0500:e2e1:ae15:103f:f376/128
+AllowedIPs=fd8d:4d6d:3ccb:e2e1:ae15:103f::/96
+
+# peer 18
+[WireGuardPeer]
+PublicKey=FC7mjuWpkM8bjM3vaLPbba2HwHGbTSDK9QsLEZvUZ2I=
+AllowedIPs=fd8d:4d6d:3ccb:0500:5660:679d:3532:94d8/128
+AllowedIPs=fd8d:4d6d:3ccb:5660:679d:3532::/96
+
+# peer 19
+[WireGuardPeer]
+PublicKey=fRdm/tbE2jGuLd6zMxSQYMP6pPfMmXYW84TUPJCPjHM=
+AllowedIPs=fd8d:4d6d:3ccb:0500:6825:573f:30f3:9472/128
+AllowedIPs=fd8d:4d6d:3ccb:6825:573f:30f3::/96
+
+# peer 20
+[WireGuardPeer]
+PublicKey=xm540z0UwfTF5f0YwfjmCX0eGdHY8bOb/4ovVA2SgCI=
+AllowedIPs=fd8d:4d6d:3ccb:0500:a94b:cd6a:a32d:90e6/128
+AllowedIPs=fd8d:4d6d:3ccb:a94b:cd6a:a32d::/96
+
+# peer 21
+[WireGuardPeer]
+PublicKey=5X5+9IiRBjaadazEKNO+CozpomiKPMIBQT7uJ4SnbVs=
+AllowedIPs=fd8d:4d6d:3ccb:0500:8d4d:0bab:7280:a09a/128
+AllowedIPs=fd8d:4d6d:3ccb:8d4d:0bab:7280::/96
+
+# peer 22
+[WireGuardPeer]
+PublicKey=d61T4K0wmS4Z3lK9M8/Z48IXzldLCOCm7a6Mx1r/A3I=
+AllowedIPs=fd8d:4d6d:3ccb:0500:a3f3:df38:19b0:0721/128
+AllowedIPs=fd8d:4d6d:3ccb:a3f3:df38:19b0::/96
+
+# peer 23
+[WireGuardPeer]
+PublicKey=Nt7N3hXfpMWsIsx9me4ID77okka+0Oe5eqnFDp00IFI=
+AllowedIPs=fd8d:4d6d:3ccb:0500:9742:9931:5217:18d5/128
+AllowedIPs=fd8d:4d6d:3ccb:9742:9931:5217::/96
diff --git a/test/test-network/conf/25-wireguard-23-peers.network b/test/test-network/conf/25-wireguard-23-peers.network
new file mode 100644
index 0000000000..4dc87f8d4c
--- /dev/null
+++ b/test/test-network/conf/25-wireguard-23-peers.network
@@ -0,0 +1,97 @@
+[Match]
+Name=wg98
+
+[Network]
+Address=fd8d:4d6d:3ccb:0500::1/64
+
+# nat64 via 1
+[Route]
+Destination = fd8d:4d6d:3ccb:0c79:2339:edce::/96
+
+# nat64 via 2
+[Route]
+Destination = fd8d:4d6d:3ccb:a072:80da:de4f::/96
+
+# nat64 via 3
+[Route]
+Destination = fd8d:4d6d:3ccb:f349:c4f0:10c1::/96
+
+# nat64 via 4
+[Route]
+Destination = fd8d:4d6d:3ccb:b684:4f81:2e3e::/96
+
+# nat64 via 5
+[Route]
+Destination = fd8d:4d6d:3ccb:c624:6bf7:4c09::/96
+
+# nat64 via 6
+[Route]
+Destination = fd8d:4d6d:3ccb:9c11:d820:2e96::/96
+
+# nat64 via 7
+[Route]
+Destination = fd8d:4d6d:3ccb:bad5:495d:8e9c::/96
+
+# nat64 via 8
+[Route]
+Destination = fd8d:4d6d:3ccb:1e54:1415:35d0::/96
+
+# nat64 via 9
+[Route]
+Destination = fd8d:4d6d:3ccb:1dbf:ca8a:32d3::/96
+
+# nat64 via 10
+[Route]
+Destination = fd8d:4d6d:3ccb:dcdd:d33b:90c9::/96
+
+# nat64 via 11
+[Route]
+Destination = fd8d:4d6d:3ccb:6f2e:6888:c6fd::/96
+
+# nat64 via 12
+[Route]
+Destination = fd8d:4d6d:3ccb:d4f9:05dc:9296::/96
+
+# nat64 via 13
+[Route]
+Destination = fd8d:4d6d:3ccb:b39c:9cdc:755a::/96
+
+# nat64 via 14
+[Route]
+Destination = fd8d:4d6d:3ccb:bfe5:c3c3:5d77::/96
+
+# nat64 via 15
+[Route]
+Destination = fd8d:4d6d:3ccb:900c:d437:ec27::/96
+
+# nat64 via 16
+[Route]
+Destination = fd8d:4d6d:3ccb:270d:b5dd:4a3f::/96
+
+# nat64 via 17
+[Route]
+Destination = fd8d:4d6d:3ccb:e2e1:ae15:103f::/96
+
+# nat64 via 18
+[Route]
+Destination = fd8d:4d6d:3ccb:5660:679d:3532::/96
+
+# nat64 via 19
+[Route]
+Destination = fd8d:4d6d:3ccb:6825:573f:30f3::/96
+
+# nat64 via 20
+[Route]
+Destination = fd8d:4d6d:3ccb:a94b:cd6a:a32d::/96
+
+# nat64 via 21
+[Route]
+Destination = fd8d:4d6d:3ccb:8d4d:0bab:7280::/96
+
+# nat64 via 22
+[Route]
+Destination = fd8d:4d6d:3ccb:a3f3:df38:19b0::/96
+
+# nat64 via 23
+[Route]
+Destination = fd8d:4d6d:3ccb:9742:9931:5217::/96
diff --git a/test/test-network/conf/25-wireguard.netdev b/test/test-network/conf/25-wireguard.netdev
index 01c5f2a28d..4866c31cca 100644
--- a/test/test-network/conf/25-wireguard.netdev
+++ b/test/test-network/conf/25-wireguard.netdev
@@ -10,6 +10,7 @@ FwMark=1234
[WireGuardPeer]
PublicKey=RDf+LSpeEre7YEIKaxg+wbpsNV7du+ktR99uBEtIiCA=
AllowedIPs=fd31:bf08:57cb::/48,192.168.26.0/24
-Endpoint=wireguard.example.com:51820
+#Endpoint=wireguard.example.com:51820
+Endpoint=192.168.27.3:51820
PresharedKey=IIWIV17wutHv7t4cR6pOT91z6NSz/T8Arh0yaywhw3M=
PersistentKeepalive=20
diff --git a/test/test-network/conf/dhcp-server-veth-peer.network b/test/test-network/conf/dhcp-server-veth-peer.network
index 7b38e72b7e..33d8be3964 100644
--- a/test/test-network/conf/dhcp-server-veth-peer.network
+++ b/test/test-network/conf/dhcp-server-veth-peer.network
@@ -2,5 +2,5 @@
Name=veth-peer
[Network]
-Address=2600::1
+Address=2600::1/0
Address=192.168.5.1/24
diff --git a/test/test-network/conf/dhcp-v4-server-veth-peer.network b/test/test-network/conf/dhcp-v4-server-veth-peer.network
index 5c91d65432..3dfc5290ad 100644
--- a/test/test-network/conf/dhcp-v4-server-veth-peer.network
+++ b/test/test-network/conf/dhcp-v4-server-veth-peer.network
@@ -2,5 +2,5 @@
Name=veth-peer
[Network]
-Address=192.168.0.1
-Address=192.168.5.1
+Address=192.168.0.1/24
+Address=192.168.5.1/24
diff --git a/test/test-network/systemd-networkd-tests.py b/test/test-network/systemd-networkd-tests.py
index 19572be151..1fc7094d28 100755
--- a/test/test-network/systemd-networkd-tests.py
+++ b/test/test-network/systemd-networkd-tests.py
@@ -9,7 +9,6 @@ import signal
import socket
import subprocess
import sys
-import threading
import time
import unittest
from shutil import copytree
@@ -20,7 +19,6 @@ networkd_ci_path='/run/networkd-ci'
network_sysctl_ipv6_path='/proc/sys/net/ipv6/conf'
network_sysctl_ipv4_path='/proc/sys/net/ipv4/conf'
-dnsmasq_config_file='/run/networkd-ci/test-dnsmasq.conf'
dnsmasq_pid_file='/run/networkd-ci/test-test-dnsmasq.pid'
dnsmasq_log_file='/run/networkd-ci/test-dnsmasq-log-file'
@@ -37,6 +35,39 @@ def expectedFailureIfModuleIsNotAvailable(module_name):
return f
+def expectedFailureIfERSPANModuleIsNotAvailable():
+ def f(func):
+ rc = subprocess.call(['ip', 'link', 'add', 'dev', 'erspan99', 'type', 'erspan', 'seq', 'key', '30', 'local', '192.168.1.4', 'remote', '192.168.1.1', 'erspan_ver', '1', 'erspan', '123'])
+ if rc == 0:
+ subprocess.call(['ip', 'link', 'del', 'erspan99'])
+ return func
+ else:
+ return unittest.expectedFailure(func)
+
+ return f
+
+def expectedFailureIfRoutingPolicyPortRangeIsNotAvailable():
+ def f(func):
+ rc = subprocess.call(['ip', 'rule', 'add', 'from', '192.168.100.19', 'sport', '1123-1150', 'dport', '3224-3290', 'table', '7'])
+ if rc == 0:
+ subprocess.call(['ip', 'rule', 'del', 'from', '192.168.100.19', 'sport', '1123-1150', 'dport', '3224-3290', 'table', '7'])
+ return func
+ else:
+ return unittest.expectedFailure(func)
+
+ return f
+
+def expectedFailureIfRoutingPolicyIPProtoIsNotAvailable():
+ def f(func):
+ rc = subprocess.call(['ip', 'rule', 'add', 'not', 'from', '192.168.100.19', 'ipproto', 'tcp', 'table', '7'])
+ if rc == 0:
+ subprocess.call(['ip', 'rule', 'del', 'not', 'from', '192.168.100.19', 'ipproto', 'tcp', 'table', '7'])
+ return func
+ else:
+ return unittest.expectedFailure(func)
+
+ return f
+
def setUpModule():
os.makedirs(network_unit_file_path, exist_ok=True)
@@ -100,8 +131,9 @@ class Utilities():
if (os.path.exists(os.path.join(network_unit_file_path, unit + '.d'))):
shutil.rmtree(os.path.join(network_unit_file_path, unit + '.d'))
- def start_dnsmasq(self):
- subprocess.check_call('dnsmasq -8 /var/run/networkd-ci/test-dnsmasq-log-file --log-queries=extra --log-dhcp --pid-file=/var/run/networkd-ci/test-test-dnsmasq.pid --conf-file=/dev/null --interface=veth-peer --enable-ra --dhcp-range=2600::10,2600::20 --dhcp-range=192.168.5.10,192.168.5.200 -R --dhcp-leasefile=/var/run/networkd-ci/lease --dhcp-option=26,1492 --dhcp-option=option:router,192.168.5.1 --dhcp-option=33,192.168.5.4,192.168.5.5', shell=True)
+ def start_dnsmasq(self, additional_options=''):
+ dnsmasq_command = 'dnsmasq -8 /var/run/networkd-ci/test-dnsmasq-log-file --log-queries=extra --log-dhcp --pid-file=/var/run/networkd-ci/test-test-dnsmasq.pid --conf-file=/dev/null --interface=veth-peer --enable-ra --dhcp-range=2600::10,2600::20 --dhcp-range=192.168.5.10,192.168.5.200 -R --dhcp-leasefile=/var/run/networkd-ci/lease --dhcp-option=26,1492 --dhcp-option=option:router,192.168.5.1 --dhcp-option=33,192.168.5.4,192.168.5.5 --port=0 ' + additional_options
+ subprocess.check_call(dnsmasq_command, shell=True)
time.sleep(10)
@@ -144,33 +176,6 @@ class Utilities():
time.sleep(5)
print()
-global ip
-global port
-
-class DHCPServer(threading.Thread):
- def __init__(self, name):
- threading.Thread.__init__(self)
- self.name = name
-
- def run(self):
- self.start_dhcp_server()
-
- def start_dhcp_server(self):
- sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
-
- server_address = ('0.0.0.0', 67)
- sock.bind(server_address)
-
- print('Starting DHCP Server ...\n')
- data, addr = sock.recvfrom(1024) # buffer size is 1024 bytes
-
- global ip
- ip = addr[0]
-
- global port
- port = addr[1]
- sock.close()
-
class NetworkdNetDevTests(unittest.TestCase, Utilities):
links =[
@@ -201,6 +206,7 @@ class NetworkdNetDevTests(unittest.TestCase, Utilities):
'vti6tun99',
'vtitun99',
'vxlan99',
+ 'wg98',
'wg99']
units = [
@@ -234,6 +240,8 @@ class NetworkdNetDevTests(unittest.TestCase, Utilities):
'25-vti6-tunnel.netdev',
'25-vti-tunnel.netdev',
'25-vxlan.netdev',
+ '25-wireguard-23-peers.netdev',
+ '25-wireguard-23-peers.network',
'25-wireguard.netdev',
'6rd.network',
'gre.network',
@@ -388,9 +396,29 @@ class NetworkdNetDevTests(unittest.TestCase, Utilities):
if shutil.which('wg'):
subprocess.call('wg')
+ output = subprocess.check_output(['wg', 'show', 'wg99', 'listen-port']).rstrip().decode('utf-8')
+ self.assertTrue(output, '51820')
+ output = subprocess.check_output(['wg', 'show', 'wg99', 'fwmark']).rstrip().decode('utf-8')
+ self.assertTrue(output, '0x4d2')
+ output = subprocess.check_output(['wg', 'show', 'wg99', 'allowed-ips']).rstrip().decode('utf-8')
+ self.assertTrue(output, 'RDf+LSpeEre7YEIKaxg+wbpsNV7du+ktR99uBEtIiCA=\t192.168.26.0/24 fd31:bf08:57cb::/48')
+ output = subprocess.check_output(['wg', 'show', 'wg99', 'persistent-keepalive']).rstrip().decode('utf-8')
+ self.assertTrue(output, 'RDf+LSpeEre7YEIKaxg+wbpsNV7du+ktR99uBEtIiCA=\t20')
+ output = subprocess.check_output(['wg', 'show', 'wg99', 'endpoints']).rstrip().decode('utf-8')
+ self.assertTrue(output, 'RDf+LSpeEre7YEIKaxg+wbpsNV7du+ktR99uBEtIiCA=\t192.168.27.3:51820')
self.assertTrue(self.link_exits('wg99'))
+ @expectedFailureIfModuleIsNotAvailable('wireguard')
+ def test_wireguard_23_peers(self):
+ self.copy_unit_to_networkd_unit_path('25-wireguard-23-peers.netdev', '25-wireguard-23-peers.network')
+ self.start_networkd()
+
+ if shutil.which('wg'):
+ subprocess.call('wg')
+
+ self.assertTrue(self.link_exits('wg98'))
+
def test_geneve(self):
self.copy_unit_to_networkd_unit_path('25-geneve.netdev')
self.start_networkd()
@@ -478,6 +506,7 @@ class NetworkdNetDevTests(unittest.TestCase, Utilities):
self.assertTrue(self.link_exits('dummy98'))
self.assertTrue(self.link_exits('sittun99'))
+ @expectedFailureIfERSPANModuleIsNotAvailable()
def test_erspan_tunnel(self):
self.copy_unit_to_networkd_unit_path('25-erspan-tunnel.netdev')
self.start_networkd()
@@ -536,9 +565,12 @@ class NetworkdNetWorkTests(unittest.TestCase, Utilities):
'25-fibrule-port-range.network',
'25-ipv6-address-label-section.network',
'25-neighbor-section.network',
+ '25-link-local-addressing-no.network',
+ '25-link-local-addressing-yes.network',
'25-link-section-unmanaged.network',
'25-route-gateway.network',
'25-route-gateway-on-link.network',
+ '25-route-ipv6-src.network',
'25-route-reverse-order.network',
'25-route-section.network',
'25-route-tcp-window-settings.network',
@@ -618,6 +650,7 @@ class NetworkdNetWorkTests(unittest.TestCase, Utilities):
subprocess.call(['ip', 'rule', 'del', 'table', '7'])
+ @expectedFailureIfRoutingPolicyPortRangeIsNotAvailable()
def test_routing_policy_rule_port_range(self):
self.copy_unit_to_networkd_unit_path('25-fibrule-port-range.network', '11-dummy.netdev')
self.start_networkd()
@@ -635,6 +668,7 @@ class NetworkdNetWorkTests(unittest.TestCase, Utilities):
subprocess.call(['ip', 'rule', 'del', 'table', '7'])
+ @expectedFailureIfRoutingPolicyIPProtoIsNotAvailable()
def test_routing_policy_rule_invert(self):
self.copy_unit_to_networkd_unit_path('25-fibrule-invert.network', '11-dummy.netdev')
self.start_networkd()
@@ -650,6 +684,22 @@ class NetworkdNetWorkTests(unittest.TestCase, Utilities):
subprocess.call(['ip', 'rule', 'del', 'table', '7'])
+ def test_address_peer(self):
+ self.copy_unit_to_networkd_unit_path('25-address-section.network', '12-dummy.netdev')
+ self.start_networkd()
+
+ self.assertTrue(self.link_exits('dummy98'))
+
+ output = subprocess.check_output(['ip', 'address', 'show', 'dummy98']).rstrip().decode('utf-8')
+ print(output)
+ self.assertRegex(output, 'inet 10.2.3.4 peer 10.2.3.5/16 scope global 32')
+ self.assertRegex(output, 'inet 10.6.7.8/16 brd 10.6.255.255 scope global 33')
+ self.assertRegex(output, 'inet6 2001:db8::20 peer 2001:db8::10/128 scope global')
+
+ output = subprocess.check_output(['networkctl', 'status', 'dummy98']).rstrip().decode('utf-8')
+ print(output)
+ self.assertRegex(output, 'State: routable \(configured\)')
+
def test_address_preferred_lifetime_zero_ipv6(self):
self.copy_unit_to_networkd_unit_path('25-address-section-miscellaneous.network', '12-dummy.netdev')
self.start_networkd()
@@ -756,6 +806,22 @@ class NetworkdNetWorkTests(unittest.TestCase, Utilities):
self.assertRegex(output, 'scope')
self.assertRegex(output, 'link')
+ def test_ip_route_ipv6_src_route(self):
+ # a dummy device does not make the addresses go through tentative state, so we
+ # reuse a bond from an earlier test, which does make the addresses go through
+ # tentative state, and do our test on that
+ self.copy_unit_to_networkd_unit_path('23-active-slave.network', '25-route-ipv6-src.network', '25-bond-active-backup-slave.netdev', '12-dummy.netdev')
+ self.start_networkd()
+
+ self.assertTrue(self.link_exits('dummy98'))
+ self.assertTrue(self.link_exits('bond199'))
+
+ output = subprocess.check_output(['ip', '-6', 'route', 'list', 'dev', 'bond199']).rstrip().decode('utf-8')
+ print(output)
+ self.assertRegex(output, 'abcd::/16')
+ self.assertRegex(output, 'src')
+ self.assertRegex(output, '2001:1234:56:8f63::2')
+
def test_ip_link_mac_address(self):
self.copy_unit_to_networkd_unit_path('25-address-link-section.network', '12-dummy.netdev')
self.start_networkd()
@@ -795,7 +861,67 @@ class NetworkdNetWorkTests(unittest.TestCase, Utilities):
output = subprocess.check_output(['ip', 'neigh', 'list']).rstrip().decode('utf-8')
print(output)
self.assertRegex(output, '192.168.10.1.*00:00:5e:00:02:65.*PERMANENT')
- self.assertRegex(output, '2004:da8:1:0::1.*00:00:5e:00:02:66.*PERMANENT')
+ self.assertRegex(output, '2004:da8:1::1.*00:00:5e:00:02:66.*PERMANENT')
+
+ def test_link_local_addressing(self):
+ self.copy_unit_to_networkd_unit_path('25-link-local-addressing-yes.network', '11-dummy.netdev',
+ '25-link-local-addressing-no.network', '12-dummy.netdev')
+ self.start_networkd()
+
+ self.assertTrue(self.link_exits('test1'))
+ self.assertTrue(self.link_exits('dummy98'))
+
+ time.sleep(10)
+
+ output = subprocess.check_output(['ip', 'address', 'show', 'dev', 'test1']).rstrip().decode('utf-8')
+ print(output)
+ self.assertRegex(output, 'inet .* scope link')
+ self.assertRegex(output, 'inet6 .* scope link')
+
+ output = subprocess.check_output(['ip', 'address', 'show', 'dev', 'dummy98']).rstrip().decode('utf-8')
+ print(output)
+ self.assertNotRegex(output, 'inet6* .* scope link')
+
+ output = subprocess.check_output(['networkctl', 'status', 'test1']).rstrip().decode('utf-8')
+ print(output)
+ self.assertRegex(output, 'State: degraded \(configured\)')
+
+ output = subprocess.check_output(['networkctl', 'status', 'dummy98']).rstrip().decode('utf-8')
+ print(output)
+ self.assertRegex(output, 'State: carrier \(configured\)')
+
+ '''
+ Documentation/networking/ip-sysctl.txt
+
+ addr_gen_mode - INTEGER
+ Defines how link-local and autoconf addresses are generated.
+
+ 0: generate address based on EUI64 (default)
+ 1: do no generate a link-local address, use EUI64 for addresses generated
+ from autoconf
+ 2: generate stable privacy addresses, using the secret from
+ stable_secret (RFC7217)
+ 3: generate stable privacy addresses, using a random secret if unset
+ '''
+
+ test1_addr_gen_mode = ''
+ if os.path.exists(os.path.join(os.path.join(network_sysctl_ipv6_path, 'test1'), 'stable_secret')):
+ with open(os.path.join(os.path.join(network_sysctl_ipv6_path, 'test1'), 'stable_secret')) as f:
+ try:
+ f.readline()
+ except IOError:
+ # if stable_secret is unset, then EIO is returned
+ test1_addr_gen_mode = '0'
+ else:
+ test1_addr_gen_mode = '2'
+ else:
+ test1_addr_gen_mode = '0'
+
+ if os.path.exists(os.path.join(os.path.join(network_sysctl_ipv6_path, 'test1'), 'addr_gen_mode')):
+ self.assertEqual(self.read_ipv6_sysctl_attr('test1', 'addr_gen_mode'), '0')
+
+ if os.path.exists(os.path.join(os.path.join(network_sysctl_ipv6_path, 'dummy98'), 'addr_gen_mode')):
+ self.assertEqual(self.read_ipv6_sysctl_attr('dummy98', 'addr_gen_mode'), '1')
def test_sysctl(self):
self.copy_unit_to_networkd_unit_path('25-sysctl.network', '12-dummy.netdev')
@@ -954,7 +1080,7 @@ class NetworkdNetworkDHCPServerTests(unittest.TestCase, Utilities):
self.assertRegex(output, 'NTP: 192.168.5.1')
def test_domain(self):
- self.copy_unit_to_networkd_unit_path( '12-dummy.netdev', '24-search-domain.network')
+ self.copy_unit_to_networkd_unit_path('12-dummy.netdev', '24-search-domain.network')
self.start_networkd()
self.assertTrue(self.link_exits('dummy98'))
@@ -994,8 +1120,10 @@ class NetworkdNetworkDHCPClientTests(unittest.TestCase, Utilities):
'dhcp-client-listen-port.network',
'dhcp-client-route-metric.network',
'dhcp-client-route-table.network',
+ 'dhcp-client.network',
'dhcp-server-veth-peer.network',
- 'dhcp-v4-server-veth-peer.network']
+ 'dhcp-v4-server-veth-peer.network',
+ 'static.network']
def setUp(self):
self.link_remove(self.links)
@@ -1009,7 +1137,7 @@ class NetworkdNetworkDHCPClientTests(unittest.TestCase, Utilities):
self.remove_log_file()
def test_dhcp_client_ipv6_only(self):
- self.copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network','dhcp-client-ipv6-only.network')
+ self.copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network', 'dhcp-client-ipv6-only.network')
self.start_networkd()
self.assertTrue(self.link_exits('veth99'))
@@ -1022,7 +1150,7 @@ class NetworkdNetworkDHCPClientTests(unittest.TestCase, Utilities):
self.assertNotRegex(output, '192.168.5')
def test_dhcp_client_ipv4_only(self):
- self.copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network','dhcp-client-ipv4-only-ipv6-disabled.network')
+ self.copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network', 'dhcp-client-ipv4-only-ipv6-disabled.network')
self.start_networkd()
self.assertTrue(self.link_exits('veth99'))
@@ -1111,21 +1239,15 @@ class NetworkdNetworkDHCPClientTests(unittest.TestCase, Utilities):
def test_dhcp_client_listen_port(self):
self.copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network', 'dhcp-client-listen-port.network')
-
- dh_server = DHCPServer("dhcp_server")
- dh_server.start()
-
self.start_networkd()
self.assertTrue(self.link_exits('veth99'))
- global port
- global ip
-
- self.assertRegex(str(port), '5555')
- self.assertRegex(str(ip), '0.0.0.0')
+ self.start_dnsmasq('--dhcp-alternate-port=67,5555')
- dh_server.join()
+ output = subprocess.check_output(['ip', '-4', 'address', 'show', 'dev', 'veth99']).rstrip().decode('utf-8')
+ print(output)
+ self.assertRegex(output, '192.168.5.* dynamic')
def test_dhcp_route_table_id(self):
self.copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-v4-server-veth-peer.network', 'dhcp-client-route-table.network')
@@ -1174,6 +1296,43 @@ class NetworkdNetworkDHCPClientTests(unittest.TestCase, Utilities):
print(output)
self.assertRegex(output, '192.168.5.*')
+ def test_dhcp_client_reuse_address_as_static(self):
+ self.copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network', 'dhcp-client.network')
+ self.start_networkd()
+
+ self.assertTrue(self.link_exits('veth99'))
+
+ self.start_dnsmasq()
+
+ output = subprocess.check_output(['ip', 'address', 'show', 'dev', 'veth99', 'scope', 'global']).rstrip().decode('utf-8')
+ print(output)
+ self.assertRegex(output, '192.168.5')
+ self.assertRegex(output, '2600::')
+
+ ipv4_address = re.search('192\.168\.5\.[0-9]*/24', output)
+ ipv6_address = re.search('2600::[0-9a-f:]*/128', output)
+ static_network = '\n'.join(['[Match]', 'Name=veth99', '[Network]', 'IPv6AcceptRA=no', 'Address=' + ipv4_address.group(), 'Address=' + ipv6_address.group()])
+ print(static_network)
+
+ self.remove_unit_from_networkd_path(['dhcp-client.network'])
+
+ with open(os.path.join(network_unit_file_path, 'static.network'), mode='w') as f:
+ f.write(static_network)
+
+ self.start_networkd()
+
+ self.assertTrue(self.link_exits('veth99'))
+
+ output = subprocess.check_output(['ip', '-4', 'address', 'show', 'dev', 'veth99', 'scope', 'global']).rstrip().decode('utf-8')
+ print(output)
+ self.assertRegex(output, '192.168.5')
+ self.assertRegex(output, 'valid_lft forever preferred_lft forever')
+
+ output = subprocess.check_output(['ip', '-6', 'address', 'show', 'dev', 'veth99', 'scope', 'global']).rstrip().decode('utf-8')
+ print(output)
+ self.assertRegex(output, '2600::')
+ self.assertRegex(output, 'valid_lft forever preferred_lft forever')
+
if __name__ == '__main__':
unittest.main(testRunner=unittest.TextTestRunner(stream=sys.stdout,
verbosity=3))