第187篇:SRv6 转发流程与 End/End.X SID
关键词:SRv6转发、End行为、End.X行为、Segment Left、IPv6目的路由、跨域转发
一、引言
SRv6 的转发流程与传统 IPv6 转发有本质区别。在传统 IPv6 中,报文的目的地址就是最终目的地;在 SRv6 中,报文的目的地址是当前待处理的 Segment(中间节点或终点)。理解 SRv6 的转发流程,关键在于掌握 Segments Left 计数器的变化规律以及 End 和 End.X 两种基本行为的处理逻辑。
二、核心概念
2.1 SRv6 SID 行为(Behavior)总览
| 行为 | 名称 | 说明 |
|---|---|---|
| End | IPv6 终结 | 在本地执行 IPv6 路由转发 |
| End.X | IPv6 跨域转发 | 弹出 SRH,基于内层报文执行 IP 转发 |
| End.DT6 | 查 SRv6 转发表 | 基于 SRv6 转发表(非传统 IPv6 路由表)转发 |
| End.DT4 | IPv4 查 SRv6 转发表 | 内层为 IPv4 时的查表转发 |
| End.B6 | 聚合 SID 查表 | 基于聚合 SID 查表 |
| End.T | 翻译 | IPv6 到 IPv4 翻译(NAT64) |
2.2 End 行为(IPv6 终结转发)
End 是 SRv6 中最基本的行为,当报文的目的地址匹配本地 Node-SID 时触发:

End 行为处理步骤详解:
| 步骤 | 操作 |
|---|---|
| 1 | 检查报文目的地址是否匹配本地 SID |
| 2 | 如果 Segments Left = 0,执行 SID 关联的终结函数 |
| 3 | 如果 Segments Left > 0,递减 Segments Left |
| 4 | 将 IPv6 目的地址更新为 Segment List[Segments Left] |
| 5 | 按更新后的目的地址做 IPv6 转发 |
2.3 End.X 行为(跨域转发)
End.X 用于跨域场景,当 Endpoint 同时也是通往客户网络的出口时,需要弹出 SRH 并基于内层报文做转发:

End.X 行为处理步骤:
| 步骤 | 操作 |
|---|---|
| 1 | 检查报文目的地址是否匹配本地 SID |
| 2 | 弹出整个 SRH 扩展头 |
| 3 | 报文恢复为原始 IPv6 报文(目的地址为原始目的) |
| 4 | 基于原始目的地址执行标准 IPv6 路由查找 |
| 5 | 将报文转发到查找结果对应的出接口 |
2.4 End vs End.X 对比
| 特性 | End | End.X |
|---|---|---|
| SRH 处理 | 保留 SRH,递减 Segments Left | 弹出 SRH |
| 转发依据 | 下一个 SID(SRH 内) | 内层报文的目的地址 |
| 适用场景 | 中间 Segment(路径中点) | 最终 Segment(出口节点) |
| Segments Left | 递减后 > 0(继续处理) | 递减后 = 0(终结 SRv6) |
| 标签栈类比 | 类似 SR-MPLS 的 Pop+暴露下一层 | 类似 SR-MPLS 的 Pop+IP 转发 |
三、技术细节
3.1 SRv6 完整转发流程

