From 922949abc03e5769c057bfaf5aeb8aa0cb3fbe47 Mon Sep 17 00:00:00 2001 From: Tim Wilkinson Date: Mon, 10 Apr 2023 10:21:30 -0700 Subject: [PATCH] Eliminate false network rejoins using LQM information (#781) * Use LQM information to filter out neighbors we dont care about. These can cause false rejoin events and degrade the network. * Only use active station monitor with LQM info. --- files/usr/local/bin/mgr/station_monitor.lua | 36 +++++++++++++++++---- 1 file changed, 29 insertions(+), 7 deletions(-) diff --git a/files/usr/local/bin/mgr/station_monitor.lua b/files/usr/local/bin/mgr/station_monitor.lua index 772f8d95..410f9a22 100755 --- a/files/usr/local/bin/mgr/station_monitor.lua +++ b/files/usr/local/bin/mgr/station_monitor.lua @@ -33,7 +33,8 @@ --]] -local unresponsive_max = 3 +local unresponsive_max = 5 +local unresponsive_report = 3 local last = {} local wifiiface local frequency @@ -73,6 +74,12 @@ function station_monitor() rejoin_network() end + -- Only monitor if we have LQM information + if uci.cursor():get("aredn", "@lqm[0]", "enable") ~= "1" then + exit_app() + return + end + while true do run_station_monitor() @@ -83,6 +90,16 @@ end function run_station_monitor() + -- Use the LQM state to ignore nodes we dont care about + local trackers = nil + local f = io.open("/tmp/lqm.info") + if f then + local lqm = luci.jsonc.parse(f:read("*a")) + f:close() + trackers = lqm.trackers + end + local now = nixio.sysinfo().uptime + -- Check each station to make sure we can broadcast and unicast to them local total = 0 local old = last @@ -91,8 +108,13 @@ function run_station_monitor() function (entry) if entry.Device == wifiiface then local ip = entry["IP address"] - local mac = entry["HW address"] - if entry["Flags"] ~= "0x0" and ip and mac then + local mac = entry["HW address"] or "" + -- Only consider nodes which have valid ip and macs, routable and not pending + local tracker = { pending = 0, routable = true } + if trackers then + tracker = trackers[mac:upper()] or { pending = now, routable = false } + end + if entry["Flags"] ~= "0x0" and ip and mac ~= "" and tracker.routable and tracker.pending < now then -- Two arp pings - the first is broadcast, the second unicast for line in io.popen(ARPING .. " -c 2 -I " .. wifiiface .. " " .. ip):lines() do @@ -101,12 +123,12 @@ function run_station_monitor() if line:match("Received 1 response") then local val = (old[ip] or 0) + 1 last[ip] = val - if val > 1 then + if val > unresponsive_report then log:write("Possible unresponsive node: " .. ip .. " [" .. mac .. "]") log:flush() - if val > total then - total = val - end + end + if val > total then + total = val end break end