提交 4d788192 编写于 作者: F Felix Fietkau 提交者: Zheng Zengkai

mac80211: upgrade passive scan to active scan on DFS channels after beacon rx

stable inclusion
from stable-v5.10.121
commit 873069e393c5e56a95a98b799e69184a85fa6cf6
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I5L6CQ

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=873069e393c5e56a95a98b799e69184a85fa6cf6

--------------------------------

commit b041b7b9 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: NCatrinel Catrinescu <cc@80211.de>
Signed-off-by: NFelix Fietkau <nbd@nbd.name>
Link: https://lore.kernel.org/r/20220420104907.36275-1-nbd@nbd.nameSigned-off-by: NJohannes Berg <johannes.berg@intel.com>
Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: NZheng Zengkai <zhengzengkai@huawei.com>
Acked-by: NXie XiuQi <xiexiuqi@huawei.com>
上级 cb285a85
...@@ -1103,6 +1103,9 @@ struct tpt_led_trigger { ...@@ -1103,6 +1103,9 @@ struct tpt_led_trigger {
* a scan complete for an aborted scan. * a scan complete for an aborted scan.
* @SCAN_HW_CANCELLED: Set for our scan work function when the scan is being * @SCAN_HW_CANCELLED: Set for our scan work function when the scan is being
* cancelled. * 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 { enum {
SCAN_SW_SCANNING, SCAN_SW_SCANNING,
...@@ -1111,6 +1114,8 @@ enum { ...@@ -1111,6 +1114,8 @@ enum {
SCAN_COMPLETED, SCAN_COMPLETED,
SCAN_ABORTED, SCAN_ABORTED,
SCAN_HW_CANCELLED, SCAN_HW_CANCELLED,
SCAN_BEACON_WAIT,
SCAN_BEACON_DONE,
}; };
/** /**
......
...@@ -277,6 +277,16 @@ void ieee80211_scan_rx(struct ieee80211_local *local, struct sk_buff *skb) ...@@ -277,6 +277,16 @@ void ieee80211_scan_rx(struct ieee80211_local *local, struct sk_buff *skb)
if (likely(!sdata1 && !sdata2)) if (likely(!sdata1 && !sdata2))
return; 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)) { if (ieee80211_is_probe_resp(mgmt->frame_control)) {
struct cfg80211_scan_request *scan_req; struct cfg80211_scan_request *scan_req;
struct cfg80211_sched_scan_request *sched_scan_req; struct cfg80211_sched_scan_request *sched_scan_req;
...@@ -783,6 +793,8 @@ static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata, ...@@ -783,6 +793,8 @@ static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata,
IEEE80211_CHAN_RADAR)) || IEEE80211_CHAN_RADAR)) ||
!req->n_ssids) { !req->n_ssids) {
next_delay = IEEE80211_PASSIVE_CHANNEL_TIME; next_delay = IEEE80211_PASSIVE_CHANNEL_TIME;
if (req->n_ssids)
set_bit(SCAN_BEACON_WAIT, &local->scanning);
} else { } else {
ieee80211_scan_state_send_probe(local, &next_delay); ieee80211_scan_state_send_probe(local, &next_delay);
next_delay = IEEE80211_CHANNEL_TIME; next_delay = IEEE80211_CHANNEL_TIME;
...@@ -994,6 +1006,8 @@ static void ieee80211_scan_state_set_channel(struct ieee80211_local *local, ...@@ -994,6 +1006,8 @@ static void ieee80211_scan_state_set_channel(struct ieee80211_local *local,
!scan_req->n_ssids) { !scan_req->n_ssids) {
*next_delay = IEEE80211_PASSIVE_CHANNEL_TIME; *next_delay = IEEE80211_PASSIVE_CHANNEL_TIME;
local->next_scan_state = SCAN_DECISION; local->next_scan_state = SCAN_DECISION;
if (scan_req->n_ssids)
set_bit(SCAN_BEACON_WAIT, &local->scanning);
return; return;
} }
...@@ -1086,6 +1100,8 @@ void ieee80211_scan_work(struct work_struct *work) ...@@ -1086,6 +1100,8 @@ void ieee80211_scan_work(struct work_struct *work)
goto out; goto out;
} }
clear_bit(SCAN_BEACON_WAIT, &local->scanning);
/* /*
* as long as no delay is required advance immediately * as long as no delay is required advance immediately
* without scheduling a new work * without scheduling a new work
...@@ -1096,6 +1112,10 @@ void ieee80211_scan_work(struct work_struct *work) ...@@ -1096,6 +1112,10 @@ void ieee80211_scan_work(struct work_struct *work)
goto out_complete; 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) { switch (local->next_scan_state) {
case SCAN_DECISION: case SCAN_DECISION:
/* if no more bands/channels left, complete scan */ /* if no more bands/channels left, complete scan */
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册