Thursday, 7 May 2015

Proposal: enable stateless persistant network interface names

Hello all,

Problem: The kernel generally detects network interfaces ("eth0",
"wlan1", etc.) in an unpredictable and often unstable order. But in
order to refer to a particular one in /etc/network/ifupdown, networkd,
firewall configs etc. you need to identify a particular one with a
stable name.

The general schema for this is to have an udev rule which does some
matches to identify a particular interface, and assings a NAME="foo"
to it. Interfaces with an explicit NAME= get called just like this,
and others just get a kernel driver default, usually ethN, wlanN, or
sometimes others (some wifi drivers have their own naming schemas).

Over the years several solutions have appeared:

- [mac] For many many years our we have installed an udev rule
/lib/udev/rules.d/75-persistent-net-generator.rules which on first
boot creates a MAC address → current name mapping and writes

- [biosdevname] is a package originally written by Dell (IIRC),
which reads port/index/slot names from the BIOS and sets them in

- [ifnames] For about two years (since 197) upstream's udev has a
builtin persistant name generator which checks firmware/BIOS
provided index numbers or slot names (like biosdevname), falls back
to slot names (PCI numbers, etc., in the spirit of
/dev/disks/by-path/), and then optionally (not done by default)
falls back to MAC address (similar to [mac]). This happens in

Note that these solutions can, and do get combined: The first rule
which sets a name wins, i. e. currently [biosdevname] beats [mac]
beats [ifnames].

Details about [mac]
This is our current solution which applies to most hardware out there.
It was an useful hack almost a decade ago, but it really shows its

* It's subject to inherent race conditions (detecting a new device
vs. renaming an existing one), which sometimes leads to devices
being called "renameX" and breaking your boot.

* It requires a writable /etc/udev/rules.d/ for persistantly storing
the assignment. We don't want/have that with system-image

* It's incompatible with how cloud images operate, as the "physical"
(emulated from the VM host) devices can change between boots.
Hence we maintain an ever-growing blacklist in
75-persistent-net-generator.rules which causes bugs and pain with
each new cloud or virtualization provider. Recent examples:
LP #1437375, #1367883, #1361272, #1317776, #1274348, #1099278.

Support for [mac] got dropped in upstream udev two years ago, and
since then we have maintained it on the Debian/Ubuntu side.

Details about [biosdevname]
We have installed biosdevname from the server install images for
several years, but never on desktop. This is a very good approach in
principle, but unfortunately most desktop and laptop BIOSes out there
don't actually set this kind of information, and of course none of the
non-x86 machines do. I don't know how pervasive it is on dedicated
server hardware. So this only actually helps for a small minority of
cases, and currently falls back to [mac].

Details about [ifnames]
This is a generic solution which extends the [biosdevname] idea and
thus applies to all practical cases and all architectures. It doesn't
need any persistant state (i. e. dynamic /etc/udev/rules.d/) and thus
applies nicely to snappy/touch, and also avoids the race condition.

The main downside is that by nature the device names are not familiar
to current admins yet. For BIOS provided names you get e. g. ens0, for
PCI slot names enp1s1 (ethernet) or wlp3s0 (wlan). But that's a
necessary price to pay (biosdevname names look similar).

As this hasn't been discussed yet, Debian and Ubuntu disable this by
default. You can opt into this by booting with "net.ifnames=1" (which
is a patch against upstream: there you disable it by booting with
net.ifnames=0 or disabling 80-net-setup-link.rules).

I propose to retire [mac], i. e. drop
/lib/udev/rules.d/75-persistent-net-generator.rules and enable
[ifnames] by default on all platforms (client, server, touch, snappy),
and stop installing biosdevname on server.

This will provide the new stable interface names for all new
installations, stop the different handling of server/client, work with
system-image, and stops the woes cloud providers have with Ubuntu's

For upgrades: As we don't know what refers to existing stable network
names, we can't ever safely remove a generated
/etc/udev/rules.d/70-persistent-net.rules or uninstall biosdevname. So
when we do the above, names on existing installations will *not*
change (as 70-persistent-net.rules trumps [biosdevname] trumps [ifnames]).

So we can only let time and replacing/reinstalling machines take care
of this. /etc/udev/rules.d/70-persistent-net.rules requires zero
maintenance from us (it's just like the admin had manually set their
own rules). It doesn't look like biosdevname is being maintained
upstream still, but it also doesn't really have to change unless Dell
comes up with a new naming schema for new hardware.

FTR, I will also discuss this in Debian, so that we use the same
approach there.




Martin Pitt |
Ubuntu Developer ( | Debian Developer (