NETWORKING MASTERY · PHASE 3 · MODULE 11 · WEEK 9
🔄 OSPF Internals
Link-state routing · LSA types · SPF algorithm · Areas · DR/BDR election · Convergence · OSPFv3
Intermediate Prerequisite: M10 Routing RFC 2328 · RFC 5340 Enterprise IGP 2 Labs

OSPF — OPEN SHORTEST PATH FIRST

🌐

What OSPF Is — Link-State Routing

OVERVIEW

OSPF (Open Shortest Path First, RFC 2328) is the dominant Interior Gateway Protocol (IGP) in enterprise and service-provider networks. It is a link-state routing protocol — each router builds a complete topological map of the network (the Link State Database, LSDB) and runs Dijkstra's shortest path algorithm on it to compute optimal routes.

Why link-state outperforms distance-vector (RIP):

  • No routing loops — each router has the full topology and computes paths independently; it doesn't relay information it learned from neighbours (which is how distance-vector creates loops)
  • Fast convergence — topology changes propagate as flooded LSAs; SPF recalculation can complete in milliseconds with incremental SPF
  • Scales to large networks — hierarchical areas limit LSDB size and SPF scope
  • Cost-based metric — OSPF cost is proportional to interface bandwidth; optimal path is truly the lowest-cost path, not just the fewest hops

OSPF runs over IP directly (Protocol 89) — not TCP or UDP. Uses multicast for most communication: 224.0.0.5 (all OSPF routers) and 224.0.0.6 (DR/BDR only).

📊

OSPF Cost — The Routing Metric

METRIC

OSPF uses cost as its metric. The default cost formula is 10^8 / interface_bandwidth_bps. Lower cost = better path. The cost of a route is the sum of costs of all outgoing interfaces on the path from source to destination.

/* Default OSPF costs (reference bandwidth = 100 Mbps) */
10 Mbps  Ethernet:  10^8 / 10^7  = 10
100 Mbps Ethernet:  10^8 / 10^8  = 1   (minimum default)
1 Gbps   Ethernet:  10^8 / 10^9  = 0.1 → rounds up to 1 (same as 100M!)
10 Gbps  Ethernet:  10^8 / 10^10 = 0.01 → rounds up to 1 (same!)

/* Problem: default reference bandwidth doesn't differentiate fast links */
/* Solution: increase reference bandwidth to 100 Gbps */

auto-cost reference-bandwidth 100000  # Cisco IOS (Mbps)
ip ospf cost 10                       # manual cost per interface

/* With 100G reference bandwidth */
1 Gbps:  10^11 / 10^9  = 100
10 Gbps: 10^11 / 10^10 = 10
100 Gbps: 10^11 / 10^11 = 1

/* Linux FRR OSPF */
vtysh
  router ospf
    ospf router-id 1.1.1.1
    network 192.168.0.0/24 area 0
    auto-cost reference-bandwidth 100000

OSPF NEIGHBOUR STATES — FROM DOWN TO FULL

🤝

OSPF Neighbour State Machine

STATES

OSPF neighbours must exchange the full LSDB before routing can start. This process goes through a defined sequence of states. Understanding these states is essential for troubleshooting OSPF — "stuck in 2-Way" or "stuck in Exstart" are common failure modes.

/* OSPF Neighbour States */

DOWN        No Hello received. Initial state or after timeout.

INIT        Hello received from neighbour, but our Router-ID
            not yet in their neighbour list.

2-WAY       Our Router-ID seen in neighbour's Hello.
            Bidirectional communication confirmed.
            On broadcast networks: DR/BDR election happens here.
            Non-DR/BDR neighbours stop here (2-Way with DR/BDR → Full).

EXSTART     Master/Slave election via DBD packets.
            Higher Router-ID becomes Master, controls sequence numbers.

EXCHANGE    Routers exchange Database Description (DBD) packets —
            summaries of their LSDB (LSA headers only, not full LSAs).

LOADING     Router sends LSR (Link State Request) for LSAs it's missing.
            Neighbour sends LSU (Link State Update) with the requested LSAs.

FULL        LSDBs are synchronised. Routing table can be computed.
            This is the healthy operational state.

/* Hello packet fields that must match for neighbour formation */
Area ID:             must be identical
Authentication:      must match (none/simple/MD5)
Hello interval:      must match (default 10s point-to-point, 10s broadcast)
Dead interval:       must match (default 40s = 4 × hello)
Subnet mask:         must match (point-to-point links exempt)
Stub area flag:      must match

/* Troubleshooting stuck neighbours */
show ip ospf neighbor           # current state
show ip ospf neighbor detail    # full detail including timers
debug ip ospf adj               # live adjacency events

/* Stuck in EXSTART: MTU mismatch — one side has jumbo frames, other doesn't */
# DBD packets use the interface MTU — if mismatched, packets get fragmented
# Fix: ip ospf mtu-ignore  (or fix the MTU)
📡

Hello Protocol — The OSPF Heartbeat

HELLO

OSPF Hello packets are sent periodically to discover and maintain neighbour relationships. Sent to multicast 224.0.0.5 (all OSPF routers) on broadcast networks, or unicast on point-to-point links.

/* Hello packet key fields */
Router ID:       4-byte identifier for this router (highest loopback IP, or manually set)
Area ID:         which OSPF area this interface belongs to
Auth Type/Data:  authentication (0=none, 1=cleartext, 2=MD5 hmac)
Hello Interval:  how often this router sends Hellos (default 10s)
Dead Interval:   time without Hello before declaring neighbour dead (default 40s)
DR:              IP of current Designated Router (0.0.0.0 if unknown)
BDR:             IP of current Backup DR
Neighbour List:  Router IDs of all neighbours from whom we've heard Hellos

/* Timers — trade-off between convergence speed and CPU load */
Default:      Hello=10s, Dead=40s   → convergence after 40s
Fast:         Hello=1s,  Dead=4s    → convergence after 4s (higher CPU)
BFD:          sub-second detection  → millisecond convergence (separate protocol)

/* Linux FRR — configure OSPF timers per interface */
interface eth0
  ip ospf hello-interval 1
  ip ospf dead-interval 4

LSA TYPES — THE BUILDING BLOCKS OF THE LINK STATE DATABASE

📋

LSA Types — What Each Describes

LSA REFERENCE

Link State Advertisements (LSAs) are the data records in OSPF's distributed database. Each LSA describes a piece of the network topology. Routers flood LSAs throughout the network (or area) so every router has an identical copy of the LSDB.

TypeNameGenerated ByFlooded ToDescribes
1Router LSAEvery routerWithin areaRouter's own links (interfaces), their types, and costs. Every router generates one Type 1 LSA per area it belongs to.
2Network LSADR onlyWithin areaList of all routers attached to a multi-access (broadcast) segment. Only generated when DR exists (broadcast/NBMA networks).
3Summary LSAABR (Area Border Router)Between areasPrefix reachability information from one area advertised into other areas. ABR summarises intra-area prefixes as inter-area routes.
4ASBR Summary LSAABRBetween areasTells other areas how to reach an ASBR (AS Boundary Router — a router that redistributes external routes into OSPF).
5External LSA (AS External)ASBREntire OSPF domainExternal routes redistributed into OSPF (from BGP, static, RIP, connected). Type E1 includes OSPF path cost; Type E2 does not.
7NSSA External LSAASBR in NSSANSSA area only → converted to Type 5 at ABRExternal routes in Not-So-Stubby Areas. Allows external route origination without flooding Type 5 into the stub area.
9/10/11Opaque LSAAny routerLink/Area/Domain scopeExtension mechanism for OSPF — carries TE (Traffic Engineering) extensions, MPLS TE, Segment Routing info.

