[lxc-devel] [PATCH] hwaddr templating

Serge Hallyn serge.hallyn at ubuntu.com
Mon Jan 6 16:44:44 UTC 2014


Quoting Guillaume ZITTA (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 chage 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    | 36 ++++++++++++++++++++++++++++++++++--
>  src/lxc/utils.c      | 22 ++++++++++++++++++++++
>  src/lxc/utils.h      |  2 ++
>  4 files changed, 61 insertions(+), 3 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..3d7554a 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,21 @@ static int config_network_hwaddr(const char
> *key, const char *value,
>  {
>  	struct lxc_netdev *netdev;
> 
> -	netdev = network_netdev(key, value, &lxc_conf->network);
> +	char *newval = strdup(value);

Since this is strdup'd,

> +
> +	rand_complete_hwaddr(newval);
> +
> +	netdev = network_netdev(key, newval, &lxc_conf->network);
>  	if (!netdev)

this error path needs to free it,

>  		return -1;
> 
> -	return config_string_item(&netdev->hwaddr, value);
> +	if (!newval || strlen(newval) == 0) {
> +		netdev->hwaddr = NULL;

as does this one in the case where newval != 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..860af4f 100644
> --- a/src/lxc/utils.c
> +++ b/src/lxc/utils.c
> @@ -1108,3 +1108,25 @@ 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;
> +    process_lock();
> +    f = fopen("/dev/urandom", "r");
> +    process_unlock();
> +    if (f) {
> +        unsigned int seed;
> +        int ret = fread(&seed, sizeof(seed), 1, f);
> +        if (ret != 1)
> +            seed = time(NULL);
> +        process_lock();
> +        fclose(f);
> +        process_unlock();
> +        srand(seed);
> +    } else
> +        srand(time(NULL));
> +}
> \ No newline at end of file
> 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