一、OSPF簡介
OSPF(Open Shortest Path First)是一種基於鏈路狀態的路由協議,常見於企業級網絡中。它通過在整個網絡中分發和計算鏈路狀態信息來構建當前最短路徑樹。OSPF支持基於IPv4和IPv6的網絡,同時可以對不同類型的網絡進行分層管理。
二、OSPF狀態機介紹
OSPF路由器的工作狀態可以根據不同的條件發生變化。狀態機是用來描述和維護OSPF路由器工作狀態變化的一種方法。
在OSPF中,每個鄰居路由器都有一個獨特的標識符。狀態機會針對每個鄰居路由器分別維護一組狀態。OSPF狀態機主要包括以下四種狀態:
- Down狀態:在Down狀態下,路由器沒有和鄰居路由器建立鄰居關係。
- Init狀態:在Init狀態下,路由器正在嘗試和鄰居路由器建立鄰居關係。
- Two-way狀態:在Two-way狀態下,路由器和鄰居路由器已經建立了鄰居關係並且可以互相通信。
- Full狀態:在Full狀態下,路由器和鄰居路由器擁有完整的鄰居關係,可以在路由表中交換完整的路由信息。
三、狀態機過程
1. 鄰居路由器發現
在OSPF中,路由器通過多播方式向網絡中的所有路由器發送Hello報文。當兩個路由器收到對方發送的Hello報文,就會建立鄰居關係。
void ospf_rx_hello(ospf_packet* pkt, interface_t* iface){ //檢查收到的報文是否是Hello廣播報文 if(!pkt->header->lsp_type == OSPF_LSP_TYPE_HELLO){ return; } //從報文中提取鄰居路由器信息 neighbor_info_t neighbor_info; neighbor_info.router_id = pkt->header->router_id; neighbor_info.ip_address = ntohl(pkt->hello->neighbor_ip); //根據提供的鄰居信息更新狀態機中對應路由器的狀態 neighbor_t* neighbor = ospf_add_neighbor(iface->ospf_if, neighbor_info); if(neighbor){ switch(neighbor->state){ case OSPF_NEIGHBOR_STATE_DOWN: ospf_neighbor_event(neighbor, OSPF_NEIGHBOR_EVENT_HELLO_RECEIVED); break; case OSPF_NEIGHBOR_STATE_INIT: ospf_neighbor_event(neighbor, OSPF_NEIGHBOR_EVENT_HELLO_RECEIVED); ospf_neighbor_event(neighbor, OSPF_NEIGHBOR_EVENT_TWO_WAY_RECEIVED); break; case OSPF_NEIGHBOR_STATE_TWO_WAY: ospf_neighbor_event(neighbor, OSPF_NEIGHBOR_EVENT_HELLO_RECEIVED); ospf_neighbor_event(neighbor, OSPF_NEIGHBOR_EVENT_TWO_WAY_RECEIVED); ospf_neighbor_event(neighbor, OSPF_NEIGHBOR_EVENT_ADJ_EXSTART_RECEIVED); break; case OSPF_NEIGHBOR_STATE_EXSTART: case OSPF_NEIGHBOR_STATE_EXCHANGE: case OSPF_NEIGHBOR_STATE_LOADING: case OSPF_NEIGHBOR_STATE_FULL: default: break; } } }
2. 鄰居狀態變更
在OSPF中,鄰居狀態發生變化可能是由於不同事件觸發的。比如,當一方路由器收到另一方路由器的Database Descriptor報文時,就會觸發鄰居狀態從Exchange狀態轉換為Loading狀態。同樣地,鄰居狀態也有可能由於鏈接失效而發生變化,此時狀態機會判斷鄰居路由器是否已經失去連接,並觸髮狀態轉換事件。
void ospf_neighbor_state_machine(neighbor_t* neighbor, ospf_neighbor_event_t event){ switch(neighbor->state){ case OSPF_NEIGHBOR_STATE_DOWN: if(event == OSPF_NEIGHBOR_EVENT_HELLO_RECEIVED){ neighbor->state = OSPF_NEIGHBOR_STATE_INIT; } break; case OSPF_NEIGHBOR_STATE_INIT: if(event == OSPF_NEIGHBOR_EVENT_HELLO_RECEIVED){ neighbor->state = OSPF_NEIGHBOR_STATE_TWO_WAY; } break; case OSPF_NEIGHBOR_STATE_TWO_WAY: if(event == OSPF_NEIGHBOR_EVENT_TWO_WAY_RECEIVED){ neighbor->state = OSPF_NEIGHBOR_STATE_TWO_WAY; } else if(event == OSPF_NEIGHBOR_EVENT_ADJ_EXSTART_RECEIVED){ neighbor->state = OSPF_NEIGHBOR_STATE_EXSTART; ospf_adj_state_machine(neighbor, event); } break; case OSPF_NEIGHBOR_STATE_EXSTART: //... break; case OSPF_NEIGHBOR_STATE_EXCHANGE: //... break; case OSPF_NEIGHBOR_STATE_LOADING: //... break; case OSPF_NEIGHBOR_STATE_FULL: //... break; } }
3. 鄰居關係建立
在OSPF中,當一個路由器和鄰居路由器建立完整的鄰居關係後,可以在路由表中交換完整的路由信息。
void ospf_rx_dbd(ospf_packet* pkt, neighbor_t* neighbor, interface_t* iface){ //檢查收到的報文是否是Database Descriptor報文 if(!pkt->header->lsp_type == OSPF_LSP_TYPE_DBD){ return; } //處理Database Descriptor報文 ospf_adj_state_machine(neighbor, OSPF_NEIGHBOR_EVENT_ADJ_EXCHANGE); //檢查鄰居路由器的狀態,決定是否可以開始交換LSA信息 switch(neighbor->state){ case OSPF_NEIGHBOR_STATE_EXCHANGE: if(ospf_is_exchange_done(neighbor)){ ospf_adj_state_machine(neighbor, OSPF_NEIGHBOR_EVENT_ADJ_EXCHANGE_DONE); } break; case OSPF_NEIGHBOR_STATE_LOADING: //... break; case OSPF_NEIGHBOR_STATE_FULL: if(ospf_is_exchange_done(neighbor)){ ospf_adj_state_machine(neighbor, OSPF_NEIGHBOR_EVENT_ADJ_EXCHANGE_DONE); ospf_send_ls_upd(neighbor, iface); } break; default: break; } }
四、總結
OSPF是一種分布式的鏈路狀態路由協議,具有高度的自適應性和可擴展性。OSPF路由器之間的鄰居關係是通過狀態機進行維護和改變的。狀態機確定了路由器之間不同狀態的轉換條件和事件。狀態機的實現需要依據實際情況進行調整和修改。
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/230465.html