qcacld-3.0: Use MLD address for auth frames in SAE ML roaming

SAE authentication happens with MLD address rather than link
addresses as it's common authentication for all links in an ML
connection. But OTA exchange of authentication frames happens
with a chosen link address from available links.
As userspace takes care of the SAE authentication, host driver
has to replace the rx SAE auth frame SA with peer MLD and DA with
self MLD address. Similarly for tx SAE auth frames, replace self
SA with link address and DA with peer link address.

Current change is to support the same for roaming case. Fetch the
MLD from scan cache corresponds to link address provided in roam
auth event and replace as mentioned above.

Change-Id: Ide15caa122f78301391b5ea891e2e6eaf4af8974
CRs-Fixed: 3441483
This commit is contained in:
Rahul Gusain
2023-03-24 17:17:29 +05:30
committed by Madan Koyyalamudi
parent b6f2edbfd1
commit 64f4ef5843
8 changed files with 383 additions and 24 deletions

View File

@@ -1933,4 +1933,105 @@ wlan_cm_get_assoc_btm_cap(struct wlan_objmgr_vdev *vdev);
* Return: bool, true: self mld roam supported
*/
bool wlan_cm_is_self_mld_roam_supported(struct wlan_objmgr_psoc *psoc);
#ifdef WLAN_FEATURE_11BE_MLO
/**
* wlan_cm_is_sae_auth_addr_conversion_required() - check whether address
* conversion is required or not.
* @vdev: pointer to vdev
*
* This API checks the address conversion (mld to link and vice-versa) for sae
* auth frames for below listed scenarios when mlo sae auth external conversion
* is true.
*
* Connected AP Roam AP Connection Conversion
* (MLO vdev)
* non-ML non-ML initial FALSE
* non-ML ML initial FALSE
* non-ML non-ML roam FALSE
* non-ML ML roam TRUE
* ML non-ML initial TRUE
* ML ML initial TRUE
* ML non-ML roam FALSE
* ML ML roam TRUE
*
* Return: true if address conversion required, otherwise false.
*/
bool
wlan_cm_is_sae_auth_addr_conversion_required(struct wlan_objmgr_vdev *vdev);
#else
static inline bool
wlan_cm_is_sae_auth_addr_conversion_required(struct wlan_objmgr_vdev *vdev)
{
return false;
}
#endif /* WLAN_FEATURE_11BE_MLO */
#if defined(WLAN_FEATURE_11BE_MLO) && defined(WLAN_FEATURE_ROAM_OFFLOAD)
/**
* wlan_cm_store_mlo_roam_peer_address() - cache peer mld and link address
* while roaming
* @pdev: pdev object
* @auth_event: auth offload event data
*
* Return: void
*/
void
wlan_cm_store_mlo_roam_peer_address(struct wlan_objmgr_pdev *pdev,
struct auth_offload_event *auth_event);
/**
* wlan_cm_roaming_get_peer_mld_addr() - retrieve the peer mld address for
* roaming.
* @vdev: vdev pointer
*
* Return: pointer to struct qdf_mac_addr
*/
struct qdf_mac_addr *
wlan_cm_roaming_get_peer_mld_addr(struct wlan_objmgr_vdev *vdev);
/**
* wlan_cm_roaming_get_peer_link_addr() - get peer link address for roaming
* @vdev: vdev pointer
*
* Return: pointer to struct qdf_mac_addr
*/
struct qdf_mac_addr *
wlan_cm_roaming_get_peer_link_addr(struct wlan_objmgr_vdev *vdev);
/**
* wlan_cm_roam_is_mlo_ap() - to check whether vdev will be roam to ml ap
* @vdev: object manager vdev
*
* this function check whether roaming vdev will be connected to ml ap or not.
*
* Return: true if roam ap is ml capable otherwise false
*/
bool
wlan_cm_roam_is_mlo_ap(struct wlan_objmgr_vdev *vdev);
#else
static inline void
wlan_cm_store_mlo_roam_peer_address(struct wlan_objmgr_pdev *pdev,
struct auth_offload_event *auth_event)
{
}
static inline struct qdf_mac_addr *
wlan_cm_roaming_get_mld_addr(struct wlan_objmgr_vdev *vdev)
{
return NULL;
}
static inline struct qdf_mac_addr *
wlan_cm_roaming_get_peer_link_addr(struct wlan_objmgr_vdev *vdev)
{
return NULL;
}
static inline bool
wlan_cm_roam_is_mlo_ap(struct wlan_objmgr_vdev *vdev)
{
return false;
}
#endif /* WLAN_FEATURE_11BE_MLO && WLAN_FEATURE_ROAM_OFFLOAD */
#endif /* WLAN_CM_ROAM_API_H__ */

