Ensuring network interfaces remain named consistently
Posted by Anonymous on Thu 16 Nov 2006 at 11:08
I was answering a recent weblog post and I figured the reply was sufficiently interesting to be a short and sweet article, plus the feedback from you guys is always great. So, here it is: Making sure that network interface ordering remains constant.
A NIC card trick
Cards::ShuffleIf you have more than one network card, there is no guarantee that eth0 when you first boot up remains eth0 in the next boot. It could swap with eth1. This can happen especially if the cards are the same chipset, I reckon. If you change kernels or switch to using something like hotplug or udev you can also find the same problem.
Cards::DealA simple way to fix this is to use the nameif command which is contained in the net-tools package.
For example add the following contents to /etc/mactab file like this, (this example is for three cards):
want_eth0 00:23:B7:89:39:E2 want_eth1 00:08:A3:20:F8:29 want_eth2 00:50:BA:29:B7:32
The things to the right are the MAC addresses (which you can find by running "ifconfig | grep HWaddr", or "ip | grep ether").
Then create a script under pre-up:
$cat /etc/network/if-pre-up.d/nameif #!/bin/sh PATH=/sbin nameif #above tries to set want_ethX names in /etc/mactab nameif eth0 00:23:B7:89:39:E2 nameif eth1 00:08:A3:20:F8:29 nameif eth2 00:50:BA:29:B7:32
Cards::Play
Now "/etc/init.d/networking restart" will assign the interfaces in the order you want. The pre-up script is quite dirty (it whines while doing the job), but it will do what you intend.
PJ
Belzabar Software
[ Parent | Reply to this comment ]
It seems the most important line is
----
ENV{INTERFACE_NEW}=="?*", NAME="$env{INTERFACE_NEW}"
----
But where does the environment variable INTERFACE_NEW come from and what is its content ?
[ Parent | Reply to this comment ]
# These rules generate rules to keep network interface names unchanged # across reboots write them to /etc/udev/rules.d/z25_persistent-net.rules.and then looking at referenced /etc/udev/rules.d/z25_persistent-net.rules provides a clue :-)
[ Parent | Reply to this comment ]
[ Send Message | View dkg's Scratchpad | View Weblogs ]
[ Parent | Reply to this comment ]
I'm thinking that simply removing the z25_persistent-net.rules file before imaging may work, but that seems too easy.
Does anyone have any ideas?
[ Parent | Reply to this comment ]
[ Parent | Reply to this comment ]
add a file in /etc/udev/rules.d/custom_network.rules with
--- begin ---
# 3com network card (3c59x)
KERNEL=="eth*", SYSFS{address}=="00:04:76:10:5e:94", NAME="mega1"
# realtek onboard card (r8169)
KERNEL=="eth*", SYSFS{address}=="00:11:09:ce:a8:a4", NAME="mega2"
--- end ---
and change every reference in /etc with mega1 or mega2 or whatever (easily found with grep -r "eth[0-9]")
restart - works.
[ Parent | Reply to this comment ]
One gotcha: I had a working 'ifrename' setup. I upgraded to etch and then things started to go wrong... the udev ruleset tries to live peaceably with ifrename, if it's installed, but it doesn't quite work (from memory, it broke after ACPI suspend-to-RAM). Once I saw that udev was the One True Way and uninstalled ifrename, everything was fine.
[ Parent | Reply to this comment ]
You can choose arbitrary, self-explaning names like "ethinternal" instead of "eth0", and you're not bound to use MAC addresses to identify your NIC: you could also use the driver type, the PCI ID...
[ Parent | Reply to this comment ]
PJ
[ Parent | Reply to this comment ]
[ Parent | Reply to this comment ]
[ Parent | Reply to this comment ]
Short answer: I s'pect it just growed.
Long answer: Initially I thought just running nameif with /etc/mactab settings defining
the names eth[0-2] (rather than want_eth[0-2]) would do the change. I ran into problems
because the names were already in use. So as a more universal solution I assigned them
placeholder names (hence the want_ prefix) and added a second stage in the pre-up
script. Ideally I should just have the names all in one place, in the pre-up script.
Actually, ideally we should scrap nameif, and use ifrename instead - ifrename doesn't
need us to put in a placeholder name.
PJ
[ Parent | Reply to this comment ]
[ Send Message | View dkg's Scratchpad | View Weblogs ]
[ Parent | Reply to this comment ]
as i am currently using this & i edit it when i add/change cards
[ Parent | Reply to this comment ]
[ Send Message | View dkg's Scratchpad | View Weblogs ]
[ Parent | Reply to this comment ]
On my system I have my /etc/mactab file like so:
lan 00:04:23:A8:D8:EC
dmz 00:04:23:A8:D8:ED
isp 00:14:6C:72:FD:41
And then I just put a call at the top of my /etc/init.d/networking script like so:
[ -x /sbin/nameif ] && [ -r /etc/mactab ] && /sbin/nameif
You could put the above command into the if-up script instead I'd imagine.
[ Parent | Reply to this comment ]
As others have pointed out, udev is the One True Way if you have moved upward from sarge.
PJ
[ Parent | Reply to this comment ]
#!/bin/sh
if [ -n "$IF_MAC" ]
then
nameif $IFACE $IF_MAC
fi
(nope, it's not my original idea, I've got it from similar discussion on one of Debian lists over a year ago)
This way /etc/network/interfaces can contain:
auto lan0
iface lan0 inet static
mac 00:aa:bb:cc:dd:ee
address 192.168.0.1
netmask 255.255.255.0
so I can have everything in one place.
btw. I like netX, lanX, dmzX instead of standard ethX (and I don't need to do tricks with double renaming). I wonder if someone knows good three letter acronym for wireless interfaces? ;)
[ Parent | Reply to this comment ]
The output of "ip link show" is short enough and contains the current interface names.
[ Parent | Reply to this comment ]
The "show" is implicit by the way. A good tip is to use full commands for scripts so you can understand them later, and to use abbreviated commands for command line interaction while you're debugging for convenience. Which makes sense.
[ Parent | Reply to this comment ]