netdev: Remove improper use of netdev_connect_failed

When a roam event is received, iwd generates a firmware scan request and
notifies its event filter of the ROAMING condition.  In cases where the
firmware scan could not be started successfully, netdev_connect_failed
is invoked.  This is not a correct use of netev_connect_failed since it
doesn't actually disconnect the underlying netdev and the reflected
state becomes de-synchronized from the underlying kernel device.

The firmware scan request could currently fail for two reasons:
  1. nl80211 genl socket is in a bad state, or
  2. the scan context does not exist

Since both reasons are highly unlikely, simply use L_WARN instead.

The other two cases where netdev_connect_failed is used could only occur
if the kernel message is invalid.  The message is ignored in that case
and a warning is printed.

The situation described above also exists in netdev_get_fw_scan_cb. If
the scan could not be completed successfully, there's not much iwd can
do to recover.  Have iwd remain in roaming state and print an error.
This commit is contained in:
Denis Kenzior 2023-11-14 16:57:48 -06:00
parent c59669a366
commit 972d277363
1 changed files with 11 additions and 24 deletions

View File

@ -4934,7 +4934,7 @@ static bool netdev_get_fw_scan_cb(int err, struct l_queue *bss_list,
if (err < 0) { if (err < 0) {
l_error("Failed to get scan after roam (%d)", err); l_error("Failed to get scan after roam (%d)", err);
goto failed; return false;
} }
/* /*
@ -4946,7 +4946,7 @@ static bool netdev_get_fw_scan_cb(int err, struct l_queue *bss_list,
if (!bss) { if (!bss) {
l_error("Roam target BSS not found in scan results"); l_error("Roam target BSS not found in scan results");
goto failed; return false;
} }
netdev->fw_roam_bss = bss; netdev->fw_roam_bss = bss;
@ -4958,17 +4958,10 @@ static bool netdev_get_fw_scan_cb(int err, struct l_queue *bss_list,
return false; return false;
} }
if (netdev->sm) { if (netdev->sm)
if (!eapol_start(netdev->sm)) L_WARN_ON(!eapol_start(netdev->sm));
goto failed;
}
return false; return false;
failed:
netdev_connect_failed(netdev, NETDEV_RESULT_ABORTED,
MMPDU_REASON_CODE_UNSPECIFIED);
return false;
} }
/* /*
@ -4998,8 +4991,8 @@ static void netdev_roam_event(struct l_genl_msg *msg, struct netdev *netdev)
netdev->operational = false; netdev->operational = false;
if (!l_genl_attr_init(&attr, msg)) if (L_WARN_ON(!l_genl_attr_init(&attr, msg)))
goto failed; return;
while (l_genl_attr_next(&attr, &type, &len, &data)) { while (l_genl_attr_next(&attr, &type, &len, &data)) {
switch (type) { switch (type) {
@ -5014,7 +5007,7 @@ static void netdev_roam_event(struct l_genl_msg *msg, struct netdev *netdev)
if (!mac) { if (!mac) {
l_error("Failed to parse ATTR_MAC from CMD_ROAM"); l_error("Failed to parse ATTR_MAC from CMD_ROAM");
goto failed; return;
} }
/* Handshake completed in firmware, just get the roamed BSS */ /* Handshake completed in firmware, just get the roamed BSS */
@ -5031,20 +5024,14 @@ static void netdev_roam_event(struct l_genl_msg *msg, struct netdev *netdev)
get_fw_scan: get_fw_scan:
handshake_state_set_authenticator_address(netdev->handshake, mac); handshake_state_set_authenticator_address(netdev->handshake, mac);
if (!scan_get_firmware_scan(netdev->wdev_id, netdev_get_fw_scan_cb, if (L_WARN_ON(!scan_get_firmware_scan(netdev->wdev_id,
netdev, NULL)) netdev_get_fw_scan_cb,
goto failed; netdev, NULL)))
return;
if (netdev->event_filter) if (netdev->event_filter)
netdev->event_filter(netdev, NETDEV_EVENT_ROAMING, netdev->event_filter(netdev, NETDEV_EVENT_ROAMING,
NULL, netdev->user_data); NULL, netdev->user_data);
return;
failed:
l_error("Failed to properly handle the ROAM event -- submit logs!");
netdev_connect_failed(netdev, NETDEV_RESULT_ABORTED,
MMPDU_REASON_CODE_UNSPECIFIED);
} }
static void netdev_send_sa_query_delay(struct l_timeout *timeout, static void netdev_send_sa_query_delay(struct l_timeout *timeout,