aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/sys/cddl/zfs/tests/zfsd/Makefile2
-rw-r--r--tests/sys/cddl/zfs/tests/zfsd/zfsd_offline_001_neg.ksh64
-rw-r--r--tests/sys/cddl/zfs/tests/zfsd/zfsd_offline_002_neg.ksh66
-rwxr-xr-xtests/sys/cddl/zfs/tests/zfsd/zfsd_test.sh60
-rw-r--r--tests/sys/fs/fusefs/pre-init.cc72
-rw-r--r--tests/sys/kern/Makefile2
-rw-r--r--tests/sys/kern/copy_file_range.c231
-rw-r--r--tests/sys/kern/ptrace_test.c2
-rw-r--r--tests/sys/net/Makefile1
-rwxr-xr-xtests/sys/net/if_bridge_test.sh282
-rw-r--r--tests/sys/net/if_gif.sh154
-rw-r--r--tests/sys/net/if_ovpn/if_ovpn.sh76
-rw-r--r--tests/sys/netpfil/pf/Makefile1
-rw-r--r--tests/sys/netpfil/pf/frag4.py72
-rw-r--r--tests/sys/netpfil/pf/nat.sh1
-rw-r--r--tests/sys/netpfil/pf/nat64.py34
-rw-r--r--tests/sys/netpfil/pf/nat64.sh182
-rw-r--r--tests/sys/netpfil/pf/route_to.sh2
-rw-r--r--tests/sys/netpfil/pf/sctp.py33
-rwxr-xr-xtests/sys/netpfil/pf/src_track.sh3
-rw-r--r--tests/sys/netpfil/pf/table.sh42
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"
}