You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
104 lines
2.8 KiB
104 lines
2.8 KiB
3 years ago
|
#!/bin/bash
|
||
|
|
||
|
INTERVAL=1
|
||
|
PACKETS=1
|
||
|
#reliable hosts for checking are cloudflare, quad9, hgoogle
|
||
|
HOSTS=("1.1.1.1" "9.9.9.9" "8.8.8.8")
|
||
|
WAN1=eth0
|
||
|
WAN2=wwan0
|
||
|
USINGWAN=eth0
|
||
|
CHECKWAN=eth0
|
||
|
COUNTER=0
|
||
|
CHANGED=0
|
||
|
|
||
|
function change_wan_metric() {
|
||
|
CHANGED=$SECONDS
|
||
|
local ROUTE=0
|
||
|
# 100 just in case this runs away for some reason
|
||
|
while [ $ROUTE -le 100 ]
|
||
|
do
|
||
|
local ROUTE_IFACE=`uci get network.@route[$ROUTE].interface`
|
||
|
if [ "$ROUTE_INTERFACE" == "uci: Entry not found" ]; then
|
||
|
break
|
||
|
elif [ "$ROUTE_INTERFACE" == "wan" ]; then
|
||
|
uci set network.@route[$ROUTE].metric='$1'
|
||
|
uci commit
|
||
|
reload_config
|
||
|
break
|
||
|
fi
|
||
|
let ROUTE++
|
||
|
done
|
||
|
}
|
||
|
|
||
|
function debug {
|
||
|
logger -t failover "`date`: pings:$PINGS, counter:$COUNTER, changed:$CHANGED, seconds:$SECONDS, usingwan:$USINGWAN, checkwan:$CHECKWAN"
|
||
|
}
|
||
|
|
||
|
logger -t failover "`date`: Failover script started."
|
||
|
while sleep $INTERVAL
|
||
|
do
|
||
|
|
||
|
if [ "$USINGWAN" == "$WAN2" ] && [ $(($SECONDS-$CHANGED)) -gt 300 ]; then
|
||
|
debug
|
||
|
# after 5 minutes on failover wan2, check main wan. if it fails counter will go to 1 but since
|
||
|
# wan2 is still fine it should reset to 0 next time and stay on wan2, until the check repeats and so on.
|
||
|
CHECKWAN=$WAN1
|
||
|
CHANGED=$SECONDS #and reset changed so it just tried once then returns to checking working wan
|
||
|
fi
|
||
|
|
||
|
PINGS=0
|
||
|
for (( c=0; c<${#HOSTS[@]}; c++ ))
|
||
|
do
|
||
|
RET=`ping -I $CHECKWAN -w 1 -W 1 -c $PACKETS ${HOSTS[c]} 2>/dev/null | awk '/received/ {print $4}'`
|
||
|
if [ "$RET" == "$PACKETS" ]; then
|
||
|
let PINGS++
|
||
|
fi
|
||
|
done
|
||
|
|
||
|
#debug if any pings fail, just for fun
|
||
|
if [ $PINGS -lt ${#HOSTS[@]} ]; then
|
||
|
debug
|
||
|
fi
|
||
|
|
||
|
|
||
|
# if all pings failed increase counter
|
||
|
if [ $PINGS -eq 0 ]; then
|
||
|
let COUNTER++
|
||
|
else
|
||
|
COUNTER=0
|
||
|
fi
|
||
|
|
||
|
# counter failed pings to all hosts multiple times, switch WAN
|
||
|
if [ $COUNTER -gt 3 ]; then
|
||
|
debug
|
||
|
# NOTE: if both wan fail, it will just switch back and forth. but not like it matters, neither would work anyway... lol
|
||
|
if [ "$USINGWAN" == "$WAN1" ]; then
|
||
|
#if failed and currently on wan, switch to wanb
|
||
|
change_wan_metric 2
|
||
|
USINGWAN=$WAN2
|
||
|
CHECKWAN=$USINGWAN
|
||
|
logger -t failover "`date`: Changed active WAN metric to 4G modem!"
|
||
|
elif [ "$USINGWAN" == "$WAN2" ]; then
|
||
|
#if failed and currently on wanb, switch back to wan
|
||
|
change_wan_metric 0
|
||
|
USINGWAN=$WAN1
|
||
|
CHECKWAN=$USINGWAN
|
||
|
logger -t failover "`date`: Changed active WAN metric to Cable connection!"
|
||
|
fi
|
||
|
elif [ $COUNTER -eq 0 ]; then
|
||
|
# counter is successful, if on wan2 and wan1 has recovered return to wan1
|
||
|
if [ "$CHECKWAN" == "$WAN1" ] && [ "$USINGWAN" == "$WAN2" ]; then
|
||
|
debug
|
||
|
#if failed and currently on wanb, switch back to wan
|
||
|
change_wan_metric 0
|
||
|
USINGWAN=$WAN1
|
||
|
CHECKWAN=$USINGWAN
|
||
|
logger -t failover "`date`: Changed active WAN metric to Cable connection!"
|
||
|
fi
|
||
|
fi
|
||
|
|
||
|
#set the checkwan back to the usingwan, in case it was set to the other wan for recovery check
|
||
|
CHECKWAN=$USINGWAN
|
||
|
|
||
|
done;
|