Thursday, December 15, 2011

Dealing with the Hyper-V default MAC pool

This is my little hack around dealing with the Hyper-V default MAC address pool range.

If you have been following, I have a bunch of virtual machines that I am creating.  And it is important that each has a unique MAC address.

Here is where software behavior gets into my way.

By default a Hyper-V Server MAC address range is only 255 MAC addresses ( 00 – FF ).  But a Hyper-V server can support 385 VMs, or VMs can have multiple virtual NICs.  So my pool can get depleted pretty quickly.

The other issue is that when assigning a MAC address to a VM the MACs are taken from the pool sequentially.  Not a big issue, and it actually adds some predictability.  However, once the end of the list is reached it starts over from the beginning.

The last issue, a Hyper-V Server only reserves the MAC of a VM when that VM is on that host.  Here is where my scenario makes all the problems.  I have a cluster of Hyper-V Servers, I am using one of them to create all my VM copies, then my VMs will migrate away.  Once the VM is no longer on the host where it was created its MAC is marked available in the pool (this is not tracked at the cluster level).

Combine this with the circular assignment action and this MAC can be assigned a second time, to a different VM.

SCVMM can solve this, as it tracks static MACs for all VMs that it manages.  But why use SCVMM just to prevent MAC duplication?

My hack?  Make the pool larger.  Only modify the octet that is necessary to achieve it.  And, randomize it to reduce the possibility of collision from a different host.

In a previous post I modified the MAC pool of a Hyper-V Server.  Here is where I embellish it to help with this duplicate MAC address issue.  Some interesting parts are converting from hexadecimal to decimal and then back again.

Additional background; leave the Hyper-V range "00155D", modify some part of the last 3 octets.  Increasing the next to last octet should give enough MAC addresses to prevent the range from rolling over and cover the number of VMs in a cluster (maximum of 1000).  I just want to make the pool bigger and the last octet of the MaximumMacAddress is always 255 (FF).

$VMManagementService = Get-WmiObject -Namespace root\virtualization -Class Msvm_VirtualSystemManagementService -ComputerName $hypervHost

$vsmssd = Get-WmiObject Msvm_VirtualSystemManagementServiceSettingData -Namespace "root\virtualization" -ComputerName $hypervHost

$intOctFive = [Convert]::ToInt32(($vsmssd.MaximumMacAddress.Substring(8,2)),16)

If ($intOctFive -lt 254) {
    $newIntOct = Get-Random -minimum ($intOctFive + 1) -maximum 255
    $newStrOct = ([Convert]::ToString($newIntOct, 16)).ToUpper()
    $vsmssd.MaximumMacAddress = ($vsmssd.MaximumMacAddress.Substring(0,8) + $newStrOct + $vsmssd.MaximumMacAddress.Substring(10,2))
}
Else {
    $intOctFour = [Convert]::ToInt32(($vsmssd.MaximumMacAddress.Substring(6,2)),16)
    $newIntOct = Get-Random -minimum ($intOctFour + 1) -maximum 255
    $newStrOct = ([Convert]::ToString($newIntOct, 16)).ToUpper()
    $vsmssd.MaximumMacAddress = ($vsmssd.MaximumMacAddress.Substring(0,6) + $newStrOct + $vsmssd.MaximumMacAddress.Substring(8,4))
}

$VMManagementService.ModifyServiceSettings($vsmssd.psbase.gettext(1))

1 comment:

@adamwessin said...

very nice