]> git.ipfire.org Git - thirdparty/lxc.git/commitdiff
Replace mktemp() by a new mkifname()
authorStéphane Graber <stgraber@ubuntu.com>
Fri, 9 Aug 2013 09:32:55 +0000 (11:32 +0200)
committerStéphane Graber <stgraber@ubuntu.com>
Fri, 9 Aug 2013 13:05:19 +0000 (15:05 +0200)
Using mktemp() leads to build time warnings and isn't actually
appropriate for what we want to do as it's checking for the existence of
a file and not a network interface.

Replace those calls by an equivalent mkifname() function which uses the
same template as mktemp but instead checks for existing network
interfaces.

Signed-off-by: Stéphane Graber <stgraber@ubuntu.com>
Acked-by: Serge Hallyn <serge.hallyn@ubuntu.com>
src/lxc/conf.c

index 53c05e6670bd452578c10eda111d6f7e6b40aca6..1bd8c1454200c70bac836e3fe68aa697d8658127 100644 (file)
@@ -31,6 +31,8 @@
 #include <unistd.h>
 #include <sys/wait.h>
 #include <sys/syscall.h>
+#include <ifaddrs.h>
+#include <time.h>
 
 #if HAVE_PTY_H
 #include <pty.h>
@@ -272,6 +274,64 @@ static struct caps_opt caps_opt[] = {
 static struct caps_opt caps_opt[] = {};
 #endif
 
+static char padchar[] =
+"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+
+static char *mkifname(char *template)
+{
+       char *name = NULL;
+       int i = 0;
+       FILE *urandom;
+       unsigned int seed;
+       char randstate[2048];
+       struct ifaddrs *ifaddr, *ifa;
+       int ifexists = 0;
+
+       /* Get all the network interfaces */
+       getifaddrs(&ifaddr);
+
+       /* Initialize the random number generator */
+       urandom = fopen ("/dev/urandom", "r");
+       if (urandom != NULL) {
+               if (fread (&seed, sizeof(seed), 1, urandom) <= 0)
+                       seed = time(0);
+               fclose(urandom);
+       }
+       else
+               seed = time(0);
+       initstate(seed, randstate, 256);
+
+       /* Generate random names until we find one that doesn't exist */
+       while(1) {
+               ifexists = 0;
+               name = strdup(template);
+
+               if (name == NULL)
+                       return NULL;
+
+               for (i = 0; i < strlen(name); i++) {
+                       if (name[i] == 'X') {
+                               name[i] = padchar[random() % (strlen(padchar) - 1)];
+                       }
+               }
+
+               for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
+                       if (strcmp(ifa->ifa_name, name) == 0) {
+                               ifexists = 1;
+                               break;
+                       }
+               }
+
+               if (ifexists == 0)
+                       break;
+
+               free(name);
+       }
+
+       freeifaddrs(ifaddr);
+       return name;
+}
+
 static int run_buffer(char *buffer)
 {
        FILE *f;
@@ -2174,13 +2234,13 @@ static int instanciate_veth(struct lxc_handler *handler, struct lxc_netdev *netd
                        ERROR("veth1 name too long");
                        return -1;
                }
-               veth1 = mktemp(veth1buf);
+               veth1 = mkifname(veth1buf);
                /* store away for deconf */
                memcpy(netdev->priv.veth_attr.veth1, veth1, IFNAMSIZ);
        }
 
        snprintf(veth2buf, sizeof(veth2buf), "vethXXXXXX");
-       veth2 = mktemp(veth2buf);
+       veth2 = mkifname(veth2buf);
 
        if (!strlen(veth1) || !strlen(veth2)) {
                ERROR("failed to allocate a temporary name");
@@ -2286,7 +2346,7 @@ static int instanciate_macvlan(struct lxc_handler *handler, struct lxc_netdev *n
        if (err >= sizeof(peerbuf))
                return -1;
 
-       peer = mktemp(peerbuf);
+       peer = mkifname(peerbuf);
        if (!strlen(peer)) {
                ERROR("failed to make a temporary name");
                return -1;