Currently, we depends on ip command to attach interface to container. It means we only implemented it by python.
This patch implement adding and removing interface by c and added them in struct container. Signed-off-by: Dongsheng Yang <yangds.f...@cn.fujitsu.com> --- src/lxc/lxccontainer.c | 88 +++++++++++++++++++++++++++++++++++++++++++++++++- src/lxc/lxccontainer.h | 19 +++++++++++ 2 files changed, 106 insertions(+), 1 deletion(-) diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c index ece03ab..72563fe 100644 --- a/src/lxc/lxccontainer.c +++ b/src/lxc/lxccontainer.c @@ -39,6 +39,7 @@ #include <lxc/lxccontainer.h> #include <lxc/version.h> +#include <lxc/network.h> #include "config.h" #include "lxc.h" @@ -1483,7 +1484,7 @@ static inline bool enter_to_ns(struct lxc_container *c) pid_t pid = c->init_pid(c); if ((geteuid() != 0 || (c->lxc_conf && !lxc_list_empty(&c->lxc_conf->id_map))) && access("/proc/self/ns/user", F_OK) == 0) { - if (switch_to_ns(pid, "user")) + if (!switch_to_ns(pid, "user")) return false; } @@ -3456,6 +3457,89 @@ static bool lxcapi_remove_device_node(struct lxc_container *c, const char *src_p return add_remove_device_node(c, src_path, dest_path, false); } +static bool lxcapi_attach_interface(struct lxc_container *c, const char *ifname, + const char *dst_ifname) +{ + int ret = 0; + if (am_unpriv()) { + ERROR(NOT_SUPPORTED_ERROR, __FUNCTION__); + return false; + } + + ret = lxc_netdev_isup(ifname); + if (ret < 0) + goto err; + + /* netdev of ifname is up. */ + if (ret) { + ret = lxc_netdev_down(ifname); + if (ret) + goto err; + } + + ret = lxc_netdev_move_by_name(ifname, c->init_pid(c), dst_ifname); + if (ret) + goto err; + + return true; +err: + /* -EINVAL means there is no netdev named as ifanme. */ + if (ret == -EINVAL) { + ERROR("No network device named as %s.", ifname); + } + return false; +} + +static bool lxcapi_detach_interface(struct lxc_container *c, const char *ifname, + const char *dst_ifname) +{ + pid_t pid, pid_outside; + + if (am_unpriv()) { + ERROR(NOT_SUPPORTED_ERROR, __FUNCTION__); + return false; + } + + pid_outside = getpid(); + pid = fork(); + if (pid < 0) { + ERROR("failed to fork task to get interfaces information"); + return false; + } + + if (pid == 0) { // child + int ret = 0; + if (!enter_to_ns(c)) { + ERROR("failed to enter namespace"); + exit(-1); + } + + ret = lxc_netdev_isup(ifname); + if (ret < 0) + exit(ret); + + /* netdev of ifname is up. */ + if (ret) { + ret = lxc_netdev_down(ifname); + if (ret) + exit(ret); + } + + ret = lxc_netdev_move_by_name(ifname, pid_outside, dst_ifname); + + /* -EINVAL means there is no netdev named as ifanme. */ + if (ret == -EINVAL) { + ERROR("No network device named as %s.", ifname); + } + exit(ret); + } + + if (wait_for_pid(pid) != 0) + return false; + + return true; +} + struct criu_opts { /* The type of criu invocation, one of "dump" or "restore" */ char *action; @@ -4051,6 +4135,8 @@ struct lxc_container *lxc_container_new(const char *name, const char *configpath c->may_control = lxcapi_may_control; c->add_device_node = lxcapi_add_device_node; c->remove_device_node = lxcapi_remove_device_node; + c->attach_interface = lxcapi_attach_interface; + c->detach_interface = lxcapi_detach_interface; c->checkpoint = lxcapi_checkpoint; c->restore = lxcapi_restore; diff --git a/src/lxc/lxccontainer.h b/src/lxc/lxccontainer.h index 6344f3d..f9feeba 100644 --- a/src/lxc/lxccontainer.h +++ b/src/lxc/lxccontainer.h @@ -762,6 +762,25 @@ struct lxc_container { bool (*remove_device_node)(struct lxc_container *c, const char *src_path, const char *dest_path); /*! + * \brief Add specified netdev to the container. + * + * \param c Container. + * \param dev name of net device. + * + * \return \c true on success, else \c false. + */ + bool (*attach_interface)(struct lxc_container *c, const char *dev, const char *dst_dev); + + /*! + * \brief Remove specified netdev from the container. + * + * \param c Container. + * \param dev name of net device. + * + * \return \c true on success, else \c false. + */ + bool (*detach_interface)(struct lxc_container *c, const char *dev, const char *dst_dev); + /*! * \brief Checkpoint a container. * * \param c Container. -- 1.8.4.2 _______________________________________________ lxc-devel mailing list lxc-devel@lists.linuxcontainers.org http://lists.linuxcontainers.org/listinfo/lxc-devel