OSPF — OPEN SHORTEST PATH FIRST
What OSPF Is — Link-State Routing
OVERVIEWOSPF (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
METRICOSPF 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
STATESOSPF 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
HELLOOSPF 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 REFERENCELink 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.
| Type | Name | Generated By | Flooded To | Describes |
|---|---|---|---|---|
1 | Router LSA | Every router | Within area | Router's own links (interfaces), their types, and costs. Every router generates one Type 1 LSA per area it belongs to. |
2 | Network LSA | DR only | Within area | List of all routers attached to a multi-access (broadcast) segment. Only generated when DR exists (broadcast/NBMA networks). |
3 | Summary LSA | ABR (Area Border Router) | Between areas | Prefix reachability information from one area advertised into other areas. ABR summarises intra-area prefixes as inter-area routes. |
4 | ASBR Summary LSA | ABR | Between areas | Tells other areas how to reach an ASBR (AS Boundary Router — a router that redistributes external routes into OSPF). |
5 | External LSA (AS External) | ASBR | Entire OSPF domain | External routes redistributed into OSPF (from BGP, static, RIP, connected). Type E1 includes OSPF path cost; Type E2 does not. |
7 | NSSA External LSA | ASBR in NSSA | NSSA area only → converted to Type 5 at ABR | External routes in Not-So-Stubby Areas. Allows external route origination without flooding Type 5 into the stub area. |
9/10/11 | Opaque LSA | Any router | Link/Area/Domain scope | Extension 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
FLOODINGOSPF 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
ALGORITHMAfter 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
AREASA 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 Type | Contains | Accepts | Use Case |
|---|---|---|---|
| Backbone (Area 0) | All Type 1,2,3,5 LSAs | All LSA types | Core transit area — all areas must connect to it (directly or virtually) |
| Regular Area | Type 1,2,3,5 LSAs | All LSA types | Standard non-backbone area with external routes |
| Stub Area | Type 1,2,3 LSAs (no Type 5) | No external LSAs; default route injected instead | Leaf areas with no external connectivity; reduces LSDB size |
| Totally Stubby | Type 1,2 LSAs only | No Type 3 or 5; only default route | Maximum LSDB reduction for hub-and-spoke leaves |
| NSSA | Type 1,2,3,7 LSAs | External 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/BDROn 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| Timer | Default | Purpose |
|---|---|---|
| Hello Interval | 10s (broadcast), 30s (NBMA) | How often Hello packets are sent |
| Dead Interval | 4 × Hello (40s or 120s) | How long to wait before declaring neighbour dead |
| Retransmit Interval | 5s | How long to wait for LSAck before retransmitting LSU |
| SPF Delay | 5s | Delay before running SPF after topology change (prevents SPF thrashing) |
| SPF Hold Time | 10s | Minimum time between successive full SPF runs |
| LSA Refresh Time | 30 min | How often routers re-originate their own LSAs to prevent aging out |
| MaxAge | 3600s (1 hr) | LSA expires and is purged after this age |
OSPFv3 — OSPF FOR IPv6 (RFC 5340)
OSPFv3 vs OSPFv2 — Key Differences
OSPFv3| Feature | OSPFv2 | OSPFv3 |
|---|---|---|
| IP version | IPv4 | IPv6 (also supports IPv4 with address families) |
| Transport | IP Protocol 89 | IPv6 Protocol 89 |
| Router ID | 32-bit IPv4 address | 32-bit value (looks like IPv4 but is just an ID, not an address) |
| Addressing in packets | IPv4 addresses in LSAs | Link-local addresses for neighbour communication; global addresses in separate LSA types |
| Authentication | Built-in (cleartext or MD5) | Uses IPsec AH/ESP (authentication outsourced) |
| New LSA types | Type 1–5, 7 | Adds Type 8 (Link LSA), Type 9 (Intra-Area Prefix LSA). Type 1/2 no longer carry IP prefixes. |
| Multiple instances | One per link | Multiple 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
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.
sudo apt install frr. Enable OSPF: in /etc/frr/daemons, set ospfd=yes. Restart: sudo systemctl restart frr. Access FRR CLI: sudo vtysh.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.show ip ospf database. Identify: how many Type 1 LSAs? Which router generated the Type 2 LSA? What prefixes appear in the database?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?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.
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).M11 MASTERY CHECKLIST
- Know OSPF is a link-state protocol: each router builds a complete topology map (LSDB) and runs Dijkstra SPF independently
- Know OSPF uses IP Protocol 89 (not TCP/UDP), multicast 224.0.0.5 (all routers) and 224.0.0.6 (DR/BDR)
- Know OSPF cost formula: 10^8 / bandwidth; know why default reference bandwidth fails for GigE+ links
- Know the 7 OSPF neighbour states: DOWN, INIT, 2-WAY, EXSTART, EXCHANGE, LOADING, FULL
- Know Hello parameters that must match: Area ID, authentication, hello interval, dead interval, subnet mask, stub flag
- Know what causes stuck-in-EXSTART: MTU mismatch between neighbours
- Know the 6 primary LSA types: 1=Router, 2=Network(DR), 3=Summary(ABR), 4=ASBR Summary, 5=External(ASBR), 7=NSSA External
- Know which LSAs are flooded where: Type 1/2 = within area, Type 3/4 = between areas, Type 5 = entire OSPF domain
- Know LSA fields for versioning: Sequence Number (increments), Age (increments), MaxAge=3600s
- Know Dijkstra SPF: start at self=0, iteratively add minimum-cost unconfirmed node, update neighbours
- Know SPF throttling: delays between SPF runs prevent thrashing on unstable networks
- Know OSPF area types: Backbone (Area 0), Regular, Stub (no Type 5), Totally Stubby (no Type 3/5), NSSA
- Know router roles: Internal, ABR (Area Border), ASBR (AS Boundary), Backbone
- Know why DR/BDR exist: reduce N×(N-1)/2 adjacencies to 2×(N-1) on broadcast segments
- Know DR election: highest priority wins, then highest Router-ID; NOT preemptive
- Know convergence timeline: link-down = sub-second; router crash = Dead Interval (40s default)
- Know BFD: sub-millisecond failure detection independent of OSPF Hello timers
- Know OSPFv3 key differences: IPv6 transport, link-local addressing, IPsec auth, new LSA types 8/9
- Completed Lab 1: built 3-router OSPF network with FRR, observed LSDB, tested convergence on link failure
- Completed Lab 2: implemented Dijkstra SPF in Python, verified path computation and re-convergence after failure
✅ 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.