Message ID | bcafaec62d6d2c7d7de659d2d038d8da@mazekey.pl |
---|---|
State | Accepted |
Headers | show |
Series | hostapd: fix opclass during CSA with DFS channels | expand |
On Tue, Apr 23, 2024 at 11:08:08AM +0200, marek@mazekey.pl wrote: > During CSA with DFS channels, disable, enable interface > is a part of the algorithm. > When interface was enabled old operating class before switch > and new channel were used causing mismatch in > configured_fixed_chan_to_freq function. > > Example of log when switch from channel 157 to 108 was triggered: > "Could not convert op_class 124 channel 108 to operating frequency" Could you please provide full hostapd configuration that can trigger this and a debug log showing this? In particular, I'd like to understand which country code was used. This did not seem to show any issues in a hwsim test setup with country code US, and I'd like to be able to add a regression test case with this type of fixes.
We can easy reproduce it when switch to non DFS channel, then to DFS channel with different opclass, country code US. Examples: a) - CSA to channel 36 - DFS CSA to channel 100 Could not convert op_class 115 channel 100 to operating frequency b) - CSA to channel 157 - DFS CSA to channel 56 Could not convert op_class 124 channel 56 to operating frequency You can reproduce it with hwsim with small modification: From 5edc4a0a21ca677fc142857a349ba2a94b57ca2a Mon Sep 17 00:00:00 2001 From: Marek Kwaczynski <marek@mazekey.pl> Date: Sat, 27 Apr 2024 00:01:06 +0200 Subject: [PATCH] tests: hwsim: check CSA between non DFS and DFS chan Add test to validate CSA between non DFS channel and DFS channel with different operating class. Signed-off-by: Marek Kwaczynski <marek@mazekey.pl> --- tests/hwsim/test_dfs.py | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/tests/hwsim/test_dfs.py b/tests/hwsim/test_dfs.py index d0bae5a66..3be64b147 100644 --- a/tests/hwsim/test_dfs.py +++ b/tests/hwsim/test_dfs.py @@ -640,7 +640,7 @@ def test_dfs_chan_switch(dev, apdev): if freq != "5260": raise Exception("Unexpected frequency") - dev[0].connect("dfs", key_mgmt="NONE", scan_freq="5260 5280") + dev[0].connect("dfs", key_mgmt="NONE", scan_freq="5260 5280 5180 5500") dev[0].wait_regdom(country_ie=True) hwsim_utils.test_connectivity(dev[0], hapd) @@ -666,6 +666,39 @@ def test_dfs_chan_switch(dev, apdev): dev[0].wait_connected(timeout=30) hwsim_utils.test_connectivity(dev[0], hapd) + + # Move to non DFS channel: 36, opclass 115 + if "OK" not in hapd.request("CHAN_SWITCH 5 5180"): + raise Exception("CHAN_SWITCH failed") + ev = wait_dfs_event(hapd, "AP-CSA-FINISHED", 5) + + if "freq=5180" not in ev: + raise Exception("Unexpected channel: " + ev) + hwsim_utils.test_connectivity(dev[0], hapd) + + # Move to channel 100, opclass 121 + if "OK" not in hapd.request("CHAN_SWITCH 5 5500 ht"): + raise Exception("CHAN_SWITCH failed") + # This results in BSS going down before restart, so the STA is expected + # to report disconnection. + dev[0].wait_disconnected() + ev = wait_dfs_event(hapd, "DFS-CAC-START", 5) + if "freq=5500" not in ev: + raise Exception("Unexpected channel: " + ev) + ev = wait_dfs_event(hapd, "DFS-CAC-COMPLETED", 70) + if "success=1" not in ev: + raise Exception("CAC failed") + if "freq=5500" not in ev: + raise Exception("Unexpected DFS freq result") + ev = hapd.wait_event(["AP-ENABLED"], timeout=5) + if not ev: + raise Exception("AP setup timed out") + freq = hapd.get_status_field("freq") + if freq != "5500": + raise Exception("Unexpected frequency") + + dev[0].wait_connected(timeout=30) + hwsim_utils.test_connectivity(dev[0], hapd) finally: clear_regdom(hapd, dev)
On Tue, Apr 23, 2024 at 11:08:08AM +0200, marek@mazekey.pl wrote: > During CSA with DFS channels, disable, enable interface > is a part of the algorithm. > When interface was enabled old operating class before switch > and new channel were used causing mismatch in > configured_fixed_chan_to_freq function. > > Example of log when switch from channel 157 to 108 was triggered: > "Could not convert op_class 124 channel 108 to operating frequency" > > Fixes: bb781c763 ("AP: Populate iface->freq before starting AP") Thanks, applied.
diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c index 130b6ebc6..8d0601e6a 100644 --- a/src/ap/hostapd.c +++ b/src/ap/hostapd.c @@ -4466,6 +4466,8 @@ hostapd_switch_channel_fallback(struct hostapd_iface *iface, { u8 seg0_idx = 0, seg1_idx = 0; enum oper_chan_width bw = CONF_OPER_CHWIDTH_USE_HT; + u8 op_class; + u8 chan; wpa_printf(MSG_DEBUG, "Restarting all CSA-related BSSes");
During CSA with DFS channels, disable, enable interface is a part of the algorithm. When interface was enabled old operating class before switch and new channel were used causing mismatch in configured_fixed_chan_to_freq function. Example of log when switch from channel 157 to 108 was triggered: "Could not convert op_class 124 channel 108 to operating frequency" Fixes: bb781c763 ("AP: Populate iface->freq before starting AP") Signed-off-by: Marek Kwaczynski <marek@mazekey.pl> --- src/ap/hostapd.c | 7 +++++++ 1 file changed, 7 insertions(+) @@ -4505,6 +4507,11 @@ hostapd_switch_channel_fallback(struct hostapd_iface *iface, iface->freq = freq_params->freq; iface->conf->channel = freq_params->channel; iface->conf->secondary_channel = freq_params->sec_channel_offset; + ieee80211_freq_to_channel_ext(freq_params->freq, freq_params->sec_channel_offset, bw, &op_class, &chan); + if (chan != freq_params->channel) + wpa_printf(MSG_ERROR, "Channel mismatch: %d -> %d", freq_params->channel, chan); + + iface->conf->op_class = op_class; hostapd_set_oper_centr_freq_seg0_idx(iface->conf, seg0_idx); hostapd_set_oper_centr_freq_seg1_idx(iface->conf, seg1_idx); hostapd_set_oper_chwidth(iface->conf, bw);