linux下使用udev更改接口卡
2011-01-12 11:16:28 阿炯

最近在ubuntu下新安装了一块Intel 82576 双千兆 PCI-E 网卡,用以替换服务器(Dell R610)上板载的4个Broadcom NetXtreme II 5709c的网络接口卡。将机器重启后进入bios将两组板载网卡(共4端口)禁用,在拆下机器安装上这块Intel的网卡,当进入系统后却发现新的那块网卡上的两个端口被赋名为eth4、eth5,而我希望它们直接取代我之前配置好的eth0及eth1口,这就要通过配置udev来实现了。

通过修改目录'/etc/udev/rules.d/'下的配置文件来实现网络接口是我们预期的顺序结果,在网络规则文件(70-persistent-net.rules )后系统加入新安装的两个接口,且命名为eth4和eth5,现将其更名为eth0及eth1,当然原来的接口名称要么改掉要么将其注释。另外,接口名称编号与其硬件地址编号有顺序大小关系。

另注:在虚拟机下有时也会发生网络接口顺序错乱的现象,也可通过这种方法修正。

# more /etc/udev/rules.d/70-persistent-net.rules

# This file was automatically generated by the /lib/udev/write_net_rules
# program, run by the persistent-net-generator.rules rules file.
#
# You can modify it, as long as you keep each rule on a single
# line, and change only the value of the NAME= key.

# PCI device 0x14e4:0x1639 (bnx2)
#SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="00:22:19:6b:ee:a4", ATTR{dev_id}=="0x0", ATTR{type}=="1", KERNEL=="eth*", NAME="eth1"

# PCI device 0x14e4:0x1639 (bnx2)
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="00:22:19:6b:ee:a8", ATTR{dev_id}=="0x0", ATTR{type}=="1", KERNEL=="eth*", NAME="eth3"

# PCI device 0x14e4:0x1639 (bnx2)
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="00:22:19:6b:ee:a6", ATTR{dev_id}=="0x0", ATTR{type}=="1", KERNEL=="eth*", NAME="eth2"

# PCI device 0x14e4:0x1639 (bnx2)
#SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="00:22:19:6b:ee:a2", ATTR{dev_id}=="0x0", ATTR{type}=="1", KERNEL=="eth*", NAME="eth0"

# PCI device 0x8086:0x10c9 (igb)
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="00:1b:21:5a:57:b1", ATTR{dev_id}=="0x0", ATTR{type}=="1", KERNEL=="eth*", NAME="eth1"

# PCI device 0x8086:0x10c9 (igb)
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="00:1b:21:5a:57:b0", ATTR{dev_id}=="0x0", ATTR{type}=="1", KERNEL=="eth*", NAME="eth0"

多个同类型设备(网卡、声卡)每次启动的都不同,可以明显地看到,原来的bcm网的的驱动为'bnx2',而新换上的intel的网卡驱动为'igb',而且的硬件地址编码的最后一位是相邻的。这里对'NAME='后的内容进行更改即可,重启服务器后实现。

因为udev同时加载所有模块,所以一些设备可能初始化顺序不同。例如同时有两个网卡时,它们总是在eth0和eth1之间变来变去。

常用的解决办法是在您的rc.conf文件中通过修改MODULES队列来指明顺序。这个队列里的模块将在udev自动加载之前由系统加载,因此您可以控制模块在启动时加载顺序。

# 在e100之前加载8139too
MODULES=(8139too e100)

另一个解决网卡的方法是使用udev方法为每个网卡静态命名。创建文件/etc/udev/rules.d/10-network.rules然后将不同的网卡通过MAC地址绑定到不同的名字上:
SUBSYSTEM=="net", SYSFS{address}=="aa:bb:cc:dd:ee:ff", NAME="lan0"
SUBSYSTEM=="net", SYSFS{address}=="ff:ee:dd:cc:bb:aa", NAME="wlan0"

同时,您需要注意以下内容:
    * 您可以通过下面的命令获得网卡的MAC地址:: udevinfo -a -p /sys/class/net/
    * 注意在udev规则文件中使用小写的16进制MAC地址,因为udev无法识别大写的MAC地址。
    * 一些用户在使用旧的命名方式时出现问题,例如: eth0, eth1, 等等. 如果出现这个问题,试试使用 "lan"或者"wlan"之类的名字.

当然,对网卡的重新命名不一定要沿用eth0.1.2...等名称,也可以为其取更形象的名称,可以参考下面的文档:

Create a new file in the udev rules directory, e.g. /etc/udev/rules.d/010_netinterfaces.rules

In it specify the renaming in the following way for each interface on its own line

KERNEL="oldnameprefix*", SYSFS{address}=="MACaddress", NAME="newname"

where the oldnameprefix is typically eth. Note that in the MAC address, the hexadecimal digits should be in lowercase, otherwise udev fails to match them properly with the network interface.

You have quite a bit of freedom in choosing the new name, We recommend to keep it short and without any spaces or weird characters though. You can e.g. specify a fixed eth0, eth1, eth2 for specific MAC addresses, or you can name them after their use, or anything really. Remember that some applications that poke on a low level may dislike them not being called in the normal fashion of eth0, eth1..etc

Examples using udev

Example: Three network interfaces being present on a computer, setting a fixed eth0, eth1 and eth2 as their names.

KERNEL=="eth*", SYSFS{address}=="00:12:34:fe:dc:ba", NAME="eth0"
KERNEL=="eth*", SYSFS{address}=="00:56:78:98:76:54", NAME="eth1"
KERNEL=="eth*", SYSFS{address}=="00:90:ab:32:10:fe", NAME="eth2"

Example: Three network interfaces (one Intel, one NVIDIA, and one 3Com) being present on a computer, naming them after the manufacturer of the interfaces.

KERNEL=="eth*", SYSFS{address}=="00:12:34:fe:dc:ba", NAME="eth-intel"
KERNEL=="eth*", SYSFS{address}=="00:56:78:98:76:54", NAME="eth-nv"
KERNEL=="eth*", SYSFS{address}=="00:90:ab:32:10:fe", NAME="eth-3com"

Updating network configuration

If you named the interfaces in a different fashion as they were named before, the network configuration needs to be updated for the new interface device names to be used.

Edit the /etc/network/interfaces file, and change all instances of the old names to the new names.

E.g. if you previously used eth0 and have renamed it newname, you'd replace all instances of eth0 in that file with newname

But if you just put a fixed eth0, eth1, ... as their names, you just need to make sure the one you want to have as the primary network interface is set to the one you want in the file.

Example

Having renamed the existing eth0, eth1, and eth2 to eth-intel, eth-nv and eth-3com, choosing to use the eth-intel one as the primary interface

The /etc/network/interfaces file before changes

# The primary network interface
auto eth0
iface eth0 inet dhcp

# Currently unused network interfaces
iface eth1 inet dhcp
iface eth2 inet dhcpThe file after changes:

# The primary network interface
auto eth-intel
iface eth-intel inet dhcp

# Currently unused network interfaces
iface eth-nv inet dhcp
iface eth-3com inet dhcp

Reboot and verify your configuration

Reboot the computer and verify that the new network interface names are in use with e.g. ifconfig

#ifconfig newname

Where newname is the new interface name you specified. Repeat procedure for each one you renamed.