Thursday, March 25, 2021

Renaming Linux network interfaces via udev rules

I had this issue recently when I set up a new server with a bunch of built-in ports.  The default interface assignments when I performed my initial install of Ubuntu on the device made perfect sense (e.g., eno1 was "port 1" from the server guide, etc.), but after installing EVE-NG I ended up with ethX names that were spread all over the place.  This is what it took to get the names to make sense again, and note that this process makes use of the interface bus address, rather than MAC address, to ensure the name doesn't change.

Step 1:  Allow the kernel to rename network devices via udev

You should be able to do this in /etc/default/grub.  Edit the file, and make sure that GRUB_CMDLINE_LINUX includes net.ifnames=1.  After making the change (if necessary), run update-grub to update /boot/grub/grub.cfg.

Step 2:  Identify where the network interfaces appear on the PCI bus

Run the command lspci | grep net and check the output.  Here is what I see on my server:

root@superserver-01:~# lspci | grep net
65:00.0 Ethernet controller: Intel Corporation I350 Gigabit Network Connection (rev 01)
65:00.1 Ethernet controller: Intel Corporation I350 Gigabit Network Connection (rev 01)
65:00.2 Ethernet controller: Intel Corporation I350 Gigabit Network Connection (rev 01)
65:00.3 Ethernet controller: Intel Corporation I350 Gigabit Network Connection (rev 01)
b7:00.0 Ethernet controller: Intel Corporation Ethernet Connection X722 for 10GBASE-T (rev 04)
b7:00.1 Ethernet controller: Intel Corporation Ethernet Connection X722 for 10GBASE-T (rev 04)
b7:00.2 Ethernet controller: Intel Corporation Ethernet Connection X722 for 10GbE SFP+ (rev 04)
b7:00.3 Ethernet controller: Intel Corporation Ethernet Connection X722 for 10GbE SFP+ (rev 04)

As you can see, there are two Ethernet controllers on-board, and each controller is attached to four physical interfaces.  Make note of the PCI address associated with each interface.

Step 3:  Create the udev rule

The udev rules are located in /etc/udev/rules.d.  Some OS'es will have a default file named 70-persistent-net.rules already there.  Whether you instance does or not, we will create another rule intended to preempt any changes the pre-installed rule will make.  So, create a new file named 60-persistent-net.rules.  For each network interface you wish to name, create a line like the following:

SUBSYSTEM=="net", ACTION=="add", KERNELS=="<pci_address>", NAME:="<if_name>"

In my case, I have the following:

root@superserver-01:~# cat /etc/udev/rules.d/60-persistent-net.rules
SUBSYSTEM=="net", ACTION=="add", KERNELS=="0000:65:00.0", NAME:="eth0"
SUBSYSTEM=="net", ACTION=="add", KERNELS=="0000:65:00.1", NAME:="eth1"
SUBSYSTEM=="net", ACTION=="add", KERNELS=="0000:65:00.2", NAME:="eth2"
SUBSYSTEM=="net", ACTION=="add", KERNELS=="0000:65:00.3", NAME:="eth3"
SUBSYSTEM=="net", ACTION=="add", KERNELS=="0000:b7:00.0", NAME:="eth4"
SUBSYSTEM=="net", ACTION=="add", KERNELS=="0000:b7:00.1", NAME:="eth5"
SUBSYSTEM=="net", ACTION=="add", KERNELS=="0000:b7:00.2", NAME:="eth6"
SUBSYSTEM=="net", ACTION=="add", KERNELS=="0000:b7:00.3", NAME:="eth7"

Two things to note: First, the PCI address that you grabbed from lspci is prefixed by 0000: here.  Second, note that the name assignment includes the operator := rather than just =.  This ensures that the interface name will not be rewritten by subsequent rules.

Now you can save the changes and reboot.  When the server is up and running again, you should see that your interfaces are named how you want.

Good luck!

Wednesday, February 03, 2021

Linux Networking with Netplan: Examples, etc.

This is not meant to be a prose-y post.  It's really just a handful of examples to illustrate how to use netplan to implement host networking in Linux.  Remember to use sudo netplan generate to syntax-check your changes, and sudo netplan apply to implement them.

The netplan reference is located at https://netplan.io/reference/

Using DHCP

network:
  version: 2
  renderer: NetworkManager
  ethernets:
    eth0:
      dhcp4: yes
      dhcp6: yes

Assigning a static IP address (with gateway, DNS, etc.)

network:
  version: 2
  renderer: NetworkManager
  ethernets:
    eth0:
      dhcp4: no
      addresses: [192.168.100.118/24]
      gateway4: 192.168.100.1
      nameservers:
        search: [lab]
        addresses: [1.1.1.1, 9.9.9.9]


Creating a bond interface (also illustrates a static route)

network:
  version: 2
  renderer: NetworkManager
  ethernets:
    eth1:
      dhcp4: no
    eth2:
      dhcp4: no
  bonds:
    bond0:
      interfaces: [eth1, eth2]
      addresses: [172.24.100.116/24]
      dhcp4: no
      dhcp6: no
      routes:
      - to: 172.16.0.0/12
        via: 172.24.100.1
      parameters:
        mode: 802.3ad
        lacp-rate: fast
        transmit-hash-policy: layer3+4
        mii-monitor-interval: 100

Creating a VLAN-tagged interface

network:
  version: 2
  renderer: NetworkManager
  ethernets:
    eth1:
      dhcp4: no
      dhcp6: no
  vlans:
    eth1.101:
      id: 101
      link: eth1
      addresses: [172.24.101.118/24]
      routes:
      - to: 172.16.0.0/12
        via: 172.24.101.1
    eth1.102:
      id: 102
      link: eth1
      addresses: [172.24.102.118/24]
      routes:
      - to: 172.16.0.0/12
        via: 172.24.102.1