Linux网络设备命名规则简介

几年前, Linux内核为网络接口分配名称采用的是一种简单和直观的方式:一个固定的前缀和一个递增的序号。比如,内核使用eth0名称以标识启动后第一个加载的网络设备,第二个加载的设备名称是eth1,第三个是eth2,以此类推。。。如果用户想要在系统启动后添加一个新的网卡,那么内核也会按这个规则为它分配新的设备名称。

不过,内核分配的网卡名称有一个隐患:每次系统启动时网络设备的加载顺序是不固定的(多数发生在为系统增加网卡,否则加载顺序基本固定),当系统重启时,内核可能会为因加载顺序为同一个网络设备分配一个与之前不同的名称,原本名称为eth0的网卡,可能经过一次系统重启后就变成了eth1。这样就会对部分涉及到网卡数据采集的应用程序产生影响,因此经开发者们商讨后,决定采用一致性网络设备命名规则。

一致性网络设备命名规则采用udev设备管理器来实现对网络设备的重命名,该方式通过获取网卡的固件、结构、未知等信息,从而固定一张网卡的名称,这样做带来了如下几点好处:

  1. 设备名称完全可以预测;
  2. 由于不依赖加载顺序分配名称,不论是添加还是移除设备,设备名称都是固定的,不会被改变;
  3. 当设备出现故障时,能够无感知地使用新设备代替。

接下来本文将详细介绍该网络设备命名规则。

基础概念

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类型。

修改后重启生效。

参考文档

Chapter 1. Consistent network interface device naming Red Hat Enterprise Linux 8 | Red Hat Customer Portal

Linux┊详解udev - 无双的小宝 - 博客园 (cnblogs.com)

udev(7) - Linux manual page (man7.org)

Linux网络设备命名规则简介的更多相关文章

  1. 《linux就该这么学》第七节课:文件的各种权限以及linux分区命名规则

    笔记 (借鉴请改动) 5.3:文件特殊权限 SUID  临时拥有文件所有者的权限(基本上只是执行权限) SGID  临时拥有文件所有组的权限,在目录中创建文件自动继承该目录的用户组. SBIT  粘滞 ...

  2. Cisco网络设备命名规则

      1. CISCO 开头的产品都是路由器:2. RSP 开头的都是CISCO7500 系列产品的引擎:3. VIP 开头的产品都是CISCO 7500系列产品的多功能接口处理器模块:4. PA 开头 ...

  3. Linux网卡命名规则

    网卡命名 一.为什么需要这个      服务器通常有多块网卡,有板载集成的,同时也有插在PCIe插槽的.Linux系统的命名原来是eth0,eth1这样的形式,但是这个编号往往不一定准确对应网卡接口的 ...

  4. Linux文件命名规则

    Linux目录结构命名规定 几乎所有的Linux版本都会遵循FHS(Filesystem Hierarchy Standard),中文翻译过来即为文件系统层次化标准.类似于Windows操作系统中c盘 ...

  5. Linux网络端口命名规则,一致性网络设备命名

    参考文档: https://www.cnblogs.com/pipci/p/9229571.html 一致性网络设备命名,即Consistent Network Device Naming. 一.服务 ...

  6. linux 文件权限、类型、命名规则

    文件权限 -rwxr-x--t        文件类型 用户权限 组权限 其他用户权限 umask是一个掩码,设置文件的默认权限,会屏蔽掉不想授予该安全级别的权限,从对象的全权权限中减掉:对文件全权权 ...

  7. 常见linux系统中RPM包的通用命名规则

    本文重点说一下在常见的linux系统中,RPM包通用的命名规则. RPM包的一般格式为:name-version-arch.rpmname-version-arch.src.rpm 例:httpd-2 ...

  8. linux 软件包的命名规则

     linux软件包的命名规则 eg:主包       bind-9.7.1-1.el7.i586.rpm 子包 bind-libs-9.7.1-1.el7.i586.rpm bind-utils-9. ...

  9. linux初级学习笔记二:linux操作系统及常用命令,文件的创建与删除和命名规则,命令行展开以及linux中部分目录的作用!(视频序号:02_3)

    本节学习的命令:tree,mkdir,rmdir,touch,stat,rm 本节学习的技能:Linux中主要的目录作用以及特殊的目录文件: 文件的命名规则,命令行展开: 文件的创建与删除: Linu ...

  10. Linux发行版的系统目录名称命名规则以及用途

    linux各种发行版都遵循LSB(Linux Stadards Base)规则,使用一致的相关的基础目录名称,使用根目录系统结构(root filesystem),使用FHS(Files Hierar ...

随机推荐

  1. Linux进程管理(命令)入门

    进程是一个运行中的程序 进程查看 ps 能够查看当前终端下运行的进程 $ ps PID TTY TIME CMD 26305 pts/0 00:00:00 bash 26312 pts/0 00:00 ...

  2. 测试环境治理之MYSQL索引优化篇

    作者:京东物流 李光新 1 治理背景 测试环境这个话题对于开发和测试同学一定不陌生,大家几乎每天都会接触.但是说到对测试环境的印象,却鲜有好评: •环境不稳定,测试五分钟,排查两小时 •基础建设不全, ...

  3. Scanner对象的用法

    Java流程控制 想要实现程序与人的交互,我们必须使用Java给我们提供的工具类.就像我最开始写的一篇博客,用Java提供给我们的一个机器人类Robot是控制鼠标键盘的.今天我们学习的是一个可以获取用 ...

  4. elastic-job源码(1)- job自动装配

    版本:3.1.0-SNAPSHOT git地址:https://github.com/apache/shardingsphere-elasticjob   Maven 坐标 <dependenc ...

  5. 深度学习-08(PaddlePaddle文本分类)

    深度学习-08(PaddlePaddle文本分类) 文章目录 深度学习-08(PaddlePaddle文本分类) NLP概述 NLP基本概念 什么是NLP NLP的主要任务 传统NLP方法 传统NLP ...

  6. 【易车网实例】x-sign逆向保姆级教程

    易车号x-sign逆向 前言 许多网站都有反爬机制,x-sign加密就是许多反爬虫机制的其中一种,本次将以易车号作为目标进行演示. 方法仅供学习参考. 链接:https://hao.yiche.com ...

  7. 2022-02-17:寻找最近的回文数。 给定一个表示整数的字符串 n ,返回与它最近的回文整数(不包括自身)。如果不止一个,返回较小的那个。 “最近的”定义为两个整数差的绝对值最小。 示例 1: 输

    2022-02-17:寻找最近的回文数. 给定一个表示整数的字符串 n ,返回与它最近的回文整数(不包括自身).如果不止一个,返回较小的那个. "最近的"定义为两个整数差的绝对值最 ...

  8. Django中多个app放置同一文件夹中

    在pycharm中新建一个管理app的python package目录:apps 将存在的app用拖拽到apps目录下,此时会弹出对话框,取消勾选Search for references(搜索索引) ...

  9. 解决:django.db.utils.OperationalError: no such table: auth_user

    解决:django.db.utils.OperationalError: no such table: auth_user 我们在创建Django项目的时候已经创建这个表了,表一般都保存在轻量级数据库 ...

  10. 《啊哈C语言——逻辑的挑战》学习笔记

    第一章 梦想启航 第1节 让计算机开口说话 1.基础知识 1)计算机"说话"的两种方式 显示在屏幕上 通过喇叭发出声音 2)计算机"说话"之显示在屏幕上 格式: ...