blob: 7540588c7c09c81f23f7ccbc334396827f97bda9 [file] [log] [blame]
/*
* Copyright (c) 2017-2021 The Linux Foundation. All rights reserved.
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
*
* 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
* copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
/*
* DOC: contains scan cache filter logic
*/
#include <wlan_scan_utils_api.h>
#include "wlan_scan_main.h"
#include "wlan_scan_cache_db_i.h"
#include <wlan_dfs_utils_api.h>
#include "wlan_crypto_global_def.h"
#include "wlan_crypto_global_api.h"
/**
* scm_check_open() - Check if scan entry support open authmode
* @filter: scan filter
* @db_entry: db entry
* @security: matched security.
*
* Return: true if open security else false
*/
static bool scm_check_open(struct scan_filter *filter,
struct scan_cache_entry *db_entry,
struct security_info *security)
{
if (db_entry->cap_info.wlan_caps.privacy) {
scm_debug(QDF_MAC_ADDR_FMT" : have privacy set",
QDF_MAC_ADDR_REF(db_entry->bssid.bytes));
return false;
}
if (filter->ucastcipherset &&
!(QDF_HAS_PARAM(filter->ucastcipherset, WLAN_CRYPTO_CIPHER_NONE))) {
scm_debug(QDF_MAC_ADDR_FMT" : Filter doesn't have CIPHER none in uc %x",
QDF_MAC_ADDR_REF(db_entry->bssid.bytes),
filter->ucastcipherset);
return false;
}
if (filter->mcastcipherset &&
!(QDF_HAS_PARAM(filter->mcastcipherset, WLAN_CRYPTO_CIPHER_NONE))) {
scm_debug(QDF_MAC_ADDR_FMT" : Filter doesn't have CIPHER none in mc %x",
QDF_MAC_ADDR_REF(db_entry->bssid.bytes),
filter->mcastcipherset);
return false;
}
QDF_SET_PARAM(security->ucastcipherset, WLAN_CRYPTO_CIPHER_NONE);
QDF_SET_PARAM(security->mcastcipherset, WLAN_CRYPTO_CIPHER_NONE);
return true;
}
/**
* scm_check_wep() - Check if scan entry support WEP authmode
* @filter: scan filter
* @db_entry: db entry
* @security: matched security.
*
* Return: true if WEP security else false
*/
static bool scm_check_wep(struct scan_filter *filter,
struct scan_cache_entry *db_entry,
struct security_info *security)
{
/* If privacy bit is not set, consider no match */
if (!db_entry->cap_info.wlan_caps.privacy) {
scm_debug(QDF_MAC_ADDR_FMT" : doesn't have privacy set",
QDF_MAC_ADDR_REF(db_entry->bssid.bytes));
return false;
}
if (!(db_entry->security_type & SCAN_SECURITY_TYPE_WEP)) {
scm_debug(QDF_MAC_ADDR_FMT" : doesn't support WEP",
QDF_MAC_ADDR_REF(db_entry->bssid.bytes));
return false;
}
if (!filter->ucastcipherset || !filter->mcastcipherset) {
scm_debug(QDF_MAC_ADDR_FMT" : Filter uc %x or mc %x cipher are 0",
QDF_MAC_ADDR_REF(db_entry->bssid.bytes),
filter->ucastcipherset,
filter->mcastcipherset);
return false;
}
if (!(QDF_HAS_PARAM(filter->ucastcipherset, WLAN_CRYPTO_CIPHER_WEP) ||
QDF_HAS_PARAM(filter->ucastcipherset, WLAN_CRYPTO_CIPHER_WEP_40) ||
QDF_HAS_PARAM(filter->ucastcipherset,
WLAN_CRYPTO_CIPHER_WEP_104))) {
scm_debug(QDF_MAC_ADDR_FMT" : Filter doesn't have WEP cipher in uc %x",
QDF_MAC_ADDR_REF(db_entry->bssid.bytes),
filter->ucastcipherset);
return false;
}
if (!(QDF_HAS_PARAM(filter->mcastcipherset, WLAN_CRYPTO_CIPHER_WEP) ||
QDF_HAS_PARAM(filter->mcastcipherset, WLAN_CRYPTO_CIPHER_WEP_40) ||
QDF_HAS_PARAM(filter->mcastcipherset,
WLAN_CRYPTO_CIPHER_WEP_104))) {
scm_debug(QDF_MAC_ADDR_FMT" : Filter doesn't have WEP cipher in mc %x",
QDF_MAC_ADDR_REF(db_entry->bssid.bytes),
filter->mcastcipherset);
return false;
}
if (QDF_HAS_PARAM(filter->ucastcipherset, WLAN_CRYPTO_CIPHER_WEP))
QDF_SET_PARAM(security->ucastcipherset, WLAN_CRYPTO_CIPHER_WEP);
if (QDF_HAS_PARAM(filter->ucastcipherset, WLAN_CRYPTO_CIPHER_WEP_40))
QDF_SET_PARAM(security->ucastcipherset,
WLAN_CRYPTO_CIPHER_WEP_40);
if (QDF_HAS_PARAM(filter->ucastcipherset, WLAN_CRYPTO_CIPHER_WEP_104))
QDF_SET_PARAM(security->ucastcipherset,
WLAN_CRYPTO_CIPHER_WEP_104);
if (QDF_HAS_PARAM(filter->mcastcipherset, WLAN_CRYPTO_CIPHER_WEP))
QDF_SET_PARAM(security->mcastcipherset, WLAN_CRYPTO_CIPHER_WEP);
if (QDF_HAS_PARAM(filter->mcastcipherset, WLAN_CRYPTO_CIPHER_WEP_40))
QDF_SET_PARAM(security->mcastcipherset,
WLAN_CRYPTO_CIPHER_WEP_40);
if (QDF_HAS_PARAM(filter->mcastcipherset, WLAN_CRYPTO_CIPHER_WEP_104))
QDF_SET_PARAM(security->mcastcipherset,
WLAN_CRYPTO_CIPHER_WEP_104);
return true;
}
/**
* scm_chk_if_cipher_n_akm_match() - Check if akm and ciphers match
* @filter: scan filter
* @ap_crypto: aps crypto params
*
* Return: true if matches
*/
static bool scm_chk_if_cipher_n_akm_match(struct scan_filter *filter,
struct wlan_crypto_params *ap_crypto)
{
/* Check AP's pairwise ciphers.*/
if (!(filter->ucastcipherset & ap_crypto->ucastcipherset))
return false;
/* Check AP's group cipher match.*/
if (!(filter->mcastcipherset & ap_crypto->mcastcipherset))
return false;
/* Check AP's AKM match with filter's AKM.*/
if (!(filter->key_mgmt & ap_crypto->key_mgmt))
return false;
/* Check AP's mgmt cipher match if present.*/
if ((filter->mgmtcipherset && ap_crypto->mgmtcipherset) &&
!(filter->mgmtcipherset & ap_crypto->mgmtcipherset))
return false;
if (filter->ignore_pmf_cap)
return true;
if (filter->pmf_cap == WLAN_PMF_REQUIRED &&
!(ap_crypto->rsn_caps & WLAN_CRYPTO_RSN_CAP_MFP_ENABLED))
return false;
if (filter->pmf_cap == WLAN_PMF_DISABLED &&
(ap_crypto->rsn_caps & WLAN_CRYPTO_RSN_CAP_MFP_REQUIRED))
return false;
return true;
}
static bool scm_chk_crypto_params(struct scan_filter *filter,
struct wlan_crypto_params *ap_crypto,
bool is_adaptive_11r,
struct scan_cache_entry *db_entry,
struct security_info *security)
{
if (!scm_chk_if_cipher_n_akm_match(filter, ap_crypto)) {
scm_debug(QDF_MAC_ADDR_FMT": fail. adaptive 11r %d Self: AKM %x CIPHER: mc %x uc %x mgmt %x pmf %d AP: AKM %x CIPHER: mc %x uc %x mgmt %x, RSN caps %x",
QDF_MAC_ADDR_REF(db_entry->bssid.bytes), is_adaptive_11r,
filter->key_mgmt, filter->mcastcipherset,
filter->ucastcipherset, filter->mgmtcipherset,
filter->pmf_cap, ap_crypto->key_mgmt,
ap_crypto->mcastcipherset, ap_crypto->ucastcipherset,
ap_crypto->mgmtcipherset, ap_crypto->rsn_caps);
return false;
}
security->mcastcipherset =
ap_crypto->mcastcipherset & filter->mcastcipherset;
security->ucastcipherset =
ap_crypto->ucastcipherset & filter->ucastcipherset;
security->key_mgmt = ap_crypto->key_mgmt & filter->key_mgmt;
security->rsn_caps = ap_crypto->rsn_caps;
return true;
}
/**
* scm_check_rsn() - Check if scan entry support RSN security
* @filter: scan filter
* @db_entry: db entry
* @security: matched security.
*
* Return: true if RSN security else false
*/
static bool scm_check_rsn(struct scan_filter *filter,
struct scan_cache_entry *db_entry,
struct security_info *security)
{
bool is_adaptive_11r;
QDF_STATUS status;
struct wlan_crypto_params *ap_crypto;
bool match;
if (!util_scan_entry_rsn(db_entry)) {
scm_debug(QDF_MAC_ADDR_FMT" : doesn't have RSN IE",
QDF_MAC_ADDR_REF(db_entry->bssid.bytes));
return false;
}
ap_crypto = qdf_mem_malloc(sizeof(*ap_crypto));
if (!ap_crypto)
return false;
status = wlan_crypto_rsnie_check(ap_crypto,
util_scan_entry_rsn(db_entry));
if (QDF_IS_STATUS_ERROR(status)) {
scm_err(QDF_MAC_ADDR_FMT": failed to parse RSN IE, status %d",
QDF_MAC_ADDR_REF(db_entry->bssid.bytes), status);
qdf_mem_free(ap_crypto);
return false;
}
is_adaptive_11r = db_entry->adaptive_11r_ap &&
filter->enable_adaptive_11r;
/* If adaptive 11r is enabled set the FT AKM for AP */
if (is_adaptive_11r) {
if (QDF_HAS_PARAM(ap_crypto->key_mgmt,
WLAN_CRYPTO_KEY_MGMT_IEEE8021X)) {
QDF_SET_PARAM(ap_crypto->key_mgmt,
WLAN_CRYPTO_KEY_MGMT_FT_IEEE8021X);
}
if (QDF_HAS_PARAM(ap_crypto->key_mgmt,
WLAN_CRYPTO_KEY_MGMT_PSK)) {
QDF_SET_PARAM(ap_crypto->key_mgmt,
WLAN_CRYPTO_KEY_MGMT_FT_PSK);
}
if (QDF_HAS_PARAM(ap_crypto->key_mgmt,
WLAN_CRYPTO_KEY_MGMT_PSK_SHA256)) {
QDF_SET_PARAM(ap_crypto->key_mgmt,
WLAN_CRYPTO_KEY_MGMT_FT_PSK);
}
if (QDF_HAS_PARAM(ap_crypto->key_mgmt,
WLAN_CRYPTO_KEY_MGMT_IEEE8021X_SHA256)) {
QDF_SET_PARAM(ap_crypto->key_mgmt,
WLAN_CRYPTO_KEY_MGMT_FT_IEEE8021X);
}
}
match = scm_chk_crypto_params(filter, ap_crypto, is_adaptive_11r,
db_entry, security);
qdf_mem_free(ap_crypto);
return match;
}
/**
* scm_check_wpa() - Check if scan entry support WPA security
* @filter: scan filter
* @db_entry: db entry
* @security: matched security.
*
* Return: true if WPA security else false
*/
static bool scm_check_wpa(struct scan_filter *filter,
struct scan_cache_entry *db_entry,
struct security_info *security)
{
QDF_STATUS status;
struct wlan_crypto_params *ap_crypto;
bool match;
if (!util_scan_entry_wpa(db_entry)) {
scm_debug(QDF_MAC_ADDR_FMT" : doesn't have WPA IE",
QDF_MAC_ADDR_REF(db_entry->bssid.bytes));
return false;
}
ap_crypto = qdf_mem_malloc(sizeof(*ap_crypto));
if (!ap_crypto)
return false;
status = wlan_crypto_wpaie_check(ap_crypto,
util_scan_entry_wpa(db_entry));
if (QDF_IS_STATUS_ERROR(status)) {
scm_err(QDF_MAC_ADDR_FMT": failed to parse WPA IE, status %d",
QDF_MAC_ADDR_REF(db_entry->bssid.bytes), status);
qdf_mem_free(ap_crypto);
return false;
}
match = scm_chk_crypto_params(filter, ap_crypto, false,
db_entry, security);
qdf_mem_free(ap_crypto);
return match;
}
/**
* scm_check_wapi() - Check if scan entry support WAPI security
* @filter: scan filter
* @db_entry: db entry
* @security: matched security.
*
* Return: true if WAPI security else false
*/
static bool scm_check_wapi(struct scan_filter *filter,
struct scan_cache_entry *db_entry,
struct security_info *security)
{
QDF_STATUS status;
struct wlan_crypto_params *ap_crypto;
if (!util_scan_entry_wapi(db_entry)) {
scm_debug(QDF_MAC_ADDR_FMT" : doesn't have WAPI IE",
QDF_MAC_ADDR_REF(db_entry->bssid.bytes));
return false;
}
ap_crypto = qdf_mem_malloc(sizeof(*ap_crypto));
if (!ap_crypto)
return false;
status = wlan_crypto_wapiie_check(ap_crypto,
util_scan_entry_wapi(db_entry));
if (QDF_IS_STATUS_ERROR(status)) {
scm_err(QDF_MAC_ADDR_FMT": failed to parse WAPI IE, status %d",
QDF_MAC_ADDR_REF(db_entry->bssid.bytes), status);
qdf_mem_free(ap_crypto);
return false;
}
if (!scm_chk_if_cipher_n_akm_match(filter, ap_crypto)) {
scm_debug(QDF_MAC_ADDR_FMT": fail. Self: AKM %x CIPHER: mc %x uc %x mgmt %x pmf %d AP: AKM %x CIPHER: mc %x uc %x mgmt %x, RSN caps %x",
QDF_MAC_ADDR_REF(db_entry->bssid.bytes), filter->key_mgmt,
filter->mcastcipherset, filter->ucastcipherset,
filter->mgmtcipherset, filter->pmf_cap,
ap_crypto->key_mgmt, ap_crypto->mcastcipherset,
ap_crypto->ucastcipherset, ap_crypto->mgmtcipherset,
ap_crypto->rsn_caps);
qdf_mem_free(ap_crypto);
return false;
}
security->mcastcipherset =
ap_crypto->mcastcipherset & filter->mcastcipherset;
security->ucastcipherset =
ap_crypto->ucastcipherset & filter->ucastcipherset;
security->key_mgmt = ap_crypto->key_mgmt & filter->key_mgmt;
security->rsn_caps = ap_crypto->rsn_caps;
qdf_mem_free(ap_crypto);
return true;
}
/**
* scm_match_any_security() - Check if any security in filter match
* @filter: scan filter
* @db_entry: db entry
* @security: matched security.
*
* Return: true if any security else false
*/
static bool scm_match_any_security(struct scan_filter *filter,
struct scan_cache_entry *db_entry,
struct security_info *security)
{
struct wlan_crypto_params *ap_crypto = {0};
QDF_STATUS status;
bool match = false;
ap_crypto = qdf_mem_malloc(sizeof(*ap_crypto));
if (!ap_crypto)
return match;
if (util_scan_entry_rsn(db_entry)) {
status = wlan_crypto_rsnie_check(ap_crypto,
util_scan_entry_rsn(db_entry));
if (QDF_IS_STATUS_ERROR(status)) {
scm_err(QDF_MAC_ADDR_FMT": failed to parse RSN IE, status %d",
QDF_MAC_ADDR_REF(db_entry->bssid.bytes), status);
goto free;
}
security->mcastcipherset = ap_crypto->mcastcipherset;
security->ucastcipherset = ap_crypto->ucastcipherset;
security->key_mgmt = ap_crypto->key_mgmt;
security->rsn_caps = ap_crypto->rsn_caps;
QDF_SET_PARAM(security->authmodeset, WLAN_CRYPTO_AUTH_RSNA);
match = true;
goto free;
}
if (util_scan_entry_wpa(db_entry)) {
status = wlan_crypto_wpaie_check(ap_crypto,
util_scan_entry_wpa(db_entry));
if (QDF_IS_STATUS_ERROR(status)) {
scm_err(QDF_MAC_ADDR_FMT": failed to parse WPA IE, status %d",
QDF_MAC_ADDR_REF(db_entry->bssid.bytes), status);
goto free;
}
security->mcastcipherset = ap_crypto->mcastcipherset;
security->ucastcipherset = ap_crypto->ucastcipherset;
security->key_mgmt = ap_crypto->key_mgmt;
security->rsn_caps = ap_crypto->rsn_caps;
QDF_SET_PARAM(security->authmodeset, WLAN_CRYPTO_AUTH_WPA);
match = true;
goto free;
}
if (util_scan_entry_wapi(db_entry)) {
status = wlan_crypto_wapiie_check(ap_crypto,
util_scan_entry_wapi(db_entry));
if (QDF_IS_STATUS_ERROR(status)) {
scm_err(QDF_MAC_ADDR_FMT": failed to parse WPA IE, status %d",
QDF_MAC_ADDR_REF(db_entry->bssid.bytes),
status);
goto free;
}
security->mcastcipherset = ap_crypto->mcastcipherset;
security->ucastcipherset = ap_crypto->ucastcipherset;
security->key_mgmt = ap_crypto->key_mgmt;
security->rsn_caps = ap_crypto->rsn_caps;
QDF_SET_PARAM(security->authmodeset, WLAN_CRYPTO_AUTH_WAPI);
match = true;
goto free;
}
if (db_entry->cap_info.wlan_caps.privacy) {
QDF_SET_PARAM(security->ucastcipherset, WLAN_CRYPTO_CIPHER_WEP);
QDF_SET_PARAM(security->mcastcipherset, WLAN_CRYPTO_CIPHER_WEP);
QDF_SET_PARAM(security->authmodeset, WLAN_CRYPTO_AUTH_SHARED);
match = true;
goto free;
}
QDF_SET_PARAM(security->ucastcipherset, WLAN_CRYPTO_CIPHER_NONE);
QDF_SET_PARAM(security->mcastcipherset, WLAN_CRYPTO_CIPHER_NONE);
QDF_SET_PARAM(security->authmodeset, WLAN_CRYPTO_AUTH_OPEN);
match = true;
free:
qdf_mem_free(ap_crypto);
return match;
}
/**
* scm_is_security_match() - Check if security in filter match
* @filter: scan filter
* @db_entry: db entry
* @security: matched security.
*
* Return: true if security match else false
*/
static bool scm_is_security_match(struct scan_filter *filter,
struct scan_cache_entry *db_entry,
struct security_info *security)
{
int i;
bool match = false;
if (!filter->authmodeset)
return scm_match_any_security(filter, db_entry, security);
for (i = 0; i < WLAN_CRYPTO_AUTH_MAX && !match; i++) {
if (!QDF_HAS_PARAM(filter->authmodeset, i))
continue;
security->authmodeset = 0;
QDF_SET_PARAM(security->authmodeset, i);
switch (i) {
case WLAN_CRYPTO_AUTH_NONE:
case WLAN_CRYPTO_AUTH_OPEN:
case WLAN_CRYPTO_AUTH_AUTO:
match = scm_check_open(filter, db_entry, security);
if (match)
break;
/* If not OPEN, then check WEP match */
/* fallthrough */
case WLAN_CRYPTO_AUTH_SHARED:
match = scm_check_wep(filter, db_entry, security);
break;
case WLAN_CRYPTO_AUTH_8021X:
case WLAN_CRYPTO_AUTH_RSNA:
case WLAN_CRYPTO_AUTH_CCKM:
case WLAN_CRYPTO_AUTH_SAE:
case WLAN_CRYPTO_AUTH_FILS_SK:
/* First check if there is a RSN match */
match = scm_check_rsn(filter, db_entry, security);
break;
case WLAN_CRYPTO_AUTH_WPA:
match = scm_check_wpa(filter, db_entry, security);
break;
case WLAN_CRYPTO_AUTH_WAPI:/* WAPI */
match = scm_check_wapi(filter, db_entry, security);
break;
default:
break;
}
}
return match;
}
static bool scm_ignore_ssid_check_for_owe(struct scan_filter *filter,
struct scan_cache_entry *db_entry)
{
bool is_hidden;
is_hidden = util_scan_entry_is_hidden_ap(db_entry);
if (is_hidden &&
QDF_HAS_PARAM(filter->key_mgmt, WLAN_CRYPTO_KEY_MGMT_OWE) &&
util_is_bssid_match(&filter->bssid_hint, &db_entry->bssid))
return true;
/* Dump only for hidden SSID as non-hidden are anyway rejected */
if (is_hidden)
scm_debug(QDF_MAC_ADDR_FMT ": Ignore hidden AP as key_mgmt 0x%x is not OWE or bssid hint: "
QDF_MAC_ADDR_FMT " does not match",
QDF_MAC_ADDR_REF(db_entry->bssid.bytes),
filter->key_mgmt,
QDF_MAC_ADDR_REF(filter->bssid_hint.bytes));
return false;
}
#ifdef WLAN_FEATURE_FILS_SK
/**
* scm_is_fils_config_match() - Check if FILS config matches
* @filter: scan filter
* @db_entry: db entry
*
* Return: true if FILS config matches else false
*/
static bool scm_is_fils_config_match(struct scan_filter *filter,
struct scan_cache_entry *db_entry)
{
int i;
struct fils_indication_ie *indication_ie;
uint8_t *data;
uint8_t *end_ptr;
if (!filter->fils_scan_filter.realm_check)
return true;
if (!db_entry->ie_list.fils_indication)
return false;
indication_ie =
(struct fils_indication_ie *)db_entry->ie_list.fils_indication;
end_ptr = (uint8_t *)indication_ie + indication_ie->len + 2;
data = indication_ie->variable_data;
if (indication_ie->is_cache_id_present &&
(data + CACHE_IDENTIFIER_LEN) <= end_ptr)
data += CACHE_IDENTIFIER_LEN;
if (indication_ie->is_hessid_present &&
(data + HESSID_LEN) <= end_ptr)
data += HESSID_LEN;
for (i = 1; i <= indication_ie->realm_identifiers_cnt &&
(data + REALM_HASH_LEN) <= end_ptr; i++) {
if (!qdf_mem_cmp(filter->fils_scan_filter.fils_realm,
data, REALM_HASH_LEN))
return true;
/* Max realm count reached */
if (indication_ie->realm_identifiers_cnt == i)
break;
data = data + REALM_HASH_LEN;
}
return false;
}
#else
static inline bool scm_is_fils_config_match(struct scan_filter *filter,
struct scan_cache_entry *db_entry)
{
return true;
}
#endif
static bool scm_check_dot11mode(struct scan_cache_entry *db_entry,
struct scan_filter *filter)
{
switch (filter->dot11mode) {
case ALLOW_ALL:
break;
case ALLOW_11N_ONLY:
if (!util_scan_entry_htcap(db_entry))
return false;
break;
case ALLOW_11AC_ONLY:
if (!util_scan_entry_vhtcap(db_entry))
return false;
break;
case ALLOW_11AX_ONLY:
if (!util_scan_entry_hecap(db_entry))
return false;
break;
default:
scm_debug("Invalid dot11mode filter passed %d",
filter->dot11mode);
}
return true;
}
bool scm_filter_match(struct wlan_objmgr_psoc *psoc,
struct scan_cache_entry *db_entry,
struct scan_filter *filter,
struct security_info *security)
{
int i;
bool match = false;
struct scan_default_params *def_param;
struct wlan_objmgr_pdev *pdev;
def_param = wlan_scan_psoc_get_def_params(psoc);
if (!def_param)
return false;
if (db_entry->ssid.length) {
for (i = 0; i < filter->num_of_ssid; i++) {
if (util_is_ssid_match(&filter->ssid_list[i],
&db_entry->ssid)) {
match = true;
break;
}
}
}
/*
* In OWE transition mode, ssid is hidden. And supplicant does not issue
* scan with specific ssid prior to connect as in other hidden ssid
* cases. Add explicit check to allow OWE when ssid is hidden.
*/
if (!match)
match = scm_ignore_ssid_check_for_owe(filter, db_entry);
if (!match && filter->num_of_ssid)
return false;
match = false;
for (i = 0; i < filter->num_of_bssid; i++) {
if (util_is_bssid_match(&filter->bssid_list[i],
&db_entry->bssid)) {
match = true;
break;
}
}
if (!match && filter->num_of_bssid) {
/*
* Do not print if ssid is not present in filter to avoid
* excessive prints
*/
if (filter->num_of_ssid)
scm_debug(QDF_MAC_ADDR_FMT ": Ignore as BSSID not in list (no. of BSSID in list %d)",
QDF_MAC_ADDR_REF(db_entry->bssid.bytes),
filter->num_of_bssid);
return false;
}
if (filter->age_threshold &&
filter->age_threshold < util_scan_entry_age(db_entry)) {
/*
* Do not print if bssid/ssid is not present in filter to avoid
* excessive prints
*/
if (filter->num_of_bssid || filter->num_of_ssid)
scm_debug(QDF_MAC_ADDR_FMT ": Ignore as age %lu ms is greater than threshold %lu ms",
QDF_MAC_ADDR_REF(db_entry->bssid.bytes),
util_scan_entry_age(db_entry),
filter->age_threshold);
return false;
}
if (filter->dot11mode && !scm_check_dot11mode(db_entry, filter)) {
scm_debug(QDF_MAC_ADDR_FMT ": Ignore as dot11mode %d didn't match phymode %d",
QDF_MAC_ADDR_REF(db_entry->bssid.bytes),
filter->dot11mode, db_entry->phy_mode);
return false;
}
if (filter->ignore_6ghz_channel &&
WLAN_REG_IS_6GHZ_CHAN_FREQ(db_entry->channel.chan_freq)) {
/*
* Do not print if bssid/ssid is not present in filter to avoid
* excessive prints
*/
if (filter->num_of_bssid || filter->num_of_ssid)
scm_debug(QDF_MAC_ADDR_FMT ": Ignore as its on 6Ghz freq %d",
QDF_MAC_ADDR_REF(db_entry->bssid.bytes),
db_entry->channel.chan_freq);
return false;
}
pdev = wlan_objmgr_get_pdev_by_id(psoc, db_entry->pdev_id,
WLAN_SCAN_ID);
if (!pdev) {
scm_err(QDF_MAC_ADDR_FMT ": Ignore as pdev not found",
QDF_MAC_ADDR_REF(db_entry->bssid.bytes));
return false;
}
if (filter->ignore_nol_chan &&
utils_dfs_is_freq_in_nol(pdev, db_entry->channel.chan_freq)) {
wlan_objmgr_pdev_release_ref(pdev, WLAN_SCAN_ID);
scm_debug(QDF_MAC_ADDR_FMT ": Ignore as chan in NOL list",
QDF_MAC_ADDR_REF(db_entry->bssid.bytes));
return false;
}
wlan_objmgr_pdev_release_ref(pdev, WLAN_SCAN_ID);
match = false;
for (i = 0; i < filter->num_of_channels; i++) {
if (!filter->chan_freq_list[i] ||
filter->chan_freq_list[i] ==
db_entry->channel.chan_freq) {
match = true;
break;
}
}
if (!match && filter->num_of_channels) {
/*
* Do not print if bssid/ssid is not present in filter to avoid
* excessive prints (e.g RRM case where only freq list is
* provided to get AP's in specific frequencies)
*/
if (filter->num_of_bssid || filter->num_of_ssid)
scm_debug(QDF_MAC_ADDR_FMT ": Ignore as AP's freq %d is not in freq list",
QDF_MAC_ADDR_REF(db_entry->bssid.bytes),
db_entry->channel.chan_freq);
return false;
}
if (filter->rrm_measurement_filter)
return true;
if (!filter->ignore_auth_enc_type && !filter->match_security_func &&
!scm_is_security_match(filter, db_entry, security)) {
scm_debug(QDF_MAC_ADDR_FMT ": Ignore as security profile didn't match",
QDF_MAC_ADDR_REF(db_entry->bssid.bytes));
return false;
}
if (filter->match_security_func &&
!filter->match_security_func(filter->match_security_func_arg,
db_entry)) {
scm_debug(QDF_MAC_ADDR_FMT ": Ignore as custom security match failed",
QDF_MAC_ADDR_REF(db_entry->bssid.bytes));
return false;
}
if (filter->ccx_validate_bss &&
!filter->ccx_validate_bss(filter->ccx_validate_bss_arg,
db_entry, 0)) {
scm_debug(QDF_MAC_ADDR_FMT ": Ignore as CCX validateion failed",
QDF_MAC_ADDR_REF(db_entry->bssid.bytes));
return false;
}
if (!util_is_bss_type_match(filter->bss_type, db_entry->cap_info)) {
scm_debug(QDF_MAC_ADDR_FMT ": Ignore as bss type didn't match cap_info %x bss_type %d",
QDF_MAC_ADDR_REF(db_entry->bssid.bytes),
db_entry->cap_info.value, filter->bss_type);
return false;
}
/* Match realm */
if (!scm_is_fils_config_match(filter, db_entry)) {
scm_debug(QDF_MAC_ADDR_FMT ":Ignore as fils config didn't match",
QDF_MAC_ADDR_REF(db_entry->bssid.bytes));
return false;
}
if (!util_mdie_match(filter->mobility_domain,
(struct rsn_mdie *)db_entry->ie_list.mdie)) {
scm_debug(QDF_MAC_ADDR_FMT ": Ignore as mdie didn't match",
QDF_MAC_ADDR_REF(db_entry->bssid.bytes));
return false;
}
return true;
}