Community discussions

 
TLS
just joined
Topic Author
Posts: 3
Joined: Fri Sep 02, 2016 9:01 pm

Dual Wan failover with 1 static and 1 dynamic IP?

Mon Sep 26, 2016 3:33 pm

I am trying to figure out how to implement WAN failover with 2 different ISP's - A Comcast connection providing a static IP and a Century Link connection providing a dynamic IP.

I believe I've figured out how to accomplish this if both were static, correct me if I am wrong, under IP Addresses I would simply assign ether1 and ether2 their own static IP's and then under System Scripts I would add this script (http://wiki.mikrotik.com/wiki/Failover_Scripting) and edit where necessary.

And from some replies I got on an older post, if I understand correctly; then for the dynamic Wan I change the script for Ether2 with this line ":local GatewayISP2 [/ip dhcp-client get value-name=gateway number=0];"

Is that correct?
 
ant0nwax
just joined
Posts: 3
Joined: Sun Oct 21, 2018 8:47 am

Re: Dual Wan failover with 1 static and 1 dynamic IP?

Sun Oct 21, 2018 8:50 am

Hi, did you manage to implement this with a dynamic gateway?
I have two dynamic Gateways (CableModem and LTEModem)
thanks for feedback
 
nbencic
just joined
Posts: 3
Joined: Fri Oct 26, 2018 5:45 pm

Re: Dual Wan failover with 1 static and 1 dynamic IP?

Fri Oct 26, 2018 7:42 pm

If you don't have them yet, make 2 static routes with gw set as network interfaces of ur CableModem and LTEModem,
Comment out both routes

Change:
# Fill the WAN interface gateways ( ip address or interface name - preferred is IP address, but for dhcp-client WAN use interface name )
:local GatewayISP1 ether1
:local GatewayISP2 ether2

# Mark routes with comments and fill their marks ( unique comments only !!! )
:local RouteISP1 [/ip route find comment="WAN1"];
:local RouteISP2 [/ip route find comment="WAN2"];
and give it a shot
# ------------------- header -------------------
# Base script created by 
# Script by Tomas Kirnak, version 1.0.7
# 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


# Script modifications and adaptations done by Nikola Bencic v1.0.0
# 26.oct.2018. in Reykjavik
# ------------------- header -------------------

# Fill the WAN interface gateways ( ip address or interface name - preferred is IP address, but for dhcp-client WAN use interface name )
:local GatewayISP1 ether1
:local GatewayISP2 ether2

# Mark routes with comments and fill their marks ( unique comments only !!! )
:local RouteISP1 [/ip route find comment="WAN1"];
:local RouteISP2 [/ip route find comment="WAN2"];

# Check hosts: opendns, googledns, 0.ntp.europe.pool ( you can add more hosts if needed - but remember to chec firewall rules and whitelist them if you need )
:local PingTargets {"208.67.222.222";"8.8.8.8";"185.19.184.35"}

# Amount of ping fails needed to declare route as faulty
:local FailTreshold 3

# Define the distance increase of a route when it fails ( number should be count of ISPs or greater )
:local DistanceIncrease 5

# -------------- stop editing here --------------

# Declare the global variables
:global PingFailCountISP1
:global OriginalRouteDistanceISP1
:global PingFailCountISP2
:global OriginalRouteDistanceISP2

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

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

# Clean routing table just in case we have a leftover route 
/ip route remove [find comment="FAILOVER CHECK ROUTE"]


###########################################################################################
# Check ISP1

# Check remote ip 3 times
:foreach k,pingTarget in=$PingTargets do={

	:delay 1s;
	/ip route add comment="FAILOVER CHECK ROUTE" distance=1 gateway=$GatewayISP1 dst-address=$pingTarget
	:local testRouteID [/ip route find comment="FAILOVER CHECK ROUTE"];
	/log warning "Pinging $pingTarget thru $GatewayISP1"

	:set PingResult [ping $pingTarget count=1];

 	:if ([/ip route get $testRouteID gateway-status] ~"unreachable"=true) do={

		:set PingFailCountISP1 ($PingFailCountISP1 + 1)
		/log error "Ping to $pingTarget thru $GatewayISP1 FAILED - unreachable gw"

 	} else={

		# remote ping failed, increase fail count isp +1
		:if ($PingResult = 0) do={
			:set PingFailCountISP1 ($PingFailCountISP1 + 1)
			/log error "Ping to $pingTarget thru $GatewayISP1 FAILED - no ping"
		};

		# remote ping passed, decrease fail count isp -1
		:if ($PingResult = 1) do={
			:if ($PingFailCountISP1 > 0) do={
				:set PingFailCountISP1 ($PingFailCountISP1 - 1)
			};
		};

 	}

	/ip route remove [find comment="FAILOVER CHECK ROUTE"]
};

#if ping to all 3 hosts failed, declare route as faulty
:if ($PingFailCountISP1 >= $FailTreshold) do={

	:if ([:typeof $OriginalRouteDistanceISP1] = "nothing") do={
		:set OriginalRouteDistanceISP1 [/ip route get $RouteISP1 distance]
	} 

	:if ($OriginalRouteDistanceISP1 + $DistanceIncrease != [/ip route get $RouteISP1 distance]) do={

		/log warning "ISP1 has a problem en route to $pingTarget - increasing distance of route."
		/ip route set $RouteISP1 distance=($OriginalRouteDistanceISP1 + $DistanceIncrease)
		/log warning "ISP1 Route distance increase finished."
	}
}

:if ($PingFailCountISP1 < $FailTreshold) do={

	/log warning "ISP1 is working ok"

	:if ([:typeof $OriginalRouteDistanceISP1] != "nothing") do={

		:if ([/ip route get $RouteISP1 distance] != $OriginalRouteDistanceISP1) do={

			/log warning "ISP1 can reach $pingTarget again - bringing back original distance of route."

			# if ISP1RecoverSpeed is "fast" - recovery of ISP will be FASTER - but there is potential danger of flapping in route ( if its unstable ISP )
			#
			# if ISP1RecoverSpeed is "slow" - recovery of ISP will be SLOWER - but there we are safe in case of unstable ISP
			:local ISP1RecoverSpeed "slow";

			:if ($ISP1RecoverSpeed = "slow") do={
				/log warning "ISP1 recovery is set to SLOW"
				:for pingRun from 0 to 2 do={
					:if ($PingFailCountISP1 > 0) do={
						:set PingFailCountISP1 ($PingFailCountISP1 - 1)
					}
				}
			} else={
				/log warning "ISP1 recovery is set to FAST"
				:set PingFailCountISP1 0
			}

			:if ($PingFailCountISP1 = 0) do={
				
				/ip route set $RouteISP1 distance=($OriginalRouteDistanceISP1)
				/log warning "ISP1 Route distance returned to original value."
			}
		}
	}
}

###########################################################################################
# Check ISP2

# Check remote ip 3 times
:foreach k,pingTarget in=$PingTargets do={

	:delay 1s;
	/ip route add comment="FAILOVER CHECK ROUTE" distance=1 gateway=$GatewayISP2 dst-address=$pingTarget
	:local testRouteID [/ip route find comment="FAILOVER CHECK ROUTE"];
	/log warning "Pinging $pingTarget thru $GatewayISP2"

	:set PingResult [ping $pingTarget count=1];

 	:if ([/ip route get $testRouteID gateway-status] ~"unreachable"=true) do={

		:set PingFailCountISP2 ($PingFailCountISP2 + 1)
		/log error "Ping to $pingTarget thru $GatewayISP2 FAILED - unreachable gw"

 	} else={

		# remote ping failed, increase fail count isp +1
		:if ($PingResult = 0) do={
			:set PingFailCountISP2 ($PingFailCountISP2 + 1)
			/log error "Ping to $pingTarget thru $GatewayISP2 FAILED - no ping"
		};

		# remote ping passed, decrease fail count isp -1
		:if ($PingResult = 1) do={
			:if ($PingFailCountISP2 > 0) do={
				:set PingFailCountISP2 ($PingFailCountISP2 - 1)
			};
		};

 	}

	/ip route remove [find comment="FAILOVER CHECK ROUTE"]
};

#if ping to all 3 hosts failed, declare route as faulty
:if ($PingFailCountISP2 >= $FailTreshold) do={

	:if ([:typeof $OriginalRouteDistanceISP2] = "nothing") do={
		:set OriginalRouteDistanceISP2 [/ip route get $RouteISP2 distance]
	} 

	:if ($OriginalRouteDistanceISP2 + $DistanceIncrease != [/ip route get $RouteISP2 distance]) do={

		/log warning "ISP2 has a problem en route to $pingTarget - increasing distance of route."
		/ip route set $RouteISP2 distance=($OriginalRouteDistanceISP2 + $DistanceIncrease)
		/log warning "ISP2 Route distance increase finished."
	}
}

:if ($PingFailCountISP2 < $FailTreshold) do={

	/log warning "ISP2 is working ok"

	:if ([:typeof $OriginalRouteDistanceISP2] != "nothing") do={

		:if ([/ip route get $RouteISP2 distance] != $OriginalRouteDistanceISP2) do={

			/log warning "ISP2 can reach $pingTarget again - bringing back original distance of route."

			# if ISP2RecoverSpeed is "fast" - recovery of ISP will be FASTER - but there is potential danger of flapping in route ( if its unstable ISP )
			#
			# if ISP2RecoverSpeed is "slow" - recovery of ISP will be SLOWER - but there we are safe in case of unstable ISP
			:local ISP2RecoverSpeed "slow";

			:if ($ISP2RecoverSpeed = "slow") do={
				/log warning "ISP2 recovery is set to SLOW"
				:for pingRun from 0 to 2 do={
					:if ($PingFailCountISP2 > 0) do={
						:set PingFailCountISP2 ($PingFailCountISP2 - 1)
					}
				}
			} else={
				/log warning "ISP2 recovery is set to FAST"
				:set PingFailCountISP2 0
			}

			:if ($PingFailCountISP2 = 0) do={
				
				/ip route set $RouteISP2 distance=($OriginalRouteDistanceISP2)
				/log warning "ISP2 Route distance returned to original value."
			}
		}
	}
}

Who is online

Users browsing this forum: Majestic-12 [Bot] and 9 guests