Hi everyone,
I’m trying to create a script that restarts my mikrotik when the connectivity status changes from up to down, if the connection is already down it shouldn’t restart. I tried with netwatch but since it starts as an “unknown” state when the state changes to “down” it goes into a reboot loop setting system reboot as script.
Anyone know how to help me?
Set global variable in startup script to any “non-unknown” state recognized by your script … eg. value 0.
Then let your script check line changes and if there are enough changes in some period reboot the device.
I use sth. like this
:global vDevPingArray
:local vTmpPingArray [:toarray ""]
:local vIP
:local vHostInfo
:local vTmpIP
:local vTmpHostInfo
:local vNil
:local vMailBody ""
:local vPingLimit 2
:set vPingLimit 2
#:log info "DEVPING START"
#
# add hosts which are in the DEVPING address list
#
:foreach vLease in=[/ip firewall address-list find where (list=DEVPING && !disabled) ] do={
:set vIP ([/ip firewall address-list get $vLease address])
:if ( ($vTmpPingArray->"$vIP")=nil) do={
:set ($vTmpPingArray->"$vIP") { missed=0;\
lastseen;\
noping;\
upping;\
name="$[/ip firewall address-list get $vLease comment]"}
}
}
#
# add hosts which are in the static DNS table
#
:foreach vLease in=[/ip dns static find where !disabled ] do={
:set vIP ([/ip dns static get $vLease address])
:if ( ($vTmpPingArray->"$vIP")=nil) do={
:set ($vTmpPingArray->"$vIP") { missed=0;\
lastseen;\
noping;\
upping;\
name="$[/ip dns static get $vLease name]"}
}
}
#
# add hosts which are in the interface EOIP
#
:foreach vLease in=[/interface eoip find where !disabled ] do={
:set vIP ([/interface eoip get $vLease remote-address])
:if ( ($vTmpPingArray->"$vIP")=nil) do={
:set ($vTmpPingArray->"$vIP") { missed=0;\
lastseen;\
noping;\
upping;\
name="$[/interface eoip get $vLease name]"}
}
}
#
# add hosts which are in the interface IPIP
#
:foreach vLease in=[/interface ipip find where !disabled ] do={
:set vIP ([/interface ipip get $vLease remote-address])
:if ( ($vTmpPingArray->"$vIP")=nil) do={
:set ($vTmpPingArray->"$vIP") { missed=0;\
lastseen;\
noping;\
upping;\
name="$[/interface ipip get $vLease name]"}
}
}
#
# add hosts which are in the interface GRE
#
:foreach vLease in=[/interface gre find where !disabled ] do={
:set vIP ([/interface gre get $vLease remote-address])
:if ( ($vTmpPingArray->"$vIP")=nil) do={
:set ($vTmpPingArray->"$vIP") { missed=0;\
lastseen;\
noping;\
upping;\
name="$[/interface gre get $vLease name]"}
}
}
#
# update vTmpPingArray with data from current vDevPingArray
#
:foreach vTmpIP,vTmpHostInfo in=$vTmpPingArray do={
:local vOldHostInfo ($vDevPingArray->"$vTmpIP")
:if ( $vOldHostInfo!=nil) do={
# if host found in old table then copy old data. Check if name is the same
:if ( ($vOldHostInfo->"name")!=($vTmpHostInfo->"name") ) do={
:local vStateTxt (($vTmpHostInfo->"name") . " ($vTmpIP) changed name from " . ($vOldHostInfo->"name") . ".")
:set vMailBody ($vStateTxt . "\n" . $vMailBody)
:log warning ("$vStateTxt" )
}
:set ($vOldHostInfo->"name") ($vTmpHostInfo->"name")
:set ($vTmpPingArray->"$vTmpIP") $vOldHostInfo
}
}
:set vDevPingArray $vTmpPingArray
:foreach vIP,vHostInfo in=$vDevPingArray do={
:if ([/ping $vIP count=1 interval=1s]=0) do={
:set ($vHostInfo->"missed") (($vHostInfo->"missed")+1)
# no ping, first -> set change moment, following pings -> do nothing
# missed=1 -> lastseen = do not touch = moment of last ping
# noping = first miss moment
# missed>1 -> do not touch anything
:if ( ($vHostInfo->"missed")=1 ) do={
:set ($vHostInfo->"noping") ([/system clock get date] . " at " . [/system clock get time])
}
} else={
# ping OK
# always update lastseen...device still on-line or just appeared
:set ($vHostInfo->"lastseen") ([/system clock get date] . " at " . [/system clock get time])
# the magic:
# change missed to opposite sign
# if device is online, no misses...just online the missed = 0 and operator does not change anything
# if device was missing then missed becomes < 0
:set ($vHostInfo->"missed") (-($vHostInfo->"missed"))
# missed<-PingLimit -> ther was more than PingLimit consecutive misses so assume that we need to report it
# upping = lastessen
# missed=0 -> do not nothing
:if ( ($vHostInfo->"missed")<(-1*$vPingLimit) ) do={
:set ($vHostInfo->"upping") ($vHostInfo->"lastseen")
}
}
}
#
# Look for host which has changed state and report the change
#
:foreach vIP,vHostInfo in=$vDevPingArray do={
:local missed ($vHostInfo->"missed")
:local vState 0
:if ( missed!=0 ) do={
# <0 - back on-line only if missed<-5
:if ( missed<0 ) do={
:if ( missed<-5 ) do={
:set vState 1
}
:set ($vHostInfo->"missed") 0
}
#
# small feature: (missed > 5) reports off-line each time, (missed = 6) reports once
#
:if ( missed=6 ) do={
:set vState -1
}
:if ( $vState != 0 ) do={
:local vStateTxt ""
:set vStateTxt (($vDevPingArray->$vIP->"name") . " ($vIP) now ")
if ( $vState=-1 ) do={
# down
:set vStateTxt ($vStateTxt . "Offline.")
# add lastseen if only host had been ever seen - happens when we add device or after router startup
:if ( ($vDevPingArray->$vIP->"lastseen")!=nil) do={
:set vStateTxt ($vStateTxt . " It was last seen on " . ($vDevPingArray->$vIP->"lastseen" . "."))
}
:log error ("$vStateTxt" )
:set vMailBody ($vStateTxt . "\n" . $vMailBody)
} else={
# up
:set vStateTxt ($vStateTxt . "Online at " . ($vDevPingArray->$vIP->"upping") . ".")
# add noping if only host had been ever unseen - happens when we add device or after router startup
:if ( ($vDevPingArray->$vIP->"noping")!=nil) do={
:set vStateTxt ($vStateTxt . " It was offline since " . ($vDevPingArray->$vIP->"noping" . "."))
}
:log warning ("$vStateTxt" )
:set vMailBody ($vStateTxt . "\n" . $vMailBody)
}
}
}
}
#
# send e-mail when is anything to send
#
:if ( ([:len $vMailBody])>0 ) do={
[/tool e-mail send to=............ subject=("$[/system identity get name] @ $[/system clock get date] $[/system clock get time]") body=($vMailBody)]
}
#:log info "DEVPING KONIEC"
/system watchdog watch-address (IP; Default: )
The system will reboot, in case 6 sequential pings to the given IP address will fail. If set to none this feature is disabled. By default, the router will reboot every 6 minutes if the watch-address is set and not reachable.
thanks nescafe2002,
but I need that if there is no connectivity the mikrotik does not restart. I tried to use watchdog but after 6 minutes it restarts.
var bool ConnWasUp == false;
while true;
if (ConnWasUp = true) then
if (connection down) then reboot;
sleep 2;
if (connection up) then ConnWasUp == True
BartoszP
do you know how to translate the following script to ros?
var bool ConnWasUp == false;
while true;
if (ConnWasUp = true) then
if (connection down) then reboot;
sleep 2;
if (connection up) then ConnWasUp == True
You can add two scheduler entries, one on startup (unset watch-address) and another one to set the watch-address when there is connectivy. Not sure what problem you are trying to solve here?