mirror of
https://github.com/openwrt/packages.git
synced 2025-12-22 10:24:31 +04:00
This makes mwan3rtmon check if mwan3_get_routes returns a route before removing it. This helps with IPv6 routes with source address selector removal where multiple original routes are transformed to the same mwan3 route if one of the source routes is removed while the others are kept. Signed-off-by: Jonas Lochmann <git@inkompetenz.org>
180 lines
4.3 KiB
Bash
Executable File
180 lines
4.3 KiB
Bash
Executable File
#!/bin/sh
|
|
|
|
. /lib/functions.sh
|
|
. /lib/functions/network.sh
|
|
. /lib/mwan3/mwan3.sh
|
|
|
|
trap_with_arg()
|
|
{
|
|
func="$1" ; shift
|
|
pid="$1" ; shift
|
|
for sig ; do
|
|
# shellcheck disable=SC2064
|
|
trap "$func $sig $pid" "$sig"
|
|
done
|
|
}
|
|
|
|
func_trap()
|
|
{
|
|
kill -${1} ${2} 2>/dev/null
|
|
}
|
|
|
|
mwan3_add_all_routes()
|
|
{
|
|
local tid IP IPT route_line family active_tbls tid initial_state error
|
|
local ipv=$1
|
|
|
|
add_active_tbls()
|
|
{
|
|
let tid++
|
|
config_get family "$1" family ipv4
|
|
config_get initial_state "$1" initial_state "online"
|
|
[ "$family" != "$ipv" ] && return
|
|
if $IPT -S "mwan3_iface_in_$1" &> /dev/null; then
|
|
active_tbls="$active_tbls${tid} "
|
|
fi
|
|
}
|
|
|
|
add_route()
|
|
{
|
|
let tid++
|
|
[ -n "${active_tbls##* $tid *}" ] && return
|
|
error=$($IP route add table $tid $route_line 2>&1) ||
|
|
LOG warn "failed to add $route_line to table $tid - error: $error"
|
|
}
|
|
|
|
mwan3_update_dev_to_table
|
|
[ "$ipv" = "ipv6" ] && [ $NO_IPV6 -ne 0 ] && return
|
|
if [ "$ipv" = "ipv4" ]; then
|
|
IP="$IP4"
|
|
IPT="$IPT4"
|
|
elif [ "$ipv" = "ipv6" ]; then
|
|
IP="$IP6"
|
|
IPT="$IPT6"
|
|
fi
|
|
tid=0
|
|
active_tbls=" "
|
|
config_foreach add_active_tbls interface
|
|
[ "$active_tbls" = " " ] && return
|
|
mwan3_get_routes | while read -r route_line; do
|
|
mwan3_route_line_dev "tid" "$route_line" "$ipv"
|
|
if [ -n "$tid" ] && [ -z "${active_tbls##* $tid *}" ]; then
|
|
$IP route add table $tid $route_line
|
|
elif [ -n "${route_line##default*}" ] && [ -n "${route_line##fe80::/64*}" ]; then
|
|
config_foreach add_route interface
|
|
fi
|
|
done
|
|
}
|
|
|
|
mwan3_rtmon_route_handle()
|
|
{
|
|
local action route_line family tbl device line tid
|
|
|
|
route_line=${1##"Deleted "}
|
|
route_family=$2
|
|
|
|
if [ "$route_line" = "$1" ]; then
|
|
action="replace"
|
|
$IPS -! add mwan3_connected_${route_family} ${route_line%% *}
|
|
else
|
|
action="del"
|
|
mwan3_set_connected_${route_family}
|
|
fi
|
|
|
|
if [ -z "${route_line##*linkdown*}" ]; then
|
|
LOG debug "attempting to add link on down interface - $route_line"
|
|
fi
|
|
|
|
if [ "$route_family" = "ipv4" ]; then
|
|
IP="$IP4"
|
|
elif [ "$route_family" = "ipv6" ] && [ $NO_IPV6 -eq 0 ]; then
|
|
IP="$IP6"
|
|
else
|
|
LOG warn "route update called with invalid family - $route_family"
|
|
return
|
|
fi
|
|
route_line=$(echo "$route_line" | sed -ne "$MWAN3_ROUTE_LINE_EXP")
|
|
|
|
if [ "$action" = "del" ]; then
|
|
if mwan3_get_routes | grep -qxF "$route_line"; then
|
|
LOG debug "deleted but route still exists - $route_line"
|
|
return
|
|
fi
|
|
fi
|
|
|
|
handle_route() {
|
|
local error
|
|
local iface=$1
|
|
tbl=$($IP route list table $tid 2>/dev/null)$'\n'
|
|
|
|
if [ -n "$iface" ] && [ "$(mwan3_get_mwan3track_status $iface)" != "active" ]; then
|
|
LOG debug "interface $iface is disabled - skipping '$route_line'";
|
|
return
|
|
fi
|
|
|
|
# check that action needs to be performed. May not need to take action if we
|
|
# got a delete event, but table was already flushed
|
|
if [ $action = "del" ] && [ -n "${tbl##*$route_line$'\n'*}" ]; then
|
|
LOG debug "skipping already deleted route table $tid - skipping '$route_line'"
|
|
return
|
|
fi
|
|
|
|
network_get_device device "$iface"
|
|
LOG debug "adjusting route $device: '$IP route $action table $tid $route_line'"
|
|
error=$($IP route "$action" table $tid $route_line 2>&1)||
|
|
LOG warn "failed: '$IP route $action table $tid $route_line' - error: $error"
|
|
}
|
|
handle_route_cb(){
|
|
local iface=$1
|
|
let tid++
|
|
config_get family "$iface" family ipv4
|
|
[ "$family" != "$route_family" ] && return
|
|
handle_route "$iface"
|
|
}
|
|
|
|
mwan3_update_dev_to_table
|
|
mwan3_route_line_dev "tid" "$route_line" "$route_family"
|
|
|
|
if [ -n "$tid" ]; then
|
|
handle_route
|
|
elif [ -n "${route_line##default*}" ] && [ -n "${route_line##fe80::/64*}" ]; then
|
|
config_foreach handle_route_cb interface
|
|
fi
|
|
}
|
|
|
|
main()
|
|
{
|
|
local IP family
|
|
|
|
mwan3_init
|
|
|
|
family=$1
|
|
[ -z $family ] && family=ipv4
|
|
if [ "$family" = "ipv6" ]; then
|
|
if [ $NO_IPV6 -ne 0 ]; then
|
|
LOG warn "mwan3rtmon started for ipv6, but ipv6 not enabled on system"
|
|
exit 1
|
|
fi
|
|
IP="$IP6"
|
|
else
|
|
IP="$IP4"
|
|
fi
|
|
sh -c "echo \$\$; exec $IP monitor route" | {
|
|
read -r monitor_pid
|
|
trap_with_arg func_trap "$monitor_pid" SIGINT SIGTERM SIGKILL
|
|
KILL -SIGSTOP $$
|
|
while IFS='' read -r line; do
|
|
[ -z "${line##*table*}" ] && continue
|
|
LOG debug "handling route update $family '$line'"
|
|
mwan3_rtmon_route_handle "$line" "$family"
|
|
done
|
|
} &
|
|
child=$!
|
|
trap_with_arg func_trap "$child" SIGINT SIGTERM SIGKILL
|
|
mwan3_set_connected_${family}
|
|
mwan3_add_all_routes ${family}
|
|
kill -SIGCONT $child
|
|
wait $child
|
|
}
|
|
main "$@"
|