Commit 3146dca8 authored by Francesc Guasch's avatar Francesc Guasch
Browse files

fix(KVM): unique MAC in all network cards

issue #1294
parent 059b4bc4
...@@ -2489,6 +2489,7 @@ sub _execute { ...@@ -2489,6 +2489,7 @@ sub _execute {
die "I can't fork" if !defined $pid; die "I can't fork" if !defined $pid;
if ( $pid == 0 ) { if ( $pid == 0 ) {
srand();
$self->_do_execute_command($sub, $request); $self->_do_execute_command($sub, $request);
exit; exit;
} }
......
...@@ -1963,7 +1963,7 @@ sub _set_controller_network($self, $number, $data) { ...@@ -1963,7 +1963,7 @@ sub _set_controller_network($self, $number, $data) {
my $pci_slot = $self->_new_pci_slot(); my $pci_slot = $self->_new_pci_slot();
my $device = "<interface type='network'> my $device = "<interface type='network'>
<mac address='52:54:00:a7:49:71'/> <mac address='".$self->_vm->_new_mac()."'/>
<source network='default'/> <source network='default'/>
<model type='$driver'/> <model type='$driver'/>
<address type='pci' domain='0x0000' bus='0x00' slot='$pci_slot' function='0x0'/> <address type='pci' domain='0x0000' bus='0x00' slot='$pci_slot' function='0x0'/>
......
...@@ -64,6 +64,7 @@ $DIR_XML = "/var/lib/ravada/xml/" if $0 =~ m{^/usr/sbin}; ...@@ -64,6 +64,7 @@ $DIR_XML = "/var/lib/ravada/xml/" if $0 =~ m{^/usr/sbin};
our $FILE_CONFIG_QEMU = "/etc/libvirt/qemu.conf"; our $FILE_CONFIG_QEMU = "/etc/libvirt/qemu.conf";
our $XML = XML::LibXML->new(); our $XML = XML::LibXML->new();
our %USED_MAC;
#----------- #-----------
# #
...@@ -2041,52 +2042,55 @@ sub _new_uuid { ...@@ -2041,52 +2042,55 @@ sub _new_uuid {
} }
sub _xml_modify_mac { sub _read_used_macs($self) {
my $self = shift; return if keys %USED_MAC;
my $doc = shift or confess "Missing XML doc";
my @old_macs;
for my $dom ($self->vm->list_all_domains) { for my $dom ($self->vm->list_all_domains) {
my $doc; my $doc;
eval { $doc = $XML->load_xml(string => $dom->get_xml_description()) } ; eval { $doc = $XML->load_xml(string => $dom->get_xml_description()) } ;
next if !$doc; next if !$doc;
for my $nic ( $doc->findnodes('/domain/devices/interface/mac')) { for my $nic ( $doc->findnodes('/domain/devices/interface/mac')) {
my $nic_mac = $nic->getAttribute('address'); my $nic_mac = lc($nic->getAttribute('address'));
push @old_macs,($nic_mac); $USED_MAC{$nic_mac}++;
} }
} }
}
for my $if_mac ($doc->findnodes('/domain/devices/interface/mac') ) { sub _new_mac($self,$mac='52:54:00:a7:49:71') {
my $mac = $if_mac->getAttribute('address');
my @macparts0 = split/:/,$mac;
my $new_mac; $self->_read_used_macs();
my @macparts = split/:/,$mac;
$macparts[5] = sprintf"%02X",($$ % 254);
my @tried; my @tried;
my $foundit; my $foundit;
for ( 1 .. 1000 ) { for ( 1 .. 1000 ) {
for my $cont ( 1 .. 1000 ) { my $pos = int(rand(scalar(@macparts)-3))+3;
my @macparts = @macparts0; for ( 0 .. 2 ) {
my $pos = int(rand(scalar(@macparts)-3))+3;
my $num =sprintf "%02X", rand(0xff); my $num =sprintf "%02X", rand(0xff);
die "Missing num " if !defined $num; die "Missing num " if !defined $num;
$macparts[$pos] = $num; $macparts[$pos] = $num;
$new_mac = lc(join(":",@macparts)); $pos++;
push @tried,($new_mac); $pos = 3 if $pos>5;
last if !grep /^$new_mac$/i,@old_macs && $self->_unique_mac($new_mac);
push @old_macs,($new_mac);
} }
my $new_mac = lc(join(":",@macparts));
push @tried,($new_mac);
if ( $self->_unique_mac($new_mac) ) { return $new_mac if !$USED_MAC{$new_mac}++ && $self->_unique_mac($new_mac);
$if_mac->setAttribute(address => $new_mac); }
$foundit = 1; die "I can't find a new unique mac\n".Dumper(\@tried) if !$foundit;
last;
} }
}
die "I can't find a new unique mac '$new_mac'\n".Dumper(\@tried) if !$foundit; sub _xml_modify_mac {
my $self = shift;
my $doc = shift or confess "Missing XML doc";
for my $if_mac ($doc->findnodes('/domain/devices/interface/mac') ) {
my $mac = $if_mac->getAttribute('address');
my $new_mac = $self->_new_mac($mac);;
$if_mac->setAttribute(address => $new_mac);
} }
} }
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment