157 lines
		
	
	
		
			6.0 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			157 lines
		
	
	
		
			6.0 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
	
	
| #!/bin/sh
 | |
| 
 | |
| # Copyright(C) 2018, Rafal Kupiec <belliash@codingworkshop.eu.org>
 | |
| 
 | |
| 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)
 | |
| FLAPPING=$(/sbin/uci -q get wanmonitor.@wanmonitor[0].flapping)
 | |
| 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
 | |
| 			sleep ${FLAPPING}
 | |
| 		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
 |