大多数的路由选择协议属于下面二者之一:
距离矢量(distance vector)和链路状态(link state)。
本篇学习的是距离矢量路由选择协议的基础。
大多数的距离矢量算法是R.E.Bellman、L.R.Ford和D.R.Fulkerson所做的工作为基础的,所有有时距离矢量算法又称为Bellman-Ford或者Ford-Fulkerson算法。
值得注意的是EIGRP是一个例外,它是基于J.J.Garcia Luna Aceves开发的算法实现的。
距离矢量名称的由来是因为路由器是以矢量(距离、方向)的方式被通告出去的,其中距离是根据度量定义的,方向是根据下一跳路由器定义的。
例如,"目标A在下一跳路由器X的方向,距离5跳之远"。这个表述隐含了每台路由器向邻接路由器学习它们所观察到的路由器信息,然后在向外通告自己观察到的路由器的信息,而每台路由器的信息又是根据邻接的路由器,所以所有距离矢量路由选择有时又被认为是"依据传闻进行路由选择"。
下面列举的都属于距离矢量路由协议:
IP路由选择信息协议(RIP);
Xerox网络系统的XNS RIP;
Novell的IPX RIP;
Cisco Systems的Internet网关路由选择协议(IGRP)和增强型Internet网管路由选择协议(EIGRP);
DEC的DNA阶段4;
Apple Talk的路由选择表维护协议(RTMP)。
通用属性
典型的距离矢量路由选择协议通常会使用一个路由选择算法,算法中路由器通过广播整个路由表,定期地向所有邻居发送路由更新信息(EIGRP不是这样的)。
上面表述包含了大量信息。
1. 定期更新
2. 邻居
3. 广播更新
4. 全路由选择表更新
依照传闻进行路由选择
在图中正在进行一个距离矢量算法,其中使用跳数作为度量。
在T0时刻,路由器A到路由器D正好可用,而且T0时刻4台路由器所具有的惟一信息就是它们的直连网络。
路由表标识了这些网络,并且指明了它们没有经过下一跳路由器,是直接连接到路由器上的,所以跳数为0。
每台路由器都将在它所有的链路上广播这些信息。
在T1时刻,路由器接受并处理第1个更新信息。
查看此时路由器A的路由表,路由器B发给路由器A的更新信息发现路由器B能够到达网络10.1.2.0和10.1.3.0,而且距离都为0跳。
如果这些目标网络距离路由器B为0跳,那么距离路由器A则为1跳。
所以路由器A将跳数增加1,然后检查自己的路由表。
路由表中显示网络10.1.2.0已知,且距离为0跳,小于路由器B通告的跳数,所以路由器A忽略此信息。
图 距离矢量协议逐跳收敛
由于网络10.1.3.0对于路由器A来说是新信息,所以路由器A将其输入到路由表中。更新数据包的源地址是路由器B的接口地址(10.1.2.2),因此该地址连同计算的跳数一起被保存到路由表中。
注意T1时刻,其他路由器也进行了类似操作。
在T2时刻,随着更新周期的再次到期,另一组更新消息被广播,路由器C告知路由器B的路由信息。
路由器B发送了最新的路由表,路由器A更新此时的路由信息。
在T3时刻,网络已经收敛。每台路由器都已经知道了每个网络以及达到每个网络的下一跳路由器的地址和距离跳数。
距离矢量算法提供了指向网络的路标。该算法给出了方向和距离,但没有给出沿着这条路径行走的细节。就像交叉路口一样,很容容易受到意外或故意的误导。
下面给出的是距离矢量算法的困境以及一些改进的措施。
路由失效计数器
如果网络已经收敛,那么当部分网络的拓扑发生变化时,它怎样处理重新收敛问题呢?
如果网络10.1.5.0发生故障,答案很简单——在下一个周期中,路由器D将这个网络标记为不可达并且发送该信息。
如果网络10.1.5.0没有发生故障,而是路由器D发生故障了?
路由器A、B、C的路由表中仍然保存着关于网络10.1.5.0的信息,虽然该信息不再有用,但是却没有路由器通知它们。
它们将不知不觉地向一个不可达网络转发着数据包——即在网络中打开了一个黑洞。
处理这个问题的方式是为路由表中的每个表项设置一个失效计时器。
例如,当路由器C首次知道10.1.5.0并将其输入到路由表中时,路由器C将为该路由器设置计时器。
每隔一定时间间隔路由器C都会收到路由器D的更新信息,路由器C在丢弃有关10.1.5.0的信息的同时复位该路由的计时器。
如果路由器D发生故障,路由器C将不能接收到关于10.1.5.0的更新信息。这时计时器将会超时,路由器C将把该路由标记为不可达,并将在下一个更新周期时传递该信息。
路由器超时的典型周期范围是3~6个更新周期。路由器在丢失单个更新信息之后将不会使路由器无效的,因为数据包的损坏、丢失或者某种网络延迟都会造成这种事件的发生。但是如果路由失效周期太长,网络收敛速度将会非常慢。
水平分隔
目前,每个路由器在每个更新周期都要向每个邻居发送它的整个路由表。但是并没有必要,如果路由器A将学自路由器B的网络再广播给路由器B,那么这是一种浪费,因为B已经知道这些网络。
路由的指向与数据包流动方向相反的路由被称为逆向路由(reverse route)。水平分隔(split horizon)是一种在两台路由器之间阻止逆向路由的技术。
这样除了不会浪费资源,还因为不会把从路由器学习的可达性信息再返回给这台路由器。
动态路由选择协议最重要的功能就是监测和补偿拓扑变化——如果网络的最优路径不可用,协议必须寻找下一个最优路径。
假设路由器监测到网络10.1.5.0发生故障,将网络标记为不可达并且在下一个更新周期通知路由器C。然后在路由器D更新计时器触发更新之前,意外的事情发生了。路由器C的更新消息到达了路由器D,声明路由器C可以到达网络10.1.5.0,距离为1跳!
但是路由器D并不知道路由器C通告的下一条最优路径并不合理,因而路由器D将跳数加1并在路由表中记录一下信息:通过路由器C的接口(10.1.4.1)可以到达网络10.1.5.0,距离为2条。
这样路由器D查询路由表又将数据包转发给路由器C,路由器C再转回给路由器D,一直无穷无尽地进行下去,因而导致路由环路的发生。
执行水平分隔可以阻止路由环路的发生。有两类水平分隔方法:简单水平分隔法和毒性逆转水平分隔法。
简单水平分隔的规则是:从某接口发送的更新消息不能包含从该接口收到的更新所包含的网络。
简单水平分隔采用的抑制信息的工作方式。毒性逆转水平分隔法是一种改进方法,可以提供更积极的信息。
毒性逆转水平分隔法的规则是:当更新信息被发送出某接口时,信息中将指定从该接口的更新信息中获取的网络是不可达的。
毒性逆转水平分隔法被认为比简单水平分隔法更安全更健壮——一种"坏信息总比没有消息好"的方法。
大部分现代距离矢量算法的实现都是用了毒性逆转水平分隔法。缺点是使路由器更新数据包更大了,可能会加剧链路的拥塞问题。
计数到无穷大
水平分隔法切断的是邻居路由器之间的环路,但是它不能隔断网络中的环路。可达网络的距离在不断地在路由器信息增大的时候会到无穷大。减轻计数到无穷大影响的方法是定义无穷大。大多数距离矢量协议定义无穷大为16跳。
随着更新消息在路由器中转圈,到某个不可达网络的跳数会达到16,那时网络被认为是不可达。
这也是路由器如何通告一个网络不可达的方法。
设置最大跳数15有助于解决计数到无穷大的问题,但是收敛速度仍旧非常慢。假设更新周期为30s,网络可能花7.5min达到收敛,在这期间容易受到路由错误的影响。触发更新可以用于减少网络收敛时间。
触发更新
触发更新(Triggered Update)又叫快速更新,非常简单:如果一个度量变好或者变坏,那么路由器将立即发送更新信息,而不等更新计时超时。
抑制计时器
如果到一个目标的距离增加,那么路由器将为该路由设置抑制计时器。直到计时器超时,路由器才可以接受有关此路由的更新信息。
异步更新
一组连接在以太骨干网上的路由器,将不会同时广播更新信息,因为会导致数据包发生碰撞。但是几个路由器共享一个广播网络时可能会发生这种情况。
以下两种方法维持异步更新(Asynchronous Update):
- 每台路由器的更新计时器独立于路由选择进程,因而不会受到路由器处理负载的影响
- 每个更新周期中加入一个小的随机时间或定时抖动作为偏移