packages/net/mwan3/files/usr/sbin/mwan3rtmon
Aaron Goodman 39f58789e6 mwan3: use ip monitor route to detect routing changes
use only committed uci changes for updating routing table

use functions.sh functions rather than uci command line tool
to find interfaces for routing table.

consolidate rtmon_ipv4 and rtmon_ipv6 functions into a single function

Signed-off-by: Aaron Goodman <aaronjg@stanford.edu>
2020-08-15 20:19:56 -04:00

109 lines
2.8 KiB
Bash
Executable file

#!/bin/sh
. /lib/functions.sh
. /lib/functions/network.sh
. /lib/mwan3/mwan3.sh
mwan3_rtmon_route_handle()
{
config_load mwan3
local section action route_line family tbl device metric tos dst line
local route_device tid
route_line=${1##"Deleted "}
route_family=$2
if [ "$route_family" = "ipv4" ]; then
IP="$IP4"
elif [ "$route_family" = "ipv6" ] && [ $NO_IPV6 -eq 0 ]; then
IP="$IP6"
else
return
fi
if [ "$route_line" == "$1" ]; then
action="add"
else
action="del"
fi
# never add default route lines, since this is handled elsewhere
[ -z "${route_line##default*}" ] && return
[ -z "${route_line##::/0*}" ] && return
route_line=${route_line%% linkdown*}
route_line=${route_line%% unreachable*}
mwan3_update_dev_to_table
mwan3_route_line_dev "tid" "$route_line" "$route_family"
handle_route() {
tbl=$($IP route list table $tid)
if [ $action = "add" ]; then
echo "$tbl" | grep -q "^default\|^::/0" || return
else
[ -z "$tbl" ] && return
fi
# check that action needs to be performed. May not need to take action if:
# Got a route update on ipv6 where route is already in the table
# Got a delete event, but table was already flushed
[ $action = "add" ] && [ -z "${tbl##*$route_line*}" ] && return
[ $action = "del" ] && [ -n "${tbl##*$route_line*}" ] && return
network_get_device device "$section"
LOG debug "adjusting route $device: $IP route "$action" table $tid $route_line"
$IP route "$action" table $tid $route_line ||
LOG warn "failed: $IP route $action table $tid $route_line"
}
handle_route_cb(){
let tid++
config_get family "$section" family ipv4
[ "$family" != "$route_family" ] && return
handle_route
}
if [ $action = "add" ]; then
## handle old routes from 'change' or 'replace'
metric=${route_line##*metric }
[ "$metric" = "$route_line" ] && unset metric || metric=${metric%% *}
tos=${route_line##*tos }
[ "$tos" = "$route_line" ] && unset tos || tos=${tos%% *}
dst=${route_line%% *}
grep_line="$dst ${tos:+tos $tos}.*table [0-9].*${metric:+metric $metric}"
$IP route list table all | grep "$grep_line" | while read line; do
tbl=${line##*table }
tbl=${tbl%% *}
[ $tbl -gt $MWAN3_INTERFACE_MAX ] && continue
LOG debug "removing route on ip route change/replace: $line"
$IP route del $line
done
fi
if [ -n "$tid" ]; then
handle_route
else
config_foreach handle_route_cb interface
fi
}
main()
{
local IP family
config_load mwan3
family=$1
[ -z $family ] && family=ipv4
if [ "$family" = ipv6 ]; then
IP="$IP6"
else
IP="$IP4"
fi
mwan3_init
$IP monitor route | while read line; do
[ -z "${line##*table*}" ] && continue
LOG debug "handling route update $family $line"
mwan3_lock "service" "mwan3rtmon"
mwan3_rtmon_route_handle "$line" "$family"
mwan3_unlock "service" "mwan3rtmon"
done
}
main "$@"