OSPF和OSPF鄰接關係的建立過程

一、OSPF的簡單介紹

       OSPF(Open Shortest Path First,開放式最短路優先)是一種典型的鏈路狀態路由協議,由IETF(Internet Engineering Task Force,Internet工程任務組)的OSPF工作小組開發,是目前應用最廣泛的IGP(Interior Gateway Protocal,內部網關協議)之一。OSPF中的“O”意爲“Open”,即開放的意思,所有的廠商的設備都可以實現OSPF,它們都要遵循公有標準。OSPF支VLSM(Variable Length Subnet Mask,可變長子網掩碼)、支持認證、支持路由彙總等,另外區域(Area)的概念引入使得OSPF能夠支持更大規模的網絡。當網絡拓撲發生變化時,OSPF能夠快速地感知並進行路由的計算和重新收斂。目前OSPF主要有兩個版本,一是OSPFv2,該版本主要針對IPv4;另外一個版本是OSPFv3,該版本主要針對IPv6。本文主要探討OSPFv2。

二、OSPF的基本概念

2.1 基本原理

       《計算機網絡》這本書中是這樣表述OSPF的“在OSPF協議中,路由器會將自己的鏈路狀態信息一次性地泛洪給其他路由器”,通俗點的理解是這樣的,每臺路由器都產生一個描述自家門口情況的通告。這些通告會泛洪到整個網絡,從而保證網絡中的每臺路由器都擁有對該網絡的一直認知。路由器將這些鏈路狀態信息存儲在LSDB(Link-State Database,鏈路狀態數據庫)之中,LSDB內的數據有助於路由器還原全網的拓撲結構。接下來,每臺路由器都基於LSDB使用相同的算法進行計算,計算的結果是得到一顆以自己爲根的、無環的最短路徑“樹”。有了這棵樹“樹”,事實上路由器就已經知道了到達網絡各個角落的最優路徑。最後,路由器將計算出來的最優路徑加載到自己的路由表。

2.2 Router-ID

       OSPF Router-ID(Router Identification,路由器標識符)是一個32bit長度的數值,通常使用點分十進制的形式表現,用於在OSPF域中唯一標識一臺OSPF路由器。OSPF要求路由器的Router-ID必須全域唯一,即在同一個域內不允許出現兩臺OSPF路由器擁有相同Router-ID的情況。

2.3 OSPF的三張表

  • 鄰居表
           在OSPF交互鏈路狀態通告之前,兩臺直連路由器需建立OSPF鄰居關係。當一個接口激活OSPF後,該接口將週期性地發送OSPF Hello報文,同時也開始偵聽Hello報文從而發現直連鏈路上的鄰居。當OSPF在接口上發現鄰居後,鄰居的信息就會被寫入路由器的OSPF鄰居表,隨後一個鄰接關係的建立過程也就開始了。下圖是運行了OSPF的華爲路由器的鄰居表。從這張表中我們可以看見路由器的鄰居狀態(Full)、Router ID、主從關係(Slave)、接口IP地址等信息。
    在這裏插入圖片描述
  • 鏈路狀態數據庫
           運行鏈路狀態路由協議的路由器在網絡中泛洪鏈路狀態信息,在OSPF中,這些信息被稱 LSA(Link-State Advertisement,鏈路狀態通告),路由器將網絡中的LSA蒐集後裝載到自己的LSDB中,因此LSDB可以當作是路由器對網絡的完整認知。下圖是運行了OSPF的華爲路由器的LSDB。
    在這裏插入圖片描述
  • OSPF路由表
           OSPF根據LSDB中的數據,運行SPF算法並且得到一顆以自己爲根的、無環的最短路徑樹,基於這棵樹,OSPF能夠發現到達網絡中各個網段的最佳路徑,從而得到路由信息並將其加載到OSPF路由表中。下圖展示的是一個OSPF路由表。
    在這裏插入圖片描述

三、報文類型及其格式

       OSPF協議基於IP運行,協議的數據報文直接採用IP封裝,在IP報文頭部中對應的協議號爲89。多數情況下,OSPF的協議報文使用組播地址作爲目的IP地址。OSPF一共定義了五種報文,各有用途下表羅列了這五種報文,以及報文的描述。

類型 報文名稱 報文描述
1 Hello 用於發現直連鏈路上的OSPF鄰居,以及維護OSPF鄰居關係
2 DD(Database Description,數據庫描述) 用於描述LSDB,該報文中攜帶的是LSDB中LSA的頭部數據
3 LSR(Link State Request,鏈路狀態請求) 用於向OSPF鄰居請求LSA
4 LSU(Link State Update,鏈路狀態更新) 用於發送LSA,該報文中攜帶的是完整的LSA數據。LSA是承載在LSU中進行泛洪的
5 LSAck(Link State Acknowledgment,鏈路狀態確認) 設備收到LSU後,LSAck用於對接收的LSA進行確認

3.1 OSPF報文頭格式

      OSPF這五種報文具有相同的報文頭格式,長度爲24字節。
                     在這裏插入圖片描述
                                                               OSPF報文頭格式

字段 長度 含義
Version 1字節 版本,OSPF的版本號。對於OSPFv2來說,其值爲2。
Type 1字節 類型,OSPF報文的類型,有下面幾種類型:1:Hello報文;2:DD報文;3:LSR報文;4:LSU報文;5:LSAck報文。
Packet length 2字節 OSPF報文的總長度,包括報文頭在內,單位爲字節。
Router ID 4字節 發送該報文的路由器標識。
Area ID 4字節 發送該報文的所屬區域。
Checksum 2字節 校驗和,包含除了認證字段的整個報文的校驗和。
AuType 2字節 驗證類型,值有如下幾種表示, 0:不驗證;1:簡單認證;2:MD5認證。
Authentication 8字節 鑑定字段,其數值根據驗證類型而定。當驗證類型爲0時未作定義;類型爲1時此字段爲密碼信息;類型爲2時此字段包括Key ID、MD5驗證數據長度和序列號的信息。MD5驗證數據添加在OSPF報文後面,不包含在Authenticaiton字段中。

3.2 Hello報文

       Hello報文是最常用的一種報文,其作用爲建立和維護鄰接關係,週期性的在使能了OSPF的接口上發送。報文內容包括一些定時器的數值、DR、BDR以及自己已知的鄰居。
                     在這裏插入圖片描述
                                                               OSPF Hello報文格式

字段 長度 含義
Network Mask 32比特 發送Hello報文的接口所在網絡的掩碼。
HelloInterval 16比特 發送Hello報文的時間間隔。
Options 8比特 可選項:E:允許Flood AS-External-LSAs MC:轉發IP組播報文 N/P:處理Type-7 LSAsDC:處理按需鏈路
Rtr Pri 8比特 DR優先級。默認爲1。如果設置爲0,則路由器不能參與DR或BDR的選舉。
RouterDeadInterval 32比特 失效時間。如果在此時間內未收到鄰居發來的Hello報文,則認爲鄰居失效。
Designated Router 32比特 DR的接口地址。
Backup Designated Router 32比特 BDR的接口地址。
Neighbor 32比特 鄰居,以Router ID標識。

下面是抓包圖:
在這裏插入圖片描述

3.3 DD報文

       兩臺路由器在鄰接關係初始化時,用DD報文(Database Description Packet)來描述自己的LSDB,進行數據庫的同步。
                     在這裏插入圖片描述
                                                               OSPF DD報文格式

字段 長度 含義
Interface MTU 16比特 在不分片的情況下,此接口最大可發出的IP報文長度。
Options 8比特 可選項: E:允許Flood AS-External-LSAs;MC:轉發IP組播報文;N/P:處理Type-7 LSAs;DC:處理按需鏈路。
I 1比特 當發送連續多個DD報文時,如果這是第一個DD報文,則置爲1,否則置爲0。
M (More) 1比特 當發送連續多個DD報文時,如果這是最後一個DD報文,則置爲0。否則置爲1,表示後面還有其他的DD報文。
M/S (Master/Slave) 1比特 當兩臺OSPF路由器交換DD報文時,首先需要確定雙方的主從關係,Router ID大的一方會成爲Master。當值爲1時表示發送方爲Master。
DD sequence number 32比特 DD報文序列號。主從雙方利用序列號來保證DD報文傳輸的可靠性和完整性。
LSA Headers 可變 該DD報文中所包含的LSA的頭部信息。

