Failover Scripting

From MikroTik Wiki
Revision as of 15:13, 19 September 2012 by Tomaskir (talk | contribs)
Jump to: navigation, search

This is an easy to use script for your failover needs.

It works by pinging any IP address you specify using the connections you tell it to. If a ping failure is detected in increases a route's distance in the routing table by an ammount you specify.

WORK IN PROGRESS.

# -------------- header --------------
# Script by Tomas Kirnak, version 1.0.4
# If you use this script, or edit and
# re-use it, please keep the header intact.
#
# For more information and details about
# this script please visit the wiki page at
# http://wiki.mikrotik.com/wiki/Failover_Scripting
# -------------- header --------------



# -------------- start editing here --------------
# Edit the variables below to suit your needs

# Please fill the WAN interface names
:local Interface_ISP1 ether1
:local Interface_ISP2 ether2

# Please fill the gateway IPs (or interface names in case of PPP)
:local Gateway_ISP1 1.1.1.1
:local Gateway_ISP2 2.2.2.2

# Please fill the ping check host - currently: resolver1.opendns.com
:local PingTarget 208.67.222.222

# Please fill how many ping failures are allowed before fail-over happends
:local FailTreshold 3

# Define the distance increase of a route when it fails
:local DistanceIncrease 2

# Editing the script after this point may break it
# -------------- stop editing here --------------



# Declare the global variables
:global PingFailCount_ISP1
:global PingFailCount_ISP2

# This inicializes the PingFailCount variables, in case this is the 1st time the script has ran
:if ([:typeof $PingFailCount_ISP1] = "nothing") do={:set PingFailCount_ISP1 0}
:if ([:typeof $PingFailCount_ISP2] = "nothing") do={:set PingFailCount_ISP2 0}

# This variable will be used to keep results of individual ping attempts
:local PingResult



# Check ISP1
:set PingResult [ping $PingTarget count=1 interface=$Interface_ISP1]
:put $PingResult

:if ($PingResult = 0) do={
	:if ($PingFailCount_ISP1 < ($FailTreshold+2)) do={
		:set PingFailCount_ISP1 ($PingFailCount_ISP1 + 1)
		
		:if ($PingFailCount_ISP1 = $FailTreshold) do={
			:log warning "ISP1 has a problem en route to $PingTarget - increasing distance of routes."
			:foreach i in=[/ip route find gateway=$Gateway_ISP1 && static] do={/ip route set $i distance=([/ip route get $i distance] + $DistanceIncrease)}
			:log warning "Route distance increase finished."
		}
	}
}
:if ($PingResult = 1) do={
	:if ($PingFailCount_ISP1 > 0) do={
		:set PingFailCount_ISP1 ($PingFailCount_ISP1 - 1)
		
		:if ($PingFailCount_ISP1 = ($FailTreshold -1)) do={
			:log warning "ISP1 can reach $PingTarget again - bringing back original distance of routes."
			:foreach i in=[/ip route find gateway=$Gateway_ISP1 && static] do={/ip route set $i distance=([/ip route get $i distance] - $DistanceIncrease)}
			:log warning "Route distance decrease finished."
		}
	}
}



# Check ISP2
:set PingResult [ping $PingTarget count=1 interface=$Interface_ISP2]
:put $PingResult

:if ($PingResult = 0) do={
	:if ($PingFailCount_ISP2 < ($FailTreshold+2)) do={
		:set PingFailCount_ISP2 ($PingFailCount_ISP2 + 1)
		
		:if ($PingFailCount_ISP2 = $FailTreshold) do={
			:log warning "ISP2 has a problem en route to $PingTarget - increasing distance of routes."
			:foreach i in=[/ip route find gateway=$Gateway_ISP2 && static] do={/ip route set $i distance=([/ip route get $i distance] + $DistanceIncrease)}
			:log warning "Route distance increase finished."
		}
	}
}
:if ($PingResult = 1) do={
	:if ($PingFailCount_ISP2 > 0) do={
		:set PingFailCount_ISP2 ($PingFailCount_ISP2 - 1)
		
		:if ($PingFailCount_ISP2 = ($FailTreshold -1)) do={
			:log warning "ISP2 can reach $PingTarget again - bringing back original distance of routes."
			:foreach i in=[/ip route find gateway=$Gateway_ISP2 && static] do={/ip route set $i distance=([/ip route get $i distance] - $DistanceIncrease)}
			:log warning "Route distance decrease finished."
		}
	}
}