路由与 BGP

本页目录

路由器收到两条到同一前缀的路径,一条 AS_PATH 更短,另一条符合更高的本地优先级,后者可能获选。但如果目的地址还匹配一条更具体的前缀,实际转发又会使用更具体路由。理解路由,首先要区分“为同一前缀选候选路径”和“为一个目的地址查最长前缀”。

问题所在层次
这个前缀有哪些候选协议接收、导入策略和 RIB
同一前缀选哪条路径协议优选及跨协议选择
下一跳怎样到达递归路由解析、IGP/直连/静态路由
当前这个包走哪里策略规则、FIB 最长前缀匹配、ECMP
改动多久影响数据检测、计算、传播与 FIB 安装形成的收敛过程

RIB 与 FIB:候选信息和转发结果

RIB 是路由信息的逻辑组织,FIB 面向实际转发。BGP 还区分从邻居接收的 Adj-RIB-In、本地选择的 Loc-RIB,以及面向邻居通告的 Adj-RIB-Out。它们是协议模型,不要求每种实现都原样保存三份完全独立的数据结构。RFC 4271:路由信息模型

一条路由从收到到可转发,需要经过多层判断 协议候选路由 接收、过滤、属性 选路与下一跳解析 协议优选、跨协议选择 FIB 与出口邻接 安装、接口、ARP/NDP 实际包:策略规则选择上下文 → 表内最长前缀 → 下一跳/出口 BGP 会话 Established、路由已收到、已选优、已安装、数据可达,是五个不同的状态。

在 Linux 软件路由场景,FRR 等守护进程可以通过内核接口安装路由;硬件设备还可能需要进一步下发 ASIC。RIB 中有路由,不保证下一跳可解析或安装成功;FIB 中有路由,也不保证出口邻居和回程正常。

最长前缀匹配是语义,trie、压缩层级、硬件表等是实现。不能把 Linux LC-trie 简写为任何规模与访问条件下都恒定 O(1),也不能用一个不断变化的全球前缀总数描述所有路由器的内存需求:邻居数量、地址族、候选路径和策略同样重要。

把最长前缀算清楚

假设同一张表中有默认路由、203.0.113.0/24 经 A、203.0.113.128/25 经 B。目标 .140 同时匹配三条,选 /25 经 B;目标 .20 选 /24 经 A。即使 /24 的 BGP LOCAL_PREF 很高,也不会覆盖已安装 /25 的最长前缀优势。

跨协议优先级通常解决相同前缀的候选竞争,不应该拿某设备的静态路由管理距离与另一条不同长度前缀混算。路由聚合减少条目时还会扩大被覆盖范围,需要考虑缺失更具体路由时是否把流量送入黑洞。

Linux 策略路由:先决定查哪张表

RPDB 按规则优先级由小到大处理,可以依据源地址、fwmark、输入接口等选择动作。规则匹配后执行查表,若没有得到终止结果,可能继续后续规则;因此“第一条匹配规则必定结束”不准确。throw 路由可结束当前表的查找并继续规则链,而 blackhole、unreachable 等具有不同终止语义。ip-rule 手册、ip-route 手册

常见预置规则依次查询 local(255)、main(254)和 default(253)。名为 default 的表不等于默认路由:0.0.0.0/0 或 ::/0 可以位于 main 或其他表。自定义表编号也不局限于 1~252。

例如某源前缀先查表 100,表 100 没有匹配路由,则可继续查 main;若表 100 有默认路由,通常已经给出结果,不会为了寻找 main 中更具体路由而继续。⁠最长前缀比较发生在当前查表上下文中,不是把所有表合并排序。

# 只读观察命令,实际接口、目标和源地址按环境替换。
ip rule show
ip route show table all
ip route get <目标IPv4> from <源IPv4>
ip -6 route get <目标IPv6> from <源IPv6>

更具体的路由,为什么可能根本没被查到?

把 main 表里的匹配范围一直留在图上,再检查查询记录是否真的走到了 main。这样,目的地址命中 /25 却仍经 C 转发的情况,就能由规则终止条件解释,而不必错误地修改最长前缀规则。

正在呈现知识画面
更具体的路由,为什么可能根本没被查到?

最长前缀匹配发生在当前表内。前一张表给出默认路由或黑洞终止结果后,不会继续到下一表寻找更长前缀;throw 则继续规则链。

IGP:把链路代价累加到路径上

