ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

OSPF特殊区域与选路规则:从LSA到路由优先级全解析

OSPF特殊区域与选路规则:从LSA到路由优先级全解析

做网络运维的人早晚会遇到OSPF特殊区域这几个字,我印象里第一次被它“教育”不是在认证题库里,而是一张跑了三四年的核心网络在扩到十几个汇聚节点之后,核心路由器不断报警,内存和CPU双双吃紧。查来查去,罪魁祸首就是Type-5外部路由每一条都在全网泛洪,把每个区域的链路状态数据库都撑大了。后来把几个边缘区域陆续改成特殊区域,设备瞬间消停了。这篇文章把特殊区域和选路规则放在一起讲,因为它们表面上是两件事——一个管LSDB里能装哪些LSA,一个管路由表里按什么标准选路——但在真实配置里,这两件事永远缠在一起。适合已经会配基础OSPF、但想把区域类型和路由偏好彻底吃透的网工朋友。

1. 特殊区域出现之前:一张全网LSDB带来的痛

1.1 区域存在的意义不是隔离,而是划界

OSPF划分区域,本质上是把链路状态信息的扩散范围“画地为牢”。区域内的每台路由器必须同步整张本区域LSDB,这样才能保证对拓扑的认知一致。区域与区域之间不直接交换明细链路状态,而是由ABR在边界把区域内的路线整理成汇总后的Type-3 LSA,再发给其他区域。

用一个生活化的类比:如果全网所有人都要把每一栋楼的内部图纸背下来,迟早有人背不动。OSPF区域就是让每栋楼只共享一张“楼宇信息牌”,告诉别人这栋楼有哪些功能,而不必公开每家每户的装修图。ABR就是负责做这张信息牌的物业中心。

区域划分之后,普通区域内部依然会收到完整的链路状态通告。这意味着只要网络规模够大,一台边缘路由器就要保存整个区域所有接口、网段、邻居关系的信息,并参与SPF计算。当网络拓扑抖动时,这个区域的每一台路由器都要重新运行算法,设备压力是同步的。

1.2 普通区域里什么都能装

在没有特殊区域之前,一个普通区域的LSDB里通常会同时存在好几类LSA:

  • Type-1(Router LSA):区域内每台路由器把自己接口和邻居关系描述出来。
  • Type-2(Network LSA):由DR(指定路由器)在广播网络中产生,描述一个多路访问网段内有哪些路由器。
  • Type-3(Summary LSA):ABR生成的区域间汇总路由,描述其他区域的网段。
  • Type-4(ASBR Summary LSA):ABR生成的指向ASBR的描述信息,用于告诉其他区域“外部路由的入口在这台设备”。
  • Type-5(External LSA):ASBR引入的外部路由,默认会向全网泛洪。

普通区域把这五类全盘接收,最难伺候的就是Type-5。因为它不像Type-3那样经过汇总和过滤,每条外部路由都保持明细状态被传播到所有普通区域。一旦ASBR接入了几百甚至几千条外部路由,每个区域的LSDB都会同步膨胀,而外部路由的抖动又会触发大范围的SPF重算。

1.3 痛点:设备规格和网络规模之间存在矛盾

我接触过的真实网络里,最难受的往往不是核心设备,而是接入层和汇聚层的低端设备。核心路由器内存动辄几十GB,可以轻松承载上万条LSA;接入交换机却可能只有一二百MB内存,运行基础协议已经捉襟见肘。

最典型的现象是,ASBR侧有人重分发了一条不稳定的静态路由,状态一会儿up一会儿down。如果区域划分得不够“狠”,每一次变更都会产生新的Type-5 LSA,然后全网泛洪。LSDB每次更新后,区域里的每台路由器都要重跑SPF。低端设备就会周期性出现CPU飙高、OSPF邻居震荡,甚至整台设备短暂失联。

特殊区域的存在,就是为了在“路由信息够不够精确”和“设备扛不扛得住”之间做一道选择题。它的通用思路是:在末梢区域边界人为削减LSA类型,让区域内路由器只保留必要信息,用一条默认路由代替大量明细外部路由。这个思路说起来简单,落地时却有stub、totally stub、NSSA、totally NSSA这四种变体,每一种对应的选路行为都不一样。

