Giving your Linux network interfaces fixed names (under udevd and networkd)

June 30, 2021

Suppose, not entirely hypothetically, that you always want your machine's primary network interface to be called 'em0' regardless of what the combination of the kernel, networkd, and the systemd udevd want to call them today (something that has been known to change). Until recently, my (incorrect) setup for this was a <link>.link file that looked like this:

[Match]
MACAddress=2c:fd:a1:xx:xx:xx

[Link]
Description=Onboard motherboard port
MACAddressPolicy=persistent
Name=em0
# Stop VLAN renaming
NamePolicy=keep

I had this NamePolicy because I had VLANs on top of em0 and this was how I made them work. This .link file worked for about a year and a half, and then I upgraded my Fedora 33 workstation from 5.12.11 to 5.12.12 and rebooted. It promptly dropped off the network because my interface had the wrong name and nothing got configured on it.

What I was trying to do was rename the interface with that MAC address to em0. What my addition of NamePolicy=keep did was create a situation where the interface would be renamed to em0 if and only if nothing else had renamed it before udevd processed my .link file. In 5.12.12 (but not 5.12.11), something (either the kernel or udevd) decided to rename my interface to enp8s0 before my .link file took effect, and then the interface didn't get renamed again to em0.

(This is the implication of '[...] or all policies configured [in NamePolicy] must fail' in the manpage's description of 'Name='. If the device hasn't already been given a name, the 'keep' policy would fail and it would be renamed to em0 by my 'Name='.)

If you (I) want to give your network interfaces fixed names but have your .link files apply only to real Ethernet interfaces instead of matching broadly, what I believe you want is:

[Match]
MACAddress=2c:fd:a1:xx:xx:xx
Type=ether
# Before systemd v245, use eg
# Property=ID_BUS=pci

[Link]
Description=Onboard motherboard port
MACAddressPolicy=persistent
Name=em0

With no NamePolicy, this will unconditionally rename anything matching that MAC to em0. With Type=ether, this will only apply to real Ethernet devices, not your VLANs or other things that inherit the MAC from the underlying Ethernet interface.

PS: At this point one may want to read the systemd.net-naming-scheme manpage. I believe that names of the form 'emX' are safe from ever colliding with kernel-assigned interface names, but I'm not completely sure.

PPS: In 5.12.12, my kernel boot logs clearly show that there are two renamings with this .link setup:

igb 0000:08:00.0 enp8s0: renamed from eth0
[...]
igb 0000:08:00.0 em0: renamed from enp8s0

So my new .link doesn't prevent the initial renaming in 5.12.12 to enp8s0; it just allows my .link to rename the interface again to the em0 that I want.

Written on 30 June 2021.
« Monitoring the status of Linux network interfaces with Prometheus
Dealing with CSS fixed position headers and footers in Firefox »

Page tools: View Source, Add Comment.
Search:
Login: Password:
Atom Syndication: Recent Comments.

Last modified: Wed Jun 30 16:41:47 2021
This dinky wiki is brought to you by the Insane Hackers Guild, Python sub-branch.