Mutual Route Redistribution Loop Prevention: The Loop Lives in the Routing Table, Not in Either Protocol
Mutual redistribution at a single router is safe. Mutual redistribution at two routers is where networks break, and the mechanism is not subtle once you see it: a route leaves its home protocol at one boundary, travels through the second protocol, arrives back at the other boundary, and is redistributed home again — now carrying a different administrative distance. If that distance is better than the one the route natively has, a router prefers the copy that came the long way round, points at a next hop in the wrong direction, and the traffic loops.
The reason this catches experienced engineers is that the loop does not involve either protocol malfunctioning. EIGRP's DUAL is loop-free, OSPF's SPF is loop-free, and both are working correctly on their own routes. The loop lives in the routing table, between the protocols, in the administrative-distance comparison that decides which of two correct answers to install. Neither protocol can see the other's copy of the route as anything other than a legitimate advertisement from a neighbour, because from the protocol's perspective that is exactly what it is.
This article builds the loop deliberately and then removes it. Section one lays out the topology and shows the failure. Section two walks the administrative distances step by step so the mechanism is unambiguous. Section three implements route tagging, which is the answer that scales. Section four covers the alternatives — prefix filtering and distance manipulation — and when each is defensible. Section five is verification: how to prove the loop is gone rather than currently dormant.

