Switching to new network interfaces naming schemes

Registered by Albert Syriy

###########################################################################
## The issue

Traditionally Linux used network interface naming schema as ethX (eth0, eth1, ... etc). By default, systemd will name Ethernet interfaces using different (from the classical) policy and can apply one of supported naming schemes. See the link for details about naming schemes: http://www.freedesktop.org/wiki/Software/systemd/PredictableNetworkInterfaceNames/

Example of classical interface naming (ethX):
============Example 1===========
# ip -o -4 link
...
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP mode DEFAULT qlen 1000\ link/ether 00:50:56:9c:74:4d brd ff:ff:ff:ff:ff:ff
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP mode DEFAULT qlen 1000\ link/ether 00:50:56:9c:03:0a brd ff:ff:ff:ff:ff:ff
================================
The Ethernet interfaces are named eth0 , eth1 .

Example of interface naming based on physical location of the hardware (PCI bus).
============Example 2===========
# ip -o -4 link
...
2: enp0s3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT qlen 1000\ link/ether 08:00:27:4b:f0:40 brd ff:ff:ff:ff:ff:ff
3: enp0s8: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT qlen 1000\ link/ether 08:00:27:bc:4d:85 brd ff:ff:ff:ff:ff:ff
================================
The interfaces are named enp0s3 , enp0s8 .

Example of interface naming based on MAC addresses:
============Example 3===========
# ip -o -4 link
...
2: enx0800274bf040: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT qlen 1000\ link/ether 08:00:27:4b:f0:40 brd ff:ff:ff:ff:ff:ff
3: enx080027bc4d85: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT qlen 1000\ link/ether 08:00:27:bc:4d:85 brd ff:ff:ff:ff:ff:ff
================================
The interfaces are named enx0800274bf040 , enx080027bc4d85 .

Ethernet interfaces could also have names incorporating Firmware/BIOS provided index numbers for on-board devices (example: eno1), names incorporating Firmware/BIOS provided PCI Express hotplug slot index numbers (example: ens1).

###########################################################################
## Proposal

In general, Fuel should deal with any arbitrary name of Ethernet interface given (assigned) in udev rules. The main idea do not bound to a particular naming schema, but get Fuel works with any given interface names.

Hard-coded interface names ethX in Fuel code should be changed to support any naming schema.
For example, the following pieces of code, using ethX template should be re-worked:
============Example 4===========
ADMIN=eth0
PUBLIC=eth1
ALL_ETH_IP = $( ip -o -4 addr | grep "eth." | awk '{print \$4 }' | cut -d/ -f1 )
===============================
So the "eth0", "eth1" and "eth." should be changed in the code above.

There are default settings (expectations) in the code. For example, the interface eth0 currently expected to be the admin interface by default. There are assignment for public and private networks etc ...

Since Ethernet interfaces could have any names (we can't predict which one it would be),
and preserve backward compatibility with the current classical naming schema (ethX), the following approach is proposed:
1. List of physical Ethernet interface names should be collected from the system.
2. This list is sorted in alphabetic manner
3. The very first interface from the sorted list is assigned to the role of eth0, the second interface is assigned to the role of eth1 , etc ...

For example, we have a host with the interfaces named as in the Example 2 (two interfaces named enp0s3 and enp0s8) and the piece of (bash) script from Example 4:
ADMIN=eth0
PUBLIC=eth1
list_interfaces = $( ip -o -4 addr | grep "eth." | awk '{print \$4 }' | cut -d/ -f1 )

The script should be changed to the following manner. (Let us assume there is the function list_ethernet_interfaces() which returns a list of the physical Ethernet interfaces in the host).
============Example 5===========
ADMIN= $( list_ethernet_interfaces() | sort -V | head -1 )
PUBLIC= $( list_ethernet_interfaces() | sort -V | head -2 | tail -1 )
ALL_ETH_IP = $( for INTF in list_ethernet_interfaces() ; do \
                      $( ip -o -4 addr show dev $INTF | awk '{print \$4 }' | cut -d/ -f1 ) \
                      done; )
===============================

This actually the script will turn up into:

ADMIN=enp0s3
PUBLIC=enp0s8
ALL_ETH_IP="<ip address of enp0s3> <ip address of enp0s8> "

###########################################################################
## Function gathering physical Ethernet interface names

The folder /sys/class/net/ contains links to the all network devices (and may have files, which should be ignored during the analysis).
The function gathering physical Ethernet interface names should ignore virtual devices like loopback interface, bond, tunnels, VLANs ...
The different network devices have different type. Ethernet devices are marked by number "1" in the file /sys/class/net/<device>/type and could be recognized by that fact. Unfortunately Ethernet and wireless devices have the same type number, so additional check for wireless is required.

Here is an example of the function (written in bash) gathering Ethernet interfaces name on a host:
=============================
function get_ethernet_interfaces() {
  # Return list of names for Ethernet interfaces
  # exclude wireless, bond, vlan, loopback, tunnels ...
  for DEV in /sys/class/net/* ; do
    # Take only links into account, skip files
    if test ! -L \$DEV ; then
        continue
    fi
    DEVPATH=\$(readlink -f \$DEV)
    # Drop virtual devices like loopback, tunnels, bonding, vlans ...
    case \$DEVPATH in
       */virtual/*)
           continue
      ;;
    esac
    IF=\${DEVPATH##*/}
    # Check Ethernet only
    case "`cat \$DEV/type`" in
         1)
            # TYPE=1 is Ethernet, may also be wireless
            # Virtual (lo, bound, VLAN, tunnel ...) have been skipped before
            if test -d \$DEV/wireless -o -L \$DEV/phy80211 ;
            then
                 continue
            else
                 # Finally catch Ethernet non-virtual device
                       echo $IF
             fi
             ;;
          *) continue
             ;;
    esac
  done
}

Blueprint information

Status:
Not started
Approver:
None
Priority:
Undefined
Drafter:
Albert Syriy
Direction:
Needs approval
Assignee:
None
Definition:
New
Series goal:
None
Implementation:
Unknown
Milestone target:
milestone icon next

Whiteboard

Gerrit topic: https://review.openstack.org/#q,topic:bp/network-interfaces-naming-schema,n,z

Addressed by: https://review.openstack.org/236848
    Switching to new network interfaces naming schemes

Addressed by: https://review.openstack.org/254323
    Workaround to let rename udev interface using as PXE on Ubuntu bootstrap

(?)

Work Items

This blueprint contains Public information 
Everyone can see this information.

Subscribers

No subscribers.