跳到主要内容

2. IGMP 侦听推荐做法 (IGMP Snooping Recommendations)

以下各节列出 IGMP 侦听交换机的推荐做法。每条推荐做法先给出结论, 再补充一种可能的实现方式的说明。所有实现讨论都只是示例, 完全可能存在其他实现同样功能的方法。

2.1. 转发规则 (Forwarding Rules)​

IGMP 侦听功能分为控制部分 (IGMP 转发) 与数据部分 (数据转发)。

2.1.1. IGMP 转发规则 (IGMP Forwarding Rules)​

  1. 侦听交换机应当 (SHOULD) 只把 IGMP 成员关系报告转发到连接了组播路由器的端口。

换言之: 侦听交换机不应 (SHOULD NOT) 把 IGMP 成员关系报告转发到只连接主机的端口。可以提供一种管理控制来覆盖此限制, 允许把报告报文泛洪到其他端口。

这是控制路径上 IGMP 侦听的主要功能。

对于 IGMPv1 与 IGMPv2, 把成员关系报告发送给其他主机可能导致某台主机无意中无法加入特定的组播组。当 IGMPv1 或 IGMPv2 主机收到它打算加入的组地址的成员关系报告时, 该主机将抑制自己针对同一组的成员关系报告。这种加入/报文抑制是 IGMPv1 与 IGMPv2 主机的要求。但是, 如果交换机没有收到来自该主机的成员关系报告, 它就不会把组播数据转发给该主机。

在只有 IGMPv3 的网络中不存在此问题, 因为那里不抑制 IGMP 成员关系报告。

该管理控制使得 IGMP 成员关系报告报文可以被网络监控设备(例如数据包分析器或端口复制器)处理。

支持 IGMP 侦听的交换机必须 (MUST) 维护一份组播路由器及其所连接端口的列表。该列表可以通过以下方式的任意组合来构建:

  • a) 该列表应当 (SHOULD) 由侦听交换机发送 IGMP 组播路由器发现 [MRDISC] 中描述的组播路由器请求 (Multicast Router Solicitation) 报文来构建。它也可以侦听其他节点之间发送的组播路由器通告 (Multicast Router Advertisement) 报文。

  • b) 源地址不是 0.0.0.0 的 IGMP 查询(由组播路由器发送)的到达端口。0.0.0.0 地址表示一种特殊情况: 交换机为加快网络收敛而代理 IGMP 查询, 但它本身不是查询器 (Querier)。交换机不使用自己的 IP 地址(即使它有 IP 地址), 因为那样会使这些查询看起来来自新选出的查询器。0.0.0.0 地址用于表明这些查询报文不是来自组播路由器。

  • c) 由管理显式配置为 IGMP 转发端口的端口, 作为上述检测路由器端口方法的补充或替代。

  1. IGMP 网络中也可能包含实现 "代理报告 (proxy-reporting)" 的设备, 它们把从下游主机收到的报告汇总起来, 用于构建内部的成员关系状态。这类代理报告设备在向上游转发汇总报告时可能使用全零 IP 源地址。因此, 侦听交换机收到的 IGMP 成员关系报告不得 (MUST NOT) 因为源 IP 地址被设为 0.0.0.0 而被拒绝。

  2. 支持 IGMP 侦听的交换机必须 (MUST) 把所有无法识别的 IGMP 报文泛洪到其他所有端口, 并且不得 (MUST NOT) 试图使用超出网络层头部范围的任何信息。

此外, 较早版本的 IGMP 应按各自版本的定义解释 IGMP 字段, 并且在转发报文时不得 (MUST NOT) 修改这些字段。生成新报文时, 某个 IGMP 版本应按自身版本设置相应字段值。如果某些字段对某个 IGMP 版本是保留或未定义的, 解析报文时应忽略这些字段, 而该 IGMP 版本的实现生成新报文时必须 (MUST) 将这些字段置零。有例外情况: 交换机正在执行欺骗 (spoofing) 功能, 并且知道为正确欺骗另一个 IGMP 版本所需的新增或保留字段的设置。

之所以要关注这些细节, 是因为 IGMPv3 复用了旧 IGMP 查询报文的类型号 (0x11), 但使用了扩展头部。因此存在 IGMPv3 查询被例如 IGMPv2 侦听交换机当作旧版本查询解释的风险。这一点已被报告 [IETF56], 并在第 2.2 节中讨论。

  1. IGMP 侦听交换机应当 (SHOULD) 关注生成树 (Spanning Tree) 操作引起的链路层拓扑变化。当某个端口被生成树启用或禁用时, 可以在所有活动的非路由器端口上发送通用查询 (General Query), 以减少网络收敛时间。非查询器交换机应当 (SHOULD) 了解查询器是否处于 IGMPv3 模式。如果是, 除非交换机能够发送符合真实查询器最近所发送信息的 IGMPv3 查询, 否则不应 (SHOULD NOT) 欺骗任何通用查询。交换机在任何情况下都不得把欺骗的 IGMPv2 查询引入 IGMPv3 网络, 因为这可能造成严重的网络中断。

如果交换机不是查询器, 它在这些代理查询中应当 (SHOULD) 使用 '全零' IP 源地址(即使某些主机可能选择不处理源地址为 0.0.0.0 的查询)。收到这类代理查询时, 不得 (MUST NOT) 把它们计入查询器选举过程。

  1. 对于 IP 或 IGMP 头部存在校验和或完整性错误的 IGMP 报文, IGMP 侦听交换机不得 (MUST NOT) 使用其中的信息。交换机不应 (SHOULD NOT) 泛洪这类报文; 如果确实泛洪了, 也应当 (SHOULD) 对事件有所记录(例如递增计数器)。这些错误及其处理在 [IGMPv3]、[MLD] 与 [MLDv2] 中进一步讨论。

  2. 侦听交换机不得 (MUST NOT) 仅依赖 IGMP 离组 (Group Leave) 通告的出现来决定何时从转发表中删除表项。它应当 (SHOULD) 在其所有非路由器端口上实现成员关系超时机制, 例如 IGMP 与 MLD 规范中描述的 IGMP 协议的路由器侧功能(IGMPv1-3 与 MLDv1-2 见规范性引用一节)。该超时值应当 (SHOULD) 可配置。

2.1.2. 数据转发规则 (Data Forwarding Rules)​

  1. 目的 IP 地址在 224.0.0.X 之外且不是 IGMP 的报文, 应当 (SHOULD) 按基于组的端口成员关系表转发, 并且必须 (MUST) 同时在路由器端口上转发。

这是数据路径上 IGMP 侦听的主要功能。一种实现方式是在软件中分别维护成员关系表与组播路由器表, 然后把这两张表 "合并" 成转发表。

  1. 目的 IP (DIP) 地址在 224.0.0.X 范围内且不是 IGMP 的报文, 必须 (MUST) 在所有端口上转发。

该推荐做法基于以下事实: 许多主机系统在发送或监听 IP 组播报文之前, 不会为这一范围内的组播地址发送加入 (Join)。此外, 由于 224.0.0.X 地址范围被定义为链路本地(不可路由), 为这一范围中的每个地址保留状态似乎没有必要。另外, 有些路由器在 224.0.0.X 地址范围内工作而不发出 IGMP 加入; 如果交换机因为没有看到来自该路由器的加入组报文而剪除它们, 这些应用就会被破坏。

  1. 未注册报文定义为: 目的地址与先前 IGMP 成员关系报告中所通告的任何组都不匹配的 IPv4 组播报文。

如果交换机收到未注册报文, 它必须 (MUST) 把该报文转发到所有连接了 IGMP 路由器的端口。交换机可以默认在所有端口上转发未注册报文。不在所有端口上转发未注册报文的交换机, 必须 (MUST) 提供配置选项, 以便强制在指定端口上泛洪未注册报文。

在 IGMPv3 主机与尚不支持 IGMPv3 的侦听交换机混合的环境中, 交换机未能泛洪未注册流可能导致 v3 主机收不到自己的流量。反之, 在侦听交换机支持环境中出现的所有 IGMP 版本时, 泛洪未注册流可能使 IGMP 主机被组播流量淹没, 甚至到收不到查询、无法为自己的组发出新的成员关系报告的程度。

鼓励侦听交换机至少识别并处理 IGMPv3 加入报告, 即使该处理仅限于按 IGMPv2 加入的行为进行(即不考虑任何额外的 "包含源 (include source)" 或 "排除源 (exclude source)" 过滤)。当无法识别 IGMPv3 加入时, 侦听交换机可能错误地剪除这些组的未注册数据流(如上所述); 或者, 如果该组先前已作为 IGMPv2 加入, 交换机可能无法为任何新的 IGMPv3 主机添加转发(因为该数据流被视为已注册)。

  1. 所有非 IPv4 组播报文应当 (SHOULD) 继续按照正常 IEEE 桥接操作泛洪到处于转发状态的所有其余端口。

该推荐做法源于以下事实: 由 IPv4 主机与 IPv6 主机组成的组是完全独立、不同的组。因此, 从 IPv4 组成员之间的拓扑获得的信息, 在构建 IPv6 组成员之间的拓扑时不适用。

  1. IGMP 侦听交换机可以维护基于 MAC 地址或基于 IP 地址的转发表。如果交换机同时支持这两种转发表, 默认行为应当 (SHOULD) 使用 IP 地址。优先采用基于 IP 地址的转发, 是因为 IP 组播地址与链路层组播地址之间的映射是有歧义的。以以太网为例, 1 个以太网地址对应 32 个 IP 地址 [RFC1112]。

  2. 依赖 IP 头部信息的交换机应当 (SHOULD) 验证 IP 头部校验和是否正确。如果校验和失败, 不得 (MUST NOT) 把该报文中的信息纳入转发表。此外, 该报文应当 (SHOULD) 被丢弃。

  3. 当在共享网段上收到 IGMPv3 的 "包含源" 与 "排除源" 成员关系报告时, 交换机需要把所有收到的成员关系报告的超集转发到该共享网段。只要共享网段上至少有一台主机报告了类型为 INCLUDE(G, Slist1) 或 EXCLUDE(G, Slist2) 的 IGMPv3 成员关系, 就必须 (MUST) 转发来自特定源 S 到组 G 的流量, 其中 S 是 Slist1 的元素且不是 Slist2 的元素。

基于 (G,S1,S2,...) 的数据转发表的实际实现不在本文档的范围之内。不过, 一种可能的做法是维护两个 (G,S) 转发列表: 一个用于 INCLUDE 过滤器, 只有匹配特定 (G,S) 才发生转发; 另一个用于 EXCLUDE 过滤器, 匹配特定 (G,S) 将导致不转发。

在由 IGMPv3 路由器以及通过 IGMPv2 侦听交换机互联的 IGMPv2 与 IGMPv3 主机组成的网络中, 会出现一个特殊问题, 如最近所报告 [IETF56]。即使存在 IGMPv2 主机, 路由器仍会继续维持 IGMPv3, 因此网络不会收敛到 IGMPv2。但 IGMPv2 侦听交换机很可能无法识别或处理 IGMPv3 成员关系报告。于是这些无法识别的报告所对应的组要么被泛洪(在组播负载较重的网络中会给主机带来各种问题), 要么被侦听交换机剪除。

因此, 在此类网络中, 推荐把组播路由器配置为使用 IGMPv2。如果无法做到这一点, 而侦听交换机又无法识别并处理 IGMPv3 成员关系报告, 则推荐改为禁用交换机的 IGMP 侦听功能, 因为该问题没有明确的解决方案。