OSPF协议原理OSPF是OpenShortestPathFirst(即“开放最短路由优先协议”)的缩写。它是IETF(InternetEngineeringTaskForce)组织开发的一个基于链路状态的自治系统内部路由协议。在IP网络上,它通过收集和传递自治系统的链路状态来动态地发现并传播路由。当前OSPF协议使用的是第二版,最新的RFC是2328。OSPF协议具有如下特点:适应范围:OSPF支持各种规模的网络,最多可支持几百台路由器。快速收敛:如果网络的拓扑结构发生变化,OSPF立即发送更新报文,使这一变化在自治系统中同步。无自环:由于OSPF通过收集到的链路状态用最短路径树算法计算路由,故从算法本身保证了不会生成自环路由。子网掩码:由于OSPF在描述路由时携带网段的掩码信息,所以OSPF协议不受自然掩码的限制,对VLSM提供很好的支持。区域划分:OSPF协议允许自治系统的网络被划分成区域来管理,区域间传送的路由信息被进一步抽象,从而减少了占用网络的带宽。等值路由:OSPF支持到同一目的地址的多条等值路由。路由分级:OSPF使用4类不同的路由,按优先顺序来说分别是:区域内路由、区域间路由、第一类外部路由、第二类外部路由。支持验证:它支持基于接口的报文验证以保证路由计算的安全性。组播发送:OSPF在有组播发送能力的链路层上以组播地址发送协议报文,即达到了广播的作用,又最大程度的减少了对其他网络设备的干扰。1.2OSPF基本概念1.RouterIDOSPF协议使用一个被称为RouterID的32位无符号整数来唯一标识一台路由器。基于这个目的,每一台运行OSPF的路由器都需要一个RouterID。这个RouterID一般需要手工配置,一般将其配置为该路由器的某个接口的IP地址。由于IP地址是唯一的,所以这样就很容易保证RouterID的唯一性。在没有手工配置RouterID的情况下,一些厂家的路由器(包括Quidway系列)支持自动从当前所有接口的IP地址自动选举一个IP地址作为RouterID。2.协议号OSPF协议用IP报文直接封装协议报文,协议号是89。1.3链路状态OSPF协议计算路由是以本路由器周边网络的拓扑结构为基础的。每台路由器将自己周边的网络拓扑描述出来,传递给其他所有的路由器。OSPF将不同的网络拓扑抽象为以下四种类型:?该接口所连的网段中只有本路由器自己。(stubnetworks)?该接口通过点到点的网络与一台路由器相连。(point-to-point)?该接口通过广播或NBMA的网络与多台路由器相连。(broadcastorNBMAnetworks)?该接口通过点到多点的网络与多台路由器相连。(point-to-multipoint)NBMA与点到多点的区别:在OSPF协议中NBMA和点到多点都是指非广播多点可达的网络,但NBMA网络必须满足全连通(fullmeshed)的要求,即任意两点都可以不经转发而使报文直达对端。否则,我们称该网络是点到多点网络。如上图所示:RTA作为网络中的一台路由器,其周围的链路状态情况可归纳为以下四种:?通过PPP协议与另一台路由器RTB直接相连;?通过一个X.25网络与RTC和RTD相连(该网络是全连通的);?通过一个FrameRelay网络与RTE和RTF相连(该网络不是全连通的,RTE与RTF不直接相连);?直接连接着一个局域网。1.4计算路由上图中描述了通过OSPF协议计算路由的过程。(1)由四台路由器组成的网络,连线旁边的数字表示从一台路由器到另一台路由器所需要的花费。为简化问题,我们假定两台路由器相互之间发送报文所需花费是相同的。(2)每台路由器都根据自己周围的网络拓扑结构生成一条LSA(链路状态广播),并通过相互之间发送协议报文将这条LSA发送给网络中其它的所有路由器。这样每台路由器都收到了其它路由器的LSA,所有的LSA放在一起称作LSDB(链路状态数据库)。显然,4台路由器的LSDB都是相同的。(3)由于一条LSA是对一台路由器周围网络拓扑结构的描述,那么LSDB则是对整个网络的拓扑结构的描述。路由器很容易将LSDB转换成一张带权的有向图,这张图便是对整个网络拓扑结构的真实反映。显然,4台路由器得到的是一张完全相同的图。(4)接下来每台路由器在图中以自己为根节点,使用SPF算法计算出一棵最短路径树,由这棵树得到了到网络中各个节点的路由表。显然,4台路由器各自得到的路由表是不同的。这样每台路由器都计算出了到其它路由器的路由。由上面的分析可知:OSPF协议计算出路由主要有以下三个主要步骤:?描述本路由器周边的网络拓扑结构,并生成LSA。?将自己生成的LSA在自治系统中传播。并同时收集所有的其他路由器生成的LSA。?根据收集的所有的LSA计算路由。1.5OSPF的协议报文OSPF的报文类型一共有五种:HELLO报文(HelloPacket):最常用的一种报文,周期性的发送给本路由器的邻居。内容包括一些定时器的数值,DR,BDR,以及自己已知的邻居。DD报文(DatabaseDescriptionPacket):两台路由器进行数据库同步时,用DD报文来描述自己的LSDB,内容包括LSDB中每一条LSA的摘要(摘要是指LSA的HEAD,通过该HEAD可以唯一标识一条LSA)。这样做是为了减少路由器之间传递信息的量,因为LSA的HEAD只占一条LSA的整个数据量的一小部分,根据HEAD,对端路由器就可以判断出是否已经有了这条LSA。LSR报文(LinkStateRequestPacket):两台路由器互相交换过DD报文之后,知道对端的路由器有哪些LSA是本地的LSDB所缺少的或是对端更新的LSA,这时需要发送LSR报文向对方请求所需的LSA。内容包括所需要的LSA的摘要。LSU报文(LinkStateUpdatePacket):用来向对端路由器发送所需要的LSA,内容是多条LSA(全部内容)的集合。LSAck报文(LinkStateAcknowledgmentPacket)用来对接收到的LSU报文进行确认。内容是需要确认的LSA的HEAD(一个报文可对多个LSA进行确认)。1.6OSPF的邻居状态机Down:邻居状态机的初始状态,是指在过去的Dead-Interval时间内没有收到对方的Hello报文。Attempt:只适用于NBMA类型的接口,处于本状态时,定期向那些手工配置的邻居发送HELLO报文。Init:本状态表示已经收到了邻居的HELLO报文,但是该报文中列出的邻居中没有包含我的RouterID(对方并没有收到我发的HELLO报文)。2-Way:本状态表示双方互相收到了对端发送的HELLO报文,建立了邻居关系。在广播和NBMA类型的网络中,两个接口状态是DROther的路由器之间将停留在此状态。其他情况状态机将继续转入高级状态。ExStart:在此状态下,路由器和它的邻居之间通过互相交换DD报文(该报文并不包含实际的内容,只包含一些标志位)来决定发送时的主/从关系。建立主/从关系主要是为了保证在后续的DD报文交换中能够有序的发送。Exchange:路由器将本地的LSDB用DD报文来描述,并发给邻居。Loading:路由器发送LSR报文向邻居请求对方的DD报文。Full:在此状态下,邻居路由器的LSDB中所有的LSA本路由器全都有了。即,本路由器和邻居建立了邻接(adjacency)状态。注意:1.灰色的状态是指稳定的状态,其他状态则是在转换过程中瞬间(一般不会超过几分钟)存在的状态。2.本路由器和状态可能与对端路由器的状态不相同。例如本路由器的邻居状态是Full,对端的邻居状态可能是Loading。1.7链路状态数据库的同步过程上图显示了两台路由器之间如何通过发送5种协议报文来建立邻接关系,以及邻居状态机的迁移。1.RT1的一个连接到广播类型网络的接口上激活了OSPF协议,并发送了一个HELLO报文(使用组播地址224.0.0.5)。由于此时RT1在该网段中还未发现任何邻居,所以HELLO报文中的Neighbor字段为空。2.RT2收到RT1发送的HELLO报文后,为RT1创建一个邻居的数据结构。RT2发送一个HELLO报文回应RT1,并且在报文中的Neighbor字段中填入RT1的Routerid,表示已收到RT1的HELLO报文,并且将RT1的邻居状态机置为Init。3.RT1收到RT2回应的HELLO报文后,为RT2创建一个邻居的数据结构,并将邻居状态机置为Exstart状态。下一步双方开始发送各自的链路状态数据库。为了提高发送的效率,双方需先了解一下对端数据库中那些LSA是自己所需要的(如果某一条LSA自己已经有了,就不再需要请求了)。方法是先发送DD报文,DD报文中包含了对本地数据库中LSA的摘要描述(每一条摘要可以惟一标识一条LSA,但所占的空间要少得多)。由于OSPF直接用IP报文来封装自己的协议报文,所以在传输的过程中必须考虑到报文传输的可靠性。为了做到这一点,在DD报文的发送过程中需要确定双方的主从关系。作为Master的一方定义一个序列号seq,每发送一个新的DD报文将seq加一。作为Slave的一方,每次发送DD报文时使用接收到的上一个Master的DD报文中的seq。实际上这种序列号机制是一种隐含的确认方法。如果再加上每个报文都有超时重传,就可以保证这种传输是可靠的。RT1首先发送一个DD报文,宣称自己是Master(MS=1),并规定序列号为x。I=1表示这是第一个DD报文,报文中并不包含LSA的摘要,只是为了协商主从关系。M=1说明这不是最后一个报文。4.RT2在收到RT1的DD报文后,将RT1的邻居状态机改为Exstart,并且回应了一个DD报文(该报文中同样不包含LSA的摘要信息)。由于RT2的RouterID较大,所以在报文中RT2认为自己是Master,并且重新规定了序列号为y。5.RT1收到报文后,同意了RT2为Master,并将RT2的邻居状态机改为Exchange。RT1使用RT2的序列号y来发送新的DD报文,该报文开始正式地传送LSA的摘要。在报文中RT1将MS=0,说明自己是Slave。6.RT2收到报文后,将RT1的邻居状态机改为Exchange,并发送新的DD报文来描述自己的LSA摘要,需要注意的是:此时RT2已将报文的序列号改为y+1了。7.上述过程持续进行,RT1通过重复RT2的序列号来确认已收到RT2的报文。RT2通过将序列号+1来确认已收到RT1的报文。当RT2发送最后一个DD报文时,将报文中的M=0,表示这是最后一个DD报文了。8.RT1收到最后一个DD报文后,发现RT2的数据库中有许多LSA是自己没有的,将邻居状态机改为Loading状态。此时RT2也收到了RT1的最后一个DD报文,但RT1的LSA,RT2都已经有了,不需要再请求,所以直接将RT1的邻居状态机改为Full状态。9.RT1发送LSRequest报文向RT2请求所需要的LSA。RT2用LSUpdate报文来回应RT1的请求。RT1收到之后,需要发送LSAck报文来确认。上述过程持续到RT1中的LSA与RT2的LSA完全同步为止。此时RT1将RT2的邻居状态机改为Full状态。注意:以上过程是两台路由器由相互没有发现对方的存在到建立邻接关系的过程。或者可以理解为网络中新加入一台路由器时的处理情况。当两台路由器之间的状态机都已经达到Full状态之后,如果此时网络中再有路由变化时,就无须重复以上的所有步骤。只由一方发送LSUpdate报文通知需要更新的内容,另一方发送LSAck报文予以回应即可。双方的邻居状态机在此过程中不再发生变化。1.8DR和BDRDR的概念:在广播和NBMA类型的网络上,任意两台路由器之间都需要传递路由信息(flood),如果网络中有N台路由器,则需要建立N*(N-1)/2个邻接关系。任何一台路由器的路由变化,都需要在网段中进行N*(N-1)/2次的传递。这是没有必要的,也浪费了宝贵的带宽资源。为了解