Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
Generate systemd nspawn interface MAC aadresses based on the host id and container name
#!/usr/bin/env python3
This script implements systemd-nspawn MAC aadress generation algorithm
import sys
import struct
from subprocess import run
import siphashc #
# from src/nspawn/nspawn-network.c
# -n,--network-veth
# host side of vb-/ve- interface
HOST_HASH_KEY = bytes.fromhex("1a376fc746ec450bada3d53106605db1")
# container side of vb-/ve- interface
CONTAINER_HASH_KEY = bytes.fromhex("c3c4f919b557b21ce6cf1427039ceea2")
# --network-veth-extra
VETH_EXTRA_HOST_HASH_KEY = bytes.fromhex("48c7f6b7ea9d4c9eb728d4de91d5bf66")
VETH_EXTRA_CONTAINER_HASH_KEY = bytes.fromhex("af501761cef94d35840d2b2054bece59")
# --network-macvlan
MACVLAN_HASH_KEY = bytes.fromhex("00136dbc66834481bb0cf9511f24a66f")
# used when interface name is too long
SHORTEN_IFNAME_HASH_KEY = bytes.fromhex("e190a404a8ef4b518cccc33a9f11fca2")
# Based on systemd src/nspawn/nspawn-network.c
def generate_mac(machine_id, machine_name, hash_key, idx=0):
if type(machine_name) == str:
machine_name = machine_name.encode()
if idx > 0:
v = machine_id + struct.pack('<Q', idx) + machine_name
v = machine_id + machine_name
result = siphashc.siphash(hash_key, v).to_bytes(8, byteorder='little')
mac = bytearray(result[:6])
mac[0] &= 0xfe; # clear multicast bit
mac[0] |= 0x02; # set local assignment bit (IEEE802)
return bytes(mac)
def format_mac(mac):
if type(mac) == bytes:
mac = mac.hex()
l = []
for idx in range(0, len(mac), 2):
return ":".join(l)
if __name__ == "__main__":
if len(sys.argv) == 3:
machine_id = bytes.fromhex(sys.argv[1])
machine_name = sys.argv[2]
elif len(sys.argv) == 2:
machine_name = sys.argv[1]
machine_id_proc = run(["systemd-id128", "machine-id"], capture_output=True, text=True)
machine_id = bytes.fromhex(machine_id_proc.stdout.strip())
print("Usage: {} [machine-id] machine-name".format(sys.argv[0]), file=sys.stderr)
mac = generate_mac(machine_id, machine_name, CONTAINER_HASH_KEY)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.