Skip to content

OSPF Advanced Configuration

This guide covers four advanced OSPF configuration topics in RouterOS 7: virtual links for areas without direct backbone connectivity, area ranges for inter-area route summarization, route redistribution from connected/static/BGP sources, and routing filters that control which routes enter or leave the OSPF domain.

All examples use RouterOS 7 syntax. RouterOS 7 uses /routing ospf interface-template for interface assignment; the legacy /routing ospf interface and /routing ospf network menus from RouterOS 6 are not used here.


A virtual link is a logical OSPF link through a transit area that provides backbone connectivity for an area that cannot physically connect to Area 0. Virtual links are also used to repair a partitioned backbone when the backbone loses connectivity between two segments.

OSPF requires all non-backbone areas to connect directly to the backbone (Area 0). Two situations arise where this is not possible:

  1. Area without direct backbone attachment — a new area is added to the network and can only reach the backbone through an intermediate (transit) area.
  2. Partitioned backbone — Area 0 loses physical continuity, splitting into two disconnected segments. A virtual link through an adjacent area reconnects the backbone.
Area 0 (backbone)
┌─────────────────────────────────────────┐
│ │
R1 (1.1.1.1) R3 (3.3.3.3)
│ │
│ Area 2 (transit area) │
R1 ─── ether2 ─── Area2 ─── ether1 ─── R2 (2.2.2.2)
Area 3 (remote)
needs backbone access

In this diagram, R2 connects Area 3 but has no direct link to Area 0. A virtual link through Area 2 between R1 and R2 gives R2 logical backbone connectivity.

In RouterOS 7, virtual links are configured as interface-template entries with type=virtual-link. Each end of the virtual link requires:

  • type=virtual-link — marks this template as a virtual link endpoint
  • vlink-transit-area — the intermediate area the virtual link traverses
  • vlink-neighbor-id — the router ID of the remote ABR at the other end
  • area — must be the backbone area (backbone), since virtual links extend the backbone

Both ABRs must configure the virtual link pointing at each other.

R1 (backbone-connected ABR, router-id 1.1.1.1):

/routing ospf instance
add name=ospf1 version=2 router-id=1.1.1.1
/routing ospf area
add name=backbone area-id=0.0.0.0 instance=ospf1
add name=area2 area-id=0.0.0.2 instance=ospf1
/routing ospf interface-template
add interfaces=ether1 area=backbone network-type=point-to-point # backbone link
add interfaces=ether2 area=area2 # transit area link
# Virtual link to R2 through Area 2
add type=virtual-link area=backbone vlink-transit-area=area2 vlink-neighbor-id=2.2.2.2

R2 (remote ABR, router-id 2.2.2.2):

/routing ospf instance
add name=ospf1 version=2 router-id=2.2.2.2
/routing ospf area
add name=backbone area-id=0.0.0.0 instance=ospf1
add name=area2 area-id=0.0.0.2 instance=ospf1
add name=area3 area-id=0.0.0.3 instance=ospf1
/routing ospf interface-template
add interfaces=ether1 area=area2 # transit area link to R1
add interfaces=ether2 area=area3 # remote area link
# Virtual link to R1 through Area 2
add type=virtual-link area=backbone vlink-transit-area=area2 vlink-neighbor-id=1.1.1.1

Virtual links have specific constraints that differ from physical OSPF links:

  • The transit area must be a standard area — stub, totally stubby, and NSSA areas cannot be used as transit areas.
  • Both endpoints must have full OSPF connectivity through the transit area before the virtual link can form.
  • Virtual link timers (hello and dead intervals) must match between the two endpoints.
  • Authentication must be configured consistently on both virtual link endpoints if the backbone area uses authentication.
# Check virtual link neighbor state (should reach FULL)
/routing ospf neighbor print
# View virtual link details including transit area and neighbor router-id
/routing ospf interface-template print detail where type=virtual-link
# Verify backbone connectivity has been restored (look for area 0 LSAs)
/routing ospf lsa print where area=backbone
# Check that Area 3 routes appear in the routing table on R1
/ip route print where ospf~"."

A healthy virtual link shows the neighbor in Full state in /routing ospf neighbor print. If the neighbor is absent or stuck in Init, verify:

  1. The transit area has physical OSPF adjacencies between R1 and R2.
  2. Both sides specify the same vlink-transit-area and each points vlink-neighbor-id at the other router’s router-id.
  3. Firewall rules permit IP protocol 89 on the transit area interfaces.

If the backbone area uses MD5 authentication, the virtual link must also authenticate. Authentication is configured on the interface-template entry for the virtual link:

/routing ospf interface-template
add type=virtual-link area=backbone vlink-transit-area=area2 vlink-neighbor-id=2.2.2.2 \
authentication=md5 auth-key=SecretKey auth-key-id=1

Both ABRs must use matching auth-key and auth-key-id values.

Virtual links are a workaround for topological constraints, not a design goal. They increase troubleshooting complexity, add a dependency on transit area stability, and can behave unexpectedly during reconvergence. Prefer resolving connectivity issues by adding a physical backbone link. Use virtual links only when:

  • Physical links to Area 0 are not feasible.
  • The backbone has partitioned temporarily and needs immediate repair pending a physical fix.

Area ranges configure an ABR to aggregate multiple routes from one area into a single summary advertisement, reducing LSDB size and dampening topology change propagation. For area type details including stub and NSSA configurations, see OSPF Area Types.


Route redistribution introduces external routes into the OSPF domain. For complete coverage of connected/static/BGP redistribution, metric types, default route origination, NSSA ASBR configuration, and filtering, see OSPF Route Redistribution.


RouterOS 7 OSPF filtering uses the same /routing filter rule syntax as other routing protocols. Filters attach to the OSPF instance and are evaluated on a per-route basis.

Filter parameterDirectionEffect
in-filter-chainInbound (import)Applied to OSPF-learned routes before installation into the routing table
out-filter-chainOutbound (export/redistribution)Applied to routes being redistributed into OSPF as external LSAs

Inbound filtering controls which OSPF-learned routes are accepted into the local routing table. This does not affect LSA propagation — the routes still exist in the LSDB and propagate to other routers. The filter only affects whether this router installs the route locally.

Attach the filter via in-filter-chain:

/routing ospf instance
set ospf1 in-filter-chain=ospf-import

Filter rules are evaluated top-to-bottom. Routes that match no accept rule are implicitly rejected. Always include an explicit accept at the end unless you intend to reject all unmatched routes.

/routing filter rule
add chain=ospf-import rule="if (dst == 192.168.50.0/24) { reject }"
add chain=ospf-import rule="accept"
/routing ospf instance
set ospf1 in-filter-chain=ospf-import

Block More-Specific Routes Beyond a Prefix Length

Section titled “Block More-Specific Routes Beyond a Prefix Length”

Prevents overly long prefixes from entering the routing table while allowing aggregates:

/routing filter rule
# Accept the aggregate but reject anything more specific than /24
add chain=ospf-import rule="if (dst in 10.20.0.0/16 && dst-len > 24) { reject }"
add chain=ospf-import rule="accept"

Multiple Prefix Blocks (Prefix-List Style)

Section titled “Multiple Prefix Blocks (Prefix-List Style)”

RouterOS 7 does not have a dedicated ip prefix-list object. Implement the equivalent using sequential filter rules in a single chain:

/routing filter rule
# Block specific prefixes
add chain=ospf-import rule="if (dst == 172.16.10.0/24) { reject }"
add chain=ospf-import rule="if (dst == 172.16.11.0/24) { reject }"
# Block host routes from OSPF (common with leaked connected routes)
add chain=ospf-import rule="if (dst in 172.16.0.0/16 && dst-len >= 30) { reject }"
# Accept everything else
add chain=ospf-import rule="accept"

Filter rules can match on OSPF-specific attributes:

PropertyValuesDescription
ospf-typeintra, inter, ext1, ext2Route category
ospf-metricintegerOSPF metric of the route
ospf-tagintegerExternal route tag
/routing filter rule
# Block all type-2 external routes from a specific prefix
add chain=ospf-import rule="if (dst in 203.0.113.0/24 && ospf-type ext2) { reject }"
# Block all inter-area routes from a distrusted range
add chain=ospf-import rule="if (ospf-type inter && dst in 10.99.0.0/16) { reject }"
# Accept all intra-area and inter-area routes; reject uncontrolled externals
add chain=ospf-import rule="if (ospf-type == intra || ospf-type == inter) { accept }"
add chain=ospf-import rule="reject"

Outbound filters control which routes are redistributed into OSPF as external LSAs. These are described in detail in the redistribution section above and in OSPF Route Redistribution.

/routing ospf instance
set ospf1 redistribute=connected,static,bgp out-filter-chain=ospf-ext-out

When a filter rejects routes unexpectedly, add a log action before the reject rule to identify which routes are hitting it:

/routing filter rule
# Insert before the reject: log and pass through for inspection
add chain=ospf-import rule="log ospf-debug; passthrough" place-before=0
/log print where topics~"ospf-debug"

Remove the log rule after debugging.

To verify which filter chains are attached to the instance:

/routing ospf instance print detail

Section titled “Complete Example: Multi-Area Network with Virtual Link and Filtering”

This example combines the topics above: a three-area network with a remote area connected via virtual link, route redistribution with filtering, and import policy.

