VirtualBox为操作系统多网口指定固定名称
修改运行在vbox中的主机网络接口名称记。
本文要解决的问题:在udev支持较弱的linux发行版本下解决网卡名称分配设置的问题。
在虚拟机上只有一块网卡时,不会有大问题;当有两块时,有问题但问题不大,手动调整一下就能解决问题且后续也不会有什么重新调整的问题。
但在有三张网卡时问题就比较大了,经常会将主机之前指定的网口名称(与mac地址关系错乱)弄错且无规律可循,导致一些运行在其的应用无法正常或按预期工作。
Linux 设备管理器工作过程,一个现代设备管理器必须:
在用户空间中运行。
动态创建和删除device file。
提供一致的设备命名。
提供用户空间应用程序接口(API)。
每当设备结构发生变化时,内核都会发出一个由设备管理器获取的 uevent ,然后设备管理器遵循 /etc/udev/rules.d, /run/udev/rules.d 和 /lib/udev/rules.d 目录中声明的规则,根据uevent中包含的信息,它会找到触发和执行所需操作所需的规则。这些动作可能涉及设备文件的创建或删除,还可能触发将特定固件文件加载到内核内存中。
即便在单网卡模式下,依然不能对网卡按配置文件的写法进行配置的情形:
Configuring network interface... Cannot find device "eth0"
ifup: failed to bring up eth0
failed
但在dmesg中有看到有修改成功:
[3.693510] e1000 0000:00:11.0 enp0s17: renamed from eth0
Naming network interfaces in Linux
一致性网络设备命名(Consistent Network Device Naming)
在Centos-v5的时习惯了eth0这样的网络设备命名,在Centos-v6发现网络设备变成了em1这样的命名。那时在安装的时候,给启动参数加上 biosdevname=0,就可以继续使用eth0这样的命名。升级到Centos-v7后,发现原有的参数'biosdevname=0'不起作用了,网络设备变成了eno1这样的名称。Centos-v7这种变化的原因是由于systemd/udev引入了一种新的网络设备命名方式:一致网络设备命名(CONSISTENT NETWORK DEVICE NAMING)。
服务器通常有多块网卡,有板载集成的,同时也有插在PCIe插槽的。Linux系统的命名原来是eth0、eth1这样的形式,但是这个编号往往不一定准确对应网卡接口的物理顺序。为解决这类问题,Dell开发了biosdevname方案(systemd v197版本中将dell的方案作了进一步的一般化拓展)。目前的Centos既支持biosdevname,也支持systemd的方案。
命名规范
biosdevname、net.ifnames 是一对 Linux 内核参数,它们共同影响网卡的命名方式:
biosdevname:指向网卡的 BIOS 设备名称;
net.ifnames:指定网卡在系统中的名称。
biosdevname:指定内核是否应该使用 BIOS 分配的名称来命名网络接口。
缺点:这个命名方式的网卡顺序是由识别顺序决定的,所以可能会出现网卡对不上的情况。
eth0
eth1
em1 板载网卡
p3p4 pci网卡
net.ifnames:指定内核是否应该使用用户定义的名称来命名网络接口,更可靠,一些常见的命名:
en 代表以太网
wl 代表无线局域网(WLAN)
ww 代表无线广域网(WWANs)
o<on-board_index_number> 主板自带板载网卡
s<hot_plug_slot_index_number>[f<function>][d<device_id>] 主板自带板载PCI-E网卡
x<MAC> MAC 地址
p<bus>s<slot>[f<function>][d<device_id>] PCI-E独立网卡
[P<domain_number>]p<bus>s<slot>[f<function>][u<usb_port>][…][c<config>][i<interface>] USB网卡
示例:
enp3s0f1:
en Ethernet network card
p3 PCI bus #3
s0 Slot #0
f1 Function #1 (eg. a dual porta LAN has two functions).
eno1 板载1号网卡
enp0s2 以太网0号PCI扩展卡的2号端口
ens33 由主板 BIOS 内置的 PCI-E 接口的网卡
wlp3s0 无线第3号PCI扩展卡的0号端口
wwp0s29f7u2i2 4G modem
wlp0s2f1u4u1 连接在USB Hub上的无线网卡
enx78e7d1ea46da pci网卡
(Centos-v7)系统默认命名顺序
默认情况下,systemd 会使用以下策略,采用支持的命名方案为接口命名:
Scheme1(方案1): 如果从BIOS中能够取到可用的板载网卡的索引号,则使用这个索引号命名,例如:eno1,如不能则尝试Scheme2
Scheme2(方案2): 如果从BIOS中能够取到可以用的网卡所在的PCI-E热插拔插槽的索引号,则使用这个索引号命名,例如:ens1,如不能则尝试Scheme3
Scheme3(方案3): 如果能拿到设备所连接的物理位置信息,则使用这个信息命名,例如:enp2s0,如不能则尝试Scheme5
Scheme4(方案4): 使用网卡的MAC地址来命名,这个方法一般不使用。如:enx78e7d1ea46da
Scheme5(方案5):传统的kernel命名方法,例如:eth0,这种命名方法的结果不可预知的,即可能第二块网卡对应eth0,第一块网卡对应eth1。
网卡配置文件(RHEL派系Linux)对网卡名的影响
DEVICE 字段指定网卡的设备名称。设备名称是一个唯一标识符,它用于在内核中识别网卡。
NAME 字段指定网卡的逻辑名称。逻辑名称是一个用户友好的名称,它可以用于在应用程序中识别网卡。
在网卡配置文件中,DEVICE字段的优先级高于 NAME 字段。这意味着,如果 DEVICE 和 NAME 字段同时指定,则 DEVICE 字段的值将用于识别网卡。MAC 字段的优先级低于 DEVICE 和 NAME 字段。如果网卡漂移问题是由网卡驱动或系统配置引起的,那么在网卡配置文件中添加MAC + DEVICE可以解决问题。但如果网卡漂移问题是由硬件问题引起的,那么在网卡配置文件中添加MAC + DEVICE无法解决问题。
systemd中的实际执行顺序
按照如下顺序执行udev的rule
1./usr/lib/udev/rules.d/60-net.rules
2./usr/lib/udev/rules.d/71-biosdevname.rules
3./lib/udev/rules.d/75-net-description.rules
4./usr/lib/udev/rules.d/80-net-name-slot.rules
60-net.rules
使用/lib/udev/rename_device这个程序,去查询/etc/sysconfig/network-scripts/下所有以ifcfg-开头的文件
如果在ifcfg-xx中匹配到HWADDR=xx:xx:xx:xx:xx:xx参数的网卡接口
则选取DEVICE=yyyy中设置的名字作为网卡名称。
71-biosdevname.rules
如果系统中安装了biosdevname,且内核参数未指定biosdevname=0,且上一步没有重命名网卡,则按照biosdevname的命名规范,从BIOS中取相关信息来命名网卡。
主要是取SMBIOS中的type 9 (System Slot) 和 type 41 (Onboard Devices Extended Information)
不过要求SMBIOS的版本要高于2.6,且系统中要安装biosdevname程序。
75-net-description.rules
udev通过检查网卡信息,填写如下这些udev的属性值
ID_NET_NAME_ONBOARD
ID_NET_NAME_SLOT
ID_NET_NAME_PATH
ID_NET_NAME_MAC
80-net-name-slot.rules
如果在60-net.rules,71-biosdevname.rules这两条规则中没有重命名网卡,且内核未指定net.ifnames=0参数
则udev依次尝试使用以下属性值来命名网卡,如果这些属性值都没有,则网卡不会被重命名。
ID_NET_NAME_ONBOARD
ID_NET_NAME_SLOT
ID_NET_NAME_PATH
上边的71-biosdevname.rules 是实际执行biosdevname的policy
75-net-description.rules和80-net-name-slot.rules实际执行Scheme 1,2,3
根据上述的过程,可见网卡命名受 biosdevname和net.ifnames这两个内核参数影响。
在启动文件中配置相关选项
grep 'biosdevname' /etc/sysconfig/grub
biosdevname=0 net.ifnames=1 # 表示关闭biosdevname,启用net.ifnames
或
dmesg | grep ifname
# 变更以及生效 (重启可能会因为网卡配置不对而断网!)
/etc/sysconfig/grub
# 修改命名方式 例如:网卡名 "eth0"
biosdevname=0 net.ifnames=0
grub2-mkconfig -o /boot/grub2/grub.cfg
例如:
biosdevname=0, net.ifnames=1 网卡名 "enp5s2"
biosdevname=1, net.ifnames=0 网卡名 "em1"
biosdevname=0, net.ifnames=0 网卡名 "eth0"
biosdevname/net.ifnames的应用
这两个参数都可以在grub配置中提供,biosdevname=0是系统默认值(Dell服务器默认是1),net.ifnames=1是系统默认值。
#vim /boot/grub/grub.conf
kernel /boot/vmlinuz biosdevname=1
前面所说的Scheme的策略顺序是系统默认的。
1.如系统BIOS符合要求,且系统中安装了biosdevname,且biosdevname=1启用,则biosdevname优先;
2.如果BIOS不符合biosdevname要求或biosdevname=0,则仍然是systemd的规则优先。
3.如果用户自己定义了udev rule来修改内核设备名字,则用户规则优先。
内核参数组合使用的时候,其结果如下:
默认内核参数(biosdevname=0,net.ifnames=1): 网卡名 "enp5s2"
biosdevname=1,net.ifnames=0:网卡名 "em1"
biosdevname=0,net.ifnames=0:网卡名 "eth0" (最传统的方式,eth0、eth1 傻傻分不清楚)
Centos-v7网卡重命名为ethN格式
如果希望继续使用 eth0 这样的传统名称,那么在安装启动(pxe)时加上参数:
net.ifnames=0 biosdevname=0
cobbler profile 的修改方法:
cobbler profile edit --name=Centos-7.9-x86_64 --kopts='net.ifnames=0 biosdevname=0'
如果已经安装完成了,希望改成eth0这样的名称,那么执行如下操作需要:
1.修改grub2启动参数,在GRUB_CMDLINE_LINUX的中加上"net.ifnames=0 biosdevname=0"的参数
vim /etc/sysconfig/grub
GRUB_CMDLINE_LINUX=”rd.lvm.lv=vg0/swap vconsole.keymap=us crashkernel=auto vconsole.font=latarcyrheb-sun16 net.ifnames=0 biosdevname=0 rd.lvm.lv=vg0/usr rhgb quiet”
2.重新加载到启动中
grub2-mkconfig -o /boot/grub2/grub.cfg
3.重新对网卡配置文件进行命名(网卡文件全部重命名,并修改配置文件中的NAME、DEVICE名称)
mv /etc/sysconfig/network-scripts/ifcfg-enp0s3 /etc/sysconfig/network-scripts/ifcfg-eth0
4.reboot重启生效
这里收录转发一个老外的最简操作过程
Linux change NIC name
1.Change grub.cfg
2.Change udev rules
3.Change Network Interface Card Configuration
1.Change grub.cfg
rpm-based:
Edit /etc/sysconfig/grub, find the line including GRUB_CMDLINE_LINUX,add net.ifnames=0 biosdevname=0
grub2-mkconfig -o /boot/grub2/grub.cfg
deb-based/archlinux:
Edit /etc/default/grub, find the line including GRUB_CMDLINE_LINUX,add net.ifnames=0 biosdevname=0
grub-mkconfig -o /boot/grub/grub.cfg
2.Change udev rules
mv /etc/udev/rules.d/70-persistent-ipoib.rules /etc/udev/rules.d/70-persistent-ipoib.rules.bak
Edit /etc/udev/rules.d/10-network.rules
SUBSYSTEM=="net",ACTION=="add",ENV{ID_NET_NAME_MAC}=="enx000c2926e8bc",NAME="eth0"
SUBSYSTEM=="net",ACTION=="add",ATTR{address}=="00:01:02:8c:30:29",NAME="eth1"
NOTE
cat /sys/class/net/<device-name>/address can get MAC addr
Use the lower-case hex values in MAC addr
3.Change Network Interface Card Configuration
cd /etc/sysconfig/network-scripts/
mv ifcfg-eno\* ifcfg-eth\*
Edit ifcfg-eth\*, change NAME=esp** to NAME=eth{N}
Linux内核中的网卡信息
linux内核对网卡信息索引
What:/sys/class/net/<iface>/addr_assign_type
Date:July 2010
KernelVersion:3.2
Contact:netdev@vger.kernel.org
Description:Indicates the address assignment type. Possible values are:
== ============================
0 permanent address
1 randomly generated
2 stolen from another device
3 set (by) dev_set_mac_address
== ============================
从实践来看,这个值并不可靠。
如何确认网卡是物理还是虚拟的
check the network interface is physical (device) or virtual (alias)
1.显然,物理网口是有MAC地址的,这是两者的明显区别。
ip -details -oneline link
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000\ link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 promiscuity 0 minmtu 0 maxmtu 0 addrgenmode eui64 numtxqueues 1 numrxqueues 1 gso_max_size 65536 gso_max_segs 65535
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000\ link/ether 08:00:27:5e:b7:92 brd ff:ff:ff:ff:ff:ff promiscuity 0 minmtu 46 maxmtu 16110 addrgenmode eui64 numtxqueues 1 numrxqueues 1 gso_max_size 65536 gso_max_segs 65535
3: eth2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000\ link/ether 08:00:27:31:02:11 brd ff:ff:ff:ff:ff:ff promiscuity 0 minmtu 46 maxmtu 16110 addrgenmode eui64 numtxqueues 1 numrxqueues 1 gso_max_size 65536 gso_max_segs 65535
4: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000\ link/ether 08:00:27:8d:76:46 brd ff:ff:ff:ff:ff:ff promiscuity 0 minmtu 46 maxmtu 16110 addrgenmode eui64 numtxqueues 1 numrxqueues 1 gso_max_size 65536 gso_max_segs 65535
5: vpn0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN mode DEFAULT group default qlen 1000\ link/ether 26:21:d3:67:02:00 brd ff:ff:ff:ff:ff:ff promiscuity 0 minmtu 68 maxmtu 65521 \ tun type tap pi off vnet_hdr off persist off addrgenmode eui64 numtxqueues 1 numrxqueues 1 gso_max_size 65536 gso_max_segs 65535
但明显第5块网卡是虚拟网卡,却有MAC地址?
2./sys/class/net
ls -l /sys/class/net
br-lan -> ../../devices/virtual/net/br-lan
eth0 -> ../../devices/platform/ag71xx.0/net/eth0
lan1 -> ../../devices/platform/dsa.0/net/lan1
lo -> ../../devices/virtual/net/lo
pppoe-wan -> ../../devices/virtual/net/pppoe-wan
wan -> ../../devices/platform/dsa.0/net/wan
可见路径里有'virtual'字样的为虚拟设备。
Each of the entries in this directory is a symbolic link representing one of the real or virtual networking devices that are visible in the network namespace of the process that is accessing the directory. Each of these symbolic links refers to entries in the /sys/devices directory.
checking if the value of /sys/class/net/<interface>/type is 1 (ARPHRD_ETHER) should be enough to understand if the device is a physical one.
3.ethtool -P {Network interface name}
"Permanent address: 00:00:00:00:00:00" will indicate it's a virtual network interface.
for i in $(ip -o link show | awk -F': ' '{print $2}'); do mac=$(ethtool -P $i) && printf '%-10s %-10s\n' "$i" "$mac"; done
lo Permanent address: 00:00:00:00:00:00
enp5s0f0 Permanent address: 43:1e:a1:73:39:c8
virbr0 Permanent address: 00:00:00:00:00:00
OR
lo Permanent address: not set
eth0 Permanent address: 08:00:27:d9:57:d0
vpn0 Permanent address: not set
网卡的名称管理还可以使用nameif, ip link, ifrename等指令工具
nameif
nameif命令是一个较旧的命令,已正式弃用。然而仍有一些人使用它来完成特定的任务。该命令的唯一目的是根据设备的MAC地址命名接口。例如:
# nameif -c /etc/mactab -s 08:00:27:30:52:a7
-c选项允许指定希望从哪个配置文件中读取,默认使用/etc/mactab。-s标志让系统将任何错误消息发送到syslog,然后给它指定要重命名的接口的MAC地址。
注意,在启动接口之前必须运行nameif,否则将失败。具体使用过程如下:
net-tools::nameif实用程序可以更改网卡的名称。在提供的示例中,该实用程序用于更改eth1接口的名称,该接口的MAC地址为00:30:48:84:76:07,处于down状态。
要修改接口名称,首先需要修改/etc/mactab文件:
# vim /etc/mactab
interfaceName0 00:30:48:84:76:07
一个条目中包含所需的网络接口名称及其MAC地址,并以空格隔开。
之后可以执行nameif命令并使用ifconfig -a检查结果。将看到eth1已重命名为freeoa0。要使更改永久生效,请将nameif命令添加到启动脚本中,例如/etc/rc.local。
ifrename
默认情况下,网络接口名称是动态的,并按照先到先服务的原则分配:eth0、eth1、eth2等等。ifrename工具允许为接口分配一致的名称,可以通过几种方式设置它。然而,这里最常见的用法是基于MAC地址来设置名称。这样做是有意义的,因为MAC地址对设备来说是唯一的。与nameif非常相似,必须在启动接口之前运行ifrename以避免失败。该工具还从配置文件中提取数据;但这次我们使用的是/etc/iftab(除非另有说明)。来看看如何使用它,语法原文如下:
# ifrename [-c configfile] [-i interface] [-n newname]
-c - allows you to specify a config file other than /etc/iftab
-i - allows you to rename only a specific interface rather than all system interfaces
-n - allows you to specify the new name of the interface (use with -i)
-D - allows the user to enter "dry-run" mode. Here, ifrename won't change the name of the interface. It only prints the new name and return. This is a great way to make sure that you have the command correct before running for real.
-V - gives verbose output with additional information used for debugging issues.
# Example /etc/iftab file
eth2 mac 08:00:09:DE:82:0E
eth3 driver wavelan interrupt 15 baseaddress 0x390
eth4 driver pcnet32 businfo 0000:02:05.0
# wildcard name: pick the lowest available name of air0, air1, air2, etc.
air* mac 00:07:0E:* arp 1
ip link
ip命令是Linux组网命令中的“瑞士军刀”。特别关注ip link,这是一个用于命名和修改网络接口的命令。
ip link show
注意,该命令没有提供IP地址信息。需要的话可使用ip addr命令来满足这一需求。具体接口信息请参见:
ip link show dev enp0s3
要更改接口的名称,可以使用以下命令:
ip link set eth0 name eth123
请注意,必须禁用接口,更改名称后将其恢复以进行变更。完整的过程如下:
ip link set eth1 down
ip link set eth1 name eth11
ip link set eth11 up
还需要将/etc/sysconfig/network-scripts/ifcfg_old_device_name文件的标题和内容修改为新的设备名称。
引导器中的设备命名配置参数对结果有影响:
/etc/default/grub的GRUB_CMDLINE_LINUX参数:
net.ifnames=0 biosdevname=0
系统组init进程对(网卡)设备名称的影响
systemd and udevd
systemctl restart systemd-udevd
Network Manager
udev相关指令的用法
udevadm指令可以看到设备的一些内部信息,还是相当不有用的。
udevadm info -n /dev/sda
=>
udevadm info -n sda
udevadm info -q all -p /sys/class/net/eth0
calling: info
P: /devices/pci0000:00/0000:00:08.0/net/eth0
E: DEVPATH=/devices/pci0000:00/0000:00:08.0/net/enp0s8
E: ID_BUS=pci
E: ID_MM_CANDIDATE=1
E: ID_MODEL_FROM_DATABASE=82545EM Gigabit Ethernet Controller (Copper) (PRO/1000 MT Single Port Adapter)
E: ID_MODEL_ID=0x100f
E: ID_NET_NAME_MAC=enx0800275eb792
E: ID_NET_NAME_PATH=enp0s8
E: ID_OUI_FROM_DATABASE=PCS Systemtechnik GmbH
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=2
E: INTERFACE=eth0
E: MAJOR=0
E: MINOR=0
E: SUBSYSTEM=net
E: USEC_INITIALIZED=2261067
E: net.ifnames=1
udevadm test-builtin net_id /sys/class/net/eth0
udevadm test-builtin blkid /sys/class/block/sda
部分参考链接
Udev in gentoo wiki
Renaming network interfaces
Debian NetworkInterfaceNames
Implementing consistent network interface naming
重启网络网卡的部分方法
这是一个各显神通的场合了,非常有意思。在Linux中重新启动网络可能有多种原因:
1.应用更新或更改网络设置,包括IP地址,主机名,DNS服务器,网关等。
2.解决网络连接问题,包括连接缓慢或不稳定、数据包丢失、路由错误等。
3.添加或删除网络接口,包括VPN、以太网和Wi-Fi。
4.更新网络状态并删除所有缓存,包括ARP表、DNS缓存和路由表。
先说最为常见的:
service 与 systemctl 是引入systemd初始管理系统后的分界点,而前者还可以到其操作的脚本目录下进行类似操作(如/etc/init.d/networking status)。
当然还有像ifup/ifdown这样的小甜点可以品尝。因net-tools工具集中间有多家未曾更新,后被linux自家出身的iproute2工具集所取代成为linux事实上IP操作标准工具。
还有非常重要的NetworkManager服务
该服务是用来自动配置和管理网络连接的,所以通常不需要手动设置网络设置。但如果需要更改IP地址或DNS设置,可以使用NetworkManager GUI或在终端中编辑配置文件来更改网络配置。它通常以network-manager或NetworkManager.service的名称出现在系统中,当然该服务也不是必须的。
但这种混乱的局面还是引起了部分能人的不满,毕竟推陈出新才是linux社区的正道,因此nmcli工具粉墨登场。
nmcli工具是NetworkManager包的一部分。其在Linux中使用它来重新启动网络非常简单。可管理不同Linux版本的网络连接:
nmcli networking on|off
'nmcli -o'可展示当前网络运行的状态信息,等同于'systemctl status NetworkManager'。对命令行界面恐惧的人还可以尝试:nmtui,当然各类桌面中也集成了相关可视化工具。
windows下也有命令行的操作工具,如网络与TCP/IP Stack的重置:
netsh winsock reset
重置TCP/IP Stack
netsh int ip reset
Debian-NetworkConfiguration
Devuan4在vbox下的网口绑定
/etc/udev/rules.d/19-persistent-net.rules
#PCI device
#NAME:="some name" , := is used to make sure that device name will be persistent.
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="08:00:27:8D:76:46", ATTR{dev_id}=="0x0", ATTR{type}=="1", KERNEL=="eth*", NAME:="eth0"
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="08:00:27:D9:57:D2", ATTR{dev_id}=="0x0", ATTR{type}=="1", KERNEL=="eth*", NAME:="eth1"
# PCI Net device
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="08:00:27:8d:76:46", KERNEL=="eth*", NAME="eth0"
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="08:00:27:d9:57:d2", KERNEL=="eth*", NAME="eth1"
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="08:00:27:31:02:11", KERNEL=="eth*", NAME="eth2"
# PCI device
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="08:00:27:8d:76:46", ATTR{dev_id}=="0x0", ATTR{type}=="1", KERNEL=="eth*", NAME="eth0"
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="08:00:27:d9:57:d2", ATTR{dev_id}=="0x0", ATTR{type}=="1", KERNEL=="eth*", NAME="eth1"
udev项目很早就投入systemd阵营,导致一些non-systemd的发行版本下设备的管理工作不尽人意,虽有gentoo建立eudev项目,但结果依然不太理想;因此non-systemd的Linux操作系统的udev体系就得不到好的支撑。devuan下就会有此类问题的困扰:
devuan rename netcard name
eudev sometimes fails to generate initial hotplug events in devuan
因此上面的udev的rules规则基本上没有什么用处,真让人沮丧。
2024年11月,手动编写了脚本,借用ip指令以MAC地址绑定网络接口的名称:
use v5.20;
use Data::Dumper;
#241228 by zheng
#slove netcard name when system has more than 3.
#diy the cardname by its mac and config it.
#250118,add chage netcard name with orig begin with eth,plus it order index first
#then modify netcard name like openwrt
###netcards
my %ecardsmac;
##new net card config
my %nncc=(
'08:00:27:8d:76:46'=>{'nname'=>'eth1','cmd'=>'ip addr add 172.18.0.3/24 dev eth1'},
'08:00:27:31:02:11'=>{'nname'=>'eth2','cmd'=>'ip addr add dev eth2 192.168.25.1/24'},
'08:00:27:5e:b7:92'=>{'nname'=>'eth0','cmd'=>'dhclient eth0 -v'},
);
my ($ncidx_plus)=(10);
#所有的以太网卡
my @enc=('lo','vpn0');#需要排除的接口卡
my ($ncdir,$dh)=('/sys/class/net');
if(-d -x $ncdir){
opendir($dh,$ncdir);# && chdir($ncdir);
while(my $nc=readdir($dh)){
next if($nc=~/^\./);
next if(grep {$_ eq $nc} @enc);#主动过滤那些要排除的网卡
$ecardsmac{$nc}=get_phnc_mac("$ncdir/$nc");
}
}
foreach my $card (keys %ecardsmac){
if($card=~/(?<ncn>\w+[a-z])(?<nci>\d+$)/){
#change eth-net-card
if(($+{ncn} eq 'eth') && length($+{nci})){
my $ncard="$+{ncn}".($+{nci}+$ncidx_plus);
system(qq[ip link set $card down; ip link set $card name $ncard; ip link set $ncard up]);
$ecardsmac{$ncard}=$ecardsmac{$card};
delete $ecardsmac{$card};
}
}
}
foreach my $card (keys %ecardsmac){
say "Change Orig NetCard $card to $nncc{$ecardsmac{$card}}{nname}, and config it...";
system(qq[ip link set $card down; ip link set $card name $nncc{$ecardsmac{$card}}{nname}]);
system(qq[$nncc{$ecardsmac{$card}}{cmd}; ip link set $nncc{$ecardsmac{$card}}{nname} up]);
}
#从OS中取得信息如果是以太网卡侧返回其mac地址
sub get_phnc_mac{
my $ncd=shift;
my ($ist,$mac)=(0,undef);
chdir($ncd);
if(-l 'device'){
my $frt=get_oline_file("$ncd/type");
$ist=1,$mac=get_oline_file("$ncd/address") if($frt == 1);
}
return $ist?$mac:undef;
}
#返回只有一行文件的文件内容
sub get_oline_file{
my $fpn=shift;
my ($fh,$oline);
if(-r $fpn){
open($fh,'<',$fpn);
$oline=do{local $/;<$fh>};
chomp($oline);
close $fh;
$oline=~s/^\s+|\s+$//;
return $oline;
}else{
return undef;
}
}
END{
#say Dumper(\%nncc,\%ecardsmac);
exit(0);
}
OpenWRT在双网卡的情况下,也会出现网卡识别错乱的情形,而且也是重启后有惊喜。其下运行上述脚本时报需要perl的(Tie)包模块依赖:
perlbase-tie 5.28.1-9 21.89 KiB Tie perl module
使用此脚本后系统的网络配置文件(/etc/network/interfaces)就可以不使用了。另外不得不说一下,freebsd在vbox下多网卡时也会出现重启时之前设定网卡错位的问题,但比较好解决,使用系统工具:sysutils/ethname
在系统配置/etc/rc.conf中加入如下的配置:
ethname_enable="YES"
ethname_emN_mac="aa:bb:cc:dd:ee:ff"
就能解决网卡MAC与名称错位的问题了,在freebsd-v12下实测通过。
本文要解决的问题:在udev支持较弱的linux发行版本下解决网卡名称分配设置的问题。
在虚拟机上只有一块网卡时,不会有大问题;当有两块时,有问题但问题不大,手动调整一下就能解决问题且后续也不会有什么重新调整的问题。
但在有三张网卡时问题就比较大了,经常会将主机之前指定的网口名称(与mac地址关系错乱)弄错且无规律可循,导致一些运行在其的应用无法正常或按预期工作。
Linux 设备管理器工作过程,一个现代设备管理器必须:
在用户空间中运行。
动态创建和删除device file。
提供一致的设备命名。
提供用户空间应用程序接口(API)。
每当设备结构发生变化时,内核都会发出一个由设备管理器获取的 uevent ,然后设备管理器遵循 /etc/udev/rules.d, /run/udev/rules.d 和 /lib/udev/rules.d 目录中声明的规则,根据uevent中包含的信息,它会找到触发和执行所需操作所需的规则。这些动作可能涉及设备文件的创建或删除,还可能触发将特定固件文件加载到内核内存中。
即便在单网卡模式下,依然不能对网卡按配置文件的写法进行配置的情形:
Configuring network interface... Cannot find device "eth0"
ifup: failed to bring up eth0
failed
但在dmesg中有看到有修改成功:
[3.693510] e1000 0000:00:11.0 enp0s17: renamed from eth0
Naming network interfaces in Linux
一致性网络设备命名(Consistent Network Device Naming)
在Centos-v5的时习惯了eth0这样的网络设备命名,在Centos-v6发现网络设备变成了em1这样的命名。那时在安装的时候,给启动参数加上 biosdevname=0,就可以继续使用eth0这样的命名。升级到Centos-v7后,发现原有的参数'biosdevname=0'不起作用了,网络设备变成了eno1这样的名称。Centos-v7这种变化的原因是由于systemd/udev引入了一种新的网络设备命名方式:一致网络设备命名(CONSISTENT NETWORK DEVICE NAMING)。
服务器通常有多块网卡,有板载集成的,同时也有插在PCIe插槽的。Linux系统的命名原来是eth0、eth1这样的形式,但是这个编号往往不一定准确对应网卡接口的物理顺序。为解决这类问题,Dell开发了biosdevname方案(systemd v197版本中将dell的方案作了进一步的一般化拓展)。目前的Centos既支持biosdevname,也支持systemd的方案。
命名规范
biosdevname、net.ifnames 是一对 Linux 内核参数,它们共同影响网卡的命名方式:
biosdevname:指向网卡的 BIOS 设备名称;
net.ifnames:指定网卡在系统中的名称。
biosdevname:指定内核是否应该使用 BIOS 分配的名称来命名网络接口。
缺点:这个命名方式的网卡顺序是由识别顺序决定的,所以可能会出现网卡对不上的情况。
eth0
eth1
em1 板载网卡
p3p4 pci网卡
net.ifnames:指定内核是否应该使用用户定义的名称来命名网络接口,更可靠,一些常见的命名:
en 代表以太网
wl 代表无线局域网(WLAN)
ww 代表无线广域网(WWANs)
o<on-board_index_number> 主板自带板载网卡
s<hot_plug_slot_index_number>[f<function>][d<device_id>] 主板自带板载PCI-E网卡
x<MAC> MAC 地址
p<bus>s<slot>[f<function>][d<device_id>] PCI-E独立网卡
[P<domain_number>]p<bus>s<slot>[f<function>][u<usb_port>][…][c<config>][i<interface>] USB网卡
示例:
enp3s0f1:
en Ethernet network card
p3 PCI bus #3
s0 Slot #0
f1 Function #1 (eg. a dual porta LAN has two functions).
eno1 板载1号网卡
enp0s2 以太网0号PCI扩展卡的2号端口
ens33 由主板 BIOS 内置的 PCI-E 接口的网卡
wlp3s0 无线第3号PCI扩展卡的0号端口
wwp0s29f7u2i2 4G modem
wlp0s2f1u4u1 连接在USB Hub上的无线网卡
enx78e7d1ea46da pci网卡
(Centos-v7)系统默认命名顺序
默认情况下,systemd 会使用以下策略,采用支持的命名方案为接口命名:
Scheme1(方案1): 如果从BIOS中能够取到可用的板载网卡的索引号,则使用这个索引号命名,例如:eno1,如不能则尝试Scheme2
Scheme2(方案2): 如果从BIOS中能够取到可以用的网卡所在的PCI-E热插拔插槽的索引号,则使用这个索引号命名,例如:ens1,如不能则尝试Scheme3
Scheme3(方案3): 如果能拿到设备所连接的物理位置信息,则使用这个信息命名,例如:enp2s0,如不能则尝试Scheme5
Scheme4(方案4): 使用网卡的MAC地址来命名,这个方法一般不使用。如:enx78e7d1ea46da
Scheme5(方案5):传统的kernel命名方法,例如:eth0,这种命名方法的结果不可预知的,即可能第二块网卡对应eth0,第一块网卡对应eth1。
网卡配置文件(RHEL派系Linux)对网卡名的影响
DEVICE 字段指定网卡的设备名称。设备名称是一个唯一标识符,它用于在内核中识别网卡。
NAME 字段指定网卡的逻辑名称。逻辑名称是一个用户友好的名称,它可以用于在应用程序中识别网卡。
在网卡配置文件中,DEVICE字段的优先级高于 NAME 字段。这意味着,如果 DEVICE 和 NAME 字段同时指定,则 DEVICE 字段的值将用于识别网卡。MAC 字段的优先级低于 DEVICE 和 NAME 字段。如果网卡漂移问题是由网卡驱动或系统配置引起的,那么在网卡配置文件中添加MAC + DEVICE可以解决问题。但如果网卡漂移问题是由硬件问题引起的,那么在网卡配置文件中添加MAC + DEVICE无法解决问题。
systemd中的实际执行顺序
按照如下顺序执行udev的rule
1./usr/lib/udev/rules.d/60-net.rules
2./usr/lib/udev/rules.d/71-biosdevname.rules
3./lib/udev/rules.d/75-net-description.rules
4./usr/lib/udev/rules.d/80-net-name-slot.rules
60-net.rules
使用/lib/udev/rename_device这个程序,去查询/etc/sysconfig/network-scripts/下所有以ifcfg-开头的文件
如果在ifcfg-xx中匹配到HWADDR=xx:xx:xx:xx:xx:xx参数的网卡接口
则选取DEVICE=yyyy中设置的名字作为网卡名称。
71-biosdevname.rules
如果系统中安装了biosdevname,且内核参数未指定biosdevname=0,且上一步没有重命名网卡,则按照biosdevname的命名规范,从BIOS中取相关信息来命名网卡。
主要是取SMBIOS中的type 9 (System Slot) 和 type 41 (Onboard Devices Extended Information)
不过要求SMBIOS的版本要高于2.6,且系统中要安装biosdevname程序。
75-net-description.rules
udev通过检查网卡信息,填写如下这些udev的属性值
ID_NET_NAME_ONBOARD
ID_NET_NAME_SLOT
ID_NET_NAME_PATH
ID_NET_NAME_MAC
80-net-name-slot.rules
如果在60-net.rules,71-biosdevname.rules这两条规则中没有重命名网卡,且内核未指定net.ifnames=0参数
则udev依次尝试使用以下属性值来命名网卡,如果这些属性值都没有,则网卡不会被重命名。
ID_NET_NAME_ONBOARD
ID_NET_NAME_SLOT
ID_NET_NAME_PATH
上边的71-biosdevname.rules 是实际执行biosdevname的policy
75-net-description.rules和80-net-name-slot.rules实际执行Scheme 1,2,3
根据上述的过程,可见网卡命名受 biosdevname和net.ifnames这两个内核参数影响。
在启动文件中配置相关选项
grep 'biosdevname' /etc/sysconfig/grub
biosdevname=0 net.ifnames=1 # 表示关闭biosdevname,启用net.ifnames
或
dmesg | grep ifname
# 变更以及生效 (重启可能会因为网卡配置不对而断网!)
/etc/sysconfig/grub
# 修改命名方式 例如:网卡名 "eth0"
biosdevname=0 net.ifnames=0
grub2-mkconfig -o /boot/grub2/grub.cfg
例如:
biosdevname=0, net.ifnames=1 网卡名 "enp5s2"
biosdevname=1, net.ifnames=0 网卡名 "em1"
biosdevname=0, net.ifnames=0 网卡名 "eth0"
biosdevname/net.ifnames的应用
这两个参数都可以在grub配置中提供,biosdevname=0是系统默认值(Dell服务器默认是1),net.ifnames=1是系统默认值。
#vim /boot/grub/grub.conf
kernel /boot/vmlinuz biosdevname=1
前面所说的Scheme的策略顺序是系统默认的。
1.如系统BIOS符合要求,且系统中安装了biosdevname,且biosdevname=1启用,则biosdevname优先;
2.如果BIOS不符合biosdevname要求或biosdevname=0,则仍然是systemd的规则优先。
3.如果用户自己定义了udev rule来修改内核设备名字,则用户规则优先。
内核参数组合使用的时候,其结果如下:
默认内核参数(biosdevname=0,net.ifnames=1): 网卡名 "enp5s2"
biosdevname=1,net.ifnames=0:网卡名 "em1"
biosdevname=0,net.ifnames=0:网卡名 "eth0" (最传统的方式,eth0、eth1 傻傻分不清楚)
Centos-v7网卡重命名为ethN格式
如果希望继续使用 eth0 这样的传统名称,那么在安装启动(pxe)时加上参数:
net.ifnames=0 biosdevname=0
cobbler profile 的修改方法:
cobbler profile edit --name=Centos-7.9-x86_64 --kopts='net.ifnames=0 biosdevname=0'
如果已经安装完成了,希望改成eth0这样的名称,那么执行如下操作需要:
1.修改grub2启动参数,在GRUB_CMDLINE_LINUX的中加上"net.ifnames=0 biosdevname=0"的参数
vim /etc/sysconfig/grub
GRUB_CMDLINE_LINUX=”rd.lvm.lv=vg0/swap vconsole.keymap=us crashkernel=auto vconsole.font=latarcyrheb-sun16 net.ifnames=0 biosdevname=0 rd.lvm.lv=vg0/usr rhgb quiet”
2.重新加载到启动中
grub2-mkconfig -o /boot/grub2/grub.cfg
3.重新对网卡配置文件进行命名(网卡文件全部重命名,并修改配置文件中的NAME、DEVICE名称)
mv /etc/sysconfig/network-scripts/ifcfg-enp0s3 /etc/sysconfig/network-scripts/ifcfg-eth0
4.reboot重启生效
这里收录转发一个老外的最简操作过程
Linux change NIC name
1.Change grub.cfg
2.Change udev rules
3.Change Network Interface Card Configuration
1.Change grub.cfg
rpm-based:
Edit /etc/sysconfig/grub, find the line including GRUB_CMDLINE_LINUX,add net.ifnames=0 biosdevname=0
grub2-mkconfig -o /boot/grub2/grub.cfg
deb-based/archlinux:
Edit /etc/default/grub, find the line including GRUB_CMDLINE_LINUX,add net.ifnames=0 biosdevname=0
grub-mkconfig -o /boot/grub/grub.cfg
2.Change udev rules
mv /etc/udev/rules.d/70-persistent-ipoib.rules /etc/udev/rules.d/70-persistent-ipoib.rules.bak
Edit /etc/udev/rules.d/10-network.rules
SUBSYSTEM=="net",ACTION=="add",ENV{ID_NET_NAME_MAC}=="enx000c2926e8bc",NAME="eth0"
SUBSYSTEM=="net",ACTION=="add",ATTR{address}=="00:01:02:8c:30:29",NAME="eth1"
NOTE
cat /sys/class/net/<device-name>/address can get MAC addr
Use the lower-case hex values in MAC addr
3.Change Network Interface Card Configuration
cd /etc/sysconfig/network-scripts/
mv ifcfg-eno\* ifcfg-eth\*
Edit ifcfg-eth\*, change NAME=esp** to NAME=eth{N}
Linux内核中的网卡信息
linux内核对网卡信息索引
What:/sys/class/net/<iface>/addr_assign_type
Date:July 2010
KernelVersion:3.2
Contact:netdev@vger.kernel.org
Description:Indicates the address assignment type. Possible values are:
== ============================
0 permanent address
1 randomly generated
2 stolen from another device
3 set (by) dev_set_mac_address
== ============================
从实践来看,这个值并不可靠。
如何确认网卡是物理还是虚拟的
check the network interface is physical (device) or virtual (alias)
1.显然,物理网口是有MAC地址的,这是两者的明显区别。
ip -details -oneline link
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000\ link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 promiscuity 0 minmtu 0 maxmtu 0 addrgenmode eui64 numtxqueues 1 numrxqueues 1 gso_max_size 65536 gso_max_segs 65535
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000\ link/ether 08:00:27:5e:b7:92 brd ff:ff:ff:ff:ff:ff promiscuity 0 minmtu 46 maxmtu 16110 addrgenmode eui64 numtxqueues 1 numrxqueues 1 gso_max_size 65536 gso_max_segs 65535
3: eth2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000\ link/ether 08:00:27:31:02:11 brd ff:ff:ff:ff:ff:ff promiscuity 0 minmtu 46 maxmtu 16110 addrgenmode eui64 numtxqueues 1 numrxqueues 1 gso_max_size 65536 gso_max_segs 65535
4: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000\ link/ether 08:00:27:8d:76:46 brd ff:ff:ff:ff:ff:ff promiscuity 0 minmtu 46 maxmtu 16110 addrgenmode eui64 numtxqueues 1 numrxqueues 1 gso_max_size 65536 gso_max_segs 65535
5: vpn0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN mode DEFAULT group default qlen 1000\ link/ether 26:21:d3:67:02:00 brd ff:ff:ff:ff:ff:ff promiscuity 0 minmtu 68 maxmtu 65521 \ tun type tap pi off vnet_hdr off persist off addrgenmode eui64 numtxqueues 1 numrxqueues 1 gso_max_size 65536 gso_max_segs 65535
但明显第5块网卡是虚拟网卡,却有MAC地址?
2./sys/class/net
ls -l /sys/class/net
br-lan -> ../../devices/virtual/net/br-lan
eth0 -> ../../devices/platform/ag71xx.0/net/eth0
lan1 -> ../../devices/platform/dsa.0/net/lan1
lo -> ../../devices/virtual/net/lo
pppoe-wan -> ../../devices/virtual/net/pppoe-wan
wan -> ../../devices/platform/dsa.0/net/wan
可见路径里有'virtual'字样的为虚拟设备。
Each of the entries in this directory is a symbolic link representing one of the real or virtual networking devices that are visible in the network namespace of the process that is accessing the directory. Each of these symbolic links refers to entries in the /sys/devices directory.
checking if the value of /sys/class/net/<interface>/type is 1 (ARPHRD_ETHER) should be enough to understand if the device is a physical one.
3.ethtool -P {Network interface name}
"Permanent address: 00:00:00:00:00:00" will indicate it's a virtual network interface.
for i in $(ip -o link show | awk -F': ' '{print $2}'); do mac=$(ethtool -P $i) && printf '%-10s %-10s\n' "$i" "$mac"; done
lo Permanent address: 00:00:00:00:00:00
enp5s0f0 Permanent address: 43:1e:a1:73:39:c8
virbr0 Permanent address: 00:00:00:00:00:00
OR
lo Permanent address: not set
eth0 Permanent address: 08:00:27:d9:57:d0
vpn0 Permanent address: not set
网卡的名称管理还可以使用nameif, ip link, ifrename等指令工具
nameif
nameif命令是一个较旧的命令,已正式弃用。然而仍有一些人使用它来完成特定的任务。该命令的唯一目的是根据设备的MAC地址命名接口。例如:
# nameif -c /etc/mactab -s 08:00:27:30:52:a7
-c选项允许指定希望从哪个配置文件中读取,默认使用/etc/mactab。-s标志让系统将任何错误消息发送到syslog,然后给它指定要重命名的接口的MAC地址。
注意,在启动接口之前必须运行nameif,否则将失败。具体使用过程如下:
net-tools::nameif实用程序可以更改网卡的名称。在提供的示例中,该实用程序用于更改eth1接口的名称,该接口的MAC地址为00:30:48:84:76:07,处于down状态。
要修改接口名称,首先需要修改/etc/mactab文件:
# vim /etc/mactab
interfaceName0 00:30:48:84:76:07
一个条目中包含所需的网络接口名称及其MAC地址,并以空格隔开。
之后可以执行nameif命令并使用ifconfig -a检查结果。将看到eth1已重命名为freeoa0。要使更改永久生效,请将nameif命令添加到启动脚本中,例如/etc/rc.local。
ifrename
默认情况下,网络接口名称是动态的,并按照先到先服务的原则分配:eth0、eth1、eth2等等。ifrename工具允许为接口分配一致的名称,可以通过几种方式设置它。然而,这里最常见的用法是基于MAC地址来设置名称。这样做是有意义的,因为MAC地址对设备来说是唯一的。与nameif非常相似,必须在启动接口之前运行ifrename以避免失败。该工具还从配置文件中提取数据;但这次我们使用的是/etc/iftab(除非另有说明)。来看看如何使用它,语法原文如下:
# ifrename [-c configfile] [-i interface] [-n newname]
-c - allows you to specify a config file other than /etc/iftab
-i - allows you to rename only a specific interface rather than all system interfaces
-n - allows you to specify the new name of the interface (use with -i)
-D - allows the user to enter "dry-run" mode. Here, ifrename won't change the name of the interface. It only prints the new name and return. This is a great way to make sure that you have the command correct before running for real.
-V - gives verbose output with additional information used for debugging issues.
# Example /etc/iftab file
eth2 mac 08:00:09:DE:82:0E
eth3 driver wavelan interrupt 15 baseaddress 0x390
eth4 driver pcnet32 businfo 0000:02:05.0
# wildcard name: pick the lowest available name of air0, air1, air2, etc.
air* mac 00:07:0E:* arp 1
ip link
ip命令是Linux组网命令中的“瑞士军刀”。特别关注ip link,这是一个用于命名和修改网络接口的命令。
ip link show
注意,该命令没有提供IP地址信息。需要的话可使用ip addr命令来满足这一需求。具体接口信息请参见:
ip link show dev enp0s3
要更改接口的名称,可以使用以下命令:
ip link set eth0 name eth123
请注意,必须禁用接口,更改名称后将其恢复以进行变更。完整的过程如下:
ip link set eth1 down
ip link set eth1 name eth11
ip link set eth11 up
还需要将/etc/sysconfig/network-scripts/ifcfg_old_device_name文件的标题和内容修改为新的设备名称。
引导器中的设备命名配置参数对结果有影响:
/etc/default/grub的GRUB_CMDLINE_LINUX参数:
net.ifnames=0 biosdevname=0
系统组init进程对(网卡)设备名称的影响
systemd and udevd
systemctl restart systemd-udevd
Network Manager
udev相关指令的用法
udevadm指令可以看到设备的一些内部信息,还是相当不有用的。
udevadm info -n /dev/sda
=>
udevadm info -n sda
udevadm info -q all -p /sys/class/net/eth0
calling: info
P: /devices/pci0000:00/0000:00:08.0/net/eth0
E: DEVPATH=/devices/pci0000:00/0000:00:08.0/net/enp0s8
E: ID_BUS=pci
E: ID_MM_CANDIDATE=1
E: ID_MODEL_FROM_DATABASE=82545EM Gigabit Ethernet Controller (Copper) (PRO/1000 MT Single Port Adapter)
E: ID_MODEL_ID=0x100f
E: ID_NET_NAME_MAC=enx0800275eb792
E: ID_NET_NAME_PATH=enp0s8
E: ID_OUI_FROM_DATABASE=PCS Systemtechnik GmbH
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=2
E: INTERFACE=eth0
E: MAJOR=0
E: MINOR=0
E: SUBSYSTEM=net
E: USEC_INITIALIZED=2261067
E: net.ifnames=1
udevadm test-builtin net_id /sys/class/net/eth0
udevadm test-builtin blkid /sys/class/block/sda
部分参考链接
Udev in gentoo wiki
Renaming network interfaces
Debian NetworkInterfaceNames
Implementing consistent network interface naming
重启网络网卡的部分方法
这是一个各显神通的场合了,非常有意思。在Linux中重新启动网络可能有多种原因:
1.应用更新或更改网络设置,包括IP地址,主机名,DNS服务器,网关等。
2.解决网络连接问题,包括连接缓慢或不稳定、数据包丢失、路由错误等。
3.添加或删除网络接口,包括VPN、以太网和Wi-Fi。
4.更新网络状态并删除所有缓存,包括ARP表、DNS缓存和路由表。
先说最为常见的:
service 与 systemctl 是引入systemd初始管理系统后的分界点,而前者还可以到其操作的脚本目录下进行类似操作(如/etc/init.d/networking status)。
当然还有像ifup/ifdown这样的小甜点可以品尝。因net-tools工具集中间有多家未曾更新,后被linux自家出身的iproute2工具集所取代成为linux事实上IP操作标准工具。
还有非常重要的NetworkManager服务
该服务是用来自动配置和管理网络连接的,所以通常不需要手动设置网络设置。但如果需要更改IP地址或DNS设置,可以使用NetworkManager GUI或在终端中编辑配置文件来更改网络配置。它通常以network-manager或NetworkManager.service的名称出现在系统中,当然该服务也不是必须的。
但这种混乱的局面还是引起了部分能人的不满,毕竟推陈出新才是linux社区的正道,因此nmcli工具粉墨登场。
nmcli工具是NetworkManager包的一部分。其在Linux中使用它来重新启动网络非常简单。可管理不同Linux版本的网络连接:
nmcli networking on|off
'nmcli -o'可展示当前网络运行的状态信息,等同于'systemctl status NetworkManager'。对命令行界面恐惧的人还可以尝试:nmtui,当然各类桌面中也集成了相关可视化工具。
windows下也有命令行的操作工具,如网络与TCP/IP Stack的重置:
netsh winsock reset
重置TCP/IP Stack
netsh int ip reset
Debian-NetworkConfiguration
Devuan4在vbox下的网口绑定
/etc/udev/rules.d/19-persistent-net.rules
#PCI device
#NAME:="some name" , := is used to make sure that device name will be persistent.
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="08:00:27:8D:76:46", ATTR{dev_id}=="0x0", ATTR{type}=="1", KERNEL=="eth*", NAME:="eth0"
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="08:00:27:D9:57:D2", ATTR{dev_id}=="0x0", ATTR{type}=="1", KERNEL=="eth*", NAME:="eth1"
# PCI Net device
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="08:00:27:8d:76:46", KERNEL=="eth*", NAME="eth0"
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="08:00:27:d9:57:d2", KERNEL=="eth*", NAME="eth1"
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="08:00:27:31:02:11", KERNEL=="eth*", NAME="eth2"
# PCI device
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="08:00:27:8d:76:46", ATTR{dev_id}=="0x0", ATTR{type}=="1", KERNEL=="eth*", NAME="eth0"
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="08:00:27:d9:57:d2", ATTR{dev_id}=="0x0", ATTR{type}=="1", KERNEL=="eth*", NAME="eth1"
udev项目很早就投入systemd阵营,导致一些non-systemd的发行版本下设备的管理工作不尽人意,虽有gentoo建立eudev项目,但结果依然不太理想;因此non-systemd的Linux操作系统的udev体系就得不到好的支撑。devuan下就会有此类问题的困扰:
devuan rename netcard name
eudev sometimes fails to generate initial hotplug events in devuan
因此上面的udev的rules规则基本上没有什么用处,真让人沮丧。
2024年11月,手动编写了脚本,借用ip指令以MAC地址绑定网络接口的名称:
use v5.20;
use Data::Dumper;
#241228 by zheng
#slove netcard name when system has more than 3.
#diy the cardname by its mac and config it.
#250118,add chage netcard name with orig begin with eth,plus it order index first
#then modify netcard name like openwrt
###netcards
my %ecardsmac;
##new net card config
my %nncc=(
'08:00:27:8d:76:46'=>{'nname'=>'eth1','cmd'=>'ip addr add 172.18.0.3/24 dev eth1'},
'08:00:27:31:02:11'=>{'nname'=>'eth2','cmd'=>'ip addr add dev eth2 192.168.25.1/24'},
'08:00:27:5e:b7:92'=>{'nname'=>'eth0','cmd'=>'dhclient eth0 -v'},
);
my ($ncidx_plus)=(10);
#所有的以太网卡
my @enc=('lo','vpn0');#需要排除的接口卡
my ($ncdir,$dh)=('/sys/class/net');
if(-d -x $ncdir){
opendir($dh,$ncdir);# && chdir($ncdir);
while(my $nc=readdir($dh)){
next if($nc=~/^\./);
next if(grep {$_ eq $nc} @enc);#主动过滤那些要排除的网卡
$ecardsmac{$nc}=get_phnc_mac("$ncdir/$nc");
}
}
foreach my $card (keys %ecardsmac){
if($card=~/(?<ncn>\w+[a-z])(?<nci>\d+$)/){
#change eth-net-card
if(($+{ncn} eq 'eth') && length($+{nci})){
my $ncard="$+{ncn}".($+{nci}+$ncidx_plus);
system(qq[ip link set $card down; ip link set $card name $ncard; ip link set $ncard up]);
$ecardsmac{$ncard}=$ecardsmac{$card};
delete $ecardsmac{$card};
}
}
}
foreach my $card (keys %ecardsmac){
say "Change Orig NetCard $card to $nncc{$ecardsmac{$card}}{nname}, and config it...";
system(qq[ip link set $card down; ip link set $card name $nncc{$ecardsmac{$card}}{nname}]);
system(qq[$nncc{$ecardsmac{$card}}{cmd}; ip link set $nncc{$ecardsmac{$card}}{nname} up]);
}
#从OS中取得信息如果是以太网卡侧返回其mac地址
sub get_phnc_mac{
my $ncd=shift;
my ($ist,$mac)=(0,undef);
chdir($ncd);
if(-l 'device'){
my $frt=get_oline_file("$ncd/type");
$ist=1,$mac=get_oline_file("$ncd/address") if($frt == 1);
}
return $ist?$mac:undef;
}
#返回只有一行文件的文件内容
sub get_oline_file{
my $fpn=shift;
my ($fh,$oline);
if(-r $fpn){
open($fh,'<',$fpn);
$oline=do{local $/;<$fh>};
chomp($oline);
close $fh;
$oline=~s/^\s+|\s+$//;
return $oline;
}else{
return undef;
}
}
END{
#say Dumper(\%nncc,\%ecardsmac);
exit(0);
}
OpenWRT在双网卡的情况下,也会出现网卡识别错乱的情形,而且也是重启后有惊喜。其下运行上述脚本时报需要perl的(Tie)包模块依赖:
perlbase-tie 5.28.1-9 21.89 KiB Tie perl module
使用此脚本后系统的网络配置文件(/etc/network/interfaces)就可以不使用了。另外不得不说一下,freebsd在vbox下多网卡时也会出现重启时之前设定网卡错位的问题,但比较好解决,使用系统工具:sysutils/ethname
在系统配置/etc/rc.conf中加入如下的配置:
ethname_enable="YES"
ethname_emN_mac="aa:bb:cc:dd:ee:ff"
就能解决网卡MAC与名称错位的问题了,在freebsd-v12下实测通过。