So Linux has adopted Persistent Device Naming, which is a really great thing for most systems. Unlike the old days where we just had
eth2 etc (which at least has no spaces unlike
Local Area Connection 6 that another OS uses), whose order depended on driver initialization in the kernel. Most people just had
eth0 and were happy, and most people will still just have one Ethernet interface and will still be happy.
But with more complex setups, this persistent naming can be a problem, especially as PCIe devices come and go and change the bus layout. I’d really like truly persistent naming, tied to the specific MAC address or something, that won’t ever change no matter what else I do with the system.
To be fair to persistent device names, for most people who are not making regular hardware changes, they are a good thing. The hierarchy of naming prefers onboard naming when possible (i.e. provided by the UEFI / HW), followed by the device path. This device path is consistent across reboots, but adding or removing hardware can cause items in the list to move up and down, changing their path ID (i.e.
enp5 after adding another PCIe card). But at least replacing hardware with identical hardware will keep the path IDs the same, so we can replace NICs or really anything else in the system without messing up our network configuration.
The solution is to rename these devices on our own terms instead of the udev methodology. We can match hardware based on IDs such as the MAC address, which identifies a singular NIC, and use this to assign a name of our own. Now it’s up to us to modify this file if we ever replace a NIC, but at least other things in the system won’t change our name.
So given that information, I constructed the absolute minimal link file for my Proxmox system. We can’t use any name that the system might assign automatically (such as ethX, enoX, enpX, …) or we are in for trouble. I was originally going to name them
geX for gigabit ethernet and
xgX for 10/25Gig, but Proxmox’s web UI was not a fan of this and refused to do any networking administration since it couldn’t figure out what type those were by parsing the
/etc/network/interfaces file. So, I settled on
enge0 for my onboard gigabit Ethernet and
enxg1 for the port on the 25 gig card that I’m using (enxg0 is the other port on the card, since these used to be function 0 and function 1 of the device). Remember that
enx is used by devices identified by their MAC address and nothing else (usually USB NICs), so don’t use that.
ens are all used by udev as well.
We now need to write a unit file for each interface we want to have a really permanent name, and it needs to start with a number less than 99, since 99-default.link will set the interface to regular persistent naming.
That results in a file like
[Match] MACAddress=12:34:56:78:9a:bc [Link] Name=enge0
Add one for each, in my case I added 3. Make sure you get the MAC right. Now go into
/etc/network/interfaces and replace the old name with the new one. On reboot, udev should do its thing, call systemd-link, which will do it’s thing, and everything should magically come up.
/etc/network/interfaces on Proxmox now looks like this:
# network interface settings; autogenerated # Please do NOT modify this file directly, unless you know what # you're doing. # # I know what I'm doing so I edited it manually auto lo iface lo inet loopback #Real gigabit NIC auto enge0 iface enge0 inet6 manual #Dual port Mellanox NIC auto enxg0 iface enxg0 inet6 static address fd69:beef:cafe:6::70/64 #Dual port Mellanox NIC auto enxg1 iface enxg1 inet6 manual #Bond primary LAN NICs for failover auto bond0 iface bond0 inet manual bond-slaves enge0 enxg1 bond-miimon 100 bond-mode active-backup bond-primary enxg1 #Primary VM bridge to LAN auto vmbr0 iface vmbr0 inet static address 172.27.1.70/20 gateway 172.27.0.1 bridge-ports bond0 bridge-stp off bridge-fd 0 bridge-vlan-aware yes bridge-vids 2-4094 iface vmbr0 inet6 static address 2001:db8:6969:420::70/64 gateway 2001:db8:6969:420::1
And they show up Proxmox UI too!
And of course
ip a shows the interfaces as expected!
3: enge0: <NO-CARRIER,BROADCAST,MULTICAST,SLAVE,UP> mtu 1500 qdisc pfifo_fast master bond0 state DOWN group default qlen 1000 link/ether 26:a9:1e:5e:7f:5d brd ff:ff:ff:ff:ff:ff permaddr a8:a1:59:22:48:32 7: enxg0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000 link/ether b8:ce:f6:ae:38:e4 brd ff:ff:ff:ff:ff:ff inet6 fd69:beef:cafe:6::70/64 scope global valid_lft forever preferred_lft forever inet6 fe80::bace:f6ff:feae:38e4/64 scope link valid_lft forever preferred_lft forever 8: enxg1: <BROADCAST,MULTICAST,SLAVE,UP,LOWER_UP> mtu 1500 qdisc mq master bond0 state UP group default qlen 1000 link/ether 26:a9:1e:5e:7f:5d brd ff:ff:ff:ff:ff:ff permaddr b8:ce:f6:ae:38:e5 9: bond0: <BROADCAST,MULTICAST,MASTER,UP,LOWER_UP> mtu 1500 qdisc noqueue master vmbr0 state UP group default qlen 1000 link/ether 26:a9:1e:5e:7f:5d brd ff:ff:ff:ff:ff:ff 10: vmbr0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000 link/ether 26:a9:1e:5e:7f:5d brd ff:ff:ff:ff:ff:ff inet 172.27.1.70/20 scope global vmbr0 valid_lft forever preferred_lft forever inet6 2001:db8:6969:420::70/64 scope global valid_lft forever preferred_lft forever inet6 fe80::24a9:1eff:fe5e:7f5d/64 scope link valid_lft forever preferred_lft forever
So now I’m free to add/remove PCIe cards at will (this system gets used for a lot of testing random devices) and not worry about what that will do to my main NIC.