DFS radar detection channel recovery - hostapd

Hi all,

I am experiencing an issue with my WRT3200ACM, however I suspect the issue is common across all AC routers running LEDE with DFS.

Occasionally (seemingly about once every couple of weeks) I will get a DFS 'radar detected' message in the kernel log for the 5GHz radio. This triggers a channel change to a non-DFS frequency. As far as I can tell from reading the IEEE specifications for DFS this channel change is only supposed to be temporary defined by the DFS NOP (non-occupancy) period for the regulatory region - which is in most cases 30 minutes. After this period the radio is permitted to move back to the original DFS protected channel if no further radar signals are detected for 60 seconds.

However the behavior on my LEDE (from master) build is that once radar is detected the radio changes channel and stays on the alternate non-DFS channel indefinitely. This causes problems because often the alternative channel selection is a congested non-DFS 5GHz channel, which starts to cause performance problems for clients.

It seems right now the only way to fix is to manually go in an change the frequency back to original when I notice the performance issues. This also highlights a 'quirk' in LUCI/UCI because the config still 'thinks' the radio is on the original DFS channel, so simply hitting 'Update' has no effect as there isn't a settings 'change'. Instead I have to do a two-step fix to first move the radio on the another channel, then back to the original DFS channel in order to have LUCI/UCI actually reconfigure the radio.

I raised this issue with the driver package maintainer and they believe this behavior should be controlled by hostapd not the driver firmware. So a couple of questions:

  1. Is it possible to configure hostapd to correctly revert for the original DFS channel once the DFS NOP period has expired - if so how?

  2. I assume there would be an easy alternative fix to schedule a script to move the radio back to the original channel every night - could someone give me some pointers on how to achieve this?

Many thanks!

I can confirm that the same thing happened to me about a year ago on an Archer C7.

You could schedule a Cron job that would check the current channel every 5 mins if it detects a difference btw current and configged channel, and the file doesn't exist, it touches a file /etc/channelchange, if that file is older than 30 mins, change the channel with iw and delete the file.

Yes - this is what I am thinking also, however I would want to schedule the time of the channel switch as it triggers another DFS CAC which results in 60 seconds of radio downtime.

So the script logic would be:

IF (current frequency != configured frequency) AND (time is between 00:00 and 06:00) THEN (change channel to configured channel) and run it every 30 mins.

Would someone be so kind as to give me the skeleton of an ash script that would work for this? I have never scripted anything in Linux before.

Ash basically should be POSIX so you can follow that. E.g. tutorial. The checks and if statements are the easy parts. The more specific ones are your actual test commands, which would be:

root@lede:~# uci show wireless.radio0.channel
root@lede:~# iw dev wlan0 info|awk '/channel/{print $2}'

That should get you going. If anyone knows a neater way to extract the channel info from iw, I'd be happy to learn!

Might try

ubus -v call network.wireless status '{}'
ubus -v call hostapd.wlan1-1 get_clients '{}'

or the like, especially as iw explicitly states
Do NOT screenscrape this tool, we don't consider its output stable.

You might also want to consider "listening" to ubus events, rather than a cron job, assuming that they indicate when the channel has changed. That way you could, for example, create an at job (not installed by default) to check if action should be taken N minutes later.

For those used to Bash-isms, https://wiki.ubuntu.com/DashAsBinSh can help in writing "pure" sh scripts.

I'm trying this out, the idea to use simple bash from https://www.signorini.ch/content/openwrt-reload-conf-when-radar-is-detected , as well as good explanation about dfs

# crontab -l
*/15 * * * * [[ $(uci get wireless.radio0.channel) -ne $(iw dev wlan0 info|awk '/channel/{print $2}') ]] && wifi down radio0 && sleep 2 && wifi up radio0
1 Like

Yes... that does not work with ACS though in which case the channel in uci would be "auto". Also will it auto-return systematically after 30 minutes or only 30min with no radar detection?

OTOH I can see in the log that hostapd gets notified when returning to the normal channel:

hostapd: wlan0: DFS-NOP-FINISHED freq=5260 ht_enabled=0 chan_offset=0 chan_width=0 cf1=5260 cf2=0
hostapd: wlan0: DFS-NOP-FINISHED freq=5280 ht_enabled=0 chan_offset=0 chan_width=0 cf1=5280 cf2=0
hostapd: wlan0: DFS-NOP-FINISHED freq=5300 ht_enabled=0 chan_offset=0 chan_width=0 cf1=5300 cf2=0
hostapd: wlan0: DFS-NOP-FINISHED freq=5320 ht_enabled=0 chan_offset=0 chan_width=0 cf1=5320 cf2=0

if you have auto channel configured, do you really need this?
script forces the return to a specific channel after DFS triggered a channel switch. openwrt will not switch back automatically.

if you do have a preferred channel, replace $(uci get wireless.radio0.channel) with an explicit number, the channel you want to return to after DFS trigger

1 Like

auto only means the chipset/driver/hostapd (not sure exactly which one takes the decision) scans all frequencies and selects the best one on ifup, but once set it should remain in use, and DFS should still only temporarily switch the frequency.

In my case I have another problem, but this is why I was looking into this thread. As soon as the DFS even occurs my 5GHz band stops working and hostapd starts throwing failed to set beacon parameters errors every few minutes. I can stop the errors by restarting hostapd but I need to restart the wireless interface to actually fix the issue.

I'm tempted to move to non-radar freqs, but since I have 3 AP's to cover the home I can get decent 5GHz in most rooms so I don't really need the higher tx power of the non-DFS frequencies. I might be better off sticking to the low-power and low-interference DFS freqs anyway.