qcacmn: Delete pmkid and single pmkid on connect failure
Add logic to delete the pmkid and single pmkid depending on connect response status code and failure. Change-Id: I7a27f887173ba7cdc13c3ce49ded5d2fcc8198fa CRs-Fixed: 2792774
Tento commit je obsažen v:
@@ -401,6 +401,30 @@ void cm_calculate_scores(struct wlan_objmgr_pdev *pdev,
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline void cm_delete_pmksa_for_bssid(struct cnx_mgr *cm_ctx,
|
||||
struct qdf_mac_addr *bssid)
|
||||
{
|
||||
struct wlan_crypto_pmksa pmksa = {0};
|
||||
|
||||
qdf_copy_macaddr(&pmksa.bssid, bssid);
|
||||
wlan_crypto_set_del_pmksa(cm_ctx->vdev, &pmksa, false);
|
||||
}
|
||||
|
||||
#if defined(WLAN_SAE_SINGLE_PMK) && defined(WLAN_FEATURE_ROAM_OFFLOAD)
|
||||
static inline
|
||||
void cm_delete_pmksa_for_single_pmk_bssid(struct cnx_mgr *cm_ctx,
|
||||
struct qdf_mac_addr *bssid)
|
||||
{
|
||||
cm_delete_pmksa_for_bssid(cm_ctx, bssid);
|
||||
}
|
||||
#else
|
||||
static inline
|
||||
void cm_delete_pmksa_for_single_pmk_bssid(struct cnx_mgr *cm_ctx,
|
||||
struct qdf_mac_addr *bssid)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline void
|
||||
cm_set_pmf_caps(struct cm_connect_req *cm_req, struct scan_filter *filter)
|
||||
{
|
||||
@@ -708,27 +732,28 @@ static QDF_STATUS cm_get_valid_candidate(struct cnx_mgr *cm_ctx,
|
||||
{
|
||||
struct scan_cache_node *scan_node = NULL;
|
||||
qdf_list_node_t *cur_node = NULL, *next_node = NULL;
|
||||
struct scan_cache_node *cur_candidate;
|
||||
struct scan_cache_node *new_candidate = NULL, *prev_candidate;
|
||||
QDF_STATUS status = QDF_STATUS_SUCCESS;
|
||||
uint8_t vdev_id = wlan_vdev_get_id(cm_ctx->vdev);
|
||||
|
||||
prev_candidate = cm_req->connect_req.cur_candidate;
|
||||
if (cm_req->connect_req.connect_attempts >=
|
||||
cm_ctx->max_connect_attempts) {
|
||||
mlme_info(CM_PREFIX_FMT "%d attempts tried, max %d",
|
||||
CM_PREFIX_REF(vdev_id, cm_req->cm_id),
|
||||
cm_req->connect_req.connect_attempts,
|
||||
cm_ctx->max_connect_attempts);
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
status = QDF_STATUS_E_FAILURE;
|
||||
goto flush_single_pmk;
|
||||
}
|
||||
|
||||
cur_candidate = cm_req->connect_req.cur_candidate;
|
||||
/*
|
||||
* Get next candidate if cur_candidate is not NULL, else get
|
||||
* Get next candidate if prev_candidate is not NULL, else get
|
||||
* the first candidate
|
||||
*/
|
||||
if (cur_candidate)
|
||||
if (prev_candidate)
|
||||
qdf_list_peek_next(cm_req->connect_req.candidate_list,
|
||||
&cur_candidate->node, &cur_node);
|
||||
&prev_candidate->node, &cur_node);
|
||||
else
|
||||
qdf_list_peek_front(cm_req->connect_req.candidate_list,
|
||||
&cur_node);
|
||||
@@ -740,7 +765,7 @@ static QDF_STATUS cm_get_valid_candidate(struct cnx_mgr *cm_ctx,
|
||||
node);
|
||||
status = cm_validate_candidate(cm_ctx, scan_node->entry);
|
||||
if (QDF_IS_STATUS_SUCCESS(status)) {
|
||||
cur_candidate = scan_node;
|
||||
new_candidate = scan_node;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -756,13 +781,23 @@ static QDF_STATUS cm_get_valid_candidate(struct cnx_mgr *cm_ctx,
|
||||
mlme_debug(CM_PREFIX_FMT "No more candidates left",
|
||||
CM_PREFIX_REF(vdev_id, cm_req->cm_id));
|
||||
cm_req->connect_req.cur_candidate = NULL;
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
status = QDF_STATUS_E_FAILURE;
|
||||
goto flush_single_pmk;
|
||||
}
|
||||
|
||||
cm_req->connect_req.connect_attempts++;
|
||||
cm_req->connect_req.cur_candidate = cur_candidate;
|
||||
cm_req->connect_req.cur_candidate = new_candidate;
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
flush_single_pmk:
|
||||
/*
|
||||
* If connection fails with Single PMK bssid (prev candidate),
|
||||
* clear the pmk entry.
|
||||
*/
|
||||
if (prev_candidate && util_scan_entry_single_pmk(prev_candidate->entry))
|
||||
cm_delete_pmksa_for_single_pmk_bssid(cm_ctx,
|
||||
&prev_candidate->entry->bssid);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static void cm_create_bss_peer(struct cnx_mgr *cm_ctx,
|
||||
@@ -1115,6 +1150,13 @@ QDF_STATUS cm_connect_rsp(struct wlan_objmgr_vdev *vdev,
|
||||
}
|
||||
|
||||
if (QDF_IS_STATUS_SUCCESS(resp->connect_status)) {
|
||||
/*
|
||||
* On successful connection to sae single pmk AP,
|
||||
* clear all the single pmk AP.
|
||||
*/
|
||||
if (cm_is_cm_id_current_candidate_single_pmk(cm_ctx, cm_id))
|
||||
wlan_crypto_selective_clear_sae_single_pmk_entries(vdev,
|
||||
&resp->bssid);
|
||||
qdf_status =
|
||||
cm_sm_deliver_event(vdev,
|
||||
WLAN_CM_SM_EV_CONNECT_SUCCESS,
|
||||
@@ -1128,6 +1170,15 @@ QDF_STATUS cm_connect_rsp(struct wlan_objmgr_vdev *vdev,
|
||||
goto post_err;
|
||||
}
|
||||
|
||||
/*
|
||||
* Delete the PMKID of the BSSID for which the assoc reject is
|
||||
* received from the AP due to invalid PMKID reason.
|
||||
* This will avoid the driver trying to connect to same AP with
|
||||
* the same stale PMKID. when connection is tried again with this AP.
|
||||
*/
|
||||
if (resp->reason_code == STATUS_INVALID_PMKID)
|
||||
cm_delete_pmksa_for_bssid(cm_ctx, &resp->bssid);
|
||||
|
||||
/* In case of failure try with next candidate */
|
||||
qdf_status =
|
||||
cm_sm_deliver_event(vdev,
|
||||
@@ -1136,7 +1187,12 @@ QDF_STATUS cm_connect_rsp(struct wlan_objmgr_vdev *vdev,
|
||||
|
||||
if (QDF_IS_STATUS_SUCCESS(qdf_status))
|
||||
return qdf_status;
|
||||
|
||||
/*
|
||||
* If connection fails with Single PMK bssid, clear this pmk
|
||||
* entry in case of post failure.
|
||||
*/
|
||||
if (cm_is_cm_id_current_candidate_single_pmk(cm_ctx, cm_id))
|
||||
cm_delete_pmksa_for_single_pmk_bssid(cm_ctx, &resp->bssid);
|
||||
post_err:
|
||||
/*
|
||||
* If there is a event posting error it means the SM state is not in
|
||||
|
@@ -504,6 +504,18 @@ cm_fill_bss_info_in_connect_rsp_by_cm_id(struct cnx_mgr *cm_ctx,
|
||||
wlan_cm_id cm_id,
|
||||
struct wlan_cm_connect_rsp *resp);
|
||||
|
||||
#if defined(WLAN_SAE_SINGLE_PMK) && defined(WLAN_FEATURE_ROAM_OFFLOAD)
|
||||
bool cm_is_cm_id_current_candidate_single_pmk(struct cnx_mgr *cm_ctx,
|
||||
wlan_cm_id cm_id);
|
||||
#else
|
||||
static inline
|
||||
bool cm_is_cm_id_current_candidate_single_pmk(struct cnx_mgr *cm_ctx,
|
||||
wlan_cm_id cm_id)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* cm_flush_pending_request() - Flush all pending requests matching flush prefix
|
||||
* @cm_ctx: connection manager context
|
||||
|
@@ -402,6 +402,42 @@ cm_fill_bss_info_in_connect_rsp_by_cm_id(struct cnx_mgr *cm_ctx,
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
|
||||
#if defined(WLAN_SAE_SINGLE_PMK) && defined(WLAN_FEATURE_ROAM_OFFLOAD)
|
||||
bool cm_is_cm_id_current_candidate_single_pmk(struct cnx_mgr *cm_ctx,
|
||||
wlan_cm_id cm_id)
|
||||
{
|
||||
qdf_list_node_t *cur_node = NULL, *next_node = NULL;
|
||||
struct cm_req *cm_req;
|
||||
uint32_t prefix = CM_ID_GET_PREFIX(cm_id);
|
||||
struct scan_cache_node *candidate;
|
||||
bool is_single_pmk = false;
|
||||
|
||||
if (prefix != CONNECT_REQ_PREFIX)
|
||||
return is_single_pmk;
|
||||
|
||||
cm_req_lock_acquire(cm_ctx);
|
||||
qdf_list_peek_front(&cm_ctx->req_list, &cur_node);
|
||||
while (cur_node) {
|
||||
qdf_list_peek_next(&cm_ctx->req_list, cur_node, &next_node);
|
||||
cm_req = qdf_container_of(cur_node, struct cm_req, node);
|
||||
|
||||
if (cm_req->cm_id == cm_id) {
|
||||
candidate = cm_req->connect_req.cur_candidate;
|
||||
if (candidate &&
|
||||
util_scan_entry_single_pmk(candidate->entry))
|
||||
is_single_pmk = true;
|
||||
break;
|
||||
}
|
||||
|
||||
cur_node = next_node;
|
||||
next_node = NULL;
|
||||
}
|
||||
cm_req_lock_release(cm_ctx);
|
||||
|
||||
return is_single_pmk;
|
||||
}
|
||||
#endif
|
||||
|
||||
QDF_STATUS cm_add_req_to_list_and_indicate_osif(struct cnx_mgr *cm_ctx,
|
||||
struct cm_req *cm_req,
|
||||
enum wlan_cm_source source)
|
||||
|
Odkázat v novém úkolu
Zablokovat Uživatele