动态路由协议RIP

RIP概述

RIP(Routing Information Protocol,路由信息协议)是最典型的距离矢量路由协议,常被用于在小型的网络中交互路由信息,它是最先得到广泛使用的IGP协议。

RIP目前有三个版本,分别是面向IPv4的RIPv1和RIPv2,以及面向IPv6的RIPng。 RIP定义了路由的最大跳数15,当一条路由度量值达到16跳时,该路由被视为不可达。

每台路由器都维护着一个RIP 数据库,数据库中保存着路由器发现的所以RIP路由,其中包括直连路由及从其他路由器收到的路由。RIP数据库路由条目包含:目的网络地址、网络掩码、度量值、下一跳地址、老化计时器及路由状态信息标识等信息。

RIP基本工作机制

工作机制简述

每台运行RIP的路由器周期性的将自己的路由表通告出去,当路由器收到RIP路由更新时,如果这些路由是自己并未发现的并且是有效的,则将其加载到路由表,同时设置路由的度量值和下一跳。
通告原则:运行RIP的路由器将自己路由表中的路由通告RIP协议报文周期性的从所有激活了RIP的接口通告出去。

RIP工作机制的案例

R1、R2、R3三台路由器直连,路由器激活了RIP,因此它们都将自己路由表中的路由通过RIP协议报文周期性地从激活了RIP的接口通告出去,我们来观察它的交互过程。
在这里插入图片描述

路由器初次启动

对于R1来说,它路由表加载了两条直连路由:192.168.12.0/24,10.0.0.0/8,RIP将直连路由的度量值视为0跳,因为直连网段就在家门口。
所谓“0跳”,就是指到达该网段不需要经过任何一台路由器

初次交换路由信息

对R2来说,它会将自己的路由表从G0/0/0与G0/0/1接口通告出去,以192.168.23.0/24为例,R2会将关于该路由的更新从G0/0/0接口通告给R1,它将路由的度量值设置为1跳(加上自己这一跳)。

而收到该路由更新的RIP路由器将路由安装到自己路由表时则使用这个度量值,R1收到R2所通告的路由更新后发现,192.168.23.0/24在其路由表中并不存在,于是将该路由“学习”过来,加载到路由表中,将路由的度量值设置为1跳(意思是自己要达到192.168.23.0/24,需要经过一个RIP路由器)

此外还将该路由的下一跳设置为路由的更新源2(它从路由更新报文的源地址获得R2的IP地址),出接口设置为GE0/0/0。

R3也会接收R2的路由通告,学习到192.168.12.0/24,将其加载到路由表中,设置路由下一跳为R2,出接口设置G0/0/0,度量值为1。R2会在G0/0/0收到R1的路由通告,在G0/0/1收到R3的路由通告,并最终学习到1.0.0.0/8与3.0.0.0/8两条路由。

路由完成收敛

由于运行RIP的路由器会周期性的将自己的路由表通告出去,因此在下一个更新周期到来时,所有路由器再次将自己的路由表通告出去,R1收到R2的路由发现3.0.0.0/8并不存在,会将其加载至路由表并关联度量值:2跳,意味着R1到达R3要经过两个路由器,同理,R3也是如此。

如此一来,三台路由器都拥有了到达全网各个网段的路由,而且设备的路由表已经稳定,这个阶段被称为“网络中的路由完成了收敛”,虽然网络中路由表已经趋于稳定,但它们依然会周期性的将自己的路由表通过RIP通告出去,以确保路由的有效性。

路由器完成收敛,所有路由器获知了全网各个网段的路由。
在这里插入图片描述

RIP版本

RIPv1使用广播地址作为协议报文的目的IP地址,RIPv2则使用组播地址。

RIP路由更新与路由表

RIP是距离矢量路由协议,从单台RIP路由器的角度看,它的工作机制就是简单的侦听直连的RIP路由器所通告的RIP路由更新,从更新中发现、学习路由并加载到路由表中。
它也将自己的路由表通告出去,以便直连的路由器能够学习到,实际上对于RIP路由器而言,它并不知晓整个网络的拓扑结构。

RIP与静态路由

RIP与静态路由实例

R1、R2、R3、R4运行RIP,R1将本地直连网段1.0.0.0/8发布到了RIP,R2通过RIP学习与加载到路由表,并通过RIP通告给R3,R3->R4,最终网络中4台路由器都会学习到1.0.0.0/8路由。

在这里插入图片描述
现在R1与R3新增一条高宽带链路,希望将R3发往1.0.0.0/8的流量引导至新增宽带上,由于R1与R3并不是通过新增链路直连(中间有其他设备),因此它们无法运行RIP交互信息。

因此,我们需要在R3配置了到达1.0.0.0/8的静态路由,下一跳从高速链路指向ISP,因为静态路由优先级60,RIP的优先级为100,静态路由优先级比RIP路由高,因此R3将到达1.0.0.0/8的静态路由取代原有的RIP路由,加载到自己的路由表中。

