創建完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連接會隨即中斷。