qcacld-3.0: Add global MAC filters to filter beacon/probe frames in PE

Add filter structures in global mac context and apply the filter for
beacon/probe frames received in pe_handle_mgmt_frames before posting
the frames to PE queue.

Change-Id: Ic0e574705764c1bb247977a4c86e394b47941f5b
CRs-Fixed: 2226223
This commit is contained in:
Vignesh Viswanathan 2018-04-06 00:06:27 +05:30 committed by nshrivas
parent cad91325bf
commit b3dbbc8cba
6 changed files with 332 additions and 57 deletions

View File

@ -1,9 +1,6 @@
/*
* Copyright (c) 2012-2018 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all
@ -19,12 +16,6 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/*
* This file was originally distributed by Qualcomm Atheros, Inc.
* under proprietary terms before Copyright ownership was assigned
* to the Linux Foundation.
*/
#ifndef _ANIGLOBAL_H
#define _ANIGLOBAL_H
@ -875,6 +866,28 @@ struct vdev_type_nss {
uint8_t ocb;
};
/**
* struct mgmt_beacon_probe_filter
* @bcn_filter_lock: Spinlock for the filter structure
* @num_sta_sessions: Number of active PE STA sessions
* @sta_bssid: Array of PE STA session's peer BSSIDs
* @num_ibss_sessions: Number of active PE IBSS sessions
* @ibss_ssid: Array of PE IBSS session's SSID
* @num_sap_session: Number of active PE SAP sessions
* @sap_channel: Array of PE SAP session's channels
*
* Used to filter the STA/IBSS/SAP beacons/probes required in PE and
* drop other unwanted beacon/probe response frames
*/
struct mgmt_beacon_probe_filter {
uint8_t num_sta_sessions;
tSirMacAddr sta_bssid[SIR_MAX_SUPPORTED_BSS];
uint8_t num_ibss_sessions;
tSirMacSSid ibss_ssid[SIR_MAX_SUPPORTED_BSS];
uint8_t num_sap_sessions;
uint8_t sap_channel[SIR_MAX_SUPPORTED_BSS];
};
/* ------------------------------------------------------------------- */
/* / MAC Sirius parameter structure */
typedef struct sAniSirGlobal {
@ -949,6 +962,7 @@ typedef struct sAniSirGlobal {
uint16_t usr_cfg_ba_buff_size;
uint8_t no_ack_policy_cfg[MAX_NUM_AC];
uint32_t he_sgi_ltf_cfg_bit_mask;
struct mgmt_beacon_probe_filter bcn_filter;
} tAniSirGlobal;

View File

@ -1,9 +1,6 @@
/*
* Copyright (c) 2012-2018 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all
@ -19,12 +16,6 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/*
* This file was originally distributed by Qualcomm Atheros, Inc.
* under proprietary terms before Copyright ownership was assigned
* to the Linux Foundation.
*/
#if !defined(__LIM_SESSION_H)
#define __LIM_SESSION_H
@ -697,4 +688,46 @@ uint8_t pe_get_active_session_count(tpAniSirGlobal mac_ctx);
*/
void pe_delete_fils_info(tpPESession session);
#endif
/**
* lim_set_bcn_probe_filter - set the beacon/probe filter in mac context
*
* @mac_ctx: pointer to global mac context
* @session: pointer to the PE session
* @ibss_ssid: SSID of the session for IBSS sessions
* @sap_channel: Operating Channel of the session for SAP sessions
*
* Sets the beacon/probe filter in the global mac context to filter
* and drop beacon/probe frames before posting it to PE queue
*
* Return: None
*/
void lim_set_bcn_probe_filter(tpAniSirGlobal mac_ctx,
tpPESession session,
tSirMacSSid *ibss_ssid,
uint8_t sap_channel);
/**
* lim_reset_bcn_probe_filter - clear the beacon/probe filter in mac context
*
* @mac_ctx: pointer to the global mac context
* @session: pointer to the PE session whose filter is to be cleared
*
* Return: None
*/
void lim_reset_bcn_probe_filter(tpAniSirGlobal mac_ctx, tpPESession session);
/**
* lim_update_bcn_probe_filter - Update the beacon/probe filter in mac context
*
* @mac_ctx: pointer to the global mac context
* @session: pointer to the PE session whose filter is to be cleared
*
* This API is applicable only for SAP sessions to update the SAP channel
* in the filter during a channel switch
*
* Return: None
*/
void lim_update_bcn_probe_filter(tpAniSirGlobal mac_ctx, tpPESession session);
#endif /* #if !defined( __LIM_SESSION_H ) */

View File

@ -1,9 +1,6 @@
/*
* Copyright (c) 2011-2018 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all
@ -19,12 +16,6 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/*
* This file was originally distributed by Qualcomm Atheros, Inc.
* under proprietary terms before Copyright ownership was assigned
* to the Linux Foundation.
*/
/*
* This file lim_api.cc contains the functions that are
* exported by LIM to other modules.
@ -77,6 +68,8 @@
#include "os_if_nan.h"
#include <wlan_scan_ucfg_api.h>
#include <wlan_p2p_ucfg_api.h>
#include "wlan_utility.h"
static void __lim_init_scan_vars(tpAniSirGlobal pMac)
{
@ -1214,6 +1207,87 @@ static QDF_STATUS pe_drop_pending_rx_mgmt_frames(tpAniSirGlobal mac_ctx,
return QDF_STATUS_SUCCESS;
}
/**
* pe_filter_drop_bcn_probe_frame - Apply filter on the received frame
*
* @mac_ctx: pointer to the global mac context
* @hdr: pointer to the 802.11 header of the frame
* @rx_pkt_info: pointer to the rx packet meta
*
* Applies the filter from global mac context on the received beacon/
* probe response frame before posting it to the PE queue
*
* Return: true if frame is allowed, false if frame is to be dropped.
*/
static bool pe_filter_bcn_probe_frame(tpAniSirGlobal mac_ctx,
tpSirMacMgmtHdr hdr,
uint8_t *rx_pkt_info)
{
uint8_t session_id;
uint8_t *body;
const uint8_t *ssid_ie;
uint16_t frame_len;
struct mgmt_beacon_probe_filter *filter;
tpSirMacCapabilityInfo bcn_caps;
tSirMacSSid bcn_ssid;
filter = &mac_ctx->bcn_filter;
/*
* If any STA session exists and beacon source matches any of the
* STA BSSIDs, allow the frame
*/
if (filter->num_sta_sessions) {
for (session_id = 0; session_id < SIR_MAX_SUPPORTED_BSS;
session_id++) {
if (sir_compare_mac_addr(filter->sta_bssid[session_id],
hdr->bssId)) {
return true;
}
}
}
/*
* If any IBSS session exists and beacon is has IBSS capability set
* and SSID matches the IBSS SSID, allow the frame
*/
if (filter->num_ibss_sessions) {
body = WMA_GET_RX_MPDU_DATA(rx_pkt_info);
frame_len = WMA_GET_RX_PAYLOAD_LEN(rx_pkt_info);
if (frame_len < SIR_MAC_B_PR_SSID_OFFSET)
return false;
bcn_caps = (tpSirMacCapabilityInfo)
(body + SIR_MAC_B_PR_CAPAB_OFFSET);
if (!bcn_caps->ibss)
return false;
ssid_ie = wlan_get_ie_ptr_from_eid(SIR_MAC_SSID_EID,
body + SIR_MAC_B_PR_SSID_OFFSET,
frame_len);
if (!ssid_ie)
return false;
bcn_ssid.length = ssid_ie[1];
qdf_mem_copy(&bcn_ssid.ssId,
&ssid_ie[2],
bcn_ssid.length);
for (session_id = 0; session_id < SIR_MAX_SUPPORTED_BSS;
session_id++) {
if (filter->ibss_ssid[session_id].length ==
bcn_ssid.length &&
(!qdf_mem_cmp(filter->ibss_ssid[session_id].ssId,
bcn_ssid.ssId, bcn_ssid.length))) {
return true;
}
}
}
return false;
}
/* --------------------------------------------------------------------------- */
/**
* pe_handle_mgmt_frame() - Process the Management frames from TXRX
@ -1277,6 +1351,18 @@ static QDF_STATUS pe_handle_mgmt_frame(struct wlan_objmgr_psoc *psoc,
mHdr = WMA_GET_RX_MAC_HEADER(pRxPacketInfo);
/*
* Filter the beacon/probe response frames before posting it
* on the PE queue
*/
if ((mHdr->fc.subType == SIR_MAC_MGMT_BEACON ||
mHdr->fc.subType == SIR_MAC_MGMT_PROBE_RSP) &&
!pe_filter_bcn_probe_frame(pMac, mHdr, pRxPacketInfo)) {
cds_pkt_return_packet(pVosPkt);
pVosPkt = NULL;
return QDF_STATUS_SUCCESS;
}
if (QDF_STATUS_SUCCESS !=
pe_drop_pending_rx_mgmt_frames(pMac, mHdr, pVosPkt))
return QDF_STATUS_E_FAILURE;
@ -2269,12 +2355,13 @@ QDF_STATUS pe_roam_synch_callback(tpAniSirGlobal mac_ctx,
lim_print_mac_addr(mac_ctx, bss_desc->bssId, LOGE);
return status;
}
ft_session_ptr->peSessionId = session_id;
/* Update the beacon/probe filter in mac_ctx */
lim_set_bcn_probe_filter(mac_ctx, ft_session_ptr, NULL, 0);
sir_copy_mac_addr(ft_session_ptr->selfMacAddr, session_ptr->selfMacAddr);
sir_copy_mac_addr(roam_sync_ind_ptr->self_mac.bytes,
session_ptr->selfMacAddr);
sir_copy_mac_addr(ft_session_ptr->limReAssocbssId, bss_desc->bssId);
ft_session_ptr->bssType = eSIR_INFRASTRUCTURE_MODE;
session_ptr->bRoamSynchInProgress = true;
ft_session_ptr->bRoamSynchInProgress = true;
ft_session_ptr->limSystemRole = eLIM_STA_ROLE;

View File

@ -1,8 +1,6 @@
/*
* Copyright (c) 2016-2018 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all
@ -450,13 +448,17 @@ void lim_handle_ft_pre_auth_rsp(tpAniSirGlobal pMac, tSirRetStatus status,
psessionEntry->ftPEContext.ftPreAuthStatus = status;
goto send_rsp;
}
pftSessionEntry->peSessionId = sessionId;
pftSessionEntry->smeSessionId = psessionEntry->smeSessionId;
sir_copy_mac_addr(pftSessionEntry->selfMacAddr,
psessionEntry->selfMacAddr);
sir_copy_mac_addr(pftSessionEntry->limReAssocbssId,
pbssDescription->bssId);
pftSessionEntry->bssType = psessionEntry->bssType;
/* Update the beacon/probe filter in mac_ctx */
lim_set_bcn_probe_filter(pMac,
pftSessionEntry,
NULL, 0);
if (pftSessionEntry->bssType == eSIR_INFRASTRUCTURE_MODE)
pftSessionEntry->limSystemRole = eLIM_STA_ROLE;

View File

@ -1,9 +1,6 @@
/*
* Copyright (c) 2012-2018 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all
@ -19,12 +16,6 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/*
* This file was originally distributed by Qualcomm Atheros, Inc.
* under proprietary terms before Copyright ownership was assigned
* to the Linux Foundation.
*/
/*
* This file lim_process_sme_req_messages.cc contains the code
* for processing SME request messages.
@ -643,6 +634,11 @@ __lim_handle_sme_start_bss_request(tpAniSirGlobal mac_ctx, uint32_t *msg_buf)
ret_code = eSIR_SME_RESOURCES_UNAVAILABLE;
goto free;
}
/* Update the beacon/probe filter in mac_ctx */
lim_set_bcn_probe_filter(mac_ctx, session,
&sme_start_bss_req->ssId,
sme_start_bss_req->channelId);
}
if (QDF_NDI_MODE != sme_start_bss_req->bssPersona) {
@ -676,9 +672,6 @@ __lim_handle_sme_start_bss_request(tpAniSirGlobal mac_ctx, uint32_t *msg_buf)
/* Store the session related params in newly created session */
session->pLimStartBssReq = sme_start_bss_req;
/* Store PE session_id in session Table */
session->peSessionId = session_id;
/* Store SME session Id in sessionTable */
session->smeSessionId = sme_start_bss_req->sessionId;
@ -1328,17 +1321,21 @@ __lim_process_sme_join_req(tpAniSirGlobal mac_ctx, uint32_t *msg_buf)
pe_err("Session Can not be created");
ret_code = eSIR_SME_RESOURCES_UNAVAILABLE;
goto end;
} else
} else {
pe_debug("SessionId:%d New session created",
session_id);
}
/* Update the beacon/probe filter in mac_ctx */
lim_set_bcn_probe_filter(mac_ctx, session,
&sme_join_req->ssId,
bss_desc->channelId);
}
session->max_amsdu_num = sme_join_req->max_amsdu_num;
/*
* Store Session related parameters
* Store PE session Id in session Table
*/
session->peSessionId = session_id;
/* store the smejoin req handle in session table */
session->pLimJoinReq = sme_join_req;

