qcacld-3.0: Do not allow duplicate peer creation for ML-SAP

As per current design, peer conflict detection logic allows
a peer with particular mac/mld to be created as long as
the ml dev context is same. However, this causes issues
for ML-STA wherein 2 different peer ML-STA could have same
mac address. In this case, the second peer creations should
be disallowed.

To fix this, skip the mac/mld conflict checks on the ml-dev
context of the ML-SAP and handle it separately.

In addition to the current checks add the following checks
for ML-SAP and reject the peer creation if:
a) MLO peer exists for the link mac of peer with different AID.
b) MLO peer exists for the MLD mac of peer with different AID:
c) If the associating client's MLD != one of the link mac address
and there is an MLO peer with different AID.

Change-Id: I75935e2362d6db1411c6a67f1e9db35f3b3963f2
CRs-Fixed: 3719956
Tento commit je obsažen v:
Vinod Kumar Pirla
2024-02-05 02:48:51 -08:00
odevzdal Ravindra Konda
rodič 96f926f3ec
revize 046d969548
2 změnil soubory, kde provedl 121 přidání a 68 odebrání

Zobrazit soubor

@@ -313,43 +313,6 @@ static void lim_process_auth_open_system_algo(struct mac_context *mac_ctx,
pe_session);
}
static QDF_STATUS
lim_validate_mac_address_in_auth_frame(struct mac_context *mac_ctx,
tpSirMacMgmtHdr mac_hdr,
struct qdf_mac_addr *mld_addr,
uint8_t vdev_id)
{
struct wlan_objmgr_vdev *vdev;
/* SA is same as any of the device vdev, return failure */
vdev = wlan_objmgr_get_vdev_by_macaddr_from_pdev(mac_ctx->pdev,
mac_hdr->sa,
WLAN_LEGACY_MAC_ID);
if (vdev) {
wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_MAC_ID);
return QDF_STATUS_E_ALREADY;
}
if (mlo_mgr_ml_peer_exist_on_diff_ml_ctx(mac_hdr->sa, &vdev_id))
return QDF_STATUS_E_ALREADY;
if (qdf_is_macaddr_zero(mld_addr))
return QDF_STATUS_SUCCESS;
vdev = wlan_objmgr_get_vdev_by_macaddr_from_pdev(mac_ctx->pdev,
mld_addr->bytes,
WLAN_LEGACY_MAC_ID);
if (vdev) {
wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_MAC_ID);
return QDF_STATUS_E_ALREADY;
}
if (mlo_mgr_ml_peer_exist_on_diff_ml_ctx(mld_addr->bytes, &vdev_id))
return QDF_STATUS_E_ALREADY;
return QDF_STATUS_SUCCESS;
}
#ifdef WLAN_FEATURE_SAE
#ifdef WLAN_FEATURE_11BE_MLO
/**
@@ -804,15 +767,6 @@ static void lim_process_sae_auth_frame(struct mac_context *mac_ctx,
*/
lim_get_sta_mld_address(pe_session->vdev, body_ptr,
frame_len, &peer_mld);
status = lim_validate_mac_address_in_auth_frame(mac_ctx,
mac_hdr,
&peer_mld,
pe_session->vdev_id);
if (QDF_IS_STATUS_ERROR(status)) {
pe_debug("Drop SAE auth, duplicate entity found");
return;
}
lim_external_auth_add_pre_auth_node(mac_ctx, mac_hdr,
eLIM_MLM_WT_SAE_AUTH_STATE,
&peer_mld);
@@ -1014,7 +968,6 @@ static void lim_process_auth_frame_type1(struct mac_context *mac_ctx,
struct tLimPreAuthNode *auth_node;
uint32_t maxnum_preauth;
uint16_t associd = 0;
QDF_STATUS status;
if (lim_check_and_trigger_pmf_sta_deletion(mac_ctx, pe_session,
mac_hdr))
@@ -1106,27 +1059,6 @@ static void lim_process_auth_frame_type1(struct mac_context *mac_ctx,
if (lim_is_auth_algo_supported(mac_ctx,
(tAniAuthType) rx_auth_frm_body->authAlgoNumber,
pe_session)) {
struct qdf_mac_addr *mld_addr = &rx_auth_frm_body->peer_mld;
status = lim_validate_mac_address_in_auth_frame(mac_ctx,
mac_hdr,
mld_addr,
pe_session->vdev_id);
if (QDF_IS_STATUS_ERROR(status)) {
pe_err("Duplicate MAC address found, reject auth");
auth_frame->authAlgoNumber =
rx_auth_frm_body->authAlgoNumber;
auth_frame->authTransactionSeqNumber =
rx_auth_frm_body->authTransactionSeqNumber + 1;
auth_frame->authStatusCode =
STATUS_UNSPECIFIED_FAILURE;
lim_send_auth_mgmt_frame(mac_ctx, auth_frame,
mac_hdr->sa, LIM_NO_WEP_IN_FC,
pe_session);
return;
}
switch (rx_auth_frm_body->authAlgoNumber) {
case eSIR_OPEN_SYSTEM:
lim_process_auth_open_system_algo(mac_ctx, mac_hdr,

Zobrazit soubor

@@ -4776,6 +4776,110 @@ static void wma_get_mld_info_ap(tpAddStaParams add_sta,
*is_assoc_peer = false;
}
}
static inline QDF_STATUS
wma_check_for_mlo_peer_conflict(struct wlan_mlo_peer_context *peer_1,
struct wlan_mlo_peer_context *peer_2)
{
if (!peer_1 && !peer_2)
return QDF_STATUS_SUCCESS;
if (!peer_2) {
wma_err("ML-peer with same mac address exists for a different AID");
return QDF_STATUS_E_ALREADY;
} else if (peer_1 == peer_2) {
return QDF_STATUS_SUCCESS;
}
/* Two ML-peers exists with different AID */
QDF_ASSERT(0);
return QDF_STATUS_E_FAILURE;
}
static QDF_STATUS
wma_validate_mac_for_conflict_on_same_ml_ctx(tp_wma_handle wma,
tpAddStaParams add_sta,
uint8_t *peer_mld)
{
struct wlan_objmgr_vdev *vdev = NULL;
struct wlan_mlo_peer_context *ml_peer, *tmp_ml_peer;
struct qdf_mac_addr sta_addr = {0};
struct wlan_objmgr_peer *peer;
QDF_STATUS status = QDF_STATUS_SUCCESS;
vdev = wlan_objmgr_get_vdev_by_id_from_psoc(wma->psoc,
add_sta->smesessionId,
WLAN_LEGACY_WMA_ID);
if (!vdev)
return QDF_STATUS_E_FAILURE;
/* Not an ML-SAP, therefore skip the validation */
if (!vdev->mlo_dev_ctx)
goto release_ref;
qdf_mem_copy(&sta_addr.bytes[0], add_sta->staMac,
sizeof(tSirMacAddr));
ml_peer = wlan_mlo_get_mlpeer(vdev->mlo_dev_ctx,
&sta_addr);
/*
* ML-peer exists on the ML-dev with same address.
* If the AID is different, then another ML-STA
* is already associated to this SAP using the
* same MLD mac
*/
if (ml_peer) {
tmp_ml_peer = wlan_mlo_get_mlpeer_by_aid(vdev->mlo_dev_ctx,
add_sta->assocId);
status = wma_check_for_mlo_peer_conflict(ml_peer, tmp_ml_peer);
if (QDF_IS_STATUS_ERROR(status)) {
wma_err("Link mac address conflicts with another MLO peer on same interface");
goto release_ref;
}
}
/*
* ML-peer exists on the ML-dev with same MLD address.
* If the AID is different, reject the peer create
*/
ml_peer = wlan_mlo_get_mlpeer(vdev->mlo_dev_ctx,
(struct qdf_mac_addr *)peer_mld);
if (ml_peer) {
tmp_ml_peer = wlan_mlo_get_mlpeer_by_aid(vdev->mlo_dev_ctx,
add_sta->assocId);
status = wma_check_for_mlo_peer_conflict(ml_peer, tmp_ml_peer);
if (QDF_IS_STATUS_ERROR(status)) {
wma_err("MLD mac address conflicts with another MLO peer on same interface");
goto release_ref;
}
}
/*
* If the link address of another ML-peer(with different AID) matches
* with the MLD address of the incoming peer, reject the peer create.
*
* Note: Legacy MLD mac - link mac conflict is taken care at
* wma_create_peer_validate_mld_address()
*/
peer = wlan_objmgr_get_peer_by_mac(wma->psoc, peer_mld,
WLAN_LEGACY_WMA_ID);
if (!peer) {
goto release_ref;
} else {
if (peer->mlo_peer_ctx &&
peer->mlo_peer_ctx->assoc_id != add_sta->assocId) {
wma_err("MLD mac address conflicts with link mac address of another ML-peer on same interface");
status = QDF_STATUS_E_FAILURE;
}
wlan_objmgr_peer_release_ref(peer, WLAN_LEGACY_WMA_ID);
}
release_ref:
wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_WMA_ID);
return status;
}
#else
static void wma_get_mld_info_ap(tpAddStaParams add_sta,
uint8_t **peer_mld_addr,
@@ -4784,6 +4888,14 @@ static void wma_get_mld_info_ap(tpAddStaParams add_sta,
*peer_mld_addr = NULL;
*is_assoc_peer = false;
}
static QDF_STATUS
wma_validate_mac_for_conflict_on_same_ml_ctx(tp_wma_handle wma,
tpAddStaParams add_sta,
uint8_t *peer_mld)
{
return QDF_STATUS_SUCCESS;
}
#endif
/**
@@ -4849,6 +4961,15 @@ static void wma_add_sta_req_ap_mode(tp_wma_handle wma, tpAddStaParams add_sta)
wma_delete_invalid_peer_entries(add_sta->smesessionId, add_sta->staMac);
wma_get_mld_info_ap(add_sta, &peer_mld_addr, &is_assoc_peer);
status = wma_validate_mac_for_conflict_on_same_ml_ctx(wma, add_sta,
peer_mld_addr);
if (QDF_IS_STATUS_ERROR(status)) {
wma_err("Conflict detected with mac address, peer create failed");
add_sta->status = status;
goto send_rsp;
}
status = wma_create_peer(wma, add_sta->staMac, WMI_PEER_TYPE_DEFAULT,
add_sta->smesessionId, peer_mld_addr,
is_assoc_peer);