July 26, 2014    


 

 


On each boot, Linux assigns each Network Interface Card (NIC) a name during the kernel initialization process. In the past these NIC names have been simply “ethX” where “X” is a number the was essentially the sequence in which the NIC was discovered by the kernel during the boot process.

This led to some inconsistencies in the way the NIC names were assigned and so it was not possible to predict with certainty whether a specific NIC would have the same name after each boot. And it was a near certainty that NIC names would change after a new NIC was installed in a host that had multiple NICs.

Of course there never was a problem with naming consistency in a host with only a single NIC.

Binding to MAC address

Early attempts to resolve these issues seem to have revolved around adding the MAC address of the NIC to the /etc/sysconfig/network-scripts/ifcfg-ethx interface configuration file for each NIC. That line would look like the following.

HWADDR=00:1C:C0:91:95:F4

This was intended to bind the NIC with that MAC address to the configuration file and became a very common entry in the interface configuration files. But this also had problems and was not as consistent as one would hope. And it never really resolved the problem of naming newly installed NICs on a host where one or more NICs were already present.

Multiple naming schemes

Over the years there have been a number of naming schemes and attempts at resolving this NIC naming problem.

I have always liked the original ethX naming scheme because, once a system was stable with respect to installed NICs, names like eth0 are easy to remember and type. Problems with this were which device is eth0 and which eth1 in a multiple NIC host? Is the built-in motherboard NIC eth1 or eth0? And did it change when a new NIC was added. What happens when I plug in a USB Ethernet Dongle; what is it’s NIC name now and the next time I reboot without removing the dongle?

Then there was a naming scheme that was intended to make life simpler for folks actually working with the hardware. In this scheme NICs were named things like em1 for “embedded motherboard 1” or p1p2 for “PCI bus device 1 port 2” which I though made a bit of sense. At least I could determine whether a NIC was on the motherboard or an adapter card. However multiple NICs on adapter cards and USB dongles could still confuse things.

A very recent naming scheme is based on the path of the device in the /sys filesystem. This scheme produces names like, enp2s0f1, enp0s25, and even enp0s29f7u1, which can be very long and difficult to type and remember. The last two NIC names are ones I have on my Lenovo laptop; the name enp0s29f7u1 is actually for an Ethernet USB dongle. The names created with this scheme have no obvious relationship between physical and logical devices to make it easier to either identify the port into which an Ethernet cable is to be plugged, or for which to type a command. This scheme seems to be designed by programmers for programmers and not for users or system administrators but it does have the advantage of being very consistent and predictable. This is the default scheme used by Fedora 15 and up, and for RHEL and CentOS 7 and up.

Lastly, there is a scheme that names NICs based on their MAC address. This one does make some sense as the MAC address for each NIC is available with the dmesg command. This naming scheme is very predictable and provides a bit more of a logical link between the name and the physical device than the other schemes, at least from the system administrator’s standpoint.

UDEV for naming

The udev daemon has superseded other methods for device naming. It not only names NICs but also all devices while treating every device on a host as plug’n’pray. The udev naming engine supports all of the

I have a short article about udev that also has a link to a nice Linux Journal UDEV article by Greg Kroah-Hartman with a more in-depth explanation of udev and what it does. Note that udev has been around for over ten years as of this writing because the article was published in June of 2004.

FreeDesktop.org has a link, Predictable Network Interface Names that describes in some detail the problem, past attempts to resolve it, and the current solution. The CentOS 7 FAQ page has a good description of this also. Both of these links have instructions for disabling the new network naming conventions and the  naming options you have when doing so.

Note that even with udev the kernel still sees NICs as ethX devices. It is udev that renames them. You can use the dmesg command to see this as shown below.


[    1.991134] e1000e 0000:00:19.0 eth0: (PCI Express:2.5GT/s:Width x1) 00:24:7e:13:1e:9e
[    1.991137] e1000e 0000:00:19.0 eth0: Intel(R) PRO/1000 Network Connection
[    1.991163] e1000e 0000:00:19.0 eth0: MAC: 7, PHY: 8, PBA No: 1008FF-0FF
[    2.005092] systemd-udevd[243]: renamed network interface eth0 to enp0s25
[1268141.210554] asix 2-2:1.0 eth0: register ‘asix’ at usb-0000:00:1d.7-2, ASIX AX88178 USB 2.0 Ethernet, 00:0e:c6:88:9c:8a
[1268141.240334] systemd-udevd[19296]: renamed network interface eth0 to enp0s29f7u1


