Signed-off-by: S.Çağlar Onur <cag...@10ur.org>
---
 src/lxc/lxccontainer.c | 119 +++++++++++++++++++++++++++++++++++++++----------
 src/lxc/lxccontainer.h |   1 +
 2 files changed, 97 insertions(+), 23 deletions(-)

diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c
index 79237df..14b6942 100644
--- a/src/lxc/lxccontainer.c
+++ b/src/lxc/lxccontainer.c
@@ -1179,23 +1179,26 @@ static bool lxcapi_clear_config_item(struct 
lxc_container *c, const char *key)
        return ret == 0;
 }
 
-char** lxcapi_get_ips(struct lxc_container *c, char* interface, char* family, 
int scope)
-{
-       int count = 0;
-       struct ifaddrs *interfaceArray = NULL, *tempIfAddr = NULL;
-       char addressOutputBuffer[INET6_ADDRSTRLEN];
-       void *tempAddrPtr = NULL;
-       char **addresses = NULL, **temp;
-       char *address = NULL;
+static void exit_from_ns(struct lxc_container *c, int *old_netns, int 
*new_netns) {
+       /* Switch back to original netns */
+       if (*old_netns >= 0 && setns(*old_netns, CLONE_NEWNET))
+               SYSERROR("failed to setns");
+       if (*new_netns >= 0)
+               close(*new_netns);
+       if (*old_netns >= 0)
+               close(*old_netns);
+}
+
+static bool enter_to_ns(struct lxc_container *c, int *old_netns, int 
*new_netns) {
+       int ret = 0;
        char new_netns_path[MAXPATHLEN];
-       int old_netns = -1, new_netns = -1, ret = 0;
 
        if (!c->is_running(c))
                goto out;
 
        /* Save reference to old netns */
-       old_netns = open("/proc/self/ns/net", O_RDONLY);
-       if (old_netns < 0) {
+       *old_netns = open("/proc/self/ns/net", O_RDONLY);
+       if (*old_netns < 0) {
                SYSERROR("failed to open /proc/self/ns/net");
                goto out;
        }
@@ -1205,16 +1208,93 @@ char** lxcapi_get_ips(struct lxc_container *c, char* 
interface, char* family, in
        if (ret < 0 || ret >= MAXPATHLEN)
                goto out;
 
-       new_netns = open(new_netns_path, O_RDONLY);
-       if (new_netns < 0) {
+       *new_netns = open(new_netns_path, O_RDONLY);
+       if (*new_netns < 0) {
                SYSERROR("failed to open %s", new_netns_path);
                goto out;
        }
 
-       if (setns(new_netns, CLONE_NEWNET)) {
+       if (setns(*new_netns, CLONE_NEWNET)) {
                SYSERROR("failed to setns");
                goto out;
        }
+       return true;
+out:
+       exit_from_ns(c, old_netns, new_netns);
+       return false;
+}
+
+char** lxcapi_get_interfaces(struct lxc_container *c)
+{
+       int count = 0;
+       struct ifaddrs *interfaceArray = NULL, *tempIfAddr = NULL;
+       char **interfaces = NULL, **temp;
+       int old_netns = -1, new_netns = -1;
+
+       if (!enter_to_ns(c, &old_netns, &new_netns))
+               goto out;
+
+       /* Grab the list of interfaces */
+       if (getifaddrs(&interfaceArray)) {
+               SYSERROR("failed to get interfaces list");
+               goto out;
+       }
+
+       /* Iterate through the interfaces */
+       for (tempIfAddr = interfaceArray; tempIfAddr != NULL; tempIfAddr = 
tempIfAddr->ifa_next) {
+        if (tempIfAddr->ifa_addr == NULL)
+            continue;
+
+               if(tempIfAddr->ifa_addr->sa_family != AF_PACKET) {
+            continue;
+        }
+
+        count += 1;
+        temp = realloc(interfaces, count * sizeof(*interfaces));
+        if (!temp) {
+            count -= 1;
+            goto out;
+        }
+        interfaces = temp;
+        interfaces[count - 1] = strdup(tempIfAddr->ifa_name);
+    }
+
+out:
+       if(interfaceArray)
+               freeifaddrs(interfaceArray);
+
+       exit_from_ns(c, &old_netns, &new_netns);
+
+       /* Append NULL to the array */
+       if (count) {
+               count++;
+               temp = realloc(interfaces, count * sizeof(*interfaces));
+               if (!temp) {
+                       int i;
+                       for (i = 0; i < count-1; i++)
+                               free(interfaces[i]);
+                       free(interfaces);
+                       return NULL;
+               }
+               interfaces = temp;
+               interfaces[count - 1] = NULL;
+       }
+
+       return interfaces;
+}
+
+char** lxcapi_get_ips(struct lxc_container *c, char* interface, char* family, 
int scope)
+{
+       int count = 0;
+       struct ifaddrs *interfaceArray = NULL, *tempIfAddr = NULL;
+       char addressOutputBuffer[INET6_ADDRSTRLEN];
+       void *tempAddrPtr = NULL;
+       char **addresses = NULL, **temp;
+       char *address = NULL;
+       int old_netns = -1, new_netns = -1;
+
+       if (!enter_to_ns(c, &old_netns, &new_netns))
+               goto out;
 
        /* Grab the list of interfaces */
        if (getifaddrs(&interfaceArray)) {
@@ -1241,8 +1321,6 @@ char** lxcapi_get_ips(struct lxc_container *c, char* 
interface, char* family, in
 
                if (interface && strcmp(interface, tempIfAddr->ifa_name))
                        continue;
-               else if (!interface && strcmp("lo", tempIfAddr->ifa_name) == 0)
-                       continue;
 
                address = (char *)inet_ntop(tempIfAddr->ifa_addr->sa_family,
                                           tempAddrPtr,
@@ -1265,13 +1343,7 @@ out:
        if(interfaceArray)
                freeifaddrs(interfaceArray);
 
-       /* Switch back to original netns */
-       if (old_netns >= 0 && setns(old_netns, CLONE_NEWNET))
-               SYSERROR("failed to setns");
-       if (new_netns >= 0)
-               close(new_netns);
-       if (old_netns >= 0)
-               close(old_netns);
+       exit_from_ns(c, &old_netns, &new_netns);
 
        /* Append NULL to the array */
        if (count) {
@@ -2576,6 +2648,7 @@ struct lxc_container *lxc_container_new(const char *name, 
const char *configpath
        c->get_config_path = lxcapi_get_config_path;
        c->set_config_path = lxcapi_set_config_path;
        c->clone = lxcapi_clone;
+       c->get_interfaces = lxcapi_get_interfaces;
        c->get_ips = lxcapi_get_ips;
        c->attach = lxcapi_attach;
        c->attach_run_wait = lxcapi_attach_run_wait;
diff --git a/src/lxc/lxccontainer.h b/src/lxc/lxccontainer.h
index f9ae43b..f17d975 100644
--- a/src/lxc/lxccontainer.h
+++ b/src/lxc/lxccontainer.h
@@ -90,6 +90,7 @@ struct lxc_container {
         * the length which was our would be printed. */
        int (*get_config_item)(struct lxc_container *c, const char *key, char 
*retv, int inlen);
        int (*get_keys)(struct lxc_container *c, const char *key, char *retv, 
int inlen);
+       char** (*get_interfaces)(struct lxc_container *c);
        char** (*get_ips)(struct lxc_container *c, char* interface, char* 
family, int scope);
        /*
         * get_cgroup_item returns the number of bytes read, or an error (<0).
-- 
1.8.1.2


------------------------------------------------------------------------------
How ServiceNow helps IT people transform IT departments:
1. Consolidate legacy IT systems to a single system of record for IT
2. Standardize and globalize service processes across IT
3. Implement zero-touch automation to replace manual, redundant tasks
http://pubads.g.doubleclick.net/gampad/clk?id=51271111&iu=/4140/ostg.clktrk
_______________________________________________
Lxc-devel mailing list
Lxc-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/lxc-devel

Reply via email to