Skip to content

Commit

Permalink
mac80211: upgrade passive scan to active scan on DFS channels after b…
Browse files Browse the repository at this point in the history
…eacon rx

commit b041b7b upstream.

In client mode, we can't connect to hidden SSID APs or SSIDs not advertised
in beacons on DFS channels, since we're forced to passive scan. Fix this by
sending out a probe request immediately after the first beacon, if active
scan was requested by the user.

Cc: stable@vger.kernel.org
Reported-by: Catrinel Catrinescu <cc@80211.de>
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Link: https://lore.kernel.org/r/20220420104907.36275-1-nbd@nbd.name
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
nbd168 authored and gregkh committed Jun 9, 2022
1 parent 22741dd commit 873069e
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 0 deletions.
5 changes: 5 additions & 0 deletions net/mac80211/ieee80211_i.h
Original file line number Diff line number Diff line change
Expand Up @@ -1103,6 +1103,9 @@ struct tpt_led_trigger {
* a scan complete for an aborted scan.
* @SCAN_HW_CANCELLED: Set for our scan work function when the scan is being
* cancelled.
* @SCAN_BEACON_WAIT: Set whenever we're passive scanning because of radar/no-IR
* and could send a probe request after receiving a beacon.
* @SCAN_BEACON_DONE: Beacon received, we can now send a probe request
*/
enum {
SCAN_SW_SCANNING,
Expand All @@ -1111,6 +1114,8 @@ enum {
SCAN_COMPLETED,
SCAN_ABORTED,
SCAN_HW_CANCELLED,
SCAN_BEACON_WAIT,
SCAN_BEACON_DONE,
};

/**
Expand Down
20 changes: 20 additions & 0 deletions net/mac80211/scan.c
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,16 @@ void ieee80211_scan_rx(struct ieee80211_local *local, struct sk_buff *skb)
if (likely(!sdata1 && !sdata2))
return;

if (test_and_clear_bit(SCAN_BEACON_WAIT, &local->scanning)) {
/*
* we were passive scanning because of radar/no-IR, but
* the beacon/proberesp rx gives us an opportunity to upgrade
* to active scan
*/
set_bit(SCAN_BEACON_DONE, &local->scanning);
ieee80211_queue_delayed_work(&local->hw, &local->scan_work, 0);
}

if (ieee80211_is_probe_resp(mgmt->frame_control)) {
struct cfg80211_scan_request *scan_req;
struct cfg80211_sched_scan_request *sched_scan_req;
Expand Down Expand Up @@ -783,6 +793,8 @@ static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata,
IEEE80211_CHAN_RADAR)) ||
!req->n_ssids) {
next_delay = IEEE80211_PASSIVE_CHANNEL_TIME;
if (req->n_ssids)
set_bit(SCAN_BEACON_WAIT, &local->scanning);
} else {
ieee80211_scan_state_send_probe(local, &next_delay);
next_delay = IEEE80211_CHANNEL_TIME;
Expand Down Expand Up @@ -994,6 +1006,8 @@ static void ieee80211_scan_state_set_channel(struct ieee80211_local *local,
!scan_req->n_ssids) {
*next_delay = IEEE80211_PASSIVE_CHANNEL_TIME;
local->next_scan_state = SCAN_DECISION;
if (scan_req->n_ssids)
set_bit(SCAN_BEACON_WAIT, &local->scanning);
return;
}

Expand Down Expand Up @@ -1086,6 +1100,8 @@ void ieee80211_scan_work(struct work_struct *work)
goto out;
}

clear_bit(SCAN_BEACON_WAIT, &local->scanning);

/*
* as long as no delay is required advance immediately
* without scheduling a new work
Expand All @@ -1096,6 +1112,10 @@ void ieee80211_scan_work(struct work_struct *work)
goto out_complete;
}

if (test_and_clear_bit(SCAN_BEACON_DONE, &local->scanning) &&
local->next_scan_state == SCAN_DECISION)
local->next_scan_state = SCAN_SEND_PROBE;

switch (local->next_scan_state) {
case SCAN_DECISION:
/* if no more bands/channels left, complete scan */
Expand Down

0 comments on commit 873069e

Please sign in to comment.