1. 背景

服务器通常有多块网卡,有板载集成的,同时也有插在PCIe插槽的.

Linux系统的命名原来是eth0,eth1这样的形式,但是这个编号往往不一定准确对应网卡接口的物理顺序.

为解决这类问题,dell开发了biosdevname方案.

systemd v197版本中将dell的方案作了进一步的一般化拓展.

linux内核启动过程中,会默认给网卡以ethX方式随机命名,然后再通过systemd去rename成其他名称.

2. rename流程

step1 依据/usr/lib/udev/rules.d/60-net.rules, 查看是否有ifcfg-xx配置文件(路径在/etc/sysconfig/network-scripts/),
是否有定义了指定MAC地址的配置文件(ifcfg-xx ,xx必须和配置文件的内容DEVICE一致),如果有,则命名改网卡;

step2 依据/usr/lib/udev/rules.d/71-biosdevname.rules,如果biosdevname使能了(安装了biosdevname这个包,且内核启动参数显式设置为1),
且网卡没有在step1中定义,则按照biosdevname命名规则rename网卡;(注意,如果没有安装biosdevname这个包,就没有这个文件)

step3, 依据/lib/udev/rules.d/75-net-description.rules,将udev工具会根据device属性将填写网卡的属性命名,可能一个网卡会有多个维度的名称;

step4,udev 根据step3中的赋值,按照指定的scheme规则,去给在step1 step2中没有命名的网卡命名;

强调:这个step顺序是在我们没有自定义自己的rules的前提下,如果用户自定义了自己的rules,则用户自定义为优先级最高

3. 命令策略(scheme规则)

1.如果从BIOS中能够取到可用的,板载网卡的索引号,则使用这个索引号命名,例如: eno1,如不能则尝试2
2.如果从BIOS中能够取到可以用的,网卡所在的PCI-E热插拔插槽(注:pci槽位号)的索引号,则使用这个索引号命名,例如: ens1,如不能则尝试3
3.如果能拿到设备所连接的物理位置(PCI总线号+槽位号?)信息,则使用这个信息命名,例如:enp2s0,如不能则尝试4
4.传统的kernel命名方法,例如: eth0,这种命名方法的结果不可预知的,即可能第二块网卡对应eth0,第一块网卡对应eth1
5.使用网卡的MAC地址来命名,这个方法一般不使用

同一个网卡通常同时具有多个维度的名称,systemd在选取的时候,按照有先后次序,使用先命中的
顺序可以简单理解为(eno1-ens1-enp1)

root@Bai5gc:/sys/class/net/eth1# udevadm info /sys/class/net/eth1
P: /devices/pci0000:00/0000:00:02.2/0000:03:00.0/net/eth1
E: DEVPATH=/devices/pci0000:00/0000:00:02.2/0000:03:00.0/net/eth1
E: ID_BUS=pci
E: ID_MODEL_FROM_DATABASE=Ethernet Connection X552 10 GbE Backplane
E: ID_MODEL_ID=0x15ab
E: ID_NET_DRIVER=ixgbe
E: ID_NET_LINK_FILE=/lib/systemd/network/99-default.link
E: ID_NET_NAME_MAC=enxb4a9fca897e7
E: ID_NET_NAME_ONBOARD=eno3
E: ID_NET_NAME_PATH=enp3s0f0
E: ID_PATH=pci-0000:03:00.0
E: ID_PATH_TAG=pci-0000_03_00_0
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=3
E: INTERFACE=eth1
E: SUBSYSTEM=net
E: SYSTEMD_ALIAS=/sys/subsystem/net/devices/eth1
E: TAGS=:systemd:
E: USEC_INITIALIZED=5061037
E: net.ifnames=0

#udevadm info --query=path --path=/sys/class/net/eth1/ --attribute-walk

4. 自定义网卡名称

1.在用户没有自定义rules文件前提下,step1中的网卡命名方式也可认为是一种用户自定义的网卡命名,
即在/etc/sysconfig/network-scripts/ifcfg-xx 文件,xx就是这个网卡名称,文件内容中体现MAC_ADDRESS、NAME,
这种情况下,则会按照配置文件中指定的名称来命名网卡

2.如果用户自定义了rules文件,放在/etc/udev/rules.d/目录下,则这个优先级是最高的;
比1中ifcfg-xx方式优先级更高,但是如果两者不一致,则在重启network服务时,会依据ifcfg-xx,
所以用户不应该同时采用里两种方式给同一个网卡命不同的名称

5. biosdevname和net.ifnames两种命名规范

net.ifnames的命名规范为:设备类型+设备位置+数字

设备类型:

en 表示Ethernet

wl 表示WLAN

ww 表示无线广域网WWAN

实际的例子:

eno1 板载网卡

enp0s2  pci网卡

ens33   pci网卡

wlp3s0  PCI无线网卡

wwp0s29f7u2i2   4G modem

wlp0s2f1u4u1   连接在USB Hub上的无线网卡

enx78e7d1ea46da pci网卡


biosdevname的命名规范为: 要么是em开头,要么是p开头

实际的例子:

em1 板载网卡

p3p4 pci网卡

p3p4_1 虚拟网卡

6. 内核启动参数biosdevname/net.ifnames

默认就是内核启动参数没有biosdevname也没有net.ifnames参数(其实默认是net.ifnames=1,biosdevname=0) 这种情况下就按照上述进行网卡命名;eno-ens-enp的方式逐个匹配。但是如果使能了biosdevname.则会使用biosdevname的命名 step1没有命名的网卡

怎么样使能biosdevname呢?2个条件,安装biosdevname包,且在内核启动参数中明确 biosdevname=1. 否则使能不了

如果在启动参数中增加net.ifname=0,这个文件会在/lib/udev/rule.d/80-net-name-slot.rules体现使用价值,则告诉系统不用scheme的方式来命名,这个时候,会恢复ethx这种不确定性的命名方式

修改内核参数

1.修改grub文件
vim /etc/default/grub
GRUB_CMDLINE_LINUX="net.ifnames=0 biosdevname=0"

2.重新生成grub引导配置文件
grub-mkconfig -o /boot/grub/grub.cfg

3.reboot