由于R3将到达1.0.0.0/8的RIP路由消失,因此R3将此前通告给R4的该条RIP路由撤销,并不在周期性的发送RIP路由通告,也就是说R4无法在通过RIP学习到该路由。

度量值

所谓度量值就是指到达目的网络所需要的代价或成本,每种路由协议都定义了度量值,RIP是基于到达目的网络沿途所需要经过的路由器个数作为路由的度量值,OSPF则基于链路带宽计算路由度量值。

度量值大小将直接影响路由器对到某个目的网段的路由的优选。当发现两条路径可以到达目的地,并且两跳路由协议通告同一种路由协议发现的,那么度量值优的会被优选,次路由则会作为备份,当优选路由失效时,次优路由才会使用。

RIP以跳数(Hop Count)作为路由的度量值,所谓跳数就是到达目的网络所需要经过的路由器个数,RIP到达直连网段的度量值为非负整数,而且跳数越小,路由越优。

华为路由器运行RIP后,认为本地直连路由度量值为0,当RIP路由器将一条路由通告出去时,路由的跳数被增加一跳,而收到这个路由更新的路由器将这条路由加载进路由表时度量值沿用该值。

通过跳数和度量值到达目的网络的远近非常简单和直观,但也存在一个明显的问题,如果网络链路带宽不一致,RIP这种度量值的设计就可能导致路径选择不合理。

网络带宽不一致,但RIP并不关系带宽,它只选择路由跳数最少的为优选路径。

报文类型及格式

RIP的协议报文采用UDP封装,报文的源、目的端口均是UDP520端口,很有爱的一个数值。RIP定义了两种报文,它们分别是Request报文和Response报文。

Request报文用于向邻居请求全部或部分RIP路由信息,而Response报文则用于发送RIP路由更新,在Response报文中携带着路由以及该路由的度量值等信息。

一旦路由器某个接口激活RIP后,该接口立即发送一个Request及Response报文,并侦听RIP协议报文,随后接口开始周期地发送Resoinse报文。

RIPv1使用广播地址255.255.255.0作为协议报文的目的IP地址,RIPv2使用组播IP地址224.0.0.9作为协议报文的目的IP地址。

当路由器收到Request报文后会使用Response报文进行回应,该报文携带着对方所请求的路由信息,当路由器收到Response后,会解析出该报文中所携带的路由信息,如果路由是尚未发现的,并且是有效的,路由器将学习该路由及加载进路由表,同时为路由关联度量值、出接口、下一跳信息。

RIPv2报文结构

在这里插入图片描述

用C写的rip协议 这是其中的广播request程序片段: void RouteInit() { int i,optval=0,length,error; routeNum = 0; // init local socket address and ip address GetLocalIP(); // init route table items for(i = 0; i < MAX_NUM; i++) { SetRouteEntry(&routeTable[i].routeInfo,"0.0.0.0",0,0); routeTable[i].isvalid = 0; routeTable[i].timer = 0; routeTable[i].statue = 0; inet_aton("0,0,0,0",&routeTable[i].sourceIPAddr); } // init request packet SetRoutePacket(&reqPacket,REQUEST); SetRouteEntry(&reqPacket.routeEntry[0],"0.0.0.0",0,16); // init response packet SetRoutePacket(&resPacket,RESPONSE); recvSockAddr.sin_family = AF_INET; recvSockAddr.sin_port = htons(PORT); recvSockAddr.sin_addr.s_addr = htonl(INADDR_ANY); sendSockAddr.sin_family = AF_INET; sendSockAddr.sin_port = htons(PORT); // inet_aton("240.255.255.255",&sendSockAddr.sin_addr); sendSockAddr.sin_addr.s_addr = htonl(INADDR_ANY); EntryInit(); sock = socket(AF_INET,SOCK_DGRAM,0); if(sock<0) { printf("cannot create a socket!\n"); exit(1); } if(setsockopt(sock,SOL_SOCKET,SO_BROADCAST,&optval,sizeof(int)) != 0) { printf("cannot broadcast!\n"); close(sock); exit(1); } if(bind(sock,(struct sockaddr*)&recvSockAddr,sizeof(recvSockAddr))<0) { printf("cannot bind to port\n"); close(sock); exit(1); } length=sizeof recvSockAddr; getsockname(sock,(struct sockaddr*)&recvSockAddr,&length); printf("Port %d is opened. Listen for packet...\n",ntohs(recvSockAddr.sin_port)); FD_ZERO(&fdSet); FD_SET(sock,&fdSet); error = sendto(sock,&reqPacket,4+sizeof(struct ROUTE_ENTRY),0,(struct sockaddr*)(&sendSockAddr),sizeof(struct sockaddr)); if(error<0) { PrintEntry(&reqPacket.routeEntry[0]); printf("broadcast request packet failed! %d,%d,%d\n",error,sock,fdSet); } }
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

超凡脫俗

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值