View File

@@ -500,6 +500,18 @@ struct owe_transition_mode_info {
struct wlan_ssid ssid;
};
/**
* struct sae_roam_auth_map - map the peer address for the sae raom
* @is_mlo_ap: to check ap (to which roam) is mlo capable.
* @peer_mldaddr: peer MLD address
* @peer_linkaddr: peer link address
*/
struct sae_roam_auth_map {
bool is_mlo_ap;
struct qdf_mac_addr peer_mldaddr;
struct qdf_mac_addr peer_linkaddr;
};
/**
* struct rso_config - connect config to be used to send info in
* RSO. This is the info we dont have in VDEV or CM ctx
@@ -553,6 +565,7 @@ struct owe_transition_mode_info {
* @lost_link_rssi: lost link RSSI
* @roam_sync_frame_ind: roam sync frame ind
* @roam_band_bitmask: This allows the driver to roam within this band
* @sae_roam_auth: structure containing roam peer mld and link address.
*/
struct rso_config {
#ifdef WLAN_FEATURE_HOST_ROAM
@@ -599,6 +612,9 @@ struct rso_config {
int32_t lost_link_rssi;
struct roam_synch_frame_ind roam_sync_frame_ind;
uint32_t roam_band_bitmask;
#if defined(WLAN_FEATURE_11BE_MLO) && defined(WLAN_FEATURE_ROAM_OFFLOAD)
struct sae_roam_auth_map sae_roam_auth;
#endif
};
/**

View File

@@ -723,4 +723,46 @@ ucfg_cm_roam_stats_info_put(struct enhance_roam_info *roam_info)
{
}
#endif
#ifdef WLAN_FEATURE_11BE_MLO
/**
* ucfg_cm_is_sae_auth_addr_conversion_required() - this api is wrapper for
* "wlan_cm_is_sae_auth_addr_conversion_required" function
* @vdev: pointer to vdev
*
* Return: true for address conversion otherwise false
*/
static inline bool
ucfg_cm_is_sae_auth_addr_conversion_required(struct wlan_objmgr_vdev *vdev)
{
return wlan_cm_is_sae_auth_addr_conversion_required(vdev);
}
#else
static inline bool
ucfg_cm_is_sae_auth_addr_conversion_required(struct wlan_objmgr_vdev *vdev)
{
return false;
}
#endif
#if defined(WLAN_FEATURE_ROAM_OFFLOAD) && defined(WLAN_FEATURE_11BE_MLO)
/**
* ucfg_cm_roaming_get_peer_mld_addr() - this api is wrapper for
* "wlan_cm_roaming_get_peer_mld_addr" function.
* @vdev: pointer to vdev
*
* Return: mld address of peer
*/
static inline struct qdf_mac_addr *
ucfg_cm_roaming_get_peer_mld_addr(struct wlan_objmgr_vdev *vdev)
{
return wlan_cm_roaming_get_peer_mld_addr(vdev);
}
#else
static inline struct qdf_mac_addr *
ucfg_cm_roaming_get_peer_mld_addr(struct wlan_objmgr_vdev *vdev)
{
return NULL;
}
#endif
#endif /* _WLAN_CM_ROAM_UCFG_API_H_ */

View File

@@ -4655,3 +4655,137 @@ end:
return status;
}
#endif
#ifdef WLAN_FEATURE_11BE_MLO
bool wlan_cm_is_sae_auth_addr_conversion_required(struct wlan_objmgr_vdev *vdev)
{
if (!wlan_vdev_get_mlo_external_sae_auth_conversion(vdev))
return false;
if (wlan_cm_is_vdev_roaming(vdev)) {
if (!wlan_cm_roam_is_mlo_ap(vdev))
return false;
} else if (!wlan_vdev_mlme_is_mlo_vdev(vdev)) {
return false;
}
return true;
}
#endif /* WLAN_FEATURE_11BE_MLO */
#if defined(WLAN_FEATURE_ROAM_OFFLOAD) && defined(WLAN_FEATURE_11BE_MLO)
/**
* wlan_cm_reset_mlo_roam_peer_address() - this API reset the sae_roam_auth
* structure values to zero.
* @rso_config: pointer to struct rso_config
*
* Return: void
*/
static void wlan_cm_reset_mlo_roam_peer_address(struct rso_config *rso_config)
{
qdf_mem_zero(&rso_config->sae_roam_auth.peer_mldaddr,
QDF_MAC_ADDR_SIZE);
qdf_mem_zero(&rso_config->sae_roam_auth.peer_linkaddr,
QDF_MAC_ADDR_SIZE);
}
void wlan_cm_store_mlo_roam_peer_address(struct wlan_objmgr_pdev *pdev,
struct auth_offload_event *auth_event)
{
struct wlan_objmgr_vdev *vdev;
struct rso_config *rso_config;
struct qdf_mac_addr mld_addr;
QDF_STATUS status;
if (!pdev) {
mlme_err("pdev is NULL");
return;
}
vdev = wlan_objmgr_get_vdev_by_id_from_pdev(pdev, auth_event->vdev_id,
WLAN_LEGACY_MAC_ID);
if (!vdev) {
mlme_err("vdev %d not found", auth_event->vdev_id);
return;
}
if (!wlan_vdev_get_mlo_external_sae_auth_conversion(vdev))
goto rel_ref;
if (!wlan_cm_is_vdev_roaming(vdev))
goto rel_ref;
rso_config = wlan_cm_get_rso_config(vdev);
if (!rso_config)
goto rel_ref;
if (qdf_is_macaddr_zero(&auth_event->ta)) {
/* ta have zero value for non-ML AP */
rso_config->sae_roam_auth.is_mlo_ap = false;
wlan_cm_reset_mlo_roam_peer_address(rso_config);
goto rel_ref;
}
status = scm_get_mld_addr_by_link_addr(pdev, &auth_event->ap_bssid,
&mld_addr);
rso_config->sae_roam_auth.is_mlo_ap = true;
if (QDF_IS_STATUS_ERROR(status)) {
wlan_cm_reset_mlo_roam_peer_address(rso_config);
goto rel_ref;
}
qdf_mem_copy(rso_config->sae_roam_auth.peer_mldaddr.bytes,
mld_addr.bytes, QDF_MAC_ADDR_SIZE);
qdf_mem_copy(rso_config->sae_roam_auth.peer_linkaddr.bytes,
&auth_event->ap_bssid, QDF_MAC_ADDR_SIZE);
mlme_debug("mld addr " QDF_MAC_ADDR_FMT "link addr " QDF_MAC_ADDR_FMT,
QDF_MAC_ADDR_REF(rso_config->sae_roam_auth.peer_mldaddr.bytes),
QDF_MAC_ADDR_REF(rso_config->sae_roam_auth.peer_linkaddr.bytes));
rel_ref:
wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_MAC_ID);
}
struct qdf_mac_addr *
wlan_cm_roaming_get_peer_mld_addr(struct wlan_objmgr_vdev *vdev)
{
struct rso_config *rso_config;
rso_config = wlan_cm_get_rso_config(vdev);
if (!rso_config)
return NULL;
if (qdf_is_macaddr_zero(&rso_config->sae_roam_auth.peer_mldaddr))
return NULL;
return &rso_config->sae_roam_auth.peer_mldaddr;
}
struct qdf_mac_addr *
wlan_cm_roaming_get_peer_link_addr(struct wlan_objmgr_vdev *vdev)
{
struct rso_config *rso_config;
rso_config = wlan_cm_get_rso_config(vdev);
if (!rso_config)
return NULL;
if (qdf_is_macaddr_zero(&rso_config->sae_roam_auth.peer_linkaddr))
return NULL;
return &rso_config->sae_roam_auth.peer_linkaddr;
}
bool wlan_cm_roam_is_mlo_ap(struct wlan_objmgr_vdev *vdev)
{
struct rso_config *rso_config;
rso_config = wlan_cm_get_rso_config(vdev);
if (!rso_config)
return false;
return rso_config->sae_roam_auth.is_mlo_ap;
}
#endif /* WLAN_FEATURE_ROAM_OFFLOAD && WLAN_FEATURE_11BE_MLO */