Skip to content

net: connectivity manager: iface taken down before disconnect actioned #89802

@JordanYates

Description

@JordanYates

Describe the bug

The Connection Manager library incorrectly takes interfaces down when conn_mgr_if_disconnect is called, before the disconnect is actioned.

The disconnect implementation is required to be non-blocking, which implies that for at least some backends (e.g. HostAP) the work must be offloaded to a different thread for processing.

* @brief When called, the connectivity implementation should disconnect (disassociate), or
* stop any in-progress attempts to associate to a network, the bound iface pointed to by
* if_conn->iface.
*
* Must be non-blocking.
*
* Called by @ref conn_mgr_if_disconnect.
*/
int (*disconnect)(struct conn_mgr_conn_binding *const binding);

Inside conn_mgr_if_disconnect however, the disconnect function is called, immediately followed by conn_mgr_conn_if_auto_admin_down.

status = api->disconnect(binding);
out:
conn_mgr_binding_unlock(binding);
/* Since the connectivity implementation will not automatically attempt to reconnect after
* a call to conn_mgr_if_disconnect, conn_mgr_conn_if_auto_admin_down should be called.
*
* conn_mgr_conn_handle_iface_down will only call conn_mgr_conn_if_auto_admin_down if
* persistence is disabled. To ensure conn_mgr_conn_if_auto_admin_down is called in all
* cases, we must call it directly from here. If persistence is disabled, this will result
* in conn_mgr_conn_if_auto_admin_down being called twice, but that is not an issue.
*/
conn_mgr_conn_if_auto_admin_down(iface);

/* Take the iface admin-down if AUTO_DOWN is enabled */
if (IS_ENABLED(CONFIG_NET_CONNECTION_MANAGER_AUTO_IF_DOWN) &&
!conn_mgr_if_get_flag(iface, CONN_MGR_IF_NO_AUTO_DOWN)) {
net_if_down(iface);
}

As a result, attempting to disconnect an interface that doesn't have CONN_MGR_IF_NO_AUTO_DOWN set can result in many errors. For example with HostAP:

Expected behavior

Calling conn_mgr_if_disconnect should not result in the interface being turned off before the disconnect takes place.

Logs and console output

Example log errors while trying to disconnect from a Wi-Fi network on a nRF7002, where the NET_REQUEST_WIFI_DISCONNECT command is run from the system workqueue after being scheduled by the disconnect implementation:

[00:02:31.338,858] <dbg> conn_mgr_conn: conn_mgr_if_disconnect: iface 0x20001c10 disconnect
[00:02:31.357,778] <inf> wifi_supplicant: Network interface 1 (0x20001c10) down
[00:02:31.357,904] <err> wpa_supp: wpa_drv_zep_deauthenticate: deauthenticate op failed
[00:02:31.368,493] <dbg> conn_mgr: conn_mgr_iface_events_handler: (net_mgmt): Iface event 0xd0010003 received on iface 1 (0x20001c10)
[00:02:31.368,514] <dbg> conn_mgr: conn_mgr_iface_events_handler: (net_mgmt): Iface index 0
[00:02:31.368,521] <inf> epacket_udp: Downlink watchdog cancelled
[00:02:31.368,553] <dbg> conn_mgr: conn_mgr_iface_events_handler: (net_mgmt): Iface event 0xd0010001 received on iface 1 (0x20001c10)
[00:02:31.368,566] <dbg> conn_mgr: conn_mgr_iface_events_handler: (net_mgmt): Iface index 0
[00:02:31.368,605] <inf> wifi_mgmt: Connection released
[00:02:31.368,661] <err> app: INTERFACE STATE 0
[00:02:31.368,664] <inf> epacket_udp: Network disconnected
[00:02:31.368,688] <err> epacket_udp: Socket closed
[00:02:31.368,786] <err> wpa_supp: zephyr_get_handle_by_ifname: Unable to get wpa_s handle for wlan0
[00:02:31.368,827] <err> wpa_supp: Interface wlan0 not found

Environment (please complete the following information):

  • Zephyr v4.1

Metadata

Metadata

Assignees

Labels

area: NetworkingbugThe issue is a bug, or the PR is fixing a bugpriority: lowLow impact/importance bug

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions