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 工作过程与达到的效果
- 邻居建立:两台路由器先通过 TCP 179 建立连接,用 Open/Keepalive 报文完成参数协商,进入 Established 状态。
- 前缀通告:每台路由器把需要发布的前缀放进 Update 报文,发给 BGP 邻居。
- 路径属性追加 :路由器从邻居收到路由后,如果再通告给其他邻居,会在
AS_PATH中追加自己的 AS 号。这样路由在全球传播时累积成完整的 AS 级路径,也能防止路由回环。 - 选路与安装:本地路由器根据路径属性和 BGP 选路规则,为每个前缀选出最优路由,并写入路由表,同时可继续通告给其他邻居。
- 最终效果:每个 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 邻居建立完整流程
- TCP 连接建立:一方发起 TCP 连接(端口 179),连接成功后进入 OpenSent 状态。
- Open 报文交换:双方发送 Open 报文,协商版本、AS、Hold Time 和 Router ID,同时协商能力(如地址族)。
- Keepalive 确认:双方验证 Open 参数后发送 Keepalive,进入 Established 状态。
- 路由交换:进入 Established 状态后,双方交换 Update 报文。初始同步阶段交换完整的路由表,之后只发送增量更新。
- 路由撤销:某条路由不可达时,通过 Update 报文携带撤销路由部分通知邻居删除该路由。
- 会话保持:没有路由变化时,定期发送 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 逐条比较选路规则:
- 检查下一跳可达性:两个下一跳都是直连网段,IGP 路由可达。
- 比较 WEIGHT / LOCAL_PREF:均未配置,使用相同默认值。
- 比较 AS_PATH 长度 :
- 经 R1 的路径 AS_PATH 只有 1 个 AS:
65001; - 经 R3 的路径 AS_PATH 有 2 个 AS:
65003 65001; - 越短越优,因此 R2 优选直接来自 R1 的路由。
- 经 R1 的路径 AS_PATH 只有 1 个 AS:
最终 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 选路是一个逐步比较的过程,只有前一条件相同才比较下一条件。核心规则如下:
- 丢弃 NEXT_HOP 不可达的路由。
- 比较 WEIGHT(Cisco 私有,值越大越优)。
- 比较 LOCAL_PREF(值越大越优)。
- 优选本地始发路由(本地注入或聚合)。
- 比较 AS_PATH 长度(越短越优)。
- 比较 ORIGIN(IGP 优于 EGP,EGP 优于 Incomplete)。
- 比较 MED(值越小越优)。
- EBGP 优于 IBGP。
- 比较到 NEXT_HOP 的 IGP 度量(越小越优)。
- 如果配置了 multipath,符合条件的等价路由可以负载分担。
- 优选更老的 EBGP 路由。
- 比较 Router ID(越小越优)。
- 比较邻居地址(越小越优)。
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 的灵活性。