关键词:OSPF邻居、状态机、Down、Init、2-Way、ExStart、Exchange、Loading、Full、邻接关系

第52篇:OSPF 邻居状态机:从 Down 到 Full

一、引言

在第51篇中,我们介绍了 OSPF 通过 LSA 泛洪和 LSDB 同步实现全网拓扑学习的基本原理。而这一切的前提是:路由器之间必须先建立邻居关系。

OSPF 邻居关系的建立不是一蹴而就的,而是通过一套严格的状态机逐步推进。从完全陌生的 Down 状态,到可以交换 LSA 的 Full 状态,中间经历了 Init、2-Way、ExStart、Exchange、Loading 五个过渡状态。每个状态的转换都有明确的触发条件和前置检查。

理解 OSPF 邻居状态机,是排查 OSPF 故障的第一能力。当邻居"起不来"时,首先要回答的问题就是:邻居卡在哪个状态?本文将从状态机的角度,完整解析 OSPF 邻居关系的建立过程。

二、OSPF 邻居状态机总览

2.1 七种邻居状态

OSPF 邻居关系存在以下七种状态,按建立顺序排列:

状态 说明 关键行为
Down 初始状态,未收到任何 Hello 报文 等待 Hello 报文
Init 收到邻居的 Hello,但尚未看到自己的 Router ID 确认单向通信可达
2-Way 在对方 Hello 中看到自己的 Router ID,双向通信建立 邻居关系确认完成
ExStart 开始建立邻接关系,协商主从角色 发送空的 DBD 报文,确定 Master/Slave
Exchange 交换数据库描述(DBD)报文 互相通告 LSDB 摘要
Loading 请求并接收缺失的 LSA 详细内容 发送 LSR 请求,接收 LSU 响应
Full 邻接关系完全建立,LSDB 同步完成 可以正常交换 LSA,参与 SPF 计算

注意:对于 DR/BDR 选举网络中的 DROther 路由器之间,邻居关系在 2-Way 状态即终止,不会进一步建立邻接关系。

2.2 状态机转换图

状态机转换图 - 图示

2.3 报文交互流程

报文交互流程 - 图示

三、各状态详解

3.1 Down 状态

Down 是 OSPF 邻居关系的初始状态,表示路由器未从该接口收到任何有效的 OSPF Hello 报文。

停留原因: - 物理链路故障或接口 DOWN - 两端未配置 OSPF 或未宣告对应网段 - Hello 报文被 ACL 或防火墙拦截 - 两端 OSPF 区域号不一致

3.2 Init 状态

当路由器收到某台邻居的 Hello 报文后,将该邻居标记为 Init 状态。此时,收到的 Hello 报文中尚未包含本端的 Router ID。

关键特征: - 单向通信已验证(本端能收到对方 Hello) - 对方尚未收到本端 Hello,或刚收到但未处理 - 下一个 Hello 周期后,对方会在其 Hello 的 Neighbor 列表中列出本端 RID

3.3 2-Way 状态

当路由器在对方 Hello 报文的 Neighbor 字段中看到自己的 Router ID 时,表示双向通信已建立,进入 2-Way 状态。

重要规则: - 在广播和 NBMA 网络中,DROther 路由器之间仅维持 2-Way 邻居关系,不建立邻接 - DR 和 BDR 会与所有邻居(包括其他 DROther)建立 Full 邻接关系 - 点对点(P2P)网络中,2-Way 后立即进入 ExStart

3.4 ExStart 状态

进入 ExStart 状态后,路由器开始协商主从(Master/Slave)角色,为后续的 DBD 交换做准备。

协商过程: 1. 双方同时发送空的 DBD 报文(仅含头部,不含摘要条目) 2. DBD 报文中携带本端的 Router ID 和 MS(Master/Slave)位 3. Router ID 较大的一方成为 Master,负责控制 DBD 交换的序号 4. Router ID 较小的一方成为 Slave,跟随 Master 的序号

常见故障: - MTU 不匹配导致 DBD 报文被丢弃,双方反复停留在 ExStart - 可通过 ospf mtu-ignore 命令忽略 MTU 检查

3.5 Exchange 状态

主从关系确定后,双方开始交换 DBD(Database Description,数据库描述)报文。DBD 报文携带的是 LSDB 中所有 LSA 的摘要信息(LS Type、Link State ID、Advertising Router、Sequence Number),而非 LSA 完整内容。

交换规则: - Master 控制序号递增,Slave 跟随 - DBD 报文的 M(More)位表示是否还有后续 DBD 报文 - I(Init)位表示是否为 DBD 交换的首个报文 - 每收到一个 DBD 报文需回复确认

3.6 Loading 状态

Exchange 阶段完成后,路由器对比双方 DBD 摘要,发现自己 LSDB 中缺失的 LSA 条目。Loading 阶段用于请求这些缺失 LSA 的完整内容。

报文交互: 1. 发送 LSR(Link State Request)报文,请求缺失的 LSA 2. 对方回复 LSU(Link State Update)报文,携带完整 LSA 内容 3. 接收方回复 LSAck 确认

特殊情况:如果 Exchange 阶段对比后发现无缺失 LSA,则跳过 Loading 直接进入 Full 状态。

3.7 Full 状态

Full 状态表示两台路由器的 LSDB 已完全同步,邻接关系建立完成。此时路由器可以: - 正常接收和泛洪 LSA - 参与 SPF 计算 - 为数据平面提供 OSPF 学习的路由

四、故障案例分析

4.1 案例一:邻居卡在 Init 状态

故障现象:R1 与 R2 互联,R1 上显示 R2 的邻居状态为 Init,始终无法进入 2-Way。

拓扑: 案例一:邻居卡在 Init 状态 - 图示

排查过程:

  1. 在 R1 上查看邻居状态:
[R1] display ospf peer brief
 OSPF Process 1 with Router ID 1.1.1.1
 Peer ID            State   Pri  DeadTimer   Address
 2.2.2.2            Init    1    00:00:38    10.1.1.2
  1. 在 R2 上查看邻居状态,发现 R2 完全没有 R1 的邻居记录:
[R2] display ospf peer brief
 OSPF Process 1 with Router ID 2.2.2.2
 # 无任何邻居
  1. 在 R2 接口上检查配置,发现配置了 ospf silent-interface:
[R2] display current-configuration interface GigabitEthernet 0/0/0
 interface GigabitEthernet 0/0/0
  ip address 10.1.1.2 255.255.255.0
  ospf silent-interface

根因分析:Silent-Interface 使 R2 不发送 Hello 报文,R1 虽然能收到 R2 的单播响应(如果配置了 peer),但 R2 的 Hello 中没有 R1 的 RID,因此 R1 只能停留在 Init。

解决方案:

[R2] interface GigabitEthernet 0/0/0
[R2-GigabitEthernet0/0/0] undo ospf silent-interface

4.2 案例二:邻居卡在 ExStart 状态

故障现象:R1 与 R2 的邻居关系反复在 ExStart 和 2-Way 之间震荡。

排查过程:

  1. 观察邻居状态反复变化:
[R1] display ospf peer
 Neighbor ID    State     Pri  DeadTimer   Address        Interface
 2.2.2.2        ExStart/-  1    00:00:36    10.1.1.2       GE0/0/0
 # 状态在 ExStart 和 2-Way 之间反复跳变
  1. 使用调试命令捕获 DBD 报文:
[R1] debugging ospf packet dbd
[R1] terminal debugging
 # 观察到DBD报文发送后未收到确认
  1. 检查接口 MTU 配置:
[R1] display this interface GigabitEthernet 0/0/0
 # MTU: 1500

[R2] display this interface GigabitEthernet 0/0/0
 # MTU: 9000 (配置了jumbo frame)

根因分析:R2 的 MTU 设置为 9000,发送的 DBD 报文可能超过 R1 接口的 MTU 限制(1500),导致 R1 丢弃了 DBD 报文。OSPF 在 ExStart 阶段对 MTU 进行严格检查。

解决方案:

# 方案1:统一两端MTU(推荐)
[R2] interface GigabitEthernet 0/0/0
[R2-GigabitEthernet0/0/0] undo negotiation auto
[R2-GigabitEthernet0/0/0] ip mtu 1500

# 方案2:在R1上忽略MTU检查
[R1] interface GigabitEthernet 0/0/0
[R1-GigabitEthernet0/0/0] ospf mtu-ignore

4.3 案例三:邻居在 Full 和 Down 之间震荡

故障现象:R1 与 R2 的邻居关系周期性地在 Full 和 Down 之间跳变,每次 Full 维持约 40 秒后断开。

排查过程:

  1. 查看 OSPF 事件日志:
[R1] display ospf fault-record
 # 周期性显示邻居Down事件,间隔约40秒
  1. 检查接口的物理状态:
[R1] display interface GigabitEthernet 0/0/0
 # 接口物理状态UP,但存在CRC错误计数递增
  1. 进一步检查光模块和光纤:
[R1] display transceiver interface GigabitEthernet 0/0/0
 # 收光功率低于最小灵敏度

根因分析:光纤衰减过大导致收光功率不足,产生大量 CRC 误码。Hello 报文(DeadTimer 默认 40 秒)在 40 秒内偶尔能通一次,但很快又因误码丢包导致 DeadTimer 超时。

解决方案: - 更换光纤跳线或清洁光模块接头 - 如距离过长,增加光放大器或更换为更高功率的光模块

五、总结

状态 转换条件 关键检查点
Down → Init 收到有效的 Hello 报文 物理连通性、Hello 参数匹配
Init → 2-Way 对方 Hello 中包含本端 RID 双向通信、Hello 间隔匹配
2-Way → ExStart 需要建立邻接(非 DROther 间) DR/BDR 角色、网络类型
ExStart → Exchange Master/Slave 协商成功 MTU 匹配、DBD 报文交互
Exchange → Loading DBD 交换完成且发现缺失 LSA LSDB 摘要对比
Loading → Full 所有缺失 LSA 请求完成 LSA 完整传递
Full → Down DeadTimer 超时未收到 Hello 链路稳定性、Hello 报文可达

思考

  1. 为什么 OSPF 要设计多级状态机,而不是收到 Hello 就立即建立 Full 邻接?这种设计有哪些好处?
  2. 邻居关系卡在 ExStart 状态是最常见的 OSPF 故障之一。除了 MTU 不匹配,还有哪些原因会导致 ExStart 卡住?
  3. 在广播网络中,为什么 DROther 路由器之间只维持 2-Way 状态而不再建立 Full 邻接?这样设计的目的是什么?

下篇预告:第53篇:OSPF Hello 报文与邻居建立条件——解析 Hello 报文格式、参数匹配规则以及导致邻居无法建立的常见原因。