7. Bringing Up Adjacencies (建立邻接关系)
本章详细描述 OSPF 路由器如何建立和维护邻接关系(Adjacency)。邻接关系是 OSPF 协议的核心,决定了哪些路由器之间会同步链路状态数据库。
章节概述 (Chapter Overview)
邻接关系的建立是一个多阶段过程,涉及:
- 邻居发现
- 双向通信确认
- 主从关系协商
- 数据库同步
- 完全邻接状态达成
7.1 邻居关系 vs 邻接关系 (Neighbor vs Adjacency)
概念区分
| 概念 | 定义 | 状态 |
|---|---|---|
| 邻居 (Neighbor) | 通过 Hello 协议发现的直连路由器 | 2-Way 或更高 |
| 邻接 (Adjacency) | 同步 LSDB 的邻居 | Full 状态 |
关键差异
邻居关系
- 所有直连路由器都会成为邻居
- 通过 Hello 数据包维护
- 不一定同步数据库
邻接关系
- 仅部分邻居建立邻接
- 进行完整的数据库交换
- 达到 Full 状态
7.2 邻居状态机 (Neighbor State Machine)
状态转换图
Down → Init → 2-Way → ExStart → Exchange → Loading → Full
↓
(不建立邻接)
状态详解
1. Down (失效)
特征
- 初始状态
- 未收到任何 Hello 数据包
- 邻居不可达
2. Init (初始化)
特征
- 收到邻居的 Hello 数据包
- 但 Hello 中未列出本路由器
- 单向通信
3. 2-Way (双向通信)
特征
- 收到的 Hello 中包含本路由器 ID
- 双向通信已建立
- 决策点:是否建立邻接关系
邻接建立条件
- 点到点网络:总是建立
- 点到多点网络:总是建立
- 广播网络:仅与 DR 和 BDR
- NBMA 网络:仅与 DR 和 BDR
4. ExStart (开始交换)
特征
- 协商主从关系
- Router ID 大的成为 Master
- 确定初始 DD 序列号
数据包交换
- 交换空的 DD 数据包
- 仅包含 DD 头部信息
- 协商 MTU 和选项
5. Exchange (数据库描述)
特征
- 交换数据库描述数据包(DD)
- 描述本地 LSDB 内容
- 不包含完整 LSA,仅 LSA 头部
Master/Slave 行为
- Master 控制序列号递增
- Slave 回应 Master 的序列号
- 使用窗口机制控制流量
6. Loading (加载)
特征
- 请求缺失或过期的 LSA
- 发送 Link State Request(LSR)
- 接收 Link State Update(LSU)
完成条件
- Link State Request List 为空
- 所有请求的 LSA 已接收
7. Full (完全邻接)
特征
- 数据库完全同步
- 正常运行状态
- 可以计算路由
7.3 邻接建立决策 (Adjacency Formation Decision)
决策矩阵
| 网络类型 | 与谁建立邻接 | 原因 |
|---|---|---|
| 点到点 | 所有邻居 | 只有一个邻居 |
| 点到多点 | 所有邻居 | 视为多个点到点 |
| 广播 | DR 和 BDR | 减少邻接数量 |
| NBMA | DR 和 BDR | 减少邻接数量 |
| 虚拟链路 | 虚拟邻居 | 特殊配置 |
广播和 NBMA 网络的优化
问题:N 个路由器需要 N(N-1)/2 个邻接
解决方案:指定路由器(DR)机制
- 选举一个 DR 和一个 BDR
- 所有路由器仅与 DR 和 BDR 建立邻接
- 邻接数量减少到 2(N-1)
7.4 DR 和 BDR 选举 (DR/BDR Election)
选举算法
选举时机
- 接口状态从 Waiting 转到 DR 或 DROther
- Hello 数据包触发重新计算
选举规则
-
优先级比较
- Router Priority = 0:不参与选举
- 优先级越高越优先
-
Router ID 比较
- 优先级相同时,Router ID 大的获胜
-
两阶段选举
- 第一阶段:选举 BDR
- 第二阶段:选举 DR
选举过程
步骤 1: 选举 BDR
- 排除声明自己是 DR 的路由器
- 选择优先级最高(或 Router ID 最大)的路由器
步骤 2: 选举 DR
- 如果有路由器声明自己是 DR,选择其中最优的
- 否则,将 BDR 提升为 DR
步骤 3: 稳定性检查
- 如果本路由器成为或失去 DR/BDR 角色,重复选举
DR/BDR 的职责
DR(指定路由器)职责
- 生成 Network-LSA
- 作为多路访问网络的中心节点
- 接收并转发 LSA
BDR(备份指定路由器)职责
- 监控 DR 状态
- 维护完整邻接关系
- DR 失效时接管
7.5 数据库描述数据包 (Database Description Packets)
DD 数据包格式
头部字段
| 字段 | 大小 | 说明 |
|---|---|---|
| Interface MTU | 16位 | 接口 MTU 大小 |
| Options | 8位 | 可选能力 |
| Flags | 8位 | I/M/MS 标志 |
| DD Sequence Number | 32位 | 序列号 |
标志位说明
- I (Init): 第一个 DD 数据包
- M (More): 后续还有 DD 数据包
- MS (Master/Slave): 1=Master, 0=Slave
DD 交换过程
Master 行为
- 发送 DD 数据包,序列号 X
- 等待 Slave 响应
- 收到响应后,发送下一个 DD(序列号 X+1)
Slave 行为
- 等待 Master 的 DD
- 响应相同序列号的 DD
- 等待下一个 Master DD
7.6 Link State Request 数据包 (LSR Packets)
LSR 生成时机
触发条件
- Exchange 状态:发现邻居有更新的 LSA
- Loading 状态:继续请求缺失的 LSA
- Full 状态:偶尔请求缺失的 LSA
LSR 数据包内容
每个请求包含:
- LS Type:LSA 类型
- Link State ID:LSA 标识符
- Advertising Router:通告路由器
请求列表管理
Link State Request List
- 按 LS Type 排序
- 跟踪待请求的 LSA
- 重传机制:RxmtInterval 后重发
7.7 Link State Update 数据包 (LSU Packets)
LSU 用途
使用场景
- 响应 LSR(单播)
- 泛洪新 LSA(组播/广播)
- 定期刷新 LSA
LSU 数据包结构
LSU 数据包
├── OSPF 头部
├── LSA 数量
└── LSA 列表
├── LSA 1
├── LSA 2
└── ...
可靠传输机制
确认方式
- 显式确认:Link State Acknowledgment 数据包
- 隐式确认:接收到重复的 LSA
重传机制
- 未收到确认的 LSA 加入重传列表
- RxmtInterval(默认 5 秒)后重传
7.8 Link State Acknowledgment 数据包 (LSAck Packets)
确认时机
延迟确认
- 接收多个 LSA 后批量确认
- 延迟时间通常 < 1 秒
- 减少数据包数量
立即确认
- 接收重复的 LSA
- 收到较旧的 LSA 实例
确认数据包格式
LSAck 数据包
├── OSPF 头部
└── LSA 头部列表(仅头部,不含完整 LSA)
7.9 邻接维护 (Adjacency Maintenance)
Hello 协议的作用
持续监控
- 周期性发送 Hello 数据包
- 监听邻居的 Hello
- Dead Interval 内未收到 Hello 则邻居失效
Hello 间隔
- 点到点/广播:10 秒
- NBMA:30 秒
- 可配置
Dead 间隔
- 默认:Hello Interval × 4
- 点到点/广播:40 秒
- NBMA:120 秒
邻接失效处理
失效检测
- Dead Interval 内未收到 Hello
- 接口状态变为 Down
- 收到带有空 Neighbor List 的 Hello
失效响应
- 邻居状态转为 Down
- 删除该邻居的 LSA
- 重新计算路由表
- 必要时重新选举 DR/BDR
7.10 邻接建立示例 (Adjacency Formation Examples)
示例 1: 点到点链路
Router A ←────────→ Router B
步骤 1: 双方发送 Hello
A → B: Hello (邻居列表为空)
B → A: Hello (邻居列表为空)
步骤 2: 确认双向通信
A → B: Hello (邻居列表包含 B)
B → A: Hello (邻居列表包含 A)
状态: 2-Way
步骤 3: 协商主从(假设 Router ID: A > B)
A → B: DD (I, M, MS=1, Seq=X)
B → A: DD (I, M, MS=0, Seq=X)
A 成为 Master
步骤 4: 交换数据库描述
A → B: DD (M, MS=1, Seq=X+1) [LSA头部列表]
B → A: DD (M, MS=0, Seq=X+1) [LSA头部列表]
...继续直到交换完成
步骤 5: 请求缺失的 LSA
A → B: LSR [请求 LSA 1, 2, 3]
B → A: LSU [LSA 1, 2, 3]
A → B: LSAck [确认 1, 2, 3]
步骤 6: 达到 Full 状态
状态: Full
可以计算路由
示例 2: 广播网络
网络拓扑:
Router A (Priority 2)
Router B (Priority 1)
Router C (Priority 1)
共享以太网段
步骤 1: 所有路由器发送 Hello
步骤 2: 选举 DR 和 BDR
结果: A 成为 DR (最高优先级)
B 成为 BDR (Router ID 大于 C)
步骤 3: 建立邻接
B ↔ A: 建立邻接 (DROther ↔ DR)
C ↔ A: 建立邻接 (DROther ↔ DR)
B ↔ C: 保持 2-Way (DROther ↔ DROther)
步骤 4: A 生成 Network-LSA
7.11 性能优化考虑 (Performance Optimization)
邻接数量控制
目标
- 减少不必要的邻接
- 降低内存和 CPU 消耗
- 加快收敛速度
策略
- 使用 DR/BDR 机制
- 调整路由器优先级
- 合理规划网络拓扑
定时器调优
| 定时器 | 默认值 | 调优建议 |
|---|---|---|
| Hello Interval | 10s | 快速网络可减小 |
| Dead Interval | 40s | 应为 Hello × 4 |
| RxmtInterval | 5s | 高延迟链路增大 |
| InfTransDelay | 1s | 高延迟链路增大 |
技术要点总结 (Technical Summary)
关键机制
-
状态机驱动
- 清晰的状态转换
- 7 个邻居状态
- 事件驱动的行为
-
可靠同步
- 序列号机制
- 确认和重传
- Master/Slave 协调
-
优化设计
- DR/BDR 减少邻接
- 批量确认减少流量
- 分阶段同步数据库
故障排查要点
常见问题
- Hello 参数不匹配
- MTU 不一致
- 区域 ID 不匹配
- 认证失败
- 网络类型配置错误
调试命令参考
- 查看邻居状态
- 检查接口配置
- 验证 Hello 参数
- 查看 LSA 数据库
参考资料 (References)
- 完整原文:RFC 2328 Section 7
- OSPF 状态机:RFC 2328 Section 10
注意 (Note):邻接关系的建立是 OSPF 协议的基础。理解状态转换和数据包交换顺序对于故障排查至关重要。