From 620ca069f1adc61b5b8a55158fc6006fe4ee9ebf Mon Sep 17 00:00:00 2001 From: Deeksha Gupta Date: Mon, 10 Jan 2022 14:37:34 +0530 Subject: [PATCH] qcacld-3.0: Add support for allowed_authmode Currently, STA doesn't support roam between WPA2 to WPA3 security or vice versa. To support this feature, host sends list of allowed_authmode. So that Firmware will check and roam on those authmode. Fix, add support for allowed_authmode list in ap_profile. Change-Id: I438a133a434ea12ec34680997ace358fd4910028 CRs-Fixed: 3113219 --- .../core/src/wlan_cm_host_util.c | 6 +- .../core/src/wlan_cm_roam_offload.c | 76 ++++++++++++++----- .../core/src/wlan_cm_vdev_connect.c | 12 ++- .../inc/wlan_cm_roam_public_struct.h | 9 ++- .../dispatcher/src/wlan_cm_roam_api.c | 6 +- components/wmi/src/wmi_unified_roam_tlv.c | 39 +++++++++- core/mac/src/pe/lim/lim_api.c | 8 +- 7 files changed, 125 insertions(+), 31 deletions(-) diff --git a/components/umac/mlme/connection_mgr/core/src/wlan_cm_host_util.c b/components/umac/mlme/connection_mgr/core/src/wlan_cm_host_util.c index 2cdbce7815..c99df8db7e 100644 --- a/components/umac/mlme/connection_mgr/core/src/wlan_cm_host_util.c +++ b/components/umac/mlme/connection_mgr/core/src/wlan_cm_host_util.c @@ -121,9 +121,11 @@ QDF_STATUS cm_update_advance_roam_scan_filter( filter->enable_adaptive_11r = wlan_mlme_adaptive_11r_enabled(psoc); - if (rso_cfg->rsn_cap & WLAN_CRYPTO_RSN_CAP_MFP_REQUIRED) + if (rso_cfg->orig_sec_info.rsn_caps & + WLAN_CRYPTO_RSN_CAP_MFP_REQUIRED) filter->pmf_cap = WLAN_PMF_REQUIRED; - else if (rso_cfg->rsn_cap & WLAN_CRYPTO_RSN_CAP_MFP_ENABLED) + else if (rso_cfg->orig_sec_info.rsn_caps & + WLAN_CRYPTO_RSN_CAP_MFP_ENABLED) filter->pmf_cap = WLAN_PMF_CAPABLE; return QDF_STATUS_SUCCESS; diff --git a/components/umac/mlme/connection_mgr/core/src/wlan_cm_roam_offload.c b/components/umac/mlme/connection_mgr/core/src/wlan_cm_roam_offload.c index af8c80e3ce..6d02a8d62b 100644 --- a/components/umac/mlme/connection_mgr/core/src/wlan_cm_roam_offload.c +++ b/components/umac/mlme/connection_mgr/core/src/wlan_cm_roam_offload.c @@ -491,7 +491,7 @@ cm_roam_scan_offload_fill_lfr3_config(struct wlan_objmgr_vdev *vdev, * Instead of making another infra, send the RSN-CAPS in MSB of * beacon Caps. */ - rsn_caps = rso_cfg->rsn_cap; + rsn_caps = rso_cfg->orig_sec_info.rsn_caps; /* Fill LFR3 specific self capabilities for roam scan mode TLV */ self_caps.ess = 1; @@ -1082,7 +1082,7 @@ cm_roam_scan_offload_scan_period(uint8_t vdev_id, static void cm_roam_fill_11w_params(struct wlan_objmgr_vdev *vdev, - struct ap_profile_params *req) + struct ap_profile *profile) { uint32_t group_mgmt_cipher; bool peer_rmf_capable = false; @@ -1115,10 +1115,10 @@ cm_roam_fill_11w_params(struct wlan_objmgr_vdev *vdev, group_mgmt_cipher = WMI_CIPHER_NONE; if (peer_rmf_capable) { - req->profile.rsn_mcastmgmtcipherset = group_mgmt_cipher; - req->profile.flags |= WMI_AP_PROFILE_FLAG_PMF; + profile->rsn_mcastmgmtcipherset = group_mgmt_cipher; + profile->flags |= WMI_AP_PROFILE_FLAG_PMF; } else { - req->profile.rsn_mcastmgmtcipherset = WMI_CIPHER_NONE; + profile->rsn_mcastmgmtcipherset = WMI_CIPHER_NONE; } } @@ -1466,6 +1466,57 @@ uint32_t cm_crypto_authmode_to_wmi_authmode(int32_t authmodeset, return WMI_AUTH_OPEN; } +static void cm_update_crypto_params(struct wlan_objmgr_vdev *vdev, + struct ap_profile *profile) +{ + int32_t keymgmt, connected_akm, authmode, uccipher, mccipher; + enum wlan_crypto_key_mgmt i; + int32_t num_allowed_authmode = 0; + struct rso_config *rso_cfg; + + rso_cfg = wlan_cm_get_rso_config(vdev); + if (!rso_cfg) + return; + + /* Pairwise cipher suite */ + uccipher = wlan_crypto_get_param(vdev, WLAN_CRYPTO_PARAM_UCAST_CIPHER); + profile->rsn_ucastcipherset = cm_crpto_cipher_wmi_cipher(uccipher); + + /* Group cipher suite */ + mccipher = wlan_crypto_get_param(vdev, WLAN_CRYPTO_PARAM_MCAST_CIPHER); + profile->rsn_mcastcipherset = cm_crpto_cipher_wmi_cipher(mccipher); + + /* Group management cipher suite */ + cm_roam_fill_11w_params(vdev, profile); + + authmode = wlan_crypto_get_param(vdev, WLAN_CRYPTO_PARAM_AUTH_MODE); + /* Get connected akm */ + connected_akm = wlan_crypto_get_param(vdev, + WLAN_CRYPTO_PARAM_KEY_MGMT); + profile->rsn_authmode = + cm_crypto_authmode_to_wmi_authmode(authmode, + connected_akm, + uccipher); + /* Get keymgmt from self security info */ + keymgmt = rso_cfg->orig_sec_info.key_mgmt; + + for (i = 0; i < WLAN_CRYPTO_KEY_MGMT_MAX; i++) { + /* + * Send AKM in allowed list which are not present in connected + * akm + */ + if (QDF_HAS_PARAM(keymgmt, i) && + num_allowed_authmode < WLAN_CRYPTO_AUTH_MAX) { + profile->allowed_authmode[num_allowed_authmode++] = + cm_crypto_authmode_to_wmi_authmode(authmode, + (keymgmt & (1 << i)), + uccipher); + } + } + + profile->num_allowed_authmode = num_allowed_authmode; +} + /** * cm_roam_scan_offload_ap_profile() - set roam ap profile parameters * @psoc: psoc ctx @@ -1485,7 +1536,6 @@ cm_roam_scan_offload_ap_profile(struct wlan_objmgr_psoc *psoc, { struct wlan_mlme_psoc_ext_obj *mlme_obj; uint8_t vdev_id = wlan_vdev_get_id(vdev); - int32_t uccipher, authmode, mccipher, akm; struct ap_profile *profile = ¶ms->profile; mlme_obj = mlme_get_psoc_ext_obj(psoc); @@ -1495,18 +1545,8 @@ cm_roam_scan_offload_ap_profile(struct wlan_objmgr_psoc *psoc, params->vdev_id = vdev_id; wlan_vdev_mlme_get_ssid(vdev, profile->ssid.ssid, &profile->ssid.length); - /* Pairwise cipher suite */ - uccipher = wlan_crypto_get_param(vdev, WLAN_CRYPTO_PARAM_UCAST_CIPHER); - profile->rsn_ucastcipherset = cm_crpto_cipher_wmi_cipher(uccipher); - /* Group cipher suite */ - mccipher = wlan_crypto_get_param(vdev, WLAN_CRYPTO_PARAM_MCAST_CIPHER); - profile->rsn_mcastcipherset = cm_crpto_cipher_wmi_cipher(mccipher); - /* Group management cipher suite */ - cm_roam_fill_11w_params(vdev, params); - authmode = wlan_crypto_get_param(vdev, WLAN_CRYPTO_PARAM_AUTH_MODE); - akm = wlan_crypto_get_param(vdev, WLAN_CRYPTO_PARAM_KEY_MGMT); - profile->rsn_authmode = - cm_crypto_authmode_to_wmi_authmode(authmode, akm, uccipher); + + cm_update_crypto_params(vdev, profile); profile->rssi_threshold = rso_cfg->cfg_param.roam_rssi_diff; profile->bg_rssi_threshold = rso_cfg->cfg_param.bg_rssi_threshold; diff --git a/components/umac/mlme/connection_mgr/core/src/wlan_cm_vdev_connect.c b/components/umac/mlme/connection_mgr/core/src/wlan_cm_vdev_connect.c index 419bf31d17..63d7e39e46 100644 --- a/components/umac/mlme/connection_mgr/core/src/wlan_cm_vdev_connect.c +++ b/components/umac/mlme/connection_mgr/core/src/wlan_cm_vdev_connect.c @@ -1018,8 +1018,15 @@ QDF_STATUS cm_connect_start_ind(struct wlan_objmgr_vdev *vdev, return QDF_STATUS_E_NOSUPPORT; rso_cfg = wlan_cm_get_rso_config(vdev); - if (rso_cfg) - rso_cfg->rsn_cap = req->crypto.rsn_caps; + if (rso_cfg) { + rso_cfg->orig_sec_info.rsn_caps = req->crypto.rsn_caps; + rso_cfg->orig_sec_info.authmodeset = req->crypto.auth_type; + rso_cfg->orig_sec_info.ucastcipherset = + req->crypto.ciphers_pairwise; + rso_cfg->orig_sec_info.mcastcipherset = + req->crypto.group_cipher; + rso_cfg->orig_sec_info.key_mgmt = req->crypto.akm_suites; + } if (wlan_get_vendor_ie_ptr_from_oui(HS20_OUI_TYPE, HS20_OUI_TYPE_SIZE, @@ -1437,6 +1444,7 @@ cm_connect_complete_ind(struct wlan_objmgr_vdev *vdev, mlme_get_tdls_prohibited(vdev), vdev); wlan_p2p_status_connect(vdev); + } if (op_mode == QDF_STA_MODE && diff --git a/components/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_roam_public_struct.h b/components/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_roam_public_struct.h index 359715bab5..707c64c89a 100644 --- a/components/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_roam_public_struct.h +++ b/components/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_roam_public_struct.h @@ -445,7 +445,8 @@ struct owe_transition_mode_info { * @reassoc_timer: reassoc timer * @ctx: reassoc timer context * @cm_rso_lock: RSO lock - * @rsn_cap: original rsn caps from the connect req from supplicant + * @orig_sec_info: original security info coming from the connect req from + * supplicant, without intersection of the peer capability * @country_code: country code from connected AP's beacon IE * @disable_hi_rssi: disable high rssi * @roam_control_enable: Flag used to cache the status of roam control @@ -497,7 +498,7 @@ struct rso_config { struct reassoc_timer_ctx ctx; #endif qdf_mutex_t cm_rso_lock; - uint16_t rsn_cap; + struct security_info orig_sec_info; uint8_t country_code[REG_ALPHA2_LEN + 1]; bool disable_hi_rssi; bool roam_control_enable; @@ -748,6 +749,8 @@ struct wlan_cm_roam_vendor_btm_params { * floor in dB * @bg_rssi_threshold: Value of rssi threshold to trigger roaming * after background scan. + * @num_allowed_authmode: Number of allowerd authmode + * @allowed_authmode: List of allowed authmode other than connected */ struct ap_profile { uint32_t flags; @@ -759,6 +762,8 @@ struct ap_profile { uint32_t rsn_mcastmgmtcipherset; uint32_t rssi_abs_thresh; uint8_t bg_rssi_threshold; + uint32_t num_allowed_authmode; + uint32_t allowed_authmode[WLAN_CRYPTO_AUTH_MAX]; }; /** diff --git a/components/umac/mlme/connection_mgr/dispatcher/src/wlan_cm_roam_api.c b/components/umac/mlme/connection_mgr/dispatcher/src/wlan_cm_roam_api.c index fc5365f454..7dd209affb 100644 --- a/components/umac/mlme/connection_mgr/dispatcher/src/wlan_cm_roam_api.c +++ b/components/umac/mlme/connection_mgr/dispatcher/src/wlan_cm_roam_api.c @@ -1710,9 +1710,11 @@ void wlan_cm_fill_crypto_filter_from_vdev(struct wlan_objmgr_vdev *vdev, if (!rso_cfg) return; - if (rso_cfg->rsn_cap & WLAN_CRYPTO_RSN_CAP_MFP_REQUIRED) + if (rso_cfg->orig_sec_info.rsn_caps & + WLAN_CRYPTO_RSN_CAP_MFP_REQUIRED) filter->pmf_cap = WLAN_PMF_REQUIRED; - else if (rso_cfg->rsn_cap & WLAN_CRYPTO_RSN_CAP_MFP_ENABLED) + else if (rso_cfg->orig_sec_info.rsn_caps & + WLAN_CRYPTO_RSN_CAP_MFP_ENABLED) filter->pmf_cap = WLAN_PMF_CAPABLE; } diff --git a/components/wmi/src/wmi_unified_roam_tlv.c b/components/wmi/src/wmi_unified_roam_tlv.c index 9e91a82e2a..753cc25485 100644 --- a/components/wmi/src/wmi_unified_roam_tlv.c +++ b/components/wmi/src/wmi_unified_roam_tlv.c @@ -4248,6 +4248,8 @@ send_roam_scan_offload_ap_profile_cmd_tlv(wmi_unified_t wmi_handle, wmi_roam_cnd_min_rssi_param *min_rssi_param; wmi_owe_ap_profile *owe_ap_profile; enum roam_trigger_reason trig_reason; + uint32_t *authmode_list; + int i; len = sizeof(wmi_roam_ap_profile_fixed_param) + sizeof(wmi_ap_profile); len += sizeof(*score_param) + WMI_TLV_HDR_SIZE; @@ -4265,6 +4267,16 @@ send_roam_scan_offload_ap_profile_cmd_tlv(wmi_unified_t wmi_handle, if (ap_profile->owe_ap_profile.is_owe_transition_conn) { len += WMI_TLV_HDR_SIZE; len += sizeof(*owe_ap_profile); + } else { + len += WMI_TLV_HDR_SIZE; + } + + if (ap_profile->profile.num_allowed_authmode) { + len += WMI_TLV_HDR_SIZE; + len += ap_profile->profile.num_allowed_authmode * + sizeof(uint32_t); + } else { + len += WMI_TLV_HDR_SIZE; } buf = wmi_buf_alloc(wmi_handle, len); @@ -4563,6 +4575,32 @@ send_roam_scan_offload_ap_profile_cmd_tlv(wmi_unified_t wmi_handle, buf_ptr += WMI_TLV_HDR_SIZE; } + /* List of Allowed authmode other than the connected akm */ + if (ap_profile->profile.num_allowed_authmode) { + WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, + (ap_profile->profile.num_allowed_authmode * + sizeof(uint32_t))); + + buf_ptr += WMI_TLV_HDR_SIZE; + + authmode_list = (uint32_t *)buf_ptr; + for (i = 0; i < ap_profile->profile.num_allowed_authmode; i++) + authmode_list[i] = + ap_profile->profile.allowed_authmode[i]; + + wmi_debug("[Allowed Authmode]: num_allowed_authmode: %d", + ap_profile->profile.num_allowed_authmode); + QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, + authmode_list, + ap_profile->profile.num_allowed_authmode * + sizeof(uint32_t)); + } else { + /* set zero TLV's for allowed_authmode */ + WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, + WMITLV_GET_STRUCT_TLVLEN(0)); + buf_ptr += WMI_TLV_HDR_SIZE; + } + wmi_mtrace(WMI_ROAM_AP_PROFILE, NO_SESSION, 0); status = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_ROAM_AP_PROFILE); @@ -5392,4 +5430,3 @@ void wmi_roam_attach_tlv(wmi_unified_t wmi_handle) wmi_roam_offload_attach_tlv(wmi_handle); wmi_fils_sk_attach_tlv(wmi_handle); } - diff --git a/core/mac/src/pe/lim/lim_api.c b/core/mac/src/pe/lim/lim_api.c index 36b908e777..74ad995cc2 100644 --- a/core/mac/src/pe/lim/lim_api.c +++ b/core/mac/src/pe/lim/lim_api.c @@ -1799,9 +1799,9 @@ void lim_set_twt_peer_capabilities(struct mac_context *mac_ctx, #endif /* WLAN_SUPPORT_TWT */ #ifdef WLAN_FEATURE_ROAM_OFFLOAD -static void pe_set_rmf_caps(struct mac_context *mac_ctx, - struct pe_session *ft_session, - struct roam_offload_synch_ind *roam_synch) +static void pe_update_crypto_params(struct mac_context *mac_ctx, + struct pe_session *ft_session, + struct roam_offload_synch_ind *roam_synch) { uint8_t *assoc_body; uint16_t len; @@ -2705,7 +2705,7 @@ pe_roam_synch_callback(struct mac_context *mac_ctx, sizeof(roam_sync_ind_ptr->ssid.ssid)); qdf_mem_copy(roam_sync_ind_ptr->ssid.ssid, ft_session_ptr->ssId.ssId, roam_sync_ind_ptr->ssid.length); - pe_set_rmf_caps(mac_ctx, ft_session_ptr, roam_sync_ind_ptr); + pe_update_crypto_params(mac_ctx, ft_session_ptr, roam_sync_ind_ptr); /* Next routine may update nss based on dot11Mode */ lim_ft_prepare_add_bss_req(mac_ctx, ft_session_ptr, bss_desc);