qcacmn: Unlink hidden bss entry from kernel
Kernel maintains a list of bss and it adds/updates the bss entries whenever driver informs it. When driver receives beacon or probe response from any ap it informs kernel to update the bss list and whenever it disconnects with the AP driver unlink the bss in the kernel. If the AP is hidden, when driver gets beacon from this hidden AP it informs the kernel to update the bss list. kernel add this entry to it's bss list with NULL SSID. Now when driver receives probe response from this hidden AP it again informs the kernel to update the bss list, as this is probe response and ssid is not hidden, kernel treats this entry as new entry and adds it to its bss list and links this entry to the older hidden AP entry (But still these are two entries for hidden AP). When driver gets disconnect from the AP it unlink the bss entry corresponding to this AP from kernel's bss list, but since there are two entries for the same AP as the AP is a hidden AP, driver should clear hidden AP entry (Which was added as part of beacon) which is not happening currently. Now when AP moves from hidden to broadcasting SSID in it's beacon, kernel drops this beacon entry as its confusing because there is already a beacon entry with hidden bss for this AP. During connection driver tries to update the entry in the kernel and it fails as kernel drops the beacon resulting into the connection failure. To resolve this issue, whenever driver unlink the bss entries from the kernel bss list unlink the hidden bss entries also from the kernel's bss list. Change-Id: I629475db8e8f10a6bc403314a984939e38d0a4da CRs-Fixed: 2488955
Este cometimento está contido em:

cometido por
nshrivas

ascendente
f00622162c
cometimento
3863721077
@@ -265,6 +265,18 @@ wlan_cfg80211_inform_bss_frame_data(struct wiphy *wiphy,
|
||||
void wlan_cfg80211_inform_bss_frame(struct wlan_objmgr_pdev *pdev,
|
||||
struct scan_cache_entry *scan_params);
|
||||
|
||||
/**
|
||||
* __wlan_cfg80211_unlink_bss_list() - flush bss from the kernel cache
|
||||
* @wiphy: wiphy
|
||||
* @bssid: bssid of the BSS to find
|
||||
* @ssid: ssid of the BSS to find
|
||||
* @ssid_len: ssid len of of the BSS to find
|
||||
*
|
||||
* Return: None
|
||||
*/
|
||||
void __wlan_cfg80211_unlink_bss_list(struct wiphy *wiphy, uint8_t *bssid,
|
||||
uint8_t *ssid, uint8_t ssid_len);
|
||||
|
||||
/**
|
||||
* wlan_cfg80211_get_bss() - Get the bss entry matching the chan, bssid and ssid
|
||||
* @wiphy: wiphy
|
||||
|
@@ -1977,10 +1977,47 @@ struct cfg80211_bss *wlan_cfg80211_get_bss(struct wiphy *wiphy,
|
||||
}
|
||||
#endif
|
||||
|
||||
void __wlan_cfg80211_unlink_bss_list(struct wiphy *wiphy, uint8_t *bssid,
|
||||
uint8_t *ssid, uint8_t ssid_len)
|
||||
{
|
||||
struct cfg80211_bss *bss = NULL;
|
||||
|
||||
bss = wlan_cfg80211_get_bss(wiphy, NULL, bssid,
|
||||
ssid, ssid_len);
|
||||
if (!bss) {
|
||||
osif_info("BSS %pM not found", bssid);
|
||||
} else {
|
||||
osif_debug("unlink entry for ssid:%.*s and BSSID %pM",
|
||||
ssid_len, ssid, bssid);
|
||||
cfg80211_unlink_bss(wiphy, bss);
|
||||
wlan_cfg80211_put_bss(wiphy, bss);
|
||||
}
|
||||
|
||||
/*
|
||||
* Kernel creates separate entries into it's bss list for probe resp
|
||||
* and beacon for hidden AP. Both have separate ref count and thus
|
||||
* deleting one will not delete other entry.
|
||||
* If beacon entry of the hidden AP is not deleted and AP switch to
|
||||
* broadcasting SSID from Hiding SSID, kernel will reject the beacon
|
||||
* entry. So unlink the hidden beacon entry (if present) as well from
|
||||
* kernel, to avoid such issue.
|
||||
*/
|
||||
bss = wlan_cfg80211_get_bss(wiphy, NULL, bssid, NULL, 0);
|
||||
if (!bss) {
|
||||
osif_debug("Hidden bss not found for Ssid:%.*s BSSID: %pM sid_len %d",
|
||||
ssid_len, ssid, bssid, ssid_len);
|
||||
} else {
|
||||
osif_debug("unlink entry for Hidden ssid:%.*s and BSSID %pM",
|
||||
ssid_len, ssid, bssid);
|
||||
|
||||
cfg80211_unlink_bss(wiphy, bss);
|
||||
/* cfg80211_get_bss get bss with ref count so release it */
|
||||
wlan_cfg80211_put_bss(wiphy, bss);
|
||||
}
|
||||
}
|
||||
void wlan_cfg80211_unlink_bss_list(struct wlan_objmgr_pdev *pdev,
|
||||
struct scan_cache_entry *scan_entry)
|
||||
{
|
||||
struct cfg80211_bss *bss = NULL;
|
||||
struct pdev_osif_priv *pdev_ospriv = wlan_pdev_get_ospriv(pdev);
|
||||
struct wiphy *wiphy;
|
||||
|
||||
@@ -1990,17 +2027,10 @@ void wlan_cfg80211_unlink_bss_list(struct wlan_objmgr_pdev *pdev,
|
||||
}
|
||||
|
||||
wiphy = pdev_ospriv->wiphy;
|
||||
bss = wlan_cfg80211_get_bss(wiphy, NULL, scan_entry->bssid.bytes,
|
||||
scan_entry->ssid.ssid,
|
||||
scan_entry->ssid.length);
|
||||
if (!bss) {
|
||||
osif_err("BSS %pM not found", scan_entry->bssid.bytes);
|
||||
} else {
|
||||
osif_debug("cfg80211_unlink_bss called for BSSID %pM",
|
||||
scan_entry->bssid.bytes);
|
||||
cfg80211_unlink_bss(wiphy, bss);
|
||||
wlan_cfg80211_put_bss(wiphy, bss);
|
||||
}
|
||||
|
||||
__wlan_cfg80211_unlink_bss_list(wiphy, scan_entry->bssid.bytes,
|
||||
scan_entry->ssid.ssid,
|
||||
scan_entry->ssid.length);
|
||||
}
|
||||
|
||||
#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 12, 0))
|
||||
|
Criar uma nova questão referindo esta
Bloquear um utilizador