Use of Predictable Network Interface Names with alternate kernels

Almost constantly, I use kernels from the Ubuntu kernel PPA, or kernels I have compiled myself, using the Ubuntu kernel configuration.

The problem is when I am using the stock kernel it seems to default to using predictable network interface names (i.e. "p4p1"), but when I use any alternate kernel it seems to default to using the old method (i.e. "eth0").

While not really relevant to this question, I had a hard disk failure on my test computer and am doing a new install of Ubuntu Server 14.04.2.

I have not been able to determine what is the difference between the kernels. I suspect a kernel configuration parameter, but have been unable to identify which one.

My question: How can I make predictable network interface names work consistently across all kernels?

Additional notes: Somewhere I saw to disable predictable network interface names to add this to grub:

GRUB_CMDLINE_LINUX_DEFAULT="net.ifnames=0 biosdevname=0"

so, I thought the opposite might help:

GRUB_CMDLINE_LINUX_DEFAULT="net.ifnames=1 biosdevname=1"

but it made no difference. Actually, I can never get the non-stock kernel to use biosdevname, no matter the setting. And I can never get the stock kernel to generate a /etc/udev/rules.d/70-persistent-net.rules file (even though, that is not what I want), no matter the setting of net.ifnames. If I have net.ifnames=1, then at least the non-stock kernel doesn't generate an incorrect /etc/udev/rules.d/70-persistent-net.rules file.

Excerpts from /var/log/udev:
stock kernel:

KERNEL[9.216730] add      /devices/pci0000:00/0000:00:1c.4/0000:03:00.0/net/p4p1 (net)
ACTION=add
DEVPATH=/devices/pci0000:00/0000:00:1c.4/0000:03:00.0/net/p4p1
IFINDEX=2
INTERFACE=p4p1
SEQNUM=1945
SUBSYSTEM=net
...
UDEV  [9.241073] add      /devices/pci0000:00/0000:00:1c.4/0000:03:00.0/net/p4p1 (net)
ACTION=add
DEVPATH=/devices/pci0000:00/0000:00:1c.4/0000:03:00.0/net/p4p1
ID_BUS=pci
ID_MODEL_FROM_DATABASE=P8P67 and other motherboards
ID_MODEL_ID=0x8168
ID_NET_NAME_MAC=enxf46d04652d8e
ID_NET_NAME_PATH=enp3s0
ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC.
ID_PCI_CLASS_FROM_DATABASE=Network controller
ID_PCI_SUBCLASS_FROM_DATABASE=Ethernet controller
ID_VENDOR_FROM_DATABASE=Realtek Semiconductor Co., Ltd.
ID_VENDOR_ID=0x10ec
IFINDEX=2
INTERFACE=p4p1

From Ubuntu PPA kernel 4.1RC5:

KERNEL[10.772566] add      /devices/pci0000:00/0000:00:1c.4/0000:03:00.0/net/eth0 (net)
ACTION=add
DEVPATH=/devices/pci0000:00/0000:00:1c.4/0000:03:00.0/net/eth0
IFINDEX=2
INTERFACE=eth0
SEQNUM=1962
SUBSYSTEM=net
...
UDEV  [11.185866] add      /devices/pci0000:00/0000:00:1c.4/0000:03:00.0/net/eth0 (net)
ACTION=add
DEVPATH=/devices/pci0000:00/0000:00:1c.4/0000:03:00.0/net/eth0
ID_BUS=pci
ID_MODEL_FROM_DATABASE=P8P67 and other motherboards
ID_MODEL_ID=0x8168
ID_NET_NAME_MAC=enxf46d04652d8e
ID_NET_NAME_PATH=enp3s0
ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC.
ID_PCI_CLASS_FROM_DATABASE=Network controller
ID_PCI_SUBCLASS_FROM_DATABASE=Ethernet controller
ID_VENDOR_FROM_DATABASE=Realtek Semiconductor Co., Ltd.
ID_VENDOR_ID=0x10ec
IFINDEX=2
INTERFACE=eth0
SEQNUM=1962
SUBSYSTEM=net
USEC_INITIALIZED=3227

Note: I have temporarily moved past this issue by allowing a /etc/udev/rules.d/70-persistent-net.rules file to be created, and then editing it for proper device names. Ultimately, I would like to get rid of the file.


You need to distinguish between 3 things:

  • Predictable interfaces names
  • biosdevname
  • 70-persistent.rules udev rule

You either choose to use one of these solution but you don't use 2 or 3 at the same time. (In fact, you can but one will take precedence and mask the other(s))

A good introduction to the current situation is the post on the ubuntu dev mailing list

Predictable interface names

Predictable interface names is a udevd thing since v197 generated in /lib/udev/rules.d/80-net-setup-link.rules

systemd use by default the new predictable interface name. However, unless upstream systemd, in Ubuntu, you have to opt-in by using net.ifnames=1

It does not matter the kernel version you are running. But you need to use the kernel command line to configure it by changing grub configuration /etc/default/grub, like:

GRUB_CMDLINE_LINUX_DEFAULT="net.ifnames=1"

and run

sudo update-grub

In 14.04 or 14.10, without systemd, it should be enough to remove 70-persitent-net.rules, as described below in the note.

Biosdevname

biosdevname is a dell attempt to solve a similar problem than predictable interface name in systemd. It is the default on ubuntu server. You can have it by installing the package biosdevname

sudo apt-get install biosdevname

Note

You can disable it by using kernel command line in grub config:

GRUB_CMDLINE_LINUX_DEFAULT="biosdevname=0"

and run

sudo update-grub

or simply uninstall the package.

sudo apt-get purge biosdevname
sudo update-initramfs -u

udev rules

This is the default on Ubuntu desktop. The udev rule /lib/udev/rules.d/75-persistent-net-generator.rules creates during the first boot a custom rules /etc/udev/rules.d/70-persistent-net.rules with MAC address of your interface to get persistent name for your interface.

Note

If you are already using udev rules, you need to remove /etc/udev/rules.d/70-persistent-net.rules and to avoid it being regenerated at each boot you need to run

sudo ln -s /dev/null /etc/udev/rules.d/75-persistent-net-generator.rules

After that, if you use systemd, then you need to opt-in for predictable interface name, as describe above.


  1. In Ubuntu Server 16.04LTS all I did was run:

    ln -s /dev/null /etc/udev/rules.d/80-net-setup-link.rules
    
  2. Then create the file using

    sudo vi /etc/systemd/network/10-internet.link
    

    and add the following

    [Match]
    Path=pci-0000:(your device mac address)
    
    [Link]
    Name=eth0 (or whatever you want to name it)
    

    :wq to save the file

  3. then reboot and adjust your /etc/network/interfaces file.. then reboot again

Hope this helps someone