5. 路由实现注意事项 (Routing Implementation Considerations)
从有类网络号 (classful network numbers) 转向无类前缀 (classless prefixes) 后, 就无法再根据 IPv4 地址的初始位模式推断网络掩码. 这会影响路由信息的存储和传播方式. 路由协议必须显式携带网络掩码或前缀长度. 内部路由协议 (interior routing protocols), 例如 OSPF [RFC2328], Intermediate System to Intermediate System (IS-IS) [RFC1195], RIPv2 [RFC2453], Cisco Enhanced Interior Gateway Routing Protocol (EIGRP), 以及 BGP4 外部路由协议 [RFC4271], 都支持这一功能; 它们是在 1990 年代部署无类域间路由期间开发或修改的.
较旧的内部路由协议, 例如 RIP [RFC1058], HELLO 和 Cisco Interior Gateway Routing Protocol (IGRP), 以及较旧的外部路由协议, 例如 Exterior Gateway Protocol (EGP) [RFC904], 不支持显式携带前缀长度/掩码, 因而除了非常有限的桩网络 (stub) 配置外, 无法在 Internet 上有效使用. 虽然它们在简单的遗留终端站点配置中可能适用, 但它们被视为已过时, 不应该在连接到全球 Internet 的传输网络中使用.
类似地, 第 3 层网络设备中的路由表和转发表必须组织为同时存储前缀以及前缀长度或掩码. 按照遗留 Class A/B/C 网络/子网约定来组织路由/转发信息的设备, 不能指望其在连接到全球 Internet 的网络上正确工作; 不建议使用这类设备. 幸运的是, 目前此类设备的使用已经很少.
5.1. 路由通告规则 (Rules for Route Advertisement)
-
Internet 中的转发按最长匹配 (longest-match) 执行. 这意味着, 相对于某个路由域 (routing domain) 而言是多宿主的目的地, 必须始终显式通告到该路由域中 (即不能被汇总). 如果一个网络是多宿主的, 那么它进入网络层次结构中 "更高" 路由域的所有路径, 都必须被这个 "更高" 网络获知.
-
为多条更具体路由 (more-specific routes) 生成聚合路由的路由器, 必须丢弃那些匹配聚合路由但不匹配任何更具体路由的分组. 换言之, 聚合路由的 "next hop" 应当是空目的地 (null destination). 当聚合覆盖的某些地址不可达时, 这是防止转发环路所必需的.
请注意, 在故障期间, 对某个站点的流量可能出现部分路由: 该站点的地址空间来自一个服务提供商, 但实际只能通过另一个服务提供商到达 (即站点已经更换服务提供商的情况), 因为这类流量会沿聚合路由通告的路径转发. 规则 #2 会使这类流量被聚合路由的通告者丢弃, 从而防止分组误投递; 但 "traceroute" 和其他类似工具的输出会暗示问题出在该网络内部, 而不是出在那个不再通告更具体前缀的网络中. 这可能让诊断连通性问题的人感到困惑; 详见第 6.2 节中的示例. 对此感知到的 "问题" 的解决方案超出了本文档范围; 它依赖于对用户/运营者群体进行更好的教育, 而不是路由技术本身.
遵循这些规则的实现还应当被泛化, 以便对所有路由目的地接受任意网络号和掩码. 唯一剩余的约束是掩码必须左连续 (left contiguous). 请注意, 到前缀 0.0.0.0/0 的退化路由用作默认路由, 所有实现都必须接受它. 此外, 为防止通过域间协议意外通告此路由, 只有在路由器被显式配置为这样做时, 才应向另一个路由域通告此路由; 绝不能将其作为未配置的 "default" 选项通告.
5.2. 这些规则如何工作 (How the Rules Work)
规则 #1 保证所使用的转发算法在不同路由协议和实现之间保持一致. 多宿主网络始终由承载其路由的每个服务提供商显式通告, 即使它们是某个服务提供商聚合路由的一个具体子集 (如果不是子集, 显然更必须显式通告). 看起来 "主" 服务提供商似乎可以将多宿主站点作为其聚合的一部分隐式通告, 但最长匹配转发会使这种做法无效. 更多细节见 [RFC4116].
规则 #2 保证不会因聚合形成路由环路. 考虑一个站点, 它从其 "父" 提供商获得了 192.168.64/19, 而该提供商拥有 192.168.0.0/16. "父" 网络会向 "子" 网络通告 192.168.0.0/16. 如果 "子" 网络丢失了到 192.168.65.0/24 (它是其聚合的一部分) 的内部连通性, 从 "父" 到 "子" 且目的地为 192.168.65.1 的流量会遵循 "子" 所通告的路由. 然而, 当该流量到达 "子" 时, 子网络绝不能沿 192.168.0.0/16 路由返回 "父", 因为这会导致转发环路. 规则 #2 表明, 对于匹配自身某条聚合路由的目的地, "子" 不能遵循一条不那么具体的路由 (通常的实现方式是, 对一个网络向另一个网络通告的所有聚合前缀安装一条 "discard" 或 "null" 路由). 请注意, "default" 路由 (0.0.0.0/0) 的处理是此规则的一个特殊情况; 对于属于自身某条聚合通告的目的地, 网络不能遵循默认路由.
5.3. 关于前缀过滤器格式的说明 (A Note on Prefix Filter Formats)
处理路由通告的系统必须能够根据策略规则验证其收到的信息是否可接受. 过滤路由通告的实现必须允许过滤元素中包含掩码或前缀长度. 因此, 过去写成如下形式的过滤元素:
accept 172.16.0.0
accept 172.25.120.0.0
accept 172.31.0.0
deny 10.2.0.0
accept 10.0.0.0
现在看起来类似这样:
accept 172.16.0.0/16
accept 172.25.0.0/16
accept 172.31.0.0/16
deny 10.2.0.0/16
accept 10.0.0.0/8
这只是把过去由网络号的 Class A/B/C 分类所隐含的网络掩码显式写出. 增强过滤能力也很有用, 使其能够匹配某个前缀以及具有相同位模式的所有更具体前缀; 幸运的是, 大多数用于 Internet 的设备厂商已经实现了这一功能.
5.4. 聚合的责任与配置 (Responsibility for and Configuration of Aggregation)
在正常情况下, 已被分配或指派一组前缀的路由域 (或 "Autonomous System") 对这些前缀的聚合负有唯一责任. 在通常情况下, AS 会在其一个或多个路由器上安装配置, 基于其内部路由系统已知的更具体路由生成聚合路由. 这些聚合路由由该路由域的边界路由器通告到全球路由系统中. 与聚合路由重叠的更具体内部路由不应被全局通告. 在某些情况下, 一个 AS 可能希望把聚合责任委托给另一个 AS (例如, 客户可能希望其服务提供商代表自己生成聚合路由信息); 在这种情况下, 聚合由第二个 AS 中的路由器执行, 依据是它从第一个 AS 收到的路由, 并结合描述这些路由应如何聚合的已配置策略信息.
请注意, 一个提供商可能会在没有明确协议的情况下, 选择对从另一个提供商收到的路由执行聚合; 这称为 "代理聚合" (proxy aggregation). 这是减少一个 AS 必须承载并传播给其客户和邻居的路由状态量的有用工具. 然而, 代理聚合也可能在流量工程中产生非预期后果. 考虑如下情况: AS 2 和 AS 3 都从 AS 1 接收路由, 但 AS 2 执行代理聚合而 AS 3 不执行. 其他同时从 AS 2 和 AS 3 接收传输路由信息的 AS, 将看到 AS 1 所发起路由信息的不一致视图. 这可能导致 AS 3 的客户以及任何从 AS 3 接收传输路由的其他方, 出现流量经由 AS 3 意外转向 AS 1 的情况. 由于代理聚合可能对 Internet 中既与聚合路由来源无关, 也与提供聚合的一方无关的部分造成未预料后果, 因此应极其谨慎地使用.
配置要合并为聚合的路由属于路由策略的实现, 需要一些手工维护的信息. 除了一组可路由前缀所必须维护的信息外, 聚合配置通常只是一两行, 用于定义要聚合的 IPv4 地址块范围. 执行自身聚合的站点之所以这样做, 是因为这些地址块已经分配给它; 代表另一个站点执行聚合的站点之所以知道这些信息, 是因为存在聚合委托协议. 假设网络管理员之间交换彼此可接受前缀列表是最佳通用实践, 那么配置聚合信息不会引入显著额外的管理开销.
聚合路由的生成通常通过静态方式指定, 或者在获知聚合路由所包含某个前缀的活动动态路由后触发. 如果执行这种动态聚合路由通告, 应注意避免过度添加或撤销路由 (称为 "路由抖动" (route flapping)). 通常, 当聚合中的至少一个组成部分变为可达时, 会添加动态聚合路由通告; 只有当所有组成部分都变为不可达时, 才会撤销该通告. 配置正确时, 聚合路由比非聚合路由更稳定, 因而会改善全球路由稳定性.
实现说明: "Class D" (multicast) 地址空间的聚合超出本文档范围.
5.5. 路由传播与路由协议注意事项 (Route Propagation and Routing Protocol Considerations)
在 CIDR 最初部署之前, 常见做法是把通过外部路由协议 (即 EGP 或 BGP) 学到的路由, 经由站点的内部路由协议 (通常为 OSPF, IS-IS 或 RIP) 传播. 这样做是为了确保向通过这些协议学到的目的地发送流量时, 能选择一致且正确的出口点. 四个演进因素共同废弃了这种做法: CIDR 的出现, 全球路由状态的爆炸性增长, BGP4 的广泛采用, 以及传播完整路径信息的要求. 为确保正确的路径传播并防止 AS 间路由不一致 (BGP4 的环路检测/防止机制要求完整路径传播), 传输网络必须使用 internal BGP (iBGP) 在其网络内部以及穿越其网络时承载从其他提供商学到的路由.