[2/2] test: tun -- Check if names are not clashed in different ns

Submitted by Cyrill Gorcunov on Sept. 25, 2018, 12:44 p.m.

Details

Message ID 20180925124410.3294-3-gorcunov@gmail.com
State New
Series "tun: Fixup for old images and improve the test"
Headers show

Commit Message

Cyrill Gorcunov Sept. 25, 2018, 12:44 p.m.
To check that names are not clashed in different namespaces
and flags are fetched correctly lets create one more nested
net namespace with different tun flags but same names.

Signed-off-by: Cyrill Gorcunov <gorcunov@virtuozzo.com>
---
 test/zdtm/static/tun.c | 133 +++++++++++++++++++++++++++++++++--------
 1 file changed, 109 insertions(+), 24 deletions(-)

Patch hide | download patch | download mbox

diff --git a/test/zdtm/static/tun.c b/test/zdtm/static/tun.c
index f6bfeb91ba19..19fe4ddd839a 100644
--- a/test/zdtm/static/tun.c
+++ b/test/zdtm/static/tun.c
@@ -6,6 +6,8 @@ 
 #include <linux/if.h>
 #include <linux/if_tun.h>
 #include <sched.h>
+#include <sys/types.h>
+#include <sys/wait.h>
 
 #include "zdtmtst.h"
 
@@ -24,6 +26,17 @@  const char *test_author	= "Pavel Emelianov <xemul@parallels.com>";
 #define TUNSETQUEUE  _IOW('T', 217, int)
 #endif
 
+static char *tun_names[] = { "tunx0", "tunx1", "tunx2", "tunx3", "tapx0" };
+enum {
+	TUNX0 = 0,
+	TUNX1 = 1,
+	TUNX2 = 2,
+	TUNX3 = 3,
+	TAPX0 = 4,
+
+	TUN_MAX,
+};
+
 static int any_fail = 0;
 
 static int __open_tun(void)
@@ -108,19 +121,89 @@  static int dev_get_hwaddr(int fd, const char *name, char *a)
 	return 0;
 }
 
