mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-30 23:54:04 +08:00
cfg80211: Add option to report the bss entry in connect result
Since cfg80211 maintains separate BSS table entries for APs if the same BSSID, SSID pair is seen on multiple channels, it is possible that it can map the current_bss to a BSS entry on the wrong channel. This current_bss will not get flushed unless disconnected and cfg80211 reports a wrong channel as the associated channel. Fix this by introducing a new cfg80211_connect_bss() function which is similar to cfg80211_connect_result(), but it includes an additional parameter: the bss the STA is connected to. This allows drivers to provide the exact bss entry that matches the BSS to which the connection was completed. Reviewed-by: Jouni Malinen <jouni@qca.qualcomm.com> Signed-off-by: Vidyullatha Kanchanapally <vkanchan@qti.qualcomm.com> Signed-off-by: Sunil Dutt <usdutt@qti.qualcomm.com> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
parent
739960f128
commit
e705498945
@ -135,6 +135,7 @@
|
||||
!Finclude/net/cfg80211.h cfg80211_tx_mlme_mgmt
|
||||
!Finclude/net/cfg80211.h cfg80211_ibss_joined
|
||||
!Finclude/net/cfg80211.h cfg80211_connect_result
|
||||
!Finclude/net/cfg80211.h cfg80211_connect_bss
|
||||
!Finclude/net/cfg80211.h cfg80211_roamed
|
||||
!Finclude/net/cfg80211.h cfg80211_disconnected
|
||||
!Finclude/net/cfg80211.h cfg80211_ready_on_channel
|
||||
|
@ -4651,6 +4651,32 @@ static inline void cfg80211_testmode_event(struct sk_buff *skb, gfp_t gfp)
|
||||
#define CFG80211_TESTMODE_DUMP(cmd)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* cfg80211_connect_bss - notify cfg80211 of connection result
|
||||
*
|
||||
* @dev: network device
|
||||
* @bssid: the BSSID of the AP
|
||||
* @bss: entry of bss to which STA got connected to, can be obtained
|
||||
* through cfg80211_get_bss (may be %NULL)
|
||||
* @req_ie: association request IEs (maybe be %NULL)
|
||||
* @req_ie_len: association request IEs length
|
||||
* @resp_ie: association response IEs (may be %NULL)
|
||||
* @resp_ie_len: assoc response IEs length
|
||||
* @status: status code, 0 for successful connection, use
|
||||
* %WLAN_STATUS_UNSPECIFIED_FAILURE if your device cannot give you
|
||||
* the real status code for failures.
|
||||
* @gfp: allocation flags
|
||||
*
|
||||
* It should be called by the underlying driver whenever connect() has
|
||||
* succeeded. This is similar to cfg80211_connect_result(), but with the
|
||||
* option of identifying the exact bss entry for the connection. Only one of
|
||||
* these functions should be called.
|
||||
*/
|
||||
void cfg80211_connect_bss(struct net_device *dev, const u8 *bssid,
|
||||
struct cfg80211_bss *bss, const u8 *req_ie,
|
||||
size_t req_ie_len, const u8 *resp_ie,
|
||||
size_t resp_ie_len, u16 status, gfp_t gfp);
|
||||
|
||||
/**
|
||||
* cfg80211_connect_result - notify cfg80211 of connection result
|
||||
*
|
||||
@ -4668,10 +4694,15 @@ static inline void cfg80211_testmode_event(struct sk_buff *skb, gfp_t gfp)
|
||||
* It should be called by the underlying driver whenever connect() has
|
||||
* succeeded.
|
||||
*/
|
||||
void cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
|
||||
const u8 *req_ie, size_t req_ie_len,
|
||||
const u8 *resp_ie, size_t resp_ie_len,
|
||||
u16 status, gfp_t gfp);
|
||||
static inline void
|
||||
cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
|
||||
const u8 *req_ie, size_t req_ie_len,
|
||||
const u8 *resp_ie, size_t resp_ie_len,
|
||||
u16 status, gfp_t gfp)
|
||||
{
|
||||
cfg80211_connect_bss(dev, bssid, NULL, req_ie, req_ie_len, resp_ie,
|
||||
resp_ie_len, status, gfp);
|
||||
}
|
||||
|
||||
/**
|
||||
* cfg80211_roamed - notify cfg80211 of roaming
|
||||
|
@ -214,6 +214,7 @@ struct cfg80211_event {
|
||||
const u8 *resp_ie;
|
||||
size_t req_ie_len;
|
||||
size_t resp_ie_len;
|
||||
struct cfg80211_bss *bss;
|
||||
u16 status;
|
||||
} cr;
|
||||
struct {
|
||||
|
@ -753,19 +753,32 @@ void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
|
||||
kfree(country_ie);
|
||||
}
|
||||
|
||||
void cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
|
||||
const u8 *req_ie, size_t req_ie_len,
|
||||
const u8 *resp_ie, size_t resp_ie_len,
|
||||
u16 status, gfp_t gfp)
|
||||
/* Consumes bss object one way or another */
|
||||
void cfg80211_connect_bss(struct net_device *dev, const u8 *bssid,
|
||||
struct cfg80211_bss *bss, const u8 *req_ie,
|
||||
size_t req_ie_len, const u8 *resp_ie,
|
||||
size_t resp_ie_len, u16 status, gfp_t gfp)
|
||||
{
|
||||
struct wireless_dev *wdev = dev->ieee80211_ptr;
|
||||
struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
|
||||
struct cfg80211_event *ev;
|
||||
unsigned long flags;
|
||||
|
||||
if (bss) {
|
||||
/* Make sure the bss entry provided by the driver is valid. */
|
||||
struct cfg80211_internal_bss *ibss = bss_from_pub(bss);
|
||||
|
||||
if (WARN_ON(list_empty(&ibss->list))) {
|
||||
cfg80211_put_bss(wdev->wiphy, bss);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
ev = kzalloc(sizeof(*ev) + req_ie_len + resp_ie_len, gfp);
|
||||
if (!ev)
|
||||
if (!ev) {
|
||||
cfg80211_put_bss(wdev->wiphy, bss);
|
||||
return;
|
||||
}
|
||||
|
||||
ev->type = EVENT_CONNECT_RESULT;
|
||||
if (bssid)
|
||||
@ -780,6 +793,9 @@ void cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
|
||||
ev->cr.resp_ie_len = resp_ie_len;
|
||||
memcpy((void *)ev->cr.resp_ie, resp_ie, resp_ie_len);
|
||||
}
|
||||
if (bss)
|
||||
cfg80211_hold_bss(bss_from_pub(bss));
|
||||
ev->cr.bss = bss;
|
||||
ev->cr.status = status;
|
||||
|
||||
spin_lock_irqsave(&wdev->event_lock, flags);
|
||||
@ -787,7 +803,7 @@ void cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
|
||||
spin_unlock_irqrestore(&wdev->event_lock, flags);
|
||||
queue_work(cfg80211_wq, &rdev->event_work);
|
||||
}
|
||||
EXPORT_SYMBOL(cfg80211_connect_result);
|
||||
EXPORT_SYMBOL(cfg80211_connect_bss);
|
||||
|
||||
/* Consumes bss object one way or another */
|
||||
void __cfg80211_roamed(struct wireless_dev *wdev,
|
||||
|
@ -950,7 +950,7 @@ void cfg80211_process_wdev_events(struct wireless_dev *wdev)
|
||||
ev->cr.resp_ie, ev->cr.resp_ie_len,
|
||||
ev->cr.status,
|
||||
ev->cr.status == WLAN_STATUS_SUCCESS,
|
||||
NULL);
|
||||
ev->cr.bss);
|
||||
break;
|
||||
case EVENT_ROAMED:
|
||||
__cfg80211_roamed(wdev, ev->rm.bss, ev->rm.req_ie,
|
||||
|
Loading…
Reference in New Issue
Block a user