0

What is the significance of having two different states in FSM when both try to establish TCP Connection?

2

BGP Peers start in Idle state. In Idle state, the peers have been configured to form an adjacency with one another other, but have not yet initiated or received any communication.

BGP uses TCP as it's transport. So for there to be a BGP adjacency, the first step is to establish a TCP connection. While both peers are in IDLE state, they will each periodically attempt to initiate a TCP connection at independent intervals (based upon when the BGP peering configuration was actually completed).

When one peer initiates the TCP three way handshake with a SYN , that peer transitions into Active state. This state indicates the local router is actively trying to initiate a TCP connection.

When the other peer receives the TCP SYN from it's peer, it will transition into Connect state. This state indicates the local router has received a TCP initiation from the other router, and is/has responded with a SYN ACK.

From there, both peers continue through the remaining states: Open Sent, Open Confirmed, Established.

To summarize:

  • Active state - local router has just sent a TCP SYN
  • Connect state - local router has just received a TCP SYN from it's peer

The "initiating" BGP speaker's state transitions to form the adjacency will be: Idle, Active, Open Sent, Open Received, Established

The "responding" BGP speaker's state transitions to form the adjacency will be: Idle, Connect, Open Sent, Open Received, Established

Notice, only the peer which Initiated the TCP handshake passes through Active state. And only the peer which did NOT initiate the TCP handshake passes through the Connect state.


Adding some debugs which prove the behavior. This is Cisco router code Version 15.4(1)T.

This is from a BGP peering session between R1 (9.9.12.1) and R2 (9.9.12.2).

R2 is the initiator for this TCP session:

router1# show ip bgp neighbors | i ^BGP|host
BGP neighbor is 9.9.12.2,  remote AS 2323, external link
Local host: 9.9.12.1, Local port: 179
Foreign host: 9.9.12.2, Foreign port: 43876

Confirmed on the other Router:

router2# show ip bgp neighbors | i ^BGP|host
BGP neighbor is 9.9.12.1,  remote AS 1111, external link
Local host: 9.9.12.2, Local port: 43876
Foreign host: 9.9.12.1, Foreign port: 179

This is the (filtered) debug on R2, the initiator:

$ cat BGP-Peering_Initiator.txt | grep -e "TCP src" -e "went from"
*Oct 28 17:06:36.971: BGP: 9.9.12.1 active went from Idle to Active
*Oct 28 17:06:36.972:     TCP src=43876, dst=179, seq=1526684246, ack=0, win=16384 SYN
*Oct 28 17:06:36.975:     TCP src=179, dst=43876, seq=2072809595, ack=1526684247, win=16384 ACK SYN
*Oct 28 17:06:36.975:     TCP src=43876, dst=179, seq=1526684247, ack=2072809596, win=16384 ACK
*Oct 28 17:06:36.977: BGP: 9.9.12.1 active went from Active to OpenSent
*Oct 28 17:06:36.982:     TCP src=43876, dst=179, seq=1526684247, ack=2072809596, win=16384 ACK PSH
*Oct 28 17:06:36.985:     TCP src=179, dst=43876, seq=2072809596, ack=1526684304, win=16327 ACK
*Oct 28 17:06:36.985:     TCP src=179, dst=43876, seq=2072809596, ack=1526684304, win=16327 ACK PSH
*Oct 28 17:06:36.985: BGP: 9.9.12.1 active went from OpenSent to OpenConfirm
*Oct 28 17:06:36.985:     TCP src=43876, dst=179, seq=1526684304, ack=2072809653, win=16327 ACK PSH
*Oct 28 17:06:36.987:     TCP src=179, dst=43876, seq=2072809653, ack=1526684304, win=16327 ACK PSH
*Oct 28 17:06:36.987: BGP: 9.9.12.1 active went from OpenConfirm to Established

And this is the (filtered) debug on R1, the responder:

$ cat BGP-Peering_Responder.txt | grep -e "TCP src" -e "went from"
*Oct 28 17:06:36.973:     TCP src=43876, dst=179, seq=1526684246, ack=0, win=16384 SYN
*Oct 28 17:06:36.974:     TCP src=179, dst=43876, seq=2072809595, ack=1526684247, win=16384 ACK SYN
*Oct 28 17:06:36.976:     TCP src=43876, dst=179, seq=1526684247, ack=2072809596, win=16384 ACK
*Oct 28 17:06:36.976: BGP: 9.9.12.2 passive went from Idle to Connect
*Oct 28 17:06:36.983:     TCP src=43876, dst=179, seq=1526684247, ack=2072809596, win=16384 ACK PSH
*Oct 28 17:06:36.984:     TCP src=179, dst=43876, seq=2072809596, ack=1526684304, win=16327 ACK
*Oct 28 17:06:36.984: BGP: 9.9.12.2 passive went from Connect to OpenSent
*Oct 28 17:06:36.984: BGP: 9.9.12.2 passive went from OpenSent to OpenConfirm
*Oct 28 17:06:36.985:     TCP src=179, dst=43876, seq=2072809596, ack=1526684304, win=16327 ACK PSH
*Oct 28 17:06:36.986:     TCP src=179, dst=43876, seq=2072809653, ack=1526684304, win=16327 ACK PSH
*Oct 28 17:06:36.986:     TCP src=43876, dst=179, seq=1526684304, ack=2072809653, win=16327 ACK PSH
*Oct 28 17:06:36.986: BGP: 9.9.12.2 passive went from OpenConfirm to Established
| improve this answer | |
  • You actually have the Active and Connect states backwards. For example, The RFC says this about the Active state: "Active State: In this state, BGP FSM is trying to acquire a peer by listening for, and accepting, a TCP connection." Also, "Connect State: In this state, BGP FSM is waiting for the TCP connection to be completed." Having sent the TCP SYN. – Ron Maupin Oct 28 '19 at 16:38
  • 1
    Hi @RonMaupin . I don't think I do. I got curious after writing it out and labbed it out, and it confirms the Active/Connect states work as I described them. I'll try to put together "neat" debug output and add it to the answer. – Eddie Oct 28 '19 at 17:01
  • 1
    @RonMaupin Just added the debugs, see above. Also, I'm much more concerned with what Cisco does than what Cisco says. Feel free to tell me if you see/suspect that I'm interpreting the debugs incorrectly. – Eddie Oct 28 '19 at 17:34
  • 1
    Looking at it, the only thing I see is the responder went from Idle to Connect after the TCP connection completed. In my answer I said it was after sending the SYN/ACK. It seems it actually transitions after receiving the final ACK. – Eddie Oct 28 '19 at 17:38
  • 1
    I would interpret the line "Oct 28 17:06:36.971: BGP: 9.9.12.1 active went from Idle to Active" as R1 is going from Idle to Active. Since R2 is initiating the TCP session, this would confirm @RonMaupins view. – Mathias Weidner Oct 30 '19 at 17:01
1

TCP creates a connection between two peers, and BGP uses TCP. One TCP peer will try to connect to the other TCP peer, and this is the connect state. One peer may listen for a connection (especially after a failed connection attempt on its part), and this is the active state.

BGP has several states, and each is clearly documented in RFC 4271, A Border Gateway Protocol 4 (BGP-4). The descriptions of the states and moving from one to another (and/or back) is really too large to discuss here. Below is an image that describes the BGP Finite State Machine (FSM):

enter image description here

The RFC has full description of the various states of the FSM and what happens in each stage.

Starting with the Idle state, when a ManualStart or AutomaticStart event happens on the system, it changes its state to Connect, but the passive versions of those events (ManualStart_with_PassiveTcpEstablishment or AutomaticStart_with_PassiveTcpEstablishment) happens, then it changes its state to Active. Basicially, when it is told to connect to a peer, it changes to Connect, but when told to listen for a peer, it changes to Active.

When in the Connect state, if the TCP connection fails, it changes its state to Active to listen for a connection from the peer.

When in the Active state, and the ConnectRetryTimer_Expires event happens, then it tries the TCP connection and goes into the Connect state.

There really is a lot more to it than that, but it is far too large for a site like this.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.