Linux网络设备命名规则简介
Linux网络设备命名规则简介
几年前, Linux内核为网络接口分配名称采用的是一种简单和直观的方式:一个固定的前缀和一个递增的序号。比如,内核使用eth0名称以标识启动后第一个加载的网络设备,第二个加载的设备名称是eth1,第三个是eth2,以此类推。。。如果用户想要在系统启动后添加一个新的网卡,那么内核也会按这个规则为它分配新的设备名称。
不过,内核分配的网卡名称有一个隐患:每次系统启动时网络设备的加载顺序是不固定的(多数发生在为系统增加网卡,否则加载顺序基本固定),当系统重启时,内核可能会为因加载顺序为同一个网络设备分配一个与之前不同的名称,原本名称为eth0的网卡,可能经过一次系统重启后就变成了eth1。这样就会对部分涉及到网卡数据采集的应用程序产生影响,因此经开发者们商讨后,决定采用一致性网络设备命名规则。
一致性网络设备命名规则采用udev设备管理器来实现对网络设备的重命名,该方式通过获取网卡的固件、结构、未知等信息,从而固定一张网卡的名称,这样做带来了如下几点好处:
- 设备名称完全可以预测;
- 由于不依赖加载顺序分配名称,不论是添加还是移除设备,设备名称都是固定的,不会被改变;
- 当设备出现故障时,能够无感知地使用新设备代替。
接下来本文将详细介绍该网络设备命名规则。
基础概念
udev
udev是Linux上的一种设备管理器,它用于在设备发生事件时,管理设备文件的权限,或者在/dev目录下创建额外的软链接,也可以重命名网络设备。内核往往通过设备发现顺序来分配无法预测的设备名称,而udev则基于设备属性或配置生成软链接或网络设备名称,提供了识别这些设备的可靠方式。
systemd-udevd.service是udev的守护进程,它会直接从内核监听设备的事件,包括添加、移除、状态改变。当udev获取到一个设备事件时,它会从一系列的规则文件中读取匹配到的规则,并应用对应的动作,比如说保存额外信息到udev数据库中,或者创建设备软链接等等。
所有udev处理的设备信息都会保存到udev数据库中,这些数据可以通过libudev库访问,也可以通过udevadm info <devpath>命令读取。
更多udev的信息,比方说udev规则文件的语法,可以通过man udev命令查看。
一些常用的udev命令:
# 获取udev数据库中记录的指定设备信息
# udevadm info /sys/class/net/eno1
P: /devices/pci0000:00/0000:00:1c.4/0000:09:00.0/net/eno1
E: DEVPATH=/devices/pci0000:00/0000:00:1c.4/0000:09:00.0/net/eno1
...
E: INTERFACE=eno1
E: SUBSYSTEM=net
# 调试指定设备的添加/移除事件
# udevadm test -a add /sys/class/net/eno1
calling: test
version 239 (239-76.el8)
...
Unload module index
Unloaded link configuration context.
# 调试udev内置程序
# udevadm test-builtin net_setup_link /sys/class/net/eno1
calling: test-builtin
Load module index
...
Unload module index
Unloaded link configuration context.
udev在执行规则文件时,会事先添加一些基本的环境变量,主要如下:
DEVPATH=/devices/pci0000:00/0000:00:1c.4/0000:09:00.0/net/eno1
INTERFACE=eno1
IFINDEX=2
ACTION=add
SUBSYSTEM=net
LC_CTYPE=C.UTF-8
一致性网络设备命名规则
当启用一致性网络设备命名规则时,udev设备管理器会根据一系列的规范来创建设备的名称,根据网络设备的类型,设备名称会以如下规则生成一个两字母前缀:
en表示以太网设备wl表示无线局域网设备(WLAN)ww表示无线广域网设备(WWAN)
接着,udev会根据如下格式为以生成的网络设备名称后追加内容:
- 板载设备:
o<板载索引号> - PCIe设备:
s<PCIe热插拔索引号>[f<function号>][d<device号>] - 其他PCI设备:
[P<PCI域位置>]p<bus号>s<slot号>[f<function号>][d<device号>] - 有MAC地址的设备:
x<MAC地址> - USB设备:
[P<PCI域位置>]p<bus号>s<slot号>[f<function号>][u<usb端口>][…][c<config>][i<interface>]
原理
一致性网络设备命名规则采用udev来实现对网络设备的重命名,因此重命名的规则也都记录在udev的配置文件中,udev使用如下的顺序处理网络设备命名规则。
/usr/lib/udev/rules.d/60-net.rules
60-net.rules的作用是通过网络接口配置文件更改网络设备命名,它获取匹配网络设备MAC地址的配置文件,并将该配置文件中的设备名作为新设备名。
文件内容如下,当添加设备时,对于net子系统中任意非空设备驱动且type属性为1的设备,执行/lib/udev/rename_device程序,如果程序输出不为空,那么将设备名设置为程序输出。
ACTION=="add", SUBSYSTEM=="net", DRIVERS=="?*", ATTR{type}=="1", PROGRAM="/lib/udev/rename_device", RESULT=="?*", NAME="$result"
/lib/udev/rename_device是一个协助处理程序,它从INTERFACE环境变量中读取网络设备名称,随后通过/sys/class/net/%s/address获取MAC地址,如果/etc/sysconfig/network-scripts/ifcfg-*中有文件的HWADDR参数匹配到对应MAC地址,那么将输出该文件中DEVICE参数的值,否则输出空。
/usr/lib/udev/rules.d/71-biosdevname.rules
71-biosdevname.rules一般在需额外安装的biosdevname软件包中,该规则的作用是通过从bios获取的设备文件名更改网络设备命名,它只会在biosdevname内核参数为1时才生效。
文件内容如下,当添加设备时,对于net子系统中任意名称为空(未重命名过),type属性为1且DEVTYPE环境变量为空的设备,如果biosdevname内核参数为1,那么执行/sbin/biosdevname --smbios 2.6 --nopirq --policy physical -i %k程序(%k是设备的内核名称),将其输出作为新名称。
SUBSYSTEM!="net", GOTO="netdevicename_end"
ACTION!="add", GOTO="netdevicename_end"
NAME=="?*", GOTO="netdevicename_end"
ATTR{type}!="1", GOTO="netdevicename_end"
ENV{DEVTYPE}=="?*", GOTO="netdevicename_end"
# kernel command line "biosdevname={0|1}" can turn off/on biosdevname
IMPORT{cmdline}="biosdevname"
ENV{biosdevname}=="?*", ENV{UDEV_BIOSDEVNAME}="$env{biosdevname}"
# ENV{UDEV_BIOSDEVNAME} can be used for blacklist/whitelist
# but will be overwritten by the kernel command line argument
ENV{UDEV_BIOSDEVNAME}=="0", GOTO="netdevicename_end"
ENV{UDEV_BIOSDEVNAME}=="1", GOTO="netdevicename_start"
# off by default
GOTO="netdevicename_end"
LABEL="netdevicename_start"
# using NAME= instead of setting INTERFACE_NAME, so that persistent
# names aren't generated for these devices, they are "named" on each boot.
SUBSYSTEMS=="pci", PROGRAM="/sbin/biosdevname --smbios 2.6 --nopirq --policy physical -i %k", NAME="%c" OPTIONS+="string_escape=replace"
LABEL="netdevicename_end"
/usr/lib/udev/rules.d/75-net-description.rules
75-net-description.rules的作用是通过一些udev内置程序获取网络设备的信息并设置为环境变量,用于后续步骤。
文件内容如下,当添加网络设备时,调用net_id内置程序获取设备信息并设置内部环境变量,对于usb类型的网络设备,调用usb_id以及hwdb内置程序获取设备信息并设置内部环境变量,对于pci类型的网络设备,根据一些内核中的设备属性以及hwdb内置程序设置内部环境变量。
ACTION=="remove", GOTO="net_end"
SUBSYSTEM!="net", GOTO="net_end"
IMPORT{builtin}="net_id"
# ID_NET_NAMING_SCHEME=rhel-8.0
# ID_NET_NAME_MAC=enxac1f6b848502
# ID_OUI_FROM_DATABASE=Super Micro Computer, Inc.
# ID_NET_NAME_ONBOARD=eno1
# ID_NET_LABEL_ONBOARD=enIntel Ethernet I350AM2 #1
# ID_NET_NAME_PATH=enp9s0f0
SUBSYSTEMS=="usb", IMPORT{builtin}="usb_id", IMPORT{builtin}="hwdb --subsystem=usb"
SUBSYSTEMS=="usb", GOTO="net_end"
SUBSYSTEMS=="pci", ENV{ID_BUS}="pci", ENV{ID_VENDOR_ID}="$attr{vendor}", ENV{ID_MODEL_ID}="$attr{device}"
# ID_BUS=pci
# ID_VENDOR_ID=0x8086
# ID_MODEL_ID=0x1521
SUBSYSTEMS=="pci", IMPORT{builtin}="hwdb --subsystem=pci"
# ID_PCI_CLASS_FROM_DATABASE=Network controller
# ID_PCI_SUBCLASS_FROM_DATABASE=Ethernet controller
# ID_VENDOR_FROM_DATABASE=Intel Corporation
# ID_MODEL_FROM_DATABASE=I350 Gigabit Network Connection
LABEL="net_end"
/usr/lib/udev/rules.d/80-net-setup-link.rules
80-net-setup-link.rules的作用是通过一些udev内置程序获取网络设备的信息并设置为环境变量,用于后续步骤。
文件内容如下,当添加网络设备时,调用path_id内置程序获取设备信息,随后调用net_setup_link内置程序,如果先前没有重命名设备,且内置程序输出的ID_NET_NAME环境变量不为空,那么将该环境变量的值设置为新设备名称。
SUBSYSTEM!="net", GOTO="net_setup_link_end"
IMPORT{builtin}="path_id"
# ID_PATH=pci-0000:09:00.0
# ID_PATH_TAG=pci-0000_09_00_0
ACTION!="add", GOTO="net_setup_link_end"
IMPORT{builtin}="net_setup_link"
# ID_NET_DRIVER=igb
# ID_NET_LINK_FILE=/usr/lib/systemd/network/99-default.link
# ID_NET_NAME=eno1
NAME=="", ENV{ID_NET_NAME}!="", NAME="$env{ID_NET_NAME}"
LABEL="net_setup_link_end"
net_setup_link内置程序会读取/usr/lib/systemd/network/99-default.link配置文件,从而决定最后网络设备应该使用的名称:
[Link]
NamePolicy=kernel database onboard slot path
AlternativeNamesPolicy=database onboard slot path
MACAddressPolicy=persistent
该文件的NamePolicy参数标记了网络设备命名的优先级顺序:内核名称 > udev硬件数据库中记录名称 > onboard名称(ID_NET_NAME_ONBOARD, eno) > slot名称(ID_NET_NAME_SLOT, ens) > path名称(ID_NET_NAME_PATH, enp)。
另外,AlternativeNamesPolicy则记录了网络设备的别名,如果有该配置项,那么应用程序也可以通过别名来访问网络设备。
应用场景
换回原先网络设备命名规则
如果想要换回原先的网络设备命名规则,即ethN命名,需要在内核参数中添加net.ifnames=0以及biosdevname=0参数。
可以在grub引导程序中修改,在/etc/default/grub中的GRUB_CMDLINE_LINUX参数中追加,并通过grub2-mkconfig -o /boot/grub2/grub.cfg命令生成新grub配置文件,重启系统后生效。
除此之外,可能还要修改/etc/sysconfig/network-scripts/ifcfg-*网卡配置文件中的DEVICE参数,防止重启后出现网卡无法拉起或者网络设备名称换回失败的情况。
基于MAC地址固定网络设备名称
通过udev设备管理器,我们可以很方便的更改以及定制网络设备命名规则,比如如果想要基于MAC地址固定某个网络设备的名称,那么可以创建/etc/udev/rules.d70-fix-eno2.rules文件,内容如下:
SUBSYSTEM=="net",ACTION=="add",ATTR{address}=="ac:1f:6b:84:85:03",ATTR{type}=="1",NAME="myfixif"
其中ATTR{address}表示MAC地址,ATTR{type}=="1"表示是Ethernet类型。
修改后重启生效。
参考文档
Linux┊详解udev - 无双的小宝 - 博客园 (cnblogs.com)
udev(7) - Linux manual page (man7.org)
Linux网络设备命名规则简介的更多相关文章
- 《linux就该这么学》第七节课:文件的各种权限以及linux分区命名规则
笔记 (借鉴请改动) 5.3:文件特殊权限 SUID 临时拥有文件所有者的权限(基本上只是执行权限) SGID 临时拥有文件所有组的权限,在目录中创建文件自动继承该目录的用户组. SBIT 粘滞 ...
- Cisco网络设备命名规则
1. CISCO 开头的产品都是路由器:2. RSP 开头的都是CISCO7500 系列产品的引擎:3. VIP 开头的产品都是CISCO 7500系列产品的多功能接口处理器模块:4. PA 开头 ...
- Linux网卡命名规则
网卡命名 一.为什么需要这个 服务器通常有多块网卡,有板载集成的,同时也有插在PCIe插槽的.Linux系统的命名原来是eth0,eth1这样的形式,但是这个编号往往不一定准确对应网卡接口的 ...
- Linux文件命名规则
Linux目录结构命名规定 几乎所有的Linux版本都会遵循FHS(Filesystem Hierarchy Standard),中文翻译过来即为文件系统层次化标准.类似于Windows操作系统中c盘 ...
- Linux网络端口命名规则,一致性网络设备命名
参考文档: https://www.cnblogs.com/pipci/p/9229571.html 一致性网络设备命名,即Consistent Network Device Naming. 一.服务 ...
- linux 文件权限、类型、命名规则
文件权限 -rwxr-x--t 文件类型 用户权限 组权限 其他用户权限 umask是一个掩码,设置文件的默认权限,会屏蔽掉不想授予该安全级别的权限,从对象的全权权限中减掉:对文件全权权 ...
- 常见linux系统中RPM包的通用命名规则
本文重点说一下在常见的linux系统中,RPM包通用的命名规则. RPM包的一般格式为:name-version-arch.rpmname-version-arch.src.rpm 例:httpd-2 ...
- linux 软件包的命名规则
linux软件包的命名规则 eg:主包 bind-9.7.1-1.el7.i586.rpm 子包 bind-libs-9.7.1-1.el7.i586.rpm bind-utils-9. ...
- linux初级学习笔记二:linux操作系统及常用命令,文件的创建与删除和命名规则,命令行展开以及linux中部分目录的作用!(视频序号:02_3)
本节学习的命令:tree,mkdir,rmdir,touch,stat,rm 本节学习的技能:Linux中主要的目录作用以及特殊的目录文件: 文件的命名规则,命令行展开: 文件的创建与删除: Linu ...
- Linux发行版的系统目录名称命名规则以及用途
linux各种发行版都遵循LSB(Linux Stadards Base)规则,使用一致的相关的基础目录名称,使用根目录系统结构(root filesystem),使用FHS(Files Hierar ...
随机推荐
- Java Heap
堆 堆是一种基于树的数据结构,是一种完全二叉树,堆中的所有的节点都按照特定的顺序排列. 在堆数据结构中,如果任意父节点的值都大于其子节点,则会产生一个大顶堆:反之,如果任意父节点的值都小于其子节点,则 ...
- STM32新建模板【HAL库】
看到这篇笔记的小伙伴可能会觉得我在做无用功,明明可以通过 STM32CubeMx 软件直接生成的,还在这里慢慢的创建项目.我觉得在学习的时候最好少借助工具,当我们过度依赖工具的时候,决绝问题的能力可能 ...
- 逍遥自在学C语言 | 位运算符^的高级用法
前言 在上一篇文章中,我们介绍了|运算符的高级用法,本篇文章,我们将介绍^ 运算符的一些高级用法. 一.人物简介 第一位闪亮登场,有请今后会一直教我们C语言的老师 -- 自在. 第二位上场的是和我们一 ...
- linux下的一道堆上的格式化字符串漏洞题分析分享
简单分享一下解题过程. 下载题目,里面有三个文件,如图: DockerFIle文件: net.sh文件: shell文件是一个elf,文件情况: 64位,Full RELO,NX,PIE 丢进IDA看 ...
- 无法使用Resource注解
问题描述: 学习Spring框架的时候,发现无法使用@Resource注解,只能使用@Autowired注解. 问题原因: JDK11删除了javax.annotation包,需要导入,否则无法使用@ ...
- Java学习笔记08
1. static关键字 static可以用来修饰的成员变量和成员方法,被static修饰的成员是属于类的是放在静态区中,没有static修饰的成员变量和方法则是属于对象的. 1.1 静态变量 ...
- day06-优惠券秒杀02
功能03-优惠券秒杀02 4.功能03-优惠券秒杀 4.4一人一单 4.4.1需求分析 要求:修改秒杀业务,要求同一个优惠券,一个用户只能下一单. 在之前的做法中,加入一个对用户id和优惠券id的判断 ...
- rockyLinux 初体验(教程)PostgreSQL15
目录 数据库软件 PostgreSQL 安装 数据库软件 PostgreSQL 配置 数据库软件 PostgreSQL 交互 通用数据库管理软件 DBeaver 彼时,PostgreSQL 已经更新到 ...
- Centos7.x 安装jenkins
一.安装 前提:需查看是否安装了JDK 1.第一种方法 sudo wget -O /etc/yum.repos.d/jenkins.repo https://pkg.jenkins.io/redhat ...
- 2022-10-16:以下go语言代码输出什么?A:timed out;B:panic;C:没有任何输出。 package main import ( “context“ “fmt“
2022-10-16:以下go语言代码输出什么?A:timed out:B:panic:C:没有任何输出. package main import ( "context" &quo ...