Objective
By the end of this lab you will have taken three VyOS routers from no routing protocol at all to a converged single-area OSPF domain, and you will have watched every mechanism that decides whether an adjacency forms: the router-id, the area, the network type, the DR election, the passive flag, and the MTU. Then you will break exactly one of them and find it from evidence — while the estate carries on working, which is the part that makes this failure worth practising.
Architecture
Three VyOS routers, one broadcast segment, one point-to-point link, one site LAN each.
br-core 10.0.0.0/24 area 0, broadcast
+------------------+------------------+
| | |
eth0 10.0.0.1 eth0 10.0.0.2 eth0 10.0.0.3
+-----+ +-----+ +-----+
| R1 | | R2 | | R3 |
+--+--+ +--+--+ +--+--+
| \ | / |
| \ eth1 10.0.1.1/30 eth1 10.0.1.2/30
| +---- br-p2p 10.0.1.0/30 ----+ |
| area 0, point-to-point |
eth2 10.1.0.1/24 eth1 10.2.0.1/24 eth2 10.3.0.1/24
br-site1 br-site2 br-site3
(passive) (passive) (passive)
| Router | Router-id (lo) | br-core | br-p2p | Site LAN |
|---|---|---|---|---|
| R1 | 10.255.0.1/32 | eth0 10.0.0.1/24 | eth1 10.0.1.1/30 | eth2 10.1.0.1/24 |
| R2 | 10.255.0.2/32 | eth0 10.0.0.2/24 | — | eth1 10.2.0.1/24 |
| R3 | 10.255.0.3/32 | eth0 10.0.0.3/24 | eth1 10.0.1.2/30 | eth2 10.3.0.1/24 |
The three site LANs carry no hosts. An interface attached to an empty bridge still comes up, still gets its prefix into the link-state database, and is exactly the shape of the single-router LAN segment that the passive flag exists for. That keeps the lab to three guests.
Everything is in area 0. Multi-area design, ABRs and summarisation are the subject of the next lab; this one is about what has to be true on a single link before any of that matters.
Requirements
- A hypervisor able to run three guests across five isolated layer-2 segments. Nested virtualisation is sufficient.
- Three VyOS 1.5 LTS (circinus) guests, installed to disk, 1 GB RAM each. R1 and R3 need three NICs; R2 needs two. Every command here is VyOS 1.5 syntax.
- Console access to all three routers. Task 7 changes an interface MTU,
which resets the adjacencies on that segment. If your management path runs
over
br-coreyou will lose it at that step. - Roughly 4 GB of RAM and 12 GB of disk in total.
- No Linux guests, no DHCP, no upstream connectivity. Nothing in this lab reaches outside the five bridges.
Scenario
You are commissioning three routers for a small estate. Each one fronts a site LAN; all three share a core segment; R1 and R3 also have a dedicated link between them that was pulled for a future project and is currently spare capacity. Nothing routes yet.
The change record for the commissioning says the domain must converge, every adjacency must be Full, and the site LANs must not be sending Hello packets to an empty segment. Six weeks later somebody will change an MTU on R3 for an unrelated reason and nobody will notice for a fortnight. Task 7 is that fortnight.
Tasks
Task 1: Wire the segments and save the pre-lab configuration
Create five bridges — br-core, br-p2p, br-site1, br-site2, br-site3 —
with no physical port attached to any of them. Attach the NICs in the order
given in the Architecture table so the interfaces enumerate as shown.
On each router, before anything else, save the running configuration:
show configuration commands | save /config/pre-ospf-lab.txt
That file is what Cleanup restores from. It is written inside /config
deliberately: that directory survives a reboot and is included in a
configuration backup, so the safety net does not depend on the session staying
alive.
Task 2: Address everything, and establish that nothing routes yet
On R1:
configure
set system host-name r1
set interfaces loopback lo address 10.255.0.1/32
set interfaces ethernet eth0 address 10.0.0.1/24
set interfaces ethernet eth0 description 'core segment'
set interfaces ethernet eth1 address 10.0.1.1/30
set interfaces ethernet eth1 description 'p2p to r3'
set interfaces ethernet eth2 address 10.1.0.1/24
set interfaces ethernet eth2 description 'site 1 LAN'
commit
save
exit
On R2:
configure
set system host-name r2
set interfaces loopback lo address 10.255.0.2/32
set interfaces ethernet eth0 address 10.0.0.2/24
set interfaces ethernet eth0 description 'core segment'
set interfaces ethernet eth1 address 10.2.0.1/24
set interfaces ethernet eth1 description 'site 2 LAN'
commit
save
exit
On R3:
configure
set system host-name r3
set interfaces loopback lo address 10.255.0.3/32
set interfaces ethernet eth0 address 10.0.0.3/24
set interfaces ethernet eth0 description 'core segment'
set interfaces ethernet eth1 address 10.0.1.2/30
set interfaces ethernet eth1 description 'p2p to r1'
set interfaces ethernet eth2 address 10.3.0.1/24
set interfaces ethernet eth2 description 'site 3 LAN'
commit
save
exit
Now record the negative baseline. From R2:
show ip route
show ip route ospf
The first shows connected routes only. The second reports that no OSPF routes exist. Confirm the data plane agrees:
ping -c 3 -W 2 10.0.0.3
ping -c 3 -W 2 10.3.0.1
The first succeeds — R2 and R3 share a segment. The second fails, and it fails
for the right reason: R2 has no route to 10.3.0.0/24. Write both results
down. Everything after this point is measured against them.
Task 3: Enable OSPF and watch an adjacency form
Set the router-id explicitly on every router. The auto-derivation rule — the highest loopback address, or the highest address on any active interface — would pick the right value here by accident, and that is exactly the habit to avoid: a router whose loopback is added late or whose addressing is renumbered silently takes a new OSPF identity, invalidates every LSA it originated, and refloods the domain.
On R1:
configure
set protocols ospf parameters router-id 10.255.0.1
set protocols ospf area 0 network 10.0.0.0/24
set protocols ospf area 0 network 10.255.0.0/24
set protocols ospf area 0 network 10.1.0.0/24
set protocols ospf interface eth0 cost 10
commit
save
exit
Give that commit about forty seconds to settle before moving on. R1 is alone on the segment, so it waits out its wait timer and elects itself DR; the rest of Task 4 depends on the three routers joining in a known order.
On R2, the same shape with its own values:
configure
set protocols ospf parameters router-id 10.255.0.2
set protocols ospf area 0 network 10.0.0.0/24
set protocols ospf area 0 network 10.255.0.0/24
set protocols ospf area 0 network 10.2.0.0/24
set protocols ospf interface eth0 cost 10
commit
save
exit
Before you commit on R3, start a neighbour watch on R2 so you can see the formation rather than only its result:
watch -n 1 'vtysh -c "show ip ospf neighbor"'
Now commit R3:
configure
set protocols ospf parameters router-id 10.255.0.3
set protocols ospf area 0 network 10.0.0.0/24
set protocols ospf area 0 network 10.255.0.0/24
set protocols ospf area 0 network 10.3.0.0/24
set protocols ospf interface eth0 cost 10
commit
save
exit
You have a few seconds to catch a state below Full. Init means Hellos are
being received but this router has not yet seen itself listed in the
neighbour’s Hello; 2-Way means bidirectional visibility is established and
the DR election has run; ExStart and Exchange are the database description
handshake; Loading is the request for the LSAs this router is missing. If you
miss it, reset ip ospf process on R3 in operational mode replays the whole
sequence.
$ show ip ospf neighborNeighbor ID Pri State Up Time Dead Time Address Interface
10.255.0.1 1 Full/DR 00:01:12 38.114s 10.0.0.1 eth0:10.0.0.2
10.255.0.3 1 Full/DROther 00:00:21 37.902s 10.0.0.3 eth0:10.0.0.2Illustrative output
Read the State column as two facts joined by a slash: the adjacency state,
and the neighbour’s role on that segment. Confirm the whole domain converged:
show ip ospf
show ip ospf neighbor
show ip route ospf
show ip ospf reports the router-id this process is actually using — check it
against what you configured, not against what you intended. Then repeat the
Task 2 data-plane probe from R2:
ping -c 3 -W 2 10.3.0.1
It now succeeds, and show ip route ospf says why.
Task 4: Read the DR election, and discover that it will not preempt
br-core has three OSPF speakers, so it is a multi-access segment and OSPF
elected a Designated Router and a Backup DR. Every router forms a Full
adjacency with the DR and the BDR, and stays at 2-Way with everything else —
which is why the third router shows as DROther above rather than as a fault.
show ip ospf interface eth0
show ip ospf neighbor
Record which router-id is DR and which is BDR. Because you brought the routers
up in order, the roles are determined and not a matter of luck: R1 was alone
when it started and elected itself DR, R2 arrived to find a DR but no BDR and
took that role, and R3 arrived to find both taken and is a DROther.
That already contradicts the rule people remember. With every priority at the default of 1 the tie-break is the highest router-id, which would make R3 the DR — and R3 is not the DR, because the election had already happened.
Try to move it deliberately. On R2, claim the segment with the highest possible priority:
configure
set protocols ospf interface eth0 priority 255
commit
exit
Wait a full dead interval — 40 seconds by default — and look again:
show ip ospf interface eth0
show ip ospf neighbor
Nothing changed. The DR election is deliberately non-preemptive: once a DR is established on a segment, a better candidate does not take over, because a change of DR costs every router on the segment a rebuild of its adjacencies and a reflood. Priority decides who wins an election; it does not cause one.
Now make an election happen, by removing the router that holds the role. On R1 — the current DR — in operational mode:
reset ip ospf process
Watch what the segment does. The BDR promotes: R2 becomes DR, R3 is elected the
new BDR, and R1 — the router you just restarted — comes back to find both roles
taken and settles as a DROther, whatever its priority. A router that restarts
does not get its role back.
show ip ospf interface eth0
show ip ospf neighbor
Put R2’s priority back to the default. Note that this changes nothing either, for the same reason as before, and that the roles the segment settled on here are the ones the rest of the lab runs with:
configure
delete protocols ospf interface eth0 priority
commit
save
exit
Task 5: Make the site LANs passive, and prove it from the wire
Each site LAN has exactly one OSPF speaker on it. Today those interfaces are sending a Hello every ten seconds into a segment where nothing will ever answer. Prove that before changing it — on R1:
timeout 25 tcpdump -ni eth2 proto ospf
You will see Hello packets to 224.0.0.5 leaving eth2, roughly one every ten
seconds, and no reply. Now suppress them, on each router for its own site LAN:
configure
set protocols ospf interface eth2 passive
commit
save
exit
On R2 the site LAN is eth1, so the statement is
set protocols ospf interface eth1 passive there.
Re-run the capture. It is now silent. The prefix, however, is still in the
database — that is the whole point of passive rather than deleting the
network statement:
show ip ospf interface eth2
show ip ospf database router self-originate
The interface reports the passive flag; the router LSA still advertises the site prefix as a stub network. Confirm from a different router that nothing was lost:
show ip route ospf
10.1.0.0/24, 10.2.0.0/24 and 10.3.0.0/24 are all still there.
Task 6: Bring up the point-to-point link
The R1–R3 link has exactly two endpoints. Left at the Ethernet default it would run a DR election on a segment where a DR is meaningless. Set the network type explicitly on both ends, and give the link a deliberately higher cost so the core segment stays the preferred path while both are healthy.
On R1:
configure
set protocols ospf area 0 network 10.0.1.0/30
set protocols ospf interface eth1 network-type point-to-point
set protocols ospf interface eth1 cost 30
commit
save
exit
On R3, the same three statements — the interface is eth1 there too. Both ends
must agree on the network type; a broadcast end and a point-to-point end
exchange Hellos that disagree and form no adjacency at all, with no log entry
to say so.
show ip ospf interface eth1
show ip ospf neighbor
The interface reports network type POINTOPOINT and no DR or BDR. The
neighbour entry for this link shows Full/- rather than Full/DR — there is
no role to report, because no election ran.
Check from R2 that the new prefix propagated:
show ip route ospf
10.0.1.0/30 is now in R2’s table, learned from two routers that both describe
the same link.
Task 7: Break the MTU, and find it from evidence
Six weeks pass. Somebody reduces the MTU on R3’s core interface to make room for a tunnel they are planning. Do it:
configure
set interfaces ethernet eth0 mtu 1400
commit
save
exit
Within a dead interval, R3’s two adjacencies on br-core fail. Start from the
symptom, on R3:
$ show ip ospf neighborNeighbor ID Pri State Up Time Dead Time Address Interface
10.255.0.1 1 ExStart/DROther 00:00:00 37.551s 10.0.0.1 eth0:10.0.0.3
10.255.0.2 1 ExStart/DR 00:00:00 38.002s 10.0.0.2 eth0:10.0.0.3
10.255.0.1 0 Full/- 00:12:44 38.310s 10.0.1.1 eth1:10.0.1.2Illustrative output
ExStart is a specific accusation, not a generic failure. Hellos are being
exchanged — the routers found each other, agreed on the area, the timers, the
network type and the authentication, and ran the election, because none of that
is possible below 2-Way. What failed is the database description handshake
that comes next. The short list of causes is MTU, a duplicate router-id, and
an authentication mismatch, and only one of them is cheap to check.
show ip ospf neighbor detail
show ip ospf interface eth0
show ip ospf neighbor detail carries an Interface MTU line per neighbour.
Compare it with the local interface:
ip link show dev eth0
R3 reports 1400 and its neighbours report 1500. That is the finding. Confirm the mechanism on the wire, on R1:
timeout 30 tcpdump -ni eth0 -vv proto ospf and host 10.0.0.3
You will see Hellos in both directions and DBD packets that never complete the master/slave negotiation. RFC 2328 section 10.3 is explicit: if the Interface MTU field in a Database Description packet indicates a datagram larger than the receiving interface’s IP MTU, the packet is discarded. R1 announces 1500, R3 discards it, and the handshake never gets past its first exchange. No ICMP is sent and nothing is logged, because a silent discard is the specified behaviour, not an error.
Task 8: The failure that did not page anyone
Before fixing it, look at what the outage actually cost. From R2:
show ip route ospf
show ip route 10.3.0.0/24
10.3.0.0/24 is still reachable. The next hop, though, is no longer
10.0.0.3: R2 now reaches site 3 through R1 and the point-to-point link, at
the higher cost you configured in Task 6. Record the metric and the next hop
alongside the values you noted in Task 6.
Confirm the data plane agrees:
ping -c 3 -W 2 10.3.0.1
It succeeds. Nothing is down. Two of three adjacencies on the core segment are broken, all traffic to and from site 3 is crossing a link that was commissioned as spare capacity, and a monitoring system that alerts on reachability has nothing to say. This is the ordinary shape of an OSPF fault in a redundant estate: it does not remove connectivity, it removes headroom, and it stays until somebody looks at a neighbour table.
Now fix it. The clean fix is to align the MTU, because the mismatch here was not deliberate:
configure
set interfaces ethernet eth0 mtu 1500
commit-confirm 5
You are still in configure mode with a five-minute timer running. Operational
commands are available there through run, so you can watch the adjacencies
come back without leaving the session that owns the pending rollback:
run show ip ospf neighbor
confirm
save
exit
commit-confirm matters on this specific change: if you get the MTU wrong in
the other direction, the interface you are managing the router over is the one
that stops carrying full-size frames, and an unattended rollback is the
difference between a five-minute event and a console trip.
Now rehearse the other answer, because sooner or later the mismatch will be deliberate — a tunnel with real overhead on one side and plain Ethernet on the other. Re-break it on R3, then tell OSPF to skip the check:
configure
set interfaces ethernet eth0 mtu 1400
set protocols ospf interface eth0 mtu-ignore
commit
exit
And on R1 and R2:
configure
set protocols ospf interface eth0 mtu-ignore
commit
exit
The adjacencies reach Full again with the MTUs still disagreeing. The check
is applied by the router that receives a Database Description packet, so in
principle only the side with the smaller MTU has to ignore it — but a link
whose two ends disagree about a rule is a link somebody will misdiagnose at
03:00, so configure it on both ends and say why in the change record.
Restore the aligned state before moving on:
configure
delete protocols ospf interface eth0 mtu-ignore
set interfaces ethernet eth0 mtu 1500
commit
save
exit
Remove mtu-ignore on R1 and R2 as well.
Validation
show ip ospf neighboron R1 lists three neighbours: R2 and R3 oneth0, bothFull, and R3 oneth1asFull/-with no DR role.show ip ospf neighboron R2 lists two neighbours, bothFull. After Task 4 R2 itself is the DR, so its two neighbours readFull/BDRandFull/DROther— no entry saysFull/DR, because a router never reports its own role in its neighbour table.show ip ospfon each router reports the router-id you configured:10.255.0.1,10.255.0.2,10.255.0.3.show ip ospf interface eth1on R1 reports network typePOINTOPOINTand no DR or BDR.show ip ospf interfaceshows the passive flag on each site LAN, andtcpdump -ni eth2 proto ospfon R1 is silent for a full 30 seconds.show ip route ospfon R2 contains10.1.0.0/24,10.3.0.0/24,10.0.1.0/30, and the two loopback/32s. The next hop for10.3.0.0/24is10.0.0.3again, not10.0.0.1.ping -c 3 10.3.0.1from R2 succeeds, andping -c 3 10.255.0.3succeeds too — the loopback being reachable is what makes a router-id useful for troubleshooting.ip link show dev eth0reports MTU 1500 on all three routers, and nomtu-ignoreremains inshow configuration commands | match mtu.
Expected Outcome
A converged single-area OSPF domain across three routers, with five adjacencies
in Full, three passive site LANs whose prefixes are in the database and whose
segments are silent, and one point-to-point link running without a DR election.
Every site prefix is reachable from every router, and the path each one takes
matches the costs you set rather than whatever the auto-cost calculation
happened to produce.
Your journal holds the neighbour table at four points — during formation, after convergence, during the MTU failure, and after the fix — plus the routing-table extract showing traffic silently rerouting during the failure.
Troubleshooting
No neighbour appears at all. The two ends disagree about something carried
in the Hello: the area, the hello or dead interval, the network type, the
subnet mask, or the authentication. show ip ospf interface on both ends shows
all of these. A network statement that does not match the interface address
produces the same silence, because OSPF simply never runs on that interface.
The neighbour is stuck at Init. Hellos are arriving in one direction
only. Capture on both ends: a passive flag, a firewall dropping multicast to
224.0.0.5, or a bridge that is not actually carrying multicast will all do
this.
Two routers show the same router-id. The database has duplicate Type-1
LSAs and SPF oscillates. Set unique explicit ids, then
reset ip ospf process on one router so the database converges on the
corrected identities.
The adjacency is stuck at ExStart and the MTUs match. The other two
causes are a duplicate router-id and an authentication mismatch. Check
show ip ospf database router self-originate on both routers for the same
advertising router-id, and show ip ospf interface for an authentication
setting on one side only.
show ip route ospf is empty but the neighbours are Full. The adjacency is
up and there is nothing to advertise. Check that each router’s network
statements actually cover the prefixes you expect to see, and that the site
interfaces are up.
An interface will not join OSPF however many times you commit. Compare the
interface address with the network statement, prefix bit by prefix bit.
10.0.0.0/24 does not match an interface addressed 10.0.1.1/30.
Cleanup
Nothing in this lab writes outside the routers’ configuration, so cleanup is a configuration restore — but the OSPF removal is a routing event, so do it in an order that leaves nothing half-configured.
Step 1. On each router, remove the protocol first, then the addressing:
configure
delete protocols ospf
commit
save
exit
Confirm the adjacencies are gone and the routes with them:
show ip ospf neighbor
show ip route ospf
Step 2. Restore the configuration you saved in Task 1. Loading a saved file replaces the candidate configuration wholesale, so read the diff before you commit it:
configure
load /config/pre-ospf-lab.txt
compare
commit
save
exit
Step 3. Confirm the routers are back where they started:
show configuration commands
show interfaces
Step 4. Delete the five bridges on the hypervisor, or keep them if the next lab will reuse the wiring — the multi-area lab builds a different topology, so there is nothing to preserve here beyond the guests themselves.
What You Learned
- The router-id is an identity, not a formality. You set it explicitly on
all three routers, and
show ip ospfconfirmed the process is using the value you chose rather than one derived from whichever address happened to be highest. - A state below
Fullnames its own cause.Initis one-way Hellos;2-Waybetween DROthers is healthy;ExStartis the database handshake, which narrows the cause to three candidates before you run a second command. - The DR election does not preempt. Raising a priority to 255 changed
nothing at all; the roles only moved when the router holding the DR role was
restarted, and even then the restarted router came back as a
DROther. Priority decides who wins an election, it does not cause one. - Passive is a per-interface protocol decision with wire-visible effects. The capture went silent and the prefix stayed in the database — two facts you confirmed separately rather than assuming one from the other.
- The network type has to match, and on a two-endpoint link it should be
point-to-point. The neighbour entry showing
Full/-instead ofFull/DRis the evidence that no election ran. - An MTU mismatch is diagnosed, not guessed.
ExStartplus theInterface MTUline plusip link showis three commands to certainty, and the RFC 2328 silent discard is why no log entry was ever going to help. - A broken adjacency in a redundant estate moves traffic instead of stopping it. The prefix stayed reachable, the next hop changed, and nothing alerted.