💡 Type 1 and Type 2 build the intra-area topology map. Type 3 extends reachability between areas. Type 5 brings external routes into OSPF. The SPF algorithm uses Types 1 and 2 to compute shortest paths. Types 3, 4, 5 are handled with Bellman-Ford style processing (not Dijkstra — they're already summarised distances, not raw topology).

🔄

LSA Flooding and Reliability

FLOODING

OSPF uses reliable flooding to ensure every router in the area gets every LSA. When a router receives a new or updated LSA, it floods it out all interfaces except the one it arrived on. Receivers acknowledge receipt with explicit LSAck packets.

/* LSA versioning — Sequence Number + Age */
LSA fields for version control:
  Sequence Number:  32-bit counter, starts at 0x80000001, increments on each update
                    Higher = newer. MaxSequenceNumber (0x7FFFFFFF) triggers refresh.
  LSA Age:          seconds since originated. Incremented by each router in transit.
                    MaxAge (3600s) = LSA is stale, should be purged.
  LS Checksum:      integrity check over LSA (excluding Age field)

/* Database Exchange summary */
show ip ospf database          # list all LSAs in LSDB
show ip ospf database router   # Type 1 LSAs only
show ip ospf database summary  # Type 3 LSAs only
show ip ospf database external # Type 5 LSAs

/* LSA refresh — prevent premature aging */
# Each router re-originates its own LSAs every 30 minutes (LSRefreshTime)
# This resets the Age counter so they don't expire (MaxAge = 3600s)

SPF — DIJKSTRA'S SHORTEST PATH FIRST ALGORITHM

🧮

How Dijkstra's SPF Works in OSPF

ALGORITHM

After collecting all LSAs and building the LSDB (the complete topological graph), each router independently runs Dijkstra's SPF algorithm to compute the shortest (lowest-cost) path to every destination. The algorithm is deterministic — given the same LSDB, every router computes identical results.

/* Dijkstra's algorithm — simplified */
Input:  LSDB (directed graph of routers and links with costs)
Output: Shortest Path Tree (SPT) rooted at this router

1. Mark all routers with distance = ∞, except self = 0.
2. Put all routers in a priority queue (tentative set), keyed by distance.
3. While priority queue not empty:
   a. Extract router R with minimum distance from queue
   b. Mark R as "confirmed" (add to SPT)
   c. For each neighbour N of R (from R's Router LSA):
      new_dist = dist(R) + cost(R→N)
      if new_dist < dist(N):
          dist(N) = new_dist
          predecessor(N) = R
          Update N's priority in queue
4. SPT complete — predecessor array gives next-hop for each destination.

/* Worked example */
Network:  R1─(1)─R2─(1)─R4
           └─(10)─────────R3─(1)─R4

Computing SPT from R1:
Confirmed: {R1=0}
Tentative: {R2=1, R3=10}

Extract R2 (cost 1):
  Confirmed: {R1=0, R2=1}
  R4 via R2: cost = 1+1 = 2 → add R4=2
  Tentative: {R3=10, R4=2}

Extract R4 (cost 2):
  Confirmed: {R1=0, R2=1, R4=2}
  R3 via R4: cost = 2+1 = 3 → update R3=3 (was 10!)
  Tentative: {R3=3}

Extract R3 (cost 3):
  Confirmed: {R1=0, R2=1, R4=2, R3=3}

Result:
  R4 → via R2 (cost 2) — NOT via R3 (cost 11)
  R3 → via R2→R4 (cost 3) — NOT direct (cost 10)

💡 SPF can be computationally expensive on large networks. A full SPF run on a 1000-router network takes milliseconds, but running it for every link flap would be unacceptable. OSPF uses SPF throttling: the first SPF runs immediately, subsequent SPF runs are delayed increasingly (1s, 5s, 10s…) to batch multiple topology changes. Incremental SPF (partial SPF) only recomputes paths affected by the changed LSA — much faster.

OSPF AREAS AND DR/BDR ELECTION

🏗️

OSPF Areas — Hierarchical Scaling

AREAS

A single OSPF domain with thousands of routers would have a massive LSDB and run SPF constantly. OSPF uses areas to divide the network hierarchically, limiting LSDB size and SPF scope within each area.

Area TypeContainsAcceptsUse Case
Backbone (Area 0)All Type 1,2,3,5 LSAsAll LSA typesCore transit area — all areas must connect to it (directly or virtually)
Regular AreaType 1,2,3,5 LSAsAll LSA typesStandard non-backbone area with external routes
Stub AreaType 1,2,3 LSAs (no Type 5)No external LSAs; default route injected insteadLeaf areas with no external connectivity; reduces LSDB size
Totally StubbyType 1,2 LSAs onlyNo Type 3 or 5; only default routeMaximum LSDB reduction for hub-and-spoke leaves
NSSAType 1,2,3,7 LSAsExternal routes via Type 7 (converted to Type 5 at ABR)Stub area that needs to originate external routes (e.g., redistributed connected routes)
/* Router roles in OSPF */
Internal Router:    all interfaces in same area
ABR (Area Border):  interfaces in multiple areas — sits on area boundary
ASBR (AS Boundary): redistributes routes from/to external protocols (BGP, static)
Backbone Router:    has at least one interface in Area 0

/* Virtual links — connect non-adjacent areas to Area 0 */
router ospf 1
  area 2 virtual-link 3.3.3.3  # create virtual link through area 2 to router 3.3.3.3
👑

DR and BDR Election — Reducing Adjacencies on Broadcast Networks

DR/BDR

On a broadcast segment (Ethernet) with N routers, forming full-mesh adjacencies requires N×(N-1)/2 adjacency pairs — with 10 routers that's 45 full adjacencies, each exchanging the full LSDB. OSPF solves this with a Designated Router (DR) and Backup Designated Router (BDR):

  • All routers form full adjacency with the DR and BDR only
  • Non-DR/BDR routers reach state 2-WAY with each other — not FULL
  • All LSA flooding goes through the DR (sent to 224.0.0.5, DR forwards to 224.0.0.6)
  • With 10 routers: only 2×(N-1) = 18 adjacencies instead of 45
/* DR/BDR Election process */
1. All routers send Hellos with their Priority and Router-ID
2. Router with highest Priority wins DR election (default priority = 1)
3. Tie-break: highest Router-ID wins
4. Second-highest priority/RID wins BDR
5. Priority 0 = ineligible for DR/BDR (always a DROther)

/* Important: DR election is NOT preemptive */
# Even if a router with higher priority joins later, the current DR stays
# DR changes only when current DR fails
# This prevents constant re-election on flapping networks

/* Setting DR priority */
interface GigabitEthernet0/0
  ip ospf priority 100   # make this the preferred DR
  ip ospf priority 0     # never become DR

/* Verify DR/BDR */
show ip ospf interface GigabitEthernet0/0
# "Designated Router (ID) 2.2.2.2, Interface address 192.168.1.2"
# "Backup Designated router (ID) 1.1.1.1, Interface address 192.168.1.1"

OSPF CONVERGENCE — TIMERS, FAILURE DETECTION, AND TUNING

⏱️

OSPF Convergence Timeline

CONVERGENCE
/* What happens when a link fails */

T=0:       Link goes down
T=0:       Router detects link down (interface state change — instantaneous)
T=0:       Router generates new Router LSA (Type 1) marking the link as failed
T=0–0.1:   LSA flooded to all routers in the area
T=0–0.1:   Each router runs incremental SPF
T=0–0.1:   FIB updated — traffic rerouted
           Total: sub-second convergence for link-down detection!

/* What happens when a router fails (link stays up, router crashes) */

T=0:       Router crashes
T=0–40:    Other routers still send Hellos, get no response
T=40:      Dead interval expires — router declared dead
T=40:      LSA generated removing dead router
T=40:      LSA flooded + SPF runs
T=40+:     Routes converged
           Total: default 40 seconds! Much slower.

/* Solutions for fast failure detection */

Option 1: Reduce timers (Hello=1s, Dead=4s)
  Con: 4x more Hello processing; sensitive to packet loss

Option 2: BFD (Bidirectional Forwarding Detection)
  Sub-second (ms) failure detection, separate from OSPF
  OSPF reacts when BFD reports peer down (before Dead interval)
  bfd interval 100 min_rx 100 multiplier 3   # 300ms detection

Option 3: OSPF Fast Hello (hello every 1 second, dead 4 seconds)
  interface eth0
    ip ospf dead-interval minimal hello-multiplier 4  # hello = dead/4 = 250ms
🔧

Key OSPF Timers

TIMERS
TimerDefaultPurpose
Hello Interval10s (broadcast), 30s (NBMA)How often Hello packets are sent
Dead Interval4 × Hello (40s or 120s)How long to wait before declaring neighbour dead
Retransmit Interval5sHow long to wait for LSAck before retransmitting LSU
SPF Delay5sDelay before running SPF after topology change (prevents SPF thrashing)
SPF Hold Time10sMinimum time between successive full SPF runs
LSA Refresh Time30 minHow often routers re-originate their own LSAs to prevent aging out
MaxAge3600s (1 hr)LSA expires and is purged after this age

OSPFv3 — OSPF FOR IPv6 (RFC 5340)

🔵

OSPFv3 vs OSPFv2 — Key Differences

OSPFv3
FeatureOSPFv2OSPFv3
IP versionIPv4IPv6 (also supports IPv4 with address families)
TransportIP Protocol 89IPv6 Protocol 89
Router ID32-bit IPv4 address32-bit value (looks like IPv4 but is just an ID, not an address)
Addressing in packetsIPv4 addresses in LSAsLink-local addresses for neighbour communication; global addresses in separate LSA types
AuthenticationBuilt-in (cleartext or MD5)Uses IPsec AH/ESP (authentication outsourced)
New LSA typesType 1–5, 7Adds Type 8 (Link LSA), Type 9 (Intra-Area Prefix LSA). Type 1/2 no longer carry IP prefixes.
Multiple instancesOne per linkMultiple OSPFv3 instances per link (different instance IDs)
/* Linux FRR: configure OSPFv3 */
vtysh
  router ospf6
    ospf6 router-id 1.1.1.1   # must set manually (no IPv4 to borrow)
    interface eth0 area 0.0.0.0

  interface eth0
    ipv6 ospf6 area 0.0.0.0

show ipv6 ospf6 neighbor
show ipv6 ospf6 database
show ipv6 ospf6 route

/* Verify OSPFv3 uses link-local source addresses */
# Hellos sent from fe80::... not global unicast
# Link-local = no router will forward these beyond the segment
LAB 1

OSPF with FRR on Linux — Full Network Simulation

Objective: Build a 3-router OSPF topology using Linux network namespaces and FRR. Observe neighbour formation, LSDB contents, SPF computation, and convergence on link failure.

1
Install FRR: sudo apt install frr. Enable OSPF: in /etc/frr/daemons, set ospfd=yes. Restart: sudo systemctl restart frr. Access FRR CLI: sudo vtysh.
2
Create 3 network namespaces as routers using veth pairs. Configure IP addresses: R1(10.0.12.1/30 ↔ R2(10.0.12.2/30), R2(10.0.23.1/30) ↔ R3(10.0.23.2/30), R1 has loopback 1.1.1.1/32, R3 has loopback 3.3.3.3/32.
3
Configure OSPF on all three: router ospf; ospf router-id X.X.X.X; network 0.0.0.0/0 area 0. Verify neighbours reach FULL state: show ip ospf neighbor. Observe the 4-state transition in logs.
4
Examine the LSDB: show ip ospf database. Identify: how many Type 1 LSAs? Which router generated the Type 2 LSA? What prefixes appear in the database?
5
Test reachability: from R1, ping 3.3.3.3. Verify route learned: show ip route ospf. Now simulate link failure: ip link set veth12 down. Watch convergence — how long until ping recovers?
LAB 2

Dijkstra SPF Implementation

Objective: Implement Dijkstra's algorithm in Python to simulate what OSPF's SPF calculation does, given a network topology described as a graph.

1
Represent a network as an adjacency list: graph = {'R1': [('R2',1),('R3',10)], 'R2': [('R1',1),('R4',1)], 'R3': [('R1',10),('R4',1)], 'R4': [('R2',1),('R3',1)]}. Implement Dijkstra using a priority queue (heapq).
2
Output the shortest path tree from R1: for each destination, print the path (sequence of routers) and total cost. Verify: R1→R4 should go R1→R2→R4 (cost 2), not R1→R3→R4 (cost 11).
3
Simulate link failure: remove the R1↔R2 link. Re-run Dijkstra. Verify R4 is now reached via R1→R3→R4 (cost 11). This is what OSPF SPF re-computes after a topology change.

M11 MASTERY CHECKLIST

When complete: Move to M12 - BGP Internals. Where OSPF is the IGP within an organisation's network, BGP is the EGP that connects organisations together across the internet — and is also used within large networks (iBGP) for scalability.

← M10 Routing 🗺️ Roadmap Next: M12 - BGP →