diff options
Diffstat (limited to 'tests')
-rw-r--r-- | tests/sys/cddl/zfs/tests/zfsd/Makefile | 2 | ||||
-rw-r--r-- | tests/sys/cddl/zfs/tests/zfsd/zfsd_offline_001_neg.ksh | 64 | ||||
-rw-r--r-- | tests/sys/cddl/zfs/tests/zfsd/zfsd_offline_002_neg.ksh | 66 | ||||
-rwxr-xr-x | tests/sys/cddl/zfs/tests/zfsd/zfsd_test.sh | 60 | ||||
-rw-r--r-- | tests/sys/fs/fusefs/pre-init.cc | 72 | ||||
-rw-r--r-- | tests/sys/kern/Makefile | 2 | ||||
-rw-r--r-- | tests/sys/kern/copy_file_range.c | 231 | ||||
-rw-r--r-- | tests/sys/kern/ptrace_test.c | 2 | ||||
-rw-r--r-- | tests/sys/net/Makefile | 1 | ||||
-rwxr-xr-x | tests/sys/net/if_bridge_test.sh | 282 | ||||
-rw-r--r-- | tests/sys/net/if_gif.sh | 154 | ||||
-rw-r--r-- | tests/sys/net/if_ovpn/if_ovpn.sh | 76 | ||||
-rw-r--r-- | tests/sys/netpfil/pf/Makefile | 1 | ||||
-rw-r--r-- | tests/sys/netpfil/pf/frag4.py | 72 | ||||
-rw-r--r-- | tests/sys/netpfil/pf/nat.sh | 1 | ||||
-rw-r--r-- | tests/sys/netpfil/pf/nat64.py | 34 | ||||
-rw-r--r-- | tests/sys/netpfil/pf/nat64.sh | 182 | ||||
-rw-r--r-- | tests/sys/netpfil/pf/route_to.sh | 2 | ||||
-rw-r--r-- | tests/sys/netpfil/pf/sctp.py | 33 | ||||
-rwxr-xr-x | tests/sys/netpfil/pf/src_track.sh | 3 | ||||
-rw-r--r-- | tests/sys/netpfil/pf/table.sh | 42 |
21 files changed, 1271 insertions, 111 deletions
diff --git a/tests/sys/cddl/zfs/tests/zfsd/Makefile b/tests/sys/cddl/zfs/tests/zfsd/Makefile index e34e24b40906..588ca6e6c145 100644 --- a/tests/sys/cddl/zfs/tests/zfsd/Makefile +++ b/tests/sys/cddl/zfs/tests/zfsd/Makefile @@ -30,6 +30,8 @@ ${PACKAGE}FILES+= zfsd_hotspare_006_pos.ksh ${PACKAGE}FILES+= zfsd_hotspare_007_pos.ksh ${PACKAGE}FILES+= zfsd_hotspare_008_neg.ksh ${PACKAGE}FILES+= zfsd_import_001_pos.ksh +${PACKAGE}FILES+= zfsd_offline_001_neg.ksh +${PACKAGE}FILES+= zfsd_offline_002_neg.ksh ${PACKAGE}FILES+= zfsd_replace_001_pos.ksh ${PACKAGE}FILES+= zfsd_replace_002_pos.ksh ${PACKAGE}FILES+= zfsd_replace_003_pos.ksh diff --git a/tests/sys/cddl/zfs/tests/zfsd/zfsd_offline_001_neg.ksh b/tests/sys/cddl/zfs/tests/zfsd/zfsd_offline_001_neg.ksh new file mode 100644 index 000000000000..de7996976504 --- /dev/null +++ b/tests/sys/cddl/zfs/tests/zfsd/zfsd_offline_001_neg.ksh @@ -0,0 +1,64 @@ +#!/usr/local/bin/ksh93 -p +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# + +# +# Copyright 2025 ConnectWise. All rights reserved. +# Use is subject to license terms. + +. $STF_SUITE/tests/hotspare/hotspare.kshlib + +verify_runnable "global" + +function cleanup +{ + $ZPOOL status $TESTPOOL + if poolexists $TESTPOOL ; then + destroy_pool $TESTPOOL + fi + + partition_cleanup +} + +function verify_assertion +{ + log_must $ZPOOL offline $TESTPOOL $FAULT_DISK + + # Wait a few seconds before verifying the state + $SLEEP 10 + log_must check_state $TESTPOOL "$FAULT_DISK" "OFFLINE" +} + +log_onexit cleanup + +log_assert "ZFSD will not automatically reactivate a disk which has been administratively offlined" + +ensure_zfsd_running + +typeset FAULT_DISK=$DISK0 +typeset POOLDEVS="$DISK0 $DISK1 $DISK2" +set -A MY_KEYWORDS mirror raidz1 +for keyword in "${MY_KEYWORDS[@]}" ; do + log_must create_pool $TESTPOOL $keyword $POOLDEVS + verify_assertion + + destroy_pool "$TESTPOOL" +done diff --git a/tests/sys/cddl/zfs/tests/zfsd/zfsd_offline_002_neg.ksh b/tests/sys/cddl/zfs/tests/zfsd/zfsd_offline_002_neg.ksh new file mode 100644 index 000000000000..7d8dfc62d365 --- /dev/null +++ b/tests/sys/cddl/zfs/tests/zfsd/zfsd_offline_002_neg.ksh @@ -0,0 +1,66 @@ +#!/usr/local/bin/ksh93 -p +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# + +# +# Copyright 2025 ConnectWise. All rights reserved. +# Use is subject to license terms. + +. $STF_SUITE/tests/hotspare/hotspare.kshlib + +verify_runnable "global" + +function cleanup +{ + $ZPOOL status $TESTPOOL + if poolexists $TESTPOOL ; then + destroy_pool $TESTPOOL + fi + + partition_cleanup +} + +function verify_assertion +{ + log_must $ZPOOL offline $TESTPOOL $FAULT_DISK + + # Wait a few seconds before verifying the state + $SLEEP 10 + log_must check_state $TESTPOOL "$FAULT_DISK" "OFFLINE" + log_must check_state $TESTPOOL "$SPARE_DISK" "AVAIL" +} + +log_onexit cleanup + +log_assert "ZFSD will not automatically activate a spare when a disk has been administratively offlined" + +ensure_zfsd_running + +typeset FAULT_DISK=$DISK0 +typeset SPARE_DISK=$DISK3 +typeset POOLDEVS="$DISK0 $DISK1 $DISK2" +set -A MY_KEYWORDS mirror raidz1 +for keyword in "${MY_KEYWORDS[@]}" ; do + log_must create_pool $TESTPOOL $keyword $POOLDEVS spare $SPARE_DISK + verify_assertion + + destroy_pool "$TESTPOOL" +done diff --git a/tests/sys/cddl/zfs/tests/zfsd/zfsd_test.sh b/tests/sys/cddl/zfs/tests/zfsd/zfsd_test.sh index fe4ac4866ed3..b9924500a298 100755 --- a/tests/sys/cddl/zfs/tests/zfsd/zfsd_test.sh +++ b/tests/sys/cddl/zfs/tests/zfsd/zfsd_test.sh @@ -483,6 +483,64 @@ zfsd_autoreplace_003_pos_cleanup() ksh93 $(atf_get_srcdir)/cleanup.ksh || atf_fail "Cleanup failed" } +atf_test_case zfsd_offline_001_neg cleanup +zfsd_offline_001_neg_head() +{ + atf_set "descr" "ZFSD will not automatically reactivate a disk which has been administratively offlined" + atf_set "require.progs" "ksh93 zpool zfs" +} +zfsd_offline_001_neg_body() +{ + . $(atf_get_srcdir)/../../include/default.cfg + . $(atf_get_srcdir)/../hotspare/hotspare.cfg + . $(atf_get_srcdir)/zfsd.cfg + + verify_disk_count "$DISKS" 3 + verify_zfsd_running + ksh93 $(atf_get_srcdir)/setup.ksh || atf_fail "Setup failed" + ksh93 $(atf_get_srcdir)/zfsd_offline_001_neg.ksh + if [[ $? != 0 ]]; then + save_artifacts + atf_fail "Testcase failed" + fi +} +zfsd_offline_001_neg_cleanup() +{ + . $(atf_get_srcdir)/../../include/default.cfg + . $(atf_get_srcdir)/zfsd.cfg + + ksh93 $(atf_get_srcdir)/cleanup.ksh || atf_fail "Cleanup failed" +} + +atf_test_case zfsd_offline_002_neg cleanup +zfsd_offline_002_neg_head() +{ + atf_set "descr" "ZFSD will not automatically activate a spare when a disk has been administratively offlined" + atf_set "require.progs" "ksh93 zpool zfs" +} +zfsd_offline_002_neg_body() +{ + . $(atf_get_srcdir)/../../include/default.cfg + . $(atf_get_srcdir)/../hotspare/hotspare.cfg + . $(atf_get_srcdir)/zfsd.cfg + + verify_disk_count "$DISKS" 4 + verify_zfsd_running + ksh93 $(atf_get_srcdir)/setup.ksh || atf_fail "Setup failed" + ksh93 $(atf_get_srcdir)/zfsd_offline_002_neg.ksh + if [[ $? != 0 ]]; then + save_artifacts + atf_fail "Testcase failed" + fi +} +zfsd_offline_002_neg_cleanup() +{ + . $(atf_get_srcdir)/../../include/default.cfg + . $(atf_get_srcdir)/zfsd.cfg + + ksh93 $(atf_get_srcdir)/cleanup.ksh || atf_fail "Cleanup failed" +} + atf_test_case zfsd_replace_001_pos cleanup zfsd_replace_001_pos_head() { @@ -676,6 +734,8 @@ atf_init_test_cases() atf_add_test_case zfsd_autoreplace_001_neg atf_add_test_case zfsd_autoreplace_002_pos atf_add_test_case zfsd_autoreplace_003_pos + atf_add_test_case zfsd_offline_001_neg + atf_add_test_case zfsd_offline_002_neg atf_add_test_case zfsd_replace_001_pos atf_add_test_case zfsd_replace_002_pos atf_add_test_case zfsd_replace_003_pos diff --git a/tests/sys/fs/fusefs/pre-init.cc b/tests/sys/fs/fusefs/pre-init.cc index e990d3cafffa..2d3257500304 100644 --- a/tests/sys/fs/fusefs/pre-init.cc +++ b/tests/sys/fs/fusefs/pre-init.cc @@ -44,12 +44,26 @@ using namespace testing; /* Tests for behavior that happens before the server responds to FUSE_INIT */ class PreInit: public FuseTest { +public: void SetUp() { m_no_auto_init = true; FuseTest::SetUp(); } }; +/* + * Tests for behavior that happens before the server responds to FUSE_INIT, + * parameterized on default_permissions + */ +class PreInitP: public PreInit, + public WithParamInterface<bool> +{ +void SetUp() { + m_default_permissions = GetParam(); + PreInit::SetUp(); +} +}; + static void* unmount1(void* arg __unused) { ssize_t r; @@ -152,3 +166,61 @@ TEST_F(PreInit, signal_during_unmount_before_init) sem_post(&sem0); m_mock->join_daemon(); } + +/* + * If some process attempts VOP_GETATTR for the mountpoint before init is + * complete, fusefs should wait, just like it does for other VOPs. + * + * To verify that fuse_vnop_getattr does indeed wait for FUSE_INIT to complete, + * invoke the test like this: + * +> sudo cpuset -c -l 0 dtrace -i 'fbt:fusefs:fuse_internal_init_callback:' -i 'fbt:fusefs:fuse_vnop_getattr:' -c "./pre-init --gtest_filter=PI/PreInitP.getattr_before_init/0" +... +dtrace: pid 4224 has exited +CPU ID FUNCTION:NAME + 0 68670 fuse_vnop_getattr:entry + 0 68893 fuse_internal_init_callback:entry + 0 68894 fuse_internal_init_callback:return + 0 68671 fuse_vnop_getattr:return + * + * Note that fuse_vnop_getattr was entered first, but exitted last. + */ +TEST_P(PreInitP, getattr_before_init) +{ + struct stat sb; + nlink_t nlink = 12345; + + EXPECT_CALL(*m_mock, process( + ResultOf([=](auto in) { + return (in.header.opcode == FUSE_INIT); + }, Eq(true)), + _) + ).WillOnce(Invoke(ReturnImmediate([&](auto in, auto& out) { + SET_OUT_HEADER_LEN(out, init); + out.body.init.major = FUSE_KERNEL_VERSION; + out.body.init.minor = FUSE_KERNEL_MINOR_VERSION; + out.body.init.flags = in.body.init.flags & m_init_flags; + out.body.init.max_write = m_maxwrite; + out.body.init.max_readahead = m_maxreadahead; + out.body.init.time_gran = m_time_gran; + nap(); /* Allow stat() to run first */ + }))); + EXPECT_CALL(*m_mock, process( + ResultOf([=](auto in) { + return (in.header.opcode == FUSE_GETATTR && + in.header.nodeid == FUSE_ROOT_ID); + }, Eq(true)), + _) + ).WillOnce(Invoke(ReturnImmediate([=](auto& in, auto& out) { + SET_OUT_HEADER_LEN(out, attr); + out.body.attr.attr.ino = in.header.nodeid; + out.body.attr.attr.mode = S_IFDIR | 0644; + out.body.attr.attr.nlink = nlink; + out.body.attr.attr_valid = UINT64_MAX; + }))); + + EXPECT_EQ(0, stat("mountpoint", &sb)); + EXPECT_EQ(nlink, sb.st_nlink); +} + +INSTANTIATE_TEST_SUITE_P(PI, PreInitP, Bool()); diff --git a/tests/sys/kern/Makefile b/tests/sys/kern/Makefile index 336e73f29835..9044b1e7e4f2 100644 --- a/tests/sys/kern/Makefile +++ b/tests/sys/kern/Makefile @@ -8,6 +8,7 @@ TESTSRC= ${SRCTOP}/contrib/netbsd-tests/kernel TESTSDIR= ${TESTSBASE}/sys/kern ATF_TESTS_C+= basic_signal +ATF_TESTS_C+= copy_file_range .if ${MACHINE_ARCH} != "i386" && ${MACHINE_ARCH} != "powerpc" && \ ${MACHINE_ARCH} != "powerpcspe" # No support for atomic_load_64 on i386 or (32-bit) powerpc @@ -81,6 +82,7 @@ PROGS+= coredump_phnum_helper PROGS+= pdeathsig_helper PROGS+= sendfile_helper +LIBADD.copy_file_range+= md LIBADD.jail_lookup_root+= jail util CFLAGS.sys_getrandom+= -I${SRCTOP}/sys/contrib/zstd/lib LIBADD.sys_getrandom+= zstd diff --git a/tests/sys/kern/copy_file_range.c b/tests/sys/kern/copy_file_range.c new file mode 100644 index 000000000000..ca52eaf668e3 --- /dev/null +++ b/tests/sys/kern/copy_file_range.c @@ -0,0 +1,231 @@ +/* + * Copyright (c) 2025 Mark Johnston <markj@FreeBSD.org> + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include <sys/mman.h> +#include <sys/stat.h> + +#include <errno.h> +#include <fcntl.h> +#include <limits.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> + +#include <atf-c.h> +#include <sha256.h> + +/* + * Create a file with random data and size between 1B and 32MB. Return a file + * descriptor for the file. + */ +static int +genfile(void) +{ + char buf[256], file[NAME_MAX]; + size_t sz; + int fd; + + sz = (random() % (32 * 1024 * 1024ul)) + 1; + + snprintf(file, sizeof(file), "testfile.XXXXXX"); + fd = mkstemp(file); + ATF_REQUIRE(fd != -1); + + while (sz > 0) { + ssize_t n; + int error; + + error = getentropy(buf, sizeof(buf)); + ATF_REQUIRE(error == 0); + n = write(fd, buf, sizeof(buf) < sz ? sizeof(buf) : sz); + ATF_REQUIRE(n > 0); + + sz -= n; + } + + ATF_REQUIRE(lseek(fd, 0, SEEK_SET) == 0); + return (fd); +} + +/* + * Return true if the file data in the two file descriptors is the same, + * false otherwise. + */ +static bool +cmpfile(int fd1, int fd2) +{ + struct stat st1, st2; + void *addr1, *addr2; + size_t sz; + int res; + + ATF_REQUIRE(fstat(fd1, &st1) == 0); + ATF_REQUIRE(fstat(fd2, &st2) == 0); + if (st1.st_size != st2.st_size) + return (false); + + sz = st1.st_size; + addr1 = mmap(NULL, sz, PROT_READ, MAP_PRIVATE, fd1, 0); + ATF_REQUIRE(addr1 != MAP_FAILED); + addr2 = mmap(NULL, sz, PROT_READ, MAP_PRIVATE, fd2, 0); + ATF_REQUIRE(addr2 != MAP_FAILED); + + res = memcmp(addr1, addr2, sz); + + ATF_REQUIRE(munmap(addr1, sz) == 0); + ATF_REQUIRE(munmap(addr2, sz) == 0); + + return (res == 0); +} + +/* + * Exercise a few error paths in the copy_file_range() syscall. + */ +ATF_TC_WITHOUT_HEAD(copy_file_range_invalid); +ATF_TC_BODY(copy_file_range_invalid, tc) +{ + off_t off1, off2; + int fd1, fd2; + + fd1 = genfile(); + fd2 = genfile(); + + /* Can't copy a file to itself without explicit offsets. */ + ATF_REQUIRE_ERRNO(EINVAL, + copy_file_range(fd1, NULL, fd1, NULL, SSIZE_MAX, 0) == -1); + + /* When copying a file to itself, ranges cannot overlap. */ + off1 = off2 = 0; + ATF_REQUIRE_ERRNO(EINVAL, + copy_file_range(fd1, &off1, fd1, &off2, 1, 0) == -1); + + /* Negative offsets are not allowed. */ + off1 = -1; + off2 = 0; + ATF_REQUIRE_ERRNO(EINVAL, + copy_file_range(fd1, &off1, fd2, &off2, 42, 0) == -1); + ATF_REQUIRE_ERRNO(EINVAL, + copy_file_range(fd2, &off2, fd1, &off1, 42, 0) == -1); +} + +/* + * Make sure that copy_file_range() updates the file offsets passed to it. + */ +ATF_TC_WITHOUT_HEAD(copy_file_range_offset); +ATF_TC_BODY(copy_file_range_offset, tc) +{ + struct stat sb; + off_t off1, off2; + ssize_t n; + int fd1, fd2; + + off1 = off2 = 0; + + fd1 = genfile(); + fd2 = open("copy", O_RDWR | O_CREAT, 0644); + ATF_REQUIRE(fd2 != -1); + + ATF_REQUIRE(fstat(fd1, &sb) == 0); + + ATF_REQUIRE(lseek(fd1, 0, SEEK_CUR) == 0); + ATF_REQUIRE(lseek(fd2, 0, SEEK_CUR) == 0); + + do { + off_t ooff1, ooff2; + + ooff1 = off1; + ooff2 = off2; + n = copy_file_range(fd1, &off1, fd2, &off2, sb.st_size, 0); + ATF_REQUIRE(n >= 0); + ATF_REQUIRE_EQ(off1, ooff1 + n); + ATF_REQUIRE_EQ(off2, ooff2 + n); + } while (n != 0); + + /* Offsets should have been adjusted by copy_file_range(). */ + ATF_REQUIRE_EQ(off1, sb.st_size); + ATF_REQUIRE_EQ(off2, sb.st_size); + /* Seek offsets should have been left alone. */ + ATF_REQUIRE(lseek(fd1, 0, SEEK_CUR) == 0); + ATF_REQUIRE(lseek(fd2, 0, SEEK_CUR) == 0); + /* Make sure the file contents are the same. */ + ATF_REQUIRE_MSG(cmpfile(fd1, fd2), "file contents differ"); + + ATF_REQUIRE(close(fd1) == 0); + ATF_REQUIRE(close(fd2) == 0); +} + +/* + * Make sure that copying to a larger file doesn't cause it to be truncated. + */ +ATF_TC_WITHOUT_HEAD(copy_file_range_truncate); +ATF_TC_BODY(copy_file_range_truncate, tc) +{ + struct stat sb, sb1, sb2; + char digest1[65], digest2[65]; + off_t off; + ssize_t n; + int fd1, fd2; + + fd1 = genfile(); + fd2 = genfile(); + + ATF_REQUIRE(fstat(fd1, &sb1) == 0); + ATF_REQUIRE(fstat(fd2, &sb2) == 0); + + /* fd1 refers to the smaller file. */ + if (sb1.st_size > sb2.st_size) { + int tmp; + + tmp = fd1; + fd1 = fd2; + fd2 = tmp; + ATF_REQUIRE(fstat(fd1, &sb1) == 0); + ATF_REQUIRE(fstat(fd2, &sb2) == 0); + } + + /* + * Compute a hash of the bytes in the larger file which lie beyond the + * length of the smaller file. + */ + SHA256_FdChunk(fd2, digest1, sb1.st_size, sb2.st_size - sb1.st_size); + ATF_REQUIRE(lseek(fd2, 0, SEEK_SET) == 0); + + do { + n = copy_file_range(fd1, NULL, fd2, NULL, SSIZE_MAX, 0); + ATF_REQUIRE(n >= 0); + } while (n != 0); + + /* Validate file offsets after the copy. */ + off = lseek(fd1, 0, SEEK_CUR); + ATF_REQUIRE(off == sb1.st_size); + off = lseek(fd2, 0, SEEK_CUR); + ATF_REQUIRE(off == sb1.st_size); + + /* The larger file's size should remain the same. */ + ATF_REQUIRE(fstat(fd2, &sb) == 0); + ATF_REQUIRE(sb.st_size == sb2.st_size); + + /* The bytes beyond the end of the copy should be unchanged. */ + SHA256_FdChunk(fd2, digest2, sb1.st_size, sb2.st_size - sb1.st_size); + ATF_REQUIRE_MSG(strcmp(digest1, digest2) == 0, + "trailing file contents differ after copy_file_range()"); + + /* + * Verify that the copy actually replicated bytes from the smaller file. + */ + ATF_REQUIRE(ftruncate(fd2, sb1.st_size) == 0); + ATF_REQUIRE(cmpfile(fd1, fd2)); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, copy_file_range_invalid); + ATF_TP_ADD_TC(tp, copy_file_range_offset); + ATF_TP_ADD_TC(tp, copy_file_range_truncate); + + return (atf_no_error()); +} diff --git a/tests/sys/kern/ptrace_test.c b/tests/sys/kern/ptrace_test.c index d36dfe951e20..fee0bd2ffa38 100644 --- a/tests/sys/kern/ptrace_test.c +++ b/tests/sys/kern/ptrace_test.c @@ -3239,7 +3239,7 @@ ATF_TC_BODY(ptrace__PT_REGSET, tc) ATF_REQUIRE(ptrace(PT_GETREGSET, wpid, (caddr_t)&vec, NT_ARM_ADDR_MASK) != -1); REQUIRE_EQ(addr_mask.code, addr_mask.data); - ATF_REQUIRE(addr_mask.code == 0 || + ATF_REQUIRE(addr_mask.code == 0xff00000000000000ul || addr_mask.code == 0xff7f000000000000UL); #endif diff --git a/tests/sys/net/Makefile b/tests/sys/net/Makefile index bc8f9c5e9c80..65cc99a3e932 100644 --- a/tests/sys/net/Makefile +++ b/tests/sys/net/Makefile @@ -6,7 +6,6 @@ BINDIR= ${TESTSDIR} ATF_TESTS_C+= if_epair ATF_TESTS_SH+= if_epair_test ATF_TESTS_SH+= if_bridge_test -TEST_METADATA.if_bridge_test+= required_programs="python" TEST_METADATA.if_bridge_test+= execenv="jail" TEST_METADATA.if_bridge_test+= execenv_jail_params="vnet allow.raw_sockets" ATF_TESTS_SH+= if_clone_test diff --git a/tests/sys/net/if_bridge_test.sh b/tests/sys/net/if_bridge_test.sh index 31299c562510..0c19903714b1 100755 --- a/tests/sys/net/if_bridge_test.sh +++ b/tests/sys/net/if_bridge_test.sh @@ -899,7 +899,7 @@ member_ifaddrs_vlan_cleanup() atf_test_case "vlan_pvid" "cleanup" vlan_pvid_head() { - atf_set descr 'bridge with two ports with pvid set' + atf_set descr 'bridge with two ports with pvid and vlanfilter set' atf_set require.user root } @@ -919,18 +919,18 @@ vlan_pvid_body() bridge=$(vnet_mkbridge) - ifconfig ${bridge} up + ifconfig ${bridge} vlanfilter up ifconfig ${epone}a up ifconfig ${eptwo}a up - ifconfig ${bridge} addm ${epone}a untagged ${epone}a 20 - ifconfig ${bridge} addm ${eptwo}a untagged ${eptwo}a 20 + ifconfig ${bridge} addm ${epone}a untagged 20 + ifconfig ${bridge} addm ${eptwo}a untagged 20 # With VLAN filtering enabled, traffic should be passed. atf_check -s exit:0 -o ignore jexec one ping -c 3 -t 1 192.0.2.2 atf_check -s exit:0 -o ignore jexec two ping -c 3 -t 1 192.0.2.1 # Removed the untagged VLAN on one port; traffic should not be passed. - ifconfig ${bridge} -untagged ${epone}a + ifconfig ${bridge} -ifuntagged ${epone}a atf_check -s exit:2 -o ignore jexec one ping -c 3 -t 1 192.0.2.2 atf_check -s exit:2 -o ignore jexec two ping -c 3 -t 1 192.0.2.1 } @@ -958,16 +958,16 @@ vlan_pvid_filtered_body() vnet_mkjail one ${epone}b vnet_mkjail two ${eptwo}b - jexec one ifconfig ${epone}b 192.0.2.1/24 up - jexec two ifconfig ${eptwo}b 192.0.2.2/24 up + atf_check -s exit:0 jexec one ifconfig ${epone}b 192.0.2.1/24 up + atf_check -s exit:0 jexec two ifconfig ${eptwo}b 192.0.2.2/24 up bridge=$(vnet_mkbridge) - ifconfig ${bridge} up - ifconfig ${epone}a up - ifconfig ${eptwo}a up - ifconfig ${bridge} addm ${epone}a untagged ${epone}a 20 - ifconfig ${bridge} addm ${eptwo}a untagged ${eptwo}a 30 + atf_check -s exit:0 ifconfig ${bridge} vlanfilter up + atf_check -s exit:0 ifconfig ${epone}a up + atf_check -s exit:0 ifconfig ${eptwo}a up + atf_check -s exit:0 ifconfig ${bridge} addm ${epone}a untagged 20 + atf_check -s exit:0 ifconfig ${bridge} addm ${eptwo}a untagged 30 atf_check -s exit:2 -o ignore jexec one ping -c 3 -t 1 192.0.2.2 atf_check -s exit:2 -o ignore jexec two ping -c 3 -t 1 192.0.2.1 @@ -997,18 +997,20 @@ vlan_pvid_tagged_body() vnet_mkjail two ${eptwo}b # Create two tagged interfaces on the appropriate VLANs - jexec one ifconfig ${epone}b up - jexec one ifconfig ${epone}b.20 create 192.0.2.1/24 up - jexec two ifconfig ${eptwo}b up - jexec two ifconfig ${eptwo}b.20 create 192.0.2.2/24 up + atf_check -s exit:0 jexec one ifconfig ${epone}b up + atf_check -s exit:0 jexec one ifconfig ${epone}b.20 \ + create 192.0.2.1/24 up + atf_check -s exit:0 jexec two ifconfig ${eptwo}b up + atf_check -s exit:0 jexec two ifconfig ${eptwo}b.20 \ + create 192.0.2.2/24 up bridge=$(vnet_mkbridge) - ifconfig ${bridge} up - ifconfig ${epone}a up - ifconfig ${eptwo}a up - ifconfig ${bridge} addm ${epone}a untagged ${epone}a 20 - ifconfig ${bridge} addm ${eptwo}a untagged ${eptwo}a 20 + atf_check -s exit:0 ifconfig ${bridge} vlanfilter up + atf_check -s exit:0 ifconfig ${epone}a up + atf_check -s exit:0 ifconfig ${eptwo}a up + atf_check -s exit:0 ifconfig ${bridge} addm ${epone}a untagged 20 + atf_check -s exit:0 ifconfig ${bridge} addm ${eptwo}a untagged 20 # Tagged frames should not be passed. atf_check -s exit:2 -o ignore jexec one ping -c 3 -t 1 192.0.2.2 @@ -1042,18 +1044,18 @@ vlan_pvid_1q_body() # This forces the bridge to add and remove .1q tags to bridge the # traffic. - jexec one ifconfig ${epone}b 192.0.2.1/24 up - jexec two ifconfig ${eptwo}b up - jexec two ifconfig ${eptwo}b.20 create 192.0.2.2/24 up + atf_check -s exit:0 jexec one ifconfig ${epone}b 192.0.2.1/24 up + atf_check -s exit:0 jexec two ifconfig ${eptwo}b up + atf_check -s exit:0 jexec two ifconfig ${eptwo}b.20 create 192.0.2.2/24 up bridge=$(vnet_mkbridge) - ifconfig ${bridge} addm ${epone}a untagged ${epone}a 20 - ifconfig ${bridge} addm ${eptwo}a + atf_check -s exit:0 ifconfig ${bridge} vlanfilter up + atf_check -s exit:0 ifconfig ${bridge} addm ${epone}a untagged 20 + atf_check -s exit:0 ifconfig ${bridge} addm ${eptwo}a tagged 20 - ifconfig ${bridge} up - ifconfig ${epone}a up - ifconfig ${eptwo}a up + atf_check -s exit:0 ifconfig ${epone}a up + atf_check -s exit:0 ifconfig ${eptwo}a up atf_check -s exit:0 -o ignore jexec one ping -c 3 -t 1 192.0.2.2 atf_check -s exit:0 -o ignore jexec two ping -c 3 -t 1 192.0.2.1 @@ -1085,18 +1087,20 @@ vlan_filtering_body() vnet_mkjail one ${epone}b vnet_mkjail two ${eptwo}b - jexec one ifconfig ${epone}b up - jexec one ifconfig ${epone}b.20 create 192.0.2.1/24 up - jexec two ifconfig ${eptwo}b up - jexec two ifconfig ${eptwo}b.20 create 192.0.2.2/24 up + atf_check -s exit:0 jexec one ifconfig ${epone}b up + atf_check -s exit:0 jexec one ifconfig ${epone}b.20 \ + create 192.0.2.1/24 up + atf_check -s exit:0 jexec two ifconfig ${eptwo}b up + atf_check -s exit:0 jexec two ifconfig ${eptwo}b.20 \ + create 192.0.2.2/24 up bridge=$(vnet_mkbridge) - ifconfig ${bridge} up - ifconfig ${epone}a up - ifconfig ${eptwo}a up - ifconfig ${bridge} addm ${epone}a vlanfilter ${epone}a - ifconfig ${bridge} addm ${eptwo}a vlanfilter ${eptwo}a + atf_check -s exit:0 ifconfig ${bridge} vlanfilter up + atf_check -s exit:0 ifconfig ${epone}a up + atf_check -s exit:0 ifconfig ${eptwo}a up + atf_check -s exit:0 ifconfig ${bridge} addm ${epone}a + atf_check -s exit:0 ifconfig ${bridge} addm ${eptwo}a # Right now there are no VLANs on the access list, so everything # should be blocked. @@ -1106,25 +1110,25 @@ vlan_filtering_body() # Set the untagged vlan on both ports to 20 and make sure traffic is # still blocked. We intentionally do not pass tagged traffic for the # untagged vlan. - atf_check -s exit:0 ifconfig ${bridge} untagged ${epone}a 20 - atf_check -s exit:0 ifconfig ${bridge} untagged ${eptwo}a 20 + atf_check -s exit:0 ifconfig ${bridge} ifuntagged ${epone}a 20 + atf_check -s exit:0 ifconfig ${bridge} ifuntagged ${eptwo}a 20 atf_check -s exit:2 -o ignore jexec one ping -c 3 -t 1 192.0.2.2 atf_check -s exit:2 -o ignore jexec two ping -c 3 -t 1 192.0.2.1 - atf_check -s exit:0 ifconfig ${bridge} -untagged ${epone}a - atf_check -s exit:0 ifconfig ${bridge} -untagged ${eptwo}a + atf_check -s exit:0 ifconfig ${bridge} -ifuntagged ${epone}a + atf_check -s exit:0 ifconfig ${bridge} -ifuntagged ${eptwo}a # Add VLANs 10-30 to the access list; now access should be allowed. - ifconfig ${bridge} +tagged ${epone}a 10-30 - ifconfig ${bridge} +tagged ${eptwo}a 10-30 + atf_check -s exit:0 ifconfig ${bridge} +iftagged ${epone}a 10-30 + atf_check -s exit:0 ifconfig ${bridge} +iftagged ${eptwo}a 10-30 atf_check -s exit:0 -o ignore jexec one ping -c 3 -t 1 192.0.2.2 atf_check -s exit:0 -o ignore jexec two ping -c 3 -t 1 192.0.2.1 # Remove vlan 20 from the access list, now access should be blocked # again. - ifconfig ${bridge} -tagged ${epone}a 20 - ifconfig ${bridge} -tagged ${eptwo}a 20 + atf_check -s exit:0 ifconfig ${bridge} -iftagged ${epone}a 20 + atf_check -s exit:0 ifconfig ${bridge} -iftagged ${eptwo}a 20 atf_check -s exit:2 -o ignore jexec one ping -c 3 -t 1 192.0.2.2 atf_check -s exit:2 -o ignore jexec two ping -c 3 -t 1 192.0.2.1 } @@ -1135,58 +1139,59 @@ vlan_filtering_cleanup() } # -# Test the ifconfig 'tagged' option. +# Test the ifconfig 'iftagged' option. # -atf_test_case "vlan_ifconfig_tagged" "cleanup" -vlan_ifconfig_tagged_head() +atf_test_case "vlan_ifconfig_iftagged" "cleanup" +vlan_ifconfig_iftagged_head() { - atf_set descr 'test the ifconfig tagged option' + atf_set descr 'test the ifconfig iftagged option' atf_set require.user root } -vlan_ifconfig_tagged_body() +vlan_ifconfig_iftagged_body() { vnet_init vnet_init_bridge ep=$(vnet_mkepair) bridge=$(vnet_mkbridge) + atf_check -s exit:0 ifconfig ${bridge} vlanfilter up - ifconfig ${bridge} addm ${ep}a vlanfilter ${ep}a up - ifconfig ${ep}a up + atf_check -s exit:0 ifconfig ${bridge} addm ${ep}a + atf_check -s exit:0 ifconfig ${ep}a up # To start with, no vlans should be configured. atf_check -s exit:0 -o not-match:"tagged" ifconfig ${bridge} # Add vlans 100-149. - atf_check -s exit:0 ifconfig ${bridge} tagged ${ep}a 100-149 + atf_check -s exit:0 ifconfig ${bridge} iftagged ${ep}a 100-149 atf_check -s exit:0 -o match:"tagged 100-149" ifconfig ${bridge} # Replace the vlan list with 139-199. - atf_check -s exit:0 ifconfig ${bridge} tagged ${ep}a 139-199 + atf_check -s exit:0 ifconfig ${bridge} iftagged ${ep}a 139-199 atf_check -s exit:0 -o match:"tagged 139-199" ifconfig ${bridge} # Add vlans 100-170. - atf_check -s exit:0 ifconfig ${bridge} +tagged ${ep}a 100-170 + atf_check -s exit:0 ifconfig ${bridge} +iftagged ${ep}a 100-170 atf_check -s exit:0 -o match:"tagged 100-199" ifconfig ${bridge} # Remove vlans 104, 105, and 150-159 - atf_check -s exit:0 ifconfig ${bridge} -tagged ${ep}a 104,105,150-159 + atf_check -s exit:0 ifconfig ${bridge} -iftagged ${ep}a 104,105,150-159 atf_check -s exit:0 -o match:"tagged 100-103,106-149,160-199" \ ifconfig ${bridge} # Remove the entire vlan list. - atf_check -s exit:0 ifconfig ${bridge} tagged ${ep}a none + atf_check -s exit:0 ifconfig ${bridge} iftagged ${ep}a none atf_check -s exit:0 -o not-match:"tagged" ifconfig ${bridge} # Test some invalid vlans sets. for bad_vlan in -1 0 4096 4097 foo 0-10 4000-5000 foo-40 40-foo; do atf_check -s exit:1 -e ignore \ - ifconfig ${bridge} tagged "$bad_vlan" + ifconfig ${bridge} iftagged "$bad_vlan" done } -vlan_ifconfig_tagged_cleanup() +vlan_ifconfig_iftagged_cleanup() { vnet_cleanup } @@ -1210,18 +1215,19 @@ vlan_svi_body() vnet_mkjail one ${epone}b - jexec one ifconfig ${epone}b up - jexec one ifconfig ${epone}b.20 create 192.0.2.1/24 up + atf_check -s exit:0 jexec one ifconfig ${epone}b up + atf_check -s exit:0 jexec one ifconfig ${epone}b.20 \ + create 192.0.2.1/24 up bridge=$(vnet_mkbridge) - ifconfig ${bridge} up - ifconfig ${epone}a up - ifconfig ${bridge} addm ${epone}a tagged ${epone}a 20 + atf_check -s exit:0 ifconfig ${bridge} vlanfilter up + atf_check -s exit:0 ifconfig ${epone}a up + atf_check -s exit:0 ifconfig ${bridge} addm ${epone}a tagged 20 svi=$(vnet_mkvlan) - ifconfig ${svi} vlan 20 vlandev ${bridge} - ifconfig ${svi} inet 192.0.2.2/24 up + atf_check -s exit:0 ifconfig ${svi} vlan 20 vlandev ${bridge} + atf_check -s exit:0 ifconfig ${svi} inet 192.0.2.2/24 up atf_check -s exit:0 -o ignore ping -c 3 -t 1 192.0.2.1 } @@ -1255,21 +1261,25 @@ vlan_qinq_body() # Create a QinQ trunk between the two jails. The outer (provider) tag # is 5, and the inner tag is 10. - jexec one ifconfig ${epone}b up - jexec one ifconfig ${epone}b.5 create vlanproto 802.1ad up - jexec one ifconfig ${epone}b.5.10 create inet 192.0.2.1/24 up + atf_check -s exit:0 jexec one ifconfig ${epone}b up + atf_check -s exit:0 jexec one \ + ifconfig ${epone}b.5 create vlanproto 802.1ad up + atf_check -s exit:0 jexec one \ + ifconfig ${epone}b.5.10 create inet 192.0.2.1/24 up - jexec two ifconfig ${eptwo}b up - jexec two ifconfig ${eptwo}b.5 create vlanproto 802.1ad up - jexec two ifconfig ${eptwo}b.5.10 create inet 192.0.2.2/24 up + atf_check -s exit:0 jexec two ifconfig ${eptwo}b up + atf_check -s exit:0 jexec two ifconfig \ + ${eptwo}b.5 create vlanproto 802.1ad up + atf_check -s exit:0 jexec two ifconfig \ + ${eptwo}b.5.10 create inet 192.0.2.2/24 up bridge=$(vnet_mkbridge) - ifconfig ${bridge} up - ifconfig ${epone}a up - ifconfig ${eptwo}a up - ifconfig ${bridge} addm ${epone}a vlanfilter ${epone}a - ifconfig ${bridge} addm ${eptwo}a vlanfilter ${eptwo}a + atf_check -s exit:0 ifconfig ${bridge} vlanfilter defqinq up + atf_check -s exit:0 ifconfig ${epone}a up + atf_check -s exit:0 ifconfig ${eptwo}a up + atf_check -s exit:0 ifconfig ${bridge} addm ${epone}a + atf_check -s exit:0 ifconfig ${bridge} addm ${eptwo}a # Right now there are no VLANs on the access list, so everything # should be blocked. @@ -1277,10 +1287,16 @@ vlan_qinq_body() atf_check -s exit:2 -o ignore jexec two ping -c 3 -t 1 192.0.2.1 # Add the provider tag to the access list; now traffic should be passed. - ifconfig ${bridge} +tagged ${epone}a 5 - ifconfig ${bridge} +tagged ${eptwo}a 5 + atf_check -s exit:0 ifconfig ${bridge} +iftagged ${epone}a 5 + atf_check -s exit:0 ifconfig ${bridge} +iftagged ${eptwo}a 5 atf_check -s exit:0 -o ignore jexec one ping -c 3 -t 1 192.0.2.2 atf_check -s exit:0 -o ignore jexec two ping -c 3 -t 1 192.0.2.1 + + # Remove the qinq flag from one of the interfaces; traffic should + # be blocked again. + atf_check -s exit:0 ifconfig ${bridge} -qinq ${epone}a + atf_check -s exit:2 -o ignore jexec one ping -c 3 -t 1 192.0.2.2 + atf_check -s exit:2 -o ignore jexec two ping -c 3 -t 1 192.0.2.1 } vlan_qinq_cleanup() @@ -1311,6 +1327,108 @@ bridge_svi_in_bridge_cleanup() vnet_cleanup } +atf_test_case "vlan_untagged" "cleanup" +vlan_untagged_head() +{ + atf_set descr 'bridge with two ports with untagged set' + atf_set require.user root +} + +vlan_untagged_body() +{ + vnet_init + vnet_init_bridge + + epone=$(vnet_mkepair) + eptwo=$(vnet_mkepair) + + vnet_mkjail one ${epone}b + vnet_mkjail two ${eptwo}b + + jexec one ifconfig ${epone}b 192.0.2.1/24 up + jexec two ifconfig ${eptwo}b 192.0.2.2/24 up + + bridge=$(vnet_mkbridge) + + ifconfig ${bridge} up + ifconfig ${epone}a up + ifconfig ${eptwo}a up + ifconfig ${bridge} addm ${epone}a untagged 20 + ifconfig ${bridge} addm ${eptwo}a untagged 30 + + # With two ports on different VLANs, traffic should not be passed. + atf_check -s exit:2 -o ignore jexec one ping -c 3 -t 1 192.0.2.2 + atf_check -s exit:2 -o ignore jexec two ping -c 3 -t 1 192.0.2.1 + + # Move the second port to VLAN 20; now traffic should be passed. + atf_check -s exit:0 ifconfig ${bridge} ifuntagged ${eptwo}a 20 + atf_check -s exit:0 -o ignore jexec one ping -c 3 -t 1 192.0.2.2 + atf_check -s exit:0 -o ignore jexec two ping -c 3 -t 1 192.0.2.1 + + # Remove the first's port untagged config, now traffic should + # not pass again. + atf_check -s exit:0 ifconfig ${bridge} -ifuntagged ${epone}a + atf_check -s exit:2 -o ignore jexec one ping -c 3 -t 1 192.0.2.2 + atf_check -s exit:2 -o ignore jexec two ping -c 3 -t 1 192.0.2.1 +} + +vlan_untagged_cleanup() +{ + vnet_cleanup +} + +atf_test_case "vlan_defuntagged" "cleanup" +vlan_defuntagged_head() +{ + atf_set descr 'defuntagged (defpvid) bridge option' + atf_set require.user root +} + +vlan_defuntagged_body() +{ + vnet_init + vnet_init_bridge + + bridge=$(vnet_mkbridge) + + # Invalid VLAN IDs + atf_check -s exit:1 -ematch:"invalid vlan id: 0" \ + ifconfig ${bridge} defuntagged 0 + atf_check -s exit:1 -ematch:"invalid vlan id: 4095" \ + ifconfig ${bridge} defuntagged 4095 + atf_check -s exit:1 -ematch:"invalid vlan id: 5000" \ + ifconfig ${bridge} defuntagged 5000 + + # Check the bridge option is set and cleared correctly + atf_check -s exit:0 -onot-match:"defuntagged=" \ + ifconfig ${bridge} + + atf_check -s exit:0 ifconfig ${bridge} defuntagged 10 + atf_check -s exit:0 -omatch:"defuntagged=10$" \ + ifconfig ${bridge} + + atf_check -s exit:0 ifconfig ${bridge} -defuntagged + atf_check -s exit:0 -onot-match:"defuntagged=" \ + ifconfig ${bridge} + + # Check the untagged option is correctly set on a member + atf_check -s exit:0 ifconfig ${bridge} defuntagged 10 + + epair=$(vnet_mkepair) + atf_check -s exit:0 ifconfig ${bridge} addm ${epair}a + + tag=$(ifconfig ${bridge} | sed -Ene \ + "/member: ${epair}a/ { N;s/.*untagged ([0-9]+).*/\\1/p;q; }") + if [ "$tag" != "10" ]; then + atf_fail "wrong untagged vlan: ${tag}" + fi +} + +vlan_defuntagged_cleanup() +{ + vnet_cleanup +} + atf_init_test_cases() { atf_add_test_case "bridge_transmit_ipv4_unicast" @@ -1335,8 +1453,10 @@ atf_init_test_cases() atf_add_test_case "vlan_pvid_filtered" atf_add_test_case "vlan_pvid_tagged" atf_add_test_case "vlan_filtering" - atf_add_test_case "vlan_ifconfig_tagged" + atf_add_test_case "vlan_ifconfig_iftagged" atf_add_test_case "vlan_svi" atf_add_test_case "vlan_qinq" + atf_add_test_case "vlan_untagged" + atf_add_test_case "vlan_defuntagged" atf_add_test_case "bridge_svi_in_bridge" } diff --git a/tests/sys/net/if_gif.sh b/tests/sys/net/if_gif.sh index 5c7278d17e8f..bff88f9e75b6 100644 --- a/tests/sys/net/if_gif.sh +++ b/tests/sys/net/if_gif.sh @@ -202,10 +202,164 @@ atf_test_case "6in6" "cleanup" vnet_cleanup } +atf_test_case "etherip" "cleanup" +etherip_head() +{ + atf_set descr 'EtherIP regression' + atf_set require.user root +} + +etherip_body() +{ + vnet_init + vnet_init_bridge + + if ! kldstat -q -m if_gif; then + atf_skip "This test requires if_gif" + fi + + epair=$(vnet_mkepair) + + vnet_mkjail one ${epair}a + gone=$(jexec one ifconfig gif create) + jexec one ifconfig ${epair}a 192.0.2.1/24 up + jexec one ifconfig $gone tunnel 192.0.2.1 192.0.2.2 + jexec one ifconfig $gone 198.51.100.1/24 198.51.100.2 up + jexec one ifconfig $gone inet6 no_dad 2001:db8:1::1/64 + + bone=$(jexec one ifconfig bridge create) + jexec one ifconfig $bone addm $gone + jexec one ifconfig $bone 192.168.169.253/24 up + jexec one ifconfig $bone inet6 no_dad 2001:db8:2::1/64 + + vnet_mkjail two ${epair}b + gtwo=$(jexec two ifconfig gif create) + jexec two ifconfig ${epair}b 192.0.2.2/24 up + jexec two ifconfig $gtwo tunnel 192.0.2.2 192.0.2.1 + jexec two ifconfig $gtwo 198.51.100.2/24 198.51.100.1 up + jexec two ifconfig $gtwo inet6 no_dad 2001:db8:1::2/64 + + btwo=$(jexec two ifconfig bridge create) + jexec two ifconfig $btwo addm $gtwo + jexec two ifconfig $btwo 192.168.169.254/24 up + jexec two ifconfig $btwo inet6 no_dad 2001:db8:2::2/64 + + # Sanity check + atf_check -s exit:0 -o ignore \ + jexec one ping -c 1 192.0.2.2 + + # EtherIP tunnel test + atf_check -s exit:0 -o ignore \ + jexec one ping -c 1 192.168.169.254 + atf_check -s exit:0 -o ignore \ + jexec one ping -6 -c 1 2001:db8:2::2 + atf_check -s exit:0 -o ignore \ + jexec two ping -c 1 192.168.169.253 + atf_check -s exit:0 -o ignore \ + jexec two ping -6 -c 1 2001:db8:2::1 + + # EtherIP should not affect normal IPv[46] over IPv4 tunnel + # See bugzilla PR 227450 + # IPv4 in IPv4 Tunnel test + atf_check -s exit:0 -o ignore \ + jexec one ping -c 1 198.51.100.2 + atf_check -s exit:0 -o ignore \ + jexec two ping -c 1 198.51.100.1 + + # IPv6 in IPv4 tunnel test + atf_check -s exit:0 -o ignore \ + jexec one ping -6 -c 1 2001:db8:1::2 + atf_check -s exit:0 -o ignore \ + jexec two ping -6 -c 1 2001:db8:1::1 +} + +etherip_cleanup() +{ + vnet_cleanup +} + +atf_test_case "etherip6" "cleanup" +etherip6_head() +{ + atf_set descr 'EtherIP over IPv6 regression' + atf_set require.user root +} + +etherip6_body() +{ + vnet_init + vnet_init_bridge + + if ! kldstat -q -m if_gif; then + atf_skip "This test requires if_gif" + fi + + epair=$(vnet_mkepair) + + vnet_mkjail one ${epair}a + gone=$(jexec one ifconfig gif create) + jexec one ifconfig ${epair}a inet6 no_dad 2001:db8::1/64 up + jexec one ifconfig $gone inet6 tunnel 2001:db8::1 2001:db8::2 + jexec one ifconfig $gone 198.51.100.1/24 198.51.100.2 up + jexec one ifconfig $gone inet6 no_dad 2001:db8:1::1/64 + + bone=$(jexec one ifconfig bridge create) + jexec one ifconfig $bone addm $gone + jexec one ifconfig $bone 192.168.169.253/24 up + jexec one ifconfig $bone inet6 no_dad 2001:db8:2::1/64 + + vnet_mkjail two ${epair}b + gtwo=$(jexec two ifconfig gif create) + jexec two ifconfig ${epair}b inet6 no_dad 2001:db8::2/64 up + jexec two ifconfig $gtwo inet6 tunnel 2001:db8::2 2001:db8::1 + jexec two ifconfig $gtwo 198.51.100.2/24 198.51.100.1 up + jexec two ifconfig $gtwo inet6 no_dad 2001:db8:1::2/64 + + btwo=$(jexec two ifconfig bridge create) + jexec two ifconfig $btwo addm $gtwo + jexec two ifconfig $btwo 192.168.169.254/24 up + jexec two ifconfig $btwo inet6 no_dad 2001:db8:2::2/64 + + # Sanity check + atf_check -s exit:0 -o ignore \ + jexec one ping -6 -c 1 2001:db8::2 + + # EtherIP tunnel test + atf_check -s exit:0 -o ignore \ + jexec one ping -c 1 192.168.169.254 + atf_check -s exit:0 -o ignore \ + jexec one ping -6 -c 1 2001:db8:2::2 + atf_check -s exit:0 -o ignore \ + jexec two ping -c 1 192.168.169.253 + atf_check -s exit:0 -o ignore \ + jexec two ping -6 -c 1 2001:db8:2::1 + + # EtherIP should not affect normal IPv[46] over IPv6 tunnel + # See bugzilla PR 227450 + # IPv4 in IPv6 Tunnel test + atf_check -s exit:0 -o ignore \ + jexec one ping -c 1 198.51.100.2 + atf_check -s exit:0 -o ignore \ + jexec two ping -c 1 198.51.100.1 + + # IPv6 in IPv6 tunnel test + atf_check -s exit:0 -o ignore \ + jexec one ping -6 -c 1 2001:db8:1::2 + atf_check -s exit:0 -o ignore \ + jexec two ping -6 -c 1 2001:db8:1::1 +} + +etherip6_cleanup() +{ + vnet_cleanup +} + atf_init_test_cases() { atf_add_test_case "4in4" atf_add_test_case "6in4" atf_add_test_case "4in6" atf_add_test_case "6in6" + atf_add_test_case "etherip" + atf_add_test_case "etherip6" } diff --git a/tests/sys/net/if_ovpn/if_ovpn.sh b/tests/sys/net/if_ovpn/if_ovpn.sh index c42344da1a3b..0281e7fc273d 100644 --- a/tests/sys/net/if_ovpn/if_ovpn.sh +++ b/tests/sys/net/if_ovpn/if_ovpn.sh @@ -499,6 +499,81 @@ atf_test_case "6in6" "cleanup" ovpn_cleanup } +atf_test_case "linklocal" "cleanup" +linklocal_head() +{ + atf_set descr 'Use IPv6 link-local addresses' + atf_set require.user root + atf_set require.progs openvpn +} + +linklocal_body() +{ + ovpn_init + + l=$(vnet_mkepair) + + vnet_mkjail a ${l}a + jexec a ifconfig ${l}a inet6 fe80::a/64 up no_dad + vnet_mkjail b ${l}b + jexec b ifconfig ${l}b inet6 fe80::b/64 up no_dad + + # Sanity check + atf_check -s exit:0 -o ignore jexec a ping6 -c 1 fe80::b%${l}a + + ovpn_start a " + dev ovpn0 + dev-type tun + proto udp6 + + cipher AES-256-GCM + auth SHA256 + + local fe80::a%${l}a + server-ipv6 2001:db8:1::/64 + + ca $(atf_get_srcdir)/ca.crt + cert $(atf_get_srcdir)/server.crt + key $(atf_get_srcdir)/server.key + dh $(atf_get_srcdir)/dh.pem + + mode server + script-security 2 + auth-user-pass-verify /usr/bin/true via-env + topology subnet + + keepalive 100 600 + " + ovpn_start b " + dev tun0 + dev-type tun + + client + + remote fe80::a%${l}b + auth-user-pass $(atf_get_srcdir)/user.pass + + ca $(atf_get_srcdir)/ca.crt + cert $(atf_get_srcdir)/client.crt + key $(atf_get_srcdir)/client.key + dh $(atf_get_srcdir)/dh.pem + + keepalive 100 600 + " + + # Give the tunnel time to come up + sleep 10 + jexec a ifconfig + + atf_check -s exit:0 -o ignore jexec b ping6 -c 3 2001:db8:1::1 + atf_check -s exit:0 -o ignore jexec b ping6 -c 3 -z 16 2001:db8:1::1 +} + +linklocal_cleanup() +{ + ovpn_cleanup +} + atf_test_case "timeout_client" "cleanup" timeout_client_head() { @@ -1412,6 +1487,7 @@ atf_init_test_cases() atf_add_test_case "6in4" atf_add_test_case "6in6" atf_add_test_case "4in6" + atf_add_test_case "linklocal" atf_add_test_case "timeout_client" atf_add_test_case "explicit_exit" atf_add_test_case "multi_client" diff --git a/tests/sys/netpfil/pf/Makefile b/tests/sys/netpfil/pf/Makefile index 404d5adfb07a..616ffe560b3a 100644 --- a/tests/sys/netpfil/pf/Makefile +++ b/tests/sys/netpfil/pf/Makefile @@ -55,6 +55,7 @@ ATF_TESTS_SH+= altq \ tcp \ tos +ATF_TESTS_PYTEST+= frag4.py ATF_TESTS_PYTEST+= frag6.py ATF_TESTS_PYTEST+= header.py ATF_TESTS_PYTEST+= icmp.py diff --git a/tests/sys/netpfil/pf/frag4.py b/tests/sys/netpfil/pf/frag4.py new file mode 100644 index 000000000000..3303d2ee7780 --- /dev/null +++ b/tests/sys/netpfil/pf/frag4.py @@ -0,0 +1,72 @@ +# +# SPDX-License-Identifier: BSD-2-Clause +# +# Copyright (c) 2025 Rubicon Communications, LLC (Netgate) +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. + +import pytest +from utils import DelayedSend +from atf_python.sys.net.tools import ToolsHelper +from atf_python.sys.net.vnet import VnetTestTemplate + +class TestFrag4_NoReassemble(VnetTestTemplate): + REQUIRED_MODULES = [ "pf" ] + TOPOLOGY = { + "vnet1": {"ifaces": ["if1"]}, + "vnet2": {"ifaces": ["if1", "if2"]}, + "vnet3": {"ifaces": ["if2"]}, + "if1": {"prefixes4": [("192.0.2.1/24", "192.0.2.2/24")]}, + "if2": {"prefixes4": [("198.51.100.1/24", "198.51.100.2/24")]}, + } + + def vnet2_handler(self, vnet): + outifname = vnet.iface_alias_map["if2"].name + + ToolsHelper.print_output("/sbin/pfctl -e") + ToolsHelper.pf_rules([ + "set reassemble no", + "nat on %s from 192.0.2.0/24 to any -> (%s)" % (outifname, outifname), + "pass out" + ]) + + ToolsHelper.print_output("/sbin/sysctl net.inet.ip.forwarding=1") + + def vnet3_handler(self, vnet): + # We deliberately don't set the default gateway here, so if we get a + # reply from this we know we did NAT in vnet2 + pass + + @pytest.mark.require_user("root") + @pytest.mark.require_progs(["scapy"]) + def test_udp_frag(self): + ToolsHelper.print_output("/sbin/route add default 192.0.2.2") + ToolsHelper.print_output("/sbin/ping -c 3 198.51.100.2") + + # Import in the correct vnet, so at to not confuse Scapy + import scapy.all as sp + + pkt = sp.IP(dst="198.51.100.2", frag=123) \ + / sp.UDP(dport=12345, sport=54321) + reply = sp.sr1(pkt, timeout=3) + # We don't expect a reply + assert not reply diff --git a/tests/sys/netpfil/pf/nat.sh b/tests/sys/netpfil/pf/nat.sh index 16c981f97399..5ea1dd6d8b2f 100644 --- a/tests/sys/netpfil/pf/nat.sh +++ b/tests/sys/netpfil/pf/nat.sh @@ -782,6 +782,7 @@ empty_pool_head() { atf_set descr 'NAT with empty pool' atf_set require.user root + atf_set require.progs python3 scapy } empty_pool_body() diff --git a/tests/sys/netpfil/pf/nat64.py b/tests/sys/netpfil/pf/nat64.py index a5890fc4a161..705de72f5bc4 100644 --- a/tests/sys/netpfil/pf/nat64.py +++ b/tests/sys/netpfil/pf/nat64.py @@ -96,8 +96,10 @@ class TestNAT64(VnetTestTemplate): ToolsHelper.print_output("/sbin/route add default 192.0.2.2") ToolsHelper.print_output("/sbin/pfctl -e") ToolsHelper.pf_rules([ - "pass inet6 proto icmp6", - "pass in on %s inet6 af-to inet from 192.0.2.1" % ifname]) + "block", + "pass inet6 proto icmp6 icmp6-type { neighbrsol, neighbradv }", + "pass in on %s inet6 af-to inet from 192.0.2.1" % ifname, + ]) vnet.pipe.send(socket.if_nametoindex("pflog0")) @@ -326,3 +328,31 @@ class TestNAT64(VnetTestTemplate): packets = sp.sniff(iface=ifname, timeout=5) for r in packets: r.show() + + @pytest.mark.require_user("root") + @pytest.mark.require_progs(["scapy"]) + def test_ttl_zero(self): + """ + PR 288274: we can use an mbuf after free on TTL = 0 + """ + ifname = self.vnet.iface_alias_map["if1"].name + gw_mac = self.vnet.iface_alias_map["if1"].epairb.ether + ToolsHelper.print_output("/sbin/route -6 add default 2001:db8::1") + + import scapy.all as sp + + pkt = sp.Ether(dst=gw_mac) \ + / sp.IPv6(dst="64:ff9b::192.0.2.2", hlim=0) \ + / sp.SCTP(sport=1111, dport=2222) \ + / sp.SCTPChunkInit(init_tag=1, n_in_streams=1, n_out_streams=1, \ + a_rwnd=1500, params=[ \ + sp.SCTPChunkParamIPv4Addr() \ + ]) + pkt.show() + sp.hexdump(pkt) + s = DelayedSend(pkt, sendif=ifname) + + packets = sp.sniff(iface=ifname, timeout=5) + for r in packets: + r.show() + diff --git a/tests/sys/netpfil/pf/nat64.sh b/tests/sys/netpfil/pf/nat64.sh index da95a7bf9893..4438ad6abb85 100644 --- a/tests/sys/netpfil/pf/nat64.sh +++ b/tests/sys/netpfil/pf/nat64.sh @@ -55,15 +55,19 @@ nat64_setup_base() nat64_setup_in() { + state_policy="${1:-if-bound}" nat64_setup_base pft_set_rules rtr \ "set reassemble yes" \ - "set state-policy if-bound" \ + "set state-policy ${state_policy}" \ + "block" \ + "pass inet6 proto icmp6 icmp6-type { neighbrsol, neighbradv }" \ "pass in on ${epair}b inet6 from any to 64:ff9b::/96 af-to inet from (${epair_link}a)" } nat64_setup_out() { + state_policy="${1:-if-bound}" nat64_setup_base jexec rtr sysctl net.inet6.ip6.forwarding=1 # AF translation happens post-routing, traffic must be directed @@ -72,11 +76,11 @@ nat64_setup_out() jexec rtr route add -inet6 64:ff9b::/96 -iface ${epair_link}a; pft_set_rules rtr \ "set reassemble yes" \ - "set state-policy if-bound" \ - "pass quick inet6 proto icmp6 icmp6-type { neighbrsol, neighbradv }" \ - "pass in quick on ${epair}b from any to 64:ff9b::/96" \ - "pass out quick on ${epair_link}a from any to 64:ff9b::/96 af-to inet from (${epair_link}a)" \ - "block" + "set state-policy ${state_policy}" \ + "block" \ + "pass inet6 proto icmp6 icmp6-type { neighbrsol, neighbradv }" \ + "pass in on ${epair}b from any to 64:ff9b::/96" \ + "pass out on ${epair_link}a from any to 64:ff9b::/96 af-to inet from (${epair_link}a)" } atf_test_case "icmp_echo_in" "cleanup" @@ -185,14 +189,14 @@ fragmentation_out_cleanup() pft_cleanup } -atf_test_case "tcp_in" "cleanup" -tcp_in_head() +atf_test_case "tcp_in_if_bound" "cleanup" +tcp_in_if_bound_head() { - atf_set descr 'TCP NAT64 test on inbound interface' + atf_set descr 'TCP NAT64 test on inbound interface, if-bound states' atf_set require.user root } -tcp_in_body() +tcp_in_if_bound_body() { nat64_setup_in @@ -200,7 +204,7 @@ tcp_in_body() # Sanity check & delay for nc startup atf_check -s exit:0 -o ignore \ - ping6 -c 1 64:ff9b::192.0.2.2 + ping6 -c 3 64:ff9b::192.0.2.2 rcv=$(nc -w 3 -6 64:ff9b::c000:202 1234) if [ "${rcv}" != "foo" ]; @@ -208,21 +212,32 @@ tcp_in_body() echo "rcv=${rcv}" atf_fail "Failed to connect to TCP server" fi + + # Interfaces of the state are reversed when doing inbound NAT64! + # FIXME: Packets counters seem wrong! + states=$(mktemp) || exit 1 + jexec rtr pfctl -qvvss | normalize_pfctl_s > $states + for state_regexp in \ + "${epair_link}a tcp 192.0.2.1:[0-9]+ \(2001:db8::2\[[0-9]+\]\) -> 192.0.2.2:1234 \(64:ff9b::c000:202\[1234\]\) .* 9:9 pkts.* rule 3 .* origif: ${epair}b" \ + ; do + grep -qE "${state_regexp}" $states || atf_fail "State not found for '${state_regexp}'" + done + [ $(cat $states | grep tcp | wc -l) -eq 1 ] || atf_fail "Not exactly 1 state found!" } -tcp_in_cleanup() +tcp_in_if_bound_cleanup() { pft_cleanup } -atf_test_case "tcp_out" "cleanup" -tcp_out_head() +atf_test_case "tcp_out_if_bound" "cleanup" +tcp_out_if_bound_head() { - atf_set descr 'TCP NAT64 test on outbound interface' + atf_set descr 'TCP NAT64 test on outbound interface, if-bound states' atf_set require.user root } -tcp_out_body() +tcp_out_if_bound_body() { nat64_setup_out @@ -230,7 +245,7 @@ tcp_out_body() # Sanity check & delay for nc startup atf_check -s exit:0 -o ignore \ - ping6 -c 1 64:ff9b::192.0.2.2 + ping6 -c 3 64:ff9b::192.0.2.2 rcv=$(nc -w 3 -6 64:ff9b::c000:202 1234) if [ "${rcv}" != "foo" ]; @@ -238,9 +253,102 @@ tcp_out_body() echo "rcv=${rcv}" atf_fail "Failed to connect to TCP server" fi + + # Origif is not printed when identical as if. + states=$(mktemp) || exit 1 + jexec rtr pfctl -qvvss | normalize_pfctl_s > $states + for state_regexp in \ + "${epair}b tcp 64:ff9b::c000:202\[1234\] <- 2001:db8::2\[[0-9]+\] .* 5:4 pkts.* rule 3 .*creatorid" \ + "${epair_link}a tcp 192.0.2.1:[0-9]+ \(64:ff9b::c000:202\[1234\]\) -> 192.0.2.2:1234 \(2001:db8::2\[[0-9]+\]\).* 5:4 pkts.* rule 4 .*creatorid" \ + ; do + grep -qE "${state_regexp}" $states || atf_fail "State not found for '${state_regexp}'" + done + [ $(cat $states | grep tcp | wc -l) -eq 2 ] || atf_fail "Not exactly 2 states found!" } -tcp_out_cleanup() +tcp_out_if_bound_cleanup() +{ + pft_cleanup +} + +atf_test_case "tcp_in_floating" "cleanup" +tcp_in_floating_head() +{ + atf_set descr 'TCP NAT64 test on inbound interface, floating states' + atf_set require.user root +} + +tcp_in_floating_body() +{ + nat64_setup_in "floating" + + echo "foo" | jexec dst nc -l 1234 & + + # Sanity check & delay for nc startup + atf_check -s exit:0 -o ignore \ + ping6 -c 3 64:ff9b::192.0.2.2 + + rcv=$(nc -w 3 -6 64:ff9b::c000:202 1234) + if [ "${rcv}" != "foo" ]; + then + echo "rcv=${rcv}" + atf_fail "Failed to connect to TCP server" + fi + + # Interfaces of the state are reversed when doing inbound NAT64! + # FIXME: Packets counters seem wrong! + states=$(mktemp) || exit 1 + jexec rtr pfctl -qvvss | normalize_pfctl_s > $states + for state_regexp in \ + "all tcp 192.0.2.1:[0-9]+ \(2001:db8::2\[[0-9]+\]\) -> 192.0.2.2:1234 \(64:ff9b::c000:202\[1234\]\).* 9:9 pkts.* rule 3 .* origif: ${epair}b" \ + ; do + grep -qE "${state_regexp}" $states || atf_fail "State not found for '${state_regexp}'" + done + [ $(cat $states | grep tcp | wc -l) -eq 1 ] || atf_fail "Not exactly 1 state found!" +} + +tcp_in_floating_cleanup() +{ + pft_cleanup +} + +atf_test_case "tcp_out_floating" "cleanup" +tcp_out_floating_head() +{ + atf_set descr 'TCP NAT64 test on outbound interface, floating states' + atf_set require.user root +} + +tcp_out_floating_body() +{ + nat64_setup_out "floating" + + echo "foo" | jexec dst nc -l 1234 & + + # Sanity check & delay for nc startup + atf_check -s exit:0 -o ignore \ + ping6 -c 3 64:ff9b::192.0.2.2 + + rcv=$(nc -w 3 -6 64:ff9b::c000:202 1234) + if [ "${rcv}" != "foo" ]; + then + echo "rcv=${rcv}" + atf_fail "Failed to connect to TCP server" + fi + + # Origif is not printed when identical as if. + states=$(mktemp) || exit 1 + jexec rtr pfctl -qvvss | normalize_pfctl_s > $states + for state_regexp in \ + "all tcp 64:ff9b::c000:202\[1234\] <- 2001:db8::2\[[0-9]+\] .* 5:4 pkts,.* rule 3 .*creatorid"\ + "all tcp 192.0.2.1:[0-9]+ \(64:ff9b::c000:202\[1234\]\) -> 192.0.2.2:1234 \(2001:db8::2\[[0-9]+\]\) .* 5:4 pkts,.* rule 4 .*creatorid"\ + ; do + grep -qE "${state_regexp}" $states || atf_fail "State not found for '${state_regexp}'" + done + [ $(cat $states | grep tcp | wc -l) -eq 2 ] || atf_fail "Not exactly 2 states found!" +} + +tcp_out_floating_cleanup() { pft_cleanup } @@ -260,7 +368,7 @@ udp_in_body() # Sanity check & delay for nc startup atf_check -s exit:0 -o ignore \ - ping6 -c 1 64:ff9b::192.0.2.2 + ping6 -c 3 64:ff9b::192.0.2.2 rcv=$(echo bar | nc -w 3 -6 -u 64:ff9b::c000:202 1234) if [ "${rcv}" != "foo" ]; @@ -290,7 +398,7 @@ udp_out_body() # Sanity check & delay for nc startup atf_check -s exit:0 -o ignore \ - ping6 -c 1 64:ff9b::192.0.2.2 + ping6 -c 3 64:ff9b::192.0.2.2 rcv=$(echo bar | nc -w 3 -6 -u 64:ff9b::c000:202 1234) if [ "${rcv}" != "foo" ]; @@ -323,7 +431,7 @@ sctp_in_body() # Sanity check & delay for nc startup atf_check -s exit:0 -o ignore \ - ping6 -c 1 64:ff9b::192.0.2.2 + ping6 -c 3 64:ff9b::192.0.2.2 rcv=$(echo bar | nc --sctp -w 3 -6 64:ff9b::c000:202 1234) if [ "${rcv}" != "foo" ]; @@ -356,7 +464,7 @@ sctp_out_body() # Sanity check & delay for nc startup atf_check -s exit:0 -o ignore \ - ping6 -c 1 64:ff9b::192.0.2.2 + ping6 -c 3 64:ff9b::192.0.2.2 rcv=$(echo bar | nc --sctp -w 3 -6 64:ff9b::c000:202 1234) if [ "${rcv}" != "foo" ]; @@ -433,7 +541,9 @@ no_v4_body() jexec rtr pfctl -e pft_set_rules rtr \ - "pass in on ${epair}b inet6 from any to 64:ff9b::/96 af-to inet from (${epair_link}a)" + "block" \ + "pass inet6 proto icmp6 icmp6-type { neighbrsol, neighbradv }" \ + "pass in on ${epair}b inet6 from any to 64:ff9b::/96 af-to inet from (${epair_link}a)" \ atf_check -s exit:2 -o ignore \ ping6 -c 3 64:ff9b::192.0.2.2 @@ -484,7 +594,9 @@ range_body() pft_set_rules rtr \ "set reassemble yes" \ "set state-policy if-bound" \ - "pass in on ${epair}b inet6 from any to 64:ff9b::/96 af-to inet from 192.0.2.2/31 round-robin" + "block" \ + "pass inet6 proto icmp6 icmp6-type { neighbrsol, neighbradv }" \ + "pass in on ${epair}b inet6 from any to 64:ff9b::/96 af-to inet from 192.0.2.2/31 round-robin" \ # Use pf to count sources jexec dst pfctl -e @@ -545,6 +657,8 @@ pool_body() pft_set_rules rtr \ "set reassemble yes" \ "set state-policy if-bound" \ + "block" \ + "pass inet6 proto icmp6 icmp6-type { neighbrsol, neighbradv }" \ "pass in on ${epair}b inet6 from any to 64:ff9b::/96 af-to inet from { 192.0.2.1, 192.0.2.3, 192.0.2.4 } round-robin" # Use pf to count sources @@ -642,6 +756,8 @@ table_range_body() "set reassemble yes" \ "set state-policy if-bound" \ "table <wanaddrs> { 192.0.2.2/31 }" \ + "block" \ + "pass inet6 proto icmp6 icmp6-type { neighbrsol, neighbradv }" \ "pass in on ${epair}b inet6 from any to 64:ff9b::/96 af-to inet from <wanaddrs> round-robin" # Use pf to count sources @@ -699,6 +815,8 @@ table_common_body() "set reassemble yes" \ "set state-policy if-bound" \ "table <wanaddrs> { 192.0.2.1, 192.0.2.3, 192.0.2.4 }" \ + "block" \ + "pass inet6 proto icmp6 icmp6-type { neighbrsol, neighbradv }" \ "pass in on ${epair}b inet6 from any to 64:ff9b::/96 af-to inet from <wanaddrs> ${pool_type}" # Use pf to count sources @@ -798,6 +916,8 @@ dummynet_body() pft_set_rules rtr \ "set reassemble yes" \ "set state-policy if-bound" \ + "block" \ + "pass inet6 proto icmp6 icmp6-type { neighbrsol, neighbradv }" \ "pass in on ${epair}b inet6 from any to 64:ff9b::/96 dnpipe 1 af-to inet from (${epair_link}a)" # The ping request will pass, but take 1.2 seconds (.6 in, .6 out) @@ -860,6 +980,8 @@ gateway6_body() pft_set_rules rtr \ "set reassemble yes" \ "set state-policy if-bound" \ + "block" \ + "pass inet6 proto icmp6 icmp6-type { neighbrsol, neighbradv }" \ "pass in on ${epair_lan_link}b inet6 from any to 64:ff9b::/96 af-to inet from (${epair_link}a)" # One ping @@ -912,6 +1034,8 @@ route_to_body() pft_set_rules rtr \ "set reassemble yes" \ "set state-policy if-bound" \ + "block" \ + "pass inet6 proto icmp6 icmp6-type { neighbrsol, neighbradv }" \ "pass in on ${epair}b route-to (${epair_link}a 192.0.2.2) inet6 from any to 64:ff9b::/96 af-to inet from (${epair_link}a)" atf_check -s exit:0 -o ignore \ @@ -965,6 +1089,8 @@ reply_to_body() pft_set_rules rtr \ "set reassemble yes" \ "set state-policy if-bound" \ + "block" \ + "pass inet6 proto icmp6 icmp6-type { neighbrsol, neighbradv }" \ "pass in on ${epair}b reply-to (${epair}b 2001:db8::2) inet6 from any to 64:ff9b::/96 af-to inet from 192.0.2.1" atf_check -s exit:0 -o ignore \ @@ -1024,6 +1150,8 @@ v6_gateway_body() pft_set_rules rtr \ "set reassemble yes" \ "set state-policy if-bound" \ + "block" \ + "pass inet6 proto icmp6 icmp6-type { neighbrsol, neighbradv }" \ "pass in on ${epair_lan}b inet6 from any to 64:ff9b::/96 af-to inet from (${epair_wan_one}a)" atf_check -s exit:0 -o ignore \ @@ -1043,8 +1171,10 @@ atf_init_test_cases() atf_add_test_case "icmp_echo_out" atf_add_test_case "fragmentation_in" atf_add_test_case "fragmentation_out" - atf_add_test_case "tcp_in" - atf_add_test_case "tcp_out" + atf_add_test_case "tcp_in_if_bound" + atf_add_test_case "tcp_out_if_bound" + atf_add_test_case "tcp_in_floating" + atf_add_test_case "tcp_out_floating" atf_add_test_case "udp_in" atf_add_test_case "udp_out" atf_add_test_case "sctp_in" diff --git a/tests/sys/netpfil/pf/route_to.sh b/tests/sys/netpfil/pf/route_to.sh index fd1653cce311..765403dcb79c 100644 --- a/tests/sys/netpfil/pf/route_to.sh +++ b/tests/sys/netpfil/pf/route_to.sh @@ -865,6 +865,7 @@ empty_pool_head() { atf_set descr 'Route-to with empty pool' atf_set require.user root + atf_set require.progs python3 scapy } empty_pool_body() @@ -899,6 +900,7 @@ table_loop_head() { atf_set descr 'Check that iterating over tables poperly loops' atf_set require.user root + atf_set require.progs python3 scapy } table_loop_body() diff --git a/tests/sys/netpfil/pf/sctp.py b/tests/sys/netpfil/pf/sctp.py index da42ce527195..f492f26b63a1 100644 --- a/tests/sys/netpfil/pf/sctp.py +++ b/tests/sys/netpfil/pf/sctp.py @@ -271,6 +271,9 @@ class TestSCTP(VnetTestTemplate): "pass inet proto sctp to 192.0.2.0/24", "pass on lo"]) + # Give the server some time to come up + time.sleep(3) + # Sanity check, we can communicate with the primary address. client = SCTPClient("192.0.2.3", 1234) client.send(b"hello", 0) @@ -309,6 +312,9 @@ class TestSCTP(VnetTestTemplate): "pass on lo", "pass inet proto sctp from 192.0.2.0/24"]) + # Give the server some time to come up + time.sleep(3) + # Sanity check, we can communicate with the primary address. client = SCTPClient("192.0.2.3", 1234, "192.0.2.1") client.send(b"hello", 0) @@ -379,6 +385,9 @@ class TestSCTP(VnetTestTemplate): "pass on lo", "pass inet proto sctp to 192.0.2.0/24"]) + # Give the server some time to come up + time.sleep(3) + # Sanity check, we can communicate with the primary address. client = SCTPClient("192.0.2.3", 1234) client.send(b"hello", 0) @@ -410,6 +419,9 @@ class TestSCTP(VnetTestTemplate): "pass on lo", "pass inet proto sctp to 192.0.2.0/24"]) + # Give the server some time to come up + time.sleep(3) + # Sanity check, we can communicate with the primary address. client = SCTPClient("192.0.2.3", 1234) client.send(b"hello", 0) @@ -440,6 +452,9 @@ class TestSCTP(VnetTestTemplate): "pass on lo", "pass inet proto sctp to 192.0.2.0/24"]) + # Give the server some time to come up + time.sleep(3) + # Set up a connection, which will try to create states for all addresses # we have assigned client = SCTPClient("192.0.2.3", 1234) @@ -464,6 +479,9 @@ class TestSCTP(VnetTestTemplate): "pass inet proto sctp to 192.0.2.3", "pass on lo"]) + # Give the server some time to come up + time.sleep(3) + # Sanity check, we can communicate with the primary address. client = SCTPClient("192.0.2.3", 1234) client.send(b"hello", 0) @@ -502,6 +520,9 @@ class TestSCTP(VnetTestTemplate): "pass inet proto sctp to 192.0.2.3 keep state (allow-related)", "pass on lo"]) + # Give the server some time to come up + time.sleep(3) + # Sanity check, we can communicate with the primary address. client = SCTPClient("192.0.2.3", 1234) client.send(b"hello", 0) @@ -558,6 +579,9 @@ class TestSCTPv6(VnetTestTemplate): "pass on lo", "pass inet6 proto sctp to 2001:db8::0/64"]) + # Give the server some time to come up + time.sleep(3) + # Sanity check, we can communicate with the primary address. client = SCTPClient("2001:db8::3", 1234) client.send(b"hello", 0) @@ -596,6 +620,9 @@ class TestSCTPv6(VnetTestTemplate): "pass on lo", "pass inet6 proto sctp from 2001:db8::/64"]) + # Give the server some time to come up + time.sleep(3) + # Sanity check, we can communicate with the primary address. client = SCTPClient("2001:db8::3", 1234, "2001:db8::1") client.send(b"hello", 0) @@ -665,6 +692,9 @@ class TestSCTPv6(VnetTestTemplate): "pass on lo", "pass inet6 proto sctp to 2001:db8::0/64"]) + # Give the server some time to come up + time.sleep(3) + # Sanity check, we can communicate with the primary address. client = SCTPClient("2001:db8::3", 1234) client.send(b"hello", 0) @@ -696,6 +726,9 @@ class TestSCTPv6(VnetTestTemplate): "pass on lo", "pass inet6 proto sctp to 2001:db8::0/64"]) + # Give the server some time to come up + time.sleep(3) + # Sanity check, we can communicate with the primary address. client = SCTPClient("2001:db8::3", 1234) client.send(b"hello", 0) diff --git a/tests/sys/netpfil/pf/src_track.sh b/tests/sys/netpfil/pf/src_track.sh index f4031e9dd8ad..ae60a5df809b 100755 --- a/tests/sys/netpfil/pf/src_track.sh +++ b/tests/sys/netpfil/pf/src_track.sh @@ -508,6 +508,7 @@ mixed_af_head() { atf_set descr 'Test mixed address family source tracking' atf_set require.user root + atf_set require.progs python3 scapy } mixed_af_body() @@ -522,6 +523,8 @@ mixed_af_body() pft_set_rules router \ "set reassemble yes" \ "set state-policy if-bound" \ + "block" \ + "pass inet6 proto icmp6 icmp6-type { neighbrsol, neighbradv }" \ "pass in on ${epair_tester}b \ route-to { (${epair_server1}a ${net_server1_4_host_server}) \ } sticky-address \ diff --git a/tests/sys/netpfil/pf/table.sh b/tests/sys/netpfil/pf/table.sh index 5e5fccdaca20..c773518e95e4 100644 --- a/tests/sys/netpfil/pf/table.sh +++ b/tests/sys/netpfil/pf/table.sh @@ -610,6 +610,47 @@ flush_cleanup() pft_cleanup } +atf_test_case "large" "cleanup" +large_head() +{ + atf_set descr 'Test loading a large list of addresses' + atf_set require.user root +} + +large_body() +{ + pft_init + pwd=$(pwd) + + vnet_mkjail alcatraz + + for i in `seq 1 255`; do + for j in `seq 1 255`; do + echo "1.2.${i}.${j}" >> ${pwd}/foo.lst + done + done + expected=$(wc -l foo.lst | awk '{ print $1; }') + + jexec alcatraz pfctl -e + pft_set_rules alcatraz \ + "table <foo>" \ + "pass in from <foo>" \ + "pass" + + atf_check -s exit:0 \ + -e match:"${expected}/${expected} addresses added." \ + jexec alcatraz pfctl -t foo -T add -f ${pwd}/foo.lst + actual=$(jexec alcatraz pfctl -t foo -T show | wc -l | awk '{ print $1; }') + if [[ $actual -ne $expected ]]; then + atf_fail "Unexpected number of table entries $expected $acual" + fi +} + +large_cleanup() +{ + pft_cleanup +} + atf_init_test_cases() { atf_add_test_case "v4_counters" @@ -625,4 +666,5 @@ atf_init_test_cases() atf_add_test_case "precreate" atf_add_test_case "anchor" atf_add_test_case "flush" + atf_add_test_case "large" } |