systemd Network Interface Naming
近一兩年期間,一些 Linux 系統的網路卡命名,漸漸從 eth0
, eth1
, … 轉變成 eno1
, enp5s0
, … 這樣的格式。
一時間很不習慣,因為新命名方式較長也較複雜,輸入指令時不甚方便。
後來在網路上讀到這一篇文章的說明:
https://major.io/2015/08/21/understanding-systemds-predictable-network-device-names/
這個改變是來自 systemd 的 “Predictable Network Interface Names”,其在 Freedesktop 的說明如下:
https://www.freedesktop.org/wiki/Software/systemd/PredictableNetworkInterfaceNames/
依上述的資訊,其版本變更是在 v197
版開始,時間是 2013-01-05 ,對應的 sourcce code 如下:
https://github.com/systemd/systemd/blob/v197/src/udev/udev-builtin-net_id.c
其開頭片段有註解文字如下:
/*
* 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
*
* Two character prefixes based on the type of interface:
* en -- ethernet
* wl -- wlan
* ww -- wwan
*
* Type of names:
* o<index> -- on-board device index number
* s<slot>[f<function>][d<dev_id>] -- hotplug slot index number
* x<MAC> -- MAC address
* p<bus>s<slot>[f<function>][d<dev_id>] -- PCI geographical location
* 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.
*
* 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
*/
以 wlp0s20f3
為例:
wl
開頭表示是 Wireless local area network (WLAN)p0s20f3
則是 PCI geographical locationp0
=> bus=0s20
=> slot=20f3
=> function=3
另一個例子是 enp0s20f0u4
:
en
=> Ethernetp0s20f0
=> PCI geographical locationp0
=> bus=0s20
=> slot=20f0
=> function=0
u4
=> USB port number chain , port=4
那麼,這樣的命名的方式有什麼好處呢?
若依原先的命名方式,網路卡的 interface 名稱是看偵測到卡的順序。
假設電腦插了兩個網路裝置,今天 A 網卡比 B 網卡先偵測到,那兩張的名稱會是 A: eth0
跟 B: eth1
。
但若重開機後,B 網卡先偵測到了,那就會反過來變成 A: eth1
, B: eth0
。
那麼,原先的網路設定,例如: 防卡牆、NetowrkManager Profile、… ,都會因此亂了套。
而驅動程式的載入時間,開機環境的不同,或其他不可預期的硬體異動,都有可能造成上述的狀況。
所以 systemd 所提出的這個可預測的命名方式,能讓網卡在相同的連接埠下,不論偵測順序先後,都得到相同的命名。
Q: 如何改回原本的 interface naming?
最簡單的方式是,在開機 kernel 參數加上:
net.ifnames=0
這個參數雖然是放在 kernel params 的設定,但實際上是由 systemd 去讀取判斷。
細節可參考 man systemd-udevd.service
指令的內容。
另外,有些地方提到也要加上這個 kernel 參數:
biosdevname=0
我爬了一下文,這個參數應該是在下列情況時才會用到:
- 是 DELL 的硬體
- 有安裝
biosdevname
套件
2022-10-15
目前 naming rules 的說明,已不放在 src/udev/udev-builtin-net_id.c
處,而是改放在 man/systemd.net-naming-scheme.xml
檔案。
其變更時間點如下:
- 於
v243
之後生效 - commit
- 2019-05-10
- rev:
0b1e5b6ed8c6b9a2bc53709eb75e381d360f05bf
- github: https://github.com/systemd/systemd/commit/0b1e5b6ed8c6b9a2bc53709eb75e381d360f05bf
在 Linux 系統內可直接執行下述指令查詢格式對照表
man systemd.net-naming-scheme
或是瀏覽網頁如下:
https://www.freedesktop.org/software/systemd/man/systemd.net-naming-scheme.html
2022-10-15
若遇到舊系統,想要切換至新的命名方式,但希望在 reboot 前,能先預測 interface 名稱預先 rename 的話。 可參考下述的討論:
https://github.com/systemd/systemd/issues/23661
內文提到可利用的工具指令如下:
udevadm info -q property /sys/class/net/eth0
udevadm test-builtin net_id /sys/class/net/eth0