简介:《RFC2328中文版》是OSPF v2协议的完整中文文档,面向网络管理员、网络工程师及准备网络认证的读者,用于系统理解链路状态路由、区域划分与路由计算等核心机制。文件包共1个PDF,约1.93MB,便于在电脑或移动端查阅,也可作为实验配置、协议对照和故障排查时的案头参考。内容从协议概述、术语定义、链路状态数据库组织与SPF计算讲起,逐步展开骨干区域、区域间路由、LSA类型与老化、认证安全、操作配置及性能优化,并附连接状态数据库示例与清晰目录。已有431人学习,适合希望吃透OSPF原理、建立完整知识框架的中高级网络从业者。
1. 为什么排障老手会翻这份 RFC2328 中文版:从邻居卡在 ExStart 说起
邻居卡在 ExStart,日志只给一句重传提示,很多人第一反应是去搜配置模板。我把 RFC2328 中文版翻到第 10 章邻居状态机那一页,才发现问题不在模板,而在 DD 包的接口 MTU 与主从选举参数。RFC2328 中文版是 OSPFv2 协议规范的中文译本,不是软件包,也不是插件,它把连接状态数据库、LSA、SPF、区域和包格式按章节摊开。适合已经能配基础 OSPF、但一遇到邻居震荡、LSA 不洪泛、区域间路由缺失就靠猜的从业者;新手可以按第 3、10、12 章跟做,熟手可以直接查附录 A 的字段表。它解决的是“为什么这样配”和“失败时看哪个字段”的问题,而不是给你一键安装脚本。
2. 把 RFC2328 中文版当协议字典:先搭 LSA 与 SPF 的阅读骨架
2.1 文档结构不是目录,而是排障索引
拿到一份 80 多页的协议规范,最怕从第一页逐字读到最后一页。这份中文版的目录本身就是一张排障索引:第 2 章讲连接状态数据库怎么组织,第 3 章讲区域怎么划分,第 7、9、10 章讲邻接和状态机,第 12、13 章讲 LSA 与洪泛,第 16 章讲路由表计算,附录 A 到 C 才是字段、常量和可配置变量的速查表。阅读顺序应该跟着故障现象走,而不是跟着页码走。邻居建不起来,先翻第 7、9、10 章;数据库看起来同步了但路由不对,先翻第 12、13、16 章;区域间路由缺失,先翻第 3、12.4.3 和 16.2 节。
我在某实验室的三路由器实验环境里做过一次对照:同样的拓扑,只改接口网络类型,邻居状态就从 Full 退到 2-Way。文档第 9、10 章把接口状态和邻居状态分开描述,这个拆分很关键。接口状态管的是接口能不能发 Hello、能不能参与 DR 选举;邻居状态管的是两台路由器之间到了哪一步。排障时先看接口状态,再看邻居状态,最后才看 LSDB,顺序反了就会在错误的一层里打转。
下面这张表是我自己常用的“章节到故障”索引,不追求覆盖全部内容,只求在翻车时能快速定位:
| 现象 | 先翻章节 | 重点看什么 | 常见误判 |
|---|---|---|---|
| 邻居卡在 Init | 7.1、9.5、10.5 | Hello 包是否双向可达 | 只看本端配置,不看对端是否收到 |
| 邻居卡在 ExStart | 10.6、10.8、附录 A.3.3 | DD 包主从选举、接口 MTU | 把 MTU 不一致当成认证失败 |
| 邻居卡在 Exchange/Loading | 10.6、10.7、10.9 | DD 序号、LSR 请求的 LSA | 以为 LSDB 一定完整 |
| 路由表缺区域间路由 | 3.2、12.4.3、16.2 | ABR 是否生成 Summary-LSA | 只看 LSDB 有 LSA,不看 SPF 是否重算 |
| 外部路由不生效 | 12.4.4、16.4 | ASBR、Forwarding Address、E 位 | 把外部路由当成本区域路由查 |
| LSA 反复刷新 | 12.1.1、13、14 | LS 序号、老化时间、重传列表 | 只看日志里的“收到更新” |
这张表不是让你背,而是让你在抓包之前先确定“该看哪一页”。RFC2328 中文版的价值不在于读完,而在于你愿意在故障现场把它当字典翻。文档第 1 章把术语定义集中放在前面,第 2 章用示例 LSDB 解释路由器节点和网络节点怎么表示,这两章适合在实验前读一遍,后面再回来查。不要把它当插件说明书找“安装步骤”,它没有安装步骤,只有协议行为和字段语义。
2.2 连接状态数据库与最短路径树:SPF 计算到底看哪几节
连接状态数据库不是一张路由表,它是一张拓扑图。每台路由器把自己周围的链路状态写成 LSA,洪泛到同一个区域内的所有路由器,最后每台路由器都拿到一份相同的 LSDB。第 2.1 节讲路由器和网络的表示方法,第 2.1.1 节专门讲非广播网络怎么表示,第 2.1.2 节给了一个 LSDB 示例。这个示例很值得对照抓包看:Router-LSA 描述路由器节点和它的链路,Network-LSA 描述广播网络节点和接入的路由器,两者拼起来才是一张完整的图。
SPF 计算在第 16.1 节,核心是以本路由器为根,用 Dijkstra 算法算最短路径树。这里有两个容易读漏的点:第一,SPF 只使用同一区域的 Router-LSA 和 Network-LSA 建树,区域间路由和外部路由是后面第 16.2、16.4 节单独处理的;第二,下一跳的计算在第 16.1.1 节,不是简单取邻居接口地址,而要结合链路类型和网络节点。很多人看到 LSDB 里有 LSA 就以为路由一定会有,实际上 SPF 没触发、下一跳不可达、区域边界没汇总,都会让路由表空着。
我在模拟项目 X 里做过一次增量对比:先只跑区域 0,再在 ABR 上加入区域 1。区域 0 的 Router-LSA 数量不变,但区域 1 的 Summary-LSA 开始出现,第 16.2 节的区域间路径计算才会把目的网段加进路由表。如果只看 LSDB 的 LSA 计数,会以为“数据库没变化”;实际上变化发生在 Summary-LSA 和路由表之间。文档第 16.5、16.6 节讲增量更新,正好解释为什么有些路由要等 SPF 调度周期才出现,而不是 LSA 一到就立刻进表。
读这一节时,我建议手边放三个东西:一张手画拓扑、一份抓包里的 Router-LSA 列表、一张路由表。先按第 2.1.2 节的示例把 LSDB 画成图,再按第 16.1 节的步骤标出根节点、候选列表和最短路径树,最后对照路由表看下一跳。这个动作做一遍,比读十遍“SPF 算法”四个字有用。文档里没有花哨的公式,更多是数据结构与计算顺序,这正是排障时需要的东西。
提示:LSDB 相同不等于路由表相同。区域类型、汇总配置、外部路由引入方式、最大等价路径数,都会让同一份 LSDB 算出不同结果。
2.3 区域、骨干区域与 ABR:什么时候该翻第 3 章和第 16 章
区域划分是 OSPF 从“能跑”到“能扩”的分水岭。第 3.1 节讲骨干区域,第 3.2 节讲区域间路由,第 3.3 节把路由器分成内部路由器、区域边界路由器、骨干路由器、AS 边界路由器。这个分类不是为了背名词,而是为了判断“这条 LSA 应该由谁生成”。Router-LSA 由每台路由器生成,Network-LSA 由 DR 生成,Summary-LSA 由 ABR 生成,AS-external-LSA 由 ASBR 生成。生成者找错,排查方向就会偏。
第 3.4 节给了一个简单区域配置示例,第 3.5 节讲 IP 子网化支持,第 3.6 节讲存根区域。存根区域会阻止外部 LSA 进入,ABR 用默认路由代替。如果你的实验里区域 1 是存根区域,却还在等 AS-external-LSA,那就会一直等不到。文档第 3.6 节把行为写得很清楚:不是 LSA 丢了,而是区域类型决定了它不该进来。这个坑在真实网络里很常见,尤其是从其他协议迁移过来的人,习惯性地认为“外部路由应该 everywhere”。
第 3.7 节讲区域的划分,核心是区域不能太大、不能太碎,骨干区域必须连续。虚链路在第 15 章,用来把不连续的骨干区域接起来,但它必须穿过一个传输区域,端点必须是 ABR,传输区域不能是存根区域。很多人配了虚链路但不通,回头查第 15 章才发现传输区域类型不对,或者端点 Router ID 不可达。区域设计和虚链路不是配置技巧,而是拓扑约束,文档把约束写在前面,配置只是最后一步。
读第 3 章时,我会拿一张纸把区域 0、区域 1、ABR、ASBR 标出来,然后问三个问题:这条路由从哪个区域来、由谁汇总、下一跳在哪个区域。第 16.2 节计算区域间路径时,会检查传输区域的 Summary-LSA,第 16.3 节专门讲这个检查。如果 ABR 没有为某个网段生成 Summary-LSA,或者传输区域里缺少可达的 ABR,路由就不会进表。把这些章节连起来看,区域间路由缺失就不再是玄学,而是可以逐项排除的字段问题。
3. 用中文版对照实验:Hello 到邻接建立的参数表与状态机
3.1 Hello 包字段与邻居状态机的对应关系
Hello 包是 OSPF 邻居关系的起点,也是排障时最容易抓到的东西。附录 A.3.2 给了 Hello 包的完整格式:网络掩码、Hello 间隔、选项、路由器优先级、路由器失效间隔、指定路由器、备份指定路由器、邻居列表。第 7.1 节讲 Hello 协议,第 9.5 节讲发送 Hello 包,第 10.5 节讲接收 Hello 包。把这四节连起来看,就能明白为什么“我明明配了同一个区域,邻居还是卡在 Init”。
第一个要对的字段是网络掩码。广播网络和 NBMA 网络上,Hello 包会带接口掩码,同一网段的两台路由器如果掩码不一致,可能进入不了 2-Way。第二个是 Hello 间隔和路由器失效间隔,常见广播网络是 10 秒和 40 秒,NBMA 网络可能是 30 秒和 120 秒,两端必须一致。第三个是选项字段里的 E 位,它表示是否支持外部路由,普通区域和存根区域对 E 位的处理不同。第四个是邻居列表,Init 状态说明本端收到了对方的 Hello,但对方还没看到本端,通常是单向可达或访问控制把 Hello 挡了。
我在某高校的虚拟实验环境里用三台路由器做过对照:R1 和 R2 互连,R3 接在 R2 后面。把 R1 的 Hello 间隔从 10 秒改成 30 秒,R2 的失效间隔仍是 40 秒,邻居会从 Full 掉到 Down,然后反复尝试。抓 Hello 包能看到间隔字段不一致,但日志只会说邻居失效。这个场景说明一个顺序:先抓 Hello 包对字段,再看邻居状态机,最后才看 LSDB。字段不对,后面所有状态都是假的。
下面这张表是我排 Hello 问题时固定要对的字段,按优先级从高到低:
| Hello 字段 | 对应章节 | 常见设置 | 不一致的后果 | 排查动作 |
|---|---|---|---|---|
| 网络掩码 | A.3.2、9.5 | 与接口掩码一致 | 广播网络可能卡 Init/2-Way | 对两端接口掩码 |
| Hello 间隔 | 7.1、9.5 | 广播 10 秒,NBMA 30 秒 | 邻居反复失效 | 对两端接口参数 |
| 路由器失效间隔 | 7.1、10.5 | 通常是 Hello 的 4 倍 | 邻居无法建立或频繁重建 | 检查是否被单独改过 |
| 选项 E 位 | A.2、12.1.2 | 普通区域置位 | 存根区域行为异常 | 看区域类型与选项 |
| 路由器优先级 | 9.4、10.5 | 默认 1,可调 | 影响 DR/BDR 选举 | 确认是否需要调整 |
| 指定路由器/备份指定路由器 | 9.4、10.5 | 由选举产生 | 新加入者可能不认同 | 看选举等待时间 |
| 邻居列表 | 10.5 | 已收到的邻居 | Init 表示单向 | 查反向 Hello 与 ACL |
这张表不是让你每次全对一遍,而是让你在邻居卡住时有一个固定顺序。先对掩码和计时器,再对选项和优先级,最后看邻居列表。顺序反了,容易在 DR 选举上绕很久,最后发现只是 Hello 间隔不一致。
注意:Hello 包能通不代表邻居能到 Full。2-Way 在非 DR/BDR 之间是正常状态,不要为了追求 Full 去强行改优先级。
3.2 数据库同步:DD、LSR、LSU、LSAck 四类包怎么读
邻居从 2-Way 往上走,进入 ExStart、Exchange、Loading,最后到 Full。这个过程在附录 A.3.3 到 A.3.6 里有四类包的格式:数据库描述包、连接状态请求包、连接状态更新包、连接状态确认包。第 10.6 到 10.9 节分别讲接收 DD、接收 LSR、发送 DD、发送 LSR 的处理。第 8.1、8.2 节讲发送和接收协议包的通用流程。把这几个章节放在一起,才能看懂“数据库同步”到底同步了什么。
ExStart 阶段的关键是主从选举。Router ID 大的一方成为主,主负责发送 DD 序号,从方回应。DD 包里有一个接口 MTU 字段,两端 MTU 不一致时,某些实现会卡在 ExStart 或 Exchange。这个点在第 10.6 节和附录 A.3.3 里都能找到依据,但日志往往只给“重传 DD”。我见过一次翻车:两端接口都配了同一个网段,Hello 正常,但一端 MTU 是 1500,另一端是 9000,邻居一直卡在 ExStart。抓包看 DD 包的 MTU 字段立刻能看出来,改回一致后进入 Exchange。
Exchange 阶段交换的是 LSA 头部摘要,不是完整 LSA。每台路由器把自己 LSDB 里的 LSA 头部放进 DD 包,对方比对后,缺哪些就用 LSR 请求完整 LSA,收到 LSU 后回 LSAck。第 10.7 节讲接收 LSR,第 10.9 节讲发送 LSR,第 13.5 节讲发送 LSAck,第 13.7 节讲接收 LSAck。很多人看到邻居到了 Loading 就以为快好了,实际上 Loading 阶段还在等 LSR 的回应,如果请求的 LSA 一直没回来,邻居会卡在 Loading 或反复重传。
这里有一个容易忽略的细节:DD 包里的 LSA 头部有 LS 序号和校验和,接收方判断“我有没有这条 LSA”不是只看 Link State ID,还要看 Advertising Router 和 LS 序号。第 13.1 节讲判定较新的 LSA,规则是序号大者新、序号相同校验和大者新、再相同则年龄小者新。这个规则在数据库同步时同样适用。如果两边对“谁更新”的判断不一致,就会出现一方认为不需要请求,另一方认为需要更新,最后表现为数据库“看起来同步了”但实际有差异。
我在模拟项目 X 里做过一次人为制造差异的实验:先在 R1 上注入一条外部路由,让 R1 生成 AS-external-LSA,然后在 R2 的 LSDB 里保留旧序号。邻居重建后,R2 在 Exchange 阶段看到 R1 的 LSA 序号更大,就会发 LSR 请求,收到 LSU 后更新。如果 R2 的 LSDB 里没有这条 LSA,DD 摘要里也不会出现,R2 就不会请求,直到 R1 洪泛过来。这个顺序说明:数据库同步只保证“双方已知的 LSA 头部一致”,不保证“所有 LSA 都立刻到齐”,后者靠洪泛和第 13 章的重传机制。
读这一节时,我建议抓一次完整的邻居建立过程,按包类型数一数:几个 Hello 进入 2-Way,几个 DD 完成主从选举,几个 LSR/LSU 补齐数据库,最后几个 LSAck 确认。数完再看第 10 章的状态机,会比只看文字清楚得多。
3.3 指定路由器选举:优先级、Router ID 与等待计时器
广播网络和 NBMA 网络要选举指定路由器和备份指定路由器,目的是减少邻接数量。第 9.4 节讲选举指定路由器,第 7.3、7.4 节讲指定路由器和备份指定路由器的概念,第 10.4 节讲是否形成邻接。选举规则不复杂:优先级高者当选,优先级相同则 Router ID 大者当选,备份指定路由器是第二名的角色。但选举不是抢占式的,新加入的路由器优先级再高,也要等当前 DR 失效或重新选举才会接管。
等待计时器是这里的关键参数。广播网络上的路由器在接口启动后,会等待一个路由器失效间隔的时间再参与选举,目的是让所有路由器都听到彼此。这个等待时间在第 9.4 节和第 9.5 节里有描述。很多实验里,先启动的路由器先成为 DR,后启动的路由器即使优先级更高也只能当备份,原因就是没有触发重新选举。要强制重新选举,通常需要重启接口或调整优先级后等待,而不是改完配置立刻生效。
我在某公司的测试环境里遇到过一次“DR 不固定”的问题:三台路由器同时启动,优先级都是默认 1,结果每次重启后 DR 都不一样。后来把其中一台上调优先级到 100,并确认其他两台的优先级保持 1,DR 才稳定下来。这个过程中,Router ID 也起了作用:优先级相同的时候,Router ID 大的那台会成为 DR。如果 Router ID 是自动选的,接口地址一变,选举结果就可能变。所以我在实验环境里通常手动指定 Router ID,避免地址变化带来玄学问题。
第 10.4 节讲是否形成邻接,这里有一个容易误解的点:不是所有邻居都要到 Full。广播网络上,非 DR/BDR 之间停留在 2-Way 是正常设计,只有 DR 和其他路由器、BDR 和其他路由器之间才形成 Full 邻接。如果你看到两台非 DR/BDR 停在 2-Way,不要急着改配置,先确认它们是不是本来就不需要形成邻接。反过来,如果 DR 和某台路由器停在 2-Way,那才是问题,可能是 Hello 参数不一致、网络类型不匹配或 ACL 挡了单播。
下面这张表是我在实验里固定检查的 DR 选举参数:
| 参数 | 作用 | 常见值 | 调错后的现象 | 处理方式 |
|---|---|---|---|---|
| 接口优先级 | 决定选举排名 | 默认 1,可调 0-255 | 优先级 0 不参与选举 | 按角色规划设置 |
| Router ID | 优先级相同时比较 | 手动指定最稳 | 自动变化导致 DR 漂移 | 实验环境手动固定 |
| 等待计时器 | 启动后等待选举 | 通常等于失效间隔 | 新设备加入后不抢 DR | 确认是否需要重新选举 |
| 网络类型 | 决定是否选举 | 广播/NBMA 选举 | 点对点不选举 | 按链路实际类型配置 |
| 认证参数 | 决定 Hello 是否被接受 | 两端一致 | 邻居卡 Init 或 Down | 先对认证再对选举 |
这张表里的“网络类型”经常被忽略。点对点链路上不需要 DR/BDR,如果你把接口配成广播网络,就会多出选举行为,邻居状态也可能和预期不一样。第 9.5.1 节专门讲 NBMA 网络上发送 Hello 包,NBMA 需要手动配置邻居,和广播网络的自动发现不一样。把这些差异记住,比背选举公式更有用。
4. 把五类 LSA 讲透:生成条件、字段与洪泛路径
4.1 LSA 头部七个字段:老化、序号与校验和怎么配合
LSA 头部在附录 A.4.1 和第 12.1 节有完整描述,核心字段包括 LS 年龄、选项、LS 类型、连接状态标识、宣告路由器、连接状态序号、连接状态校验和、长度。这七个字段决定了一条 LSA 的身份、新旧和有效期。排障时如果只看 LS 类型和连接状态标识,很容易把两条不同的 LSA 当成同一条,因为宣告路由器不同、序号不同,它们就是不同的 LSA。
LS 年龄从 0 开始,随着时间增长,最大到 MaxAge。第 12.1.1 节讲连接状态时限,第 14 章讲老化连接状态数据库,第 14.1 节讲提前老化 LSA。常见常量是 LSRefreshTime 1800 秒、MaxAge 3600 秒、MinLSInterval 5 秒、MinLSArrival 1 秒。路由器会周期性地刷新自己生成的 LSA,把年龄重置;如果一条 LSA 到了 MaxAge,就会被洪泛并从数据库中删除。这里有一个坑:看到 LS 年龄接近 MaxAge 不代表 LSA 马上失效,可能只是还没到刷新周期,或者刷新包在路上。
LS 序号用来判断新旧,初始值是一个负数,向正数方向增长,回绕后有特殊处理。第 13.1 节讲判定较新的 LSA,规则是序号大者新;序号相同则校验和大者新;校验和也相同则年龄小者新,但如果年龄差超过 MaxAgeDiff,则年龄小者新,否则认为相同。这个规则在数据库同步和洪泛时都会用到。校验和覆盖 LSA 头部和内容,年龄字段在计算校验和时按特定规则处理,所以不要手动改年龄字段去“修复”LSA,容易把校验和弄坏。
我在一次实验里故意把一条 LSA 的年龄改到接近 MaxAge,观察它什么时候被删除。结果是:路由器不会因为年龄大就立刻删除,而是等到 MaxAge 才洪泛最大年龄的 LSA,其他路由器收到后从数据库中移除。如果这时原路由器还在刷新,就会重新生成一条年轻 LSA,形成“删了又出现”的现象。这个现象在第 14 章和第 13.4 节里有解释,不是数据库损坏,而是老化与刷新的正常交互。
下面这张表是我对 LSA 头部字段的速查,按排障时看的顺序排列:
| 字段 | 作用 | 异常表现 | 先看哪里 |
|---|---|---|---|
| LS 年龄 | 有效期与老化 | 接近 MaxAge 但路由还在 | 12.1.1、14 |
| LS 类型 | 区分 1-5 类 LSA | 类型对不上导致查错表 | A.4、12.1.3 |
| 连接状态标识 | 标识目的或对象 | 同 ID 不同宣告者被混淆 | 12.1.4 |
| 宣告路由器 | 谁生成的 LSA | 生成者不对导致路由缺失 | 12.1.5 |
| LS 序号 | 判断新旧 | 序号回绕导致更新不生效 | 13.1 |
| LS 校验和 | 完整性校验 | 校验和错误导致 LSA 被丢弃 | 12.1.7 |
| 长度 | 头部加内容长度 | 长度不对导致解析失败 | A.4.1 |
这张表里的“宣告路由器”是最容易被忽略的。一条 Summary-LSA 的宣告路由器应该是 ABR,如果看到内部路由器宣告了 Summary-LSA,那生成逻辑就有问题。一条 AS-external-LSA 的宣告路由器应该是 ASBR,如果 ASBR 没配置路由引入,就不会有这条 LSA。把生成者和 LSA 类型对上,排查范围会小很多。
4.2 Router-LSA 与 Network-LSA:描述拓扑的两块积木
Router-LSA 是第 1 类 LSA,由每台路由器生成,描述自己的链路。第 12.4.1 节讲生成 Router-LSA,附录 A.4.2 给格式。它包含链路数量,每条链路有 Link ID、Link Data、类型和度量。链路类型有四种:点对点、传输网络、存根网络、虚链路。点对点链路描述邻居 Router ID,传输网络描述 DR 的接口地址,存根网络描述网段和掩码,虚链路描述虚邻居。这四种类型拼起来,才是一张完整的路由器节点图。
Network-LSA 是第 2 类 LSA,由 DR 生成,描述广播或 NBMA 网络。第 12.4.2 节讲生成 Network-LSA,附录 A.4.3 给格式。它的连接状态标识是 DR 的接口 IP 地址,内容包括网络掩码和接入的路由器列表。Router-LSA 里的传输网络链路指向这个 DR 地址,Network-LSA 再把接入的路由器列出来,SPF 计算时才能把网络节点和路由器节点连起来。如果 Network-LSA 缺失,广播网络上的路由器可能只能看到直连,看不到经过网络节点的路径。
我在模拟项目 X 里做过一个对照:把广播网络改成点对点网络,Router-LSA 的链路类型从传输网络变成点对点,Network-LSA 不再生成。邻居关系仍然是 Full,但 LSDB 少了一类 LSA,SPF 树的形状也变了。这个实验说明网络类型不是“随便配配”的参数,它直接决定 LSA 的生成和 SPF 的计算方式。第 9.1 节讲接口状态,第 12.4 节讲 LSA 生成,两者要对照看。
Router-LSA 的度量是接口开销,常见计算方式是参考带宽除以接口带宽,参考带宽常见 100 Mbps,但具体实现可能不同。如果两端接口开销不一致,SPF 算出的路径可能不对称。第 16.1 节计算最短路径树时会累加开销,第 16.8 节讲等值多路径,开销相同才会形成等价路径。调开销之前,先确认参考带宽和接口实际带宽,别只看配置里的数字。
提示:Router-LSA 的链路类型 3 是存根网络,描述的是没有邻居的网段。很多人把它和区域间路由混淆,存根网络仍然在本区域的 SPF 树里,区域间路由才走 Summary-LSA。
4.3 Summary-LSA 与 AS-external-LSA:区域间和外部路由的边界
Summary-LSA 是第 3、4 类 LSA,由 ABR 生成,用于区域间路由。第 12.4.3 节讲生成 Summary-LSA,附录 A.4.4 给格式。第 3 类描述目的网络,第 4 类描述 ASBR 的位置。ABR 把自己区域内的路由汇总后,生成 Summary-LSA 发到其他区域。连接状态标识是目的网络地址,宣告路由器是 ABR,度量是 ABR 到目的网络的开销。第 16.2 节计算区域间路径时,会检查传输区域的 Summary-LSA,第 16.3 节专门讲这个检查。
AS-external-LSA 是第 5 类 LSA,由 ASBR 生成,用于引入外部路由。第 12.4.4 节讲生成 AS-external-LSA,附录 A.4.5 给格式。它包含外部路由的度量、转发地址、外部路由标记和 E 位。E 位表示度量类型,类型 1 和类型 2 的计算方式不同。第 16.4 节讲计算 AS 外部路径,第 16.4.1 节讲外部路径参数。外部路由不参与区域间 SPF 树,而是在区域间路由计算完之后再叠加,所以外部路由的下一跳可能不是 ABR,而是转发地址。
这里有一个常见误解:LSDB 里有 Summary-LSA 不代表路由表一定有对应路由。ABR 可能生成了 Summary-LSA,但传输区域不可达,或者目的区域是存根区域不接受外部 LSA,路由就不会进表。第 3.6 节讲存根区域,第 16.3 节讲传输区域检查,把这两节连起来看,才能判断是“LSA 没生成”还是“LSA 生成了但没被使用”。
我在某实验室的环境里遇到过一次“区域间路由缺失但 LSDB 有 Summary-LSA”的问题。最后发现是 ABR 到目的网段的下一跳不可达,Summary-LSA 虽然生成了,但第 16.2 节计算时无法解析下一跳,路由被丢弃。这个案例说明:LSDB 是拓扑信息,路由表是计算结果,两者之间还有可达性检查。只看 LSDB 的 LSA 数量,会得出错误结论。
4.4 洪泛、重传与 LSAck:为什么数据库会“看起来同步了”
洪泛过程在第 13 章,核心步骤是:收到 LSA 后判断是否更新,如果更新则加入数据库,从其他接口洪泛出去,并等待邻居的 LSAck;如果邻居没确认,就重传。第 13.2 节讲将 LSA 加入数据库,第 13.3 节讲洪泛过程的下一步操作,第 13.5 节讲发送 LSAck,第 13.6 节讲重传 LSA,第 13.7 节讲接收 LSAck。第 8.1、8.2 节讲发送和接收协议包的通用流程。
“看起来同步了”通常有三种情况:第一,DD 交换完成,双方都知道对方有哪些 LSA 头部,但完整 LSA 还在 LSR/LSU 过程中;第二,LSA 已经加入数据库,但 SPF 还没重算,路由表还没更新;第三,LSA 洪泛到了大部分邻居,但有一两个邻居没回 LSAck,重传列表里还有记录。第一种看邻居状态,第二种看 SPF 调度,第三种看重传列表和接口队列。
第 13.4 节讲接收自生成的 LSA,这个场景很关键:一台路由器收到自己生成的 LSA,如果序号比本地旧,要回一个更新的 LSA;如果序号相同,可能只是洪泛回环,不需要处理。这个逻辑如果理解错,就会在“LSA 反复刷新”时找不到原因。第 14.1 节讲提前老化 LSA,有时为了撤销一条路由,会把 LSA 年龄设为 MaxAge 洪泛出去,其他路由器收到后删除,但原路由器还可能收到回环,需要正确处理。
我在一次实验里看到 LSDB 里有一条 LSA 的年龄不断在 0 和 MaxAge 之间跳,日志里反复出现更新。最后查出来是两台路由器同时宣告了同一个连接状态标识,但宣告路由器不同,双方都认为自己的更新,互相覆盖。第 13.1 节的判定规则在这种情况下会频繁触发,因为序号和校验和交替变大。解决办法不是调计时器,而是找到重复宣告的源头,确认哪台路由器应该生成这条 LSA。
注意:LSAck 是确认包,不是路由更新包。看到 LSAck 多不代表数据库有问题,看到重传列表持续增长才需要查接口队列和邻居可达性。
5. 避坑与排查:中文版里最容易读漏的五个细节
5.1 现象:邻居卡在 2-Way 或 ExStart
现象:两台路由器互连,Hello 能通,邻居状态停在 2-Way;或者进入 ExStart 后长时间不动,日志只提示重传 DD。原因分两类:2-Way 在广播网络上可能是正常状态,非 DR/BDR 之间本来就不形成 Full 邻接;如果 DR 和其他路由器也停在 2-Way,就要查 Hello 参数、网络类型和访问控制。ExStart 卡住更常见的是接口 MTU 不一致、Router ID 冲突、DD 包主从选举异常,或者单向可达导致 DD 包发不出去。
解决:先抓 Hello 包对网络掩码、Hello 间隔、失效间隔、区域 ID、认证字段,确认双向都能收到。再看接口网络类型,广播网络会选举 DR/BDR,点对点网络不会,类型不匹配会让状态机走错分支。ExStart 阶段重点看 DD 包的接口 MTU 字段和 Router ID,两端 MTU 调一致,Router ID 保证唯一。如果这些都对,检查 ACL 是否放行了 OSPF 协议报文,以及是否只放行了 Hello 没放行 DD。第 10.6 节和第 10.8 节把 DD 的发送和接收分开写,对照看能定位是哪一侧没回包。
5.2 现象:LSA 年龄接近 MaxAge 但路由还在
现象:查 LSDB 发现某条 LSA 的年龄已经很大,接近 MaxAge,但路由表里对应路由还在,过一段时间又恢复正常。原因可能是周期刷新还没到,LSRefreshTime 通常是 1800 秒,年龄增长是正常的;也可能是刷新包在路上丢了,原路由器还没重传;还有一种情况是收到 MaxAge 的 LSA 后,路由表要等 SPF 重算才删除,不是立刻消失。第 12.1.1 节讲连接状态时限,第 14 章讲老化,第 14.1 节讲提前老化,三节连起来看能区分“正常老化”和“异常残留”。
解决:先确认这条 LSA 的生成者是谁,是不是本路由器生成的。如果是本路由器生成的,看刷新计时器和接口队列,确认刷新包有没有发出去。如果是其他路由器生成的,看是不是收到了 MaxAge 版本但还没触发 SPF。不要手动改年龄字段,校验和会出问题。需要撤销路由时,按第 14.1 节的提前老化流程做,让 LSA 以 MaxAge 洪泛,而不是直接删 LSDB。排查时把 LS 序号、校验和、年龄三个字段一起看,单看年龄容易误判。
5.3 现象:区域间路由缺失但 LSDB 有 Summary-LSA
现象:ABR 上能看到 Summary-LSA,目的区域的路由器 LSDB 里也有,但路由表里没有对应网段。原因可能是 ABR 没有为那个网段生成 Summary-LSA,或者生成了但传输区域不可达,或者目的区域是存根区域不接受外部 LSA,或者 SPF 没有重算。第 3.2 节讲区域间路由,第 12.4.3 节讲 Summary-LSA 生成,第 16.2 节讲区域间路径计算,第 16.3 节讲传输区域检查,这四节是排查主线。
解决:先在 ABR 上确认源区域里有对应路由,且 ABR 认为它是区域间路由或内部路由;再确认 ABR 是否配置了汇总或过滤,把 Summary-LSA 挡住了;然后看传输区域的 Router-LSA 是否能到达 ABR,下一跳是否可解析;最后看目的区域的类型,存根区域会用默认路由代替外部路由,不会出现具体的 Summary-LSA。第 16.5 节讲增量更新,如果 Summary-LSA 是新增的,SPF 调度可能有延迟,等一个周期再看。不要只看 LSDB 计数,要把 LSA 的宣告路由器、连接状态标识和度量一起看。
5.4 现象:虚链路配了但不通
现象:两台 ABR 之间配置了虚链路,接口状态看起来是 up,但邻居建不起来,或者虚链路上的路由不生效。原因可能是传输区域类型不对,虚链路必须穿过一个普通传输区域,不能穿过存根区域;端点必须是 ABR,且 Router ID 必须可达;两端 Hello 参数和认证必须一致;虚链路的接口地址通常借用传输区域的接口,配置时容易把区域 ID 写错。第 15 章讲虚拟通道,第 3.1 节讲骨干区域,第 3.6 节讲存根区域,这三节要一起看。
解决:先确认虚链路两端都是 ABR,并且都有一个接口在传输区域里;再确认传输区域不是存根区域,存根区域不允许虚链路穿过;然后检查两端 Router ID 是否在传输区域的路由表里可达,虚链路的 Hello 包是单播的,Router ID 不可达就建不起来;最后对 Hello 间隔、失效间隔、认证参数。虚链路属于骨干区域,配置时区域 ID 要写骨干区域,但传输区域要写实际经过的区域,这两个 ID 不要混。第 15 章的文字不多,但约束很硬,配之前先把拓扑画清楚。
5.5 现象:等值多路径没有生效
现象:SPF 树里有两条开销相同的路径,但路由表只选了一条,或者流量只走其中一个下一跳。原因可能是设备的最大等价路径数限制、接口开销不一致、下一跳类型不同、或者其中一条路径不在同一区域。第 16.8 节讲等值多路径,第 16.1 节讲最短路径树计算,第 12.4.1 节讲 Router-LSA 的度量,三节连起来看能判断是“没有等价路径”还是“有等价路径但没安装”。
解决:先确认两条路径的累计开销完全相同,包括接口开销和中间链路开销;再确认设备支持并启用了等价多路径,最大路径数不是 1;然后看下一跳是否都是同一类型,某些实现要求下一跳在同一接口或同一区域;最后看路由表里的路由来源,区域间路由和外部路由的等价多路径行为可能不同。不要只看 SPF 树的分支数量,SPF 树有分支不代表路由表一定安装多条。调开销时先确认参考带宽,避免改了一个接口导致全网路径重算。
6. 进阶验证:用字段级对照法把中文版读成排障手册
6.1 抓一个 Hello 包,先对六个字段
我后来固定用一个动作:邻居一出问题,先抓一个 Hello 包,按附录 A.3.2 的字段顺序逐项对,不对配置。这个动作看起来笨,但能挡住大部分“配置看起来一样、实际不一样”的翻车。具体做法是:在故障接口上抓一个入方向和一个出方向的 Hello 包,先看网络掩码、Hello 间隔、路由器失效间隔、选项、路由器优先级、邻居列表这六个字段。两端掩码不一致,广播网络可能卡 Init;计时器不一致,邻居会反复失效;选项 E 位不一致,存根区域行为会异常;邻居列表为空,说明对方没收到本端的 Hello。
对完 Hello 包,再抓一条 Router-LSA,按附录 A.4.2 对连接状态标识、宣告路由器、LS 序号、链路数量、链路类型、Link ID、Link Data、度量。这一步能把“LSDB 有 LSA 但路由不对”拆成字段问题。比如链路类型写错,SPF 树就连不到网络节点;度量不一致,等价路径就不成立;宣告路由器不对,说明生成者找错了。字段级对照的好处是,你不需要记住全部协议,只需要在故障点对几个关键字段。
| 验证项 | 抓包字段 | 中文版位置 | 异常判断 |
|---|---|---|---|
| 区域一致性 | Hello 包区域 ID | 7.1、A.3.2 | 区域 ID 不同,邻居到不了 2-Way |
| 掩码一致性 | Hello 包网络掩码 | 9.5、A.3.2 | 广播网络可能卡 Init |
| 计时器一致性 | Hello 间隔、失效间隔 | 7.1、10.5 | 邻居反复重建 |
| 选项一致性 | Options 的 E 位 | A.2、12.1.2 | 存根区域行为异常 |
| 拓扑描述 | Router-LSA 链路类型 | 12.4.1、A.4.2 | 点对点/传输网络混淆 |
| 新旧判断 | LS 序号、校验和、年龄 | 13.1、A.4.1 | 更新不生效或反复刷新 |
这张表我一般只在前三项出问题时全对一遍,后面三项作为 LSDB 排障的补充。字段级对照不是让你变成协议实现者,而是让你在配置和抓包之间有一条可验证的路径。中文版附录 A 的字段表在这里价值最大,它把每个比特的位置和含义写清楚了,比只看配置命令更接近问题本质。
从那以后我每次排查邻居问题,都先抓 Hello 包对字段,再看状态机,最后才动配置;这个习惯让我少改了很多“本来没问题”的参数。希望帮到你。
本文还有配套的精品资源,点击获取