1. 一条汇总路由引发的割接事故
去年做一个园区网的割接,骨干区域新加了一条汇总路由,结果非骨干区域里的业务网段死活学不到这条路由。当时我下意识怀疑邻居没起来,登上去看邻居状态全是FULL;又怀疑是路由策略拦了,查了一圈filter也没问题;最后把LSDB捞出来一条条比对,发现骨干预区域的ABR压根就没给那个区域生成Type 3 LSA。问题出在哪?出在我对"区域间路由计算"这条链路的理解还停留在背考点的层次,没真正吃透ABR到底在什么条件下才会做Type 3的翻译。
这件事之后我把OSPF区域间路由这一块重新梳理了一遍,从区域划分的动机、ABR的身份判定、Type 3 LSA的生成规则、SPF第二阶段的路径计算,一直捋到防环机制和虚连接的补救方案。这篇文章就是那次复盘的完整记录,适合已经能配通单区域OSPF、但对多区域之间的路由传播总是心里没底的朋友。我会尽量把"为什么这么设计"讲透,而不是只给结论。毕竟考场上背下来的东西,到了真实现场是救不了火的。
2. 单区域OSPF的三个硬伤与分区域的真实动机
2.1 LSDB膨胀带来的SPF计算压力
很多人学OSPF的时候,书上第一句话就是"区域用来减小LSDB规模",听起来像句废话。我把这句话拆开算一下你就明白压力有多大。假设一个网络有500台路由器,每台路由器平均连3个邻居、挂2个业务网段,那么整个区域里会存在500条Router LSA和约1000条Network LSA(或者按点到点链路算,Router LSA里带链路描述)。每条LSA变一次,全区域500台设备都要重新跑一次SPF。SPF算法的复杂度跟链路数量相关,规模上去之后单次计算时间和CPU占用都不是线性增长,而是肉眼可见地拖。
更麻烦的是LSDB同步。任何一条LSA的序列号变化,都要通过LSAck、LS Update、LS Request这一套流程泛洪到全区域。链路抖动频繁的场景里,泛洪本身就会吃掉不少带宽和CPU。分区域之后,大部分拓扑变化被限制在单个区域内,其他区域只看到ABR重新生成的一条Type 3汇总,泛洪范围一下缩小了一个数量级。这就是区域划分最原始的价值。
2.2 路由抖动被隔离在区域边界
我印象很深的一次现网问题:某接入区域的一条链路反复up/down,十秒一次。如果全网是单区域,这条链路的LSA会泛洪到所有设备,每台设备都要重算SPF。实际分区域之后,只有那个接入区域内部在反复计算,骨干区域和其他区域完全无感,因为那条链路的明细根本没有被翻译成Type 3传出去。区域边界在这里起到的作用,类似于一个"抖动过滤器"。
这个特性在设计时非常有用。你完全可以把不稳定的小网段、拨号链路、无线接入这些容易抖的拓扑塞进一个边缘区域,让抖动的传播半径限制在那个区域内。代价是区域间路由的精度会下降,明细被汇总或者被截断,但对大多数企业网来说这个代价是可以接受的。
2.3 骨干区域不是随便画的圈
OSPF规定所有非骨干区域必须直接或间接连到骨干区域(Area 0),这条规则背后是有计算逻辑支撑的。骨干区域承担的是"区域间路由中转站"的角色,非骨干区域之间的路由不允许直接交换,必须绕经骨干区域。这个设计让区域间路由的拓扑呈现出一种星型结构,防环判断就变得简单——只要保证Type 3 LSA不会在非骨干区域之间互相倒手,环路就不可能形成。
所以你在规划区域的时候,骨干区域的位置要放在拓扑的中心,而不是物理上的中心机房。我见过有人把Area 0划在一个偏远的汇聚节点上,结果所有跨区域流量都要先绕到那个节点再回来,时延直接翻倍。区域规划和物理拓扑可以不完全重合,但骨干区域的选择一定要服务于流量模型。
3. ABR的身份判定:接了两条区域不一定是ABR
3.1 ABR的精确定义与常见误判
ABR的定义听起来很简单:同时连接到骨干区域和非骨干区域的路由器。但实际排查中我发现,很多"我以为它是ABR"的场景,它其实不是。关键点在于"连接"这两个字指的是接口使能了OSPF并且接口所在网段被正确宣告进了对应区域,而不是物理上插了根线。
举个例子:一台路由器有两个接口,一个在Area 0,一个在Area 1,但Area 1那个接口因为掩码配错,network命令没有匹配上,实际只在Area 0里生效了。这台设备从OSPF进程的角度看,只属于Area 0,它压根不会为Area 1生成任何Type 3。你从拓扑图上看着它是ABR,从LSDB里看它不是。我遇到过一次类似的问题,排查了两个小时,最后发现是宣告网段的反掩码写错了一位。
3.2 同进程多区域才是真ABR
还有一种更隐蔽的误判:设备上跑了两个OSPF进程,进程1在Area 0,进程2在Area 1。从配置上看这台设备"跨了两个区域",但两个进程之间默认是不交换路由的,除非做重分发。这种情况下设备不是ABR,它是两个独立OSPF域的边界,区域间路由计算根本不适用。
真正的ABR必须是同一个OSPF进程下,至少有一个接口在Area 0,至少有一个接口在其他区域。判断方法很直接:查看OSPF进程下的区域列表,或者看LSDB里这台设备的Router LSA是否在多个区域里都存在。这个细节在做方案评审的时候一定要确认,不要看拓扑图想当然。
3.3 ABR与ASBR的角色叠加
实际组网里ABR经常同时也是ASBR——既连骨干又连其他区域,同时还做外部路由引入。这两个角色叠加的时候,LSA的生成逻辑会变得复杂。Type 4 LSA就是用来描述ASBR位置的,由ABR生成,告诉其他区域"那个引入外部路由的ASBR在我这个区域里,到我这里的开销是多少"。
如果一台设备既是ABR又是ASBR,它给自己所在区域生成Type 4的时候要特别小心,容易出环路或者次优路径。我的经验是尽量把ABR和ASBR的角色分开部署,实在要合并的话,外部路由引入点尽量靠近骨干区域,减少Type 4的传播层级。
4. Type 3 LSA的生成规则:路由是怎么被"翻译"的
4.1 Type 3 LSA的关键字段解读
Type 3叫Network Summary LSA,名字里的"Summary"容易让人误以为它只能做汇总,其实它承担的是区域间路由的全部翻译工作,汇总只是其中一种用法。这条LSA的几个关键字段决定了路由怎么算:
| 字段 | 含义 | 对计算的影响 |
|---|---|---|
| Link State ID | 目标网段地址(IP网络场景) | 决定这条路由指向哪个前缀 |
| Advertising Router | 生成这条LSA的ABR的Router ID | 决定下一跳往哪个方向找 |
| Metric | ABR到目标网段的开销 | 叠加到ABR自身的SPF开销上 |
| Sequence Number | 序列号 | 防止旧LSA覆盖新LSA |
这里最容易搞错的是Metric的含义。它不是"从本源到目标网段的总开销",而是"ABR自己到目标网段那一段的开销"。接收方拿到这条LSA之后,要先算出自己到Advertising Router的开销,再加上LSA里的Metric,才是最终的路由开销。这个叠加逻辑是区域间路由计算的核心,后面会专门展开。
4.2 ABR什么时候生成Type 3,什么时候不生成
ABR的翻译规则可以概括成一句话:把本区域内学到的、不属于本区域的路由,翻译成Type 3发到本区域。具体拆开看有几种情况。
第一种,ABR从Area 1学到一条区域内路由(Type 1或Type 2描述的),它会为这条路由生成Type 3,发到Area 0。这是正常的跨区域传播。第二种,ABR从Area 0学到一条路由,会生成Type 3发到Area 1。第三种,ABR从Area 1学到路由,不会直接生成Type 3发到Area 2,而是先发到Area 0,再由Area 0那边的ABR转发到Area 2。这个"必须经过骨干"的规则就是防环的基础。
还有一种情况不生成Type 3:如果目标网段就在本区域内,ABR不需要翻译,因为区域内的路由器通过Type 1/Type 2本来就能算出来。重复生成反而会造成LSDB冗余。
4.3 汇总与过滤对Type 3的影响
ABR上可以配置区域间路由汇总,把多条明细Type 3合成一条。汇总的本质是在ABR上拦截明细的翻译过程,只发一条聚合后的Type 3出去。这里有个坑:汇总之后,如果明细里有一条链路down了,只要还有其他明细存活,汇总路由就不会撤销,流量会被黑洞到一条已经不通的路径上。解决办法是在ABR上同时配置一条指向null0的汇总静态路由作为兜底,让不通的流量有一个明确的丢弃出口,而不是在区域间乱绕。
过滤方面,ABR可以在区域视图下对Type 3做入方向或出方向的过滤。出方向过滤是ABR不往某个区域发某条Type 3;入方向过滤是ABR不从某个区域接收某条Type 3。两者效果看起来相似,但影响面不同:出方向只影响下游区域,入方向会影响ABR自己以及它往其他区域翻译的结果。排查"路由学不到"的问题时,这两个方向要分别确认。
5. 区域间路由计算的完整链路:从SPF树到路由表
5.1 第一阶段:先算区域内可达性
OSPF的路由计算严格分两个阶段。第一阶段是区域内SPF,用Type 1和Type 2 LSA构建本区域的拓扑树,算出到区域内每个节点和网段的最短路径。这一步跟单区域OSPF完全一样,本文不展开。重点是要理解:第二阶段的所有计算都建立在第一阶段的结果之上。
也就是说,当接收方看到一条Type 3 LSA,它要做的第一件事是查自己的SPF树——Advertising Router这个节点在不在我的区域内拓扑里?如果不在,这条Type 3就无法计算,路由会被丢弃。这就是为什么ABR必须和接收方在同一个区域内有可达路径。如果ABR和接收方之间的区域内链路断了,即使Type 3 LSA还留在LSDB里,路由也会失效。
5.2 第二阶段:Type 3 LSA的路径叠加
假设接收方路由器R1在Area 1,ABR的Router ID是2.2.2.2,ABR生成了一条Type 3描述10.10.10.0/24,Metric是20。R1的计算过程是这样的:
- 在第一阶段的SPF树里找到2.2.2.2这个节点,查出R1到2.2.2.2的开销,假设是10。
- 取出Type 3 LSA里的Metric 20。
- 两者相加,最终路由开销 = 10 + 20 = 30。
- 下一跳指向SPF树里到2.2.2.2的下一跳。
这个叠加过程解释了一个常见现象:同样的目标网段,从不同ABR学到的Type 3,Metric可能不一样,因为不同ABR到目标网段的区域内开销不同;同时接收方到不同ABR的开销也不同。最终选路是这两段开销之和的比较,而不是单纯比Type 3里的Metric。很多人只盯着LSA里的Metric看,忽略了前半段,选路结果就对不上了。
5.3 路由表里的O IA到底代表什么
路由表里看到的"O IA"(OSPF Inter-Area),意思是这条路由是通过区域间路由计算得来的,来源是Type 3 LSA。跟它对应的是"O"(区域内,来自Type 1/2)、"O E1/E2"(外部,来自Type 5)。看到O IA的时候,你要在脑子里建立起这样一条链路:这条路由的下一跳一定指向某个ABR,开销一定包含了两段——到ABR的区域内开销加上ABR给出的Metric。
还有一类容易混淆的:O IA路由如果同时有明细和汇总,优先选明细,这是最长匹配原则,跟OSPF本身无关。排查选路问题时不要只盯着OSPF的metric看,前缀长度的影响往往更大。
5.4 等价多路径与区域间负载分担
区域间路由是支持ECMP的。如果接收方到两个ABR的开销相同,两个ABR给出的Type 3 Metric也相同,那么最终两条路径的开销相等,流量可以负载分担。这个特性在做双ABR冗余设计时非常有用。但要注意,ECMP的前提是两条路径的总开销相等,而不只是某一段相等。我曾经配过一个双ABR场景,两个ABR到接收方的区域内开销一样,但它们到目标网段的开销差了1,结果只有一条路径进路由表,另一条一直是备而不用的状态。后来把其中一条链路的cost手工调了一下才做成负载分担。
6. 防环机制:Type 3 LSA为什么不能走回头路
6.1 水平分割规则的具体表现
OSPF区域间防环的核心规则是:ABR不会把从非骨干区域学到的Type 3 LSA再翻译回骨干区域,也不会把从一个非骨干区域学到的Type 3直接翻译到另一个非骨干区域。这条规则保证了区域间路由的传播路径是树形的,不会形成闭环。
我用一个具体场景推演一下。Area 1里有一台ABR叫A,Area 2里有一台ABR叫B,两台ABR都连在Area 0上。如果允许A把从Area 1学到的路由直接发给Area 2,B又把从Area 2学到的路由发回Area 1,那么在特定拓扑下就可能出现A→B→A的环路。禁止非骨干区域之间直接交换,等于强制所有跨区域路由经过Area 0中转,环路的可能性就被消除了。
6.2 一条典型环路的推演过程
假设我们违规配置,让两个非骨干区域直接交换Type 3,看看会发生什么。Area 1的网段10.1.0.0/24,ABR-A把它翻译成Type 3发到Area 2,Metric是10。ABR-B收到后,如果又把它翻译回Area 1,Metric加上自己到Area 2的开销变成30。ABR-A收到这条Type 3,一看是自己发出去的路由又回来了,如果它不丢弃,就会在LSDB里形成两条描述同一网段的Type 3,一条来自自己(Metric 10),一条来自B(Metric 30)。按最短路径选,A会选自己那条,暂时不环。但如果A到10.1.0.0/24的直连链路断了呢?A会认为自己那条Type 3失效,转而使用B发回来的那条,流量就会从A绕到B再绕回A,形成环路,直到B那边的LSA老化。这就是水平分割规则要防的场景。
OSPF的处理方式是:ABR在生成Type 3时,会检查这条路由是否来自非骨干区域。如果来源是非骨干区域,且目标是另一个非骨干区域,直接不翻译。这就从源头上切断了环路可能。
6.3 骨干区域不连续会破坏防环前提
上面这套防环逻辑有一个隐含前提:骨干区域是连续的单块。如果Area 0被分割成两块互不相连的区域,中间隔着Area 1,那么防环规则就失效了。这种情况下,两边的ABR都认为自己是骨干区域的边界,互相之间无法通过Area 0直接通信,只能通过Area 1中转。而Area 1是非骨干区域,按照规则不能承载骨干区域的Type 3转发,路由就断了。
解决办法就是虚连接。虚连接本质上是把Area 0的逻辑延伸穿过一个transit区域,让被分割的骨干区域重新连成一体。虚连接建立之后,两端的ABR会认为彼此在Area 0内直连,Type 3的翻译和防环规则重新生效。这是虚连接最正统的用法,比用它来连接"没有直连骨干的非骨干区域"更常见也更必要。
7. 虚连接的适用边界与配置陷阱
7.1 虚连接解决的是什么问题
虚连接(Virtual Link)的核心作用是修复骨干区域的连续性。它穿过一个transit区域(必须是普通区域,不能是stub、NSSA这类特殊区域),在两台ABR之间建立一条逻辑链路,让这条链路被当作Area 0的一部分参与计算。配置的时候两端都要指定对端的Router ID和穿越的区域号,两端的Router ID必须互指,写错一个字母都起不来。
虚连接的cost是个容易被忽略的点。默认情况下虚连接的cost等于穿越区域的那段区域内开销,但很多实现允许手工指定。如果穿越区域的路径比较长,虚连接的cost会比较大,可能影响路径选择。我一般会在设计阶段就把穿越区域的cost算清楚,必要时手工指定,避免虚连接起来之后路由选得莫名其妙。
7.2 虚连接配置后必须验证的三件事
第一,虚连接两端的邻居状态。虚连接起来之后,用查看虚连接邻居的命令确认状态是FULL,PASSIVE或者DOWN都说明没起来。第二,穿越区域的Router LSA里要能看到虚连接对应的链路描述,这是虚连接参与SPF计算的依据。第三,虚连接建立后,远端的非骨干区域应该能学到原本学不到的Type 3,这是验证虚连接生效最直接的方法。
我踩过的一个坑是:虚连接配好了,邻居也FULL了,但远端区域的路由还是不全。查下来发现是transit区域的MTU不一致,虚连接虽然起来了,但大尺寸的LS Update报文过不去,导致部分LSA同步不上。后来统一了穿越路径上的MTU才解决。这个细节在文档里基本不会提,但现网里MTU不匹配是真的会出问题。
7.3 tunnel方案与虚连接的取舍
有些场景下会用GRE tunnel替代虚连接,把非骨干区域通过tunnel挂到骨干区域上。tunnel的优点是配置直观,不依赖OSPF自身的机制;缺点是tunnel是逻辑接口,会引入额外的封装开销,而且tunnel本身的稳定性依赖于底层路由,容易形成递归依赖。我的经验是:如果只是修复骨干区域不连续,优先用虚连接;如果是需要跨运营商或者跨管理域的连接,tunnel的灵活性更好。两者不要混用,否则路由计算会变得非常难排查。
8. 排错实录:区域间路由不通的四层排查法
8.1 第一层:邻居和接口状态确认
排除区域间路由问题,第一步永远是确认邻居状态和接口宣告。不要一上来就捞LSDB,那样效率太低。先确认ABR和接收方在目标区域内的邻居是FULL,接口的network宣告匹配正确,区域号没有写错。我遇到过的案例里,有一半以上是宣告问题——反掩码写错、接口被passive掉、区域号配错,这些低级错误占了相当大的比例。
确认完邻居之后,再确认ABR的Router ID。有些设备上Router ID是手工指定的,有些是自动选举的,如果ABR的Router ID变了,接收方SPF树里对它的引用会失效,Type 3就算在LSDB里也计算不出来。这个点在设备重启或者接口变动之后特别容易出问题。
8.2 第二层:Type 3 LSA是否生成与传播
邻居没问题之后,登到ABR上看LSDB里有没有目标网段的Type 3。如果没有,说明ABR没有做翻译,原因可能是目标网段不属于ABR需要翻译的范围(比如它就在本区域),也可能是被汇总或者过滤拦掉了。如果有,再登到接收方看LSDB里有没有这条Type 3,没有说明泛洪链路有问题,可能是区域边界上的filter,也可能是LSA老化或者序列号问题。
这一步我通常会把两端的LSDB抓下来做对比,重点看Link State ID、Advertising Router和Sequence Number三个字段。序列号不一致说明泛洪没有收敛,需要检查LSAck和重传。Advertising Router对不上说明有多个ABR在同时生成这条LSA,要确认选路是否符合预期。
8.3 第三层:路由计算是否成功
LSDB里有Type 3但路由表里没有路由,问题就出在计算阶段。这时候要查两件事:接收方到Advertising Router是否可达,以及是否有更优的路由覆盖了这条。前者查SPF树,后者查路由表里的等价路由和前缀长度。还有一种情况是Type 3的Metric被设置成了最大值(比如16777215),这种LSA是ABR用来撤销路由的,不会被计算成有效路由。
我遇到过一次很隐蔽的情况:接收方到ABR的区域内路径上有一条链路cost配得特别大(手工调过),导致叠加后的总开销超过了另一条绕行路径,路由表里选的是绕行路径。但绕行路径的下一跳指向另一个区域,实际转发时又绕回来了。这种情况要从SPF树的完整路径看,不能只看单跳。
8.4 第四层:策略与汇总的干扰
最后一层排查策略和汇总。区域间路由的filter、summary-address、distribute-list都可能影响Type 3的生成和接收。这些配置的特点是生效范围大、影响面广,出问题的时候往往不是完全不通,而是部分路由丢失,排查起来更费劲。
我建议在改动这类策略之前,先把改动前的LSDB和路由表做快照,改完之后逐条对比。不要一次性改多条策略,那样出问题根本定位不到是哪一条引起的。曾经有一次为了图省事,一次性加了三条汇总和两条filter,结果跨区域路由丢了七八条,回滚和逐条验证花了整整一个下午。从那以后我改区域间策略都是改一条验一条,慢是慢了点,但心里踏实。
9. 我自己在这个知识点上栽过的几个跟头
回过头看,区域间路由计算这块内容之所以容易出问题,是因为它把多个环节串成了一条长链路:邻居、LSA生成、LSA泛洪、SPF计算、路由叠加、策略过滤,任何一环出问题都表现为"路由不通",但根因可能天差地别。我后来养成了一个习惯,排查这类问题的时候先在纸上画出完整的传播链路,标出每一个可能出问题的节点,然后从下游往上游逐段验证,而不是凭直觉跳着查。
还有一个体会是,实验环境里配通和现网里配通是两码事。实验环境往往拓扑简单、策略干净,区域间路由一配就通;现网里有历史遗留的filter、有各种汇总、有不同厂商设备的实现差异,同样的配置效果可能完全不同。所以我现在做任何涉及区域边界的改动,都会先在实验环境里把现网的配置完整复刻一遍,验证通过再上现网。这个习惯帮我避开了不少坑,虽然前期多花时间,但比起半夜被叫起来处理故障,这点时间花得值。