OSPF 链路状态路由
课程(8 节,按顺序学)
第 1 课 · 链路状态协议凭什么比距离矢量强
入门 · 约 10 分钟
本课目标:先搞清 OSPF 的设计思想,后面所有机制都是从这个思想推出来的。
距离矢量的毛病
RIP 那类距离矢量协议是这么工作的:邻居告诉我「到 X 我要走 3 跳」,我就记下「到 X 走 4 跳,下一跳是这个邻居」。
问题是我只拿到了别人的计算结果,看不到原始拓扑。这带来两个后果:
· 邻居算错了我也跟着错,容易形成环路(所以要靠水平分割、毒性逆转、抑制计时器一堆补丁去打补丁)。
· 收敛慢:坏消息要一跳一跳传,还要等计时器。
链路状态的做法:传原材料,各自算
OSPF 反过来:只泛洪原始的链路信息(LSA),绝不传自己的计算结果。
每台设备把收到的 LSA 拼成一份完整的链路状态数据库(LSDB),然后以自己为根跑一遍 Dijkstra 算最短路。
这样一来:
· 每台设备看到的是同一张完整的图,天然不会环(只要 LSDB 一致)。
· 收敛快:LSA 泛洪出去,大家各自重算,不用一跳跳传递。
· 代价是内存和 CPU 更贵 —— 这就是要分区域的原因。
由此推出 OSPF 的全部机制
顺着「大家必须看到同一张图」这一条,OSPF 的设计就都能推出来了:
· 要保证 LSDB 一致 → 需要严格的同步机制(DD / LSR / LSU / LSAck 四种报文)
· 要知道该跟谁同步 → 需要邻居发现和邻居状态机(Hello)
· 广播网上两两同步太浪费 → 选个 DR 来中转
· LSDB 太大扛不住 → 划区域,把泛洪范围限制住
· 区域之间要传路由但不传拓扑 → Type3 摘要(所以区域间是矢量式的)
把这条主线记住,OSPF 就不用死背了。
动手:看一遍 SPF
加载「单区域四台设备」,去 ④ SPF 计算 页,选 R1 当根点播放。
注意 R1→R3 的 cost 只有 5、R1→R2 要 10,但去 R4 最终走的是 R2 —— 因为 10+10 < 5+30。贪心选第一跳会算错。
实验重点
- 链路状态协议只泛洪原始 LSA,不传计算结果
- 每台设备以自己为根独立跑 Dijkstra
- LSDB 必须全区域一致,否则会环
- 分区域的目的就是限制泛洪范围、控制 LSDB 大小
第 2 课 · 邻居和邻接不是一回事
入门 · 约 12 分钟
本课目标:分清 2-Way 和 Full,这是看邻居表的前提。
两个概念
· 邻居关系(到 2-Way):双方的 Hello 报文里都列出了对方,互相认识了。
· 邻接关系(到 Full):LSDB 同步完成,这条链路才会被算进 SPF。
只有 Full 的链路才会出现在 Router LSA 里。所以看到 2-Way 先别慌,要看它是不是「设计如此」。
状态机七步走
Down → Init → 2-Way → ExStart → Exchange → Loading → Full
· Init:收到对方 Hello,但里面没有我的 Router-ID —— 对方没认可我。
· 2-Way:双方 Hello 里都有对方。邻居关系建立完成。
· ExStart:协商主从(Router-ID 大的当 Master)和 DD 序列号。
· Exchange:互发 DD 报文交换 LSDB 摘要。
· Loading:用 LSR 请求自己缺的,对方用 LSU 回,自己回 LSAck。
· Full:同步完成。
广播网上 DROther 之间就停在 2-Way
这是设计如此,不是故障。
广播网上如果 n 台设备两两建邻接,要 n(n-1)/2 个邻接关系,而且同一条 LSA 会被重复泛洪很多遍。
所以 OSPF 选一个 DR 出来做中转:所有设备只跟 DR 和 BDR 建邻接(n-1 个),DROther 之间只到 2-Way。
动手:加载「广播网段 DR 选举」,去 ② 拓扑与邻居 页看邻居表 —— 会看到几对处于 2-Way 的邻居,并标注「设计如此」。
实验重点
- 邻居 = 2-Way,邻接 = Full
- 只有 Full 的链路才进 SPF 计算
- 广播网上 DROther 之间只到 2-Way,是正常的
- DR 的作用是把 n(n-1)/2 个邻接降到 n-1 个
第 3 课 · 邻居起不来怎么查
排障 · 约 16 分钟
本课目标:两条分界线定位所有邻居故障。
先记住两条分界线
① 卡在 Init → 一定是 Hello 报文里的参数不一致,对方直接把我的 Hello 丢了。
Hello 里带这些字段,任何一个不同都不行:
· Hello 间隔 / Dead 间隔
· 区域号(接口级属性!)
· 认证方式和密钥
· 掩码(广播网校验,P2P 不校验)
· Stub 标志 E-bit
② 能到 2-Way 或 ExStart 但上不去 Full → Hello 参数是对的,问题出在 DD 阶段:
· MTU 不一致(Hello 里不带 MTU,只有 DD 带 —— 所以能到 2-Way)
· Router-ID 冲突
为什么 Hello 间隔容易配错
最常见的成因不是有人手工改了间隔,而是两端网络类型配得不一样:
· 广播 / P2P:Hello 10 秒,Dead 40 秒
· NBMA / P2MP:Hello 30 秒,Dead 120 秒
所以一端配成 broadcast、另一端配成 nbma,间隔就自动不一致了。查 Hello 间隔的时候顺手看一眼网络类型。
动手:四条链路四个故障
加载「故障诊断」场景,R1 连着四台设备,每条链路埋了一个不同的经典故障。
去 ② 拓扑与邻居 页,一条条点开看状态和诊断,然后自己动手改好:
① Hello 间隔不一致 ② 区域号不一致 ③ MTU 不一致 ④ 认证不匹配
改的时候注意观察:前三个里哪些卡 Init、哪个卡 ExStart。
真机排障命令
display ospf peer brief # 先看状态 display ospf interface # 区域/cost/Hello/DR 一目了然 display ospf error # 参数不匹配的计数器,排障神器 display ospf lsdb # LSDB 是否同步
display ospf error 会直接告出「Hello interval mismatch」这类计数,比一个个 diff 配置快得多。
实验重点
- 卡 Init = Hello 参数不一致(间隔/区域/认证/掩码/E-bit)
- 能到 2-Way 但上不去 Full = MTU 不一致 或 Router-ID 冲突
- Hello 间隔不一致常常是网络类型配错的副作用
- display ospf error 直接告诉你哪个参数不匹配
第 4 课 · DR/BDR 选举
入门 · 约 10 分钟
本课目标:两条规则 + 两个坑。
选举规则只有两条
① 接口优先级大者优先,优先级 0 表示放弃参选。
② 优先级相同,比 Router-ID,大者优先。
第一名当 DR,第二名当 BDR,其余都是 DROther。
注意优先级是接口级的(ospf dr-priority),不是设备级的。
坑一:非抢占
新上线的设备即使优先级更高,也不会把现任 DR 挤下去。
为什么这么设计?因为 DR 变更要重建所有邻接、重新同步 LSDB,代价很大。OSPF 宁愿保持稳定也不追求「最优」。
后果是:现网规划好优先级之后,如果是后加的设备想当 DR,必须重启 OSPF 进程(reset ospf process)才生效。这也是「配置看起来对但 DR 不是我想要的那台」的原因。
坑二:只有广播和 NBMA 才选
P2P 和 P2MP 不选 DR/BDR,也不产生 Type2 Network LSA。
道理很直接:只有两台设备,选个 DR 出来并不能减少邻接数量。
所以现网有个常见优化:把只有两台设备的以太网链路手工改成 P2P 类型,省掉 DR 选举、少一条 Type2 LSA、收敛也更快。
动手:看选举过程
加载「广播网段 DR 选举」:四台设备接在同一个以太网上,R1 优先级 1、R2 和 R3 都是 100、R4 是 0。
去 ② 拓扑与邻居 页点那个网段,看选举结果和每台设备的角色理由 —— R2/R3 同优先级时是靠 Router-ID 分出来的,R4 因为优先级 0 直接不参选。
实验重点
- 优先级大者优先(0 不参选),相同比 Router-ID 大者
- 非抢占:后来的高优先级设备不会挤掉现任 DR
- 只有广播和 NBMA 选 DR,P2P 不选也不产生 Type2
- 两台设备的以太网建议手工改成 P2P 类型
第 5 课 · 七种 LSA 与泛洪范围
进阶 · 约 18 分钟
本课目标:记 LSA 只需要记住「谁产生、传到哪」。
一张表搞定
| 类型 | 谁产生 | 泛洪范围 | 内容 |
|---|---|---|---|
| Type1 Router | 每台路由器 | 本区域 | 自己的链路和 cost |
| Type2 Network | 只有 DR | 本区域 | 谁挂在这个广播网段上 |
| Type3 Summary | ABR | 跨区域 | 别的区域的前缀 + 开销 |
| Type4 ASBR Summary | ABR | 跨区域 | 怎么到那个 ASBR |
| Type5 AS External | ASBR | 全 AS(Stub 除外) | 引入的外部路由 |
| Type7 NSSA External | NSSA 的 ASBR | 本 NSSA 区域 | 到 ABR 转成 Type5 |
Type1 + Type2 是 SPF 的原材料,其余几种只带前缀和开销、不带拓扑。
为什么区域间不做 SPF
因为 Type3 里只有前缀和开销,没有拓扑。
所以区域间路由本质上是矢量式的:「ABR 告诉我到 X 要 20,我到 ABR 要 10,那我到 X 就是 30」。这和 RIP 的思路是一样的。
推论 1:区域间路由不可能比区域内路由更可信 —— 这就是路由优先级「区域内 > 区域间」的由来。
推论 2:既然是矢量式的就可能环,所以有了一条硬规则 —— ABR 只接受来自骨干区域 area 0 的 Type3。
再推论:所有非骨干区域必须直连 area 0,不然它的路由传不出去。实在做不到就用虚连接穿过一个区域把它接回骨干。
Type4 存在的理由
Type5 里写的下一跳是 ASBR 的 Router-ID,不是一个可路由的地址。
别的区域的设备拿到 Type5,知道「172.16.1.0/24 在 ASBR 5.5.5.5 后面」,但不知道怎么走到 5.5.5.5。
所以 ABR 要额外产生一条 Type4 说明「到 5.5.5.5 从我这走,开销 X」。
结论:Type4 只在 ASBR 和你不在同一个区域时才需要。同区域直接算就行了。
动手:看泛洪范围
加载「多区域 + ABR + ASBR」,去 ③ LSDB 页:
① 按区域看,注意 Type1/Type2 只在本区域出现;
② 看 Type3/Type4 是哪台 ABR 产生的、注入到了哪个区域;
③ 切到 Stub 场景,看 Type5 被挡在门外、变成一条默认路由。
实验重点
- Type1/2 是 SPF 原材料,只在本区域泛洪
- Type3/4 由 ABR 产生,只带前缀和开销,所以区域间是矢量式的
- ABR 只接受 area 0 的 Type3 → 非骨干区域必须直连骨干
- Type4 只在 ASBR 跨区域时才需要
第 6 课 · SPF 怎么算的
进阶 · 约 14 分钟
本课目标:看懂候选列表和最短路径树,顺便搞清 cost。
算法五步
① 把自己放进最短路径树(SPT),开销 0。
② 把直连邻居放进候选列表,开销 = 出接口 cost。
③ 从候选列表里挑累计开销最小的,放进 SPT。
④ 用它去松弛候选列表:发现更短的路径就把开销改小。
⑤ 重复 ③④,直到候选列表为空。
同开销时的处理:先取路由器节点,再按 ID 排序 —— 目的是让全网每台设备算出完全一致的结果,否则会环。
最容易犯的直觉错误
第一跳便宜 ≠ 整条路便宜。
单区域场景里:R1→R3 的 cost 是 5,R1→R2 是 10。看第一跳好像该走 R3。
但 R3→R4 要 30,R2→R4 只要 10。所以去 R4 的最短路是 R1→R2→R4(20),不是 R1→R3→R4(35)。
Dijkstra 就是为了解决这个才存在的 —— 它按累计开销推进,不是按下一跳。
cost 是怎么算的
华为默认 cost = 参考带宽 / 接口带宽,参考带宽默认 100 Mbps,最小值 1。
问题来了:千兆口算出来 100/1000 < 1 → 取 1;万兆口也是 1。千兆和万兆区分不开。
所以现网必做的一件事:把参考带宽调大(bandwidth-reference 100000)。
⚠️ 全网必须改成一样的值,否则各设备算出的 cost 不一致,选路会乱。
另外 cost 是接口级、单向的:A→B 和 B→A 可以不同,会造成来回走不同路径 —— 排查非对称路由时先看两端 cost。
实验重点
- Dijkstra 按累计开销推进,不是按第一跳
- 同开销时按固定规则打破平局,保证全网结果一致
- cost = 参考带宽/接口带宽,默认参考带宽 100M 导致千兆万兆不分
- 改参考带宽必须全网一致;cost 是单向的
第 7 课 · 路由表:四种类型和优先级
进阶 · 约 12 分钟
本课目标:搞清同一个前缀有多条时谁赢。
四种类型,硬性优先级
区域内(O) > 区域间(O IA) > 外部Type1(O E1) > 外部Type2(O E2)
注意这是硬性的:一条 cost 100 的区域内路由,压过 cost 2 的区域间路由。
先比类型,类型相同才比 cost。
道理在第 5 课讲过了:区域内路由是自己用完整拓扑算的,区域间只是别人告诉你的开销,可信度天然不同。
外部 Type1 vs Type2
· Type2 是引入时的默认:路由 cost = 只看外部 cost,不加内部开销。
好处是简单稳定;坏处是有多个 ASBR 时分不出哪个近,可能绕远。
· Type1:cost = 内部开销 + 外部开销,能反映内部路径差异。
引入时写 type 1 就能改。
同前缀同时存在 Type1 和 Type2 时,Type1 优先。
动手:对照着看
加载「多区域 + ABR + ASBR」,去 ② 拓扑与邻居 页点不同设备,在右侧详情面板里展开「OSPF 路由表」看:
① 找出 O / O IA / O E1 / O E2 各是哪些;
② 展开某条路由看「怎么算出来的」,尤其是区域间的开销累加;
③ 找一条被压掉的路由,看它输在类型还是输在 cost。
R5 引入了两条外部路由,一条 Type2 一条 Type1,正好对比。
实验重点
- 区域内 > 区域间 > 外部Type1 > 外部Type2,先比类型再比 cost
- Type2 只看外部 cost,Type1 累加内部 cost
- 同前缀 Type1 优先于 Type2
第 8 课 · 特殊区域:Stub 和 NSSA
进阶 · 约 12 分钟
本课目标:用区域类型换 LSDB 规模。
为什么要有特殊区域
Type5 是全 AS 泛洪的。如果引入了几万条外部路由,全网每台设备(包括分支的小设备)都要存这几万条 LSA、每次变化都要重算 SPF。
但分支站点其实不需要知道细节 —— 它只有一条出口,给它一条默认路由就够了。
这就是特殊区域的全部意义:用「少知道」换「省资源」。
三种类型挡什么
| 类型 | 挡掉 | ABR 补什么 |
|---|---|---|
| Stub | Type4 / Type5 | 一条 Type3 默认路由 |
| 完全 Stub(stub no-summary) | Type3 / Type4 / Type5 | 一条 Type3 默认路由 |
| NSSA | Type4 / Type5,但允许 Type7 | 可选默认路由 |
NSSA 的用途:既想挡住外面的外部路由,又想让本区域自己能引入外部路由。本区域 ASBR 产生 Type7,到了 ABR 被转换成 Type5 再往其它区域泛洪。
Stub 区域的限制(考试常问)
· 不能是骨干区域 area 0(骨干要转发所有路由)
· 区域内不能有 ASBR(因为 Type5 被挡了,引入也传不出去)—— 这正是 NSSA 存在的理由
· 不能有虚连接穿过
· 区域内所有路由器都必须配 Stub:Hello 里的 E-bit 不一致会导致邻居起不来,一台漏配就全断
动手:看 Type5 被挡住
加载「Stub 区域」(area 1 是 Stub),去 ③ LSDB 页看 R3(在 area 1 里):
① 它的 LSDB 里没有 Type5;
② 多了一条 ABR 下发的 Type3 默认路由 0.0.0.0/0;
③ 再去 ② 拓扑与邻居 页点 R3,展开「OSPF 路由表」确认它没有 O E1/O E2 路由,只有一条默认路由。
实验重点
- 特殊区域用「少知道」换「省资源」
- Stub 挡 Type4/5,完全 Stub 连 Type3 也挡,NSSA 挡 4/5 但允许 Type7
- Stub 区域不能是 area 0、不能有 ASBR、不能有虚连接
- 区域内所有路由器都要配 Stub,一台漏配就全起不来