netdev: station: fix status/reason code in callbacks

This change cleans up the mess of status vs reason codes. The two
types of codes have already been separated into different enumerations,
but netdev was still treating them the same (with last_status_code).

A new 'event_data' argument was added to the connect callback, which
has a different meaning depending on the result of the connection
(described inside netdev.h, netdev_connect_cb_t). This allows for the
removal of netdev_get_last_status_code since the status or reason
code is now passed via event_data.

Inside the netdev object last_status_code was renamed to last_code, for
the purpose of storing either status or reason. This is only used when
a disconnect needs to be emitted before failing the connection. In all
other cases we just pass the code directly into the connect_cb and do
not store it.

All ocurrences of netdev_connect_failed were updated to use the proper
code depending on the netdev result. Most of these simply changed from
REASON_CODE_UNSPECIFIED to STATUS_CODE_UNSPECIFIED. This was simply for
consistency (both codes have the same value).

netdev_[authenticate|associate]_event's were updated to parse the
status code and, if present, use that if their was a failure rather
than defaulting to UNSPECIFIED.
This commit is contained in:
James Prestwood 2019-02-28 09:32:40 -08:00 committed by Denis Kenzior
parent 6017dc5730
commit 8fed50a448
4 changed files with 39 additions and 34 deletions

View File

