systemd-udevd.service ignoring 60-net.rules

I've tried my hardest to get this to work without asking for help. I can't figure it out. I have a machine that has 6 ethernet ports. I want them to be consistently named eth0 through eth5 just as we had in CentOS 6.5.

In CentOS 6.5 we used the following udev rules using the PCI address to specify exactly what names each interface gets assigned:

    ACTION=="add", SUBSYSTEM=="net", IMPORT{program}="/lib/udev/rename_device"                                           
KERNEL=="eth?", ACTION=="add", SUBSYSTEM=="net", BUS=="pci", ID=="0000:00:19.0", NAME="eth0"                         
KERNEL=="eth?", ACTION=="add", SUBSYSTEM=="net", BUS=="pci", ID=="0000:08:00.0", NAME="eth1"                         
KERNEL=="eth?", ACTION=="add", SUBSYSTEM=="net", BUS=="pci", ID=="0000:07:00.0", NAME="eth5"                         
KERNEL=="eth?", ACTION=="add", SUBSYSTEM=="net", BUS=="pci", ID=="0000:06:00.0", NAME="eth4"                         
KERNEL=="eth?", ACTION=="add", SUBSYSTEM=="net", BUS=="pci", ID=="0000:05:00.0", NAME="eth3"                         
KERNEL=="eth?", ACTION=="add", SUBSYSTEM=="net", BUS=="pci", ID=="0000:04:00.0", NAME="eth2"                         
SUBSYSTEM=="net", RUN+="/etc/sysconfig/network-scripts/net.hotplug"

I'm now running CentOS 7.1 with Kernel version 3.10.0-229.20.1.el7.x86_64. Systemd is now running on this machine. Systemd/udev uses a new persistent and predictable naming method for ethernet devices.

I've tried all of the suggestions provided on this website: http://www.freedesktop.org/wiki/Software/systemd/PredictableNetworkInterfaceNames/ This is supposed to be the official documentation for the new systemd/udev device naming scheme.

At the bottom of this page it lists 3 ways to disable the new systemd/udev naming scheme:

  1. You disable the assignment of fixed names, so that the unpredictable kernel names are used again. For this, simply mask udev's rule file for the default policy: ln -s /dev/null /etc/udev/rules.d/80-net-setup-link.rules
  2. You create your own manual naming scheme, for example by naming your interfaces "internet0", "dmz0" or "lan0". For that create your own .link files in /etc/systemd/network/, that choose an explicit name or a better naming scheme for one, some, or all of your interfaces. See systemd.link(5) for more information.
  3. You pass the net.ifnames=0 on the kernel command line

I've tried all three methods and I still can not get it to work correctly.

When I try option 1 I still get the enp0s25...enp4 interface names.

When I try option 2 I also still get the new interface names.

Option 3 gets me closer but still not close enough. When I try option three, by adding net.ifnames=0 to the kernel command at bootup, I get my eth0 through eth5 interfaces. This is good but they're named automatically by the kernel and it's ignoring my udev rules; 60-net.rules file or the 70-persistent-net.rules (there's conflicting information as to what the file should be named) files found in /etc/udev/rules.d.

My 60-net.rules and my 70-persistent-net.rules files are both the same shown here:

-bash-4.2# cat 70-persistent-net.rules                                                                               
ACTION=="add", SUBSYSTEM=="net", IMPORT{program}="/lib/udev/rename_device"                                           
ACTION=="add", SUBSYSTEM=="net", BUS=="pci", ID=="0000:00:19.0", NAME="eth0"                                         
ACTION=="add", SUBSYSTEM=="net", BUS=="pci", ID=="0000:04:00.0", NAME="eth2"                                         
ACTION=="add", SUBSYSTEM=="net", BUS=="pci", ID=="0000:05:00.0", NAME="eth3"                                         
ACTION=="add", SUBSYSTEM=="net", BUS=="pci", ID=="0000:06:00.0", NAME="eth4"                                         
ACTION=="add", SUBSYSTEM=="net", BUS=="pci", ID=="0000:07:00.0", NAME="eth5"                                         
ACTION=="add", SUBSYSTEM=="net", BUS=="pci", ID=="0000:08:00.0", NAME="eth1" 

Here is some output to show how my machine is put together:

lspci | grep Ethernet                                                                                  
00:19.0 Ethernet controller: Intel Corporation 82567LM Gigabit Network Connection (rev 03)                           
04:00.0 Ethernet controller: Intel Corporation 82574L Gigabit Network Connection                                     
05:00.0 Ethernet controller: Intel Corporation 82574L Gigabit Network Connection                                     
06:00.0 Ethernet controller: Intel Corporation 82574L Gigabit Network Connection                                     
07:00.0 Ethernet controller: Intel Corporation 82574L Gigabit Network Connection                                     
08:00.0 Ethernet controller: Intel Corporation 82574L Gigabit Network Connection

-bash-4.2# dmesg | grep eth                                                                                          
[    6.978275] e1000e 0000:00:19.0 eth0: (PCI Express:2.5GT/s:Width x1) 00:01:05:0f:2a:a0                            
[    6.986168] e1000e 0000:00:19.0 eth0: Intel(R) PRO/1000 Network Connection                                        
[    6.993044] e1000e 0000:00:19.0 eth0: MAC: 7, PHY: 8, PBA No: FFFFFF-0FF                                          
[    7.127337] e1000e 0000:04:00.0  ready                                                                            
[  478.016884] e1000e: eth0 NIC Link is Up 1000 Mbps Full Duplex, Flow Control: Rx/Tx                                
[  478.024566] IPv6: ADDRCONF(NETDEV_CHANGE): eth0: link becomes ready                                               
[  660.262275] e1000e: eth0 NIC Link is Down                                                                         
[  660.419098] e1000e: eth1 NIC Link is Down                                                                         
[  666.229161] IPv6: ADDRCONF(NETDEV_UP): eth0: link is not ready                                                    
[  666.404529] IPv6: ADDRCONF(NETDEV_UP): eth1: link is not ready                                                    
[  668.474872] e1000e: eth0 NIC Link is Up 1000 Mbps Full Duplex, Flow Control: Rx/Tx                                
[  668.482553] IPv6: ADDRCONF(NETDEV_CHANGE): eth0: link becomes ready                                               
[  738.547269] e1000e: eth0 NIC Link is Down                                                                         
[  738.704105] e1000e: eth1 NIC Link is Down                                                                         
[  749.018153] IPv6: ADDRCONF(NETDEV_UP): eth0: link is not ready                                                    
[  749.195650] IPv6: ADDRCONF(NETDEV_UP): eth1: link is not ready                                                    
[  751.264876] e1000e: eth0 NIC Link is Up 1000 Mbps Full Duplex, Flow Control: Rx/Tx                                
[  751.272556] IPv6: ADDRCONF(NETDEV_CHANGE): eth0: link becomes ready                                               
[ 1003.295095] e1000e: eth1 NIC Link is Down                                                                         
[ 1010.842662] IPv6: ADDRCONF(NETDEV_UP): eth1: link is not ready                                                    
[ 1555.995276] e1000e: eth0 NIC Link is Down                                                                         
[ 1556.153100] e1000e: eth1 NIC Link is Down                                                                         
[ 1562.076158] IPv6: ADDRCONF(NETDEV_UP): eth0: link is not ready                                                    
[ 1562.267653] IPv6: ADDRCONF(NETDEV_UP): eth1: link is not ready                                                    
[ 1564.817867] e1000e: eth0 NIC Link is Up 1000 Mbps Full Duplex, Flow Control: Rx/Tx                                
[ 1564.825549] IPv6: ADDRCONF(NETDEV_CHANGE): eth0: link becomes ready                                               
[ 2349.926276] e1000e: eth0 NIC Link is Down                                                                         
[ 2350.083101] e1000e: eth1 NIC Link is Down                                                                         
[ 2356.570139] IPv6: ADDRCONF(NETDEV_UP): eth0: link is not ready                                                    
[ 2356.754645] IPv6: ADDRCONF(NETDEV_UP): eth1: link is not ready                                                    
[ 2358.743867] e1000e: eth0 NIC Link is Up 1000 Mbps Full Duplex, Flow Control: Rx/Tx                                
[ 2358.751548] IPv6: ADDRCONF(NETDEV_CHANGE): eth0: link becomes ready                                               
[ 2535.460274] e1000e: eth0 NIC Link is Down                                                                         
[ 2535.617098] e1000e: eth1 NIC Link is Down                                                                         
[ 2541.570159] IPv6: ADDRCONF(NETDEV_UP): eth0: link is not ready                                                    
[ 2541.756655] IPv6: ADDRCONF(NETDEV_UP): eth1: link is not ready                                                    
[ 2544.019877] e1000e: eth0 NIC Link is Up 1000 Mbps Full Duplex, Flow Control: Rx/Tx                                
[ 2544.027562] IPv6: ADDRCONF(NETDEV_CHANGE): eth0: link becomes ready   

As an example you can see from my custom udev rules I want eth1 to be specifically assigned to the interface at PCI address 0000:08:00.0. But here you can see that it's actually getting assigned to the interface at 0000:04:00.0 with this output:

-bash-4.2# ethtool -i eth1                                                                                           
driver: e1000e                                                                                                       
version: 3.2.4.2-NAPI                                                                                                
firmware-version: 1.6-0                                                                                              
bus-info: 0000:04:00.0                                                                                               
supports-statistics: yes                                                                                             
supports-test: yes                                                                                                   
supports-eeprom-access: yes                                                                                          
supports-register-dump: yes                                                                                          
supports-priv-flags: no

Here's a listing of my /etc/udev/rules.d directory:

-bash-4.2# ls -l                                                                                                     
total 12                                                                                                             
-rw-r----- 1 root root 633 May 10 00:29 60-net.rules                                                                 
-rw-r--r-- 1 root root 537 Dec 21  2015 70-persistent-net.rules                                                      
lrwxrwxrwx 1 root root   9 May 10 00:44 80-net-setup-link.rules -> /dev/null                                         
-rw-r--r-- 1 root root 701 Dec 21  2015 net.rules.old

As you can see I've also got the symlink created to /dev/null to disable systemd/udev naming scheme. But that doesn't seem to do anything for me.

I've also tried editing the 60-net.rules file found in /usr/lib/udev/rules.d but that doesn't do anything either.

In /etc/sysconfig/network-scripts I had ifcfg-eth0 and ifcfg-eth1 but I renamed them to ifcfg-ethx and ifcfg-ethx1 to ensure that they aren't getting in the way as well.

Any time I make a change to any of the files I've been issuing the following commands to apply the changes:

udevadm control --reload-rules
modprobe e1000e
systemctl stop network
systemctl start network

This doesn't really seem to work or apply any of the changes I make though.

I've tried everything I can and I just can't get it. I'm desperate at this point. Any suggestions would be huge.

Here's some additional information:

-bash-4.2# udevadm info /sys/class/net/eth1                                                                          
P: /devices/pci0000:00/0000:00:1c.3/0000:02:00.0/0000:03:01.0/0000:04:00.0/net/eth1                                  
E: DEVPATH=/devices/pci0000:00/0000:00:1c.3/0000:02:00.0/0000:03:01.0/0000:04:00.0/net/eth1                          
E: ID_BUS=pci                                                                                                        
E: ID_MODEL_FROM_DATABASE=82574L Gigabit Network Connection                                                          
E: ID_MODEL_ID=0x10d3                                                                                                
E: ID_NET_NAME_MAC=enx003059081853                                                                                   
E: ID_NET_NAME_PATH=enp4s0                                                                                           
E: ID_OUI_FROM_DATABASE=KONTRON COMPACT COMPUTERS AG                                                                 
E: ID_PCI_CLASS_FROM_DATABASE=Network controller                                                                     
E: ID_PCI_SUBCLASS_FROM_DATABASE=Ethernet controller                                                                 
E: ID_VENDOR_FROM_DATABASE=Intel Corporation                                                                         
E: ID_VENDOR_ID=0x8086                                                                                               
E: IFINDEX=5                                                                                                         
E: INTERFACE=eth1                                                                                                    
E: SUBSYSTEM=net                                                                                                     
E: SYSTEMD_ALIAS=/sys/subsystem/net/devices/eth1                                                                     
E: TAGS=:systemd:                                                                                                    
E: USEC_INITIALIZED=27130                                                                                            
E: net.ifnames=0

You can see in this output that eth1 is still being assigned to the interface located at PCI address 0000:04:00.0 and the .link files aren't being used either as there is no ID_NET_LINK_FILE property shown.

Here's an example of what my 10-eth1.link file looks like in /etc/systemd/network.

-bash-4.2# cat 10-eth1.link                                                                                          
[Match]                                                                                                              
OriginalName=enp4s0                                                                                                  
Path=pci-0000:08:00.0-*                                                                                              
Driver=e1000e                                                                                                        

[Link]                                                                                                               
Name=eth1           

I'm not an expert here, but perhaps some information is better than nothing.

My understanding is that this is impossible using the standard udev infrastructure. Red Hat's documentation at https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html/networking_guide/sec-troubleshooting_network_device_naming seems to agree:

Using the ethX names works correctly for the following scenarios:

  • The system has only one network interface.
  • When used for virtio NICs in Red Hat Enterprise Linux 7 virtual machine guests. [...]

Basically here's what happens when your system boots:

  1. The kernel assigns eth0 through ethN interface names.
  2. udev rules are later used to rename those interfaces from ethX to the desired names.

When the rules in step 2 try to rename to ethX names where X <= N, then you are likely to get errors due to naming conflicts. Here's a naming conflict error I received in a different situation, where the BIOS seems to indicate that two of my interfaces should have the same name:

systemd-udevd: could not rename interface '6' from 'eth0' to 'enp4s0': File exists

I'm fairly sure then that you can call your interfaces anything you want except eth0 through ethN. For example, if you have tools that insist on "eth" prefixes on interface names, unless you have an insanely large number of interfaces, "eth100", "eth101", etc. should be safe.

Perhaps a workaround would be to have udev rename all the interfaces to names like "other_eth0", and then have a service which runs late at system startup which renames all interfaces with "other_" prefixes to remove those prefixes, although off the top of my head I have no idea how to do interface renaming outside of udev rules.

I'm surprised that you had success with those rules on CentOS 6, as I had similar issues on CentOS 6 where interfaces couldn't be assigned their correct names and would be given names like "rename2" or something. I used the "eth100", "eth101", etc. solution on CentOS 6.