做了这么多年网络运维,OSPF是我日常打交道最多的动态路由协议,没有之一。但带过不少新人之后我发现一个规律:会配OSPF基础(network宣告、area划分)的人很多,能把特殊区域和选路规则讲清楚的人却很少。绝大多数人对特殊区域的认知停留在“能减少路由表项”这个层面,真要问起来:为什么Stub区域不能接收Type 5 LSA?为什么NSSA区域里会出现Type 7 LSA?ABR把Type 7转换成Type 5时由谁来做?一条外部路由在E1和N2之间竞争时谁会赢?——很多老工程师都要愣一下。
这篇博客就把这两块内容彻底拆开来讲:先讲清特殊区域为什么存在、怎么过滤LSA、怎么配置,再把OSPF的选路规则从优先级、cost计算到Forwarding Address一条条捋顺,最后结合我这些年处理过的现场故障,给出排查经验和设计建议。无论你是正在备考网络认证的读者,还是刚接手园区网运维的一线工程师,或者被区域类型搞到头痛的项目交付人员,这篇都值得你完整读一遍。
1. 特殊区域到底在解决什么问题
1.1 普通区域的三座资源大山
OSPF是基于链路状态的协议,每台路由器都要维护整个OSPF域的LSDB(链路状态数据库),然后以自己为根节点运行SPF算法计算去往每个网段的最短路径。这个机制在小型网络里毫无问题,但网络规模一大,三个资源瓶颈就全出来了。
首先是存储。每一条LSA都要占内存,外部路由一多,Type 5 LSA可能成千上万条。一台低端接入路由器的内存可能就几百兆,LSDB一膨胀,先被击穿的不是CPU而是内存。
其次是CPU。SPF计算是全局性的,只要链路状态发生变化,路由器就要重新计算整个区域内的最短路径树。区域内路由器数量越多、链路越复杂,SPF计算耗时越长。如果LSDB里还混着大量外部路由的Type 5 LSA,每次拓扑变化都要连带把这些外部路由重新算一遍,CPU直接吃满。
最后是带宽。LSA洪泛(Flooding)本身就是一种协议开销。区域内每台路由器都会把LSA向所有邻居转发,网络规模大、链路多的时候,一次拓扑变更能在短时间内泛洪出去成百上千条LSA,直接挤压业务流量带宽。
这三座大山,就是普通区域在大规模网络里撑不住的根源。特殊区域的设计初衷,归结起来就一句话:把离骨干区域较远、本就不需要知道太多外部信息的区域,从“什么都听”变成“只听该听的”。
1.2 区域划分还不够,特殊区域是在区域之上再做减法
很多人以为OSPF划分了区域就能隔离所有信息,这是常见的误解。普通非骨干区域虽然收不到区域内所有拓扑细节,但它依然会收到ABR泛洪过来的Type 3 LSA(区域间路由)和ASBR泛洪过来的Type 4、Type 5 LSA(外部路由信息)。也就是说,一个普通区域内的路由器,路由表里还是会堆积大量“我根本用不到”的外部路由明细。
特殊区域做的事情,本质是对区域边界做更细粒度的信息裁剪。Stub区域把外部路由挡在门外;Totally Stub区域连区域间明细路由也挡在门外;NSSA则是在“挡外部路由”和“允许本区域自己引入外部路由”之间寻找平衡。理解了这个出发点,后面所有配置和选路规则才有落点。
1.3 四类特殊区域的定位差异
把四类特殊区域放在一张表上看,它们的定位差异会非常清晰:
| 区域类型 | 核心诉求 | 典型使用场景 |
|---|---|---|
| Stub | 区域内部路由不需要知道外部路由,统一走ABR的默认路由出去 | 分支机构区域,只访问总部的内网资源,不需要了解外部链路 |
| Totally Stub | 连其他区域的明细路由也不想维护,只要一条默认路由 | 规模较小的分支接入区,希望路由表越精简越好 |
| NSSA | 区域不能接收外部路由,但又必须允许本区域自己引入外部路由 | 分公司下挂多个本地网段,需要把这些本地路由通告进OSPF域 |
| Totally NSSA | 在NSSA基础上,再屏蔽其他区域的路由明细 | 分公司区域既需要通告本地网段,又希望路由表最小化 |
一个比较直观的类比:普通区域是“全量订阅”,所有新闻推送都收;Stub区域是“只看本地新闻+一个总览头条”;NSSA是“不看外部新闻,但自己可以发稿”。搞懂这个定位,选型时就不会纠结了。
2. 七类LSA的分工是理解特殊区域的钥匙
2.1 各类LSA的职责与传播范围
要真正看懂特殊区域的过滤逻辑,必须先背熟七类LSA的分工。这张表我建议直接存下来,现场排查时经常用到:
| LSA类型 | 名称 | 产生者 | 传播范围 | 作用 |
|---|---|---|---|---|
| Type 1 | Router LSA | 每台路由器 | 所在区域内 | 描述本路由器接口状态、邻居关系、链路cost |
| Type 2 | Network LSA | 广播网络中的DR | 所在区域内 | 描述该广播网段内有哪些路由器,由DR代表整个网段宣告 |
| Type 3 | Summary LSA | ABR | 跨区域传播 | ABR把某个区域内的路由汇总后发给其他区域 |
| Type 4 | ASBR Summary LSA | ABR | 跨区域传播 | 通告“ASBR在哪”,让其他区域能到达ASBR |
| Type 5 | AS External LSA | ASBR | 整个OSPF域 | 通告外部路由,分为E1、E2两类 |
| Type 6 | Group Membership LSA | MOSPF路由器 | 组播OSPF专用 | 实际部署中几乎不用,了解即可 |
| Type 7 | NSSA External LSA | NSSA区域内的ASBR | 仅NSSA区域内 | 通告该区域引入的外部路由,分为N1、N2两类 |
这几类LSA里,Type 1和Type 2描述的是区域内的拓扑和网段,任何区域都必须收,否则SPF算法没法运行。Type 3由ABR产生,是区域间路由的载体。Type 4和Type 5是外部路由相关,正是特殊区域要过滤的对象。Type 7是NSSA的特有产物,由NSSA区域内的ASBR产生,发到本区域后由ABR转换成Type 5再传到其他区域。
2.2 特殊区域的LSA放行对照表
特殊区域的过滤规则,本质上就是回答一个问题:哪些LSA可以进入、哪些必须挡在区外。下面这张对照表是全文最核心的一张表:
| 区域类型 | Type 1/2 | Type 3明细 | Type 3默认路由 | Type 4 | Type 5 | Type 7 |
|---|---|---|---|---|---|---|
| 普通区域 | 允许 | 允许 | 不生成 | 允许 | 允许 | 不允许 |
| Stub | 允许 | 允许 | 自动生成 | 阻止 | 阻止 | 不允许 |
| Totally Stub | 允许 | 阻止 | 自动生成 | 阻止 | 阻止 | 不允许 |
| NSSA | 允许 | 允许 | 需配置生成 | 阻止 | 阻止 | 允许 |
| Totally NSSA | 允许 | 阻止 | 需配置生成 | 阻止 | 阻止 | 允许 |
注意几个容易记混的细节。第一,Stub区域仍然能接收Type 3明细LSA,也就是说其他区域的路由仍然能进入Stub区域,只是外部路由(Type 4/5)被挡掉了。很多人以为Stub区域内只有默认路由,这是错的。第二,Totally Stub区域才是把Type 3明细也挡掉、只留下Type 3默认路由。第三,NSSA虽然不接收Type 5,但允许本区域自己产生Type 7。第四,Stub和NSSA是互斥的,一个区域不可能同时又Stub又NSSA。
2.3 ABR如何向特殊区域注入默认路由
Stub和Totally Stub区域之所以不需要外部路由明细,是因为ABR会在区域内自动发布一条Type 3 LSA的默认路由(0.0.0.0/0)。区域内所有路由器看到这条默认路由,就知道“凡是本区域找不到明细的去向,统统交给ABR”。这条默认路由的cost默认是1,可以通过在ABR上配置default-cost参数来调整,后面配置部分会详细说。
NSSA的情况不太一样。NSSA区域不接收Type 5,所以ABR没法用Type 5向区域里通告默认路由。如果需要给NSSA区域下发默认路由,通常要显式配置,让ABR产生一条Type 7格式的默认路由,机制上更“绕”一些。这也是NSSA在实际配置中比Stub区域更容易出问题的地方。
2.4 特殊区域的三条铁律
理解了LSA的放行规则,还要记住几条硬性约束,否则在规划阶段就会踩坑。
Area 0(骨干区域)不能被配置为任何类型的特殊区域。特殊区域的设计前提是“区域内不需要了解太多外部信息”,但骨干区域是整个OSPF域的中枢,必须承载所有区域间的路由交换,所以它必须保持普通区域身份。
特殊区域内不允许配置虚链路(Virtual Link)。虚链路的作用是修复骨干区域不连续的问题,它的建立要求穿越普通区域,并且逻辑上被视作骨干链路。特殊区域的过滤规则会破坏虚链路所需的路由信息传播,两者天然冲突。
区域内部所有路由器的区域类型配置必须一致。如果一台路由器把Area 1配成Stub,另一台配成NSSA,两台设备的LSA过滤规则完全不同,邻居关系会在初始化阶段直接失败,这是现场最常见的故障之一。至于Totally类型的区别,只需要关注ABR上是否加了no-summary参数,区域内的其他路由器按照Stub或NSSA配置即可。
3. 特殊区域配置实操
3.1 实验拓扑与规划
用三台路由器来演示,拓扑是两条链路线:R1和R2在Area 0,R2和R3在Area 1,R2就是连接两个区域的ABR。R1的环回口或某个网段作为外部路由来源进行重分发,R3下挂一个本地网段用于演示NSSA的外部路由引入。所有配置命令以主流厂商通用风格为例,实际部署时根据设备类型替换即可。
规划如下:
| 设备 | Router ID | 接口与区域 | 附加角色 |
|---|---|---|---|
| R1 | 1.1.1.1 | G0/0/1: 10.0.12.1/24,加入Area 0 | ASBR,引入外部网段 |
| R2 | 2.2.2.2 | G0/0/1: 10.0.12.2/24,G0/0/2: 10.0.23.2/24 | ABR,连接Area 0与Area 1 |
| R3 | 3.3.3.3 | G0/0/2: 10.0.23.3/24,G0/0/3: 192.168.10.0/24 | 区域内部路由器,NSSA场景下作为ASBR |
先把三台设备的基础OSPF配置起来:
# R1 ospf 1 router-id 1.1.1.1 area 0 network 10.0.12.0 0.0.0.255 import-route static # R2 ospf 1 router-id 2.2.2.2 area 0 network 10.0.12.0 0.0.0.255 area 1 network 10.0.23.0 0.0.0.255 # R3 ospf 1 router-id 3.3.3.3 area 1 network 10.0.23.0 0.0.0.255 network 192.168.10.0 0.0.0.255R1上配置一条静态路由模拟外部网段:
ip route-static 100.100.100.0 24 NULL0然后在OSPF进程里引入,这样100.100.100.0/24就会以Type 5外部路由的形式在整个域中泛洪。
3.2 Stub区域配置与验证
把Area 1配成Stub区域,R2和R3上都要配置:
# R2 ospf 1 area 1 stub # R3 ospf 1 area 1 stub配置完成后,在R3上查看LSDB和路由表。你会发现两件事:第一,R3的路由表里没有了100.100.100.0/24这条外部路由的明细;第二,R3自动多了一条0.0.0.0/0的默认路由,下一跳指向R2。这就是ABR自动发布的Type 3默认路由在起作用。
此时在R3上用命令查看LSDB,Type 5的LSA一条都没有,因为外部路由在ABR的Area 1边界上就已经被挡掉了。数据包要想访问外部网段,R3会直接把流量交给R2这个“出口”。
3.3 Totally Stub与NSSA切换配置
如果希望Area 1内连其他区域的路由明细都不要,只需要在R2(ABR)上多打一个关键词:
# R2 ospf 1 area 1 stub no-summaryR3侧配置保持不变,仍然是stub。这个no-summary参数只影响ABR的行为,它会让ABR不再向Area 1通告任何Type 3明细LSA,只保留默认路由。验证时能看到R3的路由表里连Area 0内的具体网段(10.0.12.0/24)都不见了,只剩默认路由。
但如果Area 1里的R3自己也需要通告本地网段到OSPF域,Stub就不合适了,因为Stub区域不允许出现ASBR,不能执行路由重分发。这时候要把区域类型改为NSSA:
# R2 ospf 1 area 1 nssa # R3 ospf 1 area 1 nssa然后R3上把自己的本地网段引入OSPF:
# R3 ospf 1 import-route static这时候R3产生的192.168.10.0/24路由是以Type 7 LSA的形式存在于Area 1内部的。R2接收到Type 7 LSA后,会把它转换成Type 5 LSA再通告到Area 0,这样整个OSPF域都能学到R3的本地网段。这个转换过程是NSSA机制最精髓的部分。
3.4 Totally NSSA与默认路由注入
如果既想让Area 1能自己引入外部路由,又不想让其他区域的路由明细进来,就用Totally NSSA。在R2上配置:
# R2 ospf 1 area 1 nssa no-summaryR3侧仍然是普通的nssa。这样Area 1内的路由器只保留自己区域内的路由和ABR注入的默认路由,同时又能通告本地外部路由。
但NSSA区域默认不会自动得到默认路由,这是和Stub区域最不一样的地方。要让R3能通过默认路由访问外部网络,需要在ABR上显式下发:
# R2 ospf 1 area 1 nssa no-summary default-route-advertise这条命令会让R2向Area 1注入一条Type 7格式的默认路由。不同厂商的默认路由参数细节略有差异,但配置思路是一致的:NSSA区域的默认路由需要显式通告,不像Stub那样自动生成。
3.5 参数细节与验证命令
关于默认路由的cost,Stub和Totally Stub区域里可以通过area 1 default-cost 20这样的命令修改ABR注入默认路由的cost值。实际项目中这个值很关键:如果区域内存在多台ABR,通过调整default-cost可以控制区域内路由器优先走哪个ABR出口,相当于给默认路由做了简单的负载引导。
NSSA里控制默认路由cost的方式因厂商而异,有的在default-route-advertise后面直接跟cost参数,有的是通过外部路由的metric设置实现。部署前务必核对一下设备文档。
验证配置是否正确,命令集中在LSDB查看上:
display ospf lsdb display ospf lsdb summary display ospf lsdb ase display ospf lsdb nssa display ip routing-table通过这几条命令可以分别看到区域内有哪些类型的LSA、Type 5有没有正常传播、Type 7有没有被转换。排查问题的时候,先看LSDB再查路由表,效率会高很多。
4. OSPF选路规则:最终谁说了算
4.1 路由类型优先级
OSPF的选路不是简单的“cost小的胜出”,首先要看路由类型的优先级。去往同一个目的网段,OSPF可能同时存在多种类型的路由,这时优先级决定了哪条路由进入路由表。通用的优先级排序是:
| 优先级 | 路由类型 | LSA来源 | 说明 |
|---|---|---|---|
| 1(最高) | O 区域内路由 | Type 1/Type 2 | 最优,SPF计算得出 |
| 2 | O IA 区域间路由 | Type 3 | 跨区域学习到的路由 |
| 3 | N1 NSSA外部路由Type 1 | Type 7 | 属于第一类外部路由 |
| 4 | E1 外部路由Type 1 | Type 5 | 属于第一类外部路由 |
| 5 | N2 NSSA外部路由Type 2 | Type 7 | 属于第二类外部路由 |
| 6 | E2 外部路由Type 2 | Type 5 | 属于第二类外部路由 |
这套排序隐含了一个重要设计思想:区域内路由永远优先于区域间路由,不管区域间路径的cost多小。这样设计是为了防环。OSPF要求所有区域间的流量都必须经过骨干区域Area 0,区域间路由的可靠性依赖这个层级结构。如果你允许一条cost很小的区域间路由压过区域内的路由,就可能出现区域间绕行甚至路由环路的局面。
特殊区域和这套优先级的关系也值得注意。N1和E1之间的先后,不同厂商实现可能有细微差别,绝大多数场景下按“N1先于E1,N2先于E2”记忆都没有问题。实际排障时,如果发现路由表里出现的是E2而不是期望的N1,不要先怀疑厂商实现,先检查区域类型和LSA转换是否正常。
4.2 Type 1与Type 2外部路由的cost计算差异
优先级排完之后,同类型路由之间才比较cost。这里必须讲清楚Type 1和Type 2的最本质差异。
Type 1外部路由(E1/N1)的cost等于“本路由器到ASBR的开销+ASBR通告的外部开销”。也就是说,内部网络每一跳的cost都会累加进最终路由cost里。内部链路越远、越慢,路由的总cost就越高。Type 1把内部链路质量完整地反映在选路里。
Type 2外部路由(E2/N2)的cost则恒定等于ASBR通告的外部开销,完全忽略内部链路的差异。OSPF设计默认采用Type 2也是有道理的:外部路由通常指向上游运营商或者对端专线,外部网络路径的质量往往是决定性的,内部的几跳cost相对于外部网络的延迟和带宽来说可以忽略。所以E2的cost不随位置变化,全网的E2路由到同一目的地,看到的cost都是一样的。
但E2也不是完全不看内部路径。当存在两条E2路由且有相同的外部cost时,OSPF会再比较“本路由器到两个ASBR的内部cost”,内部路径更近的胜出。这相当于把所有E2的竞争都压到“外部cost相等”这个前提下,谁离ASBR更近谁赢。
举个例子,R1用Type 2通告外部路由100.100.100.0/24,外部cost是50。R2到R1的链路cost是1,R3到R2的链路cost也是1,那么R2和R3查看到的这条E2路由cost都是50。但如果R3到R1还有另一条链路,而R3只有一条代价较小的出口,E2不会因为内部链路短就改变cost。只有R3看到两条外部cost同为50的E2路由时,才会继续比较各自到对应ASBR的内部开销。
如果R1改用Type 1通告,外部cost仍然是50,那R3看到的最终cost就变成了“R2到R1的1+R3到R2的1+50=52”,每一个内部跳都算进去了。这就是同样一条外部路由,Type 1和Type 2给全网带来的不同感知。业务侧如果对延迟敏感,通常建议用Type 1,让OSPF内部拓扑变化能直接影响外部路由质量评估。
4.3 Forwarding Address不为人知的坑
Type 5和Type 7 LSA里都有一个字段叫Forwarding Address(转发地址,简称FA)。很多人都没注意它,但它直接影响下一跳的选择,是排障时最容易翻车的地方。
如果FA字段为0.0.0.0,表示外部路由需要通过ASBR本身去转发,那么路由表里该外部路由的下一跳就是指向ASBR的那个IP地址。这是最常见的情况。
如果FA字段是非0的地址,表示数据包不应该发给ASBR,而是应该直接发给这个FA所指向的地址。OSPF要求FA必须是一个OSPF域内可达的地址,并且不能位于特殊区域里,否则这条外部路由会因为“无法解析FA”而被直接忽略,路由根本不会安装。
FA非0的情况通常出现在一个路由器通过多个接口连接到同一个外部网络时。ASBR会选择一个最优的转发地址通告出去,这样区域内其他路由器可以直接把流量送到那个更优的地址,不一定要绕行ASBR本体。
实际项目里,因为FA不可达导致外部路由消失的情况并不少见。常见诱因是:ABR做了路由过滤或者区域汇总时,恰好把FA所在的网段过滤掉了。表现是ASBR上明明有外部路由,其他普通区域路由器却学不到,而LSDB里Type 5 LSA还在。排查时一定要查FA字段,并确认该FA在域内确实可达。
4.4 等价路由与打破平局
当两条同一类型、同一cost、同一目的网段的路由同时存在时,OSPF会把它们都放进路由表,形成等价路由(ECMP),流量按照哈希方式在多条链路上负载分担。OSPF默认支持的最大等价路由条数,在主流厂商设备上通常是4条或8条,可以通过命令调整。
等价路由的负载分担粒度通常是逐流而非逐包,也就是说同一对源目的IP的流量会被固定哈希到同一条链路上,避免同一会话的数据包在多条路径上乱序。这种设计对TCP业务是友好的,但也会导致一个问题:如果某一条链路质量已经极差,只要它的cost没有变化,哈希到这条链路上的流量依然会继续走它。排查业务卡顿而上层应用又没报错时,别忘了看一眼等价路由中是不是某一条链路已经在物理上劣化了。
如果两条路由类型相同、cost也相同,但前缀长度不同,最长前缀匹配优先于一切OSPF选路规则。更具体的掩码永远先被选中,这是路由表层面的基本原则,OSPF也不能例外。
当所有条件都相同时,Router ID会作为最终裁决依据。SPF计算和外部路由处理中的某些平局场景,OSPF会优先选择Router ID更大的路由器。这属于比较底层的细节,多数场景用不到,但排查诡异偶发问题时偶尔会有帮助。
4.5 一个完整的选路计算案例
综合以上规则,看一个完整的例子。假设一个区域里有两条到达100.100.100.0/24的路由:
第一条是R3通过Area 1内的R5(NSSA内ASBR)学到的N1路由,外部cost是30,R3到R5的内部cost是2,总cost是32。
第二条是R3通过Area 0方向学到的E2路由,外部cost是20,内部到ASBR的cost是10。
单看cost,20显然比32小,但按照OSPF选路规则,N1(Type 1)的优先级高于E2(Type 2),所以最终进入路由表的是N1这条路由,下一跳指向R5,cost显示32。这就是一个典型的“类型优先级压过cost数值”的案例。
这种场景在真实网络里经常造成误解,不少人看到E2的cost更小就以为流量会走高性价比路径,结果流量全部压到N1路径上去了。所以配置外部路由时,不仅要看cost大小,还要确认出口链路的类型设置是否符合业务预期。如果希望一条低延迟链路的E2路由胜出,可能需要改配成E1,或者调整N1路由的cost与过滤策略,而不是单纯期待数值比较。
5. 现场常见故障与排查经验
5.1 区域类型配置不一致致邻居震荡
这是配置特殊区域时遇到最多的故障。症状很典型:设备日志里反复出现OSPF邻居状态回退到ExStart或Down,区域类型相关的告警持续刷屏。两台路由器,一台把Area 1配成了Stub,另一台忘了配,或者一台配NSSA一台配Stub,两边在建立邻居关系时交换的拓扑描述信息里携带的区域类型选项不一致,协议直接判定双方无法建立完全邻接关系。
排查方法很简单,不需要抓包。登录故障路由器,查看区域配置和OSPF邻居告警,先确认故障区域在两台设备上的类型完全一致。特别提醒一点:Totally Stub和Stub的差异只在ABR侧no-summary参数,区域内其他路由器都按Stub配置,这不算不一致。但Stub和NSSA是根本矛盾,绝对不能在同一个区域内混用。
现场操作时,如果是在已有OSPF骨干正常的网络上新划特殊区域,最稳妥的顺序是先把区域类型一次性规划好,在维护窗口内同时修改边界设备配置,减少中间状态暴露的时间窗口。
5.2 默认路由丢失导致区域出口失效
Stub区域内部路由器没有默认路由,流量无法到达外部网络;或者NSSA区域内部路由器没有默认路由,本地无法访问Internet或对其他区域开放的资源。这类问题在两类场景中特别常见。
Stub区域默认路由丢失,优先怀疑ABR没有正确参与区域。检查ABR的OSPF进程里是否真的配置了该区域为Stub,以及ABR的Area 0侧的邻居是否正常。如果ABR和骨干区域失联,它自然无法向区域内生成那条Type 3默认路由。还有一个容易被忽略的点:多个ABR同时接管同一个Stub区域时,默认路由能否形成取决于ABR自身的路由表中是否有合法路径。如果ABR没有学到任何骨干路由,它不会随便下发默认路由。
NSSA区域默认路由丢失,则要先确认是否做了显式通告。很多工程师把NSSA和Stub混为一谈,以为NSSA也会自动生成默认路由,结果区域内路由器连一条默认路由都看不到。解决方式就是前面提到的在NSSA的ABR上配置默认路由通告命令。如果通告命令已经配置,但默认路由仍是悬空的,检查一下这条Type 7默认路由是否被ABR正确转换成了Type 5,以及转换后的路由是否被上层区域的过滤策略拦截。
5.3 NSSA转换器切换引发的路由抖动
NSSA机制里有一个隐藏角色:转换器(Translator)。一个NSSA区域内如果有多个ABR,整个区域只会选举一台ABR把Type 7转换为Type 5,转换器的选举通常由Router ID决定,Router ID大的优先,也可以显式指定某台ABR为转换器。
转换器切换最容易出问题的时候,是区域内的主用ABR故障恢复的瞬间。新转换器开始接管后,需要重新把区域内的Type 7转换成Type 5并向Area 0通告,同时还要等待一段时间让所有旧转换器信息老化。这个过程中可能出现短暂的“区域内有Type 7、骨干区域迟迟收不到Type 5”的真空期,业务表现为外部路由时通时断。
解决思路有两个方向。一是给转换器角色加稳定性约束,在ABR上显式指定某一台作为永久转换器,避免因为Router ID比较变化导致角色漂移。二是在设计阶段就让NSSA区域尽量只依赖一台ABR完成转换,或者在两台ABR之间做清晰的master/backup规划,而不是完全交给协议自动竞争。
这个知识点在文档里很少被强调,但生产环境里遇到NSSA区域路由抖动,第一优先排查对象就是转换器角色的稳定性。
5.4 选路结果不符合预期时按顺序查这几项
选路不符合预期的排查,我一般按固定顺序来查,效率最高。
先看路由类型。用路由表查看命令确认目标网段当前采用的是哪一类路由,O、O IA、N1、E1、N2、E2分别对应哪条路径。这一步基本能判断是不是类型优先级在起作用。如果两条不同出方向的路径当前呈现的是同一类型,再进入下一步。
再比cost。同类型路由之间的竞争只看cost。核对两条路径上每一跳接口的cost配置,注意默认cost在不同bandwidth参考值下差异可能很大。有些厂商设备默认参考带宽是100Mbps,10G接口计算出来的cost也还是1,这就很容易造成两条速率悬殊的链路被当成等价路由。
再看FA字段。外部路由缺失或指向异常时,一定要确认Type 5 LSA里的FA地址能不能在路由表里解析到。如果FA所在的内部网段被ABR汇总或过滤掉了,外部路由就会因为FA不可达而静默消失。
最后看过滤和汇总。ABR上配置的路由过滤、area范围汇总、出方向filter-list都有可能裁剪Type 3或Type 5,导致某些路径“看似存在实则被滤”。这类问题最隐蔽,因为LSDB里可能看不到被滤掉的LSA,但只要沿着ABR的过滤配置逐条检查,总能找到元凶。
5.5 排查工具与思路小结
建议维护一个“OSPF排障命令清单”,把看LSDB、看路由协议、看邻居关系、看接口cost的命令都列进去。现场操作时,我个人的习惯是:先确认邻居全起来,再看LSDB类型和数量,然后检查目标网段的路由类型与cost,最后抓具体数据包确认实际转发路径。
很多时候,网络排障卡壳是因为跳过了LSDB这一步直奔路由表。路由表只是计算结果,LSDB才是原因所在。特殊区域的很多问题,根子都在LSA的生成、过滤、转换环节。养成先看LSA再谈路由的习惯,能少走很多弯路。
6. 特殊区域与选路规则的设计建议
6.1 根据业务诉求选区域类型
做区域设计时不要为了用特殊区域而用,每一个设计决策都应该对应真实的业务约束。
总部骨干区域保持普通区域,不做特殊化处理。骨干区需要承载完整拓扑和所有区域间的路由交换,任何形式的过滤都会破坏骨干区域的连通性假设。骨干区域内部尽可能精简设备数量和路由数量,但不要用特殊区域的思维去限制它。
分支区域的设备性能较弱,业务又只需要访问总部资源时,Totally Stub是最优选。路由表最小、CPU和内存压力最低、配置也最省心。我做过一个现场优化,某分支机构的路由器原本维护着总部下发的近千条路由,改成Totally Stub后路由表瞬间缩到几十条,CPU占用率直接降了一半。
分支需要对外发布自己本地的网段,比如分公司有自己的服务器区需要被总部访问,那就必须用NSSA或Totally NSSA。至于是NSSA还是Totally NSSA,核心看这个分支要不要知道整个OSPF域内其他区域的路由明细。如果分支规模小、设备弱,Totally NSSA通常更好,因为它同时解决了外部路由引入和路由表精简两个诉求。
如果区域里有多个ABR,要特别注意NSSA转换器稳定性和默认路由注入的一致性。多ABR场景下建议把区域规划的主动权放在网络设计文档里,而不是交给协议自行选举,必要时要显式指定转换器。
6.2 实战中沉淀下来的几条心得
第一,特殊区域的规划和普通路由规划一样,需要提前写好边界。不要在运行中的网络上临时改区域类型,很多邻居震荡和路由黑洞都源于这种“就地切换”。哪怕只是加一个no-summary参数,也应该按变更流程走。
第二,注意Area 0的连续性。特殊区域破坏了区域内路由的完整性,如果骨干区域本身不连续,再叠加特殊区域的过滤,会出现非常诡异的选路结果。所有特殊区域设计都应该建立在骨干区域健康、连续的前提下。
第三,默认路由的cost需要主动设计。多ABR场景下,如果默认路由cost在各ABR上配置一致,区域内的路由器会做等价负载分担;如果想让流量更倾向从某一个出口出去,就把其他ABR的default-cost调大。这个手法在双出口分支场景里非常实用,比做一堆策略路由省事得多。
第四,理解选路规则要落到“路由类型”这个层面。很多人习惯只看cost,但OSPF的选路优先级是类型先于cost。纠正这个思维惯性之后,再遇到“明明有一条cost更小的路径却不走”的诉求,你就能准确判断是该调整策略、还是不该调整策略了。
最后说一个我自己的体会。做网络维护,最值钱的不是背了多少协议细节,而是能不能把协议行为和现场业务对应起来。特殊区域和选路规则这两块知识,恰恰是OSPF里最需要这种“对应能力”的内容。每次遇到路由多一跳、流量绕了远路、外部路由学不到这类问题,我都会把LSA类型、区域类型、路由优先级这三件事合成一张图去看。想明白一张图,问题往往就解开了一半。