OSPF 与 IS-IS 在相应范围内传播链路状态并计算路径;代价表达配置的度量,不必等于测得的延迟。以单区域简化拓扑为例,A→B 代价 10,B→D 为 10,A→C 为 5,C→D 为 30,则经 B 总计 20,优于经 C 的 35。A→B 失效后,经 C 才可能成为新的可用最短路径。RFC 2328:OSPFv2

实际收敛还要经过失效检测、状态传播、SPF 调度和转发表更新;区域结构、路由类型及策略增加更多规则。不能从 Dijkstra 算法本身推导出固定的全网切换毫秒数。IGP 也常用于提供 BGP NEXT_HOP 的域内可达性,两者共同工作。

BGP 会话:TCP 通了只是起点

BGP 使用 TCP 179,随后交换 OPEN、KEEPALIVE、UPDATE 等消息,建立协议状态。OPEN 中的版本为 4,BGP Identifier 是 32 bit 标识,并不要求就是会话端点地址。Hold Time 由双方参数协商,非零值至少为三秒;若协商为零则不运行相应 Hold/Keepalive 定时器,不能一概写成 90/30 秒。

基本 OPEN 的 My Autonomous System 字段仍是两字节;四字节 ASN 通过能力协商及兼容机制支持,不是直接把该字段拉长。RFC 6793:四字节 ASNUPDATE 宣告或撤回前缀,并携带属性;多协议扩展用相应属性承载不同地址族,不能把 IPv4 单播基本布局硬套到全部 MP-BGP 报文。

会话 Established 但没有路由,可能是地址族未启用、导入策略拒绝或对端未导出,而不一定是 TCP 故障。RFC 8212 对 eBGP 缺省导入/导出策略给出限制;实际产品还应核对版本与配置模式。RFC 4271、RFC 8212:显式 eBGP 策略

选路:用候选表解释优先级

同一 /24 的候选:本地策略先于 AS 路径长度 出口 A:LOCAL_PREF 200 AS_PATH:64501 64502 64503 出口 B:LOCAL_PREF 100 AS_PATH:64504 64503 选 A:优先级更高 若两者 LOCAL_PREF 相同, 再按本例条件选更短的 B。 假设两条路径均有效、前序属性相同;另一个更具体 /25 仍会在转发查表时优先于此 /24。

本例路径都有效、NEXT_HOP 可解析,且未出现更早的本地属性差异。A 的 LOCAL_PREF=200,高于 B 的 100,因此即使 A 的 AS 序列更长也选 A。把 A 改为 100 后,在其余前序条件相同时才比较路径长度,B 获选。

属性/条件典型用途边界
LOCAL_PREF在 AS 内表达出口偏好,通常高者优先普通 eBGP 不向外传播,不能要求对方采用本地值
AS_PATHAS 级路径信息与防环,常偏好较短序列不代表链路延迟、带宽或物理距离
ORIGIN路由起源属性的协议分类IGP 值不证明路径运行 OSPF,也不是起源认证
MED向相邻 AS 提示多入口偏好,常低者优先默认通常限来自同一相邻 AS 的候选比较
NEXT_HOP 的 IGP 代价同等条件下选择域内到出口的成本下一跳首先要可达
本地 weight、最终破同分项实现或配置增加的选择规则不属于所有厂商统一的固定列表

应从正在使用的实现文档核对完整顺序与开关;例如 FRR 的 MED 比较、多路径放宽和 router-ID 相关选项会影响结果。教学中只对明确假设下的候选做推演,避免把 Cisco、Huawei、FRR 的规则混成一份所谓标准算法。FRR BGP 选路文档

路径更短,为什么还是没被选中?

先用较高的 LOCAL_PREF 抵消 A 的较长路径,再把偏好调成相同,才能看到后续条件开始发挥作用。关闭下一跳可达性时,A 会在进入这两个数值比较之前被排除。图的顺序只代表这里明确限定的候选集合。

正在呈现知识画面
路径更短,为什么还是没被选中?

候选先要可用,再按明确的优选顺序比较。后面的路径长度不能逆转已经由 LOCAL_PREF 决定的结果。

防环、iBGP 与路由反射

普通 eBGP 通告会把本地 AS 加入路径,收到含本地 AS 的路径通常排除;iBGP 不为同一 AS 内传播重复增加本地 AS。这个机制抑制 AS 级路由环,但不能替代全部数据平面环路与错误策略检查。

