如何在Linux上更改网卡(eth1 <-> eth0)的顺序


20

安装系统后,有什么方法可以交换网络接口(eth1 <-> eth0)。

我全新安装的Debian 6.0 默认将PCI网络卡分配为“ eth0 ”,将主板集成网络设备分配为“ eth1 ”。问题是我想将集成设备用作默认(eth0)网络接口。

我已经编辑了:

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

交换名称,一切似乎都可以,并且网络正在运行,但是程序仍在尝试使用PCI网卡(现在为“ eth1 ”)作为默认接口。例如,iftop现在尝试使用“ eth1 ”作为默认设备,因为它在交换之前使用了“ eth0 ”。

这是纯粹的软件问题,因为尽管应用程序对其接口进行了命名,但它们仍尝试将找到的第一个设备用作默认设备,还是可以通过配置OS来解决此问题?


编辑:我写了一个小应用程序来打印iflist和PCI设备(eth1)出现在“ eth0 ” 之前。任何想法如何交换设备订单。


编辑:我发现了一个关于相同问题的线程,我尝试了他们提出的所有建议,除了“虚拟地”交换名称之外,其他解决方案均无用。


只是要注意,编辑/etc/udev/rules.d/70-persistent-net.rules并重新启动对我来说是
有用的

Answers:


18

我现在正在回答自己的问题,因为我终于找到了解决此问题的方法。

我发现可以通过卸载驱动程序然后以正确的顺序加载设备来重新排序设备。

第一种方法(bruteforce):

因此,我想出的第一种方法很简单,就是使用init.d脚本强行重新加载驱动程序。

以下init脚本是为Debian 6.0量身定制的,但是使用适当的init.d脚本,几乎所有发行版都可以使用相同的原理。

#!/bin/sh -e

### BEGIN INIT INFO
# Provides:          reorder-nics
# Required-Start:
# Required-Stop:
# Default-Start:     S
# Default-Stop:
# Short-Description: Reloads the nics in correct order
### END INIT INFO

#
# This script should reload the nic drivers in corrected order.
# Basically it just unloads and then loads the drivers in different order.
#

echo "Reloading NICs!"

# unload the drivers
modprobe -r driver_0        # eth0 nic interface
modprobe -r driver_1        # eth1 nic interface

# load the drivers in corrected order
modprobe driver_1
modprobe driver_0

#EOF

然后,必须将脚本添加到正确的运行级别目录。这可以在Debian上使用“ update-rc.d ”命令轻松完成。例如:update-rc.d reorder-nics start S


第二种方法(我认为更好):

我还发现了一种更优雅的方式(至少对于Debian和Ubuntu系统而言)。

首先,请确保内核不会自动加载NIC驱动程序。这可以通过在中创建黑名单文件来完成/etc/modprobe.d/。我创建了一个名为“ disable-nics.conf” 的文件。请注意,其中的文件/etc/modprobe.d/必须具有.conf后缀。另外,在其中命名模块/etc/modprobe.d/blacklist.conf不会影响内核自动加载模块,因此您必须创建自己的文件。

# Disable automatic loading of kernel driver modules
# Disable NIC drivers

blacklist driver_0     # eth0 by default
blacklist driver_1     # eth1 by default

然后以root身份运行' depmod -ae '

用' update-initramfs -u ' 重新创建initrd

最后,以正确的顺序将驱动程序名称添加到/ etc / modules文件中。

# /etc/modules: kernel modules to load at boot time.
#
# This file contains the names of kernel modules that should be loaded
# at boot time, one per line. Lines beginning with "#" are ignored.
# Parameters can be specified after the module name.

# drivers in wanted order
driver_1    # this one should be loaded as eth0
driver_0    # this one should be loaded as eth1

更改应在下次启动后生效。

但是,无需重新启动;使用以下命令轻松切换设备(当然,以root用户身份):

modprobe -r driver_0; modprobe -r driver_1; modprobe driver_1; modprobe driver_0

我在搜索解决方案时发现的一些有用链接:


2
+1当然,您绝对不应该只有一个以上的投票。
bahamat 2011年

我有一个类似的问题:我有一个集成的NIC,然后有时我运行一个创建另一个接口的VPN程序。VPN接口似乎总是优先,但我不知道为什么。我只希望在极少数情况下使用它(我希望使用它的应用程序必须指定VPN接口)。有任何想法吗?^ _ ^无论如何,我可能很快就会发布一个新问题。
赎罪有限

