天天看點

《OSPF和IS-IS詳解》一第6章 鍊路狀态資料庫同步6.1 OSPF資料庫同步

本節書摘來自異步社群《ospf和is-is詳解》一書中的第6章,第6.1節,作者 【美】jeff doyle,更多章節内容可以通路雲栖社群“異步社群”公衆号檢視

ospf和is-is詳解

有一句話作者此前曾反複提及,現在再說一遍:鍊路狀态路由協定的“精髓”在于,隸屬同一區域的每台路由器都會根據存儲在一個公共拓撲資料庫裡的資訊,執行本機路由計算。是以,在同一區域内,每台路由器所存儲的拓撲資料庫的内容必須完全一樣。路由器之間互相同步鍊路狀态資料庫的目的正是為此。在ospf或is-is網絡中,路由器隻要上線運作,就必須與鄰居路由器進行資料庫同步,以確定各自所持資料庫的内容完全相同。若路由器剛接入點到點鍊路,便會與鍊路對端的鄰居路由器互相同步資料庫。若路由器剛接入多路通路網絡,則會跟dr或dis進行資料庫同步。在執行完最初的資料庫同步任務之後,還有必要采取某些措施,讓本機資料庫與鄰機資料庫一直保持同步狀态。

請注意,除了跟(直連)鄰居路由器同步資料庫以外,任何一台路由器都不會與區域内的其他(非直連)路由器進行資料庫同步。在每一個區域内,鄰居路由器之間就是用“薪火相傳”的方式,來執行資料庫同步任務。這足能讓同一區域内的所有路由器都擁有内容相同的資料庫了。當然,這一同步資料庫的方式還得有一個前提,那就是區域内的任意兩台路由器之間都有路徑相連。在一個區域内,隻要有一台或多台路由器因“路徑中斷”而被孤立,便不能確定該區域内的所有路由器都擁有内容相同的資料庫。人們把這種情況稱為區域分割(partitioned area),第7章會對此加以讨論。目前,讀者有必要知道,在某特定區域内,確定所有路由器都擁有内容相同的資料庫的一些前提條件。這些條件包括:先通過鍊路來“串連”所有路由器;再配置路由器,令它們彼此之間建立起“連成一氣”的ospf/is-is鄰接關系。此外,還要確定不能因單點故障(單條實體鍊路或單個接口故障)而導緻區域内的某台(或某些)路由器與所有其他所有路由器分割開來。

讀至本章,讀者想必知道,ospf協定是一種結構性很強的路由協定。既然讀者都清楚ospf資料庫同步的可靠性和精确性是如此重要,那麼也就不會對用來管理ospf資料庫同步過程的狀态機(名為鄰居狀态機)的複雜程度感到驚訝了。簡而言之,在資料庫同步過程中,鄰居狀态機會驅動(ospf路由器)采取以下“行動”。

1.當相鄰的兩台路由器決定彼此建立鄰接關系時,會進行分工:一台起“主導”作用,另外一台會進行“配合”,這便是所謂的主(master)/從(slave)路由器機制。主路由器會掌控資料庫同步的其餘過程(即資料庫交換過程)。

2.鄰居路由器之間會以互發某種ospf協定資料包的方式,彼此“展示”本機資料庫裡存儲了哪些lsa(即資料庫“展示”過程,也有人稱其為資料庫描述過程)。

3.在資料庫“展示”過程中,若一台路由器得知鄰居路由器擁有本機所沒有的lsa,或得知鄰居路由器所持lsa的“版本”新于本機,就會請求鄰居路由器發送相關lsa的完整拷貝。

4.鄰居路由器之間交換完各自資料庫裡的lsa,且兩者都認為本機資料庫與對方相同,則結束資料庫同步過程,于是,便建立起了狀态為full的ospf鄰接關系。

本節首先會介紹資料庫交換過程中用到的ospf協定資料包,然後會深入探讨鄰居狀态機。

在資料庫同步過程中,會用到5種“正常”ospf協定資料包中的4種:

資料庫描述(類型2)資料包;

鍊路狀态請求(類型3)資料包;

鍊路狀态更新(類型4)資料包;

鍊路狀态确認(類型5)資料包。

上一章已經介紹了ospf路由器之間如何利用鍊路狀态更新資料包,來泛洪“整條”lsa。此外,上一章還提到,為確定lsa泛洪的可靠性,ospf路由器如何通過包含lsa頭部的鍊路狀态确認資料包,來“直接确認”(explicitly acknowledge)收到的lsa。雖然上一章給出過鍊路狀态更新資料包和鍊路狀态确認資料包的格式,但為友善讀者參考,圖6.1和圖6.2再次顯示了兩者的格式。

與鍊路狀态确認資料包一樣,資料庫描述(dd)資料包(其格式見圖6.3)也隻含可完全辨別某條lsa或lsa執行個體的lsa頭部。ospf路由器會以生成dd資料包的方式,向與其建立鄰接關系的鄰居路由器“展示”本機資料庫内包含有哪些lsa。

《OSPF和IS-IS詳解》一第6章 鍊路狀态資料庫同步6.1 OSPF資料庫同步

接口mtu字段,其值指明了生成(dd資料包的)路由器接口所能發送的不分片資料包的最大長度。若(鄰居路由器間互連接配接口的)mtu值不比對,則不能建立鄰接關系。否則,鄰居雙方中的一方就有可能會發出對方無法接收的“大型”ospf協定資料包。

選項字段,與hello資料包以及lsa中的選項字段相同,都用來通告生成(ospf協定資料包的)路由器所具備的ospf可選功能。在本章之前的内容中,已經簡要介紹過了該字段,下一節會詳細介紹其格式與用途。

《OSPF和IS-IS詳解》一第6章 鍊路狀态資料庫同步6.1 OSPF資料庫同步

一般而言,ls資料庫的規模都不會太小,在此情形,ospf路由器隻生成一個資料庫描述資料包,可能并不足以把本機ls資料庫裡的所有lsa都“展現”給鄰居路由器。是以,協定設計人員在dd資料包中設立了以下兩位,意在“告知”鄰居路由器:本資料包是否是“一串”dd資料包中的一個。

i(init)位,該位置1時,表示本資料包是“一串”dd資料包中的第一個。

m(more)位,該位置1時,表示本資料包之後還有後續的dd資料包“跟進”。

以下是對i和m位各種取值方式的解釋。

若隻用單個dd資料包便能把本機ls資料庫裡的所有lsa都“交代清楚”,則該dd資料包中的i位置1,m位置0。

若要用“一串”dd資料包才能把本機ls資料庫裡的所有lsa“交代清楚”,則“一串”當中的首個dd資料包的i位和m位要同時置1;“一串”當中的最後一個資料包的i位和m位需同時置0;首尾之間的資料包i位應置0,m位則要置1。

ms(主/從,master/slave)位,其值用來表示生成(dd資料包的)ospf路由器在資料庫交換過程中是起主導(master)(ms位置1)作用,還是起配合(slave)(ms位置0)作用,即标明生成(dd資料包的)ospf路由器是主(master)路由器還是從(slave)路由器。主/從路由器之間的關系将在6.1.5節介紹。

dd序列号字段,當用“一串”dd資料包才能把本機ls資料庫裡的所有lsa都“交代清楚”時,該字段會跟i、m位結合使用。dd序列号字段的用途也将在6.1.5節介紹。

在資料庫交換過程中,若ospf路由器在收到的dd資料包中發現了未知lsa或已知lsa的最新版本,便會發對外連結路狀态請求資料包(其格式見圖6.4),請求鄰居路由器把相關lsa的完整拷貝發給自己。可發出單個ls(鍊路狀态)請求資料包,向鄰居路由器“請求”多條lsa,倘若所要“請求”的lsa的條數過多,則可以發出多個ls請求資料包。鄰居路由器可以把多條“受到請求”的lsa,裝載進單個鍊路狀态更新資料包,然後外發。

《OSPF和IS-IS詳解》一第6章 鍊路狀态資料庫同步6.1 OSPF資料庫同步

請注意,ls請求資料包并不包含完整的lsa頭部,隻是包含了lsa頭部中的ls類型、ls id,以及通告(路由的)路由器字段。也就是說,路由器發出ls請求資料包,是要從鄰居路由器那兒“實打實”地請求某條(或多條)lsa,而不是某條(或多條)lsa的某個具體執行個體。收到ls請求資料包的鄰居路由器,自然會發出“受到請求”的lsa的最新執行個體。ls請求資料包的格式之是以會如此設計,其目的是要把這樣一種情形也考慮在内,那就是:在某台路由器從生成dd資料包(向鄰居路由器“展示”本機資料庫裡的lsa),到收到(鄰居路由器發出的)ls請求資料包,向其請求某條(或多條)lsa的這段時間内,鄰居路由器可能已經收到(自己所要請求的)lsa的最新執行個體,并将之安裝進本機資料庫了。 總而言之,隻要收到ls請求資料包,ospf路由器必會發出“受到請求”的lsa的最新拷貝。

(某幾種)ospf(協定資料包所攜帶的)選項字段是一個8位的标記集合,每一位都代表着生成(該ospf協定資料包的)路由器所具備的某項ospf功能。在上一節介紹過資料庫描述資料包之後,含選項字段的各種ospf協定封包(或資訊元素)都已在本書中介紹過了,它們是:

hello資料包;

資料庫描述資料包;

lsa頭部。

圖6.5所示為選項字段的格式。選項字段中有7位都是目前已啟用的标記位,最高位在圖中被标記為“*”,寫作本書之際,還尚未啟用。選項字段那7位中的每一位都表示一種與ospf有關的功能,路由器隻有在具備了相應的功能之後,才會把(自生成的某些ospf協定資料包的)選項字段中的相關位置1。否則,便會把選項字段中的相關位置0。

《OSPF和IS-IS詳解》一第6章 鍊路狀态資料庫同步6.1 OSPF資料庫同步

本節會簡單介紹選項字段中每一位的用途,以供讀者做一般性的了解。本書後文會專辟幾章分别介紹選項字段中各标記位所代表的相關功能。在還沒有學過這些内容之前,讀者在閱讀本節對選項字段的介紹時,可能會略感吃力。

o位,表示(生成相關ospf協定資料包的)路由器是否具備解讀不透明(opaque)lsa的功能,第10章會介紹不透明lsa。如本書第1章所述,有了不透明lsa,就能對ospf的功能進行擴充,令該協定支援其原本所不能支援的應用,比如,流量工程。o位隻會在dd資料包中置1,也隻有能解讀不透明lsa的路由器才能将該位置1,也就是說,路由器是否支援與o位“挂鈎”的ospf功能,隻有在資料庫交換過程中才能顯現出來。此後,不透明lsa将被泛洪給支援不透明功能的路由器(opaque-capable router)。

dc位,該位置1時,表示(生成相關ospf協定資料包的)路由器支援按需電路(demand circuit)功能,并能夠“解讀”與該功能有關的“donotage lsa”,這些内容将在第8章讨論。當互連(ospf路由器的)鍊路要按流量或時間來計費時,就可以(在ospf路由器上)開啟按需電路功能。此時,可以配置ospf路由器上的相關接口(比如,isdn或撥号接口),令這些接口将其所連鍊路視為按需電路,這樣一來,通過按需電路互連的ospf鄰居路由器之間,既不會定期互發hello資料包,也不會定期重新整理lsa,這就避免了按需電路被毫無必要地“接通”,去傳遞“控制層面”流量,進而起到節省通信成本的目的。能“解讀”donotage lsa的路由器,會在自生成的所有lsa中将dc位置1。此類路由器還會通過連接配接了按需電路的接口,外發dc位置1的hello和dd資料包。若此類路由器收到了dc位置0的hello或dd資料包,則表明鄰居路由器不支援或未啟用按需電路功能,于是便會改發“普通”的hello資料包,并“正常”執行lsa的重新整理機制。若不支援按需電路功能的路由器收到了dc位置1的ospf協定資料包,則會對dc位置1的情況“視而不見”。

ea位,該位置1時,表示(生成相關ospf協定資料包的)路由器能解讀外部屬性lsa(這種lsa的類型字段值為8)。與這種類型的lsa相關聯的功能現已過時,且未得到廣泛應用。

n/p位,用來支援not-so-stubby區域(詳見7.3.4節)。在hello資料包的選項字段内,該位被稱為n位,置1時,表示(生成hello資料包的)路由器支援(連接配接)not-so-stubby區域。在hello資料包中,若選項字段的n位置1,那麼e位(表示支援類型5 lsa)必須置0。若鄰居路由器之間不能對上述n位和e位的設定方式達成一緻意見,便會丢棄對方發出的hello資料包,ospf鄰接關系自然也無從建立。在nssa lsa頭部的選項字段中,該位稱為p位,同來“通知”nssa abr,令其執行lsa類型7/5間的轉換。

mc位,該位置1時,表示(生成相關ospf協定資料包的)路由器支援多點傳播ospf(mospf)功能。mospf路由器會在其生成的所有hello資料包、dd資料包以及lsa的選項字段中将mc位置1。然而,在hello資料包中,選項字段的mc位隻起“通知”作用。在資料庫交換過程中,路由器才會真正檢查dd資料包中選項字段的mc位,以了解鄰居路由器是否支援mospf功能,mospf組成員(類型6)lsa隻會被泛洪給支援mospf功能的路由器。

e位,該位置1時,表示(生成相關ospf協定資料包的)路由器支援外部路由功能。若路由器在自生成的相關ospf協定資料包的選項字段中,将e位置0,則表示其不接受外部(類型5)lsa。隻要在網絡中開辟了stub區域(詳見7.3.4節),就一定會有完全“委身”于此類區域的路由器,這些路由器會在自生成的相關ospf協定資料包的選項字段中,将e位置0。在外部lsa的選項字段中,e位必定置1;在隸屬于區域0及非stub區域的路由器生成的dd資料包和lsa的選項字段中,e位也總是置1,但是隻起“通知”作用。在hello資料包的選項字段中,e位的設定情況會影響到ospf鄰接關系的建立。交換于相鄰路由器之間的hello資料包中選項字段的e位設定不一緻——一方置1,另一方置0——hello資料包便會遭到對方的丢棄,兩者之間将建立不了ospf鄰接關系。

t位,該位置1時,表示(生成相關ospf協定資料包的)路由器支援tos路由功能。該功能現已過時,且未得到廣泛應用。

當ospf路由器通過某接口收到hello資料包,首次“探索”到鄰居路由器時,會針對其建立鄰居資料結構。鄰居資料結構(也被稱為鄰居清單)會包含本路由器必須知道的有關鄰居路由器的所有資訊。其中的某些資訊收集自鄰居路由器發出的hello和dd資料包,而另外一些資訊則來源于本路由器跟鄰居路由器挂鈎的内部程序。以下所列為鄰居資料結構表中的具體表項。

狀态(state),記錄了本路由器根據自身的鄰居狀态機(詳見6.1.6節)識别出的鄰居路由器的狀态。請注意,千萬别把此處所說的“狀态”跟接口資料結構中的“狀态”混為一談,在接口資料結構中,“狀态”字段表示的是ospf接口的狀态,以及該接口與鄰居路由器(互連)接口之間的關系。

閑置計時器(inactivity timer),是一個周期為“routerdeadinterval”(路由器失效間隔期)的計時器,針對路由器接口所連鍊路上的鄰居路由器而定義。隻要收到該鄰居路由器發出的hello資料包,閑置計時器就會歸零(重置)。該計時器到期将會觸發鄰居狀态機中的某些事件,這些事件會把該鄰居路由器的狀态改變為“down”。

主/從關系(master/slave),表示主、從路由器的選舉結果,詳見6.1.5節。在資料庫交換過程中,會牽涉到主、從路由器的選舉。

dd序列号(dd sequence number),表示在資料庫交換過程中,(本路由器)目前發送給鄰居路由器的dd資料包的序列号字段值。

最新收到的資料庫描述資料包(last received database description packet),可根據該表項的内容來确定在資料庫交換過程中(與鄰居路由器交換資料庫時),是否從鄰居路由器那裡收到了重複的dd資料包。該表項會記錄下鄰居路由器最近發出的dd資料包中的某些字段值,包括:序列号字段值、選項字段值以及i、m、ms位的設定情況。

鄰居id(neighbor id),這一項的内容為鄰居路由器的rid,取自鄰居路由器發出的hello資料包,在某些情況下(比如,在nbma或某些虛拟網絡環境中),也可以手工指定。

鄰居路由器的優先級(neighbor priority),這一項的内容取自鄰居路由器發出的hello資料包的路由器優先級字段值,執行dr/bdr選舉時會用到。

鄰居路由器(接口)的ip位址(neighbor ip address),這一項的内容為鄰居路由器用來跟本機互連的接口的ip位址,提取自鄰居路由器發出的hello資料包(標頭)的源ip位址字段。當本路由器需以單點傳播方式向鄰居路由器發出ospf協定資料包時,會用該位址作為ospf協定資料包的目的ip位址。若鄰居路由器是網絡内的dr,則這一ip位址還會成為本路由器針對該網絡生成的路由器lsa的鍊路id字段值。

鄰居路由器所支援的ospf可選功能(neighbor option),這一項的内容取自鄰居路由器發出的hello資料包(的選項字段),以及在資料庫交換過程中發出的dd資料包(的選項字段)。

鄰居路由器所知道的備份指定路由器(neighbor’s designated router),這一項的内容取自鄰居路由器發出的hello資料包的指定路由器字段值(即鄰居路由器所認為的dr的ip位址)。隻有在廣播或nbma網絡環境中,其内容才有意義。

鄰居路由器所知道的備份指定路由器(neighbor’s backup designated router),這一項的内容取自鄰居路由器發出的hello資料包的備份指定路由器字段值(即鄰居路由器所認為的bdr的ip位址)。同理,也隻有在廣播或nbma網絡環境中,其内容才有意義。

圖6.6所示為一張ospf鄰居表的輸出示例。顯而易見,其中出現了之前介紹過的大多數鄰居表表項及内容。

《OSPF和IS-IS詳解》一第6章 鍊路狀态資料庫同步6.1 OSPF資料庫同步

除了上一節所描述的内容之外,鄰居資料結構還包括3張表格。這3張與lsa有關的表格,都隻會在資料庫交換或泛洪過程中“填寫”。

鍊路狀态發送清單(link state transmission list),列在表裡的lsa都已泛洪而出,但尚未獲得确認。

資料庫彙總清單(database summary list),開始(與鄰居路由器)執行資料庫交換任務時,ospf路由器會将歸屬本機及鄰機所在ospf區域的所有lsa,都填入此表。包含于此表的所有lsa都是ospf路由器要通過dd資料包“秀”給鄰居路由器“看”的lsa。

鍊路狀态請求清單(link state request list),此表所含lsa均獲悉于鄰居路由器發出的dd資料包,包含的不是本路由器未知的lsa,就是本路由器已知lsa的最新拷貝。随後,本路由器會發對外連結路狀态請求資料包,請求鄰居路由器“傳送”表中所包含的lsa。收到鄰居路由器發出相關lsa的完整拷貝之後(相關lsa是指,本機請求鄰機發送的lsa。鄰居路由器會通過鍊路狀态更新資料包,來傳送本機請求發送的lsa的完整拷貝),本路由器會将收到的lsa從鍊路狀态請求清單中删除。

(鄰居路由器之間)互相交換ospf資料庫的内容(lsa)時,(資料傳送的)可靠性非常重要,但lsa的可靠交換并不可能一蹴而就。是以,當兩台路由器(拿本機資料庫裡的lsa,跟對方通過dd封包所“展示”的lsa)進行比對時,其中一台路由器要負責管理lsa(即ls資料庫的内容)的交換過程1。應當由哪一台路由器來充當“管理者”(主路由器),其實并不重要,隻要鄰居雙方一緻同意就成。rid更高的那台路由器會成為主路由器,從路由器則由rid較低的那台路由器充當。

以下所列為主路由器所肩負的責任。

發出首個dd資料包。

遞增dd資料包的序列号字段值。從路由器則沒有這個“權限”。

確定每次隻能有一個dd資料包“在途”(outstanding)。

在必要時重傳dd資料包。從路由器則不能重傳dd資料包。

現在,作者以兩台相鄰的路由器ra和rb為例,來講解主路由器是如何确定的。ra在驗證過本機與rb間具備了雙向連通性之後,會立刻決定跟rb建立鄰接關系。為此,ra會向rb發出一個空dd資料包(不含lsa頭部)。ra會向dd資料包的序列号字段中填入一個獨一無二的值;rfc 2328的建議是,根據當日時間來指派,但有些廠商的ospf實作也會使用某些其他方法,向(dd資料包的)序列号字段中填入一個起始值。在ra發出的這一空dd資料包中,i、m以及ms位都将置1,表示本資料包是“一串”dd資料包當中的第一個,後面還會有别的資料包“跟進”,ra還同時以主路由器自居(ms位置1)。

收到ra發出的空dd資料包後,rb會檢查其中的rid字段值。若ra的rid更高,rb便知其為主路由器,反之,則視其為從路由器。接下來,會發生兩件事情。

若rb認為本機為從路由器,便會發出包含本機所持lsa的頭部的dd資料包進行回應,這便拉開了資料庫交換的序幕。在rb發出的dd資料包中,頭部的序列号字段值會跟(ra發出的)dd資料包相同;ms位将置0,這表示本路由器為從路由器,ra為主路由器。在rb發出的首個dd資料包的頭部中,i位将會置1,m位置1還是置0,則要取決于rb有沒有通過本dd資料包,(一次性)向ra“展示”完本機資料庫所儲存的所有lsa。

若rb認為本機為主路由器,便會(向ra)發出序列号字段值為自定義,且i、m以及ms位都置1的空dd資料包。收到之後,ra會發出序列号字段值由rb所定義,且ms位置0的dd資料包進行确認,表示本機為從路由器。在這一用來行使确認功能的dd資料包中,會包含ra所持lsa的頭部,資料庫交換過程也随即開始。在這一dd資料包的頭部中,i位将會置0,因為這并非ra發出的第一個dd資料包;m位置0還是置1,則要取決于ra有沒有通過該dd資料包,(一次性)向rb“展示”完本機資料庫所儲存的所有lsa。

在驗證過與對方具備了雙向連通性之後,ra和rb有可能會幾乎同時發出空dd資料包,分别聲稱自己為主路由器。對于這種情況,相鄰兩台路由器隻要一收到對方發出的dd資料包,就知道誰是“主”,誰是“從”了。此時,會由從路由器來啟動資料庫的交換過程,具體做法是:發出包含lsa頭部的dd資料包,并在其頭部的序列号字段中填入鄰居路由器所發dd資料包的序列号字段值,且把ms位置0,對鄰居路由器發出的空dd資料包進行确認。

6.1.6節會細述(鄰居路由器之間)進行資料庫交換的完整過程。目前,讀者隻要知道在确立了主、從路由器之後,由主路由器負責“管理”資料庫交換就夠了。由于隻有主路由器才能增加dd資料包的序列号字段值,是以當主路由器發出序列号字段值為x的dd資料包之後,隻要從路由器能夠收到,就會發出序列号字段值同為x的dd資料包(其中會包含本機所持lsa的頭部),以“間接”的方式進行确認。同理,隻有收到了從路由器發出的序列号字段值為x的dd資料包之後,主路由器才能繼續發送序列号字段值為x+1的dd資料包。通過上述規則不難發現,(發生在鄰居路由器間的)資料庫交換行為就是一台路由器“主導”或“主動輪詢”(poll),另一台路由器“配合”或“被動響應”的過程,即主路由器輪詢,從路由器響應(respond)。

dr必會是主路由器嗎

在dr推舉過程中,若路由器的優先級全都相同,rid最高的路由器将成為dr。是以,有些讀者勢必以為,當drother與dr進行資料庫同步時,dr一定會是主路由器。dr在廣播或nbma網絡中所承擔的職責可能又進一步鞏固了上述推理。但事實上,在drother與dr進行資料庫交換時,卻頗有可能發生drother為主,dr為從的現象。請牢記,dr在標明之後,如無意外不會“遜位”。也就是講,在以太網絡中,新上線運作的路由器即便rid高于現有的dr,也不能自動“取而代之”。若此路由器與dr進行資料庫交換,則必擔當主路由器之職(此路由器的rid更高),而dr一定會成為從路由器。

在介紹過用來支撐(ospf路由器間)資料庫交換的所有必要元件之後,現在是時候了解ospf路由器的各種狀态、導緻ospf路由器的狀态發生改變的各種事件,以及狀态發生改變時,ospf路由器所采取的動作了。ospf鄰居狀态機由一整套狀态、事件和動作構成,詳情請見rfc 2328的10.8節。

讀者需要記住,ospf路由器會單獨針對每一個鄰居維護鄰接狀态資訊,這些資訊明确了本機與某特定鄰居之間目前的關系。在相鄰的兩台路由器之間(尤其是在建立起狀态為full的鄰接關系之前),可能會發生鄰接關系狀态認知度不統一的情況(比如,甲、乙兩台路由器相鄰,在甲路由器上,顯示其與乙路由器之間為a狀态;在乙路由器上,顯示其與甲路由器之間為b狀态)。以下所列為各種ospf鄰接關系狀态。

