1 // SPDX-License-Identifier: GPL-2.0-only
3 * vsock_test - vsock.ko test suite
5 * Copyright (C) 2017 Red Hat, Inc.
16 #include <linux/kernel.h>
17 #include <sys/types.h>
18 #include <sys/socket.h>
27 static void test_stream_connection_reset(const struct test_opts *opts)
31 struct sockaddr_vm svm;
34 .svm_family = AF_VSOCK,
36 .svm_cid = opts->peer_cid,
42 fd = socket(AF_VSOCK, SOCK_STREAM, 0);
44 timeout_begin(TIMEOUT);
46 ret = connect(fd, &addr.sa, sizeof(addr.svm));
47 timeout_check("connect");
48 } while (ret < 0 && errno == EINTR);
52 fprintf(stderr, "expected connect(2) failure, got %d\n", ret);
55 if (errno != ECONNRESET) {
56 fprintf(stderr, "unexpected connect(2) errno %d\n", errno);
63 static void test_stream_bind_only_client(const struct test_opts *opts)
67 struct sockaddr_vm svm;
70 .svm_family = AF_VSOCK,
72 .svm_cid = opts->peer_cid,
78 /* Wait for the server to be ready */
79 control_expectln("BIND");
81 fd = socket(AF_VSOCK, SOCK_STREAM, 0);
83 timeout_begin(TIMEOUT);
85 ret = connect(fd, &addr.sa, sizeof(addr.svm));
86 timeout_check("connect");
87 } while (ret < 0 && errno == EINTR);
91 fprintf(stderr, "expected connect(2) failure, got %d\n", ret);
94 if (errno != ECONNRESET) {
95 fprintf(stderr, "unexpected connect(2) errno %d\n", errno);
99 /* Notify the server that the client has finished */
100 control_writeln("DONE");
105 static void test_stream_bind_only_server(const struct test_opts *opts)
109 struct sockaddr_vm svm;
112 .svm_family = AF_VSOCK,
114 .svm_cid = VMADDR_CID_ANY,
119 fd = socket(AF_VSOCK, SOCK_STREAM, 0);
121 if (bind(fd, &addr.sa, sizeof(addr.svm)) < 0) {
126 /* Notify the client that the server is ready */
127 control_writeln("BIND");
129 /* Wait for the client to finish */
130 control_expectln("DONE");
135 static void test_stream_client_close_client(const struct test_opts *opts)
139 fd = vsock_stream_connect(opts->peer_cid, 1234);
149 static void test_stream_client_close_server(const struct test_opts *opts)
153 fd = vsock_stream_accept(VMADDR_CID_ANY, 1234, NULL);
159 /* Wait for the remote to close the connection, before check
160 * -EPIPE error on send.
162 vsock_wait_remote_close(fd);
164 send_byte(fd, -EPIPE, 0);
170 static void test_stream_server_close_client(const struct test_opts *opts)
174 fd = vsock_stream_connect(opts->peer_cid, 1234);
180 /* Wait for the remote to close the connection, before check
181 * -EPIPE error on send.
183 vsock_wait_remote_close(fd);
185 send_byte(fd, -EPIPE, 0);
191 static void test_stream_server_close_server(const struct test_opts *opts)
195 fd = vsock_stream_accept(VMADDR_CID_ANY, 1234, NULL);
205 /* With the standard socket sizes, VMCI is able to support about 100
206 * concurrent stream connections.
208 #define MULTICONN_NFDS 100
210 static void test_stream_multiconn_client(const struct test_opts *opts)
212 int fds[MULTICONN_NFDS];
215 for (i = 0; i < MULTICONN_NFDS; i++) {
216 fds[i] = vsock_stream_connect(opts->peer_cid, 1234);
223 for (i = 0; i < MULTICONN_NFDS; i++) {
225 recv_byte(fds[i], 1, 0);
227 send_byte(fds[i], 1, 0);
230 for (i = 0; i < MULTICONN_NFDS; i++)
234 static void test_stream_multiconn_server(const struct test_opts *opts)
236 int fds[MULTICONN_NFDS];
239 for (i = 0; i < MULTICONN_NFDS; i++) {
240 fds[i] = vsock_stream_accept(VMADDR_CID_ANY, 1234, NULL);
247 for (i = 0; i < MULTICONN_NFDS; i++) {
249 send_byte(fds[i], 1, 0);
251 recv_byte(fds[i], 1, 0);
254 for (i = 0; i < MULTICONN_NFDS; i++)
258 static void test_stream_msg_peek_client(const struct test_opts *opts)
262 fd = vsock_stream_connect(opts->peer_cid, 1234);
272 static void test_stream_msg_peek_server(const struct test_opts *opts)
276 fd = vsock_stream_accept(VMADDR_CID_ANY, 1234, NULL);
282 recv_byte(fd, 1, MSG_PEEK);
287 #define MESSAGES_CNT 7
288 #define MSG_EOR_IDX (MESSAGES_CNT / 2)
289 static void test_seqpacket_msg_bounds_client(const struct test_opts *opts)
293 fd = vsock_seqpacket_connect(opts->peer_cid, 1234);
299 /* Send several messages, one with MSG_EOR flag */
300 for (int i = 0; i < MESSAGES_CNT; i++)
301 send_byte(fd, 1, (i == MSG_EOR_IDX) ? MSG_EOR : 0);
303 control_writeln("SENDDONE");
307 static void test_seqpacket_msg_bounds_server(const struct test_opts *opts)
311 struct msghdr msg = {0};
312 struct iovec iov = {0};
314 fd = vsock_seqpacket_accept(VMADDR_CID_ANY, 1234, NULL);
320 control_expectln("SENDDONE");
322 iov.iov_len = sizeof(buf);
326 for (int i = 0; i < MESSAGES_CNT; i++) {
327 if (recvmsg(fd, &msg, 0) != 1) {
328 perror("message bound violated");
332 if ((i == MSG_EOR_IDX) ^ !!(msg.msg_flags & MSG_EOR)) {
341 #define MESSAGE_TRUNC_SZ 32
342 static void test_seqpacket_msg_trunc_client(const struct test_opts *opts)
345 char buf[MESSAGE_TRUNC_SZ];
347 fd = vsock_seqpacket_connect(opts->peer_cid, 1234);
353 if (send(fd, buf, sizeof(buf), 0) != sizeof(buf)) {
354 perror("send failed");
358 control_writeln("SENDDONE");
362 static void test_seqpacket_msg_trunc_server(const struct test_opts *opts)
365 char buf[MESSAGE_TRUNC_SZ / 2];
366 struct msghdr msg = {0};
367 struct iovec iov = {0};
369 fd = vsock_seqpacket_accept(VMADDR_CID_ANY, 1234, NULL);
375 control_expectln("SENDDONE");
377 iov.iov_len = sizeof(buf);
381 ssize_t ret = recvmsg(fd, &msg, MSG_TRUNC);
383 if (ret != MESSAGE_TRUNC_SZ) {
384 printf("%zi\n", ret);
385 perror("MSG_TRUNC doesn't work");
389 if (!(msg.msg_flags & MSG_TRUNC)) {
390 fprintf(stderr, "MSG_TRUNC expected\n");
397 static time_t current_nsec(void)
401 if (clock_gettime(CLOCK_REALTIME, &ts)) {
402 perror("clock_gettime(3) failed");
406 return (ts.tv_sec * 1000000000ULL) + ts.tv_nsec;
409 #define RCVTIMEO_TIMEOUT_SEC 1
410 #define READ_OVERHEAD_NSEC 250000000 /* 0.25 sec */
412 static void test_seqpacket_timeout_client(const struct test_opts *opts)
417 time_t read_enter_ns;
418 time_t read_overhead_ns;
420 fd = vsock_seqpacket_connect(opts->peer_cid, 1234);
426 tv.tv_sec = RCVTIMEO_TIMEOUT_SEC;
429 if (setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, (void *)&tv, sizeof(tv)) == -1) {
430 perror("setsockopt 'SO_RCVTIMEO'");
434 read_enter_ns = current_nsec();
436 if (read(fd, &dummy, sizeof(dummy)) != -1) {
438 "expected 'dummy' read(2) failure\n");
442 if (errno != EAGAIN) {
443 perror("EAGAIN expected");
447 read_overhead_ns = current_nsec() - read_enter_ns -
448 1000000000ULL * RCVTIMEO_TIMEOUT_SEC;
450 if (read_overhead_ns > READ_OVERHEAD_NSEC) {
452 "too much time in read(2), %lu > %i ns\n",
453 read_overhead_ns, READ_OVERHEAD_NSEC);
457 control_writeln("WAITDONE");
461 static void test_seqpacket_timeout_server(const struct test_opts *opts)
465 fd = vsock_seqpacket_accept(VMADDR_CID_ANY, 1234, NULL);
471 control_expectln("WAITDONE");
475 #define BUF_PATTERN_1 'a'
476 #define BUF_PATTERN_2 'b'
478 static void test_seqpacket_invalid_rec_buffer_client(const struct test_opts *opts)
483 int buf_size = getpagesize() * 3;
485 fd = vsock_seqpacket_connect(opts->peer_cid, 1234);
491 buf1 = malloc(buf_size);
493 perror("'malloc()' for 'buf1'");
497 buf2 = malloc(buf_size);
499 perror("'malloc()' for 'buf2'");
503 memset(buf1, BUF_PATTERN_1, buf_size);
504 memset(buf2, BUF_PATTERN_2, buf_size);
506 if (send(fd, buf1, buf_size, 0) != buf_size) {
507 perror("send failed");
511 if (send(fd, buf2, buf_size, 0) != buf_size) {
512 perror("send failed");
519 static void test_seqpacket_invalid_rec_buffer_server(const struct test_opts *opts)
522 unsigned char *broken_buf;
523 unsigned char *valid_buf;
524 int page_size = getpagesize();
525 int buf_size = page_size * 3;
527 int prot = PROT_READ | PROT_WRITE;
528 int flags = MAP_PRIVATE | MAP_ANONYMOUS;
531 fd = vsock_seqpacket_accept(VMADDR_CID_ANY, 1234, NULL);
537 /* Setup first buffer. */
538 broken_buf = mmap(NULL, buf_size, prot, flags, -1, 0);
539 if (broken_buf == MAP_FAILED) {
540 perror("mmap for 'broken_buf'");
544 /* Unmap "hole" in buffer. */
545 if (munmap(broken_buf + page_size, page_size)) {
546 perror("'broken_buf' setup");
550 valid_buf = mmap(NULL, buf_size, prot, flags, -1, 0);
551 if (valid_buf == MAP_FAILED) {
552 perror("mmap for 'valid_buf'");
556 /* Try to fill buffer with unmapped middle. */
557 res = read(fd, broken_buf, buf_size);
560 "expected 'broken_buf' read(2) failure, got %zi\n",
565 if (errno != ENOMEM) {
566 perror("unexpected errno of 'broken_buf'");
570 /* Try to fill valid buffer. */
571 res = read(fd, valid_buf, buf_size);
573 perror("unexpected 'valid_buf' read(2) failure");
577 if (res != buf_size) {
579 "invalid 'valid_buf' read(2), expected %i, got %zi\n",
584 for (i = 0; i < buf_size; i++) {
585 if (valid_buf[i] != BUF_PATTERN_2) {
587 "invalid pattern for 'valid_buf' at %i, expected %hhX, got %hhX\n",
588 i, BUF_PATTERN_2, valid_buf[i]);
594 munmap(broken_buf, page_size);
595 munmap(broken_buf + page_size * 2, page_size);
596 munmap(valid_buf, buf_size);
600 #define RCVLOWAT_BUF_SIZE 128
602 static void test_stream_poll_rcvlowat_server(const struct test_opts *opts)
607 fd = vsock_stream_accept(VMADDR_CID_ANY, 1234, NULL);
616 control_writeln("SRVSENT");
618 /* Wait until client is ready to receive rest of data. */
619 control_expectln("CLNSENT");
621 for (i = 0; i < RCVLOWAT_BUF_SIZE - 1; i++)
624 /* Keep socket in active state. */
625 control_expectln("POLLDONE");
630 static void test_stream_poll_rcvlowat_client(const struct test_opts *opts)
632 unsigned long lowat_val = RCVLOWAT_BUF_SIZE;
633 char buf[RCVLOWAT_BUF_SIZE];
639 fd = vsock_stream_connect(opts->peer_cid, 1234);
645 if (setsockopt(fd, SOL_SOCKET, SO_RCVLOWAT,
646 &lowat_val, sizeof(lowat_val))) {
647 perror("setsockopt");
651 control_expectln("SRVSENT");
653 /* At this point, server sent 1 byte. */
655 poll_flags = POLLIN | POLLRDNORM;
656 fds.events = poll_flags;
658 /* Try to wait for 1 sec. */
659 if (poll(&fds, 1, 1000) < 0) {
664 /* poll() must return nothing. */
666 fprintf(stderr, "Unexpected poll result %hx\n",
671 /* Tell server to send rest of data. */
672 control_writeln("CLNSENT");
675 if (poll(&fds, 1, 10000) < 0) {
680 /* Only these two bits are expected. */
681 if (fds.revents != poll_flags) {
682 fprintf(stderr, "Unexpected poll result %hx\n",
687 /* Use MSG_DONTWAIT, if call is going to wait, EAGAIN
690 read_res = recv(fd, buf, sizeof(buf), MSG_DONTWAIT);
691 if (read_res != RCVLOWAT_BUF_SIZE) {
692 fprintf(stderr, "Unexpected recv result %zi\n",
697 control_writeln("POLLDONE");
702 static struct test_case test_cases[] = {
704 .name = "SOCK_STREAM connection reset",
705 .run_client = test_stream_connection_reset,
708 .name = "SOCK_STREAM bind only",
709 .run_client = test_stream_bind_only_client,
710 .run_server = test_stream_bind_only_server,
713 .name = "SOCK_STREAM client close",
714 .run_client = test_stream_client_close_client,
715 .run_server = test_stream_client_close_server,
718 .name = "SOCK_STREAM server close",
719 .run_client = test_stream_server_close_client,
720 .run_server = test_stream_server_close_server,
723 .name = "SOCK_STREAM multiple connections",
724 .run_client = test_stream_multiconn_client,
725 .run_server = test_stream_multiconn_server,
728 .name = "SOCK_STREAM MSG_PEEK",
729 .run_client = test_stream_msg_peek_client,
730 .run_server = test_stream_msg_peek_server,
733 .name = "SOCK_SEQPACKET msg bounds",
734 .run_client = test_seqpacket_msg_bounds_client,
735 .run_server = test_seqpacket_msg_bounds_server,
738 .name = "SOCK_SEQPACKET MSG_TRUNC flag",
739 .run_client = test_seqpacket_msg_trunc_client,
740 .run_server = test_seqpacket_msg_trunc_server,
743 .name = "SOCK_SEQPACKET timeout",
744 .run_client = test_seqpacket_timeout_client,
745 .run_server = test_seqpacket_timeout_server,
748 .name = "SOCK_SEQPACKET invalid receive buffer",
749 .run_client = test_seqpacket_invalid_rec_buffer_client,
750 .run_server = test_seqpacket_invalid_rec_buffer_server,
753 .name = "SOCK_STREAM poll() + SO_RCVLOWAT",
754 .run_client = test_stream_poll_rcvlowat_client,
755 .run_server = test_stream_poll_rcvlowat_server,
760 static const char optstring[] = "";
761 static const struct option longopts[] = {
763 .name = "control-host",
764 .has_arg = required_argument,
768 .name = "control-port",
769 .has_arg = required_argument,
774 .has_arg = required_argument,
779 .has_arg = required_argument,
784 .has_arg = no_argument,
789 .has_arg = required_argument,
794 .has_arg = no_argument,
800 static void usage(void)
802 fprintf(stderr, "Usage: vsock_test [--help] [--control-host=<host>] --control-port=<port> --mode=client|server --peer-cid=<cid> [--list] [--skip=<test_id>]\n"
804 " Server: vsock_test --control-port=1234 --mode=server --peer-cid=3\n"
805 " Client: vsock_test --control-host=192.168.0.1 --control-port=1234 --mode=client --peer-cid=2\n"
807 "Run vsock.ko tests. Must be launched in both guest\n"
808 "and host. One side must use --mode=client and\n"
809 "the other side must use --mode=server.\n"
811 "A TCP control socket connection is used to coordinate tests\n"
812 "between the client and the server. The server requires a\n"
813 "listen address and the client requires an address to\n"
816 "The CID of the other side must be given with --peer-cid=<cid>.\n"
819 " --help This help message\n"
820 " --control-host <host> Server IP address to connect to\n"
821 " --control-port <port> Server port to listen on/connect to\n"
822 " --mode client|server Server or client mode\n"
823 " --peer-cid <cid> CID of the other side\n"
824 " --list List of tests that will be executed\n"
825 " --skip <test_id> Test ID to skip;\n"
826 " use multiple --skip options to skip more tests\n"
831 int main(int argc, char **argv)
833 const char *control_host = NULL;
834 const char *control_port = NULL;
835 struct test_opts opts = {
836 .mode = TEST_MODE_UNSET,
837 .peer_cid = VMADDR_CID_ANY,
843 int opt = getopt_long(argc, argv, optstring, longopts, NULL);
850 control_host = optarg;
853 if (strcmp(optarg, "client") == 0)
854 opts.mode = TEST_MODE_CLIENT;
855 else if (strcmp(optarg, "server") == 0)
856 opts.mode = TEST_MODE_SERVER;
858 fprintf(stderr, "--mode must be \"client\" or \"server\"\n");
863 opts.peer_cid = parse_cid(optarg);
866 control_port = optarg;
869 list_tests(test_cases);
872 skip_test(test_cases, ARRAY_SIZE(test_cases) - 1,
883 if (opts.mode == TEST_MODE_UNSET)
885 if (opts.peer_cid == VMADDR_CID_ANY)
889 if (opts.mode != TEST_MODE_SERVER)
891 control_host = "0.0.0.0";
894 control_init(control_host, control_port,
895 opts.mode == TEST_MODE_SERVER);
897 run_tests(test_cases, &opts);