13、ospf
OSPF
OSPF(Open Shortest Path First,开放最短路径优先,RFC2328)是一个被各厂商设备广泛支持的链路状态路由协议,也是现网中采用最多的路由协议,OSPF协议出现的原因是因为RIP协议限制比较多,在可扩展性方面以及协议性能上已经不适应网络发展现状的需要,例如最大跳数为15跳,大规模网络中的跳数超过了RIP所规定的15跳,而超过15跳在RIP中就表示不可达,所以RIP注定被淘汰。OSPF目前共有两个版本,为IPV4使用的OSPF V2以及为IPV6使用的OSPF V3。
OSPF采用SPF算法,不会产生环路;支持VLSM和CIDR;可以用于大型网络;采用层次化设计,容易扩展;区域化设计,减小路由更新给设备带来的负担;路由快速收敛,采用触发式更新;支持针对区域和链路的验证。执行OSPF的路由默认每隔30分钟会泛洪一次链路状态通告(LSA),成为链路状态刷新(并非周期性更新);当一条LSA被接收并存储到链路状态数据库后,路由器会给这条记录增加一个老化时间标识,默认是一小时,所以为了防止一些正常的LSA被清除,这条LSA的路由会每隔30分钟泛洪一次这条LSA的一个新拷贝。
OSPF路由协议的管理距离为110,使用IP协议号89,采用COST作为度量标准(Metric),OSPF维护邻居表、拓扑表和路由表三张表项;OSPF的消息有Hello,DBD(Database Description),LSR(Link State Request),LSU(Link State Update),LSAck(Link State Acknowledge);OSPF的网络类型有广播多路访问(BMA,Broadcast Multi Access),非广播多路访问(NBMA,None Broadcast Multi Access)。
SPF算法要求同一个OSPF区域中的每个路由器都有一致的LSDB,一个OSPF区域的每个路由器都以自己位根计算最短路径,到达每个目的地的最小Cost的路径最优,将最优的路径放入FIB中。
协议工作流程
链路状态路由协议有点像你用导航去迪士尼乐园,导航软件从一开始就知道整个上海的地图以及从你所在的地点到迪士尼乐园有哪些可能存在的路线,然后对这些潜在的路线进行比较,看看哪条路线拥堵哪条路径通畅,最后选择出一条最优的路线告诉你应该怎么走。
- 首先向激活OSPF的接口发送Hello包,比较Hello包中的几个字段(Area ID,Hello Interval,Router Dead Interval、Authentication Type、Authentication),参数匹配后将对端放入自己的第一张表——邻居表(Neighbor Table,用show ip ospf neighbor命令查看)
- 第二步向邻居(Neighbor)发送本路由器的OSPF数据库(LSDB,Link-State DataBase)中所拥有的LSA,从各个邻居收来的LSA放入自己的第二张表——拓扑表(Topology Table)也叫Database数据库,使用show ip ospf database查看。
- 第三步运行SPF算法,以自己为根计算出一棵最短路径树,这棵树有两个特点,一是最短,二是无环,最后将计算出来的最优路径放入第三张表,路由表(OSPF Routing Table,用show ip route ospf查看)
最短路径树
“以自己为根计算出一棵最短路径树”这句话有点难理解,来把这句话拆成两部分分别解释,先看前半句,什么叫“以自己为根”呢?例如在现网中有一个拓扑,假设在咱们的角度来看是按下面的形式连接的:
但在OSPF中,当各个路由器构建以自己为根的最短路径树时,和现网中的拓扑不同,每个路由器不是以物理连接形式来构建的,而是以逻辑连接方式看这个连接形式的,具体倒OSPF中就是以“根”(也就是每个路由器自己)为出发点构建的,都会假设自己这个路由器就是拓扑的核心或中心,所以每个路由器视角中的路径树分别如下:
后半句的“一棵最短路径树”这个最短路径树中的“树”,指的其实是一种数据结构,这种树状的数据结构有一个根以及去往其他节点的分支,该分支也会有其他分支,大概看上去类似下图:
LSA的泛洪
运行OSPF的路由器之间首先会建立一个协议的邻居关系。路由器之间交互的是LSA,Link State Advertisement,而不是路由,与网络或其他路由器连接的每条链路都用LSA表示,LSA可以简单的理解为,每台路由器都产生一个描述自己直连接口状态(包括接口的开销、与邻居之间的关系等)的通告。收到LSA以后首先看该条LSA是否在本地的LSDB链路状态数据库中(通过LSA ID、Advertising Router ID、Sequence number、Age这几个字段检查自己的LSDB链路状态数据库中是否有相同的LSA,避免重复将一条LSA加入LSDB链路状态数据库中),如果不存在的话先将该LSA加入本地LSDB(链路状态数据库),然后泛洪LSA给邻居路由器(因为SPF算法要求同一个OSPF区域中的每个路由器都有一致的LSDB,该LSA我这台路由器没有,可能其他路由器也没有,所以要发送给其他路由器,使得OSPF域中的所有路由器的LSDB数据库尽快一致)。如果本地LSDB动态链路数据库中存在该LSA的话要比较LSA的序列号,如果序列号相同则收到的LSA将被丢弃,因为本地已经有了相同的LSA,不需要再将其加入LSDB中;在序列号不同时,如果本地LSDB的序列号旧,则用较新的LSA替换本地的旧LSA,发给邻居LSAck表示收到了该LSU更新;如果本地LSA比收到的LSA新,则将本地的LSA泛洪给邻居。
LSDB的组建
经过了上面的LSA交互过程,路由器之间会彼此交互完所有LSA并利用LSA去构建LSDB,也就是链路状态数据库,构建了LSDB后路由器就清楚了全网的拓扑,因为LSDB中所存储的每条LSA都是由网络中各个路由器产生并且描述其直连接口的各项信息的条目,知道了这些接口的连接情况就可以根据LSDB“画出”全网络的拓扑。
SPF计算
接下去,每台路由器基于LSDB,使用SPF(Shortest Path First,最短路径优先)算法,每个设备独立计算出一棵以自己为跟的、无环的、拥有最短路径的“树”,有了这棵树,事实上路由器就已经知道了到达网络各个角落的最优路径。
维护路由表
最后,路由器将计算出来的最优路径,加载进自己的路由表。如果网络拓扑发生变化,路由器之间的LSDB链路状态数据库相互之间就不会完全一样,要重复上面的LSA交互过程。例如R4的某个接口down掉,那么R4的LSDB和其他域内的路由器不相同,会通过LSA知道;如果R4整个路由器down掉,那么其他路由器会通过hello包知道R4已经down掉,因为运行OSPF的路由器每过一段时间(Hello interval,不同网络类型的该数值不同,常见的以太网是MA类型,hello时间为10秒也就是每过10秒发送一次hello包查看邻居是否还正常工作)发送一个hello包查看邻居是否还正常工作,如果该邻居没有在规定时间内回复hello包超过了规定时间(Dead interval,默认为4倍Hello interval时间,以太网中是40秒)那么说明该邻居已经挂掉,必须重新同步本区域Area内的LSDB链路动态数据库。
当然上面这一段的讨论只限于OSPF协议中,实际中如果一条链路物理上挂掉,那么如果等Dead interval的40秒才知道邻居挂了,才开始反映显然是有点慢了,OSPF协议会通过IOS系统交互的信息了解到一条链路的状态从UP变为了DOWN。
基础概念
自治系统(AS)
自治系统(Autonomous system),采用同一种路由协议交换信息的路由器及其网络构成一个自治系统。具体到OSPF协议中,简单来说就是所有运行OSPF的路由器所组成的网络是同一自治系统。
内部网关协议(IGP)
内部网关协议,IGP,Interior Gateway Protocol,常见的OSPF、EIGRP、RIP这种都叫内部网关协议,每个自治系统(AS)都有一个IGP。 单独的自治系统(AS)可能会使用不同的IGP。与内部网关协议相对应的有外部网关协议(Exterior Gateway Protocol),与内部网关协议不同,外部网关协议其着眼点不在于发现和计算路由,而在于控制路由的传播和选择最佳路由。外部网关协议目前只有BGP这一种。
链路(Link)
相当于一个接口加入OSPF进程,就被当做是OSPF的一条链路。
链路状态(Link-State)
包括接口的IP、子网、网络类型、链路话费、链路上的邻居等。
链路状态通告(LSA)
链路状态通告(LSA)是OSPF协议的一种基本通信手段,它将路由器的本地拓扑发送给同区域(Area)的其他路由器,待所有路由器的LSA彼此交换完毕后,所有路由器就能知道整个OSPF网络的连接情况,可以进行路由计算。OSPF协议设计之初考虑了可扩展性,所以有些LSA不会在所有接口上泛洪而是只在相应区域的接口上泛洪。LSA用来描述路由器的本地状态,LSA包括的信息有路由器接口的状态和所形成的邻接状态。
泛洪
在OSPF路由器之间发布并同步LSDB链路动态数据库的过程,叫做泛洪,由于LSA构成了LSDB,也可以将泛洪理解为路由器之间同步LSA。
路由器ID(Router ID,简称RID)
RID是一个用来标识路由器的IP地址,长度为32位,在AS中唯一地标识一台路由器,不能和其他路由器的Router ID重复,可以在OSPF路由进程中手工指定,如果没有指定,路由器默认选择环回接口(Loopback接口)中最高的IP作为RID;如果没有环回地址,路由器使用所有激活的物理接口中最高的IP作为RID。
邻居路由器(Neighbor routers)
Two routers that have interfaces to a common network.Neighbor relationships are maintained by, and usually dynamically discovered by, OSPF’s Hello Protocol.
——RFC 2328 Page 10
In short, two OSPF routers are neighbors if they are connected to the same subnet and share a series of common configuration information:
- Same Area ID
- Same Area type
- Same subnet mask
- Same timers
- Same authentication
- They see their own OSPF RID in each other’s Hello packet
In essence, OSPF neighborhood is a relation of two routers that allows them to see and understand each other but nothing more. In particular, two OSPF neighbors do not exchange any routing information - the only packets they exchange is Hello packets.
——出处
OSPF的邻居(Neighbor)指的是两台运行OSPF协议的路由器彼此将对方置于2WAY状态,但2WAY状态只是知道还有个也运行OSPF切基本参数相匹配的路由器存在,并不交换任何的路由信息。从另一个角度来说,两台路由器如果允许彼此看到并且明白对方的信息,那么就可以说这两台路由器是OSPF邻居关系。
邻接关系
简单来说就是到达了FULL状态的两台路由器之间的状态,如果想具体研究可以参考上面提到的帖子及这篇文章。
邻居VS邻接
是邻居关系不一定是邻接关系,但是邻接一定是已经建立起了邻居关系。因为邻居关系处在2WAY状态,而必须经过2WAY到达FULL以后才能叫邻接关系。说实话感觉二者的区别有点太咬文嚼字了,直接说2WAY和FULL不完了嘛,更精确,还整个neighbor和adjacency,用两个概念很相近容易混淆的词来概括。
区域(Area)
OSPF通过划分区域来实现分层设计,跨越两个或两个以上区域的路由被称作ABR(Area Border Router,区域边界路由)。所有的区域都和“Area 0”相连,“Area 0”被称作骨干区域(Backbone),骨干区域路由器具有整个自治系统用中所有路由条目,LSA的扩散进限制在本区域内,可以通过划分多个区域以减小LSA扩散过程中对硬件的负担。作为骨干区域的Area 0的存在是为了快速高效的传输数据包,通常不接用户,主要负责多个常规区域的流量传输。Area 0 之外的区域叫做Regular area普通区域或nonbackbone area非骨干区域,主要为了连接用户,且所有数据交互都要通过Area 0中转,所以常规区域必须和骨干区域连接。一般一个区域内的路由器数量是30-200台。
这种层次设计的好处有:
- 减少了路由表的条目。
- LSA的泛洪在网络边界停止,能加速汇聚速度。
- 缩小网络的不稳定性,一个区域的问题不会影响到其他区域。
单区域
单区域就是所有路由器都在同一个Area中,如果一个区域内的路由器过多,那么一旦出现变化,需要同步的LSA会非常多,LSA的泛洪会很严重,泛洪完LSA后还要重新用SPF算法根据庞大的LSDB进行复杂的计算,这样的话OSPF路由器的负担会很大,因为OSPF要求区域内的所有路由器的LSDB相同,以计算出一个统一的无环的拓扑。同时单区域内的路由器过多会导致LSDB庞大,资源消耗过多,设备性能下降,影响数据转发。一般情况下,思科建议一个Area内的路由器不超过50台。
多区域
在部署OSPF时,可以采用多区域的方式部署,有且只能有一个Area 0,Area 0为骨干区域,骨干区域负责在非骨干区域之间发布由区域边界路由器汇总的路由信息,为避免区域间路由环路,非骨干区域之间不允许直接相互发布区域间路由,因此所有区域边界路由器都至少有一个接口属于Area 0,即每隔区域都必须连接到骨干区域。
网络类型
概述
OSPF是一个“接口敏感”的协议,这句话非常值得细细品味,比如路由的Cost值实际上应累加上接口的cost值,下面的DR\BDR选举也是基于接口的,另外邻居的建立也是与接口有关,因此很多机制的着眼点都与接口有关。一旦我们在某个接口上激活了OSPF协议,那么这个接口将会根据接口的二层,也就是数据链路层的封装捆绑对应的的OSPF网络类型,不同的OSPF接口的网络类型所对应的操作有所不同用。例如如果接口二层封装为以太网,那么OSPF在这个接口的网络类型为Broadcast也就是广播,如果接口的二层封装是HDLC或PPP,那么OSPF的网络类型则是P2P。OSPF定义了以下几种网络类型:
- 点到点,Point-to-Point,P2P
- 广播,Broadcast Multi access
- 非广播,Non-Broadcast,非广播中又有5种模式,分别是NBMA(non-broadcast multiple access network,RFC规定),P2MP(Point-to-Multipoint,RFC规定),P2MP nonbroadcas(Cisco),Broadcast(Cisco),P2P(Cisco)。
常见的数据链路层协议对应的默认网络类型:
在接口上使用命令show ip ospf interface X可以查看到接口的网络类型:
点到点(P2P)
- 如果二层的协议为PPP、HDLC等,则OSPF的网络类型为P2P
- 如果帧中继子接口类型为P2P的,则OSPF网络类型也为P2P
- 不用选举BDR\DR
- 使用组播地址224.0.0.5
- OSPF能够根据二层封装自动检测到P2P网络类型
多路访问(MA)
A multi access network is a network which can have multiple (more than 2) machines participating in the network. A point to point network can have only 2 and a multi access network can have more than 2. The most common example of a multi access network is Ethernet (and FastEthernet etc).
多路访问网络是有多个(超过两个)设备参与通信的网络。点对点(P2P)网络有且只有2个设备,多路访问网络可以有超过2个设备。最典型的多路访问网络就是日常生活中最常见的以太网,Ethernet。OSPF在点到点网络上是不选取DR的,正常情况下,DR只在多路访问时选取。在多路访问类型网络中,所有路由器均与DR及BDR建立邻接关系,其他路由器(DR Other)之间处于2WAY状态。DR和BDR之间使用224.0.0.5的组播地址交换信息,其他路由器(DR Other)使用224.0.0.6和DR\BDR交换信息。
多路访问网络有两种类型:广播型多路访问网络(BMA)及非广播型多路访问网络(NBMA)。以太网是一种典型的广播型多路访问网络。在OSPF中使用show ip ospf interface查看接口类型。
指定路由器(DR)
在广播多路访问网络中(Multi access)中,例如以太网接口,所有的路由器都是相同网段,处于同一个广播网络中,这些接口如果两两建立起OSPF邻接(Adjacency)关系,这就意味着,网络有:N(N-1)/2 这么多个邻接(Adjacency)关系,维护如此多的邻接关系不仅仅额外消耗设备硬件资源,更是增加了网络中LSA的泛洪数量,占用网络资源。所以为了减小多路访问网络中的OSPF流量和硬件消耗,OSPF会在每一个MA网络中选举出一个指定路由器和备用指定路由器,也就是DR和BDR。DR及BDR的身份是基于OSPF接口的,所以如果我们说“这台路由器是DR”的话,实际上这种说法是不严谨的,因为DR是接口的属性而不是路由器的属性,严格的说应该是“这台路由器的这个接口,在这个MA网络上是DR”。每台路由器都把拓扑变化发给DR和BDR,然后由DR通知多路访问网络中的其他路由器。在OSPF网络中,既不是DR也不是BDR的接口,它的角色是DR Other。
如上图中的四台路由器,R1、R2、R3、R4,运行OSPF协议且已经建立起了邻居且选举完DR\BDR,R1的接口为DR,R3的接口为BDR,R2和R4的接口为DR Other,此时,这四台设备并不是相互之间两两交互LSA,而是R2、R3、R4分别和R1交换LSA,然后由R1将其他路由器没有的LSA传送给它们。DR Other 只于DR和BDR建立完全邻接关系,其它路由器处于two-way状态。有了DR以后,MA网络中需要维护的OSPF邻接关系大幅减小,M=(n-2)X 2 +1,LSA的泛洪问题也能得到一定缓解:
假设网络已经完成了OSPF收敛,现在突然R3下挂的一个网络发生了故障,路由器R3使用224.0.0.6将这个情况通知DR及BDR,DR\BDR监听224.0.0.6获得这个情况,DR向组播地址224.0.0.5发送更新通知其他路由器,所有的OSPF路由器监听224.0.0.5这一组播地址获知携带LSA更新的LSU,更新自己的LSDB并发送LSAck确认收到该信息,经过一段时间后(SPF延迟),对更新的链路状态数据库执行SPF算法,必要时更新路由表。
之所以要选举DR是为了避免路由器之间建立完全邻接关系而引起的大量开销,OSPF要求在多路访问的网络中选举出一个DR,每个路由器都与DR建立邻接关系。选举出DR的同时也选举出一个BDR(Backup Designated Router),BDR也就是备份DR路由器,BDR在DR失效时承担起DR的职责,DR Other路由器只与DR和BDR建立邻接关系。DR和BDR通信的组播地址为224.0.0.6,DR的选举是一个路由器的接口特性而不是整个路由器的特性,也就是说,一个路由器如果有3个接口,G0/0、G0/1和G0/2,G0/0是DR,G0/1是BDR,G0/2是DR Other也是没问题的,可能在一个MA网络种存在多个DR。比如下图的R3,两个接口分别是BDR和DR Other:
DR\BDR选举
如果想了解完全版的具体过程请参见RFC,但因为我看了两遍也没搞明白所以然,故这里采用红茶三杯总结的方式加上一点自己的理解,如果哪天突然开窍了看明白了RFC再回来补上这部分的笔记。
选举的前提
- DR和BDR的选举发生在每个网段上,也就是说,如果有4个网段运行了OSPF,那么这4个网段都要选举DR和BDR,最后会选举出4个DR和4个BDR。
- 参与选举并和选举出的DR\BDR建立邻接关系需要Hello包种的参数相一致(Hello\Dead 时间,Area ID也是同一区域,认证通过,Router ID具有唯一性不与其他路由器相同)。
选举的过程
当一台OSPF路由器有效(Active)并去发现它的邻居路由器时,它将去检查有效的DR和BDR路由器(如果路由器的Priority为0那么就意味着它是无效的,不能参与选举DR和BDR),如果DR路由器存在的话(网络中某台路由器发出的Hello包中的DR字段为其自身的Router ID时就说明DR存在),这台路由器将接受已经存在的DR和BDR(为什么要接受已经存在的DR和BDR呢,是因为DR具有非抢占性的,也就是说已经有了DR了,新加入的路由器接口的Priority再低也不会重新选举DR了,如果没有非抢占性,新加入一个Priority 更大的就被选举成新的DR,所有DR Other都和这个新DR再建立邻接关系达到Full状态,太消耗系统资源,所以当一台路由器发现已经存在DR和BDR时就会接受已经存在的DR和BDR),如果BDR和DR路由器都不存在(也就是Hello包种的DR以及BDR字段都为0.0.0.0),将执行一个选举BDR的过程,没错一开始是选举BDR而不是DR,选举出具有最高优先级的路由器作为BDR路由器,选举中如果存在多台路由器具有相同的优先级(Priority),那么在数值上具有最高路由器ID的路由器将被选举成BDR(如果两台运行OSPF路由器路由器的接口的Priority都是1,那么此时一台路由器的Router-ID为1.1.1.1,另一台的Router-ID为2.2.2.2,Router-ID为2.2.2.2的显然比1.1.1.1更大,这台Router-ID为2.2.2.2的路由器的接口将被选举成BDR)。如果没有有效的DR路由器存在,那么之前选举出的BDR路由器将被选举成(或者说成提升)DR路由器,然后再选举出来BDR路由器。至此BDR和DR选举完毕。
选举的补充说明
什么情况选举BDR\DR
BDR晋升成DR
选举BDR\DR的场景中,绝大多数情况下,选举出的BDR都能顺利晋升成DR,也有极端场景比如俩OSPF路由器R1 R2在2-way刚选出BDR,另一台OSPF路由器R3接入进来发的hello里 DR是自己,这样R1 R2不知道会咋办。
已有DR\BDR
什么情况下,一个路由器会发现链路中已经有DR或BDR出现呢,常见的一种情况是,一个路由器新加入已经运行了一段时间OSPF协议的网络,常见的另一种情况是,只有两台路由器相连,R1——R2,其中一台已经先行运行了OSPF协议而且在DR选举计时器结束前没有其他OSPF的Hello包出现,这时这台路由器会把接口设定为DR。当路由器的接口运行OSPF协议时,已经启动了一个DR选举的计时器,这个计时器时4倍的Hello时间,在以太网这个MA网络中也就是和Dead时间一样的40秒,RFC上对这个计时器的描述是“A single shot timer that causes the interface to exit the Waiting state, and as a consequence select a Designated Router on the network. The length of the timer is RouterDeadInterval seconds.”,可以用命令 show ip ospf interface XX | incl timer 查看,默认的计时器是:Timer intervals configured, Hello 10, Dead 40, Wait 40, Retransmit 5。这个Wait就是DR选举的计时器。当这个计时器到时的时候,也就是OSPF启动了40秒以后依旧没其他路由器发来Hello包进行选举时,这个路由器就会把自身这个接口设置为DR,因为思科规定即使MA网络中只有一台路由器运行OSPF协议也要选举DR。
BDR\DR的抢占性
DR和BDR具有非抢占性,也就是说当DR\BDR选举完成后,新加入的路由器即使Priority再小,DR\BDR也不会发生变化,为的是维持网络的稳定性。当DR失效后,BDR会成为DR,同时产生新的BDR。DR与BDR,DR与DR Other,BDR与DR Other之间都是Full状态,DR Other相互之间是2-way状态。所有的DR Other都只和DR以及BDR建立全毗邻关系。
如何重新选举BDR\DR
由于DR选举是非抢占的,所以选举完毕后除非人工干预否则BDR\DR是不会改变的,重新选举方法有两种,一种是所有参与选举的路由器在短时间内(默认的BDR\DR选举等待的Wait计时器是40秒)重新启动;另一种是执行“clear ip ospf process”命令,如果在DR Other上执行则不会影响BDR\DR,如果在BDR上执行则会重新选举一个BDR,如果在DR上执行,则会重新执行整个BDR\DR选举过程。
其他概念
- R1、R2接口的Priority值均为0,则R1和R2之间不能建立邻居,因为在MA网络下必须选举出DR,而R1、R2相连接口的Priority值均为0,失去了选举资格,所以两者无法建立邻居。
- R1接口优先级为0,R2接口优先级为1,则R2成为DR,且该多路访问网络中没有BDR。
- 在上一步已经选出DR的基础上,R1接口优先级改为100,对网络没有影响,因为DR的非抢占性。
- 在上一步已经选出DR且R1接口优先级改为100的基础上,如果身为DR的R2重启了OSPF进程(clear IP ospf process X,X为该OSPF进程号),则R1成为DR,R2成为BDR。因为R2重启进程后会重新建立邻居重新选举DR。
- 如果R1和R2接口优先等级相同,但R2的Router ID大,一般情况下,R2应成为DR,但如果R1已经先配置了OSPF,且R2在R1配置之后40秒菜配置,那么这时候即使R2的Router-ID更大,R1已经成为了DR,原因在于Wait timer 等待计时器,这个计时器是在开始选举DR\BDR之前,路由器等待邻居路由器Hello包通告DR\BDR的时长(收集所有候选人的信息),等待计时器的长度就是Router Dead Interval的时间,因此只要R2在40秒之后才配置的,那么R1就会认为自己是DR,并且在Hello包的Designated Router部分写上自己的地址。
选举的几个为什么
为什么选举DR\BDR
之所以选举DR\BDR是因为如果运行OSPF协议的路由器两两之间建立完全邻接关系会引起大量的开销,消耗大量资源,OSPF采取了每个DR Other路由器和DR以及BDR建立邻接关系的方法,来减少资源消耗。
为什么除了DR也要有BDR
之所以除了选举DR以外还要选举出一个BDR是因为,DR Other要和DR以及BDR形成邻接关系,然后DR和BDR这两者也要形成邻接关系,如果DR由于某种情况挂掉,那么BDR就能接替DR的位置,因为所有DR Other和BDR也形成了邻接关系,DR掌握的关于网络的信息和BDR是一样的,所以BDR可以顺利完美接替DR,这样可以把DR挂掉对网络的影响降到最低。
为什么先选举BDR
之所以先选举BDR再选举DR是因为:”The reason behind the election algorithm’s complexity is the desire for an orderly transition from Backup Designated Router to Designated Router, when the current Designated Router fails. This orderly transition is ensured through the introduction of hysteresis: no new Backup Designated Router can be chosen until the old Backup accepts its new Designated Router responsibilities.”——RFC 2328 - OSPF Version 2,section 9.4 - Electing the Designated Router。先选取BDR的原因是,当DR发生故障挂掉时,需要BDR来接替DR的位置和作用,如果先选举DR,则可能会在BDR接替之前挂掉的DR前,选举出一个不是之前BDR的新DR,这个新DR还得重新从224.0.0.6上学习信息才能执行DR的角色,重新学习信息可能使得网络无法顺利转发数据。而先选举BDR则不会出现上面的问题,DR掌握的网络信息BDR都掌握,BDR可以不经过信息交互直接接替DR的功能,待BDR完美接替挂掉的旧DR的功能成为新DR后,空出来BDR的角色以后再选取BDR,不会对网络有影响。
选举的优化
由于所有DR Other要与DR\BDR交互LSA信息,会消耗一定系统资源,所以建议在接口上灵活使用ip ospf priority 避免一个路由器的多个接口成为DR,降低硬件开销,减小网络变化时产生的影响。因为如果不在接口上进行灵活配置,选举过程是先看Priority再看Router ID,默认情况下所有接口的Priority都为1,此时Router ID为最大的路由器上的所有接口都将为DR,不仅会使得路由器开销变大,也会使得万一Router ID最大的路由器一旦挂掉,会对网络造成比较大的影响,因为各网段都要重新选举BDR\DR。
组播地址
All OSPF routers continue to multicast HELLOS to 224.0.0.5, so they can keep track of their neighbors.
DROTHERs will send multicast updates to 224.0.0.6 (DR/BDR listen). DR will flood multicast updates to DROthers on 224.0.0.5.
DR and BDR can listen 224.0.0.5 not only to 244.0.0.6. DR Other listen 224.0.0.5 but not 224.0.0.6.
Summary:
* All OSPF enabled routers listen to/send LSA’s on multicast address 224.0.0.5
* DR/BDR listens on multicast-address 224.0.0.6 in addition to 224.0.0.5. This allows DR/BDR in a particular segment to figure out status updates.
OSPF通过发送Hello包到组播地址224.0.0.5来建立邻居,所以只要是运行了OSPF协议的路由器,不管是DR 、BDR还是DR Other都会监听这个地址用来建立邻居。DR Other使用224.0.0.6的组播地址,将LSU发送给DR和BDR,所以DR和BDR会监听224.0.0.6的组播地址。DR使用224.0.0.5的组播地址将LSU发送给DR Other路由器。综上所述,所有运行了OSPF的路由器都会监听224.0.0.5的组播地址,但只有DR和BDR在监听224.0.0.5地址的同时额外监听224.0.0.6的组播地址。
Cost
OSPF协议使用Cost值当作Metric去衡量到达目标网络的远近,Cost值越小越优。接口的带宽越大,计算出的Cost值越小,接口的带宽越小,计算出的Cost值越大。在每一个运行OSPF协议的接口上,都维护着一个接口的Cost值,接口的Cost值=100M / 接口带宽,也就是:10的8次方/BW(bit),这个100M(10的8次方)指的是参考带宽。一条路由的Cost值,是该路由从来源一路过来的所有入口方向的接口Cost值的总和,也就是这条路由经过接口的Cost值的综合。
例如1.1.1.0/24的路由,由于是loop back接口,所以相对于Router A来说,Cost值为1,对于Router B来说,B与A相连接的接口Cost值为64,所以1.1.1.0/24的路由相对B来说,Cost值就是1+64,也就是65。
修改Cost的方法:
- 修改参考带宽,也就是修改10的8次方这个数值,因为计算Cost的公式是10的8次方/BW(bit),通过修改参考带宽也可以修改Cost值。命令在ospf进程下配置:auto-cost reference-bandwidth XXX ,该数值的设置范围是1-4294967。
- 修改接口带宽,带宽和Cost值成反比,带宽越大,cost值越小,通过修改带宽也可以达到修改Cost值的目的。修改接口带宽的命令是在接口下配置:bandwidth XXX。该数值设置的范围是1-10000000。
- 直接修改Cost值,在接口上使用ip ospf cost XX,可以直接修改Cost值。
ospf数据包类型
- Hello:发现直连链路上的OSPF邻居、维护邻居关系。
- DBD:Database Description,数据库描述包,DBD一共有两种类型,一种是空的DBD,用于协商Master/Slave,另一种则包含LSA的头部信息(不是全部的LSA信息,相当于一个LSA的目录),用于描述LSDB的摘要。
- LSR:Link State Request,链路状态请求报文,用于向OSPF邻居请求链路状态信息。
- LSU:Link State Update,链路状态更新报文,在LSU报文中包含完整的链路状态信息,也就是完整的LSA。
- LSACK:Link State Acknowledge,链路状态确认报文,OSPF协议规定收到每个LSA后要进行确认,LSACK就是确认收到LSA的报文。
协议的三张表
邻居表(Neighbor Table):邻居表由临界数据库(Adjacency Database)生成,两台路由器的OSPF要协同工作,最基本的要求是两者要形成邻接(Adjacency)关系,邻居表储存了OSPF路由器邻居状态以及关于该邻居的其他数据,每台路由器的邻居表和其他路由器的不同,用 ‘show ip ospf neighbor ‘命令查看邻居表 。
拓扑表(Topology Table):拓扑表由链路状态数据库(Link-State Database,LSDB)生成,储存着网络中其他路由器的信息,用于构建网络拓扑,同一个区域(Area)内的路由器中的拓扑表相同(因为拓扑表用于构建区域内的网络拓扑,每个路由器都在相同网络拓扑的区域内),LSDB的概念有点不太好理解,可以理解成LSDB中的这些数据相当于本AS内的网络拓扑图一样,用 ‘show ip ospf database ‘命令查看拓扑表。
OSPF路由表(OSPF Routing Table):路由表由转发数据库(Forwarding Database)生成,在链路状态数据库(Link-State DataBase,LSDB)基础上运行SPF算法后得出路由表,用 ‘show ip route’查看路由表。
路由种类
OSPF的路由共有O、O IA、O E1、O E2、O N1和O N2这五种类型,其中O是某个区域的域内路由,由这个区域的1类和2类LSA生成;OIA是区域间路由,由3类LSA生成;OE1和OE2都是由5类LSA生成的,区别在于OE1是OSPF的域外路由,会累加Metric值,默认带的Metric也就是Cost值是20;OE2也是域外路由,不过不累加Metric值,默认Metric值也就是Cost值就是20,由外部重分布进OSPF的路由默认使用OE2类型;ON1和ON2由7类LSA生成。这几种路由之间优先级简单的来说是:O > O IA > N1 > E1 > N2 > E2,但各厂家对这几种路由的理解不同,所以在不同品牌的网络设备中,这几种路由的优先级也不同,具体哪种路由更优先要结合设备的版本以及厂家规定来看。
触发更新
当路由器、链路或网段的状态在up-down之间切换时会引发触发更新。假设下图中的网络已经完成了OSPF路由收敛,突然R3下面的一个网络发生了故障,R3用224.0.0.6的组播地址通知DR及BDR,监听224.0.0.6的DR和BDR在得知该网段故障后向组播地址224.0.0.5发送更新通知其他路由器,由于除了DR及BDR的其他路由器都会监听224.0.0.5这一组播地址,路由器收到包含变化后的LSA的LSU后,更新本路由器的LSDB,待SPF延迟计时器到期后运行SPF算法,对更新后的链路状态数据库执行SPF算法必要时更新路由表。
LSA的确认
LSA的确认方式一共有两种,显示确认和隐式确认,显示确认通过LSAck完成;隐式确认通过发送回整个相同的LSA去确认该LSA完成的,隐式确认常见在OSPF的广播网络中,大概过程如下:
- A non-DR router on an Ethernet segment detects a topology change and needs to inform other routers about it. It sends the LSU packet to the DR and BDR using the 224.0.0.6 destination IP address.
- Both DR and BDR receive the packet. Normally, you would expect that the DR would send an LSAck acknowledging the successful receipt of the LSU. However, the DR needs to propagate the LSU back to the segment using the 224.0.0.5 destination IP address anyway, so it just does exactly that, without sending a standalone LSAck.
- The original router receives the same update from the DR it sent it a moment ago, and it considers it as an implicit acknowledgement. No further LSAck from the DR is expected.
- Other routers on the segment receive the LSU and acknowledge its receipt via an explicit LSAck message back to the DR. This is an explicit form of acknowledgement.
- 当一个在以太网MA环境下的非DR路由器,路由器A发现拓扑变化后,它需要将这个拓扑变化通知给其他邻居,这时路由器A会使用LSU数据包并把数据包发送给224.0.0.6这个组播地址,因为DR和BDR监听着这个组播地址而其他DR Other只监听着224.0.0.5且DR Other只和DR、BDR建立了完全邻接关系,所有LSU都是先发给DR\BDR再由DR\BDR发送给其他DR Other的。
- 当DR和BDR都收到这个LSU后,通常情况下,DR会发送LSAck给路由器A告诉A此时DR已经接收到了这个LSU了,然而DR此时也需要将A发过来的LSU通过224.0.0.5泛洪出去,所以DR这时不会发送LSAck去确认那条A的LSA。
- 那么路由器A如何知道DR收到了那条LSA呢,假定它发送的这条LSU叫AA,A通过224.0.0.6发送特定的LSU-AA给DR,由于DR需要将这个变化通告给域内其他的路由器,所以DR再把这条LSU-AA通过224.0.0.5发送给域内其他包括A在内的路由器,A也就从DR收到了LSU-AA,A收到DR发来的相同的LSU就知道DR已经收到了之前的LSU-AA,也就不用再等待DR的LSAck了,如果没收到的话DR不可能会泛洪这条LSU-AA,这就是隐式确认。
- 在该网段的其他路由器会收到LSU-AA并返回给DR一个LSAck表示收到了这条LSU-AA,这是显示确认。
基础命令
1 | Router(config)# router ospf process-id |
- show ip ospf interface E0/0,就是查看E0/0接口上关于OSPF的配置情况。
- Process ID 1,也就是之前配置的router ospf 后面的process-id,这里可以看到该OSPF进程号为1。
- Router ID 0.0.0.2,就是该路由器的ID。
- Network Type BROADCAST,表示E0/0接口的OSPF网络类型为广播。
- Cost :10,OSPF使用开销来作为路由的度量值,一条路由的Cost值越小越优,可以在接口下使用ip ospf cost XX命令来修改cost值。
- State BDR,表示该E0/0接口的角色为BDR,也就是Backup Designated Router,备份指定路由器。
- Priority 1,表示该接口的OSPF Priority值为1,这个值在决定接口性质,也就是链路在决定一个接口的DR、BDR或DR Other时使用。Priority 最高的为DR。
show ip ospf database 命令及相关输出说明会在后面LSA类型中具体说,这里就不展开了。
clear ip route *是否会出发SPF算法的重新计算?
clear ip route *触发了SPF算法的重新计算,SPF算法运行的次数增加了,实验结果如下:
OSPF计时器
- MaxAge:LSA的老化计时器,LSA在LSDB中能存在的最长时间,说白了就是LSA的寿命上限,到了这个时间就必须从LSDB动态链路数据库中删除,LSA的寿命上限为60分钟,也就是60分钟内没收到该LSA的刷新信息就会将其从LSDB中删除;
- LSRefresh:LSA刷新计时器,定期1800秒刷新一次有效的LSA,让这些LSA继续在LSDB中存在,避免因到达Max Age而过期从LSDB中删除;
- Hello interval:Hello包发送间隔,也就是运行OSPF协议的接口每隔多久发送一次Hello消息。进入接口后用命令:ip ospf hello-interval X 进行更改。Hello interval是接口属性,可以每个接口的Hello interval不同,只要和邻居相同能建立起邻居就可以;
- Dead interval:失效间隔,表示如果多少秒后没收到邻居路由器的消息,会认为邻居路由器已Down掉进入接口后用命令:ip ospf dead-interval X 进行更改。Dead interval是接口属性,可以每个接口的Hello interval不同,只要和邻居相同能建立起邻居就可以;
OSPF协议根据接口的网络类型不同,Hello Interval、Dead Interval时间也不同,总结见下图:
- Wait:等待计时器(接口属性,各接口可以不同),和Dead interval的值相同,定义了路由器在到达2WAY状态时,等待多久后会宣告自己就是DR。比如如果Wait时间是40秒,那么当一台处于MA网络的路由器到达2WAY状态后,会等待40秒,如果40秒内都没有收到邻居的Hello跟本路由器一起选举DR,那么它就会宣告自己就是DR。
- Retransmission:重传计时器(接口属性,各接口可以不同),表示发送完LSU以后,经过多久没收到ACK消息确认收到本设备发送的LSU,就认为这个LSU没成功发送到对方,会进行重新发送。
OSPF数据包
总览
OSPF数据包有邻居发现、形成邻接关系、泛洪LSA信息等功能,共有5种数据包,分别是Hello、DBD、LSR、LSU、LSAck。OSPF数据包的二层采用以太网封装,前面说过,OSPF使用的协议组播地址为224.0.0.5或224.0.0.6,所以以太网中的目标MAC地址字段为01-00-5E-00-00-05或01-00-5E-00-00-06;三层用IP封装(Protocol字段为89),目标IP地址为224.0.0.5或224.0.0.6.OSPF部分分为OSPF Header和OSPF Message两部分,Header决定了OSPF为5种类型种的哪种数据包,Message携带了该种类型包含的信息。
OSPF Header
所有5种OSPF数据包都有着共同通用的24字节长度的OSPF报头,通用的报头让接收端路由器能进行后续的验证和处理。OSPF并不适用TCP或UDP作为四层的报头而是使用单独的协议,协议号为89。OSPF的5种数据包,Header部分只有Type字段有所区别,后面具体分析的时候就不再涉及Header部分而只说Message部分了。
- Version:版本,OSPF v2版本该字段为2,字段长度为8位。
- Packet Type:类型,根据类型字段数值不同表示不同的OSPF数据包,1为Hello,2为DBD,3为LSR,4为LSU,5为LSAck,字段长度为8位。
- Packet Length:OSPF报头总长度,字段长度为16位。
- Router ID:产生该OSPF包的源路由器的Router ID,Router ID在AS中唯一地标识一台路由器,不能和其他路由器的Router ID重复,可以在OSPF路由进程中手工指定,如果没有指定,路由器默认选择环回接口(Loopback接口)中最高的IP作为RID;如果没有环回地址,路由器使用所有激活的物理接口中最高的IP作为RID。,字段长度为32位。
- Area ID:用于标识该数据包所属的区域(Area),字段长度为32位。
- Checksum:校验和,用来检查OSPF报头在传输中的完整性,这个校验和不包括后面的身份验证(Authentication)字段,也就是从Version到Authentication Type的部门,字段长度为16位。
- Authentication Type:认证方式字段,定义该数据包的认证方式。0表示没有密码,1表示明文密码,2表示MD5认证,字段长度为16位。
- Authentication:认证字段,共64位,之所以在图中占两行是因为一行是32位,两行才是64位。
OSPF Message
OSPF Message部分根据Packet Type的不同携带不同的信息:
- Type 1:当Type为1时表示这是一个Hello包,携带的信息是已知的邻居。
- Type 2:当Type为2时表示这是一个DBD包,携带的信息是LSDB的目录,目录中包括Router ID、序列号等。
- Type 3:当Type为3时表示这是一个LSR包,携带的信息为需要的LSR以及需要LSR的路由器的Router ID。
- Type 4:当Type为4时表示这是一个LSU包,携带的信息是完整的LSA条目,一个LSU种可携带多条LSA。
- Type 5:当Type为5时表示这是一个LSAck包,携带的信息为空。
Hello
概述
Hello数据包用于与邻居建立并维持毗邻关系、交互参数以及选举BDR/DR,当接口类型为广播和P2P时默认每10秒交换一次Hello包,其他接口类型时30秒发送一次Hello包,发送地址为组播的224.0.0.5。Hello包的Packet Type为1。Hello包会周期性的在运行了OSPF的接口上用组播发送出去。为了顺利建立起邻居,所有连接到网络种的路由器的相关参数必须互相相同,这些参数包括网络掩码、Hello时间和Dead时间等。
格式分析
- Network Mask:网络掩码,指的是路由器要发送的网络的掩码,字段长度为32位。
- Hello Interval:Hello包发送间隔,也就是运行OSPF协议的接口每隔多久发送一次Hello消息,字段长度为16位。
- Opinion:选项,代表着路由器支持OSPF的哪些可选功能,字段长度为8位。
- Router Priority:路由器优先级,在选举BDR\DR时使用,字段长度为8位。
- Router Dead Interval:路由器失效间隔,表示如果多少秒后没收到邻居路由器的消息,会认为邻居路由器已Down掉,字段长度为32位。
- Designated Router:指定路由器,在NBMA以及广播这两种类型的网络中,要选举DR路由器,选举后DR的IP地址在该字段,所有DR Other路由器和DR建立完全邻接关系并交换LSA,如果没有DR则该字段为全0,字段长度为32位。
- Backup Designated Router:备份指定路由器,在NBMA以及广播这两种类型的网络中,要选举BDR路由器,BDR是DR的备份,先选举BDR然后将BDR晋升为DR,当DR Down掉后由BDR接替DR的位置并发挥DR的作用,如果没有BDR则该字段为全0,字段长度为32位。
- Neighbor:邻居,当收到其他路由器发送来的Hello包时,将其他路由器的IP地址放在此字段,如收到多个路由器的Hello包时,会存放多个,收到一个其他路由器的Hello包占据32位,收到两个占据64位,以此类推,用Wireshark抓包时此字段为Active Neighbor,比如上图有两个Active Neighbor分别是1.1.1.1和3.3.3.3,表示该路由器分别收到了1.1.1.1和3.3.3.3这两个路由器发来的Hello包。
Hello包中的Area ID,Hello Interval,Router Dead Interval、Authentication Type、Authentication几个字段在邻居建立时必须相同邻居才能成功建立。如果Hello 时间不同Debug时就会出现以下提示,说明两个路由器之间Hello时间Mismatch,也就是Hello时间不相匹配:
DBD
概述
DBD是DataBase Description的缩写,出现在邻居建立过程中的ExStart及Exchange阶段,DBD是链路状态数据摘要,也就是LSDB的摘要或者说它是LSDB中有什么LSA的简略列表,用于描述链路状态数据库(LSDB)的内容,一个域中所有路由器的LSDB必须相同,在交换LSA之前先通过比较DBD来知道需要交换哪些LSA,这个是DBD的主要作用。
格式分析
整体的DBD包:
DBD数据包的Header部分中的Packet Type为2,表示这是一个DBD数据,其他字段之前分析过这里就不再赘述了,Header部分如下图:
Message部分:
- Interface MTU:长度为16位,一个路由器的接口在不分片情况下,所能传递的IP信息的最大值。这个值两台路由器必须相等才能建立Full Adjacency的关系。
- Option:长度为8位,本地路由器在此字段中告知其所支持的功能。
- Flages:长度为8位,前5位保留值为0,后三位分别为I位(Initial位,当它置1时表示这是初始的第一个DBD包,用来协商Master\Slave关系;置0时表示这不是初始的第一个DBD包了,标志着Master\Slave选举结束)、M位(More位,当它置1时表示后续还有DBD包需要发送;置0时表示后续没有DBD包需要发送了)、MS位(Master\Slave位,当它置1时表示路由器认为自己的角色时Master;置0时表示对方为Master。)。
- DD Sequence number:长度为32位,主从关系(Master\Slave)确定前,两台路由器各自用一个随机的大数字作为自己的DD Sequence;当主从关系确定后,Slave一方会用Master一方的DD Sequence作为自己的DD Sequence发送DBD给Master表示确认收到了Master的DBD,也就是隐式确认。
- LSA Header:这部分包含了用来表述路由器LSDB的LSA头部。
DBD的Wireshark抓包如下:
补充说明
两台路由器的DBD包中的Interface MTU必须相等才能建立Full Adjacency的关系,如果不相等会出现如下的提示,提示10.1.1.2的Interface MTU更小使得Adjacency无法建立:
LSR
概述
LSR用于请求邻居路由器发送其链路状态数据库(LSDB)中的特定项。LSR一般用在两台路由器交换完DBD后,当然如果路由器发现彼此之间并不用交换LSA的话,则LSR不会出现。
格式分析
整体格式:
Header部分中的OSPF Type为3,其他部分与其他包的Header部分相同这里就不再赘述了。
Message部分:
- LS type:长度为32位,表示所传递的LSA的类型。
- Link State ID:长度32位,传递的LSA的ID,通常来说是路由器的ID或链路的ID。
- Advertising Router:长度32位,发送LSR请求的路由器的Router ID 。
LSR的Wires hark抓包如下:
LSU
概述
LSU用于向邻居路由器发送其所需要的链路状态通告(LSA)。这些LSU实现了LSA的泛洪。每条LSA中包含着描述网络的一部分信息,这些信息包括路由、度量值和拓扑信息等。本地路由器的LSA通过LSU被发送到邻居路由器,邻居路由器通过LSR来回应LSU。
格式分析
Header部分中的OSPF Type为4,其他部分与其他包的Header部分相同这里就不再赘述了。
Message部分:
需要更新给邻居的LSA,是以上图的形式,也就是LSA包含在LSU中,以LSU的形式发送给邻居路由器的,下面来看字段具体含义。
- Number of Link State Advertisments:长度32位,表示这条LSU携带了几条LSA;
- LSAs:长度可变,表示所携带的LSA,具体报文格式参考后面的LSA部分。
下图中的LSU中包含着1条1类LSA,这条1类LSA中包含着3个链路,其中两个链路为Stub类型,一个链路为P2P类型。
LSACK
概述
LSAck用来向发送方确认收到特定的LSU,由于OSPF在四层不适用TCP或UDP,而协议又对可靠性有要求,因此增加LSAck包来保证可靠性。
格式分析
OSPF的Header部分除了Type字段为5以外,其他部分之前已经写过,这里就不再赘述。
Message部分包含了已经确认收到的LSA的报头,如果收到N个LSA的话就会有N个LSA报头在其中,关于LSA的Header部分在下一节LSA中具体讨论。
LSA
LSA简介
LSA由路由器产生,路由器的角色不同会产生不同种类的LSA,LSA中包含着链路状态信息和路由信息,LSA构成了LSDB(Link-State DataBase,链路状态数据库),OSPF使用LSDB计算路由。每个区域(Area)中所有路由器的LSDB是相同的,也就是说这些路由器所掌握的LSA是相同的,LSA一共有11类,不同种类的LSA传播的范围各有不同,有些LSA只在本区域内传播,有些LSA可以跨区域传播。运行OSPF协议的路由器交换完LSA后,各自运行SPF算法,由于域内路由器的LSDB相同又采用同样的SPF算法,所以计算出的路由路径是相同的。LSA每30分钟全部刷新一次,60分钟内如果没刷新则会由LSA的始发路由器泛洪一条LSA已到达最大过期时间的LSA,让其他路由器删除该LSA。如果链路的状态因为某种原因产生了变化,那么直连该链路的路由器检测到变化后会触发关于该链路变化的更新。路由器只能对其产生的LSA进行修改,不能对其他路由器的LSA进行改动。当网络拓扑发生变化时,LSA会带着新的信息进行泛洪,如果网络收敛完毕后,拓扑没有变化则不会对LSA进行泛洪(除了30分钟的整体LSA刷新以外)。
收到LSA后的动作
Each LSA has an aging timer which carries the link-state age field. By default each OSPF LSA is only valid for 30 minutes. If the LSA expires then the router that created the LSA will resend the LSA and increase the sequence number.
Let’s walk through this flowchart together. In this example a new LSA is arriving at the router and OSPF has to decide what to do with it:
- If the LSA isn’t already in the LSDB it will be added and a LSAck (acknowledgement) will be sent to the OSPF neighbor. The LSA will be flooded to all other OSPF neighbors and we have to run SPF to update our routing table.
- If the LSA is already in the LSDB and the sequence number is the same then we will ignore the LSA.
- If the LSA is already in the LSDB and the sequence number is different then we have to take action:
- If the sequence number is higher it means this information is newer and we have to add it to our LSDB.
- If the sequence number is lower it means our OSPF neighbor has an old LSA and we should help them. We will send a LSU (Link state update) including the newer LSA to our OSPF neighbor. The LSU is an envelope that can carry multiple LSAs in it.
LSA的删除
in OSPF, no router is allowed to prematurely delete other router’s LSAs from its link-state database. LSAs may only be removed from the link-state database either if they reached their maximum age, or if their original advertising router has explicitly flushed them by flooding them with the age set to MaxAge. The loss of a neighbor does not result in its LSAs being flushed.——OSPF LSA Flooding
在OSPF协议中,路由器不能过早的删除自身LSDB中由其他路由器产生的LSA,也就是说如果R1收到一条由R2始发的LSA并将其加入LSDB后,不能无缘无故的删除这条LSA,要删除该LSA,要么是该LSA的老化计时器到时间(60分钟)R1将其删除,要么是通告该LSA的原始路由器R2泛洪一条LSA已到达最大过期时间的LSA,让其他路由器比如R1删除该LSA。
LSA的刷新
为什么需要刷新LSA
RFC 2328中规定:Every LSA has to be reoriginated (that is, refreshed) every 1800 seconds.也就是说每一条LSA每隔1800秒(30分钟)必须重新起源或者说刷新一次,不管LSA的老化计时器是否到期都会刷新LSA,为的是在LSA老化计时器的3600秒到达前还能在区域内存在并传播,路由器只刷新它生成的LSA。
刷新LSA的步骤
OSPF的刷新步骤是“What OSPF routers do each 30 minutes is that each router takes all LSAs it has originated itself, increments their sequence (revision) number, resets the age and floods them. Basically, each router floods a refreshed version of its own LSAs. Note that this is not an entire database resynchronization.——出处点击”,以及“This is the 30 minute interval which you are asking about. As the age of some self-originated LSA approaches 1800 seconds, the router will generate a refreshed version of the same LSA and flood it - an incremented sequence number, the age timer set to 0. That’s it. Nothing more. There is no some kind of resynchronization of entire link-state databases or something. You just flood a new LSA, just like you would flood an LSA if some topological event occured. The DBD packets have nothing to do here. As with all LSA flooding operations, LSAs are flooded within LSU packets, and they are confirmed with LSAck packets.——出处点击”。简单来说就是LSA的起源路由器会在30分钟的时候发送一条和之前LSA相同的新版本的LSA去刷新该条LSA,这个新版本的LSA相比之前的LSA来说,增加了序列号的数值且老化计时器为0。在LSA刷新的时候不会发送DBD,只是用LSA去刷新LSA(LSA包含在LSU中用LSU的形式泛洪),收到刷新LSA的LSU以后,路由器也会发送LSAck用来确认收到LSU。这里注意,在MA网络中由于所有DR Other只和DR\BDR建立完全邻接关系,所以在刷新LSA时,起源路由器的的LSU也是和DR\BDR交互的,由DR\BDR再泛洪给其他路由器。
刷新的对路由器是否有影响
答案是没有影响,因为近年来设备的CPU性能已足以应付每30分钟刷新一次的LSA,而且每隔域(Area)中有多个DR\BDR而不是一个,每个MA网络都有其自己的DR\BDR,只负责本MA网络的LSA泛洪就行。而且即使是一个有N台路由器的MA网络也不意味着同一时间同时泛洪LSA,因为LSA的老化计时器是在每条LSA生成泛洪时开始计时的,每条LSA生成的时间不同。即使因为巧合,所有路由器在同一时间刷新LSA,假设MA网络中有N个路由器,那么此时同时刷新的1类LSA为N条,需要更新的2类LSA由于在为1条(由于2类LSA由DR产生用来通告掩码),如果再有ABR或ASBR的话也需要泛洪的LSA也不多,所以不会对路由器有什么影响。
LSA的新旧
当一个路由器遇到两条LSA实例时,它必须分辨出哪一条更新一些,这种情况一般在收到一条和本地LSDB一样的LSA时出现,在两台路由器的LSDB交换过程中也会出现。
两条LSA是否相同由LS Type、Link-State ID和Advertising Router三个参数决定。一条LSA的两个实例由LS Sequence number、LS age和LS checksum决定哪个实例是更新一些的。
首先比较LS Sequence Number,有着更新LS Sequence Number的LSA更新;如果两个实例有着相同的LS Sequence Number且LS checksum不同,那么LS checksum更大的被认为是更新的LSA。其他情况参见RFC 2328的section13.1
路由器的角色
- Backbone router – The area 0 is known as backbone area and the routers in area 0 are known as backbone routers.
- Internal router – An internal router is a router which have all of its interfaces in a single area.
- Area Boundary Router (ABR) – The router which connects backbone area with another area is called Area Boundary Router. The ABRs therefore maintain multiple link-state databases that describe both the backbone topology and the topology of the other areas.
- Area Summary Border Router (ASBR) – When an OSPF router is connected to a different protocol like EIGRP, or Border Gateway Protocol, or any other routing protocol then it is known as AS. The router which connects two different AS (in which one of the interface is operating OSPF in area 0) is known as Area Summary Border Router. These routers perform redistribution. ASBRs run both OSPF and another routing protocol, such as RIP or BGP.
- Backbone Router:翻译成中文是骨干路由器,就是至少有一个接口在Backbone区域中的路由器。
- Internal Router:翻译成中文是内部路由器,也就是所有接口都在同一个非骨干区域的路由器。
- Area Boundary Router (ABR):翻译成中文是区域边界路由器,用以连接区域0和非骨干区域,ABR路由器在Backbone区域有一个或多个接口并且在非骨干区域也有一个或多个接口。
- Area Summary Border Router (ASBR):翻译成中文是自治系统边界路由器,当一个路由器既运行了OSPF协议,也运行了其他路由协议,比如EIGRP或BGP协议的时候,该路由器连接了两个不同的AS(其中一个接口在区域0运行OSPF)的路由器被称为自治系统边界路由器。
LSA的格式
LSA的报文格式分成两部分,Header和Body,也就是报头和信息。不管是哪种类型的LSA,都有一个相同的20位的LSA报头,根据LS Type字段数值不同,LSA信息部分包括的内容也不同。
LSA报头
- LS age:链路状态计时器,也就是这条LSA生成的时间,单位为秒,当这个字段到3600s,也就是60分钟的时候,这条LSA会从LSDB中删除,因为到达了最大存在时间;
- Options:选项,表示了路由器所支持的OSPF功能有哪些;
- LS type:LS类型,表示了这条LSA是哪种类型的LSA。该字段为1的时候是1类LSA也就是Router-LSA;2为2类LSA也就是Network-LSA;3为3类LSA也就是ABR产生的Summary-LSA;4为4类LSA也就是ASBR产生的Summary-LSA;5为5类LSA也就是AS-External-LSA;
- Link State ID:链路ID,该字段定义了这条链路,标识了LSA正在通告的内容,通常是链路代表的路由器或网段的IP地址。和Link ID概念不一样,Link ID是一条链路的标识,而Link State ID标识的是一条可能携带多条链路的LSA;
- Advertising Router:该字段表示了生成这条LSA的路由器的ID;
- LS Sequence Number:用来检测重复LSA或分清LSA新旧的序列号;
- LS Checksum:LSA的校验和,用来检测LSA在传输过程中是否被更改,在LS Sequence Number相同时也用于比较两条LSA的新旧,Checksum值大的LSA更新一些。LS Checksum的校验和包括了LSA的Header部分但并不包括LS age部分,因为前面说过LS age是这条LSA的生成时间,随时在变化,如果包括了这部分校验和肯定是每个经过的路由器校验和都不一样;
- Length:包括了20位LSA Header在内的LSA的长度。
这些信息在使用show ip ospf database X.X.X.X的时候也可以看得到
报头中的信息使用show ip ospf database也能看到:
Options字段
- E字段置1时表示它邻接的Area能处理5类LSA(ExternalRoutingCapability);
- MC字段置1时表示它支持多播扩展(MOSPF);
- N/P字段置1时表示它支持7类LSA;
- EA字段置1时表示它有接收和转发外部LSA的能力;
- DC字段置1时表示它支持demand circuits;
Options字段常见的N/P及E字段,在后文7类LSA中有具体解释,这里就简单说一下各字段的作用。
其他说明
看懂输出中关于Link State ID(有时是Link ID)的关键在于,该字段并不是一个IP地址,Link ID中的1.1.1.1不代表这个网络和1.1.1.1/32相连,它表示的是在LSDB的图中中有一个叫做1.1.1.1的路由器节点。
不同类型的LSA中的Link ID和ADV ID不同,在后文1类LSA部分中有具体说明。
LSA信息
根据LS Type值的不同,LSA共有11类,每一类的message部分差别都比较大,具体见后文。
LSA的分类
总览
- 所有运行了OSPF的路由器都会产生1类LSA,仅在本Area中传播,1类LSA用来通告,网络中的节点路由器和这些路由器之间的关系,直连接口的信息;
- DR路由器产生2类LSA,仅在本Area中传播,2类LSA中用来通告掩码信息;
- ABR路由器产生3类LSA,在除了特殊区域(Totally\Stub area、Totally\NSSA)以外的其他Area中传播,但传播范围仅为一个区域,就是从其他Area到骨干区域或从骨干区域到其他区域,通告了区域间路由;
- ABR路由器在知道ASBR的情况下会产生4类LSA,在所有区域中传播,用来通告去往ASBR的路径;
- 5类LSA由ASBR产生,在所有区域中传播,用来描述ASBR从外部AS注入OSPF区域的重分布路由;
- 7类LSA也由ASBR产生,在NSSA区域内传播,用来描述外部路由,这个外部路由由ASBR发送给ABR并且由ABR转换成5类LSA后泛洪到其他区域。
Type-1
1类SLA的英文全称是:Router Link Advertisement,每台运行OSPF的路由器都会为其所属的每个Area产生1类LSA,1类LSA描述了该路由器在本区域内链路的状态,通告了直连这个区域接口的信息,1类LSA在本区域内泛洪。OSPF用1类LSA识别本链路为以下4种链路邻接方式的哪一种:
- Stub Network,Stub网络。
- Point-to-Point links,点对点链路。
- Link to a multiaccess network,多路访问链路。
- Virtual Links,虚链路。
注意,interface(接口)和link(链路)是有区别的,两者并不是同一个概念。一个接口(Interface)表示的是一个路由器上的物理或逻辑接口,逻辑接口比如loop back接口,物理接口比如以太网接口;而一个链路(link)描述的是表格种两个节点的关系,虚链路(Virtual link)是一个说明这个概念的很好的例子,一个虚链路描述的是逻辑上连接到另一个路由器。
报文格式
Length及之前的部分都是LSA Header,有两个地方需要说一下,一个是LS Type为1,表示这是一个1类的LSA;另一个是Link State ID部分,这里该字段被设置成路由器的Router ID。LSA的Header也可以用命令”show ip ospf database”进行查看,但必须要注意这里的Link ID并不是上文倒数第二个字段Link ID,而是Link State ID,在1类LSA中就是Router ID。
Link ID和ADV Router在不同类型的LSA中表示的不同含义,ADV Router就是生成这个LSA的Router ID,比如1类LSA的ADV Router就是每台路由器本身, 因为1类LSA由每台路由器自己产生;2类LSA的ADV Router是DR的Router ID,因为2类LSA由DR产生。Link ID,是本设备为链路另一端设备所起的名字。
LSA Header中其他的字段在前面已经写过,这里从Length之后的部分开始看。
- V位:当该位置1时,表示该路由器是一个或多个已经达到Full状态的虚链路(Virtual link)的终点。V代表了Virtual link endpoint。
- E位:当该位置1时,表示该路由器时ASBR路由器,也就是AS边界路由器。E代表了External,E位不能在Stub area中置1,因为Stub area不能包含ASBR路由器。
- B位:当该位置1时,表示该路由器是ABR路由器,也就是区域边界路由器。B代表了Border,当路由器连接到2个或更多区域时,B字段应马上置1表明它的ABR身份,即使该路由器目前还没连接到核心区域B位也应置1。
- #Links:又叫Number of LSAs,也就是后面携带的LSA的数量,是路由器包含的一个区域中的总体链路的数量。
- 接下来的三个字段Link ID、Link Data以及Type,前两个字段,也就是Link ID和Link Data由Type所决定,当Type值为不同数值时,Link ID和Link Data的含义随之不同。Link ID字段定义了这条链路的对端是什么,也就是连接到的是什么;这里的Type其实是Link Type,主要用于描述OSPF路由器的接口或邻居,它的值取决于所连接网络的类型。当Type为1时,表示这是一个’Point-to-Point connection to another router’,翻译成中文就是‘点对点连接到另一台路由器’;相对应的Link ID为’Neighboring router’s Router ID’,也就是邻居路由器的路由器ID;相对应的Link Data为’the IP interface address of the associated router interface’,也就是和网络相连的始发路由器接口的IP地址。具体参见下面几张表:
- #TOS:The type of service,如果没有TOS度量和一条链路相关,那么这个字段就设置为0X00,。
- metric:度量值。
- TOS:该字段思科设备只支持为0。
- TOS metric:TOS特定的指标信息。
抓包
Type字段
概述
这个Type字段定义的是链路类型,注意这个链路类型(Link type)与网络类型(Network type)不同,链路类型(Link type)主要用于描述OSPF路由器的接口或邻居,比如Link ID字段能够了解链路对端是什么设备或者链路对端是否有设备,因为构建OSPF数据库和运行SPF算法需要每台路由器宣告它们的1类LSA,这个1类LSA中必须描述路由器链路的状态,链路状态一共有4种;而网络类型(Network type)是由OSPF协议在接口上针对不同的二层链路介质或封装而定义的,如果二层封装协议是以太网(Ethernet)那么OSPF在这个接口的网络类型为Broadcast,如果二层封装的是HDLC或PPP,那么OSPF的网络类型是P2P。网络类型(Network type)决定了路由器和相邻节点在网段上的行为,常见也比较重要的就是是否选举DR\BDR,以及Hello\Dead interval(Hello和过期时间,网络类型为广播时为10S\40S,P2P、P2MP和point to multipoint non-broadcast时为30S\120S),可以在进入接口以后用命令ip ospf network XXXX(point-to-point、broadcast….想修改成什么网络类型,这个XXXX就改成什么)进行修改。
在1类LSA中,可以看到始发该LSA的路由器所连接的所有链路、链路的类型以及相关内容,在设备上可以用show ip ospf database router internal或show ip ospf database router self-originate查看:
上面说过,1类LSA中的Type字段的值也决定了后面的Link ID和Link Data的取值,下面两张图,第一张是红茶三杯笔记中的,第二张是我结合RFC文档写的,维基百科上的图和我总结的一样,区别在于虚链路的Link Data如何取值,RFC 2328的Page 128上写的是“For links to transit networks, numbered point-to-point links and virtual links, this field specifies the IP interface address of the associated router interface”。
OSPF链路类型分为四种,分别是Stub network link、Transit network link、Point-To-Point link、Virtual link。OSPF将链路分为以上的类型自然不是吃饱了没事儿干,一方面是描述网络连接方式,P2P link和Transit network link是用于描述网络拓扑结构的而Stub network link是用于描述子网的;另一方面是不同类型的Link消耗的硬件资源不同,比如Transit network消耗资源多一些,Stub network消耗资源少一点。必须注意的是,Stub network和后面的Stub area是完全不同的两个概念,千万不要混淆二者。
Stub network link
定义
A stub network’s vertex has only incoming edges.
——RFC2328 Section 2.1
RFC的定义过于严谨所以就比较难懂,通俗一些的说法就是在一个链路中只有一台OSPF路由器的情况下,该链路被OSPF链路类型定义为Stub network link,因为一个链路中只有一台OSPF路由器,所以这个链路的网段不可能有OSPF邻居,这个网段的网关就是这台路由器。如果路由器的一个接口被通告进OSPF,无论其二层链路是什么介质,只要在该接口上没有OSPF邻居,那么它就是Stub network link。
举例说明
图中R2身后有一个10.1.23.2/24的网络,它就是Stub network,因为这个网段中只有一个R2一个路由器运行OSPF协议没有其他OSPF邻居。R2产生的1类LSA用于描述FE0/0的Link 数据就是:
1 | Link connected to: a Stub Network |
第一行’Link connected to: a Stub Network’ 对应的是Type字段表达的意思,这里的10.1.23.2是一个Stub network,也就是Type字段值为3时的‘connect to a stub network’,也就是路由器连接到一个末梢网络;Link ID是IP network/subnet number,也就是网络号或子网号,这里10.1.23.2/24这个网段的网络号是10.1.23.0;Link Data是网络的IP地址或子网掩码,这里的255.255.255.0就是这个网络的子网掩码。
邻接矩阵
运行OSPF的路由器会维护一张网络拓扑表,通常存储这个网络拓扑表的方式是内存的中邻接矩阵,矩阵图会在下文有说明这里先暂时不管,Stub network的连接图和邻接矩阵的对应图如下:
由于Stub network只有一个路由器就行,没有其他OSPF邻居,所以相比前面有两台路由器要承载穿越流量(也就是不以本地为源也不以本地为目的)的Transit network来说,Stub network需要存放的路由信息就会相对少一些。Stub network类似于快递公司中,最靠近收件人的小的快递投送点,它只需要负责周边收件人快件的投送即可,不需要将快件发送到其他快递否送点,所以只需要知道周边用户的地址即可,硬件消耗会降低一些。
Transit network link
定义
Transit networks are those capable of carrying data traffic that is neither locally originated nor locally destined. A transit network is represented by a graph vertex having both incoming and outgoing edges.
——RFC2328 Section 2.1
RFC给出的定义很严谨,但由于它过于严谨,使得理解起来过于费劲,通过RFC的定义我是没搞明白,又查了一些文章,这里以红茶三杯的笔记为主体,结合自己的理解谈谈这个概念:由于Transit有运输、经过和运送的意思,从定义上看,Transit network是指的有能力发送既不是本网段产生也不是以本网段为目的的数据。但这个定义十分的不好理解,所以也可以把Transit network等同于,至少有两台路由器需要选举DR\BDR的网络,红茶三杯的原话是“简单理解为有邻居的OSPF接口,使用Transit Link来描述。但网络类型为Point-To-Point和点到多点(Point-To-Multipoint)的接口除外,因为它们被定义为Point-To-Point Link。”(在思科论坛上看到几次有人讨论过这个问题<transit network means there is at least one OSPF neighbor on the link but does not require the election of DR/BDR even if most of the times this happens.>,也在另一个技术博客上看到有人这么说<What a transit network actually is, is any network that requires a designated router.>,所以为了方便理解这里采用这个说法),这个Transit network可以是以太网LAN或者有多个虚链路的帧中继网络,不管是哪种网络,只要需要选举DR,那么它就是一个Transit network。在之前笔记中写过,由于DR和BDR选举时是每个网段上选的,所以这个Transit network中的network其实也可以理解成网段的意思( Does the word ‘network’ in the ‘Transit network’ meaning ‘network segment’?Yes I agree——出处)。举一个不恰当的例子,Transit network有点类似于快递公司中相对大一点的集散中心,这个集散中心既能把周边地区的快递送到,也能把不属于本集散中心投送的快递交给其他靠近最终收件人的投送点进行投递,所以Transit network既要知道其他快递集散点的路径,又要知道周边收件人的地址,硬件消耗相对多一些。
举例说明
例如上图所示,R1的FE0/0接口激活了OSPF并且有一个OSPF邻居R2,因此R1在LSA1中描述这个接口时,使用Transit Link来描述,如下:
1 | Link connected to: a Transit Network |
第一行’Link connected to: a Transit Network’ 对应的是Type字段表达的意思,这里的10.1.23.2是一个Transit network,也就是Type字段值为2时的‘connect to a transit network’,也就是路由器连接到一个传送网络;Link ID是IP address of Designated Router,也就是DR接口的IP地址,这里DR接口的IP地址是10.1.23.1;Link Data是和Transit network这个链路相连的,始发路由器接口的IP地址,这里10.1.23.1就是这个始发路由器的IP地址。
邻接矩阵
由于Transit network能发送那些既不是本地产生,也不以本地为目的地的数据,而且这货必须最少有2个路由器,所以不难想象,Transit network所需要存放的关于路由的数据相对后面的Stub network要多一些。
Point-To-Point link
OSPF网络类型(network type)为Point-to-Point和Point-to-Multipoint的接口(Loop back接口除外),使用Point-to-Point Link(Link type)来描述,也就是Type字段为1时的“Point-to-Point connection to another router”,表示路由器的接口通过P2P方式连接到另一个路由器。
例如上图,R1的S0/0口的OSPF网络类型是P2P,因此R1产生的1类LSA中用于描述该接口的网络类型就是P2P Link,输出如下:
1 | Link connected to: another Router (point-to-point) |
值得注意的是,对于P2P的网络类型接口,OSPF使用了两个Link来描述,一个是P2P Link,用于描述链路对端连接的路由器ID及自己本地的接口IP地址,还用了一个Stub Network Link来描述该条链路的掩码。
点对点的链路类型比较奇怪,因为理论上来说这种类型的链路并不需要IP地址就可以通信,因为OSPF将这种类型的链路视为“unnumbered”,也就是未编号,也可以理解成没有IP地址。因为链路上只有两个设备,流量从一段发过来肯定是要到另一端去的,给它提供两个IP地址其实意义并不大,但思科IOS中,一个接口如果没有IP地址就没法发送数据,所以也可以用命令“ip unnumbered XX”来让一个接口借用其他IP地址,比如如果想让Ethernet 0 这个链路类型为P2P的接口接用其他IP地址类通信,可以配置“ip unnumbered Ethernet 0”命令。
Virtual link
这种链路类型用来描述OSPF虚链路(Virtual Link)。
在上图中,R1和R3之间建立了一条虚链路,则R1产生的LSA1中描述该虚链路的数据如下:
1 | Link connected to: a Virtual Link |
上面输出的Metric:128,指的是从本地到虚链路对端,沿途所有出接口的COST累加,例如R1产生的描述虚链路的Link数据中包含的metric值就是如图中所示绿色标记的接口的cost值累加。
为什么如此定义
为什么要定义Stub\Transit network呢?答案是为了减少内存使用(This distinction is made because of memory requirements of the OSPF implementation.——出处),OSPF最早是在1989年提出来的,当时路由器的硬件配置比较低,但现在设备的硬件性能有了很大的提高,已经不太需要去如此节约系统资源了,但理解OSPF如此规定的理念有助于对协议整体的把握,所以建议有时间还是了解一下。当然具体如何减少内存使用,说实话我也没完全搞懂,写一下目前的理解,也许有时间再把这一块完善一下。
OSPF会利用内存维护一个网络拓扑表的矩阵,这个矩阵通常的存在形式如下:
矩阵最上面,行的备注是“form”,也就是“form object”:
矩阵最左边,列的备注是“to”,也就是“to object”:
做标记的N1和RT1交汇处的数值为3,表示从RT1(行代表的意思为form,也就是从的意思)路由器去到N1(列代表的意思为to,也就是去的意思)网段的cost值为3,当然从N1网段到RT1的cost也是3。其实这个网络拓扑矩阵也就是把物理连接图用矩阵图的形式存在了路由器中,从图中也可以看出这个拓扑矩阵:
那么这个拓扑矩阵和减少内存使用有毛关系呢?从矩阵图可以看出,有两个重要元素,路由器和网段。每个路由器都在该矩阵的“from”和“to”中出现(如果路由器不在该矩阵中出现,表示这个路由器和其背后的网络均无法到达),但不是每个网段在“from”和“to”中都出现,具体来说就是,Transit network属性的网段不论是在“form”的行上,还是在“to”的列中都会出现,但Stub network属性的网段在“to”的列中会出现,因为这个网段作为其他路由器或网段的目的地(也就是在to这一列出现)是没问题的;但在“from”的行上不出现,因为Stub network中只有一个路由器没有其他邻居,而这个网段就是终点了,网段后面也没有其他网段了,它没有穿越流量,因此不需要知道去往其他网段或路由器的路径,只需要把出向流量交给和该Stub network相连的路由器就OK了,那个路由器不管是在“from”还是“to”上都有,知道所有的路径。所以Stub network在“to”的列中有,但在“from”行上不会出现。上面矩阵图中最上边的行中,只有N3、N6、N8、N9出现了,说明这几个网段为Transit network而除此之外的网段均为Stub network,Stub network不出现在from行中减少了矩阵的大小,节约了硬件资源。如果有兴趣可以看一下下面这段话的出处,感觉我的理解并不到位。
The key observation here is that the stub networks are actually uninteresting for shortest path calculations between routers because they do not provide any further path to any other part of the network. The stub network is the edge - there is nothing behind it, only the network itself. It can be considered an attribute of the router to which it is connected but it is not interesting as a transit topology object. This idea allows us to save memory by not including the stub networks into the “from” rows of the adjacency matrix and thus reducing its size. If out of N networks, only N’ (N’ < N) networks are transit networks, the adjacency matrix could be reduced to the size of (M+N’) rows x (M+N) columns.
This is why the OSPF actually has the stub/transit network distinction in the first place. ——出处
关于节约资源的部分举一个简单的例子,比如一个网络拓扑中有4台路由器和5个网段:
(N1)R1—(N2)—R2—(N3)—R3—(N4)—R4(N5)
如果不区分Transit\Stub network,那么矩阵图的大小就是9X9,矩阵图的面基为81:
区分了Transit\Stub network后,由于N1和N5这两个Stub network不用在表示from的行中出现,那么矩阵图的大小就是9X7,面基为63:
通过以上的例子能看出区分Transit和Stub链路类型后,能节约一定的资源。
Loop back接口
Loopback接口的链路类型(Link type)永远被定义为Stub host(红茶三杯笔记中这里写的时Stub network link,但看过RFC以后,我感觉还是用RFC中的Stub host更严谨一些<To facilitate this, such interfaces are advertised in router-LSAs as single host routes, whose destination is the IP interface address.—RFC 2328,Page 68>),默认使用32位掩码表示,无论配置loop back的IP地址时使用24/的掩码也是如此。如果进入loop back接口在里面配置一条ip ospf network point-to-point命令,将这个loop back接口的网络类型由loop back 变为了point-to-point,那么这个loop back接口的掩码长度就由32位变成了24位。但必须强调的是,这里更改的是接口的network type也就是网络类型,而接口的链路类型(Link type)由二层封装决定,没有变化,所以Link type还是Stub host\Stub network,也可以说除了网络掩码发生了变化其他都没有变化。
实验验证
基础配置:
R7:
1 | router ospf 1 |
R8
1 | router ospf 1 |
实验分析
默认情况下,即使R7的loopback接口的IP地址配置成24/位掩码,但在R8的OSPF路由表中,依旧是32位掩码,因为此时R7的loop back 接口的Link type,也就是链路类型是stub host:
为了改变思科IOS默认将Loop back接口的掩码设置为32位的情况,我们在思科设备中只能将接口的网络类型(Network type)设置为点对点:
R7:
1 | interface Loopback0 |
在R7的loop back接口的Network type,也就是网络类型设置为点对点后,R8的路由表中R7loop back接口的掩码由32位变成了loop back地址中配置的24位掩码:
此时再看R7的loop back接口:
LSA实验
在图中,R1有三条链路,一条是右边的E0/1口的链路,连接着R2,一条是上边的通向192.168.1.0/24网络的链路,另一条是通往下边的另一个网段的链路。R1需要用1类LSA描述这三条链路并将LSA宣告给R2。R1要给R2(或其他路由器)提供三种信息:
- 一个ID,用于将自己标识为图中的节点;
- 链路邻接关系列表;
- 与链路上所有连接的节点的关系。
为了标识图中的节点,OSPF使用32位长度的数字作为这些节点在LSDB中的标识符,成为路由器ID,英文为Router ID,简写为RID。默认情况下,OSPF选择loop back接口中最大的IP地址作为RID,如果没有环回地址,路由器使用所有激活的物理接口中最高的IP作为RID。RID也可以在OSPF进程中用“router-id XXXXX”配置。当R1生成它的1类LSA时,它将使用1.1.1.1这个RID作为Link State ID和Advertising Router字段的值,具体如下:
接下来我们看四种链路类型之一的Stub network在1类LSA中的体现:
Describing Stub Network
R1是上面拓扑中的网段192.168.1.0/24中的唯一路由器,这种链路被OSPF分类为Stub network,因为该网段除了R1外没有其他的OSPF路由器,所以流量会从以该网段为起点或终点,但不会穿越该网段,换一种说法就是,网段192.168.1.0/24不会作为传输网段。
R1为Stub network类型的Link type在其1类LSA中建模,好像它是一个连接到另一个节点的链路,用网络前缀作为它的Link ID,用子网掩码作为Link Data。这样一来,这个网段看起来像是一个直接连接到R1上的节点。在所有1类LSA描述的链路邻接节点中,只有Stub network类型的链路描述中携带了网络层地址信息。下面是R1对链路类型为Stub network的192.168.1.0/24这个网段的描述:
1 | Link connected to: a Stub Network |
Link ID后面标注的是Network/subnet number,翻译成中文就是所描述网段的网络/子网前缀,在这就是192.168.1.0这个网络号,Link Data后面标注的是Network Mask,翻译成中文就是所描述网段的网络掩码,在这就是3个255。至此R1到192.168.1.0/24这个链路类型为Stub network的网段已经描述完毕,接下来看R1如何用1类LSA描述R1和R2之间的点对点链路。
Point-to-Point
R1上看到的描述这个P2P链路输出为:
1 | Link connected to: another Router (point-to-point) |
这个P2P链路描述了R1和R2之间直连的链路,Link ID字段后面标注的是Neighboring Router ID,翻译成中文就是链路另一端的邻居设备的RID,在这里也就是R2的RID2.2.2.2。Link Data字段标注的是Router Interface address,翻译成中文就是该本路由器连接到该链路的接口的IP地址,也就是R1的E0/1的IP地址,12.1.1.1。这里必须注意,Link Data字段并不包含地址信息,因此OSPF会用另一个Stub network的LSA来描述这个链路的掩码,Link ID是IP network/subnet number,也就是网络号或子网号,这里10.1.23.2/24这个网段的网络号是10.1.23.0;Link Data是网络的IP地址或子网掩码,这里的255.255.255.0就是这个网络的子网掩码。
1 | Link connected to: a Stub Network |
OSPF谎言
看起来OSPF在描述上面R1和R2之间的,链路类型为P2P的时候撒了个谎,因为在上面说过,在宣告P2P链路时有两条LSA,一个是P2P,用来描述直连到对方的链路,另一个是Stub network,用来描述掩码,但前面同样说过Stub network是没有邻居的,也不能用于传输穿越流量,而R1和R2是邻居关系,这条链路也承载穿越流量了,比如从R2到192.168.1.0/24的网段就是穿越流量,所以两者矛盾了。
但其实是,逻辑上R1将R2和12.1.1.0/24视作网络中的两个不同节点,当用SPF算法计算路由时,通向这两个节点的每条链路都作为独立的个体,当计算1.1.1.1和2.2.2.2这两个节点之间的路径时,用P2P链路的描述参数计算,当计算通向12.1.1.0/24的网络时,用Stub network链路的描述参数计算:
具体请参见该贴中的The OSPF Lie部分。
Type-2
概述
2类LSA的英文是Network-LSA,两个或多个路由器组成广播或NBMA类型的网络时,在DR和至少一个路由器形成全邻接状态(Full adjacency)后,会由DR产生2类LSA,2类LSA描述了包括DR本身在内的连接到网络的所有路由器。2类LSA在本区域内传播。2类LSA的Link state ID字段列出了DR接口的IP地址,这个IP地址和掩码地址(2类LSA中携带着掩码地址)做与运算后,可以得出网络号。
报文格式
LSA的Header部分之前分析过,这里只看message部分。
- Network Mask:网络的掩码。
- Attached Router:连接到网络的路由器的Router ID,事实上,只有那些和DR形成了全邻接关系(Full adjacency)的设备才会在这里面显示出来,DR的Router ID也会显示在这里面。
存在意义
只用1类LSA的情况
上图中R1、R2和R3各有一个接口在同一网段,是MA类型的网络,这种情况下,如果只用1类LSA中的P2P链路类型描述三个路由器之间的关系,而完全不用2类LSA的话,也可以描述,但只能一个一个链路的描述,也就是说一个路由器需要两条1类LSA描述,比如R1的话,需要节点1.1.1.1连接到节点3.3.3.3,1.1.1.1连接到4.4.4.4这两条1类LSA才能描述,只用1类LSA描述后的逻辑拓扑如下:
只用1类LSA描述网络的连接关系不仅看起来过于繁琐,也会使LSDB显得很臃肿,庞大的LSDB数据库在运行SPF算法计算路由时会极大的消耗路由器的内存,再具体的解释请参见这个帖子。
使用2类LSA的情况
用2类LSA描述MA网络信息的方式,就是构筑一个虚拟的节点,这个虚拟节点表示这个MA网络的网段,并让该网段上的每个路由器向新节点通告他们的关系:
如果上图的连接转换成语言描述的话就是:1.1.1.1、4.4.4.4和3.3.3.3这三个节点都连接到134.1.1.4这个Transit network上。这样宣告几台路由器之间的MA网络及连接关系占用的空间比较少,OSPF认为134.1.1.4这个节点为其他与之相连的路由器(图中就是1.1.1.1、3.3.3.3、4.4.4.4)提供了连接,并将134.1.1.4这个节点视作另一个虚拟路由器。在134.1.1.0/24网段中会选举出DR,前面说过,DR\BDR是接口属性,从这里也能看出来原因,因为三台路由器各有一个接口连在这个网段中。选出的这个DR生成2类LSA宣告相关信息。在这个拓扑中,在几台路由器R4的Router ID是4.4.4.4比其他路由器的Router ID大,所以一般情况下,R4会被选举(选举过程详见之前的DR\BDR选举)为该网段的DR并宣告2类LSA,该LSA中携带着以下信息:
- R4用自己在134.1.1.0/24的接口的IP地址134.1.1.4,作为虚拟节点产生的2类LSA的Link State ID;
- 由R4产生的2类LSA,包含着和该虚拟节点相连的所有路由器的列表,也就是后面的Attached Router。
下面来看由R4生成的这条2类LSA,这条LSA描述的是134.1.1.4这个虚拟节点以及该虚拟节点连接的1.1.1.1、3.3.3.3、4.4.4.4这三个节点。因为2类LSA的Link State ID是DR的IP地址,所以其他路由器使用DR的IP地址加上后面的Network mask,也就是部分写的是/24,这两个做与运算后就是网络号,134.1.1.0/24:
1 | R1# show ip ospf database network |
连接到134.1.1.0/24网段中的R1这个路由器,用一个链路类型为Transit network的1类LSA去描述R1和虚拟路由器之间的链路:
1 | R1# show ip ospf database router self-originate |
上面描述的这个链路类型为Transit network的链路时,Link ID为134.1.1.4,既是DR(R4)在网段134.1.1.0/24上接口的IP地址,也同样时虚拟路由器的Link State ID,这个值是134.1.1.4;这条Transit network链路的Link Data部分,是R1连接到134这个网段上接口的IP地址,这个值是134.1.1.1 。
上面这两条LSA组合到一起可以后描述了R1的链路情况,节点1.1.1.1通过一个Transit link类型的链路连接到一个虚拟节点134.1.1.4,掩码为24/。这个虚拟节点连接到了节点1.1.1.1、3.3.3.3和4.4.4.4 。
特殊情况分析
A router that has formerly been the Designated Router for anetwork, but is no longer, should flush the network-LSA thatit had previously originated. This LSA is no longer used inthe routing table calculation. It is flushed by prematurely incrementing the LSA’s age to MaxAge and reflooding.
如果一个路由器接口的角色由DR变成了非DR,那么它应该刷新之前产生的那条2类LSA,因为之前这个接口还是DR时会产生2类LSA,并将LSA中的age字段设置为最大,也就是3600秒,使这条2类LSA过期,好让其他路由器从LSDB中将这条已经不适用于计算路由的2类LSA删除,因为其他路由器并不能删除那些不是本身产生的LSA。
In addition, in those rare cases where arouter’s Router ID has changed, any network-LSAs that were originated with the router’s previous Router ID must beflushed. Since the router may have no idea what it’s previous Router ID might have been, these network-LSAs are indicated by having their Link State ID equal to one of the router’s IP interface addresses and their Advertising Router equal to some value other than the router’s current RouterID .
此外,在那些路由器的Router ID改变的极少数情况下,任何之前产生的带有旧的Router ID的2类LSA都必须被刷新成带有新Router ID的2类LSA,比如在MA网络中的R12的E0/1接口角色为DR,这台路由器一开始的Router ID是1.1.1.1,后来通过配置将Router ID改成了2.2.2.2,这时候这台路由器就得重新发送2类LSA通告其他路由器它的Router ID进行了更改,因为之前2类LSA中的Advertising Router部分是DR的Router ID,而这个Router ID已经发生了变化。2类LSA的Link State ID字段的值为该路由器接口之一的IP地址,Advertising Router字段的值为路由器当前Router ID以外的值。
Type-3
概述
1类和2类LSA解决了区域内路由计算问题,计算并生成了标识为O的区域内路由,解决了区域内部的通信问题,那么区域间的路由怎么办呢?如果路由器需要访问其他区域呢?这时就需要3类LSA。3类LSA是网络汇总LSA,由ABR路由器生成,3类LSA与1类2类LSA不同的是,3类LSA不是详细描述一个区域种存在着哪些节点以及这些节点之间如何连接,它描述的是一个网络号、AS边界路由器或一个IP地址范围段(The destination described by a summary-LSA is either an IP network, an AS boundary router or a range of IP addresses——RFC2328 - Page 135),也可以理解成是路由表中需要通告给其他Area的路由条目的网络号,也就是网络前缀。3类LSA通告范围只有一个区域,也就是把3类LSA传递给邻接的Area0(flood them into the other areas to which it is attached),再由Area 0的ABR生成到其他非Backbone区域的3类LSA。
OSPF的网络号
在一个多区域OSPF网络中,存在着两种不同的路由,区域内路由和区域间路由,这两种路由也有对应的网络号(网络前缀):
- 区域内:来自区域内路由的网络号;
- 区域间:来自区域外路由的网络号;
OSPF的层次结构
还必须了解一下OSPF的层次结构。为了提高抗路由环路能力,OSPF将拓扑分成两层,顶层是Area 0,也就是Backbone Area(骨干区域),下层是除了Area 0之外的其他Area。所有的区域必须和最顶层的Area 0相连接,所有的3类LSA通过位于顶层的骨干区域进行交换后,再发送到下层的其他Area中。这种层次的结构去交换3类LSA就相当于创建了一个下图的“Hub-and-Spoke”(中心辐射型)类型的拓扑:
3类LSA的泛洪
由于采用了层级设计,有区域间、区域类两种路由要传递,且3类LSA的通告范围只有一个区域,所以3类LSA的泛洪方式如下:
- ABR会为骨干区域的区域内路由和区域间路由产生3类LSA,并将3类LSA从骨干区域泛洪到非骨干区域;
- ABR会为非骨干区域的区域内路由产生3类LSA,并将3类LSA从非骨干区域泛洪到骨干区域;
- ABR使用SPF算法计算路由时,只会用骨干区域产生的3类LSA进行计算。
比如上面的拓扑中,ABR1会为Area 1这个非骨干区域的内部路由生成3类LSA,并将该LSA泛洪到骨干区域Area 0,同样ABR1也会为骨干区域Area 0的内部路由和外部路由(剔除出原属于Area 1这个区域的路由后)生成3类LSA并将该LSA泛洪到Area1这个非骨干区域。
上面的算法意味着ABR只有连接到Area 0的时候才会产生3类LSA,在思科设备中ABR是这个工作模式,但可能其他厂商的设备中会有所不同。
有些人认为,3类LSA的通告范围是除了特殊区域的整个OSPF网络,但实际上这种说法是不严谨的,比较严谨的说法是3类LSA的通告范围只有一个区域,也就是邻接的其他那个区域。比如下面这个拓扑中,身处Area256中的R5身后192.168.5.0/24这个网段,由所在区域Area 256的ABR路由器R2生成3类LSA泛洪到Area 0中,这时可能有人要问,如果你说3类LSA的通告范围是邻接的一个区域,那么这个代表192.168.5.0/24网段的3类LSA就不会泛洪到Area 37或Area 489了,可实际实验中这两个区域是有192.168.5.0/24这个OIA的区域间路由的,这和上面3类LSA传播范围只有一个区域的说法矛盾了。是这样,R2生成的这条3类LSA发送到Area 0后,如果想将192.168.5.0/24这个OIA区域间路由用3类LSA继续传递给Area 37或Area 489,这时候R3会为Area 37重新生成一条3类LSA然后传递到这个区域中,R4会为Area 489重新生成一条3类LSA传递到这个区域中,也就是说这条由R2生成的3类LSA由Area 256泛洪到Area 0以后这条3类LSA的泛洪就结束了,如果要继续泛洪到其他Area,就要由其他的ABR,比如R3或R4重新生成,虽然表示192.168.5.0/24这条路由的的3类LSA在每个Area中都有,但由于每过一个区域就要重新生成一次3类LSA,所以严格来说已经不是同一条LSA了,因为这两条LSA的Advertising Router不同。
LSA实验
查看路由器R2的LSDB得到如下结果:
1 | R2#show ip ospf database |
这里需要注意,由于是多区域的拓扑,R2在Area 0和Area256中间,所以R2分别为这两个区域生成了1类LSA。R2的Area 0中的1类LSA中并没有R5或者R6,是因为这两个路由器处于Area 256中,同理R1、R3、R4这三个属于Area 0的路由器的1类LSA也没出现在Area 256中。show ip ospf database给出的是LSDB的摘要情况,现在我们来看看R1(Area 0)和R6(Area 256)上的1类LSA,也就是Router LSA:
1 | R1#show ip ospf database |
1 | R6#show ip ospf database |
从拓扑图中可以看到,R1、R6、R7、R8和R9这几台路由器的全部接口都在单一区域内,所以这几台路由器只有他们所在区域的拓扑信息,比如R7只有Area 37的信息,R8和R9只有Area 489的信息。因为R2、R3和R4这三台路由器的接口连接到了多个区域,所以它们是ABR(Area Border Router),也就是区域边界路由器,它们有所连接所有区域的拓扑信息,比如R2有接口在Area 256和Area 0中,所以它会有Area 256和Area 0的拓扑信息。
为了提供不同区域之间的连通性,作为ABR的R2执行了以下四个步骤:
- 查询路由表中来自Area 256的所有区域内路由条目;
- 将这些区域内的路由条目作为3类LSA宣告进骨干区域,Area 0;
- 查询路由表中来自骨干区域Area 0的区域内路由和区域间路由的网络号;
- 将这些网络号,剔除出原本属于Area 256区域的路由后,以3类LSA的形式泛洪到非骨干区域Area 256。
来看R2路由表中关于前缀192.168.5.0的条目:
1 | R2# show ip route ospf | include 192.168.5.0 |
注意这条路由最前方用的标识是“O”,也就是说这条路由对于R2来说是区域内部的路由,所以按照上面提到的四个步骤,R2将会把这条属于Area 256的内部路由用3类LSA宣告并宣告进Area 0,现在来看看关于192.168.5.0这个网络号的3类LSA:
1 | R2#show ip ospf database summary 192.168.5.0 |
R2的Link State ID后面的备注是summary Network Number,说明该值为需要汇总那条路由的网络号也就是192.168.5.0;路由的子网掩码在‘Network Mask’中体现,为24/位;Advertising Router的值设为自己的Router ID,因为3类LSA由ABR产生而自己就是ABR。最后我们可以看到这条LSA发送到了Area 0中:Summary Net Link States (Area 0)。
在Area 0 中的路由器会进行以下步骤:
- 将这条3类LSA发送过来的网络前缀放入路由表中;
- 运行SPF算法算出到2.2.2.2这个路由器的最短路径;
- 在路由计算时加入LSA中的Metric值进行计算。
执行完以上步骤后,会计算出区域间的路由前缀,在路由表中用“O IA”进行标识:
1 | R1#show ip route ospf | i 192.168.5.0 |
距离矢量特征
执行完以上的所有3类LSA需要的步骤后会发现,这些步骤和距离矢量路由协议执行的步骤相同,只是简单的将路由前缀、方向(发给路由器2.2.2.2也就是3类LSA的Advertising Router)和Cost(在这个例子中是Metric:11)通告给邻居。这样一来,在区域间添加或删除路由前缀时不需要经过完整的SPF计算。当删除区域间路由时,只需要R2这个ABR将这条3类LSA中的LS age字段设置为超过3600的值,即表示这条LSA已经过期,其他路由器就会将它们LSDB中的条目删除。看完这一段,是不是发现OSPF这个链路状态协议的区域间路由,其实和RIP这种距离矢量协议比较像,都是告诉其他路由器区你要去往X网段发给我就行,是基于传闻的,运行OSPF的路由器只知道本区域内的拓扑但并不知道其他Area的连接方式,具体参照红茶三杯的这篇博文,这里就不再赘述了。
传播范围验证
下面来验证刚才说的3类LSA传播范围,先看Area 256区域中192.168.5.0/24这条路由的的3类LSA:
1 | R2#show ip ospf database summ 192.168.5.0 |
再来看Area 0中的:
1 | R1#show ip ospf database summ 192.168.5.0 |
Area 37中的:
1 | R7#show ip ospf database summ 192.168.5.0 |
Area 489中的:
1 | R9#show ip ospf database summ 192.168.5.0 |
Area 256和Area 0中的LSA是一样的,但和Area 37以及Area 489中的LSA不同,说明3类LSA的泛洪距离为一个Area,想泛洪到其他Area中的话,必须由连接到其他Area的ABR重新生成LSA。
Type-5
概述
1 、2类LSA解决了本区域的路由,3类LSA解决了区域间的路由,如果有从外部注入的路由信息该如何表示呢?这种外部注入的路由信息可能是通过重分布注入的其他路由协议的路由,亦或是由其他OSPF进程重分布进本OSPF进程的路由,比如说一个公司A并购了同一楼层的另一个公司B,A公司网络所采用的的网络协议是OSPF,但B公司的网络用的是RIP,两个公司在同一层楼,为了方便交换信息需要把网络连接起来,这时候该如何处理呢?这时就要用到5类LSA了,也就是AS external link advertisement。5类LSA描述的是去往AS外部路由,由ASBR(AS boundary routers)路由器生成,泛洪范围为所有Area,5类LSA也是唯一一种泛洪到除了特殊区域(Stub, Totally Stubby and Not-so-stubby areas)之外的整个AS的LSA(’AS-external-LSAs are the only type of LSAs that are flooded throughout the entire Autonomous System; all other types of LSAs are specific to a single area.However, AS-external-LSAs are not flooded into/throughout stub areas’——RFC 2328,Page 40)。LSA的Link State ID的值为目标网络的IP地址,当5类LSA的Link State ID设置为0.0.0.0时,LSA用来描述到AS的默认路由。ASBR路由器通过另一个路由协议(比如BGP)或通过配置信息(比如配置静态路由然后重分布)学到外部路由,并为这些学到的外部路由生成一个5类LSA。
报文格式
- Network Mask:被宣告路由的IP地址的子网掩码;
- E位:标识了外部路由的Metric类型。Metric有两种类型,1和2,当E位置1时,表示该路由为OE2,此时这条路由的cost值为ASBR到外部目标网络的值,固定为20;当E位为0时,表示该路由为OE1,此时这条路由的cost值为整个路径的cost值,也就是外部路由到ASBR的cost,与内部路由到ASBR的cost,两者之和。具体差别详见后面的OE1 VS OE2部分。
- metric:表示这条路由的cost值,取决于之前E位的取值,具体见后面的OE1 VS OE2部分。
- Forwarding address:要发送到外部路由的数据将被发送到Forwarding address这个地址中,如果该字段被设置为0.0.0.0,则数据将被发送到这条LSA的起源路由器,例如ASBR路由器。必须注意的是,当Forwarding address字段不为0.0.0.0时,此字段应指向一个属于其他AS的地址,也就是一个不属于OSPF协议的地址。Forwarding address字段也可以指向一个默认路由,这时Link State ID字段设置为默认路由的目的地址。
- External Route Tag:为路由打上标签,防止重分布时产生路由环路。
OE1 VS OE2
E1类型路由的cost值,不仅包含了内部路由到达ASBR的cost值,还包括了ASBR到达外部路由的cost,所以E1的cost值是上面提到的两个cost值之和,而E2路由并没包含内部到达ASBR的cost值。看下面图表中的例子能更好的理解E1、E2两种外部路由类型的区别:
拓扑如上图所示,有一个外部网段10.1.1.0/24,通过R3重分布进OSPF协议,此时这条外部路由的seed metric(seed metric一般翻译成初始度量值或种子度量值,个人觉得初始度量值更容易理解。主要是因为各种不同的路由协议计算度量值的方法不一致,如RIP是跳数,OSPF则基于带宽,所以使用seed metrics建立一个标准的重分布metric值。)为20,这个seed metric对于E1和E2来说都是存在的。现在轮到R2计算去往外部网段10.1.1.0/24的metric/cost值了,这时E1和E2两种外部路由类型计算的方式出现了不同:
当这条路由为O E1时:R2会把R2和R3之间的cost值,也就是cost=1,加上外部路由原有的seed metric值,也就是20,二者之和就是1+20=21,把21当作外部网段10.1.1.0/24的cost值;R1则会在R2的cost=21的基础上再加上R1到R2的cost值,也就是说R1会认为到10.1.1.0/24这条路由的cost为1+1+20=22。
当这条路由为O E2时:R2只会计算外部网段10.1.1.0/24的seed metric值,而不会加上R2和R3之间的cost值,也就是说E2类型的外部路由的cost值恒为20,R1也将20视为这条外部路由的cost值。
LSA实验
上面拓扑中的5类LSA由R6产生,这条LSA中包含着以下三种重要信息:
- Link State ID字段的备注时External Network Number,也就是被注入OSPF路由协议的外部网段的网络号,在本例中被注入的网段是172.16.56.0/24和172.16.65.0/24;
- Advertising Router字段是ASBR路由器的Router ID,在本例中是R6的Router ID,也就是6.6.6.6;
- Forwarding Address字段的值为0.0.0.0,表示所有的其他路由器想给外部注入的网段发送数据时,只要将数据发送给ASBR路由器,也就是R6即可。
1 | R6#show ip ospf database external |
这两条5类LSA也可以简单的理解为“去往外部网段172.16.56.0/24和172.16.65.0/24的数据可以通过节点6.6.6.6到达”,由于可以通过6.6.6.6去往外部网段,所以问题从“如何去往外部网段172.16.56.0/24和172.16.65.0/24”,变成了“如何去往节点6.6.6.6”。在Area 256域中的路由器,比如R2或R5,知道如何前往节点6.6.6.6,因为他们的LSDB中有ASBR6.6.6.6的1类LSA(1类LSA描述了路由器在本区域内链路的状态,通告了直连这个区域接口的信息,所以R5有足够的信息知道去往R6的路径):
1 | R5#show ip ospf database |
1 | R5#show ip ospf database router 6.6.6.6 |
从上面的例子我们可以看出,在ASBR所在的Area中,1类LSA扮演了一个重要的角色,这个角色就是让ASBR域内的其他路由器获知到ASBR的路径,也就是如何到R6。但不在ASBR的Area的路由器的LSDB中,没有像R5一样有通告R6位置的1类LSA,毕竟1类LSA的泛洪范围只限于本Area中:
1 | R1#show ip ospf database |
这时候就需要4类LSA来告诉其他Area的路由器如何到达ASBR了。
Type-4
概述
由于5类LSA需要泛洪到AS中的所有Area中,而其他区域中的路由器并没有关于ASBR的LSA,不知道去往ASBR的路径,在这种情况下,ASBR所在区域的ABR会产生4类LSA,用来告知其他Area的路由器如何前往ASBR,所以4类LSA由ASBR所在区域的ABR生成,泛洪范围也是一个区域,4类LSA泛洪到骨干区域后,其他的ABR将重新生成一个4类LSA并将其扩散到自己的区域中。4类LSA对于那些处于非ASBR区域的区域来说,有以下两个重要的作用:
- 为其他Area的LSDB注入关于ASBR的拓扑信息;
- 使得其他Area的路由器能够选出最佳路径。
关于第一点,4类LSA会告知所有在其他Area的路由器,它们所在区域的哪台路由器有足够的信息可以到达ASBR。这样就能让其他Area的路由器做区域间路由查找,解决去往ASBR的路径问题。第二点适用于Area中有多个ABR且这些ABR到达ASBR的cost值不同的情况,当生成4类LSA时,ABR会列出它自身去往ASBR的cost值,该区域的路由器就可以根据列出的ABR值知道哪个ABR有到达ASBR的最佳路径。没有4类LSA的话,在其他Area中的路由器无法知道选择哪个ABR有前往ASBR的最佳路径了。名称中的这个summary的含义,也就是说在一个有多ABR的Area中,summary这些ABR到达ASBR的cost值,让其他路由器知道选择哪个ABR去ASBR,能算出整条路经的cost值。
为什么不把5类LSA限制在ASBR这个区域内,让它乱跑不是增加网络负担嘛?对于常规区域的OSPF设计而言,5类LSA的确是可以在OSPF区域内到处乱跑,在某些场合,可能由于OSPF网络的设计,使得OSPF路由器需要维护大量的外部路由,从而导致设备负担过重,那么你可以进行OSPF规划上的调整,例如使用特殊区域——Stub Area、NSSA Area的来优化网络。这些特殊区域能够限制4类LSA或5类LSA的泛洪,并用默认路由来解决网络连通性的问题,因此一来降低了外部路由条目过多带来的影响,二来也解决了去往AS外的连通问题,然而这也带来了一个问题,就是丢失了外部路由的精细度,只知道去往外部路由如何去,但不知道具体有那些路由,好比之前我跟你说的是韩国的妹纸ABCD都很漂亮,现在告诉你韩国的妹纸都不错,你去就是了,这就是所谓的丢失路由的精细度,这在某些特定的网络环境中可能会带来诸如次优路由等等的问题。
LSA实验
在上面的拓扑中,R6在重分布外部路由进入OSPF时,它的1类LSA中的Flags字段表示R6现在已经时一个ASBR路由器了:
1 | LSA-type 1 (Router-LSA), len 60 |
Flags字段中的E位置1时,会告知并提醒Area中的ABR(R2),R6将外部信息注入到了OSPF中,也可以用’show ip ospf database router 6.6.6.6’这条命令查看:
1 | R5#show ip ospf database router 6.6.6.6 |
和ASBR(R6)同一个Area的ABR(R2)会产生4类LSA并泛洪到所有和ABR相连接的域中,在上面的拓扑中,也就是R2会产生4类LSA泛洪到Area 0中,为了告诉Area0中的路由器如何到达ASBR路由器,也就是到达R6的路径:
1 | R2#show ip ospf database asbr-summary |
必须注意的是,没有必要将4类LSA泛洪到ASBR(R6)所在的Area 256中,因为前面说过,Area 256中的路由器中的LSDB有足够的信息让它们有到达ASBR的路径。
4类LSA中的Advertising Router字段的值为2.2.2.2,Link State ID(后面的补充信息为AS Boundary Router address,也就是ASBR的地址)值为6.6.6.6,这两个值合起来看表示R1、R3和R4为了到达ASBR(R6),必须有到达R2的最短路径,因为ABR将它自己设置成为宣告4类LSA的路由器,这些4类LSA的泛洪范围不像5类LSA那样覆盖所有的Area,4类LSA的泛洪范围只有1个Area。R2上的4类LSA其实就是在告诉其他路由器:通过我可以到达ASBR 6.6.6.6,我到ASBR的cost值是20。其他拓扑中的ABR路由器,R3和R4,会重新生成一条信的4类LSA,将它们自己设置成为LSA中的Advertising Router,例如Area 489中的4类LSA:
1 | R4#show ip ospf 1 489 database asbr-summary |
4类LSA中有ASBR的RID、宣告这条4类LSA的ABR的RID以及ABR到ASBR的cost值。
1-5类LSA组合说明
分别看完了1-5类LSA,是否感觉它们各自为战并没有组成一个有机的整体呢?事实上LSDB中不同类型LSA是用某些因素串联起来的,这些因素就是Link State ID以及Link ID。利用这些关键因素,LSDB掌握了计算两个节点之间最短距离的所有关键信息。接下来用上面的拓扑中的,R1是如何计算到网段192.168.8.0/24,以及到外部网段172.16.65.0/24的路径为例,具体说说各类LSA是如何在LSDB中组合使用去计算路由的。在每次计算路由发现下一跳时,R1会结合使用Link State ID和Link ID,将二者当作R1计算出下一跳并最终到达目标节点的关键因素。
到192.168.8.0
先看R1的LSDB中关于192.168.8.0/24的条目:
从R1的LSDB中能看到,关于192.168.8.0/24的LSA为3类LSA,所以下面看这条LSA的具体内容:
1 | R1#show ip ospf database summary 192.168.8.0 |
从这条3类LSA中可以看出,192.168.8.0这个网段由R4宣告(Advertising Router: 4.4.4.4)进本Area,cost值为21(Metric: 21),R1把4.4.4.4当作关键因素,接下来查找去往节点4.4.4.4的LSA,也就是说问题由’R1如何去往192.168.8.0/24网段’变成了’R1如何去往节点4.4.4.4’,因为这个3类LSA由R4宣告,前面说过3类LSA相当于R4告诉其他路由器,我R4到192.168.8.0/24网段的cost是21,去往该网段的数据交给我就能到达,这时R1查找去往R4的LSA,并找到了一条1类LSA能到达节点4.4.4.4:
1 | R1#show ip ospf database router 4.4.4.4 |
从上面可以看到,R1去往R4有两条链路(link),一条是链路类型为Stub network的192.168.4.0,另一条是链路类型为Transit Network的134.1.1.4。前面我们说过,Stub network无法承载穿越流量,所以不能用这条link到达R4;后面的Transit network能够承载穿越流量,这条link是到达134.1.1.4这个虚拟网络节点的,R1用134.1.1.4作为关键因素,问题由’R1如何去往192.168.8.0/24网段’,发展成’R1如何去往节点4.4.4.4’,再发展成’R1如何去往虚拟节点134.1.1.4’,因为要去往节点4.4.4.4,必须先到达虚拟节点134.1.1.4。R1此时去LSDB中查找关于134.1.1.4的LSA,可以看到是一条2类LSA,来看看具体这条2类LSA:
1 | R1#show ip ospf database network 134.1.1.4 |
R1发现134.1.1.4这个虚拟节点有通往节点1.1.1.1的链路,也就是有通往R1的链路。所以上面’R1如何去往虚拟节点134.1.1.4’的问题有了部分答案,也就是R1可以去往虚拟节点134.1.1.4,至于如何去,还要继续看LSDB,所以R1要查看自己的哪条链路能够到达虚拟节点:
1 | R1#show ip ospf database router self-originate |
从上面的1类LSA中能看出,R1可以去往虚拟节点134.1.1.4,因为它有一条和虚拟节点相连接的Transit network,只要将数据从R1的134.1.1.1接口发出就能到达虚拟节点134.1.1.4。所以问题由’R1如何去往192.168.8.0/24网段’,发展成’R1如何去往节点4.4.4.4’,再发展成’R1是否能去往并如何去往虚拟节点134.1.1.4’,答案是R1能去往虚拟节点134.1.1.4,因为R1的1类LSA中有一条Transit network能到达虚拟节点134.1.1.4,只要将数据从R1的IP地址为134.1.1.1的E0/0接口发出即可。所以R1将R4接口地址134.1.1.4作为下一跳,加上cost值21,写入RIB表中,得到了以下结果:
1 | R1#show ip route ospf | include 192.168.8.0 |
当然R1也会计算经由R3去往虚拟节点134.1.1.4的路径,但该路径的cost值为31,大于经由R4前往虚拟节点的cost值。具体怎么得到的31想彻底搞懂的麻烦自行翻译:
NOTE: R1 will also calculate R3’s path to reach the pseudo-node, but the cost value would be 31 vs the 21 of going directly to R4. This is because R1 would forward to R3, which would forward to R4. R4’s cost to the pseudo-node is not used in R1’s calculation, because it is the incoming interface and not the outgoing interface for the traffic. This leads to the cost of 21 instead of 31. In R3’s case, R3’s interface would be used to both receive R1’s packet and forward the packet to R4, which is why it is added in the total cost of the path.
到172.16.65.0
为了将数据发送到外部网段172.16.65.0/24,R1开始在LSDB中查找相关条目:
R1发现一条5类LSA有到达该网段的信息:
1 | R1#show ip ospf database external 172.16.65.0 |
从上面的5类LSA中可以看出,由于Metric字段值为20,Forward Address字段的值为0.0.0.0(当该字段为0.0.0.0时,数据将被发送到这条LSA的起源路由器,ASBR路由器,在这里就是R6)且Advertising Router字段的值为6.6.6.6,说明要将数据发送给外部网段172.16.65.0/24,只需要将数据发送到R6,R6到达外部网段的cost为20。这时问题由’R1如何将数据发送到外部网段172.16.65.0/24’,发展成’R1如何将数据发送给R6’,因为R6宣告的5类LSA中的Forward Address字段的值为0.0.0.0,说明发送给外部网段的数据发送到R6即可,从R6可以到达外部网段,cost值为20。由于R1和R6处于不同Area,R1就需要以自己为根构建一个到R6的SPT(shortest path tree,最短路径树),大概意思就是要找到一条去往R6的最短且无环路的路径。这时R1会用LSA中的Advertising Router字段的6.6.6.6为关键因素,去查找如何去往节点6.6.6.6,上面说过,由于和ASBR不在同一个Area的其他路由器不知道如何前往ASBR,所以会用4类LSA告诉其他区域的路由器,如何去往ASBR,这里来看4类LSA是如何宣告RID为6.6.6.6的ASBR的位置的:
1 | R1#show ip ospf database asbr-summary |
通过4类LSA中的Advertising Router: 2.2.2.2和Metric: 20部分,R1知道节点2.2.2.2可以到达节点6.6.6.6,cost值为20,节点2.2.2.2可以到达节点6.6.6.6,也就是到达ASBR。所以问题由’R1如何将数据发送到外部网段172.16.65.0/24’,发展成’R1如何将数据发送给节点6.6.6.6,R6’,继续发展为’R1如何将数据发送给节点2.2.2.2,R2’,因为数据要达到6.6.6.6先要发送给2.2.2.2才行。这里R1用2.2.2.2作为关键因素查找去往节点2.2.2.2的路径,R1中有一条2.2.2.2的1类LSA:
1 | R1#show ip ospf database router 2.2.2.2 |
这条1类LSA中的Stub Network无法承载穿越流量,所以无法使用,它还有另一条通往节点1.1.1.1的P2P链路,这条链路说明R1和节点2.2.2.2是相连接的,相互连接自然在一个Area中,所以这时R1以自己的RID为关键因素,查看1类LSA。问题由’R1如何将数据发送到外部网段172.16.65.0/24’,发展成’R1如何将数据发送给节点6.6.6.6,R6’,再发展为’R1如何将数据发送给节点2.2.2.2,R2’,因为R1和2.2.2.2相连,继续发展成’R1如何连接到节点2.2.2.2’:
1 | R1#show ip ospf database router self-originate |
R1查看自己的1类LSA后发现自己IP地址为12.1.1.1的E0/1接口,有一条P2P链路和节点2.2.2.2相连,cost值为10,所以问题由’R1如何将数据发送到外部网段172.16.65.0/24’,发展成’R1如何将数据发送给节点6.6.6.6,R6’,再发展为’R1如何将数据发送给节点2.2.2.2,R2’,这个问题解决了,也就是把数据从12.1.1.1的P2P接口发送出即可,下一跳设置成为对端的12.1.1.2,也就是R2和R1相连的的E0/1口即可。但要注意,R1不会为外部网段增加cost,因为这里的外部路由类型为E2,cost值恒为20:
1 | R1#show ip route ospf | include 172.16.65.0 |
本例引用自这篇文章,这个例子只是简单说明各类LSA的使用方式,在实际中,R1使用一种更彻底的方法来构建其SPT,这里就不继续写了,因为我还不会,等会了也许会继续更新本章。
Type3、Type4报文格式
由于3类LSA和4类LSA的格式几乎一样,所以RFC上将二者合并起来写的,笔记这里也用这种方式介绍这两种LSA的报文格式。
- Network Mask:在3类LSA里,这个字段表示目标网络IP地址的掩码;在4类LSA里,这个字段没有实际意义必须取值为全0。
- Metric:这条路由的cost值。和1类LSA中的接口的Cost值一个意思。
为了和之前的OSPF版本规范相兼容,LSA中还可以包含TOS-specific信息,TOS字段值的不同表示不同的意思,一般情况下为全0,表示‘normal service’。
TYPE 6
6类LSA(OSPF GROUP MEMBERSHIP LSA)是OSPF中的组播,但现在已经被PIM所代替,思科设备根本就不支持6类LSA,所以这里就不继续提了。
TYPE 7
概述
7类LSA又叫做not-so-stubby-area(NSSA) LSA,因为NSSA区域不让外部LSA,也就是不让5类LSA进入,所以为了将外部路由引入NSSA area,就要用7类LSA。7类LSA由NSSA ASBR生成,只在原始NSSA区域中泛洪,也就是生成这个7类LSA的NSSA区域中泛洪,不会进入其他常规区域。
报文格式
Options字段:
E位
5类LSA不能泛洪到Stub区域和NSSA区域中,E比特确保Stub区域和NSSA区域中的所有路由器都同意5类LSA不能泛洪进入的区域属性。E位只在Hello包和DBD包中有意义。当某一特定接口发出的Hello包中的E位置0时,意味着这个接口不会发送也不会接收5类LSA,换句话说这个接口连接到的是Stub区域或NSSA区域。两个路由器只有在对E位匹配时,也就是E位数值相同时才能成为邻居。
- E位:5类LSA不能泛洪到Stub区域和NSSA区域中,E比特确保Stub区域和NSSA区域中的所有路由器都同意5类LSA不能泛洪进入的区域属性。E位只在Hello包和DBD包中有意义。当某一特定接口发出的Hello包中的E位置0时,意味着这个接口不会发送也不会接收5类LSA,换句话说这个接口连接到的是Stub区域或NSSA区域。两个路由器只有在对E位匹配时,也就是E位数值相同时才能成为邻居。
N/P位
- N位:N位决定了路由器是否支持NSSA。N位只在Hello包中有作用有意义,N位确保了区域内所有路由器都同意NSSA区域的属性。当特定接口发出的Hello包中的N位置1时,表示路由器将从那个接口中接收和发送7类LSA。两个路由器只有在N位互相匹配时,也就是N位数值相同时才能成为邻居。如果一个路由器的N位置1,那么它的E位必须置0。因为N位置1意味着能接收发送7类LSA也就是该区域为NSSA area,但如果E位置1意味着能接收发送5类LSA,二者相互冲突,而NSSA area中不能存在5类LSA。
- P位:P位只在7类LSA的Header中使用。置1时标识NSSA的边界路由器可以将7类LSA转换成5类LSA。通常P位置0。
N/P位其实是一个字段,在Hello包中,该位是N位,用来协商路由器是否支持NSSA区域:
在7类LSA的Header中,该位是P位,用来标识NSSA的边界路由器是否能将7类LSA转换成5类LSA:
其他LSA
Type8、Type9两种LSA属于在IPV6情况下的OSPF V3版本使用,会在IPV6部分笔记中涉及;Type10、11属于MPLS-TE使用,会在MPLS中进行讨论。
区域种类
- Backbone area - The backbone area is the core of the OSPF network. Furthermore, OSPF states that every area must be connected to the backbone area (aka area 0).
- Standard areas - This is an area that is not “stub based”. This includes the backbone area.
- Stub area - With stub areas external routes are not propagated into the stub area by the ABR but replaced with a default route instead. This reduces the OSPF topology along with LSA overhead.
- Totally stubby area - This area is the same as a stub area with the addition that they do not receive type 3 LSA’s. The ABR injects a default route.
- Not-so-stubby area - Also known as NSSA, is an area similar to a stub area but with the addition of an ASBR.
Backbone Area:翻译成中文是骨干区域,也被称为区域0或区域0.0.0.0,骨干区域组成了OSPF网络的核心,所有其他区域都必须和骨干区域(Area 0)相连接,要么直接连接要么经过其他路由器和骨干区域相连,比如通过虚链路和Area 0相连,这样做是因为OSPF的所有非骨干区域之间不能直接传递LSA,必须将非骨干区域的LSA信息发送给骨干区域,再由骨干区域发送到其他区域,这样做的目的是因为OSPF的各区域间的路由是距离矢量路由(对,你没看错确实是距离矢量,我看到以后也很难以置信,但它就是距离矢量路由),所以很容易出现环路,为了避免环路强制其他区域的区域间路由先发送到Area 0 再发送给其他区域。
Standard areas:翻译成中文是标准区域,也就是除了Stub area以外的其他area,上文的骨干区域(区域0)也属于标准区域,绝大多数的区域都是Standard area。标准区域中可以存在1、2、3、4、5类LSA,也可以存在ASBR路由器。
Stub area:翻译成中文是末节区域,在Stub area中,外部路由不会通过ABR路由器直接传播进Stub area,而是采用自动下发默认路由的方式代替,这条默认路由代替了所有外部路由。这样减少了路由器的LSDB的大小从而能够减少内存消耗。Stub area中不允许引入外部路由,就是4、5类LSA。
Totally stubby area:翻译成中文是完全末节区域,这个区域和之前的Stub area的性质一样,不过和Stub area的区别在于也不能有3类LSA存在,也不允许引入外部路由,综合起来就是不允许有3、4、5类LSA的存在,同时自动下发一条默认路由(以3类LSA形式,自动下发的3类LSA是允许的)。
Not-so-stubby area:翻译成中文是非完全末节区域,另一种英文叫法是NSSA区域,和之前的Stub area性质一样,不过和Stub area的区别在于域中可以有ASBR路由器,由于ASBR既运行了OSPF协议,也运行了其他路由协议,所以表示非完全末节区域中可以引入外部路由,综上所述,NSSA区域内不允许有4、5类LSA,但外部路由可以用7类LSA的形式在NSSA中泛洪,但由于7类LSA不允许进入包括骨干区域在内的常规区域,所以NSSA的ABR会负责将7类LSA转换成5类LSA,但NSSA区域不会像其他特殊区域一样自动下发默认路由,可以使用default-information-originate命令产生默认路由(7类LSA形式)。
Totally NSSA:翻译成中文是完全非末梢区域,继承了所有NSSA区域特性(不允许4、5类LSA,外部路由用7类LSA在NSSA内泛洪,外部路由进入常规区域需要7转5)的同时,区别在于Totally NSSA区域也会将3类LSA过滤并会自动下发一条默认路由(3类LSA形式)。
常规区域
- Backbone area - The backbone area is the core of the OSPF network. Furthermore, OSPF states that every area must be connected to the backbone area (aka area 0).
- Standard areas - This is an area that is not “stub based”. This includes the backbone area.
- Backbone Area:翻译成中文是骨干区域,也被称为区域0或区域0.0.0.0,骨干区域组成了OSPF网络的核心,所有其他区域都必须和骨干区域(Area 0)相连接,要么直接连接要么经过其他路由器和骨干区域相连,比如通过虚链路和Area 0相连,这样做是因为OSPF的所有非骨干区域之间不能直接传递LSA,必须将非骨干区域的LSA信息发送给骨干区域,再由骨干区域发送到其他区域,这样做的目的是因为OSPF的各区域间的路由是距离矢量路由(对,你没看错确实是距离矢量,我看到以后也很难以置信,但它就是距离矢量路由),所以很容易出现环路,为了避免环路强制其他区域的区域间路由先发送到Area 0 再发送给其他区域。
- Standard areas:翻译成中文是标准区域,也就是除了Stub area以外的其他area,上文的骨干区域(区域0)也属于标准区域,绝大多数的区域都是Standard area。标准区域中可以存在1、2、3、4、5类LSA,也可以存在ASBR路由器。
特殊区域
为什么需要特殊区域
OSPF网络共有三个区域,骨干区域area 0为银行的一级行及二级行设备运行的区域三级行运行的是OSPF的常规区域,为了保证网络的通畅,我们将网络的各个角落都宣告进了OSPF,感觉上很爽,但其实路由器运行的压力很大,因为随着设备使用年限的增加,设备数量的增多,网络前缀越来越多,路由条目势必逐渐增多,那么路由器的压力也会越来越大,毕竟庞大的路由表、LSA以及SPF算法的运行都在极大的消耗着路由器的资源。
从网络优化的角度来看,我们一直在输途保证网络通畅的情况下减少网络中传递的路由条目以及LSA的数量,路由汇总是一种很好的方法,当然,从OSPF的设计规划角度来看,我们还有特殊区域可供使用,下面来看看OSPF的特殊区域是如何帮助我们减少LSA泛洪的。
我们拿area 1做参考区域,当area1为常规区域时,区域中有多少种LSA在泛洪呢?1类LSA肯定有,由于区域中存在MA网络,所以2类LSA也有。其他区域的前缀被ABR注入了本区域,所以3类LSA也有。此外由于area2中的ASBR引入的外部路由,10.1.1.0/24,所以5类LSA也会被泛洪进area1,由于area1的路由器不知道area2中的ASBR路由器的位置,所以4类LSA也在area1中存在。综上所述,area1中有1-5共计种LSA存在。但仔细一想就会发现,area1作为“叶”区域,没必要知道外部路由的详细情况,我只需要知道有这么一条路让我到达区域外即可,此时就需要特殊区域来解决这个问题,例如特殊区域种的stub area就能满足这种需求。
所以综上所述,特殊区域是为了应对多区域时网络设备性能不够的产物,现在设备的性能已经不能和开发OSPF协议的80年代同日而语,所以特殊区域在现网中已经很难见到了。
概述
OSPF中的特殊区域可以在一个区域中注入默认路由来取代3类或5类LSA,这样做的好处是可以将LSA的泛洪限制在最小的范围内、最小化LSDB、减少SPF算法运算并使路由表变得更小。这些特殊区域一共有四种,分别是:
- Stub area:Stub Area的ABR上会过滤4、5类LSA,同时用3类LSA的形式向内部传递一条默认路由;配置命令:area x stub;
- Totally stub area:ABR上会过滤3、4、5类LSA,同时用3类LSA的形式向内部传递一条默认路由,但不允许引入外部路由;配置命令,ABR:area x stub no-summary;其他路由器:area x stub;
- NSSA (not so stubby area):ABR上会过滤4、5类LSA,默认不会向内部传递默认路由,使用default-information-originate命令产生默认路由(7类LSA的形式),但允许引入外部路由。当NSSA中有两个ABR时需要执行7转5时,只有一个会进行转换,router-id大的转换,所有的stub区域的ABR总是会过滤掉5类LSA;配置命令:area x nssa;
- Totally NSSA (totally not so stubby area):思科私有协议,ABR上会过滤3、4、5类LSA,同时向内部传递一条默认路由(3类LSA),允许引入外部路由。当NSSA中有两个ABR需要执行7转5时,只有一个会转换,也就是router-id大的转换,所有的stub area总是会过滤掉5类LSA;配置命令:ABR:area x nssa no-summary;其他路由器:area x nssa;
Stub area
概述
我们可以通过配置,将一个常规区域设置为stub区域。Stub区域将禁止4、5类LSA进入该区域(也就是不让10.1.1.0/24这条外部路由进入),同时该区域会自动下发一条默认路由(3类LSA)进入该区域,以保证数据去往外部路由的路径没有问题。这可以形象的理解为“外面的世界再怎么精彩,你不用告诉我细节,只需要告诉我怎么出去就行了”。这就是stub area的设计思路,当引入大量外部路由进入OSPF时,适当规划某些区域为stub,可以起到不错的网络优化作用。
有一点值得注意,不能将骨干区域area 0配置为stub区域,同时,让一个区域为stub的话,该区域不允许注入外部路由,也就是不能做重发布。
配置命令
1 | router ospf 1 |
此命令需配置在stub区域中的所有路由器上,如果某台路由器没有配置该命令,那么它无法和其他stub area 中的路由器建立邻接关系。
实现效果
Area 1中将不会有4、5类LSA,也就是Area 2重发布进来的关于网段10.1.1.0/24的路由被ABR过滤掉了,同时Area 1中的路由器将获得一条3类LSA的默认路由,该默认路由是由area 1的ABR自动下发。
Totally Stub area
概述
通过将区域规划成Stub area,可以起到一定的网络优化作用,但感觉上还是不够彻底,因为Stub area只是不知道外部路由,但除了外部路由,其他区域的路由(约等于其他区域的LSA)其实我也没必要知道太多细节,用一条默认路由代替去往其他area的路由也没问题,那么这里就可以将area 1设置为完全末梢区域,也就是totally stub area,当一个区域被配置为完全末梢区域时,这个区域将:
- 阻挡3、4、5类LSA进入本区域;
- 区域的ABR自动下发一条3类LSA的默认路由进入本区域;
这么一来,area 1区域内的路由器收到的LSA数量进一步减小,LSDB进一步变小,在存储LSA及运行SPF算法的时候消耗的资源自然也就减少了,另外当区域外拓扑出现变更的时候,对本区域的影响也将变为最小,因为内部没有其他区域的LSA了。
与Stub area区域类似,无法将骨干区域area 0配置成totally stub area,当然如果一个区域被指定为totally stub area,将不能在区域中的路由器上做路由重发布动作。
配置命令
ASBR配置命令:
1 | router ospf 1 |
其他路由器配置命令:
1 | router ospf 1 |
实现效果
完成上述配置后,area 1内的路由器将只有本区域的路由(ABR除外),同时能获取到ABR下发的3类默认路由,也就是说其他区域的路由以及外部注入的路由都被ABR挡在外面,取而代之的是一条默认路由。
NSSA
概述
在前面的知识基础上,我们已经了解到,在保证网络连通性的情况下,减少LSA的泛洪以及精简路由表,我们可以将特定区域配置为末梢区域(Stub area)或完全末梢区域(totally stub area),上面的拓扑中,如果我们将area 2配置为stub area,那么该area一方面会阻挡4、5类LSA的进入,另一方面会同时禁止重发布外部路由看,那么如果此时我们期望这个区域保持“阻挡其他区域过来的4、5类LSA”这个特性,同时允许在本area 内重发布路由,该怎么办呢?
例如,假设area 2原来时作为一个stub area运行的,但突然有一个外部网络,需要接入到我们这个OSPF网络中,并且连在area 2中,这种情况下为了保证路由可达,就必须向area 2中注入外部路由了,但注入路由违反了stub area的规则,stub area禁止4、5类LSA进入,外部路由的LSA为5类,无法注入。
如何解决呢?引入NSSA(not-so-stubby-area)的概念,中文翻译就是“非完全末梢区域”,当一个区域配置为NSSA时,这个区域一方面将阻挡其他区域传来的4、5类LSA,同时“允许区域本地注入”外部路由,这些外部路由以一种特殊的LSA类型—7类LSA在NSSA中泛洪,并且7类LSA不允许进入骨干区域或常规区域,NSSA的ABR会负责将7类LSA“转换”成5类LSA,从而在常规区域中进一步泛洪。上面的“允许区域本地注入”的意思是,NSSA这个区域的路由器配置重新发布。
必须注意的是,与Stub area及totally stub area不同的是,如果你将一个区域配置为NSSA,默认情况下,NSSA的ABR不会自动下发默认路由进NSSA,因此在NSSA环境下,需要留意网络连通信问题。
配置命令
1 | router ospf 1 |
上述命令需配置在NSSA内的所有路由器上。
实现效果
将area 2配置为NSSA区域后,从骨干过来的4、5类LSA将无法进入NSSA,也就是说,如果area 1做了重发布,那么这些重发布的外部路由无法进入NSSA区域(NSSA中不许出现5类LSA),与此同时,area 2允许本地的路由器做重发布动作,重发布进来的路由,以7类LSA在NSSA中泛洪,在路由表中可以看到这些外部路由的标记为“O N”,这些7类LSA在“穿越”NSSA的ABR进入骨干区域之前,由ABR负责将7类LSA“转换”成5类LSA,最终area 0和area 1也能学到这些外部路由,不过它们路由表中呈现的是“O E”标记。
扩展知识
NSSA ABR上的路由汇总动作
NSSA 的ABR会将7类LSA转换为5类LSA,在7转5的过程中可以使用summary-address 通告汇总的5类LSA,注意,这里汇总的是针对NSSA区域外部引入路由的汇总,但如果仍想对area 1 nssa 区域自己内部的路由做汇总,则应使用area range命令。
NSSA的ABR,在某种程度上可以理解成为常规区域的ASBR,它不会为常规区域生成4类LSA。
NSSA的ABR产生了5类LSA(通过7转5)并通告进骨干区域,因此这台NSSA的ABR对于骨干区域而言就是一台ASBR,由于存在这个7转5的过程,真正的ASBR(NSSA区域中执行重发布的那台路由器)信息就不需要被骨干区域路由器知道,因此NSSA区域的ABR也不会为这个区域里的ASBR产生4类LSA并通告进骨干区域。
NSSA的双ABR问题
上图中,两个ABR都会收到7类LSA,但只有Router ID大的ABR才会执行7转5动作,两台ABR都会在NSSA区域泛洪1类LSA,并从中了解到对方的存在。
N/P位
N/P位为1bit,在HELLO和LSA中都携带option字段,N/P位在两者中分别有不同的意义。
- 在Hello报文中:N bit标识该路由器位NSSA区域路由器,当N bit被置1时,E bit就必须被清零。
- 在LSA报文中:P bit 仅在7类LSA中出现,置1时标识NSSA区域的ABR能够将这条7类LSA转成5类LSA,而P位置0时不能进行7到5的LSA转换。
- P bit 为0时,ABR将不能将该7类LSA转换成5类LSA,只有NSSA区域的ABR重发布路由时,通告的7类LSA中的P bit才为0。NSSA区域在ABR重发布时,将7类LSA的P bit 置0,通知其他NSSA区域的ABR不要对该LSA进行7转5,因为骨干区域内的其他路由器已经从骨干区域内收到该路由的5类LSA,因此NSSA区域其他ABR执行7转5是没意义的。
P bit为0,ABR将不能将该7类LSA转换成5类LSA:
NSSA区域的ABR在重发布时,将7类LSA的P位置0,用来通知NSSA区域内的其他ABR不要对该LSA进行7转5,因为骨干区域内的其他路由器已经从骨干区域内收到该路由器的5类LSA,因此NSSA区域内其他ABR执行7转5是没有意义的。
Totally NSSA
概述
Totally NSSA,翻译成中文是一个非常尴尬的名字,完全非末梢区域,Totally NSSA是在NSSA区域的基础上,进一步阻挡NSSA区域外的其他区域过来的3类LSA,同时ABR自动下发一条3类LSA的默认路由进入NSSA区域。
配置命令
ABR:
1 | router ospf 1 |
其他路由器:
1 | router ospf 1 |
实现效果
Area 2之外的其他OSPF area 过来的3、4、5类LSA,都会被ABR阻挡在NSSA区域外,同时ABR会自动下发默认路由进NSSA,这条自动下发的默认路由是3类LSA。另外,NSSA区域内的路由器做重发布动作,由于NSSA区域不让传播外部路由的4、5类LSA,所以区域内的其他路由器会学习到7类的外部LSA,这些外部LSA会被ABR转换成5类LSA并注入骨干区域。
区域LSA总结
- 骨干区域:1、2、3、4、5;
- 标准区域:1、2、3、4、5;
- Stub区域:1、2、3以及3类0.0.0.0/0(ABR向区域内发起的一条3类缺省路由LSA);
- 完全Stub区域(totally stub area):1、2、3类0.0.0.0/0(ABR向区域内发起的一条3类缺省路由LSA);
- NSSA:1、2、3、7;
- Totally NSSA:1、2、7、3类0.0.0.0/0(ABR向区域内发起的一条3类缺省路由LSA)。
特殊区域实验
无特殊区域
基础配置及结果:
CO1:
1 | interface Ethernet0/0 |
CO2:
1 | interface Ethernet0/0 |
R3:
1 | interface Ethernet0/0 |
R4:
1 | interface Ethernet0/0 |
R5:
1 | interface Ethernet0/0 |
R6:
1 | interface Ethernet0/0 |
R7:
1 | interface Loopback1 #loopback1 接口用作引入外部路由 |
R8:
1 | interface Ethernet0/0 |
此时Area1中有哪几类LSA呢?之前分析过1-5类LSA都有,实际情况是不是这样呢?
从输出结果可知,确实有5种LSA,但对于一个“叶”area来说,知道这么多种LSA,其实意义不大,这时我们引入Stub area,看结果如何。
Stub area
此时我们将Area 1配置成Stub area,理论上应该由身为ABR的R3下发一条3类LSA的默认路由,然后Area 1阻止4、5类LSA进入,现在来看是不是这样。
变更的配置
在R3、R4和R5下加入配置:
1 | router ospf 1 |
LSDB及RIB
从上面的输出结果中可以看到LSDB相比配置之前进行了一定程度的精剪,R4和R5中原本存在的4、5类LSA已经被ABR阻隔了,由身为ABR的R3下发了一条默认路由,这条默认路由是以3类LSA的形式自动下发的,因为并没有进行任何关于默认路由的配置:
Totally Stub area
现在将Area 1配置成Totally Stub area,理论上应阻止3、4、5类LSA进入Area 1并下发3类LSA构成的默认路由。
变更配置
R3:
1 | router ospf 1 |
LSDB及RIB
从上面的输出可以看出,LSDB比之前有了大幅精剪,除了由ABR,R3自动下发的一条3类LSA的默认路由以外,其他3、4、5类LSA都被阻隔在了外面,所以路由表中自然没有了其他区域的网络号,这些均由一条默认路由代替。
NSSA
变更的配置
R6、R7、R8:
1 | router ospf 1 |
LSDB及RIB
从上面的输出可以看出,外部路由10.1.1.0/24由7类LSA引入NSSA区域的,而不是本来的4、5类LSA,因为NSSA阻止了4、5类LSA的传播。
由于7类LSA不允许传入常规区域,所以由作为ABR的R6进行了转换,由7类LSA转换成5类LSA,然后传入骨干区域Area 0。
必须注意的是,默认情况下NSSA的ABR是不会自动下发默认路由到NSSA区域的,需要进行如下配置才能下发默认路由:
1 | router ospf 1 |
具体见:
This configuration generates a type 7 default route. You can configure this command on any NSSA ASBR or NSSA ABR with these rules:
- NSSA ASBR can generate a default only when it has a default route in its routing table.
- The default route must be known through non-OSPF protocol
- NSSA ABR can generate a default route with or without a default route in its own routing table.
This command is used in order to generate an NSSA default route:
1
2 router ospf 1
Area 1 nssa default-information-originate
Totally NSSA
变更的命令
R6:
1 | router ospf 1 |
LSDB及RIB
Area 2之外的其他area的3、4、5类LSA都会被阻挡在NSSA之外,同时ABR,R6会自动下发默认路由进NSSA,默认路由以3类LSA的形式下发。LSDB相比NSSA有了进一步的缩小。NSSA引入的外部7类LSA会被ABR转换成5类LSA注入骨干区域:
从R6的LSDB中可以看到,在R6上执行了7转5的步骤,在抓包中,标识可以进行7转5操作的是P位:
邻居建立
邻居状态机
Down
初始化状态,这是OSPF邻居状态机的第一个状态,在Down状态下,意味着没从其他路由器收到OSPF的Hello包,运行OSPF协议的接口仍然有尝试发现邻居的意愿,因此会不断的发送组播Hello包。
Attempt
仅在NBMA网络类型上存在,如果一个路由器,它邻居处于Attempt状态,表示它从邻居没有收到任何信息,但做了努力来与邻居联系。在NBMA网络上具有DR选取资格的路由器与其邻居路由器相连的接口开始变为有效(Active)时,或当这台路由器成为DR或BDR时,这台具有DR选举资格的路由器会把邻居路由器的状态转换到Attempt状态,在Attempt状态下,路由器将在指定的hello间隔时间内向该邻居发送单播hello包。
init
当OSPF接口收到链路上某个邻居发来的第一个Hello包时,它会在接口上将该邻居状态设置为init,注意这个Hello包种可能并未包含任何的邻居信息,也就是hello包中没有active neighbor这个字段,但这个Hello包至少证明,在运行了OSPF协议的这个接口的链路上,至少有个活着的邻居。当路由器收到邻居发来的Hello包以后,它应该将邻居Hello包中的Router-ID放入它自己的Hello包中的Active Neighbor字段,用来确认它收到了一个有效的Hello数据包。
没有active neighbor的hello包:
有active neighbor的hello包:
2 — Way
当两个路由器之间建立起了双向通信时,进入2-Way状态,双向通信意味着两个路由器都收到了对方的Hello包,而Hello包中的Active Neighbor字段中是对方的Router-ID。当OSPF路由器在某个链路上发现了邻居后,它自己发送的Hello包里就会增加一个叫“Active Neighbor”的字段,用于存储在该链路上发现的OSPF邻居。当一台OSPF Router看到自己的Router ID出现在邻居发过来的Hello包中,它就会将该邻居置为Two-Way,该状态是OSPF邻居之间可以具有的最基本的关系,也是第一个稳定状态,但此时两者还不能共享路由信息。
在2-way状态下,路由器决定是否和邻居形成邻接状态。在类型为广播(MA)或非广播多路访问的情况下,路由器只和DR以及BDR形成FULL的关系,和其他的DR Other形成2-way的关系;在点对点和点对多点的网络中,路由器和所有其他链接的路由器形成FULL关系。在2-way的时候还要选举BDR和DR,注意是先选举BDR然后再选举DR,DR/BDR具体选举步骤上文写过,这里再简单写一下重点:
当一台OSPF路由器有效(Active)并去发现它的邻居路由器时,它将去检查有效的DR和BDR路由器(如果路由器的Priority为0那么就意味着它是无效的,不能参与选举DR和BDR),如果DR和BDR路由器存在的话,这台路由器将接受已经存在的DR和BDR(为什么要接受已经存在的DR和BDR呢,是因为DR具有非抢占性的,也就是说已经有了DR了,新加入的路由器接口的Priority再低也不会重新选举DR了,如果没有非抢占性,新加入一个Priority 更大的就被选举成新的DR,所有DR Other都和这个新DR再建立邻接关系达到Full状态,太消耗系统资源,所以当一台路由器发现已经存在DR和BDR时就会接受已经存在的DR和BDR),如果BDR和DR路由器都不存在(也就是Hello包种的DR以及BDR字段都为0.0.0.0),将执行一个选举BDR的过程,选举出具有最高优先级的路由器作为BDR路由器,选举中如果存在多台路由器具有相同的优先级(Priority),那么在数值上具有最高路由器ID的路由器将被选举成BDR(如果两台运行OSPF路由器路由器的接口的Priority都是1,那么此时一台路由器的Router-ID为1.1.1.1,另一台的Router-ID为2.2.2.2,Router-ID为2.2.2.2的显然比1.1.1.1更大,这台Router-ID为2.2.2.2的路由器的接口将被选举成BDR)。如果没有有效的DR路由器存在,那么之前选举出的BDR路由器将被选举成(或者说成提升)DR路由器,然后再选举出来BDR路由器。至此BDR和DR选举完毕。
ExStart & Exchange
过程概述
在ExStart状态下,双方开始交互DBD选举Master,Router ID大的一方在选举以后会成为Master。在DBD包中有3个标记为用来管理邻居关系的建立过程:
- I 位,Initial bit,中文翻译成初始位,当该位置位为1时,表示这是第一个用于ExStart协商主从关系的初始化协商的DBD包。当两个路由已经选举完Master、Slave时,I位置0。
- M位,More bit,中文翻译为后继位,当该位置位为1时,表示后续还有其他DBD报文需要交互,当该位置0时表示没有其他DBD报文需要交互,表示从ExStart到Exchange的整个LSDB目录交换过程结束。
- MS位,Master/Slave bit,中文翻译为主/从位,当该位置位为1时,表示自己时Master,Router ID大的一方为Master,大多数情况下DR会成为Master。当两个路由器给对方发送第一个DBD报文时,双方都会将自己的MS位置位为1,然后相互比较Router ID决定主从关系。当决出主从关系时,Master的MS位不变依旧为1而Slave的MS位会置0表示自己为Slave。
双方的第一、第二个DBD的I、M、MS位均置1,用来比较出谁是Master/Slave(注意不是BDR\DR),第三个包由Slave发给Master,Slave采用了Master的序列号,I位置0因为已经不是第一个初始化的DBD了,M位置1因为之后还有DBD要交互,MS位置0因为我不是Master而对方是Master。三个数据交互完确定了Master/Slave,从此只有Master可以设置并且增加序列号,而Slave不行。确定了Master/Slave关系后进入Exchange阶段,进入Exchange阶段后,Exchange以后Master发送一个DBD,Slave必须回一个DBD(主从关系确定后,Slave不能主动发送DBD只能被动回应Master的DBD),两者用这种方式交换DBD信息。如果Slave已经没有更多DBD需要交换(也就是M位置0)而Master依旧还在发送DBD,则Slave必须用DBD响应并用Master的序列号隐式确认,但由于Slave端已经发送了所有LSA目录,此时Slave的DBD包中没有LSA的相关信息包含在内了。Master/Slave关系只在DBD中存在,DBD数据包只在ExStart/Exchange过程中存在。下面看看抓包的对比,首先是Master发送的包含有LSA目录的DBD:
接下来是Slave回应上面Master发送的DBD的消息,这个DBD用的序列号是2990,和上面Master发送的序列号相同,属于隐式确认,可以看到由于Slave的I、M、MS位都为0,说明此时它已经发送完了所有的LSA的目录,没有其他可发送了,所以抓包中并没有关于LSA的部分:
选举完Master/Slave以后,路由器会进入Exchange阶段,在该阶段中执行DBD的交换过程,并且通过交换DBD明白下一步要从邻居路由器下载哪些LSA。为什么要交换DBD呢?因为OSPF是链路状态路由协议,本Area内路由器里的LSDB要相同,这就需要邻居之间相互交换彼此没有的LSA,如何知道哪些LSA需要交换呢?先比较LSDB的目录,也就是比较DBD,DBD是链路状态数据摘要,也就是LSDB的摘要,用于描述链路状态数据库(LSDB)的内容。
在Exchange阶段,双方使用包含自己LSA头部的DBD报文进行交互,并且将对方发过来的LSA头部、自己感兴趣的LSA或自己没有的LSA存储在一个本地的OSPF接口的队列里,以便在下一个阶段进行LSA详细请求。当某个接口收到邻居发来的DBD中的M位置0,说明对方已经发完DBD了,与此同时,如果该路由器的这个OSPF接口上存在待请求的LSA,那么它会将这个邻居置为loading状态。在Exchange状态也有可能发送LSR去请求对方发送LSU。
抓包说明
空DBD包
空DBD包中只有LSA头部的信息,并没有整个LSA的信息:
而完整的LSA中包含的信息要多得多:
初始化协商的DBD消息
初始化协商的DBD消息中的I、M以及MS位均为1。I位置1,因为这是第一个用于ExStart协商主从关系的初始化协商的DBD包;M位为1,因为这不是Router发送的最后一个DBD包,因为还没开始交换DBD,所以这位肯定为1;MS也为1,因为这时Master/Slave选举还没得出结论,得出结论前两个协商的路由器都会认为自己是Master,所以都会把MS位置位为1。
我是10.0.0.1,Router ID为1.1.1.1,这是我协商主从关系的第一个DBD包(I位为1),我还有更多的DBD包要发送(M位为1),我是Master(MS位为1),我的DBD的序列号是3138。该DBD包中不包含LSA的信息。接下来我们看对方(10.0.0.3)发送的DBD初始消息。
我是10.0.0.3,Router ID为3.3.3.3,这是我协商主从关系的第一个DBD包(I位为1),我还有更多的DBD包要发送(M位为1),我是Master(MS位为1),我的DBD的序列号是2989。该DBD包中不包含LSA的信息。
交互完DBD包以后,Router ID大的一方也就是ID为3.3.3.3的10.0.0.3成为Master,Router ID小的10.0.0.1成为Slave。
交互LSDB目录的过程
第三个DBD由Slave(10.0.0.1)发给Master(10.0.0.3),序列号采用Master发送初始DBD中的序列号,I位置0因为已经不是初始化的DBD包了,也意味着此时进入了Exchange状态;M位置1表示还有后续的DBD包,不过一般实验中LSU较少所以这位为0也是正常的,因为一个DBD就交互完事儿了;MS位为0表示我是Slave。同时DBD包中也有LSA的摘要信息,但并没有LSA的具体信息,主要是交换了LSA的Router ID,表明自己有哪些路由器的信息。Master(10.0.0.3)收到这个DBD包以后,发现I位为0,于是将对方的状态改为Exchange,再查看Sequence号发现这个序号是自己这个Master产生的,于是在这个序列号的基础上+1生成新的序列号,这么做是隐式确认告诉对方之前你发的这个DBD我收到了,然后带上了自己的LSA摘要信息,发送给对方开始交互LSDB的摘要目录。
第四个DBD由Master发给Slave,序列号在之前的基础上+1,也就是2990,用以隐式确认之前收到的序列号为2899的DBD。I位为0,因为已经不是初始化的DBD包了;M位为1,表示还有后续的DBD包;MS位为1,因为自身是Master。后面带上了自己的LSA摘要信息。
第五个DBD由Slave(10.0.01)发送给Master(10.0.0.3),序列号和之前Master发给它的序列号相同,且M位置0,说明Slave没有需要发送给Master的其他LSDB目录了,这个DBD完全是用来确认之前Master的那个序列号为2990的DBD。
第六个DBD由Master(10.0.0.3)发送给Slave(10.0.0.1),序列号为之前Slave确认DBD的序列号+1,也就是2991,这时M位置0,说明Master(MS位置1)没有更多的DBD要发送了。
最后一个DBD由Slave(10.0.0.1)发送给Master(10.0.0.3),序列号和刚才Master发送的序列号一致,也是个用来确认的DBD。至此两方都没有DBD信息要交换了,Exchange阶段结束。
补充说明
为什么用空DBD包?
当两个路由器决定建立完全邻接关系时(Full adjacent),二者必须同步彼此的LSDB(Link State DataBase,链路状态信息数据库),因为OSPF是一个链路状态路由协议,每台设备都要知道网络的整体信息(在OSPF中就是了解全网的LSA)所以邻居的LSDB自己也必须掌握,掌握清楚全网的信息以后,再根据自己掌握的信息计算出路由。为了优化LSDB数据库同步过程,两台路由器会先比较它们LSDB的条目列表,这样就不用交换整个LSDB数据库了,再根据LSDB条目列表比较的情况决定去交互哪些LSA,发送空DBD包就是LSDB的条目列表,空DBD是并不包含LSA头部的DBD包,既能达到比较两台设备LSDB的目的,又减小网络及系统的开销,就好像两个商店之间互相比较存货的差异,这时只要比较两个商店的存货目录清单而不用把所有货物搬出来彼此比较一样。
如何确定对方收到DBD?
由于链路状态路由协议要获知全网的网络信息,所以必须知道和邻居之间LSDB中的LSA差别在哪,这时候需要交换空DBD以交换彼此掌握的LSA目录,但由于OSPF协议中并没给DBD包设计专门的DBD确认(必须注意,LSAck是用来确认LSU的而不是确认DBD的),这时如何确定对方收到了DBD包呢?用DBD包中的序列号做隐式确认。当Master发送M位置1\0、MS位置1的DBD并且Sequence为X的DBD时(表示我是Master,我还有后或者没有续的DBD需要发送),Slave会发送一个序列号同为X、M位置1\0,MS位置0的DBD隐式确认之前Master发送的DBD(表示我是Slave,我有或没有后续的DBD发送,我的序列号是X)。
Loading
DBD交换完成后,进入Loading状态,在Exchange状态时已经对链路状态数据库和收到的DBD的LSA头部进行了比较,已经知道要向邻居请求哪些自身没有的LSA了,于是在Loading阶段向邻居发送LSR用来请求这些没有的LSA;邻居收到LSR后,回应LSU(LSU中包含着LSA);收到邻居发来的LSU,存储这些LSA到自己的链路状态数据库,并发送LSAck确认。也就是一个LSR — LSU — LSAck的数据包交互过程,当需要交互的LSU全部发送完毕后,Loading状态结束进入Full状态。在发送LSU时,路由器中也维护着一个LSU的重传列表以便确定所有发送的LSU都能被正确接收到,如果没收到某个LSU的LSAck的话会重传该LSU,例如下图:
- R2需要向R1请求A2和B2两条LSA的LSU,R1要向R2请求B1这一条LSA的LSU。
- R1向R2发送了A2和B2这两个LSU,R2发送了A2的LSAck,表示已经收到了A2的LSU
- 当R1的LSA计时器过期(5秒)后仍然没收到关于B2的LSAck,R1明白该LSU对方并未受到于是重新发送了B2的LSU给R2。
- R2收到B2的LSU后发送了关于B2的LSAck表示该LSU已收到。
- R2发送B1的LSU给R1。
- R1发送B1的LSAck表示该LSU已收到。
Full
LSU全部交互完毕后,两台路由器拥有的LSDB,并保持在该状态。为了保持邻接状态,路由器之间会交互Hello包,确保对方的状态,如果在Deaf interval计时器到期前都未收到对方的Hello包,则邻接状态终结。一旦发现和其他路由器邻接状态终结,路由器将会泛洪该变化置域内其他路由器。
邻居无法建立常见原因
- Hello间隔和Dead间隔不同。默认情况下,Dead间隔是Hello间隔的4倍,可以在接口下通过“ip ospf hello-interval”和“ip ospf dead-interval”命令来调整。
- 区域号不一致(Area号不同)。
- 特殊区域(Stub区域和Nssa区域等)区域类型不匹配。
- 认证类型或密码不一致。
- 路由器ID相同。
- Hello包被ACL给Deny掉。
- 链路上的MTU不匹配。
- 接口下的OSPF网络类型不匹配。
OSPF路由汇总
虚链路
概述
OSPF规定每个区域都必须与区域0相连,当出现了以上情况,可以在区域1中建立一条虚链路(Virtual-link)来过度,配置命令为:
1 | area X(过渡区域的ID) virtual-link A.B.C.D(虚链路对端router 的Router ID) |
查看虚链路命令为:
1 | show ip ospf virtual-links |
也可以配合‘show ip ospf database’来使用
虚链路用来连接不连续的区域,只是一种临时或割接的手段,不建议用在常规网络的实施中。本质上虚链路是一条属于区域0的线路,所以如果在Area 0上开启了验证那么Virtual-link也要做验证,如果Area 0不做验证,只虚链路上自己做认证,那验证的范围就在虚链路上。虚链路用Hello包建立,以单播形式,虚链路一旦建立起邻居则Hello包不再发送,凡是通过虚链路学到的LSA都会标注DNA表示永远不会老化。
实验
实验1
R2:
1 | router ospf 1 |
R3:
1 | router ospf 1 |
R2上的部分LSDB:
R2上的邻居表:
实验2
OSPF选路
- 直连路由:本路由器发起的LSA 1、2;
- 区域内路由:O;LSA 1、2;
- 区域间路由:O IA;LSA 3;
- 1类外部路由:O E1;LSA 5类型1;
- 2类外部路由:O E2;LSA 5类型2;
- 1类NSSA路由:O N1;LSA7类型1;
- 2类NSSA路由:O N2;LSA 7类型2。
简单版总结就是:O>> O IA >> E1 >> N1 >>E2 >> N2,但实际中不同厂家的优先选择方式不同,以各厂家的文档为准。
参考文章:
OSPF BDR and DR-OTHER relations
When was DBD(database descriptor) packets sent ?
OSPF Neighbor States Explained with Example
OSPF - Implicit ACK vs. Explicit ACK
OSPF LSAs and LSDB flooding Tutorial
OSPF LSA TYPES - PURPOSE AND FUNCTION OF EVERY OSPF LSA