xref: /openbmc/linux/tools/testing/vsock/vsock_test.c (revision 78c06141)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * vsock_test - vsock.ko test suite
4  *
5  * Copyright (C) 2017 Red Hat, Inc.
6  *
7  * Author: Stefan Hajnoczi <stefanha@redhat.com>
8  */
9 
10 #include <getopt.h>
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <string.h>
14 #include <errno.h>
15 #include <unistd.h>
16 #include <linux/kernel.h>
17 #include <sys/types.h>
18 #include <sys/socket.h>
19 #include <time.h>
20 #include <sys/mman.h>
21 #include <poll.h>
22 
23 #include "timeout.h"
24 #include "control.h"
25 #include "util.h"
26 
test_stream_connection_reset(const struct test_opts * opts)27 static void test_stream_connection_reset(const struct test_opts *opts)
28 {
29 	union {
30 		struct sockaddr sa;
31 		struct sockaddr_vm svm;
32 	} addr = {
33 		.svm = {
34 			.svm_family = AF_VSOCK,
35 			.svm_port = 1234,
36 			.svm_cid = opts->peer_cid,
37 		},
38 	};
39 	int ret;
40 	int fd;
41 
42 	fd = socket(AF_VSOCK, SOCK_STREAM, 0);
43 
44 	timeout_begin(TIMEOUT);
45 	do {
46 		ret = connect(fd, &addr.sa, sizeof(addr.svm));
47 		timeout_check("connect");
48 	} while (ret < 0 && errno == EINTR);
49 	timeout_end();
50 
51 	if (ret != -1) {
52 		fprintf(stderr, "expected connect(2) failure, got %d\n", ret);
53 		exit(EXIT_FAILURE);
54 	}
55 	if (errno != ECONNRESET) {
56 		fprintf(stderr, "unexpected connect(2) errno %d\n", errno);
57 		exit(EXIT_FAILURE);
58 	}
59 
60 	close(fd);
61 }
62 
test_stream_bind_only_client(const struct test_opts * opts)63 static void test_stream_bind_only_client(const struct test_opts *opts)
64 {
65 	union {
66 		struct sockaddr sa;
67 		struct sockaddr_vm svm;
68 	} addr = {
69 		.svm = {
70 			.svm_family = AF_VSOCK,
71 			.svm_port = 1234,
72 			.svm_cid = opts->peer_cid,
73 		},
74 	};
75 	int ret;
76 	int fd;
77 
78 	/* Wait for the server to be ready */
79 	control_expectln("BIND");
80 
81 	fd = socket(AF_VSOCK, SOCK_STREAM, 0);
82 
83 	timeout_begin(TIMEOUT);
84 	do {
85 		ret = connect(fd, &addr.sa, sizeof(addr.svm));
86 		timeout_check("connect");
87 	} while (ret < 0 && errno == EINTR);
88 	timeout_end();
89 
90 	if (ret != -1) {
91 		fprintf(stderr, "expected connect(2) failure, got %d\n", ret);
92 		exit(EXIT_FAILURE);
93 	}
94 	if (errno != ECONNRESET) {
95 		fprintf(stderr, "unexpected connect(2) errno %d\n", errno);
96 		exit(EXIT_FAILURE);
97 	}
98 
99 	/* Notify the server that the client has finished */
100 	control_writeln("DONE");
101 
102 	close(fd);
103 }
104 
test_stream_bind_only_server(const struct test_opts * opts)105 static void test_stream_bind_only_server(const struct test_opts *opts)
106 {
107 	union {
108 		struct sockaddr sa;
109 		struct sockaddr_vm svm;
110 	} addr = {
111 		.svm = {
112 			.svm_family = AF_VSOCK,
113 			.svm_port = 1234,
114 			.svm_cid = VMADDR_CID_ANY,
115 		},
116 	};
117 	int fd;
118 
119 	fd = socket(AF_VSOCK, SOCK_STREAM, 0);
120 
121 	if (bind(fd, &addr.sa, sizeof(addr.svm)) < 0) {
122 		perror("bind");
123 		exit(EXIT_FAILURE);
124 	}
125 
126 	/* Notify the client that the server is ready */
127 	control_writeln("BIND");
128 
129 	/* Wait for the client to finish */
130 	control_expectln("DONE");
131 
132 	close(fd);
133 }
134 
test_stream_client_close_client(const struct test_opts * opts)135 static void test_stream_client_close_client(const struct test_opts *opts)
136 {
137 	int fd;
138 
139 	fd = vsock_stream_connect(opts->peer_cid, 1234);
140 	if (fd < 0) {
141 		perror("connect");
142 		exit(EXIT_FAILURE);
143 	}
144 
145 	send_byte(fd, 1, 0);
146 	close(fd);
147 }
148 
test_stream_client_close_server(const struct test_opts * opts)149 static void test_stream_client_close_server(const struct test_opts *opts)
150 {
151 	int fd;
152 
153 	fd = vsock_stream_accept(VMADDR_CID_ANY, 1234, NULL);
154 	if (fd < 0) {
155 		perror("accept");
156 		exit(EXIT_FAILURE);
157 	}
158 
159 	/* Wait for the remote to close the connection, before check
160 	 * -EPIPE error on send.
161 	 */
162 	vsock_wait_remote_close(fd);
163 
164 	send_byte(fd, -EPIPE, 0);
165 	recv_byte(fd, 1, 0);
166 	recv_byte(fd, 0, 0);
167 	close(fd);
168 }
169 
test_stream_server_close_client(const struct test_opts * opts)170 static void test_stream_server_close_client(const struct test_opts *opts)
171 {
172 	int fd;
173 
174 	fd = vsock_stream_connect(opts->peer_cid, 1234);
175 	if (fd < 0) {
176 		perror("connect");
177 		exit(EXIT_FAILURE);
178 	}
179 
180 	/* Wait for the remote to close the connection, before check
181 	 * -EPIPE error on send.
182 	 */
183 	vsock_wait_remote_close(fd);
184 
185 	send_byte(fd, -EPIPE, 0);
186 	recv_byte(fd, 1, 0);
187 	recv_byte(fd, 0, 0);
188 	close(fd);
189 }
190 
test_stream_server_close_server(const struct test_opts * opts)191 static void test_stream_server_close_server(const struct test_opts *opts)
192 {
193 	int fd;
194 
195 	fd = vsock_stream_accept(VMADDR_CID_ANY, 1234, NULL);
196 	if (fd < 0) {
197 		perror("accept");
198 		exit(EXIT_FAILURE);
199 	}
200 
201 	send_byte(fd, 1, 0);
202 	close(fd);
203 }
204 
205 /* With the standard socket sizes, VMCI is able to support about 100
206  * concurrent stream connections.
207  */
208 #define MULTICONN_NFDS 100
209 
test_stream_multiconn_client(const struct test_opts * opts)210 static void test_stream_multiconn_client(const struct test_opts *opts)
211 {
212 	int fds[MULTICONN_NFDS];
213 	int i;
214 
215 	for (i = 0; i < MULTICONN_NFDS; i++) {
216 		fds[i] = vsock_stream_connect(opts->peer_cid, 1234);
217 		if (fds[i] < 0) {
218 			perror("connect");
219 			exit(EXIT_FAILURE);
220 		}
221 	}
222 
223 	for (i = 0; i < MULTICONN_NFDS; i++) {
224 		if (i % 2)
225 			recv_byte(fds[i], 1, 0);
226 		else
227 			send_byte(fds[i], 1, 0);
228 	}
229 
230 	for (i = 0; i < MULTICONN_NFDS; i++)
231 		close(fds[i]);
232 }
233 
test_stream_multiconn_server(const struct test_opts * opts)234 static void test_stream_multiconn_server(const struct test_opts *opts)
235 {
236 	int fds[MULTICONN_NFDS];
237 	int i;
238 
239 	for (i = 0; i < MULTICONN_NFDS; i++) {
240 		fds[i] = vsock_stream_accept(VMADDR_CID_ANY, 1234, NULL);
241 		if (fds[i] < 0) {
242 			perror("accept");
243 			exit(EXIT_FAILURE);
244 		}
245 	}
246 
247 	for (i = 0; i < MULTICONN_NFDS; i++) {
248 		if (i % 2)
249 			send_byte(fds[i], 1, 0);
250 		else
251 			recv_byte(fds[i], 1, 0);
252 	}
253 
254 	for (i = 0; i < MULTICONN_NFDS; i++)
255 		close(fds[i]);
256 }
257 
258 #define MSG_PEEK_BUF_LEN 64
259 
test_msg_peek_client(const struct test_opts * opts,bool seqpacket)260 static void test_msg_peek_client(const struct test_opts *opts,
261 				 bool seqpacket)
262 {
263 	unsigned char buf[MSG_PEEK_BUF_LEN];
264 	ssize_t send_size;
265 	int fd;
266 	int i;
267 
268 	if (seqpacket)
269 		fd = vsock_seqpacket_connect(opts->peer_cid, 1234);
270 	else
271 		fd = vsock_stream_connect(opts->peer_cid, 1234);
272 
273 	if (fd < 0) {
274 		perror("connect");
275 		exit(EXIT_FAILURE);
276 	}
277 
278 	for (i = 0; i < sizeof(buf); i++)
279 		buf[i] = rand() & 0xFF;
280 
281 	control_expectln("SRVREADY");
282 
283 	send_size = send(fd, buf, sizeof(buf), 0);
284 
285 	if (send_size < 0) {
286 		perror("send");
287 		exit(EXIT_FAILURE);
288 	}
289 
290 	if (send_size != sizeof(buf)) {
291 		fprintf(stderr, "Invalid send size %zi\n", send_size);
292 		exit(EXIT_FAILURE);
293 	}
294 
295 	close(fd);
296 }
297 
test_msg_peek_server(const struct test_opts * opts,bool seqpacket)298 static void test_msg_peek_server(const struct test_opts *opts,
299 				 bool seqpacket)
300 {
301 	unsigned char buf_half[MSG_PEEK_BUF_LEN / 2];
302 	unsigned char buf_normal[MSG_PEEK_BUF_LEN];
303 	unsigned char buf_peek[MSG_PEEK_BUF_LEN];
304 	ssize_t res;
305 	int fd;
306 
307 	if (seqpacket)
308 		fd = vsock_seqpacket_accept(VMADDR_CID_ANY, 1234, NULL);
309 	else
310 		fd = vsock_stream_accept(VMADDR_CID_ANY, 1234, NULL);
311 
312 	if (fd < 0) {
313 		perror("accept");
314 		exit(EXIT_FAILURE);
315 	}
316 
317 	/* Peek from empty socket. */
318 	res = recv(fd, buf_peek, sizeof(buf_peek), MSG_PEEK | MSG_DONTWAIT);
319 	if (res != -1) {
320 		fprintf(stderr, "expected recv(2) failure, got %zi\n", res);
321 		exit(EXIT_FAILURE);
322 	}
323 
324 	if (errno != EAGAIN) {
325 		perror("EAGAIN expected");
326 		exit(EXIT_FAILURE);
327 	}
328 
329 	control_writeln("SRVREADY");
330 
331 	/* Peek part of data. */
332 	res = recv(fd, buf_half, sizeof(buf_half), MSG_PEEK);
333 	if (res != sizeof(buf_half)) {
334 		fprintf(stderr, "recv(2) + MSG_PEEK, expected %zu, got %zi\n",
335 			sizeof(buf_half), res);
336 		exit(EXIT_FAILURE);
337 	}
338 
339 	/* Peek whole data. */
340 	res = recv(fd, buf_peek, sizeof(buf_peek), MSG_PEEK);
341 	if (res != sizeof(buf_peek)) {
342 		fprintf(stderr, "recv(2) + MSG_PEEK, expected %zu, got %zi\n",
343 			sizeof(buf_peek), res);
344 		exit(EXIT_FAILURE);
345 	}
346 
347 	/* Compare partial and full peek. */
348 	if (memcmp(buf_half, buf_peek, sizeof(buf_half))) {
349 		fprintf(stderr, "Partial peek data mismatch\n");
350 		exit(EXIT_FAILURE);
351 	}
352 
353 	if (seqpacket) {
354 		/* This type of socket supports MSG_TRUNC flag,
355 		 * so check it with MSG_PEEK. We must get length
356 		 * of the message.
357 		 */
358 		res = recv(fd, buf_half, sizeof(buf_half), MSG_PEEK |
359 			   MSG_TRUNC);
360 		if (res != sizeof(buf_peek)) {
361 			fprintf(stderr,
362 				"recv(2) + MSG_PEEK | MSG_TRUNC, exp %zu, got %zi\n",
363 				sizeof(buf_half), res);
364 			exit(EXIT_FAILURE);
365 		}
366 	}
367 
368 	res = recv(fd, buf_normal, sizeof(buf_normal), 0);
369 	if (res != sizeof(buf_normal)) {
370 		fprintf(stderr, "recv(2), expected %zu, got %zi\n",
371 			sizeof(buf_normal), res);
372 		exit(EXIT_FAILURE);
373 	}
374 
375 	/* Compare full peek and normal read. */
376 	if (memcmp(buf_peek, buf_normal, sizeof(buf_peek))) {
377 		fprintf(stderr, "Full peek data mismatch\n");
378 		exit(EXIT_FAILURE);
379 	}
380 
381 	close(fd);
382 }
383 
test_stream_msg_peek_client(const struct test_opts * opts)384 static void test_stream_msg_peek_client(const struct test_opts *opts)
385 {
386 	return test_msg_peek_client(opts, false);
387 }
388 
test_stream_msg_peek_server(const struct test_opts * opts)389 static void test_stream_msg_peek_server(const struct test_opts *opts)
390 {
391 	return test_msg_peek_server(opts, false);
392 }
393 
394 #define SOCK_BUF_SIZE (2 * 1024 * 1024)
395 #define MAX_MSG_PAGES 4
396 
test_seqpacket_msg_bounds_client(const struct test_opts * opts)397 static void test_seqpacket_msg_bounds_client(const struct test_opts *opts)
398 {
399 	unsigned long curr_hash;
400 	size_t max_msg_size;
401 	int page_size;
402 	int msg_count;
403 	int fd;
404 
405 	fd = vsock_seqpacket_connect(opts->peer_cid, 1234);
406 	if (fd < 0) {
407 		perror("connect");
408 		exit(EXIT_FAILURE);
409 	}
410 
411 	/* Wait, until receiver sets buffer size. */
412 	control_expectln("SRVREADY");
413 
414 	curr_hash = 0;
415 	page_size = getpagesize();
416 	max_msg_size = MAX_MSG_PAGES * page_size;
417 	msg_count = SOCK_BUF_SIZE / max_msg_size;
418 
419 	for (int i = 0; i < msg_count; i++) {
420 		ssize_t send_size;
421 		size_t buf_size;
422 		int flags;
423 		void *buf;
424 
425 		/* Use "small" buffers and "big" buffers. */
426 		if (i & 1)
427 			buf_size = page_size +
428 					(rand() % (max_msg_size - page_size));
429 		else
430 			buf_size = 1 + (rand() % page_size);
431 
432 		buf = malloc(buf_size);
433 
434 		if (!buf) {
435 			perror("malloc");
436 			exit(EXIT_FAILURE);
437 		}
438 
439 		memset(buf, rand() & 0xff, buf_size);
440 		/* Set at least one MSG_EOR + some random. */
441 		if (i == (msg_count / 2) || (rand() & 1)) {
442 			flags = MSG_EOR;
443 			curr_hash++;
444 		} else {
445 			flags = 0;
446 		}
447 
448 		send_size = send(fd, buf, buf_size, flags);
449 
450 		if (send_size < 0) {
451 			perror("send");
452 			exit(EXIT_FAILURE);
453 		}
454 
455 		if (send_size != buf_size) {
456 			fprintf(stderr, "Invalid send size\n");
457 			exit(EXIT_FAILURE);
458 		}
459 
460 		/*
461 		 * Hash sum is computed at both client and server in
462 		 * the same way:
463 		 * H += hash('message data')
464 		 * Such hash "controls" both data integrity and message
465 		 * bounds. After data exchange, both sums are compared
466 		 * using control socket, and if message bounds wasn't
467 		 * broken - two values must be equal.
468 		 */
469 		curr_hash += hash_djb2(buf, buf_size);
470 		free(buf);
471 	}
472 
473 	control_writeln("SENDDONE");
474 	control_writeulong(curr_hash);
475 	close(fd);
476 }
477 
test_seqpacket_msg_bounds_server(const struct test_opts * opts)478 static void test_seqpacket_msg_bounds_server(const struct test_opts *opts)
479 {
480 	unsigned long sock_buf_size;
481 	unsigned long remote_hash;
482 	unsigned long curr_hash;
483 	int fd;
484 	struct msghdr msg = {0};
485 	struct iovec iov = {0};
486 
487 	fd = vsock_seqpacket_accept(VMADDR_CID_ANY, 1234, NULL);
488 	if (fd < 0) {
489 		perror("accept");
490 		exit(EXIT_FAILURE);
491 	}
492 
493 	sock_buf_size = SOCK_BUF_SIZE;
494 
495 	if (setsockopt(fd, AF_VSOCK, SO_VM_SOCKETS_BUFFER_MAX_SIZE,
496 		       &sock_buf_size, sizeof(sock_buf_size))) {
497 		perror("setsockopt(SO_VM_SOCKETS_BUFFER_MAX_SIZE)");
498 		exit(EXIT_FAILURE);
499 	}
500 
501 	if (setsockopt(fd, AF_VSOCK, SO_VM_SOCKETS_BUFFER_SIZE,
502 		       &sock_buf_size, sizeof(sock_buf_size))) {
503 		perror("setsockopt(SO_VM_SOCKETS_BUFFER_SIZE)");
504 		exit(EXIT_FAILURE);
505 	}
506 
507 	/* Ready to receive data. */
508 	control_writeln("SRVREADY");
509 	/* Wait, until peer sends whole data. */
510 	control_expectln("SENDDONE");
511 	iov.iov_len = MAX_MSG_PAGES * getpagesize();
512 	iov.iov_base = malloc(iov.iov_len);
513 	if (!iov.iov_base) {
514 		perror("malloc");
515 		exit(EXIT_FAILURE);
516 	}
517 
518 	msg.msg_iov = &iov;
519 	msg.msg_iovlen = 1;
520 
521 	curr_hash = 0;
522 
523 	while (1) {
524 		ssize_t recv_size;
525 
526 		recv_size = recvmsg(fd, &msg, 0);
527 
528 		if (!recv_size)
529 			break;
530 
531 		if (recv_size < 0) {
532 			perror("recvmsg");
533 			exit(EXIT_FAILURE);
534 		}
535 
536 		if (msg.msg_flags & MSG_EOR)
537 			curr_hash++;
538 
539 		curr_hash += hash_djb2(msg.msg_iov[0].iov_base, recv_size);
540 	}
541 
542 	free(iov.iov_base);
543 	close(fd);
544 	remote_hash = control_readulong();
545 
546 	if (curr_hash != remote_hash) {
547 		fprintf(stderr, "Message bounds broken\n");
548 		exit(EXIT_FAILURE);
549 	}
550 }
551 
552 #define MESSAGE_TRUNC_SZ 32
test_seqpacket_msg_trunc_client(const struct test_opts * opts)553 static void test_seqpacket_msg_trunc_client(const struct test_opts *opts)
554 {
555 	int fd;
556 	char buf[MESSAGE_TRUNC_SZ];
557 
558 	fd = vsock_seqpacket_connect(opts->peer_cid, 1234);
559 	if (fd < 0) {
560 		perror("connect");
561 		exit(EXIT_FAILURE);
562 	}
563 
564 	if (send(fd, buf, sizeof(buf), 0) != sizeof(buf)) {
565 		perror("send failed");
566 		exit(EXIT_FAILURE);
567 	}
568 
569 	control_writeln("SENDDONE");
570 	close(fd);
571 }
572 
test_seqpacket_msg_trunc_server(const struct test_opts * opts)573 static void test_seqpacket_msg_trunc_server(const struct test_opts *opts)
574 {
575 	int fd;
576 	char buf[MESSAGE_TRUNC_SZ / 2];
577 	struct msghdr msg = {0};
578 	struct iovec iov = {0};
579 
580 	fd = vsock_seqpacket_accept(VMADDR_CID_ANY, 1234, NULL);
581 	if (fd < 0) {
582 		perror("accept");
583 		exit(EXIT_FAILURE);
584 	}
585 
586 	control_expectln("SENDDONE");
587 	iov.iov_base = buf;
588 	iov.iov_len = sizeof(buf);
589 	msg.msg_iov = &iov;
590 	msg.msg_iovlen = 1;
591 
592 	ssize_t ret = recvmsg(fd, &msg, MSG_TRUNC);
593 
594 	if (ret != MESSAGE_TRUNC_SZ) {
595 		printf("%zi\n", ret);
596 		perror("MSG_TRUNC doesn't work");
597 		exit(EXIT_FAILURE);
598 	}
599 
600 	if (!(msg.msg_flags & MSG_TRUNC)) {
601 		fprintf(stderr, "MSG_TRUNC expected\n");
602 		exit(EXIT_FAILURE);
603 	}
604 
605 	close(fd);
606 }
607 
current_nsec(void)608 static time_t current_nsec(void)
609 {
610 	struct timespec ts;
611 
612 	if (clock_gettime(CLOCK_REALTIME, &ts)) {
613 		perror("clock_gettime(3) failed");
614 		exit(EXIT_FAILURE);
615 	}
616 
617 	return (ts.tv_sec * 1000000000ULL) + ts.tv_nsec;
618 }
619 
620 #define RCVTIMEO_TIMEOUT_SEC 1
621 #define READ_OVERHEAD_NSEC 250000000 /* 0.25 sec */
622 
test_seqpacket_timeout_client(const struct test_opts * opts)623 static void test_seqpacket_timeout_client(const struct test_opts *opts)
624 {
625 	int fd;
626 	struct timeval tv;
627 	char dummy;
628 	time_t read_enter_ns;
629 	time_t read_overhead_ns;
630 
631 	fd = vsock_seqpacket_connect(opts->peer_cid, 1234);
632 	if (fd < 0) {
633 		perror("connect");
634 		exit(EXIT_FAILURE);
635 	}
636 
637 	tv.tv_sec = RCVTIMEO_TIMEOUT_SEC;
638 	tv.tv_usec = 0;
639 
640 	if (setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, (void *)&tv, sizeof(tv)) == -1) {
641 		perror("setsockopt(SO_RCVTIMEO)");
642 		exit(EXIT_FAILURE);
643 	}
644 
645 	read_enter_ns = current_nsec();
646 
647 	if (read(fd, &dummy, sizeof(dummy)) != -1) {
648 		fprintf(stderr,
649 			"expected 'dummy' read(2) failure\n");
650 		exit(EXIT_FAILURE);
651 	}
652 
653 	if (errno != EAGAIN) {
654 		perror("EAGAIN expected");
655 		exit(EXIT_FAILURE);
656 	}
657 
658 	read_overhead_ns = current_nsec() - read_enter_ns -
659 			1000000000ULL * RCVTIMEO_TIMEOUT_SEC;
660 
661 	if (read_overhead_ns > READ_OVERHEAD_NSEC) {
662 		fprintf(stderr,
663 			"too much time in read(2), %lu > %i ns\n",
664 			read_overhead_ns, READ_OVERHEAD_NSEC);
665 		exit(EXIT_FAILURE);
666 	}
667 
668 	control_writeln("WAITDONE");
669 	close(fd);
670 }
671 
test_seqpacket_timeout_server(const struct test_opts * opts)672 static void test_seqpacket_timeout_server(const struct test_opts *opts)
673 {
674 	int fd;
675 
676 	fd = vsock_seqpacket_accept(VMADDR_CID_ANY, 1234, NULL);
677 	if (fd < 0) {
678 		perror("accept");
679 		exit(EXIT_FAILURE);
680 	}
681 
682 	control_expectln("WAITDONE");
683 	close(fd);
684 }
685 
test_seqpacket_bigmsg_client(const struct test_opts * opts)686 static void test_seqpacket_bigmsg_client(const struct test_opts *opts)
687 {
688 	unsigned long sock_buf_size;
689 	ssize_t send_size;
690 	socklen_t len;
691 	void *data;
692 	int fd;
693 
694 	len = sizeof(sock_buf_size);
695 
696 	fd = vsock_seqpacket_connect(opts->peer_cid, 1234);
697 	if (fd < 0) {
698 		perror("connect");
699 		exit(EXIT_FAILURE);
700 	}
701 
702 	if (getsockopt(fd, AF_VSOCK, SO_VM_SOCKETS_BUFFER_SIZE,
703 		       &sock_buf_size, &len)) {
704 		perror("getsockopt");
705 		exit(EXIT_FAILURE);
706 	}
707 
708 	sock_buf_size++;
709 
710 	data = malloc(sock_buf_size);
711 	if (!data) {
712 		perror("malloc");
713 		exit(EXIT_FAILURE);
714 	}
715 
716 	send_size = send(fd, data, sock_buf_size, 0);
717 	if (send_size != -1) {
718 		fprintf(stderr, "expected 'send(2)' failure, got %zi\n",
719 			send_size);
720 		exit(EXIT_FAILURE);
721 	}
722 
723 	if (errno != EMSGSIZE) {
724 		fprintf(stderr, "expected EMSGSIZE in 'errno', got %i\n",
725 			errno);
726 		exit(EXIT_FAILURE);
727 	}
728 
729 	control_writeln("CLISENT");
730 
731 	free(data);
732 	close(fd);
733 }
734 
test_seqpacket_bigmsg_server(const struct test_opts * opts)735 static void test_seqpacket_bigmsg_server(const struct test_opts *opts)
736 {
737 	int fd;
738 
739 	fd = vsock_seqpacket_accept(VMADDR_CID_ANY, 1234, NULL);
740 	if (fd < 0) {
741 		perror("accept");
742 		exit(EXIT_FAILURE);
743 	}
744 
745 	control_expectln("CLISENT");
746 
747 	close(fd);
748 }
749 
750 #define BUF_PATTERN_1 'a'
751 #define BUF_PATTERN_2 'b'
752 
test_seqpacket_invalid_rec_buffer_client(const struct test_opts * opts)753 static void test_seqpacket_invalid_rec_buffer_client(const struct test_opts *opts)
754 {
755 	int fd;
756 	unsigned char *buf1;
757 	unsigned char *buf2;
758 	int buf_size = getpagesize() * 3;
759 
760 	fd = vsock_seqpacket_connect(opts->peer_cid, 1234);
761 	if (fd < 0) {
762 		perror("connect");
763 		exit(EXIT_FAILURE);
764 	}
765 
766 	buf1 = malloc(buf_size);
767 	if (!buf1) {
768 		perror("'malloc()' for 'buf1'");
769 		exit(EXIT_FAILURE);
770 	}
771 
772 	buf2 = malloc(buf_size);
773 	if (!buf2) {
774 		perror("'malloc()' for 'buf2'");
775 		exit(EXIT_FAILURE);
776 	}
777 
778 	memset(buf1, BUF_PATTERN_1, buf_size);
779 	memset(buf2, BUF_PATTERN_2, buf_size);
780 
781 	if (send(fd, buf1, buf_size, 0) != buf_size) {
782 		perror("send failed");
783 		exit(EXIT_FAILURE);
784 	}
785 
786 	if (send(fd, buf2, buf_size, 0) != buf_size) {
787 		perror("send failed");
788 		exit(EXIT_FAILURE);
789 	}
790 
791 	close(fd);
792 }
793 
test_seqpacket_invalid_rec_buffer_server(const struct test_opts * opts)794 static void test_seqpacket_invalid_rec_buffer_server(const struct test_opts *opts)
795 {
796 	int fd;
797 	unsigned char *broken_buf;
798 	unsigned char *valid_buf;
799 	int page_size = getpagesize();
800 	int buf_size = page_size * 3;
801 	ssize_t res;
802 	int prot = PROT_READ | PROT_WRITE;
803 	int flags = MAP_PRIVATE | MAP_ANONYMOUS;
804 	int i;
805 
806 	fd = vsock_seqpacket_accept(VMADDR_CID_ANY, 1234, NULL);
807 	if (fd < 0) {
808 		perror("accept");
809 		exit(EXIT_FAILURE);
810 	}
811 
812 	/* Setup first buffer. */
813 	broken_buf = mmap(NULL, buf_size, prot, flags, -1, 0);
814 	if (broken_buf == MAP_FAILED) {
815 		perror("mmap for 'broken_buf'");
816 		exit(EXIT_FAILURE);
817 	}
818 
819 	/* Unmap "hole" in buffer. */
820 	if (munmap(broken_buf + page_size, page_size)) {
821 		perror("'broken_buf' setup");
822 		exit(EXIT_FAILURE);
823 	}
824 
825 	valid_buf = mmap(NULL, buf_size, prot, flags, -1, 0);
826 	if (valid_buf == MAP_FAILED) {
827 		perror("mmap for 'valid_buf'");
828 		exit(EXIT_FAILURE);
829 	}
830 
831 	/* Try to fill buffer with unmapped middle. */
832 	res = read(fd, broken_buf, buf_size);
833 	if (res != -1) {
834 		fprintf(stderr,
835 			"expected 'broken_buf' read(2) failure, got %zi\n",
836 			res);
837 		exit(EXIT_FAILURE);
838 	}
839 
840 	if (errno != EFAULT) {
841 		perror("unexpected errno of 'broken_buf'");
842 		exit(EXIT_FAILURE);
843 	}
844 
845 	/* Try to fill valid buffer. */
846 	res = read(fd, valid_buf, buf_size);
847 	if (res < 0) {
848 		perror("unexpected 'valid_buf' read(2) failure");
849 		exit(EXIT_FAILURE);
850 	}
851 
852 	if (res != buf_size) {
853 		fprintf(stderr,
854 			"invalid 'valid_buf' read(2), expected %i, got %zi\n",
855 			buf_size, res);
856 		exit(EXIT_FAILURE);
857 	}
858 
859 	for (i = 0; i < buf_size; i++) {
860 		if (valid_buf[i] != BUF_PATTERN_2) {
861 			fprintf(stderr,
862 				"invalid pattern for 'valid_buf' at %i, expected %hhX, got %hhX\n",
863 				i, BUF_PATTERN_2, valid_buf[i]);
864 			exit(EXIT_FAILURE);
865 		}
866 	}
867 
868 	/* Unmap buffers. */
869 	munmap(broken_buf, page_size);
870 	munmap(broken_buf + page_size * 2, page_size);
871 	munmap(valid_buf, buf_size);
872 	close(fd);
873 }
874 
875 #define RCVLOWAT_BUF_SIZE 128
876 
test_stream_poll_rcvlowat_server(const struct test_opts * opts)877 static void test_stream_poll_rcvlowat_server(const struct test_opts *opts)
878 {
879 	int fd;
880 	int i;
881 
882 	fd = vsock_stream_accept(VMADDR_CID_ANY, 1234, NULL);
883 	if (fd < 0) {
884 		perror("accept");
885 		exit(EXIT_FAILURE);
886 	}
887 
888 	/* Send 1 byte. */
889 	send_byte(fd, 1, 0);
890 
891 	control_writeln("SRVSENT");
892 
893 	/* Wait until client is ready to receive rest of data. */
894 	control_expectln("CLNSENT");
895 
896 	for (i = 0; i < RCVLOWAT_BUF_SIZE - 1; i++)
897 		send_byte(fd, 1, 0);
898 
899 	/* Keep socket in active state. */
900 	control_expectln("POLLDONE");
901 
902 	close(fd);
903 }
904 
test_stream_poll_rcvlowat_client(const struct test_opts * opts)905 static void test_stream_poll_rcvlowat_client(const struct test_opts *opts)
906 {
907 	unsigned long lowat_val = RCVLOWAT_BUF_SIZE;
908 	char buf[RCVLOWAT_BUF_SIZE];
909 	struct pollfd fds;
910 	ssize_t read_res;
911 	short poll_flags;
912 	int fd;
913 
914 	fd = vsock_stream_connect(opts->peer_cid, 1234);
915 	if (fd < 0) {
916 		perror("connect");
917 		exit(EXIT_FAILURE);
918 	}
919 
920 	if (setsockopt(fd, SOL_SOCKET, SO_RCVLOWAT,
921 		       &lowat_val, sizeof(lowat_val))) {
922 		perror("setsockopt(SO_RCVLOWAT)");
923 		exit(EXIT_FAILURE);
924 	}
925 
926 	control_expectln("SRVSENT");
927 
928 	/* At this point, server sent 1 byte. */
929 	fds.fd = fd;
930 	poll_flags = POLLIN | POLLRDNORM;
931 	fds.events = poll_flags;
932 
933 	/* Try to wait for 1 sec. */
934 	if (poll(&fds, 1, 1000) < 0) {
935 		perror("poll");
936 		exit(EXIT_FAILURE);
937 	}
938 
939 	/* poll() must return nothing. */
940 	if (fds.revents) {
941 		fprintf(stderr, "Unexpected poll result %hx\n",
942 			fds.revents);
943 		exit(EXIT_FAILURE);
944 	}
945 
946 	/* Tell server to send rest of data. */
947 	control_writeln("CLNSENT");
948 
949 	/* Poll for data. */
950 	if (poll(&fds, 1, 10000) < 0) {
951 		perror("poll");
952 		exit(EXIT_FAILURE);
953 	}
954 
955 	/* Only these two bits are expected. */
956 	if (fds.revents != poll_flags) {
957 		fprintf(stderr, "Unexpected poll result %hx\n",
958 			fds.revents);
959 		exit(EXIT_FAILURE);
960 	}
961 
962 	/* Use MSG_DONTWAIT, if call is going to wait, EAGAIN
963 	 * will be returned.
964 	 */
965 	read_res = recv(fd, buf, sizeof(buf), MSG_DONTWAIT);
966 	if (read_res != RCVLOWAT_BUF_SIZE) {
967 		fprintf(stderr, "Unexpected recv result %zi\n",
968 			read_res);
969 		exit(EXIT_FAILURE);
970 	}
971 
972 	control_writeln("POLLDONE");
973 
974 	close(fd);
975 }
976 
977 #define INV_BUF_TEST_DATA_LEN 512
978 
test_inv_buf_client(const struct test_opts * opts,bool stream)979 static void test_inv_buf_client(const struct test_opts *opts, bool stream)
980 {
981 	unsigned char data[INV_BUF_TEST_DATA_LEN] = {0};
982 	ssize_t ret;
983 	int fd;
984 
985 	if (stream)
986 		fd = vsock_stream_connect(opts->peer_cid, 1234);
987 	else
988 		fd = vsock_seqpacket_connect(opts->peer_cid, 1234);
989 
990 	if (fd < 0) {
991 		perror("connect");
992 		exit(EXIT_FAILURE);
993 	}
994 
995 	control_expectln("SENDDONE");
996 
997 	/* Use invalid buffer here. */
998 	ret = recv(fd, NULL, sizeof(data), 0);
999 	if (ret != -1) {
1000 		fprintf(stderr, "expected recv(2) failure, got %zi\n", ret);
1001 		exit(EXIT_FAILURE);
1002 	}
1003 
1004 	if (errno != EFAULT) {
1005 		fprintf(stderr, "unexpected recv(2) errno %d\n", errno);
1006 		exit(EXIT_FAILURE);
1007 	}
1008 
1009 	ret = recv(fd, data, sizeof(data), MSG_DONTWAIT);
1010 
1011 	if (stream) {
1012 		/* For SOCK_STREAM we must continue reading. */
1013 		if (ret != sizeof(data)) {
1014 			fprintf(stderr, "expected recv(2) success, got %zi\n", ret);
1015 			exit(EXIT_FAILURE);
1016 		}
1017 		/* Don't check errno in case of success. */
1018 	} else {
1019 		/* For SOCK_SEQPACKET socket's queue must be empty. */
1020 		if (ret != -1) {
1021 			fprintf(stderr, "expected recv(2) failure, got %zi\n", ret);
1022 			exit(EXIT_FAILURE);
1023 		}
1024 
1025 		if (errno != EAGAIN) {
1026 			fprintf(stderr, "unexpected recv(2) errno %d\n", errno);
1027 			exit(EXIT_FAILURE);
1028 		}
1029 	}
1030 
1031 	control_writeln("DONE");
1032 
1033 	close(fd);
1034 }
1035 
test_inv_buf_server(const struct test_opts * opts,bool stream)1036 static void test_inv_buf_server(const struct test_opts *opts, bool stream)
1037 {
1038 	unsigned char data[INV_BUF_TEST_DATA_LEN] = {0};
1039 	ssize_t res;
1040 	int fd;
1041 
1042 	if (stream)
1043 		fd = vsock_stream_accept(VMADDR_CID_ANY, 1234, NULL);
1044 	else
1045 		fd = vsock_seqpacket_accept(VMADDR_CID_ANY, 1234, NULL);
1046 
1047 	if (fd < 0) {
1048 		perror("accept");
1049 		exit(EXIT_FAILURE);
1050 	}
1051 
1052 	res = send(fd, data, sizeof(data), 0);
1053 	if (res != sizeof(data)) {
1054 		fprintf(stderr, "unexpected send(2) result %zi\n", res);
1055 		exit(EXIT_FAILURE);
1056 	}
1057 
1058 	control_writeln("SENDDONE");
1059 
1060 	control_expectln("DONE");
1061 
1062 	close(fd);
1063 }
1064 
test_stream_inv_buf_client(const struct test_opts * opts)1065 static void test_stream_inv_buf_client(const struct test_opts *opts)
1066 {
1067 	test_inv_buf_client(opts, true);
1068 }
1069 
test_stream_inv_buf_server(const struct test_opts * opts)1070 static void test_stream_inv_buf_server(const struct test_opts *opts)
1071 {
1072 	test_inv_buf_server(opts, true);
1073 }
1074 
test_seqpacket_inv_buf_client(const struct test_opts * opts)1075 static void test_seqpacket_inv_buf_client(const struct test_opts *opts)
1076 {
1077 	test_inv_buf_client(opts, false);
1078 }
1079 
test_seqpacket_inv_buf_server(const struct test_opts * opts)1080 static void test_seqpacket_inv_buf_server(const struct test_opts *opts)
1081 {
1082 	test_inv_buf_server(opts, false);
1083 }
1084 
1085 #define HELLO_STR "HELLO"
1086 #define WORLD_STR "WORLD"
1087 
test_stream_virtio_skb_merge_client(const struct test_opts * opts)1088 static void test_stream_virtio_skb_merge_client(const struct test_opts *opts)
1089 {
1090 	ssize_t res;
1091 	int fd;
1092 
1093 	fd = vsock_stream_connect(opts->peer_cid, 1234);
1094 	if (fd < 0) {
1095 		perror("connect");
1096 		exit(EXIT_FAILURE);
1097 	}
1098 
1099 	/* Send first skbuff. */
1100 	res = send(fd, HELLO_STR, strlen(HELLO_STR), 0);
1101 	if (res != strlen(HELLO_STR)) {
1102 		fprintf(stderr, "unexpected send(2) result %zi\n", res);
1103 		exit(EXIT_FAILURE);
1104 	}
1105 
1106 	control_writeln("SEND0");
1107 	/* Peer reads part of first skbuff. */
1108 	control_expectln("REPLY0");
1109 
1110 	/* Send second skbuff, it will be appended to the first. */
1111 	res = send(fd, WORLD_STR, strlen(WORLD_STR), 0);
1112 	if (res != strlen(WORLD_STR)) {
1113 		fprintf(stderr, "unexpected send(2) result %zi\n", res);
1114 		exit(EXIT_FAILURE);
1115 	}
1116 
1117 	control_writeln("SEND1");
1118 	/* Peer reads merged skbuff packet. */
1119 	control_expectln("REPLY1");
1120 
1121 	close(fd);
1122 }
1123 
test_stream_virtio_skb_merge_server(const struct test_opts * opts)1124 static void test_stream_virtio_skb_merge_server(const struct test_opts *opts)
1125 {
1126 	unsigned char buf[64];
1127 	ssize_t res;
1128 	int fd;
1129 
1130 	fd = vsock_stream_accept(VMADDR_CID_ANY, 1234, NULL);
1131 	if (fd < 0) {
1132 		perror("accept");
1133 		exit(EXIT_FAILURE);
1134 	}
1135 
1136 	control_expectln("SEND0");
1137 
1138 	/* Read skbuff partially. */
1139 	res = recv(fd, buf, 2, 0);
1140 	if (res != 2) {
1141 		fprintf(stderr, "expected recv(2) returns 2 bytes, got %zi\n", res);
1142 		exit(EXIT_FAILURE);
1143 	}
1144 
1145 	control_writeln("REPLY0");
1146 	control_expectln("SEND1");
1147 
1148 	res = recv(fd, buf + 2, sizeof(buf) - 2, 0);
1149 	if (res != 8) {
1150 		fprintf(stderr, "expected recv(2) returns 8 bytes, got %zi\n", res);
1151 		exit(EXIT_FAILURE);
1152 	}
1153 
1154 	res = recv(fd, buf, sizeof(buf) - 8 - 2, MSG_DONTWAIT);
1155 	if (res != -1) {
1156 		fprintf(stderr, "expected recv(2) failure, got %zi\n", res);
1157 		exit(EXIT_FAILURE);
1158 	}
1159 
1160 	if (memcmp(buf, HELLO_STR WORLD_STR, strlen(HELLO_STR WORLD_STR))) {
1161 		fprintf(stderr, "pattern mismatch\n");
1162 		exit(EXIT_FAILURE);
1163 	}
1164 
1165 	control_writeln("REPLY1");
1166 
1167 	close(fd);
1168 }
1169 
test_seqpacket_msg_peek_client(const struct test_opts * opts)1170 static void test_seqpacket_msg_peek_client(const struct test_opts *opts)
1171 {
1172 	return test_msg_peek_client(opts, true);
1173 }
1174 
test_seqpacket_msg_peek_server(const struct test_opts * opts)1175 static void test_seqpacket_msg_peek_server(const struct test_opts *opts)
1176 {
1177 	return test_msg_peek_server(opts, true);
1178 }
1179 
1180 static struct test_case test_cases[] = {
1181 	{
1182 		.name = "SOCK_STREAM connection reset",
1183 		.run_client = test_stream_connection_reset,
1184 	},
1185 	{
1186 		.name = "SOCK_STREAM bind only",
1187 		.run_client = test_stream_bind_only_client,
1188 		.run_server = test_stream_bind_only_server,
1189 	},
1190 	{
1191 		.name = "SOCK_STREAM client close",
1192 		.run_client = test_stream_client_close_client,
1193 		.run_server = test_stream_client_close_server,
1194 	},
1195 	{
1196 		.name = "SOCK_STREAM server close",
1197 		.run_client = test_stream_server_close_client,
1198 		.run_server = test_stream_server_close_server,
1199 	},
1200 	{
1201 		.name = "SOCK_STREAM multiple connections",
1202 		.run_client = test_stream_multiconn_client,
1203 		.run_server = test_stream_multiconn_server,
1204 	},
1205 	{
1206 		.name = "SOCK_STREAM MSG_PEEK",
1207 		.run_client = test_stream_msg_peek_client,
1208 		.run_server = test_stream_msg_peek_server,
1209 	},
1210 	{
1211 		.name = "SOCK_SEQPACKET msg bounds",
1212 		.run_client = test_seqpacket_msg_bounds_client,
1213 		.run_server = test_seqpacket_msg_bounds_server,
1214 	},
1215 	{
1216 		.name = "SOCK_SEQPACKET MSG_TRUNC flag",
1217 		.run_client = test_seqpacket_msg_trunc_client,
1218 		.run_server = test_seqpacket_msg_trunc_server,
1219 	},
1220 	{
1221 		.name = "SOCK_SEQPACKET timeout",
1222 		.run_client = test_seqpacket_timeout_client,
1223 		.run_server = test_seqpacket_timeout_server,
1224 	},
1225 	{
1226 		.name = "SOCK_SEQPACKET invalid receive buffer",
1227 		.run_client = test_seqpacket_invalid_rec_buffer_client,
1228 		.run_server = test_seqpacket_invalid_rec_buffer_server,
1229 	},
1230 	{
1231 		.name = "SOCK_STREAM poll() + SO_RCVLOWAT",
1232 		.run_client = test_stream_poll_rcvlowat_client,
1233 		.run_server = test_stream_poll_rcvlowat_server,
1234 	},
1235 	{
1236 		.name = "SOCK_SEQPACKET big message",
1237 		.run_client = test_seqpacket_bigmsg_client,
1238 		.run_server = test_seqpacket_bigmsg_server,
1239 	},
1240 	{
1241 		.name = "SOCK_STREAM test invalid buffer",
1242 		.run_client = test_stream_inv_buf_client,
1243 		.run_server = test_stream_inv_buf_server,
1244 	},
1245 	{
1246 		.name = "SOCK_SEQPACKET test invalid buffer",
1247 		.run_client = test_seqpacket_inv_buf_client,
1248 		.run_server = test_seqpacket_inv_buf_server,
1249 	},
1250 	{
1251 		.name = "SOCK_STREAM virtio skb merge",
1252 		.run_client = test_stream_virtio_skb_merge_client,
1253 		.run_server = test_stream_virtio_skb_merge_server,
1254 	},
1255 	{
1256 		.name = "SOCK_SEQPACKET MSG_PEEK",
1257 		.run_client = test_seqpacket_msg_peek_client,
1258 		.run_server = test_seqpacket_msg_peek_server,
1259 	},
1260 	{},
1261 };
1262 
1263 static const char optstring[] = "";
1264 static const struct option longopts[] = {
1265 	{
1266 		.name = "control-host",
1267 		.has_arg = required_argument,
1268 		.val = 'H',
1269 	},
1270 	{
1271 		.name = "control-port",
1272 		.has_arg = required_argument,
1273 		.val = 'P',
1274 	},
1275 	{
1276 		.name = "mode",
1277 		.has_arg = required_argument,
1278 		.val = 'm',
1279 	},
1280 	{
1281 		.name = "peer-cid",
1282 		.has_arg = required_argument,
1283 		.val = 'p',
1284 	},
1285 	{
1286 		.name = "list",
1287 		.has_arg = no_argument,
1288 		.val = 'l',
1289 	},
1290 	{
1291 		.name = "skip",
1292 		.has_arg = required_argument,
1293 		.val = 's',
1294 	},
1295 	{
1296 		.name = "help",
1297 		.has_arg = no_argument,
1298 		.val = '?',
1299 	},
1300 	{},
1301 };
1302 
usage(void)1303 static void usage(void)
1304 {
1305 	fprintf(stderr, "Usage: vsock_test [--help] [--control-host=<host>] --control-port=<port> --mode=client|server --peer-cid=<cid> [--list] [--skip=<test_id>]\n"
1306 		"\n"
1307 		"  Server: vsock_test --control-port=1234 --mode=server --peer-cid=3\n"
1308 		"  Client: vsock_test --control-host=192.168.0.1 --control-port=1234 --mode=client --peer-cid=2\n"
1309 		"\n"
1310 		"Run vsock.ko tests.  Must be launched in both guest\n"
1311 		"and host.  One side must use --mode=client and\n"
1312 		"the other side must use --mode=server.\n"
1313 		"\n"
1314 		"A TCP control socket connection is used to coordinate tests\n"
1315 		"between the client and the server.  The server requires a\n"
1316 		"listen address and the client requires an address to\n"
1317 		"connect to.\n"
1318 		"\n"
1319 		"The CID of the other side must be given with --peer-cid=<cid>.\n"
1320 		"\n"
1321 		"Options:\n"
1322 		"  --help                 This help message\n"
1323 		"  --control-host <host>  Server IP address to connect to\n"
1324 		"  --control-port <port>  Server port to listen on/connect to\n"
1325 		"  --mode client|server   Server or client mode\n"
1326 		"  --peer-cid <cid>       CID of the other side\n"
1327 		"  --list                 List of tests that will be executed\n"
1328 		"  --skip <test_id>       Test ID to skip;\n"
1329 		"                         use multiple --skip options to skip more tests\n"
1330 		);
1331 	exit(EXIT_FAILURE);
1332 }
1333 
main(int argc,char ** argv)1334 int main(int argc, char **argv)
1335 {
1336 	const char *control_host = NULL;
1337 	const char *control_port = NULL;
1338 	struct test_opts opts = {
1339 		.mode = TEST_MODE_UNSET,
1340 		.peer_cid = VMADDR_CID_ANY,
1341 	};
1342 
1343 	srand(time(NULL));
1344 	init_signals();
1345 
1346 	for (;;) {
1347 		int opt = getopt_long(argc, argv, optstring, longopts, NULL);
1348 
1349 		if (opt == -1)
1350 			break;
1351 
1352 		switch (opt) {
1353 		case 'H':
1354 			control_host = optarg;
1355 			break;
1356 		case 'm':
1357 			if (strcmp(optarg, "client") == 0)
1358 				opts.mode = TEST_MODE_CLIENT;
1359 			else if (strcmp(optarg, "server") == 0)
1360 				opts.mode = TEST_MODE_SERVER;
1361 			else {
1362 				fprintf(stderr, "--mode must be \"client\" or \"server\"\n");
1363 				return EXIT_FAILURE;
1364 			}
1365 			break;
1366 		case 'p':
1367 			opts.peer_cid = parse_cid(optarg);
1368 			break;
1369 		case 'P':
1370 			control_port = optarg;
1371 			break;
1372 		case 'l':
1373 			list_tests(test_cases);
1374 			break;
1375 		case 's':
1376 			skip_test(test_cases, ARRAY_SIZE(test_cases) - 1,
1377 				  optarg);
1378 			break;
1379 		case '?':
1380 		default:
1381 			usage();
1382 		}
1383 	}
1384 
1385 	if (!control_port)
1386 		usage();
1387 	if (opts.mode == TEST_MODE_UNSET)
1388 		usage();
1389 	if (opts.peer_cid == VMADDR_CID_ANY)
1390 		usage();
1391 
1392 	if (!control_host) {
1393 		if (opts.mode != TEST_MODE_SERVER)
1394 			usage();
1395 		control_host = "0.0.0.0";
1396 	}
1397 
1398 	control_init(control_host, control_port,
1399 		     opts.mode == TEST_MODE_SERVER);
1400 
1401 	run_tests(test_cases, &opts);
1402 
1403 	control_cleanup();
1404 	return EXIT_SUCCESS;
1405 }
1406