+#ifdef TUN_NS
+static task_waiter_t subns_wait;
+static int subns_fds[TUN_MAX];
+static pid_t subns_pid;
+
+static int prepare_ns(unsigned int nr)
+{
+	if (unshare(CLONE_NEWNET)) {
+		pr_perror("unshare (%u)", nr);
+		return -1;
+	}
+	system("ip link set up dev lo");
+	return 0;
+}
+
+static int subns_init(void)
+{
+	int i, flags = IFF_TUN | IFF_TUN_EXCL;
+	task_waiter_init(&subns_wait);
+
+	if (prepare_ns(1))
+		return -1;
+
+	for (i = 0; i < ARRAY_SIZE(subns_fds); i++)
+		subns_fds[i] = -1;
+
+	subns_pid = test_fork();
+	if (subns_pid < 0) {
+		pr_perror("Can't fork");
+		return -1;
+	} else if (subns_pid == 0) {
+		if (prepare_ns(2))
+			exit(1);
+
+		test_msg("Preparing subns tuns\n");
+		for (i = 0; i < ARRAY_SIZE(subns_fds); i++) {
+			subns_fds[i] = open_tun(tun_names[i], flags);
+			if (subns_fds[i] < 0)
+				exit(1);
+		}
+		task_waiter_complete(&subns_wait, 1);
+		task_waiter_wait4(&subns_wait, 2);
+
+		test_msg("Testing subns tuns\n");
+		for (i = 0; i < ARRAY_SIZE(subns_fds); i++) {
+			check_tun(subns_fds[i], tun_names[i], flags);
+			close(subns_fds[i]);
+			subns_fds[i] = -1;
+		}
+		task_waiter_complete(&subns_wait, 2);
+		exit(0);
+	}
+
+	task_waiter_wait4(&subns_wait, 1);
+	return 0;
+}
+
+static void subns_fini(void)
+{
+	int ret, status;
+
+	task_waiter_complete(&subns_wait, 2);
+	ret = wait(&status);
+	if (ret == -1 || !WIFEXITED(status) || WEXITSTATUS(status)) {
+		kill(subns_pid, SIGKILL);
+		fail("Unable to wait subns child %d", subns_pid);
+		any_fail = 1;
+	}
+}
+#else
+static int subns_init(void) { return 0; }
+static void subns_fini(void) { }
+#endif
+
 int main(int argc, char **argv)
 {
 	int fds[5], ret;
 	char addr[ETH_ALEN], a2[ETH_ALEN];
 
 	test_init(argc, argv);
-#ifdef TUN_NS
-	if (unshare(CLONE_NEWNET)) {
-		pr_perror("unshare");
-		return 1;
-	}
-	system("ip link set up dev lo");
-#endif
+	if (subns_init())
+		return -1;
+
 	/* fd[0] -- opened file */
 	fds[0] = __open_tun();
 	if (fds[0] < 0) {
@@ -129,31 +212,31 @@  int main(int argc, char **argv)
 	}
 
 	/* fd[1] -- opened file with tun device */
-	fds[1] = open_tun("tunx0", IFF_TUN);
+	fds[1] = open_tun(tun_names[TUNX0], IFF_TUN);
 	if (fds[1] < 0) {
 		pr_perror("No file 1");
 		return 1;
 	}
 
 	/* fd[2] and [3] -- two-queued device, with 3 detached */
-	fds[2] = open_tun("tunx1", IFF_TUN | IFF_MULTI_QUEUE);
+	fds[2] = open_tun(tun_names[TUNX1], IFF_TUN | IFF_MULTI_QUEUE);
 	if (fds[2] < 0) {
 		pr_perror("No file 2");
 		return 1;
 	}
 
-	fds[3] = open_tun("tunx1", IFF_TUN | IFF_MULTI_QUEUE);
+	fds[3] = open_tun(tun_names[TUNX1], IFF_TUN | IFF_MULTI_QUEUE);
 	if (fds[3] < 0) {
 		pr_perror("No file 3");
 		return 1;
 	}
 
-	ret = set_tun_queue(fds[3], "tunx1", IFF_DETACH_QUEUE);
+	ret = set_tun_queue(fds[3], tun_names[TUNX1], IFF_DETACH_QUEUE);
 	if (ret < 0)
 		return 1;
 
 	/* special case -- persistent device */
-	ret = open_tun("tunx2", IFF_TUN);
+	ret = open_tun(tun_names[TUNX2], IFF_TUN);
 	if (ret < 0) {
 		pr_perror("No persistent device");
 		return 1;
@@ -165,13 +248,13 @@  int main(int argc, char **argv)
 	}
 
 	/* and one tap in fd[4] */
-	fds[4] = open_tun("tapx0", IFF_TAP);
+	fds[4] = open_tun(tun_names[TAPX0], IFF_TAP);
 	if (fds[4] < 0) {
 		pr_perror("No tap");
 		return 1;
 	}
 
-	if (dev_get_hwaddr(fds[4], "tapx0", addr) < 0) {
+	if (dev_get_hwaddr(fds[4], tun_names[TAPX0], addr) < 0) {
 		pr_perror("No hwaddr for tap?");
 		return 1;
 	}
@@ -182,46 +265,46 @@  int main(int argc, char **argv)
 	test_waitsig();
 
 	/* check fds[0] is not attached to device */
-	ret = __attach_tun(fds[0], "tunx3", IFF_TUN);
+	ret = __attach_tun(fds[0], tun_names[TUNX3], IFF_TUN);
 	if (ret < 0) {
 		any_fail = 1;
 		fail("Opened tun file broken");
 	}
 
 	/* check that fds[1] has device */
-	check_tun(fds[1], "tunx0", IFF_TUN);
+	check_tun(fds[1], tun_names[TUNX0], IFF_TUN);
 
 	/* check that fds[2] and [3] are at MQ device with */
-	check_tun(fds[2], "tunx1", IFF_TUN | IFF_MULTI_QUEUE);
-	check_tun(fds[3], "tunx1", IFF_TUN | IFF_MULTI_QUEUE);
+	check_tun(fds[2], tun_names[TUNX1], IFF_TUN | IFF_MULTI_QUEUE);
+	check_tun(fds[3], tun_names[TUNX1], IFF_TUN | IFF_MULTI_QUEUE);
 
-	ret = set_tun_queue(fds[2], "tunx1", IFF_DETACH_QUEUE);
+	ret = set_tun_queue(fds[2], tun_names[TUNX1], IFF_DETACH_QUEUE);
 	if (ret < 0) {
 		any_fail = 1;
 		fail("Queue not attached");
 	}
 
-	ret = set_tun_queue(fds[3], "tunx1", IFF_ATTACH_QUEUE);
+	ret = set_tun_queue(fds[3], tun_names[TUNX1], IFF_ATTACH_QUEUE);
 	if (ret < 0) {
 		any_fail = 1;
 		fail("Queue not detached");
 	}
 
 	/* check persistent device */
-	ret = open_tun("tunx2", IFF_TUN | IFF_TUN_EXCL);
+	ret = open_tun(tun_names[TUNX2], IFF_TUN | IFF_TUN_EXCL);
 	if (ret >= 0) {
 		any_fail = 1;
 		fail("Persistent device lost");
 	} else {
-		ret = open_tun("tunx2", IFF_TUN);
+		ret = open_tun(tun_names[TUNX2], IFF_TUN);
 		if (ret < 0)
 			pr_perror("Can't attach tun2");
 		else
 			ioctl(ret, TUNSETPERSIST, 0);
 	}
 
-	check_tun(fds[4], "tapx0", IFF_TAP);
-	if (dev_get_hwaddr(fds[4], "tapx0", a2) < 0) {
+	check_tun(fds[4], tun_names[TAPX0], IFF_TAP);
+	if (dev_get_hwaddr(fds[4], tun_names[TAPX0], a2) < 0) {
 		pr_perror("No hwaddr for tap? (2)");
 		any_fail = 1;
 	} else if (memcmp(addr, a2, sizeof(addr))) {
@@ -231,6 +314,8 @@  int main(int argc, char **argv)
 		any_fail = 1;
 	}
 
+	subns_fini();
+
 	if (!any_fail)
 		pass();