
1. 先把OSPF放回它该在的位置它到底解决什么问题这份笔记最早是我给自己攒的起因很朴素一次割接前的晚上翻遍手头的资料发现讲OSPF的内容要么是RFC式的条文堆砌要么是配置手册式的命令罗列真正能让我在半小时内把“邻居为什么起不来”“路由为什么走歪了”这两件事想明白的东西几乎没有。于是我干脆按自己的理解重写了一遍把OSPF复习笔记做成了“能直接拿去排障”的版本。它讲的是OSPF这个链路状态路由协议的核心机制、区域设计逻辑、LSA体系以及在真实网络里怎么配、怎么验、怎么排。适合刚过完NA想往NP走的人也适合工作几年但一直靠“改改掩码、重启进程”混过来的朋友——如果你能独立把一个多区域OSPF从零配到收敛并且解释清楚每一条路由的来源那这份笔记你可以跳着看。1.1 链路状态和距离矢量的本质差别很多人背得出“OSPF是链路状态协议RIP是距离矢量协议”但说不出这个差别到底影响什么。我用一个类比距离矢量像村口问路你只问“去镇上多远”对方说“往前五公里”你就走至于前面是桥断了还是修路你完全不知道。链路状态则是每个人手里都有一张完整的地图谁家连着谁、路多宽、通不通全都画在图上然后自己算最短路。这个差别带来三个直接后果。第一距离矢量协议的路由是“邻居告诉我的”带毒化、水平分割这些防环手段链路状态协议每台路由器都独立跑SPF算法天然不会出现计数到无穷的问题。第二链路状态协议对拓扑变化反应更快——链路一断产生新的LSA泛洪出去所有路由器重算收敛时间通常在秒级距离矢量则要等邻居的更新周期。第三代价是资源每台路由器要维护LSDB链路状态数据库要跑Dijkstra区域大了CPU和内存都吃不消。这就是为什么OSPF必须分区域——不是设计上的花活是规模逼出来的必然选择。理解这一层后面所有“为什么要这样设计”的问题都有了根。比如为什么要有ABR、为什么Type 3 LSA要做汇总、为什么骨干区域必须连续本质上都是在回答同一个问题怎么在不牺牲链路状态优势的前提下把LSDB的规模压下来。1.2 什么规模、什么场景该上OSPF我见过不少把OSPF用在三台路由器的小网络里的情况也见过该用OSPF却硬上静态路由、最后靠文档维护的。判断标准其实不复杂路由器数量超过五六台且拓扑有冗余链路静态路由的维护成本会指数上升这时候OSPF的自动收敛价值就出来了。需要多厂商设备互通。OSPF是开放标准不同厂商设备跑在一起基本没问题这是它相对一些私有协议的最大优势。网络需要分层。接入、汇聚、核心三层结构里OSPF的区域天然对应层级汇聚层做ABR核心跑Area 0边界清晰。反过来出口只有一两条线路、内网是树形结构的小网络静态路由加一条浮动默认路由就够了上OSPF纯属给自己找事。还有一个容易忽略的点OSPF是IGP它的职责是把网络内部的路由打通不是拿来扛几十万条外部路由的。如果网络里有大量外部路由需要引入要么做汇总要么考虑用BGP。我踩过一次坑某分支机构把几百条明细路由通过Type 5灌进OSPF结果整个区域的LSDB膨胀SPF重算频率明显上升后来在ASBR上做了汇总才压下去。2. 五个报文、七种状态邻居关系是怎么一步步建立的OSPF的邻居建立过程是我认为最值得反复看的部分因为它几乎覆盖了八成的现场故障。你把五个报文和七种状态吃透排障时基本就是“对着状态找原因”而不是瞎猜。2.1 Hello报文里那些字段在协商什么Hello报文是OSPF里唯一周期性发送的报文默认广播网络10秒一次它承担的不只是“我还活着”的功能更重要的是参数协商。两台路由器要成为邻居Hello里的这些字段必须一致字段作用不一致的后果Area ID标识所属区域直接丢弃邻居起不来Hello Interval发送周期丢弃且不会进入InitDead Interval判定邻居失效的时间丢弃通常默认是Hello的4倍认证类型与密钥安全校验认证失败邻居无法建立网络掩码广播网络类型下校验掩码不一致无法建立邻接Options字段E-bit、N-bit标识区域类型能力特殊区域与普通区域混配时直接不兼容其中Dead Interval默认是Hello Interval的4倍广播网10秒/40秒NBMA和P2MP是30秒/120秒。这个4倍关系不是随便定的是留出三次丢包的容忍度。我有一次现场遇到邻居反复Up/Down最后发现是一端被人手动改成了Hello 20、Dead 80另一端还是默认值Hello能收到但因为Dead时间对不上邻居列表始终建立不起来display ospf peer里连Init都不显示很容易被误判成物理链路问题。还要注意Options字段里的两个标志位E-bit表示该区域是否允许泛洪Type 5 LSAN-bit表示是否为NSSA区域。普通区域和Stub区域对接、普通区域和NSSA对接都会因为这两个位不一致而无法建立邻居日志里通常报“option mismatch”。这个点在配特殊区域时特别容易踩一端配了Stub另一端忘了配邻居直接卡死。2.2 状态机七个阶段和三个最容易卡住的地方完整的邻居状态是Down→Init→2-Way→ExStart→Exchange→Loading→FullNBMA网络还会多一个Attempt状态。实际排障时你只需要盯住三个关键位置第一处是2-Way。收到对方的Hello、且对方Hello的邻居列表里也有自己的Router ID才进入2-Way。卡在Init说明单向通信——你能收到它的Hello它收不到你的。常见原因是ACL把组播地址224.0.0.5或224.0.0.6挡了、单向链路、或者一端接口被shutdown了一半。我遇到过一次是中间传输设备做了组播抑制单播能通、组播不通现象就是永远Init。第二处是ExStart。这个阶段要选主从比较的是Router ID大的当Master然后开始交换DBD。卡在ExStart最常见的原因是MTU不一致——两端接口MTU不同DBD报文大小对不上就一直重传。接口下敲ospf mtu-ignore能绕过但这是掩盖问题不是解决问题正确做法是两边MTU对齐。第三处是Exchange到Loading。这个阶段在交换LSA摘要Loading是根据摘要发LSR请求具体LSA。如果卡在Exchange通常是LSA的序列号或者校验和出问题如果卡在Loading一般是LSR发了但LSU回不来查一下是不是有LSA过滤或者MTU导致大包丢弃。实操心得排邻居问题我的顺序永远是“先看状态卡在哪再对着该阶段的协商字段逐项比对”。状态机本身就是一张诊断表比漫无目的地抓包高效得多。2.3 DR/BDR选举的两个规则和一个陷阱广播网络和NBMA网络里要选DR和BDR目的是减少邻接关系数量——n台路由器如果两两建邻接就是n(n-1)/2有了DR之后只需要2n-1条。选举规则不复杂先比接口优先级默认1范围0-2550表示不参与优先级高的当DR次高的当BDR优先级相同再比Router ID大的赢。但有一个陷阱必须记牢选举不抢占。也就是说DR选出来之后除非DR失效或者接口重置否则新加入一台优先级更高的路由器它也不会抢走DR的位置。这在割接时坑过我不止一次——我提前把新设备的优先级调到255以为它一上线就能接管结果它老老实实当了个DRother。想让它当DR要么重启OSPF进程要么把现有DR的接口shutdown再恢复逼一次重选。BDR的存在意义是备份DR挂了BDR立刻顶上不需要重新选举。所以规划时如果两台核心设备做双机建议一台优先级设高、一台设次高保证一台是DR一台是BDR不要两台都设成255或者都留默认否则谁当DR全看Router ID不受控。另外P2P和P2MP网络类型不选DR/BDR直接建邻接这点在配串口或者隧道时要清楚不然会对着display ospf peer里没有DR/BDR信息纳闷半天。3. LSA与区域信息是怎么被有选择地传播的如果说邻居建立是OSPF的“握手”那LSA和区域就是它的“信息传播规则”。这部分是复习的重点也是设计网络时的决策依据。3.1 六类LSA的分工与产生者OSPF靠LSA描述拓扑和路由常用的有六类类型名称产生者泛洪范围描述内容Type 1Router LSA每台路由器本区域内自己所有接口的链路状态和开销Type 2Network LSADR本区域内广播网段的子网掩码和连接的路由器Type 3Summary LSAABR跨区域把一个区域的网段摘要通告到其他区域Type 4ASBR Summary LSAABR跨区域告诉其他区域ASBR在哪Type 5AS External LSAASBR全AS除特殊区域外部引入的路由Type 7NSSA External LSANSSA内的ASBR仅本NSSA区域NSSA区域内的外部路由理解这张表的关键是抓住“谁产生、在哪泛洪、描述什么”三要素。Type 1是基础每台路由器都会产生描述自己的直连链路Type 2只有DR产生因为只有DR代表整个广播网段Type 3和Type 4是ABR的专利把区域内的信息翻译成摘要送到别的区域Type 5是ASBR的专利把OSPF域外的路由引进来Type 7是NSSA区域的特殊产物因为NSSA不允许Type 5进入就用Type 7在区域内先传着到了ABR再翻译成Type 5发出去。这里有个常被问到的点为什么需要Type 4因为其他区域的路由器看到Type 5的外部路由时只知道“这条外部路由存在”但不知道“去ASBR怎么走”。Type 4就是ABR帮ASBR打的广告告诉其他区域“ASBR在我这个方向上”。所以如果你在路由表里看到O E2路由但下一跳不可达往往是Type 4没生成或者被过滤了。3.2 特殊区域省资源还是留后路特殊区域的本质是“在LSDB规模和功能完整性之间做取舍”。常见的有四种Stub拒绝Type 5进入ABR自动下发一条Type 3的默认路由。适合末梢区域比如只有一个出口的分支机构反正出去只有一条路没必要知道外面的明细。Totally Stub在Stub基础上进一步拒绝Type 3只保留一条默认路由。LSDB最小但区域间路由全丢只剩默认。NSSA拒绝Type 5但允许Type 7区域内部可以有ASBR引入外部路由。适合那种自己有外部路由要引、又不想接收其他区域外部路由的场景。Totally NSSANSSA加上拒绝Type 3只保留默认路由和本区域的Type 7。选择逻辑很直白区域是不是末梢是的话考虑Stub区域里有没有需要引入外部路由的设备有的话就不能用Stub得用NSSA对LSDB精简要求极高、且不需要细粒度区域间路由就上Totally版本。我一般的做法是新建的分支机构区域如果只有一个出口且没有外部路由引入需求直接上Totally Stub效果最干净如果分支内部有防火墙或者第二条线路需要引入那就NSSA。配特殊区域最容易犯的错是“一端配了另一端没配”前面提过Options字段不一致邻居直接起不来。还有一个隐蔽的坑Stub区域的ABR会自动产生默认路由但如果这个ABR自己也配置了静态默认路由并通过default-route-advertise引入可能会产生两条默认路由要提前确认好哪条优先。3.3 汇总与虚链路的取舍汇总在OSPF里有两个层面区域间汇总在ABR上做把多条Type 3合成一条和外部路由汇总在ASBR上做把多条Type 5合成一条。做汇总的收益是LSDB变小、SPF计算量下降、拓扑震荡的影响范围收敛。代价是明细丢失如果汇总范围内有一条路由不可达流量还是会往汇总方向走可能造成黑洞。我的经验是汇总的掩码要尽量贴合实际地址规划。如果地址规划本身是连续的比如某区域用10.10.1.0/24到10.10.15.0/24那汇总成10.10.0.0/20很干净如果地址是东一块西一块凑出来的强行汇总就会把不属于该区域的地址也吃掉反而制造问题。所以汇总这件事七分靠规划三分靠配置。虚链路是另一个常被提起但很少该用的东西。它的作用有两个连接远离骨干区域的区域或者修补被分割的骨干区域。但虚链路本质是“用隧道把逻辑上的Area 0补起来”它带来的问题是路径不直观、故障域扩大、排障难度上升。我见过为了省事大量使用虚链路的网络出问题时根本看不出流量实际走的哪条路。能通过调整物理拓扑或者区域规划解决的就不要上虚链路。4. 动手搭一套能验证的实验环境看一百遍不如配一遍。这部分我按“能复现、能验证、能对比”的思路设计全部用通用命令描述不同设备平台的命令格式略有差异但思路一致。4.1 拓扑与地址、区域规划建议用四到五台路由器搭一个最小可验证环境R1在Area 0作为骨干R2同时连R1和R3作为ABR一边在Area 0一边在Area 1R3在Area 1作为区域内部路由器R4接在R3下面作为ASBR引入一条外部静态路由如果设备够再加一台R5和R3在同一个广播网段用来观察DR/BDR选举。地址规划上Area 0用10.0.0.0/24Area 1用10.0.1.0/24互联链路用10.0.12.0/30这种小网段。Router ID规划成1.1.1.1、2.2.2.2这样的回环地址方便记忆和排障。这里强调一下Router ID一定要手工指定不要依赖自动选举。自动选举取的是接口地址中最大的一个一旦接口变动或者顺序不同Router ID可能变化导致DR选举结果变化、邻居重建排查起来非常痛苦。4.2 基础配置到邻居Full以R2为例核心配置大致是这样interface Loopback0 ip address 2.2.2.2 255.255.255.255 interface GigabitEthernet0/0 ip address 10.0.0.2 255.255.255.0 interface GigabitEthernet0/1 ip address 10.0.1.1 255.255.255.0 router ospf 1 router-id 2.2.2.2 network 10.0.0.0 0.0.0.255 area 0 network 10.0.1.0 0.0.0.255 area 1 network 2.2.2.2 0.0.0.0 area 0配置完在每台设备上敲show ip ospf neighbor确认状态是FULL。如果只是2WAY说明对端是DRother在广播网络里DRother之间本来就不建Full邻接这是正常的不要误判成故障。验证邻居之后看LSDBshow ip ospf database确认Type 1和Type 2的数量符合预期。再看路由表show ip route ospfArea 0的设备应该能看到Area 1的网段并标记为O IA说明Type 3生效了。注意network命令里的掩码是反掩码写错一位就可能把接口划到错误的区域或者根本没启用OSPF。我见过把0.0.0.255写成0.0.0.0的结果只通告了接口地址所在的那一个/32其他网段全丢现象是邻居正常但路由不全。4.3 改Cost验证选路OSPF选路靠Cost默认公式是参考带宽除以接口带宽参考带宽默认100Mbps。这意味着百兆口Cost是1千兆口也是1——因为计算结果小于1时取1千兆口和百兆口在默认参考带宽下没有区别。这个设计在早年是合理的现在千兆、万兆遍地默认值明显不够用。改法是全局把参考带宽调大比如调到10000即10Gbps这样百兆口Cost是100千兆口是10万兆口是1区分度就出来了router ospf 1 auto-cost reference-bandwidth 10000注意这个值要在所有路由器上保持一致否则同一段链路两端算出来的Cost不同会导致非对称路由。改完之后用show ip ospf interface确认每台设备的接口Cost再show ip route看选路是否符合预期。验证选路最直接的办法是构造两条不等价路径比如R1到R3既有直连路径又有绕行R2的路径把直连路径的Cost调大观察路由是否切换到绕行路径。切换过程中用show ip ospf route和show ip route对照能看到SPF重算的过程这比看文档直观得多。4.4 Stub与NSSA的对比验证这一步是理解特殊区域最有效的方式。把Area 1先配成Stubrouter ospf 1 area 1 stub然后看R3的LSDBType 5的LSA应该全部消失路由表里多出一条O IA的默认路由指向R2。这说明ABR自动下发了默认路由。再把它改成Totally Stubrouter ospf 1 area 1 stub no-summary这次连Type 3也没了LSDB里只剩Type 1、Type 2和一条默认路由。对比两次的show ip ospf database输出能非常直观地看到“特殊区域砍掉了什么”。接着验证NSSA把Area 1改成NSSA在R3上引入一条外部静态路由router ospf 1 area 1 nssa redistribute static subnets这时候R3会产生Type 7的LSA在Area 1内部泛洪R2作为ABR收到Type 7后会做翻译转换成Type 5发到Area 0。用show ip ospf database nssa-external和show ip ospf database external分别看两边的LSA就能理解Type 7和Type 5的转换关系。这个实验我强烈建议每个学OSPF的人都亲手做一遍比背十遍概念都管用。5. 排障实录那些年卡过的邻居和走歪的路理论配完一遍真正的功夫在故障现场。下面这几个是我实际遇到过、也在别人那里反复见到的典型问题。5.1 邻居起不来从Hello字段逐项对邻居起不来的排查顺序我总结成一句话先看状态卡在哪再对着该阶段的协商字段逐项比对。如果状态一直停在Down说明Hello都没收到。查物理层、查接口是否加入OSPF、查area id是否配错、查ACL是否挡了224.0.0.5。用show ip ospf interface能看到接口是否启用了OSPF。如果停在Init说明能收到Hello但对方没看到自己。典型是单向通信或者组播被挡。这时候可以用debug ip ospf hello看收到的Hello里邻居列表有没有自己的Router ID。如果停在2-Way并且是点对点链路上说明有问题——点对点应该直接到Full。广播网络上停在2-Way则可能是正常的DRother关系。要区分这两种情况得看邻居的Role字段。如果停在ExStart先查MTU。show interface对比两端不一致就对齐。如果MTU一致还卡着检查Router ID是否冲突——两台设备Router ID相同会导致主从协商失败。如果停在Exchange或Loading重点查LSA过滤、区域类型不匹配、以及大包丢弃。我遇到过一次是中间设备做了分片限制DBD小包能过、大LSU过不去现象就是邻居停在Loading很久然后超时。5.2 Full了但不通LSA和路由表两层查邻居Full但业务不通问题通常在LSA层面或者路由计算层面。排查顺序是先看路由表有没有目的网段再看下一跳对不对最后看转发路径上有没有丢包。路由表里没有目的网段可能的原因有几类一是该网段所在的区域没有正确通告源路由器的network命令漏了二是区域间被过滤了ABR上做了filter或者在接口做了area range导致明细被吃掉三是特殊区域本来就不接收某类LSA比如Stub区域看不到外部路由。路由表里有但下一跳不对通常是汇总配置有问题或者存在多条等价路由导致负载分担不符合预期。OSPF默认支持等价负载均衡如果两条路径Cost相同流量会同时走两条这在某些场景下不是想要的可以通过调整Cost强制走主路径。还有一种情况是路由表正确但实际不通要查转发路径上的MTU和ACL。我遇到过一次路由表显示走R1但R1和R3之间的链路MTU被改小了大包被丢弃ping小包能通、业务报文不通非常隐蔽。5.3 速查表与几条踩坑经验现象高概率原因快速验证方式邻居一直Down接口未启用OSPF、area id错误、ACL挡组播show ip ospf interface邻居停在Init单向通信、组播被抑制debug ip ospf hello邻居停在ExStartMTU不一致、Router ID冲突对比两端接口MTU邻居停在LoadingLSA过滤、大包丢弃抓包看LSU是否回包邻居Full但路由缺失network漏配、区域过滤、特殊区域show ip ospf database路由震荡链路不稳定、LSA频繁刷新show ip ospf statistics默认路由异常Stub自动下发与静态引入冲突看路由来源标记几个不成文但我认为很重要的经验第一个是改配置前先备份LSDB。把show ip ospf database的完整输出存一份改完之后对比能快速看出哪些LSA变多、哪些消失比凭记忆判断准得多。第二个是特殊区域的配置永远成对改。一端改Stub另一端必须同时改不能分两次做。我曾经在割接窗口里分两步配中间那几分钟邻居全断虽然最终能恢复但过程中心跳加速的感觉不值当。第三个是汇总上线前先在测试环境验证。汇总最容易出的问题是掩码吃掉了不该吃的地址或者汇总后某条链路故障导致黑洞。上生产前先用几个明细路由验证一下汇总范围确认无误再推。第四个是Router ID一定要手工固定并且全网唯一。自动选举在业务稳定的网络里看似没问题但只要接入口一插一拔Router ID可能就变了SPF重算、DR重选、邻居重建全来一遍。手工固定一个回环地址作为Router ID是最省事也最稳的做法。这份笔记我陆陆续续改了好几版每次现场遇到新问题就补一条进去。OSPF的知识点看着多但真正决定你能不能解决问题的是几条邻居建立的条件、区域和LSA的分工、选路的Cost机制、以及特殊区域的取舍。把这四点串起来剩下的都是细节填充。