What the OSPF Neighbor States Are
An OSPF router goes through several states between discovering another router on the link with Hello packets and establishing an adjacency by synchronizing the LSDB. The state is kept per neighbor and is shown in the State column of show ospf neighbor.
When troubleshooting, “which state is it stuck in” points almost directly at the cause. Stuck at Init means the Hellos arrive but the peer does not see us; stuck around ExStart means the MTUs do not match, and so on. This article goes through what each state means and what triggers each transition, then follows a real transition on real devices (Cisco IOS XR) using debug output. For the contents of the packets themselves, see OSPF Packet Types and Header Format.
List of Neighbor States
| State | Description |
|---|---|
| Down | The initial state, in which no Hello has been received from the neighbor. A neighbor also returns to this state when the Dead interval expires. |
| Attempt | Used only on NBMA networks. Hellos are sent as unicast to a manually configured neighbor while waiting for a reply. |
| Init | A Hello has been received from the neighbor, but that Hello does not list our own router ID. Communication has only been confirmed in one direction. |
| 2-Way | Our own router ID appears in the neighbor’s Hello, so communication is confirmed in both directions. On a multi-access network the DR/BDR election happens at this point. |
| ExStart | In preparation for synchronizing the LSDB, DBDs are exchanged to decide master/slave and the initial sequence number. The router with the higher router ID becomes the master. |
| Exchange | DBDs are exchanged carrying the index of the LSDB (the list of LSA headers). |
| Loading | The LSAs found to be missing from the DBDs are requested with LSRs and received in LSUs. |
| Full | The LSDBs are synchronized and the adjacency is established. |
How Packets and States Correspond
Each state corresponds one-to-one with the packets exchanged.
- Init: the moment a Hello is received from the peer. Our own router ID is not in the peer’s neighbor list yet.
- 2-Way: the moment our own router ID is found in the peer’s Hello, which confirms two-way communication.
- ExStart: the first DBDs (with the I, M and MS bits all set) are exchanged and the router with the higher router ID becomes the master.
- Exchange: DBDs carrying LSA headers are exchanged.
- Loading: the missing LSAs are requested with LSRs and received in LSUs.
- Full: all the requested LSAs have arrived and the LSDBs are synchronized.
Because the state is kept independently for each neighbor, the state R1 sees for R2 and the state R2 sees for R1 do not necessarily match while the transition is in progress.
show ospf neighbor displays is “the state of the neighbor as this router sees it”. An asymmetric situation, where only one side is stuck at ExStart, is possible, so check the output on both sides when troubleshooting.When the State Stops at 2-Way
On a multi-access network, routers that are neither the DR nor the BDR (DROther routers) do not form adjacencies with each other and stay at 2-Way. This is not a fault: it is how OSPF concentrates the LSA exchange through the DR. Even though DROther routers do not synchronize their LSDBs with each other, the same LSAs reach them through the DR, so the LSDBs across the area still match. The DR/BDR election will be covered in DR and BDR.
On an Ethernet link with only two routers, one becomes the DR and the other the BDR, so both reach Full.
What to Suspect When the State Does Not Advance
| State it stops at | Common causes |
|---|---|
| Stays Down | The Hellos are not arriving: the interface is down, OSPF was not enabled, the interface is passive, an ACL is blocking the packets, and so on. |
| Stays Init | Hellos are only getting through in one direction: mismatched authentication, an ACL on one side only, a topology where multicast does not pass, and so on. |
| Stays 2-Way (other than DROther pairs) | Mismatched Hello parameters. The neighbor relationship does not form unless the area ID, Hello/Dead intervals, subnet mask and stub area flag all match. |
| Repeats ExStart / Exchange | A mismatch in interface MTU is the classic cause. If the Interface MTU carried in a DBD is larger than the receiver’s own MTU, the receiver discards that DBD. The state does not stay put but cycles through Init, 2-Way, ExStart and Down (see the test below). |
| Stays Loading | The requested LSAs do not come back, because of corrupted LSAs, packet loss and so on. |
Verification on Real Devices
Test Environment
The tests use the same single-area topology as What Is OSPF: three Cisco IOS XR (XRd) routers connected in a line. clear ospf 1 process is run on R1 to re-establish the adjacency, and the transition is followed on R1.
Logging the State Transitions
On IOS XR, debug ospf <process ID> adj records the process of establishing an adjacency in detail. The debug output goes into the logging buffer, so it can be read back with show logging.
RP/0/RP0/CPU0:R1#debug ospf 1 adj
RP/0/RP0/CPU0:R1#show debug
#### debug flags set from tty 'vty0' ####
ospf 1 adj flag is ON with value 0
(once done)
RP/0/RP0/CPU0:R1#undebug allshow debug says, a debug setting belongs to the session (tty) it was enabled from. If you log in over SSH and enable a debug, closing that session also clears the debug, so enabling the debug, reproducing the event and reading the log all have to happen in the same session. Debugging is expensive, so always stop it with undebug all once you are done.Below is the record of the adjacency being re-established after running clear ospf 1 process on R1 with the debug enabled.
RP/0/RP0/CPU0:Sep 5 06:56:44.755 UTC: ospf[1035]: intf Loopback0 going Down
RP/0/RP0/CPU0:Sep 5 06:56:44.755 UTC: ospf[1035]: 1.1.1.1 address 1.1.1.1 on Loopback0 is dead, state DOWN
RP/0/RP0/CPU0:Sep 5 06:56:44.755 UTC: ospf[1035]: intf GigabitEthernet0/0/0/0 going Down
RP/0/RP0/CPU0:Sep 5 06:56:44.755 UTC: ospf[1035]: 1.1.1.1 address 10.1.2.1 on GigabitEthernet0/0/0/0 is dead, state DOWN
RP/0/RP0/CPU0:Sep 5 06:56:44.755 UTC: ospf[1035]: DR: 2.2.2.2(Id) 10.1.2.2(IP Addr)
RP/0/RP0/CPU0:Sep 5 06:56:44.755 UTC: ospf[1035]: BDR: none
RP/0/RP0/CPU0:Sep 5 06:56:44.755 UTC: ospf[1035]: 2.2.2.2 address 10.1.2.2 on GigabitEthernet0/0/0/0 is dead, state DOWN
RP/0/RP0/CPU0:Sep 5 06:56:44.756 UTC: ospf[1035]: DR: none
RP/0/RP0/CPU0:Sep 5 06:56:44.756 UTC: ospf[1035]: BDR: none
RP/0/RP0/CPU0:Sep 5 06:56:44.769 UTC: ospf[1035]: intf Loopback0 going Up in area 0
RP/0/RP0/CPU0:Sep 5 06:56:44.769 UTC: ospf[1035]: intf GigabitEthernet0/0/0/0 going Up in area 0
RP/0/RP0/CPU0:Sep 5 06:56:53.509 UTC: ospf[1035]: 2 Way Communication to 2.2.2.2 on GigabitEthernet0/0/0/0, state 2WAY
RP/0/RP0/CPU0:Sep 5 06:56:53.509 UTC: ospf[1035]: Backup event seen before WAIT timer on GigabitEthernet0/0/0/0
RP/0/RP0/CPU0:Sep 5 06:56:53.509 UTC: ospf[1035]: DR: 2.2.2.2(Id) 10.1.2.2(IP Addr)
RP/0/RP0/CPU0:Sep 5 06:56:53.509 UTC: ospf[1035]: BDR: 1.1.1.1(Id) 10.1.2.1(IP Addr)
RP/0/RP0/CPU0:Sep 5 06:56:53.509 UTC: ospf[1035]: Send DBD to 2.2.2.2(10.1.2.2) on GigabitEthernet0/0/0/0 seq 0x4fd22be0 opt 0x52 flag 0x7 len 32
RP/0/RP0/CPU0:Sep 5 06:56:53.514 UTC: ospf[1035]: Rcv DBD from 2.2.2.2(10.1.2.2) on GigabitEthernet0/0/0/0 seq 0x597a68d5 opt 0x52 flag 0x7 len 32 mtu 1500 state EXSTART vrf default vrfid 0x60000000
RP/0/RP0/CPU0:Sep 5 06:56:53.514 UTC: ospf[1035]: NBR Negotiation Done. We are the SLAVE for nbr 2.2.2.2 on GigabitEthernet0/0/0/0, area 0
RP/0/RP0/CPU0:Sep 5 06:56:53.514 UTC: ospf[1035]: Send DBD to 2.2.2.2(10.1.2.2) on GigabitEthernet0/0/0/0 seq 0x597a68d5 opt 0x52 flag 0x2 len 52
RP/0/RP0/CPU0:Sep 5 06:56:53.520 UTC: ospf[1035]: Rcv DBD from 2.2.2.2(10.1.2.2) on GigabitEthernet0/0/0/0 seq 0x597a68d6 opt 0x52 flag 0x1 len 92 mtu 1500 state EXCHANGE vrf default vrfid 0x60000000
RP/0/RP0/CPU0:Sep 5 06:56:53.520 UTC: ospf[1035]: Exchange Done with 2.2.2.2 on GigabitEthernet0/0/0/0
RP/0/RP0/CPU0:Sep 5 06:56:53.520 UTC: ospf[1035]: sent LS REQ packet to 10.1.2.2, length 36
RP/0/RP0/CPU0:Sep 5 06:56:53.520 UTC: ospf[1035]: Send DBD to 2.2.2.2(10.1.2.2) on GigabitEthernet0/0/0/0 seq 0x597a68d6 opt 0x52 flag 0 len 32
RP/0/RP0/CPU0:Sep 5 06:56:53.525 UTC: ospf[1035]: Synchronized with 2.2.2.2 on GigabitEthernet0/0/0/0, state FULL
RP/0/RP0/CPU0:Sep 5 06:56:53.525 UTC: ospf[1035]: Received LS REQ packet from 2.2.2.2/10.1.2.2, length 12
RP/0/RP0/CPU0:Sep 5 06:57:03.315 UTC: ospf[1035]: DR: 2.2.2.2(Id) 10.1.2.2(IP Addr)
RP/0/RP0/CPU0:Sep 5 06:57:03.315 UTC: ospf[1035]: BDR: 1.1.1.1(Id) 10.1.2.1(IP Addr)Matching the lines against the states gives the following.
| Time | Log | Corresponding state |
|---|---|---|
| 06:56:44.755 | intf GigabitEthernet0/0/0/0 going Down / 2.2.2.2 ... is dead, state DOWN | The process restart takes every neighbor Down once |
| 06:56:44.769 | intf GigabitEthernet0/0/0/0 going Up in area 0 | OSPF is enabled on the interface again and Hellos start being sent |
| 06:56:53.509 | 2 Way Communication to 2.2.2.2 ... state 2WAY | Our router ID appears in R2’s Hello, so the state moves to 2-Way |
| 06:56:53.509 | DR: 2.2.2.2(Id) / BDR: 1.1.1.1(Id) | The DR and BDR are decided at 2-Way (R2 is the DR, R1 the BDR) |
| 06:56:53.509-514 | Send DBD ... flag 0x7 / Rcv DBD ... flag 0x7 ... state EXSTART | ExStart, exchanging DBDs with the I, M and MS bits set |
| 06:56:53.514 | NBR Negotiation Done. We are the SLAVE for nbr 2.2.2.2 | R2, with the higher router ID, becomes the master and R1 the slave |
| 06:56:53.520 | Rcv DBD ... flag 0x1 ... state EXCHANGE / Exchange Done | Exchange, exchanging DBDs that carry LSA headers |
| 06:56:53.520 | sent LS REQ packet to 10.1.2.2 | Loading, requesting the missing LSAs |
| 06:56:53.525 | Synchronized with 2.2.2.2 ... state FULL | The LSDBs are synchronized and Full is reached |
Reaching 2-Way after receiving a Hello took about 9 seconds, while going from 2-Way to Full took only 16 milliseconds. The first part is spent waiting for the neighbor’s Hello (sent every 10 seconds); the DBD, LSR, LSU and LSAck exchange that follows finishes in an instant.
How the State Appears in show ospf neighbor
The State column of show ospf neighbor is displayed as state/the neighbor's role on that link.
RP/0/RP0/CPU0:R1#show ospf neighbor
Sat Sep 5 07:07:35.271 UTC
* Indicates MADJ interface
# Indicates Neighbor awaiting BFD session up
Neighbors for OSPF 1
Neighbor ID Pri State Dead Time Address Interface
2.2.2.2 1 FULL/DR 00:00:37 10.1.2.2 GigabitEthernet0/0/0/0
Neighbor is up for 00:00:35
Total neighbor count: 1As described above, 2-Way to Full is over in an instant, so repeatedly running show ospf neighbor almost never catches an intermediate state. Right after a router boots, however, the Wait timer (40 seconds) for the DR/BDR election is running, so the 2-Way state can be observed for a while.
RP/0/RP0/CPU0:R1#show ospf neighbor
Sat Sep 5 06:54:58.365 UTC
* Indicates MADJ interface
# Indicates Neighbor awaiting BFD session up
Neighbors for OSPF 1
Neighbor ID Pri State Dead Time Address Interface
2.2.2.2 1 2WAY/DROTHER 00:00:39 10.1.2.2 GigabitEthernet0/0/0/0
Neighbor is up for 00:00:00
Total neighbor count: 12WAY/DROTHER means “the state is 2-Way and neither the DR nor the BDR has been decided yet (treated as DROther)”. Once the Wait timer expires and the DR/BDR are elected, the display changes to something like FULL/DR.
When Full Is Not Reached Because of an MTU Mismatch
The MTU of R1’s Gi0/0/0/0 is changed to 1400 bytes, creating a mismatch with R2 (the default 1500 bytes).
interface GigabitEthernet0/0/0/0
mtu 1400
!Checking both sides after a while shows that the adjacency cannot be established. Note that R1 and R2 see different states.
RP/0/RP0/CPU0:R1#show ospf neighbor
Sat Sep 5 07:00:03.667 UTC
Neighbors for OSPF 1
Neighbor ID Pri State Dead Time Address Interface
2.2.2.2 1 INIT/DROTHER 00:00:32 10.1.2.2 GigabitEthernet0/0/0/0
Total neighbor count: 1RP/0/RP0/CPU0:R2#show ospf neighbor
Sat Sep 5 07:00:13.004 UTC
Neighbors for OSPF 1
Neighbor ID Pri State Dead Time Address Interface
1.1.1.1 1 DOWN/DROTHER - 10.1.2.1 GigabitEthernet0/0/0/0
3.3.3.3 1 FULL/DR 00:00:34 10.2.3.3 GigabitEthernet0/0/0/1
Neighbor is up for 00:05:11
Total neighbor count: 2Enabling the debug on R1 records how it rejects each DBD as it arrives.
RP/0/RP0/CPU0:Sep 5 07:01:43.600 UTC: ospf[1035]: Rcv DBD from 2.2.2.2(10.1.2.2) on GigabitEthernet0/0/0/0 seq 0x3e71af09 opt 0x52 flag 0x7 len 32 mtu 1500 state INIT vrf default vrfid 0x60000000
RP/0/RP0/CPU0:Sep 5 07:01:43.600 UTC: ospf[1035]: Nbr 2.2.2.2 has larger interface MTU
RP/0/RP0/CPU0:Sep 5 07:01:51.182 UTC: ospf[1035]: 2 Way Communication to 2.2.2.2 on GigabitEthernet0/0/0/0, state 2WAY
RP/0/RP0/CPU0:Sep 5 07:01:51.183 UTC: ospf[1035]: Send DBD to 2.2.2.2(10.1.2.2) on GigabitEthernet0/0/0/0 seq 0x60209cc9 opt 0x52 flag 0x7 len 32
RP/0/RP0/CPU0:Sep 5 07:01:53.531 UTC: ospf[1035]: Rcv DBD from 2.2.2.2(10.1.2.2) on GigabitEthernet0/0/0/0 seq 0x3e71af09 opt 0x52 flag 0x7 len 32 mtu 1500 state EXSTART vrf default vrfid 0x60000000
RP/0/RP0/CPU0:Sep 5 07:01:53.531 UTC: ospf[1035]: Nbr 2.2.2.2 has larger interface MTU
RP/0/RP0/CPU0:Sep 5 07:01:55.885 UTC: ospf[1035]: 2.2.2.2 address 10.1.2.2 on GigabitEthernet0/0/0/0 is dead, state DOWNNbr 2.2.2.2 has larger interface MTU gives the cause away. A DBD carries the Interface MTU, and the receiver discards any DBD whose value is larger than its own interface MTU. On R2 the log shows that it eventually declared the neighbor down after retransmitting DBDs.
RP/0/RP0/CPU0:R2#show logging | include ADJCHG
RP/0/RP0/CPU0:Sep 5 06:56:53.528 UTC: ospf[1035]: %ROUTING-OSPF-5-ADJCHG : Process 1, Nbr 1.1.1.1 on GigabitEthernet0/0/0/0 in area 0 from LOADING to FULL, Loading Done, vrf default vrfid 0x60000000
RP/0/RP0/CPU0:Sep 5 06:59:46.822 UTC: ospf[1035]: %ROUTING-OSPF-5-ADJCHG : Process 1, Nbr 1.1.1.1 on GigabitEthernet0/0/0/0 in area 0 from EXSTART to DOWN, Neighbor Down: too many DBD retransmissions, vrf default vrfid 0x60000000 from EXSTART to DOWN, Neighbor Down: too many DBD retransmissions is the typical log for an MTU mismatch. The state does not stay fixed at ExStart: the Hellos take it to Init and 2-Way, the DBD exchange fails, and it falls back to Down, over and over. That is why INIT, 2WAY, EXSTART or DOWN can all appear depending on when show ospf neighbor is run.
The MTU value can be checked with show ospf interface. Comparing the MTU on both sides makes a mismatch obvious.
R1: Transmit Delay is 1 sec, State DR, Priority 1, MTU 1386, MaxPktSz 1386
R2: Transmit Delay is 1 sec, State DR, Priority 1, MTU 1500, MaxPktSz 1500R1’s interface MTU is 1400 bytes but the MTU that OSPF displays is 1386, because it shows the MTU of the IP payload with the 14-byte Ethernet header subtracted.
The correct fix is to make the MTUs match, but when that is not possible, mtu-ignore disables the MTU check on DBDs. Here it was configured on R1, the side with the smaller MTU.
router ospf 1
area 0
interface GigabitEthernet0/0/0/0
mtu-ignore
!
!
!RP/0/RP0/CPU0:R1#show ospf neighbor
Sat Sep 5 07:03:33.965 UTC
Neighbors for OSPF 1
Neighbor ID Pri State Dead Time Address Interface
2.2.2.2 1 FULL/DR 00:00:31 10.1.2.2 GigabitEthernet0/0/0/0
Neighbor is up for 00:00:55
Total neighbor count: 1Full was reached even with the MTUs still at 1386 and 1500. This only skips the check in the DBD, though: large packets may still be dropped along the path. After the test, mtu-ignore and the MTU setting were removed and the lab was returned to its original state.
no mtu 1400; plain no mtu did not remove it and the setting stayed in place.Verification Config
R1’s running-config after the tests (with the MTU back at its default), and the output of show ospf neighbor, show ospf interface and show logging on R1 and R2.
Download R1 config (r1_ospf-neighbor-state.cfg)
Download R1 show output (r1_ospf-neighbor-state_show.txt)
Download R2 show output (r2_ospf-neighbor-state_show.txt)
The packets exchanged while the adjacency is established are covered, with captures, in OSPF Packet Types and Header Format.
References
| RFC | Title | Summary |
|---|---|---|
| RFC 2328 | OSPF Version 2 | The neighbor state machine is defined in Section 10 (The Neighbor Data Structure). |