View File

@ -1,9 +1,6 @@
/*
* Copyright (c) 2011-2018 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all
@ -19,12 +16,6 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/*
* This file was originally distributed by Qualcomm Atheros, Inc.
* under proprietary terms before Copyright ownership was assigned
* to the Linux Foundation.
*/
/**=========================================================================
\file lim_session.c
@ -379,6 +370,152 @@ lim_get_peer_idxpool_size(uint16_t num_sta, tSirBssType bss_type)
}
#endif
void lim_set_bcn_probe_filter(tpAniSirGlobal mac_ctx,
tpPESession session,
tSirMacSSid *ibss_ssid,
uint8_t sap_channel)
{
struct mgmt_beacon_probe_filter *filter;
tSirBssType bss_type;
uint8_t session_id;
tSirMacAddr *bssid;
if (!session) {
pe_err("Invalid session pointer");
return;
}
bss_type = session->bssType;
session_id = session->peSessionId;
bssid = &session->bssId;
if (session_id >= SIR_MAX_SUPPORTED_BSS) {
pe_err("Invalid session_id %d of type %d",
session_id, bss_type);
return;
}
filter = &mac_ctx->bcn_filter;
if (eSIR_INFRASTRUCTURE_MODE == bss_type) {
filter->num_sta_sessions++;
sir_copy_mac_addr(filter->sta_bssid[session_id], *bssid);
pe_debug("Set filter for STA Session %d bssid "MAC_ADDRESS_STR,
session_id, MAC_ADDR_ARRAY(*bssid));
} else if (eSIR_IBSS_MODE == bss_type) {
if (!ibss_ssid) {
pe_err("IBSS Type with NULL SSID");
goto done;
}
filter->num_ibss_sessions++;
filter->ibss_ssid[session_id].length = ibss_ssid->length;
qdf_mem_copy(&filter->ibss_ssid[session_id].length,
ibss_ssid->ssId,
ibss_ssid->length);
pe_debug("Set filter for IBSS session %d ssid %s",
session_id, ibss_ssid->ssId);
} else if (eSIR_INFRA_AP_MODE == bss_type) {
if (!sap_channel) {
pe_err("SAP Type with invalid channel");
goto done;
}
filter->num_sap_sessions++;
filter->sap_channel[session_id] = sap_channel;
pe_debug("Set filter for SAP session %d channel %d",
session_id, sap_channel);
}
done:
pe_debug("sta %d ibss %d sap %d",
filter->num_sta_sessions, filter->num_ibss_sessions,
filter->num_sap_sessions);
}
void lim_reset_bcn_probe_filter(tpAniSirGlobal mac_ctx,
tpPESession session)
{
struct mgmt_beacon_probe_filter *filter;
tSirBssType bss_type;
uint8_t session_id;
if (!session) {
pe_err("Invalid session pointer");
return;
}
bss_type = session->bssType;
session_id = session->peSessionId;
if (session_id >= SIR_MAX_SUPPORTED_BSS) {
pe_err("Invalid session_id %d of type %d",
session_id, bss_type);
return;
}
filter = &mac_ctx->bcn_filter;
if (eSIR_INFRASTRUCTURE_MODE == bss_type) {
if (filter->num_sta_sessions)
filter->num_sta_sessions--;
qdf_mem_set(&filter->sta_bssid[session_id],
sizeof(tSirMacAddr), 0);
pe_debug("Cleared STA Filter for session %d", session_id);
} else if (eSIR_IBSS_MODE == bss_type) {
if (filter->num_ibss_sessions)
filter->num_ibss_sessions--;
filter->ibss_ssid[session_id].length = 0;
qdf_mem_set(&filter->ibss_ssid[session_id].ssId,
SIR_MAC_MAX_SSID_LENGTH, 0);
pe_debug("Cleared IBSS Filter for session %d", session_id);
} else if (eSIR_INFRA_AP_MODE == bss_type) {
if (filter->num_sap_sessions)
filter->num_sap_sessions--;
filter->sap_channel[session_id] = 0;
pe_debug("Cleared SAP Filter for session %d", session_id);
}
pe_debug("sta %d ibss %d sap %d",
filter->num_sta_sessions, filter->num_ibss_sessions,
filter->num_sap_sessions);
}
void lim_update_bcn_probe_filter(tpAniSirGlobal mac_ctx,
tpPESession session)
{
struct mgmt_beacon_probe_filter *filter;
tSirBssType bss_type;
uint8_t session_id;
if (!session) {
pe_err("Invalid session pointer");
return;
}
bss_type = session->bssType;
session_id = session->peSessionId;
if (session_id >= SIR_MAX_SUPPORTED_BSS) {
pe_err("Invalid session_id %d of type %d",
session_id, bss_type);
return;
}
filter = &mac_ctx->bcn_filter;
if (eSIR_INFRA_AP_MODE == bss_type) {
filter->sap_channel[session_id] = session->currentOperChannel;
pe_debug("Updated SAP Filter for session %d channel %d",
session_id, filter->sap_channel[session_id]);
} else {
pe_debug("Invalid session type %d session id %d",
bss_type, session_id);
}
pe_debug("sta %d ibss %d sap %d",
filter->num_sta_sessions, filter->num_ibss_sessions,
filter->num_sap_sessions);
}
/**
* pe_create_session() creates a new PE session given the BSSID
* @param pMac: pointer to global adapter context
@ -459,6 +596,8 @@ pe_create_session(tpAniSirGlobal pMac, uint8_t *bssid, uint8_t *sessionId,
session_ptr->isFastTransitionEnabled = false;
session_ptr->isFastRoamIniFeatureEnabled = false;
*sessionId = i;
session_ptr->peSessionId = i;
session_ptr->bssType = bssType;
session_ptr->gLimPhyMode = WNI_CFG_PHY_MODE_11G;
/* Initialize CB mode variables when session is created */
session_ptr->htSupportedChannelWidthSet = 0;
@ -689,6 +828,9 @@ void pe_delete_session(tpAniSirGlobal mac_ctx, tpPESession session)
session->peSessionId, session->operMode,
session->bssIdx,
MAC_ADDR_ARRAY(session->bssId));
lim_reset_bcn_probe_filter(mac_ctx, session);
for (n = 0; n < (mac_ctx->lim.maxStation + 1); n++) {
timer_ptr = &mac_ctx->lim.limTimers.gpLimCnfWaitTimer[n];
if (session->peSessionId == timer_ptr->sessionId)