mirror of
https://github.com/novatiq/packages.git
synced 2026-04-30 15:38:40 +01:00
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>
This commit is contained in:
@@ -145,6 +145,7 @@ start()
|
||||
|
||||
config_load mwan3
|
||||
config_foreach ifup interface
|
||||
mwan3_rtmon
|
||||
}
|
||||
|
||||
stop()
|
||||
@@ -154,23 +155,13 @@ stop()
|
||||
mwan3_lock "command" "mwan3"
|
||||
uci_toggle_state mwan3 globals enabled "0"
|
||||
|
||||
for pid in $(pgrep -f "mwan3rtmon"); do
|
||||
kill -TERM "$pid" > /dev/null 2>&1
|
||||
done
|
||||
|
||||
for pid in $(pgrep -f "mwan3track"); do
|
||||
kill -TERM "$pid" > /dev/null 2>&1
|
||||
done
|
||||
kill -TERM $(pgrep -f "mwan3rtmon") > /dev/null 2>&1
|
||||
kill -TERM $(pgrep -f "mwan3track") > /dev/null 2>&1
|
||||
|
||||
sleep 1
|
||||
|
||||
for pid in $(pgrep -f "mwan3rtmon"); do
|
||||
kill -KILL "$pid" > /dev/null 2>&1
|
||||
done
|
||||
|
||||
for pid in $(pgrep -f "mwan3track"); do
|
||||
kill -KILL "$pid" > /dev/null 2>&1
|
||||
done
|
||||
kill -KILL $(pgrep -f "mwan3rtmon") > /dev/null 2>&1
|
||||
kill -KILL $(pgrep -f "mwan3track") > /dev/null 2>&1
|
||||
|
||||
config_load mwan3
|
||||
config_foreach mwan3_track_clean interface
|
||||
|
||||
@@ -1,38 +1,109 @@
|
||||
#!/bin/sh
|
||||
|
||||
. /lib/functions.sh
|
||||
. /lib/functions/network.sh
|
||||
. /lib/mwan3/mwan3.sh
|
||||
|
||||
LOG="logger -t $(basename "$0")[$$] -p"
|
||||
|
||||
clean_up() {
|
||||
$LOG notice "Stopping mwan3rtmon..."
|
||||
exit 0
|
||||
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
|
||||
}
|
||||
|
||||
rtchange() {
|
||||
$LOG info "Detect rtchange event."
|
||||
}
|
||||
|
||||
main() {
|
||||
local rtmon_interval
|
||||
trap clean_up TERM
|
||||
trap rtchange USR1
|
||||
main()
|
||||
{
|
||||
local IP family
|
||||
|
||||
config_load mwan3
|
||||
config_get rtmon_interval globals rtmon_interval '5'
|
||||
family=$1
|
||||
[ -z $family ] && family=ipv4
|
||||
if [ "$family" = ipv6 ]; then
|
||||
IP="$IP6"
|
||||
else
|
||||
IP="$IP4"
|
||||
fi
|
||||
mwan3_init
|
||||
|
||||
sleep 3
|
||||
while true; do
|
||||
$IP monitor route | while read line; do
|
||||
[ -z "${line##*table*}" ] && continue
|
||||
LOG debug "handling route update $family $line"
|
||||
mwan3_lock "service" "mwan3rtmon"
|
||||
mwan3_rtmon_ipv4 || mwan3_rtmon_ipv6
|
||||
ret=$?
|
||||
mwan3_rtmon_route_handle "$line" "$family"
|
||||
mwan3_unlock "service" "mwan3rtmon"
|
||||
[ "$ret" = "0" ] || break
|
||||
[ "$rtmon_interval" = "0" ] && break
|
||||
sleep "$rtmon_interval" &
|
||||
wait
|
||||
done
|
||||
}
|
||||
|
||||
main "$@"
|
||||
|
||||
Reference in New Issue
Block a user