/** * Shutdown any running network components. * * Called on program shutdown and program reset after * configuration has changed. */ void network_plt_reset(void) { if (tap_handle) { tap_cleanup(tap_handle); tap_handle = NULL; } }
int main(int argc, char **argv) { int create_tap = 1; int num_tests; int ret = 0; int j = 0; int k = -1; int list = 0; int opt; int i; #ifdef __FreeBSD__ PLAIN_REQUIRE_KERNEL_MODULE("if_tap", 0); PLAIN_REQUIRE_KERNEL_MODULE("netmap", 0); #endif memset(&ctx_, 0, sizeof(ctx_)); { struct timespec t; int idx; clock_gettime(CLOCK_REALTIME, &t); srand((unsigned int)t.tv_nsec); idx = rand() % 8000 + 100; snprintf(ctx_.ifname, sizeof(ctx_.ifname), "tap%d", idx); idx = rand() % 800 + 100; snprintf(ctx_.bdgname, sizeof(ctx_.bdgname), "vale%d", idx); } while ((opt = getopt(argc, argv, "hi:j:l")) != -1) { switch (opt) { case 'h': usage(argv[0]); return 0; case 'i': strncpy(ctx_.ifname, optarg, sizeof(ctx_.ifname) - 1); create_tap = 0; break; case 'j': if (parse_interval(optarg, &j, &k) < 0) { usage(argv[0]); return -1; } break; case 'l': list = 1; create_tap = 0; break; default: printf(" Unrecognized option %c\n", opt); usage(argv[0]); return -1; } } num_tests = sizeof(tests) / sizeof(tests[0]); if (j < 0 || j >= num_tests || k > num_tests) { fprintf(stderr, "Test interval %d-%d out of range (%d-%d)\n", j + 1, k, 1, num_tests + 1); return -1; } if (k < 0) k = num_tests; if (list) { printf("Available tests:\n"); for (i = 0; i < num_tests; i++) { printf("#%03d: %s\n", i + 1, tests[i].name); } return 0; } if (create_tap) { struct sigaction sa; const char *av[8]; int ac = 0; #ifdef __FreeBSD__ ARGV_APPEND(av, ac, "ifconfig"); ARGV_APPEND(av, ac, ctx_.ifname); ARGV_APPEND(av, ac, "create"); ARGV_APPEND(av, ac, "up"); #else ARGV_APPEND(av, ac, "ip"); ARGV_APPEND(av, ac, "tuntap"); ARGV_APPEND(av, ac, "add"); ARGV_APPEND(av, ac, "mode"); ARGV_APPEND(av, ac, "tap"); ARGV_APPEND(av, ac, "name"); ARGV_APPEND(av, ac, ctx_.ifname); #endif ARGV_APPEND(av, ac, NULL); if (exec_command(ac, av)) { printf("Failed to create tap interface\n"); return -1; } sa.sa_handler = tap_cleanup; sigemptyset(&sa.sa_mask); sa.sa_flags = SA_RESTART; ret = sigaction(SIGINT, &sa, NULL); if (ret) { perror("sigaction(SIGINT)"); goto out; } ret = sigaction(SIGTERM, &sa, NULL); if (ret) { perror("sigaction(SIGTERM)"); goto out; } } for (i = j; i < k; i++) { struct TestContext ctxcopy; int fd; printf("==> Start of Test #%d [%s]\n", i + 1, tests[i].name); fd = open("/dev/netmap", O_RDWR); if (fd < 0) { perror("open(/dev/netmap)"); ret = fd; goto out; } memcpy(&ctxcopy, &ctx_, sizeof(ctxcopy)); ctxcopy.fd = fd; memcpy(ctxcopy.ifname_ext, ctxcopy.ifname, sizeof(ctxcopy.ifname)); ret = tests[i].test(&ctxcopy); if (ret != 0) { printf("Test #%d [%s] failed\n", i + 1, tests[i].name); goto out; } printf("==> Test #%d [%s] successful\n", i + 1, tests[i].name); context_cleanup(&ctxcopy); } out: tap_cleanup(0); return ret; }