[lxc-devel] [PATCH] hwaddr templating (with fixes from comments)
lxc at zitta.fr
lxc at zitta.fr
Mon Jan 6 22:52:36 UTC 2014
This change introduce mac address templating.
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 at zitta.fr>
---
doc/lxc.conf.sgml.in | 4 +++-
src/lxc/confile.c | 41 ++++++++++++++++++++++++++++++++++++++---
src/lxc/utils.c | 18 ++++++++++++++++++
src/lxc/utils.h | 2 ++
4 files changed, 61 insertions(+), 4 deletions(-)
diff --git a/doc/lxc.conf.sgml.in b/doc/lxc.conf.sgml.in
index e6d9689..4bbeeeb 100644
--- a/doc/lxc.conf.sgml.in
+++ b/doc/lxc.conf.sgml.in
@@ -326,7 +326,9 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301 USA
the interface mac address is dynamically allocated by
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>
diff --git a/src/lxc/confile.c b/src/lxc/confile.c
index 0982b3e..c83c5bf 100644
--- a/src/lxc/confile.c
+++ b/src/lxc/confile.c
@@ -508,6 +508,28 @@ 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;
+
+ randinit();
+
+ while (*curs != '\0')
+ {
+ if ( *curs == 'x' || *curs == 'X' ) {
+ if (curs - hwaddr == 1) {
+ //ensure address is unicast
+ *curs = hex[(rand() & 0x0E)];
+ } else {
+ *curs = hex[rand() & 0x0F];
+ }
+ }
+ curs++;
+ }
+ return 0;
+}
+
static int config_network_flags(const char *key, const char *value,
struct lxc_conf *lxc_conf)
{
@@ -575,11 +597,24 @@ 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 *newval = strdup(value);
+
+ rand_complete_hwaddr(newval);
+
+ netdev = network_netdev(key, newval, &lxc_conf->network);
+ if (!netdev) {
+ free(newval);
return -1;
+ };
- return config_string_item(&netdev->hwaddr, value);
+ if (!newval || strlen(newval) == 0) {
+ free(newval);
+ netdev->hwaddr = NULL;
+ return 0;
+ }
+
+ netdev->hwaddr = newval;
+ return 0;
}
static int config_network_vlan_id(const char *key, const char *value,
diff --git a/src/lxc/utils.c b/src/lxc/utils.c
index 1f9ceea..0451a1d 100644
--- a/src/lxc/utils.c
+++ b/src/lxc/utils.c
@@ -1108,3 +1108,21 @@ void **lxc_append_null_to_array(void **array,
size_t count)
}
return array;
}
+
+void randinit(void)
+{
+ /*
+ srand pre-seed function based on /dev/urandom
+ */
+ FILE *f;
+ f = fopen("/dev/urandom", "r");
+ if (f) {
+ unsigned int seed;
+ int ret = fread(&seed, sizeof(seed), 1, f);
+ if (ret != 1)
+ seed = time(NULL);
+ fclose(f);
+ srand(seed);
+ } else
+ srand(time(NULL));
+}
diff --git a/src/lxc/utils.h b/src/lxc/utils.h
index 847a613..9018889 100644
--- a/src/lxc/utils.h
+++ b/src/lxc/utils.h
@@ -265,5 +265,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 void randinit(void);
#endif
--
1.8.3.2
More information about the lxc-devel
mailing list