3.2 Segments Left 计数器详解
Segments Left 是 SRH 中的核心计数器,标识下一个待处理的 Segment 在 Segment List 中的索引位置:
| 时刻 | Segments Left | 说明 |
|---|---|---|
| 报文发出 | N-1 | N 个 Segment,当前处理第一个(索引从0开始) |
| 到达第1个 Segment | N-1 | 递减为 N-2 |
| 到达第2个 Segment | N-2 | 递减为 N-3 |
| ... | ... | ... |
| 到达最后一个 Segment | 0 | 执行终结行为,不再递减 |
示例:3 个 Segment 的路径 [SID_A, SID_B, SID_C]
| 节点 | Segments Left(处理前) | 操作 | Segments Left(处理后) | 新目的地址 |
|---|---|---|---|---|
| Head-End | 初始化=2 | - | - | SID_A |
| RouterA | 2 | End, 递减 | 1 | SID_B |
| RouterB | 1 | End, 递减 | 0 | SID_C |
| RouterC | 0 | End.X, 弹出 SRH | N/A | 原始目的 |
3.3 SRv6 转发表(SID Binding)
| SID | Behavior | Locator | 下一跳 | 说明 |
|---|---|---|---|---|
| 2001:DB8:1000::1 | End | NODE-A | - | 本地 Node-SID |
| 2001:DB8:1000::2 | End | NODE-B | 2001:DB8:FEED::2 | 远端 Node-SID |
| 2001:DB8:1000::8001 | End | NODE-A | 2001:DB8:FEED::2 | 本地 Adj-SID |
| 2001:DB8:2000::1 | End.X | GATEWAY | - | 出口 Node-SID |
3.4 SRH 处理开销分析
| 场景 | SRH 长度 | 额外开销 | 说明 |
|---|---|---|---|
| 2 个 Segment | 32 字节 | 32 字节 | Segment List 2 × 16 字节 |
| 4 个 Segment | 48 字节 | 48 字节 | Segment List 4 × 16 字节 |
| 8 个 Segment | 80 字节 | 80 字节 | 最大建议 8 个 Segment |
| SR-MPLS 对比 | 8 字节/标签 | 24 字节/3标签 | SRv6 开销显著大于 SR-MPLS |
四、实战配置/案例分析
4.1 End 行为配置
# ========== End行为配置(RouterB作为中间节点) ==========
[SRv6-RouterB] srv6
[SRv6-RouterB-srv6] sid 2001:DB8:1000::2 behavior End
# Node-SID, End行为(IPv6本地转发)
[SRv6-RouterB] srv6 locator NODE-B
[SRv6-RouterB-srv6-locator-NODE-B] prefix 2001:DB8:1000::/48
[SRv6-RouterB-srv6-locator-NODE-B] length 128
[SRv6-RouterB-srv6-locator-NODE-B] behavior End
# Locator默认行为为End
4.2 End.X 行为配置
# ========== End.X行为配置(出口节点) ==========
[SRv6-Gateway] srv6
[SRv6-Gateway-srv6] sid 2001:DB8:2000::1 behavior End.X
# End.X行为, 弹出SRH后转发内层报文
[SRv6-Gateway] srv6 locator GATEWAY-LOC
[SRv6-Gateway-srv6-locator-GATEWAY-LOC] prefix 2001:DB8:2000::/48
[SRv6-Gateway-srv6-locator-GATEWAY-LOC] length 128
[SRv6-Gateway-srv6-locator-GATEWAY-LOC] behavior End.X
# ========== 验证End.X路由 ==========
[SRv6-Gateway] ipv6 route-static 2001:DB8:CAFE::/48 2001:DB8:LAN::1
# 确保End.X弹出SRH后,内层报文目的地址有路由
4.3 故障排查:End.X 节点丢包
故障场景:SRv6 报文到达 End.X 节点后丢失,内层报文未转发到客户网络。
# Step 1: 检查SID行为配置
<SRv6-Gateway> display srv6 sid 2001:DB8:2000::1
SID: 2001:DB8:2000::1
Behavior: End.X
State: Active
# SID配置正常
# Step 2: 抓包分析
<SRv6-Gateway> packet-capture interface 100ge 1/0/1
# 收到SRv6报文,目的=2001:DB8:2000::1,携带SRH
# 但未看到发出的内层报文
# Step 3: 检查内层路由
<SRv6-Gateway> display ipv6 routing-table 2001:DB8:CAFE::10
# 无匹配路由!
# 根因: End.X弹出SRH后,内层报文目的地址(2001:DB8:CAFE::10)无路由
# Step 4: 添加内层路由
[SRv6-Gateway] ipv6 route-static 2001:DB8:CAFE::/48 2001:DB8:LAN::1
# Step 5: 检查SRH是否被正确弹出
<SRv6-Gateway> display srv6 statistics
# 检查End.X处理计数器
End.X Processed: 100
End.X Dropped: 50
# 仍有50%丢包
# Step 6: 检查SRH长度限制
<SRv6-Gateway> display current-configuration | include srv6
# 发现SRH最大Segment数配置为2
# 根因: SRH包含4个Segment,超出限制
# Step 7: 调整SRH最大Segment数
[SRv6-Gateway] srv6
[SRv6-Gateway-srv6] max-segments 8
# 最大Segment数调整为8
# Step 8: 最终验证
<SRv6-Gateway> display srv6 statistics
End.X Processed: 200
End.X Dropped: 0
# 丢包清零
五、总结
| 项目 | 要点 |
|---|---|
| End 行为 | 保留 SRH,递减 Segments Left,更新目的地址继续转发 |
| End.X 行为 | 弹出 SRH,基于内层报文目的地址执行 IP 转发 |
| Segments Left | 索引计数器,初始值为 N-1(N 为 Segment 数量),到达最后一个 Segment 时为 0 |
| 适用场景 | End 用于路径中间节点,End.X 用于出口节点(跨域场景) |
| 转发表 | SID → Behavior → 下一跳,通过 IS-IS/BGP-LS 分发 |
| 开销 | SRv6 SRH 开销(32~80 字节)远大于 SR-MPLS 标签栈(8~24 字节) |
思考
- End 行为和 End.X 行为的根本区别是什么?为什么 End.X 需要弹出 SRH 而不是继续处理下一个 Segment?
- 如果一个 SRv6 路径包含 5 个 Segment,Segments Left 的初始值是多少?报文到达每个 Segment 后 Segments Left 如何变化?
- End.X 节点弹出 SRH 后执行内层 IPv6 路由查找。如果内层是 IPv4 报文(如 IPv4 over SRv6),End.X 能否正确转发?如果不能,应该使用什么行为?
下篇预告:第188篇:SRv6 TE Policy 与 Color 选路