5.1 IP 多播的需求
IP多播并不是一个新概念。Steve Deering曾于1986年撰写了第一个有关多播主机需求的RFC,但直到最近,随着企业一对多和多对多应用的日益增多,大家才开始逐渐关注多播。
常见的一对多应用包括远程教育或企业新闻的视频和音频传送、基于网络的娱乐节目、新闻和股票更新、数据库或网站复制等。经典的多对多应用是会议,包括视频、音频和共享白板,多用户游戏也是一种常见的多对多应用(虽然很多企业不愿意在网络上提供该服务)。随着基于组的应用日益增多,与广播方式或重复的单播方式传送数据相比,多播所具有的效率和性能也变得更有吸引力。
在实施IP多播时,必须在大量的协议面前做出抉择,正因为如此,多播机制目前主要部署于企业网之内,因为单一管理机构比较容易做出协议选择。但随着多播应用的不断增多,客户越来越要求ISP支持穿越Internet的多播。随着越来越多重复的单播流量都要穿越Internet,消耗越来越多的带宽资源,ISP内的多播部署也越来越受关注。虽然近期企业已经开始关注多播,但最终将IP多播引向成熟的“杀手级应用”却可能是Internet娱乐。
有关多播的应用研究已经在Internet的一个子网上进行了很长一段时间,该子网被称为多播骨干网(Multicast Backbone)或MBone, ISP也开始向其用户提供多播服务,如UUNET的UUcast。但在整个Internet上都提供多播服务还有待进一步研究,并需要开发相应的AS间协议,如MBGP(Multiprotocol BGP,多协议BGP)和BGMP(Border Gateway Multicast Protocol,边界网关多播协议)。在路由策略支持能力方面,当前没有任何一种IP多播路由协议能与BGP相比拟,除非能够制定足够的策略增强工具,否则多播难以得到整个Internet的接受。
如果要在路由式互联网络上支持多播机制,必须满足以下3个基本需求。
• 必须有标识多播组的地址集;
• 必须有主机加入和离开多播组的相应机制;
• 必须有一种路由协议,让路由器在不过分占用网络资源的情况下有效地将多播流量发送给组成员。
本节将逐一分析上述基本需求,后面的章节将详细讨论满足上述基本需求的各种协议。
5.1.1 多播IP地址
IANA将D类IP地址保留用作多播地址,根据《TCP/IP路由技术(第一卷)》第2章中介绍的第一个8位组(octet)原则,D类地址的前4个bit始终是1110(如图5-4所示)。在次约束条件下计算32bit数的最小和最大值,可以知道D类地址范围为224.0.0.0~239.255.255.255。
图5-4 D类地址范围为224.0.0.0~239.255.255.255
与A、B、C类地址范围不同,D类地址范围是一种“平面”结构,不使用子网(如图5-5所示),因而D类地址有28个可变bit,可以为228(超过 268 000 000)个多播组进行编址。
图5-5 与A、B、C类IP地址不同,D类地址不分网络部分和主机部分
多播组是通过多播IP地址来定义的,多播组可以是永久性(permanent)的,也可以是临时性(transient)的。这里所说的永久组是指该多播组拥有永久分配的多播地址,而不是指其成员被永久分配到该多播组中,事实上,主机可以自由地加入或离开任何多播组。与此类似,临时组指的是非永久存在的多播组(如视频会议组),为该多播组分配一个非保留地址,并在该组终止时释放该地址。
表5-1列出了由IANA分配给永久组的周知地址,之前在学习路由协议时读者就已经遇到了其中的大多数地址。例如,在多路接入网络中,OSPF DRother路由器向地址为224.0.0.6的 OSPF DR和BDR发送更新消息,而DR则向地址为224.0.05的DRother路由器发送数据包。
表5-1 部分周知保留多播地址
IANA将地址段224.0.0.0〜224.255.255.255保留给路由协议和其他网络维护功能,多播路由器不转发目的地址为该地址段的数据包。此外,该地址段之外还有部分地址被保留给了开放组和商业组,如224.0.1.1被保留给NTP(Network Time Protocol,网络时间协议),224.0.1.8被保留给 SUN NIS+,224.0.6.0〜224.0.6.127被保留给Cornell ISIS Project。另一个被保留的地址段为239.0.0.0〜239.255.255.255,有关该地址组的使用将在5.2.6小节进行详细讨论。附录C或RFC 1700中列出了完整的D类保留地址列表。
组成员的NIC(Network Interface Card,网络接口卡)也必须支持多播,当主机加入一个多播组之后,NIC会计算出一个可预见的MAC地址,为此,所有支持多播的以太网、令牌环、FDDI NIC都使用保留的IEEE 802地址0100.5E00.0000来确定一个多播MAC地址。值得注意的是,该地址的第8个bit是1,对IEEE 802地址来说,该bit是I/G(Individual/Group,个体/组)bit,当该bit被置位时,表示该地址为多播地址。
1.以太网和FDDI上的多播
以太网和FDDI接口将组IP地址的低23位映射到被保留MAC地址的低23位,从而构建一个多播MAC地址(如图5-6所示),图5-6中利用D类IP地址235.147.18.23创建了MAC地址0100.5E13.1217。
图5-6 以太网和FDDI网络上的多播地址是将IP地址的最后23位与MAC地址0100.5E00.0000的前25位组合而成
回顾《TCP/IP路由技术(第一卷)》第9章中的内容,当时曾简要说明了全部OSPF路由器(All OSPF Routers)地址224.0.0.5使用的MAC地址是0100.5E00.0005,而OSPF指派路由器(All OSPF Designated Routers)地址224.0.0.6使用的MAC地址是0100.5E00.0006,现在就可以明白为何如此了。
由于仅将IP地址的低23位映射到MAC地址,因而多播MAC地址不是全球惟一的,如IP地址225.19.18.23与235.147.18.23生成的MAC地址都是0100.5E13.1217。事实上,通过计算D类地址的全部数量(228)与保留前缀后的NAC地址数量(223)之比,可以看到32个D类IP地址会映射为同一个MAC地址。
IETF的观点是,同一个LAN中两个或多个组地址生成完全相同的MAC地址的几率非常低,是完全可以接受的。只有在很少的场合下才可能会出现这样的地址冲突现象,此时同一个LAN中两个组的成员将能接收到对方的流量。在多数情况下,每个组的数据包都会去往不同的端口号或有不同的应用层验证机制,因而每个组的成员都会在传送层或更高层丢弃其他组发来的数据包。
这种可预测MAC地址方案有以下两个好处。
• 本地网中的多播源或路由器只需要向多播MAC地址发送一份数据帧,即可保证LAN中的组成员都能接收到;
• 由于知道了组地址之后即可知道MAC地址,因而无需ARP进程。
2.令牌环上的多播
令牌环网络上的多播处理方式有所不同。为访问运行了普通TR功能(如活动监视器、环参数服务器和环差错监视器)的站点,令牌环需要指定功能性(functional)MAC地址或功能相关(function-dependent)MAC地址。TRMAC地址的第一个8位组的第一个bit是I/G地址,该bit指示地址是单播地址(I/G=0)或广播/多播地址(I/G=1),第二个bit是U/L(Universal/Local,全球/本地)bit,该bit指示地址是设备制造商内嵌地址(U/L=0)或本地管理地址(U/L=1)。此外,第三个8位组的第一个bit是FAI(Functional Address Indicator,功能地址指示符)bit,其作用是区别功能性地址(I/G=1,U/L=1, FAI=0)与本地管理性组地址(I/G=1,U/L=1,FAI=1)。通过对FAI bit之后的31个bit中的某个bit(也只能是一个bit)进行置位,可以创建特殊的功能性地址,如活动监视器的功能地址是C000.0000.0001,网桥是C000.0000.0100。由于仅置位31个bit中的一个bit,因而一共存在32种功能性地址,该规则对IP多播来说非常重要。
令牌环MAC地址采用little-endian格式(即从右向左读取每个8位组),而以太网采用的则是big-endian格式(即从左向右读取每个8位组),因而以太网多播MAC地址 0100.5E13.1217将会被令牌环读取为8000.7AC8.48E6。该TR地址中的FAI bit是0,但FAI之后的31个bit中有多个bit被置位为1,因而令牌环认为该地址是非法功能性地址。
注意: FDDI也使用little-endian格式的MAC地址,但不使用令牌环这样的功能性地址,因而支持与以太网相似的映射方案。
由于无法像以太网地址那样将IP地址映射到令牌环地址中,因而需要其他方法来解决这个问题。目前有以下两种方法来解决TR帧携带IP多播包的问题:
• 为所有携带多播包的帧使用广播地址FFFF.FFFF.FFFF;
• 使用一个保留的功能性地址C000.0004.0000。
Cisco路由器默认使用第一种方法,通过在TR接口上配置命令ip multicast use-funct-ional,也可以支持第二种方法。
但上述两种方法都有一定的缺陷。第一种方法的效率比较低,需要将多播包传送给环中的所有站点,并依靠上层协议来接受或拒绝这些多播包。第二种方法要求环中所有站点的TR NIC都能识别该功能性地址,但并不是所有的NIC都能做到这一点。第二种方法的另一个问题是识别该功能性地址的TRNIC需要向该站点的CPU发送一个中断,这样一来,即便环中的IP多播流量中等,如果去往不同多播组的多播流量都被映射到同一个功能性地址,那么主机的性能也将受到严重影响。正因为有这么多的限制因素,所以使得令牌环难以有效地支持IP多播。
5.1.2 组成员概念
在加入一个组之前,主机(或其用户)必须知道可以加入哪些组以及如何加入这些组。宣告多播组的方法有很多种,就像在线“TV指南”或Web目录一样(如图5-7所示)。
图5-7 定位多播组的一种方法是查看Web通知
也有一些工具使用SDP(Session Description Protocol,会话描述协议)和SAP(Session Advertisement Protocol,会话宣告协议)等协议来描述多播事件并宣告这些描述。图5-8给出了一个使用这些协议的应用程序示例,用户也可以通过邀请(如通过电子邮件)了解多播会话。
图5-8 使用SDP和SAP的应用程序Multikit Listen,显示了由这些协议所宣告的多播会话
有关上述机制的详细讨论已经超出了本书范围,本节假定主机已经知道多播组,在此基础上讨论如何加入和离开多播组。在讨论完这些问题之后,读者将会明白IGMP(Internet Group Management Protocol,互联网组管理协议),是如何处理这些问题的,IGMP是在单个子网中管理IP多播组的事实协议。
1.加入和离开多播组
有趣的是,多播会话源无需是其发送流量的多播组的成员,事实上,多播源通常都不知道该多播组的成员是哪些主机。接收者可以在任何时间自由加入和离开多播组,这与早期的模拟无线电广播信号或电视信号类似,听众可以在任何时间收听/收看或关闭节目,信号发射站无法直接获知谁正在收听/收看节目。
如果多播源和所有的组成员都在同一个LAN中,则无需部署其他协议,若此时源想多播IP(和MAC)地址发送数据包,组成员“收听”该地址即可。但是,如果通过路由式互联网络发送多播流量,情况将变得十分复杂。每台路由器仅仅将所有的多播包都转发到每个LAN上(以免这些LAN中存在组成员),但这种方式在一定程度上削弱了多播节约网络资源的目的。如果某些LAN中没有组成员,那么浪费的带宽和处理资源不仅仅局限于该子网,还包括通向该子网的全部数据链路和路由器。
因而,路由器必须有一定的机制来了解其所连接的网络是否有组成员,如果有,那么须了解其属于哪个多播组。当路由器能够感知多播会话时,就可以向其所连接的子网查询希望加入接收组的主机,该查询可能会被发送给“本子网内的全部系统”地址224.0.0.1,或者被发送给某个被查询多播组的特定地址。如果有一个或多个主机返回了响应消息,那么路由器就可以只将多播包发送给这些子网(如图5-9所示)。
路由器可以周期性地向子网发送查询消息。如果子网中仍然有组成员,那么这些组成员将会响应路由器的全部查询消息,以便让路由器知道它们仍是组中的有效成员;如果没有主机响应,那么路由器就会认为子网中的全部主机都已离开了多播组,从而不再向该子网转发多播组的数据包。
图5-9 多播组成员发现
2.加入等待时间
到目前为止,前述多播方案存在的一个问题是,如果主机知道所希望加入的多播组,那么该主机并不总是能够等到路由器查询该多播组。为了减小等待时间,该主机可以向路由器发送一个请求加入多播组的消息,而无需等待路由器发出查询消息。路由器接收到加入请求之后,就会立即将多播流量转发到该主机所在的子网。
该进程的好处并不局限于本地子网,在5.2.2小节中将会看到,主机发起加入请求还能让多播路由协议更加有效。如果某路由器所连接的子网中没有任何组成员,而且这些子网也不为去往其他路由器的多播流量提供转接功能,那么该路由器就可以请求上游路由器不要向其转发多播流量,这样就可以让多播流量不进入无组成员的网络中。如果之后该路由器收到来自其所连接子网的加入请求,那么该路由器将会向上游路由器发出请求消息,并开始接收相关的数据流。
该方案的折衷方式是,如果某主机向其本地路由器发出加入请求,那么就需要等待本地路由器向其上游邻居请求正确的多播流量,从而加大了加入等待时间(join latency)。加入等待时间是从主机发送加入请求到主机能真正接收到组流量之间的时间周期。当然,如果该主机决定加入多播组的时候,其所在子网中已有该多播组的其他组成员,那么加入等待时间将几乎为零,此时该主机无需向路由器发出加入请求,而只需侦听已经被转发给子网中其他组成员的多播包。
3.离开等待时间
当主机离开多播组时,允许主机显式地通知本地路由器将会提高相应的处理效率,这样本地路由器在认为子网中已经没有组成员的时候,就无需发出查询消息并等待无主机响应,而是可以更加主动地确定子网中是否还有剩余组成员。一旦接收到主机发来的离开通告,路由器就会立即向子网发出一条查询消息,以询问是否还有剩余组成员,如果接收不到任何响应,那么路由器就会断定网络中已经没有组成员,从而不再向该子网转发该多播组的数据包。这样就可以缩短离开等待时间(leave latency),离开等待时间是从子网中的最后一个组成员离开多播组到路由器停止向该子网转发多播流量之间的时间间隔。
由主机发起的组离开机制也能提高路由协议的效率,如果路由器知道其所连接的子网上已经没有任何组成员,那么就可以将自己从多播树中“剪除”,路由器确定子网中已无组成员的速度越快,就能越早地“剪除”自己。
缩短加入和离开多播组的时间也能改善多播网络的整体质量。主机可能会知道大批的多播组,如果加入和离开等待时间较短,那么意味着终端用户可以轻易地通过可用多播组进行 “频道冲浪”,就跟用户可以随意地浏览无线电广播和电视频道一样。
4.组维护
主机希望加入某个组时会给路由器发送一条消息,该消息被称为报告(report)。主机在发送报告时可以使用多个可能的目的地址。
• 可以用单播方式将报告发送给发出查询消息的路由器。此时的问题是,该子网上可能会有多台路由器在跟踪该多播组,因而所有相关的路由器都必须接收该报告。
• 可以将报告发送给地址为224.0.0.2的“本子网内的全部路由器”。但是用户很快就会发现,这对子网上其他组成员能接收到该报告也有作用。
• 为了保证其他组成员能接收到报告,可以将报告发送到地址为224.0.0.1的“本子网内的全部系统”。但这样会降低多播的效率,强制子网内所有具备多播功能的主机(而不仅仅是组成员)都在二层以上处理该报告。
• 还可以将报告发送到组地址,这样就可以确保子网内的全部组成员以及侦听该多播组成员的路由器都能接收到该报告。对于非组成员的主机来说,其NIC可以根据二层地址来拒收这些报告。
如果子网内的所有组成员都需要响应路由器发出的查询消息,将会对带宽产生不必要的浪费,毕竟路由器只要知道子网内是否还有该多播组的组成员,而无需确切地知道到底有多少个组成员或者都是哪些主机。所有组成员都响应查询消息所带来的另一个问题是,所有组成员同时响应可能会产生一定的冲突,退避并重传会消耗更多的网络及主机资源。如果所有的组成员都在该子网内,那么在主机发送报告之前产生多次冲突的可能性会随之增大。
将报告发送到组地址可以解决统一子网中出现多个报告的问题。当接收到查询消息之后,每个组成员都根据一个随机数启动一个定时器,直到该定时器超时,组成员才发送报告。由于定时器是随机的,因而最大的可能就是只有一个定时器最先超时,由该成员发送报告;由于报告被发送到组地址,因而其他组成员也都能收到该报告,这些组成员接收到报告之后,就取消各自的定时器,也就不再发送各自的报告了,因而通常只会在子网中发送一个报告。每个子网一个报告是所有路由器的统一要求。
5.网络中存在多台路由器
同一个子网中可能存在多台路由器,每台路由器都希望知道子网中是否有组成员。图5-10给出了一个示例,子网中存在两台路由器,这两台路由器通过不同的路由从同一个多播源处接收了相同的多播流,如果其中的一台路由器或路由失效,组成员依然可以通过另一台路由器继续接收多播会话。但是在正常情况下,两台路由器同时将相同数据流转发到子网中的效率比较低。
图5-10 两台路由器接收到相同的多播会话,但只有一台路由器将其转发到子网中
路由器之间能够相互感知的原因是路由协议,因而为了保证只有一台路由器将多播会话转发到子网中,需要增加一台指派路由器或查询路由器(querier),以完成多播路由协议的功能。查询路由器的作用就是转发多播流,其他路由器仅负责侦听,并在查询路由器出现故障时才开始转发多播流。
允许路由协议选举一台查询路由器的问题是存在多种可用路由协议。如果图5-10中的两台路由器运行了两种不兼容的路由协议,那么将无法检测到对方路由器上的查询路由器选举进程,从而每台路由器都将自己确定为查询路由器,两者都转发数据流。
不过,本地组管理协议与路由协议无关,每台路由器都必须运行该通用协议来查询组成员。因而将查询路由器功能交给组管理协议非常有意义,这就保证了同一子网中的路由器在确定由谁负责转发多播会话时可以运行相同的协议。
5.1.3 IGMP
无论多播互联网络中运行了多少种路由协议,都要求在主机和路由器之间运行IGMP(Internet Group Management Protocol,互联网组管理协议),所有希望加入多播组的主机和所有接口连接的子网上存在多播主机的路由器都必须运行IGMP。该协议是类似于ICMP的控制协议,某些功能也相似。与ICMP类似,IGMP负责管理高层数据交换,IGMP消息也被封装在IP头部(协议号为2),与ICMP不同的是,该消息仅局限于本地数据链路,这由IGMP的实现规则(即要求路由器永远也不转发IGMP消息)以及将TP头部中的TTL设置为1来共同完成。
目前存在两种版本的IGMP:定义在RFC 1112中的IGMPv1和RFC 2236中的IGMPv2。Cisco IOS Software Release 11.1及以后版本默认支持IGMPv2,不过许多主机的TCP/IP实现仍然仅支持IGMPv1(如安装了服务包SP4之前的Windows NT 4.0),因而可以通过命令ip igmp version来更改默认支持的IGMP版本。
下面将主要讨论IGMPv2,并简要说明与IGMPv1的不同之处。虽然IOS目前还不支持IGMPv3,但本书也会简要提及,因为将来的Cisco IOS Software可能会支持IGMPv3。
1.IGMPv2主机功能
运行IGMPv2的主机使用下列3种类型的消息。
• Membership Report(成员关系报告)消息
• Version 1 Membership Report(版本1成员关系报告)消息
• Leave Group(离开组)消息
成员关系报告消息用于指示某主机希望加入某多播组,当主机第一次加入组时就发送该消息,其有时也作为本地路由器发出的Membership Query(成员关系查询)消息的响应消息。
当主机了解到多播组并希望加入时,不会等待本地路由器发出的查询消息,就像读者今后在各章节中学习到的多播协议那样,路由器可能不知道(事实上大多数时候都不知道)主机所希望加入的特定多播组,因而不会因组成员目的而发出查询消息。如果主机必须等待查询消息,那么可能根本就没有机会加入组。相反,当主机第一次加入某多播组之后,会主动向该多播组发送一条成员关系报告消息。
在路由器中,是通过(源,组)地址对来标识多播会话的。其中,源地址是会话发起者的地址,组地址是D类组地址。如果本地多播路由器并不知道主机所希望加入的多播会话,那么将会向上游多播源发送一个请求消息,接收到数据流之后,路由器就开始向请求了组成员关系的主机所在子网转发数据流。
成员关系报告消息的IP头部中的目的地址是组地址,该消息本身也包含了组地址。为了确保本地路由器能接收到主动发出的成员关系报告消息,主机需要在很短的间隔内发出一条或两条重复的报告消息,RFC 2236的建议间隔为10秒钟。
IGMPv2主机后向兼容,支持IGMPv1的成员关系报告消息。有关IGMPv2检测和支持同一子网内IGMPv1主机及路由器的相关机制将在后面进行详细讨论。
本地路由器利用查询消息周期性地轮询子网,每条查询消息中都包含一个Max Response Time(最大响应时间),通常为10秒(以1/10秒的倍数为单位)。主机接收到查询消息之后就设置一个延时定时器(值为0〜最大响应时间之间的任意值),在定时器到期时,主机会向其所属的每个多播组都发送一条成员关系报告消息,作为查询消息的响应消息。
注意: 所有启用了多播功能的设备都是组地址为224.0.0.1的“本子网内所有系统”组的成员。由于这属于默认特性,因而主机无需向该组发送成员关系报告消息。
由于成员关系报告消息的目的地址是组地址,因而除了路由器之外,位于本子网内的其他组成员也能接收到该消息。如果主机接收到某多播组的成员关系报告消息时,其延时定时器未到期,那么不会向该组发送成员关系报告消息。这样一来,路由器就可以知道本子网内至少有一个组成员,而无需让子网内的所有组成员都发送报告消息。
当主机离开组时,会以Leave Group(离开组)消息通告本地路由器,该消息包含了将要离开的多播组的地址。但是与成员关系报告消息不同,离开组消息被发送给地址为224.0.0.2的“本子网内全部路由器”,这是因为只有本子网内的多播路由器才需要知道主机是否要离开组,其他组成员根本无需知道。
RFC 2236建议,只有在将要离开的主机是发送了成员关系报告消息(以响应查询消息)的最后一台主机时,才发送离开组消息。下面将会解释,本地路由器响应Leave Group(离开组)消息的方式总是向其余组成员进行查询,如果不是“最后一个响应者”的其他组成员静静地离开多播组,那么路由器会继续转发多播会话,而不会发出查询消息,从而会在一定程度上节省网络带宽。不过,这种行为并不是必须的,如果多播应用的设计者不希望使用一个状态变量去记住哪台主机是最后一个响应查询消息的主机,那么也可以在任一台主机离开多播组时就发送离开组消息。
2.IGMPv2路由器功能
由路由器发送的IGMP消息只有查询消息。IGMPv2中有两种子类型的查询消息。
• General Query(常规查询)
• Group-Specific Query(特定组查询)
路由器利用General Query(常规查询)消息来轮询其所连接的每个子网,以确定是否有组成员以及检测子网中何时无任何组成员。在默认情况下,每60秒发送一条查询消息,也可以使用命令ip igmp query-interval将默认值更改为0〜65 535间的任意值。
如前所述,查询消息中也包含了最大响应时间,该值指定了主机必须以成员关系报告消息响应查询的最长时间,在默认情况下,最大响应时间为10秒。也可以使用命令ip igmp query-max-response-time来更改该默认值,最大响应时间由消息中的8bit字段来表示,以1/10秒的倍数为单位(虽然命令ip igmp query-max-response-time中的单位为秒)。例如,默认值10秒在消息中被表示成100倍的1/10秒,因而取值范围为0〜255倍的1/10秒,即0〜25.5秒。
常规查询消息被发送给地址为224.0.0.1的“本子网内全部系统”,不引用任何特定组,因而该单条消息会轮询子网中所有处于有效状态的组,以便从组成员获得报告消息。路由器会跟踪已知多播组以及连接了子网(含有有效组成员)的接口,如例5-1输出结果所示。
例5-1:命令show ip igmp groups显示了路由器所关心的IP多播组
如果Cisco多播路由器在3倍查询间隔(默认为3分钟)内无法收到特定子网上某多播组的成员关系报告消息,那么路由器将断定该子网上已经无该多播组的有效成员,从而涵盖了单个组成员被断开或在离开多播组时没有遵循IGMPv2规则等可能情况。
注意: 这与RFC 2236有所不同,RFC 2236中规定的是2倍查询间隔加上1个最大响应时间间隔。
正常情况下,主机在离开多播组时应该发送离开组消息,路由器接收到该消息后,就要确定该子网上是否还有剩余的组成员。为此,路由器需要发出Group-Specific Query(特定组查询),与常规查询不同,特定组查询中包含了组地址,并且用该组地址作为查询消息的目的地址。
如果特定组查询出现丢失或损坏,那么子网上的剩余组成员可能不会发送报告消息,这样一来,路由器可能会错误地认为该子网上已经无有效组成员,从而停止向该子网转发该多播组的会话包。为了避免这种情况的发生,路由器会以1秒为间隔发送两条特定组查询消息。
当具备多播功能的路由器初次在子网上被激活时,会将自己假定为查询路由器(负责向该子网发送所有的常规查询和特定组查询)并立即发出常规查询。
注意: RFC 2236建议发送多条查询消息,但Cisco的IGMPv2仅发送一条。
该操作方式不仅可以快速发现子网上的有效组成员,而且可以向该子网上可能存在的其他多播路由器发出通告。当子网中存在多台多播路由器时,查询路由器的选举规则非常简单:IP地址最小的路由器即为查询路由器。因而,当子网中的已有路由器接收到新路由器发送出来的常规查询之后,就会检查查询消息的源地址。如果该地址小于自己的IP地址,那么就会将查询路由器的角色转让给新路由器;如果自己的IP地址较小,那么就继续发送查询,当新路由器接收到这些查询消息之后,发现子网中的现有路由器的IP地址较小,则放弃查询路由器的角色。
如果非查询路由器在Other Querier Present Interval(其他查询路由器呈现间隔)周期内没有收到来自查询路由器发出的查询消息,那么将会认为查询路由器已不存在,从而接替查询路由器的角色。Cisco IOS软件默认的其他查询路由器呈现间隔是查询间隔(Query Interval)的2倍(即120秒),也可以使用命令ip igmp query-timeout更改该默认值。
3.IGMPv1
IGMPv1与IGMPv2之间的主要区别如下。
• IGMPv1无Leave Group(离开组)消息,这就意味着从最后一台主机离开多播组到路由器停止转发组流量的时间周期会更长。
• IGMPv1无Group-Specific Query(特定组查询)消息,原因是IGMPv1无离开组消息。
• IGMPv1无法在查询消息中包含最大响应时间,主机的最大响应时间始终为10秒钟。
• IGMPv1无查询路由器选举进程,依赖多播路由协议在子网中选举一个指派路由器。由于不同的多播路由协议采用不同的选举机制,因而在IGMPv1下,同一个子网中可能会存在多台查询路由器。
后面的“IGMP消息格式”中将解释这些区别对IGMPv1和IGMPv2消息字段的影响。
在某些情况下,IGMPv1和IGMPv2可以共存于同一个子网中。
• 某些组成员运行IGMPv1,而其他组成员运行IGMPv2;
• 某些组成员运行IGMPv1,而路由器运行IGMPv2
• 路由器运行IGMPv2,而某些组成员运行IGMPv1;
• 某台路由器运行IGMPv1,而该子网中的其他路由器运行IGMPv2。
RFC 2236中描述了多种允许IGMPv2适配这些应用场景的实现机制。如果同一子网中同时存在IGMPv1成员和IGMPv2成员,那么IGMPv2成员在确定是否要抑制自己的Membership Report(成员关系报告)消息时,将版本1和版本2成员关系报告消息视为完全一样。也就是说,如果IGMPv2成员在其延时定时器到期之前,接收到来自路由器的查询消息,并且随后又接收到版本1成员关系报告消息,那么就不再发送成员关系报告消息。另一方面,IGMPv1主机会忽略IGMPv2消息,也就是说,如果首先向多播组发送的是版本2成员关系报告消息,那么IGMPv1成员仍然会在延时定时器到期时发送报告消息,这不但不会影响IGMPv2主机,而且能让IGMPv2路由器知道组成员中存在IGMPv1成员。
如果主机运行的是IGMPv2,而本地路由器运行的是IGMPv1,那么IGMPv1路由器会忽略IGMPv2消息。因而当IGMPv2主机接收到IGMPv1查询消息之后,会发出版本1成员关系报告消息作为响应消息。由于IGMPv1查询中不指定最大响应时间,因而IGMPv2主机使用IGMPv1的固定周期10秒钟。IGMPv2主机可以向也可以不向IGMPv1路由器发送离开组消息,IGMPv1无法识别离开组消息,因而会忽略这些消息。
如果IGMPv2路由器接收到的是版本1成员关系报告消息,那么就认为该组所有成员运行的都是IGMPv1。因而该IGMPv2路由器会忽略离开组消息,也不发送会被IGMPv1成员忽略的特定组查询消息,而是设置一个被称为Old Host Present Timer(老式主机呈现定时器)的定时器(如例5-2所示)。该定时器的定时周期与Group Membership Interval(组成员关系间隔)相同,无论何时接收到一条新的版本1成员关系报告消息,该定时器都会被重置;该定时器到期时,路由器会断定子网中已经无IGMPv1成员,从而恢复为IGMPv2消息及相关处理进程。
注意; 如前所述,Group Membership Interval(组成员关系间隔)是路由器在认定子网中无任何组成员之前等待成员关系报告消息的时间。Cisco的默认组成员关系间隔是 Query Interval(查询间隔)的3倍。
例5-2:多播路由器正在接收组239.1.2.3的IGMPv2成员关系报告消息以及组228.0.5.3的IGMPv1成员关系报告消息,IGMPv1成员关系报告消息会让路由器为该组设置一个老式主机呈现定时器。
请注意,例5-2中的路由器一直在发送IGMPv2常规查询,这些查询消息与IGMPv1查询消息的主要区别在于最大响应时间不是0。IGMPv1中没有使用携带该时间值的字段,IGMPv1主机也会忽略该字段,因而IGMPv1主机会将IGMPv2查询消息解析为IGMPv1查询消息。
例5-2中另一个值得关注的地方是,仅为组228.0.5.3设置了老式主机呈现定时器,路由器仅将该组视为IGMPv1组,而将位于同一接口上的组239.1.2.3视为IGMPv2组。
如果同一个子网中同时存在IGMPv1和IGMPv2,那么IGMPv1路由器将不参与查询路由器的选举进程,因而为了保持一致性,IGMPv2路由器将按照IGMPv1进行操作。由于没有自动转换为IGMPv1的相关机制,因而必须使用命令ip igmp version 1以手工方式将IGMPv2路由器配置为IGMPv1路由器。
4.IGMPv3
由于IGMPv3仍处于发展之中,Cisco暂时也不支持,因而本小节不会像对前两个版本那样进行详细阐述,而是给出IGMPv3将要增加以及可能会得到广泛使用的一些功能特征。
IGMPv3增加的一个主要内容就是定义了Group-and-Source-Specific Query(特定组和源查询),这样不仅可以通过组地址来标识组,还可以通过源地址来标识组。与此相对应,为了支持该标识方式,对成员关系报告及离开组消息都做了相应的修改。
当某个多播组拥有多个源(属于多对多组)时,IGMPv3路由器可以根据组成员的请求进行源过滤。例如,某特定组成员可能希望从某指定源接收组流量,或者希望从指定源之外的所有源接收组流量,那么该组成员就可以在成员关系报告消息中用Iclude或Exclude来进行源过滤。如果某特定子网上没有成员希望从某特定源接收流量,那么多播路由器就不会将该多播源的流量转发到该子网中。
5.IGMP消息格式
IGMPv2使用单一消息格式(如图5-11所示),封装消息的IP头部指示协议号为2,由于IGMP消息不能离开其所发起的本地子网,因而TTL被始终设置为1。此外,IGMPv2消息中还携带了IP Router Alert(路由器告警)选项,让路由器“更严格地检查该数据包”。
图5-11 IGMPv2消息格式
IGMPv2消息的字段定义情况如下。
• 类型(Type)字段:描述了以下4种消息类型。
—多播路由器利用Membership Query(成员关系查询)消息(0x11)来检查子网中是否还有组成员,General Membership Query(通用成员关系查询)消息将组地址字段设置为0.0.0.0,而特定组查询则将该字段设置为被查询组的组地址。
—由组成员发送的Version 2 Membership Report(版本2成员关系报告)消息(0x16),以告知路由器本子网中至少还有一个组成员。
—IGMPv 2主机用来与IGMPv 1保持后向兼容性的Version 1 Membership Report(版本1成员关系报告)消息(0x12)。
—由最后一个发送成员关系报告消息的成员所发送的离开组(Leave Group)消息(0x17),以告知路由器其将要离开多播组。
• 最大响应时间(Max Response Time)字段:仅在查询消息中进行设置,对其他类型消息来说,该字段总是为0x00。该字段指定了一个时间周期(单位为1/10秒),在该时间周期内,至少要有一个组成员必须响应以成员关系报告消息。
• 校验和(Checksum)字段:16bit IGMP消息反码和的反码,使用标准的TCP/IP校验和算法。
• 组地址(Group Address)字段:在常规查询消息中被设置为0.0.0.0,在特定组查询消息中被设置为组地址。成员关系报告消息在该字段中携带被报告的多播组的地址,而离开组消息则在该字段中携带将要离开的多播组的地址。
图5-12给出了IGMPv1的消息格式。
图5-12 IGMPv1消息格式
IGMPv1与IGMPv2消息格式的区别如下。
• 第一个8位组被分为4bit版本字段和4bit类型字段;
• 第二个8位组(IGMPv2中为最大响应时间字段)未使用,被始终设置为0x00。
还有一个区别在于,IGMPv1消息的IP头部中未设置路由器告警(Router Alert)选项。
IGMPv1仅定义了以下两种类型的消息。
• 主机成员关系查询(Host Membership Query,类型1)消息
• 主机成员关系报告(Host Membership Report,类型2)消息
IGMPv1的版本字段始终为1,因而主机成员关系查询消息的版本字段加上类型字段是 0x11,与IGMPv2成员关系查询消息中的8bit类型字段值一样;主机成员关系报告消息的版本字段加上类型字段是0x12,而IGMPv2成员关系报告消息中的类型字段值为0x16。
5.1.4 CGMP
IP多播的一个基本设计原则就是仅将流量分发到希望接收流量的目的地。通过前面的学习,读者已经明白D类编址以及相应的MAC编址方式是如何在数据链路层满足该设计需求的,也知道了IGMP如何让路由器确定是否要向特定子网分发多播会话。在后面的内容中,将会介绍IP多播路由协议是如何将这些规则扩展到互联网络上的,以及如何仅将多播会话分发到那些所连子网上有组成员的路由器上。
但是,对交换式网络(如图5-13所示)来说又会如何呢?大型办公楼和园区大量存在这样的网络,以太网交换机(实际上就是高处理能力、高端口密度的透明网桥)通过学习与端口相关的MAC地址来限制单播流量,并利用该信息来过滤和转发数据帧。但是,广播流量会被转发到每一台以太网交换机的每一个端口上,因而通常会将图5-13所示的大型网络分割为多个VLAN(Virtual LAN,虚拟LAN),以控制广播流量的范围。不过,现实中经常出现的却是一个个大型“平面式”交换网络——一个子网,即一个广播域。
图5-13 除非将该交换式园区网分割为多个VLAN,否则将成为单个广播域。也就是说,路由器端口定义了一个3层子网,所有广播帧都将被转发到全部384个交换端口上
携带IP多播包的数据帧也像多播帧一样,会被转发到同一个广播域中的每个端口,其中,广播域就是所有主机所归属的多播组。图5-14解释了该问题,图中3个多播成员连接在一个24端口交换机上,其中的一个组成员向路由器发送了一条IGMP成员关系报告消息,之后路由器开始将相应的多播会话转发到该子网。由于IGMP是3层协议,因而以太网交换机没有什么简易方法来确定组成员在哪些端口上,所以会将多播流量转发到其他23个交换端口上(源端口除外)。
图5-14 3个组成员之一向路由器发出IGMP成员关系报告消息,加入多播组A(a),当路由器开始转发多播会话时,以太网交换机将数据帧复制到除源端口之外的所有端口(b)
很明显,对交换机来说,最优处理方式是仅将多播会话转发到连接了组成员的端口上。如果能实现该处理方式,不但能提高交换效率,而且也是LAN承载多播会话的一种优选方式。例如,一路视频会议多播流大约占用1Mbit/s带宽,一路MPEG II视频流则大约占用 4Mbit/s带宽,如果能将多播会话局限于组成员所在的交换端口,则将能大大节省网络和主机的资源。
CGMP(Cisco Group Membership Protocol, Cisco组成员关系协议)就是支持该功能的一种协议,可以只将多播会话分发到那些连接了组成员的交换端口上。在分析CGMP的操作方式之前,将简要回顾一下其他控制交换式多播流量的解决方案。
1.交换式网络中可选的多播控制方法
除了CGMP之外,交换式网络中还有如下3种约束多播流量的方法,Cisco Catalyst软件同时支持这些方法。
• 手工配置交换式多播树
• GMRP
• IGMP Snooping(IGMP侦听)
由于这3种解决方案都没有直接承载在路由协议之上,因而本小节仅加以简要描述,有关细节信息及完整的配置指导请参见Cisco CCO上的Catalyst Switch Software Documentation(Catalyst交换机软件文档)。
手工配置交换式多播树的意思是在交换机的桥接表中加入静态表项,Cisco Catalyst交换机将该表称为CAM(Content Addressable Memory,可编址内容存储器)表。假设图5-13中的组成员连接在交换机的端口2/3、2/4和2/19上,路由器连接在端口1/1上,组IP地址是239.0.5.10,从而相应的多播MAC地址是0100.5E00.050a。以手工方式将该信息配置到Catalyst CAM表中的命令如下。
第一条命令将该表项增加到交换机的CAM表中并写入交换机的NVRAM中,该表项只能通过命令clear cam或clear config才能予以清除。作为一种可选项,可以用关键字static来替代permanent,此时该表项就不会被写入NVRAM,在交换机重置时即可被删除。
第二条命令是可选命令,其作用是告知交换机多播路由器所处的端口位置,进而将在交换机内限制多播流量的范围。
使用手工配置方式时存在一些限制条件,其中两个最明显的限制条件是非动态、不可扩展。只要有其他组成员加入到不同的交换机端口上,有组成员离开或在交换机上增加不同的多播组,都需要手工配置这些信息。除非多播组规模较小、较固定,否则这种手工配置方式都是不可行的。
另一个限制条件是手工配置方式无法穿越VLAN边界。例如,如果组239.0.5.10位于 VLAN1上,且VLAN2也位于该交换机上,那么239.0.5.10的组成员就无法位于第二个VLAN之中——所有的组成员都必须位于同一个VALN中。
另一种可选技术是GMRP(GARP Multicast Registration Protocol, GARP多播注册协议)。GMRP是IEEE 802.1p标准中定义的开放式协议,可以在交换机中动态注册/撤销注册MAC层多播组地址。利用命令set gmrp enable即可在交换机上启用GRMP,而无需在路由器上做其他配置。如IEEE 802.1p标准所建议的那样,GRMP是一种严格的二层协议。
第三种可选技术就是IGMP Snooping,利用命令set igmp enable即可在Catalyst交换机上启用IGMP Snooping,此后交换机软件将会检查ICMP消息,并知道多播路由器和组成员所处的位置。与Cisco专有的CGMP不同,IGMP Snooping得到多数交换机制造商的支持,因而适用于多厂商交换式网络。但是,检测IGMP消息就意味着必须检测每个IP包,如果以软件方式来实现,则会严重影响交换机的性能,因而建议只有在多播网络中的所有交换机都能以硬件方式实现IGMP Snooping时才开启该功能,因为使用专用的ASIC(ApplicationSpecific Integrated Circuits,专用集成电路)可以实现对IP包的线速检测。例如,Cisco Catalyst交换机就是以NFFC II(NetFlow Feature Card II, NetFlow特性卡II)来实现该功能的。
2.CGMP的操作
虽然Cisco路由器和交换机都会被配置为运行CGMP,但是只有路由器会产生CGMP包,交换机上的CGMP进程仅仅是读取CGMP包。CGMP包的类型有以下两种。
• 加入(join)包:由路由器发出,告知交换机将一个或多个成员加入到多播组中。
• 离开(leave)包:由路由器发出,告知交换机将一个或多个成员从多播组中删除,或者删除同时删除多播组。
这两种CGMP包的格式都一样,包的目的地址也始终为保留MAC地址0100.0cdd.dddd,启用了CGMP功能的交换机将始终侦听该地址。
这两种CGMP包中的基本信息就是一对或多对MAC地址,如下所示。
• GDA(Group Destination Address,组目的地址)
• USA(Unicast Source Address,单播源地址)
当CGMP路由器被激活时,会发送一条GDA被设置为0(0000.0000.0000)、USA被设置为自身MAC地址的CGMP Join(加入)包,以便让交换机知道自己。之后,启用CGMP功能的交换机就知道接收到加入包的端口上连接了一台多播路由器,路由器每隔60秒就发送一个这样的数据包,以保持激活状态。
当主机希望加入多播组时,会发送一条IGMP成员关系报告消息,如图5-15(a)所示。此时遵循IEEE 802.1规程的交换机会将该主机的MAC地址录入到自己的CAM表中。
图5-15 当Cisco路由器在CGMP接口上接收到IGMP成员关系报告消息之后(a),会发送CGMP加入包,以告知交换机将主机的MAC地址映射到组MAC地址(b)
注意: Catalyst交换机的CAM表属于桥接表,记录所侦听到的MAC地址以及侦听到这些MAC地址的端口。
当路由器接收到IGMP成员关系报告消息之后,会发送一条GDA被设置为组MAC地址、USA被设置为主机MAC地址的加入包,如图5-15(b)所示。现在交换机已经感知了多播组,而且由于交换机知道主机所连接的端口,因而可以将该端口加入到多播组中,当路由器向组MAC地址发送数据帧时,交换机会将数据帧的拷贝发送给与该多播组相关的所有端口(路由器端口除外)。
只要交换式网络中仍然有组成员,路由器就会每隔60秒发送一次IGMP查询消息,并被交换机转发给组成员,之后由交换机将IGMP报告消息(为查询消息的响应消息)转发给路由器。
当主机发送IGMPv2离开消息时,该消息会被转发给路由器,如图5-16(a)所示。接着路由器会发送两条IGMP特定组查询消息,并被交换机转发到所有组端口,如果其他组成员响应了该特定组查询消息,那么路由器就会向交换机发送一个GDA被设置为组MAC地址、USA被设置为即将离开的组成员MAC地址的CGMP离开包,如图5-16(b)所示,以告知交换机从多播组中删除该即将离开的组成员端口。如果没有成员响应特定组查询消息,那么路由器将断定该子网中已无组成员,从而会向交换机发送一个GDA被设置为组MAC地址、USA被设置为0的CGMP离开包(如图5-16(c)所示),以告知交换机从其CAM表中删除该多播组。
表5-2汇总了CGMP包中GDA和USA的各种可能值以及相应的含义,只有最后两个离开包没有讨论过。其中一个离开包的GDA被设置为0、USA被设置为路由器的MAC地址,其作用是告知交换机从CAM表中删除所有多播组以及与路由器端口相关的端口,如果在交换机端口上关闭了路由器的CGMP功能,就会发送该消息。另一个离开包的GDA和USA均被设置为0,其作用是告知所有接收到该消息的交换机,从CAM表中删除所有多播组及相关的端口,如果在路由器上使用了命令clear ip cgmp,就会发送该消息。
图5-16 当路由器在CGMP接口上接收到IGMP离开消息后(a),会查询该子网中是否还有其他组成员(b)。如果有其他组成员发出了响应消息,路由器将会向交换机发送CGMP离开包,以告知交换机删除即将离开的组成员;如果没有收到成员响应消息,那么路由器将会向交换机发送CGMP离开包,以告知交换机删除整个多播组(c)
3. CGMP包格式
携带CGMP包的数据帧的源MAC地址是发信路由器的MAC地址,目的MAC地址是保留多播地址0100.0cdd.dddd。只有路由器能发起CGMP包,数据帧中的CGMP包被封装在SNAP头部中,SNAP头部的OUI字段是0x00000c,类型字段为0x2001
图5-17显示了CGMP的包格式。
图5-17 CGMP的包格式
CGMP包中的各字段定义如下。
• 版本(Version);总是被设置为0x1,以表示版本1。
• 类型(Type);指示数据包为Join(加入)包(0x0)或Leave(离开)包(0x1)。
• 保留(Reserved);总是被设置为0(0x0000)。
• 计数(Count):指示数据包携带了多少GDA/USA对。
• GDA是组目的地址(Group Destination Address),该字段非0时指示多播组的MAC地址,该字段为0(0000.0000.0000)时指示所有可能的多播组。
• USA是单播源地址(Unicast Source Address),该字段非0时可以指示发信路由器的MAC地址或组成员的MAC地址,该字段为0时指示所有组成员和发信路由器。