BGP 协议详解:背景、作用、报文格式与实际流程

1. BGP 协议背景

BGP(Border Gateway Protocol,边界网关协议)是目前互联网中唯一大规模使用的域间路由协议,当前版本为 BGP-4,定义于 RFC 4271。

要理解 BGP 为什么被设计出来,需要先看互联网的路由分层:

  • 域内路由协议(IGP):如 OSPF、IS-IS、RIP,运行在单个自治系统(AS)内部,负责自治系统内部的路由可达性。
  • 域间路由协议(EGP):BGP 属于这一类,运行在不同 AS 之间,负责把各 AS 的路由信息传递到整个互联网。

BGP 的设计目标是解决互联网的可扩展性 和策略控制问题。互联网由海量 AS 组成,IGP 基于链路状态或距离向量的算法无法在全网规模下有效运行;同时,不同运营商之间需要表达复杂的商业策略(如"只把流量发给付费客户""不从对等体接收转接流量"),BGP 通过丰富的路径属性来承载这些策略。

BGP 默认基于 TCP(端口 179)传输,这一设计把可靠传输交给 TCP,BGP 本身只负责路由信息的交换与计算。

2. BGP 的作用

  • 实现 AS 间路由互通

    不同 AS 各自维护内部路由,如果没有统一的外部路由协议,互联网会分裂成孤岛。BGP 让每个 AS 能把自己的网络前缀通告给邻居,并把接收到的路由传播出去,从而形成完整的全网路由视图。

  • 支持灵活的流量工程与路由策略

    BGP 的一个核心能力是携带大量路径属性(Path Attributes)。网络管理员可以通过配置路由策略工具,对这些属性进行匹配和修改,从而影响路由的接收、通告和选择。常见的策略场景包括:

    • 多宿主网络实现主备或负载分担。
    • 控制流量走向,绕开高成本链路。
    • 阻止非法或不应发布的前缀。
  • 支持策略控制与安全过滤

    运营商会根据商业关系(客户、对等、转接)对 BGP 路由进行过滤,只通告符合策略的路由。BGP 还支持社区属性(Community)来标记路由,便于批量执行策略。

  • 支持 IPv4 / IPv6 / VPN 等多种地址族

    现代 BGP 通过多协议扩展(MP-BGP)携带多种地址族信息,包括 IPv6 单播、VPNv4/VPNv6、EVPN 等,广泛用于 MPLS VPN 和 VXLAN 数据中心场景。

3. BGP 工作原理

BGP 的核心是在运行 BGP 的路由器之间交换"网络前缀 + 路径属性"信息 ,而不是交换链路状态或逐跳距离。真正参与交换的实体是运行 BGP 进程的路由器(BGP Speaker / BGP Peer),而不是抽象意义上的"AS 组织"。

3.1 谁给谁发:EBGP 与 IBGP

BGP 邻居分为两类:

  • EBGP(External BGP) :不同 AS 的边界路由器之间建立邻居。这些路由器通常是 AS 与外部相连的边界路由器(ASBR),负责把本 AS 的可达前缀通告给其他 AS,也从其他 AS 接收路由。
  • IBGP(Internal BGP):同一个 AS 内部运行 BGP 的路由器之间建立邻居。边界路由器从 EBGP 学到外部路由后,通过 IBGP 把外部路由同步给 AS 内其他 BGP 路由器,使整个 AS 对外的路由视图保持一致。

例如:AS 65001 只有 R1 与 AS 65002 相连,R1 就是 65001 的边界路由器;如果 65001 内部还有 R3,则 R1 和 R3 之间需要建立 IBGP 邻居,这样 R3 也能知道 R1 从外部学到的路由。

3.2 交换什么信息

BGP 在 Established 状态通过 Update 报文交换的核心内容主要有两类:

  • NLRI(Network Layer Reachability Information) :即"哪个网络前缀可达",例如 1.1.1.0/24、2.2.2.2/32。
  • 路径属性(Path Attributes) :和这条前缀绑定在一起的一组信息,用于选路与策略。常用属性包括:
    • NEXT_HOP:到达该前缀应使用的下一跳地址。
    • AS_PATH:该前缀已经经过的 AS 序列,用于防环。
    • ORIGIN:这条路由的来源,如 IGP、EGP 或 Incomplete。
    • LOCAL_PREF / MED:本地优先级、多出口区分,用于选路和出口/入口控制。

可以把 BGP 路由理解为一条记录:前缀 + 一堆属性。例如 AS 65002 收到的一条路由可以理解成:

text 复制代码
前缀:1.1.1.0/24
AS_PATH:65001
NEXT_HOP:10.0.0.1
ORIGIN:IGP

3.3 工作过程与达到的效果

  1. 邻居建立:两台路由器先通过 TCP 179 建立连接,用 Open/Keepalive 报文完成参数协商,进入 Established 状态。
  2. 前缀通告:每台路由器把需要发布的前缀放进 Update 报文,发给 BGP 邻居。
  3. 路径属性追加 :路由器从邻居收到路由后,如果再通告给其他邻居,会在 AS_PATH 中追加自己的 AS 号。这样路由在全球传播时累积成完整的 AS 级路径,也能防止路由回环。
  4. 选路与安装:本地路由器根据路径属性和 BGP 选路规则,为每个前缀选出最优路由,并写入路由表,同时可继续通告给其他邻居。
  5. 最终效果:每个 AS 都能感知"到达某个前缀需要经过哪些 AS、从哪个下一跳出去"。数据包因此可以沿着 AS 级路径转发,形成互联网全局可达性。

#mermaid-svg-wqpEtzJbPn79VMAi{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-wqpEtzJbPn79VMAi .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-wqpEtzJbPn79VMAi .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-wqpEtzJbPn79VMAi .error-icon{fill:#552222;}#mermaid-svg-wqpEtzJbPn79VMAi .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-wqpEtzJbPn79VMAi .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-wqpEtzJbPn79VMAi .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-wqpEtzJbPn79VMAi .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-wqpEtzJbPn79VMAi .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-wqpEtzJbPn79VMAi .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-wqpEtzJbPn79VMAi .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-wqpEtzJbPn79VMAi .marker{fill:#333333;stroke:#333333;}#mermaid-svg-wqpEtzJbPn79VMAi .marker.cross{stroke:#333333;}#mermaid-svg-wqpEtzJbPn79VMAi svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-wqpEtzJbPn79VMAi p{margin:0;}#mermaid-svg-wqpEtzJbPn79VMAi .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-wqpEtzJbPn79VMAi .cluster-label text{fill:#333;}#mermaid-svg-wqpEtzJbPn79VMAi .cluster-label span{color:#333;}#mermaid-svg-wqpEtzJbPn79VMAi .cluster-label span p{background-color:transparent;}#mermaid-svg-wqpEtzJbPn79VMAi .label text,#mermaid-svg-wqpEtzJbPn79VMAi span{fill:#333;color:#333;}#mermaid-svg-wqpEtzJbPn79VMAi .node rect,#mermaid-svg-wqpEtzJbPn79VMAi .node circle,#mermaid-svg-wqpEtzJbPn79VMAi .node ellipse,#mermaid-svg-wqpEtzJbPn79VMAi .node polygon,#mermaid-svg-wqpEtzJbPn79VMAi .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-wqpEtzJbPn79VMAi .rough-node .label text,#mermaid-svg-wqpEtzJbPn79VMAi .node .label text,#mermaid-svg-wqpEtzJbPn79VMAi .image-shape .label,#mermaid-svg-wqpEtzJbPn79VMAi .icon-shape .label{text-anchor:middle;}#mermaid-svg-wqpEtzJbPn79VMAi .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-wqpEtzJbPn79VMAi .rough-node .label,#mermaid-svg-wqpEtzJbPn79VMAi .node .label,#mermaid-svg-wqpEtzJbPn79VMAi .image-shape .label,#mermaid-svg-wqpEtzJbPn79VMAi .icon-shape .label{text-align:center;}#mermaid-svg-wqpEtzJbPn79VMAi .node.clickable{cursor:pointer;}#mermaid-svg-wqpEtzJbPn79VMAi .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-wqpEtzJbPn79VMAi .arrowheadPath{fill:#333333;}#mermaid-svg-wqpEtzJbPn79VMAi .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-wqpEtzJbPn79VMAi .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-wqpEtzJbPn79VMAi .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-wqpEtzJbPn79VMAi .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-wqpEtzJbPn79VMAi .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-wqpEtzJbPn79VMAi .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-wqpEtzJbPn79VMAi .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-wqpEtzJbPn79VMAi .cluster text{fill:#333;}#mermaid-svg-wqpEtzJbPn79VMAi .cluster span{color:#333;}#mermaid-svg-wqpEtzJbPn79VMAi div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-wqpEtzJbPn79VMAi .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-wqpEtzJbPn79VMAi rect.text{fill:none;stroke-width:0;}#mermaid-svg-wqpEtzJbPn79VMAi .icon-shape,#mermaid-svg-wqpEtzJbPn79VMAi .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-wqpEtzJbPn79VMAi .icon-shape p,#mermaid-svg-wqpEtzJbPn79VMAi .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-wqpEtzJbPn79VMAi .icon-shape .label rect,#mermaid-svg-wqpEtzJbPn79VMAi .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-wqpEtzJbPn79VMAi .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-wqpEtzJbPn79VMAi .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-wqpEtzJbPn79VMAi :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} EBGP Update:1.1.1.0/24 + AS_PATH 65001
追加 AS_PATH 65002 65001
IBGP 同步外部路由
AS 65001 内边界路由器 R1
AS 65002 边界路由器 R2
AS 65003
AS 65001 内部路由器 R3

从效果看,BGP 负责的是跨 AS 的路径信息传播与策略选择。BGP 不直接计算数据包在单个 AS 内的具体转发路径------那是 IGP(如OSPF等) 的职责;。

4. BGP 报文格式

4.1 报文头格式

每个 BGP 报文都包含一个固定 16 字节的报文头,格式如下:

复制代码
  0               8               16              24              31
 +---------------------------------------------------------------+
 |                                                               |
 |                         Marker (16 字节)                       |
 |                                                               |
 +---------------------------------------------------------------+
 |         Length                  |           Type              |
 +---------------------------------------------------------------+

各字段含义:

字段 长度 含义
Marker 16 字节 用于同步和认证。正常情况下全为 1(十六进制 0xFF)。如果协商了认证,则携带认证摘要。
Length 2 字节 整个 BGP 报文的长度(含报文头),单位为字节。最小值为 19,最大值为 4096。
Type 1 字节 BGP 报文类型,取值如下:1=Open,2=Update,3=Notification,4=Keepalive。

报文类型一共有四种:Open、Update、Keepalive、Notification。

4.2 Open 报文

Open 报文是 TCP 连接建立后发送的第一个报文,用于协商会话参数。格式如下:

复制代码
 +-------------+--------------+---------+-------+-------+
 | Version (1) | My AS (2)   | Hold Time (2) | BGP ID (4) |
 +-------------+--------------+---------+-------+-------+
 | Opt Parm Len (1) | Optional Parameters (可变长) |
 +------------------+-----------------------------+

各字段含义:

字段 长度 含义
Version 1 字节 BGP 版本号,目前为 4。
My AS 2 字节 发送者的 AS 号。
Hold Time 2 字节 接收方在该时间内未收到 Keepalive 或 Update 就认为连接失效。双方协商较小的值。
BGP Identifier 4 字节 BGP 路由器标识(Router ID),是唯一标识的 IPv4 地址。
Opt Parm Len 1 字节 可选参数总长度。
Optional Parameters 可变长 可选参数,以 TLV 方式编码,如能力通告(Capabilities)。

5. Update 报文详解

Update 报文是 BGP 中最重要的报文,用于通告可达路由、撤销不可达路由,并携带路径属性。

5.1 Update 报文结构

复制代码
 +---------------------------------------------------------+
 | Withdrawn Routes Length (2 字节)                          |
 +---------------------------------------------------------+
 | Withdrawn Routes (可变长)                                 |
 +---------------------------------------------------------+
 | Total Path Attribute Length (2 字节)                      |
 +---------------------------------------------------------+
 | Path Attributes (可变长)                                  |
 +---------------------------------------------------------+
 | NLRI (可变长)                                             |
 +---------------------------------------------------------+

5.2 各字段含义

字段 长度 含义
Withdrawn Routes Length 2 字节 撤销路由部分的长度。
Withdrawn Routes 可变长 要撤销的前缀列表。每个前缀格式为「长度(1 字节)+ 前缀(按长度取整字节)」。
Total Path Attribute Length 2 字节 路径属性部分的长度。
Path Attributes 可变长 路由携带的属性集合。
NLRI(Network Layer Reachability Information) 可变长 要通告的可达前缀列表,格式与撤销路由相同。

5.3 路径属性格式

路径属性是 BGP 支持丰富策略的关键。每个属性由头部和值组成:

复制代码
 +-----------+-------------------+-------------------+-------------------+
 | Attr Flag (1) | Attr Type (1) | Attr Length (1 or 2) | Attr Value |
 +-----------+-------------------+-------------------+-------------------+

Attr Flag 各 bit 含义:

Bit 含义
O(Optional) 属性是否可选的。1=可选,0=公认。
T(Transitive) 属性是否可传递。1=可传递,0=不可传递。
P(Partial) 属性是否被中间路由器部分处理。
E(Extended Length) 属性长度字段是否为 2 字节。

Flags 常见组合:

Flag 值 含义类别
0x40 公认必遵(Well-known mandatory),如 AS_PATH、ORIGIN、NEXT_HOP。
0x40 + 0x80 公认自选(Well-known discretionary),如 LOCAL_PREF。
0x80 可选可传递(Optional transitive),如 COMMUNITY。
0xC0 可选可传递(含扩展长度),如大型社区。
0x80 + 0x40 组合 实际中还有一些组合,但核心是以上几类。

5.4 常用路径属性

属性 类别 作用
ORIGIN 公认必遵 路由来源:0=IGP,1=EGP,2=Incomplete。
AS_PATH 公认必遵 路由经过的 AS 序列,用于防环。
NEXT_HOP 公认必遵 到达目的地应使用的下一跳地址。
LOCAL_PREF 公认自选 用于本地 AS 内选路的优先级,值越大越优先。只在 IBGP 之间传递。
MED(Multi-Exit Discriminator) 可选非传递 向外部邻居表达更优入口,值越小越优先。
COMMUNITY 可选可传递 对路由打标,用于策略过滤。
AGGREGATOR 可选可传递 路由聚合者信息。

6. Keepalive 与 Notification 报文

6.1 Keepalive 报文

Keepalive 报文只有 BGP 报文头,不携带任何数据,长度为 19 字节。作用是在已建立连接的邻居之间维持会话。默认周期为 Hold Time 的三分之一(如 Hold Time 180 秒,则 60 秒发送一次 Keepalive)。

6.2 Notification 报文

Notification 报文在检测到错误或需要主动关闭连接时发送。格式如下:

复制代码
 +-------------+----------+-----------------------+
 | Error Code (1) | Error Subcode (1) | Data (可变长) |
 +-------------+----------+-----------------------+

字段含义:

字段 长度 含义
Error Code 1 字节 错误大类,如报文头错误、Open 报文错误、Update 报文错误等。
Error Subcode 1 字节 具体错误原因。
Data 可变长 辅助诊断信息,通常是引发错误的报文数据。

常见 Error Code:

Code 错误类别
1 Message Header Error
2 Open Message Error
3 Update Message Error
4 Hold Timer Expired
5 Finite State Machine Error
6 Cease

7. BGP 邻居状态机

7.1 BGP 有限状态机(FSM)

BGP 会话从建立到断开会经历以下状态:

状态 说明
Idle 初始状态,拒绝所有连接。
Connect 发起 TCP 连接。
Active 连接失败,重试建立连接。
OpenSent TCP 连接建立,已发送 Open 报文。
OpenConfirm 已收到对端 Open 报文,等待 Keepalive 或 Notification。
Established 会话建立完成,可以交换 Update 报文。

7.2 邻居建立完整流程

  1. TCP 连接建立:一方发起 TCP 连接(端口 179),连接成功后进入 OpenSent 状态。
  2. Open 报文交换:双方发送 Open 报文,协商版本、AS、Hold Time 和 Router ID,同时协商能力(如地址族)。
  3. Keepalive 确认:双方验证 Open 参数后发送 Keepalive,进入 Established 状态。
  4. 路由交换:进入 Established 状态后,双方交换 Update 报文。初始同步阶段交换完整的路由表,之后只发送增量更新。
  5. 路由撤销:某条路由不可达时,通过 Update 报文携带撤销路由部分通知邻居删除该路由。
  6. 会话保持:没有路由变化时,定期发送 Keepalive 维持连接。

8. BGP 实际组网示例:建立连接、路由交互与选路

下面用一个三 AS 组网,演示 BGP 邻居如何建立、Update 如何交互,以及 R2 如何确定到 1.1.1.1/32 的最优路由。

8.1 组网拓扑

#mermaid-svg-OCoWZGGxAKhABlFv{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-OCoWZGGxAKhABlFv .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-OCoWZGGxAKhABlFv .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-OCoWZGGxAKhABlFv .error-icon{fill:#552222;}#mermaid-svg-OCoWZGGxAKhABlFv .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-OCoWZGGxAKhABlFv .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-OCoWZGGxAKhABlFv .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-OCoWZGGxAKhABlFv .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-OCoWZGGxAKhABlFv .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-OCoWZGGxAKhABlFv .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-OCoWZGGxAKhABlFv .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-OCoWZGGxAKhABlFv .marker{fill:#333333;stroke:#333333;}#mermaid-svg-OCoWZGGxAKhABlFv .marker.cross{stroke:#333333;}#mermaid-svg-OCoWZGGxAKhABlFv svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-OCoWZGGxAKhABlFv p{margin:0;}#mermaid-svg-OCoWZGGxAKhABlFv .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-OCoWZGGxAKhABlFv .cluster-label text{fill:#333;}#mermaid-svg-OCoWZGGxAKhABlFv .cluster-label span{color:#333;}#mermaid-svg-OCoWZGGxAKhABlFv .cluster-label span p{background-color:transparent;}#mermaid-svg-OCoWZGGxAKhABlFv .label text,#mermaid-svg-OCoWZGGxAKhABlFv span{fill:#333;color:#333;}#mermaid-svg-OCoWZGGxAKhABlFv .node rect,#mermaid-svg-OCoWZGGxAKhABlFv .node circle,#mermaid-svg-OCoWZGGxAKhABlFv .node ellipse,#mermaid-svg-OCoWZGGxAKhABlFv .node polygon,#mermaid-svg-OCoWZGGxAKhABlFv .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-OCoWZGGxAKhABlFv .rough-node .label text,#mermaid-svg-OCoWZGGxAKhABlFv .node .label text,#mermaid-svg-OCoWZGGxAKhABlFv .image-shape .label,#mermaid-svg-OCoWZGGxAKhABlFv .icon-shape .label{text-anchor:middle;}#mermaid-svg-OCoWZGGxAKhABlFv .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-OCoWZGGxAKhABlFv .rough-node .label,#mermaid-svg-OCoWZGGxAKhABlFv .node .label,#mermaid-svg-OCoWZGGxAKhABlFv .image-shape .label,#mermaid-svg-OCoWZGGxAKhABlFv .icon-shape .label{text-align:center;}#mermaid-svg-OCoWZGGxAKhABlFv .node.clickable{cursor:pointer;}#mermaid-svg-OCoWZGGxAKhABlFv .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-OCoWZGGxAKhABlFv .arrowheadPath{fill:#333333;}#mermaid-svg-OCoWZGGxAKhABlFv .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-OCoWZGGxAKhABlFv .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-OCoWZGGxAKhABlFv .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-OCoWZGGxAKhABlFv .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-OCoWZGGxAKhABlFv .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-OCoWZGGxAKhABlFv .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-OCoWZGGxAKhABlFv .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-OCoWZGGxAKhABlFv .cluster text{fill:#333;}#mermaid-svg-OCoWZGGxAKhABlFv .cluster span{color:#333;}#mermaid-svg-OCoWZGGxAKhABlFv div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-OCoWZGGxAKhABlFv .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-OCoWZGGxAKhABlFv rect.text{fill:none;stroke-width:0;}#mermaid-svg-OCoWZGGxAKhABlFv .icon-shape,#mermaid-svg-OCoWZGGxAKhABlFv .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-OCoWZGGxAKhABlFv .icon-shape p,#mermaid-svg-OCoWZGGxAKhABlFv .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-OCoWZGGxAKhABlFv .icon-shape .label rect,#mermaid-svg-OCoWZGGxAKhABlFv .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-OCoWZGGxAKhABlFv .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-OCoWZGGxAKhABlFv .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-OCoWZGGxAKhABlFv :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} AS 65003
AS 65002
AS 65001
10.0.0.0/30
10.0.2.0/30
10.0.1.0/30
R1 1.1.1.1
R2 2.2.2.2
R3 3.3.3.3

关键地址如下:

设备 AS Router ID / Loopback 互联地址
R1 65001 1.1.1.1/32 至 R2:10.0.0.1/30;至 R3:10.0.2.1/30
R2 65002 2.2.2.2/32 至 R1:10.0.0.2/30;至 R3:10.0.1.1/30
R3 65003 3.3.3.3/32 至 R1:10.0.2.2/30;至 R2:10.0.1.2/30

8.2 配置并建立邻居

R1 配置示例:

bash 复制代码
[R1] bgp 65001
[R1-bgp] router-id 1.1.1.1
[R1-bgp] peer 10.0.0.2 as-number 65002
[R1-bgp] peer 10.0.2.2 as-number 65003
[R1-bgp] ipv4-family unicast
[R1-bgp-af-ipv4] network 1.1.1.1 255.255.255.255
[R1-bgp-af-ipv4] peer 10.0.0.2 enable
[R1-bgp-af-ipv4] peer 10.0.2.2 enable

R2 配置示例:

bash 复制代码
[R2] bgp 65002
[R2-bgp] router-id 2.2.2.2
[R2-bgp] peer 10.0.0.1 as-number 65001
[R2-bgp] peer 10.0.1.2 as-number 65003
[R2-bgp] ipv4-family unicast
[R2-bgp-af-ipv4] network 2.2.2.2 255.255.255.255
[R2-bgp-af-ipv4] peer 10.0.0.1 enable
[R2-bgp-af-ipv4] peer 10.0.1.2 enable

R3 配置示例:

bash 复制代码
[R3] bgp 65003
[R3-bgp] router-id 3.3.3.3
[R3-bgp] peer 10.0.2.1 as-number 65001
[R3-bgp] peer 10.0.1.1 as-number 65002
[R3-bgp] ipv4-family unicast
[R3-bgp-af-ipv4] network 3.3.3.3 255.255.255.255
[R3-bgp-af-ipv4] peer 10.0.2.1 enable
[R3-bgp-af-ipv4] peer 10.0.1.1 enable

建立连接前,先确认 TCP 179 可达,再让 BGP 状态机从 Idle 走到 Established:

bash 复制代码
<R1> ping -a 10.0.0.1 10.0.0.2
<R1> display bgp peer

正常时应看到邻居状态为 Established。示例输出如下:

text 复制代码
 Peer            V          AS  MsgRcvd  MsgSent  OutQ  Up/Down  State
 10.0.0.2        4       65002       10        9     0 00:04:31 Established
 10.0.2.2        4       65003        8        8     0 00:03:58 Established

8.3 路由如何交互

R1 通过 network 1.1.1.1/32 将前缀放进 Update 报文,分别发给两个 EBGP 邻居:

  • 发给 R2 时:NLRI = 1.1.1.1/32,NEXT_HOP = 10.0.0.1,AS_PATH = 65001。
  • 发给 R3 时:NLRI = 1.1.1.1/32,NEXT_HOP = 10.0.2.1,AS_PATH = 65001。

R3 收到后,再把这条路由通告给 R2。因为由 EBGP 再次发出,R3 会:

  • 把 AS_PATH 追加自己的 AS 号,变成 65003 65001;
  • 把 NEXT_HOP 改为 R3 到 R2 的接口地址 10.0.1.2。

最终 R2 收到两条到达 1.1.1.1/32 的路由:

来源邻居 AS_PATH NEXT_HOP
直接来自 R1 65001 10.0.0.1
经 R3 转接 65003 65001 10.0.1.2

可以在 R2 上查看 BGP 路由表:

text 复制代码
<R2> display bgp routing-table

   Network            NextHop      Path/Ogn
   *> 1.1.1.1/32       10.0.0.1     65001i
   *  1.1.1.1/32       10.0.1.2     65003 65001i

8.4 R2 如何确定最优路由

R2 对两条 1.1.1.1/32 逐条比较选路规则:

  1. 检查下一跳可达性:两个下一跳都是直连网段,IGP 路由可达。
  2. 比较 WEIGHT / LOCAL_PREF:均未配置,使用相同默认值。
  3. 比较 AS_PATH 长度 :
    • 经 R1 的路径 AS_PATH 只有 1 个 AS:65001;
    • 经 R3 的路径 AS_PATH 有 2 个 AS:65003 65001;
    • 越短越优,因此 R2 优选直接来自 R1 的路由。

最终 R2 会把下一跳 10.0.0.1 写入路由表,发往 1.1.1.1/32 的流量走 R1,而 R3 转接路径仅作为备份。如果管理员希望优先走 R3,可以通过 WEIGHT、LOCAL_PREF、MED 等策略干预,这正是 BGP 路径属性发挥作用的地方。

8.5 R2 到 R3 路由

R2 要到 R3 时,依据的是从 R3 通过 EBGP Update 学到的 BGP 路由信息。在本拓扑中,R3 会通过 network 3.3.3.3/32 把自己的 Loopback 通告给 R2,所依赖的核心字段如下:

字段 取值 作用
NLRI 3.3.3.3/32 表示目标前缀可达
NEXT_HOP 10.0.1.2 决定实际转发出口
AS_PATH 65003 标识路由来自 AS 65003,用于防环和选路

其中真正决定数据包怎么走的是 NEXT_HOP 。R2 收到这条 Update 后,会先检查 10.0.1.2 是否可达;由于 10.0.1.2 位于直连网段 10.0.1.0/30 上,R2 可以直接到达,因此将 3.3.3.3/32 的下一跳 10.0.1.2 写入路由表。

如果 R2 只从 R3 收到这一条 3.3.3.3/32,则不需要比较 AS_PATH 长度,直接用 NEXT_HOP 决定转发。只有同时从其他邻居学到多条到 3.3.3.3/32 的路由时,才会进入 8.4 那样的选路比较;此时直连 R3 的路径 AS_PATH 通常更短,往往会被优选。

9. BGP 选路规则(13 条)BGP 选路是一个逐步比较的过程,只有前一条件相同才比较下一条件。核心规则如下:

  1. 丢弃 NEXT_HOP 不可达的路由。
  2. 比较 WEIGHT(Cisco 私有,值越大越优)。
  3. 比较 LOCAL_PREF(值越大越优)。
  4. 优选本地始发路由(本地注入或聚合)。
  5. 比较 AS_PATH 长度(越短越优)。
  6. 比较 ORIGIN(IGP 优于 EGP,EGP 优于 Incomplete)。
  7. 比较 MED(值越小越优)。
  8. EBGP 优于 IBGP。
  9. 比较到 NEXT_HOP 的 IGP 度量(越小越优)。
  10. 如果配置了 multipath,符合条件的等价路由可以负载分担。
  11. 优选更老的 EBGP 路由。
  12. 比较 Router ID(越小越优)。
  13. 比较邻居地址(越小越优)。

