![Johannes Berg](/assets/img/avatar_default.png)
Due to the previous commit, when a scan finishes, it is in theory possible to hit the following sequence: 1. interface starts being removed 2. scan is cancelled by driver and cfg80211 is notified 3. scan done work is scheduled 4. interface is removed completely, rdev->scan_req is freed, event sent to userspace but scan done work remains pending 5. new scan is requested on another virtual interface 6. scan done work runs, freeing the still-running scan To fix this situation, hang on to the scan done message and block new scans while that is the case, and only send the message from the work function, regardless of whether the scan_req is already freed from interface removal. This makes step 5 above impossible and changes step 6 to be 5. scan done work runs, sending the scan done message As this can't work for wext, so we send the message immediately, but this shouldn't be an issue since we still return -EBUSY. Signed-off-by: Johannes Berg <johannes.berg@intel.com>
80 lines
3.3 KiB
C
80 lines
3.3 KiB
C
#ifndef __NET_WIRELESS_NL80211_H
|
|
#define __NET_WIRELESS_NL80211_H
|
|
|
|
#include "core.h"
|
|
|
|
int nl80211_init(void);
|
|
void nl80211_exit(void);
|
|
void nl80211_notify_dev_rename(struct cfg80211_registered_device *rdev);
|
|
void nl80211_send_scan_start(struct cfg80211_registered_device *rdev,
|
|
struct wireless_dev *wdev);
|
|
struct sk_buff *nl80211_build_scan_msg(struct cfg80211_registered_device *rdev,
|
|
struct wireless_dev *wdev, bool aborted);
|
|
void nl80211_send_scan_result(struct cfg80211_registered_device *rdev,
|
|
struct sk_buff *msg);
|
|
void nl80211_send_sched_scan(struct cfg80211_registered_device *rdev,
|
|
struct net_device *netdev, u32 cmd);
|
|
void nl80211_send_sched_scan_results(struct cfg80211_registered_device *rdev,
|
|
struct net_device *netdev);
|
|
void nl80211_send_reg_change_event(struct regulatory_request *request);
|
|
void nl80211_send_rx_auth(struct cfg80211_registered_device *rdev,
|
|
struct net_device *netdev,
|
|
const u8 *buf, size_t len, gfp_t gfp);
|
|
void nl80211_send_rx_assoc(struct cfg80211_registered_device *rdev,
|
|
struct net_device *netdev,
|
|
const u8 *buf, size_t len, gfp_t gfp);
|
|
void nl80211_send_deauth(struct cfg80211_registered_device *rdev,
|
|
struct net_device *netdev,
|
|
const u8 *buf, size_t len, gfp_t gfp);
|
|
void nl80211_send_disassoc(struct cfg80211_registered_device *rdev,
|
|
struct net_device *netdev,
|
|
const u8 *buf, size_t len, gfp_t gfp);
|
|
void nl80211_send_auth_timeout(struct cfg80211_registered_device *rdev,
|
|
struct net_device *netdev,
|
|
const u8 *addr, gfp_t gfp);
|
|
void nl80211_send_assoc_timeout(struct cfg80211_registered_device *rdev,
|
|
struct net_device *netdev,
|
|
const u8 *addr, gfp_t gfp);
|
|
void nl80211_send_connect_result(struct cfg80211_registered_device *rdev,
|
|
struct net_device *netdev, 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);
|
|
void nl80211_send_roamed(struct cfg80211_registered_device *rdev,
|
|
struct net_device *netdev, const u8 *bssid,
|
|
const u8 *req_ie, size_t req_ie_len,
|
|
const u8 *resp_ie, size_t resp_ie_len, gfp_t gfp);
|
|
void nl80211_send_disconnected(struct cfg80211_registered_device *rdev,
|
|
struct net_device *netdev, u16 reason,
|
|
const u8 *ie, size_t ie_len, bool from_ap);
|
|
|
|
void
|
|
nl80211_michael_mic_failure(struct cfg80211_registered_device *rdev,
|
|
struct net_device *netdev, const u8 *addr,
|
|
enum nl80211_key_type key_type,
|
|
int key_id, const u8 *tsc, gfp_t gfp);
|
|
|
|
void
|
|
nl80211_send_beacon_hint_event(struct wiphy *wiphy,
|
|
struct ieee80211_channel *channel_before,
|
|
struct ieee80211_channel *channel_after);
|
|
|
|
void nl80211_send_ibss_bssid(struct cfg80211_registered_device *rdev,
|
|
struct net_device *netdev, const u8 *bssid,
|
|
gfp_t gfp);
|
|
|
|
int nl80211_send_mgmt(struct cfg80211_registered_device *rdev,
|
|
struct wireless_dev *wdev, u32 nlpid,
|
|
int freq, int sig_dbm,
|
|
const u8 *buf, size_t len, u32 flags, gfp_t gfp);
|
|
|
|
void
|
|
nl80211_radar_notify(struct cfg80211_registered_device *rdev,
|
|
const struct cfg80211_chan_def *chandef,
|
|
enum nl80211_radar_event event,
|
|
struct net_device *netdev, gfp_t gfp);
|
|
|
|
void cfg80211_rdev_free_coalesce(struct cfg80211_registered_device *rdev);
|
|
|
|
#endif /* __NET_WIRELESS_NL80211_H */
|