Skip to main content
  1. Network Articles/
  2. OSPF Articles/

What Is OSPF

Table of Contents

What Is OSPF

OSPF (Open Shortest Path First) is one of the dynamic routing protocols. Dynamic routing protocols fall into two broad categories according to how they compute routes: distance-vector protocols (such as RIP), which choose routes based on distance information received from neighboring routers, and link-state protocols (OSPF, IS-IS), in which every router holds the topology of the whole network and computes the shortest paths itself. OSPF is a link-state protocol.

This article covers OSPFv2 (RFC 2328), the version used for IPv4. It explains how OSPF differs from a distance-vector protocol and how it proceeds from establishing neighbors to building the routing table, checking each step against the output of real devices (Cisco IOS XR) and packet captures. For IPv6, OSPFv3 (RFC 5340), an extension of OSPFv2, is used. For the basics of routing itself, see Routing.

ItemDescription
CategoryIGP (a routing protocol used inside an AS), link-state
StandardOSPFv2: RFC 2328 (IPv4), OSPFv3: RFC 5340 (IPv6)
TransportCarried directly over IP with IP protocol number 89 (neither TCP nor UDP is used)
Destination addressesMulticast 224.0.0.5 (all OSPF routers) and 224.0.0.6 (DR/BDR)
MetricCost (the sum of values derived from interface bandwidth)
Administrative distance110 (same on Cisco IOS XE and IOS XR)
Route computationSPF (Dijkstra) algorithm

Distance-Vector Routing (RIP)

RIP, the typical distance-vector protocol, has each router send the contents of its own routing table (destinations and hop counts) as-is to its neighbors every 30 seconds. The receiving router adds 1 to the hop count, installs the routes in its own table, and passes them on to the next neighbor.

As the figure shows, R3’s 3.3.3.3/32 reaches R2 with a hop count of 2 and R1 with a hop count of 3, but all R1 knows is “it is 3 hops away via R2”. R1 has no idea how the network beyond R2 is actually connected. This approach, in which each router decides where to forward based only on “the distance its neighbor claims”, has the following weaknesses.

  • The maximum hop count is limited to 15, so it cannot be used in large networks.
  • The whole routing table is sent every 30 seconds even when the topology has not changed, which is inefficient.
  • A neighbor going down can only be detected by updates no longer arriving (expiry of the 180-second invalid timer), so convergence is slow.
  • Each router has no choice but to trust its neighbor’s information, which makes routing loops easy to form.

Link-State Routing (OSPF)

In OSPF, each router tells every other router in the area about its own link state: “these are my links, this is who is on the other end of each, and this is the cost.” Because every router collects the same information, all routers end up holding an identical topology map, and each router independently computes the shortest paths from itself using that map. Topology changes are propagated across the area immediately, so convergence is fast, and because routes are computed with the whole map in hand, loops are inherently unlikely.

TermDescription
LSA (Link State Advertisement)The advertisement of link state generated by each router: a unit of data describing its interfaces, adjacent routers, costs, and so on. There are several types depending on purpose (see LSA Overview).
LSDB (Link State Database)The database in which received LSAs are stored. Every router in the same area holds the same LSDB.
SPF (Shortest Path First)The algorithm (Dijkstra’s algorithm) that computes the shortest-path tree rooted at the router itself from the LSDB.

OSPF builds its routing table through the following four stages. Each stage is examined below with the output of real devices.

The test environment is a single-area setup in which three Cisco IOS XR (XRd 26.1.1) routers (R1 to R3) are connected in a line, with every link in area 0. The Loopback0 address of each router is configured as its router ID (R1: 1.1.1.1, R2: 2.2.2.2, R3: 3.3.3.3). The configuration commands for IOS XR and IOS XE will be covered in separate articles, IOS XR OSPF Configuration and IOS XE OSPF Configuration.

The test runs in six stages (STEP 0 to 5). The show output, syslog and running-config collected from all three routers at every STEP are gathered in Verification config and show output at the end of the article. What follows quotes only parts of them.

STEPOperationState
0Initial state (linear topology)R1–R2–R3 are Full
1clear ospf 1 process on all three at onceCaptures everything from neighbor establishment to LSDB synchronization
2Bring up the direct R1–R3 link (triangle topology)R1 to R3 switches to the direct link (cost 2)
3Shut down the direct R1–R3 link (simulated failure)Switches to the path via R2 (cost 3)
4Bring the direct R1–R3 link back upReturns to the direct link
5Shut down the direct link, back to the linear topology (final state)Restored to the same setup as the initial state

STEP 0 and 1 use the linear topology above; STEP 2 to 4 use the triangle topology used in Route switchover on a link failure.

1. Establishing neighbors (adjacencies)

From every interface on which OSPF is enabled, a router periodically sends Hello packets to a multicast address (224.0.0.5) to discover other OSPF routers (neighbors) on the same link. The Hello interval depends on the network type; on Ethernet it is 10 seconds (see Network Types). Hellos keep being sent after the neighbor is established and are used to confirm that each side is still alive.

The state in which both sides have received each other’s Hellos and are ready to synchronize their LSDBs is called an adjacency. The state transitions up to Full are covered in OSPF Neighbor States.

When the OSPF process is reset on all three routers at once in STEP 1, R1 logs the neighbor going Down and coming back to Full about 40 seconds later (%ROUTING-OSPF-5-ADJCHG).

STEP 1 R1 syslog (around clear ospf 1 process)
RP/0/RP0/CPU0:R1#show logging start Sep 6 01:58:18
Sun Sep  6 02:02:31.905 UTC
Time Zone UTC, DST disabled
Syslog logging: enabled (0 messages dropped, 0 flushes, 0 overruns)
    Console logging: Disabled
    Monitor logging: level debugging, 0 messages logged
    Trap logging: level informational, 0 messages logged
    Buffer logging: level debugging, 85 messages logged

Log Buffer (2097152 bytes):