down(失效)狀态,此乃鄰居會話的最初狀态。把鄰居路由器的狀态顯示為down,即表明在最近一次路由器失效間隔期(routerdeadinterval)内,未收到該鄰居路由器發出的hello資料包。ospf路由器不會向狀态為down的鄰居路由器發送hello資料包,但nbma網絡環境除外。在nbma網絡環境中,(ospf路由器)會按一定的頻率(資料包的發送間隔時間要遠高于一般的hello間隔時間[hello interval]),(定期)向狀态為down的鄰居路由器發送hello資料包。這一在nbma網絡中向(失效的)鄰居路由器發送hello資料包的間隔時間稱為pollinterval(輪詢間隔時間),其時長通常為2分鐘。

attempt(嘗試)狀态,此狀态隻限于nbma網絡環境。把通過nbma接口相連的鄰居路由器顯示為attempt狀态,則表明在本機配置中已手工指明了鄰居路由器的ip位址,本機會“力争”獲得鄰居路由器的響應。之是以說“力争獲得鄰居路由器的響應”,是因為本機在發送hello資料包“聯絡”鄰居路由器時,發包的間隔時間為hellointerval(hello間隔時間,一般為30秒),并非之前提及的pollinterval(輪詢間隔時間,一般為2分鐘)。

init(初始)狀态,把鄰居路由器顯示為init狀态,則表明本機已收到鄰居路由器發出的hello資料包,但在其鄰居路由器字段中未發現本機的rid(即無法确定與鄰居路由器之間是否具備雙向連通性)。本路由器會把處于init狀态(或更進階别的狀态)的所有鄰居路由器的rid,填入自生成的hello資料包的鄰居路由器字段,然後通過相關接口外發。

2-way(雙向通信)狀态,把鄰居路由器顯示為2-way狀态,則表明本機跟鄰居路由器之間具備了雙向連通性,亦即在鄰居路由器發出的hello資料包的鄰居路由器字段中發現了自身的rid。隻有處于2-way或更進階别狀态的路由器才有資格參與dr選舉。

exstart(準備交換)狀态,把鄰居路由器顯示為exstart狀态,則表明已經拉開了資料庫交換的序幕。在此狀态下,鄰居路由器會确定“鄰裡之間”的主/從(master/slave)關系,以及用來執行資料庫交換的dd資料包的初始序列号(即序列号字段的初始值)。隻有把鄰居路由器顯示為exstart或更進階别的狀态,才能認為本機與鄰居路由器建立了鄰接關系,不過,在資料庫同步進行完之前,還不能說鄰接關系建立“齊備”(還未建立起狀态為full的鄰接關系)。

exchange(交換)狀态,把鄰居路由器顯示為exchange狀态,則表明本路由器正在向鄰居路由器“秀”(展示)自己的ls資料庫,“展示”的方法是:向鄰居路由器發出dd資料包,其中包含了存儲在本機資料庫裡的所有lsa的頭部。與此同時,本路由器還可以發對外連結路狀态請求資料包,請求鄰居路由器發送包含在鍊路請求清單裡的lsa(即在鍊路請求清單裡由鍊路狀态類型、鍊路狀态id和通告[路由]的路由器這三個字段共同辨別的lsa)。當ospf路由器向鄰居路由器泛洪lsa時,鄰居路由器必須處于exchange或更進階别的狀态。

loading(加載)狀态,把鄰居路由器顯示為loading狀态,則表明本路由器已向鄰居路由器“秀”完了自己的ls資料庫,但還沒有從鄰居路由器那裡“接收”完本機請求發送的lsa,或鄰居路由器還沒有“接收”完它請求本機發送的lsa。

full(齊備)狀态,把鄰居路由器顯示為full狀态,則表明本路由器跟鄰居路由器之間的鄰接關系狀态已建立齊備,這樣的鄰接關系會同時在(雙方發出的)路由器lsa或網絡lsa中有所展現。

圖6.7所示為兩台路由器從彼此發現,到互相同步資料庫,再到鄰接關系建立齊備時,典型的鄰居狀态變遷的全過程2。圖中兩台路由器互連接配接口的ospf網絡類型為broadcast。

《OSPF和IS-IS詳解》一第6章 鍊路狀态資料庫同步6.1 OSPF資料庫同步

以下所列為出現在圖6.7中的各個步驟。

1.ra在廣播網絡内上線運作,發出hello資料包,宣布自己上線運作。在ra發出的hello資料包中,dr字段值被設定為0.0.0.0,鄰居路由器字段為空,表示ra尚未發現任何鄰居路由器。

2.rb收到ra發出的hello資料包後,會針對ra建構一套鄰居資料結構。rb會把ra置為init狀态,因為在ra發出的hello資料包的鄰居路由器字段内,未出現rb的rid。rb向ra發出hello資料包時,會在鄰居路由器字段内填入ra的rid(10.0.0.1)。對于本例,由于rb是該廣播網絡内的dr,是以會把本機用來連接配接該廣播網絡的接口的ip位址(10.1.1.2),填入(發送給ra的hello資料包的)dr字段。

3.當ra收到rb發出的hello資料包後,也會針對rb建構一套鄰居資料結構。由于在此hello資料包的鄰居路由器字段中發現了自身的rid,是以ra就知道跟rb之間已經具備了雙向連通性。此時,ra可以把rb置為2-way狀态。但因rb是(該廣播網絡内的)dr,故ra必須與其進行資料庫同步。于是,ra把rb置為了exstart狀态,表示本機開啟了主/從路由器的選擇,并同時用lsa來填充資料庫彙總清單(詳見6.1.4節),那些lsa都是要“秀”給rb“看”的lsa。ra向rb發出了空dd資料包(不含lsa頭部),在其中提出了自己的“建議”——為序列号字段設定了一個初始值,并同時将ms位置1。由于那個空dd資料包的作用隻是“探路”,後面還會有dd資料包“跟進”,是以i、m位同樣都被置1。

