Example #1
0
/**
 * 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;
}