Network interface modules keeps re-loading

Fredrik Lindberg fli at FreeBSD.org
Sat May 12 16:41:13 UTC 2007


Hi

Due to some exciting interaction between kldunload, devctl/devd, rc(8)
and ifconfig it's currently impossible to unload a network interface
module (without stopping devd first).

What happens is that in kldunload during detach a INET DETACH
devctl message is generated which is picked up by devd.
devd will proceed by executing the default handler associated with
this message, this happens to be /etc/pccard_ether foo0 stop.
pccard_ether stop will run rc.d/netif stop foo0 which in turn executes,
among other things, ifconfig_down foo0.

ifconfig_down is defined in /etc/network.subr and runs as a last test
the following code

if ifexists $1; then
     ifconfig $1 down
     _cfg=0
fi

Now, it starts to get interesting, ifexists is defined like this

ifexists()
{
     ifconfig $1 > /dev/null 2>&1
}

This is all fine, except that the shiny new feature in ifconfig called
ifmaybeload() will load non existing drivers, and viola, we're back
where we started.

The feature of having ifconfig loading modules was discussed briefly
on current@ a while ago, but apparently nothing came out of it.

ifmaybeload() is called quite early in ifconfig, my suggestion is to
only call it if there is at least one more argument except the interface
name given on the command line.
This way the loading will still be there if one executes
ifconfig foo0 up but not if one does ifconfig foo0.
Or modify the rc-scripts in some mysterious ways to work around this.

Fredrik Lindberg
-------------- next part --------------
Index: ifconfig.c
===================================================================
RCS file: /home/ncvs/src/sbin/ifconfig/ifconfig.c,v
retrieving revision 1.130
diff -u -u -r1.130 ifconfig.c
--- ifconfig.c	24 Mar 2007 20:26:54 -0000	1.130
+++ ifconfig.c	12 May 2007 16:13:39 -0000
@@ -229,7 +229,8 @@
 		argc--, argv++;
 
 		/* check and maybe load support for this interface */
-		ifmaybeload(ifname);
+		if (argc >= 1)
+			ifmaybeload(ifname);
 
 		ifindex = if_nametoindex(ifname);
 		if (ifindex == 0) {


More information about the freebsd-current mailing list