浅谈网络层动态路由及路由协议+算法

前一篇简单阐述了静态路由中的相关知识(传送门

本篇就整理一下动态路由的相关内容

动态路由基本概念

动态路由主要是基于以下两点

  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),这样每个自治域内的路由只需交互自治域内的信息,域间的路由器才进行多个域之间的信息传递,应用热土豆选择,即是选择经过域最少的,域内经过路由最少的

猜你喜欢

转载自blog.csdn.net/ZP_icenow/article/details/81082685