前一篇简单阐述了静态路由中的相关知识(传送门)
本篇就整理一下动态路由的相关内容
动态路由主要是基于以下两点
显然在实际大型网络拓扑结构中,实现这两点有着重要的意义,所以动态路由应运而生
下面贴几张图演示一下动态学习的过程
以R4为例,首先收到相邻节点R2,R3的路由信息,并增加自己没有的信息
R4的路由表产生了更新,于是向邻居广播,希望邻居都能得到其更新的信息,
邻居们获得了R4的更新并随即学习更新了自身的路由信息,此时他们的路由信息也发生变化,于是继续广播给邻居
得到新信息的邻居继续学习更新自己的路由表,经过这一动态过程,网络域中的所有节点都动态学习到了所有的网络信息
而正是基于这种不断广播,不断学习,不断更新的过程,使得链路失效后,有效路由也能重新建立,下面给出链路失效后重新建立连接的例子
动态路由协议本质上都是依靠各个路由器上运行的特殊进程在路由器之间不断交换路由信息来推断,学习出网络的全局路由。
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
/* 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
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,之后二者就会循环递增直到达到上限被舍弃。这就是振荡过程。为抑制路由振荡,常采用以下方法
若网络中没有变化,则按通常的30秒间隔发送更新信息。但若有变化,路由器就立即发送其新的路由表。这个过程叫做触发更新。
触发更新可提高稳定性。每一个路由器在收到有变化的更新信息时就立即发出新的信息,这比平均的15秒要少得多。虽然触发更新可大大地改进路由选择,但它不能解决所有的路由选择问题。例如,用这种方法不能处理路由器出故障的问题。
读者从上面的分析中能看到,之所以出现路由振荡,原因在于 R1 不能认识到 R2 所报告的关于网络 N 的路由实际上恰恰来自于自己从前的报告,对 R2 也是一样。如果抑制这种反向报告,即规定如果一个路由器从某个近邻的报告中学习到一组新路由,则永远不再向该近邻发布包含这些路由项的报告,或更准确地说,是不再向该近邻所在的网段上组播包含这些路由项的报告。
然而,水平分裂并非适合于所有网络,即使遵循水平分裂规则也仍然存在路由振荡现象。
毒性逆转(poison reverse)是水平分割的一种变型。使用这种方法时,路由器收到的信息用来更新路由表,然后通过所有的接口发送出去。但是,已经从一个接口来的一个路由表项目在通过同样的接口发送出去时,就要将其度量置为16。
一条路由信息无效之后,一段时间内这条路由都处于抑制状态,即在一定时间内不再接收关于同一目的地址的路由更新。如果,路由器从一个网段上得知一条路径失效,然后,立即在另一个网段上得知这个路由有效。这个有效的信息往往是不正确的,抑制计时避免了这个问题,而且,当一条链路频繁起停时,抑制计时减少了路由的浮动,增加了网络的稳定性。
然而,以上并非完美的解决方案,主要问题是根据 RIP 路由更新算法,及时报告机制会触发连锁的及时报告,结果是虽然逆向毒化及时通告了路由失效,但却在短时间内引起网络负荷剧烈增加,特别是在一个网段上连接了多个路由器的情形。实际上,路由振荡是距离-矢量算法的内在矛盾,要彻底解决这一问题需要开发新的、基于不同机理的动态路由协议。
OSPF使用链路状态算法,包括LS分组分发,在每个节点使用拓扑图,使用Dijkstra算法的路由计算,即每一个节点存储的不是相邻节点的静态信息,而是整个网络全局的拓扑图。
OSPF相对与RIP主要有以下优点
在实际中更是应用层次OSPF提高运行能力
Bellman-Ford方程 (动态规划)
dx(y) := 从x到y最低代价路径的代价
dx(y) = min {c(x,v) + dv(y) } 其中min对x的所有邻居
举个例子:
基本思想:每个节点周期性的发送它自己的距离矢量以估计到其邻居;当节点x接收到来自邻居的新DV估计,它使用B-F方程更新其自己的DV :
Dijkstra算法
与其说是一种算法,不如说是一种思想,将路由分层管理,即形成自治域autonomous systems (AS),这样每个自治域内的路由只需交互自治域内的信息,域间的路由器才进行多个域之间的信息传递,应用热土豆选择,即是选择经过域最少的,域内经过路由最少的