:: [DNG] wpa_supplicant/ifup integrati…
Top Page
Delete this message
Reply to this message
Author: Isaac Dunham
Date:  
To: dng
Old-Topics: Re: [DNG] Systemd Shims
Subject: [DNG] wpa_supplicant/ifup integration documentation
On Thu, Aug 20, 2015 at 10:28:45PM +0200, Didier Kryn wrote:
>     I would also like to know what your understanding is of how the things
> are handled by the cooperative interaction of ifup, ifdown and
> wpa_supplicant. This is something for which I cannot find a comprehensive
> description, and I think a full understanding is necessary *prior* to
> endeavour what you are doing. This is because these 3 tools are doing a lot
> of things, and rather well and it is
> a waste of time and talent to re-invent the wheel.



As I understand, he's writing a UI to configure /etc/network/interfaces
to use the wpa_supplicant plugin.

For your perusal, here's an overview of how they work together; it's a 100+
line summary.
If anyone wants more details, here are some sources:
Manual pages:
interfaces(5), wpa_supplicant.conf(5), wpa_supplicant(8), wpa_cli(8),
wpa_action(8).
Scripts:
/sbin/wpa_action
/etc/network/if-*.d/wpasupplicant
/etc/wpa_supplicant/*.sh
(/etc/wpa_supplicant/functions.sh is going to be needed if you want a
low-level understanding of what's going on; the script authors have an
exceptional capacity for indirection.)

You will need to read the scripts for a practical understanding of how
it works, but the interfaces, wpa_cli, and wpa_action manpages are rather
helpful for understanding the glue.

Thanks for pointing me in the right direction, Didier!

HTH,
Isaac Dunham
wpa_supplicant and ifup integration

ifup is a one-shot command for bringing up interfaces, oriented towards
wired connections; it converts a "stanza" of options to a series of
commands that will configure an interface.
It's the standard way to configure the IP address/routing of an interface,
and is configured by /etc/network/interfaces (though another configuration
can be specified via the "-i" option).

wpa_supplicant is a daemon for negotiating connections with wireless
networks. It's configured via a user-specified config file, traditionally
/etc/wpa_supplicant/wpa_supplicant.conf, or commands passed via unix
sockets. It can notify other programs about changes in connection state,
but has no built-in way of configuring IP addresses, routing, or commands
to run.
wpa_cli is a tool that sends commands to wpa_supplicant via unix sockets,
as well as listening for notifications from wpa_supplicant. It can run
user-specified programs on connection state changes.

Fortunately, ifup supports plugins.
These plugins are scripts living in /etc/network/if-{up,down}.d/ (I'm not sure
if the scripts in /etc/network/if-{pre,post}-{up,down}.d/ should be called
plugins or not), which are invoked at interface configuration time with
no arguments but a rather large environment determined by the appropriate
stanza in /etc/network/interfaces.
Some of the relevant variables:
IFACE        The current physical interface
MODE        "start" or "stop"
PHASE        pre/post up/down
LOGICAL        the current logical interface
IF_*        (set from option names: [-a-z] becomes [_A-Z], all characters
        except [_A-Z0-9] discarded, IF_ prepended).
IF_WPA_*    (set from wpa-* options in the current stanza)


Some of these plugins allow configuration of wireless networks via iwtools
and wpa_supplicant.
To use wpa_supplicant from ifup, you will use the wpa_supplicant plugin.
On non-Debian-based systems, you may need to install this manually.


Example:
# ifup wlan0=home
# interfaces:
iface home inet dhcp
    hostname somewhere
    wpa-ssid ESSID
    wpa-psk topsecret


iface public inet dhcp
    wpa-ssid any



That allows multiple networks to be used, but not transparently.
For that, you need wpa_supplicant roaming:
#auto wlan0
iface wlan0 inet dhcp
    hostname somewhere

    

wpa.conf:
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
network={
    ssid="ESSID"
    #psk="topsecret"
    psk=bfd06f8718e250cd256c8f31344229067c4f58dc86104d4145ba0ae753c19a1b
}
network={
    ssid=any
    key_mgmt=NONE
}


At this point you might wonder how to automatically run the DHCP
client when you connect, rather than when you set the interface up.
This actually happens, but there's a bit more behind the scenes.
When wpa_supplicant runs, ifup also runs something like:
wpa_cli -i <physical interface> -a <action script>
This action script can run the DHCP client on demand.
A simple example:
case "$2" in
CONNECTED) udhcpc -i "$1" ;;
DISCONNECTED) killall udhcpc ;;
esac


Now, how do you get wpa_supplicant to configure connections to two different
networks differently?
This is where ifup integration the opposite way comes in handy.

First, what it looks like:
#wpa_supplicant.conf:
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
network={
    id_str=priv
    ssid="ESSID"
    #psk="topsecret"
    psk=bfd06f8718e250cd256c8f31344229067c4f58dc86104d4145ba0ae753c19a1b
}
network={
    ssid=any
    key_mgmt=NONE
}


#/etc/network/interfaces:
iface default inet dhcp
    hostname somewhere


iface priv inet static
    hostname somewhere
    address 192.168.2.200




Now, the explanation:
The action script gets run with an environment dependent upon the interface,
connection state, and network.
Part of that is that a network's id_str will become the variable WPA_ID_STR.
In other words, if you connect to ESSID, the action script will be run with
WPA_ID_STR=priv.
The action script is run with arguments "interface" "<connection state>";
for example,
/sbin/wpa_action wlan0 CONNECTED
is the command run on association if wpa_supplicant is configuring wlan0.
On Debian, the stock action script (wpa_action) ultimately calls something
equivalent to this:

# first, check if script ran within 4 seconds; if so, die
read DATE < $SOMEFILE
test $(($DATE + 4)) -lt `date '+%s'` || exit 0
date '+%s' >$SOMEFILE
case "$2" in
CONNECTED)
ifup $1=${WPA_ID_STR:=default}
;;
DISCONNECTED)
ifdown $1=${WPA_ID_STR:=default}
;;
esac

on association.
I assume that there's some check for the "default" interface.