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.
The route
Jump straight to the step you need, or tick off Done means at the end.
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
Choose an
id_strfor each network that needs a particular ifupdown profile. A network withoutid_struses the logical namedefault.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" }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 dhcpThe first stanza is the physical interface. The others are logical interfaces selected through
WPA_ID_STR, whichwpa_clipasses towpa_action. The manpage's examples use the same pattern:manualon 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
Confirm that
wpa_actionis executable and that the helper library exists.command -v wpa_action ls -l /usr/sbin/wpa_action /etc/wpa_supplicant/functions.shThe script exits successfully without doing anything if its helper library is absent. That quiet result can hide a broken installation, so treat the
lscheck as part of troubleshooting.Use the documented
wpa_cliaction 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 -BNormally,
wpa-roamin the interfaces stanza arranges the integration. Do not start a second listener if the service already owns one.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 reloadThe 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 toiface office inet .... If it does not, add the stanza or remove the identifier so the network deliberately usesdefault.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 wlan0A disconnect loops. Check the authentication and association state first.
DISCONNECTEDmakeswpa_actionrunifdown; 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 stopUndo it by starting the normal wpa-supplicant integration for your distribution, then verify with
sudo wpa_action wlan0 checkwhere that action is available.
Done means
wpa-roampoints at the intended configuration file.- Each required
id_strhas one matching logicalifacestanza. - The physical interface uses the
manualmethod. - A connection reaches
COMPLETEDand receives the expected address and route. - Disconnect and reload actions are visible in the service log, and you have a tested recovery path.