2. stub与totally stub:用默认路由换一份安静

2.1 stub区域的准入与禁止

stub区域是所有特殊区域里最基础的一种,设计目标很明确:把外部路由挡在外面,同时保留区域间的路由明细。

一个区域配置为stub之后,它不再接收Type-5外部路由,也不需要Type-4路由(因为ASBR信息本质上服务于外部路由定位)。但Type-3区域间汇总路由仍然允许进入。为了让区域内路由器在没有外部明细的情况下也能访问外部网络,ABR会自动向stub区域注入一条Type-3默认路由,也就是0.0.0.0/0。

配置示例(以主流商用设备通用CLI风格为例,不同厂商关键字可能略有差异):

router ospf 1 network 192.0.2.0 0.0.0.255 area 1 area 1 stub

注意一个非常容易踩的规则:同一个stub区域里的所有路由器都必须配置stub关键字,否则两台设备在建立邻居时对区域属性协商不一致,邻居关系会卡在Exstart/Exchange状态,迟迟到不了FULL。我曾经见过有人只在ABR上配了stub,区域内的接入交换机忘了配,结果整片区域路由全部收敛不起来。排查了半天,最后发现两边OSPF邻居争议的根源就是区域类型不匹配。

2.2 totally stub是stub的加强版

totally stub是在stub基础上再加一层过滤:不仅禁止Type-4和Type-5,还顺手把Type-3区域间汇总路由也挡在外面。ABR不会再向这个区域通告任何其他区域的明细路由,只保留一条默认路由作为“唯一出口”。

判断totally stub很简单,看配置里是否有no-summary关键字。以通用命令风格为例:

router ospf 1 area 1 stub no-summary

这里的no-summary只作用在ABR下发给该区域的Type-3汇总上。区域内的普通路由器依然只需要配置area 1 stub,它们不知道也不关心ABR是不是做了额外抑制,真正起过滤作用的是ABR侧。

这种区域适合什么场景呢?如果一个接入区域下面没有任何互访需求,所有流量都是“上行到核心,再转发到别处”,那就没有必要让区域内路由器知道其他区域的每一条明细路由。几十条Type-3汇总也是成本。用totally stub一把梭,区域内LSDB最小化,所有不明流量统一丢给默认路由。

2.3 配置示例和效果对比

下面这张对比表,基本能看出普通区域、stub、totally stub之间的LSA接纳差异:

区域类型Type-1/2Type-3汇总Type-4 ASBR信息Type-5外部路由默认路由
普通区域允许允许允许允许不一定有
stub允许允许禁止禁止ABR自动下发Type-3默认路由
totally stub允许禁止禁止禁止ABR只下发Type-3默认路由

配置完成后,最直接的验证方法是查看区域内的路由表和LSDB。在stub区域内部,外部明细应该完全消失,取而代之的是一条来自ABR的默认路由;在totally stub区域内部,其他区域的Type-3明细也会消失,只留下默认路由。

这里还要记住两个限制:第一,stub区域里不允许存在ASBR,也就是说你不能在同一台路由器上既部署stub区域,又通过重分发把外部路由引入这个区域。第二,虚链路不能穿越stub区域。这两个限制同样适用于totally stub,别抱侥幸心理。

3. NSSA与totally NSSA:保留外部路由,又守住边界

3.1 为什么不能继续用stub

stub区域虽然省资源,但也把所有外部路由入口都堵死了。有些区域本身就是“连接外外部世界”的末端,比如接入合作伙伴专线、接入第三方网络、或者本区域自己充当另一套路由域的中转站。如果直接把它划成stub,区域内就无法部署ASBR,外部路由也就无法注入。

这时候就需要NSSA(Not-So-Stubby Area)。它允许该区域内存在ASBR,并允许外部路由以Type-7 LSA的形式在区域内传播,同时仍然拒绝其他区域的Type-5 LSA进入。换句话说,NSSA是一扇只出不进的门:本地可以产生外部路由,但外部路由不能从外面灌进来。

3.2 七类LSA:一个只在本区域有意义的类型

Type-7 LSA和Type-5 LSA在信息形态上非常接近,但它有一个关键的差别:Type-7只能在NSSA内部泛洪,绝对不允许跨出NSSA边界。区域内的普通路由器可以通过Type-7学习到外部路由,当这些信息需要被其他普通区域使用时,必须由边界ABR把Type-7翻译成Type-5,再向区域外扩散。

配置NSSA的通用命令风格如下:

router ospf 1 area 1 nssa

如果要配置totally NSSA,则再加上no-summary:

router ospf 1 area 1 nssa no-summary

totally NSSA与totally stub的过滤思路相同:连Type-3区域间汇总都不允许进入,区域内只保留一条默认路由。但要注意,NSSA的默认路由不会像stub那样自动出现,通常需要ABR主动注入。不同厂商的默认行为有差异,最好在ABR上明确配置下发默认路由,避免区域内路由器“无路可走”。

一个我踩过(或者说看别人踩过)的坑:NSSA区域里的非ABR路由器,如果没有收到ABR下发的默认路由,且区域内没有其他去往外部的路径,它的出方向流量就会出现黑洞。配置NSSA后一定要在ABR侧确认默认路由是否已经注入到区域内部。

3.3 P-bit与Type-7到Type-5的翻译

Type-7 LSA之所以能被“安全地限制在一个区域内”,依赖的是一套翻译机制。ABR在把Type-7转换为Type-5时,会检查这条LSA的P位(Propagate位)。P位就像一张通行证:只有带通行证的外部路由才有资格被翻译并发布到NSSA之外。

默认情况下,NSSA区域内普通ASBR产生的Type-7 LSA,P位是置位的,可以被ABR翻译成Type-5。有一类特殊情况需要留意:如果ASBR本身同时又是这台区域的ABR,它自己产生的Type-7 LSA在某些厂商实现里不会被翻译成Type-5,因为它的外部路由信息完全可以单独以Type-5形式直接通告出去。具体行为在不同设备上会有差异,遇到这种边缘情况,最可靠的手段是直接查看LSDB确认。

翻译动作不是由所有ABR同时完成的。同一个NSSA区域如果有两台以上ABR,它们都会收到同样的Type-7 LSA,但最终只有一个ABR作为Translator,负责执行翻译。其他ABR等待接替。这个翻译点的选择会影响普通区域路由器的下一跳,因为Type-5 LSA的AdvRouter是翻译ABR的Router-ID。

3.4 Translator选举和ABR容灾

Translator的选举在不同设备上标准不完全一致,但常见逻辑偏向于Router-ID更高、或接口状态更优的ABR胜出。这带来一个实际影响:如果NSSA区域内一台ABR发生重启,翻译角色可能漂移到另一台ABR上。外部路由的下一跳会跟着变化,流量路径也会短暂切换。

我在规划NSSA区域时,会习惯性地为ABR指定稳定且互有大小关系的Router-ID,让翻译角色在正常情况下收敛到我希望的那台设备上。比如希望A作为主翻译者,就确保A的Router-ID比B高。这样即使B能承担翻译任务,平时也不会产生不可控的路径跳变。翻译角色漂移本身是正常容灾,但在双ABR互为备份的场景里,提前规划可以少挨不少骂。

4. OSPF选路规则:从区域到优先级的一票否决

4.1 路由类型的优先级排序

OSPF选路的第一原则,不是直接比cost,而是先看路由类型。可以理解为先按“出身”排资历,出身相同的才比“努力程度”(cost)。常见的路由类型优先级从高到低为:

  • 区域内路由(O),来自Type-1/Type-2 LSA计算得出。
  • 区域间路由(O IA),来自Type-3 LSA。
  • 外部路由Type-1(O E1或O N1)。
  • 外部路由Type-2(O E2或O N2)。