The following comments are from the systemd code that, along with udev is now responsible for assigning names to NICs.


/*
 * Predictable network interface device names based on:
 *  - firmware/bios-provided index numbers for on-board devices
 *  - firmware-provided pci-express hotplug slot index number
 *  - physical/geographical location of the hardware
 *  - the interface's MAC address
 *
 * http://www.freedesktop.org/wiki/Software/systemd/PredictableNetworkInterfaceNames
 *
 * Two character prefixes based on the type of interface:
 *   en -- ethernet
 *   sl -- serial line IP (slip)
 *   wl -- wlan
 *   ww -- wwan
 *
 * Type of names:
 *   b<number>                             -- BCMA bus core number
 *   ccw<name>                             -- CCW bus group name
 *   o<index>                              -- on-board device index number
 *   s<slot>[f<function>][d<dev_port>]     -- hotplug slot index number
 *   x<MAC>                                -- MAC address
 *   [P<domain>]p<bus>s<slot>[f<function>][d<dev_port>]
 *                                         -- PCI geographical location
 *   [P<domain>]p<bus>s<slot>[f<function>][u<port>][..][c<config>][i<interface>]
 *                                         -- USB port number chain
 *
 * All multi-function PCI devices will carry the [f<function>] number in the
 * device name, including the function 0 device.
 *
 * When using PCI geography, The PCI domain is only prepended when it is not 0.
 *
 * For USB devices the full chain of port numbers of hubs is composed. If the
 * name gets longer than the maximum number of 15 characters, the name is not
 * exported.
 * The usual USB configuration == 1 and interface == 0 values are suppressed.
 *
 * PCI ethernet card with firmware index "1":
 *   ID_NET_NAME_ONBOARD=eno1
 *   ID_NET_NAME_ONBOARD_LABEL=Ethernet Port 1
 *
 * PCI ethernet card in hotplug slot with firmware index number:
 *   /sys/devices/pci0000:00/0000:00:1c.3/0000:05:00.0/net/ens1
 *   ID_NET_NAME_MAC=enx000000000466
 *   ID_NET_NAME_PATH=enp5s0
 *   ID_NET_NAME_SLOT=ens1
 *
 * PCI ethernet multi-function card with 2 ports:
 *   /sys/devices/pci0000:00/0000:00:1c.0/0000:02:00.0/net/enp2s0f0
 *   ID_NET_NAME_MAC=enx78e7d1ea46da
 *   ID_NET_NAME_PATH=enp2s0f0
 *   /sys/devices/pci0000:00/0000:00:1c.0/0000:02:00.1/net/enp2s0f1
 *   ID_NET_NAME_MAC=enx78e7d1ea46dc
 *   ID_NET_NAME_PATH=enp2s0f1
 *
 * PCI wlan card:
 *   /sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/net/wlp3s0
 *   ID_NET_NAME_MAC=wlx0024d7e31130
 *   ID_NET_NAME_PATH=wlp3s0
 *
 * USB built-in 3G modem:
 *   /sys/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.4/2-1.4:1.6/net/wwp0s29u1u4i6
 *   ID_NET_NAME_MAC=wwx028037ec0200
 *   ID_NET_NAME_PATH=wwp0s29u1u4i6
 *
 * USB Android phone:
 *   /sys/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2/2-1.2:1.0/net/enp0s29u1u2
 *   ID_NET_NAME_MAC=enxd626b3450fb5
 *   ID_NET_NAME_PATH=enp0s29u1u2
 */

And here we have a nice example of why access to the source code is so important in the Open Source Software world. One can look at the code – ore more accurately in this case, the comments in the code – and see for one’s self what is actually going on.

These comments show the various naming conventions available and examples of each.

Changing naming schemes

It is possible to change which naming scheme is used for network interfaces. Use the links below to learn how and to choose which naming convention you wish to enable. Note that some of the file names for network naming rules have changed since the articles were written.

You should also check the 71-biosdevname.rules file in the /usr/lib/udev/rules.d/ directory.

Conclusions

Regardless of the advantages of any of these new NIC naming schemes, I still find it much easier to remember and type the old ethX NIC names when entering commands. But I suspect I will get over it. The consistency of the default renaming rules is worth it in the long run. That consistency really allows me to relax and not worry that my automation scripts will break when I install a new NIC.