Traditional Linux systems used simple sequential names like eth0, eth1 for network interfaces. Modern distributions (especially those using systemd) implement predictable network interface naming to address several issues:
# Old naming scheme (deprecated)
eth0
eth1
wlan0
# New predictable naming examples
eno1 (onboard Ethernet)
ens33 (PCI slot 33)
enp0s25 (PCI bus 0, slot 25)
enx00e04c534458 (MAC-based)
The name eno16777736
follows this structure:
- en: Ethernet interface
- o: On-board device
- 16777736: ACPI _DSM instance number (acpi_index)
To verify this on your system:
# Find the ACPI index
cat /sys/class/net/eno16777736/device/acpi_index
# Alternative way to check
udevadm info -q path -n eno16777736 | xargs -I {} udevadm info -q property -p {}
The large number (16777736) comes from the system firmware. In virtualized environments like VMware, this behavior is particularly common:
# Sample output showing the relationship
$ lspci -nnk | grep -A2 Ethernet
02:01.0 Ethernet controller [0200]: AMD 79c970 [PCnet32 LANCE] (rev 10)
Subsystem: AMD PCnet - Fast 79C971 [1028:000e]
Kernel driver in use: pcnet32
When writing scripts that need to work across different systems, consider these approaches:
# Option 1: Use ip command to find interfaces
ip -o link show | awk -F': ' '{print $2}'
# Option 2: Programmatically handle interface names in Python
import os
def get_eth_interfaces():
return [f for f in os.listdir('/sys/class/net/')
if f.startswith(('en', 'eth'))]
print(get_eth_interfaces())
Virtual machines might display either the ACPI-index-based name (eno16777736) or PCI-slot-based name (ens33). This depends on:
- VM configuration
- Hypervisor version
- Kernel version
- Firmware implementation
To force consistent naming in a VM:
# Add to kernel boot parameters
net.ifnames=0 biosdevname=0
# Then rebuild initramfs (Debian/Ubuntu)
update-initramfs -u
The traditional eth0
naming convention was replaced by predictable network interface naming to solve several pain points in modern systems:
# Old scheme (pre-systemd v197)
eth0 # First Ethernet interface
eth1 # Second Ethernet interface
wlan0 # First wireless interface
The new scheme provides deterministic naming based on:
- Firmware/BIOS topology information
- Physical connection characteristics
- Consistent naming across reboots
Let's dissect the components of eno16777736
:
en = Ethernet
o = On-board device
16777736 = ACPI index value
To trace the naming origin, use these investigative commands:
# 1. Find the PCI path
readlink /sys/class/net/eno16777736
# 2. Check ACPI index (source of the number)
cat /sys/devices/pci0000:00/0000:00:11.0/0000:02:01.0/acpi_index
# 3. Cross-reference with lspci
lspci -v | grep -A5 "Ethernet controller"
# 4. Check udev naming rules
udevadm info /sys/class/net/eno16777736 | grep ID_NET_NAME
The variation between eno16777736
and ens33
occurs because:
ens33 breakdown:
en = Ethernet
s = Hotplug slot
33 = Physical slot number
The system prioritizes different naming sources based on available information:
- ACPI index (preferred if available)
- PCI slot number (fallback)
- MAC address (last resort)
For scripts needing to handle variable interface names:
#!/bin/bash
# Find primary Ethernet interface dynamically
ETH_IFACE=$(ls /sys/class/net | grep -E '^en[o|s]' | head -1)
echo "Detected interface: $ETH_IFACE"
# Alternative method using iproute2
IPROUTE_IFACE=$(ip -o link show | awk -F': ' '/state UP/ {print $2}' | head -1)
To revert to traditional naming (not recommended):
# 1. Edit grub configuration
sudo sed -i 's/GRUB_CMDLINE_LINUX="$.*$"/GRUB_CMDLINE_LINUX="\1 net.ifnames=0"/' /etc/default/grub
# 2. Update grub and reboot
sudo update-grub
sudo reboot
For creating persistent custom names:
# Create udev rule file
cat << EOF | sudo tee /etc/udev/rules.d/10-rename-network.rules
SUBSYSTEM=="net", ACTION=="add", ATTR{address}=="00:0c:29:70:c0:39", NAME="mgmt0"
EOF
# Apply changes
sudo udevadm control --reload-rules
sudo udevadm trigger