OSPF协议详解分析

OSPF 学习笔记

OSPF 协议号是89,也就是说在ip 包的protocol 中是89,用ip 包来传送

数据包格式:

在OSPF 路由协议的数据包中,其数据包头长为24 个字节,包含如下8 个字段:

* Version number-定义所采用的OSPF 路由协议的版本。

* Type-定义OSPF 数据包类型。OSPF 数据包共有五种:

* Hello-用于建立和维护相邻的两个OSPF 路由器的关系,该数据包是周期性地发送的。

* Database Description-用于描述整个数据库,该数据包仅在OSPF 初始化时发送。

* Link state request-用于向相邻的OSPF 路由器请求部分或全部的数据,这种数据包是在当路由器发现其数据已经过期时才发送的。

* Link state update-这是对link state 请求数据包的响应,即通常所说的LSA 数据包。

* Link state acknowledgment-是对LSA 数据包的响应。

* Packet length-定义整个数据包的长度。

* Router ID-用于描述数据包的源地址,以IP 地址来表示,32bit

* Area ID-用于区分OSPF 数据包属于的区域号,所有的OSPF 数据包都属于一个特定

的OSPF 区域。

* Checksum-校验位,用于标记数据包在传递时有无误码。

* Authentication type-定义OSPF 验证类型。

* Authentication-包含OSPF 验证信息,长为8 个字节。

FDDI 或快速以太网的Cost 为1,2M 串行链路的Cost 为48,10M 以太网的Cost 为10 等。

所有路由器会通过一种被称为刷新(Flooding)的方法来交换链路状态数据。Flooding 是指路由器将其LSA 数据包传送给所有与其相邻的OSPF 路由器,相邻路由器根据其接收到的链路状态信息更新自己的数据库,并将该链路状态信息转送给与其相邻的路由器,直至稳定的一个过程。当路由器有了一个完整的链路状态数据库时,它就准备好要创建它的路由表以便能够转发数据流。CISCO 路由器上缺省的开销度量是基于网络介质的带宽。要计算到达目的地的最低开销,链路状态型路由选择协议(比如OSPF)采用Dijkstra 算法,OSPF 路由表中最多保存6 条等开销路由条目以进行负载均衡,可以通过"maximum-paths" 进行配置。如果链路上出现fapping 翻转,就会使路由器不停的计算一个新的路由表,就可能导致路由器不能收敛。路由器要重新计算客观存它的路由表之前先等一段落时间,缺省值为5 秒。在CISCO 配置命令中"timers spf spf-delay spy-holdtime" 可以对两次连续SPF 计算之间的最短时间(缺省值10 秒)进配置。

路由器初始化时Hello 包是用224.0.0.5 广播给域内所有OSPF 路由器,选出DR 后在用224.0.0.6 和DR,BDR 建立邻接。DR 用224.0.0.5 广播给DRother LSA BDR 也是

DRother 用224.0.0.6 广播LSA 给DR 和BDR

DR 是在一个以太网段内选举出来的,如果一个路由器有多个以太网段那么将会有多个DR 选举;DR 的选择是通过OSPF 的Hello 数据包来完成的,在OSPF 路由协议初始化的过程中,会通过Hello 数据包在一个广播性网段上选出一个ID 最大的路由器作为指定

路由器DR(如果设置优先级的话那么首先看优先级,优先级为0 不参加选举)并且选出ID 次大的路由器作为备份指定路由器BDR,BDR 在DR 发生故障后能自动替代DR 的所有工作然后重新选择BDR 。当一个网段上的DR 和BDR 选择产生后,该网段上的其余所有路由器都只与DR 及BDR 建立

相邻关系。见下图

DR 的选举过程:这里可以以选举村长为例

选举的时候用Hello 包中的DR 字节来标识,开始的时候都是标识的自己,一旦选举出一个DR 来那么即使后来再有优先级更高的进来也不重新选举(因为一旦重新选举那么所有的邻接关系都要重新建立)

OSPF 启动的过程:

down

init 发送Hello(224.0.0.5)DR 字段为全零(因为还没有选出DR),单通状态,我能收到对端的Hello 报文,但对方没有收到我的报

文,怎么知道对端有没有收到我的报文呢,通过Neighbors Seen

2way 2 个OSPF 路由器从Hello 中发现互相的router id(本地路由器最大

ip,一般是loopback)建立邻接

在这个阶段已经知道谁是DR 了

