关键词:BGP、Open报文、Update报文、Keepalive、Notification、BGP消息、报文格式、错误码
第82篇:BGP 报文类型:Open、Update、Keepalive、Notification
一、引言
BGP 协议使用四种基本报文类型完成邻居建立、路由交换、会话维持和错误通知。这四种报文在 BGP 会话的不同阶段发挥各自的作用,共同构成了 BGP 协议的完整消息体系。
与 IGP 协议直接在二层封装不同,BGP 报文运行在 TCP 179 端口之上传输,由 BGP 自身定义应用层协议格式。理解 BGP 报文类型的结构和作用,是进行 BGP 故障排查和协议分析的基础。当 BGP 邻居无法建立或路由不传递时,分析报文交互往往是定位根因的最直接手段。
二、核心概念
2.1 BGP 报文总览
| 报文类型 | 代码 | 主要功能 | 发送时机 |
|---|---|---|---|
| Open | 1 | 建立 BGP 会话,协商参数 | TCP 连接建立后立即发送 |
| Update | 3 | 传递路由信息(新路由/撤销路由) | 路由变化时或初始交换 |
| Keepalive | 4 | 维持 BGP 会话活跃 | 定期发送(Hold Time/3) |
| Notification | 6 | 通知错误,关闭 BGP 会话 | 检测到错误时 |
注意:BGP 报文代码中没有使用 2 和 5。代码 2 保留给未来的使用,代码 5 曾被用于 Confirmed 报文(RFC 1771 中已废弃)。
2.2 BGP 报文通用头部
所有 BGP 报文共享相同的 19 字节基本头部格式:
| 字段 | 长度(字节) | 说明 |
|---|---|---|
| Marker | 16 | 同步字段,始终填充 0xFF;与 MD5 认证无关(MD5 使用 TCP Option 机制,RFC 2385) |
| Length | 2 | 报文总长度(含头部),最小 19 字节,最大 4096 字节 |
| Type | 1 | 报文类型:1=Open,3=Update,4=Keepalive,6=Notification |
Marker 字段的作用: - 同步机制:接收端通过检查 Marker 是否全部为 0xFF 来判断报文是否属于当前会话。会话重置时,发送端会发送一个全 0 的 Marker,对端收到后丢弃旧会话残留报文,实现同步。 - MD5 认证说明:BGP 的 MD5 认证(TCP MD5 Signature Option,RFC 2385)使用 TCP Option 机制实现,与 Marker 字段无关。Marker 字段始终填充 0xFF。
2.3 BGP 报文交互流程

三、技术细节
3.1 Open 报文
Open 报文是 BGP 会话建立的第一步,用于参数协商:
| 字段 | 长度(字节) | 说明 |
|---|---|---|
| Version | 1 | BGP 版本号,当前为 4(BGP-4,RFC 4271) |
| My AS | 2 | 本地 AS 号 |
| Hold Time | 2 | 希望的保持时间(秒),0 表示不使用 Keepalive |
| BGP Identifier | 4 | BGP Router ID,32位 IPv4 地址格式 |
| Optional Param Length | 1 | 可选参数总长度 |
| Optional Parameters | 可变 | 能力协商:多协议扩展(MP_CAPABILITY)、刷新能力(RESTART)等 |
关键协商参数:
- Version:双方必须使用相同版本(当前均为 4),否则发送 Notification 关闭会话
- My AS:告知对端自己的 AS 号。eBGP 会话中,对端检查 My AS 不等于自己的 AS;iBGP 会话中,对端检查 My AS 等于自己的 AS
- Hold Time:双方取较小的值作为最终 Hold Time。若一方发送 0,另一方也必须为 0,否则协商失败
- BGP Identifier:必须唯一。iBGP Peer 之间 Router ID 冲突会导致会话无法建立
常见可选参数(Capability):
| Capability Code | 名称 | RFC | 说明 |
|---|---|---|---|
| 1 | Multiprotocol Extensions | RFC 4271 | 支持 IPv6/VPNv4/VPNv6 等地址族 |
| 6 | Graceful Restart | RFC 4724 | 支持 GR(优雅重启动) |
| 4 | Route Refresh | RFC 2918 | 支持动态刷新路由 |
| 18 | Enhanced Route Refresh | RFC 7313 | 增强路由刷新 |
3.2 Update 报文
Update 报文是 BGP 中唯一携带路由信息的报文,也是 BGP 报文中最复杂的一种:
| 字段 | 长度(字节) | 说明 |
|---|---|---|
| Withdrawn Routes Length | 2 | 撤销路由的总长度 |
| Withdrawn Routes | 可变 | 撤销路由的前缀列表(仅 NLRI,不含属性) |
| Total Path Attribute Length | 2 | 路径属性总长度 |
| Path Attributes | 可变 | 路径属性列表 |
| Network Layer PI | 可变 | NLRI(新通告的路由前缀) |
Update 报文的三种情况:
| 情况 | Withdrawn Routes | Path Attributes | NLRI | 说明 |
|---|---|---|---|---|
| 通告新路由 | 空(长度=0) | 有 | 有 | 携带完整属性和前缀 |
| 撤销路由 | 有 | 空 | 空 | 仅携带要撤销的前缀 |
| 修改路由属性 | 先撤销原路由 再通告新路由 |
有 | 有 | 等价于"撤销+通告"两步 |
批量 Update 机制: - BGP 支持在一条 Update 报文中携带多个 NLRI(只要共享相同的路径属性) - 例如:从同一 AS 学到的多条路由可以合并为一条 Update 报文,显著减少报文数量 - 延迟通知(Delayed Open):BGP 在初始交换时会等待所有 IGP 路由收敛后再批量发送 Update
3.3 Keepalive 报文
Keepalive 报文非常简单,只包含 BGP 通用头部(Type=4),无任何额外内容:
| 特性 | 说明 |
|---|---|
| 长度 | 19 字节(仅头部) |
| 发送间隔 | Negotiated Hold Time / 3(默认 Hold Time 180 秒,间隔 60 秒) |
| 作用 | 维持 BGP 会话活跃,补充 TCP 保活机制 |
| 替代机制 | Update 报文也可以重置 Hold Timer |
为什么 BGP 需要应用层心跳: - TCP 的 Keepalive 默认关闭,且超时时间很长(通常 2 小时) - BGP 的 Hold Timer 提供了更快速的故障检测(默认 180 秒) - 在 TCP 连接仍然存活但对端 BGP 进程已崩溃的场景下,BGP Keepalive 能快速检测到异常
3.4 Notification 报文
Notification 报文用于通知对端错误并关闭 BGP 会话。发送 Notification 后,BGP 立即关闭 TCP 连接:
| 字段 | 长度(字节) | 说明 |
|---|---|---|
| Error Code | 1 | 错误类型(1-9) |
| Error Subcode | 1 | 错误子类型 |
| Data | 可变 | 错误详细信息(如出错的报文副本) |
常见错误类型:
| Error Code | 名称 | 常见 Subcode | 说明 |
|---|---|---|---|
| 1 | 报文头错误 | 1=版本不兼容 2=坏报文长度 |
Open 之前的基础错误 |
| 2 | Open 错误 | 1=坏版本 2=坏AS号 3=坏Router ID 5=不支持的可选参数 |
参数协商失败 |
| 3 | Update 错误 | 1=强制属性缺失 2=属性长度错误 3=属性格式错误 5=AS_PATH环路 |
路由信息错误 |
| 4 | Hold Timer 超时 | 1=超时 | 在规定时间内未收到报文 |
| 5 | FIFO 队列错误 | 1=过多 Notification | 资源耗尽 |
| 6 | 认证故障 | 1=认证失败 | MD5/其他认证失败 |
| 7 | Connection 错误 | 1=有限资源 | TCP 连接异常 |
| 8 | Client 错误 | 1=Client配置错误 | RR 场景专用 |
| 9 | Cease | 1=最大前缀超限(Max Prefix) 2=Administrative Shutdown 6=Administrative Peer De-configuration |
通用终止原因 |
四、实战配置/案例分析
4.1 BGP 报文统计与调试
# 查看BGP报文字节统计
display bgp peer 10.1.1.2
Peer: 10.1.1.2
State: Established
Message statistics:
Update: sent 2345, received 8901
Keepalive: sent 4567, received 4568
Notification: sent 0, received 0
Open: sent 3, received 3
# 开启BGP调试(生产环境慎用)
debugging bgp packet all
terminal debugging
# 查看BGP日志
display logbuffer | include BGP
4.2 案例分析:Notification 错误码排查
故障现象:BGP 邻居反复建立后立即断开,日志显示收到 Notification 报文,错误码为 Cease(9)。
排查步骤:
- 查看 BGP 日志详细信息:
display logbuffer | include BGP
*Sep 01 10:15:32: R1/BGP/NOTIFICATION: BGP notification received from 10.1.1.2, Error code=9, Subcode=6.
-
分析 Subcode=6 的含义:Cease - Administrative Peer De-configuration(管理员去配置对等体)
-
检查配置:
display current-configuration | include peer.*10.1.1.2
# peer配置已被删除或正在被删除
-
根因:对端管理员执行了对等体去配置操作(如
undo peer),导致 BGP 发送 Cease(Subcode=6)通知并关闭会话。 -
解决方案:
# 方案1:如果对等体配置被误删,重新配置peer
[R1] bgp 100
[R1-bgp] peer 10.1.1.2 as-number 200
# 方案2:如果是正常的维护操作,确认对端计划内去配即可
4.3 案例分析:Open 报文协商失败
故障现象:BGP 邻居状态卡在 OpenSent,无法进入 OpenConfirm。
排查:
- 抓包分析 Open 报文交互:
# 发现本端发送Open后未收到对端Open,随后收到Notification
# Notification Error Code=2(Open错误), Subcode=3(Bad Router ID)
- 检查 Router ID 配置:
display current-configuration | include router-id
# R1的router-id: 1.1.1.1
# 对端R3的router-id: 1.1.1.1 ← 与R1冲突!
-
根因:对端 BGP Router ID 与本地冲突。BGP 要求同一 AS 内所有 Router ID 必须唯一,否则收到 Open 报文后直接发送 Notification(Open Error, Bad Router ID)并关闭会话。
-
修复:
[R3] bgp 200
[R3-bgp] router-id 3.3.3.3 # 修改为唯一的Router ID
[R3-bgp] reset bgp all # 重置BGP会话
4.4 案例分析:Hold Timer 超时
故障现象:BGP 邻居状态从 Established 回退到 Idle,日志显示 Hold Timer 超时。
display logbuffer | include BGP
*Sep 01 14:30:00: R1/BGP/HOLDTIMER: BGP hold timer expired for peer 10.1.1.2.
排查:
- 检查 Keepalive 报文收发统计:
display bgp peer 10.1.1.2
Keepalive: sent 1000, received 2 # 接收数量远低于发送
-
中间链路可能存在不对称路由或防火墙单向过滤,导致 Keepalive 报文无法到达。
-
解决方案:
# 临时方案:增大Hold Timer
[R1] bgp 100
[R1-bgp] timer keepalive 60 hold 180
# 根本方案:排查中间网络设备,确保双向通透
五、总结
| 报文类型 | 核心功能 | 报文大小 | 发送频率 |
|---|---|---|---|
| Open | 参数协商(版本/AS/Hold Time/Router ID/能力) | 最小 29 字节 | 会话建立时 |
| Update | 路由交换(NLRI/Path Attributes/Withdrawn Routes) | 可变,最大 4096 字节 | 路由变化时 |
| Keepalive | 会话维持(仅头部) | 19 字节 | Hold Time/3(默认 60 秒) |
| Notification | 错误通知并关闭会话 | 最小 21 字节 | 错误发生时 |
思考
- BGP 的 Open 报文在 TCP 连接建立后才发送,这意味着 BGP 邻居建立必须依赖 IP 可达性。如果 TCP 连接无法建立,BGP 自身能做什么来诊断问题?
- Update 报文同时携带"新路由通告"和"旧路由撤销"两种信息,为什么 BGP 不将这两种操作拆分为两种独立的报文?这种设计带来了什么优势?
- BGP 使用 Keepalive 报文维持会话,同时底层已经使用了 TCP 连接。为什么 BGP 还需要应用层的心跳机制?TCP Keepalive 和 BGP Keepalive 有什么区别?
下篇预告:第83篇:BGP 状态机:Idle→Connect→Active→OpenSent→OpenConfirm→Established