Mwan3: interface tracking status from a script

Hello!

I'd need to set a specific led configuration according to mwan3 interface tracking status.

I understand the best place to perform this action is on the "/etc/mwan3.user" script (LuCI: Network->Load Balancing->Notification). This script gets called every time there is an interface status change. I was hoping to store each interface state whenever it reported, but variables created inside the script are destroyed on exit, does it?

Then I thought of calling the "mwan3 interfaces" command. This is an output example:

Interface status:
 interface wan1 is online 00h:20m:37s, uptime 00h:21m:15s and tracking is active
 interface wan2 is offline and tracking is down
 interface wan3 is online 00h:15m:33s, uptime 00h:21m:12s and tracking is active

This is human-readable ASCII text that a script should parse to get each interface tracking status.

Is there an easy way to get this data for evaluating it in a script?
For example, is there a /sys/interfaces/wan1/tracking being 1 o 0?

Or do you know a way to make variables inside "/etc/mwan3.user" persistent?

Which program calls "/etc/mwan3.user"? And how could I remap script output to my ssh connection for debugging purposes?

Thanks!

1 Like

Ok, I have solved this using files to store the status of variables, effectively making them persistent on each call. I do not believe this is optimal, but I can't find a more convenient way :slightly_frowning_face:

Why do you need to store a persistent value?

You can utilize custom UCI configs/options to store the required data:
https://openwrt.org/docs/guide-user/base-system/uci

Hi dl12345 :slight_smile:

Because I need to take into account all three WANs' status to decide how to light the router LEDs. Perhaps a picture is worth a thousand words.

This is a modified Archer C7v5. LEDs labelled "ISP Avail." and "Internet" are affected by interface connection status. If tracking failed on all interfaces, not just one, then there is no internet (LED off). "ISP Avail." has 2 colours and blinking modes to indicate redundancy degradation states.

Of course, this is added functionality because, thanks to OpenWrt, this device now handles two load-balanced WANs and one failover.

Thanks vgaetera,

I thought that was an option. But unfortunately, it seems UCI cannot access mwan3's interface tracking status. Even LuCI will only report the literal human-readable output of "mwan3 interfaces" or "mwan3 status" commands as load balance status.

That leaves me with two options: parse mwan3 command output or track interface status myself in "/etc/mwan3.user". That last one requires persistence because that script is called once per interface update, for example, wan1 connected. But then I need to know the wan2 and wan3 tracking status to make a choice.

It would be nice to have a more script-friendly mwan3 API. Perhaps this is not a common use case.

uci set mwan3."${INTERFACE}".status="${ACTION}"

I'm sorry I misunderstood you. I'll try that way to store data. Thank you very much! :slight_smile:

1 Like

How about creating a simple service that you run with a procd init script. Something like the following script.

#!/bin/sh
  
function signal_handler()
{
        echo "received SIGUSR1"
}

echo "$$" > /var/run/$0.pid
trap signal_handler SIGUSR1

while true; do

        echo "sleeping"
        sleep 5

done

Then in mwan3.user, when you get an interface event, you just send a kill -s SIGUSR1 $(cat /var/run/<scriptname.pid) to the this process. Then your signal_handler() function can handle setting the LEDs. Since it's running all the time, it can track persistent states

1 Like

You can also try another way by using the socat package

Create a init.d script which starts the following shell script. This is your LED handler. It will block reading on a domain socket until some data is available, upon which it will call the led_handler() function.

#!/bin/sh

# LED control utility

socket_fd=/var/run/led.ctl

function led_handler()
{
	echo "status change: $1"
}

while true; do
	socat - UNIX-LISTEN:${socket_fd} | while read line; do
		led_handler "$line"
	done
done

Then, in the mwan3.user script, you can send data to this script by calling

echo "$action $interface $device" | socat - UNIX-CONNECT:/var/run/led.ctl

This is probably a nicer way of doing it than using a signal handler as you can pass data from the mwan3.user script and the script blocks while reading the socket if no data is available.

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.