1063 lines
43 KiB
Plaintext
Executable File
1063 lines
43 KiB
Plaintext
Executable File
Sane network interface management with Hotplug
|
|
----------------------------------------------
|
|
|
|
INTRODUCTION
|
|
------------
|
|
In the old days all wireless cards were managed by the
|
|
excellent Pcmcia subsystem and its rich configuration scripts, and
|
|
life was good. Then came the wireless PCI cards, then the wireless
|
|
USB dongles. Some unification was needed, and rather than adapt the
|
|
Pcmcia subsystem for PCI and USB, it was decided to create the much
|
|
simpler Hotplug system.
|
|
The USB subsystem already uses Hotplug. The Pcmcia subsystem
|
|
is migrating to it : CardBus cards (32 bits) already use Hotplug,
|
|
whereas Pcmcia cards (16 bits) still use the old Pcmcia scripts.
|
|
The Hotplug system is still in its infancy, but already shows
|
|
some good promise. Most users are disappointed at first by its
|
|
apparent lack of features compared to the Pcmcia scripts. In this
|
|
document, we will show how to fully exploit the Hotplug system and try
|
|
to implement the equivalent of all the functionality of the Pcmcia
|
|
scripts.
|
|
|
|
ASSUMPTIONS
|
|
-----------
|
|
The target audience of this document is mostly power users and
|
|
distribution maintainers, but it should give enough clues to help
|
|
newbies. You should have read and understood DISTRIBUTIONS.txt. The
|
|
procedures described here are more advanced than the simple
|
|
configuration described in DISTRIBUTIONS.txt.
|
|
The main focus is of course on removable wireless interfaces,
|
|
but we will to talk about network interface management in general, so
|
|
this should apply also to built-in Ethernet cards.
|
|
|
|
PROBLEM STATEMENT
|
|
-----------------
|
|
Let's assume a Linux system and two or more network devices,
|
|
Device A and Device B. Those devices may be built-in or removable,
|
|
they may be present or absent from the system at any time, and they
|
|
may activated in any particular order.
|
|
The user wants to assign Configuration A to Device A and
|
|
Configuration B to Device B, without the possibility that Device A
|
|
gets assigned Configuration B.
|
|
Different users may have different definitions of what is
|
|
Device A. For some, it's a specific instance of a specific hardware,
|
|
for others any hardware that meets some criteria (a wireless card, an
|
|
Ethernet card).
|
|
The user may also want to have multiple configurations for a
|
|
given device such that the chosen configuration depends on various
|
|
factors, just as with the old Pcmcia schemes. Device A may need
|
|
Configuration A1 or Configuration A2 depending on those factors.
|
|
By default, all network interfaces are created using default
|
|
interface names (starting at "eth0" and going up). I call that the
|
|
"all my cards are eth0" problem : im most distributions, "eth0" points
|
|
to a single fixed configuration in the configuration
|
|
database. Clearly, this won't satisfy our requirements.
|
|
|
|
EXAMPLE SYSTEM
|
|
--------------
|
|
The distribution I use is Debian 3.0, and some parts of what I
|
|
say here will be specific to it. However, it should be easy to
|
|
translate this material to other distributions and I welcome additions
|
|
to this document.
|
|
|
|
The example system is as follows :
|
|
o Linux 2.6.X SMP kernel with hotplug support
|
|
o Fully modular system (all network drivers as modules)
|
|
o PCI Ethernet card : AMD PCnet LANCE (pcnet32 - eth4)
|
|
o PCI Ethernet card : HP 100VG J2585B (hp100 - eth2)
|
|
o ISA Wireless card : Old AT&T Wavelan (wavelan - eth3)
|
|
o ISA-Pcmcia bridge : VADEM VG-469 (i82365 - slot 0)
|
|
o PCI-CardBus bridge : Ricoh RL5c475 (yenta_socket - slot 2)
|
|
o Pcmcia 802.11 card : Aironet 350 (airo_cs - eth0)
|
|
o Pcmcia 802.11 card : Lucent Orinoco (orinoco_cs - eth0)
|
|
o CardBus 802.11 card : SMC 2835W (prism54 - prism0)
|
|
|
|
This system just happens to be my Linux development box. It
|
|
has enough interfaces to make it interesting. All the examples I
|
|
present in this document are extracted from this system.
|
|
|
|
BASIC CONCEPTS
|
|
--------------
|
|
Most of the concept and tricks presented here are not really
|
|
new. The main contribution is to integrate them.
|
|
|
|
1) Removable network interfaces are managed by Hotplug
|
|
(Pcmcia, CardBus, USB...). We can't assume that those interfaces are
|
|
always present in this system and available at boot time (Pcmcia cards
|
|
were not made to be soldered in the Pcmcia slot). Therefore Hotplug is
|
|
the way to go.
|
|
2) Built-in PCI and ISA cards are managed by the init scripts,
|
|
as they have always been. The ISA subsystem will never have Hotplug
|
|
support, and hotplug is not necessary for PCI cards.
|
|
3) Built-in devices that are disable most of the time should
|
|
be enabled manually by the user. Therefore both Hotplug and the init
|
|
scripts should ignore those devices by default.
|
|
4) (1), (2) and (3) must be compatible on the same system and
|
|
play nice with each other.
|
|
|
|
5) A well defined and consistent network interface name is
|
|
assigned to each network hardware interface using 'ifrename'. Device A
|
|
is always named 'ethA' (or whatever name you like such as
|
|
'mynetworkcard').
|
|
6) No interface is called 'eth0' (or 'wlan0'). Any unknown
|
|
device would be 'eth0', so known devices should be called something
|
|
else.
|
|
7) Multiple configurations for a single interface (schemes)
|
|
are managed by the ifup/ifdown subsystem.
|
|
|
|
CONFIGURATION FROM INIT SCRIPTS
|
|
-------------------------------
|
|
It may seem paradoxical, but before setting up Hotplug, we
|
|
need to make sure that the initialisation of network cards via init
|
|
scripts is done properly and doesn't get in the way of the Hotplug
|
|
subsystem.
|
|
The configuration of network cards via init scripts is the
|
|
traditional way networking is initialised in Linux. The advantage of
|
|
this method is that it's very well documented and understood, and has
|
|
not changed much over the years. Unfortunately, it doesn't adequately
|
|
support removable cards.
|
|
|
|
The init scripts perform the following 3 functions in order :
|
|
1) Load necessary driver modules
|
|
2) Rename interface to name chosen by the user
|
|
3) Configure those network interfaces
|
|
|
|
1) Applicability
|
|
----------------
|
|
Configuration from init scripts is applicable to any built-in
|
|
network interface (ISA, PCI...), i.e., interfaces available at boot
|
|
time and that will never be removed from the system.
|
|
The Hotplug subsystem also has the ability to configure some
|
|
of the built-in network interfaces, such as PCI cards. However, there
|
|
is a class of devices that will never have Hotplug support, such as
|
|
ISA and EISA cards.
|
|
|
|
2) Loading driver modules (if/as needed)
|
|
----------------------------------------
|
|
Most distributions build the kernel drivers as modules. This
|
|
modular setup allows to minimise the amount of memory used by the
|
|
system and the flexible loading/unloading of drivers.
|
|
You can also compile your kernel with static drivers
|
|
(non-modular). In that case, the driver will always be available in
|
|
the kernel, you don't need to configure the module subsystem, so you
|
|
can skip directly to the next section.
|
|
|
|
There are 3 alternatives to manage device drivers as
|
|
modules.
|
|
1) Some distributions have an explicit list of modules
|
|
that are loaded at boot time. If you want to use that feature you need
|
|
to check the documentation of your distribution.
|
|
2) Some system, such as Hotplug, Discover or Kudzu,
|
|
can scan the various buses of the PC and load the appropriate
|
|
drivers. This is mostly configuration-free, but may not support all
|
|
devices and may load unnecessary modules.
|
|
3) The module subsystem also allows to load modules
|
|
'on-demand'. When an application try to access or configure a network
|
|
interface, the corresponding module is loaded.
|
|
|
|
I personally prefer to use the 'on-demand' feature of the
|
|
module subsystem, as this allow you to not have to specify a static
|
|
list of modules that need to be loaded, and only modules really needed
|
|
are loaded which saves kernel memory. You can also choose which module
|
|
to load when there are multiple modules available that support your
|
|
hardware (which happens quite often).
|
|
|
|
With kernel 2.6.X the module subsystem is configured in the
|
|
file /etc/modprobe.conf or files in the directory /etc/modprobe.d/. To
|
|
configure 'on-demand' module loading, on my test system I need to add
|
|
to the following lines to the configuration :
|
|
|
|
--------- /etc/modprobe.d/local or /etc/modprobe.conf ------
|
|
# HP 100VG J2585B PCI card
|
|
alias eth2 hp100
|
|
|
|
# AMD AMD PCnet LANCE PCI card
|
|
alias eth4 pcnet32
|
|
|
|
# Old AT&T Wavelan ISA card
|
|
alias eth3 wavelan
|
|
options wavelan io=0x390 irq=15
|
|
------------------------------------------------------------
|
|
|
|
Your distribution may already have lines for your interfaces,
|
|
either replace these or make sure they are correct (some distributions
|
|
are notorious for picking the wrong driver name in some cases). This
|
|
file also contains configuration for lot of other subsystems,
|
|
obviously you don't want to touch that.
|
|
In this file, you put the name you would like the interface to
|
|
have (we'll fix that in a minute). Note that for modern PCI cards this
|
|
is much more straightforward than for old ISA cards.
|
|
|
|
3) Installing 'ifrename'
|
|
------------------------
|
|
You will need to install ifrename on your system. 'ifrename'
|
|
is part of the Wireless Tools package (version 27 and later) and is a
|
|
complete rewrite of the now obsolete 'nameif'.
|
|
Some distributions, such as Debian Sarge, offer a separate
|
|
package for 'ifrename', and in this case you should just install this
|
|
package. Other distributions may include ifrename as part of their
|
|
'wireless-tools' package (this should be the case for Gentoo, Fedora
|
|
and Mandrake). Other distributions, such as Debian 3.0, don't include
|
|
ifrename at all, so you should compile yourself a recent version of
|
|
Wireless Tools (v27 or later) and install it.
|
|
|
|
In any case, you should verify that 'ifrename' is properly
|
|
installed and check the path needed to call it :
|
|
--------------------------
|
|
> which ifrename
|
|
/sbin/ifrename
|
|
--------------------------
|
|
Most distributions will install 'ifrename' in '/sbin', while if
|
|
you compile your own wireless tools, it will be in '/usr/local/sbin'.
|
|
|
|
4) Making the boot scripts call 'ifrename'
|
|
------------------------------------------
|
|
You need to make sure 'ifrename' is run at boot time. Most
|
|
distributions don't do that yet by default.
|
|
This is a part that is distribution-specific, so you will need
|
|
to look into your own init files, or ask people familiar with your
|
|
distribution. It will need to run just before the call to 'ifup' or
|
|
'ifconfig' command.
|
|
|
|
In Debian 3.0 and Debian Sarge, it needs to be run from
|
|
/etc/init.d/networking, which is not the default. The necessary patch
|
|
is below :
|
|
|
|
----------------------------------------------------------------
|
|
--- networking-orig Wed Feb 18 13:56:23 2004
|
|
+++ networking Fri Feb 20 14:51:06 2004
|
|
@@ -120,6 +120,15 @@ case "$1" in
|
|
doopt syncookies no
|
|
doopt ip_forward no
|
|
|
|
+ # Optionally remap interface names based on MAC address.
|
|
+ # '/sbin/ifrename' is part of wireless-tools package.
|
|
+ # /etc/iftab is currently not created by default. Jean II
|
|
+ if [ -x /sbin/ifrename ] && [ -r /etc/iftab ]; then
|
|
+ echo -n "Remapping network interfaces name: "
|
|
+ ifrename -p
|
|
+ echo "done."
|
|
+ fi
|
|
+
|
|
echo -n "Configuring network interfaces: "
|
|
ifup -a
|
|
echo "done."
|
|
----------------------------------------------------------------
|
|
Don't forget to set the appropriate path to the ifrename
|
|
command (see step (3) above).
|
|
|
|
You may also want to also set the proper options for ifrename
|
|
(check the man page).
|
|
The option '-p' enables module autoloading compatibility.
|
|
The default version of 'ifrename' also includes some special
|
|
Debian support : using "ifrename -p -d", only the proper modules are
|
|
loaded. If you are using Debian, you should use this option.
|
|
|
|
5) Renaming interfaces
|
|
----------------------
|
|
As stated above, we use 'ifrename' to assign names to
|
|
interfaces.
|
|
|
|
First, you need to get the MAC address of each of your
|
|
interfaces. You can read the MAC address on the label of the card, or
|
|
display it using the 'ifconfig -a' command. Remember that the
|
|
interface won't load yet with the proper name, so you may need to do a
|
|
bit looking around :
|
|
|
|
-----------------------------
|
|
# modprobe pcnet32
|
|
# ifconfig eth0
|
|
eth0 Link encap:Ethernet HWaddr 00:10:83:34:BA:E5
|
|
[...]
|
|
-----------------------------
|
|
|
|
The configuration of 'ifrename' is simple, you just specify
|
|
which name should be used for each MAC address in the file
|
|
/etc/iftab :
|
|
|
|
--------- /etc/iftab ------------------------
|
|
# HP 100VG J2585B PCI card
|
|
eth2 mac 08:00:09:*
|
|
|
|
# Old AT&T Wavelan ISA card
|
|
eth3 mac 08:00:0E:*
|
|
|
|
# AMD AMD PCnet LANCE PCI card
|
|
eth4 mac 00:10:83:*
|
|
---------------------------------------------
|
|
|
|
The '*' in the MAC address is a wildcard and allows me to
|
|
replicate my configuration between multiple identical computers. If
|
|
you have to manage large number of computers (like a rack of servers
|
|
or clusters), then you may want to look at other selectors offered by
|
|
'ifrename'.
|
|
|
|
To test that ifrename works, do the following :
|
|
o Load all your drivers, see section (2)
|
|
o Check /proc/net/dev to see which interface exist
|
|
o Bring all interfaces down : ifconfig ethX down
|
|
o Run ifrename
|
|
o Check each interface with ifconfig
|
|
o Bring all interfaces up : ifconfig ethX up
|
|
|
|
6) Configuring interfaces
|
|
-------------------------
|
|
Most likely, your distribution is already doing this part
|
|
properly. Just assign the proper IP and wireless configuration to each
|
|
of the interface names you have chosen.
|
|
This part is distribution specific, and I already document it
|
|
in the file DISTRIBUTIONS.txt.
|
|
|
|
In Debian, you would need to modify the file
|
|
/etc/network/interfaces so that it looks something like this :
|
|
|
|
--------- /etc/network/interfaces -----------
|
|
# AMD PCnet LANCE PCI card
|
|
auto eth4
|
|
iface eth4 inet dhcp
|
|
|
|
# HP 100VG J2585B PCI card
|
|
auto eth2
|
|
iface eth2 inet static
|
|
address 10.0.0.2
|
|
netmask 255.255.255.0
|
|
broadcast 10.0.0.255
|
|
gateway 10.0.0.1
|
|
---------------------------------------------
|
|
|
|
This was the last part. Now, at your next boot, all your
|
|
interfaces should be assigned the proper name and the proper
|
|
configuration.
|
|
|
|
CONFIGURATION VIA HOTPLUG
|
|
-------------------------
|
|
Dealing with removable interfaces is similar to dealing with
|
|
built-in interfaces, the main difference is that we will use the
|
|
Hotplug scripts instead of the init scripts. Another difference is
|
|
that it will likely require more work on your part because most
|
|
distributions are not fully ready for it.
|
|
|
|
1) Applicability
|
|
----------------
|
|
The Hotplug configuration method is the best choice for any
|
|
removable network interface, such as :
|
|
o Pcmcia (16 bits) network cards
|
|
o CardBus (32 bits) network cards
|
|
o USB network dongles
|
|
o Hot-PCI network cards
|
|
It may also be used to manage other types of network
|
|
interfaces, although it may not be the best choice for them.
|
|
|
|
2) How Hotplug works
|
|
--------------------
|
|
Conceptually, Hotplug is very simple. When something
|
|
interesting happens, the Linux kernel generates an Hotplug event. This
|
|
runs the proper script from the /etc/hotplug directory.
|
|
There are 3 types of Hotplug events we care about :
|
|
o PCI event : a CardBus device is added or removed
|
|
from the system. The script /etc/hotplug/pci.agent is run.
|
|
o USB event : a USB device is added or removed
|
|
from the system. The script /etc/hotplug/usb.agent is run.
|
|
o Network event : a network interface is added or
|
|
removed from the system. The script /etc/hotplug/net.agent is run.
|
|
|
|
If we insert a CardBus network card in the system, the
|
|
following happens :
|
|
1) Kernel detects new CardBus device
|
|
2) Kernel generates PCI Hotplug event
|
|
3) /etc/hotplug/pci.agent runs, finds proper driver module
|
|
4) /etc/hotplug/pci.agent loads driver module
|
|
5) Driver module initialises, creates new network device
|
|
6) Kernel detects new network device
|
|
7) Kernel generates Network Hotplug event
|
|
8) /etc/hotplug/net.agent runs, configures network device
|
|
The sequence of events is similar for removals and USB devices.
|
|
|
|
3) Make sure ifup does not deadlock
|
|
-----------------------------------
|
|
<Most people should ignore this part>
|
|
The first problem is that we need to make sure the command
|
|
'ifup' does not deadlock by calling itself re-entrantly. If the system
|
|
has built-in interfaces, the 'ifup' may reenter itself at boot time
|
|
via Hotplug :
|
|
1) Init scripts start running
|
|
2) Init script calls 'ifup -a' to initialise built-in
|
|
network interfaces
|
|
3) 'ifup' auto-loads driver module for built-in network
|
|
interface 'eth4'
|
|
4) Driver module initialises, creates new network device
|
|
5) Kernel generates Network hotplug event
|
|
6) /etc/hotplug/net.agent runs, call 'ifup eth4'
|
|
Note that you can produce the same reentrancy if you call ifup
|
|
manually on an interface which module is not yet loaded.
|
|
|
|
The default version of 'ifup' for Debian 3.0 and Debian Sarge
|
|
is not reentrant and can therefore deadlock if not used properly. The
|
|
patch to make 'ifup' properly reentrant is available here :
|
|
http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=231197
|
|
Contemporary versions of Debian (Sarge and later) have a
|
|
net.agent script that contains workarounds to prevents deadlock
|
|
situations, so for normal use the default 'ifup' should work fine.
|
|
|
|
Other distributions have very different ifup programs and I
|
|
have not tried those (tell me about it !).
|
|
|
|
4) Installing Hotplug for Debian Sarge (testing/unstable)
|
|
---------------------------------------------------------
|
|
Thanks to the great work of many people, Debian Sarge has all
|
|
the necessary packages and hotplug support, and will work mostly 'out
|
|
of the box'.
|
|
You will need to install the following packages :
|
|
o hotplug
|
|
o ifrename
|
|
|
|
While the installation of Hotplug is simple, its configuration
|
|
may seem complex. The current network Hotplug script has 3 modes :
|
|
'all', 'auto' and 'hotplug'. However for our purpose they all produce
|
|
the same results when configured. This mode is controlled by the
|
|
variable NET_AGENT_POLICY in /etc/default/hotplug.
|
|
|
|
In the mode "all", Hotplug will run ifup for all network
|
|
events. This will result in failure messages if some interfaces have
|
|
already been configured by the init scripts. This mode is not
|
|
recommended.
|
|
|
|
In the mode "auto", Hotplug will run ifup only for those
|
|
interfaces listed in a auto stanza in /etc/network/interfaces. If
|
|
you choose this mode, you need to put in /etc/network/interfaces a
|
|
"auto" line for the interfaces you want to control with hotplug.
|
|
--------- /etc/network/interfaces -----------
|
|
# Enable Hotplug support for "auto" mode (Sarge and later)
|
|
auto eth0 eth1 eth2 eth3 eth4 wlan0 wlan1 prism0 prism1 airo0 airo1
|
|
---------------------------------------------
|
|
This will result in some failure message at boot time, the
|
|
init script will attempt to enable all those interfaces, and generate
|
|
an error for all those not available at this time. It will also
|
|
generate an error messages for interface which have already been
|
|
configured by the init scripts. This mode is also not recommended.
|
|
|
|
In the mode "hotplug", hotplug network events are ignored by
|
|
ifup by default. To enable them you will need to add the following
|
|
lines to /etc/network/interfaces :
|
|
--------- /etc/network/interfaces -----------
|
|
# Enable Hotplug support for "hotplug" mode (Sarge and later)
|
|
mapping hotplug
|
|
script echo
|
|
---------------------------------------------
|
|
|
|
To enable them for only selected interfaces, e.g., ethA, make
|
|
/etc/network/interfaces look like this :
|
|
--------- /etc/network/interfaces -----------
|
|
# Enable Hotplug support for "hotplug" mode (Sarge and later)
|
|
mapping hotplug
|
|
script grep
|
|
map ethA
|
|
---------------------------------------------
|
|
|
|
5) Installing Hotplug for Debian 3.0
|
|
------------------------------------
|
|
Debian 3.0 doesn't come by default with hotplug, but the
|
|
hotplug package is available as regular Debian package (on the CD or
|
|
downloadable in Debian archive), so you can just install that.
|
|
|
|
Unfortunately, this version of hotplug is not fully compatible
|
|
with kernel 2.6.X. You will need to do the following modifications to
|
|
the file /etc/hotplug/net.agent.
|
|
|
|
------- /etc/hotplug/net.agent ------------------
|
|
--- net.agent-d1 Fri Feb 20 18:18:05 2004
|
|
+++ net.agent Fri Feb 20 18:22:50 2004
|
|
@@ -26,7 +26,7 @@ if [ "$INTERFACE" = "" ]; then
|
|
fi
|
|
|
|
case $ACTION in
|
|
-register)
|
|
+add|register)
|
|
|
|
case $INTERFACE in
|
|
# interfaces that are registered after being "up" (?)
|
|
@@ -52,7 +52,7 @@ register)
|
|
mesg $1 $ACTION event not handled
|
|
;;
|
|
|
|
-unregister)
|
|
+remove|unregister)
|
|
# Assume that we want to run ifdown no matter what,
|
|
# because it is not going to remove the data from the
|
|
# ifstate database otherwise.
|
|
-------------------------------------------------
|
|
|
|
Compared to the version in Sarge, this older version of
|
|
hotplug is much more basic, and doesn't have any scanning at boot time
|
|
and doesn't need to be enabled in /etc/network/interfaces.
|
|
|
|
6) Installing hotplug on other distributions
|
|
--------------------------------------------
|
|
The canonical version of hotplug is available at :
|
|
http://linux-hotplug.sourceforge.net/
|
|
|
|
Most distributions have customized hotplug packages and
|
|
chances are that the canonical version won't completely work on your
|
|
system. All these various changing versions make it difficult for me
|
|
to tell what exactly needs to be changed in the hotplug scripts to
|
|
make them work. However, most should work out of the box.
|
|
|
|
My guess is that in a few releases, all these problems will
|
|
sort themselves out. Just be patient.
|
|
|
|
7) Dealing with 'init' hotplug
|
|
------------------------------
|
|
In addition to the standard kernel Hotplug events, modern
|
|
versions of the Hotplug scripts add init scripts that scan the system
|
|
buses and generate pseudo Hotplug events at boot time. For the PCI
|
|
buses, the script /etc/hotplug/pci.rc is run, for the USB bus,
|
|
/etc/hotplug/usb.rc is run.
|
|
The end result is that the Hotplug subsystem will also attempt
|
|
to configure built-in devices :
|
|
1) Kernel boots
|
|
2) Init runs, start to initialise the OS
|
|
3) /etc/hotplug/pci.rc runs, generates pseudo Hotplug event
|
|
4) /etc/hotplug/pci.agent loads driver module
|
|
5) Driver module initialises, creates new network device
|
|
6) Kernel generates Network Hotplug event
|
|
7) /etc/hotplug/net.agent runs, configures network device
|
|
|
|
At this point, you realise that at initialisation, both
|
|
Hotplug and the regular init scripts (see "CONFIGURATION FROM INIT
|
|
SCRIPTS") are trying to configure the same devices in parallel. This
|
|
may create problems and is totally redundant.
|
|
Another reason I don't like this mechanism is that it blindly
|
|
attempts to load drivers for all hardware present on the system and
|
|
doesn't use the module loader configuration files to select preferred
|
|
drivers. It's fairly common to have multiple drivers for a given
|
|
hardware, and because of Murphy's law, Hotplug will usually load the
|
|
wrong one. It's also fairly common to have hardware on the system that
|
|
doesn't need enabling (for example, the IDE controller on my SCSI
|
|
machine), not loading the driver makes your kernel smaller and boot
|
|
faster.
|
|
|
|
Hotplug does have a way of disabling the loading of drivers
|
|
on a case by case basis. Drivers listed in /etc/hotplug/blacklist
|
|
will not be loaded.
|
|
Hotplug can be disabled for a whole subsystem by editing the
|
|
appropriate .rc script in /etc/hotplug, or just deleting/renaming
|
|
those files.
|
|
|
|
8) Making hotplug scripts call ifrename
|
|
---------------------------------------
|
|
The last hotplug step is to make sure that 'ifrename' is run
|
|
by the hotplug subsystem at the right time. As before, we want to run
|
|
it just before calling 'ifup'.
|
|
The latest version of the hotplug scripts have this feature
|
|
integrated. However, you need to check that the path used for calling
|
|
'ifrename' is the proper one on your system. And, for older versions
|
|
of hotplug scripts, you will need to add this support yourself.
|
|
|
|
Check the path for ifrename :
|
|
--------------------------
|
|
> which ifrename
|
|
/sbin/ifrename
|
|
--------------------------
|
|
|
|
The patch to add 'ifrename' to hotplug looks like :
|
|
|
|
------- /etc/hotplug/net.agent ------------------
|
|
--- net.agent-s2 Fri Feb 20 17:18:46 2004
|
|
+++ net.agent Fri Feb 20 17:32:43 2004
|
|
@@ -40,6 +40,21 @@ add|register)
|
|
# we can't do much here without distro-specific knowledge
|
|
# such as whether/how to invoke DHCP, set up bridging, etc.
|
|
|
|
+ # Run ifrename as needed - Jean II
|
|
+ # Remap interface names based on MAC address. This works around
|
|
+ # the dreaded configuration problem "all my cards are 'eth0'"...
|
|
+ # This needs to be done before ifup, otherwise ifup will get
|
|
+ # confused by the name change and because iface needs to be
|
|
+ # down to change its name.
|
|
+ if [ -x /sbin/ifrename ] && [ -r /etc/iftab ]; then
|
|
+ debug_mesg invoke ifrename for $INTERFACE
|
|
+ NEWNAME=`/sbin/ifrename -i $INTERFACE`
|
|
+ if [ -n "$NEWNAME" ]; then
|
|
+ debug_mesg iface $INTERFACE is remapped to $NEWNAME
|
|
+ INTERFACE=$NEWNAME
|
|
+ fi;
|
|
+ fi
|
|
+
|
|
# RedHat and similar
|
|
export IN_HOTPLUG=1
|
|
if [ -x /sbin/ifup ]; then
|
|
-------------------------------------------------
|
|
|
|
If your hotplug scripts already include ifrename support then
|
|
you should find a section in /etc/hotplug/net.agent looking like the
|
|
patch above. Otherwise, just cut'n'paste the patch above in the right
|
|
place.
|
|
The path for 'ifrename' is used twice above, so don't forget
|
|
to modify both occurences.
|
|
|
|
|
|
9) Loading driver modules
|
|
-------------------------
|
|
Wow ! The most difficult part is done.
|
|
In theory, you don't need to do any specific configuration for
|
|
the driver modules to be loaded. The 'pci.agent' and 'usb.agent'
|
|
should load the right driver module for you.
|
|
Also, you don't need to define aliases in /etc/modprobe.d/* or
|
|
in /etc/modprobe.conf, it's useless and may be counterproductive.
|
|
|
|
If you use a driver compiled statically in the kernel, you
|
|
also have nothing to do.
|
|
|
|
10) Renaming interfaces
|
|
-----------------------
|
|
We still use ifrename to assign names to interfaces. The
|
|
configuration of 'ifrename' is the same. To keep the possibility of
|
|
having multiple wireless cards (one in each CardBus slot), we use
|
|
wildcards in both the MAC address and the name :
|
|
|
|
--------- /etc/iftab -----------------------
|
|
# SMC 2835W wireless CardBus card
|
|
prism* mac 00:30:B4:*
|
|
---------------------------------------------
|
|
|
|
If you insert two cards, they would be named prism0 and
|
|
prism1. Note that 'name wildcarding' is a feature only available in
|
|
2.6.X and 2.4.30 and later, so if you use older version of 2.4.X you
|
|
will need to be explicit and list each card separatly :
|
|
|
|
--------- /etc/iftab -----------------------
|
|
# SMC 2835W wireless CardBus card
|
|
prism0 mac 00:30:B4:64:27:8B
|
|
prism1 mac 00:30:B4:64:27:8D
|
|
---------------------------------------------
|
|
|
|
11) Configuring interfaces
|
|
-------------------------
|
|
At this point, configuration of Hotplug interfaces is done
|
|
just like their built-in counterparts. This part is still distribution
|
|
specific, and still already documented in the file DISTRIBUTIONS.txt.
|
|
|
|
In Debian, you would need to modify the file
|
|
/etc/network/interfaces like this :
|
|
|
|
--------- /etc/network/interfaces -----------
|
|
# Enable Hotplug support (Sarge and later)
|
|
mapping hotplug
|
|
script grep
|
|
map prism0
|
|
|
|
# SMC 2835W wireless CardBus card
|
|
iface prism0 inet static
|
|
address 10.0.1.2
|
|
netmask 255.255.255.0
|
|
broadcast 10.0.1.255
|
|
wireless-essid THE_ESSID
|
|
wireless-mode ad-hoc
|
|
wireless-channel 5
|
|
---------------------------------------------
|
|
|
|
Note that you should not have wireless-* lines if you are
|
|
using waproamd to set these parameters.
|
|
|
|
Now, just cross your fingers and plug the card in the slot...
|
|
|
|
PCMCIA INTERFACES (16 bits)
|
|
---------------------------
|
|
The Pcmcia subsystem has quite some legacy, and can use
|
|
various configuration procedures. The Pcmcia subsystem exclusively
|
|
uses hotplug for 32 bits cards (if you are using the kernel Pcmcia
|
|
modules, which is the only option for 2.6.X). For 16 bit cards cardmgr
|
|
is still required for managing the sockets and loading
|
|
modules. Cardmgr is configured by files in the /etc/pcmcia directory.
|
|
|
|
To use Hotplug network configuration with 16 bits Pcmcia
|
|
cards, first make sure the Pcmcia subsystem is properly configured and
|
|
that cardmgr loads the right driver module (in most case, it
|
|
should). Then, make sure that you don't have any configuration entries
|
|
in /etc/pcmcia/network.opts and /etc/pcmcia/wireless.opts. Make sure
|
|
that none of the entries in your system network configuration use
|
|
'eth0' or 'wlan0' (in /etc/network/interfaces for Debian users).
|
|
Then, just follow the procedure described above for
|
|
"Configuration Using Hotplug" to configure your network cards.
|
|
|
|
You might want a little bit of explanation on why this magic
|
|
will work (which would help in case it doesn't work).
|
|
There are two types of Pcmcia network configuration scripts,
|
|
available as /etc/pcmcia/network. The original Pcmcia script
|
|
configures network cards using options found in
|
|
/etc/pcmcia/network.opts and /etc/pcmcia/wireless.opts. Most
|
|
distributions replace it with a script calling 'ifup'. By making sure
|
|
that network.opts and wireless.opts are "empty", we neutralise the
|
|
first set of scripts. By making sure no system configuration uses
|
|
'eth0' or 'wlan0', we neutralise the second set of scripts, the script
|
|
would call 'ifup' with the default interface name, which is usually
|
|
'eth0', ifup would not find a configuration for it and would just
|
|
ignore it.
|
|
The card would still be configured because hotplug network
|
|
events are generated for every interfaces, not only for devices
|
|
managed by hotplug. So, net.agent would receive an event and perform
|
|
the necessary steps to configure it.
|
|
|
|
Personally, I'm still using the original Pcmcia scripts for my
|
|
Pcmcia cards as described in the file PCMCIA.txt, because it still
|
|
works and I will migrate my complex configurations over time.
|
|
You can also decide to not use Hotplug for Pcmcia cards and
|
|
modify the distribution Pcmcia scripts in /etc/pcmcia/* to handle
|
|
Pcmcia cards with ifrename. You would need to modify
|
|
/etc/pcmcia/network to add 'ifrename' before 'ifup' the same way it
|
|
was done for /etc/hotplug/net.agent. But, as in the long term Pcmcia
|
|
will migrate to Hotplug, I would not bother...
|
|
|
|
MANUAL LOADING, DOCKING STATIONS
|
|
--------------------------------
|
|
Manual loading is used for built-in network interfaces that
|
|
are only use at specific time, and that you want disabled the rest of
|
|
the time. We assume that you still use modules so that when the
|
|
interface is not used you can remove the driver from the kernel.
|
|
|
|
First, you need to set the configuration for those interfaces,
|
|
the same way it's done for other network interfaces. The main
|
|
difference is that you need to specify that those interfaces should
|
|
not be enabled at boot time. It's also a good idea to disable Hotplug
|
|
init scripts.
|
|
With Debian, you just need to make sure that the 'auto"
|
|
keyword doesn't apply to this interface.
|
|
|
|
If you use drivers statically built in the kernel, make sure
|
|
that ifrename runs at boot time (see CONFIGURATION FROM INIT
|
|
SCRIPTS). Once it's done, you can just enable and disable those
|
|
interfaces with 'ifup ethX' and 'ifdown ethX'.
|
|
|
|
If you use both a modular system, make sure that the
|
|
'on-demand' module loading is properly configured :
|
|
|
|
--------- /etc/modprobe.d/local or /etc/modprobe.conf ------
|
|
# HP 100VG J2585B PCI card
|
|
alias eth2 hp100
|
|
|
|
# AMD AMD PCnet LANCE PCI card
|
|
alias eth4 pcnet32
|
|
------------------------------------------------------------
|
|
|
|
Then, you should instruct 'ifup' to load module and use
|
|
ifrename prior to configuring the interface, and remove the module
|
|
when going down. With Debian, this is done with :
|
|
|
|
--------- /etc/network/interfaces -----------
|
|
# AMD AMD PCnet LANCE PCI card
|
|
# noauto
|
|
iface eth4 inet dhcp
|
|
pre-up /sbin/ifrename -p -n eth4
|
|
post-down /sbin/modprobe -r eth4
|
|
|
|
# HP 100VG J2585B PCI card
|
|
# noauto
|
|
iface eth2 inet static
|
|
address 10.0.0.2
|
|
netmask 255.255.255.0
|
|
broadcast 10.0.0.255
|
|
gateway 10.0.0.1
|
|
pre-up /sbin/ifrename -p -n eth2
|
|
post-down /sbin/modprobe -r eth2
|
|
---------------------------------------------
|
|
|
|
We use the '-n' option of ifrename to specify the name of the
|
|
interface after renaming. This assume that the mapping for those
|
|
interfaces don't use wildcards. The '-p' option make sure ifrename
|
|
probes the module prior to using it.
|
|
Using "modprobe -r" make sure that if the driver is composed
|
|
of multiple module all the modules are unloaded.
|
|
|
|
To enable the interface, just use :
|
|
-----------------------------------
|
|
ifup eth4
|
|
-----------------------------------
|
|
And to disable the interface :
|
|
-----------------------------------
|
|
ifdown eth4
|
|
-----------------------------------
|
|
|
|
This solution is obviously Debian specific, but could be
|
|
adapted to other distributions. If you can't manage to get your
|
|
distributions to use those tricks, you can do things manually.
|
|
If you don't use Hotplug, you enable an interface with :
|
|
-----------------------------------
|
|
modprobe eth4
|
|
ifrename
|
|
ifup eth4
|
|
-----------------------------------
|
|
If you use hotplug, you only need to do :
|
|
-----------------------------------
|
|
modprobe eth4
|
|
-----------------------------------
|
|
On the other hand, disabling the interface is done with :
|
|
-----------------------------------
|
|
ifdown eth4
|
|
modprobe -r eth4
|
|
-----------------------------------
|
|
|
|
|
|
Docking stations for laptops may contain built-in
|
|
interfaces. My previous laptop had one, and Linux had no support for
|
|
it. After docking, I was able to bring up the network ISA card in the
|
|
docking station.
|
|
However, with most laptops and version of Linux, the issue is
|
|
that after docking, the new devices are not seen. The solutions is to
|
|
force a rescan of the PCI bus. Documentation is unclear on that, maybe
|
|
'scanpci' may help.
|
|
|
|
To be able to simply manage my docking station, I had created
|
|
two little scripts to enable and disable my network interface.
|
|
After docking, you would run :
|
|
-------- /sbin/dock ----------------------------
|
|
#!/bin/sh
|
|
modprobe eth4
|
|
ifrename
|
|
ifup eth4
|
|
------------------------------------------------
|
|
And prior to undocking, you would run :
|
|
-------- /sbin/undock ----------------------------
|
|
#!/bin/sh
|
|
ifdown eth4
|
|
modprobe -r eth4
|
|
------------------------------------------------
|
|
Thanks to 'ifrename', the network interface in your dock will
|
|
always be properly configured regardless of if you have a Pcmcia
|
|
network card in the Pcmcia slot or not.
|
|
|
|
|
|
SCHEMES (MULTI-CONFIG)
|
|
----------------------
|
|
Most Ethernet cards will only connect to a single network, or
|
|
can use DHCP to be auto-configured. With Wireless Cards, it's much
|
|
more likely that you will need multiple configurations, for example at
|
|
work, at home and on-the-go.
|
|
|
|
Most distributions have various level of support for such
|
|
schemes. Some distributions offer simple network schemes, while other
|
|
offer "overall" schemes changing the whole configuration. I document
|
|
the support for schemes in various distributions in the file
|
|
DISTRIBUTIONS.txt.
|
|
|
|
You can also use tools such as ifplugd, waproamd or
|
|
wlandetect. Those tools are a kind of "wireless-DHCP", they attempt to
|
|
automatically detect the proper wireless configuration and apply
|
|
it. Most will also attempt to detect network changes.
|
|
The main limitation of those tools is that they offer very
|
|
little manual control. If two valid alternatives are possible, you
|
|
can't switch between them. If a configuration can't be detected, they
|
|
usually fail.
|
|
That's the same concept as using DHCP versus Static IP
|
|
addresses. Some people are very happy with DHCP, my style is Static IP
|
|
addresses.
|
|
|
|
If you use Debian and want to use simple manual schemes, these
|
|
are the things you need to do.
|
|
1) Make sure that 'ifscheme' and 'ifscheme-mapping' are
|
|
installed on the system. You may find them in a separate tar file on
|
|
my web site.
|
|
2) Check the path for 'ifscheme-mapping' (using whereis).
|
|
3) Modify you /etc/network/interface to add proper mapping and
|
|
configuration.
|
|
|
|
------- /etc/network/interfaces ----------------------
|
|
# Enable Hotplug support (Sarge and later)
|
|
mapping hotplug
|
|
script echo
|
|
|
|
# SMC 2835W wireless CardBus card
|
|
mapping prism0
|
|
script /sbin/ifscheme-mapping
|
|
|
|
iface prism0-any inet dhcp
|
|
wireless-essid any
|
|
wireless-mode managed
|
|
|
|
iface prism0-adhoc inet static
|
|
address 10.0.1.2
|
|
network 10.0.1.0
|
|
netmask 255.255.255.0
|
|
broadcast 10.0.1.255
|
|
wireless-essid THE_ESSID
|
|
wireless-mode ad-hoc
|
|
wireless-channel 5
|
|
|
|
iface prism0-other inet static
|
|
address 10.10.10.2
|
|
network 10.10.10.0
|
|
netmask 255.255.255.0
|
|
broadcast 10.10.10.255
|
|
wireless-essid ANOTHER_ESSID
|
|
wireless-mode ad-hoc
|
|
wireless-key "s:secure"
|
|
------------------------------------------------------
|
|
|
|
FIRMWARE LOADING
|
|
----------------
|
|
A lot of modern wireless card don't have built in firmware and
|
|
need firmware loading. Recent kernels (2.6.X) have a firmware
|
|
loader. These are a few notes on how to use it.
|
|
|
|
First, read the documentation coming with your driver, because
|
|
each driver has specificities (like the name of the firmware file it
|
|
requires). Some drivers may offer additional ways to load the
|
|
firmware, but in the long term things should be standardised around
|
|
the hotplug method to simplify packaging in distributions.
|
|
|
|
You need to compile your kernel with firmware loading
|
|
(CONFIG_FW_LOADER in "Generic Driver Options"). If your driver was
|
|
built from the kernel, chances are that it enabled this feature
|
|
already. Make sure you boot from this new kernel.
|
|
|
|
The 'sysfs' file system must be mounted. The easiest is to
|
|
mount it at boot time, add a line for it in /etc/fstab :
|
|
|
|
-------- /etc/fstab ------------------------------
|
|
sysfs /sys sysfs defaults 0 0
|
|
--------------------------------------------------
|
|
|
|
Then, you add the firmware file in the directory where it's
|
|
expected, which is /usr/lib/hotplug/firmware/ in most cases.
|
|
|
|
Most distributions nowadays have a version of the Hotplug
|
|
scripts that knows how to deal with firmware. If it is not the case,
|
|
just grab the 'firmware.agent' file from an alternate source and copy
|
|
it into your /etc/hotplug directory (make sure it's executable).
|
|
You can try the canonical version :
|
|
http://linux-hotplug.sourceforge.net/
|
|
Or Debian's version :
|
|
http://packages.debian.org/unstable/admin/hotplug
|
|
|
|
Note that firmware loading will usually only work with
|
|
interfaces that are fully managed by Hotplug. This is the only way to
|
|
ensure the that proper sequence of action is happening in the right
|
|
order every time. Firmware loading may not work properly for
|
|
interfaces configured in the init scripts.
|
|
This means that if you have a built-in interface that require
|
|
firmware loading, you should just use manage those interfaces like
|
|
removable interfaces (see section above). However, interface
|
|
configuration need to be explicitly triggered at boot time.
|
|
|
|
One possibility is to set-up Hotplug to be run from the init
|
|
script at boot time. This is usually an option for recent
|
|
distributions (it's not the case for Hotplug in Debian 3.0). But, we
|
|
have seen that this has some issues.
|
|
The other possibility is to use an hybrid between the init
|
|
script method and the hotplug method. First, you need to add an alias
|
|
for the driver in /etc/modprobe.conf. Then, you need to specify a
|
|
mapping for this interface in /etc/iftab, and specify a configuration
|
|
for this interface and that it is enabled at boot time. Lastly,
|
|
you make sure that the network init scripts run 'ifrename
|
|
-p'. 'ifrename' will trigger the module to load, and all the Hotplug
|
|
events will be generated properly to configure the interface.
|
|
|
|
DEVICES WITH MULTIPLE NAMES
|
|
---------------------------
|
|
Some wireless drivers offer multiple network interfaces for
|
|
the same device. A classical example is the Aironet driver that
|
|
creates a 'ethX' and 'wifiY' for each card.
|
|
|
|
'ifrename' allows you a finer selection of interfaces than
|
|
'nameif'. For example, to only rename the pseudo-Ethernet network
|
|
interface name of the Aironet driver, you would do :
|
|
|
|
--------- /etc/iftab -----------------------
|
|
# Cisco Aironet 350 wireless Pcmcia card
|
|
airo* mac 00:07:0E:* arp 1
|
|
---------------------------------------------
|
|
|
|
After that, your device would be available through 'eth0' and
|
|
'wifi0'.
|
|
|
|
You can rename both interfaces. You just need to remember that
|
|
'ifrename' starts matching from the last line of the file, so you
|
|
would do :
|
|
--------- /etc/iftab -----------------------
|
|
# Cisco Aironet 350 wireless Pcmcia card
|
|
wifi* mac 00:07:0E:*
|
|
airo* mac 00:07:0E:* arp 1
|
|
---------------------------------------------
|
|
|
|
The current version of 'ifrename' supports only the most useful
|
|
selectors, but it is architectured such as adding selectors is relatively
|
|
trivial. If you find a case that 'ifrename' can't handle, you should
|
|
just extend it.
|
|
|
|
DEVICES WITHOUT MAC ADDRESSES
|
|
-----------------------------
|
|
Most Ethernet and Wireless devices have a fixed and unique MAC
|
|
address, and it is therefore advised to name them based on this
|
|
criteria. However, there are also network interfaces that don't have a
|
|
fixed and unique MAC address, for example Ethernet over USB, IP over
|
|
FireWire, PPP and tunnel interfaces.
|
|
The driver for those devices creates the interface with a name
|
|
specific to the driver, such as ppp* for PPP interfaces and usb* for
|
|
Ethernet over USB, and therefore they are easy to identify and
|
|
configure, and few users feel the need to rename them. Moreover, some
|
|
of them, such as PPP, have their own configuration scripts and
|
|
methodology addressing their unique needs.
|
|
|
|
There are a few cases where you might want to rename
|
|
interfaces without MAC addresses. One example is two Ethernet over USB
|
|
dongles. The way to do this is to use alternate ifrename
|
|
selectors. Choosing the right selector depends on what you want to
|
|
achieve.
|
|
A quick theoretical example to illustrate :
|
|
--------- /etc/iftab -----------------------
|
|
# All other usbnet devices
|
|
usb* driver usbnet
|
|
# Specific usbnet devices
|
|
usb-p firmware "Prolific PL-2301/PL-2302"
|
|
usb-4 bus-info usb-00:02.0-1.4
|
|
---------------------------------------------
|
|
|
|
TROUBLESHOOTING
|
|
---------------
|
|
If your interface doesn't show up as expected with ifconfig,
|
|
you will need to find out why. First, you need to be familiar with the
|
|
sequence of actions in the system and find which one did not happen.
|
|
|
|
You need to check that the driver module(s) was loaded using
|
|
'lsmod'.
|
|
|
|
You need to check if the interface was properly renamed with
|
|
'ifrename'. You can use 'ifrename -D -V' to debug your /etc/iftab.
|
|
Get the list of interfaces on your system with 'ifconfig -a'
|
|
or 'cat /proc/net/dev', and check if an interface is using the name
|
|
you assigned or 'eth0'. Check any suspicious interfaces with 'ifconfig
|
|
eth0', and check its MAC address. Note that some rare drivers don't
|
|
have a proper MAC address before brought up, which fools ifrename.
|
|
Verify that no line in /etc/iftab matches the all-zero MAC
|
|
address. The all-zero MAC address matches the loopback interface 'lo'
|
|
and various pseudo network devices, renaming the loopback interface is
|
|
highly discouraged.
|
|
|
|
You need to check which configuration was given to the
|
|
interface using 'ifconfig' and 'iwconfig'.
|
|
|
|
The Hotplug subsystem has also good debugging facilities.
|
|
To enable Hotplug debugging, just make sure the variable DEBUG
|
|
is defined in /sbin/hotplug :
|
|
--------- /sbin/hotplug ------------------------------
|
|
--- /sbin/hotplug-old Tue Mar 26 09:00:20 2002
|
|
+++ /sbin/hotplug Fri Feb 20 18:40:38 2004
|
|
@@ -22,7 +22,7 @@
|
|
cd /etc/hotplug
|
|
. hotplug.functions
|
|
|
|
-# DEBUG=yes export DEBUG
|
|
+DEBUG=yes export DEBUG
|
|
|
|
if [ "$DEBUG" != "" ]; then
|
|
mesg "arguments ($*) env (`env`)"
|
|
------------------------------------------------------
|
|
Then, you can check your message logs for Hotplug events with
|
|
'tail -f /var/log/messages'. Verify that the various Hotplug events
|
|
happen as expected (pci, firmware, net...), and verify the log
|
|
messages from 'net.agent'.
|
|
|
|
|
|
Have fun...
|
|
|
|
Jean
|