[Netconf-devel] Fwd: Time to rethink ifupdown

Alexey Feldgendler alexey at feldgendler.ru
Wed Aug 23 15:33:47 UTC 2006


Greetings! I'm resending here this message I've originally posted to  
debian-devel. I didn't know about netconf at the time of writing that  
message.

ifupdown, the official Debian network configuration tool, is great for  
configuring interfaces like Ethernet adapters. However, as time goes, more  
and more use cases occur which are hard to fulfill with ifupdown as it is.  
My guess is that it's time to rethink the philosophy behind ifupdown and  
give it some natural development.

First, I'll summarize the problems with the current ifupdown (use cases  
not covered).

1. When we run ifup, we express our intention to bring an interface up. In  
many cases, the fact that we wish the interface to come up is not enough.  
The interface can actually come or not come up, and significant amount of  
time can have passed between the user ordering the interface to come up  
and the interface actually starting working. A typical example is  
dial-on-demand, where the phone number can be redialled several times  
before actual connection. This is currently handled by either blocking  
ifup for an indefinite amount of time (bad: blocks handling of other  
interfaces with ifup -a, causes conflicts with other instances of ifup  
upon the ifstate file) or by forking off a process which tries to connect.  
The disadvantage of the latter approach is that ifup immediately considers  
the interface as being up, runs the up scripts and updates ifstate.  
Running the up scripts before their time has many negative consequences,  
such as putting unreachable DNS addresses into /etc/resolv.conf using  
resolvconf, setting up unusable routes etc.

2. While the interface is up from the ifupdown POV, it can periodically go  
down and up again because of network problems (a common example is pppd's  
automatic redialling). In these cases, the down and up scripts are not  
executed though they should (see above about routes, resolv.conf etc).

3. If the interface really dies and there is no way to revive it (e.g. an  
USB device has been physically disconnected), and the daemon like pppd  
exists even though it's been told to "auto-reconnect", ifupdown will never  
know, so the interface state will remain inconsistent  
[http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=263749].

4. There is a number of "supervisor" daemons which monitor the media for  
the ability to connect, and try to connect when it's possible. An example  
is ifplugd which monitors for Ethernet link state. These are usually  
configured so as to control ifup/ifdown, but actually they need to be  
controlled from ifup/ifdown themselves: ifup should start the daemon for a  
device, and ifdown should stop it. This has the advantage of passing the  
information from /etc/network/interfaces to the daemon and not having to  
duplicate it elsewhere. This is especially the case for wpasupplicant.

5. Though ifupdown has a notion of "mappers" to resolve physical  
interfaces into their logical avatars, a mapper is required to be  
synchronous: it's supposed to give an answer and finish quickly. Acually,  
there are cases when the answer is not known at the time of expressing the  
intention to bring the interface up by running ifup. Sometimes, it's  
possible to find out the logical interface only when the interface  
actually goes up. This is the case with waproamd and wpasupplicant which  
monitor the media in hope of finding a usable WiFi network -- you can't  
know in advance which network it will be.

Having summarized the conceptual problems of the current ifupdown, I'll  
describe my vision of what it should look like.

In the /etc/network/interfaces file, there is a new method "tristate" (a  
better name is welcome) similar to "manual". The difference is that the  
post-up commands are not run automatically after the up commands (ifup  
just exits after running the up commands). The up commands are supposed to  
start a background process whose responsibility is to invoke a callback by  
running "ifup --notify $IFACE". This finalizes the transition and makes  
ifup run post-up commands and mark the interface as completely up. Between  
the user-initiated ifup invocation and this callback, the interface is  
thought to be "half-up", i.e. indeterminate.

If the connection happens to disappear while the interface is up from the  
ifupdown POV, it's the responsibility of the background process to run  
"ifdown --notify $IFACE". This marks the interface as "half-up" again and  
executes the pre-down commands.

Running ifdown executes the down, then post-down commands. It's the  
responsibility of background process to run "ifdown --notify $IFACE" (if  
the link was active), then die. The user-invoked ifdown doesn't run the  
pre-down commands.

"ifup --notify" and "ifdown --notify" should be idempotent, i.e. "ifup  
--notify" should not run the post-up commands if the interface is already  
marked as "full-up".

The built-in methods involving external commands should be reformulated  
this way. This means that at least pon/poff should be given options to  
invoke the callbacks on connection/disconnection. "ifup --notify" should  
accept extra parameters like "param=value" which are passed to post-up  
scripts as "IF_PARAM=value" environment variables. This will allow, e.g.,  
pppd to provide autoconfigured settings like DNS address to the post-up  
scripts.

The /etc/network/interfaces file, in addition to ifaces and mappings,  
allows a new type of stanza: supervisor. The syntax is simple: a headline  
"supervisor <NAME>" with regular lines like pre-up, up, post-up, pre-down,  
down, post-down. A supervisor is considered a physical interface in the  
sense that you can do ifup/ifdown upon it, and that it can correspond to a  
logical interface at a given moment. However, the connection between a  
supervisor and a logical interface is not static (as in case of a mapping)  
but dynamic. A supervisor starts "disconnected" (not associated with a  
logical interface) -- this is the same as "half-up" for "tristate"  
interfaces. Here is an example:

supervisor wlan0
     up waproamd -M -i $IFACE    # Start up a waproamd instance
     down waproamd -k -i $IFACE  # Kill a running waproamd
     # We assume that waproamd is configured to run proper callbacks

iface wlan0-home inet dhcp
     wireless-essid "HomeNet"

iface wlan0-office inet static
     wireless-essid "OfficeNet"
     address 192.168.12.34
     gateway 192.168.12.1

The daemon is expected to run the following callbacks: "ifup --notify  
$IFACE=$LOGICAL" to associate the supervisor with a logical interface, and  
"ifdown --notify $IFACE" to set the supervisor back into the  
"disconnected" state. The former first runs the explicit ("up") or  
built-in (like running ifconfig) up actions on the logical interface, then  
post-up on the logical interface, then post-up on the supervisor. The  
latter runs pre-down on the supervisor, then pre-up on the logical  
interface, then the explicit or built-in actions on the logical interface.  
The pre-up or post-down actions on the logical interface are never run.  
When running post-up and pre-down actions on the supervisor, the $LOGICAL  
variable should be available.

The details need to be worked out, of course. For now, I'd love to hear  
your opinion on the idea in general. If the general direction of ifupdown  
development is accepted, I can offer my help in both detailed design and  
implementation.


-- 
Alexey Feldgendler <alexey at feldgendler.ru>
[ICQ: 115226275] http://feldgendler.livejournal.com



More information about the Netconf-devel mailing list