| From b041b7b9de6e1d4362de855ab90f9d03ef323edd Mon Sep 17 00:00:00 2001 |
| From: Felix Fietkau <nbd@nbd.name> |
| Date: Wed, 20 Apr 2022 12:49:07 +0200 |
| Subject: mac80211: upgrade passive scan to active scan on DFS channels after beacon rx |
| |
| From: Felix Fietkau <nbd@nbd.name> |
| |
| commit b041b7b9de6e1d4362de855ab90f9d03ef323edd 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> |
| --- |
| net/mac80211/ieee80211_i.h | 5 +++++ |
| net/mac80211/scan.c | 20 ++++++++++++++++++++ |
| 2 files changed, 25 insertions(+) |
| |
| --- a/net/mac80211/ieee80211_i.h |
| +++ b/net/mac80211/ieee80211_i.h |
| @@ -1066,6 +1066,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, |
| @@ -1074,6 +1077,8 @@ enum { |
| SCAN_COMPLETED, |
| SCAN_ABORTED, |
| SCAN_HW_CANCELLED, |
| + SCAN_BEACON_WAIT, |
| + SCAN_BEACON_DONE, |
| }; |
| |
| /** |
| --- a/net/mac80211/scan.c |
| +++ b/net/mac80211/scan.c |
| @@ -205,6 +205,16 @@ void ieee80211_scan_rx(struct ieee80211_ |
| 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; |
| @@ -646,6 +656,8 @@ static int __ieee80211_start_scan(struct |
| 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; |
| @@ -826,6 +838,8 @@ static void ieee80211_scan_state_set_cha |
| !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; |
| } |
| |
| @@ -918,6 +932,8 @@ void ieee80211_scan_work(struct work_str |
| goto out; |
| } |
| |
| + clear_bit(SCAN_BEACON_WAIT, &local->scanning); |
| + |
| /* |
| * as long as no delay is required advance immediately |
| * without scheduling a new work |
| @@ -928,6 +944,10 @@ void ieee80211_scan_work(struct work_str |
| 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 */ |