第2章 RIP
2.1 RIP的基本概念
RIP(Routing Information Protocol,路由信息协议)是最典型的距离矢量路由协议,常被用于在小型的网络中交互路由信息,它是最先得到广泛使用的IGP协议,由于其工作机制相对简单,因此一直以来都作为数通领域入门动态路由技术的协议被大家所熟知。
目前RIP存在三个版本,分别是面向IPv4的RIPv1和RIPv2,以及面向IPv6的RIPng。本章内容涵盖RIPv1和RIPv2,对于RIPng的讨论超出了本书的范围,请读者朋友们自行查阅相关的文档书籍。学习完本节之后,我们应该能够:
● 理解RIP路由更新及接收机制;
● 理解RIP度量值;
● 熟悉RIPv1及RIPv2的报文格式;
● 熟悉RIP的几种计时器及其含义;
● 熟悉RIP的Silent-Interface概念及配置。
2.1.1 RIP路由更新及接收
每台RIP路由器都维护着一个RIP数据库(Database),在该数据库中保存着路由器发现的所有RIP路由,其中包括自己发现的直连路由以及从其他路由器收到的路由。在RIP数据库中的每个路由条目都包含:目的网络地址/网络掩码、度量值、下一跳地址、老化计时器以及路由状态标识等信息。RIP数据库中的有效路由条目被加载到路由器的路由表中。
每台运行RIP的路由器周期性地将自己的路由表通告出去,当路由器收到RIP路由更新时,如果这些路由是自己并未发现的并且是有效的,则将其加载到路由表,同时设置路由的度量值和下一跳地址。
通过下面这个简单的示例,大家能够了解到运行了RIP的路由器是如何完成路由信息的学习和收敛的。当然这是一个微观的过程,旨在帮助大家理解RIP的基本工作机制,在真实的网络环境中未必能直接观测到相关现象。
1.路由器初始启动
在图2-1所示的网络中,R1、R2和R3三台路由器直连,图中每台设备的路由表显示了路由的目的网络地址/网络掩码、协议类型、度量值及出接口。现在我们在这三台路由器上激活RIP并观察路由的交互过程。在初始情况下,所有的路由器都能自动发现自己的直连路由,并且将直连路由写入路由表。以R1为例,它在其路由表中加载了192.168.12.0/24及1.0.0.0/8两条直连路由。在华为数通产品上,RIP将直连路由的度量值视为0跳,因为该直连网段就在“家门口”。所谓的“0跳”指的是到达该网段不需要经过任何一台路由器。
图2-1 初始时,所有的路由器都自动发现了自己直连接口的路由
2.初次交换路由信息
由于R1、R2及R3都运行了RIP,因此它们都将自己路由表中的路由通过RIP协议报文周期性地从所有激活了RIP的接口通告出去(RIPv1使用广播地址作为协议报文的目的IP地址,而RIPv2则使用组播地址)。对于R2而言,它会将自己的路由表从GE0/0/0和GE0/0/1接口通告出去。以192.168.23.0/24路由为例,R2会将关于该路由的更新从GE0/0/0接口通告给R1,它将该路由的度量值设置为1跳(0跳加1跳,也就是加上“自己这一跳”)——RIP路由器将自己路由表中的路由通告出去时将跳数加1,而收到该路由更新的RIP路由器将路由安装到自己路由表时则使用这个度量值。R1收到R2所通告的路由更新后发现192.168.23.0/24路由在其路由表中并不存在,于是将该路由“学习”过来,加载到路由表中,将路由的度量值设置为1跳(意思是自己要到达192.168.23.0/24,需要经过一个RIP路由器),此外还将该路由的下一跳设置为路由的更新源R2(它从路由更新报文的源地址获得R2的IP地址),出接口设置为GE0/0/0。
R3也会在自己的GE0/0/0接口上收到R2通告的路由更新,并学习到路由192.168.12.0/24,它将该条RIP路由加载到路由表中,并将路由的下一跳设置为R2,出接口设置为GE0/0/0,度量值设置为1。而R2会在自己的GE0/0/0接口上收到R1通告的路由更新,在GE0/0/1接口上收到R3通告的路由更新,并最终学习到1.0.0.0/8及3.0.0.0/8路由,具体过程不再赘述。
经过这一轮路由通告及学习,R1能够学习到192.168.23.0/24路由,R2能够学习到1.0.0.0/8及3.0.0.0/8两条路由,而R3能够学习到192.168.12.0/24路由,如图2-2所示。
图2-2 初次交换路由信息
3.路由完成收敛
由于运行RIP的路由器会周期性地将自己的路由表通告出去,因此在下一个更新周期到来时,所有路由器再次将自己的路由表通告出去。R1收到R2通告的路由后发现路由3.0.0.0/8在路由表中并不存在,因此将该条路由学习过来,加载到路由表并关联度量值:2跳,这意味着R1要到达3.0.0.0/8需要经过两个路由器。同理,另一边的R3也能够从R2学习到1.0.0.0/8路由。如此一来,三台路由器都拥有了到达全网各个网段的路由,如图2-3所示,而且设备的路由表此时已经稳定,这个阶段被称为“网络中的路由已经完成了收敛”。虽然网络中路由器的路由表已经稳定,但它们依然会周期性地将自己的路由表通过RIP通告出去,以确保路由的有效性。
图2-3 路由完成收敛,所有的路由器获知到达全网各个网段的路由
2.1.2 RIP路由更新与路由表
RIP是典型的距离矢量路由协议,在前面的小节中,大家已经初步了解了其基本工作机制,从单台RIP路由器的角度看,它只是简单地侦听直连的RIP路由器所通告的RIP路由更新,从该更新中发现RIP路由,并将学习到的路由加载到路由表中。另一方面,它也将自己路由表中的RIP路由通告出去,以便直连的RIP路由器能够学习到。实际上,对于RIP路由器而言,它并不知晓整个网络的拓扑结构。
在图2-4中,R1、R2、R3及R4运行了RIP,初始时,R1及R3需通过R2实现连接。R1将本地直连网段192.168.1.0/24发布到了RIP,从而R2能够通过RIP学习到该条路由,它将路由加载到自己的路由表中,然后进一步通过RIP将该路由通告给R3,同理,后者学习到路由后将其加载到自己的路由表中,然后通过RIP通告给R4。最终,网络中的4台路由器都能学习到192.168.1.0/24路由。
图2-4 RIP路由更新与路由表
现在R1及R3之间新增了一条高带宽链路,我们期望将R3发往192.168.1.0/24的流量引导到这条新增链路上。由于R1及R3并不是通过这段新增的链路直接相连(中间还有其他设备),因此无法在它们之间部署RIP——直连的网络设备之间才能够通过RIP交互路由信息,于是我们在R3上配置了到达192.168.1.0/24的静态路由,下一跳从高带宽链路指向ISP。由于静态路由的优先级值为60,而RIP路由的优先级值为100,显然,缺省情况下静态路由的优先级要比RIP路由更高,因此R3将到达192.168.1.0/24的静态路由取代原有的RIP路由加载到自己的路由表中。由于路由表中到达192.168.1.0/24的RIP路由消失,因此R3将此前通告给R4的该条RIP路由撤销,并且在此后其周期性从该接口发送的RIP路由更新中也不再包含这条路由。换句话说,R4无法再通过RIP学习到该路由。此时就必须通过其他手段,确保R4能够拥有到达该网段的路由。
从本例大家能够更加直观地了解RIP的工作过程:从直连路由器收到RIP路由更新;将路由加载到路由表;将路由通告给其他直连路由器。
2.1.3 度量值
度量值是一个非常重要的概念。简单地说,所谓度量值就是指到达目的网络所需的代价或成本。每种路由协议都定义了路由的度量值,但是它们对度量值的规定可能不尽相同,例如有的路由协议使用到达目的网络沿途需经过的路由器个数作为路由的度量值,而有的协议则基于链路带宽计算路由度量值。度量值的大小将直接影响路由器对到达某个目的网段的路由(或者说路径)的优选。例如当一台路由器发现两条路径可以到达同一个目的地(或者说路由器从两个不同的下一跳学习到去往同一个目的网络的路由),并且这两条路由都是通过同一种路由协议发现的,那么通常情况下度量值更优的那条路由会被优选,而度量次优的路由则作为备份,只有当最优路由失效时,次优路由才会被使用。
RIP以跳数(Hop Count)作为路由的度量值,所谓的跳数,就是到达目的网络所需经过的路由器个数,显然RIP的度量值需为非负整数,而且跳数越少,路由被认为越优。
在图2-5中,R1到达直连网段1.0.0.0/8的度量值为0。随着RIP更新周期的到来,它将该条路由从GE0/0/0接口通告出去,值得注意的是,在R1所通告的路由更新中,1.0.0.0/8路由携带的度量值为1,也就是说,R1将该条路由的度量值加1后才通告给R2。R2收到R1通告的路由更新后,将1.0.0.0/8路由学习过来,加载到路由表中,并将路由的度量值设置为1,也就是沿用R1所通告的度量值。接着R2将1.0.0.0/8路由从自己的GE0/0/1接口通告出去,而在R2所通告的路由更新中,该条路由的度量值被设置为2——R2将路由的度量值加1后通告给R3。最后,R3也能学习到1.0.0.0/8路由。华为路由器运行RIP后,认为本地直连路由的跳数为0。当RIP路由器将一条路由通告出去时,路由的跳数被增加1跳,而收到这个路由更新的路由器将这条路由加载进路由表时度量值沿用该值。
图2-5 RIP使用跳数作为路由的度量值
RIP使用跳数作为度量值的设定使得路由器能够直观地知道自己距离目的网络的“远近”。在路由优选的过程中,通过比较度量值,RIP会从可选路径中选择一条到达目的网络的最优路径,所谓最优也就是跳数最小。在图2-6中,假设所有路由器都运行了RIP,则R5会将路由5.0.0.0/8通告给R2和R4,通告时路由的度量值设置为1跳,在收到这条路由更新后,R2会把这条路由通告给R1并告知度量值为2跳,如此一来,R1便发现了一条到达5.0.0.0/8的路由。另一方面,R4从R5学习到5.0.0.0/8路由后会进一步通告给R3,而R3又会将其通告给R1,这样R1又发现了另一条到达5.0.0.0/8的路由。此刻对于R1而言,有两条路由可以到达5.0.0.0/8,那么R1就会进行最优路由的选择,拥有更少跳数的路由将被优选并最终被加载到路由表中作为数据转发的依据。因此在R1的路由表中,5.0.0.0/8路由的下一跳是R2。
图2-6 RIP路由器优选跳数更少的路由
通过跳数来度量到达目的网络的远近非常简单和直观,但是也存在一个明显的问题。在上文介绍的这个例子中,如果网络链路带宽不一致,RIP的这种度量值的设计就可能导致路径选择不合理。如图2-7所示,网络中的链路带宽是不一致的,但是RIP并不关心链路的带宽,它只关心到达目的地沿途需经过的路由器个数,因此即使R1—R3—R4—R5这条路径的沿途链路带宽要比另一条路径高得多,但由于这条路径的跳数更大,因此它将永远不会被R1选择作为到达5.0.0.0/8的路径(除非另一条路径失效),这显然是不合理的。在这种场景中,网络管理员可以通过对RIP路由的度量值进行适当地调整——例如,将低带宽路径的RIP路由的度量值增加一个特定的量,使得其不被目标设备优选,进而影响数据流量的转发路径。
图2-7 R1依然优选R2通告过来的5.0.0.0/8路由,虽然经R2到达该目的网段的路径是低带宽路径
2.1.4 报文类型及格式
RIP的协议报文采用UDP封装,报文的源、目的端口均是UDP520端口。RIP定义了两种报文,它们分别是请求(Request)报文和响应(Response)报文。RIPv1和RIPv2在协议报文各个字段的定义中存在些许差异,这些差异实际上是两个版本工作机制的不同所造成的。Request报文用于向邻居请求全部或部分RIP路由信息,而Response报文则用于发送RIP路由更新,在Response报文中携带着路由以及该路由的度量值等信息。
一旦路由器的某个接口激活RIP后,该接口立即发送一个Request报文和Response报文,并开始侦听RIP协议报文。随后接口开始Response报文的周期性发送。RIPv1使用广播地址255.255.255.255作为协议报文的目的IP地址,而RIPv2则不同,它使用组播IP地址224.0.0.9作为协议报文的目的IP地址。当RIP路由器收到Request报文后,会使用Response报文进行回应,在该报文中携带对方所请求的路由信息。当RIP路由器收到Response报文后,会解析出该报文中所携带的路由信息,如果报文中的路由信息是自己尚未发现的,并且路由的度量值有效,则路由器将学习该路由并将路由加载进路由表,同时为这条路由关联度量值、出接口和下一跳信息。
1.RIPv1的报文结构
RIPv1报文(如图2-8所示)中各个字段的含义如下。
图2-8 RIPv1报文格式
● 命令字段(Command):该字段用于标识RIP报文的类型。
■ 值为1时该报文为Request报文,用于向直连路由器请求全部或部分路由信息。
■ 值为2时该报文为Response报文,用于发送路由更新,该报文可以作为对Request报文的回应,也可以是路由器自主发送的,例如周期性发送路由更新或者触发性发送路由更新。一个Response报文中最多可携带25个路由条目,当待发送的路由数量大于该值时,需使用多个Response报文。
● 版本字段(Version):在RIPv1中,该字段的值为1。
● 地址族标识符(Address Family Identifier,AFI):该字段值为2时表示IP协议。如果该报文为Request报文并且是用于向直连路由器请求其整张路由表,则该字段值被设置为0,同时这个Request报文中包含且只包含一个路由条目,该路由的目的网络地址为0.0.0.0,度量值为16。
● IP地址(IP Address):路由的目的网络地址。
● 度量值(Metric):路由的度量值。
值得注意的是,RIPv1的Response报文中并不携带路由的目的网络掩码。
2.RIPv2的报文结构
RIPv2报文(如图2-9所示)中各个字段的含义如下。
图2-9 RIPv2的报文结构
● 命令字段(Command):与RIPv1类似,不再赘述。
● 版本字段(Version):在RIPv2中,该字段的值为2。
● 地址族标识符(Address Family Identifier):与RIPv1类似,不再赘述。
● 路由标记(Route Tag):用于为路由设置标记信息,缺省为0。当一条外部路由被引入RIP从而形成一条RIP路由时,RIP可以为该路由设置路由标记,当这条路由在整个RIP域内传播时,路由标记不会丢失。
● IP地址(IP Address):路由的目的网络地址。
● 网络掩码(Netmask):RIPv1路由器在通告路由时是不携带目的网络掩码的,这是因为在RIPv1的报文中并没有定义相应的字段,这使得RIPv1无法支持VLSM(Variable Length Subnet Mask,可变长子网掩码)。RIPv2在这一点上做了改进,定义了该字段用于存储路由条目的目的网络掩码,如此一来,RIPv2便能够支持VLSM。
● 下一跳(Next Hop):RIPv2定义了该字段,使得路由器在多路访问网络上可以避免次优路径现象。一般情况下,在路由器所发送的路由更新中,路由条目的“下一跳”字段会被设置为0.0.0.0,此时收到该路由的路由器将路由条目加载到路由表时,将路由的更新源视为到达目的网段的下一跳。在某些特殊的场景下,该字段值会被设置为非0.0.0.0,本章将在“下一跳字段”一节中介绍该字段。
● 度量值(Metric):该路由的度量值。
2.1.5 计时器
RIP定义了多个计时器,其中最重要的三个计时器如下。
● 更新计时器(Update Timer):该计时器的时间为RIP路由器周期性泛洪路由表(周期性在接口上发送Response报文)的时间间隔。在缺省情况下,路由器以30s为周期从已经激活RIP的接口向外发送Response报文。
如果一个网络中有多台RIP路由器接入,每台路由器所有激活RIP的接口如果在更新计时器超时后一齐泛洪Response报文,就有可能引发不必要的冲突或者使得同一时间内网络中充斥着大量的RIP广播或组播报文。为了避免这个问题,RIP引入一个随机的偏移量,也就是路由器不以严格的30s为周期发送RIP报文,而是在该时间的基础上关联一个随机的、细小的偏移量(加/减0~5s)。
● 老化计时器(Age Timer):每一条RIP路由都关联两个计时器,其中之一就是老化计时器(也被称为超时计时器)。当一条RIP路由被学习并加载到路由表时,路由器立即为该路由启动老化计时器(缺省180s),该计时器被启动后即开始计时。此后每当更新周期来临时,路由器会再次收到该条路由的更新,老化计时器又被重置并重新开始计时。以华为AR2200路由器为例,若一条路由持续未被刷新并最终导致老化计时器超时,路由则变为不可用并从路由表中删除,虽然被立即从路由表中删除,但该条路由依然被保存在RIP数据库中(以便路由随时能够恢复),在老化计时器超时的同时,该路由的垃圾回收计时器也被立即启动。值得注意的是,对于老化计时器已超时的失效RIP路由,依然会被包含在路由器对外发送的Response报文中,只不过路由的度量值被设置为16跳,即不可达。
● 垃圾回收计时器(Garbage-Collect Timer):垃圾回收计时器缺省被设置为120s。上文已经说到,当一条RIP路由的老化计时器超时,该条路由会变为不可用并被设备从路由表中删除,但是依然被保存在RIP数据库中,同时设备立即为该路由启动垃圾回收计时器。在垃圾回收计时器计数的这段时间,RIP路由器在泛洪路由更新时将该条路由的度量值设置为16跳,以便告知其他路由器关于该网络的不可达情况。若连该计时器也超时,则路由便被彻底删除。
在RIP配置视图下,使用times rip命令可以修改上述三个计时器的时间值,该命令可指定三个参数,分别对应RIP的路由更新时间间隔、老化时间以及垃圾回收时间。例如:
完成上述配置后,华为网络设备的RIP的路由更新时间间隔、老化时间以及垃圾回收时间将分别被修改为35s、190s及200s。
2.1.6 Silent-Interface
在缺省情况下,一旦路由器的某个接口激活了RIP,RIP就开始在该接口周期性地发送Response报文,同时也在该接口上侦听RIP报文。在图2-10所示的网络中,为了让PC与R2直连的192.168.2.0/24网段实现互通,就必须让R2学习到192.168.1.0/24路由,让R1学习到192.168.2.0/24路由。如果在R1及R2之间部署RIP,那么对于R1而言,需要在其GE0/0/1及GE0/0/2接口上都激活RIP。如此一来,R1便会在这两个接口上发送Response报文,当然,也会在这两个接口上侦听RIP报文。R1会将携带了192.168.1.0/24路由的Response报文从GE0/0/2接口发送出去,使得R2能够学习到该路由,它也会将Response报文(携带了192.168.12.0/24以及从R2学习到的路由)从GE0/0/1接口发送出去。但实际上,这些RIP报文对于其GE0/0/1接口所连接的网段来说是没有任何意义的——这里没有任何RIP路由器,因此R1在该网段中所发送的Response报文实际上给PC带来了额外的负担。
图2-10 R1的GE0/0/1接口一旦激活了RIP,它便开始在该接口上周期性泛洪并侦听RIP报文
使用Silent-Interface(静默接口)特性可以解决这个问题。一个RIP接口一旦被指定为Silent-Interface,则该接口将不再发送RIP报文,而只是被动地接收RIP报文,也就是只收不发。所以在本例中,如果将R1的GE0/0/1接口激活RIP同时配置为Silent-Interface,则R1不再向GE0/0/1接口发送Response报文,这就消除了PC为解析RIP报文所产生的资源损耗。
另一方面,虽然GE0/0/1接口被指定为Silent-Interface,但是由于该接口已经激活了RIP,因此当R1从其他接口发送Response报文时,依然会在报文中携带192.168.1.0/24路由信息,也就是说,将GE0/0/1接口设置为Silent-Interface并不妨碍R2通过RIP学习到该接口的路由。最后需强调的是,Silent-Interface接口仅仅是不向外泛洪Response报文,但是它依然可以接收Response报文。