1. 为什么邻居和邻接这两个词值得单独拎出来讲刚接触OSPF的人十有八九会在“邻居”和“邻接”这两个词上栽跟头。书上看一遍觉得懂了抓包一看Hello包满天飞状态机从Down一路跳到Full又觉得好像没那么简单。我见过不少做了几年网络的同行排障时依然会把“邻居卡在ExStart”和“邻接建立失败”混为一谈结果方向跑偏浪费大半天。这篇内容就是冲着这个痛点来的。OSPF里的邻居Neighbor和邻接Adjacency不是同义词它们描述的是两个不同阶段、不同深度的关系。邻居是“能聊上话”邻接是“聊透了、能交换完整路由信息”。搞不清这个区别你就没法理解为什么广播网络里非DR/BDR之间只停在2-Way也没法解释为什么点对点链路一上来就奔着Full去。适合谁看正在备考网络认证的、刚上手配置OSPF的、以及排障时被状态机卡住的老手都能从这篇里拿到能直接用的东西。我会把状态机逐层拆开把邻居到邻接的跃迁条件讲透再配上实际环境里的抓包现象和排障思路。不堆术语讲人话重点放在“为什么这么设计”和“出问题了怎么查”。2. 邻居与邻接的核心概念拆解2.1 邻居关系的本质能收到对方的Hello邻居关系是OSPF里最基础的一层关系。两台路由器接口启用了OSPF并且接口处于同一网段、Area ID一致、Hello/Dead计时器匹配、认证通过、MTU在特定阶段检查没问题它们就能互相收到对方的Hello包从而进入邻居关系。这个阶段的核心动作只有一个周期性发送Hello包确认对方还活着。Hello包默认在广播网络里每10秒发一次Dead时间是40秒在NBMA和点对多点网络里Hello是30秒Dead是120秒。只要在Dead时间内收到对方的Hello邻居关系就维持着。但注意邻居关系建立起来不代表能交换路由。你可以把邻居理解成“点头之交”——知道有这么个人见面打个招呼但还没到交换核心信息的程度。在广播网络中非DR/BDR路由器之间就停在这个阶段状态显示为2-Way。这不是故障是正常设计。2.2 邻接关系的本质能交换LSA邻接关系是在邻居关系基础上更进一步。两台路由器不仅要能收Hello还要完成数据库描述DBD交换、链路状态请求LSR、链路状态更新LSU、链路状态确认LSAck这一整套流程最终达到链路状态数据库同步状态机走到Full。只有建立了邻接关系的路由器之间才会互相泛洪LSA才会把对方通告的路由算进SPF树。换句话说邻接是“能一起算路”的关系。那为什么不让所有邻居都变成邻接因为广播网络里路由器多了如果两两都建邻接LSA泛洪会变成N的平方级别开销爆炸。所以OSPF在广播和NBMA网络里引入DR/BDR机制让所有路由器只和DR/BDR建邻接DR/BDR之间也建邻接非DR/BDR之间只保持2-Way邻居关系。这样邻接数量从N*(N-1)/2降到2N-3左右泛洪效率大幅提升。2.3 一张表看清邻居和邻接的区别对比维度邻居关系邻接关系核心标志能互相收到Hello链路状态数据库同步完成状态机终点2-WayFull是否交换LSA否是是否参与SPF计算否是广播网络中的范围所有同网段OSPF路由器仅DR/BDR与其他路由器之间点对点网络中的范围两端路由器两端路由器邻居即邻接建立前提Hello参数匹配邻居关系 主从协商 DBD/LSR/LSU/LSAck完成这张表建议存下来排障时对着看能快速判断问题出在哪一层。3. OSPF状态机逐层拆解从Down到Full到底发生了什么3.1 Down与Attempt还没聊上的阶段Down状态是状态机的起点表示还没从对方收到任何Hello。在NBMA网络里如果配置了邻居但还没收到Hello会进入Attempt状态这个状态只在NBMA里出现表示主动尝试联系对方但还没成功。广播和点对点网络里没有Attempt直接从Down跳到Init。这里有个实操细节如果你在广播网络里看到邻居一直卡在Down先查物理层和二层——接口up没up、VLAN通不通、ACL有没有挡掉组播。OSPF的Hello包目的地址是224.0.0.5AllSPFRouters如果ACL把组播挡了Hello根本到不了对方状态机永远起不来。3.2 Init单向通信的尴尬Init状态表示从对方收到了Hello但对方的Hello里没有列出自己的Router ID。这说明什么说明你能听到对方说话但对方没听到你说话或者对方听到了但还没把你加进邻居列表。单向通信是Init状态的典型特征。常见原因有几个一是单向链路比如光纤收发对调了二是ACL只放行了一个方向三是组播问题一边能发组播一边收不到四是认证配置一边有一边没有对方收到你的Hello但因为认证失败丢弃了自然不会把你列进邻居列表。我踩过的一个坑某次在交换机上配了端口镜像结果镜像口把OSPF的Hello包也镜像走了导致一边收不到Hello状态卡在Init。这种问题抓包一看就明白——一边有Hello发出另一边没有回应。3.3 2-Way邻居关系达成的标志当双方互相在Hello包里看到自己的Router ID状态机进入2-Way。这是邻居关系正式建立的标志。在广播网络里2-Way之后会进行DR/BDR选举。如果路由器不是DR也不是BDR且它和另一个非DR/BDR路由器之间的状态就停在2-Way不会继续往下走。这是正常的不是故障。但如果你发现两台路由器应该建邻接却卡在2-Way就要查DR/BDR选举。常见原因接口优先级都是0导致没有DR/BDR或者DR/BDR选举被干预了比如优先级配置不一致导致预期外的路由器当了DR。提示在广播网络里排障时先看DR/BDR是谁再看谁和谁应该建邻接。非DR/BDR之间卡2-Way是正常的别浪费时间。3.4 ExStart主从协商的暗战ExStart状态是邻接关系建立的第一个阶段核心任务是协商主从关系。双方通过交换DBD包比较Router IDRouter ID大的成为Master小的成为Slave。Master负责控制DBD交换的序列号Slave只能回应。为什么要有主从因为DBD交换需要可靠的传输机制需要一个序列号来保证顺序和确认。如果没有主从双方都发DBD序列号冲突数据库描述就乱了。ExStart卡住是排障中的高频问题。最常见的原因是MTU不匹配。OSPF在DBD包里会携带接口MTU如果两端MTU不一致DBD交换会失败状态机卡在ExStart或ExChange。华为设备默认会检查MTU思科设备默认不检查但可以开启。我遇到过好几次因为一端是1500一端是9000导致卡ExStart的案例改一致后立马跳到Full。另一个原因是Router ID冲突。如果两台路由器Router ID一样主从协商会出问题。Router ID冲突在OSPF里是严重问题必须改掉。3.5 Exchange数据库描述包的互换ExStart协商完主从后进入Exchange状态双方开始互相发送DBD包描述自己的链路状态数据库摘要。DBD包里包含LSA的头部信息——类型、Link State ID、Advertising Router、序列号但不包含完整LSA内容。这个阶段的核心是比对数据库。双方通过DBD交换知道对方有哪些LSA、自己有哪些LSA然后决定需要请求哪些缺失的LSA。Exchange卡住的常见原因MTU不匹配和ExStart一样、DBD包被丢弃、序列号异常。抓包时如果看到DBD包重传基本就是MTU或序列号问题。3.6 Loading请求缺失的LSAExchange完成后进入Loading状态路由器根据DBD比对结果向对方发送LSR链路状态请求请求自己缺失的LSA。对方收到LSR后用LSU链路状态更新回应把完整LSA发过来。收到LSU的一方要发LSAck确认。Loading状态卡住通常是LSR/LSU/LSAck交互出了问题。常见原因LSA被过滤、MTU问题导致LSU分片丢弃、单向通信。如果看到LSR反复重传但收不到LSU查ACL和MTU。3.7 Full邻接关系建立的终点当所有缺失的LSA都请求到、数据库同步完成状态机进入Full。此时两台路由器建立了完整的邻接关系可以互相泛洪LSA参与SPF计算。Full是OSPF邻接关系的最终状态也是我们最希望看到的状态。但要注意Full不代表路由一定正确——如果LSA内容有问题、区域配置错误、SPF计算出问题即使邻居是Full路由也可能不对。所以排障时不能只看邻居状态还要看路由表和LSDB。4. 不同网络类型下的邻居与邻接行为差异4.1 广播网络DR/BDR机制下的邻接关系广播网络如以太网是OSPF最常见的场景。在这种网络里所有路由器通过组播Hello发现邻居然后进行DR/BDR选举。DR指定路由器和BDR备份指定路由器负责与所有其他路由器建立邻接关系非DR/BDR之间只保持2-Way邻居关系。DR/BDR选举规则先比接口优先级优先级高的当DR优先级相同比Router ID大的当DR。优先级范围0-255默认1优先级0表示不参与选举。BDR是优先级第二高的DR挂了BDR顶上。这里有个容易混淆的点DR/BDR选举是非抢占的。也就是说如果DR已经选出来了后来了一台优先级更高的路由器它不会抢走DR角色除非DR失效或重启OSPF进程。这个设计是为了避免网络震荡。实操中如果你想让某台路由器当DR除了配高优先级还要确保它在其他路由器之前启动OSPF或者重启OSPF进程触发重新选举。4.2 点对点网络邻居即邻接点对点网络如PPP、HDLC、点对点以太网里没有DR/BDR选举两端路由器直接建立邻接关系。邻居关系建立后状态机一路走到Full没有2-Way停留。点对点网络的好处是简单、收敛快。但要注意如果接口类型配置错误比如把广播网络配成了点对点或者反过来会导致邻居关系异常。我见过把以太网接口配成点对点但两端配置不一致的情况一端发组播Hello一端发单播邻居根本建不起来。4.3 NBMA与点对多点手动指定邻居的坑NBMA非广播多路访问网络如帧中继、ATM不支持组播和广播需要手动指定邻居。在NBMA里DR/BDR选举是必须的但邻居需要手动配置。点对多点网络可以看作多个点对点链路的集合不需要DR/BDR但需要手动指定邻居或使用组播如果底层支持。这两种网络类型在现代网络里越来越少见了但在一些传统行业网络里还能碰到。配置时最容易踩的坑是邻居指定不全或网络类型不匹配。比如一端配了NBMA一端配了广播Hello发送方式不同邻居建不起来。5. 实操排障邻居卡在某个状态怎么办5.1 排障前的信息收集清单遇到OSPF邻居问题别急着改配置先把信息收集全。我习惯按这个顺序查show ip ospf neighbor看邻居状态和状态持续时间show ip ospf interface看接口的OSPF参数——区域、网络类型、Hello/Dead计时器、认证、MTUshow ip ospf看Router ID、进程信息show run interface看接口配置抓包看Hello/DBD/LSR/LSU交互这五步走完基本能定位到问题在哪一层。5.2 常见卡状态原因速查表卡住状态最可能原因排查方法解决方式Down物理层/二层不通、ACL挡组播查接口状态、VLAN、ACL修复链路、放行224.0.0.5Init单向通信、认证不一致抓包看双向Hello、查认证配置修复单向链路、统一认证2-WayDR/BDR选举问题、优先级全0查DR/BDR、查接口优先级调整优先级、确保有DRExStartMTU不匹配、Router ID冲突查接口MTU、查Router ID统一MTU、改Router IDExchangeMTU不匹配、DBD丢弃抓包看DBD重传统一MTU、查ACLLoadingLSA过滤、LSU分片丢弃抓包看LSR/LSU查ACL、统一MTU5.3 三个真实排障案例复盘案例一MTU不匹配导致卡ExStart。某次割接后两台核心交换机OSPF邻居卡在ExStart。查配置发现一端接口MTU是1500另一端是9000。改一致后邻居立马跳到Full。这个问题的隐蔽性在于ping大包可能通但OSPF的DBD包因为携带MTU字段被对方拒绝。案例二认证不一致导致卡Init。一端配了MD5认证另一端没配。没配的一端能收到Hello但认证失败丢弃所以不会把对方列进邻居列表。配认证的一端收不到有效Hello状态卡Init。统一认证后解决。案例三DR优先级全0导致卡2-Way。广播网络里所有路由器接口优先级都配了0导致没有DR/BDR所有路由器都停在2-Way。把其中两台优先级改成1后DR/BDR选出来邻接建立。5.4 抓包分析的关键看点抓包是排障的终极手段。看OSPF抓包时重点看这几个Hello包的Neighbor List字段如果对方Hello里没有你的Router ID说明对方没收到你的Hello或认证失败DBD包的MTU字段两端MTU是否一致DBD包的Master/Slave字段主从协商是否正常LSR/LSU的交互是否有请求没回应Wireshark里过滤ospf就能看到所有OSPF包。如果看到Hello包正常但DBD包重传基本就是MTU或序列号问题。6. 邻居与邻接关系的优化与设计建议6.1 广播网络里如何控制DR/BDR控制DR/BDR是广播网络OSPF设计的关键。我的建议是明确指定DR和BDR不要让选举随机发生。具体做法是给期望当DR的路由器配高优先级比如100期望当BDR的配次高比如50其他路由器配0不参与选举。这样设计的好处是DR/BDR稳定不会因为某台路由器重启导致角色切换。角色切换会引起LSA重新泛洪网络震荡。另外DR/BDR应该选性能好、稳定性高的设备。DR要负责与所有路由器建邻接、泛洪LSA负担比普通路由器重。6.2 点对点网络里的邻接优化点对点网络里没有DR/BDR邻居即邻接相对简单。但有几个优化点如果链路稳定可以适当调大Hello/Dead计时器减少Hello包开销如果链路质量差调小Hello/Dead计时器加快收敛确保两端网络类型一致避免一端点对点一端广播点对点网络里还可以启用OSPF的快速收敛特性比如BFD联动链路故障时毫秒级切换。6.3 大规模网络里的邻接数量控制大规模广播网络里邻接数量是设计重点。假设一个广播域有N台路由器DR/BDR机制下邻接数量是2N-3。如果N50邻接数量约97每台路由器要维护97个邻接LSDB同步开销很大。控制方法划分更小的广播域用VLAN隔离或者把网络类型改成点对点如果拓扑允许或者用OSPF的区域划分把大网络拆成多个区域。我个人的经验是单个广播域里的OSPF路由器不要超过20台超过就考虑拆分。邻接数量太多会导致SPF计算频繁、LSDB过大、收敛变慢。6.4 邻居关系监控与告警生产环境里OSPF邻居关系要监控。重点监控邻居状态是否Full非DR/BDR之间的2-Way是正常的邻居状态变化频率频繁翻转说明链路或配置有问题LSDB大小和LSA数量突增说明网络异常可以用SNMP采集OSPF邻居状态或者用脚本定期执行show ip ospf neighbor解析结果。告警阈值建议邻居非Full持续超过1分钟就告警邻居翻转超过3次/小时就告警。7. 几个容易被忽略的细节和我的实操心得7.1 Router ID冲突的隐蔽性Router ID冲突在OSPF里是严重问题但表现可能很隐蔽。两台Router ID相同的路由器不会建立邻接状态可能卡在ExStart或Exchange。更麻烦的是如果冲突发生在不同区域可能只影响部分路由。排查Router ID冲突的方法show ip ospf看自己的Router IDshow ip ospf neighbor看邻居的Router ID如果发现邻居Router ID和自己一样就是冲突了。解决方法是改Router ID然后重启OSPF进程。建议在规划阶段就统一分配Router ID用Loopback接口地址作为Router ID确保唯一性。7.2 认证配置的坑OSPF认证有三种空认证、明文认证、MD5认证。配置时最容易踩的坑是两端认证类型或密钥不一致。一端MD5一端明文或者密钥一个字母大小写不同都会导致Hello被丢弃邻居建不起来。我的习惯是配置认证时先在一端配好抓包确认Hello里带了认证字段再在另一端配相同的认证。配完立即show ip ospf neighbor确认状态。另外认证是在接口下配置的不是进程下。ip ospf authentication message-digest和ip ospf message-digest-key 1 md5 password要配对使用。7.3 网络类型不匹配的排查网络类型不匹配是邻居建立失败的常见原因。一端广播一端点对点Hello发送方式不同组播vs单播邻居根本建不起来。排查时用show ip ospf interface看两端的网络类型确保一致。如果拓扑允许我倾向于把以太网接口配成点对点ip ospf network point-to-point这样可以跳过DR/BDR选举收敛更快邻接关系更简单。但要注意点对点网络里两端必须在同一网段且不能有第三台路由器。7.4 我的实操心得汇总最后分享几条我踩坑总结的经验改OSPF配置前先备份尤其是Router ID和网络类型改错了影响面很大排障时先看邻居状态再看LSDB最后看路由表从下往上查效率高抓包是最可靠的排障手段别猜直接看包MTU问题在OSPF里很常见统一MTU能避免很多莫名其妙的卡状态DR/BDR选举非抢占想让某台设备当DR要么重启OSPF进程要么等DR失效邻居Full不代表路由正确还要查LSDB和SPF计算结果这些经验在书本上不一定能看到但实际工作中非常有用。OSPF的邻居和邻接关系是理解OSPF运行机制的基础把这块搞透了排障时就能快速定位问题不会在错误的方向上浪费时间。