Here is a routing puzzle. An OSPF router has a route to an external network. The route is in the routing table. The next hop is a device that is not the router that advertised it and is not even running OSPF. Nothing in the configuration says to do this. How?
That is the OSPF forwarding address doing its job. It is a genuinely clever optimisation that eliminates a suboptimal hop, and it is also the cause of one of the most baffling silent failures in OSPF - a route that vanishes from the RIB while its LSA sits happily in the database, with no log message and no obvious cause.
This article covers the five conditions that set a non-zero forwarding address, the optimisation it produces, and the failure mode nobody documents - all with real output from a CML lab. For the fundamentals, start at the complete OSPF guide.
The problem it solves
Picture a shared Ethernet segment. On it sit three devices: two OSPF routers (call them R2 and R3), and a firewall (R6) that does not speak OSPF at all. Behind the firewall is 172.20.20.0/24.
R3 has a static route to that network pointing at the firewall, and redistributes it into OSPF. R3 is now the ASBR.
Without a forwarding address, every router in the OSPF domain would compute its path to 172.20.20.0/24 as "go to the ASBR (R3), and R3 will handle it". So R2, which is sitting on the same Ethernet segment as the firewall, would send its packets across the segment to R3, and R3 would immediately send them straight back across the same segment to the firewall. The packet crosses the wire twice for no reason.
The forwarding address fixes exactly this. Instead of advertising "send it to me", the ASBR advertises "send it to this address" - the firewall's address on the shared segment. R2 sees that it can reach that address directly, and forwards straight to the firewall.
The five conditions
OSPF sets a non-zero forwarding address in a Type-5 LSA only when all five of these are true of the ASBR's interface toward the external route's next hop:
network statement or has ip ospf configured).Fail any one of them and the forwarding address is 0.0.0.0, which means "send it to me, the ASBR".
Read the list again and notice how much sense it makes. The whole point is that other OSPF routers should be able to reach the forwarding address directly. That is only plausible if the ASBR's interface is (a) in OSPF, so other routers know the subnet exists, and (b) a multiaccess segment, so other routers can plausibly be attached to the same wire. On a point-to-point link, nobody else is on that wire, so a forwarding address would be pointless - and OSPF correctly declines to set one.
The lab
R3 is the ASBR in area 1, on a shared broadcast segment with R2 (also OSPF) and R6 (a non-OSPF device with 172.20.20.0/24 behind it).
R3:
interface Ethernet0/1
description SHARED-SEGMENT-AREA1
ip address 10.0.234.3 255.255.255.0
!
ip route 172.20.20.0 255.255.255.0 10.0.234.6
!
router ospf 1
network 10.0.234.0 0.0.0.255 area 1
redistribute static subnetsAll five conditions are met. The LSA:
R2#show ip ospf database external 172.20.20.0
LS Type: AS External Link
Link State ID: 172.20.20.0 (External Network Number )
Advertising Router: 3.3.3.3
Network Mask: /24
Metric Type: 2 (Larger than any link state path)
Metric: 20
Forward Address: 10.0.234.6
External Route Tag: 0Forward Address: 10.0.234.6. That is R6, the firewall. R3 is advertising "do not send this to me, send it to R6".
And R2's routing table obeys:
R2#show ip route 172.20.20.0
Routing entry for 172.20.20.0/24
Known via "ospf 1", distance 110, metric 20, type extern 2, forward metric 10
Last update from 10.0.234.6 on Ethernet0/2, 00:01:05 ago
Routing Descriptor Blocks:
* 10.0.234.6, from 3.3.3.3, 00:01:05 ago, via Ethernet0/2Read that carefully. The route was learned from 3.3.3.3 (the ASBR), but the next hop is 10.0.234.6 (the firewall). The extra hop through R3 has been eliminated. That is the optimisation.
Note also forward metric 10 - a separate field. The route's OSPF metric (20) is the external cost. The forward metric is the internal cost to reach the forwarding address. It matters, and we will come back to it.
Breaking a condition
Make R3's segment interface passive, and condition 2 fails:
R3(config-router)#passive-interface Ethernet0/1
R2#show ip ospf database external 172.20.20.0 | include Forward|Advertising|Metric
Advertising Router: 3.3.3.3
Metric Type: 2 (Larger than any link state path)
Metric: 20
Forward Address: 0.0.0.0
R2#show ip route 172.20.20.0
Routing entry for 172.20.20.0/24
Last update from 10.0.23.2 on Ethernet0/1, 00:00:10 ago
Routing Descriptor Blocks:
* 10.0.23.2, from 3.3.3.3, 00:00:10 ago, via Ethernet0/1The forwarding address reverted to 0.0.0.0 and R2's next hop is now 10.0.23.2 - the ASBR, over a completely different link. The packet will now take the long way round and hairpin. Forwarding still works; it is just worse.
The failure mode nobody documents
Now the part that will cost you a Saturday if you have not seen it before.
RFC 2328 §16.4 says that when the forwarding address is non-zero, the router must look it up in its routing table, and the matching route must be an intra-area or inter-area OSPF path. If the forwarding address cannot be resolved that way, the external route is discarded entirely.
So: anything that removes the forwarding address's subnet from the OSPF routing table silently kills the external route on every router that loses it.
In the lab, we enabled prefix suppression on the ABRs - a perfectly ordinary optimisation, applied to shrink the core table, with nothing to do with external routes. The shared segment 10.0.234.0/24 is a transit prefix, so it was suppressed. And:
R1#show ip route 172.20.20.0
% Network not in table
R1#show ip ospf database external 172.20.20.0 | include Forward|Advertising
Advertising Router: 3.3.3.3
Forward Address: 10.0.234.6 <-- the LSA is right there
R1#show ip route 10.0.234.6
% Subnet not in table <-- but the forwarding address is unreachableThe LSA is in the database. The route is not in the RIB. There is no log message.
We reproduced the same failure a second way, with an area range not-advertise on the ABR, and confirmed it right down to the data plane:
R2(config-router)#area 1 range 10.0.234.0 255.255.255.0 not-advertise
R1#show ip route 10.0.234.6
% Subnet not in table
R1#show ip route 172.20.20.0
% Network not in table
R1#ping 172.20.20.1 source Loopback0
.....
Success rate is 0 percent (0/5)An engineer summarising the core, or suppressing transit prefixes, or filtering a subnet they were sure nobody needed - and an external network goes dark on the other side of the building.
The check to run before you filter anything
show ip ospf database external | include Forward AddressIf every line reads 0.0.0.0, filter freely. If any line names a real address, find out which subnet it lives on, and protect that subnet from suppression, summarisation and filtering. Put a comment in the config.
Type-7 LSAs always carry a forwarding address
An NSSA external LSA (Type 7) is different: it always has a non-zero forwarding address, and it is normally the ASBR's own router ID or loopback:
R4#show ip ospf database nssa-external 172.16.99.0 | include Advertising|Metric Type|Forward
Advertising Router: 5.5.5.5
Metric Type: 1 (Comparable directly to link state metric)
Forward Address: 5.5.5.5This is not an optimisation, it is a requirement. When the NSSA ABR translates a Type-7 into a Type-5 for the backbone, the resulting Type-5 needs a forwarding address so that backbone routers can reach the originating ASBR inside the NSSA. Without one, the translated LSA would point at the ABR, which is not where the route actually lives.
The practical consequence: the NSSA ASBR's forwarding address must be advertised into the backbone. If you filter the NSSA's loopback range at the ABR, you break every external route the NSSA originates. Same failure mode, different LSA type.
Troubleshooting
- An external route is in the LSDB but not the RIB. Check the forwarding address (
show ip ospf database external <prefix>). If it is non-zero, check whether you have an OSPF route to it (show ip route <FA>). This is the answer far more often than people expect. - Traffic is taking a strange path to an external network. Look for a non-zero forwarding address. The route may be going somewhere you never configured, and that may well be correct.
- The forwarding address is 0.0.0.0 and you expected it not to be. Walk the five conditions. In practice the culprit is almost always
passive-interfaceor a point-to-point network type. - The forwarding address is non-zero and you wish it were not. Make the ASBR's next-hop interface passive, or change its network type to point-to-point. Both force it to 0.0.0.0.
- Two ASBRs advertise the same external. The tiebreak uses the forward metric (the cost to reach the forwarding address), not just the external metric. Two E2 routes with equal external metric are broken by forward metric - which is why
show ip routeprints it.
Key takeaways
- The forwarding address lets an ASBR say "send it to that device over there", eliminating a pointless hairpin through the ASBR on a shared segment.
- It is set only when all five conditions hold. In practice: an OSPF-enabled, non-passive, broadcast-type interface whose subnet contains the external route's next hop.
- Passive-interface or a point-to-point network type will force it to 0.0.0.0. That is the usual reason it "does not work".
- A non-zero forwarding address must resolve to an intra-area or inter-area OSPF route, or the external route is silently discarded. Prefix suppression, area ranges and filtering can all cause this, with no log message.
- Run
show ip ospf database external | include Forward Addressbefore you suppress, summarise or filter anything in the core. - Type-7 (NSSA) LSAs always carry a non-zero forwarding address. It must remain reachable from the backbone or the translated Type-5 is useless.
- The forward metric - the cost to reach the forwarding address - is a real tiebreaker between equal-cost E2 routes.
Next: OSPF filtering compared - area range, filter-list, distribute-list and summary-address, and which of them touch the LSDB versus only the RIB. The full cluster index lives on the OSPF pillar guide.