diff options
Diffstat (limited to 'tests')
52 files changed, 1455 insertions, 232 deletions
diff --git a/tests/atf_python/sys/net/vnet.py b/tests/atf_python/sys/net/vnet.py index 7afb5c721bf3..c96eb5d671fc 100644 --- a/tests/atf_python/sys/net/vnet.py +++ b/tests/atf_python/sys/net/vnet.py @@ -103,6 +103,7 @@ class VnetInterface(object): if1 = cls(alias_name, name) ret = [if1] if name.startswith("epair"): + run_cmd("/sbin/ifconfig {} -txcsum -txcsum6".format(name)) if2 = cls(alias_name, name[:-1] + "b") if1.epairb = if2 ret.append(if2); diff --git a/tests/ci/Makefile b/tests/ci/Makefile index bc45c6acdfb4..30ca34a810be 100644 --- a/tests/ci/Makefile +++ b/tests/ci/Makefile @@ -41,6 +41,11 @@ TARGET_ARCH= ${TARGET} .endif IMAKE= ${MAKE} TARGET=${TARGET} TARGET_ARCH=${TARGET_ARCH} +.if !defined(CIENV) || empty(CIENV) +CIENV= local +LOG_TARGET= > ${.CURDIR}/_.${TARGET_ARCH}.${.TARGET} 2>&1 || (echo "${.TARGET} failed, check _.${TARGET_ARCH}.${.TARGET} for details" ; false) +.endif + .if defined(CROSS_TOOLCHAIN) || !empty(CROSS_TOOLCHAIN) CROSS_TOOLCHAIN_PARAM= "CROSS_TOOLCHAIN=${CROSS_TOOLCHAIN}" .endif @@ -170,17 +175,14 @@ ci-buildworld: .PHONY @echo "Building world for ${TARGET_ARCH}" ${IMAKE} -j${PARALLEL_JOBS} -C ${WORLDDIR} ${METAMODE} \ ${CROSS_TOOLCHAIN_PARAM} __MAKE_CONF=${MAKECONF} SRCCONF=${SRCCONF} \ - ${EXTRA_MAKE_FLAGS} buildworld > ${.CURDIR}/_.${TARGET_ARCH}.${.TARGET} 2>&1 || \ - (echo "${.TARGET} failed, check _.${TARGET_ARCH}.${.TARGET} for details" ; false) - + ${EXTRA_MAKE_FLAGS} buildworld ${LOG_TARGET} ci-buildkernel: ci-buildworld-${TARGET_ARCH:tl} .PHONY @echo "Building kernel for ${TARGET_ARCH}" ${IMAKE} -j${PARALLEL_JOBS} -C ${WORLDDIR} ${METAMODE} \ ${CROSS_TOOLCHAIN_PARAM} __MAKE_CONF=${MAKECONF} SRCCONF=${SRCCONF} \ ${EXTRA_MAKE_FLAGS} KERNCONF=${KERNCONF} \ - buildkernel > ${.CURDIR}/_.${TARGET_ARCH}.${.TARGET} 2>&1 || \ - (echo "${.TARGET} failed, check _.${TARGET_ARCH}.${.TARGET} for details" ; false) + buildkernel ${LOG_TARGET} ci-buildimage: ${QEMUTGT} ci-buildkernel-${TARGET_ARCH:tl} .PHONY @echo "Building ci image for ${TARGET_ARCH}" @@ -190,9 +192,7 @@ ci-buildimage: ${QEMUTGT} ci-buildkernel-${TARGET_ARCH:tl} .PHONY ${RELEASEDIR}/scripts/mk-vmimage.sh \ -C ${RELEASEDIR}/tools/vmimage.subr -d ${.OBJDIR}/${.TARGET} -F ${VMFS} \ -i ${.OBJDIR}/ci.img -s ${VMSIZE} -f ${FORMAT} \ - -S ${WORLDDIR} -o ${.OBJDIR}/${CIIMAGE} -c ${CICONF} \ - > ${.CURDIR}/_.${TARGET_ARCH}.${.TARGET} 2>&1 || \ - (echo "${.TARGET} failed, check _.${TARGET_ARCH}.${.TARGET} for details" ; false) + -S ${WORLDDIR} -o ${.OBJDIR}/${CIIMAGE} -c ${CICONF} ${LOG_TARGET} touch ${.TARGET} ci-set-smoke-var: .PHONY diff --git a/tests/ci/tools/ci.conf b/tests/ci/tools/ci.conf index 1d2921ab75f3..2302fc479a47 100644 --- a/tests/ci/tools/ci.conf +++ b/tests/ci/tools/ci.conf @@ -119,7 +119,6 @@ fdesc /dev/fd fdescfs rw 0 0 EOF mkdir -p ${DESTDIR}/usr/local/etc/rc.d cp -p ${scriptdir}/../../tests/ci/tools/freebsdci ${DESTDIR}/usr/local/etc/rc.d/ - touch ${DESTDIR}/firstboot return 0 } diff --git a/tests/sys/aio/Makefile b/tests/sys/aio/Makefile index 5cddb28c27a6..578d16b7bf32 100644 --- a/tests/sys/aio/Makefile +++ b/tests/sys/aio/Makefile @@ -2,6 +2,7 @@ TESTSDIR= ${TESTSBASE}/sys/aio ATF_TESTS_C+= aio_test ATF_TESTS_C+= lio_test +TEST_METADATA+= required_kmods="aio" TEST_METADATA.aio_test+= timeout="30" TEST_METADATA.lio_test+= timeout="10" # Some lio_test testcases involve system resource limitations, so cannot run concurrently diff --git a/tests/sys/aio/aio_kqueue_test.c b/tests/sys/aio/aio_kqueue_test.c index 5e5cb40d0752..43a7ebf91f96 100644 --- a/tests/sys/aio/aio_kqueue_test.c +++ b/tests/sys/aio/aio_kqueue_test.c @@ -45,7 +45,6 @@ #include <string.h> #include <unistd.h> -#include "freebsd_test_suite/macros.h" #include "local.h" #define PATH_TEMPLATE "aio.XXXXXXXXXX" @@ -70,7 +69,6 @@ main (int argc, char *argv[]) int tmp_file = 0; int i, j; - PLAIN_REQUIRE_KERNEL_MODULE("aio", 0); PLAIN_REQUIRE_UNSAFE_AIO(0); max_queue_per_proc_size = sizeof(max_queue_per_proc); diff --git a/tests/sys/aio/aio_test.c b/tests/sys/aio/aio_test.c index 64939825ec66..b9f8e7062203 100644 --- a/tests/sys/aio/aio_test.c +++ b/tests/sys/aio/aio_test.c @@ -63,7 +63,6 @@ #include <atf-c.h> -#include "freebsd_test_suite/macros.h" #include "local.h" /* @@ -452,7 +451,6 @@ aio_file_test(completion comp, struct sigevent *sev, bool vectored) struct aio_context ac; int fd; - ATF_REQUIRE_KERNEL_MODULE("aio"); ATF_REQUIRE_UNSAFE_AIO(); fd = open(FILE_PATHNAME, O_RDWR | O_CREAT, 0600); @@ -514,7 +512,6 @@ aio_fifo_test(completion comp, struct sigevent *sev) int error, read_fd = -1, write_fd = -1; struct aio_context ac; - ATF_REQUIRE_KERNEL_MODULE("aio"); ATF_REQUIRE_UNSAFE_AIO(); ATF_REQUIRE_MSG(mkfifo(FIFO_PATHNAME, 0600) != -1, @@ -588,8 +585,6 @@ aio_unix_socketpair_test(completion comp, struct sigevent *sev, bool vectored) struct rusage ru_before, ru_after; int sockets[2]; - ATF_REQUIRE_KERNEL_MODULE("aio"); - ATF_REQUIRE_MSG(socketpair(PF_UNIX, SOCK_STREAM, 0, sockets) != -1, "socketpair failed: %s", strerror(errno)); @@ -662,7 +657,6 @@ aio_pty_test(completion comp, struct sigevent *sev) struct termios ts; int error; - ATF_REQUIRE_KERNEL_MODULE("aio"); ATF_REQUIRE_UNSAFE_AIO(); ATF_REQUIRE_MSG(openpty(&read_fd, &write_fd, NULL, NULL, NULL) == 0, @@ -732,7 +726,6 @@ aio_pipe_test(completion comp, struct sigevent *sev) struct aio_context ac; int pipes[2]; - ATF_REQUIRE_KERNEL_MODULE("aio"); ATF_REQUIRE_UNSAFE_AIO(); ATF_REQUIRE_MSG(pipe(pipes) != -1, @@ -793,8 +786,6 @@ aio_md_setup(void) struct md_ioctl mdio; char buf[80]; - ATF_REQUIRE_KERNEL_MODULE("aio"); - mdctl_fd = open("/dev/" MDCTL_NAME, O_RDWR, 0); ATF_REQUIRE_MSG(mdctl_fd != -1, "opening /dev/%s failed: %s", MDCTL_NAME, strerror(errno)); @@ -985,9 +976,6 @@ aio_zvol_setup(const char *unique) char zvol_name[160]; char devname[160]; - ATF_REQUIRE_KERNEL_MODULE("aio"); - ATF_REQUIRE_KERNEL_MODULE("zfs"); - pid = getpid(); snprintf(vdev_name, sizeof(vdev_name), "%s", ZVOL_VDEV_PATHNAME); snprintf(pool_name, sizeof(pool_name), "%s_%s.%d", POOL_NAME, unique, @@ -1057,7 +1045,6 @@ ATF_TC_BODY(aio_large_read_test, tc) int clamped; #endif - ATF_REQUIRE_KERNEL_MODULE("aio"); ATF_REQUIRE_UNSAFE_AIO(); #ifdef __LP64__ @@ -1133,7 +1120,6 @@ ATF_TC_BODY(aio_socket_two_reads, tc) int s[2]; char c; - ATF_REQUIRE_KERNEL_MODULE("aio"); #if __FreeBSD_version < 1100101 aft_tc_skip("kernel version %d is too old (%d required)", __FreeBSD_version, 1100101); @@ -1187,8 +1173,6 @@ aio_socket_blocking_short_write_test(bool vectored) socklen_t len; int s[2]; - ATF_REQUIRE_KERNEL_MODULE("aio"); - ATF_REQUIRE(socketpair(PF_UNIX, SOCK_STREAM, 0, s) != -1); len = sizeof(sb_size); @@ -1356,8 +1340,6 @@ ATF_TC_BODY(aio_socket_short_write_cancel, tc) socklen_t len; int s[2]; - ATF_REQUIRE_KERNEL_MODULE("aio"); - ATF_REQUIRE(socketpair(PF_UNIX, SOCK_STREAM, 0, s) != -1); len = sizeof(sb_size); @@ -1423,8 +1405,6 @@ ATF_TC_BODY(aio_socket_shutdown, tc) size_t bsz; int error, s[2]; - ATF_REQUIRE_KERNEL_MODULE("aio"); - ATF_REQUIRE(socketpair(PF_UNIX, SOCK_STREAM, 0, s) != -1); bsz = 1024; @@ -1485,7 +1465,6 @@ ATF_TC_BODY(aio_fsync_errors, tc) int fd; struct aiocb iocb; - ATF_REQUIRE_KERNEL_MODULE("aio"); ATF_REQUIRE_UNSAFE_AIO(); fd = open(FILE_PATHNAME, O_RDWR | O_CREAT, 0600); @@ -1529,7 +1508,6 @@ aio_fsync_test(int op) unsigned i; int fd; - ATF_REQUIRE_KERNEL_MODULE("aio"); ATF_REQUIRE_UNSAFE_AIO(); fd = open(FILE_PATHNAME, O_RDWR | O_CREAT, 0600); @@ -1618,7 +1596,6 @@ ATF_TC_BODY(aio_writev_dos_iov_len, tc) ssize_t r; int fd; - ATF_REQUIRE_KERNEL_MODULE("aio"); ATF_REQUIRE_UNSAFE_AIO(); fd = open("testfile", O_RDWR | O_CREAT, 0600); @@ -1656,7 +1633,6 @@ ATF_TC_BODY(aio_writev_dos_iovcnt, tc) ssize_t len; int fd; - ATF_REQUIRE_KERNEL_MODULE("aio"); ATF_REQUIRE_UNSAFE_AIO(); fd = open("testfile", O_RDWR | O_CREAT, 0600); @@ -1693,7 +1669,6 @@ ATF_TC_BODY(aio_writev_efault, tc) long seed; int fd; - ATF_REQUIRE_KERNEL_MODULE("aio"); ATF_REQUIRE_UNSAFE_AIO(); fd = aio_md_setup(); @@ -1728,7 +1703,6 @@ ATF_TC_BODY(aio_writev_empty_file_poll, tc) struct aiocb aio; int fd; - ATF_REQUIRE_KERNEL_MODULE("aio"); ATF_REQUIRE_UNSAFE_AIO(); fd = open("testfile", O_RDWR | O_CREAT, 0600); @@ -1751,7 +1725,6 @@ ATF_TC_BODY(aio_writev_empty_file_signal, tc) struct aiocb aio; int fd; - ATF_REQUIRE_KERNEL_MODULE("aio"); ATF_REQUIRE_UNSAFE_AIO(); fd = open("testfile", O_RDWR | O_CREAT, 0600); @@ -1781,8 +1754,6 @@ ATF_TC_BODY(ev_oneshot, tc) struct kevent events[1]; struct timespec timeout; - ATF_REQUIRE_KERNEL_MODULE("aio"); - kq = kqueue(); ATF_REQUIRE(kq >= 0); @@ -1844,7 +1815,6 @@ ATF_TC_BODY(vectored_big_iovcnt, tc) int fd, i; ssize_t sysctl_len = sizeof(max_buf_aio); - ATF_REQUIRE_KERNEL_MODULE("aio"); ATF_REQUIRE_UNSAFE_AIO(); if (sysctlbyname(oid, &max_buf_aio, &sysctl_len, NULL, 0) == -1) @@ -1946,6 +1916,7 @@ ATF_TC_HEAD(vectored_unaligned, tc) "Vectored AIO should still work even if the iov contains elements " "that aren't a multiple of the sector size."); atf_tc_set_md_var(tc, "require.user", "root"); + atf_tc_set_md_var(tc, "require.kmods", "zfs"); } ATF_TC_BODY(vectored_unaligned, tc) { @@ -1958,7 +1929,6 @@ ATF_TC_BODY(vectored_unaligned, tc) if (atf_tc_get_config_var_as_bool_wd(tc, "ci", false)) atf_tc_skip("https://bugs.freebsd.org/258766"); - ATF_REQUIRE_KERNEL_MODULE("aio"); ATF_REQUIRE_UNSAFE_AIO(); /* @@ -2045,6 +2015,7 @@ ATF_TC_WITH_CLEANUP(vectored_zvol_poll); ATF_TC_HEAD(vectored_zvol_poll, tc) { atf_tc_set_md_var(tc, "require.user", "root"); + atf_tc_set_md_var(tc, "require.kmods", "zfs"); } ATF_TC_BODY(vectored_zvol_poll, tc) { diff --git a/tests/sys/aio/lio_kqueue_test.c b/tests/sys/aio/lio_kqueue_test.c index f891ab95f3ca..6ac99af9254c 100644 --- a/tests/sys/aio/lio_kqueue_test.c +++ b/tests/sys/aio/lio_kqueue_test.c @@ -40,7 +40,6 @@ #include <string.h> #include <unistd.h> -#include "freebsd_test_suite/macros.h" #include "local.h" #define PATH_TEMPLATE "aio.XXXXXXXXXX" @@ -68,7 +67,6 @@ main(int argc, char *argv[]) char *file, pathname[sizeof(PATH_TEMPLATE)]; int tmp_file = 0, failed = 0; - PLAIN_REQUIRE_KERNEL_MODULE("aio", 0); PLAIN_REQUIRE_UNSAFE_AIO(0); max_queue_per_proc_size = sizeof(max_queue_per_proc); diff --git a/tests/sys/aio/lio_test.c b/tests/sys/aio/lio_test.c index a59f9bd518bc..546cd6c5b790 100644 --- a/tests/sys/aio/lio_test.c +++ b/tests/sys/aio/lio_test.c @@ -38,7 +38,6 @@ #include <atf-c.h> #include "local.h" -#include "freebsd_test_suite/macros.h" static sem_t completions; @@ -71,7 +70,6 @@ ATF_TC_BODY(lio_listio_eagain_kevent, tc) const char *path="tempfile"; void *udata[2]; - ATF_REQUIRE_KERNEL_MODULE("aio"); ATF_REQUIRE_UNSAFE_AIO(); max_queue_per_proc_size = sizeof(max_queue_per_proc); diff --git a/tests/sys/common/vnet.subr b/tests/sys/common/vnet.subr index bd98b02da33f..0a32e6caf813 100644 --- a/tests/sys/common/vnet.subr +++ b/tests/sys/common/vnet.subr @@ -42,6 +42,11 @@ vnet_init() vnet_mkepair() { ifname=$(ifconfig epair create) + # When transmit checksum offloading is enabled, if_epair does not + # compute checksums, it just marks packets that this computation still + # needs to be done. However, some test cases verify the checksum. + # Therefore disable this for IPv4 and IPv6. + ifconfig ${ifname} -txcsum -txcsum6 list_interface $ifname list_interface ${ifname%a}b echo ${ifname%a} diff --git a/tests/sys/fs/fusefs/last_local_modify.cc b/tests/sys/fs/fusefs/last_local_modify.cc index 5fcd3c36c892..6b8c19f1efc7 100644 --- a/tests/sys/fs/fusefs/last_local_modify.cc +++ b/tests/sys/fs/fusefs/last_local_modify.cc @@ -174,7 +174,15 @@ static void* write_th(void* arg) { if (sem) sem_wait(sem); - fd = open("mountpoint/some_file.txt", O_RDWR); + /* + * Open the file in direct mode. + * The race condition affects both direct and non-direct writes, and + * they have separate code paths. However, in the non-direct case, the + * kernel updates last_local_modify _before_ sending FUSE_WRITE to the + * server. So the technique that this test program uses to invoke the + * race cannot work. Therefore, test with O_DIRECT only. + */ + fd = open("mountpoint/some_file.txt", O_RDWR | O_DIRECT); if (fd < 0) return (void*)(intptr_t)errno; @@ -332,7 +340,7 @@ TEST_P(LastLocalModify, lookup) /* Wait for FUSE_SETATTR to be sent */ sem_wait(&sem); - /* Lookup again, which will race with setattr */ + /* Lookup again, which will race with the mutator */ ASSERT_EQ(0, stat(FULLPATH, &sb)) << strerror(errno); ASSERT_EQ((off_t)newsize, sb.st_size); diff --git a/tests/sys/fs/fusefs/mockfs.cc b/tests/sys/fs/fusefs/mockfs.cc index 65cdc3919652..e8081dea9604 100644 --- a/tests/sys/fs/fusefs/mockfs.cc +++ b/tests/sys/fs/fusefs/mockfs.cc @@ -472,7 +472,7 @@ MockFS::MockFS(int max_read, int max_readahead, bool allow_other, sprintf(fdstr, "%d", m_fuse_fd); build_iovec(&iov, &iovlen, "fd", fdstr, -1); if (m_maxread > 0) { - char val[10]; + char val[12]; snprintf(val, sizeof(val), "%d", m_maxread); build_iovec(&iov, &iovlen, "max_read=", &val, -1); diff --git a/tests/sys/kern/socket_accf.c b/tests/sys/kern/socket_accf.c index ae6522397cf7..939ca9495689 100644 --- a/tests/sys/kern/socket_accf.c +++ b/tests/sys/kern/socket_accf.c @@ -69,14 +69,8 @@ clientsock(struct sockaddr_in *sin) static void accfon(int l, struct accept_filter_arg *af) { - if (setsockopt(l, SOL_SOCKET, SO_ACCEPTFILTER, af, sizeof(*af)) != 0) { - if (errno == ENOENT) - atf_tc_skip("Accept filter %s not loaded in kernel", - af->af_name); - else - atf_tc_fail("setsockopt(SO_ACCEPTFILTER): %s", - strerror(errno)); + atf_tc_fail("setsockopt(SO_ACCEPTFILTER): %s", strerror(errno)); } } @@ -95,7 +89,11 @@ usend(int s, const void *msg, size_t len) return (rv); } -ATF_TC_WITHOUT_HEAD(data); +ATF_TC(data); +ATF_TC_HEAD(data, tc) +{ + atf_tc_set_md_var(tc, "require.kmods", "accf_data"); +} ATF_TC_BODY(data, tc) { struct accept_filter_arg afa = { @@ -113,7 +111,11 @@ ATF_TC_BODY(data, tc) ATF_REQUIRE((a = accept(l, NULL, 0)) > 0); } -ATF_TC_WITHOUT_HEAD(http); +ATF_TC(http); +ATF_TC_HEAD(http, tc) +{ + atf_tc_set_md_var(tc, "require.kmods", "accf_http"); +} ATF_TC_BODY(http, tc) { struct accept_filter_arg afa = { @@ -152,7 +154,11 @@ ATF_TC_BODY(http, tc) ATF_REQUIRE((a = accept(l, NULL, 0)) > 0); } -ATF_TC_WITHOUT_HEAD(tls); +ATF_TC(tls); +ATF_TC_HEAD(tls, tc) +{ + atf_tc_set_md_var(tc, "require.kmods", "accf_tls"); +} ATF_TC_BODY(tls, tc) { struct accept_filter_arg afa = { @@ -210,7 +216,11 @@ ATF_TC_BODY(tls, tc) } /* Check changing to a different filter. */ -ATF_TC_WITHOUT_HEAD(change); +ATF_TC(change); +ATF_TC_HEAD(change, tc) +{ + atf_tc_set_md_var(tc, "require.kmods", "accf_data accf_http"); +} ATF_TC_BODY(change, tc) { struct accept_filter_arg dfa = { diff --git a/tests/sys/kern/unix_stream.c b/tests/sys/kern/unix_stream.c index bb811f78f620..49d621dc5b0a 100644 --- a/tests/sys/kern/unix_stream.c +++ b/tests/sys/kern/unix_stream.c @@ -467,6 +467,29 @@ ATF_TC_BODY(peershutdown_wakeup_kevent, tc) }); } +ATF_TC_WITHOUT_HEAD(ourshutdown_kevent); +ATF_TC_BODY(ourshutdown_kevent, tc) +{ + struct kevent kev; + int sv[2], kq; + + do_socketpair(sv); + ATF_REQUIRE(kq = kqueue()); + + EV_SET(&kev, sv[1], EVFILT_WRITE, EV_ADD, 0, 0, NULL); + ATF_REQUIRE(kevent(kq, &kev, 1, NULL, 0, NULL) == 0); + + ATF_REQUIRE(shutdown(sv[1], SHUT_WR) == 0); + + ATF_REQUIRE(kevent(kq, NULL, 0, &kev, 1, NULL) == 1); + ATF_REQUIRE(kev.ident == (uintptr_t)sv[1] && + kev.filter == EVFILT_WRITE && + kev.flags == EV_EOF); + + close(sv[0]); + close(sv[1]); +} + ATF_TP_ADD_TCS(tp) { ATF_TP_ADD_TC(tp, getpeereid); @@ -482,6 +505,7 @@ ATF_TP_ADD_TCS(tp) ATF_TP_ADD_TC(tp, peershutdown_wakeup_select); ATF_TP_ADD_TC(tp, peershutdown_wakeup_poll); ATF_TP_ADD_TC(tp, peershutdown_wakeup_kevent); + ATF_TP_ADD_TC(tp, ourshutdown_kevent); return atf_no_error(); } diff --git a/tests/sys/mqueue/mqtest1.c b/tests/sys/mqueue/mqtest1.c index 78acde1122ce..7f4ee74f9e8d 100644 --- a/tests/sys/mqueue/mqtest1.c +++ b/tests/sys/mqueue/mqtest1.c @@ -6,8 +6,6 @@ #include <signal.h> #include <stdio.h> -#include "freebsd_test_suite/macros.h" - #define MQNAME "/mytstqueue1" int @@ -18,8 +16,6 @@ main(void) mqd_t mq; int status; - PLAIN_REQUIRE_KERNEL_MODULE("mqueuefs", 0); - attr.mq_maxmsg = 2; attr.mq_msgsize = 100; mq = mq_open(MQNAME, O_CREAT | O_RDWR | O_EXCL, 0666, &attr); diff --git a/tests/sys/mqueue/mqtest2.c b/tests/sys/mqueue/mqtest2.c index 08d4d9a8003a..efdca42eb37e 100644 --- a/tests/sys/mqueue/mqtest2.c +++ b/tests/sys/mqueue/mqtest2.c @@ -9,8 +9,6 @@ #include <stdlib.h> #include <unistd.h> -#include "freebsd_test_suite/macros.h" - #define MQNAME "/mytstqueue2" #define LOOPS 1000 #define PRIO 10 @@ -29,9 +27,7 @@ main(void) mqd_t mq; int status; pid_t pid; - - PLAIN_REQUIRE_KERNEL_MODULE("mqueuefs", 0); - + mq_unlink(MQNAME); attr.mq_maxmsg = 5; diff --git a/tests/sys/mqueue/mqtest3.c b/tests/sys/mqueue/mqtest3.c index 65b8f4fcc2b9..b2c9155c37ba 100644 --- a/tests/sys/mqueue/mqtest3.c +++ b/tests/sys/mqueue/mqtest3.c @@ -10,8 +10,6 @@ #include <stdlib.h> #include <unistd.h> -#include "freebsd_test_suite/macros.h" - #define MQNAME "/mytstqueue3" #define LOOPS 1000 #define PRIO 10 @@ -32,8 +30,6 @@ main(void) mqd_t mq; pid_t pid; - PLAIN_REQUIRE_KERNEL_MODULE("mqueuefs", 0); - mq_unlink(MQNAME); attr.mq_maxmsg = 5; diff --git a/tests/sys/mqueue/mqtest4.c b/tests/sys/mqueue/mqtest4.c index 99841c670b5c..68648b01a9e4 100644 --- a/tests/sys/mqueue/mqtest4.c +++ b/tests/sys/mqueue/mqtest4.c @@ -11,8 +11,6 @@ #include <stdlib.h> #include <unistd.h> -#include "freebsd_test_suite/macros.h" - #define MQNAME "/mytstqueue4" #define LOOPS 1000 #define PRIO 10 @@ -33,8 +31,6 @@ main(void) int kq, status; pid_t pid; - PLAIN_REQUIRE_KERNEL_MODULE("mqueuefs", 0); - mq_unlink(MQNAME); attr.mq_maxmsg = 5; diff --git a/tests/sys/mqueue/mqtest5.c b/tests/sys/mqueue/mqtest5.c index f48ef1121289..6671839829bf 100644 --- a/tests/sys/mqueue/mqtest5.c +++ b/tests/sys/mqueue/mqtest5.c @@ -11,8 +11,6 @@ #include <stdlib.h> #include <unistd.h> -#include "freebsd_test_suite/macros.h" - #define MQNAME "/mytstqueue5" #define LOOPS 1000 #define PRIO 10 @@ -35,8 +33,6 @@ main(void) mqd_t mq; pid_t pid; - PLAIN_REQUIRE_KERNEL_MODULE("mqueuefs", 0); - mq_unlink(MQNAME); sigemptyset(&set); diff --git a/tests/sys/mqueue/mqueue_test.sh b/tests/sys/mqueue/mqueue_test.sh index 8b3f45159ad9..4f947dc260ed 100644 --- a/tests/sys/mqueue/mqueue_test.sh +++ b/tests/sys/mqueue/mqueue_test.sh @@ -27,7 +27,7 @@ mqtest1_head() { - : + atf_set require.kmods mqueuefs } mqtest1_body() { @@ -36,7 +36,7 @@ mqtest1_body() mqtest2_head() { - : + atf_set require.kmods mqueuefs } mqtest2_body() { @@ -45,7 +45,7 @@ mqtest2_body() mqtest3_head() { - : + atf_set require.kmods mqueuefs } mqtest3_body() { @@ -54,7 +54,7 @@ mqtest3_body() mqtest4_head() { - : + atf_set require.kmods mqueuefs } mqtest4_body() { @@ -63,7 +63,7 @@ mqtest4_body() mqtest5_head() { - : + atf_set require.kmods mqueuefs } mqtest5_body() { @@ -74,7 +74,7 @@ atf_init_test_cases() { atf_add_test_case mqtest1 atf_add_test_case mqtest2 - #atf_add_test_case mqtest3 - #atf_add_test_case mqtest4 + atf_add_test_case mqtest3 + atf_add_test_case mqtest4 atf_add_test_case mqtest5 } diff --git a/tests/sys/net/Makefile b/tests/sys/net/Makefile index 65cc99a3e932..e390c6e8059d 100644 --- a/tests/sys/net/Makefile +++ b/tests/sys/net/Makefile @@ -40,6 +40,7 @@ ${PACKAGE}FILESMODE_stp.py= 0555 MAN= PROGS+= randsleep +PROGS+= transient_tuntap CFLAGS+= -I${.CURDIR:H:H} diff --git a/tests/sys/net/if_bridge_test.sh b/tests/sys/net/if_bridge_test.sh index 0c19903714b1..b3405fd978c8 100755 --- a/tests/sys/net/if_bridge_test.sh +++ b/tests/sys/net/if_bridge_test.sh @@ -586,6 +586,25 @@ gif_body() jexec one ping -c 1 -s 1200 198.51.100.2 atf_check -s exit:0 -o ignore \ jexec one ping -c 1 -s 2000 198.51.100.2 + + # Assigning IP addresses on the gif tunneling interfaces + jexec one sysctl net.link.bridge.member_ifaddrs=1 + atf_check -s exit:0 -o ignore \ + jexec one ifconfig ${gif_one} 192.168.0.224/24 192.168.169.254 + atf_check -s exit:0 -o ignore \ + jexec one ifconfig ${gif_one} inet6 no_dad 2001:db8::1/64 + jexec one ifconfig ${bridge_one} deletem ${gif_one} + atf_check -s exit:0 -o ignore \ + jexec one ifconfig ${bridge_one} addm ${gif_one} + + jexec two sysctl net.link.bridge.member_ifaddrs=0 + atf_check -s exit:0 -o ignore \ + jexec two ifconfig ${gif_two} 192.168.169.254/24 192.168.0.224 + atf_check -s exit:0 -o ignore \ + jexec two ifconfig ${gif_two} inet6 no_dad 2001:db8::2/64 + jexec two ifconfig ${bridge_two} deletem ${gif_two} + atf_check -s exit:0 -o ignore \ + jexec two ifconfig ${bridge_two} addm ${gif_two} } gif_cleanup() diff --git a/tests/sys/net/if_epair.c b/tests/sys/net/if_epair.c index 0817b298d427..5ee4a48aea86 100644 --- a/tests/sys/net/if_epair.c +++ b/tests/sys/net/if_epair.c @@ -44,6 +44,7 @@ ATF_TC(params); ATF_TC_HEAD(params, tc) { atf_tc_set_md_var(tc, "require.user", "root"); + atf_tc_set_md_var(tc, "require.kmods", "if_epair"); } ATF_TC_BODY(params, tc) @@ -51,9 +52,6 @@ ATF_TC_BODY(params, tc) struct ifreq ifr; int s; - kldload("if_epair"); - ATF_REQUIRE_KERNEL_MODULE("if_epair"); - s = socket(AF_INET, SOCK_DGRAM, 0); if (s < 0) atf_tc_fail("Failed to create socket"); diff --git a/tests/sys/net/if_ovpn/if_ovpn.sh b/tests/sys/net/if_ovpn/if_ovpn.sh index 0281e7fc273d..9dafce2242d8 100644 --- a/tests/sys/net/if_ovpn/if_ovpn.sh +++ b/tests/sys/net/if_ovpn/if_ovpn.sh @@ -510,6 +510,7 @@ linklocal_head() linklocal_body() { ovpn_init + ovpn_check_version 2.7.0 l=$(vnet_mkepair) @@ -1399,6 +1400,7 @@ float_head() float_body() { ovpn_init + ovpn_check_version 2.7.0 l=$(vnet_mkepair) diff --git a/tests/sys/net/if_ovpn/if_ovpn_c.c b/tests/sys/net/if_ovpn/if_ovpn_c.c index fa8a9a07fa35..7b558f1975dd 100644 --- a/tests/sys/net/if_ovpn/if_ovpn_c.c +++ b/tests/sys/net/if_ovpn/if_ovpn_c.c @@ -78,6 +78,7 @@ ATF_TC_WITH_CLEANUP(tcp); ATF_TC_HEAD(tcp, tc) { atf_tc_set_md_var(tc, "require.user", "root"); + atf_tc_set_md_var(tc, "require.kmods", "if_ovpn"); } ATF_TC_BODY(tcp, tc) @@ -87,10 +88,6 @@ ATF_TC_BODY(tcp, tc) int ret; nvlist_t *nvl; - /* Ensure the module is loaded. */ - if (kldfind("if_ovpn") == -1 && errno == ENOENT) - atf_tc_skip("if_ovpn not loaded"); - ovpn_fd = socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK, 0); /* Kick off a connect so there's a local address set, which we need for diff --git a/tests/sys/net/if_ovpn/utils.subr b/tests/sys/net/if_ovpn/utils.subr index 0da35119b2bf..fbe7dc98630a 100644 --- a/tests/sys/net/if_ovpn/utils.subr +++ b/tests/sys/net/if_ovpn/utils.subr @@ -40,6 +40,25 @@ ovpn_init() fi } +ovpn_check_version() +{ + expected=$1 + + expected_minor=$(echo $expected | + awk '{ split($1, ver, "\."); print(ver[2]); }') + actual_minor=$(openvpn --version 2>&1 | + awk 'NR == 1 \ + { \ + split($2, ver, "\."); \ + split(ver[2], minor, "_"); \ + print(minor[1]); \ + }') + + if [ ${actual_minor} -lt ${expected_minor} ]; then + atf_skip "OpenVPN version < ${expected}" + fi +} + ovpn_cleanup() { for jail in `cat ovpn_jails.lst | sort -u` diff --git a/tests/sys/net/if_tun_test.sh b/tests/sys/net/if_tun_test.sh index a4ffe66e04ce..f4ce7800272e 100755 --- a/tests/sys/net/if_tun_test.sh +++ b/tests/sys/net/if_tun_test.sh @@ -56,8 +56,30 @@ basic_cleanup() vnet_cleanup } +atf_test_case "transient" "cleanup" +transient_head() +{ + atf_set descr "Test transient tunnel support" + atf_set require.user root +} +transient_body() +{ + vnet_init + vnet_mkjail one + + tun=$(jexec one ifconfig tun create) + atf_check -s exit:0 -o not-empty jexec one ifconfig ${tun} + jexec one $(atf_get_srcdir)/transient_tuntap /dev/${tun} + atf_check -s not-exit:0 -e not-empty jexec one ifconfig ${tun} +} +transient_cleanup() +{ + vnet_cleanup +} + atf_init_test_cases() { atf_add_test_case "235704" atf_add_test_case "basic" + atf_add_test_case "transient" } diff --git a/tests/sys/net/transient_tuntap.c b/tests/sys/net/transient_tuntap.c new file mode 100644 index 000000000000..b0cf43064317 --- /dev/null +++ b/tests/sys/net/transient_tuntap.c @@ -0,0 +1,54 @@ +/*- + * Copyright (c) 2024 Kyle Evans <kevans@FreeBSD.org> + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +/* + * This test simply configures the tunnel as transient and exits. By the time + * we return, the tunnel should be gone because the last reference disappears. + */ + +#include <sys/types.h> +#include <sys/ioctl.h> +#include <net/if_tun.h> +#include <net/if_tap.h> + +#include <assert.h> +#include <err.h> +#include <fcntl.h> +#include <string.h> +#include <unistd.h> + +int +main(int argc, char *argv[]) +{ + unsigned long tunreq; + const char *tundev; + int one = 1, tunfd; + + assert(argc > 1); + tundev = argv[1]; + + tunfd = open(tundev, O_RDWR); + assert(tunfd >= 0); + + /* + * These are technically the same request, but we'll use the technically + * correct one just in case. + */ + if (strstr(tundev, "tun") != NULL) { + tunreq = TUNSTRANSIENT; + } else { + assert(strstr(tundev, "tap") != NULL); + tunreq = TAPSTRANSIENT; + } + + if (ioctl(tunfd, tunreq, &one) == -1) + err(1, "ioctl"); + + /* Final close should destroy the tunnel automagically. */ + close(tunfd); + + return (0); +} diff --git a/tests/sys/netinet/divert.sh b/tests/sys/netinet/divert.sh index d50620d94a09..f521038ba687 100755 --- a/tests/sys/netinet/divert.sh +++ b/tests/sys/netinet/divert.sh @@ -29,19 +29,13 @@ . $(atf_get_srcdir)/../common/vnet.subr -load_divert_module() { - kldstat -q -m ipdivert - if [ $? -ne 0 ]; then - atf_skip "ipdivert module is not loaded" - fi -} - atf_test_case "ipdivert_ip_output_remote_success" "cleanup" ipdivert_ip_output_remote_success_head() { atf_set descr 'Test diverting IPv4 packet to remote destination' atf_set require.user root atf_set require.progs python3 scapy + atf_set require.kmods ipdivert } ipdivert_ip_output_remote_success_body() { @@ -62,7 +56,6 @@ ipdivert_ip_output_remote_success_body() { fi vnet_init - load_divert_module ip4a="192.0.2.5" ip4b="192.0.2.6" @@ -97,6 +90,7 @@ ipdivert_ip_input_local_success_head() { atf_set descr 'Test diverting IPv4 packet to remote destination' atf_set require.user root atf_set require.progs python3 scapy + atf_set require.kmods ipdivert } ipdivert_ip_input_local_success_body() { @@ -117,7 +111,6 @@ ipdivert_ip_input_local_success_body() { fi vnet_init - load_divert_module ip4a="192.0.2.5" ip4b="192.0.2.6" diff --git a/tests/sys/netinet/tcp_md5_getsockopt.c b/tests/sys/netinet/tcp_md5_getsockopt.c index deaa4170caea..e23cfa67185a 100644 --- a/tests/sys/netinet/tcp_md5_getsockopt.c +++ b/tests/sys/netinet/tcp_md5_getsockopt.c @@ -45,9 +45,6 @@ void test_tcp_md5_getsockopt(int); void test_tcp_md5_getsockopt(int v6) { - if (kldfind("tcpmd5.ko") == -1) - atf_tc_skip("Test requires the tcpmd5 kernel module to be loaded"); - struct sockaddr_in *s; struct sockaddr_in6 s6 = { 0 }; struct sockaddr_in s4 = { 0 }; @@ -108,6 +105,7 @@ ATF_TC(tcp_md5_getsockopt_v4); ATF_TC_HEAD(tcp_md5_getsockopt_v4, tc) { atf_tc_set_md_var(tc, "descr", "Test getsockopt for TCP MD5 SIG (IPv4)"); + atf_tc_set_md_var(tc, "require.kmods", "tcpmd5"); } ATF_TC_BODY(tcp_md5_getsockopt_v4, tc) @@ -119,6 +117,7 @@ ATF_TC(tcp_md5_getsockopt_v6); ATF_TC_HEAD(tcp_md5_getsockopt_v6, tc) { atf_tc_set_md_var(tc, "descr", "Test getsockopt for TCP MD5 SIG (IPv6)"); + atf_tc_set_md_var(tc, "require.kmods", "tcpmd5"); } ATF_TC_BODY(tcp_md5_getsockopt_v6, tc) diff --git a/tests/sys/netlink/netlink_socket.c b/tests/sys/netlink/netlink_socket.c index 6dcc894b6695..3c2c5f857591 100644 --- a/tests/sys/netlink/netlink_socket.c +++ b/tests/sys/netlink/netlink_socket.c @@ -116,7 +116,11 @@ fullsocket(void) return (fd); } -ATF_TC_WITHOUT_HEAD(overflow); +ATF_TC(overflow); +ATF_TC_HEAD(overflow, tc) +{ + atf_tc_set_md_var(tc, "require.kmods", "netlink"); +} ATF_TC_BODY(overflow, tc) { char buf[BUFLEN]; @@ -143,7 +147,11 @@ ATF_TC_BODY(overflow, tc) ATF_REQUIRE(timer_done == 0); } -ATF_TC_WITHOUT_HEAD(peek); +ATF_TC(peek); +ATF_TC_HEAD(peek, tc) +{ + atf_tc_set_md_var(tc, "require.kmods", "netlink"); +} ATF_TC_BODY(peek, tc) { char *buf; @@ -185,7 +193,11 @@ cmsg_check(struct msghdr *msg) ATF_REQUIRE((msg->msg_flags & MSG_CTRUNC) == 0); } -ATF_TC_WITHOUT_HEAD(sizes); +ATF_TC(sizes); +ATF_TC_HEAD(sizes, tc) +{ + atf_tc_set_md_var(tc, "require.kmods", "netlink"); +} ATF_TC_BODY(sizes, tc) { #define NLMSG_LARGE 2048 /* XXX: match kernel nl_buf */ @@ -273,7 +285,11 @@ nla_RTA_DST(struct nlattr *start, ssize_t len) * Check that NETLINK_ADD_MEMBERSHIP subscribes us. Add & delete a temporary * route and check if announcements came in. */ -ATF_TC_WITHOUT_HEAD(membership); +ATF_TC(membership); +ATF_TC_HEAD(membership, tc) +{ + atf_tc_set_md_var(tc, "require.kmods", "netlink"); +} ATF_TC_BODY(membership, tc) { struct { @@ -329,9 +345,6 @@ ATF_TC_BODY(membership, tc) ATF_TP_ADD_TCS(tp) { - if (modfind("netlink") == -1) - atf_tc_skip("netlink module not loaded"); - ATF_TP_ADD_TC(tp, overflow); ATF_TP_ADD_TC(tp, peek); ATF_TP_ADD_TC(tp, sizes); diff --git a/tests/sys/netlink/test_snl.c b/tests/sys/netlink/test_snl.c index 040414a96e2c..3990aa0b075d 100644 --- a/tests/sys/netlink/test_snl.c +++ b/tests/sys/netlink/test_snl.c @@ -25,13 +25,6 @@ static const struct snl_hdr_parser *snl_all_route_parsers[] = { &_addr_fbsd_parser, &snl_rtm_addr_parser, &_nh_fbsd_parser, &snl_nhmsg_parser, }; -static void -require_netlink(void) -{ - if (modfind("netlink") == -1) - atf_tc_skip("netlink module not loaded"); -} - ATF_TC(snl_verify_core_parsers); ATF_TC_HEAD(snl_verify_core_parsers, tc) { @@ -60,6 +53,7 @@ ATF_TC(snl_parse_errmsg_capped); ATF_TC_HEAD(snl_parse_errmsg_capped, tc) { atf_tc_set_md_var(tc, "descr", "Tests snl(3) correctly parsing capped errors"); + atf_tc_set_md_var(tc, "require.kmods", "netlink"); } ATF_TC_BODY(snl_parse_errmsg_capped, tc) @@ -67,8 +61,6 @@ ATF_TC_BODY(snl_parse_errmsg_capped, tc) struct snl_state ss; struct snl_writer nw; - require_netlink(); - if (!snl_init(&ss, NETLINK_ROUTE)) atf_tc_fail("snl_init() failed"); @@ -102,6 +94,7 @@ ATF_TC(snl_parse_errmsg_capped_extack); ATF_TC_HEAD(snl_parse_errmsg_capped_extack, tc) { atf_tc_set_md_var(tc, "descr", "Tests snl(3) correctly parsing capped errors with extack"); + atf_tc_set_md_var(tc, "require.kmods", "netlink"); } ATF_TC_BODY(snl_parse_errmsg_capped_extack, tc) @@ -109,8 +102,6 @@ ATF_TC_BODY(snl_parse_errmsg_capped_extack, tc) struct snl_state ss; struct snl_writer nw; - require_netlink(); - if (!snl_init(&ss, NETLINK_ROUTE)) atf_tc_fail("snl_init() failed"); @@ -145,6 +136,7 @@ ATF_TC(snl_parse_errmsg_uncapped_extack); ATF_TC_HEAD(snl_parse_errmsg_uncapped_extack, tc) { atf_tc_set_md_var(tc, "descr", "Tests snl(3) correctly parsing errors with extack"); + atf_tc_set_md_var(tc, "require.kmods", "netlink"); } ATF_TC_BODY(snl_parse_errmsg_uncapped_extack, tc) @@ -152,8 +144,6 @@ ATF_TC_BODY(snl_parse_errmsg_uncapped_extack, tc) struct snl_state ss; struct snl_writer nw; - require_netlink(); - ATF_CHECK(snl_init(&ss, NETLINK_ROUTE)); int optval = 1; @@ -185,6 +175,7 @@ ATF_TC(snl_list_ifaces); ATF_TC_HEAD(snl_list_ifaces, tc) { atf_tc_set_md_var(tc, "descr", "Tests snl(3) listing interfaces"); + atf_tc_set_md_var(tc, "require.kmods", "netlink"); } struct nl_parsed_link { @@ -212,8 +203,6 @@ ATF_TC_BODY(snl_list_ifaces, tc) struct snl_state ss; struct snl_writer nw; - require_netlink(); - if (!snl_init(&ss, NETLINK_ROUTE)) atf_tc_fail("snl_init() failed"); diff --git a/tests/sys/netlink/test_snl_generic.c b/tests/sys/netlink/test_snl_generic.c index c63b1380f2ad..8613bf04a45c 100644 --- a/tests/sys/netlink/test_snl_generic.c +++ b/tests/sys/netlink/test_snl_generic.c @@ -15,13 +15,6 @@ static const struct snl_hdr_parser *snl_all_genl_parsers[] = { &_genl_ctrl_getfam_parser, &_genl_ctrl_mc_parser, }; -static void -require_netlink(void) -{ - if (modfind("netlink") == -1) - atf_tc_skip("netlink module not loaded"); -} - ATF_TC(snl_verify_genl_parsers); ATF_TC_HEAD(snl_verify_genl_parsers, tc) { @@ -38,14 +31,13 @@ ATF_TC(test_snl_get_genl_family_success); ATF_TC_HEAD(test_snl_get_genl_family_success, tc) { atf_tc_set_md_var(tc, "descr", "Tests successfull resolution of the 'nlctrl' family"); + atf_tc_set_md_var(tc, "require.kmods", "netlink"); } ATF_TC_BODY(test_snl_get_genl_family_success, tc) { struct snl_state ss; - require_netlink(); - if (!snl_init(&ss, NETLINK_GENERIC)) atf_tc_fail("snl_init() failed"); @@ -56,14 +48,13 @@ ATF_TC(test_snl_get_genl_family_failure); ATF_TC_HEAD(test_snl_get_genl_family_failure, tc) { atf_tc_set_md_var(tc, "descr", "Tests unsuccessfull resolution of 'no-such-family' family"); + atf_tc_set_md_var(tc, "require.kmods", "netlink"); } ATF_TC_BODY(test_snl_get_genl_family_failure, tc) { struct snl_state ss; - require_netlink(); - if (!snl_init(&ss, NETLINK_GENERIC)) atf_tc_fail("snl_init() failed"); @@ -74,6 +65,7 @@ ATF_TC(test_snl_get_genl_family_groups); ATF_TC_HEAD(test_snl_get_genl_family_groups, tc) { atf_tc_set_md_var(tc, "descr", "Tests getting 'nlctrl' groups"); + atf_tc_set_md_var(tc, "require.kmods", "netlink"); } ATF_TC_BODY(test_snl_get_genl_family_groups, tc) @@ -82,8 +74,6 @@ ATF_TC_BODY(test_snl_get_genl_family_groups, tc) struct snl_writer nw; struct nlmsghdr *hdr; - require_netlink(); - if (!snl_init(&ss, NETLINK_GENERIC)) atf_tc_fail("snl_init() failed"); diff --git a/tests/sys/netmap/Makefile b/tests/sys/netmap/Makefile index ee00d0421620..bd713ff795bc 100644 --- a/tests/sys/netmap/Makefile +++ b/tests/sys/netmap/Makefile @@ -3,6 +3,7 @@ PACKAGE= tests TESTSDIR= ${TESTSBASE}/sys/netmap TEST_METADATA+= required_user="root" TEST_METADATA+= is_exclusive=true +TEST_METADATA+= required_kmods="if_tap netmap" PLAIN_TESTS_C+= ctrl-api-test diff --git a/tests/sys/netmap/ctrl-api-test.c b/tests/sys/netmap/ctrl-api-test.c index 6b45dbb1cfea..36c131980360 100644 --- a/tests/sys/netmap/ctrl-api-test.c +++ b/tests/sys/netmap/ctrl-api-test.c @@ -59,8 +59,6 @@ #include <stddef.h> #ifdef __FreeBSD__ -#include "freebsd_test_suite/macros.h" - static int eventfd(int x __unused, int y __unused) { @@ -2199,11 +2197,6 @@ main(int argc, char **argv) int opt; int i; -#ifdef __FreeBSD__ - PLAIN_REQUIRE_KERNEL_MODULE("if_tap", 0); - PLAIN_REQUIRE_KERNEL_MODULE("netmap", 0); -#endif - memset(&ctx_, 0, sizeof(ctx_)); { diff --git a/tests/sys/netpfil/pf/Makefile b/tests/sys/netpfil/pf/Makefile index 616ffe560b3a..9f993eec61d0 100644 --- a/tests/sys/netpfil/pf/Makefile +++ b/tests/sys/netpfil/pf/Makefile @@ -61,6 +61,7 @@ ATF_TESTS_PYTEST+= header.py ATF_TESTS_PYTEST+= icmp.py ATF_TESTS_PYTEST+= igmp.py ATF_TESTS_PYTEST+= mld.py +ATF_TESTS_PYTEST+= nat44.py ATF_TESTS_PYTEST+= nat64.py ATF_TESTS_PYTEST+= nat66.py ATF_TESTS_PYTEST+= return.py diff --git a/tests/sys/netpfil/pf/fragmentation_pass.sh b/tests/sys/netpfil/pf/fragmentation_pass.sh index 5deaba18301d..c749aac793ee 100644 --- a/tests/sys/netpfil/pf/fragmentation_pass.sh +++ b/tests/sys/netpfil/pf/fragmentation_pass.sh @@ -648,6 +648,72 @@ dummynet_fragmented_cleanup() pft_cleanup } +atf_test_case "counters" "cleanup" +counters_head() +{ + atf_set descr 'Test fragment counters' + atf_set require.user root +} + +counters_body() +{ + pft_init + + epair=$(vnet_mkepair) + vnet_mkjail alcatraz ${epair}a + + ifconfig ${epair}b inet 192.0.2.1/24 up + jexec alcatraz ifconfig ${epair}a 192.0.2.2/24 up + + jexec alcatraz pfctl -e + pft_set_rules alcatraz \ + "set reassemble yes" \ + "pass keep state" + + # All fragment counters are zero + counters=$(jexec alcatraz pfctl -si -v | grep -A 4 '^Fragments') + atf_check -s exit:0 -o match:"current entries[[:space:]]+0" \ + echo $counters + atf_check -s exit:0 -o match:"searches[[:space:]]+0" \ + echo $counters + atf_check -s exit:0 -o match:"inserts[[:space:]]+0" \ + echo $counters + atf_check -s exit:0 -o match:"removals[[:space:]]+0" \ + echo $counters + + # They remain zero after we've seen non-fragmented traffic + atf_check -s exit:0 -o ignore \ + ping -c 1 192.0.2.2 + counters=$(jexec alcatraz pfctl -si -v | grep -A 4 '^Fragments') + atf_check -s exit:0 -o match:"current entries[[:space:]]+0" \ + echo $counters + atf_check -s exit:0 -o match:"searches[[:space:]]+0" \ + echo $counters + atf_check -s exit:0 -o match:"inserts[[:space:]]+0" \ + echo $counters + atf_check -s exit:0 -o match:"removals[[:space:]]+0" \ + echo $counters + + # But once we've reassembled they're no longer zero + # (Count is 2, because in + out) + atf_check -s exit:0 -o ignore \ + ping -c 1 -s 2000 192.0.2.2 + counters=$(jexec alcatraz pfctl -si -v | grep -A 4 '^Fragments') + atf_check -s exit:0 -o match:"current entries[[:space:]]+0" \ + echo $counters + atf_check -s exit:0 -o match:"searches[[:space:]]+2" \ + echo $counters + atf_check -s exit:0 -o match:"inserts[[:space:]]+2" \ + echo $counters + atf_check -s exit:0 -o match:"removals[[:space:]]+2" \ + echo $counters +} + +counters_cleanup() +{ + pft_cleanup +} + atf_init_test_cases() { atf_add_test_case "too_many_fragments" @@ -665,4 +731,5 @@ atf_init_test_cases() atf_add_test_case "dummynet" atf_add_test_case "dummynet_nat" atf_add_test_case "dummynet_fragmented" + atf_add_test_case "counters" } diff --git a/tests/sys/netpfil/pf/igmp.py b/tests/sys/netpfil/pf/igmp.py index b339a2825082..5d72a1c093a7 100644 --- a/tests/sys/netpfil/pf/igmp.py +++ b/tests/sys/netpfil/pf/igmp.py @@ -93,3 +93,9 @@ class TestIGMP(VnetTestTemplate): options=[sp.IPOption_Router_Alert()]) \ / sc.igmp.IGMP(type=0x11, mrcode=1) assert not self.find_igmp_reply(pkt, ifname) + + # Or with the wrong destination address + pkt = sp.IP(dst="224.0.0.2%%%s" % ifname, ttl=2, + options=[sp.IPOption_Router_Alert()]) \ + / sc.igmp.IGMP(type=0x11, mrcode=1) + assert not self.find_igmp_reply(pkt, ifname) diff --git a/tests/sys/netpfil/pf/ioctl/validation.c b/tests/sys/netpfil/pf/ioctl/validation.c index 18fafe11c6ab..3e03163cc752 100644 --- a/tests/sys/netpfil/pf/ioctl/validation.c +++ b/tests/sys/netpfil/pf/ioctl/validation.c @@ -41,8 +41,6 @@ static int dev; #define COMMON_HEAD() \ - if (modfind("pf") == -1) \ - atf_tc_skip("pf not loaded"); \ dev = open("/dev/pf", O_RDWR); \ if (dev == -1) \ atf_tc_skip("Failed to open /dev/pf"); @@ -64,6 +62,7 @@ ATF_TC_WITH_CLEANUP(addtables); ATF_TC_HEAD(addtables, tc) { atf_tc_set_md_var(tc, "require.user", "root"); + atf_tc_set_md_var(tc, "require.kmods", "pf"); } ATF_TC_BODY(addtables, tc) @@ -116,6 +115,7 @@ ATF_TC_WITH_CLEANUP(deltables); ATF_TC_HEAD(deltables, tc) { atf_tc_set_md_var(tc, "require.user", "root"); + atf_tc_set_md_var(tc, "require.kmods", "pf"); } ATF_TC_BODY(deltables, tc) @@ -159,6 +159,7 @@ ATF_TC_WITH_CLEANUP(gettables); ATF_TC_HEAD(gettables, tc) { atf_tc_set_md_var(tc, "require.user", "root"); + atf_tc_set_md_var(tc, "require.kmods", "pf"); } ATF_TC_BODY(gettables, tc) @@ -197,6 +198,7 @@ ATF_TC_WITH_CLEANUP(gettstats); ATF_TC_HEAD(gettstats, tc) { atf_tc_set_md_var(tc, "require.user", "root"); + atf_tc_set_md_var(tc, "require.kmods", "pf"); } ATF_TC_BODY(gettstats, tc) @@ -235,6 +237,7 @@ ATF_TC_WITH_CLEANUP(clrtstats); ATF_TC_HEAD(clrtstats, tc) { atf_tc_set_md_var(tc, "require.user", "root"); + atf_tc_set_md_var(tc, "require.kmods", "pf"); } ATF_TC_BODY(clrtstats, tc) @@ -280,6 +283,7 @@ ATF_TC_WITH_CLEANUP(settflags); ATF_TC_HEAD(settflags, tc) { atf_tc_set_md_var(tc, "require.user", "root"); + atf_tc_set_md_var(tc, "require.kmods", "pf"); } ATF_TC_BODY(settflags, tc) @@ -325,6 +329,7 @@ ATF_TC_WITH_CLEANUP(addaddrs); ATF_TC_HEAD(addaddrs, tc) { atf_tc_set_md_var(tc, "require.user", "root"); + atf_tc_set_md_var(tc, "require.kmods", "pf"); } ATF_TC_BODY(addaddrs, tc) @@ -360,6 +365,7 @@ ATF_TC_WITH_CLEANUP(deladdrs); ATF_TC_HEAD(deladdrs, tc) { atf_tc_set_md_var(tc, "require.user", "root"); + atf_tc_set_md_var(tc, "require.kmods", "pf"); } ATF_TC_BODY(deladdrs, tc) @@ -395,6 +401,7 @@ ATF_TC_WITH_CLEANUP(setaddrs); ATF_TC_HEAD(setaddrs, tc) { atf_tc_set_md_var(tc, "require.user", "root"); + atf_tc_set_md_var(tc, "require.kmods", "pf"); } ATF_TC_BODY(setaddrs, tc) @@ -430,6 +437,7 @@ ATF_TC_WITH_CLEANUP(getaddrs); ATF_TC_HEAD(getaddrs, tc) { atf_tc_set_md_var(tc, "require.user", "root"); + atf_tc_set_md_var(tc, "require.kmods", "pf"); } ATF_TC_BODY(getaddrs, tc) @@ -467,6 +475,7 @@ ATF_TC_WITH_CLEANUP(getastats); ATF_TC_HEAD(getastats, tc) { atf_tc_set_md_var(tc, "require.user", "root"); + atf_tc_set_md_var(tc, "require.kmods", "pf"); } ATF_TC_BODY(getastats, tc) @@ -504,6 +513,7 @@ ATF_TC_WITH_CLEANUP(clrastats); ATF_TC_HEAD(clrastats, tc) { atf_tc_set_md_var(tc, "require.user", "root"); + atf_tc_set_md_var(tc, "require.kmods", "pf"); } ATF_TC_BODY(clrastats, tc) @@ -541,6 +551,7 @@ ATF_TC_WITH_CLEANUP(tstaddrs); ATF_TC_HEAD(tstaddrs, tc) { atf_tc_set_md_var(tc, "require.user", "root"); + atf_tc_set_md_var(tc, "require.kmods", "pf"); } ATF_TC_BODY(tstaddrs, tc) @@ -578,6 +589,7 @@ ATF_TC_WITH_CLEANUP(inadefine); ATF_TC_HEAD(inadefine, tc) { atf_tc_set_md_var(tc, "require.user", "root"); + atf_tc_set_md_var(tc, "require.kmods", "pf"); } ATF_TC_BODY(inadefine, tc) @@ -615,6 +627,7 @@ ATF_TC_WITH_CLEANUP(igetifaces); ATF_TC_HEAD(igetifaces, tc) { atf_tc_set_md_var(tc, "require.user", "root"); + atf_tc_set_md_var(tc, "require.kmods", "pf"); } ATF_TC_BODY(igetifaces, tc) @@ -649,6 +662,7 @@ ATF_TC_WITH_CLEANUP(cxbegin); ATF_TC_HEAD(cxbegin, tc) { atf_tc_set_md_var(tc, "require.user", "root"); + atf_tc_set_md_var(tc, "require.kmods", "pf"); } ATF_TC_BODY(cxbegin, tc) @@ -688,6 +702,7 @@ ATF_TC_WITH_CLEANUP(cxrollback); ATF_TC_HEAD(cxrollback, tc) { atf_tc_set_md_var(tc, "require.user", "root"); + atf_tc_set_md_var(tc, "require.kmods", "pf"); } ATF_TC_BODY(cxrollback, tc) @@ -727,6 +742,7 @@ ATF_TC_WITH_CLEANUP(commit); ATF_TC_HEAD(commit, tc) { atf_tc_set_md_var(tc, "require.user", "root"); + atf_tc_set_md_var(tc, "require.kmods", "pf"); } ATF_TC_BODY(commit, tc) @@ -766,6 +782,7 @@ ATF_TC_WITH_CLEANUP(getsrcnodes); ATF_TC_HEAD(getsrcnodes, tc) { atf_tc_set_md_var(tc, "require.user", "root"); + atf_tc_set_md_var(tc, "require.kmods", "pf"); } ATF_TC_BODY(getsrcnodes, tc) @@ -798,6 +815,7 @@ ATF_TC_WITH_CLEANUP(tag); ATF_TC_HEAD(tag, tc) { atf_tc_set_md_var(tc, "require.user", "root"); + atf_tc_set_md_var(tc, "require.kmods", "pf"); } ATF_TC_BODY(tag, tc) @@ -835,6 +853,7 @@ ATF_TC_WITH_CLEANUP(rpool_mtx); ATF_TC_HEAD(rpool_mtx, tc) { atf_tc_set_md_var(tc, "require.user", "root"); + atf_tc_set_md_var(tc, "require.kmods", "pf"); } ATF_TC_BODY(rpool_mtx, tc) @@ -872,6 +891,7 @@ ATF_TC_WITH_CLEANUP(rpool_mtx2); ATF_TC_HEAD(rpool_mtx2, tc) { atf_tc_set_md_var(tc, "require.user", "root"); + atf_tc_set_md_var(tc, "require.kmods", "pf"); } ATF_TC_BODY(rpool_mtx2, tc) @@ -898,6 +918,7 @@ ATF_TC_WITH_CLEANUP(natlook); ATF_TC_HEAD(natlook, tc) { atf_tc_set_md_var(tc, "require.user", "root"); + atf_tc_set_md_var(tc, "require.kmods", "pf"); } ATF_TC_BODY(natlook, tc) diff --git a/tests/sys/netpfil/pf/killstate.sh b/tests/sys/netpfil/pf/killstate.sh index 0d98db822535..ffb01df57908 100644 --- a/tests/sys/netpfil/pf/killstate.sh +++ b/tests/sys/netpfil/pf/killstate.sh @@ -105,6 +105,68 @@ v4_cleanup() pft_cleanup } +atf_test_case "src_dst" "cleanup" +src_dst_head() +{ + atf_set descr 'Test killing a state with source and destination specified' + atf_set require.user root +} + +src_dst_body() +{ + pft_init + + epair=$(vnet_mkepair) + ifconfig ${epair}a 192.0.2.1/24 up + + vnet_mkjail alcatraz ${epair}b + jexec alcatraz ifconfig ${epair}b 192.0.2.2/24 up + jexec alcatraz pfctl -e + + pft_set_rules alcatraz "block all" \ + "pass in proto icmp" \ + "set skip on lo" + + # Sanity check & establish state + atf_check -s exit:0 -o ignore ${common_dir}/pft_ping.py \ + --sendif ${epair}a \ + --to 192.0.2.2 \ + --replyif ${epair}a + + # Change rules to now deny the ICMP traffic + pft_set_rules noflush alcatraz "block all" + if ! find_state; + then + atf_fail "Setting new rules removed the state." + fi + + # Killing with the wrong source IP doesn't affect our state + jexec alcatraz pfctl -k 192.0.2.3 -k 192.0.2.2 + if ! find_state; + then + atf_fail "Killing with the wrong source IP removed our state." + fi + + # Killing with the wrong destination IP doesn't affect our state + jexec alcatraz pfctl -k 192.0.2.1 -k 192.0.2.3 + if ! find_state; + then + atf_fail "Killing with the wrong destination IP removed our state." + fi + + # But it does with the correct one + jexec alcatraz pfctl -k 192.0.2.1 -k 192.0.2.2 + if find_state; + then + atf_fail "Killing with the correct IPs did not remove our state." + fi +} + +src_dst_cleanup() +{ + pft_cleanup +} + atf_test_case "v6" "cleanup" v6_head() { @@ -698,6 +760,7 @@ nat_cleanup() atf_init_test_cases() { atf_add_test_case "v4" + atf_add_test_case "src_dst" atf_add_test_case "v6" atf_add_test_case "label" atf_add_test_case "multilabel" diff --git a/tests/sys/netpfil/pf/limits.sh b/tests/sys/netpfil/pf/limits.sh index 69f0b6af2ccf..a0d6b891ee19 100644 --- a/tests/sys/netpfil/pf/limits.sh +++ b/tests/sys/netpfil/pf/limits.sh @@ -112,8 +112,43 @@ zero_cleanup() pft_cleanup } +atf_test_case "anchors" "cleanup" +anchors_head() +{ + atf_set descr 'Test increasing maximum number of anchors' + atf_set require.user root +} + +anchors_body() +{ + pft_init + + vnet_mkjail alcatraz + + jexec alcatraz pfctl -e + + pft_set_rules alcatraz \ + "set limit anchors 1" + + pft_set_rules alcatraz \ + "set limit anchors 2" \ + "pass" \ + "anchor \"foo\" {\n + pass in\n + }" \ + "anchor \"bar\" {\n + pass out\n + }" +} + +anchors_cleanup() +{ + pft_cleanup +} + atf_init_test_cases() { atf_add_test_case "basic" atf_add_test_case "zero" + atf_add_test_case "anchors" } diff --git a/tests/sys/netpfil/pf/mbuf.sh b/tests/sys/netpfil/pf/mbuf.sh index e3f138bb73b9..3abae65203cd 100644 --- a/tests/sys/netpfil/pf/mbuf.sh +++ b/tests/sys/netpfil/pf/mbuf.sh @@ -69,22 +69,22 @@ inet_in_mbuf_len_body() # Should still work for m_len=0 jexec alcatraz pfilctl link -i dummymbuf:inet inet jexec alcatraz sysctl net.dummymbuf.rules="inet in ${epair}b pull-head 0;" - atf_check_equal "0" "$(jexec alcatraz sysctl -n net.dummymbuf.hits)" + atf_check_equal '0' '$(jexec alcatraz sysctl -n net.dummymbuf.hits)' atf_check -s exit:0 -o ignore ping -c1 192.0.2.2 - atf_check_equal "1" "$(jexec alcatraz sysctl -n net.dummymbuf.hits)" + atf_check_equal '1' '$(jexec alcatraz sysctl -n net.dummymbuf.hits)' # m_len=1 jexec alcatraz sysctl net.dummymbuf.rules="inet in ${epair}b pull-head 1;" jexec alcatraz sysctl net.dummymbuf.hits=0 atf_check -s exit:0 -o ignore ping -c1 192.0.2.2 - atf_check_equal "1" "$(jexec alcatraz sysctl -n net.dummymbuf.hits)" + atf_check_equal '1' '$(jexec alcatraz sysctl -n net.dummymbuf.hits)' # m_len=19 # provided IPv4 basic header is 20 bytes long, it should impact the dst addr jexec alcatraz sysctl net.dummymbuf.rules="inet in ${epair}b pull-head 19;" jexec alcatraz sysctl net.dummymbuf.hits=0 atf_check -s exit:0 -o ignore ping -c1 192.0.2.2 - atf_check_equal "1" "$(jexec alcatraz sysctl -n net.dummymbuf.hits)" + atf_check_equal '1' '$(jexec alcatraz sysctl -n net.dummymbuf.hits)' } inet_in_mbuf_len_cleanup() { @@ -140,22 +140,22 @@ inet6_in_mbuf_len_body() # Should still work for m_len=0 jexec alcatraz pfilctl link -i dummymbuf:inet6 inet6 jexec alcatraz sysctl net.dummymbuf.rules="inet6 in ${epair}b pull-head 0;" - atf_check_equal "0" "$(jexec alcatraz sysctl -n net.dummymbuf.hits)" + atf_check_equal '0' '$(jexec alcatraz sysctl -n net.dummymbuf.hits)' atf_check -s exit:0 -o ignore ping -c1 2001:db8::2 - atf_check_equal "1" "$(jexec alcatraz sysctl -n net.dummymbuf.hits)" + atf_check_equal '1' '$(jexec alcatraz sysctl -n net.dummymbuf.hits)' # m_len=1 jexec alcatraz sysctl net.dummymbuf.rules="inet6 in ${epair}b pull-head 1;" jexec alcatraz sysctl net.dummymbuf.hits=0 atf_check -s exit:0 -o ignore ping -c1 2001:db8::2 - atf_check_equal "1" "$(jexec alcatraz sysctl -n net.dummymbuf.hits)" + atf_check_equal '1' '$(jexec alcatraz sysctl -n net.dummymbuf.hits)' # m_len=39 # provided IPv6 basic header is 40 bytes long, it should impact the dst addr jexec alcatraz sysctl net.dummymbuf.rules="inet6 in ${epair}b pull-head 39;" jexec alcatraz sysctl net.dummymbuf.hits=0 atf_check -s exit:0 -o ignore ping -c1 2001:db8::2 - atf_check_equal "1" "$(jexec alcatraz sysctl -n net.dummymbuf.hits)" + atf_check_equal '1' '$(jexec alcatraz sysctl -n net.dummymbuf.hits)' } inet6_in_mbuf_len_cleanup() { @@ -205,29 +205,29 @@ ethernet_in_mbuf_len_body() # Should still work for m_len=0 jexec alcatraz pfilctl link -i dummymbuf:ethernet ethernet jexec alcatraz sysctl net.dummymbuf.rules="ethernet in ${epair}b pull-head 0;" - atf_check_equal "0" "$(jexec alcatraz sysctl -n net.dummymbuf.hits)" + atf_check_equal '0' '$(jexec alcatraz sysctl -n net.dummymbuf.hits)' atf_check -s exit:0 -o ignore ping -c1 192.0.2.2 - atf_check_equal "1" "$(jexec alcatraz sysctl -n net.dummymbuf.hits)" + atf_check_equal '1' '$(jexec alcatraz sysctl -n net.dummymbuf.hits)' # m_len=1 jexec alcatraz sysctl net.dummymbuf.rules="ethernet in ${epair}b pull-head 1;" jexec alcatraz sysctl net.dummymbuf.hits=0 atf_check -s exit:0 -o ignore ping -c1 192.0.2.2 - atf_check_equal "1" "$(jexec alcatraz sysctl -n net.dummymbuf.hits)" + atf_check_equal '1' '$(jexec alcatraz sysctl -n net.dummymbuf.hits)' # m_len=11 # for the simplest L2 Ethernet frame it should impact src field jexec alcatraz sysctl net.dummymbuf.rules="ethernet in ${epair}b pull-head 11;" jexec alcatraz sysctl net.dummymbuf.hits=0 atf_check -s exit:0 -o ignore ping -c1 192.0.2.2 - atf_check_equal "1" "$(jexec alcatraz sysctl -n net.dummymbuf.hits)" + atf_check_equal '1' '$(jexec alcatraz sysctl -n net.dummymbuf.hits)' # m_len=13 # provided L2 Ethernet simplest header is 14 bytes long, it should impact ethertype field jexec alcatraz sysctl net.dummymbuf.rules="ethernet in ${epair}b pull-head 13;" jexec alcatraz sysctl net.dummymbuf.hits=0 atf_check -s exit:0 -o ignore ping -c1 192.0.2.2 - atf_check_equal "1" "$(jexec alcatraz sysctl -n net.dummymbuf.hits)" + atf_check_equal '1' '$(jexec alcatraz sysctl -n net.dummymbuf.hits)' } ethernet_in_mbuf_len_cleanup() { diff --git a/tests/sys/netpfil/pf/nat44.py b/tests/sys/netpfil/pf/nat44.py new file mode 100644 index 000000000000..d69e794a62c3 --- /dev/null +++ b/tests/sys/netpfil/pf/nat44.py @@ -0,0 +1,76 @@ +# +# 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 atf_python.sys.net.tools import ToolsHelper +from atf_python.sys.net.vnet import VnetTestTemplate + +class TestNAT44(VnetTestTemplate): + REQUIRED_MODULES = [ "pf" ] + TOPOLOGY = { + "vnet1": {"ifaces": ["if1"]}, + "vnet2": {"ifaces": ["if1", "if2"]}, + "vnet3": {"ifaces": ["if2"]}, + "if1": {"prefixes4": [("192.0.2.2/24", "192.0.2.1/24")]}, + "if2": {"prefixes4": [("198.51.100.1/24", "198.51.100.2")]}, + } + + def vnet2_handler(self, vnet): + outifname = vnet.iface_alias_map["if2"].name + ToolsHelper.print_output("/sbin/sysctl net.inet.ip.forwarding=1") + + ToolsHelper.print_output("/sbin/pfctl -e") + ToolsHelper.print_output("/sbin/pfctl -x loud") + ToolsHelper.pf_rules([ + "set reassemble yes", + "nat on {} inet from 192.0.2.0/24 -> ({})".format(outifname, outifname), + "pass"]) + + def vnet3_handler(self, vnet): + pass + + @pytest.mark.require_user("root") + @pytest.mark.require_progs(["scapy"]) + def test_nat_igmp(self): + "Verify that NAT translation of !(TCP|UDP|SCTP|ICMP) doesn't panic" + ToolsHelper.print_output("/sbin/route add default 192.0.2.1") + ToolsHelper.print_output("ping -c 3 198.51.100.2") + + # Import in the correct vnet, so at to not confuse Scapy + import scapy.all as sp + import scapy.contrib as sc + import scapy.contrib.igmp + + pkt = sp.IP(dst="198.51.100.2", ttl=64) \ + / sc.igmp.IGMP(type=0x11, mrcode=1) + sp.send(pkt) + + # This time we'll hit an existing state + pkt = sp.IP(dst="198.51.100.2", ttl=64) \ + / sc.igmp.IGMP(type=0x11, mrcode=1) + reply = sp.sr1(pkt, timeout=3) + if reply: + reply.show() diff --git a/tests/sys/netpfil/pf/pflog.sh b/tests/sys/netpfil/pf/pflog.sh index a34ec893a75c..550548a59c11 100644 --- a/tests/sys/netpfil/pf/pflog.sh +++ b/tests/sys/netpfil/pf/pflog.sh @@ -394,6 +394,64 @@ rdr_action_cleanup() pft_cleanup } +atf_test_case "rule_number" "cleanup" +rule_number_head() +{ + atf_set descr 'Test rule numbers with anchors' + atf_set require.user root +} + +rule_number_body() +{ + pflog_init + + epair=$(vnet_mkepair) + + vnet_mkjail alcatraz ${epair}b + jexec alcatraz ifconfig ${epair}b 192.0.2.1/24 up + + ifconfig ${epair}a 192.0.2.2/24 up + ifconfig ${epair}a inet alias 192.0.2.3/24 up + ifconfig ${epair}a inet alias 192.0.2.4/24 up + + jexec alcatraz pfctl -e + jexec alcatraz ifconfig pflog0 up + pft_set_rules alcatraz \ + "pass log from 192.0.2.2" \ + "anchor \"foo\" {\n \ + pass log from 192.0.2.3\n \ + }" \ + "pass log from 192.0.2.4" + + jexec alcatraz tcpdump -n -e -ttt --immediate-mode -l -U -i pflog0 >> pflog.txt & + sleep 1 # Wait for tcpdump to start + + atf_check -s exit:0 -o ignore \ + ping -c 1 -S 192.0.2.2 192.0.2.1 + atf_check -s exit:0 -o ignore \ + ping -c 1 -S 192.0.2.3 192.0.2.1 + atf_check -s exit:0 -o ignore \ + ping -c 1 -S 192.0.2.4 192.0.2.1 + + jexec alcatraz pfctl -sr -a '*' -vv + + # Give tcpdump a little time to finish writing to the file + sleep 1 + cat pflog.txt + + atf_check -o match:"rule 0/0\(match\): pass in.*: 192.0.2.2.*ICMP echo request" \ + cat pflog.txt + atf_check -o match:"rule 1.foo.0/0\(match\): pass in.*: 192.0.2.3.*: ICMP echo request" \ + cat pflog.txt + atf_check -o match:"rule 2/0\(match\): pass in.*: 192.0.2.4.*: ICMP echo request" \ + cat pflog.txt +} + +rule_number_cleanup() +{ + pft_cleanup +} + atf_init_test_cases() { atf_add_test_case "malformed" @@ -403,4 +461,5 @@ atf_init_test_cases() atf_add_test_case "unspecified_v4" atf_add_test_case "unspecified_v6" atf_add_test_case "rdr_action" + atf_add_test_case "rule_number" } diff --git a/tests/sys/netpfil/pf/route_to.sh b/tests/sys/netpfil/pf/route_to.sh index 765403dcb79c..13b60c8f80bc 100644 --- a/tests/sys/netpfil/pf/route_to.sh +++ b/tests/sys/netpfil/pf/route_to.sh @@ -28,6 +28,75 @@ common_dir=$(atf_get_srcdir)/../common +# We need to somehow test if the random algorithm of pf_map_addr() is working. +# The table or prefix contains multiple IP next-hop addresses, for each one try +# to establish up to 10 connections. Fail the test if with this many attempts +# the "good" target has not been chosen. However this choice is random, +# the check might still ocasionally fail. +check_random() { + if [ "$1" = "IPv4" ]; then + ping_from="${net_clients_4}.1" + ping_to="${host_server_4}" + else + ping_from="${net_clients_6}::1" + ping_to="${host_server_6}" + fi + good_targets="$2" + bad_targets="$3" + + port=42000 + states=$(mktemp) || exit 1 + for good_target in $good_targets; do + found="no" + for attempt in $(seq 1 10); do + port=$(( port + 1 )) + jexec router pfctl -Fs + atf_check -s exit:0 ${common_dir}/pft_ping.py \ + --sendif ${epair_tester}a --replyif ${epair_tester}a \ + --fromaddr ${ping_from} --to ${ping_to} \ + --ping-type=tcp3way --send-sport=${port} + jexec router pfctl -qvvss | normalize_pfctl_s > $states + cat $states + if [ -n "${bad_targets}" ]; then + for bad_target in $bad_targets; do + if grep -qE "route-to: ${bad_target}@" $states; then + atf_fail "Bad target ${bad_target} selected!" + fi + done + fi; + if grep -qE "route-to: ${good_target}@" $states; then + found=yes + break + fi + done + if [ "${found}" = "no" ]; then + atf_fail "Target ${good_target} not selected after ${attempt} attempts!" + fi + done +} + +pf_map_addr_common() +{ + setup_router_server_nat64 + + # Clients will connect from another network behind the router. + # This allows for using multiple source addresses. + jexec router route add -6 ${net_clients_6}::/${net_clients_6_mask} ${net_tester_6_host_tester} + jexec router route add ${net_clients_4}.0/${net_clients_4_mask} ${net_tester_4_host_tester} + + # The servers are reachable over additional IP addresses for + # testing of tables and subnets. The addresses are noncontinougnus + # for pf_map_addr() counter tests. + for i in 0 1 4 5; do + a1=$((24 + i)) + jexec server1 ifconfig ${epair_server1}b inet ${net_server1_4}.${a1}/32 alias + jexec server1 ifconfig ${epair_server1}b inet6 ${net_server1_6}::42:${i}/128 alias + a2=$((40 + i)) + jexec server2 ifconfig ${epair_server2}b inet ${net_server2_4}.${a2}/32 alias + jexec server2 ifconfig ${epair_server2}b inet6 ${net_server2_6}::42:${i}/128 alias + done +} + atf_test_case "v4" "cleanup" v4_head() { @@ -893,7 +962,6 @@ empty_pool_cleanup() pft_cleanup } - atf_test_case "table_loop" "cleanup" table_loop_head() @@ -905,24 +973,7 @@ table_loop_head() table_loop_body() { - setup_router_server_nat64 - - # Clients will connect from another network behind the router. - # This allows for using multiple source addresses. - jexec router route add -6 ${net_clients_6}::/${net_clients_6_mask} ${net_tester_6_host_tester} - jexec router route add ${net_clients_4}.0/${net_clients_4_mask} ${net_tester_4_host_tester} - - # The servers are reachable over additional IP addresses for - # testing of tables and subnets. The addresses are noncontinougnus - # for pf_map_addr() counter tests. - for i in 0 1 4 5; do - a1=$((24 + i)) - jexec server1 ifconfig ${epair_server1}b inet ${net_server1_4}.${a1}/32 alias - jexec server1 ifconfig ${epair_server1}b inet6 ${net_server1_6}::42:${i}/128 alias - a2=$((40 + i)) - jexec server2 ifconfig ${epair_server2}b inet ${net_server2_4}.${a2}/32 alias - jexec server2 ifconfig ${epair_server2}b inet6 ${net_server2_6}::42:${i}/128 alias - done + pf_map_addr_common jexec router pfctl -e pft_set_rules router \ @@ -976,6 +1027,626 @@ table_loop_cleanup() } +atf_test_case "roundrobin" "cleanup" + +roundrobin_head() +{ + atf_set descr 'multiple gateways of mixed AF, including prefixes and tables, for IPv6 packets' + atf_set require.user root + atf_set require.progs python3 scapy +} + +roundrobin_body() +{ + pf_map_addr_common + + # The rule is defined as "inet6 proto tcp" so directly given IPv4 hosts + # will be removed from the pool by pfctl. Tables will still be loaded + # and pf_map_addr() will only use IPv6 addresses from them. It will + # iterate over members of the pool and inside of tables and prefixes. + + jexec router pfctl -e + pft_set_rules router \ + "set debug loud" \ + "set reassemble yes" \ + "set state-policy if-bound" \ + "table <rt_targets> { ${net_server2_4}.40/31 ${net_server2_4}.44 ${net_server2_6}::42:0/127 ${net_server2_6}::42:4 }" \ + "pass in on ${epair_tester}b \ + route-to { \ + (${epair_server1}a ${net_server1_4_host_server}) \ + (${epair_server2}a <rt_targets_empty>) \ + (${epair_server1}a ${net_server1_6}::42:0/127) \ + (${epair_server2}a <rt_targets_empty>) \ + (${epair_server2}a <rt_targets>) \ + } \ + inet6 proto tcp \ + keep state" + + for port in $(seq 1 6); do + port=$((4200 + port)) + atf_check -s exit:0 ${common_dir}/pft_ping.py \ + --sendif ${epair_tester}a --replyif ${epair_tester}a \ + --fromaddr ${net_clients_6}::1 --to ${host_server_6} \ + --ping-type=tcp3way --send-sport=${port} + done + + states=$(mktemp) || exit 1 + jexec router pfctl -qvvss | normalize_pfctl_s > $states + + for state_regexp in \ + "${epair_tester}b tcp ${host_server_6}\[9\] <- ${net_clients_6}::1\[4201\] .* route-to: ${net_server1_6}::42:0@${epair_server1}a" \ + "${epair_tester}b tcp ${host_server_6}\[9\] <- ${net_clients_6}::1\[4202\] .* route-to: ${net_server1_6}::42:1@${epair_server1}a" \ + "${epair_tester}b tcp ${host_server_6}\[9\] <- ${net_clients_6}::1\[4203\] .* route-to: ${net_server2_6}::42:0@${epair_server2}a" \ + "${epair_tester}b tcp ${host_server_6}\[9\] <- ${net_clients_6}::1\[4204\] .* route-to: ${net_server2_6}::42:1@${epair_server2}a" \ + "${epair_tester}b tcp ${host_server_6}\[9\] <- ${net_clients_6}::1\[4205\] .* route-to: ${net_server2_6}::42:4@${epair_server2}a" \ + "${epair_tester}b tcp ${host_server_6}\[9\] <- ${net_clients_6}::1\[4206\] .* route-to: ${net_server1_6}::42:0@${epair_server1}a" \ + ; do + grep -qE "${state_regexp}" $states || atf_fail "State not found for '${state_regexp}'" + done +} + +roundrobin_cleanup() +{ + pft_cleanup +} + +atf_test_case "random_table" "cleanup" + +random_table_head() +{ + atf_set descr 'Pool with random flag and a table for IPv6' + atf_set require.user root + atf_set require.progs python3 scapy +} + +random_table_body() +{ + pf_map_addr_common + + # The "random" flag will pick random hosts from the table but will + # not dive into prefixes, always choosing the 0th address. + # Proper address family will be choosen. + + jexec router pfctl -e + pft_set_rules router \ + "set debug loud" \ + "set reassemble yes" \ + "set state-policy if-bound" \ + "table <rt_targets> { ${net_server2_4}.40/31 ${net_server2_4}.44 ${net_server2_6}::42:0/127 ${net_server2_6}::42:4 }" \ + "pass in on ${epair_tester}b \ + route-to { (${epair_server2}a <rt_targets>) } random \ + inet6 proto tcp \ + keep state" + + good_targets="${net_server2_6}::42:0 ${net_server2_6}::42:4" + bad_targets="${net_server2_6}::42:1" + check_random IPv6 "${good_targets}" "${bad_targets}" +} + +random_table_cleanup() +{ + pft_cleanup +} + +atf_test_case "random_prefix" "cleanup" + +random_prefix_head() +{ + atf_set descr 'Pool with random flag and a table for IPv4' + atf_set require.user root + atf_set require.progs python3 scapy +} + +random_prefix_body() +{ + pf_map_addr_common + + # The "random" flag will pick random hosts from given prefix. + # The choice being random makes testing it non-trivial. We do 10 + # attempts to have each target chosen. Hopefully this is enough to have + # this test pass often enough. + + jexec router pfctl -e + pft_set_rules router \ + "set debug loud" \ + "set reassemble yes" \ + "set state-policy if-bound" \ + "pass in on ${epair_tester}b \ + route-to { (${epair_server2}a ${net_server2_6}::42:0/127) } random \ + inet6 proto tcp \ + keep state" + + good_targets="${net_server2_6}::42:0 ${net_server2_6}::42:1" + check_random IPv6 "${good_targets}" +} + +random_prefix_cleanup() +{ + pft_cleanup +} + +atf_test_case "prefer_ipv6_nexthop_single_ipv4" "cleanup" + +prefer_ipv6_nexthop_single_ipv4_head() +{ + atf_set descr 'prefer-ipv6-nexthop option for a single IPv4 gateway' + atf_set require.user root + atf_set require.progs python3 scapy +} + +prefer_ipv6_nexthop_single_ipv4_body() +{ + pf_map_addr_common + + # Basic forwarding test for prefer-ipv6-nexthop pool option. + # A single IPv4 gateway will work only for IPv4 traffic. + + jexec router pfctl -e + pft_set_rules router \ + "set reassemble yes" \ + "set state-policy if-bound" \ + "pass in on ${epair_tester}b \ + route-to (${epair_server1}a ${net_server1_4_host_server}) prefer-ipv6-nexthop \ + proto tcp \ + keep state" + + atf_check -s exit:0 ${common_dir}/pft_ping.py \ + --sendif ${epair_tester}a --replyif ${epair_tester}a \ + --fromaddr ${net_clients_4}.1 --to ${host_server_4} \ + --ping-type=tcp3way --send-sport=4201 \ + + atf_check -s exit:1 ${common_dir}/pft_ping.py \ + --sendif ${epair_tester}a --replyif ${epair_tester}a \ + --fromaddr ${net_clients_6}::1 --to ${host_server_6} \ + --ping-type=tcp3way --send-sport=4202 + + states=$(mktemp) || exit 1 + jexec router pfctl -qvvss | normalize_pfctl_s > $states + + for state_regexp in \ + "${epair_tester}b tcp ${host_server_4}:9 <- ${net_clients_4}.1:4201 .* route-to: ${net_server1_4_host_server}@${epair_server1}a" \ + ; do + grep -qE "${state_regexp}" $states || atf_fail "State not found for '${state_regexp}'" + done + + # The IPv6 packet could not have been routed over IPv4 gateway. + atf_check -o "match:map-failed +1 +" -x "jexec router pfctl -qvvsi 2> /dev/null" +} + +prefer_ipv6_nexthop_single_ipv4_cleanup() +{ + pft_cleanup +} + +atf_test_case "prefer_ipv6_nexthop_single_ipv6" "cleanup" + +prefer_ipv6_nexthop_single_ipv6_head() +{ + atf_set descr 'prefer-ipv6-nexthop option for a single IPv6 gateway' + atf_set require.user root + atf_set require.progs python3 scapy +} + +prefer_ipv6_nexthop_single_ipv6_body() +{ + pf_map_addr_common + + # Basic forwarding test for prefer-ipv6-nexthop pool option. + # A single IPve gateway will work both for IPv4 and IPv6 traffic. + + jexec router pfctl -e + pft_set_rules router \ + "set reassemble yes" \ + "set state-policy if-bound" \ + "pass in on ${epair_tester}b \ + route-to (${epair_server1}a ${net_server1_6_host_server}) prefer-ipv6-nexthop \ + proto tcp \ + keep state" + + atf_check -s exit:0 ${common_dir}/pft_ping.py \ + --sendif ${epair_tester}a --replyif ${epair_tester}a \ + --fromaddr ${net_clients_4}.1 --to ${host_server_4} \ + --ping-type=tcp3way --send-sport=4201 \ + + atf_check -s exit:0 ${common_dir}/pft_ping.py \ + --sendif ${epair_tester}a --replyif ${epair_tester}a \ + --fromaddr ${net_clients_6}::1 --to ${host_server_6} \ + --ping-type=tcp3way --send-sport=4202 + + states=$(mktemp) || exit 1 + jexec router pfctl -qvvss | normalize_pfctl_s > $states + + for state_regexp in \ + "${epair_tester}b tcp ${host_server_4}:9 <- ${net_clients_4}.1:4201 .* route-to: ${net_server1_6_host_server}@${epair_server1}a" \ + "${epair_tester}b tcp ${host_server_6}\[9\] <- ${net_clients_6}::1\[4202\] .* route-to: ${net_server1_6_host_server}@${epair_server1}a" \ + ; do + grep -qE "${state_regexp}" $states || atf_fail "State not found for '${state_regexp}'" + done +} + +prefer_ipv6_nexthop_single_ipv6_cleanup() +{ + pft_cleanup +} + +atf_test_case "prefer_ipv6_nexthop_mixed_af_roundrobin_ipv4" "cleanup" + +prefer_ipv6_nexthop_mixed_af_roundrobin_ipv4_head() +{ + atf_set descr 'prefer-ipv6-nexthop option for multiple gateways of mixed AF with prefixes and tables, round robin selection, for IPv4 packets' + atf_set require.user root + atf_set require.progs python3 scapy +} + +prefer_ipv6_nexthop_mixed_af_roundrobin_ipv4_body() +{ + pf_map_addr_common + + # pf_map_addr() starts iterating over hosts of the pool from the 2nd + # host. This behaviour was here before adding prefer-ipv6-nexthop + # support, we test for it. Some targets are hosts and some are tables. + # Those are iterated too. Finally the iteration loops back + # to the beginning of the pool. Send out IPv4 probes. They will use all + # IPv4 and IPv6 addresses from the pool. + + jexec router pfctl -e + pft_set_rules router \ + "set reassemble yes" \ + "set state-policy if-bound" \ + "table <rt_targets> { ${net_server2_4}.40/31 ${net_server2_4}.44 ${net_server2_6}::42:4/127 }" \ + "pass in on ${epair_tester}b \ + route-to { \ + (${epair_server1}a ${net_server1_6_host_server}) \ + (${epair_server1}a ${net_server1_6}::42:0/127) \ + (${epair_server2}a ${net_server2_4_host_server}) \ + (${epair_server2}a <rt_targets_empty>) \ + (${epair_server1}a ${net_server1_4}.24/31) \ + (${epair_server2}a <rt_targets>) \ + } prefer-ipv6-nexthop \ + proto tcp \ + keep state" + + for port in $(seq 1 12); do + port=$((4200 + port)) + atf_check -s exit:0 ${common_dir}/pft_ping.py \ + --sendif ${epair_tester}a --replyif ${epair_tester}a \ + --fromaddr ${net_clients_4}.1 --to ${host_server_4} \ + --ping-type=tcp3way --send-sport=${port} + done + + states=$(mktemp) || exit 1 + jexec router pfctl -qvvss | normalize_pfctl_s > $states + + for state_regexp in \ + "${epair_tester}b tcp ${host_server_4}:9 <- ${net_clients_4}.1:4201 .* route-to: ${net_server1_6}::42:0@${epair_server1}a" \ + "${epair_tester}b tcp ${host_server_4}:9 <- ${net_clients_4}.1:4202 .* route-to: ${net_server1_6}::42:1@${epair_server1}a" \ + "${epair_tester}b tcp ${host_server_4}:9 <- ${net_clients_4}.1:4203 .* route-to: ${net_server2_4_host_server}@${epair_server2}a" \ + "${epair_tester}b tcp ${host_server_4}:9 <- ${net_clients_4}.1:4204 .* route-to: ${net_server1_4}.24@${epair_server1}a" \ + "${epair_tester}b tcp ${host_server_4}:9 <- ${net_clients_4}.1:4205 .* route-to: ${net_server1_4}.25@${epair_server1}a" \ + "${epair_tester}b tcp ${host_server_4}:9 <- ${net_clients_4}.1:4206 .* route-to: ${net_server2_6}::42:4@${epair_server2}a" \ + "${epair_tester}b tcp ${host_server_4}:9 <- ${net_clients_4}.1:4207 .* route-to: ${net_server2_6}::42:5@${epair_server2}a" \ + "${epair_tester}b tcp ${host_server_4}:9 <- ${net_clients_4}.1:4208 .* route-to: ${net_server2_4}.40@${epair_server2}a" \ + "${epair_tester}b tcp ${host_server_4}:9 <- ${net_clients_4}.1:4209 .* route-to: ${net_server2_4}.41@${epair_server2}a" \ + "${epair_tester}b tcp ${host_server_4}:9 <- ${net_clients_4}.1:4210 .* route-to: ${net_server2_4}.44@${epair_server2}a" \ + "${epair_tester}b tcp ${host_server_4}:9 <- ${net_clients_4}.1:4211 .* route-to: ${net_server1_6_host_server}@${epair_server1}a" \ + "${epair_tester}b tcp ${host_server_4}:9 <- ${net_clients_4}.1:4212 .* route-to: ${net_server1_6}::42:0@${epair_server1}a" \ + ; do + grep -qE "${state_regexp}" $states || atf_fail "State not found for '${state_regexp}'" + done +} + +prefer_ipv6_nexthop_mixed_af_roundrobin_ipv4_cleanup() +{ + pft_cleanup +} + +prefer_ipv6_nexthop_mixed_af_roundrobin_ipv6_head() +{ + atf_set descr 'prefer-ipv6-nexthop option for multiple gateways of mixed AF with prefixes and tables, round-robin selection, for IPv6 packets' + atf_set require.user root + atf_set require.progs python3 scapy +} + +prefer_ipv6_nexthop_mixed_af_roundrobin_ipv6_body() +{ + pf_map_addr_common + + # The "random" flag will pick random hosts from the table but will + # not dive into prefixes, always choosing the 0th address. + # Proper address family will be choosen. The choice being random makes + # testing it non-trivial. We do 10 attempts to have each target chosen. + # Hopefully this is enough to have this test pass often enough. + + # pf_map_addr() starts iterating over hosts of the pool from the 2nd + # host. This behaviour was here before adding prefer-ipv6-nexthop + # support, we test for it. Some targets are hosts and some are tables. + # Those are iterated too. Finally the iteration loops back + # to the beginning of the pool. Send out IPv6 probes. They will use only + # IPv6 addresses from the pool. + + jexec router pfctl -e + pft_set_rules router \ + "set reassemble yes" \ + "set state-policy if-bound" \ + "table <rt_targets> { ${net_server2_4}.40/31 ${net_server2_4}.44 ${net_server2_6}::42:4/127 }" \ + "pass in on ${epair_tester}b \ + route-to { \ + (${epair_server1}a ${net_server1_6_host_server}) \ + (${epair_server1}a ${net_server1_6}::42:0/127) \ + (${epair_server2}a ${net_server2_4_host_server}) \ + (${epair_server2}a <rt_targets_empty>) \ + (${epair_server1}a ${net_server1_4}.24/31) \ + (${epair_server2}a <rt_targets>) \ + } prefer-ipv6-nexthop \ + proto tcp \ + keep state" + + for port in $(seq 1 6); do + port=$((4200 + port)) + atf_check -s exit:0 ${common_dir}/pft_ping.py \ + --sendif ${epair_tester}a --replyif ${epair_tester}a \ + --fromaddr ${net_clients_6}::1 --to ${host_server_6} \ + --ping-type=tcp3way --send-sport=${port} + done + + states=$(mktemp) || exit 1 + jexec router pfctl -qvvss | normalize_pfctl_s > $states + + for state_regexp in \ + "${epair_tester}b tcp ${host_server_6}\[9\] <- ${net_clients_6}::1\[4201\] .* route-to: ${net_server1_6}::42:0@${epair_server1}a" \ + "${epair_tester}b tcp ${host_server_6}\[9\] <- ${net_clients_6}::1\[4202\] .* route-to: ${net_server1_6}::42:1@${epair_server1}a" \ + "${epair_tester}b tcp ${host_server_6}\[9\] <- ${net_clients_6}::1\[4203\] .* route-to: ${net_server2_6}::42:4@${epair_server2}a" \ + "${epair_tester}b tcp ${host_server_6}\[9\] <- ${net_clients_6}::1\[4204\] .* route-to: ${net_server2_6}::42:5@${epair_server2}a" \ + "${epair_tester}b tcp ${host_server_6}\[9\] <- ${net_clients_6}::1\[4205\] .* route-to: ${net_server1_6_host_server}@${epair_server1}a" \ + "${epair_tester}b tcp ${host_server_6}\[9\] <- ${net_clients_6}::1\[4206\] .* route-to: ${net_server1_6}::42:0@${epair_server1}a" \ + ; do + grep -qE "${state_regexp}" $states || atf_fail "State not found for '${state_regexp}'" + done +} + +prefer_ipv6_nexthop_mixed_af_roundrobin_ipv6_cleanup() +{ + pft_cleanup +} + +atf_test_case "prefer_ipv6_nexthop_mixed_af_random_ipv4" "cleanup" + +prefer_ipv6_nexthop_mixed_af_random_table_ipv4_head() +{ + atf_set descr 'prefer-ipv6-nexthop option for a mixed-af table with random selection for IPv4 packets' + atf_set require.user root + atf_set require.progs python3 scapy +} + +prefer_ipv6_nexthop_mixed_af_random_table_ipv4_body() +{ + pf_map_addr_common + + # Similarly to the test "random_table" the algorithm will choose + # IP addresses from the table not diving into prefixes. + # *prefer*-ipv6-nexthop means that IPv6 nexthops are preferred, + # so IPv4 ones will not be chosen as long as there are IPv6 ones + # available. With this tested there is no need for a test for IPv6-only + # next-hops table. + + jexec router pfctl -e + pft_set_rules router \ + "set reassemble yes" \ + "set state-policy if-bound" \ + "table <rt_targets> { ${net_server2_4}.40/31 ${net_server2_4}.44 ${net_server2_6}::42:0/127 ${net_server2_6}::42:4 }" \ + "pass in on ${epair_tester}b \ + route-to { (${epair_server2}a <rt_targets>) } random prefer-ipv6-nexthop \ + proto tcp \ + keep state" + + good_targets="${net_server2_6}::42:0 ${net_server2_6}::42:4" + bad_targets="${net_server2_4}.40 ${net_server2_4}.41 ${net_server2_4}.44 ${net_server2_6}::42:1" + check_random IPv4 "${good_targets}" "${bad_targets}" +} + +prefer_ipv6_nexthop_mixed_af_random_table_ipv4_cleanup() +{ + pft_cleanup +} + +prefer_ipv6_nexthop_ipv4_random_table_ipv4_head() +{ + atf_set descr 'prefer-ipv6-nexthop option for an IPv4-only table with random selection for IPv4 packets' + atf_set require.user root + atf_set require.progs python3 scapy +} + +prefer_ipv6_nexthop_ipv4_random_table_ipv4_body() +{ + pf_map_addr_common + + # Similarly to the test pf_map_addr:random_table the algorithm will + # choose IP addresses from the table not diving into prefixes. + # There are no IPv6 nexthops in the table, so the algorithm will + # fall back to IPv4. + + jexec router pfctl -e + pft_set_rules router \ + "set reassemble yes" \ + "set state-policy if-bound" \ + "table <rt_targets> { ${net_server2_4}.40/31 ${net_server2_4}.44 }" \ + "pass in on ${epair_tester}b \ + route-to { (${epair_server2}a <rt_targets>) } random prefer-ipv6-nexthop \ + proto tcp \ + keep state" + + good_targets="${net_server2_4}.40 ${net_server2_4}.44" + bad_targets="${net_server2_4}.41" + check_random IPv4 "${good_targets}" "${bad_targets}" +} + +prefer_ipv6_nexthop_ipv4_random_table_ipv4_cleanup() +{ + pft_cleanup +} + +prefer_ipv6_nexthop_ipv4_random_table_ipv6_head() +{ + atf_set descr 'prefer-ipv6-nexthop option for an IPv4-only table with random selection for IPv6 packets' + atf_set require.user root + atf_set require.progs python3 scapy +} + +prefer_ipv6_nexthop_ipv4_random_table_ipv6_body() +{ + pf_map_addr_common + + # IPv6 packets can't be forwarded over IPv4 next-hops. + # The failure happens in pf_map_addr() and increases the respective + # error counter. + + jexec router pfctl -e + pft_set_rules router \ + "set reassemble yes" \ + "set state-policy if-bound" \ + "table <rt_targets> { ${net_server2_4}.40/31 ${net_server2_4}.44 }" \ + "pass in on ${epair_tester}b \ + route-to { (${epair_server2}a <rt_targets>) } random prefer-ipv6-nexthop \ + proto tcp \ + keep state" + + atf_check -s exit:1 ${common_dir}/pft_ping.py \ + --sendif ${epair_tester}a --replyif ${epair_tester}a \ + --fromaddr ${net_clients_6}::1 --to ${host_server_6} \ + --ping-type=tcp3way --send-sport=4201 + + atf_check -o "match:map-failed +1 +" -x "jexec router pfctl -qvvsi 2> /dev/null" +} + +prefer_ipv6_nexthop_ipv4_random_table_ipv6_cleanup() +{ + pft_cleanup +} + +prefer_ipv6_nexthop_ipv6_random_prefix_ipv4_head() +{ + atf_set descr 'prefer-ipv6-nexthop option for an IPv6 prefix with random selection for IPv4 packets' + atf_set require.user root + atf_set require.progs python3 scapy +} + +prefer_ipv6_nexthop_ipv6_random_prefix_ipv4_body() +{ + pf_map_addr_common + + jexec router pfctl -e + pft_set_rules router \ + "set reassemble yes" \ + "set state-policy if-bound" \ + "pass in on ${epair_tester}b \ + route-to { (${epair_server2}a ${net_server2_6}::42:0/127) } random prefer-ipv6-nexthop \ + proto tcp \ + keep state" + + good_targets="${net_server2_6}::42:0 ${net_server2_6}::42:1" + check_random IPv4 "${good_targets}" +} + +prefer_ipv6_nexthop_ipv6_random_prefix_ipv4_cleanup() +{ + pft_cleanup +} + +prefer_ipv6_nexthop_ipv6_random_prefix_ipv6_head() +{ + atf_set descr 'prefer-ipv6-nexthop option for an IPv6 prefix with random selection for IPv6 packets' + atf_set require.user root + atf_set require.progs python3 scapy +} + +prefer_ipv6_nexthop_ipv6_random_prefix_ipv6_body() +{ + pf_map_addr_common + + jexec router pfctl -e + pft_set_rules router \ + "set reassemble yes" \ + "set state-policy if-bound" \ + "pass in on ${epair_tester}b \ + route-to { (${epair_server2}a ${net_server2_6}::42:0/127) } random prefer-ipv6-nexthop \ + proto tcp \ + keep state" + + good_targets="${net_server2_6}::42:0 ${net_server2_6}::42:1" + check_random IPv6 "${good_targets}" +} + +prefer_ipv6_nexthop_ipv6_random_prefix_ipv6_cleanup() +{ + pft_cleanup +} + +prefer_ipv6_nexthop_ipv4_random_prefix_ipv4_head() +{ + atf_set descr 'prefer-ipv6-nexthop option for an IPv4 prefix with random selection for IPv4 packets' + atf_set require.user root + atf_set require.progs python3 scapy +} + +prefer_ipv6_nexthop_ipv4_random_prefix_ipv4_body() +{ + pf_map_addr_common + + jexec router pfctl -e + pft_set_rules router \ + "set reassemble yes" \ + "set state-policy if-bound" \ + "pass in on ${epair_tester}b \ + route-to { (${epair_server2}a ${net_server2_4}.40/31) } random prefer-ipv6-nexthop \ + proto tcp \ + keep state" + + good_targets="${net_server2_4}.40 ${net_server2_4}.41" + check_random IPv4 "${good_targets}" +} + +prefer_ipv6_nexthop_ipv4_random_prefix_ipv4_cleanup() +{ + pft_cleanup +} + +prefer_ipv6_nexthop_ipv4_random_prefix_ipv6_head() +{ + atf_set descr 'prefer-ipv6-nexthop option for an IPv4 prefix with random selection for IPv6 packets' + atf_set require.user root + atf_set require.progs python3 scapy +} + +prefer_ipv6_nexthop_ipv4_random_prefix_ipv6_body() +{ + pf_map_addr_common + + # IPv6 packets can't be forwarded over IPv4 next-hops. + # The failure happens in pf_map_addr() and increases the respective + # error counter. + + jexec router pfctl -e + pft_set_rules router \ + "set reassemble yes" \ + "set state-policy if-bound" \ + "pass in on ${epair_tester}b \ + route-to { (${epair_server2}a ${net_server2_4}.40/31) } random prefer-ipv6-nexthop \ + proto tcp \ + keep state" + + atf_check -s exit:1 ${common_dir}/pft_ping.py \ + --sendif ${epair_tester}a --replyif ${epair_tester}a \ + --fromaddr ${net_clients_6}::1 --to ${host_server_6} \ + --ping-type=tcp3way --send-sport=4201 + + atf_check -o "match:map-failed +1 +" -x "jexec router pfctl -qvvsi 2> /dev/null" +} + +prefer_ipv6_nexthop_ipv4_random_prefix_ipv6_cleanup() +{ + pft_cleanup +} + atf_init_test_cases() { atf_add_test_case "v4" @@ -995,5 +1666,25 @@ atf_init_test_cases() atf_add_test_case "sticky" atf_add_test_case "ttl" atf_add_test_case "empty_pool" + # Tests for pf_map_addr() without prefer-ipv6-nexthop atf_add_test_case "table_loop" + atf_add_test_case "roundrobin" + atf_add_test_case "random_table" + atf_add_test_case "random_prefix" + # Tests for pf_map_addr() without prefer-ipv6-nexthop + # Next hop is a Single IP address + atf_add_test_case "prefer_ipv6_nexthop_single_ipv4" + atf_add_test_case "prefer_ipv6_nexthop_single_ipv6" + # Next hop is tables and prefixes, accessed by the round-robin algorithm + atf_add_test_case "prefer_ipv6_nexthop_mixed_af_roundrobin_ipv4" + atf_add_test_case "prefer_ipv6_nexthop_mixed_af_roundrobin_ipv6" + # Next hop is a table, accessed by the random algorithm + atf_add_test_case "prefer_ipv6_nexthop_mixed_af_random_table_ipv4" + atf_add_test_case "prefer_ipv6_nexthop_ipv4_random_table_ipv4" + atf_add_test_case "prefer_ipv6_nexthop_ipv4_random_table_ipv6" + # Next hop is a prefix, accessed by the random algorithm + atf_add_test_case "prefer_ipv6_nexthop_ipv6_random_prefix_ipv4" + atf_add_test_case "prefer_ipv6_nexthop_ipv6_random_prefix_ipv6" + atf_add_test_case "prefer_ipv6_nexthop_ipv4_random_prefix_ipv4" + atf_add_test_case "prefer_ipv6_nexthop_ipv4_random_prefix_ipv6" } diff --git a/tests/sys/netpfil/pf/sctp.sh b/tests/sys/netpfil/pf/sctp.sh index 57dcdad1d866..78055f5a9dd2 100644 --- a/tests/sys/netpfil/pf/sctp.sh +++ b/tests/sys/netpfil/pf/sctp.sh @@ -673,6 +673,9 @@ pfsync_body() atf_fail "Initial SCTP connection failed" fi + # Give pfsync some time to do its thing + sleep 1 + # Verify that two has the connection too state=$(jexec ${j}two pfctl -ss | grep sctp) if [ -z "${state}" ]; diff --git a/tests/sys/netpfil/pf/src_track.sh b/tests/sys/netpfil/pf/src_track.sh index ae60a5df809b..e12d0464ee8c 100755 --- a/tests/sys/netpfil/pf/src_track.sh +++ b/tests/sys/netpfil/pf/src_track.sh @@ -526,10 +526,12 @@ mixed_af_body() "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 \ - inet6 proto tcp from any to 64:ff9b::/96 \ - af-to inet from ${net_clients_4}.0/${net_clients_4_mask} round-robin sticky-address" + route-to { \ + (${epair_server1}a ${net_server1_4_host_server}) \ + (${epair_server2}a ${net_server2_6_host_server}) \ + } prefer-ipv6-nexthop sticky-address \ + inet6 proto tcp from any to 64:ff9b::/96 \ + af-to inet from ${net_clients_4}.0/${net_clients_4_mask} round-robin sticky-address" atf_check -s exit:0 ${common_dir}/pft_ping.py \ --sendif ${epair_tester}a \ @@ -538,6 +540,20 @@ mixed_af_body() --to 64:ff9b::192.0.2.100 \ --ping-type=tcp3way \ --send-sport=4201 + atf_check -s exit:0 ${common_dir}/pft_ping.py \ + --sendif ${epair_tester}a \ + --replyif ${epair_tester}a \ + --fromaddr 2001:db8:44::1 \ + --to 64:ff9b::192.0.2.100 \ + --ping-type=tcp3way \ + --send-sport=4202 + atf_check -s exit:0 ${common_dir}/pft_ping.py \ + --sendif ${epair_tester}a \ + --replyif ${epair_tester}a \ + --fromaddr 2001:db8:44::2 \ + --to 64:ff9b::192.0.2.100 \ + --ping-type=tcp3way \ + --send-sport=4203 states=$(mktemp) || exit 1 jexec router pfctl -qvvss | normalize_pfctl_s > $states @@ -546,16 +562,22 @@ mixed_af_body() # States are checked for proper route-to information. # The route-to gateway is IPv4. + # FIXME: Sticky-address is broken for af-to pools! + # The SN is created but apparently not used, as seen in states. for state_regexp in \ - "${epair_tester}b tcp 203.0.113.0:4201 \(2001:db8:44::1\[4201\]\) -> 192.0.2.100:9 \(64:ff9b::c000:264\[9\]\) .* route-to: 198.51.100.18@${epair_server1}a" \ + "${epair_tester}b tcp 203.0.113.0:4201 \(2001:db8:44::1\[4201\]\) -> 192.0.2.100:9 \(64:ff9b::c000:264\[9\]\) .* route-to: 2001:db8:4202::2@${epair_server2}a" \ + "${epair_tester}b tcp 203.0.113.1:4202 \(2001:db8:44::1\[4202\]\) -> 192.0.2.100:9 \(64:ff9b::c000:264\[9\]\) .* route-to: 2001:db8:4202::2@${epair_server2}a" \ + "${epair_tester}b tcp 203.0.113.2:4203 \(2001:db8:44::2\[4203\]\) -> 192.0.2.100:9 \(64:ff9b::c000:264\[9\]\) .* route-to: 198.51.100.18@${epair_server1}a" \ ; do grep -qE "${state_regexp}" $states || atf_fail "State not found for '${state_regexp}'" done # Source nodes map IPv6 source address onto IPv4 gateway and IPv4 SNAT address. for node_regexp in \ - '2001:db8:44::1 -> 203.0.113.0 .* states 1, .* NAT/RDR sticky-address' \ - '2001:db8:44::1 -> 198.51.100.18 .* states 1, .* route sticky-address' \ + '2001:db8:44::2 -> 203.0.113.2 .* states 1, .* NAT/RDR sticky-address' \ + '2001:db8:44::2 -> 198.51.100.18 .* states 1, .* route sticky-address' \ + '2001:db8:44::1 -> 203.0.113.0 .* states 2, .* NAT/RDR sticky-address' \ + '2001:db8:44::1 -> 2001:db8:4202::2 .* states 2, .* route sticky-address' \ ; do grep -qE "${node_regexp}" $nodes || atf_fail "Source node not found for '${node_regexp}'" done diff --git a/tests/sys/netpfil/pf/table.sh b/tests/sys/netpfil/pf/table.sh index c773518e95e4..69fe12fc9804 100644 --- a/tests/sys/netpfil/pf/table.sh +++ b/tests/sys/netpfil/pf/table.sh @@ -641,9 +641,31 @@ large_body() -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 + if [ $actual -ne $expected ]; then atf_fail "Unexpected number of table entries $expected $acual" fi + + # The second pass should work too, but confirm we've inserted everything + atf_check -s exit:0 \ + -e match:"0/${expected} addresses added." \ + jexec alcatraz pfctl -t foo -T add -f ${pwd}/foo.lst + + echo '42.42.42.42' >> ${pwd}/foo.lst + expected=$((${expected} + 1)) + + # And we can also insert one additional address + atf_check -s exit:0 \ + -e match:"1/${expected} addresses added." \ + jexec alcatraz pfctl -t foo -T add -f ${pwd}/foo.lst + + # Try to delete one address + atf_check -s exit:0 \ + -e match:"1/1 addresses deleted." \ + jexec alcatraz pfctl -t foo -T delete 42.42.42.42 + # And again, for the same address + atf_check -s exit:0 \ + -e match:"0/1 addresses deleted." \ + jexec alcatraz pfctl -t foo -T delete 42.42.42.42 } large_cleanup() @@ -651,6 +673,80 @@ large_cleanup() pft_cleanup } +atf_test_case "show_recursive" "cleanup" +show_recursive_head() +{ + atf_set descr 'Test displaying tables in every anchor' + atf_set require.user root +} + +show_recursive_body() +{ + pft_init + + vnet_mkjail alcatraz + + pft_set_rules alcatraz \ + + (echo "table <bar> persist" + echo "block in quick from <bar> to any" + ) | jexec alcatraz pfctl -a anchorage -f - + + pft_set_rules noflush alcatraz \ + "table <foo> counters { 192.0.2.1 }" \ + "pass in from <foo>" \ + "anchor anchorage" + + jexec alcatraz pfctl -sr -a "*" + + atf_check -s exit:0 -e ignore -o match:'-pa-r-- bar@anchorage' \ + jexec alcatraz pfctl -v -a "*" -sT + atf_check -s exit:0 -e ignore -o match:'--a-r-C foo' \ + jexec alcatraz pfctl -v -a "*" -sT +} + +show_recursive_cleanup() +{ + pft_cleanup +} + +atf_test_case "in_anchor" "cleanup" +in_anchor_head() +{ + atf_set descr 'Test declaring tables in anchors' + atf_set require.user root +} + +in_anchor_body() +{ + pft_init + + epair_send=$(vnet_mkepair) + ifconfig ${epair_send}a 192.0.2.1/24 up + + vnet_mkjail alcatraz ${epair_send}b + jexec alcatraz ifconfig ${epair_send}b 192.0.2.2/24 up + + jexec alcatraz pfctl -e + + pft_set_rules alcatraz \ + "block all" \ + "anchor \"foo\" {\n + table <bar> counters { 192.0.2.1 }\n + pass in from <bar>\n + }\n" + + atf_check -s exit:0 -o ignore ping -c 3 192.0.2.2 + + jexec alcatraz pfctl -sr -a "*" -vv + jexec alcatraz pfctl -sT -a "*" -vv +} + +in_anchor_cleanup() +{ + pft_cleanup +} + atf_init_test_cases() { atf_add_test_case "v4_counters" @@ -667,4 +763,6 @@ atf_init_test_cases() atf_add_test_case "anchor" atf_add_test_case "flush" atf_add_test_case "large" + atf_add_test_case "show_recursive" + atf_add_test_case "in_anchor" } diff --git a/tests/sys/netpfil/pf/utils.subr b/tests/sys/netpfil/pf/utils.subr index 3f8d437920f9..a48f26653f8c 100644 --- a/tests/sys/netpfil/pf/utils.subr +++ b/tests/sys/netpfil/pf/utils.subr @@ -274,8 +274,8 @@ setup_router_server_ipv6() jexec server inetd -p ${PWD}/inetd.pid $inetd_conf } -# Create a router and 2 server jails for nat64 and rfc5549 test cases. -# The router is connected to servers, both are dual-stack, and to the +# Create a router and 2 server jails for nat64 and prefer-ipv6-nexthop test +# cases. The router is connected to servers, both are dual-stack, and to the # tester jail. All links are dual stack. setup_router_server_nat64() { diff --git a/tests/sys/opencrypto/blake2_test.c b/tests/sys/opencrypto/blake2_test.c index b397f8a8ec4c..0e6943d150cf 100644 --- a/tests/sys/opencrypto/blake2_test.c +++ b/tests/sys/opencrypto/blake2_test.c @@ -126,15 +126,12 @@ do_cryptop(int fd, int ses, size_t inlen, void *out) } static void -test_blake2b_vectors(const char *devname, const char *modname) +test_blake2b_vectors(const char *devname) { uint8_t hash[BLAKE2B_OUTBYTES]; int crid, fd, ses; size_t i; - ATF_REQUIRE_KERNEL_MODULE(modname); - ATF_REQUIRE_KERNEL_MODULE("cryptodev"); - initialize_constant_buffers(); fd = get_handle_fd(); crid = lookup_crid(fd, devname); @@ -150,15 +147,12 @@ test_blake2b_vectors(const char *devname, const char *modname) } static void -test_blake2s_vectors(const char *devname, const char *modname) +test_blake2s_vectors(const char *devname) { uint8_t hash[BLAKE2S_OUTBYTES]; int crid, fd, ses; size_t i; - ATF_REQUIRE_KERNEL_MODULE(modname); - ATF_REQUIRE_KERNEL_MODULE("cryptodev"); - initialize_constant_buffers(); fd = get_handle_fd(); crid = lookup_crid(fd, devname); @@ -173,33 +167,49 @@ test_blake2s_vectors(const char *devname, const char *modname) } } -ATF_TC_WITHOUT_HEAD(blake2b_vectors); +ATF_TC(blake2b_vectors); +ATF_TC_HEAD(blake2b_vectors, tc) +{ + atf_tc_set_md_var(tc, "require.kmods", "nexus/cryptosoft cryptodev"); +} ATF_TC_BODY(blake2b_vectors, tc) { ATF_REQUIRE_SYSCTL_INT("kern.crypto.allow_soft", 1); - test_blake2b_vectors("cryptosoft0", "nexus/cryptosoft"); + test_blake2b_vectors("cryptosoft0"); } -ATF_TC_WITHOUT_HEAD(blake2s_vectors); +ATF_TC(blake2s_vectors); +ATF_TC_HEAD(blake2s_vectors, tc) +{ + atf_tc_set_md_var(tc, "require.kmods", "nexus/cryptosoft cryptodev"); +} ATF_TC_BODY(blake2s_vectors, tc) { ATF_REQUIRE_SYSCTL_INT("kern.crypto.allow_soft", 1); - test_blake2s_vectors("cryptosoft0", "nexus/cryptosoft"); + test_blake2s_vectors("cryptosoft0"); } #if defined(__i386__) || defined(__amd64__) -ATF_TC_WITHOUT_HEAD(blake2b_vectors_x86); +ATF_TC(blake2b_vectors_x86); +ATF_TC_HEAD(blake2b_vectors_x86, tc) +{ + atf_tc_set_md_var(tc, "require.kmods", "nexus/blake2 cryptodev"); +} ATF_TC_BODY(blake2b_vectors_x86, tc) { ATF_REQUIRE_SYSCTL_INT("kern.crypto.allow_soft", 1); - test_blake2b_vectors("blaketwo0", "nexus/blake2"); + test_blake2b_vectors("blaketwo0"); } -ATF_TC_WITHOUT_HEAD(blake2s_vectors_x86); +ATF_TC(blake2s_vectors_x86); +ATF_TC_HEAD(blake2s_vectors_x86, tc) +{ + atf_tc_set_md_var(tc, "require.kmods", "nexus/blake2 cryptodev"); +} ATF_TC_BODY(blake2s_vectors_x86, tc) { ATF_REQUIRE_SYSCTL_INT("kern.crypto.allow_soft", 1); - test_blake2s_vectors("blaketwo0", "nexus/blake2"); + test_blake2s_vectors("blaketwo0"); } #endif diff --git a/tests/sys/opencrypto/poly1305_test.c b/tests/sys/opencrypto/poly1305_test.c index ab455784efba..c51ffacfd1cc 100644 --- a/tests/sys/opencrypto/poly1305_test.c +++ b/tests/sys/opencrypto/poly1305_test.c @@ -350,16 +350,13 @@ do_cryptop(int fd, int ses, const void *inp, size_t inlen, void *out) } static void -test_rfc7539_poly1305_vectors(int crid, const char *modname) +test_rfc7539_poly1305_vectors(int crid) { uint8_t comptag[POLY1305_HASH_LEN], exptag[POLY1305_HASH_LEN], key[POLY1305_KEY_LEN], msg[512]; int fd, ses; size_t i; - ATF_REQUIRE_KERNEL_MODULE(modname); - ATF_REQUIRE_KERNEL_MODULE("cryptodev"); - fd = get_handle_fd(); for (i = 0; i < nitems(rfc7539_kats); i++) { @@ -378,11 +375,15 @@ test_rfc7539_poly1305_vectors(int crid, const char *modname) } } -ATF_TC_WITHOUT_HEAD(poly1305_vectors); +ATF_TC(poly1305_vectors); +ATF_TC_HEAD(poly1305_vectors, tc) +{ + atf_tc_set_md_var(tc, "require.kmods", "nexus/cryptosoft cryptodev"); +} ATF_TC_BODY(poly1305_vectors, tc) { ATF_REQUIRE_SYSCTL_INT("kern.crypto.allow_soft", 1); - test_rfc7539_poly1305_vectors(CRYPTO_FLAG_SOFTWARE, "nexus/cryptosoft"); + test_rfc7539_poly1305_vectors(CRYPTO_FLAG_SOFTWARE); } ATF_TP_ADD_TCS(tp) diff --git a/tests/sys/sound/sndstat.c b/tests/sys/sound/sndstat.c index ed292b570429..bbf18aca2824 100644 --- a/tests/sys/sound/sndstat.c +++ b/tests/sys/sound/sndstat.c @@ -40,17 +40,11 @@ #include <stdlib.h> #include <unistd.h> -static void -load_dummy(void) -{ - if (kldload("snd_dummy.ko") < 0 && errno != EEXIST) - atf_tc_skip("snd_dummy.ko not found"); -} - ATF_TC(sndstat_nv); ATF_TC_HEAD(sndstat_nv, tc) { atf_tc_set_md_var(tc, "descr", "/dev/sndstat nvlist test"); + atf_tc_set_md_var(tc, "require.kmods", "snd_dummy"); } ATF_TC_BODY(sndstat_nv, tc) @@ -62,8 +56,6 @@ ATF_TC_BODY(sndstat_nv, tc) size_t nitems, nchans, i, j; int fd, rc, pchan, rchan; - load_dummy(); - if ((fd = open("/dev/sndstat", O_RDONLY)) < 0) atf_tc_skip("/dev/sndstat not found, load sound(4)"); @@ -223,6 +215,7 @@ ATF_TC(sndstat_udev); ATF_TC_HEAD(sndstat_udev, tc) { atf_tc_set_md_var(tc, "descr", "/dev/sndstat userdev interface test"); + atf_tc_set_md_var(tc, "require.kmods", "snd_dummy"); } ATF_TC_BODY(sndstat_udev, tc) @@ -234,8 +227,6 @@ ATF_TC_BODY(sndstat_udev, tc) size_t nitems, i; int fd, rc, pchan, rchan, n; - load_dummy(); - if ((fd = open("/dev/sndstat", O_RDWR)) < 0) atf_tc_skip("/dev/sndstat not found, load sound(4)"); diff --git a/tests/sys/vmm/vmm_cred_jail.sh b/tests/sys/vmm/vmm_cred_jail.sh index 5b02b5dc0b42..dd7907b15352 100644 --- a/tests/sys/vmm/vmm_cred_jail.sh +++ b/tests/sys/vmm/vmm_cred_jail.sh @@ -35,12 +35,10 @@ vmm_cred_jail_host_head() { atf_set "descr" "Tests deleting the host's VM from within a jail" atf_set "require.user" "root" + atf_set "require.kmods" "vmm" } vmm_cred_jail_host_body() { - if ! -c /dev/vmmctl; then - atf_skip "vmm is not loaded" - fi bhyvectl --vm=testvm --create vmm_mkjail myjail atf_check -s exit:1 -e ignore jexec myjail bhyvectl --vm=testvm --destroy @@ -56,12 +54,10 @@ vmm_cred_jail_other_head() { atf_set "descr" "Tests deleting a jail's VM from within another jail" atf_set "require.user" "root" + atf_set "require.kmods" "vmm" } vmm_cred_jail_other_body() { - if ! -c /dev/vmmctl; then - atf_skip "vmm is not loaded" - fi vmm_mkjail myjail1 vmm_mkjail myjail2 atf_check -s exit:0 jexec myjail1 bhyvectl --vm=testvm --create |