diff --git a/crtools.c b/crtools.c index 3c10a81bc..901a6c72a 100644 --- a/crtools.c +++ b/crtools.c @@ -20,6 +20,7 @@ #include "syscall.h" #include "files.h" #include "sk-inet.h" +#include "net.h" struct cr_options opts; @@ -70,6 +71,7 @@ int main(int argc, char *argv[]) /* Default options */ opts.final_state = TASK_DEAD; + INIT_LIST_HEAD(&opts.veth_pairs); while (1) { static struct option long_opts[] = { @@ -90,6 +92,7 @@ int main(int argc, char *argv[]) { "version", no_argument, 0, 'V'}, { "evasive-devices", no_argument, 0, 45}, { "pidfile", required_argument, 0, 46}, + { "veth-pair", required_argument, 0, 47}, { }, }; @@ -173,6 +176,25 @@ int main(int argc, char *argv[]) case 46: opts.pidfile = optarg; break; + case 47: + { + struct veth_pair *n; + + n = xmalloc(sizeof(*n)); + if (n == NULL) + return -1; + n->outside = strchr(optarg, '='); + if (n->outside == NULL) { + xfree(n); + pr_err("Invalid agument for --veth-pair\n"); + goto usage; + } + + *n->outside++ = '\0'; + n->inside = optarg; + list_add(&n->node, &opts.veth_pairs); + } + break; case 'V': pr_msg("Version: %d.%d\n", CRIU_VERSION_MAJOR, CRIU_VERSION_MINOR); return 0; @@ -262,6 +284,7 @@ usage: pr_msg(" --%s checkpoint/restore established TCP connections\n", SK_EST_PARAM); pr_msg(" -r|--root [PATH] change the root filesystem (when run in mount namespace)\n"); pr_msg(" --evasive-devices use any path to a device file if the original one is inaccessible\n"); + pr_msg(" --veth-pair [IN=OUT] correspondence between outside and inside names of veth devices\n"); pr_msg("\n* Logging:\n"); pr_msg(" -o|--log-file [NAME] log file name (relative path is relative to --images-dir)\n"); diff --git a/include/crtools.h b/include/crtools.h index d2b36aab8..8ad8ce894 100644 --- a/include/crtools.h +++ b/include/crtools.h @@ -93,6 +93,7 @@ struct cr_options { char *output; char *root; char *pidfile; + struct list_head veth_pairs; }; extern struct cr_options opts; diff --git a/include/net.h b/include/net.h index 309abc70d..b210679d0 100644 --- a/include/net.h +++ b/include/net.h @@ -1,5 +1,8 @@ #ifndef __CR_NET_H__ #define __CR_NET_H__ + +#include "list.h" + struct cr_options; void show_netdevices(int fd, struct cr_options *); @@ -7,4 +10,10 @@ struct cr_fdset; int dump_net_ns(int pid, struct cr_fdset *); int prepare_net_ns(int pid); int netns_pre_create(void); + +struct veth_pair { + struct list_head node; + char *inside; + char *outside; +}; #endif diff --git a/net.c b/net.c index 538be68ef..5988159f1 100644 --- a/net.c +++ b/net.c @@ -10,6 +10,7 @@ #include "namespaces.h" #include "net.h" #include "libnetlink.h" +#include "crtools.h" #include "protobuf.h" #include "protobuf/netdev.pb-c.h" @@ -203,7 +204,7 @@ static int veth_link_info(NetDeviceEntry *nde, struct newlink_req *req) { struct rtattr *veth_data, *peer_data; struct ifinfomsg ifm; - char veth_host_name[] = "veth_host"; + struct veth_pair *n; BUG_ON(ns_fd < 0); @@ -214,7 +215,12 @@ static int veth_link_info(NetDeviceEntry *nde, struct newlink_req *req) peer_data = NLMSG_TAIL(&req->h); memset(&ifm, 0, 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)); + list_for_each_entry(n, &opts.veth_pairs, node) { + if (!strcmp(nde->name, n->inside)) + break; + } + if (&n->node != &opts.veth_pairs) + addattr_l(&req->h, sizeof(*req), IFLA_IFNAME, n->outside, strlen(n->outside)); 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; veth_data->rta_len = (void *)NLMSG_TAIL(&req->h) - (void *)veth_data;