2021-06-30
Giving your Linux network interfaces fixed names (under udevd and networkd)
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.