Skip to main content
  1. Network Articles/
  2. BGP Articles/

BGP Neighbor State Transitions

Table of Contents

What Are BGP Neighbor State Transitions?

BGP defines the process of establishing a session with a peer as six states. These transitions are specified in RFC 4271 as a finite state machine (FSM), and when a session fails to come up, the state it is stuck in points directly at the cause. This article explains the meaning of each state and the conditions for moving between them, and then observes the actual state changes in an IOS XR (XRd) lab.

For the basics of how BGP works, see BGP (Border Gateway Protocol), and for the messages exchanged during these transitions, see BGP Messages.

The Six States

StateMeaning
IdleThe initial state. All connections are refused and no resources are allocated. On a Start event the router initiates a TCP connection and moves to Connect. Any error also returns the session to this state.
ConnectWaiting for the TCP three-way handshake to complete. On success the router sends an OPEN and moves to OpenSent; on failure it moves to Active.
ActiveThe router’s own TCP connection attempt failed, so it retries while also waiting for a connection from the peer. Once a connection succeeds it moves to OpenSent.
OpenSentAn OPEN message has been sent and the peer’s OPEN is awaited. The received OPEN is validated (version, AS number, BGP Identifier, Hold Time), and if it is acceptable the router sends a KEEPALIVE and moves to OpenConfirm.
OpenConfirmWaiting for a KEEPALIVE from the peer. On receiving one the session moves to Established.
EstablishedThe session is up and route information can be exchanged with UPDATE messages.
Despite its name, Active does not mean “actively working and healthy.” It is the state in which the router’s own TCP connection attempt failed and is being retried, so a session stuck here points at TCP reachability or a wrong peer address.

What Returns a Session to Idle

From any state, any of the following returns the session to Idle.

  • A NOTIFICATION message was sent or received
  • The TCP session was torn down
  • Neither a KEEPALIVE nor an UPDATE was received within the Hold Time (Hold Timer Expired)
  • An administrator ran shutdown or reset the session

After returning to Idle, the router waits for the connect retry timer (60 seconds by default) to expire before trying again. When attempts keep failing, some implementations back this interval off exponentially.

Checking the State

On IOS XR, the St/PfxRcd column of show bgp summary shows the state of each peer. For a peer in Established this column shows the number of prefixes received; in any other state it shows the state name itself.

Neighbor        Spk    AS MsgRcvd MsgSent       TblVer  InQ OutQ  Up/Down  St/PfxRcd
10.2.3.3          0 65002     108     105           12    0    0 00:30:41          2

For details of an individual peer, use show bgp neighbor <address>. BGP state is the current state, Previous State is the state before it, and Last reset gives the reason the session was torn down.

State changes are also logged to syslog. On IOS XR they appear as %ROUTING-BGP-5-ADJCHANGE, reporting the peer going up or down and the reason.

Common Reasons a Session Gets Stuck

Stuck inTypical causes
IdleNo route to the peer address. shutdown is configured. The BGP process is not running.
ActiveTCP port 179 is unreachable. The peer address is wrong. An ACL or firewall is blocking it. The eBGP peer is not directly connected and ebgp-multihop is not configured.
OpenSentThe configured remote-as does not match. The BGP Identifier (Router ID) is duplicated. The proposed Hold Time is unacceptable.
OpenConfirmKEEPALIVEs are not arriving. Traffic is failing in one direction.

In every case the Error code and subcode of the NOTIFICATION indicate the cause. For the list of error codes, see BGP Messages.

Verification on Real Devices

I use the same lab as in BGP (Border Gateway Protocol): four IOS XR (XRd) routers spread across three ASes. R1 - R2 is an iBGP peering, and R2 - R3 and R3 - R4 are eBGP peerings.

Starting from a healthy session, I deliberately introduce faults and observe how the state changes. The three operations below were performed, and in every case the configuration was restored and recovery confirmed.

TestOperation
Ashutdown the neighbor toward R3 on R2
BConfigure a peer that does not exist (10.2.3.99) on R2
CSet a wrong remote-as (65999) for R3 on R2

