-
-
Save zackramjan/e08e5c82429bcc179232e643bd83d90b to your computer and use it in GitHub Desktop.
EdgeOS ready script that tests for WAN connection degradation (via packet loss and latency checks)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh | |
# | |
# USG and EdgeRouter route-test script for failover | |
# | |
# uses ping to check latency and packet loss. | |
# returns zero when within thresholds and non zero (1) when above thresholds | |
# uses ping, traceroute, and logger | |
# | |
# by https://github.com/popmonkey | |
# | |
# v0.8.1 2019.10.12 - don't wait for log_traceroute to return failure | |
# v0.8.0 2019.10.06 - on failure, dump traceroute info | |
# v0.7.0 2019.10.05 - ping more than one host | |
# v0.6.2 2019.10.04 - refactored - also checks packetloss | |
# v0.5.0 2019.10.03 - first working version | |
# | |
# this is meant to be used as the test script in the load-balance groups | |
# e.g. | |
# group wan_failover { | |
# interface eth0 { | |
# route-test { | |
# count { | |
# failure 1 | |
# success 1 | |
# } | |
# type { | |
# script /config/scripts/network_test.sh | |
# } | |
# } | |
# } | |
# interface eth2 { | |
# failover-only | |
# route-test { | |
# count { | |
# failure 1 | |
# success 1 | |
# } | |
# type { | |
# script /config/scripts/network_test.sh | |
# } | |
# } | |
# } | |
# sticky { | |
# dest-addr enable | |
# dest-port enable | |
# source-addr enable | |
# } | |
# transition-script /config/scripts/wan-event-report.sh | |
# } | |
PING_HOSTS='68.56.72.1 1.1.1.1 8.8.8.8 75.75.75.75' | |
MAX_AVERAGE_PING=50 | |
MAX_PACKET_LOSS=50 | |
PING_COUNT=4 | |
GROUP=${1:-unknown} | |
IFACE=${2:-eth0} | |
STATE=${3:-DOWN} | |
# floating point greater than | |
fp_gt() { | |
# NOTE: in bash 0 - true, 1 - false | |
return $((1 - $(echo "$1 $2" | awk '{print ($1 > $2)}'))) | |
} | |
# average of n floats (space separated) | |
fp_avg() { | |
echo $(echo $@ | awk "{ for (i = 1; i <= NF; i++) s = s+\$i }; END { print s / NF }") | |
} | |
# logging function | |
log() { | |
logger -t "NETWORK_WATCHDOG" -- "[$GROUP : $IFACE ($STATE)] $@" | |
} | |
# examine ping | |
do_ping() { | |
PACKET_LOSS_RE='[^0-9.]([0-9.]+)% packet loss' | |
AVERAGE_PING_RE='[0-9.]+\/([0-9.]+)\/[0-9.]+\/[0-9.]' | |
PINGOUT=$(/bin/ping -c $PING_COUNT -I $IFACE $1) | |
if [[ $PINGOUT =~ $PACKET_LOSS_RE ]]; then | |
PACKET_LOSS=${BASH_REMATCH[1]} | |
fi | |
if [[ $PINGOUT =~ $AVERAGE_PING_RE ]]; then | |
AVERAGE_PING=${BASH_REMATCH[1]} | |
fi | |
echo "$(echo $PACKET_LOSS | awk '{print $1+0}') $(echo $AVERAGE_PING | awk '{print $1+0}')" | |
} | |
LOSSES="" | |
PINGS="" | |
for host in $(echo $PING_HOSTS); do | |
PING_OUT=$(do_ping $host) | |
log "TESTING $host: loss=${PING_OUT}ms" | |
LOSSES="$LOSSES $(echo $PING_OUT | awk '{print $1}')" | |
PINGS="$PINGS $(echo $PING_OUT | awk '{print $2}')" | |
done | |
AVG_LOSS=$(fp_avg "$LOSSES") | |
AVG_PING=$(fp_avg "$PINGS") | |
if fp_gt $AVG_LOSS $MAX_PACKET_LOSS; then | |
log "TEST FAILED: high packetloss: $AVG_LOSS% > $MAX_PACKET_LOSS%" | |
exit 1 | |
fi | |
if fp_gt $AVG_PING $MAX_AVERAGE_PING; then | |
log "TEST FAILED: high ping: ${AVG_PING}ms > ${MAX_AVERAGE_PING}ms" | |
exit 1 | |
fi | |
log "TEST PASSED: avg_ping: $AVG_PING < $MAX_AVERAGE_PING AND avg_loss: $AVG_LOSS < $MAX_PACKET_LOSS" | |
exit 0 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment