摘要

  • RFC 10018 让入口 PE 以 <Root, Tree-ID> 通告 SR P2MP P-tunnel,并通过 MVPN/EVPN Auto-Discovery 路由形成叶集合;这些都是有边界的控制面事实,不是控制器、每台复制节点和最终接收者共同签署的交付证明。
  • 多点业务只有在同一候选路径与 PTI Instance-ID 下,把应到、已通告、控制器已接纳、复制段已装入、FIB 已生效、OAM 已响应和正确业务载荷已收到的叶集合逐项对齐,才有资格结案;撤回也必须拥有对称的终态证据。

一棵树不能只数“绿灯”,要数回执

设想一次面向十二个站点的广播变更。入口设备通告正常,控制器显示 ACTIVE,总流量与基线只差几个百分点,十一处探针持续收到数据。值班人员很容易把异常归入“远端应用问题”,因为网络图上整棵树都是绿色。第十二处站点却从切换时刻起没有收到一个有效载荷。

这不是反常边角,而是点到多点系统最典型的偏差。点到点故障常把整个会话拉红;多点故障可能只丢一条分支。多数叶子替少数叶子制造了健康外观,汇总指标于是从观测工具变成遮蔽物。

RFC 10018 的价值,在于把此前分散的服务成员与 Segment Routing 多点树连接起来。MVPN 或 EVPN 可以在 BGP Auto-Discovery 路由的 PMSI Tunnel Attribute 中通告 SR-MPLS 或 SRv6 P2MP P-tunnel;入口 PE 据此维护 SR P2MP Policy 的候选路径和叶集合,控制器再计算并实例化 P2MP Tree Instance(PTI)。RFC 同时保留另一条完全不同的路:入口复制,也就是入口 PE 为每个出口单独复制并走单播。

标准把交换什么、怎样命名、何时加入或撤回写清楚了。它没有声称自己能看见控制器内部是否真的完成计算、每台设备是否装入正确 Replication-SID、远端是否绑定到正确 MVPN/EVI,或接收程序是否得到内容。标准越精确,运营者越不应给它附加不存在的证明能力。

第一份名单来自业务,第二份来自 BGP,第三份在控制器里

多点交付至少有三份叶名单。

第一份是业务意图:合同、租户配置或服务编排决定哪些出口 PE 本应收到内容。它回答的是“谁应当在树上”。

第二份来自协议。MVPN 场景中,入口 PE 导入相应的 Intra-AS I-PMSI 或 Leaf A-D 路由后,把出口 PE 加入叶集合;路由撤回时再移除。出口 PE 导入入口侧相关通告后,以 Leaf 或 Bud 身份加入;当 PTA 设置了 Leaf Information Required 标志时,还必须起源 Leaf A-D 路由。EVPN 使用 IMET、S-PMSI 与 Leaf A-D 路由完成相应生命周期。

第三份存在于控制器所处理的当前候选路径中。入口侧 SR P2MP Policy 模块需要把候选路径、约束、优化目标和更新后的叶集合交给控制器。RFC 10018 提到 PCEP、BGP、NETCONF 等可能方式,同时明确说具体机制不在本文范围之内。

这三份名单的数量可能相同,成员却不同。旧叶已在 BGP 撤回,但控制器尚未消费更新;新叶已经起源 Leaf A-D,入口模块却在队列阻塞后仍显示旧版本;业务编排要求十二个出口,协议层因为策略或导入问题只认出十一个。仅比较 count=12 会错过真正的差集。

运营记录必须给名单加版本。应写成“业务版本 48 要求 PE-A 至 PE-L;入口在 10:02:11 形成叶集版本 184;控制器修订 921 消费它;PTI Instance-ID 37 包含同一批叶”,而不是一句“leaf count 12”。时间与版本不是审计装饰,它们决定了几份事实能否互相证明。

<Root, Tree-ID> 是地址,不是竣工证

RFC 10018 在 PTA 中用 <Root, Tree-ID> 标识 SR P2MP Policy。编码顺序是 Tree-ID 在前、Root IP 在后;Tree-ID 是在该 Root 上唯一的 32 位无符号值。IANA 把 0x0C 分配给 SR-MPLS P2MP Tree,把 0x0D 分配给 SRv6 P2MP Tree。

这个标识能让两个实现谈论同一策略对象,但它没有包含 PTI 的完整运行历史。一个策略可以有多个候选路径;一个候选路径可能因为控制器无法满足约束而没有 PTI;在 make-before-break 中,同一候选还可能短暂存在新旧两个 PTI。按照 RFC 9960,同一候选只能有一个活动实例;若两个都处于活动状态,叶节点可能收到重复流量。

PTI 还拥有自己的 16 位 Instance-ID。逐节点复制段的控制面标识进一步包含 Root、Tree-ID、Instance-ID 与 Node-ID。到了这一级,“树已安装”才有可核对的对象:根上的复制段、每个中间复制点以及每个叶/芽节点上的本地状态,都属于同一个确切实例。

因此,Tree-ID 适合回答“这是什么策略”,Instance-ID 适合回答“这一次是哪棵具体的树”。若监控只保留前者,旧 PTI 的成功探针可以被误记到新 PTI;延迟到达的安装回执可以更新错误的变更;标识复用后,事故时间线甚至无法区分两次生命周期。

控制器的成功必须能拆到每台节点

RFC 9960 并不假装复制段安装永远成功。节点应报告成功;安装也可能失败,例如 Replication-SID 与本机其他 SID 冲突。节点应报告失败,最好附带原因。控制器应在有上限的次数内重试,并在最终失败后告警。部分复制段失败时,控制器可以决定拆除 PTI;根节点复制段安装失败时,文档建议拆除。

这里不存在一个由标准替所有业务做出的唯一决定。运营者可以规定:所有必要叶与中间节点确认后才允许激活;也可以在明确名单、期限与影响范围下接受部分树;还可以保留失败 PTI 供诊断,但绝不让它承载生产流量。协议提供动作边界,服务责任人选择容错政策。

RFC 9960 给出一种很有启发性的实例化顺序:先安装叶与中间复制段,全部成功后再安装根节点,随后才激活。它把“根最后开闸”的安全逻辑说得很清楚,却不证明任何具体控制器都照此执行。采购与变更评审应要求供应方回答:何时把状态称为 ACTIVE?是在完成计算后、发完请求后、收到全部确认后,还是根 FIB 真正指向该实例后?

一个只给整棵树一个绿灯的控制器,把最需要管理的信息压扁了。可靠接口应返回每个 Node-ID 的请求版本、Replication-SID、确认或失败、失败原因、重试次数、终态与时间;汇总状态只能由一条公开的决策规则从这些事实推导。

抵达叶节点,也可能进入错误的业务

Tree-SID 是 PTI 的数据面标识。Root 把载荷封装进 Tree-SID,中间节点按照 Replication segment 复制,叶节点移除 Tree-SID 并交付。这条路径解决“怎样沿树前进”,不一定解决“落到哪个租户或实例”。

当一棵 P-tunnel 只服务一个 MVPN 时,Tree-SID 可以足以识别 MVPN 上下文。多项 MVPN 共用一棵树时,还需要 upstream-assigned MPLS label 或 SRv6 Multicast Service SID 作为业务上下文。RFC 10018 为 SRv6 MVPN 定义了转置约束,并引入 End.DTMC4、End.DTMC6 与 End.DTMC46;IANA 分配的代码点分别为 76、77、78。

于是会出现一种比“完全收不到”更隐蔽的失败:包走过正确的 PTI,到了正确出口 PE,却因 service SID、label、转置参数或本地绑定错误而进入错误 MVPN,或根本无法执行正确的多播表查找。树的 OAM 可以绿,租户业务仍是错的。

EVPN 还有单独的 split-horizon 问题。Ethernet Segment 多归属需要过滤重复 BUM 流量;SR-MPLS 依赖 ESI label 的栈位置,SRv6 使用 End.DT2M 的 Arg.FE2。一处叶子“收到包”不是绝对好消息:它也可能收到了本应因分割视界被过滤的副本,甚至重复交付。

所以最终证据不能只写“reachable”。它必须绑定 PTI、业务上下文、叶、预期副本数量和载荷结果。Tree-SID 是转发句柄,不是租户授权,也不是应用回执。

入口复制是另一条责任链

RFC 10018 也规定了 over SR 的 ingress replication。入口 PE 为每个出口制作一份副本,并通过单播转发送达;SR P2MP Policy 模块和控制器不参与。

这不是“同一棵树规模较小”。它改变了故障归属与证据形状。入口复制需要核对每个出口的成员状态、业务标识、匹配的单播/SR-TE policy、实际副本与收包结果。SR P2MP 则必须核对控制器计算、PTI、拼接的复制段、活动实例和树 OAM。