Internet
R1 (1.1.1.1) ── Area 0 ── R2 (2.2.2.2)
│ │
Area 1 (stub) Area 2 (transit)
R3 (3.3.3.3)
Area 3 (remote — virtual link to R1 through Area 2)

R1 — backbone + stub ABR + internet edge (ASBR):

/routing ospf instance
add name=ospf1 version=2 router-id=1.1.1.1 \
redistribute=connected \
out-filter-chain=edge-out \
distribute-default=if-installed-as-type2 \
in-filter-chain=ospf-import
/routing ospf area
add name=backbone area-id=0.0.0.0 instance=ospf1
add name=area1 area-id=0.0.0.1 instance=ospf1 type=stub
add name=area2 area-id=0.0.0.2 instance=ospf1
/routing ospf interface-template
add interfaces=ether1 area=backbone network-type=point-to-point # to R2
add interfaces=ether2 area=area1 # stub branch
add interfaces=ether3 area=area2 network-type=point-to-point # transit to R3
add interfaces=lo0 area=backbone passive=yes
# Virtual link to R3 through Area 2
add type=virtual-link area=backbone vlink-transit-area=area2 vlink-neighbor-id=3.3.3.3
/routing ospf area range
add area=area1 range=10.1.0.0/16 advertise=yes
/routing filter rule
# Redistribute only loopback
add chain=edge-out rule="if (protocol connected && dst-len == 32) { \
set ospf-ext-type type2; set ospf-ext-metric 10; accept }"
add chain=edge-out rule="reject"
# Import: block host routes from entering routing table
add chain=ospf-import rule="if (dst-len == 32 && ospf-type ext2) { reject }"
add chain=ospf-import rule="accept"

R3 — remote ABR, Area 3 + virtual link to backbone through Area 2:

/routing ospf instance
add name=ospf1 version=2 router-id=3.3.3.3 \
redistribute=connected \
out-filter-chain=r3-out
/routing ospf area
add name=backbone area-id=0.0.0.0 instance=ospf1
add name=area2 area-id=0.0.0.2 instance=ospf1
add name=area3 area-id=0.0.0.3 instance=ospf1
/routing ospf interface-template
add interfaces=ether1 area=area2 network-type=point-to-point # transit to R1
add interfaces=ether2 area=area3 # remote area link
# Virtual link back to R1 through Area 2
add type=virtual-link area=backbone vlink-transit-area=area2 vlink-neighbor-id=1.1.1.1
/routing ospf area range
add area=area3 range=10.3.0.0/16 advertise=yes
/routing filter rule
add chain=r3-out rule="if (protocol connected && dst in 10.3.0.0/16) { \
set ospf-ext-type type2; set ospf-ext-metric 20; accept }"
add chain=r3-out rule="reject"

# Check virtual link template exists on both ABRs
/routing ospf interface-template print detail where type=virtual-link
# Verify the transit area has OSPF adjacency between the two ABRs
/routing ospf neighbor print
# Confirm router-IDs match vlink-neighbor-id values
/routing ospf instance print detail

Common causes:

  • The transit area is a stub or NSSA — change it to a standard area.
  • vlink-neighbor-id does not match the remote router’s router-id.
  • No physical OSPF adjacency through the transit area yet (the virtual link depends on transit area reachability).
  • Firewall blocking protocol 89 on the transit area interfaces.
# Verify this router is an ABR (has interfaces in multiple areas)
/routing ospf interface-template print
# Check that the range covers the actual prefixes
/routing ospf area range print
/ip route print where ospf~"."

Area ranges only apply on ABRs. If all interfaces are in a single area, the range has no effect.

Routing Filter Rejecting Unexpected Routes

Section titled “Routing Filter Rejecting Unexpected Routes”
# View filter rules in the import chain
/routing filter rule print where chain=ospf-import
# Add temporary log rule to identify routes hitting the filter
/routing filter rule add chain=ospf-import rule="log ospf-debug; passthrough" place-before=0
/log print where topics~"ospf-debug"
# Confirm redistribute and filter chain settings
/routing ospf instance print detail
# Verify the filter chain has an accept rule for the intended protocols
/routing filter rule print where chain=ospf-ext-out
# Temporarily remove filter to confirm redistribution itself works
/routing ospf instance set ospf1 out-filter-chain=""
/routing ospf lsa print where type=external

  • OSPF — Fundamentals, LSA types, neighbor states, authentication
  • OSPF Area Types — Stub, totally stubby, NSSA, and interface-template area assignment
  • OSPF Configuration — Multi-area setup and DR/BDR election
  • OSPF Route Redistribution — Detailed redistribution guide with NSSA ASBR, default route, and loop prevention
  • Route Filters — Routing filter rule syntax and available matchers