You are on page 1of 3

#:log info "Inicio failover para router con 4 ISPs";

:global ispsCaidosAnt;

# Variable isps
# Cada elemento está compuesto por un par de números,
# el primero indica el ID del ISP y el segundo la cantidad de pasos
# asignados al ISP
# {{ID:nPasos}; {ID:nPasos}};
#
# Ejemplos:
# Si el ISP1 tiene 20Mbps y los otros 3 10Mbps entonces la cantidad de
# pasos para el ISP1 son 2 pasos y la variable isps quedaria:
# :local isps {{1;2}; {2;1}; {3;1}; {4;1} };
#
# Si el ISP1 e ISP3 tienen 30 Mbps cada uno y los demás tienen 10Mbps,
# la variable isps quedaria:
# :local isps {{1;3}; {2;1}; {3;3}; {4;1} };
#
# Si el ISP1 tiene 50Mbps, el ISP3 tiene 20Mbps y los otros tienen 10Mbps
# la variable isps quedaria:
# :local isps {{1;5}; {2;1}; {3;2}; {4;1} };
#
# La declaración por default de la variable isps toma en cuenta que todos
# los ISPs tienen la misma capacidad, sin importar qué capacidad tengan
#
:local isps {{1;1}; {2;1}; {3;1}; {4;1} };
:local pasos 0;
:local ispsCaidos;

# Cantidad de pruebas ping que se lanzaran a la IP externa para determinar si


# el ISP está caido
:local nPruebasPing 5;

# IP de DNS a donde se lanzan las pruebas de ping


# En este caso se usa una IP de OpenDNS
:local ipExterna "208.67.222.222";

# Inicialización de los ISP caidos anteriormente


:if ([:typeof $ispsCaidosAnt]="nothing") do={ :set ispsCaidosAnt {nil}; }

# Inicialización de los ISPs caidos


:if ([:typeof $ispsCaidos]="nothing") do={ :set ispsCaidos {nil}; }

# Proceso de pruebas de conexión a internet por los distintos ISPs


:foreach isp in=[$isps] do={
#:log info ($isp->1);
:local indiceIsp ($isp->0);

:local rping [/ping $ipExterna routing-table="to_ISP$indiceIsp"


count=$nPruebasPing];

# Si la respuesta de ping fue 0, entonces el ISP está caido y se agrega a la


lista de ispsCaidos
:if ($rping=0) do={
:set ($ispsCaidos->"$indiceIsp") $indiceIsp;
:log info "ISP$indiceIsp caido";
}
}

# Compara los ISPs caidos actualmente contra los ISPs caidos previamente
# Si son iguales evita ejecutar por completo el script
:if ( $ispsCaidos = $ispsCaidosAnt) do={
:exit;
}
# Si son diferentes, se actualizan los ispsCaidosAnt
:if ( $ispsCaidos != $ispsCaidosAnt ) do={
:set ispsCaidosAnt ($ispsCaidos);
}

# Cálculo de los pasos totales


:foreach isp in=[$isps] do={
:local estaCaido false;

:foreach ispCaido in=[$ispsCaidos] do={


:if ($isp->0=$ispCaido) do={
:set estaCaido true;
}
}

:if ($estaCaido=false) do={


:set pasos ($pasos + ($isp->1));
}
}
#:log info $pasos;

# Desactivacion de las mark_connection de ISPs caidos


:foreach isp in=[$ispsCaidos] do={
/ip firewall mangle disable [find new-connection-mark="ISP$isp_conn" and per-
connection-classifier~"both-addresses"];
}

# Actualización de los pasos en función de los ISPs activos


:local pasosTmp 0;
:foreach isp in=[$isps] do={
:local estaCaido false;
:local idIsp ($isp->0);

:foreach ispCaido in=[$ispsCaidos] do={


:if (($isp->0)=$ispCaido) do={
:set estaCaido true;
}
}

# Si el ISP no está caido se procede a actualizar las reglas con los "pasos"
correctos
:if ($estaCaido=false) do={
# Desactivar las reglas del ISP activo para hacer la actualizacion
/ip firewall mangle disable [find new-connection-mark="ISP$idIsp_conn" and per-
connection-classifier~"both-addresses"];

# Obtención de los IDs de las reglas del ISP con new-connection-mark


:local idsReglas [/ip firewall mangle find new-connection-mark="ISP$idIsp_conn"
and per-connection-classifier~"both-addresses"];

# Por cada ID de la regla se procede a asignar el total de pasos y el número de


paso correspondiente
:foreach idRegla in=[$idsReglas] do={
/ip firewall mangle set [find .id=$idRegla] per-connection-classifier="both-
addresses:$pasos/$pasosTmp"

#Incremento del contador de pasosTmp


:set pasosTmp ($pasosTmp + 1);
}

# Activación de las reglas del ISP activo


/ip firewall mangle enable [find new-connection-mark="ISP$idIsp_conn" and per-
connection-classifier~"both-addresses"];
}
}

#:log info "Fin failover-script";

You might also like