RP/0/RP0/CPU0:Sep  6 01:58:18.787 UTC: logger[67540]: %OS-SYSLOG-6-LOG_INFO : informational STEP1-BEGIN 
RP/0/RP0/CPU0:Sep  6 01:58:19.162 UTC: ssh_syslog_proxy[1188]: %SECURITY-SSHD_SYSLOG_PRX-6-INFO_GENERAL : sshd[6052]: Received disconnect from 10.100.3.1 port 50041:11: disconnected by user 
RP/0/RP0/CPU0:Sep  6 01:58:19.162 UTC: ssh_syslog_proxy[1188]: %SECURITY-SSHD_SYSLOG_PRX-6-INFO_GENERAL : sshd[6052]: Disconnected from user cisco 10.100.3.1 port 50041 
RP/0/RP0/CPU0:Sep  6 01:59:51.811 UTC: ssh_syslog_proxy[1188]: %SECURITY-SSHD_SYSLOG_PRX-6-INFO_GENERAL : sshd[6262]: Accepted authentication/pam for cisco from 10.100.3.1 port 50077 ssh2 
RP/0/RP0/CPU0:Sep  6 01:59:53.729 UTC: ospf[1035]: %ROUTING-OSPF-5-ADJCHG : Process 1, Nbr 2.2.2.2 on GigabitEthernet0/0/0/0 in area 0 from FULL to DOWN, Neighbor Down: interface down or detached, vrf default vrfid 0x60000000 
RP/0/RP0/CPU0:Sep  6 01:59:54.203 UTC: ssh_syslog_proxy[1188]: %SECURITY-SSHD_SYSLOG_PRX-6-INFO_GENERAL : sshd[6267]: Received disconnect from 10.100.3.1 port 50077:11: disconnected by user 
RP/0/RP0/CPU0:Sep  6 01:59:54.203 UTC: ssh_syslog_proxy[1188]: %SECURITY-SSHD_SYSLOG_PRX-6-INFO_GENERAL : sshd[6267]: Disconnected from user cisco 10.100.3.1 port 50077 
RP/0/RP0/CPU0:Sep  6 02:00:34.101 UTC: ospf[1035]: %ROUTING-OSPF-5-ADJCHG : Process 1, Nbr 2.2.2.2 on GigabitEthernet0/0/0/0 in area 0 from LOADING to FULL, Loading Done, vrf default vrfid 0x60000000 

It takes about 40 seconds to get back to Full because Hellos have to be exchanged and the Wait timer (the same 40 seconds as the dead interval) has to expire. The neighbors on each router after convergence are as follows.

RP/0/RP0/CPU0:R1#show ospf neighbor
Sun Sep  6 02:02:20.171 UTC

* Indicates MADJ interface
# Indicates Neighbor awaiting BFD session up

Neighbors for OSPF 1

Neighbor ID     Pri   State           Dead Time   Address         Interface
2.2.2.2         1     FULL/DR         00:00:35    10.1.2.2        GigabitEthernet0/0/0/0
    Neighbor is up for 00:02:17

Total neighbor count: 1
RP/0/RP0/CPU0:R2#show ospf neighbor
Sun Sep  6 02:02:48.512 UTC

* Indicates MADJ interface
# Indicates Neighbor awaiting BFD session up

Neighbors for OSPF 1

Neighbor ID     Pri   State           Dead Time   Address         Interface
1.1.1.1         1     FULL/BDR        00:00:35    10.1.2.1        GigabitEthernet0/0/0/0
    Neighbor is up for 00:02:46
3.3.3.3         1     FULL/DR         00:00:36    10.2.3.3        GigabitEthernet0/0/0/1
    Neighbor is up for 00:02:45

Total neighbor count: 2
RP/0/RP0/CPU0:R3#show ospf neighbor
Sun Sep  6 02:03:18.247 UTC

* Indicates MADJ interface
# Indicates Neighbor awaiting BFD session up

Neighbors for OSPF 1

Neighbor ID     Pri   State           Dead Time   Address         Interface
2.2.2.2         1     FULL/BDR        00:00:33    10.2.3.2        GigabitEthernet0/0/0/0
    Neighbor is up for 00:03:15

Total neighbor count: 1

R1 and R3 are Full with R2, and R2 is Full with both R1 and R3. What follows the / in the State column is the neighbor’s role on that link (DR / BDR). Because the process was reset on all three routers at once, the router with the higher router ID won the election on each segment (R2 on R1–R2, R3 on R2–R3); see DR and BDR. Dead Time is the time left before the neighbor is declared down if no Hello arrives, and it is reset to 40 seconds every time a Hello is received.

2. Synchronizing the LSDB by exchanging LSAs

Routers that have established an adjacency first exchange the list of LSAs they hold (DBD: Database Description), then request the LSAs they are missing (LSR: Link State Request) and receive the bodies from the other side (LSU: Link State Update). This synchronizes their LSDBs. The five OSPF packet types are covered in OSPF Packet Types and Header Format.

Once synchronization is complete, only LSAs that change are updated and flooded, and only when the topology changes. Even with no change, each LSA is re-sent 30 minutes after it was generated so its contents can be confirmed, and an LSA that has not been updated for 60 minutes is removed from the LSDB.

The following are the packets involved in establishing the adjacency, taken from the capture on the R1–R2 link in STEP 1 (47 packets in total).

No.TimeSourceDestinationInfo
10.00010.1.2.2224.0.0.5Hello Packet
28.19110.1.2.1224.0.0.5Hello Packet
1349.30610.1.2.1224.0.0.5Hello Packet
1449.39610.1.2.2224.0.0.5Hello Packet
1551.44610.1.2.110.1.2.2DB Description
1651.75610.1.2.210.1.2.1DB Description
1751.75910.1.2.110.1.2.2DB Description
1851.76310.1.2.210.1.2.1DB Description
1951.76610.1.2.110.1.2.2LS Request
2051.76610.1.2.110.1.2.2DB Description
2151.76910.1.2.210.1.2.1LS Update
2251.77010.1.2.210.1.2.1LS Request
2351.77310.1.2.110.1.2.2LS Update
2451.77810.1.2.2224.0.0.5LS Update
2551.81210.1.2.2224.0.0.5LS Update
2651.82610.1.2.1224.0.0.6LS Update
2751.85710.1.2.2224.0.0.5LS Update
2853.77410.1.2.1224.0.0.6LS Acknowledge
2953.77710.1.2.2224.0.0.5LS Acknowledge
3056.59610.1.2.210.1.2.1LS Update
3158.60010.1.2.1224.0.0.6LS Acknowledge
3258.86310.1.2.1224.0.0.5Hello Packet
  • No.1-14: right after the process reset, both sides do nothing but send Hellos every 10 seconds for about 40 seconds. The Wait timer expires during this time and the DR/BDR are settled.
  • No.15-20: the DBD exchange. The first two (No.15 and 16) settle the master/slave relationship and the sequence number, and the next three hand over the list of LSAs. The DBD/LSR/LSU exchanged while the adjacency forms are unicast to the peer’s interface address, not multicast.
  • No.19 and 21: R1 requests R2’s Router-LSA (2.2.2.2) with an LSR and R2 returns it in an LSU.
  • No.22 and 23: conversely R2 requests R1’s Router-LSA (1.1.1.1) and R1 returns it.
  • No.24-27: once the LSDBs are synchronized, R2 as the DR floods the Network-LSA for this segment (10.1.2.2) and the Router-LSAs of R2 and R3 to 224.0.0.5.
  • No.26: R1, the BDR, sends its own Router-LSA to 224.0.0.6 (the DR/BDR address). The use of each multicast address is covered in DR and BDR.
  • No.28-31: the LSAcks for the LSAs received. No.30 is a retransmission of an LSU from R2, acknowledged by R1 in No.31.
  • No.32 onwards: only the 10-second Hellos keep flowing; no more LSAs are exchanged.

Expanding the LSU in No.23 shows R1 advertising two links as its own link state, Loopback0 (1.1.1.1/32) and the segment to R2 (10.1.2.0/24), each with a cost (Metric) of 1.

