]> git.proxmox.com Git - mirror_lxc.git/commitdiff
This change introduce mac address templating.
authorSerge Hallyn <serge.hallyn@ubuntu.com>
Mon, 13 Jan 2014 16:02:29 +0000 (10:02 -0600)
committerSerge Hallyn <serge.hallyn@ubuntu.com>
Mon, 13 Jan 2014 16:04:10 +0000 (10:04 -0600)
By setting lxc.network.hwaddr to something like fe:xx:xx:xx:xx:xx each
"x" will be replaced by a random value.  If less significant bit of
first byte is "templated", it will be set to 0.

This change introduce also a common randinit() function that could be
used to initialize random generator.

Signed-off-by: gza <lxc@zitta.fr>
Acked-by: Serge Hallyn <serge.hallyn@ubuntu.com>
doc/lxc.conf.sgml.in
src/lxc/confile.c
src/lxc/utils.c
src/lxc/utils.h

index 1aa78171c17b3e7a3e75aae911d1db1ebcb1d288..ba109399249a72dc9592746d51a2494d52f0f1d0 100644 (file)
@@ -361,6 +361,9 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
              default to the virtual interface, but in some cases,
              this is needed to resolve a mac address conflict or to
              always have the same link-local ipv6 address
+             always have the same link-local ipv6 address.
+             Any "x" in address will be replaced by random value,
+             this allows setting hwaddr templates.
            </para>
          </listitem>
        </varlistentry>
index 3c5687636052e5fd4b6647df51600cea3932c8c7..50d09dae1b09eb25008ada98ec9e281a8835387c 100644 (file)
@@ -510,6 +510,37 @@ static int macvlan_mode(int *valuep, const char *value)
        return -1;
 }
 
+static int rand_complete_hwaddr(char *hwaddr)
+{
+       const char hex[] = "0123456789abcdef";
+       char *curs = hwaddr;
+
+#ifndef HAVE_RAND_R
+       randseed(true);
+#else
+       unsigned int seed=randseed(false);
+#endif
+       while (*curs != '\0')
+       {
+               if ( *curs == 'x' || *curs == 'X' ) {
+                       if (curs - hwaddr == 1) {
+                               //ensure address is unicast
+#ifdef HAVE_RAND_R
+                               *curs = hex[rand_r(&seed) & 0x0E];
+                       } else {
+                               *curs = hex[rand_r(&seed) & 0x0F];
+#else
+                               *curs = hex[rand() & 0x0E];
+                       } else {
+                               *curs = hex[rand() & 0x0F];
+#endif
+                       }
+               }
+               curs++;
+       }
+       return 0;
+}
+
 static int config_network_flags(const char *key, const char *value,
                                struct lxc_conf *lxc_conf)
 {
@@ -577,11 +608,27 @@ static int config_network_hwaddr(const char *key, const char *value,
 {
        struct lxc_netdev *netdev;
 
-       netdev = network_netdev(key, value, &lxc_conf->network);
-       if (!netdev)
+       char *new_value = strdup(value);
+       if (!new_value) {
+               SYSERROR("failed to strdup '%s': %m", value);
                return -1;
+       }
+       rand_complete_hwaddr(new_value);
 
-       return config_string_item(&netdev->hwaddr, value);
+       netdev = network_netdev(key, new_value, &lxc_conf->network);
+       if (!netdev) {
+               free(new_value);
+               return -1;
+       };
+
+       if (!new_value || strlen(new_value) == 0) {
+               free(new_value);
+               netdev->hwaddr = NULL;
+               return 0;
+       }
+
+       netdev->hwaddr = new_value;
+       return 0;
 }
 
 static int config_network_vlan_id(const char *key, const char *value,
index 3755bcd3ea50a27251acbb90b495b21fd994d34d..2bb4d7205ab4d8a570039ad77029593acc3db580 100644 (file)
@@ -1084,3 +1084,25 @@ void **lxc_append_null_to_array(void **array, size_t count)
        }
        return array;
 }
+
+int randseed(bool srand_it)
+{
+       /*
+          srand pre-seed function based on /dev/urandom
+          */
+       unsigned int seed=time(NULL)+getpid();
+
+       FILE *f;
+       f = fopen("/dev/urandom", "r");
+       if (f) {
+               int ret = fread(&seed, sizeof(seed), 1, f);
+               if (ret != 1)
+                       DEBUG("unable to fread /dev/urandom, %s, fallback to time+pid rand seed", strerror(errno));
+               fclose(f);
+       }
+
+       if (srand_it)
+               srand(seed);
+
+       return seed;
+}
index 1121d743706f4d6412dd59e39f4e0e8dd351eaec..ab2bd8426e61de953a59b4ef1b807fb0ccab4d06 100644 (file)
@@ -257,5 +257,7 @@ extern void lxc_free_array(void **array, lxc_free_fn element_free_fn);
 extern size_t lxc_array_len(void **array);
 
 extern void **lxc_append_null_to_array(void **array, size_t count);
+//initialize rand with urandom
+extern int randseed(bool);
 
 #endif