A hands-on lab that uses NetLab and Containerlab with FRRouting (FRR) containers to demonstrate the six fundamental OSPF area types in a single, reproducible topology.
graph TB
subgraph area0["Area 0 — Backbone"]
lan0(["`Backbone LAN
172.16.0.0/24
DR/BDR election`"])
bb["`bb
lo: 10.0.0.1`"]
abr1["`abr1
lo: 10.0.0.2`"]
abr2["`abr2
lo: 10.0.0.3`"]
abr3["`abr3
lo: 10.0.0.4`"]
abr4["`abr4
lo: 10.0.0.5`"]
abr5["`abr5
lo: 10.0.0.6`"]
end
lan0 -- "172.16.0.1" --- bb
lan0 -- "172.16.0.2" --- abr1
lan0 -- "172.16.0.3" --- abr2
lan0 -- "172.16.0.4" --- abr3
lan0 -- "172.16.0.5" --- abr4
lan0 -- "172.16.0.6" --- abr5
subgraph area1["Area 1 — Regular Area"]
r1["`r1
lo: 10.0.0.7`"]
end
abr1 -- "10.1.0.0/30" --- r1
subgraph area2["Area 2 — Stub Area"]
r2["`r2
lo: 10.0.0.8`"]
end
abr2 -- "10.1.0.4/30" --- r2
subgraph area3["Area 3 — Totally Stubby Area"]
r3["`r3
lo: 10.0.0.9`"]
end
abr3 -- "10.1.0.8/30" --- r3
subgraph area4["Area 4 — NSSA"]
r4["`r4 (ASBR)
lo: 10.0.0.10`"]
end
abr4 -- "10.1.0.12/30" --- r4
ext4["`10.99.0.0/24
external, not in OSPF
r4: 10.99.0.10`"]
r4 -. "redistribute connected as Type-7 LSA" .-> ext4
subgraph area5["Area 5 — Totally NSSA"]
r5["`r5 (ASBR)
lo: 10.0.0.11`"]
end
abr5 -- "10.1.0.16/30" --- r5
ext5["`10.100.0.0/24
external, not in OSPF
r5: 10.100.0.11`"]
r5 -. "redistribute connected as Type-7 LSA" .-> ext5
| Router | Role | Area |
|---|---|---|
bb |
Backbone router | Area 0 |
abr1 |
Area Border Router | Area 0 ↔ Area 1 |
abr2 |
Area Border Router | Area 0 ↔ Area 2 |
abr3 |
Area Border Router | Area 0 ↔ Area 3 |
abr4 |
Area Border Router | Area 0 ↔ Area 4 |
abr5 |
Area Border Router | Area 0 ↔ Area 5 |
r1 |
Internal router | Area 1 (Regular) |
r2 |
Internal router | Area 2 (Stub) |
r3 |
Internal router | Area 3 (Totally Stubby) |
r4 |
Internal router / ASBR | Area 4 (NSSA) |
r5 |
Internal router / ASBR | Area 5 (Totally NSSA) |
Every OSPF autonomous system has exactly one backbone area (0.0.0.0). All other areas must connect directly to it (via an ABR) to exchange routing information. The backbone carries all inter-area and external routes as Type-3/4/5 LSAs. In this lab bb is the central backbone router and the five ABRs (abr1–abr5) all share a single broadcast LAN segment in Area 0. Because the segment has more than two routers, OSPF performs DR/BDR election on it — one router is elected Designated Router (DR) and another is elected Backup Designated Router (BDR) to reduce the number of adjacencies and LSA flooding on the segment.
A regular area behaves identically to the backbone: it receives all LSA types (Type 1–5). Every prefix in the OSPF domain, including external routes redistributed anywhere else, is visible to r1. This is the default area type and requires no extra configuration.
A stub area blocks Type-5 LSAs (AS-external routes). Instead of carrying external prefixes, the ABR (abr2) injects a single default route (0.0.0.0/0) into the area. This reduces the size of the LSDB and is ideal for sites that have only one exit point toward the rest of the network. Router r2 reaches all external destinations through that default route.
The ospf.areas plugin automatically applies the equivalent of:
router ospf
area 0.0.0.2 stub
A totally stubby area is a Cisco-originated extension (supported by FRR) that blocks Type-3, -4, and -5 LSAs, leaving only the default route injected by the ABR. Router r3 has the smallest possible LSDB: only intra-area routes and one default route. This is the most restrictive area type and is ideal for stub sites with a single upstream ABR.
The ospf.areas plugin automatically applies the equivalent of:
router ospf
area 0.0.0.3 stub no-summary
no-summaryis the keyword that suppresses Type-3 summary LSAs, making the stub area "totally stubby".
An NSSA blocks Type-5 external LSAs like a stub area, but allows an ASBR inside the area to redistribute external routes. Instead of Type-5, the ASBR generates Type-7 LSAs that are local to the NSSA. The ABR (abr4) translates selected Type-7 LSAs into Type-5 LSAs before flooding them into the backbone. In this lab r4 acts as the ASBR.
The 10.99.0.0/24 link on r4 has role: external, which means the interface is not part of the OSPF process at all. NetLab's ospf.import: [connected] on r4 redistributes those connected routes into OSPF as Type-7 LSAs.
The ospf.areas plugin automatically applies the equivalent of:
router ospf
area 0.0.0.4 nssa
A Totally NSSA combines the properties of NSSA and Totally Stubby: Type-5 external LSAs are blocked and Type-3 inter-area summary LSAs are suppressed. An ASBR inside the area can still inject external routes as Type-7 LSAs (converted at the ABR to Type-5 for the backbone). Router r5 receives only intra-area routes and a single default route from abr5.
The 10.100.0.0/24 link on r5 has role: external, which means the interface is not part of the OSPF process at all. NetLab's ospf.import: [connected] on r5 redistributes those connected routes into OSPF as Type-7 LSAs.
The ospf.areas plugin automatically applies the equivalent of:
router ospf
area 0.0.0.5 nssa no-summary
no-summaryadded to thenssakeyword suppresses Type-3 summary LSAs, making it "Totally NSSA".
Tip: You can skip local setup entirely by launching the lab in GitHub Codespaces — all dependencies are pre-installed in the dev container.
Follow the official installation guide: 👉 https://netlab.tools/install/
NetLab installs all required dependencies (including Containerlab and the FRR container image) automatically. The quickest way to get started:
python3 -m pip install networklab
netlab install --allgit clone https://github.com/severindellsperger/netlab-ospf-lab.git
cd netlab-ospf-labClick the button below to open this lab in a pre-configured cloud environment — no local installation required:
Once the Codespace is ready, run netlab up in the terminal to start the lab.
netlab upnetlab up will:
- Parse
topology.ymland calculate IP addresses and OSPF parameters. - Use the
ospf.areasplugin to automatically configure stub, totally-stubby, NSSA, and totally-NSSA area types on every router. - Generate Containerlab and FRR configuration files.
- Start all containers via Containerlab.
- Deploy the generated FRR configuration to every container.
After a few seconds all OSPF adjacencies should come up. You can verify:
# Show OSPF neighbours on the backbone router
netlab connect bb -- vtysh -c "show ip ospf neighbor"
# Show the LSDB on r3 (Totally Stubby – should contain only Type-1 and the default Type-3)
netlab connect r3 -- vtysh -c "show ip ospf database"
# Show the routing table on r2 (Stub – external routes replaced by a default route)
netlab connect r2 -- vtysh -c "show ip route ospf"You can also open an interactive vtysh shell on any device, or use the --show flag as a convenient shorthand:
# Open an interactive vtysh shell on bb
netlab connect bb vtysh
# Use --show for quick read-only commands (no need for the full vtysh -c syntax)
netlab connect bb --show ip ospf neighborYou can also connect directly to a container's interactive FRR shell using docker exec. The container name follows the pattern clab-<lab-name>-<node>, for example:
docker exec -it clab-netlabospfla-r5 vtyshnetlab downnetlab down destroys all containers and removes the generated configuration files, leaving the repository in a clean state.
This lab is provided as-is for educational purposes.