OSPF Summary LSA Loop Prevention

A networking-focused entity known only as humblegrumble sent me the following question after reading my When OSPF Becomes a Distance Vector Protocol article:

How do A1 and A2 know not to advertise a Type-3 summary LSA generated from area 1 prefixes back into area 1?

He’s right. There is no “originating area” information in the type-3 LSA, so how does an ABR know not to reinsert the type-3 LSA generated by another ABR back into the area?

TL&DR: The OSPF route selection process takes care of that.

Want to know the gory details? Let’s examine them using this sample network:

  • A1 and A2 are ABRs. The link between them is in area 0 (black).
  • S1 and S2 are in area 1, as are their links with the ABRs (green).
  • R2 is in area 2 (blue), and R3 is in area 3 (red).
  • Each ABR is thus in three areas: the backbone area, area 1, and area 2 or 3.
  • All point-to-point links are unnumbered. The only prefixes we should see in the OSPF data and the IP routing table are the loopback prefixes.

After starting the lab, you should see the following summary LSAs on A2 (the printout on A1 is similar, but has the summary LSA information for area 2):

Summary LSAs on A2 (edited to remove router link states)
a2# show ip ospf database

       OSPF Router with ID (10.0.0.4)

                Summary Link States (Area 0.0.0.0)

Link ID         ADV Router      Age  Seq#       CkSum  Route
10.0.0.5       10.0.0.3         265 0x80000001 0xae88 10.0.0.5/32
10.0.0.6       10.0.0.4         264 0x80000001 0x9e96 10.0.0.6/32
192.168.0.1    10.0.0.3         265 0x80000001 0xa734 192.168.0.1/32
192.168.0.1    10.0.0.4         264 0x80000001 0x06ca 192.168.0.1/32
192.168.0.2    10.0.0.3         265 0x80000001 0x02ce 192.168.0.2/32
192.168.0.2    10.0.0.4         264 0x80000001 0x9742 192.168.0.2/32

                Summary Link States (Area 0.0.0.1)

Link ID         ADV Router      Age  Seq#       CkSum  Route
10.0.0.3       10.0.0.3         281 0x80000001 0x5ee4 10.0.0.3/32
10.0.0.3       10.0.0.4         274 0x80000001 0xbc7b 10.0.0.3/32
10.0.0.4       10.0.0.3         276 0x80000001 0xb87f 10.0.0.4/32
10.0.0.4       10.0.0.4         279 0x80000001 0x4ef2 10.0.0.4/32
10.0.0.5       10.0.0.3         267 0x80000001 0xae88 10.0.0.5/32
10.0.0.5       10.0.0.4         264 0x80000001 0x0d1f 10.0.0.5/32
10.0.0.6       10.0.0.3         267 0x80000001 0x0923 10.0.0.6/32
10.0.0.6       10.0.0.4         264 0x80000001 0x9e96 10.0.0.6/32

                Summary Link States (Area 0.0.0.3)

Link ID         ADV Router      Age  Seq#       CkSum  Route
10.0.0.3       10.0.0.4         274 0x80000001 0xbc7b 10.0.0.3/32
10.0.0.4       10.0.0.4         279 0x80000001 0x4ef2 10.0.0.4/32
10.0.0.5       10.0.0.4         264 0x80000001 0x0d1f 10.0.0.5/32
192.168.0.1    10.0.0.4         264 0x80000001 0x06ca 192.168.0.1/32
192.168.0.2    10.0.0.4         264 0x80000001 0x9742 192.168.0.2/32

Indeed, the summary LSA for 192.168.0.1/32 is inserted into area 3, but not back into area 1.

As we know, OSPF would never consider a path that is not the best path to a destination. The next step on our journey should thus be the OSPF routes (the results of the SPF calculation):

OSPF routes on A2
a2# show ip ospf route
============ OSPF network routing table ============
N    10.0.0.3/32           [10] area: 0.0.0.0
                           via 10.0.0.3, eth1
N    10.0.0.4/32           [0] area: 0.0.0.0
                           directly attached to lo
N IA 10.0.0.5/32           [20] area: 0.0.0.0
                           via 10.0.0.3, eth1
N    10.0.0.6/32           [10] area: 0.0.0.3
                           via 10.0.0.6, eth3
N    192.168.0.1/32        [20] area: 0.0.0.1
                           via 192.168.0.2, eth2
