OSPF 选路只看开销,一条最短路径就完事。BGP 不一样——它面对的是不同运营商、不同策略、不同商业关系的网络,所以它准备了十几条规则,一条条比下去。
记住大方向:前几条管"我想怎么走"(出向,自己说了算),中间几条管"别人希望我怎么走"(入向,别人能影响),最后几条是"实在没差别就随便挑一个"(兜底)。
路径属性的四种分类
BGP 的每条路由都挂着一堆路径属性(Path Attributes)。选路就是比这些属性。属性按两个维度分类:
| 公认(Well-known) | 可选(Optional) | |
|---|---|---|
| 过渡 Transitive |
公认必遵 每台 BGP 都必须认,且必须发给邻居 AS_PATH、NEXT_HOP、ORIGIN |
可选过渡 你可以不认,但必须原封不动转发给邻居 Community、Aggregator |
| 非过渡 Non-transitive |
公认任意 每台 BGP 都必须认,但不要求转发 Local_Pref、Atomic Aggregate |
可选非过渡 不认就可以直接丢掉,不转发 MED、Cluster_List、Originator_ID |
一句话记法:"必遵"必须发,"任意"可以不发,"过渡"必须转发,"非过渡"可以不转。
四个主角属性
AS_PATH:路径长度
记录这条路由经过的所有 AS 号,从左到右是"最近的 AS 在前"。两个作用:
- 防环:收到含自己 AS 号的路由,直接丢弃;
- 选路:越短越优。
因为它是公认必遵,所以一定能比——这也是为什么很多流量工程的手段是"在 AS_PATH 上做文章"(AS_PATH 过滤器、apply as-path 追加 AS 号来"加长"某条路径)。
LOCAL_PREF:AS 内的统一出口
这是最常用的出向选路工具:
- 只在 IBGP 对等体之间传递,不会传出 AS(EBGP 邻居收到时不带这个属性);
- 华为默认值 100,越大越优;
- 作用是"让整个 AS 统一从哪个出口出去"——在边界路由器上用
apply local-preference改,然后泛洪给全 AS。
AS 100 有两个出口:
R1 → AS 200 想让所有流量走这里
R2 → AS 300 备用
做法:在 R1 上把从 AS 200 学来的路由 Local_Pref 调高
R1(config-route-policy)# apply local-preference 200
R2 保持缺省 100
结果:AS 100 内所有路由器(通过 IBGP 学到)都优先走 R1
★ Local_Pref 是【AS 内统一意志】,一台改了全 AS 都知道
MED:告诉邻居"请从这边进来"
MED(Multi-Exit Discriminator,多出口鉴别器)是入向的选路工具,方向正好和 Local_Pref 相反:
- 在 EBGP 之间传递,进入 AS 后默认不再向外转发(可选非过渡);
- 缺省值 0,越小越优;
- 作用是"我这边有两个入口,请尽量从低 MED 那个进来";
- 但要不要听,取决于邻居——MED 只是个建议,对方可以用自己的策略覆盖。
我要出去(出向) 别人要进来(入向)
┌──────────────┐ ┌──────────────┐
│ Local_Pref │ │ MED │
│ 我自己说了算 │ │ 邻居说了算 │
│ AS 内统一 │ │ 只在 EBGP 传 │
│ 越大越优 │ │ 越小越优 │
└──────────────┘ └──────────────┘
ORIGIN:路由怎么来的
| 取值 | 含义 | 优先级 |
|---|---|---|
| i | IGP,用 network 命令宣告的 | 最高 |
| e | EGP(已淘汰,基本见不到) | 中 |
| ? | Incomplete,用 import-route 引入的 | 最低 |
所以同一个网段,用 network 宣告比用 import-route 引入更优。这是实际排障里很容易踩的一个坑。
华为 VRP 的 11 步选路
收到同一目的地的多条路由时,按下面的顺序逐条比较,比出胜负就停:
| # | 比较项 | 优选 | 备注 |
|---|---|---|---|
| 1 | PreVal(协议首选值) | 大 | 华为私有,只在本机有效,不传递。排最前面,等于"本机最高否决权" |
| 2 | Local_Pref | 大 | 默认 100,只在 IBGP 传 |
| 3 | 路由来源 | 手动聚合 > 自动聚合 > network > import-route > 从对等体学 | 自己产生的优于学来的 |
| 4 | AS_PATH 长度 | 短 | 只数 AS 个数,as-set 里的算 1 个 |
| 5 | ORIGIN | IGP(i) > EGP(e) > Incomplete(?) | — |
| 6 | MED | 小 | 默认只比来自同一个邻居 AS 的路由 |
| 7 | EBGP / IBGP | EBGP 优 | 从 AS 外学来的更可信 |
| 8 | 到 NEXT_HOP 的 IGP 开销 | 小 | 同一 AS 内的"出口距离" |
| 9 | Cluster_List 长度 | 短 | 路由反射器场景,防环 |
| 10 | Router ID | 小 | 发布者的 Router ID |
| 11 | 对等体地址 | 小 | 最后的兜底,保证结果唯一 |
把这 11 条按"能不能自己控制"分三类:1~3 条(本机说了算)、4~6 条(策略能影响)、7~11 条(协议自动兜底)。现场做流量工程,改的基本都是前 6 条。
补充:思科的顺序略有不同,前面多了 Weight(Cisco 私有,作用类似 PreVal),后面还有"优选最早学到的路由"。原理一致,细节有差异。
团体属性:给路由打标签
团体(Community)是一个 32 位的值,写成 AS:Value 的形式。它的作用是把一大批路由打上同一个标记,然后用一条策略统一处理,而不是逐个网段配。
有四个公认团体,行为是固定的:
| 名称 | 值 | 收到后怎么做 |
|---|---|---|
| Internet | 0x00000000 | 可以通告给任何 BGP 对等体(缺省所有路由都带它) |
| No_Advertise | 0xFFFFFF02 | 收到后不向任何 BGP 对等体通告 |
| No_Export | 0xFFFFFF01 | 收到后不向 AS 外通告(联盟内可以) |
| No_Export_Subconfed | 0xFFFFFF03 | 收到后不向 AS 外通告,也不向 AS 内的其他子 AS 通告 |
# 打标签:给引入的路由加团体 100:1
route-policy SET_COMM permit node 10
apply community 100:1
bgp 100
import-route static route-policy SET_COMM
# 匹配团体
ip community-filter 1 permit 100:1
route-policy MATCH_COMM permit node 10
if-match community-filter 1
apply local-preference 200
★ 注意:默认情况下团体属性【不会传给邻居】,
需要在 BGP 视图下开:
peer 2.2.2.2 advertise-community
路由反射器:IBGP 全互联的替代方案
BGP 有一条规矩:从 IBGP 学到的路由,不会再转发给其他 IBGP 邻居(防止 AS 内出环)。结果就是 AS 内 N 台路由器要建 N×(N−1)/2 条 IBGP 会话——10 台就是 45 条,50 台就是 1225 条。
解法是路由反射器(Route Reflector, RR):指定一台(或几台)做 RR,允许它把从 IBGP 学到的路由反射给其他 IBGP 邻居。
| 角色 | 说明 |
|---|---|
| RR | 反射器。从客户端学到的路由,反射给所有客户端 + 所有非客户端;从非客户端学到的,只反射给客户端 |
| Client | 客户端。和 RR 建 IBGP,不需要和其他客户端建 |
| Non-client | 非客户端。和 RR 建 IBGP,和其他非客户端仍需全互联 |
RR 用两个属性防环:
- Originator_ID:记录路由最初发起者的 Router ID。收到含自己 Router ID 的路由,直接丢弃;
- Cluster_List:记录经过的集群 ID。收到含自己 Cluster ID 的路由,直接丢弃。这也对应选路第 9 条——Cluster_List 越短越优。
BGP 报文与状态机
| 报文 | 作用 |
|---|---|
| Open | 建立邻居,协商版本、AS 号、Hold Time、能力 |
| Keepalive | 维护邻居,默认周期 60 秒(Hold Time 180 秒) |
| Update | 通告/撤销路由,携带路径属性 |
| Notification | 检测到错误时发送,发送后关闭连接 |
| Route-refresh | 路由策略变化时,请求邻居重新通告路由 |
所有 BGP 报文都跑在 TCP 179 上——所以 BGP 是"可靠的",它不需要自己做重传。
Idle ──▶ Connect ──▶ Active ──▶ OpenSent ──▶ OpenConfirm ──▶ Established
↑____________| │ │
└────────── 失败重试 ──────────┘ │
│
★ Idle:初始状态。配好对等体后尝试建 TCP
★ Connect:TCP 三次握手进行中
★ Active:TCP 建连失败,正在重试
—— 一直卡在 Idle/Active,最常见原因就是【没有到对等体的路由】
★ OpenSent:已发出 Open,等对方 Open
★ OpenConfirm:收到 Open 且参数对得上,等 Keepalive
★ Established:邻居建立成功,开始交换路由(唯一正常状态)
选路实验:看清每一步
R1(AS 100)── EBGP ── R2(AS 200)── EBGP ── R3(AS 300)
R1 同时从 R2 学到 10.1.1.0/24,路径为:
① 经 R2,AS_PATH = 200
② 经 R3,AS_PATH = 300 200
按第 4 条规则:AS_PATH 短的优 → 选 ①
现在用策略干扰:
在 R3 上:apply as-path 400 500 additive
→ ② 的 AS_PATH 变成 400 500 300 200,更长,更选不上了
反过来想让 ② 赢:
在 R2 上:apply as-path 100 100 additive(把 ① 加长)
→ ① 变长,② 胜出
★ 这就是"AS_PATH 预置(prepending)"——最经典的入向流量工程手段
验证与排错
display bgp peer # 邻居状态(看是不是 Established)
display bgp routing-table # BGP 路由表
display bgp routing-table 10.1.1.0 # ★ 看某条路由的所有路径 + 属性
display bgp routing-table community # 按团体查
display bgp routing-table as-path-filter # 按 AS_PATH 过滤查
display bgp routing-table peer 2.2.2.2 received-routes # 从某邻居收到的
display bgp routing-table peer 2.2.2.2 advertised-routes # 发给某邻居的
# 看某条路由为什么选它 —— 最有用的一条
display bgp routing-table 10.1.1.0 verbose
reset bgp all # 重置所有 BGP 连接(慎用)
排错思路:
- 邻居起不来 → 先看状态:Idle/Active 基本都是路由不可达或 TCP 179 被拦;OpenSent 卡住看 AS 号/版本;
- 邻居起来了但没路由 → 查
advertised-routes(我发出去了吗)和received-routes(我收到了吗),再看是不是被 import 策略过滤了; - 路由选了不对的那条 → 用
verbose看全部候选和属性,按 11 条规则倒推是哪一步分的胜负。
一句话总结:PreVal 本机否决 → Local_Pref 决定出向 → 路由来源 → AS_PATH 长短 → ORIGIN → MED 决定入向 → EBGP 优先 → IGP 开销 → Cluster_List → Router ID → 对等体地址。前 6 条是你能动手的地方,后面 5 条是协议兜底。方向别记反:Local_Pref 越大越优,MED 越小越优。
📌 本篇整理自 2024–2025 的「数通」学习笔记(HCIE-Datacom 方向)
合并了原始笔记中「BGP选路规则 / BGP路径属性 / bgp团体属性community / 路由反射器 / bgp选路实验」几页。
原笔记里夹着大量 eNSP 实验截图(含 display bgp routing-table 输出),本文把截图里的关键字段(PrefVal、LocPrf、MED、Path/Ogn)整理成了规则表和实验说明。
选路顺序按华为 VRP 整理,文末标注了与思科的差异。