Linux网卡命名规则

内核态默认网卡命名规则

基本流程:

1、首先内核发现网卡设备,去调用设备probe函数去完成接下来的操作;

2、网卡初始化操作:网卡驱动会默认提供一个eth%d的名称供该网口使用,然后调用内核接口register_netdev函数

3、register_netdev流程中,会根据系统中已有的接口情况,找出一个最小的还没有使用的数字编号,分给新注册的网卡。比如,系统中当前有,eth0, eth2, eth3三块网卡。那么新注册的网卡,名字就是eth1了。

strcpy(netdev->name, "eth%d");//此时net_device结构体中的name成员为(eth%d)
err = register_netdev(netdev);

register_netdev() 会调用 dev_get_valid_name(),判断 netdev->name 含有转义字符 %d,因此动态地分配了 index number 用于唯一标识这个网卡。

Note: 若 netdev->name 无转义字符 %d,则其值即为网卡名称,不会动态地分配 index number,此设备也只能存在一个该类型的网卡。

register_netdev函数如何找到合适的%d数值并赋值给新注册的网卡?

最终会调用dev_get_valid_name函数分配完整的设备名称。内核最终调用__dev_alloc_name确定设备的名称。内核可支持的设备数量最大为8*PAGE_SIZE,即一个页面的大小的比特数量(通常为8 * 4K=32k个设备总是)。每一位代表一个设备。当前需要做的就是,在net命名空间中,遍历所有的设备名称,将其索引值在一个空白页面中的应用位置置位。遍历完成之后,只需要在页面中查找第一个未置位的位,作为新设备的索引值。将其替换name格式字符串中的%d,赋值于buf保存新的设备名称。

内核默认命名规则的局限性:

往往不一定准确对应网卡接口的物理顺序,而且每次启动只根据内核发现网卡的顺序进行命名,因此并不固定;所以目前一般情况下会在用户态启用其他的方式去更改网卡名称,原则就是在内核命名ethx后将其在根据用户态的规则rename为其他的名字,这种规则往往是根据网卡的Mac地址以及其他能够唯一代表一块网卡的参数去命名,因此会一一对应;

用户态网卡重命名规则

一致性网络设备命名规范

CentOS 7提供了在网络接口中使用一致且可预期的网络设备命名方法, 目前默认使用的是net.ifnames规则。

  • 1、/usr/lib/udev/rules.d/60-net.rules 文件中的规则会让 udev 帮助工具/lib/udev/rename_device 查看所有 /etc/sysconfig/network-scripts/ifcfg-suffix 文
    件。如果发现包含 HWADDR 条目的 ifcfg 文件与某个接口的 MAC 地址匹配,它会将该接口重命名为ifcfg 文件中由 DEVICE 指令给出的名称。

    rename条件:如果网卡的ifconfig文件中未加入HWADDR,则rename脚本并不会根据配置文件去重命名网卡;

ACTION=="add", SUBSYSTEM=="net", DRIVERS=="?*", ATTR{type}=="1", PROGRAM="/lib/udev/rename_device", RESULT=="?*", NAME="$result"
  • 2、/usr/lib/udev/rules.d/71-biosdevname.rules 中的规则让 biosdevname 根据其命名策略重命名该接口,即在上一步中没有重命名该接口、安装biosdevname、且在 boot 命令行中将biosdevname=0 作为内核命令给出。(bisodevname规则,从CentOS 7 开始默认不使用,所以该条规则在不配置的情况下失效,直接去执行3;默认在cmdline中bisodevname=0,如果需要启用,则需要设置bisodevname=1)

  • 3、/lib/udev/rules.d/75-net-description.rules 中的规则让 udev 通过检查网络接口设备,填写内部 udev 设备属性值 ID_NET_NAME_ONBOARD、ID_NET_NAME_SLOT、ID_NET_NAME_PATH、ID_NET_NAME_MAC。注:有些设备属性可能处于未定义状态。

    运行了这条规则之后,会将ID_NET_NAME_ONBOARD、ID_NET_NAME_SLOT、ID_NET_NAME_PATH、ID_NET_NAME_MAC等属性值设置完成,可使用udevadm info查看,待后续规则取用;

#/lib/udev/rules.d/75-net-description.rules
ACTION=="remove", GOTO="net_end"
SUBSYSTEM!="net", GOTO="net_end"
IMPORT{builtin}="net_id"
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}"
SUBSYSTEMS=="pci", IMPORT{builtin}="hwdb --subsystem=pci"
LABEL="net_end"
#通过udevadm info查询网口信息如下:
#会提前将所有的命名规则名字均定义好,然后在根据不同的规则去取;如下的信息是在规则75-net-de中去配置好的
#已这个网卡为例,会设置好ID_NET_NAME_SLOT、ID_NET_NAME_PATH、ID_NET_NAME_MAC属性值,这里ID_NET_NAME_ONBOARD值缺失;
P: /devices/pci0000:17/0000:17:02.0/0000:19:00.0/net/ens3f0
E: DEVPATH=/devices/pci0000:17/0000:17:02.0/0000:19:00.0/net/ens3f0
E: ID_NET_DRIVER=ixgbe
E: ID_NET_NAME_MAC=enx7057bff9f52c
E: ID_NET_NAME_PATH=enp25s0f0
E: ID_NET_NAME_SLOT=ens3f0
E: INTERFACE=ens3f0
E: SUBSYSTEM=net
E: SYSTEMD_ALIAS=/sys/subsystem/net/devices/ens3f0
  • 4、/usr/lib/udev/rules.d/80-net-name-slot.rules 中的规则让 udev 重命名该接口,优先顺序如下:ID_NET_NAME_ONBOARD、ID_NET_NAME_SLOT、ID_NET_NAME_PATH。并提供如下信息:没有在步骤 1 或 2 中重命名该接口,同时未给出内核参数 net.ifnames=0。如果一个参数未设定,则会按列表的顺序设定下一个。如果没有设定任何参数,则不会重命名该接口;
#/usr/lib/udev/rules.d/80-net-name-slot.rules
#按照ID_NET_NAME_ONBOARD、ID_NET_NAME_SLOT、ID_NET_NAME_PATH的顺序依次寻找,如果找到ID_NET_NAME_ONBOARD即用其命名;已上面的网卡信息为例,缺失ID_NET_NAME_ONBOARD属性,依照顺序找到ID_NET_NAME_SLOT=ens3f0,则最终网卡名字命名为ens3f0;
#同时可以将其他的属性值加入到规则中,例如ID_NET_NAME_MAC(默认不会使用该属性值)。或者自己更改优先顺序;
IMPORT{cmdline}="net.ifnames"//net.ifnames命名规则,默认为1,可在cmdline中取配置是否使用该规则,若配置为net.ifnames=0,则不执行该规则;
ENV{net.ifnames}=="0", GOTO="net_name_slot_end"
NAME=="", ENV{ID_NET_NAME_ONBOARD}!="", NAME="$env{ID_NET_NAME_ONBOARD}"#on-board板载网卡
NAME=="", ENV{ID_NET_NAME_SLOT}!="", NAME="$env{ID_NET_NAME_SLOT}"
NAME=="", ENV{ID_NET_NAME_PATH}!="", NAME="$env{ID_NET_NAME_PATH}"

net.ifnames命名规范

格式描述
o板载设备索引号
s【f】【d<dev_port>】热插拔插槽索引号
xMAC 地址
ps【f】【d<dev_port>】【d<dev_id>】
  • 所有多功能 PCI 设备都在其设备名称中包含 [f] 号,其中包括 function 0 设备。

    具体命名函数为:systemd源码函数dev_pci_slot

    “%x:%x:%x.%u”, &domain, &bus, &slot, &func 0000:19:00.1

    address:0000:19:00

例如ens3f1是如何识别的:

根据address去遍历/sys/bus/pci/slots寻找该设备的slots号,

[root@localhost slots]# ls
1  10  2  3  9
[root@localhost ~]# ls /sys/bus/pci/slots/3/
address  cur_bus_speed  max_bus_speed
[root@localhost ~]# cat /sys/bus/pci/slots/3/address
0000:19:00

那么就能确定该网卡的slots为3,同时func为1,因此命名为ens3f1;

 //systemd代码
 * 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://dev_pci_slot
 *   /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
/* retrieve on-board index number and label from firmware */
static int dev_pci_onboard(struct udev_device *dev, struct netnames *names) {
        const char *index;
        int idx;

        /* ACPI _DSM  -- device specific method for naming a PCI or PCI Express device */
        index = udev_device_get_sysattr_value(names->pcidev, "acpi_index");
        /* SMBIOS type 41 -- Onboard Devices Extended Information */
        if (!index)
                index = udev_device_get_sysattr_value(names->pcidev, "index");
        if (!index)
                return -ENOENT;
        idx = strtoul(index, NULL, 0);
        if (idx <= 0)
                return -EINVAL;
        snprintf(names->pci_onboard, sizeof(names->pci_onboard), "o%d", idx);

        names->pci_onboard_label = udev_device_get_sysattr_value(names->pcidev, "label");
        return 0;
}

后续需要继续确认的流程

1、网卡配置文件是如何产生的?

参考网址

https://blog.csdn.net/tiantao2012/article/details/76177363

https://vvl.me/2021/06/netdev-name-in-linux/

https://www.codenong.com/p12092731/

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值