N    192.168.0.2/32        [10] area: 0.0.0.1
                           via 192.168.0.2, eth2

============ OSPF router routing table =============
R    10.0.0.3              [30] area: 0.0.0.1, ABR
                           via 192.168.0.2, eth2
                           [10] area: 0.0.0.0, ABR
                           via 10.0.0.3, eth1

A2 prefers the path A2-S2-S1, which is indeed the lowest-cost path to S1. However, all links in our network have equal OSPF cost (10). If we change the cost of the S2-A2 link to 50, we might force A2 to take the path through A1, right?

Nope. Even though the cost to reach 192.168.0.1/32 has increased to 60, A2 still doesn’t want to consider the better path through area 0.

OSPF routes on A2 after changing the A2-S2 cost to 50
a2# show ip ospf route
============ OSPF network routing table ============
N    10.0.0.3/32           [10] area: 0.0.0.0
                           via 10.0.0.3, eth1
N    10.0.0.4/32           [0] area: 0.0.0.0
                           directly attached to lo
N IA 10.0.0.5/32           [20] area: 0.0.0.0
                           via 10.0.0.3, eth1
N    10.0.0.6/32           [10] area: 0.0.0.3
                           via 10.0.0.6, eth3
N    192.168.0.1/32        [60] area: 0.0.0.1
                           via 192.168.0.2, eth2
N    192.168.0.2/32        [50] area: 0.0.0.1
                           via 192.168.0.2, eth2

============ OSPF router routing table =============
R    10.0.0.3              [70] area: 0.0.0.1, ABR
                           via 192.168.0.2, eth2
                           [10] area: 0.0.0.0, ABR
                           via 10.0.0.3, eth1

The root cause of that behavior is the bullet (6) in section 16.2 of the OSPFv2 RFC that describes how to deal with inter-area routes (summary LSAs):

Else, if the paths present in the table are intra-area paths, do nothing with the LSA (intra-area paths are always preferred).

As I wrote in 2008:

Intra-area routes are preferred over inter-area or external routes regardless of their cost.

So far, so good, but how does that impact the generation of summary LSAs? The summary LSAs are generated from the OSPF routing table (the results of the SPF calculation) (RFC 2328, section 12.4.3):

Summary-LSAs are originated by area border routers. The precise summary routes to advertise into an area are determined by examining the routing table structure (see Section 11) in accordance with the algorithm described below. Note that only intra-area routes are advertised into the backbone, while both intra-area and inter-area routes are advertised into the other areas.

The backbone summary LSA for 192.168.0.1/32 is not in the OSPF routing table on A2 (it prefers the more expensive intra-area route) and thus never gets inserted back into area 1. Likewise, the summary LSA inserted into area 3 has a higher cost than it would have had were A2 considering the backbone summary LSA:

Summary LSA observed by R3 (in area 3)
r3# show ip ospf database summary 192.168.0.1

       OSPF Router with ID (10.0.0.6)


                Summary Link States (Area 0.0.0.3)

  LS age: 970
  Options: 0x2  : *|-|-|-|-|-|E|-
  LS Flags: 0x6
  LS Type: summary-LSA
  Link State ID: 192.168.0.1 (summary Network Number)
  Advertising Router: 10.0.0.4
  LS Seq Number: 80000002
  Checksum: 0x9512
  Length: 28

  Network Mask: /32
        TOS: 0  Metric: 60

Double-Checking Our Conclusions

Let’s double-check our conclusions. If the intra-area route is the only obstacle stopping A2 from inserting a summary LSA into area 1, then partitioning the area (disconnecting the link between S1 and S2) should remove that obstacle, and we should see a backbone summary LSA generated from area 1 reinserted into the other part of area 1.

OSPF LSAs carry no area information. Thus, it’s perfectly legal, albeit not wise, to have multiple disjoint network areas with the same area number.

That’s exactly what happens. The router LSA describing S1 remains in the OSPF database of A2, but it’s no longer connected to any other LSA in the same area, and is thus ignored in the SPF calculation.

Area 1 router LSAs in the OSPF database on A2
a2# show ip ospf database

       OSPF Router with ID (10.0.0.4)
...
                Router Link States (Area 0.0.0.1)

