aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorEnji Cooper <ngie@FreeBSD.org>2017-02-04 18:06:09 +0000
committerEnji Cooper <ngie@FreeBSD.org>2017-02-04 18:06:09 +0000
commit9b3ece1c2eb92a881cb2553271e123382bfe31c1 (patch)
tree36a89226bd366ee1277c4707fe82cd271233b743 /tests
parent4421971444c1e90ecaf338bcc43b596911b2a472 (diff)
parent3c7ccf15c787dc25a1f5c0d781aac4d32430f5c7 (diff)
downloadsrc-9b3ece1c2eb92a881cb2553271e123382bfe31c1.tar.gz
src-9b3ece1c2eb92a881cb2553271e123382bfe31c1.zip
MFhead@r313243
Notes
Notes: svn path=/projects/netbsd-tests-upstream-01-2017/; revision=313244
Diffstat (limited to 'tests')
-rw-r--r--tests/sys/aio/aio_test.c336
-rwxr-xr-xtests/sys/geom/class/gate/ggate_test.sh62
-rw-r--r--tests/sys/kern/Makefile8
-rw-r--r--tests/sys/kern/libkern_crc32.c132
-rwxr-xr-xtests/sys/netinet/fibs_test.sh252
5 files changed, 643 insertions, 147 deletions
diff --git a/tests/sys/aio/aio_test.c b/tests/sys/aio/aio_test.c
index 33ccd7d3ab7b..ca8b41eec242 100644
--- a/tests/sys/aio/aio_test.c
+++ b/tests/sys/aio/aio_test.c
@@ -33,7 +33,7 @@
* reading it from a second descriptor using AIO. For some targets, the same
* fd is used for write and read (i.e., file, md device), but for others the
* operation is performed on a peer (pty, socket, fifo, etc). A timeout is
- * initiated to detect undo blocking. This test does not attempt to exercise
+ * initiated to detect undue blocking. This test does not attempt to exercise
* error cases or more subtle asynchronous behavior, just make sure that the
* basic operations work on some basic object types.
*/
@@ -74,6 +74,13 @@
#define GLOBAL_MAX 16384
#define BUFFER_MAX GLOBAL_MAX
+
+/*
+ * A completion function will block until the aio has completed, then return
+ * the result of the aio. errno will be set appropriately.
+ */
+typedef ssize_t (*completion)(struct aiocb*);
+
struct aio_context {
int ac_read_fd, ac_write_fd;
long ac_seed;
@@ -179,6 +186,45 @@ aio_context_init(struct aio_context *ac, int read_fd,
ac->ac_cleanup_arg = cleanup_arg;
}
+static ssize_t
+poll(struct aiocb *aio) {
+ int error;
+
+ while ((error = aio_error(aio)) == EINPROGRESS && !aio_timedout)
+ usleep(25000);
+ switch (error) {
+ case EINPROGRESS:
+ errno = EINTR;
+ return (-1);
+ case 0:
+ return (aio_return(aio));
+ default:
+ return (error);
+ }
+}
+
+static ssize_t
+suspend(struct aiocb *aio) {
+ const struct aiocb *const iocbs[] = {aio};
+ int error;
+
+ error = aio_suspend(iocbs, 1, NULL);
+ if (error == 0)
+ return (aio_return(aio));
+ else
+ return (error);
+}
+
+static ssize_t
+waitcomplete(struct aiocb *aio) {
+ struct aiocb *aiop;
+ ssize_t ret;
+
+ ret = aio_waitcomplete(&aiop, NULL);
+ ATF_REQUIRE_EQ(aio, aiop);
+ return (ret);
+}
+
/*
* Each tester can register a callback to clean up in the event the test
* fails. Preserve the value of errno so that subsequent calls to errx()
@@ -201,13 +247,11 @@ aio_cleanup(struct aio_context *ac)
* file descriptor.
*/
static void
-aio_write_test(struct aio_context *ac)
+aio_write_test(struct aio_context *ac, completion comp)
{
- struct aiocb aio, *aiop;
+ struct aiocb aio;
ssize_t len;
- ATF_REQUIRE_KERNEL_MODULE("aio");
-
bzero(&aio, sizeof(aio));
aio.aio_buf = ac->ac_buffer;
aio.aio_nbytes = ac->ac_buflen;
@@ -227,24 +271,23 @@ aio_write_test(struct aio_context *ac)
atf_tc_fail("aio_write failed: %s", strerror(errno));
}
- len = aio_waitcomplete(&aiop, NULL);
+ len = comp(&aio);
if (len < 0) {
if (errno == EINTR) {
if (aio_timedout) {
aio_cleanup(ac);
- atf_tc_fail("aio_waitcomplete timed out");
+ atf_tc_fail("aio timed out");
}
}
aio_cleanup(ac);
- atf_tc_fail("aio_waitcomplete failed: %s", strerror(errno));
+ atf_tc_fail("aio failed: %s", strerror(errno));
}
aio_timeout_stop();
if (len != ac->ac_buflen) {
aio_cleanup(ac);
- atf_tc_fail("aio_waitcomplete short write (%jd)",
- (intmax_t)len);
+ atf_tc_fail("aio short write (%jd)", (intmax_t)len);
}
}
@@ -253,13 +296,11 @@ aio_write_test(struct aio_context *ac)
* provided file descriptor.
*/
static void
-aio_read_test(struct aio_context *ac)
+aio_read_test(struct aio_context *ac, completion comp)
{
- struct aiocb aio, *aiop;
+ struct aiocb aio;
ssize_t len;
- ATF_REQUIRE_KERNEL_MODULE("aio");
-
bzero(ac->ac_buffer, ac->ac_buflen);
bzero(&aio, sizeof(aio));
aio.aio_buf = ac->ac_buffer;
@@ -273,30 +314,30 @@ aio_read_test(struct aio_context *ac)
if (errno == EINTR) {
if (aio_timedout) {
aio_cleanup(ac);
- atf_tc_fail("aio_write timed out");
+ atf_tc_fail("aio_read timed out");
}
}
aio_cleanup(ac);
atf_tc_fail("aio_read failed: %s", strerror(errno));
}
- len = aio_waitcomplete(&aiop, NULL);
+ len = comp(&aio);
if (len < 0) {
if (errno == EINTR) {
if (aio_timedout) {
aio_cleanup(ac);
- atf_tc_fail("aio_waitcomplete timed out");
+ atf_tc_fail("aio timed out");
}
}
aio_cleanup(ac);
- atf_tc_fail("aio_waitcomplete failed: %s", strerror(errno));
+ atf_tc_fail("aio failed: %s", strerror(errno));
}
aio_timeout_stop();
if (len != ac->ac_buflen) {
aio_cleanup(ac);
- atf_tc_fail("aio_waitcomplete short read (%jd)",
+ atf_tc_fail("aio short read (%jd)",
(intmax_t)len);
}
@@ -316,9 +357,11 @@ aio_read_test(struct aio_context *ac)
* Test with a classic file. Assumes we can create a moderate size temporary
* file.
*/
+#define FILE_LEN GLOBAL_MAX
+#define FILE_PATHNAME "testfile"
+#define FILE_TIMEOUT 30
struct aio_file_arg {
int afa_fd;
- char *afa_pathname;
};
static void
@@ -328,15 +371,12 @@ aio_file_cleanup(void *arg)
afa = arg;
close(afa->afa_fd);
- unlink(afa->afa_pathname);
+ unlink(FILE_PATHNAME);
}
-#define FILE_LEN GLOBAL_MAX
-#define FILE_TIMEOUT 30
-ATF_TC_WITHOUT_HEAD(aio_file_test);
-ATF_TC_BODY(aio_file_test, tc)
+static void
+aio_file_test(completion comp)
{
- char pathname[PATH_MAX];
struct aio_file_arg arg;
struct aio_context ac;
int fd;
@@ -344,25 +384,43 @@ ATF_TC_BODY(aio_file_test, tc)
ATF_REQUIRE_KERNEL_MODULE("aio");
ATF_REQUIRE_UNSAFE_AIO();
- strcpy(pathname, PATH_TEMPLATE);
- fd = mkstemp(pathname);
- ATF_REQUIRE_MSG(fd != -1, "mkstemp failed: %s", strerror(errno));
+ fd = open(FILE_PATHNAME, O_RDWR | O_CREAT);
+ ATF_REQUIRE_MSG(fd != -1, "open failed: %s", strerror(errno));
arg.afa_fd = fd;
- arg.afa_pathname = pathname;
aio_context_init(&ac, fd, fd, FILE_LEN,
FILE_TIMEOUT, aio_file_cleanup, &arg);
- aio_write_test(&ac);
- aio_read_test(&ac);
+ aio_write_test(&ac, comp);
+ aio_read_test(&ac, comp);
aio_file_cleanup(&arg);
}
+ATF_TC_WITHOUT_HEAD(file_poll);
+ATF_TC_BODY(file_poll, tc)
+{
+ aio_file_test(poll);
+}
+
+ATF_TC_WITHOUT_HEAD(file_suspend);
+ATF_TC_BODY(file_suspend, tc)
+{
+ aio_file_test(suspend);
+}
+
+ATF_TC_WITHOUT_HEAD(file_waitcomplete);
+ATF_TC_BODY(file_waitcomplete, tc)
+{
+ aio_file_test(waitcomplete);
+}
+
+#define FIFO_LEN 256
+#define FIFO_PATHNAME "testfifo"
+#define FIFO_TIMEOUT 30
struct aio_fifo_arg {
int afa_read_fd;
int afa_write_fd;
- char *afa_pathname;
};
static void
@@ -375,39 +433,25 @@ aio_fifo_cleanup(void *arg)
close(afa->afa_read_fd);
if (afa->afa_write_fd != -1)
close(afa->afa_write_fd);
- unlink(afa->afa_pathname);
+ unlink(FIFO_PATHNAME);
}
-#define FIFO_LEN 256
-#define FIFO_TIMEOUT 30
-ATF_TC_WITHOUT_HEAD(aio_fifo_test);
-ATF_TC_BODY(aio_fifo_test, tc)
+static void
+aio_fifo_test(completion comp)
{
int error, read_fd = -1, write_fd = -1;
struct aio_fifo_arg arg;
- char pathname[PATH_MAX];
struct aio_context ac;
ATF_REQUIRE_KERNEL_MODULE("aio");
ATF_REQUIRE_UNSAFE_AIO();
- /*
- * In theory, mkstemp() can return a name that is then collided with.
- * Because this is a regression test, we treat that as a test failure
- * rather than retrying.
- */
- strcpy(pathname, PATH_TEMPLATE);
- ATF_REQUIRE_MSG(mkstemp(pathname) != -1,
- "mkstemp failed: %s", strerror(errno));
- ATF_REQUIRE_MSG(unlink(pathname) == 0,
- "unlink failed: %s", strerror(errno));
- ATF_REQUIRE_MSG(mkfifo(pathname, 0600) != -1,
+ ATF_REQUIRE_MSG(mkfifo(FIFO_PATHNAME, 0600) != -1,
"mkfifo failed: %s", strerror(errno));
- arg.afa_pathname = pathname;
arg.afa_read_fd = -1;
arg.afa_write_fd = -1;
- read_fd = open(pathname, O_RDONLY | O_NONBLOCK);
+ read_fd = open(FIFO_PATHNAME, O_RDONLY | O_NONBLOCK);
if (read_fd == -1) {
error = errno;
aio_fifo_cleanup(&arg);
@@ -417,7 +461,7 @@ ATF_TC_BODY(aio_fifo_test, tc)
}
arg.afa_read_fd = read_fd;
- write_fd = open(pathname, O_WRONLY);
+ write_fd = open(FIFO_PATHNAME, O_WRONLY);
if (write_fd == -1) {
error = errno;
aio_fifo_cleanup(&arg);
@@ -429,12 +473,30 @@ ATF_TC_BODY(aio_fifo_test, tc)
aio_context_init(&ac, read_fd, write_fd, FIFO_LEN,
FIFO_TIMEOUT, aio_fifo_cleanup, &arg);
- aio_write_test(&ac);
- aio_read_test(&ac);
+ aio_write_test(&ac, comp);
+ aio_read_test(&ac, comp);
aio_fifo_cleanup(&arg);
}
+ATF_TC_WITHOUT_HEAD(fifo_poll);
+ATF_TC_BODY(fifo_poll, tc)
+{
+ aio_fifo_test(poll);
+}
+
+ATF_TC_WITHOUT_HEAD(fifo_suspend);
+ATF_TC_BODY(fifo_suspend, tc)
+{
+ aio_fifo_test(waitcomplete);
+}
+
+ATF_TC_WITHOUT_HEAD(fifo_waitcomplete);
+ATF_TC_BODY(fifo_waitcomplete, tc)
+{
+ aio_fifo_test(waitcomplete);
+}
+
struct aio_unix_socketpair_arg {
int asa_sockets[2];
};
@@ -451,8 +513,8 @@ aio_unix_socketpair_cleanup(void *arg)
#define UNIX_SOCKETPAIR_LEN 256
#define UNIX_SOCKETPAIR_TIMEOUT 30
-ATF_TC_WITHOUT_HEAD(aio_unix_socketpair_test);
-ATF_TC_BODY(aio_unix_socketpair_test, tc)
+static void
+aio_unix_socketpair_test(completion comp)
{
struct aio_unix_socketpair_arg arg;
struct aio_context ac;
@@ -471,12 +533,12 @@ ATF_TC_BODY(aio_unix_socketpair_test, tc)
aio_unix_socketpair_cleanup, &arg);
ATF_REQUIRE_MSG(getrusage(RUSAGE_SELF, &ru_before) != -1,
"getrusage failed: %s", strerror(errno));
- aio_write_test(&ac);
+ aio_write_test(&ac, comp);
ATF_REQUIRE_MSG(getrusage(RUSAGE_SELF, &ru_after) != -1,
"getrusage failed: %s", strerror(errno));
ATF_REQUIRE(ru_after.ru_msgsnd == ru_before.ru_msgsnd + 1);
ru_before = ru_after;
- aio_read_test(&ac);
+ aio_read_test(&ac, comp);
ATF_REQUIRE_MSG(getrusage(RUSAGE_SELF, &ru_after) != -1,
"getrusage failed: %s", strerror(errno));
ATF_REQUIRE(ru_after.ru_msgrcv == ru_before.ru_msgrcv + 1);
@@ -484,6 +546,24 @@ ATF_TC_BODY(aio_unix_socketpair_test, tc)
aio_unix_socketpair_cleanup(&arg);
}
+ATF_TC_WITHOUT_HEAD(socket_poll);
+ATF_TC_BODY(socket_poll, tc)
+{
+ aio_unix_socketpair_test(poll);
+}
+
+ATF_TC_WITHOUT_HEAD(socket_suspend);
+ATF_TC_BODY(socket_suspend, tc)
+{
+ aio_unix_socketpair_test(suspend);
+}
+
+ATF_TC_WITHOUT_HEAD(socket_waitcomplete);
+ATF_TC_BODY(socket_waitcomplete, tc)
+{
+ aio_unix_socketpair_test(waitcomplete);
+}
+
struct aio_pty_arg {
int apa_read_fd;
int apa_write_fd;
@@ -501,8 +581,8 @@ aio_pty_cleanup(void *arg)
#define PTY_LEN 256
#define PTY_TIMEOUT 30
-ATF_TC_WITHOUT_HEAD(aio_pty_test);
-ATF_TC_BODY(aio_pty_test, tc)
+static void
+aio_pty_test(completion comp)
{
struct aio_pty_arg arg;
struct aio_context ac;
@@ -535,12 +615,30 @@ ATF_TC_BODY(aio_pty_test, tc)
aio_context_init(&ac, read_fd, write_fd, PTY_LEN,
PTY_TIMEOUT, aio_pty_cleanup, &arg);
- aio_write_test(&ac);
- aio_read_test(&ac);
+ aio_write_test(&ac, comp);
+ aio_read_test(&ac, comp);
aio_pty_cleanup(&arg);
}
+ATF_TC_WITHOUT_HEAD(pty_poll);
+ATF_TC_BODY(pty_poll, tc)
+{
+ aio_pty_test(poll);
+}
+
+ATF_TC_WITHOUT_HEAD(pty_suspend);
+ATF_TC_BODY(pty_suspend, tc)
+{
+ aio_pty_test(suspend);
+}
+
+ATF_TC_WITHOUT_HEAD(pty_waitcomplete);
+ATF_TC_BODY(pty_waitcomplete, tc)
+{
+ aio_pty_test(waitcomplete);
+}
+
static void
aio_pipe_cleanup(void *arg)
{
@@ -552,8 +650,8 @@ aio_pipe_cleanup(void *arg)
#define PIPE_LEN 256
#define PIPE_TIMEOUT 30
-ATF_TC_WITHOUT_HEAD(aio_pipe_test);
-ATF_TC_BODY(aio_pipe_test, tc)
+static void
+aio_pipe_test(completion comp)
{
struct aio_context ac;
int pipes[2];
@@ -566,12 +664,30 @@ ATF_TC_BODY(aio_pipe_test, tc)
aio_context_init(&ac, pipes[0], pipes[1], PIPE_LEN,
PIPE_TIMEOUT, aio_pipe_cleanup, pipes);
- aio_write_test(&ac);
- aio_read_test(&ac);
+ aio_write_test(&ac, comp);
+ aio_read_test(&ac, comp);
aio_pipe_cleanup(pipes);
}
+ATF_TC_WITHOUT_HEAD(pipe_poll);
+ATF_TC_BODY(pipe_poll, tc)
+{
+ aio_pipe_test(poll);
+}
+
+ATF_TC_WITHOUT_HEAD(pipe_suspend);
+ATF_TC_BODY(pipe_suspend, tc)
+{
+ aio_pipe_test(suspend);
+}
+
+ATF_TC_WITHOUT_HEAD(pipe_waitcomplete);
+ATF_TC_BODY(pipe_waitcomplete, tc)
+{
+ aio_pipe_test(waitcomplete);
+}
+
struct aio_md_arg {
int ama_mdctl_fd;
int ama_unit;
@@ -608,13 +724,8 @@ aio_md_cleanup(void *arg)
#define MD_LEN GLOBAL_MAX
#define MD_TIMEOUT 30
-ATF_TC(aio_md_test);
-ATF_TC_HEAD(aio_md_test, tc)
-{
-
- atf_tc_set_md_var(tc, "require.user", "root");
-}
-ATF_TC_BODY(aio_md_test, tc)
+static void
+aio_md_test(completion comp)
{
int error, fd, mdctl_fd, unit;
char pathname[PATH_MAX];
@@ -654,16 +765,48 @@ ATF_TC_BODY(aio_md_test, tc)
aio_context_init(&ac, fd, fd, MD_LEN, MD_TIMEOUT,
aio_md_cleanup, &arg);
- aio_write_test(&ac);
- aio_read_test(&ac);
+ aio_write_test(&ac, comp);
+ aio_read_test(&ac, comp);
aio_md_cleanup(&arg);
}
+ATF_TC(md_poll);
+ATF_TC_HEAD(md_poll, tc)
+{
+
+ atf_tc_set_md_var(tc, "require.user", "root");
+}
+ATF_TC_BODY(md_poll, tc)
+{
+ aio_md_test(poll);
+}
+
+ATF_TC(md_suspend);
+ATF_TC_HEAD(md_suspend, tc)
+{
+
+ atf_tc_set_md_var(tc, "require.user", "root");
+}
+ATF_TC_BODY(md_suspend, tc)
+{
+ aio_md_test(suspend);
+}
+
+ATF_TC(md_waitcomplete);
+ATF_TC_HEAD(md_waitcomplete, tc)
+{
+
+ atf_tc_set_md_var(tc, "require.user", "root");
+}
+ATF_TC_BODY(md_waitcomplete, tc)
+{
+ aio_md_test(waitcomplete);
+}
+
ATF_TC_WITHOUT_HEAD(aio_large_read_test);
ATF_TC_BODY(aio_large_read_test, tc)
{
- char pathname[PATH_MAX];
struct aiocb cb, *cbp;
ssize_t nread;
size_t len;
@@ -689,11 +832,10 @@ ATF_TC_BODY(aio_large_read_test, tc)
len = INT_MAX;
#endif
- strcpy(pathname, PATH_TEMPLATE);
- fd = mkstemp(pathname);
- ATF_REQUIRE_MSG(fd != -1, "mkstemp failed: %s", strerror(errno));
+ fd = open(FILE_PATHNAME, O_RDWR | O_CREAT);
+ ATF_REQUIRE_MSG(fd != -1, "open failed: %s", strerror(errno));
- unlink(pathname);
+ unlink(FILE_PATHNAME);
memset(&cb, 0, sizeof(cb));
cb.aio_nbytes = len;
@@ -937,7 +1079,6 @@ ATF_TC_BODY(aio_fsync_test, tc)
char *buffer;
} buffers[16];
struct stat sb;
- char pathname[PATH_MAX];
ssize_t rval;
unsigned i;
int fd;
@@ -945,10 +1086,9 @@ ATF_TC_BODY(aio_fsync_test, tc)
ATF_REQUIRE_KERNEL_MODULE("aio");
ATF_REQUIRE_UNSAFE_AIO();
- strcpy(pathname, PATH_TEMPLATE);
- fd = mkstemp(pathname);
- ATF_REQUIRE_MSG(fd != -1, "mkstemp failed: %s", strerror(errno));
- unlink(pathname);
+ fd = open(FILE_PATHNAME, O_RDWR | O_CREAT);
+ ATF_REQUIRE_MSG(fd != -1, "open failed: %s", strerror(errno));
+ unlink(FILE_PATHNAME);
ATF_REQUIRE(fstat(fd, &sb) == 0);
ATF_REQUIRE(sb.st_blksize != 0);
@@ -1009,12 +1149,24 @@ ATF_TC_BODY(aio_fsync_test, tc)
ATF_TP_ADD_TCS(tp)
{
- ATF_TP_ADD_TC(tp, aio_file_test);
- ATF_TP_ADD_TC(tp, aio_fifo_test);
- ATF_TP_ADD_TC(tp, aio_unix_socketpair_test);
- ATF_TP_ADD_TC(tp, aio_pty_test);
- ATF_TP_ADD_TC(tp, aio_pipe_test);
- ATF_TP_ADD_TC(tp, aio_md_test);
+ ATF_TP_ADD_TC(tp, file_poll);
+ ATF_TP_ADD_TC(tp, file_suspend);
+ ATF_TP_ADD_TC(tp, file_waitcomplete);
+ ATF_TP_ADD_TC(tp, fifo_poll);
+ ATF_TP_ADD_TC(tp, fifo_suspend);
+ ATF_TP_ADD_TC(tp, fifo_waitcomplete);
+ ATF_TP_ADD_TC(tp, socket_poll);
+ ATF_TP_ADD_TC(tp, socket_suspend);
+ ATF_TP_ADD_TC(tp, socket_waitcomplete);
+ ATF_TP_ADD_TC(tp, pty_poll);
+ ATF_TP_ADD_TC(tp, pty_suspend);
+ ATF_TP_ADD_TC(tp, pty_waitcomplete);
+ ATF_TP_ADD_TC(tp, pipe_poll);
+ ATF_TP_ADD_TC(tp, pipe_suspend);
+ ATF_TP_ADD_TC(tp, pipe_waitcomplete);
+ ATF_TP_ADD_TC(tp, md_poll);
+ ATF_TP_ADD_TC(tp, md_suspend);
+ ATF_TP_ADD_TC(tp, md_waitcomplete);
ATF_TP_ADD_TC(tp, aio_large_read_test);
ATF_TP_ADD_TC(tp, aio_socket_two_reads);
ATF_TP_ADD_TC(tp, aio_socket_blocking_short_write);
diff --git a/tests/sys/geom/class/gate/ggate_test.sh b/tests/sys/geom/class/gate/ggate_test.sh
index ffdb341a4b28..162744d818df 100755
--- a/tests/sys/geom/class/gate/ggate_test.sh
+++ b/tests/sys/geom/class/gate/ggate_test.sh
@@ -4,7 +4,6 @@ PIDFILE=ggated.pid
PLAINFILES=plainfiles
PORT=33080
CONF=gg.exports
-RETRIES=16
atf_test_case ggated cleanup
ggated_head()
@@ -21,31 +20,23 @@ ggated_body()
work=$(alloc_md)
src=$(alloc_md)
- dd if=/dev/random of=/dev/$work bs=1m count=1 conv=notrunc
- dd if=/dev/random of=/dev/$src bs=1m count=1 conv=notrunc
+ atf_check -e ignore -o ignore \
+ dd if=/dev/random of=/dev/$work bs=1m count=1 conv=notrunc
+ atf_check -e ignore -o ignore \
+ dd if=/dev/random of=/dev/$src bs=1m count=1 conv=notrunc
echo $CONF >> $PLAINFILES
echo "127.0.0.1 RW /dev/$work" > $CONF
atf_check ggated -p $PORT -F $PIDFILE $CONF
- for try in `jot $RETRIES`; do
- ggatec create -p $PORT -u $us 127.0.0.1 /dev/$work && break
- # wait for ggated to be ready
- sleep 0.25
- done
- if [ "$try" -eq "$RETRIES" ]; then
- atf_fail "ggatec create failed"
- fi
+ atf_check ggatec create -p $PORT -u $us 127.0.0.1 /dev/$work
- for try in `jot $RETRIES`; do
- dd if=/dev/${src} of=/dev/ggate${us} bs=1m count=1 conv=notrunc\
- && break
- # Wait for /dev/ggate${us} to be ready
- sleep 0.25
- done
- if [ "$try" -eq "$RETRIES" ]; then
- atf_fail "dd failed; /dev/ggate${us} isn't working"
- fi
+ ggate_dev=/dev/ggate${us}
+
+ wait_for_ggate_device ${ggate_dev}
+
+ atf_check -e ignore -o ignore \
+ dd if=/dev/${src} of=${ggate_dev} bs=1m count=1 conv=notrunc
checksum /dev/$src /dev/$work
}
@@ -74,7 +65,12 @@ ggatel_file_body()
atf_check ggatel create -u $us work
- dd if=src of=/dev/ggate${us} bs=1m count=1 conv=notrunc
+ ggate_dev=/dev/ggate${us}
+
+ wait_for_ggate_device ${ggate_dev}
+
+ atf_check -e ignore -o ignore \
+ dd if=src of=${ggate_dev} bs=1m count=1 conv=notrunc
checksum src work
}
@@ -99,12 +95,19 @@ ggatel_md_body()
work=$(alloc_md)
src=$(alloc_md)
- dd if=/dev/random of=$work bs=1m count=1 conv=notrunc
- dd if=/dev/random of=$src bs=1m count=1 conv=notrunc
+ atf_check -e ignore -o ignore \
+ dd if=/dev/random of=$work bs=1m count=1 conv=notrunc
+ atf_check -e ignore -o ignore \
+ dd if=/dev/random of=$src bs=1m count=1 conv=notrunc
atf_check ggatel create -u $us /dev/$work
- dd if=/dev/$src of=/dev/ggate${us} bs=1m count=1 conv=notrunc
+ ggate_dev=/dev/ggate${us}
+
+ wait_for_ggate_device ${ggate_dev}
+
+ atf_check -e ignore -o ignore \
+ dd if=/dev/$src of=${ggate_dev} bs=1m count=1 conv=notrunc
checksum /dev/$src /dev/$work
}
@@ -191,3 +194,14 @@ common_cleanup()
fi
true
}
+
+# Bug 204616: ggatel(8) creates /dev/ggate* asynchronously if `ggatel create`
+# isn't called with `-v`.
+wait_for_ggate_device()
+{
+ ggate_device=$1
+
+ while [ ! -c $ggate_device ]; do
+ sleep 0.5
+ done
+}
diff --git a/tests/sys/kern/Makefile b/tests/sys/kern/Makefile
index 61b315f18d12..795752cd7779 100644
--- a/tests/sys/kern/Makefile
+++ b/tests/sys/kern/Makefile
@@ -29,13 +29,19 @@ NETBSD_ATF_TESTS_C+= mqueue_test
CFLAGS.mqueue_test+= -I${SRCTOP}/tests
LIBADD.mqueue_test+= rt
+.if ${MACHINE_ARCH} == "amd64" || ${MACHINE_ARCH} == "i386"
+ATF_TESTS_C+= libkern_crc32
+CFLAGS.libkern_crc32+= -msse4 -DUSERSPACE_TESTING
+LDADD.libkern_crc32+= ${SRCTOP}/sys/libkern/x86/crc32_sse42.c
+.endif
+
# subr_unit.c contains functions whose prototypes lie in headers that cannot be
# included in userland. But as far as subr_unit_test goes, they're effectively
# static. So it's ok to disable -Wmissing-prototypes for this program.
CFLAGS.subr_unit.c+= -Wno-missing-prototypes
SRCS.subr_unit_test+= subr_unit.c
-WARNS?= 5
+WARNS?= 3
TESTS_SUBDIRS+= acct
TESTS_SUBDIRS+= execve
diff --git a/tests/sys/kern/libkern_crc32.c b/tests/sys/kern/libkern_crc32.c
new file mode 100644
index 000000000000..5eef045c4573
--- /dev/null
+++ b/tests/sys/kern/libkern_crc32.c
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 2017 Conrad Meyer <cem@FreeBSD.org>
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/param.h>
+
+#include <stdint.h>
+
+#include <atf-c.h>
+
+extern uint32_t sse42_crc32c(uint32_t, const unsigned char *, unsigned);
+
+ATF_TC_WITHOUT_HEAD(crc32c_basic_correctness);
+ATF_TC_BODY(crc32c_basic_correctness, tc)
+{
+ const uint64_t inputs[] = {
+ 0xf408c634b3a9142,
+ 0x80539e8c7c352e2b,
+ 0x62e9121db6e4d649,
+ 0x899345850ed0a286,
+ 0x2302df11b4a43b15,
+ 0xe943de7b3d35d70,
+ 0xdf1ff2bf41abf56b,
+ 0x9bc138abae315de2,
+ 0x31cc82e56234f0ff,
+ 0xce63c0cd6988e847,
+ 0x3e42f6b78ee352fa,
+ 0xfa4085436078cfa6,
+ 0x53349558bf670a4b,
+ 0x2714e10e7d722c61,
+ 0xc0d3261addfc6908,
+ 0xd1567c3181d3a1bf,
+ };
+ const uint32_t results[] = {
+ 0x2ce33ede,
+ 0xc49cc573,
+ 0xb8683c96,
+ 0x6918660d,
+ 0xa904e522,
+ 0x52dbc42c,
+ 0x98863c22,
+ 0x894d5d2c,
+ 0xb003745d,
+ 0xfc496dbd,
+ 0x97d2fbb5,
+ 0x3c062ef1,
+ 0xcc2eff18,
+ 0x6a9b09f6,
+ 0x420242c1,
+ 0xfd562dc3,
+ };
+ size_t i;
+ uint32_t act;
+
+ ATF_REQUIRE(nitems(inputs) == nitems(results));
+
+ for (i = 0; i < nitems(inputs); i++) {
+ act = sse42_crc32c(~0, (const void *)&inputs[i],
+ sizeof(inputs[0]));
+ ATF_REQUIRE_MSG(act == results[i],
+ "crc32c(0x%jx) = 0x%08x, got 0x%08x", (uintmax_t)inputs[i],
+ results[i], act);
+ }
+}
+
+ATF_TC_WITHOUT_HEAD(crc32c_alignment);
+ATF_TC_BODY(crc32c_alignment, tc)
+{
+ const uint64_t input = 0xf408c634b3a9142;
+ const uint32_t result = 0x2ce33ede;
+ unsigned char buf[15];
+ size_t i;
+ uint32_t act;
+
+
+ for (i = 1; i < 8; i++) {
+ memcpy(&buf[i], &input, sizeof(input));
+
+ act = sse42_crc32c(~0, (const void *)&buf[i], sizeof(input));
+ ATF_REQUIRE_MSG(act == result,
+ "crc32c(0x%jx) = 0x%08x, got 0x%08x", (uintmax_t)input,
+ result, act);
+ }
+}
+
+ATF_TC_WITHOUT_HEAD(crc32c_trailing_bytes);
+ATF_TC_BODY(crc32c_trailing_bytes, tc)
+{
+ const unsigned char input[] = {
+ 0x87, 0x54, 0x74, 0xd2, 0xb, 0x9b, 0xdd, 0xf6, 0x68, 0x37,
+ 0xd4, 0x4, 0x5e, 0xa9, 0xb3
+ };
+ const uint32_t result = 0xec638d62;
+ uint32_t act;
+
+ act = sse42_crc32c(~0, input, sizeof(input));
+ ATF_REQUIRE_MSG(act == result, "expected 0x%08x, got 0x%08x", result,
+ act);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, crc32c_basic_correctness);
+ ATF_TP_ADD_TC(tp, crc32c_alignment);
+ ATF_TP_ADD_TC(tp, crc32c_trailing_bytes);
+ return (atf_no_error());
+}
diff --git a/tests/sys/netinet/fibs_test.sh b/tests/sys/netinet/fibs_test.sh
index 70b53e81e8da..bf5a54b451a2 100755
--- a/tests/sys/netinet/fibs_test.sh
+++ b/tests/sys/netinet/fibs_test.sh
@@ -75,9 +75,9 @@ arpresolve_checks_interface_fib_body()
get_fibs 2
# Configure TAP interfaces
- setup_tap "$FIB0" ${ADDR0} ${MASK0}
+ setup_tap "$FIB0" inet ${ADDR0} ${MASK0}
TAP0=$TAP
- setup_tap "$FIB1" ${ADDR1} ${MASK1}
+ setup_tap "$FIB1" inet ${ADDR1} ${MASK1}
TAP1=$TAP
# Simulate a crossover cable
@@ -112,7 +112,7 @@ arpresolve_checks_interface_fib_cleanup()
atf_test_case loopback_and_network_routes_on_nondefault_fib cleanup
loopback_and_network_routes_on_nondefault_fib_head()
{
- atf_set "descr" "When creating and deleting loopback routes, use the interface's fib"
+ atf_set "descr" "When creating and deleting loopback IPv4 routes, use the interface's fib"
atf_set "require.user" "root"
atf_set "require.config" "fibs"
}
@@ -132,7 +132,7 @@ loopback_and_network_routes_on_nondefault_fib_body()
get_fibs 1
# Configure a TAP interface
- setup_tap ${FIB0} ${ADDR} ${MASK}
+ setup_tap ${FIB0} inet ${ADDR} ${MASK}
# Check whether the host route exists in only the correct FIB
setfib ${FIB0} netstat -rn -f inet | grep -q "^${ADDR}.*UHS.*lo0"
@@ -156,7 +156,7 @@ loopback_and_network_routes_on_nondefault_fib_body()
setfib 0 netstat -rn -f inet | \
grep -q "^${SUBNET}/${MASK}.*${TAPD}"
if [ 0 -eq $? ]; then
- setfib ${FIB0} netstat -rn -f inet
+ setfib 0 netstat -rn -f inet
atf_fail "Network route appeared in the wrong FIB"
fi
}
@@ -166,12 +166,70 @@ loopback_and_network_routes_on_nondefault_fib_cleanup()
cleanup_tap
}
+atf_test_case loopback_and_network_routes_on_nondefault_fib_inet6 cleanup
+loopback_and_network_routes_on_nondefault_fib_inet6_head()
+{
+ atf_set "descr" "When creating and deleting loopback IPv6 routes, use the interface's fib"
+ atf_set "require.user" "root"
+ atf_set "require.config" "fibs"
+}
+
+loopback_and_network_routes_on_nondefault_fib_inet6_body()
+{
+ atf_expect_fail "PR196361 IPv6 network routes don't respect net.add_addr_allfibs=0"
+ # Configure the TAP interface to use a nonrouteable RFC3849
+ # address and a non-default fib
+ ADDR="2001:db8::2"
+ SUBNET="2001:db8::"
+ MASK="64"
+
+ # Check system configuration
+ if [ 0 != `sysctl -n net.add_addr_allfibs` ]; then
+ atf_skip "This test requires net.add_addr_allfibs=0"
+ fi
+ get_fibs 1
+
+ # Configure a TAP interface
+ setup_tap ${FIB0} inet6 ${ADDR} ${MASK}
+
+ # Check whether the host route exists in only the correct FIB
+ setfib ${FIB0} netstat -rn -f inet6 | grep -q "^${ADDR}.*UHS.*lo0"
+ if [ 0 -ne $? ]; then
+ setfib ${FIB0} netstat -rn -f inet6
+ atf_fail "Host route did not appear in the correct FIB"
+ fi
+ setfib 0 netstat -rn -f inet6 | grep -q "^${ADDR}.*UHS.*lo0"
+ if [ 0 -eq $? ]; then
+ setfib 0 netstat -rn -f inet6
+ atf_fail "Host route appeared in the wrong FIB"
+ fi
+
+ # Check whether the network route exists in only the correct FIB
+ setfib ${FIB0} netstat -rn -f inet6 | \
+ grep -q "^${SUBNET}/${MASK}.*${TAPD}"
+ if [ 0 -ne $? ]; then
+ setfib ${FIB0} netstat -rn -f inet6
+ atf_fail "Network route did not appear in the correct FIB"
+ fi
+ setfib 0 netstat -rn -f inet6 | \
+ grep -q "^${SUBNET}/${MASK}.*${TAPD}"
+ if [ 0 -eq $? ]; then
+ setfib 0 netstat -rn -f inet6
+ atf_fail "Network route appeared in the wrong FIB"
+ fi
+}
+
+loopback_and_network_routes_on_nondefault_fib_inet6_cleanup()
+{
+ cleanup_tap
+}
+
# Regression test for kern/187552
atf_test_case default_route_with_multiple_fibs_on_same_subnet cleanup
default_route_with_multiple_fibs_on_same_subnet_head()
{
- atf_set "descr" "Multiple interfaces on the same subnet but with different fibs can both have default routes"
+ atf_set "descr" "Multiple interfaces on the same subnet but with different fibs can both have default IPv4 routes"
atf_set "require.user" "root"
atf_set "require.config" "fibs"
}
@@ -193,9 +251,9 @@ default_route_with_multiple_fibs_on_same_subnet_body()
get_fibs 2
# Configure TAP interfaces
- setup_tap "$FIB0" ${ADDR0} ${MASK}
+ setup_tap "$FIB0" inet ${ADDR0} ${MASK}
TAP0=$TAP
- setup_tap "$FIB1" ${ADDR1} ${MASK}
+ setup_tap "$FIB1" inet ${ADDR1} ${MASK}
TAP1=$TAP
# Attempt to add default routes
@@ -215,6 +273,53 @@ default_route_with_multiple_fibs_on_same_subnet_cleanup()
cleanup_tap
}
+atf_test_case default_route_with_multiple_fibs_on_same_subnet_inet6 cleanup
+default_route_with_multiple_fibs_on_same_subnet_inet6_head()
+{
+ atf_set "descr" "Multiple interfaces on the same subnet but with different fibs can both have default IPv6 routes"
+ atf_set "require.user" "root"
+ atf_set "require.config" "fibs"
+}
+
+default_route_with_multiple_fibs_on_same_subnet_inet6_body()
+{
+ # Configure the TAP interfaces to use nonrouteable RFC3849
+ # addresses and non-default FIBs
+ ADDR0="2001:db8::2"
+ ADDR1="2001:db8::3"
+ GATEWAY="2001:db8::1"
+ SUBNET="2001:db8::"
+ MASK="64"
+
+ # Check system configuration
+ if [ 0 != `sysctl -n net.add_addr_allfibs` ]; then
+ atf_skip "This test requires net.add_addr_allfibs=0"
+ fi
+ get_fibs 2
+
+ # Configure TAP interfaces
+ setup_tap "$FIB0" inet6 ${ADDR0} ${MASK}
+ TAP0=$TAP
+ setup_tap "$FIB1" inet6 ${ADDR1} ${MASK}
+ TAP1=$TAP
+
+ # Attempt to add default routes
+ setfib ${FIB0} route -6 add default ${GATEWAY}
+ setfib ${FIB1} route -6 add default ${GATEWAY}
+
+ # Verify that the default route exists for both fibs, with their
+ # respective interfaces.
+ atf_check -o match:"^default.*${TAP0}$" \
+ setfib ${FIB0} netstat -rn -f inet6
+ atf_check -o match:"^default.*${TAP1}$" \
+ setfib ${FIB1} netstat -rn -f inet6
+}
+
+default_route_with_multiple_fibs_on_same_subnet_inet6_cleanup()
+{
+ cleanup_tap
+}
+
# Regression test for PR kern/189089
# Create two tap interfaces and assign them both the same IP address but with
@@ -223,7 +328,7 @@ default_route_with_multiple_fibs_on_same_subnet_cleanup()
atf_test_case same_ip_multiple_ifaces_fib0 cleanup
same_ip_multiple_ifaces_fib0_head()
{
- atf_set "descr" "Can remove an IP alias from an interface when the same IP is also assigned to another interface."
+ atf_set "descr" "Can remove an IPv4 alias from an interface when the same IPv4 is also assigned to another interface."
atf_set "require.user" "root"
atf_set "require.config" "fibs"
}
@@ -237,16 +342,16 @@ same_ip_multiple_ifaces_fib0_body()
# of net.add_addr_allfibs
# Setup the interfaces, then remove one alias. It should not panic.
- setup_tap 0 ${ADDR} ${MASK0}
+ setup_tap 0 inet ${ADDR} ${MASK0}
TAP0=${TAP}
- setup_tap 0 ${ADDR} ${MASK1}
+ setup_tap 0 inet ${ADDR} ${MASK1}
TAP1=${TAP}
ifconfig ${TAP1} -alias ${ADDR}
# Do it again, in the opposite order. It should not panic.
- setup_tap 0 ${ADDR} ${MASK0}
+ setup_tap 0 inet ${ADDR} ${MASK0}
TAP0=${TAP}
- setup_tap 0 ${ADDR} ${MASK1}
+ setup_tap 0 inet ${ADDR} ${MASK1}
TAP1=${TAP}
ifconfig ${TAP0} -alias ${ADDR}
}
@@ -266,7 +371,7 @@ same_ip_multiple_ifaces_fib0_cleanup()
atf_test_case same_ip_multiple_ifaces cleanup
same_ip_multiple_ifaces_head()
{
- atf_set "descr" "Can remove an IP alias from an interface when the same IP is also assigned to another interface, on non-default FIBs."
+ atf_set "descr" "Can remove an IPv4 alias from an interface when the same address is also assigned to another interface, on non-default FIBs."
atf_set "require.user" "root"
atf_set "require.config" "fibs"
}
@@ -282,18 +387,18 @@ same_ip_multiple_ifaces_body()
get_fibs 2
# Setup the interfaces, then remove one alias. It should not panic.
- setup_tap ${FIB0} ${ADDR} ${MASK0}
+ setup_tap ${FIB0} inet ${ADDR} ${MASK0}
TAP0=${TAP}
- setup_tap ${FIB1} ${ADDR} ${MASK1}
+ setup_tap ${FIB1} inet ${ADDR} ${MASK1}
TAP1=${TAP}
ifconfig ${TAP1} -alias ${ADDR}
atf_check -o not-match:"^${ADDR}[[:space:]]" \
setfib ${FIB1} netstat -rn -f inet
# Do it again, in the opposite order. It should not panic.
- setup_tap ${FIB0} ${ADDR} ${MASK0}
+ setup_tap ${FIB0} inet ${ADDR} ${MASK0}
TAP0=${TAP}
- setup_tap ${FIB1} ${ADDR} ${MASK1}
+ setup_tap ${FIB1} inet ${ADDR} ${MASK1}
TAP1=${TAP}
ifconfig ${TAP0} -alias ${ADDR}
atf_check -o not-match:"^${ADDR}[[:space:]]" \
@@ -304,15 +409,58 @@ same_ip_multiple_ifaces_cleanup()
# Due to PR kern/189088, we must destroy the interfaces in LIFO order
# in order for the routes to be correctly cleaned up.
for TAPD in `tail -r "tap_devices_to_cleanup"`; do
+ echo ifconfig ${TAPD} destroy
ifconfig ${TAPD} destroy
done
}
+atf_test_case same_ip_multiple_ifaces_inet6 cleanup
+same_ip_multiple_ifaces_inet6_head()
+{
+ atf_set "descr" "Can remove an IPv6 alias from an interface when the same address is also assigned to another interface, on non-default FIBs."
+ atf_set "require.user" "root"
+ atf_set "require.config" "fibs"
+}
+same_ip_multiple_ifaces_inet6_body()
+{
+ ADDR="2001:db8::2"
+ MASK0="64"
+ MASK1="128"
+
+ # Unlike most of the tests in this file, this is applicable regardless
+ # of net.add_addr_allfibs
+ get_fibs 2
+
+ # Setup the interfaces, then remove one alias. It should not panic.
+ setup_tap ${FIB0} inet6 ${ADDR} ${MASK0}
+ TAP0=${TAP}
+ setup_tap ${FIB1} inet6 ${ADDR} ${MASK1}
+ TAP1=${TAP}
+ atf_check -s exit:0 ifconfig ${TAP1} inet6 ${ADDR} -alias
+ atf_check -o not-match:"^${ADDR}[[:space:]]" \
+ setfib ${FIB1} netstat -rn -f inet6
+ ifconfig ${TAP1} destroy
+ ifconfig ${TAP0} destroy
+
+ # Do it again, in the opposite order. It should not panic.
+ setup_tap ${FIB0} inet6 ${ADDR} ${MASK0}
+ TAP0=${TAP}
+ setup_tap ${FIB1} inet6 ${ADDR} ${MASK1}
+ TAP1=${TAP}
+ atf_check -s exit:0 ifconfig ${TAP0} inet6 ${ADDR} -alias
+ atf_check -o not-match:"^${ADDR}[[:space:]]" \
+ setfib ${FIB0} netstat -rn -f inet6
+}
+same_ip_multiple_ifaces_inet6_cleanup()
+{
+ cleanup_tap
+}
+
# Regression test for kern/187550
atf_test_case subnet_route_with_multiple_fibs_on_same_subnet cleanup
subnet_route_with_multiple_fibs_on_same_subnet_head()
{
- atf_set "descr" "Multiple FIBs can have subnet routes for the same subnet"
+ atf_set "descr" "Multiple FIBs can have IPv4 subnet routes for the same subnet"
atf_set "require.user" "root"
atf_set "require.config" "fibs"
}
@@ -333,8 +481,8 @@ subnet_route_with_multiple_fibs_on_same_subnet_body()
get_fibs 2
# Configure TAP interfaces
- setup_tap "$FIB0" ${ADDR0} ${MASK}
- setup_tap "$FIB1" ${ADDR1} ${MASK}
+ setup_tap "$FIB0" inet ${ADDR0} ${MASK}
+ setup_tap "$FIB1" inet ${ADDR1} ${MASK}
# Check that a subnet route exists on both fibs
atf_check -o ignore setfib "$FIB0" route get $ADDR1
@@ -346,6 +494,43 @@ subnet_route_with_multiple_fibs_on_same_subnet_cleanup()
cleanup_tap
}
+atf_test_case subnet_route_with_multiple_fibs_on_same_subnet_inet6 cleanup
+subnet_route_with_multiple_fibs_on_same_subnet_inet6_head()
+{
+ atf_set "descr" "Multiple FIBs can have IPv6 subnet routes for the same subnet"
+ atf_set "require.user" "root"
+ atf_set "require.config" "fibs"
+}
+
+subnet_route_with_multiple_fibs_on_same_subnet_inet6_body()
+{
+ # Configure the TAP interfaces to use a RFC3849 nonrouteable addresses
+ # and a non-default fib
+ ADDR0="2001:db8::2"
+ ADDR1="2001:db8::3"
+ SUBNET="2001:db8::"
+ MASK="64"
+
+ # Check system configuration
+ if [ 0 != `sysctl -n net.add_addr_allfibs` ]; then
+ atf_skip "This test requires net.add_addr_allfibs=0"
+ fi
+ get_fibs 2
+
+ # Configure TAP interfaces
+ setup_tap "$FIB0" inet6 ${ADDR0} ${MASK}
+ setup_tap "$FIB1" inet6 ${ADDR1} ${MASK}
+
+ # Check that a subnet route exists on both fibs
+ atf_check -o ignore setfib "$FIB0" route -6 get $ADDR1
+ atf_check -o ignore setfib "$FIB1" route -6 get $ADDR0
+}
+
+subnet_route_with_multiple_fibs_on_same_subnet_inet6_cleanup()
+{
+ cleanup_tap
+}
+
# Test that source address selection works correctly for UDP packets with
# SO_DONTROUTE set that are sent on non-default FIBs.
# This bug was discovered with "setfib 1 netperf -t UDP_STREAM -H some_host"
@@ -386,9 +571,9 @@ udp_dontroute_body()
get_fibs 2
# Configure the TAP interfaces
- setup_tap ${FIB0} ${ADDR0} ${MASK}
+ setup_tap ${FIB0} inet ${ADDR0} ${MASK}
TARGET_TAP=${TAP}
- setup_tap ${FIB1} ${ADDR1} ${MASK}
+ setup_tap ${FIB1} inet ${ADDR1} ${MASK}
# Send a UDP packet with SO_DONTROUTE. In the failure case, it will
# return ENETUNREACH, or send the packet to the wrong tap
@@ -397,8 +582,8 @@ udp_dontroute_body()
cleanup_tap
# Repeat, but this time target the other tap
- setup_tap ${FIB0} ${ADDR0} ${MASK}
- setup_tap ${FIB1} ${ADDR1} ${MASK}
+ setup_tap ${FIB0} inet ${ADDR0} ${MASK}
+ setup_tap ${FIB1} inet ${ADDR1} ${MASK}
TARGET_TAP=${TAP}
atf_check -o ignore setfib ${FIB1} \
@@ -415,10 +600,14 @@ atf_init_test_cases()
{
atf_add_test_case arpresolve_checks_interface_fib
atf_add_test_case loopback_and_network_routes_on_nondefault_fib
+ atf_add_test_case loopback_and_network_routes_on_nondefault_fib_inet6
atf_add_test_case default_route_with_multiple_fibs_on_same_subnet
+ atf_add_test_case default_route_with_multiple_fibs_on_same_subnet_inet6
atf_add_test_case same_ip_multiple_ifaces_fib0
atf_add_test_case same_ip_multiple_ifaces
+ atf_add_test_case same_ip_multiple_ifaces_inet6
atf_add_test_case subnet_route_with_multiple_fibs_on_same_subnet
+ atf_add_test_case subnet_route_with_multiple_fibs_on_same_subnet_inet6
atf_add_test_case udp_dontroute
}
@@ -464,24 +653,27 @@ get_tap()
# Create a tap(4) interface, configure it, and register it for cleanup.
# parameters:
# fib
+# Protocol (inet or inet6)
# IP address
# Netmask in number of bits (eg 24 or 8)
# Return: the tap interface name as the env variable TAP
setup_tap()
{
local FIB=$1
- local ADDR=$2
- local MASK=$3
+ local PROTO=$2
+ local ADDR=$3
+ local MASK=$4
get_tap
- echo setfib ${FIB} ifconfig $TAP ${ADDR}/${MASK} fib $FIB
- setfib ${FIB} ifconfig $TAP ${ADDR}/${MASK} fib $FIB
+ echo setfib ${FIB} ifconfig $TAP ${PROTO} ${ADDR}/${MASK} fib $FIB
+ setfib ${FIB} ifconfig $TAP ${PROTO} ${ADDR}/${MASK} fib $FIB
}
cleanup_tap()
{
if [ -f tap_devices_to_cleanup ]; then
for tap_device in $(cat tap_devices_to_cleanup); do
- ifconfig "${tap_device}" destroy
+ echo ifconfig "${tap_device}" destroy
+ ifconfig "${tap_device}" destroy 2>/dev/null || true
done
rm -f tap_devices_to_cleanup
fi