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 SOCK_BUF_SIZE (2 * 1024 * 1024)
288 #define MAX_MSG_SIZE (32 * 1024)
290 static void test_seqpacket_msg_bounds_client(const struct test_opts *opts)
292 unsigned long curr_hash;
297 fd = vsock_seqpacket_connect(opts->peer_cid, 1234);
303 /* Wait, until receiver sets buffer size. */
304 control_expectln("SRVREADY");
307 page_size = getpagesize();
308 msg_count = SOCK_BUF_SIZE / MAX_MSG_SIZE;
310 for (int i = 0; i < msg_count; i++) {
316 /* Use "small" buffers and "big" buffers. */
318 buf_size = page_size +
319 (rand() % (MAX_MSG_SIZE - page_size));
321 buf_size = 1 + (rand() % page_size);
323 buf = malloc(buf_size);
330 memset(buf, rand() & 0xff, buf_size);
331 /* Set at least one MSG_EOR + some random. */
332 if (i == (msg_count / 2) || (rand() & 1)) {
339 send_size = send(fd, buf, buf_size, flags);
346 if (send_size != buf_size) {
347 fprintf(stderr, "Invalid send size\n");
352 * Hash sum is computed at both client and server in
354 * H += hash('message data')
355 * Such hash "controls" both data integrity and message
356 * bounds. After data exchange, both sums are compared
357 * using control socket, and if message bounds wasn't
358 * broken - two values must be equal.
360 curr_hash += hash_djb2(buf, buf_size);
364 control_writeln("SENDDONE");
365 control_writeulong(curr_hash);
369 static void test_seqpacket_msg_bounds_server(const struct test_opts *opts)
371 unsigned long sock_buf_size;
372 unsigned long remote_hash;
373 unsigned long curr_hash;
375 char buf[MAX_MSG_SIZE];
376 struct msghdr msg = {0};
377 struct iovec iov = {0};
379 fd = vsock_seqpacket_accept(VMADDR_CID_ANY, 1234, NULL);
385 sock_buf_size = SOCK_BUF_SIZE;
387 if (setsockopt(fd, AF_VSOCK, SO_VM_SOCKETS_BUFFER_MAX_SIZE,
388 &sock_buf_size, sizeof(sock_buf_size))) {
389 perror("setsockopt(SO_VM_SOCKETS_BUFFER_MAX_SIZE)");
393 if (setsockopt(fd, AF_VSOCK, SO_VM_SOCKETS_BUFFER_SIZE,
394 &sock_buf_size, sizeof(sock_buf_size))) {
395 perror("setsockopt(SO_VM_SOCKETS_BUFFER_SIZE)");
399 /* Ready to receive data. */
400 control_writeln("SRVREADY");
401 /* Wait, until peer sends whole data. */
402 control_expectln("SENDDONE");
404 iov.iov_len = sizeof(buf);
413 recv_size = recvmsg(fd, &msg, 0);
423 if (msg.msg_flags & MSG_EOR)
426 curr_hash += hash_djb2(msg.msg_iov[0].iov_base, recv_size);
430 remote_hash = control_readulong();
432 if (curr_hash != remote_hash) {
433 fprintf(stderr, "Message bounds broken\n");
438 #define MESSAGE_TRUNC_SZ 32
439 static void test_seqpacket_msg_trunc_client(const struct test_opts *opts)
442 char buf[MESSAGE_TRUNC_SZ];
444 fd = vsock_seqpacket_connect(opts->peer_cid, 1234);
450 if (send(fd, buf, sizeof(buf), 0) != sizeof(buf)) {
451 perror("send failed");
455 control_writeln("SENDDONE");
459 static void test_seqpacket_msg_trunc_server(const struct test_opts *opts)
462 char buf[MESSAGE_TRUNC_SZ / 2];
463 struct msghdr msg = {0};
464 struct iovec iov = {0};
466 fd = vsock_seqpacket_accept(VMADDR_CID_ANY, 1234, NULL);
472 control_expectln("SENDDONE");
474 iov.iov_len = sizeof(buf);
478 ssize_t ret = recvmsg(fd, &msg, MSG_TRUNC);
480 if (ret != MESSAGE_TRUNC_SZ) {
481 printf("%zi\n", ret);
482 perror("MSG_TRUNC doesn't work");
486 if (!(msg.msg_flags & MSG_TRUNC)) {
487 fprintf(stderr, "MSG_TRUNC expected\n");
494 static time_t current_nsec(void)
498 if (clock_gettime(CLOCK_REALTIME, &ts)) {
499 perror("clock_gettime(3) failed");
503 return (ts.tv_sec * 1000000000ULL) + ts.tv_nsec;
506 #define RCVTIMEO_TIMEOUT_SEC 1
507 #define READ_OVERHEAD_NSEC 250000000 /* 0.25 sec */
509 static void test_seqpacket_timeout_client(const struct test_opts *opts)
514 time_t read_enter_ns;
515 time_t read_overhead_ns;
517 fd = vsock_seqpacket_connect(opts->peer_cid, 1234);
523 tv.tv_sec = RCVTIMEO_TIMEOUT_SEC;
526 if (setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, (void *)&tv, sizeof(tv)) == -1) {
527 perror("setsockopt(SO_RCVTIMEO)");
531 read_enter_ns = current_nsec();
533 if (read(fd, &dummy, sizeof(dummy)) != -1) {
535 "expected 'dummy' read(2) failure\n");
539 if (errno != EAGAIN) {
540 perror("EAGAIN expected");
544 read_overhead_ns = current_nsec() - read_enter_ns -
545 1000000000ULL * RCVTIMEO_TIMEOUT_SEC;
547 if (read_overhead_ns > READ_OVERHEAD_NSEC) {
549 "too much time in read(2), %lu > %i ns\n",
550 read_overhead_ns, READ_OVERHEAD_NSEC);
554 control_writeln("WAITDONE");
558 static void test_seqpacket_timeout_server(const struct test_opts *opts)
562 fd = vsock_seqpacket_accept(VMADDR_CID_ANY, 1234, NULL);
568 control_expectln("WAITDONE");
572 static void test_seqpacket_bigmsg_client(const struct test_opts *opts)
574 unsigned long sock_buf_size;
580 len = sizeof(sock_buf_size);
582 fd = vsock_seqpacket_connect(opts->peer_cid, 1234);
588 if (getsockopt(fd, AF_VSOCK, SO_VM_SOCKETS_BUFFER_SIZE,
589 &sock_buf_size, &len)) {
590 perror("getsockopt");
596 data = malloc(sock_buf_size);
602 send_size = send(fd, data, sock_buf_size, 0);
603 if (send_size != -1) {
604 fprintf(stderr, "expected 'send(2)' failure, got %zi\n",
609 if (errno != EMSGSIZE) {
610 fprintf(stderr, "expected EMSGSIZE in 'errno', got %i\n",
615 control_writeln("CLISENT");
621 static void test_seqpacket_bigmsg_server(const struct test_opts *opts)
625 fd = vsock_seqpacket_accept(VMADDR_CID_ANY, 1234, NULL);
631 control_expectln("CLISENT");
636 #define BUF_PATTERN_1 'a'
637 #define BUF_PATTERN_2 'b'
639 static void test_seqpacket_invalid_rec_buffer_client(const struct test_opts *opts)
644 int buf_size = getpagesize() * 3;
646 fd = vsock_seqpacket_connect(opts->peer_cid, 1234);
652 buf1 = malloc(buf_size);
654 perror("'malloc()' for 'buf1'");
658 buf2 = malloc(buf_size);
660 perror("'malloc()' for 'buf2'");
664 memset(buf1, BUF_PATTERN_1, buf_size);
665 memset(buf2, BUF_PATTERN_2, buf_size);
667 if (send(fd, buf1, buf_size, 0) != buf_size) {
668 perror("send failed");
672 if (send(fd, buf2, buf_size, 0) != buf_size) {
673 perror("send failed");
680 static void test_seqpacket_invalid_rec_buffer_server(const struct test_opts *opts)
683 unsigned char *broken_buf;
684 unsigned char *valid_buf;
685 int page_size = getpagesize();
686 int buf_size = page_size * 3;
688 int prot = PROT_READ | PROT_WRITE;
689 int flags = MAP_PRIVATE | MAP_ANONYMOUS;
692 fd = vsock_seqpacket_accept(VMADDR_CID_ANY, 1234, NULL);
698 /* Setup first buffer. */
699 broken_buf = mmap(NULL, buf_size, prot, flags, -1, 0);
700 if (broken_buf == MAP_FAILED) {
701 perror("mmap for 'broken_buf'");
705 /* Unmap "hole" in buffer. */
706 if (munmap(broken_buf + page_size, page_size)) {
707 perror("'broken_buf' setup");
711 valid_buf = mmap(NULL, buf_size, prot, flags, -1, 0);
712 if (valid_buf == MAP_FAILED) {
713 perror("mmap for 'valid_buf'");
717 /* Try to fill buffer with unmapped middle. */
718 res = read(fd, broken_buf, buf_size);
721 "expected 'broken_buf' read(2) failure, got %zi\n",
726 if (errno != EFAULT) {
727 perror("unexpected errno of 'broken_buf'");
731 /* Try to fill valid buffer. */
732 res = read(fd, valid_buf, buf_size);
734 perror("unexpected 'valid_buf' read(2) failure");
738 if (res != buf_size) {
740 "invalid 'valid_buf' read(2), expected %i, got %zi\n",
745 for (i = 0; i < buf_size; i++) {
746 if (valid_buf[i] != BUF_PATTERN_2) {
748 "invalid pattern for 'valid_buf' at %i, expected %hhX, got %hhX\n",
749 i, BUF_PATTERN_2, valid_buf[i]);
755 munmap(broken_buf, page_size);
756 munmap(broken_buf + page_size * 2, page_size);
757 munmap(valid_buf, buf_size);
761 #define RCVLOWAT_BUF_SIZE 128
763 static void test_stream_poll_rcvlowat_server(const struct test_opts *opts)
768 fd = vsock_stream_accept(VMADDR_CID_ANY, 1234, NULL);
777 control_writeln("SRVSENT");
779 /* Wait until client is ready to receive rest of data. */
780 control_expectln("CLNSENT");
782 for (i = 0; i < RCVLOWAT_BUF_SIZE - 1; i++)
785 /* Keep socket in active state. */
786 control_expectln("POLLDONE");
791 static void test_stream_poll_rcvlowat_client(const struct test_opts *opts)
793 unsigned long lowat_val = RCVLOWAT_BUF_SIZE;
794 char buf[RCVLOWAT_BUF_SIZE];
800 fd = vsock_stream_connect(opts->peer_cid, 1234);
806 if (setsockopt(fd, SOL_SOCKET, SO_RCVLOWAT,
807 &lowat_val, sizeof(lowat_val))) {
808 perror("setsockopt(SO_RCVLOWAT)");
812 control_expectln("SRVSENT");
814 /* At this point, server sent 1 byte. */
816 poll_flags = POLLIN | POLLRDNORM;
817 fds.events = poll_flags;
819 /* Try to wait for 1 sec. */
820 if (poll(&fds, 1, 1000) < 0) {
825 /* poll() must return nothing. */
827 fprintf(stderr, "Unexpected poll result %hx\n",
832 /* Tell server to send rest of data. */
833 control_writeln("CLNSENT");
836 if (poll(&fds, 1, 10000) < 0) {
841 /* Only these two bits are expected. */
842 if (fds.revents != poll_flags) {
843 fprintf(stderr, "Unexpected poll result %hx\n",
848 /* Use MSG_DONTWAIT, if call is going to wait, EAGAIN
851 read_res = recv(fd, buf, sizeof(buf), MSG_DONTWAIT);
852 if (read_res != RCVLOWAT_BUF_SIZE) {
853 fprintf(stderr, "Unexpected recv result %zi\n",
858 control_writeln("POLLDONE");
863 #define INV_BUF_TEST_DATA_LEN 512
865 static void test_inv_buf_client(const struct test_opts *opts, bool stream)
867 unsigned char data[INV_BUF_TEST_DATA_LEN] = {0};
872 fd = vsock_stream_connect(opts->peer_cid, 1234);
874 fd = vsock_seqpacket_connect(opts->peer_cid, 1234);
881 control_expectln("SENDDONE");
883 /* Use invalid buffer here. */
884 ret = recv(fd, NULL, sizeof(data), 0);
886 fprintf(stderr, "expected recv(2) failure, got %zi\n", ret);
890 if (errno != EFAULT) {
891 fprintf(stderr, "unexpected recv(2) errno %d\n", errno);
895 ret = recv(fd, data, sizeof(data), MSG_DONTWAIT);
898 /* For SOCK_STREAM we must continue reading. */
899 if (ret != sizeof(data)) {
900 fprintf(stderr, "expected recv(2) success, got %zi\n", ret);
903 /* Don't check errno in case of success. */
905 /* For SOCK_SEQPACKET socket's queue must be empty. */
907 fprintf(stderr, "expected recv(2) failure, got %zi\n", ret);
911 if (errno != EAGAIN) {
912 fprintf(stderr, "unexpected recv(2) errno %d\n", errno);
917 control_writeln("DONE");
922 static void test_inv_buf_server(const struct test_opts *opts, bool stream)
924 unsigned char data[INV_BUF_TEST_DATA_LEN] = {0};
929 fd = vsock_stream_accept(VMADDR_CID_ANY, 1234, NULL);
931 fd = vsock_seqpacket_accept(VMADDR_CID_ANY, 1234, NULL);
938 res = send(fd, data, sizeof(data), 0);
939 if (res != sizeof(data)) {
940 fprintf(stderr, "unexpected send(2) result %zi\n", res);
944 control_writeln("SENDDONE");
946 control_expectln("DONE");
951 static void test_stream_inv_buf_client(const struct test_opts *opts)
953 test_inv_buf_client(opts, true);
956 static void test_stream_inv_buf_server(const struct test_opts *opts)
958 test_inv_buf_server(opts, true);
961 static void test_seqpacket_inv_buf_client(const struct test_opts *opts)
963 test_inv_buf_client(opts, false);
966 static void test_seqpacket_inv_buf_server(const struct test_opts *opts)
968 test_inv_buf_server(opts, false);
971 #define HELLO_STR "HELLO"
972 #define WORLD_STR "WORLD"
974 static void test_stream_virtio_skb_merge_client(const struct test_opts *opts)
979 fd = vsock_stream_connect(opts->peer_cid, 1234);
985 /* Send first skbuff. */
986 res = send(fd, HELLO_STR, strlen(HELLO_STR), 0);
987 if (res != strlen(HELLO_STR)) {
988 fprintf(stderr, "unexpected send(2) result %zi\n", res);
992 control_writeln("SEND0");
993 /* Peer reads part of first skbuff. */
994 control_expectln("REPLY0");
996 /* Send second skbuff, it will be appended to the first. */
997 res = send(fd, WORLD_STR, strlen(WORLD_STR), 0);
998 if (res != strlen(WORLD_STR)) {
999 fprintf(stderr, "unexpected send(2) result %zi\n", res);
1003 control_writeln("SEND1");
1004 /* Peer reads merged skbuff packet. */
1005 control_expectln("REPLY1");
1010 static void test_stream_virtio_skb_merge_server(const struct test_opts *opts)
1012 unsigned char buf[64];
1016 fd = vsock_stream_accept(VMADDR_CID_ANY, 1234, NULL);
1022 control_expectln("SEND0");
1024 /* Read skbuff partially. */
1025 res = recv(fd, buf, 2, 0);
1027 fprintf(stderr, "expected recv(2) returns 2 bytes, got %zi\n", res);
1031 control_writeln("REPLY0");
1032 control_expectln("SEND1");
1034 res = recv(fd, buf + 2, sizeof(buf) - 2, 0);
1036 fprintf(stderr, "expected recv(2) returns 8 bytes, got %zi\n", res);
1040 res = recv(fd, buf, sizeof(buf) - 8 - 2, MSG_DONTWAIT);
1042 fprintf(stderr, "expected recv(2) failure, got %zi\n", res);
1046 if (memcmp(buf, HELLO_STR WORLD_STR, strlen(HELLO_STR WORLD_STR))) {
1047 fprintf(stderr, "pattern mismatch\n");
1051 control_writeln("REPLY1");
1056 static struct test_case test_cases[] = {
1058 .name = "SOCK_STREAM connection reset",
1059 .run_client = test_stream_connection_reset,
1062 .name = "SOCK_STREAM bind only",
1063 .run_client = test_stream_bind_only_client,
1064 .run_server = test_stream_bind_only_server,
1067 .name = "SOCK_STREAM client close",
1068 .run_client = test_stream_client_close_client,
1069 .run_server = test_stream_client_close_server,
1072 .name = "SOCK_STREAM server close",
1073 .run_client = test_stream_server_close_client,
1074 .run_server = test_stream_server_close_server,
1077 .name = "SOCK_STREAM multiple connections",
1078 .run_client = test_stream_multiconn_client,
1079 .run_server = test_stream_multiconn_server,
1082 .name = "SOCK_STREAM MSG_PEEK",
1083 .run_client = test_stream_msg_peek_client,
1084 .run_server = test_stream_msg_peek_server,
1087 .name = "SOCK_SEQPACKET msg bounds",
1088 .run_client = test_seqpacket_msg_bounds_client,
1089 .run_server = test_seqpacket_msg_bounds_server,
1092 .name = "SOCK_SEQPACKET MSG_TRUNC flag",
1093 .run_client = test_seqpacket_msg_trunc_client,
1094 .run_server = test_seqpacket_msg_trunc_server,
1097 .name = "SOCK_SEQPACKET timeout",
1098 .run_client = test_seqpacket_timeout_client,
1099 .run_server = test_seqpacket_timeout_server,
1102 .name = "SOCK_SEQPACKET invalid receive buffer",
1103 .run_client = test_seqpacket_invalid_rec_buffer_client,
1104 .run_server = test_seqpacket_invalid_rec_buffer_server,
1107 .name = "SOCK_STREAM poll() + SO_RCVLOWAT",
1108 .run_client = test_stream_poll_rcvlowat_client,
1109 .run_server = test_stream_poll_rcvlowat_server,
1112 .name = "SOCK_SEQPACKET big message",
1113 .run_client = test_seqpacket_bigmsg_client,
1114 .run_server = test_seqpacket_bigmsg_server,
1117 .name = "SOCK_STREAM test invalid buffer",
1118 .run_client = test_stream_inv_buf_client,
1119 .run_server = test_stream_inv_buf_server,
1122 .name = "SOCK_SEQPACKET test invalid buffer",
1123 .run_client = test_seqpacket_inv_buf_client,
1124 .run_server = test_seqpacket_inv_buf_server,
1127 .name = "SOCK_STREAM virtio skb merge",
1128 .run_client = test_stream_virtio_skb_merge_client,
1129 .run_server = test_stream_virtio_skb_merge_server,
1134 static const char optstring[] = "";
1135 static const struct option longopts[] = {
1137 .name = "control-host",
1138 .has_arg = required_argument,
1142 .name = "control-port",
1143 .has_arg = required_argument,
1148 .has_arg = required_argument,
1153 .has_arg = required_argument,
1158 .has_arg = no_argument,
1163 .has_arg = required_argument,
1168 .has_arg = no_argument,
1174 static void usage(void)
1176 fprintf(stderr, "Usage: vsock_test [--help] [--control-host=<host>] --control-port=<port> --mode=client|server --peer-cid=<cid> [--list] [--skip=<test_id>]\n"
1178 " Server: vsock_test --control-port=1234 --mode=server --peer-cid=3\n"
1179 " Client: vsock_test --control-host=192.168.0.1 --control-port=1234 --mode=client --peer-cid=2\n"
1181 "Run vsock.ko tests. Must be launched in both guest\n"
1182 "and host. One side must use --mode=client and\n"
1183 "the other side must use --mode=server.\n"
1185 "A TCP control socket connection is used to coordinate tests\n"
1186 "between the client and the server. The server requires a\n"
1187 "listen address and the client requires an address to\n"
1190 "The CID of the other side must be given with --peer-cid=<cid>.\n"
1193 " --help This help message\n"
1194 " --control-host <host> Server IP address to connect to\n"
1195 " --control-port <port> Server port to listen on/connect to\n"
1196 " --mode client|server Server or client mode\n"
1197 " --peer-cid <cid> CID of the other side\n"
1198 " --list List of tests that will be executed\n"
1199 " --skip <test_id> Test ID to skip;\n"
1200 " use multiple --skip options to skip more tests\n"
1205 int main(int argc, char **argv)
1207 const char *control_host = NULL;
1208 const char *control_port = NULL;
1209 struct test_opts opts = {
1210 .mode = TEST_MODE_UNSET,
1211 .peer_cid = VMADDR_CID_ANY,
1218 int opt = getopt_long(argc, argv, optstring, longopts, NULL);
1225 control_host = optarg;
1228 if (strcmp(optarg, "client") == 0)
1229 opts.mode = TEST_MODE_CLIENT;
1230 else if (strcmp(optarg, "server") == 0)
1231 opts.mode = TEST_MODE_SERVER;
1233 fprintf(stderr, "--mode must be \"client\" or \"server\"\n");
1234 return EXIT_FAILURE;
1238 opts.peer_cid = parse_cid(optarg);
1241 control_port = optarg;
1244 list_tests(test_cases);
1247 skip_test(test_cases, ARRAY_SIZE(test_cases) - 1,
1258 if (opts.mode == TEST_MODE_UNSET)
1260 if (opts.peer_cid == VMADDR_CID_ANY)
1263 if (!control_host) {
1264 if (opts.mode != TEST_MODE_SERVER)
1266 control_host = "0.0.0.0";
1269 control_init(control_host, control_port,
1270 opts.mode == TEST_MODE_SERVER);
1272 run_tests(test_cases, &opts);
1275 return EXIT_SUCCESS;