Commit 19e9df29 authored by Cyrill Gorcunov's avatar Cyrill Gorcunov Committed by Andrei Vagin

tun: Add support for multiple net ns

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: 's avatarCyrill Gorcunov <gorcunov@gmail.com>
Signed-off-by: 's avatarAndrei Vagin <avagin@gmail.com>
parent 348b2d11
...@@ -5,6 +5,8 @@ ...@@ -5,6 +5,8 @@
#define TUN_MINOR 200 #define TUN_MINOR 200
#endif #endif
struct ns_id *ns;
#include <linux/netlink.h> #include <linux/netlink.h>
#include "images/netdev.pb-c.h" #include "images/netdev.pb-c.h"
...@@ -12,7 +14,7 @@ ...@@ -12,7 +14,7 @@
extern const struct fdtype_ops tunfile_dump_ops; extern const struct fdtype_ops tunfile_dump_ops;
extern int dump_tun_link(NetDeviceEntry *nde, struct cr_imgset *fds, struct nlattr **info); extern int dump_tun_link(NetDeviceEntry *nde, struct cr_imgset *fds, struct nlattr **info);
struct net_link; 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 struct collect_image_info tunfile_cinfo;
extern int check_tun_cr(int no_tun_err); extern int check_tun_cr(int no_tun_err);
extern int check_tun_netns_cr(bool *result); extern int check_tun_netns_cr(bool *result);
......
...@@ -1524,7 +1524,7 @@ static int __restore_link(struct ns_id *ns, struct net_link *link, int nlsk) ...@@ -1524,7 +1524,7 @@ static int __restore_link(struct ns_id *ns, struct net_link *link, int nlsk)
case ND_TYPE__VETH: case ND_TYPE__VETH:
return restore_one_link(ns, link, nlsk, veth_link_info, NULL); return restore_one_link(ns, link, nlsk, veth_link_info, NULL);
case ND_TYPE__TUN: case ND_TYPE__TUN:
return restore_one_tun(link, nlsk); return restore_one_tun(ns, link, nlsk);
case ND_TYPE__BRIDGE: case ND_TYPE__BRIDGE:
return restore_one_link(ns, link, nlsk, bridge_link_info, NULL); return restore_one_link(ns, link, nlsk, bridge_link_info, NULL);
case ND_TYPE__MACVLAN: case ND_TYPE__MACVLAN:
......
...@@ -100,6 +100,7 @@ static LIST_HEAD(tun_links); ...@@ -100,6 +100,7 @@ static LIST_HEAD(tun_links);
struct tun_link { struct tun_link {
char name[IFNAMSIZ]; char name[IFNAMSIZ];
struct list_head l; struct list_head l;
unsigned ns_id;
union { union {
struct { struct {
unsigned flags; unsigned flags;
...@@ -112,7 +113,7 @@ struct tun_link { ...@@ -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; struct tun_link *tl;
...@@ -128,22 +129,24 @@ static int list_tun_link(NetDeviceEntry *nde) ...@@ -128,22 +129,24 @@ static int list_tun_link(NetDeviceEntry *nde)
* with (i.e. -- with which it was created. * with (i.e. -- with which it was created.
*/ */
tl->rst.flags = nde->tun->flags; tl->rst.flags = nde->tun->flags;
tl->ns_id = ns_id;
list_add_tail(&tl->l, &tun_links); list_add_tail(&tl->l, &tun_links);
return 0; 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; struct tun_link *tl;
list_for_each_entry(tl, &tun_links, l) list_for_each_entry(tl, &tun_links, l) {
if (!strcmp(tl->name, name)) if (!strcmp(tl->name, name) &&
tl->ns_id == ns_id)
return tl; return tl;
}
return NULL; 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 tun_link *tl;
struct sock_fprog flt; struct sock_fprog flt;
...@@ -152,6 +155,7 @@ static struct tun_link *__dump_tun_link_fd(int fd, char *name, unsigned flags) ...@@ -152,6 +155,7 @@ static struct tun_link *__dump_tun_link_fd(int fd, char *name, unsigned flags)
if (!tl) if (!tl)
goto err; goto err;
strlcpy(tl->name, name, sizeof(tl->name)); strlcpy(tl->name, name, sizeof(tl->name));
tl->ns_id = ns_id;
if (ioctl(fd, TUNGETVNETHDRSZ, &tl->dmp.vnethdr) < 0) { if (ioctl(fd, TUNGETVNETHDRSZ, &tl->dmp.vnethdr) < 0) {
pr_perror("Can't dump vnethdr size for %s", name); pr_perror("Can't dump vnethdr size for %s", name);
...@@ -193,16 +197,16 @@ err: ...@@ -193,16 +197,16 @@ err:
return NULL; 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 tun_link *tl;
tl = find_tun_link(name); tl = find_tun_link(name, ns_id);
if (tl) if (tl)
return tl; return tl;
tl = __dump_tun_link_fd(fd, name, flags); tl = __dump_tun_link_fd(fd, name, ns_id, flags);
if (tl) if (tl) {
/* /*
* Keep this in list till links dumping code starts. * Keep this in list till links dumping code starts.
* We can't let it dump all this stuff itself, since * 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) ...@@ -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. * will attach to the device and get the needed stuff.
*/ */
list_add(&tl->l, &tun_links); list_add(&tl->l, &tun_links);
}
return tl; return tl;
} }
...@@ -252,12 +256,12 @@ err: ...@@ -252,12 +256,12 @@ err:
return -1; 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; struct tun_link *tl;
int fd; int fd;
tl = find_tun_link(name); tl = find_tun_link(name, ns_id);
if (tl) if (tl)
return tl; return tl;
...@@ -283,7 +287,7 @@ static struct tun_link *get_tun_link_fd(char *name, unsigned flags) ...@@ -283,7 +287,7 @@ static struct tun_link *get_tun_link_fd(char *name, unsigned flags)
if (fd < 0) if (fd < 0)
return NULL; return NULL;
tl = __dump_tun_link_fd(fd, name, flags); tl = __dump_tun_link_fd(fd, name, ns_id, flags);
close(fd); close(fd);
return tl; return tl;
...@@ -339,7 +343,7 @@ static int dump_tunfile(int lfd, u32 id, const struct fd_parms *p) ...@@ -339,7 +343,7 @@ static int dump_tunfile(int lfd, u32 id, const struct fd_parms *p)
tfe.detached = true; 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; return -1;
} }
...@@ -382,7 +386,7 @@ static int tunfile_open(struct file_desc *d, int *new_fd) ...@@ -382,7 +386,7 @@ static int tunfile_open(struct file_desc *d, int *new_fd)
/* just-opened tun file */ /* just-opened tun file */
goto ok; goto ok;
tl = find_tun_link(ti->tfe->netdev); tl = find_tun_link(ti->tfe->netdev, ns_id);
if (!tl) { if (!tl) {
pr_err("No tun device for file %s\n", ti->tfe->netdev); pr_err("No tun device for file %s\n", ti->tfe->netdev);
goto err; goto err;
...@@ -469,7 +473,7 @@ int dump_tun_link(NetDeviceEntry *nde, struct cr_imgset *fds, struct nlattr **in ...@@ -469,7 +473,7 @@ int dump_tun_link(NetDeviceEntry *nde, struct cr_imgset *fds, struct nlattr **in
if (ret < 0) if (ret < 0)
return ret; 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) if (!tl)
return ret; return ret;
...@@ -480,7 +484,7 @@ int dump_tun_link(NetDeviceEntry *nde, struct cr_imgset *fds, struct nlattr **in ...@@ -480,7 +484,7 @@ int dump_tun_link(NetDeviceEntry *nde, struct cr_imgset *fds, struct nlattr **in
return write_netdev_img(nde, fds, info); 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; NetDeviceEntry *nde = link->nde;
int fd, ret = -1, aux; int fd, ret = -1, aux;
...@@ -536,7 +540,7 @@ int restore_one_tun(struct net_link *link, int nlsk) ...@@ -536,7 +540,7 @@ int restore_one_tun(struct net_link *link, int nlsk)
goto out; goto out;
} }
ret = list_tun_link(nde); ret = list_tun_link(nde, ns->id);
out: out:
close(fd); close(fd);
return ret; return ret;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment