上一篇VLAN 笔记停在二层:广播域被切开了,但 VLAN 之间还是不通。要通,就得靠三层;要在三层上跑起来,就得先让路由器互相"认识"。这篇整理的是 OSPF 邻居建立——它到底用几种报文把关系谈下来的,中间会经过哪几个状态,以及广播网段上那个绕不开的 DR/BDR 是怎么来的。
先把结论放这儿:OSPF 不是一上来就交换路由的。它先交换"我认识谁",再交换"我知道什么",最后才各自算路。邻居没起来,一切白搭——这也是现场排障第一个要看的地方。
OSPF 是个什么样的协议
- 链路状态(Link-State)路由协议,基于 SPF(Shortest Path First,最短路径优先)算法,也就是 Dijkstra 算法;
- 路由器之间交换的是 LSA(链路状态通告),不是路由条目。每个人手里攒出一张完整的"地图"(LSDB,链路状态数据库),然后各自算路;
- 触发式更新:拓扑一变立刻泛洪;同时每 30 分钟做一次定期更新兜底;
- 支持 VLSM / CIDR,是无类路由协议;
- 支持区域划分,天生为大网络设计;
- 版本:OSPFv2(IPv4,RFC 2328)与 OSPFv3(IPv6,RFC 2740)。
和距离矢量的邻居(RIP、EIGRP 里的"道听途说")比,链路状态的思路更像"人手一份地图":我不知道你听谁说的,我只认地图。
距离矢量(Distance Vector) 链路状态(Link-State)
────────────────────────── ──────────────────────────
只知道自己有哪些邻居 知道整个区域的拓扑
互相通告"我这条路多远" 互相通告"我连着谁"
类似路牌,道听途说 类似地图,自己算路
RIP / EIGRP OSPF / IS-IS
五种报文,各干各的
OSPF 的所有工作都装在 IP 报文里直接承载(IP 协议号 89),没有 TCP/UDP 那一层。一共五种:
| 类型 | 名称 | 干什么用 |
|---|---|---|
| 1 | Hello | 发现、建立、维护邻居;广播网段上还负责 DR/BDR 选举 |
| 2 | DD / DBD | Database Description,描述本地 LSDB 的摘要(只有 LSA 头部) |
| 3 | LSR | Link-State Request,向邻居索要自己没有的那几条 LSA |
| 4 | LSU | Link-State Update,把完整的 LSA 送过去(泛洪就靠它) |
| 5 | LSAck | Link-State Acknowledgment,确认"收到了",保证可靠传输 |
把这五种串起来看,邻居建立的过程就是一个"先握手、再对目录、后补书"的过程:
Hello 报文里装了什么
Hello 是最不起眼、但最关键的一个。它的字段决定了"能不能成为邻居":
┌──────────────────────────────────────────────────────┐
│ 版本 │ 类型(=1) │ 报文长度 │ Router ID │
├──────────────────────────────────────────────────────┤
│ Area ID │ 校验和 │ 认证类型 │ 认证 │
├──────────────────────────────────────────────────────┤
│ 网络掩码 │ Hello 间隔 │ 选项 │ 优先级 │ Dead 间隔 │
├──────────────────────────────────────────────────────┤
│ DR │ BDR │ 邻居列表 │
└──────────────────────────────────────────────────────┘
| 字段 | 作用 | 两端必须一致? |
|---|---|---|
| Router ID | 路由器的唯一标识 | 不能冲突 |
| Area ID | 所在区域 | 必须一致 |
| 认证类型 / 认证 | 防伪造,支持明文、MD5、HMAC-SHA | 必须一致 |
| 网络掩码 | 接口掩码(MA 网络才校验) | 必须一致 |
| Hello 间隔 | 默认 10s(广播 / P2P),NBMA 30s | 必须一致 |
| Dead 间隔 | 默认 4 × Hello = 40s,超时就拆邻居 | 必须一致 |
| 优先级 | DR/BDR 选举用,默认 1,0 表示不参选 | 不必一致 |
| DR / BDR | 本网段选举结果 | 不必一致 |
| 邻居列表 | 本接口已经看到的所有邻居 Router ID | — |
记住一个现场经验:只要 Hello 里"该一致的"有一项不一致,邻居就永远停在某个中间状态,而且不报错。这也是 OSPF 排障比 BGP 更依赖抓包的原因。
邻居(Neighbor)不等于邻接(Adjacency)
这是最容易混的一对概念:
- 邻居关系:Hello 互相看到了,状态到 2-Way 就算建立;
- 邻接关系:LSDB 同步完成,状态到 Full 才算建立。
广播网段上,只有 DR/BDR 之间、以及 DROther 与 DR/BDR 之间才会走到 Full;两台 DROther 之间永远停在 2-Way——这是正常现象,不是故障。
七个状态,一步步爬到 Full
邻居状态机是 OSPF 排障的"路标":看到卡在哪一格,基本就知道问题在哪一类。
| 状态 | 含义 | 触发事件 |
|---|---|---|
| Down | 初始状态,一个 Hello 都没收到 | — |
| Init | 收到 Hello 了,但对方邻居列表里没有我(单向) | HelloReceived |
| 2-Way | 收到 Hello 且列表里有我,邻居关系建立 | 2-WayReceived |
| ExStart | 协商主从:Router ID 大的是 Master,决定 DBD 序号 | 决定建立邻接 |
| Exchange | 互发 DBD,交换 LSDB 的目录摘要 | NegotiationDone |
| Loading | 用 LSR 索要缺失的 LSA,对方用 LSU 送来 | ExchangeDone |
| Full | LSDB 完全同步,邻接关系建立 | LoadingDone |
卡住了怎么看
| 卡在 | 大概率原因 |
|---|---|
| 一直 Down | Router ID 冲突、Area ID 不一致、认证不一致、Hello/Dead 间隔不一致、二层不通 |
| Init | 单向可达——回程路由不通、组播被过滤、认证只配了一端 |
| ExStart | 经典原因:两端接口 MTU 不一致(DBD 里带 MTU 字段,大的等小的) |
| Exchange / Loading | LSA 一直收不全——MTU、泛洪被拦、LSDB 里有过期 LSA |
| 2-Way | 广播网段上两台 DROther 之间属正常;P2P 网络上卡 2-Way 才是不正常 |
DR / BDR:广播网段上的"班长"
广播网段(比如一个以太网 VLAN)上如果挂 5 台路由器,全互联需要 5×4÷2 = 10 条邻接;挂 20 台就是 190 条。LSDB 同步和泛洪的开销会爆炸。
OSPF 的解法是选一个"班长":每台路由器只和 DR(指定路由器)、BDR(备份指定路由器)建立邻接,其余路由器之间只停在 2-Way。这样邻接数从 O(N²) 降到 O(N)。
选举规则
- 先比接口的 DR 优先级(默认 1),大者胜;优先级为 0 表示不参与选举;
- 优先级相同时比 Router ID,大者胜;
- 先选出 DR,再在剩下的里面选 BDR。
两个容易踩的点:
- 选举是"非抢占"的:DR 一旦选出,后面再进来一台优先级更高的路由器,也不会把 DR 抢走——除非 DR 失效,或重启 OSPF 进程;
- DR/BDR 是接口级的概念,同一台路由器在不同网段上的角色可以不同。
两个组播地址
224.0.0.5 AllSPFRouters 所有运行 OSPF 的路由器都监听(Hello 默认发这里)
224.0.0.6 AllDRouters 只有 DR / BDR 监听(DROther 用它上报给 DR)
路由器在这个区域里是什么角色
| 类型 | 英文 | 判定条件 |
|---|---|---|
| 内部路由器 | Internal Router | 所有接口都属于同一个区域 |
| 骨干路由器 | Backbone Router | 至少有一个接口在骨干区域 Area 0 |
| 区域边界路由器 | ABR | 连接多个区域到骨干区域,至少一个接口在 Area 0 |
| 自治系统边界路由器 | ASBR | 执行了路由引入,连接 OSPF 域与其他协议域 |
一台路由器可以同时是 ABR 和 ASBR。
为什么要划区域
网络一大,LSDB 就大,SPF 计算就重。OSPF 用区域(Area)把大网切开:
- 每个 OSPF 路由器只维护自己所在区域的完整链路状态信息;
- Area 0 是骨干区域,其他区域原则上必须直接挂在 Area 0 上;
- 区域用区域号标识,可以写成十进制整数,也可以写成 IP 形式(Area 0 = Area 0.0.0.0)。
好处是三条:LSDB 变小、SPF 计算变少、故障域被限制在区域内。
配置:华为与思科对照
两台路由器 R1(1.1.1.1)和 R2(2.2.2.2)直连在 192.168.1.0/24,跑 Area 0:
# 全局启用 OSPF 进程,并指定 Router ID
ospf 1 router-id 1.1.1.1
area 0.0.0.0
network 192.168.1.0 0.0.0.255
interface GigabitEthernet0/0/1
ip address 192.168.1.1 255.255.255.0
ospf enable 1 area 0.0.0.0
# 调 DR 优先级(0 表示不参选)
ospf dr-priority 100
router ospf 1
router-id 1.1.1.1
network 192.168.1.0 0.0.0.255 area 0
! 调 DR 优先级
interface GigabitEthernet0/0
ip ospf priority 100
Router ID 的选取顺序:手动配置(推荐)→ 最大的 Loopback 接口 IP → 最大的物理接口 IP。Router ID 一旦选定,改了要重启 OSPF 进程才生效——所以生产环境一律手工指定。
验证与排错
display ospf peer brief # 邻居列表 + 当前状态
display ospf interface GigabitEthernet0/0/1 # 本接口的 Hello/Dead、DR/BDR
display ospf lsdb # 链路状态数据库
display ospf brief # 进程级信息:Router ID、区域、SPF 次数
display ospf error # 报文级错误计数(排错神器)
reset ospf process # 重启 OSPF 进程(会断邻居,慎用)
show ip ospf neighbor
show ip ospf interface
show ip ospf database
show ip ospf statistics
把上面两张表拼起来,现场排障就是一条链:先看状态卡在哪 → 再看是"参数不一致"还是"报文没到" → 不一致就对着 Hello 字段逐项比,没到就查二层和 ACL。
一句话总结:OSPF 建立邻居是"Hello 认识 → 2-Way 确立邻居 → 主从协商 → 对摘要 → 补 LSA → Full"这条链。广播网段上再叠一层 DR/BDR 选举,把 N² 条邻接压成 N 条。卡住的时候,状态机就是路标。
📌 本篇整理自 2026-09 的 OSPF 学习笔记(数通 / HCIE-Datacom 方向)
原始笔记是一份 700MB+ 的 OneNote 分区,内容以华为培训胶片和实验记录为主。
本文把其中"邻居建立"这一块抽出来重排了顺序:先讲协议定位,再讲报文,再讲状态机,最后讲 DR/BDR 和配置验证。
配置命令保留华为 VRP 原样,思科命令做对照。