No.23 LS Update (R1 to R2, R1's Router-LSA)
Open Shortest Path First
    OSPF Header
        Version: 2
        Message Type: LS Update (4)
        Packet Length: 76
        Source OSPF Router: 1.1.1.1
        Area ID: 0.0.0.0 (Backbone)
        Checksum: 0xe698 [correct]
        Instance ID: Base IPv4 Unicast Instance (0)
        Auth Type: Null (0)
        Auth Data (none): 0000000000000000
    LS Update Packet
        Number of LSAs: 1
        LSA-type 1 (Router-LSA), len 48
            .000 0000 0010 1001 = LS Age (seconds): 41
            0... .... .... .... = Do Not Age Flag: 0
            Options: 0x22, (DC) Demand Circuits, (E) External Routing
                0... .... = DN: Not set
                .0.. .... = (O) Opaque: Not set
                ..1. .... = (DC) Demand Circuits: Supported
                ...0 .... = (L) LLS Data block: Not Present
                .... 0... = (N) NSSA: Not supported
                .... .0.. = (MC) Multicast: Not capable
                .... ..1. = (E) External Routing: Capable
                .... ...0 = (MT) Multi-Topology Routing: No
            LS Type: Router-LSA (1)
            Link State ID: 1.1.1.1
            Advertising Router: 1.1.1.1
            Sequence Number: 0x80000001
            Checksum: 0x5bac
            Length: 48
            Flags: 0x00
                0... .... = (H) Host: No
                ..0. .... = (S) Shortcut-capable ABR: No
                ...0 .... = (N) NSSA translation: No
                .... 0... = (W) Wild-card multicast receiver: No
                .... .0.. = (V) Virtual link endpoint: No
                .... ..0. = (E) AS boundary router: No
                .... ...0 = (B) Area border router: No
            Number of Links: 2
            Type: Stub     ID: 1.1.1.1         Data: 255.255.255.255 Metric: 1
                Link ID: 1.1.1.1 - IP network/subnet number
                Link Data: 255.255.255.255
                Link Type: 3 - Connection to a stub network
                Number of Metrics: 0 - TOS
                0 Metric: 1
            Type: Stub     ID: 10.1.2.0        Data: 255.255.255.0   Metric: 1
                Link ID: 10.1.2.0 - IP network/subnet number
                Link Data: 255.255.255.0
                Link Type: 3 - Connection to a stub network
                Number of Metrics: 0 - TOS
                0 Metric: 1
Download the pcap of the packet in the tshark output above (No.23 LSU)

At this point the adjacency is not Full yet, so 10.1.2.0/24 is advertised as a stub network (Type: Stub). Once synchronization completes, R2 as the DR generates and floods the Network-LSA for this segment (No.24). It lists 1.1.1.1 and 2.2.2.2 as the routers attached to it.

No.24 LS Update (R2 to 224.0.0.5, the Network-LSA generated by the DR)
Open Shortest Path First
    OSPF Header
        Version: 2
        Message Type: LS Update (4)
        Packet Length: 60
        Source OSPF Router: 2.2.2.2
        Area ID: 0.0.0.0 (Backbone)
        Checksum: 0x10a3 [correct]
        Instance ID: Base IPv4 Unicast Instance (0)
        Auth Type: Null (0)
        Auth Data (none): 0000000000000000
    LS Update Packet
        Number of LSAs: 1
        LSA-type 2 (Network-LSA), len 32
            .000 0000 0000 0001 = LS Age (seconds): 1
            0... .... .... .... = Do Not Age Flag: 0
            Options: 0x22, (DC) Demand Circuits, (E) External Routing
                0... .... = DN: Not set
                .0.. .... = (O) Opaque: Not set
                ..1. .... = (DC) Demand Circuits: Supported
                ...0 .... = (L) LLS Data block: Not Present
                .... 0... = (N) NSSA: Not supported
                .... .0.. = (MC) Multicast: Not capable
                .... ..1. = (E) External Routing: Capable
                .... ...0 = (MT) Multi-Topology Routing: No
            LS Type: Network-LSA (2)
            Link State ID: 10.1.2.2
            Advertising Router: 2.2.2.2
            Sequence Number: 0x80000001
            Checksum: 0x31e5
            Length: 32
            Netmask: 255.255.255.0
            Attached Router: 1.1.1.1
            Attached Router: 2.2.2.2
Download the pcap of the packet in the tshark output above (No.24 LSU)

R1 then rebuilds its own Router-LSA. In No.26, 10.1.2.0/24 has changed from Type: Stub to a transit network (Type: Transit) reached through the DR (10.1.2.2 = R2), and the sequence number has advanced to 0x80000002. It goes to 224.0.0.6 (the DR/BDR address) because R1 is the BDR on this segment.

No.26 LS Update (R1 to 224.0.0.6, R1's updated Router-LSA)
Open Shortest Path First
    OSPF Header
        Version: 2
        Message Type: LS Update (4)
        Packet Length: 76
        Source OSPF Router: 1.1.1.1
        Area ID: 0.0.0.0 (Backbone)
        Checksum: 0x8126 [correct]
        Instance ID: Base IPv4 Unicast Instance (0)
        Auth Type: Null (0)
        Auth Data (none): 0000000000000000
    LS Update Packet
        Number of LSAs: 1
        LSA-type 1 (Router-LSA), len 48
            .000 0000 0000 0001 = LS Age (seconds): 1
            0... .... .... .... = Do Not Age Flag: 0
            Options: 0x22, (DC) Demand Circuits, (E) External Routing
                0... .... = DN: Not set
                .0.. .... = (O) Opaque: Not set
                ..1. .... = (DC) Demand Circuits: Supported
                ...0 .... = (L) LLS Data block: Not Present
                .... 0... = (N) NSSA: Not supported
                .... .0.. = (MC) Multicast: Not capable
                .... ..1. = (E) External Routing: Capable
                .... ...0 = (MT) Multi-Topology Routing: No
            LS Type: Router-LSA (1)
            Link State ID: 1.1.1.1
            Advertising Router: 1.1.1.1
            Sequence Number: 0x80000002
            Checksum: 0xb542
            Length: 48
            Flags: 0x00
                0... .... = (H) Host: No
                ..0. .... = (S) Shortcut-capable ABR: No
                ...0 .... = (N) NSSA translation: No
                .... 0... = (W) Wild-card multicast receiver: No
                .... .0.. = (V) Virtual link endpoint: No
                .... ..0. = (E) AS boundary router: No
                .... ...0 = (B) Area border router: No
            Number of Links: 2
            Type: Stub     ID: 1.1.1.1         Data: 255.255.255.255 Metric: 1
                Link ID: 1.1.1.1 - IP network/subnet number
                Link Data: 255.255.255.255
                Link Type: 3 - Connection to a stub network
                Number of Metrics: 0 - TOS
                0 Metric: 1
            Type: Transit  ID: 10.1.2.2        Data: 10.1.2.1        Metric: 1
                Link ID: 10.1.2.2 - IP address of Designated Router
                Link Data: 10.1.2.1
                Link Type: 2 - Connection to a transit network
                Number of Metrics: 0 - TOS
                0 Metric: 1
Download the pcap of the packet in the tshark output above (No.26 LSU)

3. Building the topology map from the LSDB

Once the LSAs have been exchanged, each router assembles a topology map of the whole network from the contents of its LSDB. Because the LSDB is synchronized across the area, it looks the same on every router.

RP/0/RP0/CPU0:R1#show ospf database
Sun Sep  6 02:02:22.004 UTC


            OSPF Router with ID (1.1.1.1) (Process ID 1)

		Router Link States (Area 0)

Link ID         ADV Router      Age         Seq#       Checksum Link count
1.1.1.1         1.1.1.1         108         0x80000002 0x00b542 2
2.2.2.2         2.2.2.2         109         0x80000002 0x00e0d6 3
3.3.3.3         3.3.3.3         109         0x80000002 0x0006d2 2

		Net Link States (Area 0)

Link ID         ADV Router      Age         Seq#       Checksum
10.1.2.2        2.2.2.2         109         0x80000001 0x0031e5
10.2.3.3        3.3.3.3         110         0x80000001 0x0046c1
RP/0/RP0/CPU0:R2#show ospf database
Sun Sep  6 02:02:50.572 UTC


            OSPF Router with ID (2.2.2.2) (Process ID 1)

		Router Link States (Area 0)

Link ID         ADV Router      Age         Seq#       Checksum Link count
1.1.1.1         1.1.1.1         138         0x80000002 0x00b542 2
2.2.2.2         2.2.2.2         137         0x80000002 0x00e0d6 3
3.3.3.3         3.3.3.3         138         0x80000002 0x0006d2 2

		Net Link States (Area 0)

Link ID         ADV Router      Age         Seq#       Checksum
10.1.2.2        2.2.2.2         137         0x80000001 0x0031e5
10.2.3.3        3.3.3.3         138         0x80000001 0x0046c1
RP/0/RP0/CPU0:R3#show ospf database
Sun Sep  6 02:03:20.256 UTC


            OSPF Router with ID (3.3.3.3) (Process ID 1)

		Router Link States (Area 0)

Link ID         ADV Router      Age         Seq#       Checksum Link count
1.1.1.1         1.1.1.1         168         0x80000002 0x00b542 2
2.2.2.2         2.2.2.2         167         0x80000002 0x00e0d6 3
3.3.3.3         3.3.3.3         166         0x80000002 0x0006d2 2

		Net Link States (Area 0)

Link ID         ADV Router      Age         Seq#       Checksum
10.1.2.2        2.2.2.2         167         0x80000001 0x0031e5
10.2.3.3        3.3.3.3         166         0x80000001 0x0046c1

All three hold the same contents: three Router-LSAs (Router Link States) and two Network-LSAs (Net Link States). Each router generates one Router-LSA, and the DR generates one Network-LSA per segment, giving two here: R1–R2 (DR is R2, Link ID 10.1.2.2) and R2–R3 (DR is R3, Link ID 10.2.3.3). Link count is the number of links that router advertises; only R2, which has links on both sides, has 3.

The contents of a Router-LSA can be checked with show ospf database router. The links R1 advertises are the stub network of Loopback0 and the transit network towards R2.

STEP 1 R1 contents of its own Router-LSA
RP/0/RP0/CPU0:R1#show ospf database router
Sun Sep  6 02:02:22.865 UTC


            OSPF Router with ID (1.1.1.1) (Process ID 1)

		Router Link States (Area 0)

  LS age: 109
  Options: (No TOS-capability, DC)
  LS Type: Router Links
  Link State ID: 1.1.1.1
  Advertising Router: 1.1.1.1
  LS Seq Number: 80000002
  Checksum: 0xb542
  Length: 48
   Number of Links: 2

    Link connected to: a Stub Network
     (Link ID) Network/subnet number: 1.1.1.1
     (Link Data) Network Mask: 255.255.255.255
      Number of TOS metrics: 0
       TOS 0 Metrics: 1

    Link connected to: a Transit Network
     (Link ID) Designated Router address: 10.1.2.2
     (Link Data) Router Interface address: 10.1.2.1
      Number of TOS metrics: 0
       TOS 0 Metrics: 1

4. Computing the SPF tree and building the routing table

From the topology in the LSDB, each router computes a shortest-path tree (SPF tree) rooted at itself and installs the best path (next hop and cost) to each destination network in its routing table. The LSDB is the same on every router, but the SPF tree differs depending on which router is the root.

The result of the SPF calculation itself can be seen with show ospf routes (the OSPF topology table). For each destination it shows the cost (metric) and the router that advertised the route (from).

STEP 1 R1 result of the SPF calculation
RP/0/RP0/CPU0:R1#show ospf routes
Sun Sep  6 02:02:25.711 UTC

Topology Table for ospf 1 with ID 1.1.1.1

Codes: O - Intra area, O IA - Inter area
       O E1 - External type 1, O E2 - External type 2
       O N1 - NSSA external type 1, O N2 - NSSA external type 2

O    1.1.1.1/32, metric 1
       1.1.1.1, directly connected, via Loopback0, ifIndex 7
O    2.2.2.2/32, metric 2
       10.1.2.2, from 2.2.2.2, via GigabitEthernet0/0/0/0, ifIndex 4, path-id 1
O    3.3.3.3/32, metric 3
       10.1.2.2, from 3.3.3.3, via GigabitEthernet0/0/0/0, ifIndex 4, path-id 1
O    10.1.2.0/24, metric 1
       10.1.2.1, directly connected, via GigabitEthernet0/0/0/0, ifIndex 4
O    10.2.3.0/24, metric 2
       10.1.2.2, from 3.3.3.3, via GigabitEthernet0/0/0/0, ifIndex 4, path-id 1

Every link in the test environment is GigabitEthernet (cost 1) and Loopback0 also has a cost of 1, so from R1 the Loopback0 of R2 (2.2.2.2/32) is cost 2 and the Loopback0 of R3 (3.3.3.3/32) is cost 3. Of these results, the routes that are not directly connected are installed in the routing table.

RP/0/RP0/CPU0:R1#show route ospf
Sun Sep  6 02:02:17.005 UTC

O    2.2.2.2/32 [110/2] via 10.1.2.2, 00:01:42, GigabitEthernet0/0/0/0
O    3.3.3.3/32 [110/3] via 10.1.2.2, 00:01:38, GigabitEthernet0/0/0/0
O    10.2.3.0/24 [110/2] via 10.1.2.2, 00:01:42, GigabitEthernet0/0/0/0
RP/0/RP0/CPU0:R2#show route ospf
Sun Sep  6 02:02:45.498 UTC

O    1.1.1.1/32 [110/2] via 10.1.2.1, 00:02:11, GigabitEthernet0/0/0/0
O    3.3.3.3/32 [110/2] via 10.2.3.3, 00:02:11, GigabitEthernet0/0/0/1
RP/0/RP0/CPU0:R3#show route ospf
Sun Sep  6 02:03:14.891 UTC

O    1.1.1.1/32 [110/3] via 10.2.3.2, 00:02:40, GigabitEthernet0/0/0/0
O    2.2.2.2/32 [110/2] via 10.2.3.2, 00:02:40, GigabitEthernet0/0/0/0
O    10.1.2.0/24 [110/2] via 10.2.3.2, 00:02:40, GigabitEthernet0/0/0/0

In [110/2], 110 is the administrative distance of OSPF and 2 is the cost.

When SPF ran can be traced with show ospf trace spf. IOS XR continuously records events inside the OSPF process in a trace buffer, so they can be read back later without having set up a debug. One SPF run starts at Begin SPF and finishes at SPF Processing ends.

STEP 1 R1 record of an SPF run (one run from show ospf trace spf)
367  Sep  6 02:00:38.978  ospf_run_spf: Begin SPF
368  Sep  6 02:00:38.978  ospf_wdsysmon_olc_start: Begin: Sending Start OLC to wdsysmon, vrf 0x60000000
369  Sep  6 02:00:38.978  ospf_wdsysmon_olc_start: End: Sending Start OLC to wdsysmon, vrf 0x60000000
370  Sep  6 02:00:38.978  spf_intra: area 0.0.0.0 vrf 0x60000000 abr 0 ribupdate 1
371  Sep  6 02:00:38.978  delete_old_routes: area 0.0.0.0
372  Sep  6 02:00:38.978  ospf_rib_ipv4_update_priority: for Q: 5 running rt cnt 1 lfa cnt 0 (inst 0x60000000)
373  Sep  6 02:00:38.978  ospf_run_spf:     SPF Dijkstra TRUE
374  Sep  6 02:00:38.978  ospf_rib_ipv4_update_done: for Q: 6 running rt cnt 1 lfa cnt 0 (inst 0x60000000)
375  Sep  6 02:00:38.978  ospf_rib_ipv4_update_done:  running rt cnt 1 (inst 0x60000000) op_rib_conv 0x1 op_rib_conv_event 0x1
376  Sep  6 02:00:38.978  ospf_update_done_cb: SPF complete: Elapse time:  0 ms.
377  Sep  6 02:00:38.978  ospf_update_done_cb: batch stats : level 0:  batches: 0 routes: 0
378  Sep  6 02:00:38.978  ospf_update_done_cb: batch stats, paths: add 0 err 0, del 0 err 0
379  Sep  6 02:00:38.978  ospf_update_done_cb: batch stats : level 1:  batches: 0 routes: 0
380  Sep  6 02:00:38.978  ospf_update_done_cb: batch stats, paths: add 0 err 0, del 0 err 0
381  Sep  6 02:00:38.978  ospf_update_done_cb: batch stats : level 2:  batches: 0 routes: 0
382  Sep  6 02:00:38.978  ospf_update_done_cb: batch stats, paths: add 0 err 0, del 0 err 0
383  Sep  6 02:00:38.978  ospf_update_done_cb: batch stats : level 3:  batches: 0 routes: 0
384  Sep  6 02:00:38.978  ospf_update_done_cb: batch stats, paths: add 0 err 0, del 0 err 0
385  Sep  6 02:00:38.978  ospf_update_done_cb: batch stats : level 4:  batches: 4 routes: 4
386  Sep  6 02:00:38.978  ospf_update_done_cb: batch stats, paths: add 4 err 0, del 0 err 0
387  Sep  6 02:00:38.978  ospf_update_done_cb: batch stats : level 5:  batches: 0 routes: 0
388  Sep  6 02:00:38.978  ospf_update_done_cb: batch stats, paths: add 0 err 0, del 0 err 0
389  Sep  6 02:00:38.978  ospf_update_done_cb: batch stats : level 6:  batches: 6 routes: 3
390  Sep  6 02:00:38.978  ospf_update_done_cb: batch stats, paths: add 3 err 0, del 0 err 0
391  Sep  6 02:00:38.978  ospf_update_done_cb: batch stats : level 7:  batches: 0 routes: 0
392  Sep  6 02:00:38.978  ospf_update_done_cb: batch stats, paths: add 0 err 0, del 0 err 0
393  Sep  6 02:00:38.978  ospf_run_spf: SPF Processing ends

spf_intra is the intra-area SPF calculation, SPF Dijkstra TRUE is the run of Dijkstra’s algorithm, and SPF complete: Elapse time is how long it took. At this scale it finishes in under a millisecond. SPF runs whenever the LSDB changes; the next section shows it running again in response to a link failure.

Route switchover on a link failure

The advantage of dynamic routing such as OSPF is that traffic switches to an alternative path without any operator action when a failure occurs. To confirm this, the following triangle topology adds a direct R1–R3 link (10.1.3.0/24) to the linear topology.

Bringing up the direct link (STEP 2)

no shutdown GigabitEthernet0/0/0/1 on R1 and R3 to bring up the direct link. In this topology R1 has two paths to R3’s Loopback0 (3.3.3.3/32): via the direct link (cost 2) and via R2 (cost 3). SPF selects the cheaper one, the direct link.

STEP 2 R1 after bringing up the direct link
RP/0/RP0/CPU0:R1#show ospf neighbor
Sun Sep  6 02:05:50.021 UTC

* Indicates MADJ interface
# Indicates Neighbor awaiting BFD session up

Neighbors for OSPF 1

Neighbor ID     Pri   State           Dead Time   Address         Interface
2.2.2.2         1     FULL/DR         00:00:33    10.1.2.2        GigabitEthernet0/0/0/0
    Neighbor is up for 00:05:46
3.3.3.3         1     FULL/DR         00:00:38    10.1.3.3        GigabitEthernet0/0/0/1
    Neighbor is up for 00:01:18

Total neighbor count: 2
RP/0/RP0/CPU0:R1#show route ospf
Sun Sep  6 02:05:50.923 UTC

O    2.2.2.2/32 [110/2] via 10.1.2.2, 00:05:16, GigabitEthernet0/0/0/0
O    3.3.3.3/32 [110/2] via 10.1.3.3, 00:00:48, GigabitEthernet0/0/0/1
O    10.2.3.0/24 [110/2] via 10.1.2.2, 00:00:48, GigabitEthernet0/0/0/0
                 [110/2] via 10.1.3.3, 00:00:48, GigabitEthernet0/0/0/1
RP/0/RP0/CPU0:R1#traceroute 3.3.3.3 source 1.1.1.1
Sun Sep  6 02:05:51.193 UTC

Type escape sequence to abort.
Tracing the route to 3.3.3.3

 1  10.1.3.3 20 msec  *  9 msec 

The route to 3.3.3.3/32 now has next hop 10.1.3.3 (cost 2) and traceroute reaches it in one hop. The segment between R2 and R3, 10.2.3.0/24, costs the same 2 whether it goes via R2 or via R3, so both next hops are installed. OSPF installs all of them when several paths have the same cost; this equal-cost multipath (ECMP) is covered in a later section.

Taking the direct link down (STEP 3)

Shut down both ends of the direct link (GigabitEthernet0/0/0/1 on R1 and R3) to simulate a link failure. The R1–R2 link was captured while doing so (43 packets in total).

No.TimeSourceDestinationInfo
10.00010.1.2.2224.0.0.5Hello Packet
25.96410.1.2.1224.0.0.5Hello Packet
39.04110.1.2.2224.0.0.5Hello Packet
410.45210.1.2.1224.0.0.5LS Update
512.45710.1.2.2224.0.0.5LS Acknowledge
1449.81410.1.2.2224.0.0.5LS Update
1551.85110.1.2.1224.0.0.5LS Acknowledge
28108.93310.1.2.2224.0.0.5LS Update
  • No.4: the LSU R1 sends right after shutting down its own GigabitEthernet0/0/0/1, flooding its updated Router-LSA.
  • No.5: the LSAck from R2.
  • No.14: before R3’s interface was shut down, R3’s updated Router-LSA and the removal of the Network-LSA for the direct segment arrive via R2.
  • No.28: R3’s Router-LSA update after its side was shut down as well.

Expanding the LSU in No.4 shows the number of links in R1’s Router-LSA dropping from 3 to 2: the direct segment to R3 (10.1.3.0/24) is gone, leaving only Loopback0 and the transit segment to R2. The sequence number has advanced to 0x80000005, so routers that receive it install it as a newer LSA and recompute SPF.

No.4 LS Update (R1 to 224.0.0.5, R1's Router-LSA after the failure)
Open Shortest Path First
    OSPF Header
        Version: 2
        Message Type: LS Update (4)
        Packet Length: 76
        Source OSPF Router: 1.1.1.1
        Area ID: 0.0.0.0 (Backbone)
        Checksum: 0x8720 [correct]
        Instance ID: Base IPv4 Unicast Instance (0)
        Auth Type: Null (0)
        Auth Data (none): 0000000000000000
    LS Update Packet
        Number of LSAs: 1
        LSA-type 1 (Router-LSA), len 48
            .000 0000 0000 0001 = LS Age (seconds): 1
            0... .... .... .... = Do Not Age Flag: 0
            Options: 0x22, (DC) Demand Circuits, (E) External Routing
                0... .... = DN: Not set
                .0.. .... = (O) Opaque: Not set
                ..1. .... = (DC) Demand Circuits: Supported
                ...0 .... = (L) LLS Data block: Not Present
                .... 0... = (N) NSSA: Not supported
                .... .0.. = (MC) Multicast: Not capable
                .... ..1. = (E) External Routing: Capable
                .... ...0 = (MT) Multi-Topology Routing: No
            LS Type: Router-LSA (1)
            Link State ID: 1.1.1.1
            Advertising Router: 1.1.1.1
            Sequence Number: 0x80000005
            Checksum: 0xaf45
            Length: 48
            Flags: 0x00
                0... .... = (H) Host: No
                ..0. .... = (S) Shortcut-capable ABR: No
                ...0 .... = (N) NSSA translation: No
                .... 0... = (W) Wild-card multicast receiver: No
                .... .0.. = (V) Virtual link endpoint: No
                .... ..0. = (E) AS boundary router: No
                .... ...0 = (B) Area border router: No
            Number of Links: 2
            Type: Stub     ID: 1.1.1.1         Data: 255.255.255.255 Metric: 1
                Link ID: 1.1.1.1 - IP network/subnet number
                Link Data: 255.255.255.255
                Link Type: 3 - Connection to a stub network
                Number of Metrics: 0 - TOS
                0 Metric: 1
            Type: Transit  ID: 10.1.2.2        Data: 10.1.2.1        Metric: 1
                Link ID: 10.1.2.2 - IP address of Designated Router
                Link Data: 10.1.2.1
                Link Type: 2 - Connection to a transit network
                Number of Metrics: 0 - TOS
                0 Metric: 1
Download the pcap of the packet in the tshark output above (No.4 LSU)

No.14 carries two LSAs. In R3’s Router-LSA the direct segment 10.1.3.0/24 has changed from Type: Transit to Type: Stub, because the adjacency with R1 is gone and no other router remains on that segment. At the same time the Network-LSA for that segment (Link State ID 10.1.3.3) is flushed with an LS Age of 3600 seconds (MaxAge) and removed from the LSDB.

No.14 LS Update (R2 to 224.0.0.5, R3's Router-LSA and the removal of the Network-LSA)
Open Shortest Path First
    OSPF Header
        Version: 2
        Message Type: LS Update (4)
        Packet Length: 120
        Source OSPF Router: 2.2.2.2
        Area ID: 0.0.0.0 (Backbone)
        Checksum: 0xa5b1 [correct]
        Instance ID: Base IPv4 Unicast Instance (0)
        Auth Type: Null (0)
        Auth Data (none): 0000000000000000
    LS Update Packet
        Number of LSAs: 2
        LSA-type 1 (Router-LSA), len 60
            .000 0000 0000 0010 = LS Age (seconds): 2
            0... .... .... .... = Do Not Age Flag: 0
            Options: 0x22, (DC) Demand Circuits, (E) External Routing
                0... .... = DN: Not set
                .0.. .... = (O) Opaque: Not set
                ..1. .... = (DC) Demand Circuits: Supported
                ...0 .... = (L) LLS Data block: Not Present
                .... 0... = (N) NSSA: Not supported
                .... .0.. = (MC) Multicast: Not capable
                .... ..1. = (E) External Routing: Capable
                .... ...0 = (MT) Multi-Topology Routing: No
            LS Type: Router-LSA (1)
            Link State ID: 3.3.3.3
            Advertising Router: 3.3.3.3
            Sequence Number: 0x80000005
            Checksum: 0x783e
            Length: 60
            Flags: 0x00
                0... .... = (H) Host: No
                ..0. .... = (S) Shortcut-capable ABR: No
                ...0 .... = (N) NSSA translation: No
                .... 0... = (W) Wild-card multicast receiver: No
                .... .0.. = (V) Virtual link endpoint: No
                .... ..0. = (E) AS boundary router: No
                .... ...0 = (B) Area border router: No
            Number of Links: 3
            Type: Stub     ID: 3.3.3.3         Data: 255.255.255.255 Metric: 1
                Link ID: 3.3.3.3 - IP network/subnet number
                Link Data: 255.255.255.255
                Link Type: 3 - Connection to a stub network
                Number of Metrics: 0 - TOS
                0 Metric: 1
            Type: Transit  ID: 10.2.3.3        Data: 10.2.3.3        Metric: 1
                Link ID: 10.2.3.3 - IP address of Designated Router
                Link Data: 10.2.3.3
                Link Type: 2 - Connection to a transit network
                Number of Metrics: 0 - TOS
                0 Metric: 1
            Type: Stub     ID: 10.1.3.0        Data: 255.255.255.0   Metric: 1
                Link ID: 10.1.3.0 - IP network/subnet number
                Link Data: 255.255.255.0
                Link Type: 3 - Connection to a stub network
                Number of Metrics: 0 - TOS
                0 Metric: 1
        LSA-type 2 (Network-LSA), len 32
            .000 1110 0001 0000 = LS Age (seconds): 3600
            0... .... .... .... = Do Not Age Flag: 0
            Options: 0x22, (DC) Demand Circuits, (E) External Routing
                0... .... = DN: Not set
                .0.. .... = (O) Opaque: Not set
                ..1. .... = (DC) Demand Circuits: Supported
                ...0 .... = (L) LLS Data block: Not Present
                .... 0... = (N) NSSA: Not supported
                .... .0.. = (MC) Multicast: Not capable
                .... ..1. = (E) External Routing: Capable
                .... ...0 = (MT) Multi-Topology Routing: No
            LS Type: Network-LSA (2)
            Link State ID: 10.1.3.3
            Advertising Router: 3.3.3.3
            Sequence Number: 0x80000002
            Checksum: 0x2edd
            Length: 32
            Netmask: 255.255.255.0
            Attached Router: 1.1.1.1
            Attached Router: 3.3.3.3
Download the pcap of the packet in the tshark output above (No.14 LSU)

Once R3’s interface is shut down as well, 10.1.3.0/24 disappears from R3’s Router-LSA altogether (No.28: link count 3 to 2, sequence number 0x80000006).

No.28 LS Update (R2 to 224.0.0.5, the Router-LSA after R3's side was shut down too)
Open Shortest Path First
    OSPF Header
        Version: 2
        Message Type: LS Update (4)
        Packet Length: 76
        Source OSPF Router: 2.2.2.2
        Area ID: 0.0.0.0 (Backbone)
        Checksum: 0x287a [correct]
        Instance ID: Base IPv4 Unicast Instance (0)
        Auth Type: Null (0)
        Auth Data (none): 0000000000000000
    LS Update Packet
        Number of LSAs: 1
        LSA-type 1 (Router-LSA), len 48
            .000 0000 0000 0010 = LS Age (seconds): 2
            0... .... .... .... = Do Not Age Flag: 0
            Options: 0x22, (DC) Demand Circuits, (E) External Routing
                0... .... = DN: Not set
                .0.. .... = (O) Opaque: Not set
                ..1. .... = (DC) Demand Circuits: Supported
                ...0 .... = (L) LLS Data block: Not Present
                .... 0... = (N) NSSA: Not supported
                .... .0.. = (MC) Multicast: Not capable
                .... ..1. = (E) External Routing: Capable
                .... ...0 = (MT) Multi-Topology Routing: No
            LS Type: Router-LSA (1)
            Link State ID: 3.3.3.3
            Advertising Router: 3.3.3.3
            Sequence Number: 0x80000006
            Checksum: 0xfdd6
            Length: 48
            Flags: 0x00
                0... .... = (H) Host: No
                ..0. .... = (S) Shortcut-capable ABR: No
                ...0 .... = (N) NSSA translation: No
                .... 0... = (W) Wild-card multicast receiver: No
                .... .0.. = (V) Virtual link endpoint: No
                .... ..0. = (E) AS boundary router: No
                .... ...0 = (B) Area border router: No
            Number of Links: 2
            Type: Stub     ID: 3.3.3.3         Data: 255.255.255.255 Metric: 1
                Link ID: 3.3.3.3 - IP network/subnet number
                Link Data: 255.255.255.255
                Link Type: 3 - Connection to a stub network
                Number of Metrics: 0 - TOS
                0 Metric: 1
            Type: Transit  ID: 10.2.3.3        Data: 10.2.3.3        Metric: 1
                Link ID: 10.2.3.3 - IP address of Designated Router
                Link Data: 10.2.3.3
                Link Type: 2 - Connection to a transit network
                Number of Metrics: 0 - TOS
                0 Metric: 1
Download the pcap of the packet in the tshark output above (No.28 LSU)

Having received the LSA updates, R1 recomputes SPF and switches the route to 3.3.3.3/32 to the path via R2 (cost 3). Traceroute now takes two hops.

STEP 3 R1 after the link failure
RP/0/RP0/CPU0:R1#show route ospf
Sun Sep  6 02:10:31.615 UTC

O    2.2.2.2/32 [110/2] via 10.1.2.2, 00:09:57, GigabitEthernet0/0/0/0
O    3.3.3.3/32 [110/3] via 10.1.2.2, 00:02:34, GigabitEthernet0/0/0/0
O    10.2.3.0/24 [110/2] via 10.1.2.2, 00:02:34, GigabitEthernet0/0/0/0
RP/0/RP0/CPU0:R1#traceroute 3.3.3.3 source 1.1.1.1
Sun Sep  6 02:10:31.829 UTC

Type escape sequence to abort.
Tracing the route to 3.3.3.3

 1  10.1.2.2 6 msec  5 msec  5 msec 
 2  10.2.3.3 9 msec  *  9 msec 

That SPF really did run again can be confirmed with show ospf trace spf. It ran twice, at 02:07:56 when R1’s side was shut down and at 02:09:35 when R3’s side was (the run at 02:08:36 is the recomputation triggered by R3’s LSA update).

R1 SPF runs around the link failure (excerpt from show ospf trace spf | include SPF)
497  Sep  6 02:07:56.969  ospf_run_spf: Begin SPF
503  Sep  6 02:07:56.970  ospf_run_spf:     SPF Dijkstra TRUE
506  Sep  6 02:07:56.970  ospf_update_done_cb: SPF complete: Elapse time:  0 ms.
523  Sep  6 02:07:56.970  ospf_run_spf: SPF Processing ends
528  Sep  6 02:08:36.377  ospf_run_spf: Begin SPF
534  Sep  6 02:08:36.377  ospf_run_spf:     SPF Dijkstra TRUE
537  Sep  6 02:08:36.377  ospf_update_done_cb: SPF complete: Elapse time:  0 ms.
554  Sep  6 02:08:36.377  ospf_run_spf: SPF Processing ends
559  Sep  6 02:09:35.496  ospf_run_spf: Begin SPF
565  Sep  6 02:09:35.496  ospf_run_spf:     SPF Dijkstra TRUE
568  Sep  6 02:09:35.496  ospf_update_done_cb: SPF complete: Elapse time:  0 ms.
585  Sep  6 02:09:35.496  ospf_run_spf: SPF Processing ends

Restoring the direct link (STEP 4)

Bringing both ends back up with no shutdown re-establishes the adjacency, and the route to 3.3.3.3/32 goes back to the direct link (cost 2).

STEP 4 R1 after restoring the direct link
RP/0/RP0/CPU0:R1#show ospf neighbor
Sun Sep  6 02:14:32.717 UTC

* Indicates MADJ interface
# Indicates Neighbor awaiting BFD session up

Neighbors for OSPF 1

Neighbor ID     Pri   State           Dead Time   Address         Interface
2.2.2.2         1     FULL/DR         00:00:31    10.1.2.2        GigabitEthernet0/0/0/0
    Neighbor is up for 00:14:29
3.3.3.3         1     FULL/DR         00:00:32    10.1.3.3        GigabitEthernet0/0/0/1
    Neighbor is up for 00:01:14

Total neighbor count: 2
RP/0/RP0/CPU0:R1#show route ospf
Sun Sep  6 02:14:33.476 UTC

O    2.2.2.2/32 [110/2] via 10.1.2.2, 00:13:59, GigabitEthernet0/0/0/0
O    3.3.3.3/32 [110/2] via 10.1.3.3, 00:00:44, GigabitEthernet0/0/0/1
O    10.2.3.0/24 [110/2] via 10.1.2.2, 00:00:43, GigabitEthernet0/0/0/0
                 [110/2] via 10.1.3.3, 00:00:43, GigabitEthernet0/0/0/1
RP/0/RP0/CPU0:R1#traceroute 3.3.3.3 source 1.1.1.1
Sun Sep  6 02:14:33.797 UTC

Type escape sequence to abort.
Tracing the route to 3.3.3.3

 1  10.1.3.3 7 msec  *  9 msec 

No operator rewrote any route. The router whose link state changed updated its LSA and flooded it, every router that received it recomputed SPF, and the route switched over and back on its own. That is how dynamic routing works.

Equal-cost multipath (ECMP)

SPF picks the lowest-cost route to each destination. However, it does not narrow the result down to one route when several routes have exactly the same cost. OSPF installs all of the equal-cost routes in the routing table and spreads traffic across them. This is called equal-cost multipath (ECMP).

An example already appeared in the show route ospf output of STEP 2. From R1, 10.2.3.0/24 (the segment between R2 and R3) is reachable through R2 (next hop 10.1.2.2) and through R3 (next hop 10.1.3.3) at the same cost of 2, so both next hops were installed. For a destination where the costs differ, such as 3.3.3.3/32 over the direct link (cost 2) versus through R2 (cost 3), only the lower one is selected as before.

This behavior is specified in RFC 2328 §2.4 and §16.8; it is not a vendor extension. Section 16.8 states that the multiple routes to one destination all have the same type (intra-area, inter-area, external type 1, external type 2), the same cost, and the same associated area, and differ only in their next hop and advertising router. It also states that a router is not required to keep track of every equal-cost route and that an implementation may keep only a fixed number of routes per destination. The limits shown below come from that provision.

Neither IOS XR nor IOS XE needs any special configuration to use ECMP. Whenever SPF produces equal costs, the multiple next hops are installed in the routing table (RIB) and the forwarding table (FIB) as they are. The STEP 2 output above came from a configuration that only puts the interfaces into router ospf 1. Some protocols, such as BGP, require multipath to be enabled explicitly (with maximum-paths), but OSPF has no such step.

Configuration is only needed when you want more paths than the default limit. The limit is changed with maximum-paths under router ospf.

PlatformCommandRangeDefault
IOS XRmaximum-paths under router ospf <process>1 to 88
IOS XEmaximum-paths under router ospf <process>1 to 324

These limits were not verified in this lab. They can differ between platforms and releases, so check the command reference for your version before changing them.

Note that it is not OSPF but the forwarding plane (CEF) that decides how traffic is spread over the multiple paths. The default is per-flow load sharing, using a hash of the source and destination addresses among other fields, rather than per-packet. Splitting the packets of one flow across different paths would reorder them and hurt TCP performance. As a result, a ping or a traceroute may well show only one of the paths even when ECMP is in effect.

Equal costs are not limited to intra-area routes. In OSPF external routes (redistributing static routes), two ASBRs advertise the same prefix as the same type 2 with the same seed metric, and the internal cost to each of them is equal, so both external routes end up in the routing table at the same time.

Verification config and show output

At every STEP the following three files were collected from all three routers, split per router. The verification config is the ..._run.txt file (the final state is the one from STEP 5).

FileContents
..._show.txtshow version / show interface description / show route / show route ospf / show ospf / show ospf interface / show ospf interface brief / show ospf neighbor / show ospf neighbor detail / show ospf database / show ospf database router / show ospf database network / show ospf statistics interface / show ospf routes / show ospf trace events / show ospf trace spf
..._log.txtshow logging narrowed down to that STEP. A marker is written with logmsg at the start of each STEP and its timestamp is passed to show logging start (STEP 0 holds the whole history since boot)
..._run.txtshow running-config at that STEP (that is, the verification config of that STEP)

Some STEPs also include the record of running clear ospf 1 process (..._clear.txt), show route ospf with traceroute (..._trace.txt), and an excerpt of show ospf trace spf | include SPF (..._trace-spf.txt).

STEP 0: initial state (linear topology; Gi0/0/0/1 on R1 and R3 shut down) — every link in area 0; R1–R2–R3 are Full

Routershowsyslogrunning-config
R1showlogrun
R2showlogrun
R3showlogrun

STEP 1: clear ospf 1 process on all three at once — neighbor establishment through LSDB synchronization, captured on the R1–R2 link

Routershowsyslogrunning-config
R1showlogrun
R2showlogrun
R3showlogrun

Additional: R1 clear / R2 clear / R3 clear

STEP 2: no shutdown Gi0/0/0/1 on R1 and R3 (triangle topology) — R1 to R3 switches to the direct link (cost 2)

Routershowsyslogrunning-config
R1showlogrun
R2showlogrun
R3showlogrun

Additional: R1 routes and traceroute

STEP 3: shutdown Gi0/0/0/1 on R1 and R3 (simulated failure) — switches to the path via R2 (cost 3); captured on the R1–R2 link

Routershowsyslogrunning-config
R1showlogrun
R2showlogrun
R3showlogrun

Additional: R1 routes and traceroute

STEP 4: no shutdown Gi0/0/0/1 on R1 and R3 again — back to the direct link (cost 2)

Routershowsyslogrunning-config
R1showlogrun
R2showlogrun
R3showlogrun

Additional: R1 routes and traceroute

STEP 5: shutdown Gi0/0/0/1 on R1 and R3 (final state) — restored to the same linear topology as the initial state

Routershowsyslogrunning-config
R1showlogrun
R2showlogrun
R3showlogrun

Additional: R1 SPF run history

The two capture files are below.

Download the capture of adjacency and LSDB sync, STEP 1 (ospf-adjacency.pcap)

Download the capture of the flooding on a link failure, STEP 3 (ospf-link-down.pcap)

References

RFCTitleSummary
RFC 2328OSPF Version 2The specification of OSPFv2 for IPv4.
RFC 5340OSPF for IPv6The specification of OSPFv3 for IPv6.

Related articles