OSPF
该协议叫做 OSPF - open shortest path first ,开放式 最短 路径 优先级协议,通过该协议计算出来的肯定是去往一个目标网络时,所使用的最短的、无环的转发路径。
该协议属于 OSI 模型第三层,协议号是 89 。 所有的 OSPF 报文,都是包含在IP头部后面
该协议的报文,是通过组播的方式发送的,组播地址是 224.0.0.5 和 224.0.0.6 。
然后在路由器之间来回的发送,从而就可以让路由器互相学习彼此的路由条目。
OSPF工作原理
- 建立邻居表:包含的是成为邻居关系的设备,所有的OSPF报文,仅仅在邻居之间发送
- 同步数据库:包含的是自己的以及从邻居学习过来的“链路状态信息/通告”- LSA(advertisement)
- 计算路由表:包含的自己基于“数据库中的LSA”计算出来的最好的路由条目
OSPF报文类型
- hello,用于邻居表的建立、维护和拆除
- dd,database description,数据库描述报文,用于实现数据库的快速和可靠的同步
- lsr,link state request,链路状态请求,用于请求想要的“LSA”的
- lsu,link state update,链路状态更新,用于发送 LSA 报文的
- lsack,link state acknowledge,链路状态确认,用于实现 LSR 和 LSU 的可靠传输
OSPF报文分析之 Hello
- OSPF报文封装
OSPF报文是封装在IP头部后面,协议号为 89 ,目标IP是 224.0.0.5 - OSPF头部
- version: 表示的是 OSPF 协议的版本,默认是2。支持的IPv4;
- message type : 信息类型,表示的是 OSPF 的报文类型,此时是 hello
- source ospf router : 表示的是发送这个 ospf 报文的路由器的 router-id
- packet length:表示的是后面的这个 OSPF 报文的大小/长度
- area id : 表示的是该报文是从哪个区域发送出来的
- packet checksum :表示的报文的校验和,用于检测报文在传输过程中是否出错
- auth type:表示的是认证类型,也就是常说的加密类型,一般都是明文或者密文,默认情况下,OSPF的认证类型是 Null(空,也就是没认证)
- auth data : 表示的是加密的密码
- OSPF hello
- network mask : 表示的是发送这个Hello报文的出接口的掩码
- hello interval : 表示的是该端口发送hello报文的周期,默认是 10s
- options:可选项,也通常被称之为“特殊标记位”,用来表示一个路由器的能力
- router priority : 路由优先级,默认是 1
- router dead interval : 表示的是(邻居)路由器的死亡时间,默认是 40s
- designated router : 指定路由器,俗称 DR
- back designated router : 备份的指定路由器,俗称 BDR
- active neighbor : 活动邻居,通常称之为 neighbor-list → 邻居列表。表示的是自己认可、承认的邻居设备的 router-id
OSPF邻居建立影响因素
- 确保设备之间的IP地址互通
建立邻居的设备,必须是同一个网段的;
两个接口的IP地址,必须能够互相 ping 通 - 确保设备可以发送 hello 报文
- 接口必须通过 network 命令,正确宣告
- 确保接口不能够被配置为 OSPF 的静默接口
- 确定设备之间发送报文的方式
- 要么都是组播
- 要么都是单播
- 确保设备可以接收 hello报文
- 接口必须通过 network 命令,正确宣告
- 确保接口不能够被配置为 OSPF 的静默接口
- 该端口上如果配置了策略(ACL),不能拒绝 OSPF 报文
- 确保设备可以比较 hello 报文
- router-id 不能相同
- area-id 必须相同
- 认证类型必须相同
- 认证密码必须相同
- 掩码必须相同**(特殊情况下)**
- hello 计时器必须相同
- 特殊标记位,必须相同
- 端口优先级,不能全为0**(特殊情况下)**
- dead计时器必须相同
注意:特殊情况下,指的是“一个网段中需要 DR的情况”
OSPF邻居状态详解
- init
初始化状态。
当收到了对方设备发送过来的hello报文,并且参数协商成功。此时就会将该设备的router-id 放入到自己的邻居表中,状态设置为 init
如果邻居卡在了该状态,说明:设备之间存在单向链路故障 - attempt
尝试状态
该状态呢,仅仅出现在NBMA 网络环境下,两边通过单播建立邻居的时候。
每一个peer命令配置最后,都可以在邻居表中看到一个 处于 attempt 状态的邻居。 - two-way
双向通信状态。
当在对方发送过来的 hello 报文中的,发现自己的 router-id (active neighbor),此时邻居的状态就会立刻从init 过渡到 two-way 状态。
如果该网段中,同时存在多个 OSPF 路由器,那么就要在该状态(two-way)状态,进行DR/BDR的选举。
但是,这个选举过程中,通常会在该状态持续 40s 的时间,目的就是为了在这个时间内尽量的收集更多的同网段设备发送的 ospf hello报文,这样一来呢,竞选出来的 dr/bdr 更加的客观。
但是如此一来,就会导致 OSPF 邻居建立的时间就会变长
如果邻居卡在了该状态,说明:设备之间想选DR,但是死活选不出来。因为优先级全0 - exstart
交换初始化状态(exchange start)
该状态下,两边互相交换的是第一个 DD 报文,但是此时该 DD报文中,啥简要信息都没包含。因为此时发送第一个 DD 报文的主要目的是,是为了确定两个设备之间的主从关系,为了实现后续的 DD 报文的可靠传输。一旦邻居设备之间的主从关系确定以后:从设备发送的DD报文的序列号,一定要和主设备发送的DD报文的序列号一致。
主设备和从设备的竞选原则:
仅仅比较设备之间的 router-id ,越大越好。
并且,在该状态下,有的时候,设备之间是需要检查 DD 报文中的 MTU 字段的。
如果两边的 MTU 取值不同,则邻居状态就会卡在 exstart,不会继续下去了。
但是,在华为设备上,默认情况下,关闭了“MTU检查机制”。
但是,在思科设备上,默认是开启了“DD报文中的MTU检查机制的”。
如果邻居卡在了该状态,说明:两边的MTU取值不相同
- exchange
交换状态
该状态下,设备之间交换的就是大量的 DD 报文了。该报文中包含的是每个OSPF路由器的数据库中的 LSA 条目的简要信息。当两边的数据库题目的简要信息全都发送完毕了,就开始对比两边的数据库之间的差异了。知道了两边的数据库的不同之后,邻居设备之间就开始向对方请求自己没有的那些数据库条目信息 — LSA 。
在上述的 DD报文中,我们可以明确的区分出 DD 报文是由主设备发送的,还是从设备发送的,可以明确的判断出当前两边的 DD 报文是否传输完毕了。因为在DD报文中
包含了下面的3个重要的字段信息:
- master/slave : 该字段如果取值1,说明是master(主设备);如果取值0,则是从设备
- more:该字段表示后面还有更多的 dd 报文;如果取值1,说明后续还有;如果取值0,
则说明后续没有更多DD报文,即当前这个DD报文是最后1个DD报文 - init:该字段表示是不是第一个DD报文;如果取值1,说明是第一个DD报文;如果
取值0,则说明不是第一个DD报文
- loading
加载状态
该状态下,就是通过不断的发送 LSR 报文和 LSU 报文,实现两边的数据库同步。并且整个过程中,应该确保是安全和稳定的,所以每次发送 LSR 和LSU ,都会伴随着 LSAck的发送。 - Full
完全邻接状态
该状态下,两边的数据库条目(LSA)就完全一致了。 - down
挂掉了
该状态下,表示没有在规定的 dead 时间内,收到对方的任何的 ospf 报文 - 关于LSA的讨论
- 区域56中,有没有4类LSA?没有
- R2上,有几个4类LSA?2个
- 区域19的R9上,有没有R6产生的5类LSA?有
- 区域19的R9上,有没有R6产生的5类LSA表示的路由?没有的
- 区域12的R1上,关于 192.168.56.0/24 这个路由是通过几类LSA表示的? 3类
- 在R1上有几个关于 192.168.56.0/24 的3类LSA ? 2个
- 在R12上有几个关于 192.168.56.0/24 的3类LSA ? 3个 0区域中R5发送的、12区域自己发送的、12区域另外一个ABR-R2发送的1个