[lxc-devel] [PATCH] hwaddr templating (with fixes from comments)
Serge Hallyn
serge.hallyn at ubuntu.com
Tue Jan 7 00:07:13 UTC 2014
Quoting lxc at zitta.fr (lxc at zitta.fr):
> 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>
Sorry, two more changes needed. If you prefer I can do them
in-line.
1. strdup value needs to be checked in case it's NULL.
2. rand() is not thread-safe. Better to use rand_r(). I'm not
sure that it's all *that* important as I don't think anything
will misbehave as a result, but it's worth switching.
> ---
> 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
>
>
> _______________________________________________
> lxc-devel mailing list
> lxc-devel at lists.linuxcontainers.org
> http://lists.linuxcontainers.org/listinfo/lxc-devel
More information about the lxc-devel
mailing list