mirror of
https://git.proxmox.com/git/mirror_lxc
synced 2025-07-27 09:35:31 +00:00
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@zitta.fr> Acked-by: Serge Hallyn <serge.hallyn@ubuntu.com>
This commit is contained in:
parent
bf3e09c00e
commit
508c263ee6
@ -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>
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user