1. 程式人生 > >淺談網路層動態路由及路由協議+演算法

淺談網路層動態路由及路由協議+演算法

前一篇簡單闡述了靜態路由中的相關知識(傳送門

本篇就整理一下動態路由的相關內容

動態路由基本概念

動態路由主要是基於以下兩點

  1. 能否設計一種機制使各個路由器根據自己靜態的不完整的資訊“學習”出比較複雜的,甚至是全域性的路由資訊?
  2. 如果靜態路由中的某些節點/路徑失效,能否設計一種機制,使路由器自動將失效路由更新為可行的新路由資訊?

顯然在實際大型網路拓撲結構中,實現這兩點有著重要的意義,所以動態路由應運而生

下面貼幾張圖演示一下動態學習的過程

以R4為例,首先收到相鄰節點R2,R3的路由資訊,並增加自己沒有的資訊

R4的路由表產生了更新,於是向鄰居廣播,希望鄰居都能得到其更新的資訊,

鄰居們獲得了R4的更新並隨即學習更新了自身的路由資訊,此時他們的路由資訊也發生變化,於是繼續廣播給鄰居

得到新資訊的鄰居繼續學習更新自己的路由表,經過這一動態過程,網路域中的所有節點都動態學習到了所有的網路資訊

而正是基於這種不斷廣播,不斷學習,不斷更新的過程,使得鏈路失效後,有效路由也能重新建立,下面給出鏈路失效後重新建立連線的例子

動態路由協議

動態路由協議本質上都是依靠各個路由器上執行的特殊程序在路由器之間不斷交換路由資訊來推斷,學習出網路的全域性路由。

  距離-向量動態路由協議:RIP

RIP協議的工作機理就像上圖描述的一樣,從路由啟動的初始狀態開始,通過與相鄰路由不斷交換資訊來學習新路由,在RIP協議中,一個路由器傳送的表項為<目標網路,最短到達距離>,從接收的資訊中計算出最短路由的下一站路由器。如果有多條最短路由則取其中一條,下面給出虛擬碼

 /* T 是來自鄰接路由器R 的路由報告; 
本路由器是R0 , 其當前路由表是T0 */ 
 Vector_Distance_Shortest_Route_Discover(R, T) { 
     for( T的每一項(Nk , Dk)) { 
         if(T0中不存在形如(Nk ,﹒,﹒)的表項) { 
             insert(T0, (Nk , R, Dk+1)); /* R0 發現了一個新目標網路及其路由*/ 
             continue; 
         } 
         if(T0中存在形如(Nk , R, D)的表項&& D≠Dk+1) { 
             /* R0 到目標網路N的路由的距離發生了變化, R0無條件地接受這一變化3 */ 
             將T0的表項(Nk , R, D)更新為(Nk , R, Dk+1); 
             continue; 
         } 
         if(T0中存在形如(Nk , Rk, D)的表項&& Dk +1<D) { /* 這時一定R≠Rk */ 
             /* R0發現了到達目標網路Nk的距離更短的路由*/ 
             將T0的表項(Nk , Rk, D)更新為(Nk , R, Dk+1);4
             continue; 
         } 
     } 
 } 
 /* T 是來自鄰接路由器R 的路由報告; 
本路由器是R0 , 其當前路由表是T0 */ 
 Vector_Distance_Shortest_Route_Discover_RIP(R, T) { 
     for( T的每一項(Nk , Dk)) { 
         if(Dk==16&& T0中存在形如(Nk , R, D)的表項&& D≠16){ /*失效的路由*/ 
             將T0的表項(Nk , R, D)更新為(Nk , R, 16); 
             啟動表項(Nk , R, 16)的失效-刪除定時器; 
            /* 超時後若該失效項仍存在則將其永久刪除 */ 
            continue; 
         } 
         if(T0中不存在形如(Nk ,﹒,﹒)的表項) { 
             insert(T0, (Nk , R, Dk+1)); /* R0 發現了一個新目標網路及其路由*/ 
             啟動表項(Nk , R, Dk+1)的壽命定時器; 
            continue; 
         } 
         if(T0中存在形如(Nk , R, D)的表項) { 
            if( D≠Dk+1) { 
                 /* R0 到目標網路N的路由的距離發生了變化, R0無條件地接受這一變化5*/ 
                 將T0的表項(Nk , R, D)更新為(Nk , R, Dk+1); 
             } 
             啟動表項(Nk , R, Dk+1)的壽命定時器; /*復位-重啟*/ 
             continue; 
        } 
         if(T0中存在形如(Nk , Rk, D)的表項&& Dk +1<D) { /* 這時一定有R≠Rk */ 
             /* R0發現了到達目標網路Nk的距離更短的路由*/ 
             將T0的表項(Nk , Rk , D)更新為(Nk , R, Dk+1);6
             啟動表項(Nk , R, Dk+1)的壽命定時器; 
            continue; 
         } 
     } 
 } 

 RIP 的報告週期為 30 秒,路由表項的壽命時限為 180 秒,刪除定時器時限為 120 秒。路由表的刪除動作在定時器的時間超限例程中執行,這裡沒有寫出。

  路由振盪

距離-向量路由演算法如果收斂,則一定收斂到最短距離的路由。但從實用的角度看,不僅要求路由發現演算法能夠收斂,而且收斂時間越短越好。一個收斂時間過長的演算法是沒有實用價值的。距離-向量路由演算法的收斂時間一般會有多長? 甚至有沒有可能不收斂?通過分析我們將看到即使對這樣一個非常簡單的網路,如果不進行特殊的處理,距離-向量演算法確實有可能不收斂。這種不收斂或長時間進行路由更新而達不到穩態路由的現象,稱為路由振盪。

貼張圖解釋一下

比如R1到N距離是d,那麼R2到N即是d+1,某一時刻R1到N的路徑失效,此時R1到達N的距離變為無窮(在實際中常將距離設為16表示不可達),此時R1要尋找新的路徑,當他詢問R2時,R2到達N的距離還保留著d+1,那麼R1就會將自己到達N的距離更新成d+2,但顯然二者都是互相指向對方,形成了環路。若此時到達廣播週期,R1就會將表項廣播給R2,但是R2的距離來源即是R1,因此受到R1的更新後,R2無條件地+1變成d+3,之後二者就會迴圈遞增直到達到上限被捨棄。這就是振盪過程。為抑制路由振盪,常採用以下方法

    1.觸發更新

若網路中沒有變化,則按通常的30秒間隔傳送更新資訊。但若有變化,路由器就立即傳送其新的路由表。這個過程叫做觸發更新。

觸發更新可提高穩定性。每一個路由器在收到有變化的更新資訊時就立即發出新的資訊,這比平均的15秒要少得多。雖然觸發更新可大大地改進路由選擇,但它不能解決所有的路由選擇問題。例如,用這種方法不能處理路由器出故障的問題。

    2.水平分割(split horizon update)

讀者從上面的分析中能看到,之所以出現路由振盪,原因在於 R1 不能認識到 R2 所報告的關於網路 N 的路由實際上恰恰來自於自己從前的報告,對 R2 也是一樣。如果抑制這種反向報告,即規定如果一個路由器從某個近鄰的報告中學習到一組新路由,則永遠不再向該近鄰釋出包含這些路由項的報告,或更準確地說,是不再向該近鄰所在的網段上組播包含這些路由項的報告。

然而,水平分裂並非適合於所有網路,即使遵循水平分裂規則也仍然存在路由振盪現象。 

    3.毒性逆轉(poisoned reverse)

毒性逆轉(poison reverse)是水平分割的一種變型。使用這種方法時,路由器收到的資訊用來更新路由表,然後通過所有的介面傳送出去。但是,已經從一個介面來的一個路由表專案在通過同樣的介面傳送出去時,就要將其度量置為16。

    4.抑制計時(holddown timer)

一條路由資訊無效之後,一段時間內這條路由都處於抑制狀態,即在一定時間內不再接收關於同一目的地址的路由更新。如果,路由器從一個網段上得知一條路徑失效,然後,立即在另一個網段上得知這個路由有效。這個有效的資訊往往是不正確的,抑制計時避免了這個問題,而且,當一條鏈路頻繁起停時,抑制計時減少了路由的浮動,增加了網路的穩定性。

然而,以上並非完美的解決方案,主要問題是根據 RIP 路由更新演算法,及時報告機制會觸發連鎖的及時報告,結果是雖然逆向毒化及時通告了路由失效,但卻在短時間內引起網路負荷劇烈增加,特別是在一個網段上連線了多個路由器的情形。實際上,路由振盪是距離-向量演算法的內在矛盾,要徹底解決這一問題需要開發新的、基於不同機理的動態路由協議。

  開放最短路優先:OSPF

OSPF使用鏈路狀態演算法,包括LS分組分發,在每個節點使用拓撲圖,使用Dijkstra演算法的路由計算,即每一個節點儲存的不是相鄰節點的靜態資訊,而是整個網路全域性的拓撲圖。

OSPF相對與RIP主要有以下優點

  • 安全性: all OSPF messages authenticated (to prevent malicious intrusion)
  • 執行多條費用相同的路徑(在RIP中僅一條路徑)
  • 對每條鏈路,對不同的TOS(服務型別),設定多種費用度量(如衛星鏈路費用置為用於盡力而服務為“低”,高為實時服務)
  • 綜合的單播和多播支援: 多播OSPF (MOSPF)使用與OSPF相同的拓撲資料庫
  • 在大域中層次的OSPF

在實際中更是應用層次OSPF提高執行能力

  • 兩級層次: 本地, 主幹
  • 鏈路狀態通告僅在本地
  • 每個節點具有詳細的區域拓撲;僅知道到其他區域網路的方向(最短路)
  • 區域邊界路由器 : “摘要”到在自己區域網路的距離,向其他區域邊界路由器通告
  • 主幹路由器 : 執行OSPF 選路限制到主幹
  • 邊界路由器 : 連線到其他AS

  邊界閘道器協議:BGP

  • 路由器的對(BGP對等方)交換選路資訊通過半永久的TCP連線: BGP會話
  • 注意到BGP會話不對應著物理鏈路(覆蓋網路)
  • 當AS2向AS1通告一個字首, AS2則承諾它將轉發任何指向該字首的資料報,其中AS2和AS1都是兩個自治域,即劃分出的一小塊網路域
  • 自治域內部執行iBGP,自治域間執行eBGP

路由演算法

  距離向量演算法 dv

Bellman-Ford方程 (動態規劃)

dx(y) := 從x到y最低代價路徑的代價

dx(y) = min {c(x,v) + dv(y) }     其中min對x的所有鄰居

舉個例子:

  • 好訊息傳播得快
  • 壞訊息傳播得慢—“計數到無窮”
  • 毒性逆轉以解決計數到無窮

基本思想:每個節點週期性的傳送它自己的距離向量以估計到其鄰居;當節點x接收到來自鄰居的新DV估計,它使用B-F方程更新其自己的DV :

鏈路狀態演算法ls

Dijkstra演算法

  • 所有節點知道網路拓撲、鏈路費用
  • 經“鏈路狀態廣播”完成
  • 所有節點具有相同資訊
  • 從一個節點(源)到所有其他節點計算最低費用路徑
  • 給出對這些節點的轉發表
  • 迭代: k次迭代後,得知到k個目的地的最低費用路徑
  • c(x,y): 從節點x到y的鏈路費用;  = ∞ 如果不是直接鄰居
  • D(v):從源到目的地v路徑費用的當前值
  • p(v): 從源到v沿路徑的前任節點
  • N‘: 已知在最小費用路徑中的節點集合

LSDV演算法的比較

報文複雜性

  • LS: 對n個節點,E條鏈路, 傳送O(nE) 報文 
  • DV: 僅在鄰居之間交換
  • 收斂時間變化

收斂速度

  • LS: O(n2) 演算法要求 O(nE)報文
  •        可能具有振盪
  • DV: 收斂時間變化
  •        可能有選路環路
  •        計數到無窮問題

健壯性: 如果路由器異常,將發生什麼現象?

  • LS:
  •       節點可能通告不正確的鏈路代價
  •       每個節點僅計算它自己的表
  • DV:
  •       DV節點通告不正確的路徑費用
  •       每個節點表能由其他人使用
  •       差錯通過網路傳播

Hierarchical Routing(分層路由)

與其說是一種演算法,不如說是一種思想,將路由分層管理,即形成自治域autonomous systems (AS),這樣每個自治域內的路由只需互動自治域內的資訊,域間的路由器才進行多個域之間的資訊傳遞,應用熱土豆選擇,即是選擇經過域最少的,域內經過路由最少的