下面是抓包圖:在這裏插入圖片描述

3.4 LSR報文

      兩臺路由器互相交換過DD報文之後,知道對端的路由器有哪些LSA是本地的LSDB所缺少的和哪些LSA是已經失效的,這時需要發送LSR報文(Link State Request Packet)向對方請求所需的LSA。內容包括所需要的LSA的摘要。
                     在這裏插入圖片描述
                                                        OSPF LSR報文格式

字段 長度 含義
LS type 32比特 LSA的類型號。
Link State ID 32比特 根據LSA中的LS Type和LSA description在路由域中描述一個LSA。
Advertising Router 32比特 產生此LSA的路由器的Router ID。

下面是抓包圖:
在這裏插入圖片描述

3.5 LSU報文

       路由器收到鄰居發送過來的LSR後,會以LSU報文進行迴應,在LSU報文中就包含了對方請求的LSA的完整信息,一個LSU可以包含多個LSA。
                     在這裏插入圖片描述
                                                        OSPF LSU報文格式

字段 長度 含義
Number of LSAs 32比特 LSA的數量。

下面是抓包圖:
在這裏插入圖片描述

3.6 LSAck報文

       爲了確保LSA能夠可靠送達,當一臺路由器收到鄰居發送過來的LSU報文時。需要對報文中含有的LSA進行確認,這個確認行爲可以回覆一個LSAck報文。
                     在這裏插入圖片描述
                                                        OSPF LSU報文格式

字段 長度 含義
LSAs Headers 可變 通過LSA的頭部信息確認收到該LSA。

下面是抓包圖:
在這裏插入圖片描述
四、鄰接關係及其建立

4.1 鄰接關係

       在《報文類型及其格式》一節中,我們已經知道了路由器在運行了OSPF之後會進行一系列的報文交互,最後完成LSDB的同步,路由器形成了對網絡拓撲的一致認知,並開始獨立計算路由。此時,我們稱這兩臺路由器形成了鄰接關係。接下來具體學習鄰接關係建立過程之前我們先了解8種OSPF的鄰居狀態。

狀態 狀態描述
Down(失效) OSPF路由器的初始狀態
Init(初始) 當OSPF路由器收到直連鏈路上某個鄰居發送過來的有效Hello報文,但並未在Hello報文的鄰居字段看到自己的Router-ID
Attempt(嘗試) 該狀態只在NBMA類型的接口中出現
2-Way(雙向通信) 當OSPF路由器收到直連鏈路上某個鄰居發送過來的Hello報文,並在Hello報文的鄰居字段看到自己的Router-ID
ExStart(j交換初始) 在該狀態下路由器協商Master/Slave
Exchange(交換) 該狀態下路由器向自己的鄰居發送描述自己LSDB的DD報文,報文中含有LSA的頭部
Loading(加載) 路由器向鄰居發送LSR以便請求完整LSA
Full(全毗鄰) LSA列表爲空,LSDB完成同步