4.收到ra發出的空dd資料包後,rb會把ra置為exstart狀态,并同時用某些lsa來填充資料庫彙總清單,那些lsa都是要給ra“過目”的lsa。然後,向ra發送空dd資料包。由于rb的rid高于ra,是以rb知道本機應作為主路由器,于是會把這一空dd資料包的ms位置1,并自行為序列号字段設定了一個初始值y。在該dd資料包内,i、m位同樣都被置1,表示這是rb發出的首個dd資料包,後面還會有dd資料包“跟進”。

5.收到rb發出的首個(空)dd資料包後,ra便知rb為主路由器了。随着主/從路由器選舉完畢,資料庫交換的序幕也随即拉開,是以ra會把rb置為exchange狀态。ra會向rb發出dd資料包,其序列号字段值為rb(在空dd資料包内)設定的初始值y;ms位則置0,表示本機為從路由器。該dd資料包中會包含“刊登”在資料庫彙總清單裡的多個lsa的頭部,“刊登”在資料庫彙總清單裡的lsa跟ra所持ls資料庫裡的lsa相同。對于本例,ra要發多個dd資料包,才能向rb完整地展示本機ls資料庫(裡的lsa),是以,該dd資料包的m位将會置1,表示後面還有dd資料包會“跟進”;而i位則會置0,因為這并不是ra發給rb的第一個dd資料包了。

6.收到ra發出的(含lsa頭部的)dd資料包後,rb會把ra置為exchange狀态。對于dd資料包中包含的本機所需要的任何一條lsa,rb都會錄入進鍊路狀态請求清單(見6.1.4節)。然後,rb向ra發出dd資料包,其中會包含“刊登”在資料庫彙總清單裡的多個lsa的頭部。身為主路由器,rb要負責把該dd資料包的序列号字段值調整為y+1。跟ra相同,rb也得發出多個dd資料包,方能向ra完整地展示本機lsa資料庫(裡的lsa),當然,該dd資料包的m位将會置1。此外,rb還會将通過該dd資料包對外“展示”的lsa錄傳入連結路狀态重傳清單,并啟動重傳計時器。

7.收到了rb發出的dd資料包後,ra會先從資料庫彙總清單中,将此前已向rb展示過的lsa清除,那些lsa的頭部都包含在此前ra向rb發出的dd資料包内(詳見步驟5)。若rb在該dd資料包中“展示”的lsa有自己所需,ra就會把那些lsa錄傳入連結路狀态請求清單。然後,ra将繼續向rb發送dd資料包,其中會包含“刊登”在資料庫彙總清單裡的“下一批”lsa的頭部。ra也會把該dd資料包中的序列号字段值設定為y+1。如此一來,ra也就向rb确認了本機已收到其此前發出的dd資料包,以及包内所包含的lsa的頭部。

8.收到了ra發出的序列号字段值為y+1的dd資料包後,rb會停掉之前啟動的重傳計時器,該計時器是為之前發出的dd資料包中所要“展示”的lsa而啟動。此外,rb還會從鍊路狀态重傳清單中清除那些lsa。然後,rb會繼續向ra發送新的dd資料包,其序列号字段值為y+2,其中包含了要“秀”給ra“看”的下一批lsa(的頭部)。通過該dd資料包,rb也“秀”完了“刊登”在資料庫彙總清單裡的lsa,是以此包的m将置0,表示後面沒有dd資料包“跟進”。

9.收到了rb發出的最後一個dd資料包(其m位置0)後,ra知道rb“秀”完了自己的資料庫。但由于ra的鍊路請求清單裡還“刊載”有尚未請求rb發送的lsa,是以ra會把rb置為loading狀态。然後,ra再發出序列号字段值為y+2的dd資料包,确認已經收到了rb發出的最後一個dd資料包。在此dd資料包中,包含了ra的資料庫彙總清單裡的最後一批lsa的頭部,是以此包的m位會置0。

10.收到ra發出的最後一個dd資料包後,rb會從鍊路狀态重傳清單中,清除已得到ra确認的lsa。此時,在rb的鍊路請求清單中已無任何lsa,這表示rb已對ra資料庫裡的所有lsa“一清二楚”,于是,便将ra置為full狀态。但ra的鍊路狀态請求清單中還“刊載”有lsa,是以ra會發對外連結路狀态請求資料包,請求rb發送相應的lsa。rb會以鍊路狀态更新資料包進行回應,其中包含了ra所要請求的完整的lsa。當ra的鍊路狀态請求清單為空時,則表示其已從rb那裡收到了自己需要的所有lsa,于是,會把rb置為full狀态。

由圖6.7可知,ospf路由器隻有在收到(鄰居路由器發出的)相關ospf協定資料包後,才會改變鄰居路由器的狀态。導緻ospf路由器改變鄰居路由器狀态的事件包括:收到了鄰居路由器發出的ospf協定資料包,或鄰居路由器發出的ospf協定資料包裡的内容發生了改變3。然而,并不是所有導緻ospf路由器改變鄰居路由器狀态的事件,都與自己收到(鄰居路由器發出的)相關ospf協定資料包有關。

以下所列為會讓鄰居路由器的狀态呈“良性”發展的事件。

helloreceived(收到hello資料包)——收到了鄰居路由器發出的hello資料包。

start(啟動)——在hello間隔時間(hello interval)内,應向鄰居路由器發送hello資料包。本事件隻對位于nbma網絡中的鄰居路由器生效。

2-wayreceived(雙向連通性具備)——在鄰居路由器發出的hello資料包(的鄰居路由器字段)中,發現了本機rid,這表示本機與鄰機之間具備了雙向連通性。

negotiationdone(完成協商)——完成了主/從路由器的協商。

exchangedone(完成交換)——兩台路由器都通過dd資料包,把本機資料庫裡的lsa完全展示給了對方。

badlsrequest(鍊路狀态請求出錯)——收到了(鄰居路由器發出的)鍊路狀态請求資料包,但其所請求的lsa在本機資料庫裡沒有,這表示在資料庫交換過程中發生了錯誤。

loadingdone(資料庫加載完畢)——資料庫交換過程完畢之後,鍊路狀态請求清單也已清空。

adjok?(能建立齊備的鄰居關系嗎?)——這是一個決策點,表示(本路由器在決定)應不應該跟鄰居路由器建立或維持鄰接關系。

圖6.8所示為鄰居路由器的狀态與事件(是指能使鄰居路由器的狀态呈“良性”發展的事件)間的關系圖。

還有一些事件會使鄰居路由器的狀态呈“惡性”發展。這些事件大都因錯誤、故障或計時器到期所緻。當鄰居路由器處于以下任一狀态時,就會發生這些事件。

seqnumbermismatch(序列号不比對)——收到了(鄰居路由器發出的)dd資料包,但其序列号字段值跟本機預期的不符(不是n+1)、i位設定有誤,或選項字段值跟上一次收到dd資料包裡的不一樣。該事件會導緻(本路由器)放棄或重新開始與處于exstart狀态的鄰居路由器交換ls資料庫。

1-way(單向連通性)——與鄰居路由器之間喪失了雙向連通性,其征兆為:在鄰居路由器發出的hello資料包的鄰居路由器字段内,未發現本路由器的rid。若鄰居路由器處于2-way或更進階的狀态,則(本路由器)會将其置為init狀态。

killnbr(鄰居路由器“失蹤”)——與鄰居路由器完全失去了“聯系”,(本路由器)會将其置為down狀态。

inactivitytimer(計時器閑置)——在最後一次路由器失效間隔時間(routerdeadinterval)内,未收到鄰居路由器發出的hello資料包,(本路由器)會将其置為down狀态。

lldown(底層協定狀态為down)——底層協定(lower-level protocol)顯示鄰居路由器不可達,導緻(本路由器)會将其置為down狀态。

《OSPF和IS-IS詳解》一第6章 鍊路狀态資料庫同步6.1 OSPF資料庫同步

ospf路由器間的資料庫交換過程,并不總是像上一節描述的那般“井然有序”。比方說,(ospf鄰居之間)仍然在交換dd資料包的同時,可能還會互相發送鍊路狀态請求和鍊路狀态更新資料包。此外,(一台路由器)接口狀态(的改變)也會對鄰居路由器的狀态産生影響。不管怎樣,隻要能弄清在建立起狀态為full的ospf鄰接關系的過程中,鄰居路由器之間是如何“互動”的,肯定會對排除ospf故障有極大幫助。

要是相鄰兩台ospf路由器之間建立不了鄰接關系,那麼應首先從哪兒查起呢?

互連接配接口的ip位址配置正确嗎?

能ping通鄰居路由器的互連接配接口的ip位址嗎?

ospf鄰居路由器間互連接配接口的ip位址都隸屬于同一ospf區域嗎?

若啟用了ospf認證功能(詳見第9章),兩“邊”的認證資訊配置一緻嗎?密碼或密鑰比對嗎?

兩“邊”的ospf可選功能配置是否一緻?

兩“邊”的各種ospf計時器配置是否一緻?

ospf鄰居路由器間互連接配接口的mtu值是否比對?

要是經過一翻排查,上述所有問題的答案都是“是”,但ospf鄰接關系仍“死活”建立不了,那就應該去深究鄰居路由器間的“互動”過程。也就是說,需要在路由器上通過任何一款可用的ospf排障工具,來記錄并“破譯”鄰居路由器間的“會話”。此類排障工具不但能準确地“告訴”網管人員,故障出在鄰接關系建立或資料庫同步的哪一步,而且還能幫助定位故障的原因,或至少能讓人獲得一點“蛛絲馬迹”。網管人員可根據這些“蛛絲馬迹”,來進一步判斷故障的原因。

圖6.9所示為由一台juniper路由器生成的日志檔案,其内容包括了各種ospf事件、協定資料包的收發過程以及鄰居狀态的變遷。作者對這份日志檔案(以及圖7.10中的debug輸出)做了适當的修訂,删去了某些無關資訊,比如,記錄hello資料包的收發情況的資訊。

這份日志檔案記錄了(本路由器)與鄰居路由器建立狀态為full的ospf鄰接關系的整個過程。乍一看,這份日志檔案有好幾頁紙,讓人望而生畏。但隻要讀者了解了與接口和鄰居有關的各種狀态,弄清了導緻這些狀态發生改變的各種事件,同時熟知建構鄰接關系所涉及的協定資料包與各種表格(比如,鄰居清單、鍊路狀态發送清單、資料庫彙總清單等),讀懂這份日志檔案卻也不難。是以,作者并沒有逐句解讀這份日志檔案,而是提出了一些問題,讓讀者自己尋找答案。以下所列為相關提示資訊。

本路由器的rid為192.168.254.6。

本路由器的接口ip位址為192.168.7.1。

本路由器的實體接口為fe-4/0/0.0。

鄰居路由器的rid為192.168.254.8。

鄰居路由器的接口ip位址為192.168.7.2。

請讀者在閱讀日志檔案的過程中,對時間戳多加注意,此外,請千萬不要把接口狀态的改變(interface state change)和鄰居狀态的改變(neighbor state change)混為一談。以下為作者提出的要求或問題。

首先,應根據狀态的“變遷”,把這份日志檔案分為幾個部分來解讀。

從開始發現鄰居路由器192.168.254.8,到與其建立起狀态為full的鄰接關系,一共經曆了多長時間?

請注意,日志檔案顯示的鄰居狀态的變化過程是從init狀态到2-way狀态,再到exstart狀态,而非上一節示例中所描述的從init狀态直接過渡到exstart狀态。請仔細閱讀與上述鄰居狀态的改變有關的日志記錄,看看能否找到“理論依據”。(提示:請留意與接口狀态的改變有關的日志記錄。)

資料庫交換過程實際要耗時多久?

進行資料庫同步時,網絡内已經存在dr和bdr了嗎?

圖6.9 記錄了ospf鄰接關系建立全過程的日志檔案(由juniper路由器生成)

每一家廠商的路由器都有自己的一套排障資訊生成(提供)方法,其基本原理全都相通,隻是輸出格式有所不同。隻要能夠了解底層協定及其運作機制,就應能不費吹灰之力地讀懂任何一家廠商的路由器生成的路由協定相關的日志資訊。

有一台cisco路由器,與生成圖6.9所示日志記錄的那台juniper路由器相鄰,這台cisco路由器接入該廣播網絡的實體接口為e0。圖6.10所示為該cisco路由器生成的與ospf鄰接關系的建立、(鄰接關系建立過程中發生的)事件以及協定資料包的收發有關的debug輸出。這份debug輸出所覆寫的時間範圍跟圖6.9所示的日志檔案大緻相同。

跟之前一樣,也應根據狀态的“變遷”,把這份debug輸出分為幾個部分來解讀。

從這份debug輸出中找出與圖6.9所示的日志檔案中相比對的事件。

兩台路由器的時鐘并未同步,可能會有1~2秒的誤差。對于兩份輸出中相比對的事件,在發生的時間周期上也比對嗎?

根據圖6.9和圖6.10所提供的資訊,像圖6.7那樣試着畫一張圖,來描繪出兩台路由器之間協定資料包的交換情況,以及鄰居狀态的變遷過程。

圖6.10 對端路由器(cisco路由器)生成的建立同一個ospf鄰接關系的debug輸出

在新型ospf或is-is網絡中,導緻路由選擇故障(資料包不能正确轉發)的原因一般都非常常見,不是鍊路故障,就是路由器配置有誤。通常,隻要仔細觀察路由器的路由資訊表和轉發資訊表,便不難發現故障的根源。因某個區域内(ospf路由器間的)ls資料庫不一緻,而造成的路由選擇故障非常罕見。說其罕見,是因為倘若一對ospf鄰居路由器在同步過資料庫之後,ls資料庫還不能保持一緻,将會導緻鄰接關系的“破裂”。此外,區域内的路由器在做出路由決策時,也會将鄰接關系建立出現問題的這對路由器之間的路徑(鍊路)排除在外。

然而,(區域内ospf路由器間)ls資料庫不同步的現象卻絕對有可能發生。這多半要拜賜于糟糕的ospf實作,或包含ospf實作的os出現了 bug。本節會展示如何比較(不同路由器的)ls資料庫,以幫助讀者應對某些極端情況。所謂極端情況是指:明知網絡中發生了路由選擇故障,但不管怎麼查,都查不出故障原因。

首先,應比較(不同路由器的)ls資料庫彙總資訊,以驗證存儲在每台路由器的資料庫裡的lsa的類型和數量是否比對。跟上一節所舉示例相同,由不同廠商的路由器生成的ls資料庫彙總資訊的輸出(格式)雖然各不相同,但所反映出的内容卻大體相同。圖6.11和圖6.12分别顯示了由juniper和cisco路由器(即上一節用來舉例的那兩台路由器)生成的ls資料庫彙總資訊。經過比較,可以發現兩台路由器在區域0的ls資料庫裡存儲的lsa至少在條數上相同:

《OSPF和IS-IS詳解》一第6章 鍊路狀态資料庫同步6.1 OSPF資料庫同步

4條路由器lsa;

4條網絡lsa;

10條網絡彙總lsa;

1條asbr彙總lsa;

2條外部lsa(在cisco路由器生成的ls資料庫彙總資訊裡,這2條外部lsa出現在“process 1 database summary”下的“type-5 ext”一欄)。

圖6.12 cisco路由器生成的ospf ls資料庫彙總資訊

由于那台cisco路由器(見圖6.12)擔任abr一職,固其還持有區域20的ls資料庫。但區域20的ls資料庫的資訊跟本節所要讨論的内容無關,理由是那兩台路由器的互連接配接口都隸屬于區域0。

雖然那兩台路由器的ls資料庫所儲存的lsa的條數比對,但會不會發生一條或多條lsa的執行個體不一緻的現象呢?要想對此加以驗證,就得先把那兩個ls資料庫裡的所有lsa的校驗和分别相加,然後再進行比較。隻要那兩個資料庫裡的lsa執行個體相同,校驗和的相加結果也必定相等。否則,就得到兩個資料庫中分别比較每條lsa的校驗和,以發現不一緻的lsa的執行個體。

圖6.13和圖6.14分别顯示了juniper路由器和cisco路由器生成的lsa頭部的輸出。作者分别把兩個資料庫裡的所有lsa(隻限于區域0,不含外部lsa)的校驗和累加,得到的結果都是0xb4c0d。

所有路由器lsa的校驗和相加:0x2938a。

所有網絡lsa的校驗和相加:0x24718。

所有網絡彙總lsa的校驗和相加:0x5f5ae。

所有asbr彙總lsa的校驗和相加:0x7bbd。

圖6.13 juniper路由器生成的ls資料庫裡的lsa頭部資訊

圖6.14 cisco路由器生成的ls資料庫裡的lsa頭部資訊

juniper路由器和cisco路由器的兩條外部lsa的校驗和之和分别為0x12406和0x12804。當然,對于本例,逐一比對兩個資料庫裡的那兩條外部lsa的校驗和,要比比較兩條外部lsa的校驗和之和簡單得多。不過,要是資料庫的規模一大,哪種比較方法更加簡單,那就很難說了。讓人頭痛的是,對于大型網絡,路由器控制台顯示出的ls資料庫的輸出,肯定會比圖6.11和圖6.12長很多,無論使用哪種比較方法都既容易犯錯,又枯燥無味。更悲催的是,要是讀者在捕獲兩台路由器的ls資料庫輸出的間隔期,網絡中有路由器重新整理了自己的資料庫,那麼即便那兩台路由器的ls資料庫的内容一緻,相比較的結果也肯定不比對。

幸運的是,解決方案倒不是沒有。無論讀者管理什麼樣的網絡,隻要網絡規模一大,多半都會部署基于snmp的網管軟體。利用以下所列ospf mib,就能(通過網管軟體)自動采集到lsa的校驗和之和,可讓網管人員免遭枯燥無味的十六進制數加法計算之苦。

ospfarealsacksumsum 能用來擷取一個區域内所有lsa的校驗和之和(外部lsa除外)。

ospfexternlsacksumsum 能用來擷取外部(類型5)lsa的校驗和之和。

然而,(兩台路由器資料庫裡的)lsa的校驗和之和不比對,隻是表明存在資料庫同步問題。單憑這些資訊,既無法定位導緻問題的原因,也肯定搞不清具體是哪條lsa不比對。退一步來說,一般的網管人員能判斷出網絡存在ospf資料庫不同步問題,水準也算不俗。在判斷出網絡存在類似問題之後,網管人員可嘗試先手工拆除,再重建鄰接關系,讓相關ospf鄰居路由器之間重新同步資料庫。若症狀還未消失,那就趕緊緻電裝置廠商的技術支援團隊,需要由他們來深入分析,并判斷ospf軟硬體實作方面是否存在問題。

1譯者注:原文是“so when two ospf neighbors are comparing lsas, one of the neighbors manages the exchange”。

2本例擴充自rfc 2328 10.10節所舉示例,以及routing tcp/ip, volume i 445~447頁所載示例。

3譯者注:原文是“the actual events causing the state changes are discoveries or changes of information included in the packets”。