quagga源碼學習--BGP協議對等體連接建立的狀態機


創建完bgp peer之后,就要bgp start了,不然費那么大勁創建出來不做事情就銷毀了,就很尷尬了。

那么對等體一旦start起來,就會進入各自的狀態,在不同的狀態下處理各自的事件消息。

下面列舉一些狀態和事件的集合:

 1 /* BGP finite state machine status.  */
 2 #define Idle                                     1
 3 #define Connect                                  2
 4 #define Active                                   3
 5 #define OpenSent                                 4
 6 #define OpenConfirm                              5
 7 #define Established                              6
 8 #define Clearing                                 7
 9 #define Deleted                                  8
10 #define BGP_STATUS_MAX                           9
11 
12 /* BGP finite state machine events.  */
13 #define BGP_Start                                1
14 #define BGP_Stop                                 2
15 #define TCP_connection_open                      3
16 #define TCP_connection_closed                    4
17 #define TCP_connection_open_failed               5
18 #define TCP_fatal_error                          6
19 #define ConnectRetry_timer_expired               7
20 #define Hold_Timer_expired                       8
21 #define KeepAlive_timer_expired                  9
22 #define Receive_OPEN_message                    10
23 #define Receive_KEEPALIVE_message               11
24 #define Receive_UPDATE_message                  12
25 #define Receive_NOTIFICATION_message            13
26 #define Clearing_Completed                      14
27 #define BGP_EVENTS_MAX                          15

全局變量FSM定義了狀態機每個狀態下的動作執行之后的下一個狀態:

1 /* Finite State Machine structure */
2 static const struct {
3   int (*func) (struct peer *);
4   int next_state;
5 } FSM [BGP_STATUS_MAX - 1][BGP_EVENTS_MAX - 1]

限於篇幅就不掉書袋了。

下面的bgp_event函數是通用的事件處理流程,通過FSM數組的定義在這里就能看到了化繁為簡的效果:

 1 /* Execute event process. */
 2 int
 3 bgp_event(struct thread *thread) {
 4     ......
 5     
 6     /* Logging this event. */
 7     next = FSM[peer->status - 1][event - 1].next_state;
 8 
 9     /* Call function. */
10     if (FSM[peer->status - 1][event - 1].func) ret = (*(FSM[peer->status - 1][event - 1].func))(peer);
11 
12     /* When function do not want proceed next job return -1. */
13     if (ret >= 0) {
14         /* If status is changed. */
15         if (next != peer->status) bgp_fsm_change_status(peer, next);
16         /* Make sure timer is set. */
17         bgp_timer_set(peer);
18     }
19     return ret;
20 }

上面可以看到bgp_timer_set這個函數,它在bgp_create的時候也會調用,通過它將任務添加到thread消息調度流程中去,維持整個協議流程的運轉。

 

bgp是基於tcp協議的,即包含了tcp協議的優點,因此上面的狀態機也就跟tcp連接有一定的關系:

1、tcp連接建立階段的狀態:Idle, Connect, Active

2、tcp連接建立完成之后: OpenSent, OpenConfirm, Established

 

進入到Established階段,說明一切正常,可以開始交換路由了。

 

附錄:

BGP有限狀態機

BGP有限狀態機共有六種狀態,分別是Idle、Connect、Active、OpenSent、OpenConfirm和Established。
    Idle狀態下,BGP拒絕任何進入的連接請求,是BGP初始狀態。
    Connect狀態下,BGP等待TCP連接的建立完成后再決定后續操作。
    Active狀態下,BGP將嘗試進行TCP連接的建立,是BGP的中間狀態。
    OpenSent狀態下,BGP等待對等體的Open消息。
    OpenConfirm狀態下,BGP等待一個Notification報文或Keepalive報文。
    Established狀態下,BGP對等體間可以交換Update報文、Route-Refresh報文、Keepalive報文和Notification報文。
    
在BGP對等體建立的過程中,通常可見的三個狀態是:Idle、Active、Established。
BGP對等體雙方的狀態必須都為Established,BGP鄰居關系才能成立,雙方通過Update報文交換路由信息。

BGP處理過程

    因為BGP的傳輸層協議是TCP協議,所以在BGP對等體建立之前,對等體之間首先進行TCP連接。BGP鄰居間會通過Open消息協商相關參數,建立起BGP對等體關系。
    建立連接后,BGP鄰居之間交換整個BGP路由表。BGP協議不會定期更新路由表,但當BGP路由發生變化時,會通過Update消息增量地更新路由表。 BGP會發送Keepalive消息來維持鄰居間的BGP連接。當BGP檢測到網絡中的錯誤狀態時(例如:收到不支持的協商能力或者收到錯誤報文時),BGP會發送Notification消息進行報錯,BGP連接會隨即中斷。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM