Commit 1a62282d authored by Pavel Emelyanov's avatar Pavel Emelyanov

net: Push the host end of a veth to original netns

The call will then have to handle this end (put into a bridge).
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
parent 076faf74
...@@ -50,6 +50,7 @@ ...@@ -50,6 +50,7 @@
#include "mount.h" #include "mount.h"
#include "inotify.h" #include "inotify.h"
#include "pstree.h" #include "pstree.h"
#include "net.h"
#include "protobuf.h" #include "protobuf.h"
#include "protobuf/sa.pb-c.h" #include "protobuf/sa.pb-c.h"
...@@ -529,6 +530,15 @@ static inline int fork_with_pid(struct pstree_item *item, unsigned long ns_clone ...@@ -529,6 +530,15 @@ static inline int fork_with_pid(struct pstree_item *item, unsigned long ns_clone
} else } else
BUG_ON(pid != 1); BUG_ON(pid != 1);
if (ca.clone_flags & CLONE_NEWNET)
/*
* When restoring a net namespace we need to communicate
* with the original (i.e. -- init) one. Thus, prepare for
* that before we leave the existing namespaces.
*/
if (netns_pre_create())
goto err_unlock;
ret = clone(restore_task_with_children, stack + STACK_SIZE, ret = clone(restore_task_with_children, stack + STACK_SIZE,
ca.clone_flags | SIGCHLD, &ca); ca.clone_flags | SIGCHLD, &ca);
......
...@@ -6,4 +6,5 @@ void show_netdevices(int fd, struct cr_options *); ...@@ -6,4 +6,5 @@ void show_netdevices(int fd, struct cr_options *);
struct cr_fdset; struct cr_fdset;
int dump_net_ns(int pid, struct cr_fdset *); int dump_net_ns(int pid, struct cr_fdset *);
int prepare_net_ns(int pid); int prepare_net_ns(int pid);
int netns_pre_create(void);
#endif #endif
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#include <string.h> #include <string.h>
#include <net/if_arp.h> #include <net/if_arp.h>
#include <sys/wait.h> #include <sys/wait.h>
#include <sched.h>
#include "syscall-types.h" #include "syscall-types.h"
#include "namespaces.h" #include "namespaces.h"
#include "net.h" #include "net.h"
...@@ -13,6 +14,8 @@ ...@@ -13,6 +14,8 @@
#include "protobuf.h" #include "protobuf.h"
#include "protobuf/netdev.pb-c.h" #include "protobuf/netdev.pb-c.h"
static int ns_fd = -1;
void show_netdevices(int fd, struct cr_options *opt) void show_netdevices(int fd, struct cr_options *opt)
{ {
pb_show_plain(fd, PB_NETDEV); pb_show_plain(fd, PB_NETDEV);
...@@ -192,12 +195,18 @@ enum { ...@@ -192,12 +195,18 @@ enum {
}; };
#endif #endif
#if IFLA_MAX <= 28
#define IFLA_NET_NS_FD 28
#endif
static int veth_link_info(NetDeviceEntry *nde, struct newlink_req *req) static int veth_link_info(NetDeviceEntry *nde, struct newlink_req *req)
{ {
struct rtattr *veth_data, *peer_data; struct rtattr *veth_data, *peer_data;
struct ifinfomsg ifm; struct ifinfomsg ifm;
char veth_host_name[] = "veth_host"; char veth_host_name[] = "veth_host";
BUG_ON(ns_fd < 0);
addattr_l(&req->h, sizeof(*req), IFLA_INFO_KIND, "veth", 4); addattr_l(&req->h, sizeof(*req), IFLA_INFO_KIND, "veth", 4);
veth_data = NLMSG_TAIL(&req->h); veth_data = NLMSG_TAIL(&req->h);
...@@ -206,6 +215,7 @@ static int veth_link_info(NetDeviceEntry *nde, struct newlink_req *req) ...@@ -206,6 +215,7 @@ static int veth_link_info(NetDeviceEntry *nde, struct newlink_req *req)
memset(&ifm, 0, sizeof(ifm)); memset(&ifm, 0, sizeof(ifm));
addattr_l(&req->h, sizeof(*req), VETH_INFO_PEER, &ifm, sizeof(ifm)); addattr_l(&req->h, sizeof(*req), VETH_INFO_PEER, &ifm, sizeof(ifm));
addattr_l(&req->h, sizeof(*req), IFLA_IFNAME, veth_host_name, sizeof(veth_host_name)); addattr_l(&req->h, sizeof(*req), IFLA_IFNAME, veth_host_name, sizeof(veth_host_name));
addattr_l(&req->h, sizeof(*req), IFLA_NET_NS_FD, &ns_fd, sizeof(ns_fd));
peer_data->rta_len = (void *)NLMSG_TAIL(&req->h) - (void *)peer_data; peer_data->rta_len = (void *)NLMSG_TAIL(&req->h) - (void *)peer_data;
veth_data->rta_len = (void *)NLMSG_TAIL(&req->h) - (void *)veth_data; veth_data->rta_len = (void *)NLMSG_TAIL(&req->h) - (void *)veth_data;
...@@ -373,5 +383,19 @@ int prepare_net_ns(int pid) ...@@ -373,5 +383,19 @@ int prepare_net_ns(int pid)
if (!ret) if (!ret)
ret = restore_route(pid); ret = restore_route(pid);
close(ns_fd);
return ret; return ret;
} }
int netns_pre_create(void)
{
ns_fd = open("/proc/self/ns/net", O_RDONLY);
if (ns_fd < 0) {
pr_perror("Can't cache net fd");
return -1;
}
pr_info("Saved netns fd for links restore\n");
return 0;
}
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