NEWS

新闻

了解openKylin最新资讯,关注社区和产品动态。

NEWS

Learn about the latest news.

【干货分享】openKylin系统上udev网卡命名策略

2023-08-29 10:04:09

一、概述

大型计算机通常有多块网卡,有板载集成的,也有插在PCIe插槽的。Linux系统的命名原来是eth0、eth1这样的形式,但是这个编号往往不一定准确对应网卡接口的物理顺序,机器重启后,同一物理位置的网卡可能会获得不同的“eth”编号

在openKylin系统上,我们可以在内核启动参数上加上“net.ifnames=0”选项,跳过udev的重命名过程,此时只是根据内核扫描到的网卡先后顺序进行命名。通过查看网络连接界面,我们可以看到此时网卡命名只是简单的eth0:

openKylin(开放麒麟)


因此,为解决这一问题,systemd和udev引入了一种新的网络设备命名方式:一致网络设备命名(CONSISTENT NETWORK DEVICE NAMING)。根据固件、拓扑、位置信息来设置固定名字,带来的好处是命名自动化,名字完全可预测,这样可以让硬件的更换无缝化。此时,再次查看openKylin上的网络连接界面,可以看到网卡已经按照物理位置进行了命名,为enp4s0:

openKylin(开放麒麟)


systemd的网络设备命名方案为systemd.net-naming-scheme,该方案根据设备的确定接口信息来给网络设备生成属性(udev property,可以通过“udevadm info --query property”命令查询)。这些属性由udev内建(buildin)程序“net_id”生成添加,udev的内建程序“net_setup_link”会根据“
/lib/systemd/network/99-default.link”文件中的“NamePolicy”和“AlternativeNamesPolicy”参数,选择一个可行的命名策略对网卡进行重命名。


二、命名第一步:net_id添加udev属性

查看udev rules文件“
/lib/udev/rules.d/75-net-description.rules”,内容如下:

openKylin(开放麒麟)


当一个udev事件的“SUBSYSTEM”为“net”,且“ACTION”不为“remove”时,会触发内建程序“net_id”的运行。net_id程序会为网络设备添加“ID_NET_NAME_xxxx”类型的属性,这些属性就是“database、onboard、slot、path、mac”中某一命名策略的生成名字。这些属性可以用“udevadm info --query property”命令查询,例如:

openKylin(开放麒麟)


通过命令“udevadm info --query property /sys/class/net/enp4s0”得到了网卡“enp4s0”的所有属性,其中由net_id添加的属性有:

  • ID_NET_NAME_MAC=enx88a4c262c304
  • ID_NET_NAME_PATH=enp4s0

2.1 网卡命名前缀及设备类型

网卡命名规范中,所有名字的前两个字母称为前缀,根据设备类型不同,包含以下五种前缀:

Prefix

Description

en

以太网(Ethernet)

ib

无限带宽(InfiniBand)

sl

串列线路互联网协议(Serial line IP (slip))

wl

无线局域网(Wireless local area network (WLAN))

ww

无限广域网(Wireless wide area network (WWAN))

其中,对于“en、ib、sl”三种设备的判断,通过设备路径下的“type”类型来区分,例如:

openKylin(开放麒麟)


可见本机网卡enp3s0的type为1,type值与设备类型对应如下:

type值

设备类型

1

en

32

ib

256

sl

对于“wl、ww”两种类型,则判断设备属性中的devtype内容来区分,例如:

openKylin(开放麒麟)


其中,DEVTYPE=wlan,因此设备类型为“wl”;同理,当DEVTYPE=wwan时,设备类型为“ww”。

2.2 udev命名属性类型

根据设备类型得到相应的前缀后,再根据不同的命名策略构造相应的网卡名,然后将此命名添加到设备属性,属性类型有如下5种:

属性名

来源

ID_NET_NAME_FROM_DATABASE

来自于udev硬件数据库

ID_NET_NAME_ONBOARD

来自于板载网卡固件

ID_NET_NAME_MAC

来自于网卡的固定MAC地址

ID_NET_NAME_SLOT

来自于可插拔网卡固件

ID_NET_NAME_PATH

来自于网卡的总线位置

  • ID_NET_NAME_FROM_DATABASE由hwdb中获得,不会由“net_id”产生。
  • ID_NET_NAME_ONBOARD由固件提供的板载设备索引号信息合成,字母“o”后面接板载PCI的索引号,字母“d”后面接设备树别名索引号,如“eno1、end1”,板载设备才会有这项属性,比较少见。
  • ID_NET_NAME_MAC由字母“x”后接设备的MAC地址组成,MAC地址记录在设备路径下的“address”文件中,例如:
openKylin(开放麒麟)


  • ID_NET_NAME_SLOT描述设备的插槽位置,根据不同的总线类型会使用不同的引导字母,如“s”后接slot编号,“f”接function编号,“u”接USB端口编号,这些编号都是通过设备路径解析获得的。
  • ID_NET_NAME_PATH描述的是设备的安装位置,常见的格式形如“enp4s0”,这个命名信息也是从设备路径解析获得的。

下面提供一个生成命名的例子。

例1:查询网卡enp4s0属性:

openKylin(开放麒麟)


可知设备路径:


/devices/pci0000:00/0000:00:1c.2/0000:04:00.0/net/enp4s0

父设备子系统为pci,通过names_pci函数解析对设备路径进行处理;

通过字符串处理截取其中的0000:04:00.0,将此字符串格式化输入:

sscanf(sysname, "%x:%x:%x.%u", &domain, &bus, &slot, &func)

得到domain=0、bus=4、slot=0、func=0的值,再将这几个值格式化打印:

strpcpyf(&s, l, "p%us%u", bus, slot)

得到一个字符串“p4s0”,加上前缀,得到“enp4s0”。


三、命名第二步:udev重命名

在2.1节的描述中,rules文件“
/lib/udev/rules.d/75-net-description.rules”首先被触发,内建“net_id”程序会向设备添加“ID_NET_NAME_XXXX”属性,在此规则处理完后,rules文件“/lib/udev/rules.d/80-net-setup-link.rules”会被触发,文件如下:

openKylin(开放麒麟)


根据此rules文件可知,当设备类型为“net”且动作不为“remove”时会触发内建函数“net_setup_link”,此函数会根据udev命名策略选择2.2中“net_id”生成的属性名字添加为新的属性“ID_NET_NAME”,如果NAME为空且属性中的ID_NET_NAME非空,则会触发修改网卡名,NAME修改为ID_NET_NAME。

内建程序“net_setup_link”被触发时,读取命名策略配置文件“
/lib/systemd/network/99-default.link”,查看文件内容如下:

openKylin(开放麒麟)


依据上述配置文件,先执行NamePolicy,再执行AlternativeNamesPolicy。执行时,从前往后开始执行策略,当前一策略执行成功,则后续策略不会再执行。可用命名策略如下:

  • keep:如果网卡已经被用户空间命名(创建新设备时命名或对已有设备重命名), 那么就保留它(不进行重命名操作)。
  • kernel:如果内核 已经为此网卡设置了固定的可预测名称, 那么不进行任何重命名操作。
  • database:基于网卡的 ID_NET_NAME_FROM_DATABASE 属性值设置网卡的名称。
  • onboard:基于网卡的 ID_NET_NAME_ONBOARD 属性值设置网卡的名称。
  • slot:基于网卡的 ID_NET_NAME_SLOT 属性值设置网卡的名称。
  • path:基于网卡的 ID_NET_NAME_PATH 属性值设置网卡的名称。
  • mac:基于网卡的 ID_NET_NAME_MAC 属性值设置网卡的名称。

注:database、onboard、slot、path、mac五种策略只要设备的属性中有相应的ID_NET_NAME_XXXX属性(由第2节net_id生成),就会用这个属性的名字重命名,即可认为执行该策略成功。

MACAddressPolicy描述MAC地址的设置策略,可选的策略有:persistent、random、none。

  • persistent:如果内核使用了网卡硬件固有的MAC地址(绝大多数网卡都有),那么啥也不做,直接使用内核的MAC地址。 否则, 将会随机新生成一个 确保在多次启动之间保持固定不变的MAC地址(针对给定的主板与网卡)。自动生成MAC地址的特性要求网卡必须存在 ID_NET_NAME_* 属性, 否则无法自动生成MAC地址。
  • random:如果内核使用了随机生成的MAC地址(而不是网卡硬件固有的MAC地址), 那么啥也不做,直接使用内核的MAC地址。否则,将在网卡每次出现的时候(一般在启动过程中)随机新生成一个MAC地址。
  • none:无条件的直接使用内核的MAC地址。


四、总结

网络设备事件上来时通常名字为传统命名“ethx”,udev识别到事件子系统为“net”且动作不为“remove”,触发内建程序“net_id”,为设备添加“ID_NET_NAME_XXXX”属性,随后触发内建程序“net_setup_link”,依据配置文件命名策略选择一个“ID_NET_NAME_XXXX”属性添加为新属性“ID_NET_NAME”,然后将这个“ID_NET_NAME”作为网络设备新名字进行重命名操作。至此,网卡重命名操作完成。


五、参考资料

  • https://www.freedesktop.org/software/systemd/man/systemd.link.html#
  • https://www.freedesktop.org/software/systemd/man/systemd.net-naming-scheme.html#
  • https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html/networking_guide/ch-consistent_network_device_naming