[3/3] tun: Add support for multiple net ns

Submitted by Cyrill Gorcunov on Sept. 21, 2018, 8:41 a.m.

Details

Message ID 20180921084145.18740-4-gorcunov@gmail.com
State Accepted
Series "tun: Fixes for netns sake"
Headers show

Commit Message

Cyrill Gorcunov Sept. 21, 2018, 8:41 a.m.
The tun files may have same names but different
net namespace so consider ns_id when searching
for particluar tun device name.

Signed-off-by: Cyrill Gorcunov <gorcunov@gmail.com>
---
 criu/include/tun.h |  4 +++-
 criu/net.c         |  2 +-
 criu/tun.c         | 42 +++++++++++++++++++++++-------------------
 3 files changed, 27 insertions(+), 21 deletions(-)

Patch hide | download patch | download mbox

diff --git a/criu/include/tun.h b/criu/include/tun.h
index 2ccd007c2fe5..ce0b266a6440 100644
--- a/criu/include/tun.h
+++ b/criu/include/tun.h
@@ -5,6 +5,8 @@ 
 #define TUN_MINOR	200
 #endif
 
+struct ns_id *ns;
+
 #include <linux/netlink.h>
 
 #include "images/netdev.pb-c.h"
@@ -12,7 +14,7 @@ 
 extern const struct fdtype_ops tunfile_dump_ops;
 extern int dump_tun_link(NetDeviceEntry *nde, struct cr_imgset *fds, struct nlattr **info);
 struct net_link;
-extern int restore_one_tun(struct net_link *link, int nlsk);
+extern int restore_one_tun(struct ns_id *ns, struct net_link *link, int nlsk);
 extern struct collect_image_info tunfile_cinfo;
 extern int check_tun_cr(int no_tun_err);
 extern int check_tun_netns_cr(bool *result);
diff --git a/criu/net.c b/criu/net.c
index 0431b62f9011..84dce6c3bfc7 100644
--- a/criu/net.c
+++ b/criu/net.c
@@ -1524,7 +1524,7 @@  static int __restore_link(struct ns_id *ns, struct net_link *link, int nlsk)
 	case ND_TYPE__VETH:
 		return restore_one_link(ns, link, nlsk, veth_link_info, NULL);
 	case ND_TYPE__TUN:
-		return restore_one_tun(link, nlsk);
+		return restore_one_tun(ns, link, nlsk);
 	case ND_TYPE__BRIDGE:
 		return restore_one_link(ns, link, nlsk, bridge_link_info, NULL);
 	case ND_TYPE__MACVLAN:
diff --git a/criu/tun.c b/criu/tun.c
index e9c18c0abbe2..b13148b0b912 100644
--- a/criu/tun.c
+++ b/criu/tun.c
@@ -100,6 +100,7 @@  static LIST_HEAD(tun_links);
 struct tun_link {
 	char name[IFNAMSIZ];
 	struct list_head l;
+	unsigned ns_id;
 	union {
 		struct {
 			unsigned flags;
@@ -112,7 +113,7 @@  struct tun_link {
 	};
 };
 
-static int list_tun_link(NetDeviceEntry *nde)
+static int list_tun_link(NetDeviceEntry *nde, unsigned ns_id)
 {
 	struct tun_link *tl;
 
@@ -128,22 +129,24 @@  static int list_tun_link(NetDeviceEntry *nde)
 	 * with (i.e. -- with which it was created.
 	 */
 	tl->rst.flags = nde->tun->flags;
+	tl->ns_id = ns_id;
 	list_add_tail(&tl->l, &tun_links);
 	return 0;
 }
 
-static struct tun_link *find_tun_link(char *name)
+static struct tun_link *find_tun_link(char *name, unsigned int ns_id)
 {
 	struct tun_link *tl;
 
-	list_for_each_entry(tl, &tun_links, l)
-		if (!strcmp(tl->name, name))
+	list_for_each_entry(tl, &tun_links, l) {
+		if (!strcmp(tl->name, name) &&
+		    tl->ns_id == ns_id)
 			return tl;
-
+	}
 	return NULL;
 }
 
-static struct tun_link *__dump_tun_link_fd(int fd, char *name, unsigned flags)
+static struct tun_link *__dump_tun_link_fd(int fd, char *name, unsigned ns_id, unsigned flags)
 {
 	struct tun_link *tl;
 	struct sock_fprog flt;
@@ -152,6 +155,7 @@  static struct tun_link *__dump_tun_link_fd(int fd, char *name, unsigned flags)
 	if (!tl)
 		goto err;
 	strlcpy(tl->name, name, sizeof(tl->name));
+	tl->ns_id = ns_id;
 
 	if (ioctl(fd, TUNGETVNETHDRSZ, &tl->dmp.vnethdr) < 0) {
 		pr_perror("Can't dump vnethdr size for %s", name);
@@ -193,16 +197,16 @@  static struct tun_link *__dump_tun_link_fd(int fd, char *name, unsigned flags)
 	return NULL;
 }
 
-static struct tun_link *dump_tun_link_fd(int fd, char *name, unsigned flags)
+static struct tun_link *dump_tun_link_fd(int fd, char *name, unsigned ns_id, unsigned flags)
 {
 	struct tun_link *tl;
 
-	tl = find_tun_link(name);
+	tl = find_tun_link(name, ns_id);
 	if (tl)
 		return tl;
 
-	tl = __dump_tun_link_fd(fd, name, flags);
-	if (tl)
+	tl = __dump_tun_link_fd(fd, name, ns_id, flags);
+	if (tl) {
 		/*
 		 * Keep this in list till links dumping code starts.
 		 * We can't let it dump all this stuff itself, since
@@ -213,7 +217,7 @@  static struct tun_link *dump_tun_link_fd(int fd, char *name, unsigned flags)
 		 * will attach to the device and get the needed stuff.
 		 */
 		list_add(&tl->l, &tun_links);
-
+	}
 	return tl;
 }
 
@@ -252,12 +256,12 @@  static int open_tun_dev(char *name, unsigned int idx, unsigned flags)
 	return -1;
 }
 
-static struct tun_link *get_tun_link_fd(char *name, unsigned flags)
+static struct tun_link *get_tun_link_fd(char *name, unsigned ns_id, unsigned flags)
 {
 	struct tun_link *tl;
 	int fd;
 
-	tl = find_tun_link(name);
+	tl = find_tun_link(name, ns_id);
 	if (tl)
 		return tl;
 
@@ -283,7 +287,7 @@  static struct tun_link *get_tun_link_fd(char *name, unsigned flags)
 	if (fd < 0)
 		return NULL;
 
-	tl = __dump_tun_link_fd(fd, name, flags);
+	tl = __dump_tun_link_fd(fd, name, ns_id, flags);
 	close(fd);
 
 	return tl;
@@ -339,7 +343,7 @@  static int dump_tunfile(int lfd, u32 id, const struct fd_parms *p)
 			tfe.detached = true;
 		}
 
-		if (dump_tun_link_fd(lfd, tfe.netdev, ifr.ifr_flags) == NULL)
+		if (dump_tun_link_fd(lfd, tfe.netdev, tfe.ns_id, ifr.ifr_flags) == NULL)
 			return -1;
 	}
 
@@ -382,7 +386,7 @@  static int tunfile_open(struct file_desc *d, int *new_fd)
 		/* just-opened tun file */
 		goto ok;
 
-	tl = find_tun_link(ti->tfe->netdev);
+	tl = find_tun_link(ti->tfe->netdev, ns_id);
 	if (!tl) {
 		pr_err("No tun device for file %s\n", ti->tfe->netdev);
 		goto err;
@@ -469,7 +473,7 @@  int dump_tun_link(NetDeviceEntry *nde, struct cr_imgset *fds, struct nlattr **in
 	if (ret < 0)
 		return ret;
 
-	tl = get_tun_link_fd(nde->name, tle.flags);
+	tl = get_tun_link_fd(nde->name, nde->peer_nsid, tle.flags);
 	if (!tl)
 		return ret;
 
@@ -480,7 +484,7 @@  int dump_tun_link(NetDeviceEntry *nde, struct cr_imgset *fds, struct nlattr **in
 	return write_netdev_img(nde, fds, info);
 }
 
-int restore_one_tun(struct net_link *link, int nlsk)
+int restore_one_tun(struct ns_id *ns, struct net_link *link, int nlsk)
 {
 	NetDeviceEntry *nde = link->nde;
 	int fd, ret = -1, aux;
@@ -536,7 +540,7 @@  int restore_one_tun(struct net_link *link, int nlsk)
 		goto out;
 	}
 
-	ret = list_tun_link(nde);
+	ret = list_tun_link(nde, ns->id);
 out:
 	close(fd);
 	return ret;