How Linux Assigns Persistent Network Interface Names

Modern Linux operating systems assign persistent network interface names primarily through systemd-udevd to guarantee that network hardware retains the same identifier across reboots and hardware changes. Historically, the kernel dynamically assigned names like eth0 and eth1 based on the order devices were detected during boot, which frequently caused interfaces to swap names unpredictably. Today, systemd and udev query hardware topology, firmware information, and bus paths to generate deterministic, stable names such as eno1 or enp3s0.

The Problem with Traditional Naming

In earlier Linux architectures, the kernel probed hardware concurrently during boot. If two network cards were installed, whichever card responded first was named eth0, and the second became eth1. This race condition often reversed the names after a reboot, breaking firewall rules, routing tables, and static IP network configurations. Persistent network interface naming solves this by binding the interface name to physical or electrical attributes of the hardware.

The Naming Scheme Hierarchy

The systemd predictable network interface device naming mechanism implements a five-step fallback policy to establish stable names. It checks properties in the following order:

  1. Firmware/BIOS Provided Index Numbers: If the system firmware or BIOS provides an index number for an onboard device, that number is used (e.g., eno1).
  2. Firmware/BIOS Provided Hotplug Slot Numbers: If the PCI card slot architecture provides a physical slot number, it is utilized (e.g., ens1).
  3. Physical/Geographic Location: If bus topology is available, the physical hardware connector location on the bus is derived (e.g., enp2s0).
  4. MAC Address: If explicitly requested or if other methods fail, the hardware interface's MAC address is used to form the name (e.g., enx78e7d1ea46da).
  5. Traditional Kernel Naming: If all predictable mechanisms are unavailable or disabled, the system falls back to the traditional naming convention (e.g., eth0).

Decoding Interface Prefix and Types

The generated name combines a two-character interface type prefix with a location identifier:

Following the prefix, the naming scheme applies specific format characters:

Configuration and Implementation via systemd-udevd

During system initialization, the kernel detects the network card and generates a sysfs tree containing the device's hardware attributes. Next, systemd-udevd evaluates these attributes using predefined rules located in /usr/lib/systemd/network/99-default.link.

This default configuration instructs udev to attempt naming via firmware index, slot, and physical path, in that sequence:

[Match]
OriginalName=*

[Link]
NamePolicy=keep kernel database onboard slot path
AlternativeNamesPolicy=database onboard slot path mac
MACAddressPolicy=persistent

Administrators can override this behavior by creating higher-priority files in /etc/systemd/network/. For instance, to assign a custom name based on a MAC address, a file named /etc/systemd/network/10-eth-local.link can be created:

[Match]
MACAddress=00:11:22:33:44:55

[Link]
Name=lan0

Disabling Predictable Naming

If traditional names like eth0 are required for legacy scripts or specific testing environments, persistent naming can be disabled at boot time. Passing the kernel parameters net.ifnames=0 and biosdevname=0 via the bootloader (such as GRUB) instructs the system to ignore firmware and topology rules, allowing the kernel to assign names sequentially as it probes each device.