What Does the Lab Topology Look Like and Why Does It Loop?
What is the minimum configuration that fails?
Two routers, R1 and R2, each connected to both an EIGRP domain and an OSPF domain, each configured to redistribute in both directions with no filtering. R3 originates 10.5.0.0/16 in EIGRP. R5 lives in OSPF. Every statement is individually correct and the reachability test passes on the first try, which is precisely why the configuration ships. The failure appears later — sometimes immediately, sometimes only when a link fails and the metrics shift — and it appears as traffic taking an absurd path or not arriving at all. What makes it hard to attribute is that the change which exposes it is usually unrelated to redistribution — a link failure, a metric adjustment, a new prefix — so the investigation starts somewhere other than the boundary routers.
A Deeper Dive into the Failing Configuration
The configuration that produces the loop
! ===== R1: mutual redistribution, no tags, no filters =====
router ospf 1
redistribute eigrp 100 metric 20 subnets
network 10.0.1.0 0.0.0.255 area 0
!
router eigrp CORP
address-family ipv4 unicast autonomous-system 100
topology base
redistribute ospf 1 metric 1000000 100 255 1 1500
exit-af-topology
network 10.1.0.0 0.0.255.255
exit-address-family
!
! ===== R2: identical. That is the whole problem. =====
router ospf 1
redistribute eigrp 100 metric 20 subnets
network 10.0.2.0 0.0.0.255 area 0
!
router eigrp CORP
address-family ipv4 unicast autonomous-system 100
topology base
redistribute ospf 1 metric 1000000 100 255 1 1500
exit-af-topology
network 10.2.0.0 0.0.255.255
exit-address-family
What the failure looks like
! On R1, a prefix that originated in EIGRP two hops away
R1# show ip route 10.5.0.0
Routing entry for 10.5.0.0/16
Known via "ospf 1", distance 110, metric 20, type extern 2
Last update from 10.0.1.2 on GigabitEthernet0/1
* 10.0.1.2, from 10.0.2.1, 00:02:14 ago, via GigabitEthernet0/1
! ^ R1 is pointing INTO OSPF for a prefix that lives in EIGRP
! behind it. The EIGRP path is still there but lost at AD 170.
!
! The traceroute makes it obvious
R1# traceroute 10.5.0.1
1 10.0.1.2 [OSPF core] 1 msec
2 10.0.2.1 [R2] 1 msec
3 10.1.0.1 [R1] 2 msec
4 10.0.1.2 2 msec
5 10.0.2.1 3 msec
! ^ R1 and R2 handing the packet back and forth until TTL expires.
Why the reachability test passed
Immediately after configuration, R1 typically still has the native EIGRP route, because the redistributed copy has not completed its round trip yet. A ping from R1 succeeds, the change is marked complete, and the loop forms seconds or minutes later when the OSPF external LSA propagates back and the distance comparison runs again. A test performed within the first few seconds of a mutual redistribution proves nothing at all. Waiting for the second protocol to converge fully — which on OSPF means the external LSA reaching every router and the SPF running everywhere — before testing is the difference between a verification and a coincidence.
show running-config | include redistribute across all boundary routers; more than one router redistributing in both directions between the same protocol pair, with no route-map, is the finding. Fix: apply the tag scheme to every boundary including the original one. The original router's configuration is now wrong even though it has not changed, which is why "we did not touch it" is not evidence that it is still correct.How Does Administrative Distance Create the Loop?
What is the exact sequence?
A prefix originates in protocol A and is known at both boundary routers with A's native distance. R1 redistributes it into protocol B, where it becomes an external route with B's external distance. That copy propagates through B and reaches R2, which redistributes it back into A as an A-external route with A's external distance. R1 now holds two entries for the prefix: the original from A at A's internal distance, and the copy from B at B's distance. If B's distance is lower, R1 installs the copy — whose next hop points into B, away from the prefix's actual location — and the packet is handed back and forth between R1 and R2.
A Deeper Dive into the Distance Mechanics
The distances that decide it
| Route source | Administrative distance | Beats | Loses to |
|---|---|---|---|
| Connected | 0 | Everything | Nothing |
| Static | 1 | All dynamic protocols | Connected |
| eBGP | 20 | All IGPs | Static, connected |
| EIGRP internal | 90 | OSPF, IS-IS, RIP, EIGRP external | eBGP, static, connected |
| OSPF (internal and external alike) | 110 | IS-IS, RIP, EIGRP external | EIGRP internal, eBGP |
| IS-IS | 115 | RIP, EIGRP external | OSPF, EIGRP internal |
| RIP | 120 | EIGRP external | OSPF, IS-IS, EIGRP internal |
| EIGRP external | 170 | iBGP only | Everything else |
| iBGP / local BGP | 200 | Nothing | Everything |
The row that matters is EIGRP external at 170. OSPF does not distinguish internal from external in its distance — both are 110 — so an OSPF copy of an EIGRP-originated route always beats the EIGRP external copy coming back, and frequently beats nothing else because the original EIGRP internal route at 90 is still better. The loop forms specifically where the original is not present at 90 on the router making the decision.
The case where it bites hardest
Consider a prefix that was itself redistributed into EIGRP from somewhere else — a static route, a connected interface on a third router, another protocol. It exists in EIGRP as an external route at distance 170. Now the OSPF copy returning at 110 beats it everywhere, including on the router that originally injected it, and every router in the EIGRP domain prefers the path through OSPF. That is not merely suboptimal; on the injecting router it is a loop.
! R3 redistributes a static into EIGRP - it is EIGRP EXTERNAL, AD 170
R3(config)# ip route 10.5.0.0 255.255.0.0 10.9.0.1
R3(config-router-af-topology)# redistribute static metric 1000000 100 255 1 1500
!
! On R3 the static still wins locally at AD 1, so R3 is fine.
R3# show ip route 10.5.0.0 | include Known via
Known via "static", distance 1
!
! But R1, which has no static, compares 170 against 110
R1# show ip route 10.5.0.0 | include Known via
Known via "ospf 1", distance 110
! ^ R1 prefers the OSPF copy of a prefix that reaches it through EIGRP.
! Every EIGRP router between R1 and R3 now points the wrong way.
Why split horizon does not help either
Split horizon prevents a protocol from advertising a route back out the interface it learned it on, which is real loop prevention within a protocol. It does nothing here because the route does not return by the same protocol — it leaves as EIGRP, comes back as OSPF, and the two protocols have no shared state that would let either recognise the other's copy as its own. The same reasoning applies to EIGRP's feasibility condition and OSPF's SPF: both guarantee loop freedom over the topology their own protocol computed, and neither has any visibility into a path that left and returned through a different one.
Why the metric does not save you
Administrative distance is compared before metric and across protocols; metric is compared only within a protocol. A redistributed route with an appalling metric still wins against a native route with an excellent one if its distance is lower. That is why setting a very high seed metric feels like it should help and does not — the comparison never reaches the metric.
! An enormous seed metric changes nothing about the outcome
router ospf 1
redistribute eigrp 100 metric 16777214 subnets
!
R1# show ip route 10.5.0.0
Known via "ospf 1", distance 110, metric 16777214, type extern 2
! ^ Still installed. AD 110 beat AD 170 before the metric mattered.
Suboptimal routing, which is the same problem without the loop
Not every distance inversion produces a loop. Where the returning copy wins on a router that is not in the return path, the result is a working but longer path — traffic that should have left through the nearby boundary crosses the network to the far one. This is more common than an outright loop and considerably harder to notice, because everything reaches its destination and only latency and link utilisation reveal it.
The cause is identical and so is the fix. A router preferring an external copy of a prefix it could reach natively is making the same wrong comparison; whether that produces a loop or merely a detour depends on where the router sits relative to the two boundaries. Treating suboptimal routing across a redistribution boundary as a symptom of the same problem, rather than as a separate tuning exercise, saves considerable time.
! R4 sits deep in EIGRP, two hops from R3 which originates the prefix
R4# show ip route 10.5.0.0
Known via "eigrp 100", distance 170, metric 3072000, type external
* 10.1.0.2, from 10.1.0.2, via GigabitEthernet0/1
! ^ AD 170 means this is the copy that came back through OSPF,
! not the native EIGRP route. No loop - R4 is not a boundary -
! but the path crosses the OSPF domain and returns.
!
R4# traceroute 10.5.0.1
1 10.1.0.2 [R2] 1 msec
2 10.0.2.2 [core] 2 msec
3 10.0.1.1 [R1] 3 msec
4 10.1.0.1 [R3] 4 msec
5 10.5.0.1 4 msec
! ^ Four hops through OSPF to reach something two hops away in EIGRP.
! It works. It is still the redistribution problem.
Protocol pairs and their risk
| Pair | Direction at risk | Why | Severity |
|---|---|---|---|
| EIGRP and OSPF | OSPF copy returning into EIGRP | 110 beats EIGRP external 170 | High — the classic case |
| EIGRP and RIP | RIP copy returning into EIGRP | 120 beats EIGRP external 170 | High |
| OSPF and RIP | OSPF copy returning into RIP | 110 beats RIP 120 | High |
| OSPF and IS-IS | OSPF copy returning into IS-IS | 110 beats IS-IS 115 | Moderate |
| Two OSPF processes | Either direction | Both are 110 — metric decides, unpredictably | High |
| Two EIGRP autonomous systems | Either direction | Both externals are 170 | High |
| IGP and BGP | Usually safe | iBGP 200 loses to every IGP | Low |
show ip route <prefix> on a boundary router shows ospf as the source for a prefix that should be reached through EIGRP; show ip eigrp topology <prefix> shows it present but not installed. Fix: tag on export and deny on import. Distance 90 protecting some prefixes is not protection; it is a partial failure that hides the problem until the exposed prefixes matter.How Do I Prevent It with Route Tags?
What is the tagging pattern?
On every redistribution point, in every direction: set a tag identifying the source protocol as the route leaves, and deny any route carrying that same tag as routes come back in. A route tagged 90 on its way from EIGRP into OSPF is, by definition, one that this network already had in EIGRP — so refusing to redistribute anything tagged 90 back into EIGRP closes the loop without needing to know which prefixes exist. The scheme scales because it is prefix-independent: adding a new subnet anywhere requires no change to the tagging configuration.
A Deeper Dive into Tag-Based Prevention
The complete configuration, both directions, both routers
! ===== Tag convention =====
! 90 = this route came from EIGRP
! 110 = this route came from OSPF
! Any value works; consistency across all boundary routers is
! what matters.
!
! ===== EIGRP -> OSPF =====
route-map EIGRP-TO-OSPF deny 10
match tag 110
! Refuse anything OSPF gave us in the first place
route-map EIGRP-TO-OSPF permit 20
set tag 90
!
! ===== OSPF -> EIGRP =====
route-map OSPF-TO-EIGRP deny 10
match tag 90
! Refuse anything EIGRP gave us in the first place
route-map OSPF-TO-EIGRP permit 20
set tag 110
! ===== Applied identically on R1 AND R2 =====
router ospf 1
redistribute eigrp 100 metric 20 metric-type 1 subnets route-map EIGRP-TO-OSPF
network 10.0.1.0 0.0.0.255 area 0
!
router eigrp CORP
address-family ipv4 unicast autonomous-system 100
topology base
redistribute ospf 1 metric 1000000 100 255 1 1500 route-map OSPF-TO-EIGRP
exit-af-topology
network 10.1.0.0 0.0.255.255
exit-address-family
! ^ Both routers, identical maps. A single untagged boundary
! reintroduces the loop for every prefix crossing it.
Why it works without knowing the prefixes
The tag is a statement about provenance rather than about identity. A route arriving in OSPF with tag 90 says "an EIGRP-to-OSPF boundary in this network put me here", and the only correct response at an OSPF-to-EIGRP boundary is to leave it alone — EIGRP already has it by a shorter path. That reasoning holds for every prefix, including ones created after the configuration was written, which is exactly what prefix-list filtering cannot offer.
! Verify the tag survives the transition
R5# show ip route 10.5.0.0
Known via "ospf 1", distance 110, metric 30, type extern 1
Tag 90
!
! And that the reverse direction refuses it
R2# show ip eigrp topology 10.5.0.0/16
! Present via EIGRP natively, NOT as a redistributed external.
!
! On R1, the native path wins again
R1# show ip route 10.5.0.0 | include Known via
Known via "eigrp 100", distance 90
Tag values and where they are carried
| Protocol | Tag width | Carried in | Survives redistribution |
|---|---|---|---|
| OSPF | 32 bits | External Route Tag in Type 5 and Type 7 LSAs | Yes |
| EIGRP | 32 bits | Administrator Tag in the external route TLV | Yes |
| IS-IS | 32 bits | Administrative tag sub-TLV | Yes |
| RIPv2 | 16 bits | Route Tag field | Yes, truncated to 16 bits |
| BGP | — | No native tag | Use a community and translate |
| Static | 32 bits | Set on the ip route statement |
Yes, once redistributed |
Designing the tag scheme
Two conventions are common and both work. The simplest uses the administrative distance of the source protocol as the tag value — 90 for EIGRP, 110 for OSPF, 120 for RIP — which is self-documenting and needs no lookup table. The more structured approach encodes the source protocol and the boundary router, so a route arriving with tag 90001 says "EIGRP, via boundary 1", which is useful in a network with several boundaries because it identifies which one leaked a route that should not have crossed.
Whichever you choose, two properties matter more than the values. Every boundary router uses the same values, because a mismatched tag at one boundary means the others do not recognise its routes. And the scheme is written down somewhere that survives the engineers, because a match tag 90 with no explanation is indistinguishable from a mistake and will eventually be removed by somebody tidying up.
! Convention A: tag = the source protocol's administrative distance
! 90 EIGRP 110 OSPF 115 IS-IS 120 RIP 200 BGP
! Self-documenting; no table needed.
!
! Convention B: source protocol and boundary identity
! 9001 = EIGRP via boundary 1 9002 = EIGRP via boundary 2
! 1101 = OSPF via boundary 1 1102 = OSPF via boundary 2
!
! Convention B lets you deny by source while still identifying
! which boundary a stray route came through
route-map OSPF-TO-EIGRP deny 10
match tag 9001 9002
route-map OSPF-TO-EIGRP permit 20
set tag 1101
!
! And makes an audit possible
R3# show ip route | include Tag 9002
! ^ Every route that crossed via boundary 2, listed.
The BGP exception
BGP carries no route tag, so a tag set on an IGP route is lost the moment it enters BGP and cannot be recovered on the way out. The equivalent is a community: set a community when redistributing into BGP, match that community when redistributing out. The translation has to be written explicitly in both directions, and forgetting one half produces exactly the loop the tag scheme was meant to prevent.
! IGP tag -> BGP community on the way in
route-map OSPF-TO-BGP deny 10
match community FROM-BGP
route-map OSPF-TO-BGP permit 20
set community 65000:110 additive
!
! BGP community -> IGP tag on the way out
route-map BGP-TO-OSPF deny 10
match community FROM-OSPF
route-map BGP-TO-OSPF permit 20
set tag 200
!
ip community-list standard FROM-OSPF permit 65000:110
ip community-list standard FROM-BGP permit 65000:200
What Are the Alternatives and When Are They Right?
What else can close the loop?
Two things, both inferior to tagging in the general case and both defensible in specific ones. Prefix filtering enumerates which prefixes may cross in each direction, which is exact and auditable and requires editing every time the address plan changes. Administrative distance manipulation raises the distance of the returning copy — or lowers the native route's — so the native path always wins the comparison, which is a single command and is fragile because it depends on distances staying as configured everywhere. A third option, which is not a workaround at all, is to remove the second redistribution point.
A Deeper Dive into the Alternatives
Prefix filtering
Listing what may cross is unambiguous and easy to review, and it is the right answer when the set is small, stable, and externally specified — a handful of prefixes that a contract or a security policy defines. It is the wrong answer in a growing network, because every new subnet requires a change on every boundary router and the failure mode of forgetting is either a missing route or a returning loop.
! Only these prefixes cross from EIGRP into OSPF
ip prefix-list EIGRP-ORIGINATED seq 5 permit 10.1.0.0/16 le 24
ip prefix-list EIGRP-ORIGINATED seq 10 permit 10.5.0.0/16 le 24
!
route-map EIGRP-TO-OSPF permit 10
match ip address prefix-list EIGRP-ORIGINATED
set tag 90
! implicit deny keeps everything else out
!
! And only these cross the other way
ip prefix-list OSPF-ORIGINATED seq 5 permit 10.2.0.0/16 le 24
!
route-map OSPF-TO-EIGRP permit 10
match ip address prefix-list OSPF-ORIGINATED
set tag 110
! ^ Correct today. Wrong the first time somebody adds a subnet.
Administrative distance manipulation
Raising the distance of the returning route above the native one makes the native path win. On OSPF the tool is distance ospf external; on EIGRP it is distance eigrp with separate internal and external values. It is one line and it works, and it is fragile: the change must be applied on every router that could receive the returning copy, not just the boundaries, and it silently changes the outcome of every other distance comparison involving that protocol.
! Make OSPF externals lose to EIGRP externals (170)
router ospf 1
distance ospf external 180
! ^ Now the returning OSPF copy at 180 loses to EIGRP's 170.
! It also loses to RIP at 120 and IS-IS at 115, which may or
! may not be what anybody wanted.
!
! Or per-source, which is narrower but harder to maintain
access-list 20 permit 10.5.0.0 0.0.255.255
router ospf 1
distance 180 10.0.2.1 0.0.0.0 20
! AD source-router wildcard acl
!
! EIGRP: internal and external distances are set together
router eigrp CORP
address-family ipv4 unicast autonomous-system 100
topology base
distance eigrp 90 175
exit-af-topology
exit-address-family
distance command that makes the native route win restores service in seconds, and that is worth a great deal at three in the morning. The mistake is leaving it there afterwards. Treat it as a tourniquet: apply it, restore service, then implement the tag scheme during the follow-up change and remove the distance command in the same window.Removing the second boundary
The option people skip. A second redistribution point exists for redundancy, and redundancy can often be provided differently: a summary route or a default from one domain to the other covers the failure of the single boundary without a second full redistribution. Where the second boundary exists because two sites each grew their own, consolidating is a design cleanup rather than a workaround, and it removes the problem rather than managing it.
! One boundary does full mutual redistribution
! R1 only:
router ospf 1
redistribute eigrp 100 metric 20 metric-type 1 subnets
!
! R2 provides a backup path with a summary, not redistribution
router eigrp CORP
address-family ipv4 unicast autonomous-system 100
af-interface GigabitEthernet0/1
summary-address 0.0.0.0 0.0.0.0
exit-af-interface
exit-address-family
! ^ EIGRP gets a default via R2 if R1 fails. No second
! redistribution point, therefore no loop to prevent.
The three compared
| Approach | Scales with new prefixes | Survives a topology change | Configuration burden | When it is right |
|---|---|---|---|---|
| Route tagging | Yes | Yes | Two route-maps per boundary | Almost always |
| Prefix filtering | No — edit every boundary | Yes | Grows with the address plan | Small, fixed, externally specified sets |
| Distance manipulation | Yes | No — depends on distances everywhere | One line, wide blast radius | A temporary fix during an incident |
| Single boundary | Yes | Yes | None — removes the problem | Where redundancy can come from a summary |
| Tagging plus filtering | Yes | Yes | Highest | Where a policy also constrains which prefixes cross |
distance command applied years ago to resolve a redistribution loop causes an unrelated routing anomaly after a new protocol is introduced, and nobody can explain why routes from that protocol are being ignored. Cause: administrative distance is global to the protocol on that router, so changing it to win one comparison changes the outcome of every other comparison involving that protocol — including ones that did not exist when the change was made. Confirm: show running-config | include distance on the affected routers, compared against the platform defaults. Fix: replace it with tag-based filtering, which affects only the redistribution it is attached to, and remove the distance command. Keep distance manipulation for incident response, where a single line that works immediately has real value.How Do I Verify the Loop Is Actually Gone?
What proves it rather than suggesting it?
Four checks. On each boundary router, confirm the native path won — show ip route for a sample prefix should name the protocol it actually originated in, not the other one. Confirm the tag is present on routes that crossed, because a missing tag means the route-map did not run. Confirm the reverse redistribution is refusing them, by checking that the destination protocol's database does not contain routes it originated. And traceroute across the boundary in both directions, because the routing table can look correct on each router individually while the forwarding path still alternates.
A Deeper Dive into Verification
Why the routing table alone is not enough
Each router's table can look entirely reasonable while the forwarding path still loops, because a loop is a property of the sequence of routers rather than of any one of them. R1 pointing at R2 is correct in isolation; R2 pointing back at R1 is also correct in isolation; the two together are the loop. That is why the verification sequence ends with a traceroute rather than with a routing table, and why checking only the router you happen to be logged into is the most common incomplete verification.
Check one: the native path won
! A prefix that originated in EIGRP, checked on both boundaries
R1# show ip route 10.5.0.0 | include Known via
Known via "eigrp 100", distance 90
R2# show ip route 10.5.0.0 | include Known via
Known via "eigrp 100", distance 90
! ^ Both boundaries prefer EIGRP for an EIGRP-native prefix.
!
! And a prefix that originated in OSPF
R1# show ip route 10.2.0.0 | include Known via
Known via "ospf 1", distance 110
Check two: tags are present and correct
! In OSPF, EIGRP-sourced prefixes carry tag 90
R5# show ip route 10.5.0.0 | include Tag
Tag 90
!
! In EIGRP, OSPF-sourced prefixes carry tag 110
R3# show ip route 10.2.0.0 | include Tag
Tag 110
!
! Anything with no tag crossed a boundary with no route-map
R5# show ip route ospf | include ^O E
! Cross-reference against the tagged set; an untagged external
! is a boundary somebody configured without the map.
Check three: the reverse direction is refusing
! EIGRP should NOT contain externals for its own prefixes
R2# show ip eigrp topology 10.5.0.0/16 | include External
! (no output - it is a native internal route, not an external)
!
! OSPF should NOT have external LSAs for OSPF-native prefixes
R1# show ip ospf database external | include 10.2.0.0
! (no output)
!
! Count the externals in each protocol and compare to expectation
R5# show ip route ospf | count ^O E
Number of lines which match regexp = 47
R3# show ip route eigrp | count ^D EX
Number of lines which match regexp = 31
! ^ 47 EIGRP-originated prefixes in OSPF, 31 OSPF-originated in
! EIGRP. If either number is close to the sum of both, routes
! are making the round trip and the tags are not working.
Check four: traceroute, both directions
! From the OSPF side into EIGRP
R5# traceroute 10.5.0.1
1 10.0.1.1 [R1] 1 msec
2 10.1.0.1 [R3] 2 msec
3 10.5.0.1 2 msec
! ^ Straight through. No router appears twice.
!
! And back
R3# traceroute 10.2.0.1
1 10.1.0.2 [R1] 1 msec
2 10.0.1.2 [core] 2 msec
3 10.2.0.1 2 msec
!
! The failure signature, for comparison
! 3 10.1.0.1 [R1]
! 4 10.0.1.2
! 5 10.0.2.1 [R2]
! 6 10.1.0.1 [R1] <- R1 appears twice = loop
Keeping it correct after the change
Tag schemes decay. A new boundary router is built from a template that predates the scheme; an engineer adds a redistribution during an incident and does not attach the map; a device is replaced and its configuration restored from a backup taken before the tags were added. Each of these reintroduces the problem for whatever crosses that boundary, and none of them produces an error at the time.
Two cheap audits catch it. A configuration check that every redistribute statement has a route-map attached finds the missing map directly. And a routing-table check for external routes carrying no tag finds routes that crossed a boundary without one, which is the same finding from the other end and works even when the offending router is not in your configuration management.
! Audit 1: every redistribute statement has a route-map
R1# show running-config | include redistribute
redistribute eigrp 100 metric 20 metric-type 1 subnets route-map EIGRP-TO-OSPF
redistribute ospf 1 metric 1000000 100 255 1 1500 route-map OSPF-TO-EIGRP
! ^ Any line without 'route-map' is a finding.
!
! Audit 2: external routes with no tag
R5# show ip route ospf | include ^O E
! ...then check a sample for the Tag line
R5# show ip route 10.7.0.0 | include Tag
! (no output) = this prefix crossed a boundary with no route-map
!
! Audit 3: does any boundary disagree about the tag values?
R2# show running-config | include set tag|match tag
match tag 110
set tag 90
match tag 90
set tag 110
! ^ Compare against R1. They must be identical.
Testing under failure, which is where loops appear
A tag scheme that works in steady state can still be incomplete if one boundary was configured and another was not, because the misconfigured boundary only matters when it becomes the active path. Shutting each boundary in turn, and repeating the four checks with the other carrying everything, is the test that finds the boundary somebody missed.
! Fail one boundary and re-verify everything
R1(config)# interface GigabitEthernet0/1
R1(config-if)# shutdown
!
R5# traceroute 10.5.0.1
R3# show ip route 10.2.0.0 | include Known via|Tag
R2# show ip route 10.5.0.0 | include Known via
!
R1(config-if)# no shutdown
! Then repeat with R2 shut instead.
| Check | Command | Expected | Failure signature |
|---|---|---|---|
| Native path wins | show ip route <prefix> |
Source protocol matches origin | The other protocol is the source |
| Tag present | show ip route <prefix> | include Tag |
The expected tag value | No Tag line |
| Reverse refused | Protocol database for own prefixes | No external entry | External entry for a native prefix |
| Counts sane | count ^O E / count ^D EX |
Each roughly the other domain's size | Either close to the total of both |
| Forwarding path | traceroute both directions |
No router appears twice | Two routers alternating |
| Under failure | All of the above with one boundary shut | Unchanged | A loop appears only in this state |
Conclusion
The mutual-redistribution loop is a routing-table problem wearing routing-protocol clothes. Both protocols are behaving correctly: EIGRP's DUAL is loop-free, OSPF's SPF is loop-free, and each is faithfully advertising a route it legitimately learned. What fails is the comparison between them, which happens in the RIB, uses administrative distance, and has no visibility into whether the two entries describe the same physical path traversed in opposite directions. No amount of metric tuning reaches that comparison, because distance is evaluated first.
Route tagging works because it adds the one piece of information the comparison lacks: where the route has already been. A tag set as a prefix leaves EIGRP travels with it through OSPF and is still there when it reaches the boundary that would send it back. Refusing tagged routes at that point is a statement about provenance rather than about addresses, which is why it keeps working as the network grows and why prefix-list filtering does not.
Three practical points carry most of the value. Tag from the first boundary, before a second one exists, so adding the second is purely additive. Apply the identical maps at every boundary — one untagged boundary reintroduces the problem for everything crossing it. And test by failing each boundary in turn, because a scheme that is complete on the active path and missing on the standby one behaves perfectly until the day it matters. Build the loop in a lab first; watching a traceroute alternate between two routers is worth more than any explanation of why it does.
External Links Recommendations
- Cisco — Redistributing Routing Protocols: the mutual redistribution problem, administrative distance, and worked loop-prevention examples.
- RFC 2328 — OSPF Version 2: Section 12.4.4 defines the AS-external LSA and the External Route Tag field used for tagging.
- RFC 7868 — Cisco's Enhanced Interior Gateway Routing Protocol (EIGRP): the external route TLV including the administrator tag.
- RFC 1058 and RFC 2453 — RIP: the 16-bit route tag field, for networks where RIP is one of the redistributed protocols.
- Cisco — What Is Administrative Distance?: the default values and how the comparison is performed.
- Cisco IOS-XE IP Routing Protocol-Independent Configuration Guide:
redistribute,distance, and route-map tag syntax. - Cisco Learning Network — CCIE Enterprise Infrastructure: current blueprint and lab equipment list.
Reference Notes
- Cisco, "Redistributing Routing Protocols" — mutual redistribution at two or more points can create routing loops through administrative distance interaction.
- Cisco, "Redistributing Routing Protocols" — route tagging as the recommended loop-prevention mechanism for multi-point redistribution.
- Cisco, "What Is Administrative Distance?" — default distances: connected 0, static 1, eBGP 20, EIGRP internal 90, OSPF 110, IS-IS 115, RIP 120, EIGRP external 170, iBGP 200.
- Cisco, "What Is Administrative Distance?" — administrative distance is compared before metric, and across protocols metric is not comparable.
- RFC 2328, Section 12.4.4 — the AS-external-LSA format including the 32-bit External Route Tag, which OSPF carries without interpreting.
- RFC 2328, Section 16.4 — external route calculation; OSPF assigns the same administrative preference to internal and external routes on Cisco platforms.
- RFC 7868, Section 5.7 — the EIGRP external route TLV, carrying the originating protocol, external metric, and a 32-bit administrator tag.
- RFC 2453, Section 4 — the RIPv2 Route Tag field, 16 bits, preserved and re-advertised without interpretation.
- Cisco IOS-XE IP Routing Configuration Guide —
set tagandmatch tagin route-maps applied toredistributestatements. - Cisco IOS-XE IP Routing Configuration Guide —
distance ospf externalanddistance eigrpfor per-protocol administrative distance adjustment. - Cisco IOS-XE IP Routing Configuration Guide — the
distancecommand with a source address and access-list, for per-source distance adjustment. - Cisco IOS-XE EIGRP Configuration Guide — in named mode,
distance eigrpandredistributeare configured undertopology base.