2

您可以使用netdev=内核命令行参数(您需要将其传递给grub中的内核)来指示内核将给定的irq链接到给定的接口,例如:netdev=irq=2,name=eth0


1
我使用grub config修改启动了我的机器,但在许多应用程序中,我仍将eth1作为默认设备。我检查了网络信息和dmesg的,它说的是,集成NIC仍具有“ eth1的 ”为IFNAME: forcedeth 0000:00:04.0: ifname eth1, PHY OUI 0x57d @ 1, addr 40:40:00:40:40:40。这不是一个很严重的问题,但是它确实使我不寒而栗,因为集成的是1GB卡,它应该是默认设备。
Athabaska Dick

1
我现在尝试使用nameif更改网络接口名称,但是看起来它的作用与udev相同。“实际” NIC顺序没有变化。我还尝试更改了PCI NIC的物理位置,但这也无济于事。集成NIC具有IRQ 22,而PCI NIC具有IRQ 17,因此内核似乎通过IRQ对它们进行了排序,用户无法以任何方式改变这一事实。有什么新主意吗?
Athabaska Dick

1

您可能必须进入每个受影响的程序配置文件,并将“ eth1”更改为“ eth0”。安装或首次使用当前检测到的NIC运行时,将设置此类程序的默认设置。

我使用Linux作为路由器,并且在使用脚本时遇到此问题。我现在有一个名为一个很好的剧本片段netconf,我在源每当我需要使用NIC名称的任何其他脚本,这个文件给了我一个中央位置来指定它们(即LAN_IFACE=eth0WAN_IFACE=eth1等)


2
看起来很多程序只是依赖<net / if.h>标头中的if_nameindex()函数。他们只是使用找到的第一个设备,而完全忽略了接口名称。我可以看到为什么这样做,使用第一个找到的设备比对名称进行排序要容易得多。
Athabaska Dick

1

您无法更改像这样的应用中默认使用的接口iftop。他们调用C库函数,if_nameindex并默认使用返回数组中的第一个元素。if_nameindexLinux上的GNU libc 是SIOCGIFCONFioctl的薄包装。这将根据网络驱动程序初始化的顺序和每个驱动程序检测每个设备的顺序以固定的顺序返回接口。

如果您真的不想传递-iiftop类似程序,则可以使用进行小型包装if_nameindex,以对返回列表中的元素进行重新排序LD_PRELOAD。我认为这比它值得的麻烦多得多。


我也设法将“问题”精确定位为if_nameindex功能。也许我现在就离开它。幸运的是,某些应用程序确实会检查接口名称。另一方面,某些应用程序甚至没有默认配置选项,因此我只需要使用-i选项。我只是想知道为什么内核加载选项netdev=irq=22,name=eth0不起作用?我认为应该可以在内核启动时更改NIC的顺序。
Athabaska Dick

快速浏览内核源代码(for_each_netdev宏)后,将按大致加载驱动程序的顺序枚举接口。您的界面可能使用不同的驱动程序,因此您必须安排要按所需顺序加载驱动程序。我希望这会很困难,特别是如果您希望通过内核升级进行调整的话。
吉尔斯(Gillles)“所以-别再邪恶了”,

1

如果它们具有不同的驱动程序,至少可以追溯到当天,您可以放入以下模块配置文件之一:

alias eth0 driver1
alias eth1 driver2

这是一些相当古老的知识,但可能会有所帮助。


-1

看一下“ ifrename”包。这使您可以根据各种信息(例如,在/ etc / iftab文件中配置的接口的MAC地址,驱动程序,中断...)重命名接口名称。

手册页中的一些示例:

   # This is a comment
   eth2      mac 08:00:09:DE:82:0E
   eth3      driver wavelan interrupt 15 baseaddress 0x390
   eth4      driver pcnet32 businfo 0000:02:05.0
   air*      mac 00:07:0E:* arp 1
   myvpn     SYSFS{address} 00:10:83:* SYSFS{type} 1
   bcm*      SYSFS{device} 0000:03:00.0 SYSFS{device/driver} bcm43xx
   bcm*      SYSFS{..} 0000:03:00.0 SYSFS{../driver} bcm43xx

欢迎使用U&L,您能为我们提供完整的答案,而不仅仅是提示吗?您不应该张贴诸如“有手册页...”之类的内容。
Archemar
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.