Home / Alt manpages / wpa_action(8)

  • wpa_action(8)
  • Admin command
  • linux

Roam Wi-Fi with wpa_action and ifupdown

This guide sets up wpa_action so that a Wi-Fi connection event selects an ifupdown profile. A network can use DHCP, while a named network can use a fixed address or extra interface commands. Allow about 20 minutes if wpa_supplicant and ifupdown are already installed, plus time to test without losing your remote connection.

Before you start

You need root access, the wpasupplicant package, ifupdown, a wireless interface name, and a working wpa_supplicant.conf. This guide uses wlan0 as the interface placeholder. Replace it with the name shown by ip link.

The installed package here is Ubuntu's wpasupplicant version 2:2.10-21ubuntu0.4. The manpage describes the CONNECTED, DISCONNECTED, stop and reload actions. This installed script also accepts down as an alias for stop, and has a check action that verifies its daemon pid files. Package versions can differ, so check your local script before depending on those extra actions.

Checkpoint: make the network names agree

  1. Choose an id_str for each network that needs a particular ifupdown profile. A network without id_str uses the logical name default.

    For example, add identifiers to the relevant network blocks. Keep the existing authentication settings and replace only the example values as needed.

    network={
        ssid="office-wifi"
        psk="REPLACE_WITH_A_REAL_PASSPHRASE"
        id_str="office"
    }
    
    network={
        ssid="guest-wifi"
        psk="REPLACE_WITH_A_REAL_PASSPHRASE"
    }
    
  2. Make the physical interface manual in /etc/network/interfaces, then add logical stanzas whose names match the identifiers. This is an elevated change and can affect the interface as soon as ifupdown reloads it.

    iface wlan0 inet manual
        wpa-roam /etc/wpa_supplicant/wpa_supplicant.conf
    
    iface default inet dhcp
    
    iface office inet static
        address 192.0.2.25
        netmask 255.255.255.0
        gateway 192.0.2.1
    
    iface guest-wifi inet dhcp
    

    The first stanza is the physical interface. The others are logical interfaces selected through WPA_ID_STR, which wpa_cli passes to wpa_action. The manpage's examples use the same pattern: manual on the physical interface, then DHCP or static settings on logical names.

Check the identifiers and syntax before restarting anything:

sudo grep -nE '^[[:space:]]*(id_str|iface|wpa-roam)' \
    /etc/wpa_supplicant/wpa_supplicant.conf /etc/network/interfaces
sudo wpa_action wlan0 check

On this package, a successful check action is quiet and exits zero when both the wpa_supplicant and wpa_cli pid files refer to live processes. If your package has no check action, the script prints an unknown-action error; use the daemon's service status instead.

Checkpoint: start action handling

  1. Confirm that wpa_action is executable and that the helper library exists.

    command -v wpa_action
    ls -l /usr/sbin/wpa_action /etc/wpa_supplicant/functions.sh
    

    The script exits successfully without doing anything if its helper library is absent. That quiet result can hide a broken installation, so treat the ls check as part of troubleshooting.

  2. Use the documented wpa_cli action form when you need to run it directly. This starts a background action listener and requires elevated privileges.

    sudo wpa_cli -i wlan0 -a /usr/sbin/wpa_action -B
    

    Normally, wpa-roam in the interfaces stanza arranges the integration. Do not start a second listener if the service already owns one.

  3. Reload the configuration after editing it. This is service-disrupting: test from a local console or keep an out-of-band route available before running it.

    sudo wpa_action wlan0 reload
    

    The installed script asks the running supplicant to reload its configuration. The action itself does not validate every SSID or password, so inspect the service log and association state afterwards.

Verify the selected profile

After the interface associates, inspect the supplicant's current network identifier and the address assigned by ifupdown:

sudo wpa_cli -i wlan0 status | grep -E '^(wpa_state|ssid|id|id_str)='
ip -4 addr show dev wlan0
ip route show dev wlan0

A named network should show its configured identifier and the matching logical stanza should have supplied the address. A network with no id_str falls back to default. The script logs connected and disconnected action output through syslog; on systems using systemd, search the journal:

sudo journalctl -b | grep -E 'wpa_action|wpa_supplicant'

Common traps and recovery

  • The name does not match. id_str="office" must map to iface office inet .... If it does not, add the stanza or remove the identifier so the network deliberately uses default.

  • The interface is still managed elsewhere. NetworkManager or another service can race ifupdown. Stop the competing manager only after identifying its owner, and record the change so you can re-enable it if this migration fails.

  • A static change breaks access. Restore the previous logical stanza from your backup, then bring the interface down and up from a local console:

    sudo ifdown wlan0
    sudo ifup wlan0
    
  • A disconnect loops. Check the authentication and association state first. DISCONNECTED makes wpa_action run ifdown; it cannot repair an invalid passphrase or unavailable access point.

  • You need to stop automatic control. This is disruptive and requires root. The documented recovery command stops the action listener, brings the interface down when present, and stops the supplicant:

    sudo wpa_action wlan0 stop
    

    Undo it by starting the normal wpa-supplicant integration for your distribution, then verify with sudo wpa_action wlan0 check where that action is available.

Done means

  • wpa-roam points at the intended configuration file.
  • Each required id_str has one matching logical iface stanza.
  • The physical interface uses the manual method.
  • A connection reaches COMPLETED and receives the expected address and route.
  • Disconnect and reload actions are visible in the service log, and you have a tested recovery path.