@ -104,7 +104,7 @@ struct netdev {
uint32_t set_interface_cmd_id;
uint32_t rekey_offload_cmd_id;
enum netdev_result result;
uint16_t last_status_code;
uint16_t last_code; /* reason or status, depending on result */
struct l_timeout *neighbor_report_timeout;
struct l_timeout *sa_query_timeout;
struct l_timeout *group_handshake_timeout;
@ -339,11 +339,6 @@ const char *netdev_get_path(struct netdev *netdev)
return path;
}
uint16_t netdev_get_last_status_code(struct netdev *netdev)
{
return netdev->last_status_code;
}
static void netdev_set_powered_result(int error, uint16_t type,
const void *data,
uint32_t len, void *user_data)
@ -586,7 +581,7 @@ static void netdev_connect_free(struct netdev *netdev)
netdev->event_filter = NULL;
netdev->user_data = NULL;
netdev->result = NETDEV_RESULT_OK;
netdev->last_status_code = 0;
netdev->last_code = 0;
netdev->in_ft = false;
netdev_rssi_polling_update(netdev);
@ -602,22 +597,19 @@ static void netdev_connect_free(struct netdev *netdev)
static void netdev_connect_failed(struct netdev *netdev,
enum netdev_result result,
uint16_t status_code)
uint16_t status_or_reason)
{
netdev_connect_cb_t connect_cb = netdev->connect_cb;
netdev_event_func_t event_filter = netdev->event_filter;
void *connect_data = netdev->user_data;
netdev->result = result;
netdev->last_status_code = status_code;
netdev->disconnect_cmd_id = 0;
/* Done this way to allow re-entrant netdev_connect calls */
netdev_connect_free(netdev);
if (connect_cb)
connect_cb(netdev, result, connect_data);
connect_cb(netdev, result, &status_or_reason, connect_data);
else if (event_filter)
event_filter(netdev, NETDEV_EVENT_DISCONNECT_BY_SME,
connect_data);
@ -627,9 +619,7 @@ static void netdev_disconnect_cb(struct l_genl_msg *msg, void *user_data)
{
struct netdev *netdev = user_data;
/* FIXME: This should be a status code */
netdev_connect_failed(netdev, netdev->result,
MMPDU_REASON_CODE_UNSPECIFIED);
netdev_connect_failed(netdev, netdev->result, netdev->last_code);
}
static void netdev_free(void *data)
@ -1056,7 +1046,8 @@ static void netdev_connect_ok(struct netdev *netdev)
netdev->operational = true;
if (netdev->connect_cb) {
netdev->connect_cb(netdev, NETDEV_RESULT_OK, netdev->user_data);
netdev->connect_cb(netdev, NETDEV_RESULT_OK, NULL,
netdev->user_data);
netdev->connect_cb = NULL;
}
@ -1488,7 +1479,7 @@ void netdev_handshake_failed(struct handshake_state *hs, uint16_t reason_code)
netdev->sm = NULL;
netdev->result = NETDEV_RESULT_HANDSHAKE_FAILED;
netdev->last_status_code = reason_code;
netdev->last_code = reason_code;
switch (netdev->type) {
case NL80211_IFTYPE_STATION:
@ -2081,7 +2072,7 @@ static void netdev_cmd_ft_reassociate_cb(struct l_genl_msg *msg,
struct l_genl_msg *cmd_deauth;
netdev->result = NETDEV_RESULT_ASSOCIATION_FAILED;
netdev->last_status_code = MMPDU_REASON_CODE_UNSPECIFIED;
netdev->last_code = MMPDU_STATUS_CODE_UNSPECIFIED;
cmd_deauth = netdev_build_cmd_deauthenticate(netdev,
MMPDU_REASON_CODE_UNSPECIFIED);
netdev->disconnect_cmd_id = l_genl_family_send(nl80211,
@ -2274,7 +2265,7 @@ auth_error:
ft_error:
netdev->result = NETDEV_RESULT_AUTHENTICATION_FAILED;
netdev->last_status_code = MMPDU_REASON_CODE_UNSPECIFIED;
netdev->last_code = MMPDU_STATUS_CODE_UNSPECIFIED;
cmd_deauth = netdev_build_cmd_deauthenticate(netdev,
MMPDU_REASON_CODE_UNSPECIFIED);
netdev->disconnect_cmd_id = l_genl_family_send(nl80211, cmd_deauth,
@ -2360,7 +2351,7 @@ static void netdev_authenticate_event(struct l_genl_msg *msg,
auth_error:
netdev_connect_failed(netdev, NETDEV_RESULT_AUTHENTICATION_FAILED,
MMPDU_REASON_CODE_UNSPECIFIED);
MMPDU_STATUS_CODE_UNSPECIFIED);
}
static void netdev_associate_event(struct l_genl_msg *msg,
@ -2399,7 +2390,7 @@ static void netdev_associate_event(struct l_genl_msg *msg,
assoc_failed:
netdev_connect_failed(netdev, NETDEV_RESULT_ASSOCIATION_FAILED,
MMPDU_REASON_CODE_UNSPECIFIED);
MMPDU_STATUS_CODE_UNSPECIFIED);
}
static void netdev_cmd_connect_cb(struct l_genl_msg *msg, void *user_data)
@ -2435,7 +2426,7 @@ static void netdev_cmd_connect_cb(struct l_genl_msg *msg, void *user_data)
}
netdev_connect_failed(netdev, NETDEV_RESULT_ASSOCIATION_FAILED,
MMPDU_REASON_CODE_UNSPECIFIED);
MMPDU_STATUS_CODE_UNSPECIFIED);
}
static struct l_genl_msg *netdev_build_cmd_authenticate(struct netdev *netdev,
@ -2504,7 +2495,7 @@ static void netdev_sae_complete(uint16_t status, void *user_data)
auth_failed:
netdev_connect_failed(netdev, NETDEV_RESULT_AUTHENTICATION_FAILED,
MMPDU_REASON_CODE_UNSPECIFIED);
MMPDU_STATUS_CODE_UNSPECIFIED);
}
static void netdev_tx_sae_frame_cb(struct l_genl_msg *msg,
@ -2544,7 +2535,7 @@ static void netdev_owe_auth_cb(struct l_genl_msg *msg, void *user_data)
netdev_connect_failed(netdev,
NETDEV_RESULT_AUTHENTICATION_FAILED,
MMPDU_REASON_CODE_UNSPECIFIED);
MMPDU_STATUS_CODE_UNSPECIFIED);
return;
}
}
@ -2563,7 +2554,7 @@ static void netdev_owe_tx_authenticate(void *user_data)
l_genl_msg_unref(msg);
netdev_connect_failed(netdev,
NETDEV_RESULT_AUTHENTICATION_FAILED,
MMPDU_REASON_CODE_UNSPECIFIED);
MMPDU_STATUS_CODE_UNSPECIFIED);
}
}
@ -2575,7 +2566,7 @@ static void netdev_owe_assoc_cb(struct l_genl_msg *msg, void *user_data)
l_error("Error sending CMD_ASSOCIATE");
netdev_connect_failed(netdev, NETDEV_RESULT_ASSOCIATION_FAILED,
MMPDU_REASON_CODE_UNSPECIFIED);
MMPDU_STATUS_CODE_UNSPECIFIED);
}
}
@ -2593,7 +2584,7 @@ static void netdev_owe_tx_associate(struct iovec *ie_iov, size_t iov_len,
netdev, NULL)) {
l_genl_msg_unref(msg);
netdev_connect_failed(netdev, NETDEV_RESULT_ASSOCIATION_FAILED,
MMPDU_REASON_CODE_UNSPECIFIED);
MMPDU_STATUS_CODE_UNSPECIFIED);
}
}
@ -3151,7 +3142,7 @@ static void netdev_cmd_authenticate_ft_cb(struct l_genl_msg *msg,
if (l_genl_msg_get_error(msg) < 0)
netdev_connect_failed(netdev,
NETDEV_RESULT_AUTHENTICATION_FAILED,
MMPDU_REASON_CODE_UNSPECIFIED);
MMPDU_STATUS_CODE_UNSPECIFIED);
}
int netdev_fast_transition(struct netdev *netdev, struct scan_bss *target_bss,

View File

@ -66,8 +66,21 @@ enum netdev_iftype {
typedef void (*netdev_command_cb_t)(struct netdev *netdev, int result,
void *user_data);
/*
* Callback for a connection attempt. This callback is called on both success
* and failure. Depending on result, the event_data will have different
* meanings:
*
* NETDEV_RESULT_OK - unused
* NETDEV_RESULT_AUTHENTICATION_FAILED - MMPDU_STATUS_CODE
* NETDEV_RESULT_ASSOCIATION_FAILED - MMPDU_STATUS_CODE
* NETDEV_RESULT_HANDSHAKE_FAILED - MMPDU_REASON_CODE
* NETDEV_RESULT_KEY_SETTINGS_FAILED - unused
* NETDEV_RESULT_ABORTED - unused.
*/
typedef void (*netdev_connect_cb_t)(struct netdev *netdev,
enum netdev_result result,
void *event_data,
void *user_data);
typedef void (*netdev_event_func_t)(struct netdev *netdev,
enum netdev_event event,
@ -110,7 +123,6 @@ const char *netdev_get_name(struct netdev *netdev);
bool netdev_get_is_up(struct netdev *netdev);
struct device *netdev_get_device(struct netdev *netdev);
const char *netdev_get_path(struct netdev *netdev);
uint16_t netdev_get_last_status_code(struct netdev *netdev);
struct handshake_state *netdev_handshake_state_new(struct netdev *netdev);
struct handshake_state *netdev_get_handshake(struct netdev *netdev);

View File

@ -849,6 +849,7 @@ static void station_roam_failed(struct station *station)
static void station_reassociate_cb(struct netdev *netdev,
enum netdev_result result,
void *event_data,
void *user_data)
{
struct station *station = user_data;
@ -867,6 +868,7 @@ static void station_reassociate_cb(struct netdev *netdev,
static void station_fast_transition_cb(struct netdev *netdev,
enum netdev_result result,
void *event_data,
void *user_data)
{
struct station *station = user_data;
@ -1670,10 +1672,9 @@ static void station_connect_dbus_reply(struct station *station,
}
static void station_connect_cb(struct netdev *netdev, enum netdev_result result,
void *user_data)
void *event_data, void *user_data)
{
struct station *station = user_data;
uint16_t status_code = netdev_get_last_status_code(netdev);
l_debug("%u, result: %d", netdev_get_ifindex(station->netdev), result);
@ -1682,7 +1683,8 @@ static void station_connect_cb(struct netdev *netdev, enum netdev_result result,
blacklist_remove_bss(station->connected_bss->addr);
break;
case NETDEV_RESULT_HANDSHAKE_FAILED:
if (!station_can_retry(status_code))
/* reason code in this case */
if (!station_can_retry(l_get_u16(event_data)))
break;
/* fall through */
case NETDEV_RESULT_AUTHENTICATION_FAILED:

View File

@ -204,7 +204,7 @@ static void wsc_disconnect_cb(struct netdev *netdev, bool success,
}
static void wsc_connect_cb(struct netdev *netdev, enum netdev_result result,
void *user_data)
void *event_data, void *user_data)
{
struct wsc *wsc = user_data;
@ -373,7 +373,7 @@ static void wsc_netdev_event(struct netdev *netdev, enum netdev_event event,
case NETDEV_EVENT_DISCONNECT_BY_AP:
l_debug("Disconnect by AP");
wsc_connect_cb(wsc->netdev,
NETDEV_RESULT_HANDSHAKE_FAILED, wsc);
NETDEV_RESULT_HANDSHAKE_FAILED, NULL, wsc);
break;
case NETDEV_EVENT_RSSI_THRESHOLD_LOW:
case NETDEV_EVENT_RSSI_THRESHOLD_HIGH: