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

Reply via email to