两种模式在流量工程上也不同。入口复制可以根据出口提供逐出口处理;P2MP 在 PTI 内复制,入口为整棵树指定一种处理,不能对每个叶分别套用不同 TE。把两者放进一个“multicast over SR”绿灯,会让故障调查找错系统。

故障切换同样需要版本。若从 P2MP 临时退回入口复制,记录必须证明旧 Root 何时停止注入、逐出口副本何时开始、是否发生重叠、旧 PTI 何时去编程。否则“恢复覆盖”可能同时制造重复交付。

OAM 要问的是“哪一个实例”,而不是“这棵树大概通不通”

RFC 9961 为 SR P2MP Policy 定义 ping 与 traceroute。探针针对确切候选路径与 PTI,沿对应 Replication segment 被复制,各叶向 Root 返回响应。实现应能分别测试每个候选及其 PTI,包括当前不活动的实例。

这在 make-before-break 中尤其重要。旧 PTI 回答正常,不能替新 PTI 作证,即使两者共享 Root 与 Tree-ID。探针记录需要 Instance-ID、时间、应答叶清单、超时叶清单和当时的活动状态。

非相邻复制段又暴露一条边界。P2MP OAM 测试复制结构,而连接两段的单播路径可能还要用单播 OAM;RFC 9961 明确不把后者的故障探测收入自身范围。一个层面的成功不应自动填补另一层未执行的测试。

即使所有叶都回复了 OAM,也还差最后一步。诊断包证明某个确切转发上下文处理了探针,不证明生产包用了正确 service SID,不证明丢包与抖动符合承诺,不证明 split horizon 正确,更不证明接收进程接受了内容。

因此需要逐叶 payload canary:带序列号的测试帧、可归因的内容标记、与业务上下文绑定的接收计数或应用级确认。实现方式可以本地决定,但 canary 必须带上与前面相同的 PTI 版本键。

用差集结案,而不是用一句“已恢复”

一套可执行的模型可以把叶分为八个集合:

  • E:业务合同规定应当存在的出口;
  • A:当前 A-D/Leaf A-D 状态中的出口;
  • C:控制器对当前候选路径实际接纳的叶;
  • I:同一 PTI 下到该叶的必要复制段均成功安装;
  • F:活动 PTI 的当前转发面确实覆盖该叶;
  • O:对确切候选与 Instance-ID 的 OAM 有响应;
  • D:在正确 MVPN/EVI 上下文中收到预期载荷;
  • W:退出后已证明撤回、去编程并经过静默期的叶。

严格服务可以要求激活前 E = A = C = I = F = O = D。允许降级的服务可以批准一个明确子集,但差集必须有责任人、原因、受影响客户、到期时间与恢复条件。成员退出只有在活动集合中消失,并在 W 中留下终态后才算完成。

这个模型把“谁的问题”变成可分派的问题:E − A 是业务/协议成员差异;A − C 是控制器消费漂移;C − I 是安装未完成;I − F 质疑成功回执与实际转发;F − O 是路径或诊断异常;O − D 则把调查推进到业务语义与应用结果。

集合数量相等仍不够,成员与版本也必须相等。十二个 OAM 回执若包含一处已撤回旧叶,同时漏掉一处新叶,不能证明十二个当前目标都健康。

公开资料能证明什么,不能证明什么

RFC 10018、RFC 9960、RFC 9961 与相关基础 RFC 证明的是架构、编码、状态转换和诊断能力。它们不证明任何具名运营者采用了这些机制,不证明某产品支持所有选项,也不证明现实中存在本文设想的第十二个黑暗叶子。

IANA 表能证明隧道类型和 endpoint behaviour 已获得共同代码点,不能证明运行二进制实现、安装或执行了它们。Standards Track 也不等于强制部署。IETF 提供公共语义,不运营某家网络的树,更不替本地团队承担激活与交付责任。

本文的假设案例只是控制测试。标准资料说明部分状态为何可能出现,以及怎样把原因分开;它们没有提供故障频率、客户损失、厂商归因或采用比例。

这与 Lu Heng 的运行代码优先相吻合:文档或机构声称的效果,必须接受运行面证据的约束。同时,最小初始规范、本地化未来决策与自愿采用提醒我们,共同规范可以保持精确,部署、容错和风险决定仍属于本地责任。

运行状态也不是自动正确。陈旧 FIB、过期控制器拓扑或已失去授权却仍在收包的叶,都可能真实存在。优先的是可观测事实对主张的纠正能力,而不是让事实脱离协议语义与服务合同。

来源