OmniCube Reference Manualgenerate_mac_address_vm(1)

generate_mac_address_vm(1)

User Commands · OmniCube · August 10, 2026

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:

28-bit base value

8C-A6-82-D

EUI-48 address block

0-00-00 through F-FF-FF (2**20 = 1048576 addresses)

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

0

An address was printed, or the run-level guard aborted the run (host shutting down, rebooting, halting or in single-user state), in which case no output is produced.

nonzero

No failure path of its own: the script has no error exits. Any nonzero status comes from the interpreter or the shell, for example a Python traceback (1) or a missing /usr/bin/python3.13 interpreter (127 from the invoking shell).

FILES

/opt/omnicube/bin/generate_mac_address_vm

This command.

/etc/nologin

Presence aborts the run through the standalone run-level guard.

/usr/bin/python3.13

Interpreter named in the shebang line.

ENVIRONMENT

OC_IGNORE_RUNLEVEL

When set to a non-empty value, skips the run-level guard.

PATH

Must resolve who(1), which the run-level guard executes.

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).

man1/generate_mac_address_vm.1generated 2026-09-02 05:17 CEST