Sometimes Mikrotik scripting is a pain and also a gain. WAN failover using a script…

If you are using Mikrotik’s /interface/detect-internet and have been googling for a solution, or even a reason, as to how to use the thing, then perhaps the following will help.

Scenario:

You have 3 wan links, and want to fail over between which ever one is up/down to the least preferred.

Mikrotik’s detect-internet uses the source IP and routing of an interface, to try and connect to a Mikrotik cloud service. If it’s reachable via an interface the status changes to “internet”.

This means that detect-internet is capable of telling you whether a WAN link has internet capability without having to roll your own solution. You can read more about the feature here.

This script uses that capability to change the interface (whether DHCP or static default route) to the weight that you require. This is good, because ROS does the work of using the correct source interface, so that you don’t have to go and add routing entries and ping destinations for each interface to monitor to see if a link is up.

“detect-internet” uses a source-ip bound connection to cloud.mikrotik.com to determine if a link has internet accces. Essentially if an interface has connectvity, it’s /interface/detect-internet/state entry will be “internet” and that’s a really easy way to know of a specific WAN interface has connectivity, without too much trouble

You have to setup the interfaces in interface->detect-internet however. Applicable to ROS 7.

I’m not a fan of mikrotik scripting, the syntax is terrible. But it gets the job done. Schedule the script below every 20 seconds using /system/scheduler, and it will check the status of each interface, and apply the default route distances making the most viable route the default.

All you have to do is edit the bottom 3 lines of the script, and set your preferred default route distances so that your WAN links will always choose the most available default route. Add some more, or less, depending on your requirements.

 
:global checkinternet do={
    :local hasinternet [/interface/detect-internet/state/find name=$ifname and state=internet]
    :local rtid [/ip/route find where dst-address=0.0.0.0/0 and immediate-gw~$ifname]

    :if ([:len $rtid] = 0) do={
#        :log info "$linkname/$ifname has no default route"
    } else {
        :local distance [/ip/route/get value-name=distance [find where dst-address=0.0.0.0/0 and immediate-gw~$ifname]]
#        [:log info "$linkname/$ifname distance is $distance" ]
        :if ([:len $hasinternet] = 0) do={            
            :if ($distance!=$downdistance) do={
                [:log info "$linkname/$ifname is down" ]
                /ip route set [find where dst-address=0.0.0.0/0 and immediate-gw~$ifname] distance=$downdistance
            }
        } else={             
            :if ($distance!=$updistance) do={
                [:log info "$linkname/$ifname is up" ]
                /ip route set $rtid distance=$updistance
            }
        }
    }
}

 
$checkinternet linkname="CISP" ifname="ether6" downdistance="50" updistance="5"
$checkinternet linkname="AFRIHOST" ifname="ether7" downdistance="100" updistance="10"
$checkinternet linkname="LTE" ifname="ether8" downdistance="150" updistance="15"

Author: roelf on December 11, 2024
Category: Uncategorized

Last articles