exstart 预启动状态,OSPF 路由器建立主从关系(看谁的routerid 大)然后

协商一个序列号(因为ip 是不可靠的传输采用确认+超时重传

就可以)准备传送,头两个DD 报文为空,不包含LSA 的数据Router 1:

DD seq=x,I=1,M=1,MS=1

I 是第一个报文

M 是more 表示还有后续报文

MS 是表示Router 1 是Master

Router 2:

DD seq=y,I=1,M=1,MS=1

I 是第一个报文

M 是more 表示还有后续报文

MS 是表示Router 2 是Master

究竟谁是master 呢,就会选一个router id 大的作为

master

谁当了master 序列号就用谁生成的那个数,在这里应该

是Router 2 的y

exchange 和DR 开始交换数据,master 先发送lsdb 报文,此报文只是一个index(如同一本书的目录)不包含实际的路由数据,slave 也发

送报文,看谁的序列号高,序列高的数据新,相邻路由器可以根

据数据库描述数据包的序列号与自身数据库的数据作比较,若发

现接收到的数据比数据库内的数据序列号大,则相邻路由器会针

对序列号较大的数据发出请求,并用请求得到的数据来更新其链

路状态数据库。

Router 1 先发送DD 报文序列号用master 的并且MS 字段为0

RouteR2 回应报文把序列号加1 表示已经收到了刚才的DD 报文

且也包含自己的DD 报文,下一个Router 1 的DD 报文还用y+1

来表示因为slave 无权把序列号加1。如果DD 报文中的M=0

那么表示DD 报文发送结束

loading 装入状态,如果新加入的路由器的从DD 报文中看出那个是自己

需要的路由数据,则发送lsr 报文,请求发送数据,对端发送LSU

报文,此报文包含所需的全部数据。

full 收到LSU 报文后发送确认,完成充满状态。

Hello 包TTL 值是1,在以太网中每10 秒发送一次,而且不穿过路由器,通常OSPF 协

议报文的TTL 都是1(虚连接除外)link status 包flood 整个area (麦子说flood 是由区域内所有路由器接力完成)一个DD 报文可以含有很多个LSA 的头部信息从init――――loading 是路由器第一次交换信息的时候才出现,到了full 以后如果在有路由变化那么就只发送LSU

邻居状态机(灰色为可以长期存在的状态,白颜色为短暂状态)2-way 为2 个DRother 之间可以有这种状态

OSPF 五种协议报文:

LSA 类型

type 1 又被称为路由器链路信息数据包(Router Link),所有的OSPF 路由器都会产生这种数据包,用于描述路由器上联接到某一个区域的链路或是某一端口的状态信息。路由器链路信息数据包只会在某一个特定的区域内广播,而不会广播至其它的区域。在类型1 的链路数据包中,OSPF 路由器通过对数据包中某些特定数据位的设定,告诉其余的路由器自身是一个区域边界路由器或是一个AS 边界路由器。并且,类型1 的链路状态数据包在描述其所联接的链路时,会根据各链路所联接的网络类型对各链路打上链路标识,Link ID 。表一列出了常见的链路类型及链路标识。

相邻路由器的路由器标

1 用于描述点对点的网络

2 用于描述至一个广播性网络的链路DR 的端口地址

3 用于描述至非穿透网络,即stub 网络的链路stub 网络的网络号码

相邻路由器的路由器标

4 用于描述虚拟链路

链路类型3(1 对0 或者Stub 网络)的链路状态描述――link id10.0.0.0 / 网段/

data:255.0.0.0 / 掩码

type:StubNet (3) / 类型/

metric:50 /度量/

链路类型1(点对点)的链路状态描述,首先要描述一下接口的路由信息:link

id:20.0.0.0 / 网段/ data:255.0.0.0 /掩码/

type:StubNet(3) / 类型/ 此处还是3,因为ppp 类型分成2 部分,首先把它想象成一

个1:0 也就是类型3 的网络这么做是为了描述接口的路由,

20.0.0.0,第二步在描述对端连接的那台路由器

metric:5 /度量值/

对对端路由器的描述:

link id:2.2.2.2 / 对端RouterID/

data:20.0.0.2 /对端路由器的接口地址/

type:Router (1) /类型/

metric:5

对帧中继(点对多点)链路状态的描述:首先也是先描述接口网段的路由

link id:40.0.0.1 /网段/ 描述的是自己的接口地址,不是网段