Link ID         ADV Router      Age  Seq#       CkSum  Link count
10.0.0.3       10.0.0.3         369 0x80000006 0xbcca 1
10.0.0.4       10.0.0.4        1395 0x80000006 0xc196 1
192.168.0.1    192.168.0.1      358 0x8000000a 0xd01b 3
192.168.0.2    192.168.0.2       38 0x8000000c 0xfea2 2

The best OSPF route for 192.168.0.1/32 is thus the summary LSA originated in the backbone area by A1:

Best OSPF routes on A2
a2# show ip ospf route
============ OSPF network routing table ============
N    10.0.0.3/32           [10] area: 0.0.0.0
                           via 10.0.0.3, eth1
N    10.0.0.4/32           [0] area: 0.0.0.0
                           directly attached to lo
N IA 10.0.0.5/32           [20] area: 0.0.0.0
                           via 10.0.0.3, eth1
N    10.0.0.6/32           [10] area: 0.0.0.3
                           via 10.0.0.6, eth3
N IA 192.168.0.1/32        [20] area: 0.0.0.0
                           via 10.0.0.3, eth1
N    192.168.0.2/32        [50] area: 0.0.0.1
                           via 192.168.0.2, eth2

A2 thus inserts the summary LSA for 192.168.0.1/32 into (a different) area 1:

Area 1 summary LSAs in the OSPF database on A2
a2# show ip ospf database

       OSPF Router with ID (10.0.0.4)
...
                Summary Link States (Area 0.0.0.1)

Link ID         ADV Router      Age  Seq#       CkSum  Route
10.0.0.3       10.0.0.3         653 0x80000002 0x5ce5 10.0.0.3/32
10.0.0.3       10.0.0.4         650 0x80000002 0xba7c 10.0.0.3/32
10.0.0.4       10.0.0.3         683 0x80000002 0xb680 10.0.0.4/32
10.0.0.4       10.0.0.4         660 0x80000002 0x4cf3 10.0.0.4/32
10.0.0.5       10.0.0.3         623 0x80000002 0xac89 10.0.0.5/32
10.0.0.5       10.0.0.4         670 0x80000002 0x0b20 10.0.0.5/32
10.0.0.6       10.0.0.3         663 0x80000002 0x0724 10.0.0.6/32
10.0.0.6       10.0.0.4         620 0x80000002 0x9c97 10.0.0.6/32
192.168.0.1    10.0.0.4         341 0x80000001 0x06ca 192.168.0.1/32

The OSPF database on A2 still contains the summary LSAs created by A1 before the area partitioning. Those LSAs are no longer used because there’s no way to reach A1 through area 1. They will disappear only after their age exceeds the MaxAge (1 hour, specified in the RFC, not negotiable).

There is no way to flush those LSAs from the OSPF database. Resetting the OSPF process on A2 will remove them, but they will reappear as soon as the A2-S2 adjacency is reestablished and S2 tells A2 it has a few interesting LSAs to share (more scary details).

Reproducing the Results

I used the following netlab topology when writing this blog post. You can start it (immediately and free-of-charge) in a GitHub Codespace container – change the directory within the Codespace container to OSPF/area-range and execute netlab up. Have fun.

module: [ ospf ]
provider: clab
defaults.device: frr
addressing.p2p.ipv4: True

nodes:
  s1:
    ospf.area: 1
    loopback.ipv4: 192.168.0.1/32
  s2:
    ospf.area: 1
    loopback.ipv4: 192.168.0.2/32
  a1:
    ospf.area: 0
  a2:
    ospf.area: 0
  r2:
    ospf.area: 2
  r3:
    ospf.area: 3

links:
- group: backbone
  ospf.area: 0
  members: [ a1-a2 ]
- group: area_1
  ospf.area: 1
  members: [ s1-a1, s2-a2, s1-s2 ]
- group: area_2
  ospf.area: 2
  members: [ r2-a1 ]
- group: area_3
  ospf.area: 3
  members: [ r3-a2 ]

Notes:

  • I set the loopback addresses on S1 and S2 to fixed values to make them stand out in the routing tables (lines 9 and 12)
  • The OSPF area of a node’s loopback interface has to be specified in the node data (lines 8, 11, 14, 16, 18, and 20). The default OSPF area is zero (backbone), but I still specified it on A1 and A2 to make it more evident.
  • If the attached nodes have different OSPF areas, the link’s OSPF area might have to be specified (lines 27, 30, and 33).
  • I used link groups to set the same ospf.area on multiple links. The group names also nicely describe what the links do.
Add comment
Sidebar