1. 先搞清楚内部路由选择协议到底在解决什么问题
干网络这行的,谁没在半夜被“某段链路不通”叫起来过。抓起电脑连上设备,display ip routing-table或者show ip route一敲,屏幕上密密麻麻几十条路由,直连的、静态的、动态的混在一起,你得在两分钟内判断出这条路径到底是哪个协议算出来的、为什么它没算对。内部路由选择协议(Interior Gateway Protocol,IGP)就是网络层里最接地气、也最容易出事故的那块内容。它不像子网划分那样可以纸上谈兵,也不像TCP三次握手那样背下来就能应付考试,它是一套跑在真实设备上、会随时间变化、会因为一行配置错误而让整个机房哑掉的东西。这篇内容适合两类人:一类是刚学完网络层理论、知道“路由表”三个字但没真正配过协议的,另一类是干了一两年、平时靠模板复制粘贴配置、一出问题就只会重启进程的。我会把RIP、OSPF、IS-IS这几套内部路由选择协议的选择逻辑、参数计算、实操步骤和踩坑经验摊开讲清楚,尤其是那些手册上不会写、但现场一定会遇到的东西。
1.1 从一次ping不通说起:路由表到底是怎么来的
很多人对路由表的理解停留在“设备里天生就有”这个层面,实际上路由表里的每一条目都有明确来源,归成三类:直连路由、静态路由、动态路由。直连路由是接口配上地址、状态变成UP之后自动进表的,最可靠,管理距离最小,但它只知道“我直连的那一小块”。静态路由是人为写死的,适合出口方向、末梢网络,可控但不会自己变。动态路由就是内部路由选择协议干的事:设备之间互相说话,把各自知道的网络告诉对方,最后每台设备自己算出一张完整的表。
为什么必须要有动态的?算笔账就明白了。假设某实验室有一张20台路由器组成的实验网,任意两台之间都可能需要互通。如果全靠静态路由,理论上每台设备都要知道其余19台设备身后的网段,一条条写下来,全网的路由条目数量级是 n×(n-1),20台就是380条。这还只是数量问题,更麻烦的是变更:任何一台设备的某个接口DOWN掉,或者新增一个网段,你都得在其余19台上手工改。凌晨三点做这种操作,出错概率有多高不用我说。动态路由协议把这件事变成了“设备自己商量”,拓扑一变,消息传开,各设备重新计算,人只需要保证协议本身配置正确。这就是内部路由选择协议存在的根本理由——不是为了炫技,是为了把人的重复劳动换成机器的自动收敛。
1.2 自治系统边界与IGP/EGP的分工
讲内部路由选择协议绕不开一个概念:自治系统(Autonomous System,AS)。你可以把它理解成一个“自己说了算”的网络域,域内的路由策略由自己定,对外只暴露一个统一的入口。这个边界一划,路由协议就分成了两拨:域内跑的叫IGP,域间跑的叫EGP,后者最典型的就是BGP。
为什么要分两层而不是一套协议打天下?核心是目标和规模完全不同。IGP的任务是“在域内找到一条代价最小的路径”,它关心的是链路带宽、延迟、跳数这些可计算的度量值,追求的是快速收敛和无环。BGP的任务是“在域间按照策略选择路径”,它关心的不是快,而是“我愿不愿意把流量交给这个邻居”“这条路径经过哪些域”。一个追求性能,一个追求策略,硬塞进一套协议里必然两头不讨好。
生活化的类比:IGP像城市内部的导航,你要从城东到城西,导航帮你算哪条路红绿灯少、哪条路不堵;BGP像跨省物流,走哪条高速不只看远近,还要看各地的通行规则、哪个关口排队短。你在城里开车不需要操心跨省的事,跨省调度也不需要精确到每个路口。所以实际组网里,IGP通常只承载域内网段和环回口地址,域间路由一律交给BGP,这个分工是稳定的工程共识,不要试图用IGP去承载几十万条外部路由,那会把设备的LSDB和CPU直接压垮。
1.3 距离向量与链路状态:两条根本不同的技术路线
所有内部路由选择协议,归根结底就两条路线:距离向量(Distance Vector)和链路状态(Link State)。这个分类不是学术上的文字游戏,它直接决定了协议的行为特征和排障思路,理解这一点比记住任何配置命令都重要。
距离向量的世界观是“我只信邻居”。每台设备周期性地把自己知道的整张路由表告诉直连邻居,内容包括“到某个网段有多远、下一跳是谁”。收到之后跟自己的表比对,如果邻居给的路径更短就更新,否则忽略。它的信息是间接的、传话式的,所以叫“道听途说”。优点是实现简单、开销小、对设备性能要求低;缺点也致命:收敛慢,而且天然存在环路风险,需要额外机制打补丁。
链路状态的世界观是“我要看清全图”。每台设备把“我连着谁、代价多少”这条本地信息打包成LSA,泛洪给域内所有设备,每台设备收集齐所有LSA后建一个完整的拓扑数据库(LSDB),然后以自己为根跑一遍最短路径优先(SPF)算法,算出到每个网段的最优路径。它的信息是第一手的、全局的,所以收敛快、天然无环,但代价是内存和CPU开销大,泛洪控制和区域划分是必须做的功课。
2. 距离向量:RIP的朴素智慧与它的天花板
RIP(Routing Information Protocol)是很多人接触的第一个动态路由协议,也是被吐槽最多的一个。教育场景里它是最好的教学样本,因为逻辑足够简单;生产环境里它通常只出现在很小的末梢网络或者临时组网里。把RIP吃透,距离向量这条线的所有毛病你都能看得清清楚楚,后面再理解其他距离向量型的协议会轻松很多。
2.1 Bellman-Ford算法:跳数是怎么一轮轮传开的
RIP跑的是Bellman-Ford算法,本质是“逐跳累加、反复迭代”。给它一个具体场景你就能看明白。三台设备串成一条线:R1—R2—R3,R1身后挂一个网段A。假设链路代价都用跳数,直连算0跳或1跳(不同实现的计数起点略有差异,但相对关系一致)。
第一轮,R3只知道自己直连的东西,对网段A一无所知。R2同样。R1知道自己直连网段A,跳数为0。第二轮,R1把“网段A,0跳”告诉R2,R2收到后更新为“网段A,1跳,下一跳R1”。第三轮,R2把这个信息转告R3,R3入表“网段A,2跳,下一跳R2”。整个收敛过程需要若干个更新周期,每个周期默认30秒,看起来慢,但在只有几台设备的小网里完全够用。
关键点在于:RIP的每条路由只记住“距离”和“下一跳”,它不知道路径经过哪些设备,也不知道链路带宽。所以一条2跳的百兆链路和一条2跳的万兆链路在它眼里完全一样。这就是为什么RIP在带宽差异大的网络里表现很差——它会把流量扔到一条堵得水泄不通但跳数更少的路上。
2.2 计数到无穷:距离向量最经典的坑
链路断开时的行为,是RIP最需要讲清楚的部分。还是上面那个拓扑,R1身后的网段A断掉了。R1把网段A的跳数标成16(16代表不可达),但它如果只等自己的定时器慢慢老化,中间这段时间会发生什么?
R2本来从R1学到“网段A,1跳”。现在R1说自己不行了,但R2手里还有一条“我通过R3能到网段A,2跳”。于是R2可能反过来告诉R1:“我这儿有条2跳的路,你要不要?”R1一看,从R2那里学到的路径比自己的16要好,就更新成“网段A,3跳,下一跳R2”。然后R1又告诉R2“我能到,3跳”,R2更新成4跳……两个邻居互相欺骗,跳数一路涨到15,第16跳才判定不可达。这个过程叫“计数到无穷”,收敛时间可能长达几分钟,这几分钟里流量全在黑洞里打转。
针对这个问题的补丁有好几个,每个都有明确的适用边界。水平分割:从哪个接口学来的路由,不再从这个接口发回去,从源头掐断互相欺骗。毒性逆转:跟水平分割相反的思路,允许发回去,但把度量设成16,明确告诉对方“我这条路是死的,别信”。这两种选一种用,毒性逆转信息更明确但报文更大。触发更新:拓扑一变立刻发更新,不等30秒周期,把收敛时间从分钟级压到秒级。抑制时间:收到某条路由不可达后,在180秒内不接受关于它的新信息,防止抖动。最大跳数15:硬性上限,超过就判死,这是最后一道保险。
注意:这几种机制不是互相替代关系,实际部署里水平分割加触发更新是标配,抑制时间看网络抖动情况决定开不开。但如果你的网络里RIP已经在频繁抖,别指望靠调这几个参数救回来,那说明协议选错了,该换OSPF。
2.3 RIPv1和RIPv2的差距,以及定时器的实际调法
RIPv1和RIPv2差的不只是一个版本号。v1是有类路由协议,发更新的时候不带子网掩码,收到方只能按A/B/C类默认掩码去理解,也不支持认证,用广播方式发送。v2是无类的,带掩码,支持变长子网划分和路由汇总,支持明文和MD5认证,改用组播发送。这个差距意味着:只要你的网络里做过子网划分(几乎没人不做),v1基本就没法用。
RIPv2的关键参数和定时器值得记一下,排障时全靠这些数:更新周期30秒,路由老化时间180秒(6个周期没收到就标记不可达),抑制时间180秒,清除时间240秒(不可达后再等60秒彻底删掉)。组播地址是224.0.0.9,端口520。认证配置在所有设备上必须一致,密钥错了邻居关系是静默失败的,报文直接丢弃,不会有任何提示,这是新手最容易卡住的地方。
一个典型的RIPv2配置(不同设备语法略有差异,核心逻辑一致):
# 启用RIP进程并指定版本2 router rip version 2 # 关闭自动汇总,手工控制 no auto-summary # 宣告直连网段,注意是宣告网段不是宣告接口 network 192.168.10.0 network 10.0.0.0 # 接口层面做认证 interface GigabitEthernet0/1 ip rip authentication mode md5 ip rip authentication key-chain RIPKEY我个人的经验是:RIP只在三种场景还值得用——设备性能极弱的老旧终端、临时搭建的测试环境、以及某些嵌入式系统只为兼容性保留的RIP实现。真要做生产网络,哪怕只有十台设备,OSPF的可维护性也远胜RIP。
3. 链路状态:OSPF是怎么把全网画成一张图的
OSPF(Open Shortest Path First)是内部路由选择协议里用得最广的一个,也是面试和实操中被问得最细的一个。它的核心思路只有一句话:每台设备都拿到全网的拓扑图,然后各自以自己为根算最短路。但这句简单的话背后有一整套机制——邻居发现、邻接建立、LSA泛洪、数据库同步、SPF计算、区域划分,每一层都需要理解到位,否则你只会照抄配置,出了问题完全无从下手。
3.1 从Hello报文到邻居关系:五道匹配条件缺一不可
OSPF设备之间第一次见面靠Hello报文。Hello默认每10秒发一次(广播网络和点对点网络),死亡时间40秒,也就是连续4个Hello没收到就判定邻居失效;在NBMA网络里这两个值分别是30秒和120秒。Hello报文里携带了一堆字段,其中五项必须完全一致,邻居关系才能往下走:
| 匹配项 | 说明 | 不一致的后果 |
|---|---|---|
| Area ID | 区域号 | 邻居停在Init,无法建立 |
| Hello/Dead间隔 | 定时器 | 邻居抖动,反复建立又断开 |
| 认证类型与密钥 | 明文或MD5 | 报文被丢弃,状态不动 |
| 网络掩码 | 广播网络上的掩码 | 邻居卡在ExStart之前 |
| MTU | 最大传输单元 | 卡在ExStart,DD报文交换失败 |
前四项在Hello报文里就能比对,MTU例外——它是在DD(Database Description)报文交换阶段才检查的,所以表现出的现象不一样:前三项不一致时邻居状态停在Init或者根本看不到邻居,掩码不一致时可能停在2-Way之后,MTU不一致时邻居已经出现在列表里但卡在ExStart。这个区别在排障时非常好用,看到ExStart直接去查MTU,基本八九不离十。
邻居状态机有七个状态,值得完整过一遍:Down(初始,没收到任何Hello)、Init(收到Hello但自己的Router ID不在对方的邻居列表里,说明是单向的)、2-Way(双向确认,这是选举DR/BDR的节点)、ExStart(协商主从关系,决定谁先发DD)、Exchange(互发DD报文,交换LSDB摘要)、Loading(请求自己缺失的完整LSA)、Full(数据库完全同步)。非DR/BDR之间停在2-Way是正常状态,不是故障。
3.2 LSA泛洪与LSDB同步:可靠泛洪是怎么做到的
邻居建起来之后,真正的信息交换靠LSA。OSPF把不同类型的拓扑信息封装成不同种类的LSA,最常用的六种必须分清:
- Type 1 Router LSA:每台设备产生,描述自己的所有接口、接口代价、邻居Router ID。只在本区域内泛洪,不跨区域。
- Type 2 Network LSA:由DR产生,描述广播网络上连接了哪些设备。也只有本区域有效。
- Type 3 Summary LSA:由ABR产生,把本区域的网段信息汇总后通告给其他区域,是区域间路由的来源。
- Type 4 ASBR Summary LSA:由ABR产生,告诉其他区域“到ASBR怎么走”,配合Type 5使用。
- Type 5 External LSA:由ASBR产生,描述引入的外部路由,泛洪整个AS(除特殊区域)。
- Type 7 NSSA External LSA:在NSSA区域里替代Type 5使用,到ABR处再转成Type 5。
每个LSA都带序列号、老化时间(最大3600秒,每1800秒刷新一次)和校验和,这三个字段保证同一份LSA的新旧能被正确判断。泛洪的可靠性靠LSAck报文确认:收到LSA先回一个确认,没收到确认就重传。这套机制比RIP的“30秒广播一次整张表”要精细得多,但也意味着LSDB规模会随网络规模线性增长,这就是为什么大网必须分区域。
3.3 SPF计算:以自己为根画一棵树
LSDB同步完整之后,每台设备独立跑SPF算法(Dijkstra算法)。算法过程可以简化成三步:第一步,把自己放进树里,作为根节点,代价为0;第二步,从树外找一条到树内代价最小的链路,把它对应的节点和链路加进树;第三步,重复第二步直到所有节点都在树里。算完之后,每个目的网段的代价等于路径上所有出接口代价之和,然后写入路由表。
举个具体例子:R1到R3有两条路,一条是R1—R2—R3,两段链路代价各10,合计20;另一条是R1—R4—R3,两段代价各100,合计200。SPF算出两条都可达,选代价小的20,走R2。如果R1—R2这段升到100,总代价变成110,依然小于200,还是走R2。只有当R1—R2总代价超过200时才会切换到R4。这个“逐跳累加、全局择优”的逻辑解释了OSPF的一个重要特性:它天然无环,因为每台设备算的树不同但方向一致,不会出现A指向B、B又指回A的情况。
代价怎么算?默认公式是参考带宽除以接口带宽,参考带宽默认100Mbps,结果取整且最小为1。所以百兆口代价1,千兆口代价1(100M/1000M=0.1,取最小1),万兆口也是1。这里就有问题了:千兆和万兆在默认设置下无法区分,两条路一条千兆一条万兆,OSPF会认为代价一样,直接做等价多路径分担,导致万兆链路上跑一半流量,浪费资源。
3.4 区域划分:为什么要划,怎么划才不出事
单区域OSPF在几十台设备以内还能凑合,一旦规模上去,两个问题同时爆发:一是LSDB太大,每台设备存全网拓扑,内存吃不消;二是任何一条链路抖动都会触发全网所有设备重跑SPF,CPU瞬间打满。解决方法是分区域:骨干区域Area 0负责中转,其他区域只保留本区域的完整拓扑,跨区域的信息由ABR(区域边界路由器)汇总成Type 3 LSA传递。
区域设计有几条硬规则不能碰。所有非骨干区域必须直接连到Area 0,跨区域的流量必须经过Area 0中转,不允许两个非骨干区域之间直接对接——这条规则不理解清楚,配出来的网络就是次优路径。实在物理上连不到Area 0的,用虚连接(Virtual Link)穿过一个传输区域打隧道过去,但虚连接本身是个补丁,能用物理链路解决就不要用它。还有一条经验阈值:单个区域内的设备数量建议控制在50台以内,超过就考虑再分。我见过一个单区域塞了将近两百台设备的网,每次接口抖动都能让核心设备的CPU跑到90%以上,后来拆成四个区域才压下来。
ABR上做路由汇总是个必做的优化。不做汇总的话,一个区域里200个网段,会变成200条Type 3 LSA泛洪到其他所有区域,网络规模一大LSA数量就爆炸。在ABR上配置area 10 range 10.10.0.0 255.255.0.0这样的汇总,200条明细变成一条,LSDB直接瘦身。但汇总有个副作用必须提前想清楚:如果某个明细网段在区域内部断了,汇总路由依然存在,流量会被引到ABR然后黑洞掉。所以关键业务网段要么不做汇总,要么配合明细的blackhole路由一起做。
4. 工程落地:参数计算、选路规则与协议对比
理论讲完,落地的时候真正决定成败的是一堆具体数值和选路规则。这部分内容手册上都有,但分散在各处,我按实际操作顺序整理一遍。
4.1 管理距离、最长匹配与选路优先级
一台设备上有多个路由来源时,先信谁?规则分两层。第一层是最长匹配:目的地址匹配度最高的路由优先,这条规则高于一切。比如路由表里有10.0.0.0/8和10.1.0.0/16两条,去往10.1.2.3的包一定走第二条,跟协议类型无关。
在掩码长度相同的情况下,才比管理距离(Administrative Distance,AD),AD小的优先。常见取值:直连0,静态1,某厂商私有的增强型距离向量协议内部路由90,OSPF 110,IS-IS 115,RIP 120,该协议的外部路由170。这些数值是厂商实现约定,不同厂商之间可能有细微差异,跨厂商组网时要以实际设备的输出为准,不要照搬记忆里的数字。
AD相同的情况才比度量值,度量值小的优先。度量值也相同的,做等价多路径(ECMP),默认情况下多数设备支持4到8条等价路径同时转发,这个功能在双上行组网里非常实用。
一个常见误区:很多人以为AD小的路由会“覆盖”AD大的路由,其实不是。不同AD的路由可以同时存在于路由表中,只是AD大的那条被标记为备用,不在转发表里。一旦AD小的那条消失,备用路由立刻顶上,这个切换过程很快,不需要重新收敛。理解这一点,你在设计双协议冗余时就有底了——比如OSPF做主、静态做备,静态路由配个高AD值挂着,主路径一断马上生效。
4.2 OSPF开销计算的实操与参考带宽调整
前面说过默认参考带宽100Mbps导致高带宽接口代价都是1的问题,解决办法是调大参考带宽。命令层面通常是auto-cost reference-bandwidth 10000(单位Mbps,即10Gbps)。调整后的对应关系:
| 接口带宽 | 默认参考带宽100M下的cost | 参考带宽10G下的cost |
|---|---|---|
| 10M | 10 | 1000 |
| 100M | 1 | 100 |
| 1G | 1 | 10 |
| 10G | 1 | 1 |
| 40G | 1 | 1(需手工改) |
| 100G | 1 | 1(需手工改) |
可以看到,就算把参考带宽调到10G,40G和100G接口的cost还是1,因为公式取了整数且最小为1。这种超高速接口必须手工指定cost,比如ip ospf cost 1给100G、ip ospf cost 2给40G,人为拉开差距。
注意:参考带宽必须在同一个区域内的所有设备上配成一致的值。只改了一部分设备,会导致两个方向算出来的路径不一样,出现单向次优甚至非对称转发,这种问题排查起来极其费劲——因为路由表看起来都是对的,只有抓包比对来回路径才能发现。
4.3 DR/BDR选举:为什么需要,怎么控制
广播型网络(比如一台交换机上挂了十几台路由器)里,如果每两台都建立完整邻接,邻接数量是 n×(n-1)/2。10台设备就是45个邻接,每个邻接都要同步LSDB、泛洪LSA,开销大得离谱。DR/BDR机制就是来解决这个的:选一个DR和一个BDR,所有设备只跟DR/BDR建立Full邻接,设备之间停留在2-Way。10台设备的邻接数从45降到17个左右(DR对8台,BDR对8台,DR对BDR),泛洪范围也被限制住了。
选举规则两条:先比接口优先级(默认1,取值范围0到255,0表示不参选),优先级高的赢;优先级相同比Router ID,数值大的赢。这里有个必须记住的特性:选举是非抢占的。也就是说,DR选出来之后,就算新加入一台优先级更高的设备,它也不会抢走DR角色,除非DR失效或者OSPF进程重启。很多人调优先级发现没生效,就是踩在这个点上。
控制DR的实操建议:核心设备上把优先级显式调高(比如ip ospf priority 200),接入设备保持默认或设成0(不参与选举),这样角色固定,不会因为某台设备重启导致DR漂移。点对点链路上DR机制没意义,接口配成ip ospf network point-to-point可以把邻居建立时间从40秒缩短到几秒,同时省掉DR选举开销,串行链路和专线上都建议这么配。
4.4 几种内部路由协议横向对比
选协议的时候,把这张表过一遍基本就有答案了:
| 维度 | RIP | OSPF | IS-IS | 某厂商私有增强型距离向量 |
|---|---|---|---|---|
| 算法类型 | 距离向量 | 链路状态 | 链路状态 | 混合型 |
| 度量依据 | 跳数 | 带宽(cost) | 接口开销(可自定义) | 带宽+延迟综合 |
| 最大规模 | 15跳 | 单区域几十台,多区域上千 | 大规模承载能力强 | 中等规模 |
| 收敛速度 | 分钟级 | 秒级 | 秒级 | 秒级 |
| 区域划分 | 不支持 | 支持 | 支持 | 不支持(靠其他机制) |
| 组播地址 | 224.0.0.9 | 224.0.0.5/224.0.0.6 | 二层组播 | 224.0.0.10 |
| IPv6支持 | 需单独版本 | OSPFv3 | 原生扩展 | 独立实现 |
| 典型场景 | 极小末梢 | 企业网主流 | 运营商/大型承载 | 单厂商环境 |
对绝大多数企业网,OSPF是默认答案:生态成熟、排障资料多、跨厂商兼容好。IS-IS在运营商和大型数据中心里更常见,因为它在扩展性和对IPv6的原生支持上更顺,但学习曲线比OSPF陡,配置习惯也完全不同,中小企业没必要为了“看起来高级”去选它。RIP只在设备资源极度受限的场合保留。至于某厂商私有的那套,思路确实不错(融合了距离向量的简单和链路状态的速度),但一旦网络里混入其他厂商的设备就傻眼了,选它之前先确认自己的采购策略是不是单一来源。
5. 排障实录:邻居起不来、路由有了不通、收敛慢
协议配置完成只是开始,真正花时间的是出问题之后的定位。下面这几类问题我遇到了不知道多少次,整理成固定的排查顺序,比漫无目的地翻配置高效得多。
5.1 邻居建不起来:按状态机定位
排查邻居问题,第一步永远是看邻居状态停在哪个阶段,状态本身就是最好的线索。
根本看不到邻居:先查二层。接口是不是UP、VLAN是不是放通、直连能不能ping通。二层不通,上层什么配置都是白搭。二层通了再看组播——有些环境下组播报文被ACL或者端口隔离挡住了,单播能通、组播不通,现象就是邻居完全看不见。抓包确认224.0.0.5的报文有没有到达对端。
停在Init:这个状态说明“我收到了你的Hello,但你的Hello里没有我”。典型原因是单向可达——A能到B,B回不到A,比如一边的ACL只放行了单向。也可能是Router ID冲突,两台设备配了同样的ID,互相认为对方是自己。
停在2-Way:先别急着修,广播网络里非DR/BDR之间停在2-Way是正常设计。如果所有邻居都停在2-Way,那才是DR选举出了问题,检查优先级和Router ID。
停在ExStart:九成是MTU不一致。两端接口MTU不同,DD报文大小对不上,协商就卡住。ping带不分片参数、指定大小试探一下就能确认。解决方法是把两端MTU调成一致,或者接口上配置忽略MTU检查(能改MTU就别用后者,掩盖问题)。
停在Exchange或Loading:说明DD交换或LSA请求出了问题。检查LSDB里是不是有异常的老化LSA,或者设备内存不足导致LSA处理失败。这种情况比较少见,一般伴随日志报错。
5.2 路由表里有条目但业务不通
这是最迷惑人的一类:邻居Full,路由表里有目标网段,下一跳也对,但业务就是不通。链路状态协议算出来的路由天然无环,所以问题往往不在协议本身。
第一种可能:单向路由。A有到B的路由,B没有回A的路由,去包能到、回包丢了。查法是两端都看路由表,别只看一端。区域划分不当很容易造成这种局面——比如某个网段只在一个区域里被宣告,另一个区域没有对应的Type 3。
第二种可能:汇总导致的黑洞。ABR上做了区域汇总,明细被抑制,区域内部某个子网断了,汇总路由还在,流量被引到ABR后无处可去。这类问题的特征是“大网段通、小网段不通”,用traceroute看断在哪一跳就能定位。
第三种可能:路由过滤或者策略路由。有些环境为了控制流量走向,在ABR或者ASBR上做了filter,把某些明细路由过滤掉了。display ospf lsdb能看到LSA在,但路由表里没有,说明被过滤了,去查filter配置。
第四种可能:非对称路径引发的问题。来回路径不一致本身不是错,但如果路径上有一台设备没跑相应的协议、或者有状态防火墙只认单向会话,业务就断了。抓包看请求和响应分别走哪条路,是唯一的确认方法。
5.3 收敛慢、路由抖动怎么优化
OSPF默认的SPF计算有节流机制:收到拓扑变化后先等5秒再算第一次,之后间隔递增,最长10秒算一次。这个设计是为了防止频繁变化打爆CPU,但代价是收敛变慢。对延迟敏感的业务,可以调小这些值,但别调得太激进,否则一次大规模抖动就能让CPU过载。
真正有效的优化是这么几条。启用BFD:OSPF自己的Hello/Dead是秒级的,故障感知慢。BFD能把检测时间压到毫秒级(比如50毫秒发一次、连续3次收不到判定故障),故障一发生立刻通知OSPF,收敛时间从几十秒降到亚秒级。这是目前性价比最高的优化手段。接口开阻尼:链路上如果有周期性闪断(比如光模块老化),路由会反复撤销又加回,引发全网SPF。接口阻尼能在一定时间内抑制频繁变化的链路,代价是这段时间内该链路不可用,属于用可用性换网络整体的平稳。控制LSA泛洪范围:把不稳定的网段放进单独的区域(比如Stub区域或者NSSA),外部路由变化就不会扩散到全网。部分路由计算:Type 3和Type 5的LSA变化时,设备其实不需要重跑整棵SPF树,部分实现支持只重算受影响的部分,这个特性默认一般开着,但如果设备型号较老要确认一下。
5.4 常见问题速查表
| 现象 | 最可能原因 | 快速验证方法 | 处理动作 |
|---|---|---|---|
| 邻居看不见 | 二层不通或组播被过滤 | 抓包看224.0.0.5 | 查VLAN、ACL、端口隔离 |
| 邻居停Init | 单向可达或Router ID冲突 | 看对端邻居列表有没有自己 | 查反向ACL、改Router ID |
| 邻居停ExStart | MTU不一致 | 不分片ping大包测试 | 两端MTU统一 |
| 邻居反复Up/Down | Hello/Dead间隔不一致或链路抖动 | 看日志时间戳 | 定时器统一、查物理层 |
| 路由有但不通 | 单向路由、汇总黑洞、过滤 | 两端对比路由表+traceroute | 查Type 3、查filter |
| 收敛慢 | 未启用BFD、SPF节流 | 断开链路计时看恢复时间 | 上BFD、调节流参数 |
| 高带宽链路未分担 | 参考带宽未调整、cost都是1 | 看接口cost值 | 调参考带宽或手工cost |
| DR角色漂移 | 优先级配置不当、非抢占特性 | 看DR/BDR列表 | 核心设备固定高优先级 |
最后分享一个自己常用的排查习惯:任何OSPF相关问题,先敲三条命令建立基线——看邻居状态、看LSDB里各类LSA的数量、看路由表里目标网段的具体条目。这三条输出一摆出来,问题范围基本就缩小到一两个方向了,比在配置文件里翻来翻去快得多。另外,调试开关(debug)能不开就不开,开了务必配ACL限制只抓关心的邻居,否则日志刷屏本身就能把设备拖垮。这个亏我在早期踩过不止一次,凌晨在机房里看着终端疯狂滚屏却停不下来的滋味,真不想再体验第二回。