两个客户用同一个 /24?VPNv4 需要 RD 和标签
两个租户之所以能宣告同一个 /24,只是因为 RD 给每条路由各自的标识。标签回答的是另一个问题:如何转发。
两个租户都把自己的分支机构编成 10.50.0.0/24,改动之后其中一个租户的路由在运营商边缘消失了,另一个却仍然正常。这类工单背后的简化做法通常是去掉路由区分符(RD),理由是「标签已经能识别客户」。这并不成立。RD 和标签回答的是两个不同的问题,只有在地址重叠逼出这个问题时,差别才会显现。
本该有两条路由的地方只剩一条
普通 IPv4 单播会比较通往同一前缀的两条路径,只安装较好的那一条。租户 A 的 10.50.0.0/24 和租户 B 的 10.50.0.0/24 是同一个键,于是一条胜出,另一条只作为备份路径存活。协议只是照做;真正被要求的是让控制平面把两条不同的路由存在同一个标识之下。
结果看起来像路由消失,而不是报错:竞争失败的那台 PE 仍在本地转发自己的租户,所以站内连通性测试成功,跨站测试失败。在动任何策略之前,先数一数 VPNv4 表里该前缀的条目。
RD 把一个键变成两个
八字节的路由区分符被加到 IPv4 前缀前面,BGP 承载的对象就变成 VPN-IPv4 地址,而不再是 IPv4 前缀。两个租户可以持有相同的 32 位,因为前面那 64 位不同。RD 有基于 AS 和基于地址两种格式类型,选择权在发起方 PE 手里。PE 共享同一个 AS 时常用基于 AS 的 RD,不共享时用基于地址的。
不要把 RD 读成成员标签。路由目标决定导入和导出,并决定哪些 VRF 可以安装该路由;RD 只保证这条路由拥有自己的标识。为每个 VRF 分配各自的 RD 是常见做法,因为这样在路由查看器里这种对应关系才读得清楚。
标签是本地转发指令
每条通告还会携带一个 MPLS 标签,其含义仅限于分配它的那台路由器。另一台 PE 可能把同一个编号发给毫不相关的目的地。正因如此,标签不能代替客户标识:这个编号只有紧挨着下一跳和安装它的转发状态时才正确。
分配粒度随实现和设计而不同:有的平台每个 VRF 分配一个标签,有的按前缀分配,标签也可能标识的是某个转发动作而不是客户。两个不同标签到达同一目的地并不矛盾,两台 PE 上出现相同标签号也不矛盾。
| Field | Where it lives | Scope | If you remove it |
|---|---|---|---|
| RD | VPNv4 NLRI | Per advertised route | Overlapping prefixes collide |
| Route target | Extended community | Import and export policy | Route lands in the wrong VRF |
| Label | Labeled NLRI and forwarding state | Per allocating router | No instruction for the data plane |
| Next hop | Path attribute | Per path | The label cannot be resolved |
为什么一个不能替代另一个
读一条通告,是把四样东西放在一起看:带 RD 的前缀、路由目标、下一跳和标签。读一个用户报文,是看由这些信息安装出来的栈。健康的设计显示两侧吻合,出问题的设计通常是一侧正确、另一侧过期。正是这种对照把标识问题和转发问题分开。
控制平面与数据平面这种整齐的对照是教学手段,而不是对编码的描述。 RFC 8277把标签放进带标签的 NLRI 里,所以通告本身携带了绑定关系;把它用于转发是之后独立的一步。
当某个租户的路由消失时,按这个顺序检查:该前缀是否有两条 VPNv4 条目、每条上的路由目标是否正确、下一跳是否可解析、接收方 PE 是否有对应标签的状态。用转发值去修标识,或者反过来,会通过一项检查而在下一项失败。