data: 255.255.255.255 / 掩码/ type:StubNet(3) /类型/ 此

处还是描述成1 对0 的网段metric: 5 /度量值/

link id: 3.3.3.3 /对端routerF 的id/ 因为是连接多点的,所以有多段描述

data:40.0.0.1 /与router F 相连的接口地址/ type:Router(1) / 类型/ metric:5 /度量值/

link id:4.4.4.4 /对端routerE 的id/

data:40.0.0.1 /与router E 相连的接口地址/ 此处描述的是routerA 的接口地址,并

不是Router E 的接口地址,没关系因为

点对多点连接的接口地址都在一个子网

type:Router(1) /类型/

metric:5 /度量值/

对广播型网络链路状态的描述:不描述接口网段的路由了

link id:30.0.0.3 /网络中DR 的接口地址/ data:30.0.0.1 /本接口的地址/

type:TransNet(2) /类型/ metric:50 /花费/ 每个路由器只生成这些信息,缺少的信息有DR 补齐,这样会节省很多的描述信息,如果不是的话假如这里有100 台路由器那么得生成100 段描述信息。

DR 会单独生成一条(也就是说不管DRother 有多少条)LSA(type 2)描述掩码和这个网段中有那些路由器/DR(6.6.6.6) 生成的LSA/ Net mask:255.255.255.0 Attached 30.0.0.1 router Attached 30.0.0.2 router Attached 30.0.0.3 router

以上的这些描述信息还要加上LSA 的头(head)type:Router /LSA 的类

型/ 此处的Router 表示是LSA 类型1 ls id:1.1.1.1 /LSA 的标识/ adv

rtr: 1.1.1.1 /生成该LSA 的路由器/ 表示这条LSA 是谁生成的ls

age:4 /本条LSA 的老化时间/ 每隔1 秒这个数字会涨1 len: 108 /LSA

的长度/ seq#:80000001 /LSA 序列号/link count:7 /本LSA 中包含的

连接个数/

此时RouterA 路由器完成自己周边链路状态的描述

flood 完lsdb 后就要用spf 生成路由表了,见下图:(以Router A 为例)

首先每个路由器都已自己为根计算路由,以Router a 为例它把每一个LSA 打开,分析每一段,碰到StubNet 这种类型的LSA 就知道这是描述的一条网段路由,于是就直接加到路由表中比如上图中的10.0.0.0 和20.0.0.0 就直接加到路由表中不过这两条是本

路由器直接相连的网段所以意义不大,那么看第三段,这段描述的是一个点对点的类型,路由器看到这段就会先停止计算,它会去找RouterB 生成的LSA(因为这段描述的到router b 的点对点连接)因为每个LSA 都有router id(adv id)路由器就会以2.2.2.2 为关键字检索就会找到router b 的LSA,找到以后在打开看它有什么信息,router b 中有一个直连网段50.0.0.0 ,这个网段对于router a 是未知的,所以就加入路由表中下一跳就指向20.0.0.2( 因为此LSA 是Router b 告诉我的)Metric 值相加50+5=55,这样这条路由就完全加入到路由表中了。如果Router B 的LSA 中还连着一个Router W,那么路由器还继续去找Router W 的LSA 找到后在继续算Router w 的路由(因为是RouterB 连接的RouterW 下一跳还是RouterB,Metric 在相加)。RouterA 通过递归和回朔算完所有的LSA 的路由,所有的路由都是从每个router LSA 的StubNet 这种网络中得出路由的,因为StubNet 才是描述接口网段的路由,才是我们最终需要的路由信息,那么Type:Router 只是描述的是下一跳地址。每台路由器都有义务描述自己周边的链路状态(包括自己直连的路由器)见上图

每台路由器把周边的链路状态都发送到整个area ,这样,所有的路由器都存有一张同样的lsdb 信息,在由这个库算出来spf 路由。

当一台路由器的连接的某一个网段发生故障,那么就会产生一个LSA 在flood 到整个区域,所有的路由器都要在计算一边spf 路由,因为路由器不知道这条LSA 会影响那个路由,所以要重新把所有的lsdb 重新计算一遍,耗时并且占cpu 。

