The rfkill subsystem in Linux provides a mechanism to disable radio transmitters, as Wi-Fi, Bluetooth cards or WWAN modems installed in the system.
From the kernel point of view, such devices typically have a
associated rfkill device (also called killswitch) that is visible in
the output of the rfkill
utility.
$ rfkill
ID TYPE DEVICE SOFT HARD
0 bluetooth tpacpi_bluetooth_sw blocked unblocked
2 wlan phy0 blocked unblocked
Each rfkill device has a type (bluetooth, wlan, wwan) and two flags to indicate whether the killswitch is hard-blocked (when radio transmission is blocked via a hardware switch) or soft-blocked (when radio is disabled but can be re-enabled in software).
Support in NetworkManager
NetworkManager can manage the global rfkill state for Wi-Fi and WWAN devices.
It uses udev to discover (at startup, but also at runtime) the available killswitches. For each of them, NetworkManager keeps track of the current state (unblocked, soft-blocked, hard-blocked).
Each killswitch can be a platform one or a non-platform (or device) one. Platform killswitches are those belonging to the “platform” or “acpi” udev subsystem. Device switches, if hard-killed typically cannot be changed except by a physical hardware switch. Also it is common that platform killswitches control device killswitches. That is, a hard-blocked device switch can often be unblocked by a platform switch.
Therefore, when determining the global killswitch state for a given hardware type (Wi-Fi or WWAN), blocked platform switches have higher priority. If all platform switches are unblocked, then the global state is the maximum blocked state of device switches.
The global killswitch state for a hardware type is “unavailable” when no killswitches of that kind were found on the system and there are no compatible devices.
D-Bus API
The rkfill state is exposed on D-Bus via the following boolean
properties of the org.freedesktop.NetworkManager
interface on the
/org/freedesktop/NetworkManager
object:
- WirelessEnabled (read-write)
- WirelessHardwareEnabled (read-only)
- WwanEnabled (read-write)
- WwanHardwareEnabled (read-only)
‘Hardware’ properties cannot be written as they refer to the hardware-blocked state. The other two properties refer to the software-blocked state.
Since version 1.38, NetworkManager also exposes a RadioFlags
property on the same interface. It currently supports two flags:
NM_RADIO_FLAG_WLAN_AVAILABLE = 0x1
NM_RADIO_FLAG_WWAN_AVAILABLE = 0x2
indicating whether any Wi-fi or WWAN hardware is present in the system.
When WirelessEnabled (or WwanEnabled) gets written, NetworkManager updates the soft-blocked state of all Wi-Fi (or WWAN) killswitches in kernel; in addition, it enables or disables any NetworkManager device of type ‘wifi’ (or ‘gsm’).
The soft-blocked state set via D-Bus is also saved in a persistent
state file (/var/lib/NetworkManager/NetworkManager.state
) that is
reloaded at the next restart.
nmcli
nmcli implements the radio
subcommand to control the rfkill state.
$ nmcli radio
WIFI-HW WIFI WWAN-HW WWAN
enabled disabled enabled enabled
For Wi-Fi and WWAN, bot the hardware and software killswitch states are displayed.
The soft-blocked states can be changed via
nmcli radio {all | wifi | wwan} [on | off]
and this basically controls the soft-blocked D-Bus properties as described in the previous section.
Note that since version 1.38 nmcli displays missing
in the
*-HW column when there are no killswitches or compatible devices.