hc
2023-12-11 d2ccde1c8e90d38cee87a1b0309ad2827f3fd30d
kernel/tools/testing/vsock/vsock_diag_test.c
....@@ -1,44 +1,30 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * vsock_diag_test - vsock_diag.ko test suite
34 *
45 * Copyright (C) 2017 Red Hat, Inc.
56 *
67 * Author: Stefan Hajnoczi <stefanha@redhat.com>
7
- *
8
- * This program is free software; you can redistribute it and/or
9
- * modify it under the terms of the GNU General Public License
10
- * as published by the Free Software Foundation; version 2
11
- * of the License.
128 */
139
1410 #include <getopt.h>
1511 #include <stdio.h>
16
-#include <stdbool.h>
1712 #include <stdlib.h>
1813 #include <string.h>
1914 #include <errno.h>
2015 #include <unistd.h>
21
-#include <signal.h>
22
-#include <sys/socket.h>
2316 #include <sys/stat.h>
2417 #include <sys/types.h>
2518 #include <linux/list.h>
2619 #include <linux/net.h>
2720 #include <linux/netlink.h>
2821 #include <linux/sock_diag.h>
22
+#include <linux/vm_sockets_diag.h>
2923 #include <netinet/tcp.h>
30
-
31
-#include "../../../include/uapi/linux/vm_sockets.h"
32
-#include "../../../include/uapi/linux/vm_sockets_diag.h"
3324
3425 #include "timeout.h"
3526 #include "control.h"
36
-
37
-enum test_mode {
38
- TEST_MODE_UNSET,
39
- TEST_MODE_CLIENT,
40
- TEST_MODE_SERVER
41
-};
27
+#include "util.h"
4228
4329 /* Per-socket status */
4430 struct vsock_stat {
....@@ -339,7 +325,7 @@
339325 free(st);
340326 }
341327
342
-static void test_no_sockets(unsigned int peer_cid)
328
+static void test_no_sockets(const struct test_opts *opts)
343329 {
344330 LIST_HEAD(sockets);
345331
....@@ -350,7 +336,7 @@
350336 free_sock_stat(&sockets);
351337 }
352338
353
-static void test_listen_socket_server(unsigned int peer_cid)
339
+static void test_listen_socket_server(const struct test_opts *opts)
354340 {
355341 union {
356342 struct sockaddr sa;
....@@ -388,35 +374,14 @@
388374 free_sock_stat(&sockets);
389375 }
390376
391
-static void test_connect_client(unsigned int peer_cid)
377
+static void test_connect_client(const struct test_opts *opts)
392378 {
393
- union {
394
- struct sockaddr sa;
395
- struct sockaddr_vm svm;
396
- } addr = {
397
- .svm = {
398
- .svm_family = AF_VSOCK,
399
- .svm_port = 1234,
400
- .svm_cid = peer_cid,
401
- },
402
- };
403379 int fd;
404
- int ret;
405380 LIST_HEAD(sockets);
406381 struct vsock_stat *st;
407382
408
- control_expectln("LISTENING");
409
-
410
- fd = socket(AF_VSOCK, SOCK_STREAM, 0);
411
-
412
- timeout_begin(TIMEOUT);
413
- do {
414
- ret = connect(fd, &addr.sa, sizeof(addr.svm));
415
- timeout_check("connect");
416
- } while (ret < 0 && errno == EINTR);
417
- timeout_end();
418
-
419
- if (ret < 0) {
383
+ fd = vsock_stream_connect(opts->peer_cid, 1234);
384
+ if (fd < 0) {
420385 perror("connect");
421386 exit(EXIT_FAILURE);
422387 }
....@@ -434,68 +399,21 @@
434399 free_sock_stat(&sockets);
435400 }
436401
437
-static void test_connect_server(unsigned int peer_cid)
402
+static void test_connect_server(const struct test_opts *opts)
438403 {
439
- union {
440
- struct sockaddr sa;
441
- struct sockaddr_vm svm;
442
- } addr = {
443
- .svm = {
444
- .svm_family = AF_VSOCK,
445
- .svm_port = 1234,
446
- .svm_cid = VMADDR_CID_ANY,
447
- },
448
- };
449
- union {
450
- struct sockaddr sa;
451
- struct sockaddr_vm svm;
452
- } clientaddr;
453
- socklen_t clientaddr_len = sizeof(clientaddr.svm);
454
- LIST_HEAD(sockets);
455404 struct vsock_stat *st;
456
- int fd;
405
+ LIST_HEAD(sockets);
457406 int client_fd;
458407
459
- fd = socket(AF_VSOCK, SOCK_STREAM, 0);
460
-
461
- if (bind(fd, &addr.sa, sizeof(addr.svm)) < 0) {
462
- perror("bind");
463
- exit(EXIT_FAILURE);
464
- }
465
-
466
- if (listen(fd, 1) < 0) {
467
- perror("listen");
468
- exit(EXIT_FAILURE);
469
- }
470
-
471
- control_writeln("LISTENING");
472
-
473
- timeout_begin(TIMEOUT);
474
- do {
475
- client_fd = accept(fd, &clientaddr.sa, &clientaddr_len);
476
- timeout_check("accept");
477
- } while (client_fd < 0 && errno == EINTR);
478
- timeout_end();
479
-
408
+ client_fd = vsock_stream_accept(VMADDR_CID_ANY, 1234, NULL);
480409 if (client_fd < 0) {
481410 perror("accept");
482
- exit(EXIT_FAILURE);
483
- }
484
- if (clientaddr.sa.sa_family != AF_VSOCK) {
485
- fprintf(stderr, "expected AF_VSOCK from accept(2), got %d\n",
486
- clientaddr.sa.sa_family);
487
- exit(EXIT_FAILURE);
488
- }
489
- if (clientaddr.svm.svm_cid != peer_cid) {
490
- fprintf(stderr, "expected peer CID %u from accept(2), got %u\n",
491
- peer_cid, clientaddr.svm.svm_cid);
492411 exit(EXIT_FAILURE);
493412 }
494413
495414 read_vsock_stat(&sockets);
496415
497
- check_num_sockets(&sockets, 2);
498
- find_vsock_stat(&sockets, fd);
416
+ check_num_sockets(&sockets, 1);
499417 st = find_vsock_stat(&sockets, client_fd);
500418 check_socket_state(st, TCP_ESTABLISHED);
501419
....@@ -503,15 +421,10 @@
503421 control_expectln("DONE");
504422
505423 close(client_fd);
506
- close(fd);
507424 free_sock_stat(&sockets);
508425 }
509426
510
-static struct {
511
- const char *name;
512
- void (*run_client)(unsigned int peer_cid);
513
- void (*run_server)(unsigned int peer_cid);
514
-} test_cases[] = {
427
+static struct test_case test_cases[] = {
515428 {
516429 .name = "No sockets",
517430 .run_server = test_no_sockets,
....@@ -527,30 +440,6 @@
527440 },
528441 {},
529442 };
530
-
531
-static void init_signals(void)
532
-{
533
- struct sigaction act = {
534
- .sa_handler = sigalrm,
535
- };
536
-
537
- sigaction(SIGALRM, &act, NULL);
538
- signal(SIGPIPE, SIG_IGN);
539
-}
540
-
541
-static unsigned int parse_cid(const char *str)
542
-{
543
- char *endptr = NULL;
544
- unsigned long int n;
545
-
546
- errno = 0;
547
- n = strtoul(str, &endptr, 10);
548
- if (errno || *endptr != '\0') {
549
- fprintf(stderr, "malformed CID \"%s\"\n", str);
550
- exit(EXIT_FAILURE);
551
- }
552
- return n;
553
-}
554443
555444 static const char optstring[] = "";
556445 static const struct option longopts[] = {
....@@ -575,6 +464,16 @@
575464 .val = 'p',
576465 },
577466 {
467
+ .name = "list",
468
+ .has_arg = no_argument,
469
+ .val = 'l',
470
+ },
471
+ {
472
+ .name = "skip",
473
+ .has_arg = required_argument,
474
+ .val = 's',
475
+ },
476
+ {
578477 .name = "help",
579478 .has_arg = no_argument,
580479 .val = '?',
....@@ -584,7 +483,7 @@
584483
585484 static void usage(void)
586485 {
587
- fprintf(stderr, "Usage: vsock_diag_test [--help] [--control-host=<host>] --control-port=<port> --mode=client|server --peer-cid=<cid>\n"
486
+ fprintf(stderr, "Usage: vsock_diag_test [--help] [--control-host=<host>] --control-port=<port> --mode=client|server --peer-cid=<cid> [--list] [--skip=<test_id>]\n"
588487 "\n"
589488 " Server: vsock_diag_test --control-port=1234 --mode=server --peer-cid=3\n"
590489 " Client: vsock_diag_test --control-host=192.168.0.1 --control-port=1234 --mode=client --peer-cid=2\n"
....@@ -598,7 +497,18 @@
598497 "listen address and the client requires an address to\n"
599498 "connect to.\n"
600499 "\n"
601
- "The CID of the other side must be given with --peer-cid=<cid>.\n");
500
+ "The CID of the other side must be given with --peer-cid=<cid>.\n"
501
+ "\n"
502
+ "Options:\n"
503
+ " --help This help message\n"
504
+ " --control-host <host> Server IP address to connect to\n"
505
+ " --control-port <port> Server port to listen on/connect to\n"
506
+ " --mode client|server Server or client mode\n"
507
+ " --peer-cid <cid> CID of the other side\n"
508
+ " --list List of tests that will be executed\n"
509
+ " --skip <test_id> Test ID to skip;\n"
510
+ " use multiple --skip options to skip more tests\n"
511
+ );
602512 exit(EXIT_FAILURE);
603513 }
604514
....@@ -606,9 +516,10 @@
606516 {
607517 const char *control_host = NULL;
608518 const char *control_port = NULL;
609
- int mode = TEST_MODE_UNSET;
610
- unsigned int peer_cid = VMADDR_CID_ANY;
611
- int i;
519
+ struct test_opts opts = {
520
+ .mode = TEST_MODE_UNSET,
521
+ .peer_cid = VMADDR_CID_ANY,
522
+ };
612523
613524 init_signals();
614525
....@@ -624,19 +535,26 @@
624535 break;
625536 case 'm':
626537 if (strcmp(optarg, "client") == 0)
627
- mode = TEST_MODE_CLIENT;
538
+ opts.mode = TEST_MODE_CLIENT;
628539 else if (strcmp(optarg, "server") == 0)
629
- mode = TEST_MODE_SERVER;
540
+ opts.mode = TEST_MODE_SERVER;
630541 else {
631542 fprintf(stderr, "--mode must be \"client\" or \"server\"\n");
632543 return EXIT_FAILURE;
633544 }
634545 break;
635546 case 'p':
636
- peer_cid = parse_cid(optarg);
547
+ opts.peer_cid = parse_cid(optarg);
637548 break;
638549 case 'P':
639550 control_port = optarg;
551
+ break;
552
+ case 'l':
553
+ list_tests(test_cases);
554
+ break;
555
+ case 's':
556
+ skip_test(test_cases, ARRAY_SIZE(test_cases) - 1,
557
+ optarg);
640558 break;
641559 case '?':
642560 default:
....@@ -646,35 +564,21 @@
646564
647565 if (!control_port)
648566 usage();
649
- if (mode == TEST_MODE_UNSET)
567
+ if (opts.mode == TEST_MODE_UNSET)
650568 usage();
651
- if (peer_cid == VMADDR_CID_ANY)
569
+ if (opts.peer_cid == VMADDR_CID_ANY)
652570 usage();
653571
654572 if (!control_host) {
655
- if (mode != TEST_MODE_SERVER)
573
+ if (opts.mode != TEST_MODE_SERVER)
656574 usage();
657575 control_host = "0.0.0.0";
658576 }
659577
660
- control_init(control_host, control_port, mode == TEST_MODE_SERVER);
578
+ control_init(control_host, control_port,
579
+ opts.mode == TEST_MODE_SERVER);
661580
662
- for (i = 0; test_cases[i].name; i++) {
663
- void (*run)(unsigned int peer_cid);
664
-
665
- printf("%s...", test_cases[i].name);
666
- fflush(stdout);
667
-
668
- if (mode == TEST_MODE_CLIENT)
669
- run = test_cases[i].run_client;
670
- else
671
- run = test_cases[i].run_server;
672
-
673
- if (run)
674
- run(peer_cid);
675
-
676
- printf("ok\n");
677
- }
581
+ run_tests(test_cases, &opts);
678582
679583 control_cleanup();
680584 return EXIT_SUCCESS;