Test A: Administrative Shutdown

Shut down the neighbor toward R3 on R2.

Shutting down the neighbor on R2
router bgp 65001
 neighbor 10.2.3.3
  shutdown

The same event is displayed differently on the two sides. R2 shows Idle (Admin), making it explicit that the session was stopped by an administrator.

R2 show bgp summary (after the shutdown)
RP/0/RP0/CPU0:R2#show bgp summary
<snip>
Neighbor        Spk    AS MsgRcvd MsgSent       TblVer  InQ OutQ  Up/Down  St/PfxRcd
10.0.0.1          0 65001     104     110           14    0    0 01:40:22          1
10.2.3.3          0 65002     115     113            0    0    0 00:00:09  Idle (Admin)

R3, on the other hand, shows Idle and then moves to Active. After the session is torn down by the CEASE NOTIFICATION from R2, R3 keeps retrying the TCP connection on its own.

R3 show bgp summary (at the same time)
RP/0/RP0/CPU0:R3#show bgp summary
<snip>
Neighbor        Spk    AS MsgRcvd MsgSent       TblVer  InQ OutQ  Up/Down  St/PfxRcd
10.2.3.2          0 65001     111     115            0    0    0 00:00:17  Idle
10.3.4.4          0 65003     106     113           14    0    0 01:40:28          1

In show bgp neighbor, R2 gains an Administratively shut down line, and the reason in Last reset is recorded as an administrative shutdown with a CEASE NOTIFICATION sent.

R2 show bgp neighbor 10.2.3.3 (excerpt)
RP/0/RP0/CPU0:R2#show bgp neighbor 10.2.3.3
Sat Sep  5 04:50:39.569 UTC

BGP neighbor is 10.2.3.3
 Remote AS 65002, local AS 65001, external link
 Administratively shut down
 Description: eBGP to R3
 Remote router ID 0.0.0.0
  BGP state = Idle
  Previous State: Closing
  Last Received Message: KeepAlive
  NSR State: None
  Last read 00:00:00, Last read before reset 00:00:41
  Hold time is 180, keepalive interval is 60 seconds
  Configured hold time: 180, keepalive: 60, min acceptable hold time: 3
  Received 115 messages, 0 notifications, 0 in queue
  Sent 113 messages, 2 notifications, 0 in queue
  Connections established 2; dropped 2
  Local host: 10.2.3.2, Local port: 179, IF Handle: 0x00000020
  Foreign host: 10.2.3.3, Foreign port: 35164
  Last reset 00:00:29, due to Admin. shutdown (CEASE notification sent - administrative shutdown)
  Time since last notification sent to neighbor: 00:00:29
  Error Code: administrative shutdown

On R3 the state is Active, Last Received Message is Notification, and the reason in Last reset is that a NOTIFICATION was received. This shows that Active is not a healthy operating state but a state in which the connection is being retried.

R3 show bgp neighbor 10.2.3.2 (excerpt)
RP/0/RP0/CPU0:R3#show bgp neighbor 10.2.3.2
Sat Sep  5 04:51:04.588 UTC

BGP neighbor is 10.2.3.2
 Remote AS 65001, local AS 65002, external link
 Description: eBGP to R2
 Remote router ID 0.0.0.0
  BGP state = Active
  Previous State: Idle
  Last Received Message: Notification
  NSR State: None
  Last read 00:00:00, Last read before reset 00:00:54
  Hold time is 180, keepalive interval is 60 seconds
  Configured hold time: 180, keepalive: 60, min acceptable hold time: 3
  Received 111 messages, 2 notifications, 0 in queue
  Sent 115 messages, 0 notifications, 0 in queue
  Connections established 2; dropped 2
  Local host: 10.2.3.3, Local port: 35164, IF Handle: 0x00000010
  Foreign host: 10.2.3.2, Foreign port: 179
  Last reset 00:00:54, due to BGP Notification received: administrative shutdown
  Time since last notification received from neighbor: 00:00:54
  Error Code: administrative shutdown

State changes are also logged to syslog. After restoring with no shutdown, an Up message appeared about 20 seconds later.

R3 syslog (BGP lines only)
RP/0/RP0/CPU0:Sep  5 04:50:10.097 UTC: bgp[1084]: %ROUTING-BGP-5-ADJCHANGE : neighbor 10.2.3.2 Down - BGP Notification received, administrative shutdown (VRF: default) (AS: 65001) 
RP/0/RP0/CPU0:Sep  5 04:51:33.388 UTC: bgp[1084]: %ROUTING-BGP-5-ADJCHANGE : neighbor 10.2.3.2 Up (VRF: default) (AS: 65001) 

Here are the packets captured on the R2 - R3 link. After R2 sends the NOTIFICATION and closes the TCP session (No. 3 to 7), R3 repeatedly attempts a TCP connection and R2 refuses every one with an RST (No. 8 to 15). This is what the Active state on R3 actually looks like on the wire.

Packet capture between R2 and R3 (Test A)
    1   0.000000     10.2.3.3 → 10.2.3.2     BGP 73 KEEPALIVE Message
    2   0.203173     10.2.3.2 → 10.2.3.3     TCP 54 179 → 35164 [ACK] Seq=1 Ack=20 Win=31708 Len=0
    3  11.714561     10.2.3.2 → 10.2.3.3     BGP 75 NOTIFICATION Message
    4  11.714775     10.2.3.2 → 10.2.3.3     TCP 54 179 → 35164 [FIN, ACK] Seq=22 Ack=20 Win=31708 Len=0
    5  11.719860     10.2.3.3 → 10.2.3.2     TCP 54 35164 → 179 [ACK] Seq=20 Ack=23 Win=31814 Len=0
    6  11.722405     10.2.3.3 → 10.2.3.2     TCP 54 35164 → 179 [FIN, ACK] Seq=20 Ack=23 Win=31814 Len=0
    7  11.724591     10.2.3.2 → 10.2.3.3     TCP 54 179 → 35164 [ACK] Seq=23 Ack=21 Win=31708 Len=0
    8  52.113483     10.2.3.3 → 10.2.3.2     TCP 62 29663 → 179 [SYN] Seq=0 Win=32768 Len=0 MSS=1240 WS=1
    9  52.116845     10.2.3.2 → 10.2.3.3     TCP 54 179 → 29663 [RST, ACK] Seq=1 Ack=1 Win=0 Len=0
   10  54.114524     10.2.3.3 → 10.2.3.2     TCP 62 [TCP Port numbers reused] 29663 → 179 [SYN] Seq=0 Win=32768 Len=0 MSS=1240 WS=1
   11  54.117588     10.2.3.2 → 10.2.3.3     TCP 54 179 → 29663 [RST, ACK] Seq=1 Ack=1 Win=0 Len=0
   12  58.114782     10.2.3.3 → 10.2.3.2     TCP 62 [TCP Port numbers reused] 29663 → 179 [SYN] Seq=0 Win=32768 Len=0 MSS=1240 WS=1
   13  58.117419     10.2.3.2 → 10.2.3.3     TCP 54 179 → 29663 [RST, ACK] Seq=1 Ack=1 Win=0 Len=0
   14  66.115859     10.2.3.3 → 10.2.3.2     TCP 62 [TCP Port numbers reused] 29663 → 179 [SYN] Seq=0 Win=32768 Len=0 MSS=1240 WS=1
   15  66.119372     10.2.3.2 → 10.2.3.3     TCP 54 179 → 29663 [RST, ACK] Seq=1 Ack=1 Win=0 Len=0
   16  92.990066     10.2.3.2 → 10.2.3.3     TCP 62 55616 → 179 [SYN] Seq=0 Win=32768 Len=0 MSS=1240 WS=1

Inside the NOTIFICATION, the Error code is 6 (Cease) and the subcode is 2 (Administratively Shutdown). This is distinct from subcode 4 (Administratively Reset) seen with clear bgp in BGP Messages, so a shutdown can be told apart from a reset.

Download just this No.3 (NOTIFICATION) (bgp-neighbor-state-no3.pcap)
No. 3 NOTIFICATION (R2 to R3) tshark -V
Border Gateway Protocol - NOTIFICATION Message
    Marker: ffffffffffffffffffffffffffffffff
    Length: 21
    Type: NOTIFICATION Message (3)
    Major error Code: Cease (6)
    Minor error Code (Cease): Administratively Shutdown (2)

Test B: Configuring an Unreachable Peer

Configure the non-existent address 10.2.3.99 as a peer on R2.

Configuring an unreachable peer on R2
router bgp 65001
 neighbor 10.2.3.99
  remote-as 65099
  address-family ipv4 unicast
   route-policy PASS-ALL in
   route-policy PASS-ALL out

Since the TCP connection keeps failing, one would expect Active, but on XRd the state stayed Idle.

R2 show bgp summary (with the unreachable peer added)
RP/0/RP0/CPU0:R2#show bgp summary
<snip>
Neighbor        Spk    AS MsgRcvd MsgSent       TblVer  InQ OutQ  Up/Down  St/PfxRcd
10.0.0.1          0 65001     105     113           16    0    0 01:41:50          1
10.2.3.3          0 65002     120     118           14    0    0 00:00:14          2
10.2.3.99         0 65099       0       0            0    0    0 00:00:00  Idle

The details show zero messages sent and received, zero connections established, and not even a local port allocated (Local port: 0). Because the peer does not exist on the connected segment, ARP cannot be resolved, so no TCP connection request can even be sent and the session never progresses past Idle.

R2 show bgp neighbor 10.2.3.99 (excerpt)
RP/0/RP0/CPU0:R2#show bgp neighbor 10.2.3.99
Sat Sep  5 04:51:59.349 UTC

BGP neighbor is 10.2.3.99
 Remote AS 65099, local AS 65001, external link
 Description: test: unreachable peer
 Remote router ID 0.0.0.0
  BGP state = Idle
  Previous State: Idle
  Last Received Message: None
  NSR State: None
  Last read 00:00:00, Last read before reset 00:00:00
  Hold time is 180, keepalive interval is 60 seconds
  Configured hold time: 180, keepalive: 60, min acceptable hold time: 3
  Received 0 messages, 0 notifications, 0 in queue
  Sent 0 messages, 0 notifications, 0 in queue
  Connections established 0; dropped 0
  Local host: 0.0.0.0, Local port: 0, IF Handle: 0x00000000
  Foreign host: 10.2.3.99, Foreign port: 0
  Last reset 00:00:00
Active is the state reached after a TCP connection was attempted and failed; when the connection request cannot even be sent, the session stays in Idle. A wrong peer address can therefore show up as either Active or Idle, so it helps to also check whether Connections established and Local port remain 0.

Test C: Mismatched AS Numbers

On R2, change the remote-as for R3 to 65999, which does not match reality.

Misconfiguring remote-as on R2
router bgp 65001
 neighbor 10.2.3.3
  remote-as 65999

R2 expects AS number 65999 in the OPEN, but R3 announces 65002, so the mismatch is detected in the OpenSent stage and the session never establishes. The state is displayed as Idle.

R2 show bgp summary (AS number mismatch)
RP/0/RP0/CPU0:R2#show bgp summary
<snip>
Neighbor        Spk    AS MsgRcvd MsgSent       TblVer  InQ OutQ  Up/Down  St/PfxRcd
10.0.0.1          0 65001     106     115           18    0    0 01:42:51          1
10.2.3.3          0 65999     123     119            0    0    0 00:00:09  Idle

show bgp neighbor shows Connections established 3; dropped 3, meaning TCP connections were established and torn down repeatedly. TCP itself succeeds and the failure happens later, during validation of the OPEN.

R2 show bgp neighbor 10.2.3.3 (excerpt)
RP/0/RP0/CPU0:R2#show bgp neighbor 10.2.3.3
Sat Sep  5 04:52:48.303 UTC

BGP neighbor is 10.2.3.3
 Remote AS 65999, local AS 65001, external link
 Description: eBGP to R3
 Remote router ID 0.0.0.0
  BGP state = Idle
  Previous State: Closing
  Last Received Message: Update
  NSR State: None
  Hold time is 180, keepalive interval is 60 seconds
  Configured hold time: 180, keepalive: 60, min acceptable hold time: 3
  Received 123 messages, 0 notifications, 0 in queue
  Sent 119 messages, 2 notifications, 0 in queue
  Connections established 3; dropped 3
  Local host: 10.2.3.2, Local port: 55616, IF Handle: 0x00000020
  Foreign host: 10.2.3.3, Foreign port: 179
  Last reset 00:00:10, due to Remote AS configuration changed

R3’s syslog also records that the peer closed the session.

R3 syslog (BGP lines only)
RP/0/RP0/CPU0:Sep  5 04:52:38.290 UTC: bgp[1084]: %ROUTING-BGP-5-ADJCHANGE : neighbor 10.2.3.2 Down - Peer closing down the session (VRF: default) (AS: 65001) 

In the packet capture, the TCP three-way handshake completes (No. 37 to 39), and immediately after R3 sends its OPEN, R2 returns a NOTIFICATION and closes the session (No. 40 to 47). This is the classic shape of a failure in OpenSent: TCP reaches the peer, but the OPEN is rejected.

Packet capture between R2 and R3 (Test C)
   37 191.652350     10.2.3.3 → 10.2.3.2     TCP 62 38683 → 179 [SYN] Seq=0 Win=32768 Len=0 MSS=1240 WS=1
   38 191.656169     10.2.3.2 → 10.2.3.3     TCP 62 179 → 38683 [SYN, ACK] Seq=0 Ack=1 Win=16384 Len=0 MSS=1240 WS=1
   39 191.658813     10.2.3.3 → 10.2.3.2     TCP 54 38683 → 179 [ACK] Seq=1 Ack=1 Win=32768 Len=0
   40 191.660056     10.2.3.3 → 10.2.3.2     BGP 129 OPEN Message
   41 193.660811     10.2.3.3 → 10.2.3.2     TCP 129 [TCP Retransmission] 38683 → 179 [PSH, ACK] Seq=1 Ack=1 Win=32768 Len=75
   42 193.665035     10.2.3.2 → 10.2.3.3     TCP 54 179 → 38683 [ACK] Seq=1 Ack=76 Win=32768 Len=0
   43 193.665308     10.2.3.2 → 10.2.3.3     BGP 79 NOTIFICATION Message
   44 193.665415     10.2.3.2 → 10.2.3.3     TCP 54 179 → 38683 [FIN, ACK] Seq=26 Ack=76 Win=32768 Len=0
   45 193.668311     10.2.3.3 → 10.2.3.2     TCP 54 38683 → 179 [ACK] Seq=76 Ack=27 Win=32743 Len=0
   46 193.670023     10.2.3.3 → 10.2.3.2     TCP 54 38683 → 179 [FIN, ACK] Seq=76 Ack=27 Win=32743 Len=0
   47 193.672491     10.2.3.2 → 10.2.3.3     TCP 54 179 → 38683 [ACK] Seq=27 Ack=77 Win=32768 Len=0
   48 223.666499     10.2.3.2 → 10.2.3.3     TCP 54 179 → 38683 [RST, ACK] Seq=27 Ack=77 Win=32768 Len=0

The NOTIFICATION carries Error code 2 (OPEN Message Error) with subcode 2 (Bad Peer AS), indicating that the configured remote-as does not match the AS number the peer actually announced.

Download just this No.43 (NOTIFICATION) (bgp-neighbor-state-no43.pcap)
No. 43 NOTIFICATION (R2 to R3) tshark -V
Border Gateway Protocol - NOTIFICATION Message
    Marker: ffffffffffffffffffffffffffffffff
    Length: 25
    Type: NOTIFICATION Message (3)
    Major error Code: OPEN Message Error (2)
    Minor error Code (Open Message): Bad Peer AS (2)
    Bad Peer AS: 3942449152

Recovery

Restoring remote-as to the correct 65002 brings the session back up.

R2 syslog (BGP lines only)
RP/0/RP0/CPU0:Sep  5 04:54:23.213 UTC: bgp[1084]: %ROUTING-BGP-5-ADJCHANGE : neighbor 10.2.3.3 Up (VRF: default) (AS: 65002) 
R2 show bgp summary (after recovery)
RP/0/RP0/CPU0:R2#show bgp summary
<snip>
Neighbor        Spk    AS MsgRcvd MsgSent       TblVer  InQ OutQ  Up/Down  St/PfxRcd
10.0.0.1          0 65001     108     118           20    0    0 01:44:45          1
10.2.3.3          0 65002     131     127           20    0    0 00:00:18          2

The configuration was restored at 04:53:46 and the Up message appeared at 04:54:23, so recovery took about 37 seconds. After repeated connection failures the wait before the next attempt grows, so a session may not reach Established immediately after the configuration is fixed.

Here are the packets during recovery. TCP establishment, the OPEN exchange, acceptance with KEEPALIVEs, and route exchange with UPDATEs all flow in one sequence, exactly the normal session establishment procedure described in BGP Messages.

Packet capture between R2 and R3 (recovery)
   63 262.819168     10.2.3.2 → 10.2.3.3     TCP 62 23990 → 179 [SYN] Seq=0 Win=32768 Len=0 MSS=1240 WS=1
   64 262.822744     10.2.3.3 → 10.2.3.2     TCP 62 179 → 23990 [SYN, ACK] Seq=0 Ack=1 Win=16384 Len=0 MSS=1240 WS=1
   65 262.825677     10.2.3.2 → 10.2.3.3     TCP 54 23990 → 179 [ACK] Seq=1 Ack=1 Win=32768 Len=0
   66 262.827615     10.2.3.2 → 10.2.3.3     BGP 129 OPEN Message
   67 264.828419     10.2.3.2 → 10.2.3.3     TCP 129 [TCP Retransmission] 23990 → 179 [PSH, ACK] Seq=1 Ack=1 Win=32768 Len=75
   68 264.833015     10.2.3.3 → 10.2.3.2     TCP 54 179 → 23990 [ACK] Seq=1 Ack=76 Win=32768 Len=0
   69 264.833261     10.2.3.3 → 10.2.3.2     BGP 148 OPEN Message, KEEPALIVE Message
   70 264.837829     10.2.3.2 → 10.2.3.3     BGP 73 KEEPALIVE Message
   71 264.869424     10.2.3.3 → 10.2.3.2     BGP 194 UPDATE Message, UPDATE Message, UPDATE Message
   72 265.072809     10.2.3.2 → 10.2.3.3     TCP 54 23990 → 179 [ACK] Seq=95 Ack=235 Win=32534 Len=0
   73 266.867355     10.2.3.2 → 10.2.3.3     BGP 190 UPDATE Message, UPDATE Message, UPDATE Message
   74 267.072666     10.2.3.3 → 10.2.3.2     TCP 54 179 → 23990 [ACK] Seq=235 Ack=231 Win=32613 Len=0
Download bgp-neighbor-state.pcap

Configuration Files

Download R1 config (r1_bgp-neighbor-state.cfg)

Download R2 config (r2_bgp-neighbor-state.cfg)

Download R3 config (r3_bgp-neighbor-state.cfg)

Download R4 config (r4_bgp-neighbor-state.cfg)

References

SourceTitleSummary
RFC 4271A Border Gateway Protocol 4 (BGP-4)The base specification of BGP-4; Section 8 defines the FSM (state transitions).
IANABorder Gateway Protocol (BGP) ParametersThe registry of numbers used by BGP, including NOTIFICATION error codes and subcodes.

Related Articles