9. 抓包观察 BGP 报文

下面用 Wireshark 抓取 BGP 会话建立过程,展示关键报文。

9.1 Open 报文示例

复制代码
BGP Message
    Marker: ffffffffffffffffffffffffffffffff
    Length: 45
    Type: OPEN (1)
    Version: 4
    My AS: 65001
    Hold time: 180
    BGP Identifier: 1.1.1.1
    Optional Parameters Length: 16
    Optional Parameters:
        Capability: IPv4 Unicast
        Capability: Route Refresh
        Capability: 4-octet AS number

9.2 Update 报文示例

来自 R2 的 Update 通告 2.2.2.2/32:

复制代码
BGP Message
    Marker: ffffffffffffffffffffffffffffffff
    Length: 61
    Type: UPDATE (2)
    Withdrawn Routes Length: 0
    Total Path Attribute Length: 24
    Path Attributes:
        ORIGIN: IGP
        AS_PATH: 65002
        NEXT_HOP: 10.0.0.2
    NLRI: 2.2.2.2/32

9.3 Keepalive 报文示例

复制代码
BGP Message
    Marker: ffffffffffffffffffffffffffffffff
    Length: 19
    Type: KEEPALIVE (4)

10. 常见问题与排障

10.1 BGP 邻居无法建立

常见原因排查思路:

现象 可能原因
状态在 Idle 或 Active TCP 连接失败,检查 IP 可达性和 179 端口连通性。
收到 Notification 检查错误码,最常见的是 AS 号配置错误或 Hold Time 不匹配。
状态在 OpenSent/OpenConfirm 检查是否有防火墙过滤 BGP 流量,或路由策略阻断。

常用排障命令:

bash 复制代码
<R1> display bgp peer verbose
<R1> display tcp status
<R1> ping -a 1.1.1.1 10.0.0.2

10.2 路由没有学到

检查要点:

  • 对端是否用 network 命令通告了该前缀。
  • 本地是否有策略过滤了该前缀。
  • 地址族是否匹配(IPv4/IPv6)。
  • NEXT_HOP 是否可达。

11. 总结

BGP 是互联网的"神经系统",承载着全球路由信息的传播。本文从 BGP 的背景与定位出发,详细讲解了四类报文的结构与字段含义,梳理了邻居状态机与实际建立流程,给出了 13 条选路规则,并通过配置、验证和抓包示例展示了完整的实际应用过程。

掌握 BGP 的核心在于理解三个层面:

  • 传输层:基于 TCP 179,保证可靠性。
  • 会话层:四类报文配合状态机完成邻居建立与维持。
  • 策略层:路径属性承载丰富的路由策略,是 BGP 区别于 IGP 的灵魂所在。

在真实网络中,还需要结合路由策略工具(Route Policy、Prefix List、Community Filter 等)才能充分发挥 BGP 的灵活性。

相关推荐
小张成长计划..4 小时前
【Linux】32:Socket编程2-UDP
网络·网络协议·udp
xixiaoyunya4 小时前
搭一个浏览器即用的二进制文件分发点:目录规范与权限边界实践
网络·windows
李&@杰5 小时前
小型园区网从零到精通
网络·tcp/ip·华为
Liuqy-055 小时前
TCP与UDP
网络·网络协议·tcp/ip·udp·c
车载中间件通信5 小时前
[TC8测试]TCP_PROBING_WINDOWS_05
网络·网络协议·tcp/ip·tc8
曦夜日长5 小时前
主从 Reactor 高并发服务器实战 (三):服务器套接字Socket模块详解与实现
运维·服务器·网络
鹿鸣天涯6 小时前
2026年下半年网络规划设计师论文
网络·计算机网络·网络规划设计师
echome8886 小时前
Linux 定时任务:crontab 写法与常见失效原因
linux·运维·网络·定时任务·crontab
从琳开始9896 小时前
从Socket到TCP回显服务器:Java网络编程完整指南
java·服务器·网络·tcp/ip·java-ee