这个顺序意味着什么呢?哪怕一条区域内路由的cost是500,一条区域间路由的cost是1,路由器也会优先选择区域内路由。很多人刚学OSPF时只记“cost越小越优先”,结果看到路由表里放着一条高cost的O路由,却无视低cost的O IA路由,就以为设备坏了。其实设备没坏,是路由类型的优先级排在cost前面。

4.2 E1与E2外部路由:cost是否累加

外部路由内部又分成Type-1和Type-2,二者的差异在于外部cost是否要累加沿途内部路由cost。

  • E1:路由表中显示的cost = ASBR通告的外部cost + 本地到达ASBR的内部cost。它反映了真实的路径开销,适合存在多个ASBR、希望路由器依据距离选择“最近出口”的场景。
  • E2:路由表中只显示ASBR通告的外部cost,不累加内部cost。这也是默认外部路由类型,适合只有一个出口或外部网络距离可比性不重要的场景。

举一个直观的例子:两台ASBR同时通告同一条目标网段,外部cost都是50。在E2方式下,路由器看到的cost都是50,一般还要再比较到达ASBR的内部距离,才能分出谁近谁远;而如果改用E1方式,两台ASBR对应的路由cost会分别加上路由器到达它们的内部开销,最优到底是谁,一眼就能看出来。

E2不是不好,它效率高、路由稳定,但如果你发现外部路由没有按照预期走“更近的出口”,优先检查是不是E2特性在作怪。

4.3 区域内、区域间与外部路由的互通方式

区域间的路由看似是“全网共享”,但它其实遵循距离向量的思路。ABR只把它在骨干区域中计算出的最优区域间路由,以Type-3 LSA形式通告到非骨干区域,非骨干区域内部的路由器不会自行重新计算一条“绕过ABR、直接从本区域到达目标区域网段”的路径。

这句话翻译成人话就是:区域间路由的下一跳始终是某个ABR,区域内路由器看到O IA路由,不代表它知道目标网段在区域内的另一条更近路径。OSPF的区域内路由可以在内部自由计算最优路径,但区域间路由完全依赖ABR通告,无法再做全局最优判断。

这就会产生著名的“次优路由”现象。例如Area 1内部有一台路由器可以通过直连链路快速到达某个网段,但因为该网段属于Area 2,ABR通告的Type-3路由只告诉Area 1的路由器“往ABR走”,于是流量宁可绕道ABR,也不走那条本区域内更短的路径。OSPF协议设计如此,不算bug,但在做区域划分和路由设计时必须心里有数。

外部路由同样遵循这个逻辑。stub区域里的路由器根本不认识Type-5 LSA,它们只有一条ABR下发的默认路由,所以去往外部任何目标,第一步都是找ABR。如果有多台ABR,区域内路由器会按照默认路由的cost选择把流量交给哪一台ABR。

4.4 等价路径与ECMP的边界

除了路由类型和cost,OSPF还支持等价路径负载分担。当同一路由类型、同一目标、多条路径cost相同时,路由器会把这些路径全部放进路由表,实现ECMP。

默认情况下,设备允许的最大的等价路径数量有上限,常见默认值是4条或8条,具体看设备规格和配置。在特殊区域里,默认路由也可以成为等价路由。比如totally stub区域有两台ABR,两台ABR都向区域内下发默认路由,且cost相同,边缘路由器就会形成两条等价默认路由,出方向流量在两条链路上做负载分担。

ECMP看起来很美,但在真实网络里要留意“非对称路由”问题。如果两台上行ABR分别连接不同的外部出口,某些外部目标从A出口可达、从B出口不可达,那么等价默认路由会让部分流量随身丢到黑洞。遇到这种情况,不要盲目追求等价,适当调整cost让流量有主备之分,反而更稳定。

5. 特殊区域和选路规则的实战坑位清单

5.1 stub区域里看不到外部明细,不代表没有外部路由

很多人刚配完stub区域,会有一个疑问:为什么区域内路由表看不到外部路由明细,可ping外部地址却通呢?因为stub区域通过ABR下发的默认路由实现了“路由收敛的替代方案”。

但这带来一个实际选路风险:默认路由对区域内所有外部目标一视同仁。如果该区域连接了两台ABR,而两台ABR到不同外部目标的真实路径质量完全不同,stub区域无法按目标区分出口。此时不必强行将区域改成普通区域,通过调整两台ABR下发的默认路由cost,可以让出方向流量有主次之分。比如想让A作为主出口,就把A的默认路由cost设小,B的默认路由作为备份。

反过来也有一种更精细的诉求:如果需要在stub区域中按目标网段来选择不同出口,但又不希望整张外部明细表进入区域,可以考虑使用NSSA或配置策略路由,而不是硬改OSPF。

5.2 NSSA外部路由的转发路径偏了:forwarding address在作怪

NSSA区域里最容易出的选路问题,是外部路由翻译成Type-5之后,普通区域路由器的下一跳变得“绕路”。原因是Type-7 LSA里带了一个Forwarding Address字段,也就是转发地址。

Type-5 LSA本身没有可用的路由信息时,路由器就把下一跳指向通告它的ABR。如果ABR翻译Type-7成Type-5时,转发地址为零,普通区域内的路由器会认为去往外部路由应该找ABR。于是流量先从普通区域走到ABR,再由ABR走回NSSA区域内的ASBR。这个来回不仅增加跳数,如果ABR与ASBR之间链路拥塞,还会放大延迟。

正确姿势是确认ASBR产生的Type-7 LSA携带了有效的转发地址,这样ABR翻译时就能把这个地址保留下来,普通区域路由器直接以转发地址作为下一跳,流量一步到位。常见问题发生在ASBR的接口配置、下一跳可达性判断边缘场景。别只看路由表里的cost,用tracker跟踪一条真实流量路径,马上能暴露问题。

5.3 虚链路与特殊区域不兼容的坑

OSPF虚链路是用来把一块无法直接接入骨干区域的地块“打隧道”接回Area 0的机制。但虚链路对经过的区域有要求:它不能穿越stub区域,也不能穿越NSSA区域。因为虚链路在运行时会依赖Type-5和Type-4来完成跨区域外部路由的下一跳定位,而特殊区域恰恰主动丢弃了这些LSA类型。

有一次我在规划一张新园区网络时,为了节省SPF资源,把一个计划作为虚链路经过的区域配成了totally stub。结果虚链路一直无法完全建立,邻居状态卡在Down。后来重新梳理,发现规划上的硬伤:特殊区域不适合做虚链路承载区。这不算设备故障,而是设计约束,提前在文档里标记清楚,后面就不会反复踩。

5.4 配置后的验证三板斧

特殊区域配置完之后,我最常用的验证手段就三招,简单但有效。

第一招,看数据库。在区域内的设备上查看OSPF LSDB,确认Type-5是否如期消失、Type-7是否如期出现、Type-3汇总是否被抑制。这一步能把“配置有没有生效”直接钉死。

第二招,看路由表。stub区域内应出现默认路由,并没有外部明细;totally stub区域内还应消失其他区域的Type-3明细;NSSA区域内应出现N1/N2路由;totally NSSA同样只剩默认路由。路由表是最终表现,任何配置差错都会在这里露出马脚。

第三招,追真实流量。挑一条外部目标地址,在区域内入口设备上做路径探测,观察第一跳是ABR还是ASBR。特别要注意NSSA网络的场景,如果第一跳不是预期中的出口,基本就可以怀疑转发地址或翻译者选举出了问题。真实流量永远是答案。

我在实际维护中还有一个习惯:每调整一次区域类型,都先在维护窗口内把LSDB和路由表截图存档,再对比调整前后的变化。很多时候,问题不是突然出现的,而是某次“顺手”改动之后悄悄埋下的,有存档对比就会好查得多。

OSPF特殊区域和选路规则这件事,表面上是跑几个命令、看几张表,真正值钱的功夫在理解每一类LSA活在哪里、每一类路由凭什么排在前面。配置永远不难,难的是流量走错路时,你能从LSDB和路由表里快速读出真正的原因。

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进