NAME
generate_mac_address_vm - generate a random VM MAC address in the MA-M block
SYNOPSIS
/opt/omnicube/bin/generate_mac_address_vm
generate_mac_address_vm
DESCRIPTION
generate_mac_address_vm prints one randomly generated 48-bit MAC address, suitable for a virtual NIC of an OmniCube guest, on standard output and exits. The address is written in lower-case hexadecimal with colon separators and a trailing newline, for example:
8c:a6:82:d7:1f:4b
The generated address always falls inside the IEEE MA-M (Medium, 28-bit) assignment held by the site:
Concretely, bytes 1 to 3 are fixed at 8c, a6 and 82; the high nibble of byte 4 is fixed at D (binary 1101), so byte 4 is drawn from 0xd0 to 0xdf inclusive; and bytes 5 and 6 are drawn from 0x00 to 0xff. That leaves exactly 20 bits of entropy, all of it inside the assigned block. The generator uses the Python random module, which is not a cryptographic source; that is adequate here, since the value only has to be locally unique.
This is a small helper, written in Python (#!/usr/bin/python3.13), meant to be run by hand or captured in a shell variable while preparing a zone or VM configuration, for example the mac-address property of a net resource or a template value in vm_tpl.cfg(5). It is not invoked from cron or from an SMF method.
Unlike the shell tools of the suite this script does not source /opt/omnicube/lib/common/utils.sh. It therefore reads no SMF properties, takes no lock, writes nothing to syslog and sends no mail, and it needs no privileges: it can be run as any user without pfexec. It does, however, carry its own standalone copy of the run-level guard: the internal _oc_shutting_down predicate returns true when /etc/nologin exists, or when the field following the run-level token in the output of `who -r' is 0, 1, 5, 6, S or s. In that case the script raises SystemExit(0) and prints nothing. Setting OC_IGNORE_RUNLEVEL to any non-empty value disables the guard. Any error while running who is swallowed and treated as "not shutting down".
OPERANDS
This command takes no options and no operands. Anything passed on the command line is ignored.
EXAMPLES
Example 1: Generate one address
$ /opt/omnicube/bin/generate_mac_address_vm 8c:a6:82:d3:0a:e1
Example 2: Capture the address for a zone configuration
$ mac=$(generate_mac_address_vm)
$ pfexec zonecfg -z vm-web01 \\
"select net physical=vnic0; \\
set mac-address=${mac}; end; verify; commit"
Example 3: Check the new address is not already in use
$ mac=$(generate_mac_address_vm)
$ dladm show-vnic -o macaddress | grep -i "${mac}" && \\
echo "collision, generate another"
Example 4: Generate one during single-user maintenance
$ OC_IGNORE_RUNLEVEL=1 generate_mac_address_vm 8c:a6:82:dd:4c:90
EXIT STATUS
FILES
ENVIRONMENT
NOTES
The command does not check the generated address against addresses already in use: it does not read dladm(8) output, existing zone configurations or a registry of allocated addresses, and successive invocations are independent. Uniqueness rests on the 1048576 addresses of the MA-M block and on the operator verifying the value before committing it, for instance with `dladm show-vnic' on each node, as in Example 3. With 20 bits of entropy the birthday bound gives roughly a 0.5 percent chance of at least one collision once about 100 addresses have been generated cluster-wide, so the check is worth making.
Only the low nibble of byte 4 and bytes 5 and 6 vary. Earlier versions of this script drew byte 4 from the whole range 0xd0 to 0xff, which put roughly two thirds of the generated addresses outside the site's MA-M block, inside ranges (0xe0-0xff) assigned to other holders, with a real risk of conflicts on a shared LAN. The upper bound is now 0xdf. Addresses generated by an older version should be regenerated.
The addresses are globally administered (the local bit of the first octet is clear, since 0x8c is 10001100), which is correct for an MA-M assignment; do not substitute a locally administered 02:xx range without also updating the block documented above.
A caller that runs during a shutdown gets an empty string and exit status 0, not an error. Scripts that capture the output must therefore check for an empty value before using it.
SEE ALSO
activate_zone_vnc.sh(1), create_zone_config.sh(8), manage_zone.sh(8), oc_runlevel(3), omnicube_utils(3), vm_tpl.cfg(5), omnicube(7).