一. 概述
OSPF 是基于链路状态的路由协议,工作在 IGP 内,会在全网形成统一的 LSDB 数据库,Router 根据 LSDB 以自身为 Root 节点使用迪杰斯特拉(Dijkstra)算法生成 SPF 并基于此生成路由。因为其触发更新,路由控制,区域,无环,收敛速度快等特点,特别适合在大型企业网络中部署。
二. 原理
2.1 基础概念
- ProcessID: 在 OSPFv4 中本地区分不同的 OSPF 进程;
- RouterID: 在进程内唯一标识一台路由器,可手动配置,可自动生成;
- AreaID: 在进程内标识一个 Area,长度 32 bit,可使用点分十进制表示;
- Cost: OSPF 每种接口都会对应一个 Cost 值,在路由入方向累加;
- OSPF 三张表: 邻居表,LSDB 表, 路由表;
- OSPF 报文类型:
- Hello - 类型1 - 发现和维护邻居关系
- Database Description - 类型2 - 交互 LSDB 摘要
- Link State Request - 类型3 - 请求 LSA
- Link State Update - 类型4 - 发送 LSA
- Link State Ack - 类型5 - 确认 LSA
- OSPF 链路类型:
- 实际链路类型:p2p p2mp brocast non-brocast
- ospf 链路描述: StubNet TransNet P2P Virtual-link
2.2 报文
2.2.1 报文头部

- RouterID:
- 建立邻居条件 - 域内 Router-id 不可相同
- AreaID:
- 建立邻居条件 - 邻居间 AreaID 必须相同
- authentication:
- 建立邻居条件 - 认证必须通过
2.2.2 Hello 包
Hello 报文的交互使用 224.0.0.5(普通 Router), 224.0.0.6(DR/BDR) 两个地址,P2P 中可指定单播交互;

- Network Mask:
- 建立邻居条件 - MA 中必须一致, P2P 不要求,P2MP 可关闭
- HelloInterval: 为交互 hello 报文的频率, 默认为 10s
- 建立邻居条件 - 邻居间必须一致
- Options: 额外功能/信息选项, E=是否支持外部路由, MC=是否支持转发组播数据包, N/P=是否为 NSSA 区域;
- 建立邻居条件 - 特殊区域必须一致
- Rtr Pri: DR/BDR 的选举优先级,默认为 1 越大越优,0 则表示不参加 DR/BDR 选举;
- 建立邻居条件 - MA 网络中不能多有 Router 均为 0
- RouterDeadInterval: 邻居失效时间,默认为 40s
- 建立邻居条件 - 邻居间必须一致
- Designated Router / Backup Designated Router: hello 中携带 DR/BDR 的 routerID;
- Neighbor: 发出该报文接口的所有已知 Nei 的 RouterID;
2.2.3 DD 报文
两台设备在邻接关系初始化时,使用 DD 报文描述本端设备的 LSDB,报文包含每个 LSA 的头部;

- Interface MTU: 不分片的情况下,该接口可发出最大的 IP 报文长度;
- 建立邻接条件 - 必须保证两端 MTU 一致,否则会卡在 exstart/exchange 状态;
- Options: E=是否支持外部路由, N/P=处理Type-7 LSA, DC: 处理按需链路;
- I: 第一个报文 DD 置 1 ,否则为 0;
- M: 是否为最后一个 DD 报文;
- M/S: 邻居间交互 DD 报文前,确认主从,RouterID 大的为主,M/S 为 1 是标识发送方为主路由器;
- DD sequence: DD 报文序列号,用于确保 DD 传输的可靠性和完整性;
- LSA Headers: DD 报文中的 LSA 头部,LSA 头部可以唯一标识一个 LSA;
2.2.4 LSR 报文
用于向邻居请求 DD 中有,但本地 LSDB 中没有的 LSA;

- LS type: LSA 的类型号
- Link State ID: 与 LS type 一起描述路由域内唯一的 LSA;
- Advertising Router: 产生该 LSA的路由器的 RouterID;
- LS type + Link State ID + Advertising Router 可以唯一标识一个 LSA;
- LSA 的新旧程度需要根据 LSA 内部的 LS sequence number, LS checksum 和 LS age 判断;
2.2.5 LSU 报文
向对端设备发送其需要的 LSA 或者泛洪本端更新的 LSA;

- Number of LSAs: 报文中包含的 LSA 数量;
- LSA: 具体的每个 LSA,有独立的结构;
2.2.6 LSAck 报文
向对端设备发送其需要的 LSA 或者泛洪本端更新的 LSA;

- LSAs Headers: 告知邻居已收到的 LSA 信息;
2.3 DR 与 BDR
- 作用: 在 MA 网络中,将 LSA 同步的算法规模由 N^2 降低为 N,同时也方便对 MA 网络的描述;
- 选举: 大的接口优先级 > 大的 RouterID,如果收到的 hello 报文中已携带 DR/BDR, 不抢占;
- 过程:
- 接口 UP 后,路由器发送无 DR/BDR 的 Hello 报文,并进入 wait 状态,等待一个 Holdtime;
- 在 wait 状态下,收到包含 DR/BDR 的 Hello 报文,停止 wait,进入 Two-Way;
- 在 wait 结束时,基于选举规则与现有的邻居信息,选举 DR/BDR;
- 当 DR 故障时,BDR 变为 DR,其他非 0 优先级的路由器选举 BDR;
- 优化: 如果 MA 网络的实际拓扑是 P2P 建议更改链路类型为 P2P, 可以加快收敛;
2.4 收敛过程
- Down:
- 进入 - 启动 OSPF 进程后;
- 动作 - 发出 Nei 为 Null 的 hello 包;
- Init:
- 进入 - 收到 Nei 为 Null 的 hello 包;
- 动作 - 发送 Nei 不为 Null 的 hello 包;
- Two-way:
- 进入 - 收到 Nei 有自身的 RouterID 的 hello 包;
- 收敛 - Dother 间保持该状态;
- 动作 - 发送不包含摘要的 DD 报文;
- ExStart:
- 进入 - 发送过不包含摘要的 DD 报文后;
- 动作 - 等待对端的 DD 报文并完成主从选举;
- ExChange:
- 进入 - 主从选取完毕,开始正式交互 DD 报文;
- 动作 - 邻居间进行 DD 报文的交互;
- Loading:
- 进入 - 邻居间完成 DD 信息的交互,开始同步 LSA;
- 动作 - 依据 DD 信息,相互请求自身不存在的 LSA,直至完全相同;
- Full:
- 进入 - LSA 同步完毕,LSDB 完全相同;
- 收敛 - 此后进入 SPF 的计算并生成路由;