传统 iBGP 从一个 iBGP 邻居学到的路由不会再直接通告给另一个 iBGP 邻居,因此简单互联并不自动形成完整传播。全互联、路由反射与联盟分别解决规模或组织问题;反射器依赖 ORIGINATOR_ID、CLUSTER_LIST 等附加机制防止相应反射环路。RFC 4456:路由反射

iBGP 会话可跨多跳建立,而路由中的 NEXT_HOP 仍必须能递归解析。next-hop-self 是改变下一跳通告的一种策略选择,不是所有部署都必须无条件开启。

Communities 与流量工程:标签需要策略解释

普通 Community 是 32 bit,常写成两个 16 bit 十进制值;Extended 为 8 B,Large 为 12 B,不能认为三者仅显示格式不同。RFC 8092:Large Communities普通标签没有自动动作,双方必须约定怎样匹配和实施策略。

NO_ADVERTISE 限制向任何 BGP 邻居通告;NO_EXPORT 的边界是联盟边界,不能粗略等价成任何形式的 eBGP 会话都禁止传播。联盟内部还需要区分 NO_EXPORT_SUBCONFED 等语义。RFC 1997:标准 Communities

AS_PATH prepend 可以增加某一路径的表观长度,影响远端入站选择,但远端 LOCAL_PREF 可能先决定结果。因此“多 prepend 两次就一定改走另一个出口”不成立。出站偏好由自己的策略直接控制较多,入站通常只能通过通告和约定影响对方。

ECMP:分担的是散列结果,不是精确字节配额

多个符合条件的下一跳可装入 FIB,按地址、端口、Flow Label 或其他所选字段散列。具体字段取决于协议族、内核与配置;Linux 文档提供 fib_multipath_hash_policy,并非永远只使用源/目的 IP。

在稳定成员集与散列策略下,同一流通常保持路径一致以减少乱序。成员增减或路由变化可能重映射流;即使权重 2:1,大流大小不均也会使实际字节量远离 2:1,更不保证单连接获得两条链路之和的吞吐。Linux 多路径散列配置

收敛与起源验证:别只看绿色会话状态

一条路径失效后,设备需要检测、撤回或排除候选、重新优选并安装 FIB,再把变动传播给其他节点。BFD 等可改变检测环节,却不消除整个链条的开销。Graceful Restart 保留旧转发表的假设也要成立,否则保留状态可能延长黑洞。

RPKI 起源验证比较路由前缀、起源 AS 与授权信息,可得到 Valid、Invalid、NotFound。Valid 不认证整个 AS_PATH,也不保证不存在路由泄漏;NotFound 不等于明确错误。是否丢弃或调整优先级需要策略兑现。RFC 6811:起源验证

核查时依次回答:收到什么、被哪条策略处理、为何获选或淘汰、NEXT_HOP 怎样解析、是否安装,以及真实包和回程是否通过。这样可以把“BGP 有路由但不通”拆成具体可验证的问题。

本地推演:前缀与策略先后

from ipaddress import ip_network, ip_address

def lookup(address, entries):
    matches = [(ip_network(prefix), hop) for prefix, hop in entries
               if ip_address(address) in ip_network(prefix)]
    return max(matches,key=lambda item:item[0].prefixlen)[1] if matches else None

main = [('0.0.0.0/0','default'),('203.0.113.0/24','A'),('203.0.113.128/25','B')]
assert lookup('203.0.113.140',main) == 'B'
assert lookup('203.0.113.20',main) == 'A'
policy_table = [('0.0.0.0/0','C')]
assert (lookup('203.0.113.140',policy_table) or lookup('203.0.113.140',main)) == 'C'

# 仅模拟前序条件一致时 LOCAL_PREF 与 AS 序列长度两项。
paths = [('A',200,[64501,64502,64503]),('B',100,[64504,64503])]
def best(candidates):
    return min(candidates,key=lambda x:(-x[1],len(x[2])))[0]
assert best(paths) == 'A'
paths[0] = ('A',100,[64501,64502,64503])
assert best(paths) == 'B'
assert min(10+10,5+30) == 20
print('最长前缀、策略表优先、两项 BGP 候选与路径代价检查通过')

这不是完整 BGP 实现,也不模拟 MED、路由反射或收敛计时。

继续查阅

  • IPv4 协议:地址、下一跳与转发字段。
  • ICMP 与 PMTUD:路径观测与错误反馈。
  • TCP:网络路径之上的可靠传输。