Skip to main content

Recursive routing in RouterOS 6 vs 7

Recursive routing allows you to create a route with a defined next hop that is not actually directly adjacent to the router.

The working example configurations below assume three distinct Internet connections from three different providers. Each connection is serviced by a provider supplied modem/router combo CPE device running NAT with 192.168.1/2/3.1 IP addresses on the respective LAN interfaces, meaning if the Internet connection in front of any one modem fails, the Mikrotik router connected behind the provider CPE device will still be able to ping its immediate default gateway of 192.168.1/2/3.1. This is where recursive lookups come in.

RouterOS 6 working example configuration

ROSv6 does not enforce the rules related to scope and target-scope for rules that use recursive lookups. This is important to note when upgrading from ROSv6 to v7 as those rules will no longer work after the upgrade, until you fix the target-scopes.


RouterOS 7 working example configuration

ROSv7 adds a slight bit of complexity as it actually enforces some rules related to scope and target-scope that ROSv6 did not.

/routing table
add fib name=isp1
add fib name=isp2
add fib name=isp3

/ip/route

#
# recursive lookup entries
#
add disabled=no distance=1 dst-address=1.1.1.1/32         gateway=192.168.1.1 routing-table=main scope=10 target-scope=10 comment="STATIC ROUTE FOR RECURSIVE ROUTING - via isp1 - Cloudflare primary   DNS server"
add disabled=no distance=1 dst-address=1.0.0.1/32         gateway=192.168.2.1 routing-table=main scope=10 target-scope=10 comment="STATIC ROUTE FOR RECURSIVE ROUTING - via isp2 - Cloudflare secondary DNS server"

add disabled=no distance=1 dst-address=8.8.8.8/32         gateway=192.168.1.1 routing-table=main scope=10 target-scope=10 comment="STATIC ROUTE FOR RECURSIVE ROUTING - via isp1 - Google primary   DNS server"
add disabled=no distance=1 dst-address=8.8.4.4/32         gateway=192.168.2.1 routing-table=main scope=10 target-scope=10 comment="STATIC ROUTE FOR RECURSIVE ROUTING - via isp2 - Google secondary DNS server"
add disabled=no distance=1 dst-address=4.2.2.2/32         gateway=192.168.3.1 routing-table=main scope=10 target-scope=10 comment="STATIC ROUTE FOR RECURSIVE ROUTING - via isp3 - Google tertiary  DNS server"

add disabled=no distance=1 dst-address=9.9.9.9/32         gateway=192.168.1.1 routing-table=main scope=10 target-scope=10 comment="STATIC ROUTE FOR RECURSIVE ROUTING - via isp1 - Quad9 primary   DNS server"
add disabled=no distance=1 dst-address=149.112.112.112/32 gateway=192.168.2.1 routing-table=main scope=10 target-scope=10 comment="STATIC ROUTE FOR RECURSIVE ROUTING - via isp2 - Quad9 secondary DNS server"
add disabled=no distance=1 dst-address=9.9.9.11/32        gateway=192.168.3.1 routing-table=main scope=10 target-scope=10 comment="STATIC ROUTE FOR RECURSIVE ROUTING - via isp3 - Quad9 primary   EDNS server"
add disabled=no distance=1 dst-address=149.112.112.11/32  gateway=192.168.3.1 routing-table=main scope=10 target-scope=10 comment="STATIC ROUTE FOR RECURSIVE ROUTING - via isp3 - Quad9 secondary EDNS server"

add disabled=no distance=1 dst-address=68.94.156.1/32     gateway=192.168.3.1 routing-table=main scope=10 target-scope=10 comment="STATIC ROUTE FOR RECURSIVE ROUTING - via isp3 - AT&T primary DNS server"
add disabled=no distance=1 dst-address=68.94.157.1/32     gateway=192.168.3.1 routing-table=main scope=10 target-scope=10 comment="STATIC ROUTE FOR RECURSIVE ROUTING - via isp3 - AT&T primary DNS server"


#
# default routes using various recursive lookup entries as the gateway
#
add check-gateway=ping dst-address=0.0.0.0/0 gateway=1.1.1.1 routing-table=main distance=1 scope=30 target-scope=11 comment="default gateway via isp1 using recursive lookup"
add check-gateway=ping dst-address=0.0.0.0/0 gateway=8.8.8.8 routing-table=main distance=2 scope=30 target-scope=11 comment="default gateway via isp1 using recursive lookup"
add check-gateway=ping dst-address=0.0.0.0/0 gateway=9.9.9.9 routing-table=main distance=3 scope=30 target-scope=11 comment="default gateway via isp1 using recursive lookup"

add check-gateway=ping dst-address=0.0.0.0/0 gateway=1.0.0.1         routing-table=main distance=4 scope=30 target-scope=11 comment="default gateway via isp2 using recursive lookup"
add check-gateway=ping dst-address=0.0.0.0/0 gateway=8.8.4.4         routing-table=main distance=5 scope=30 target-scope=11 comment="default gateway via isp2 using recursive lookup"
add check-gateway=ping dst-address=0.0.0.0/0 gateway=149.112.112.112 routing-table=main distance=6 scope=30 target-scope=11 comment="default gateway via isp2 using recursive lookup"

add check-gateway=ping dst-address=0.0.0.0/0 gateway=68.94.156.1 routing-table=main distance=7 scope=30 target-scope=11 comment="default gateway via isp3 using recursive lookup"
add check-gateway=ping dst-address=0.0.0.0/0 gateway=68.94.157.1 routing-table=main distance=8 scope=30 target-scope=11 comment="default gateway via isp3 using recursive lookup"
add check-gateway=ping dst-address=0.0.0.0/0 gateway=4.2.2.2.2   routing-table=main distance=9 scope=30 target-scope=11 comment="default gateway via isp3 using recursive lookup"

#
# default routes using actual next hops - no outage detection will occur unless the physical Ethernet interface is disconnect
# having distances above 200 allows learned routes via OSPF (110) and BGP (200) to be used before these are
#
add check-gateway=none dst-address=0.0.0.0/0 gateway=192.168.1.1 routing-table=main distance=201 scope=30 target-scope=10 comment="default gateway via isp using actual next hop - no failover unless Ethernet is disconnected"
add check-gateway=none dst-address=0.0.0.0/0 gateway=192.168.2.1 routing-table=main distance=202 scope=30 target-scope=10 comment="default gateway via isp using actual next hop - no failover unless Ethernet is disconnected"
add check-gateway=none dst-address=0.0.0.0/0 gateway=192.168.3.1 routing-table=main distance=203 scope=30 target-scope=10 comment="default gateway via isp using actual next hop - no failover unless Ethernet is disconnected"