#!/bin/sh # Copyright(C) 2018, Rafal Kupiec source /lib/functions/network.sh DAEMONIZE=0 LOGGER_ALERT=1 LOGGER_CRITICAL=2 LOGGER_ERROR=3 LOGGER_WARNING=4 LOGGER_NOTICE=5 LOGGER_INFO=6 LOGGER_DEBUG=7 CHECK_HOST=$(/sbin/uci -q get wanmonitor.@wanmonitor[0].check_host) INTERVAL=$(/sbin/uci -q get wanmonitor.@wanmonitor[0].interval) SLEEP=$(/sbin/uci -q get wanmonitor.@wanmonitor[0].sleep) WAN_PRIMARY=$(/sbin/uci -q get wanmonitor.@wanmonitor[0].wan_primary) WAN_PRIMARY_METRIC=$(/sbin/uci -q get network.${WAN_PRIMARY}.metric) WAN_SECONDARY=$(/sbin/uci -q get wanmonitor.@wanmonitor[0].wan_secondary) WAN_SECONDARY_METRIC=$(/sbin/uci -q get network.${WAN_SECONDARY}.metric) function initialize() { network_get_device IFNAME_WAN_PRIMARY ${WAN_PRIMARY} network_get_gateway GATEWAY_WAN_PRIMARY ${WAN_PRIMARY} network_get_device IFNAME_WAN_SECONDARY ${WAN_SECONDARY} network_get_gateway GATEWAY_WAN_SECONDARY ${WAN_SECONDARY} if [ "x${IFNAME_WAN_PRIMARY}" = "x" ]; then IFNAME_WAN_PRIMARY=$(/sbin/uci -q -P /var/state get network.${WAN_PRIMARY}.ifname) fi if [ "x${GATEWAY_WAN_PRIMARY}" = "x" ]; then GATEWAY_WAN_PRIMARY=$(uci -q -P /var/state get network.${WAN_PRIMARY}.gateway) fi if [ "x${GATEWAY_WAN_PRIMARY}" = "x" ]; then GATEWAY_WAN_PRIMARY=$(ifstatus ${WAN_PRIMARY} | grep -A 2 "\"target\": \"0.0.0.0\"," | awk '/nexthop/ {gsub(/[",]/, "");print $2}') fi if [ "x${IFNAME_WAN_SECONDARY}" = "x" ]; then IFNAME_WAN_SECONDARY=$(/sbin/uci -q -P /var/state get network.${WAN_SECONDARY}.ifname) fi if [ "x${GATEWAY_WAN_SECONDARY}" = "x" ]; then GATEWAY_WAN_SECONDARY=$(uci -q -P /var/state get network.${WAN_SECONDARY}.gateway) fi if [ "x${GATEWAY_WAN_SECONDARY}" = "x" ]; then GATEWAY_WAN_SECONDARY=$(ifstatus ${WAN_SECONDARY} | grep -A 2 "\"target\": \"0.0.0.0\"," | awk '/nexthop/ {gsub(/[",]/, "");print $2}') fi } function prepare() { /usr/bin/logger -t $0 -p ${LOGGER_NOTICE} "Starting WAN Monitor ..." sleep ${SLEEP} /usr/bin/logger -t $0 -p ${LOGGER_NOTICE} "Initializing WAN Monitor & Failover Connection Manager" initialize for IFNAME_WAN in ${IFNAME_WAN_PRIMARY} ${IFNAME_WAN_SECONDARY}; do if [ "x${IFNAME_WAN}" = "x" ]; then /usr/bin/logger -t $0 -p ${LOGGER_CRITICAL} "Lack of logical interface for one of WAN connections!" exit 1 fi done for GATEWAY_WAN in ${GATEWAY_WAN_PRIMARY} ${GATEWAY_WAN_SECONDARY}; do if [ "x${GATEWAY_WAN}" = "x" ]; then /usr/bin/logger -t $0 -p ${LOGGER_CRITICAL} "Lack of gateway on logical interface for one of WAN connections!" exit 2 fi done /usr/bin/logger -t $0 -p ${LOGGER_DEBUG} "Primary WAN Interface: ${IFNAME_WAN_PRIMARY}, Gateway: ${GATEWAY_WAN_PRIMARY}, Metric: ${WAN_PRIMARY_METRIC:-0}" /usr/bin/logger -t $0 -p ${LOGGER_DEBUG} "Secondary WAN Interface: ${IFNAME_WAN_SECONDARY}, Gateway: ${GATEWAY_WAN_SECONDARY}, Metric: ${WAN_SECONDARY_METRIC:-0}" /usr/bin/logger -t $0 -p ${LOGGER_DEBUG} "Checking host: ${CHECK_HOST} every ${INTERVAL} seconds interval" } function status() { echo -e "Primary WAN Interface: ${IFNAME_WAN_PRIMARY}, Gateway: ${GATEWAY_WAN_PRIMARY}, Metric: ${WAN_PRIMARY_METRIC:-0}" echo -e "Secondary WAN Interface ${IFNAME_WAN_SECONDARY}, Gateway: ${GATEWAY_WAN_SECONDARY}, Metric: ${WAN_SECONDARY_METRIC:-0}" echo -e "Checking host: ${CHECK_HOST} every ${INTERVAL} seconds interval" echo ACTIVE=$(/bin/ps | grep 'wanmonitor -d' | grep -v 'grep' | wc -l) if [ "x${ACTIVE}" = "x0" ]; then echo -e "WAN Monitor & Failover Connection Manager is NOT RUNNING" else echo -e "WAN Monitor & Failover Connection Manager is RUNNING" fi ACTIVE_INTERFACE=$(route | grep default | awk '{print $8}') if [ "x${ACTIVE_INTERFACE}" = "x${IFNAME_WAN_PRIMARY}" ]; then ACTIVE_WAN="${WAN_PRIMARY}" elif [ "x${ACTIVE_INTERFACE}" = "x${IFNAME_WAN_SECONDARY}" ]; then ACTIVE_WAN="${WAN_SECONDARY}" else ACTIVE_WAN="UNKNOWN" fi echo -e "Active WAN connection: ${ACTIVE_WAN}" } until [[ -z "${1}" ]]; do case "${1}" in -d|--daemon) DAEMONIZE=1 ;; *) echo "Unknown option: ${1}" ;; esac shift done if [ "x${DAEMONIZE}" = "x0" ]; then initialize status exit 0 fi prepare /usr/bin/logger -t $0 -p ${LOGGER_NOTICE} "Entering link monitoring loop ..." WAN=0 while true; do WAN_PRIMARY_STATUS=$(ifstatus ${WAN_PRIMARY} | grep \"up\" | awk '{gsub(/[",]/, ""); print $2}') if [ "x${WAN_PRIMARY_STATUS}" = "xtrue" ]; then CHECK_HOST_ROUTE=$(route | grep ${CHECK_HOST} | grep ${IFNAME_WAN_PRIMARY} | wc -l) if [ "x${CHECK_HOST_ROUTE}" = "x0" ]; then /sbin/route add -host ${CHECK_HOST} gateway ${GATEWAY_WAN_PRIMARY} metric 0 ${IFNAME_WAN_PRIMARY} &>/dev/null fi WAN_PRIMARY_PING=$(ping -I ${IFNAME_WAN_PRIMARY} -w 3 -c 3 ${CHECK_HOST} 2>/dev/null | awk '/packets received/ {print $4}') fi if [ "x${WAN_PRIMARY_STATUS}" = "xfalse" ] || [ "x${WAN_PRIMARY_PING}" = "x0" ]; then if [ "${WAN}" = "0" ] || [ "${WAN}" = "1" ]; then /usr/bin/logger -t $0 -p ${LOGGER_ALERT} "Primary WAN Interface is DOWN! Switching traffic to ${WAN_SECONDARY}." /sbin/route del default gw ${GATEWAY_WAN_PRIMARY} metric ${WAN_PRIMARY_METRIC:-0} ${IFNAME_WAN_PRIMARY} &>/dev/null CHECK_SECONDARY_ROUTE=$(route | grep default | grep ${IFNAME_WAN_SECONDARY} | wc -l) if [ "x${CHECK_SECONDARY_ROUTE}" = "x0" ]; then /sbin/route add default gw ${GATEWAY_WAN_SECONDARY} metric ${WAN_SECONDARY_METRIC:-0} ${IFNAME_WAN_SECONDARY} &>/dev/null fi WAN=2 fi else if [ "${WAN}" = "0" ] || [ "${WAN}" = "2" ]; then /usr/bin/logger -t $0 -p ${LOGGER_ALERT} "Primary WAN Interface is UP! Switching traffic to ${WAN_PRIMARY}." /sbin/route del default gw ${GATEWAY_WAN_SECONDARY} metric ${WAN_SECONDARY_METRIC:-0} ${IFNAME_WAN_SECONDARY} &>/dev/null CHECK_PRIMARY_ROUTE=$(route | grep default | grep ${IFNAME_WAN_PRIMARY} | wc -l) if [ "x${CHECK_PRIMARY_ROUTE}" = "x0" ]; then /sbin/route add default gw ${GATEWAY_WAN_PRIMARY} metric ${WAN_PRIMARY_METRIC:-0} ${IFNAME_WAN_PRIMARY} &>/dev/null fi WAN=1 fi fi sleep ${INTERVAL} done