diff options
author | Chaitanya Tata <chaitanya.tata@bluwireless.co.uk> | 2019-05-01 18:25:24 +0530 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2019-05-28 09:35:39 +0200 |
commit | a3ce17d1495b65d62fceb2c7a704bb97133c5de9 (patch) | |
tree | d9dc6949a0dc8ad884a344b0d5cd71e662ab95e7 /net/wireless/sme.c | |
parent | cec4f328c929f72ad634e8f385b589bd6eac80e5 (diff) | |
download | linux-a3ce17d1495b65d62fceb2c7a704bb97133c5de9.tar.gz linux-a3ce17d1495b65d62fceb2c7a704bb97133c5de9.tar.bz2 linux-a3ce17d1495b65d62fceb2c7a704bb97133c5de9.zip |
cfg80211: Handle bss expiry during connection
If the BSS is expired during connection, the connect result will
trigger a kernel warning. Ideally cfg80211 should hold the BSS
before the connection is attempted, but as the BSSID is not known
in case of auth/assoc MLME offload (connect op) it doesn't.
For those drivers without the connect op cfg80211 holds down the
reference so it wil not be removed from list.
Fix this by removing the warning and silently adding the BSS back to
the bss list which is return by the driver (with proper BSSID set) or
in case the BSS is already added use that.
The requirements for drivers are documented in the API's.
Signed-off-by: Chaitanya Tata <chaitanya.tata@bluwireless.co.uk>
[formatting fixes, keep old timestamp]
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/wireless/sme.c')
-rw-r--r-- | net/wireless/sme.c | 32 |
1 files changed, 28 insertions, 4 deletions
diff --git a/net/wireless/sme.c b/net/wireless/sme.c index 7d34cb884840..7a6c38ddc65a 100644 --- a/net/wireless/sme.c +++ b/net/wireless/sme.c @@ -796,12 +796,36 @@ void cfg80211_connect_done(struct net_device *dev, u8 *next; if (params->bss) { - /* Make sure the bss entry provided by the driver is valid. */ struct cfg80211_internal_bss *ibss = bss_from_pub(params->bss); - if (WARN_ON(list_empty(&ibss->list))) { - cfg80211_put_bss(wdev->wiphy, params->bss); - return; + if (list_empty(&ibss->list)) { + struct cfg80211_bss *found = NULL, *tmp = params->bss; + + found = cfg80211_get_bss(wdev->wiphy, NULL, + params->bss->bssid, + wdev->ssid, wdev->ssid_len, + wdev->conn_bss_type, + IEEE80211_PRIVACY_ANY); + if (found) { + /* The same BSS is already updated so use it + * instead, as it has latest info. + */ + params->bss = found; + } else { + /* Update with BSS provided by driver, it will + * be freshly added and ref cnted, we can free + * the old one. + * + * signal_valid can be false, as we are not + * expecting the BSS to be found. + * + * keep the old timestamp to avoid confusion + */ + cfg80211_bss_update(rdev, ibss, false, + ibss->ts); + } + + cfg80211_put_bss(wdev->wiphy, tmp); } } |