xref: /linux/tools/testing/vsock/vsock_test.c (revision 6c8c1406a6d6a3f2e61ac590f5c0994231bc6be7)
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 static void test_stream_msg_peek_client(const struct test_opts *opts)
259 {
260 	int fd;
261 
262 	fd = vsock_stream_connect(opts->peer_cid, 1234);
263 	if (fd < 0) {
264 		perror("connect");
265 		exit(EXIT_FAILURE);
266 	}
267 
268 	send_byte(fd, 1, 0);
269 	close(fd);
270 }
271 
272 static void test_stream_msg_peek_server(const struct test_opts *opts)
273 {
274 	int fd;
275 
276 	fd = vsock_stream_accept(VMADDR_CID_ANY, 1234, NULL);
277 	if (fd < 0) {
278 		perror("accept");
279 		exit(EXIT_FAILURE);
280 	}
281 
282 	recv_byte(fd, 1, MSG_PEEK);
283 	recv_byte(fd, 1, 0);
284 	close(fd);
285 }
286 
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)
290 {
291 	int fd;
292 
293 	fd = vsock_seqpacket_connect(opts->peer_cid, 1234);
294 	if (fd < 0) {
295 		perror("connect");
296 		exit(EXIT_FAILURE);
297 	}
298 
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);
302 
303 	control_writeln("SENDDONE");
304 	close(fd);
305 }
306 
307 static void test_seqpacket_msg_bounds_server(const struct test_opts *opts)
308 {
309 	int fd;
310 	char buf[16];
311 	struct msghdr msg = {0};
312 	struct iovec iov = {0};
313 
314 	fd = vsock_seqpacket_accept(VMADDR_CID_ANY, 1234, NULL);
315 	if (fd < 0) {
316 		perror("accept");
317 		exit(EXIT_FAILURE);
318 	}
319 
320 	control_expectln("SENDDONE");
321 	iov.iov_base = buf;
322 	iov.iov_len = sizeof(buf);
323 	msg.msg_iov = &iov;
324 	msg.msg_iovlen = 1;
325 
326 	for (int i = 0; i < MESSAGES_CNT; i++) {
327 		if (recvmsg(fd, &msg, 0) != 1) {
328 			perror("message bound violated");
329 			exit(EXIT_FAILURE);
330 		}
331 
332 		if ((i == MSG_EOR_IDX) ^ !!(msg.msg_flags & MSG_EOR)) {
333 			perror("MSG_EOR");
334 			exit(EXIT_FAILURE);
335 		}
336 	}
337 
338 	close(fd);
339 }
340 
341 #define MESSAGE_TRUNC_SZ 32
342 static void test_seqpacket_msg_trunc_client(const struct test_opts *opts)
343 {
344 	int fd;
345 	char buf[MESSAGE_TRUNC_SZ];
346 
347 	fd = vsock_seqpacket_connect(opts->peer_cid, 1234);
348 	if (fd < 0) {
349 		perror("connect");
350 		exit(EXIT_FAILURE);
351 	}
352 
353 	if (send(fd, buf, sizeof(buf), 0) != sizeof(buf)) {
354 		perror("send failed");
355 		exit(EXIT_FAILURE);
356 	}
357 
358 	control_writeln("SENDDONE");
359 	close(fd);
360 }
361 
362 static void test_seqpacket_msg_trunc_server(const struct test_opts *opts)
363 {
364 	int fd;
365 	char buf[MESSAGE_TRUNC_SZ / 2];
366 	struct msghdr msg = {0};
367 	struct iovec iov = {0};
368 
369 	fd = vsock_seqpacket_accept(VMADDR_CID_ANY, 1234, NULL);
370 	if (fd < 0) {
371 		perror("accept");
372 		exit(EXIT_FAILURE);
373 	}
374 
375 	control_expectln("SENDDONE");
376 	iov.iov_base = buf;
377 	iov.iov_len = sizeof(buf);
378 	msg.msg_iov = &iov;
379 	msg.msg_iovlen = 1;
380 
381 	ssize_t ret = recvmsg(fd, &msg, MSG_TRUNC);
382 
383 	if (ret != MESSAGE_TRUNC_SZ) {
384 		printf("%zi\n", ret);
385 		perror("MSG_TRUNC doesn't work");
386 		exit(EXIT_FAILURE);
387 	}
388 
389 	if (!(msg.msg_flags & MSG_TRUNC)) {
390 		fprintf(stderr, "MSG_TRUNC expected\n");
391 		exit(EXIT_FAILURE);
392 	}
393 
394 	close(fd);
395 }
396 
397 static time_t current_nsec(void)
398 {
399 	struct timespec ts;
400 
401 	if (clock_gettime(CLOCK_REALTIME, &ts)) {
402 		perror("clock_gettime(3) failed");
403 		exit(EXIT_FAILURE);
404 	}
405 
406 	return (ts.tv_sec * 1000000000ULL) + ts.tv_nsec;
407 }
408 
409 #define RCVTIMEO_TIMEOUT_SEC 1
410 #define READ_OVERHEAD_NSEC 250000000 /* 0.25 sec */
411 
412 static void test_seqpacket_timeout_client(const struct test_opts *opts)
413 {
414 	int fd;
415 	struct timeval tv;
416 	char dummy;
417 	time_t read_enter_ns;
418 	time_t read_overhead_ns;
419 
420 	fd = vsock_seqpacket_connect(opts->peer_cid, 1234);
421 	if (fd < 0) {
422 		perror("connect");
423 		exit(EXIT_FAILURE);
424 	}
425 
426 	tv.tv_sec = RCVTIMEO_TIMEOUT_SEC;
427 	tv.tv_usec = 0;
428 
429 	if (setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, (void *)&tv, sizeof(tv)) == -1) {
430 		perror("setsockopt 'SO_RCVTIMEO'");
431 		exit(EXIT_FAILURE);
432 	}
433 
434 	read_enter_ns = current_nsec();
435 
436 	if (read(fd, &dummy, sizeof(dummy)) != -1) {
437 		fprintf(stderr,
438 			"expected 'dummy' read(2) failure\n");
439 		exit(EXIT_FAILURE);
440 	}
441 
442 	if (errno != EAGAIN) {
443 		perror("EAGAIN expected");
444 		exit(EXIT_FAILURE);
445 	}
446 
447 	read_overhead_ns = current_nsec() - read_enter_ns -
448 			1000000000ULL * RCVTIMEO_TIMEOUT_SEC;
449 
450 	if (read_overhead_ns > READ_OVERHEAD_NSEC) {
451 		fprintf(stderr,
452 			"too much time in read(2), %lu > %i ns\n",
453 			read_overhead_ns, READ_OVERHEAD_NSEC);
454 		exit(EXIT_FAILURE);
455 	}
456 
457 	control_writeln("WAITDONE");
458 	close(fd);
459 }
460 
461 static void test_seqpacket_timeout_server(const struct test_opts *opts)
462 {
463 	int fd;
464 
465 	fd = vsock_seqpacket_accept(VMADDR_CID_ANY, 1234, NULL);
466 	if (fd < 0) {
467 		perror("accept");
468 		exit(EXIT_FAILURE);
469 	}
470 
471 	control_expectln("WAITDONE");
472 	close(fd);
473 }
474 
475 #define BUF_PATTERN_1 'a'
476 #define BUF_PATTERN_2 'b'
477 
478 static void test_seqpacket_invalid_rec_buffer_client(const struct test_opts *opts)
479 {
480 	int fd;
481 	unsigned char *buf1;
482 	unsigned char *buf2;
483 	int buf_size = getpagesize() * 3;
484 
485 	fd = vsock_seqpacket_connect(opts->peer_cid, 1234);
486 	if (fd < 0) {
487 		perror("connect");
488 		exit(EXIT_FAILURE);
489 	}
490 
491 	buf1 = malloc(buf_size);
492 	if (!buf1) {
493 		perror("'malloc()' for 'buf1'");
494 		exit(EXIT_FAILURE);
495 	}
496 
497 	buf2 = malloc(buf_size);
498 	if (!buf2) {
499 		perror("'malloc()' for 'buf2'");
500 		exit(EXIT_FAILURE);
501 	}
502 
503 	memset(buf1, BUF_PATTERN_1, buf_size);
504 	memset(buf2, BUF_PATTERN_2, buf_size);
505 
506 	if (send(fd, buf1, buf_size, 0) != buf_size) {
507 		perror("send failed");
508 		exit(EXIT_FAILURE);
509 	}
510 
511 	if (send(fd, buf2, buf_size, 0) != buf_size) {
512 		perror("send failed");
513 		exit(EXIT_FAILURE);
514 	}
515 
516 	close(fd);
517 }
518 
519 static void test_seqpacket_invalid_rec_buffer_server(const struct test_opts *opts)
520 {
521 	int fd;
522 	unsigned char *broken_buf;
523 	unsigned char *valid_buf;
524 	int page_size = getpagesize();
525 	int buf_size = page_size * 3;
526 	ssize_t res;
527 	int prot = PROT_READ | PROT_WRITE;
528 	int flags = MAP_PRIVATE | MAP_ANONYMOUS;
529 	int i;
530 
531 	fd = vsock_seqpacket_accept(VMADDR_CID_ANY, 1234, NULL);
532 	if (fd < 0) {
533 		perror("accept");
534 		exit(EXIT_FAILURE);
535 	}
536 
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'");
541 		exit(EXIT_FAILURE);
542 	}
543 
544 	/* Unmap "hole" in buffer. */
545 	if (munmap(broken_buf + page_size, page_size)) {
546 		perror("'broken_buf' setup");
547 		exit(EXIT_FAILURE);
548 	}
549 
550 	valid_buf = mmap(NULL, buf_size, prot, flags, -1, 0);
551 	if (valid_buf == MAP_FAILED) {
552 		perror("mmap for 'valid_buf'");
553 		exit(EXIT_FAILURE);
554 	}
555 
556 	/* Try to fill buffer with unmapped middle. */
557 	res = read(fd, broken_buf, buf_size);
558 	if (res != -1) {
559 		fprintf(stderr,
560 			"expected 'broken_buf' read(2) failure, got %zi\n",
561 			res);
562 		exit(EXIT_FAILURE);
563 	}
564 
565 	if (errno != ENOMEM) {
566 		perror("unexpected errno of 'broken_buf'");
567 		exit(EXIT_FAILURE);
568 	}
569 
570 	/* Try to fill valid buffer. */
571 	res = read(fd, valid_buf, buf_size);
572 	if (res < 0) {
573 		perror("unexpected 'valid_buf' read(2) failure");
574 		exit(EXIT_FAILURE);
575 	}
576 
577 	if (res != buf_size) {
578 		fprintf(stderr,
579 			"invalid 'valid_buf' read(2), expected %i, got %zi\n",
580 			buf_size, res);
581 		exit(EXIT_FAILURE);
582 	}
583 
584 	for (i = 0; i < buf_size; i++) {
585 		if (valid_buf[i] != BUF_PATTERN_2) {
586 			fprintf(stderr,
587 				"invalid pattern for 'valid_buf' at %i, expected %hhX, got %hhX\n",
588 				i, BUF_PATTERN_2, valid_buf[i]);
589 			exit(EXIT_FAILURE);
590 		}
591 	}
592 
593 	/* Unmap buffers. */
594 	munmap(broken_buf, page_size);
595 	munmap(broken_buf + page_size * 2, page_size);
596 	munmap(valid_buf, buf_size);
597 	close(fd);
598 }
599 
600 #define RCVLOWAT_BUF_SIZE 128
601 
602 static void test_stream_poll_rcvlowat_server(const struct test_opts *opts)
603 {
604 	int fd;
605 	int i;
606 
607 	fd = vsock_stream_accept(VMADDR_CID_ANY, 1234, NULL);
608 	if (fd < 0) {
609 		perror("accept");
610 		exit(EXIT_FAILURE);
611 	}
612 
613 	/* Send 1 byte. */
614 	send_byte(fd, 1, 0);
615 
616 	control_writeln("SRVSENT");
617 
618 	/* Wait until client is ready to receive rest of data. */
619 	control_expectln("CLNSENT");
620 
621 	for (i = 0; i < RCVLOWAT_BUF_SIZE - 1; i++)
622 		send_byte(fd, 1, 0);
623 
624 	/* Keep socket in active state. */
625 	control_expectln("POLLDONE");
626 
627 	close(fd);
628 }
629 
630 static void test_stream_poll_rcvlowat_client(const struct test_opts *opts)
631 {
632 	unsigned long lowat_val = RCVLOWAT_BUF_SIZE;
633 	char buf[RCVLOWAT_BUF_SIZE];
634 	struct pollfd fds;
635 	ssize_t read_res;
636 	short poll_flags;
637 	int fd;
638 
639 	fd = vsock_stream_connect(opts->peer_cid, 1234);
640 	if (fd < 0) {
641 		perror("connect");
642 		exit(EXIT_FAILURE);
643 	}
644 
645 	if (setsockopt(fd, SOL_SOCKET, SO_RCVLOWAT,
646 		       &lowat_val, sizeof(lowat_val))) {
647 		perror("setsockopt");
648 		exit(EXIT_FAILURE);
649 	}
650 
651 	control_expectln("SRVSENT");
652 
653 	/* At this point, server sent 1 byte. */
654 	fds.fd = fd;
655 	poll_flags = POLLIN | POLLRDNORM;
656 	fds.events = poll_flags;
657 
658 	/* Try to wait for 1 sec. */
659 	if (poll(&fds, 1, 1000) < 0) {
660 		perror("poll");
661 		exit(EXIT_FAILURE);
662 	}
663 
664 	/* poll() must return nothing. */
665 	if (fds.revents) {
666 		fprintf(stderr, "Unexpected poll result %hx\n",
667 			fds.revents);
668 		exit(EXIT_FAILURE);
669 	}
670 
671 	/* Tell server to send rest of data. */
672 	control_writeln("CLNSENT");
673 
674 	/* Poll for data. */
675 	if (poll(&fds, 1, 10000) < 0) {
676 		perror("poll");
677 		exit(EXIT_FAILURE);
678 	}
679 
680 	/* Only these two bits are expected. */
681 	if (fds.revents != poll_flags) {
682 		fprintf(stderr, "Unexpected poll result %hx\n",
683 			fds.revents);
684 		exit(EXIT_FAILURE);
685 	}
686 
687 	/* Use MSG_DONTWAIT, if call is going to wait, EAGAIN
688 	 * will be returned.
689 	 */
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",
693 			read_res);
694 		exit(EXIT_FAILURE);
695 	}
696 
697 	control_writeln("POLLDONE");
698 
699 	close(fd);
700 }
701 
702 static struct test_case test_cases[] = {
703 	{
704 		.name = "SOCK_STREAM connection reset",
705 		.run_client = test_stream_connection_reset,
706 	},
707 	{
708 		.name = "SOCK_STREAM bind only",
709 		.run_client = test_stream_bind_only_client,
710 		.run_server = test_stream_bind_only_server,
711 	},
712 	{
713 		.name = "SOCK_STREAM client close",
714 		.run_client = test_stream_client_close_client,
715 		.run_server = test_stream_client_close_server,
716 	},
717 	{
718 		.name = "SOCK_STREAM server close",
719 		.run_client = test_stream_server_close_client,
720 		.run_server = test_stream_server_close_server,
721 	},
722 	{
723 		.name = "SOCK_STREAM multiple connections",
724 		.run_client = test_stream_multiconn_client,
725 		.run_server = test_stream_multiconn_server,
726 	},
727 	{
728 		.name = "SOCK_STREAM MSG_PEEK",
729 		.run_client = test_stream_msg_peek_client,
730 		.run_server = test_stream_msg_peek_server,
731 	},
732 	{
733 		.name = "SOCK_SEQPACKET msg bounds",
734 		.run_client = test_seqpacket_msg_bounds_client,
735 		.run_server = test_seqpacket_msg_bounds_server,
736 	},
737 	{
738 		.name = "SOCK_SEQPACKET MSG_TRUNC flag",
739 		.run_client = test_seqpacket_msg_trunc_client,
740 		.run_server = test_seqpacket_msg_trunc_server,
741 	},
742 	{
743 		.name = "SOCK_SEQPACKET timeout",
744 		.run_client = test_seqpacket_timeout_client,
745 		.run_server = test_seqpacket_timeout_server,
746 	},
747 	{
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,
751 	},
752 	{
753 		.name = "SOCK_STREAM poll() + SO_RCVLOWAT",
754 		.run_client = test_stream_poll_rcvlowat_client,
755 		.run_server = test_stream_poll_rcvlowat_server,
756 	},
757 	{},
758 };
759 
760 static const char optstring[] = "";
761 static const struct option longopts[] = {
762 	{
763 		.name = "control-host",
764 		.has_arg = required_argument,
765 		.val = 'H',
766 	},
767 	{
768 		.name = "control-port",
769 		.has_arg = required_argument,
770 		.val = 'P',
771 	},
772 	{
773 		.name = "mode",
774 		.has_arg = required_argument,
775 		.val = 'm',
776 	},
777 	{
778 		.name = "peer-cid",
779 		.has_arg = required_argument,
780 		.val = 'p',
781 	},
782 	{
783 		.name = "list",
784 		.has_arg = no_argument,
785 		.val = 'l',
786 	},
787 	{
788 		.name = "skip",
789 		.has_arg = required_argument,
790 		.val = 's',
791 	},
792 	{
793 		.name = "help",
794 		.has_arg = no_argument,
795 		.val = '?',
796 	},
797 	{},
798 };
799 
800 static void usage(void)
801 {
802 	fprintf(stderr, "Usage: vsock_test [--help] [--control-host=<host>] --control-port=<port> --mode=client|server --peer-cid=<cid> [--list] [--skip=<test_id>]\n"
803 		"\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"
806 		"\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"
810 		"\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"
814 		"connect to.\n"
815 		"\n"
816 		"The CID of the other side must be given with --peer-cid=<cid>.\n"
817 		"\n"
818 		"Options:\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"
827 		);
828 	exit(EXIT_FAILURE);
829 }
830 
831 int main(int argc, char **argv)
832 {
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,
838 	};
839 
840 	init_signals();
841 
842 	for (;;) {
843 		int opt = getopt_long(argc, argv, optstring, longopts, NULL);
844 
845 		if (opt == -1)
846 			break;
847 
848 		switch (opt) {
849 		case 'H':
850 			control_host = optarg;
851 			break;
852 		case 'm':
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;
857 			else {
858 				fprintf(stderr, "--mode must be \"client\" or \"server\"\n");
859 				return EXIT_FAILURE;
860 			}
861 			break;
862 		case 'p':
863 			opts.peer_cid = parse_cid(optarg);
864 			break;
865 		case 'P':
866 			control_port = optarg;
867 			break;
868 		case 'l':
869 			list_tests(test_cases);
870 			break;
871 		case 's':
872 			skip_test(test_cases, ARRAY_SIZE(test_cases) - 1,
873 				  optarg);
874 			break;
875 		case '?':
876 		default:
877 			usage();
878 		}
879 	}
880 
881 	if (!control_port)
882 		usage();
883 	if (opts.mode == TEST_MODE_UNSET)
884 		usage();
885 	if (opts.peer_cid == VMADDR_CID_ANY)
886 		usage();
887 
888 	if (!control_host) {
889 		if (opts.mode != TEST_MODE_SERVER)
890 			usage();
891 		control_host = "0.0.0.0";
892 	}
893 
894 	control_init(control_host, control_port,
895 		     opts.mode == TEST_MODE_SERVER);
896 
897 	run_tests(test_cases, &opts);
898 
899 	control_cleanup();
900 	return EXIT_SUCCESS;
901 }
902