/ip firewall mangle add action=mark-connection chain=forward connection-mark=no-mark \ in-interface=ISP1 new-connection-mark=ISP1 passthrough=no add action=mark-routing chain=prerouting connection-mark=ISP1 in-interface=\ bridge-local new-routing-mark=to_ISP1 passthrough=no add action=mark-connection chain=forward connection-mark=no-mark \ in-interface=ISP2 new-connection-mark=ISP2 passthrough=no add action=mark-routing chain=prerouting connection-mark=ISP2 in-interface=\ bridge-local new-routing-mark=to_ISP2 passthrough=no /ip firewall nat add action=masquerade chain=srcnat out-interface=ISP1 add action=masquerade chain=srcnat out-interface=ISP2 /ip route add distance=1 gateway=ISP1 routing-mark=to_ISP1 add distance=1 gateway=ISP2 routing-mark=to_ISP2
global FailoverTimes; global FailoverLastTime; global FailoverLastBackTime; local ifMain "ISP1"; local ifRes "ISP2"; local scriptName "Failover"; local state 0; local pingNum 0; local pingRes; local routeDist; local routeDist2; local tmp; local ip { xxxx; yyyy; zzzz }; local pingSrcAddr 192.168.xx.yy;
if ( [len [/system script job find where script=$scriptName]] > 1) do= { error "single instance" }; delay 15;
if ($state = 0) do= { do { if ($pingNum >= 3) do= { set $pingNum 0; } if ([ping ($ip->$pingNum) count=1] = 0) do= { set $pingRes [ping ($ip->0) count=2]; set $pingRes ($pingRes+[ping ($ip->1) count=2]); set $pingRes ($pingRes+[ping ($ip->2) count=2]); if ($pingRes = 0) do= { set $FailoverLastTime "$[/system clock get date] $[/system clock get time]"; set $FailoverTimes ([tonum $FailoverTimes] + 1) set $state 1; log info "$scriptName: state changed 0->1"; } } set $pingNum ($pingNum + 1); if ($state = 0) do= { delay 15 }; } while ($state = 0); }
if ($state = 1) do= { if ( [/interface l2tp-client get $ifMain default-route-distance] > 10) do= { /interface ppp-client set $ifRes default-route-distance=1; } /interface enable $ifRes; beep frequency=2000 length=250ms; delay 500ms; beep frequency=2000 length=250ms; delay 500ms; delay 6; /interface disable $ifMain; set $routeDist ([/interface ppp-client get $ifRes default-route-distance] + 1); /interface l2tp-client set $ifMain default-route-distance=$routeDist; /interface enable $ifMain; set $state 2; log info "$scriptName: state changed 1->2"; }
if ($state = 2) do= { do { if ( [len [interface find where name=$ifMain and running] ] = 1) do= { set $pingRes [ping ($ip->0) src-address=$pingSrcAddr count=2]; set $pingRes ($pingRes+[ping ($ip->1) src-address=$pingSrcAddr count=2]); set $pingRes ($pingRes+[ping ($ip->2) src-address=$pingSrcAddr count=2]); if ($pingRes > 0) do= { set $state 3; log info "$scriptName: state changed 2->3"; } } if ($state = 2) do= { delay 15 }; } while ($state = 2); }
/ip firewall mangle add action=mark-routing chain=output comment=Failover_script_rule \ dst-address=!192.168.xx.0/24 new-routing-mark=to_ISP1 passthrough=no \ protocol=icmp src-address=192.168.xx.yy /ip route rule add action=lookup-only-in-table routing-mark=to_ISP1 src-address=\ 192.168.xx.yy/32 table=to_ISP1
if ($state = 3) do= { /interface disable $ifRes; set $routeDist ([/interface l2tp-client get $ifMain default-route-distance] + 1); /interface ppp-client set $ifRes default-route-distance=$routeDist; set $state 0; set $FailoverLastBackTime "$[/system clock get date] $[/system clock get time]"; log info "$scriptName: state changed 3->0"; beep frequency=500 length=500ms; }
set $routeDist [/interface l2tp-client get $ifMain default-route-distance]; set $routeDist2 [/interface ppp-client get $ifRes default-route-distance]; if ($routeDist < $routeDist2) do= { if ( [/interface get $ifMain running] = true) do= { set $state 0; } else= { set $state 1; } } else= { if ( [/interface get $ifMain disabled] = true) do= { /interface enable $ifMain; } if ($routeDist > $routeDist2 and [/interface get $ifRes disabled] = false) do= { set $state 2; } else= { set $state 3; } } log info "$scriptName: initial state $state";
if ($state = 2) do= { do { if (([ping DNSip1 count=1] > 0) or ([ping DNSip2 count=1] > 0)) do= { set $tmp 0; do { resolve VPNaddress server=DNSip1; } on-error= { }; do { resolve VPNaddress server=DNSip2; } on-error= { }; do { resolve VPNaddress } on-error= { set $tmp 1; }; if ($tmp = 0) do= { set $state 3; log info "$scriptName: state changed 2->3"; delay 5; } } if ($state = 2) do= { delay 15 }; } while ($state = 2); }
global FailoverDisabled; if ( [len [/system script job find where script="Failover"]] = 0 and $FailoverDisabled != 1) do= { do { execute script="Failover"; } on-error= { log info "$scriptName: Failed to execute Failover" }; }
global FailoverTimes; global FailoverLastTime; global FailoverLastBackTime; local ifMain "ISP1"; local ifRes "ISP2"; local scriptName "Failover"; local state 0; local pingNum 0; local pingRes; local routeDist; local routeDist2; local tmp; local ip { xxxx; yyyy; zzzz }; local pingSrcAddr 192.168.xx.yy; if ( [len [/system script job find where script=$scriptName]] > 1) do= { error "single instance" }; delay 15; set $routeDist [/interface l2tp-client get $ifMain default-route-distance]; set $routeDist2 [/interface ppp-client get $ifRes default-route-distance]; if ($routeDist < $routeDist2) do= { if ( [/interface get $ifMain running] = true) do= { set $state 0; } else= { set $state 1; } } else= { if ( [/interface get $ifMain disabled] = true) do= { /interface enable $ifMain; } if ($routeDist > $routeDist2 and [/interface get $ifRes disabled] = false) do= { set $state 2; } else= { set $state 3; } } log info "$scriptName: initial state $state"; do { if ($state = 0) do= { do { if ($pingNum >= 3) do= { set $pingNum 0; } if ([ping ($ip->$pingNum) count=1] = 0) do= { set $pingRes [ping ($ip->0) count=2]; set $pingRes ($pingRes+[ping ($ip->1) count=2]); set $pingRes ($pingRes+[ping ($ip->2) count=2]); if ($pingRes = 0) do= { set $FailoverLastTime "$[/system clock get date] $[/system clock get time]"; set $FailoverTimes ([tonum $FailoverTimes] + 1) set $state 1; log info "$scriptName: state changed 0->1"; } } set $pingNum ($pingNum + 1); if ($state = 0) do= { delay 15 }; } while ($state = 0); } # endof if state = 0 if ($state = 1) do= { if ( [/interface l2tp-client get $ifMain default-route-distance] > 10) do= { /interface ppp-client set $ifRes default-route-distance=1; } /interface enable $ifRes; beep frequency=2000 length=250ms; delay 500ms; beep frequency=2000 length=250ms; delay 500ms; delay 6; /interface disable $ifMain; set $routeDist ([/interface ppp-client get $ifRes default-route-distance] + 1); /interface l2tp-client set $ifMain default-route-distance=$routeDist; /interface enable $ifMain; set $state 2; log info "$scriptName: state changed 1->2"; } if ($state = 2) do= { do { if ( [len [interface find where name=$ifMain and running] ] = 1) do= { set $pingRes [ping ($ip->0) src-address=$pingSrcAddr count=2]; set $pingRes ($pingRes+[ping ($ip->1) src-address=$pingSrcAddr count=2]); set $pingRes ($pingRes+[ping ($ip->2) src-address=$pingSrcAddr count=2]); if ($pingRes > 0) do= { set $state 3; log info "$scriptName: state changed 2->3"; } } if ($state = 2) do= { delay 15 }; } while ($state = 2); } # endof if state = 2 if ($state = 3) do= { /interface disable $ifRes; set $routeDist ([/interface l2tp-client get $ifMain default-route-distance] + 1); /interface ppp-client set $ifRes default-route-distance=$routeDist; set $state 0; set $FailoverLastBackTime "$[/system clock get date] $[/system clock get time]"; log info "$scriptName: state changed 3->0"; beep frequency=500 length=500ms; } # bad programming protection delay 1; } while= ( true );
Source: https://habr.com/ru/post/252729/
All Articles