type 2 由DR 发送,指定路由器产生用于描述所处的网段的链路数据包—network link,该数据包里包含在该网段上所有的路由器,包括指定路由器本身的状态信息指定路由器DR 只有在与至少一个路由器建立相邻关系后才会产生网络链路信息数据包,在该数据包中含有对所有已经与DR 建立相邻关系的路由器的描述,包括DR 路由器本身。类型2 的链路信息只会在包含DR 所处的广播性网络的区域中广播,不会广播至其余的OSPF 路由区域。

type 3 4 类型3 和类型4 的链路状态广播在OSPF 路由协议中又称为总结链路信息数据包(Summary Link),该链路状态广播是由区域边界路由器或AS 边界路由器产生的。Summary Link 描述的是到某一个区域外部的路由信息,这一个目的地地址必须是同一个AS 中。Summary Link 也只会在某一个特定的区域内广播。类型3 与类型4 两种总结性链路信息的区别在于,类型3 是由区域边界路由器产生的,用于描述到同一个AS 中不同区域之间的链路状态;而类型4 是由AS 边界路由器产生的,用于描述不同AS 的链路状态信息。

Type 3 类型的特点是每一条type 3 的LSA 都对应一条路由

值得一提的是,只有类型3 的Summary Link 才能广播进一个残域,因为在一个残域中不允许存在AS 边界路由器。残域的区域边界路由器产生一条默认的Summary Link 对域内广播,从而在其余路由器上产生一条默认路由信息。采用Summary Link 可以减小残域中路由器的链路状态数据库的大小,进而减少对路由器资源的利用,提高路由器的运算速度。

abr 会把各端口所属的各个区域的LSA type 1 阻断,如:type:Router(1)的LSA

那上图中area3 如何知道area 0 中的路由呢,abr 会把area 0 中所有的路由信息,比如有100 条路由,会以100 条type 3 类型的LSA 发送到area 3 中并且下一跳是abr 本身。这样可以减少LSA 的容量,如果area 0 中有一条路由down 了,那么在area3 中直接可以把这条路由删掉就可以了,不用像以前那样重新计算

在区域间的路由器上不再描述链路状态而是采用dv 算法

type 5 类型5 的链路状态广播称为AS 外部链路状态信息数据包。类型5 的链路数据包是由AS 边界路由器产生的,用于描述到AS 外的目的地的路由信息,该数据包会在AS 中除残域以外的所有区域中广播。一般来说,这种链路状态信息描述的是到AS 外部某一特定网络的路由信息,在这种情况下,类型5 的链路状态数据包的链路标识采用的是目的地网络的IP 地址;在某些情况下,AS 边界路由器可以对AS 内部广播默认路由信息,在这时,类型5 的链路广播数据包的链路标识采用的是默认网络号码0.0.0.0 。External 外部路由又分成了External 1 和2 两种情况

1:把外部进来的路由传进来cost 在area 中要叠加的(一般情况)

2:进来的时候cost 是多少那么就一直是多少,不管经过多少路由器(负载均衡时用)

type 4 类型只是描述如何到达asbr,见上图网段写的是asbr 的router id ,下一跳指向abr 为什么不把它当成type 3 那样处理呢?直接生成type 3 的路由信息因为是避免自环,因为外部路由是不可靠的,所以第五类的路由的优先级不一样,这些路由在路由表中标识出ase,优先级很低

各LSA 都有有它自己的老化计时器,承载在LS 寿命域内。缺省值为30 分钟

LSA 的分类

区域的类型:1:backbone 骨干域

每一个区域都有着该区域独立的网络拓扑数据库及网络拓扑图。对于每一个区域,其网络拓扑结构在区域外是不可见的,同样,在每一个区域中的路由器对其域外的其余网络结构也不了解。这意味着OSPF 路由域中的网络链路状态数据广播被区域的边界挡住了,这样做有利于减少网络中链路状态数据包在全网范围内的广播,也是OSPF 将其路由域或一个AS 划分成很多个区域的重要原因。

骨干域传播域间路由

在OSPF 路由协议中存在一个骨干区域(Backbone),该区域包括属于这个区域的网络及相应的路由器,骨干区域必须是连续的,同时也要求其余区域必须与骨干区域直接相连。骨干区域一般为区域0,其主要工作是在其余区域间传递路由信息。所有的区域,包括骨干区域之间的网络结构情况是互不可见的,当一个区域的路由信息对外广播时,其路由信息是先传递至区域0(骨干区域),再由区域0 将该路由信息向其余区域作广播(见上图)

如果骨干网不连续要设置虚链路解决(见下图)

相关主题
相关文档
最新文档