摘要

  • ECMP 表示路由器有多个代价相同的有效下一跳,并不证明这些路径的 MTU、时延、分组顺序或组播作用相同。
  • RFC 2991 比较了让同一流留在一条路径上、并在下一跳集合变化时限制重新分配范围的方法;不同算法用不同的计算成本换取稳定性。

一条 traceroute 能记录探测分组走过的路,却未必能揭示路由器当时还有哪些候选下一跳,更无法说明其他流量如何分配。这里的“相等”很容易被读得过宽:它说的是路由代价相同,不是物理路径表现一致。

2000 年 11 月,Dave Thaler 与 Christian Hopps 发布了信息性文件 RFC 2991,讨论单播和组播中的多路径下一跳选择。OSPF 与 IS-IS 明确允许等价多路径;一些路由器实现也把这种方式用于 RIP 等协议。对同一目的地址,一旦出现多个有效下一跳,转发设备仍得决定每个分组交给谁。

轮流把分组送往不同出口,看起来能平均分担流量;但同一条会话于是可能跨越 MTU 和时延各异的路径。路径 MTU 发现不再面对稳定条件。较早发送的分组晚到时,TCP 可能先收到后续序号,把这种乱序当作丢包信号,触发快速重传,增加带宽消耗和缓存压力。Ping 与 traceroute 也可能分别看见不同分支,拼出误导性的路径图。组播的要求更硬:RFC 所讨论的协议构造一棵通向源、核心或汇聚点的树,并依靠朝树根的单一下一跳抑制环路与重复分组。逐包轮换不只是改变流量外观,而会触及树的结构假设。

RFC 2991 用“流”指路由器保存状态的粒度——如果它保存状态的话。它不必等于 RFC 2474 所说的五元组微流。实现可以只看目的地址,也可以看源地址、目的地址和协议号。非首片可能没有传输层端口;把端口纳入路径选择,还可能妨碍同一端点后续连接复用 MTU 等路径缓存。因而“一个流是什么”并非无关紧要的术语问题,而是实现自行划定的控制边界。

让同一流固定走一条路径,可以避免会话内部不断换路;但下一跳加入或退出时,新的问题随即出现:多少既有流必须改道?启用 ECMP 后,更多路由成员的变化会直接触及正在转发的流量。RFC 因此同时看两笔账:转发计算要足够轻,拓扑变化造成的流量扰动要尽量小。

Modulo-N 哈希计算便宜:对流标识求哈希,再对下一跳数取模。但下一跳数量变化时,RFC 给出的比例是 (N-1)/N 的流会换路。阈值哈希把哈希空间划成各下一跳的区域;区域边界移动时,只有一部分结果改变,不过增删一个成员仍可能令四分之一到二分之一的流重新分配。RFC 2992 对阈值算法的扰动范围作了分析。最高随机权重(HRW)则分别对流和每个候选下一跳计算哈希,并选取结果最高者;单个成员变动约影响 1/N 的流,计算量约为 Modulo-N 的 N 倍。

这些比例是给定算法模型下的推导,不是生产网络的测量值;分母是“流”,不是字节、用户、业务或受影响程度。少量长流可能承载大部分字节,所以按流数均衡不能自动推出容量均衡。

转发器是否保存流状态,决定了计算何时发生。若已有状态,可以在创建状态时选定下一跳,而不必每个分组都重算。RFC 建议有状态单播以及保存源/组状态的组播采用 HRW;没有单播流状态时,路由器得在分组到达时计算,当 CPU 比路径稳定性更紧要时,建议使用阈值哈希。这是带有前提的工程取舍,不是脱离架构的通用排名。

2011 年的 RFC 6438 仍把均衡路径份额、避免同一流乱序、充分利用链路列为可能互相牵制的目标。它表明这个选择长期存在,却不能证明每台设备都采用 RFC 2991 的具体算法。

这段历史的关键在于不要让一个层次替另一个层次作证:路由代价用于筛选候选,转发选择器为流量分配路径,物理路径决定真实 MTU 与时延,传输端再根据收到的分组作出反应。稳定性需要计算或承受不均衡;重新分配则让既有流暴露于拓扑变化。路由表上的“等价”不能替网络选好这笔成本。

可预测性也是控制面

RFC 2991 还提醒实现者,流到下一跳的映射不能只按分布是否均匀来评价。如果外部可以轻易预测或操纵散列结果,攻击者就可能刻意把大量流量压向一个下一跳。一个在平均条件下平衡良好的选择器,仍可能在对抗条件下暴露集中风险。这里不能把“随机权重”误读成密码学安全保证:RFC 讨论的是分配算法及其扰动性质,而不是给出一套抗攻击的密钥管理方案。实现需要把散列输入、种子或其他本地秘密的生命周期纳入安全边界,并在轮换这些参数时评估它们是否会像下一跳成员变化一样引发大规模重映射。

这也解释了为什么后来只保存一张路由表快照不够。快照能够说明哪些下一跳曾经具有相同代价,却无法还原某个流当时为何落在其中一条路径上。若要让事故分析具有证据价值,至少还需要时间一致的候选集合、流键定义、算法与版本、实现参数,以及路径本身的 MTU、时延和可用性观测。缺少这些材料时,探测结果只能说明某次探测经历了什么,不能证明所有并发流共享同一路径,也不能证明重映射从未发生。

RFC 2991 因而留下了一个比具体算法更耐久的制度问题:谁有权改变选择器,改变时需要保留什么证据,又由谁承担变化的成本。路由协议可以在不宣布故障的情况下增删等价成员,设备升级可以改变散列实现,运维人员可以调整流键;这些动作都可能让业务看到一次真实的路径迁移。把它们仅仅归入“内部优化”,会遮蔽对外部流量的实际影响。明确记录选择器的控制权和变更历史,才可能把路由层的符号状态与转发层发生的事实重新对齐。

来源