4.2 鄰接關係的建立

              在這裏插入圖片描述
                                          R1與R2在直連鏈路上發現彼此形成鄰居關係

       在上圖的例子中兩個路由器的對應接口都激活OSPF,R1的接口激活OSPF後開始發送組播的Hello報文,在該報文的OSPF頭部中,填寫着R1的Router-ID和區域ID,Hello報文的荷載中,填寫着其他信息(詳細見上圖)。R2在收到這個報文後,首先檢查對接方的子網掩碼、Hello間隔、路由器失效間隔是否一致,如果不一致忽略該報文。如果通過了檢查R2將R1狀態設置爲Init。接下來,R2在自己發送的Hello報文的“鄰居”字段中寫入R1的Router-ID。而當R1收到R2發送過來的Hello報文並且在“鄰居”字段中發現自己的Router-ID時,它意識到鄰居R2已經發現了自己,並且認可了自己所發送的Hello報文中的相關參數,於是它將R2添加到自己的鄰居表並且把R2的狀態設置爲2-Way。隨後R1在自己發送的Hello報文的“鄰居”字段中寫入R2的Router-ID,後者收到該報文後,在其鄰居表中將R1的狀態切換到2-Way。至此,R1與R2形成了鄰居關係。
                     在這裏插入圖片描述
                                                 R1與R2使用DD報文描述自己的LSDB

       接下來,在ExStart狀態下R1及R2需要交互空的DD報文以便協商Master/Slave。由於R2的Router-ID更大,因此它勝出成爲Master路由器。用於協商Master/Slave的DD報文並不攜帶任何LSA頭部,而且I比特位被設爲1。然後將R2的狀態切換到Exchange併發送帶有LSA頭部的DD報文這個DD報文的DD序列號爲300(也就是R2發送過來的DD序列號)M比特位設置爲1表示後續還有更多的DD報文,而MS比特位設置爲0。接着R2收到了R1發送過來的DD報文,於是將R1的狀態切換到Exchange,隨後自己也開始發送攜帶LSA頭部的DD報文,此時DD報文的DD序列號爲301(在上一個序列號300 的基礎上加1),M及MS比特位均設置爲1。由於雙方的LSDB中都包含較多LSA,因此需交互多個DD報文,而在該過程中,Master路由器R2將DD序列號逐次加1,Slave路由器R1則使用前者的DD序列號來發送自己的DD報文,如此這般有序的進行。
                     在這裏插入圖片描述
                                                               R1與R2達到全毗鄰狀態

       經過數次DD報文交互後,R2發送的DD序列號達到308,使用該DD序列號發送了自己最後一個DD報文,在該報文中,它將M比特位設置爲0。R2收到該DD報文後,繼續發送自己的DD報文描述剩餘LSA頭部,而恰巧這也是它的最後一個DD報文,它在該報文中將M比特位設置爲0。當該報文到達R1後,雖然此時它已經描述完了自己的LSDB,但是它依然需要確認R2所發送的最後一個DD報文,於是它向R2發送一個空的DD報文,該報文的DD序列號爲309。R1及R2收到對方發送的最後-一個DD報文後,便徹底瞭解了對方的LSDB中所包含的LSA(頭部),此時它們需要從對方獲取感興趣的LSA的完整數據,因此R1將R2的鄰居狀態切換爲Loading,D報文,在該報文中,它將M比特位設置爲0。R2收到該DD報文後,繼續發送自己的DD報文描述剩餘LSA頭部,而恰巧這也是它的最後一個DD報文,它在該報文中將M比特位設置爲0。當該報文到達R1後,雖然此時它已經描述完了自己的LSDB,但是它依然需要確認R2所發送的最後一個DD報文,於是它向R2發送一個空的DD報文,該報文的DD序列號爲309。R1及R2收到對方發送的最後-一個DD報文後,便徹底瞭解了對方的LSDB中所包含的LSA(頭部),此時它們需要從對方獲取感興趣的LSA的完整數據,因此R1將R2的鄰居狀態切換爲Loading,R2同理。接下來,便是數據庫同步過程,R1向R2發送LSR報文,用於請求感興趣的LSA,而R2則使用包含LSA完整數據的LSU報文進行迴應,同理,R2也向R1發送用於請求LSA的LSR報文,而後者也使用LSU報文進行迴應。雙方可能會交互多個LSR及LSU報文,直到LSDB實現同步.R1或R2收到對方發送的LSU報文後,將報文中所包含的LSA加載到自己的LSDB中,並使用LSAck確認這些LSA。當R1或R2發現自已沒有其他的LSA需要從鄰居獲取後,便將鄰居的狀態切換爲Full。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章