IGMP用于接收者和直连组播路由之间,建立和维护组播成员关系的组播协议,本章课程将介绍IGMP的原理,以及它不同版本的区别,还有一些其它特性。
IGMP介绍
组播网络的转发困境

正常情况下,组播源将组播报文推送给第一跳路由器之后,第一跳路由器就应该将这个数据推送给特定的接收者成员,现在问题在于,路由器去判断组播成员在哪里。第二个是,对于用户而言,哪些成员想要接收组播报文,组成员又要去选择哪些组播数据来进行正常接收。以及是否会存在其它的新增组播成员,都是所面临的问题。所学习的IGMP,它就是用于感知组播组成员的。
感知组播组成员

正常情况下有两种,第一种,可以在组播路由器上手工配置该接口下面的用户,想要接收某个组的消息,这样的情况下,对于新上线的用户能够直接快速上线,能够接收想要的组播数据流量,但是缺点是非常明显的,因为组播用户的上线和下线是不确定,很随机性的,没有办法实时感知整个组播网络的状况,因此,用静态的方式去配置的话,工作量非常大,而且灵活性也非常差,因此,一般情况下,采用的是动态,动态感知就是通过IGMP这个协议,去通知整个组播网络中哪些成员想要接收组播数据,以及哪些成员它想要接收哪个组的组播数据,都是通过IGMP协议去实现的,这种方式更加灵活,配置也非常简单。
基于IGMP,得知成员的位置和它想要加入的组播之后,就可以基于这些信息,将组播数据报文推送给想要加入的成员,其中IGMP这个协议,是运行在最后一条路由器和组播组成员之间。而从第一跳路由器到最后一跳路由器,中间转发组播数据的过程,是由组播路由协议去实现的。
IGMP协议的概述∑

IGMP这个协议是在IPv4的网络中,是用来管理组播成员的一个协议,这是由主机和直连组播路由器,也就是最后一跳路由器,来建立和维护组播成员关系的,IGMP一共有三个版本,v1,v2和v3,在现网中,用的最多的是v2和v3的版本,v1的版本已经被淘汰了,在组播路由器和组成员之间,通过IGMP协议,会生成IGMP路由表项,以及IGMP的组表项。通过这样的一个协议,就能够正常的去感知成员所在的位置以及它想要加入的组播组。
IGMP组表项与路由表项

通过IGMP这个协议,它生成的两个表项分别是什么含义?在正式介绍这两个表项之前,回顾一下两个比较重要的概念,分别是(*,G)表项,和(S,G)表项。
(*,G)表项,*是代表想要加入的是任意源,G代表它想要加入的组播组。正常情况下,(*,G)表项是由主机,直连组播路由器,去触发,生成这样的一个表项。因为对于主机而言,它并不知道它想要接收的组播是来自于哪个源的,它只想要接收该组的消息,所以成员端,和直连组播路由器之间,所建立的是(*,G)表项。
(S,G)表项,正常情况下,一般是由组播路由器接收到组播源,接收到推送过来的组播数据之后形成的(S,G)表项,因为得知是哪个组播源发送过来的组播数据,给这台路由器,因此,它是知道源在哪里。
当运行IGMP协议之后,如果终端设备和组播路由器正常交互的话,这个时候就会生成IGMP组表项,时面包含了哪些重要的信息,最后一个向组播路由器发送报告的成员的IP地址,前面是它想要加入的组播组。
IGMP路由表项,会生成一个(*,G)表项,表明,它想要接收的组播组,最关键的在于接口是出接口,这个出接口有什么作用呢?
得知通过IGMP生成的两个表项,第一个能够知道哪一台成员想要接收哪个组的消息,就完成了成员的位置,以及它想要加入的组播组,再到后面这个出接口,针对整个组播数据的转发有什么意义呢?
IGMP表项与组播路由表项

正常运行的组播路由协议的路由器,它需要转发组播流量,然后再到最后一条路由器,由最后一跳路由器去推送流到成员端。组播路由表,它并不是单一的运行组播路由协议就能够产生,它是由IGMP路由表项,IGMP组表项,以及运行组播路由协议,也就是PIM路由表项,汇总而成的,也就是说这是一个比较复杂的过程,当最后一条路由器,运行了IGMP以及PIM协议之后,它会生成IGMP的组表项,IGMP的路由表项,包括PIM的路由表项,将这三个表项里面的信息进行汇总之后,再组成了组播路由表项,由组播路由表项指导组播流量的转发。
首先,它包含的是(S,G)表项,这个G表明想要加入的组播组,这个组播组是怎么来的呢?就是由IGMP组表项里面的组播组映射过来的,第二个IGMP路由表项的出接口有什么作用,它会直接映射到组播路由表项里面的下游的出接口,这样的意义在于什么呢?想像一下,一台路由器,运行了PIM协议,运行了IGMP协议,最后形成了组播路由表项,当它收到这样一个组播数据流之后,要对应着从某一个接口把数据流推送下去,应该从哪个接口推送下去呢?也就是说组播路由协议的下游接口对应着IGMP路由表项的出接口,因为从该接口接收到了IGMP里面所想要加入的组播组的这样的一个信息,表明我接收到该组的组播流量,应该从该出接口再转发下去,给下面的成员端设备,因此,它们之间是一个映射的关系,在这里大家可能有很多疑问,比如说,组播路由表项,它是怎么指导组播数据转发的,PIM路由表是怎样的。
IGMP工作原理
理解成员和直连路由器之间的邻居关系建立以及维护这个关系。
IGMPv1基本概念

在IGMPv1的版本中,会发现它的机制非常简单,正常情况下,只有两个报文。第一个是普遍组查询报文,第二个成员关系报告报文。
普通组查询报文是由查询器,也就是说某一台设备,向该网络上所有的主机和路由器之间,周期性的去发送查询报文,去询问下面是否有某些组播组成员,想要接收该组的消息,类似于我主动向我的成员端去发送各种通知,问你们有没有想要接收的组播组,而成员关系报告报文是由主机主动向查询器去汇报,我想要接收某个组播的消息。因此,你会发现,这两个报文是针对不同的设备而言,一个是查询器主动向下游去询问,一个是下游组播组成员主动向上游去告知。
在IGMPv1版本中,其实有一个非常大的问题,在一个多路访问里面,只需要一台组播路由器去发送查询报告就可以了,比如说按图中的案例,在一个MA网络中,如果这两台路由器都充当查询器,向下游设备去查询某些成员想要接收哪个组的消息,这样就会显得非常繁琐,而且查询的消息也重复了,浪费了设备的带宽以及这样的一个链路的资源。因此,只要选举一台设备,作为查询器进行查询,就可以完成这样的操作,但是在IGMPv1版本中,它自己没有本身机制去选举查询器,在IGMPV1版本中,查询器的选举是依赖于组播路由协议PIM协议,去完成的,也就是说如果用的是IGMPv1的版本,最后一条路由器不仅要在接口上去运行IGMP,同时也要运行PIM协议,才能去实现这样一个查询器的选举,然后由查询器周期性发送普遍组查询报文。它存在着一个依赖关系。
在后续的版本中,它就会有自己本身的机制去选举查询器。
IGMPv1报文格式

IGMPv1的报文格式非常简单,主要是包含了两个报文类型,分别是普通组查询报文和成员关系报告报文,其中Group Address是组播组地址,在普遍组查询报文中该字段全为0,因为在普遍组查询报文中,它表明所有主机都应该去接收这样的一个查询报文,然后由你向我进行响应,因此,0.0可以理解为代表所有的意思,而在成员关系报告报文中,这个字段就表明它自己想要加入的某个组播的组播地址。
IGMPv1组成员加组机制

周期性的去发送成员关系查询报文是为了获知下面的主机是否想要加入某个组,来判断这样的组播流量是否要下发给成员端。
首先,查询器会周期性的发送普遍组查询报文,正常情况下每60秒发送一次,当成员端所有主机接收到这样的一个普遍查询报文之后,如果它想要加入某个组播组,这个时候它就应该正常通过成员关系报告报文进行反馈,但是如果多台主机想要加入同一个组播组,它应该是怎样的反馈呢?
现在假设PC1和PC2它们都想要加入组播组G1,这个时候它们接收到普遍组查询报文之后,会怎么办呢?第一步,它们会启动一个定时器,这个定时器在0~10秒内随机选取一个数值,按图中的案例,比如PC1它选出来了是5秒,PC2它最后随机选出来的一个是7秒,通过定时器开始倒计时,谁先倒计时完成,然后谁先向查询器去发送成员关系报告报文,这个时候成员关系报告报文不仅会发送给查询器,也会发送给同一组的成员端主机,这个时候会造成什么问题呢?对于查询器而言,接收到这样的一个成员关系报告报文之后,它就会形成相应的IGMP的路由表项,和IGMP的组表项,里面包含了想要加入的某个组以及对应的出接口。这样当从上游设备接收到关于某个组的流量之后,就会从对应的出接口将流量推送下来给下面的成员端主机,对于其它主机而言,这样的一个成员关系报告报文,它起到的作用是一个抑制的概念,PC1和PC2都想要加入到组播给G1中,这个时候如果PC1已经向查询器汇报了我需要这们的组播流量,这个时候,查询器就会将这样的组播流量从出接口推送下来给下游成员端主机,既然已经完成了这个操作,组播流量已经推送下来了,这个时候自己的成员2不需要再去发送成员关系报告报文了,因为我想要的组播流量已经推送下来了,我会接收的到。如果再发送成员关系报告报文,类似于做了一个重复的这样的操作,并没有任何意义,因此,为了节省资源,就抑制了这样的一个成员关系报告,是通过这样一个定时器来完成 的,谁先数到0谁先报告,然后其它的成员主机就会抑制成员关系报告报文的发送。实际上,在现网中,成员关系报文都是需要去发送的,因为这会涉及到后续一个比较重要的机制,正常情况下,不需要抑制的,而是需要去发送成员关系报告报文。
IGMPv1查询器选举机制

在IGMPv1版本中,是要选举一个查询器的,这个查询器类似于帮助我们去查询下面的终端设备想要加入的组播组,如果多台设备都去发送查询的话,那就完全浪费了设备的资源,这个查询器类似于DR的概念,在v1的版本中,并没有本身的机制能够选举这个查询器,因此,在v1的版本中,它需要和组播路由协议,也就是PIM协议,通过它去选举一个成员端DR,由成员端的DR充当查询器,在v1版本中向下游设备发送成员关系查询报文。如何在PIM协议中选举成员端的DR?
IGMPv1组成员离组机制

组播的这样的一个成员,它想要加入组和离开组都是随机性的,完全没有办法去干涉,这个时候如果说某一台主机它想要离开组,不接受关于该组的消息之后,会发生怎样的情况呢?在IGMPv1版本中,它的机制是比较落后的,它没有专门定义离开消息,也就是说成员离开类似于静默离开,悄悄的走,查询器并不知道你走了,它是通过怎样的机制去判断你离开的呢?然后再杜绝发送组播流量给下游设备。
之前介绍过查询器会周期性的发送普遍组查询报文,这个时间是60秒,按图中的案例,现在这两台成员想要接收的组播组的这样的一个消息是不同的,分别是G1和G2, 现在通过周期性的发送普遍组查询报文给下游设备,就类似于下游设备是否想要接收组1的消息,是否想要接收组2的消息,现在G1里面的PC1,它依然想要接收该组的消息,因此它会去反馈成员关系报告,依然想要接收关于G1的流量,给查询器,但是成员2,它里面所有的成员全部离开了,没有任何一台设备想要接收关于G2的组播流量,因此它就不做任何响应,这个时候关于G2就会启动一个定时器,这个定时器也可以简单的理解为一个超时时间,就是130秒,在130秒以内,查询器没有接收到关于G2组播组的任何成员关系的反馈,查询器就默认为关于G2的流量,下面已经没有任何人想要接收了,这个时候就不应该将组播的流量推送给下游设备,因为没有接收者,推送数据流下来就等于浪费了链路的带宽,因此,就会在IGMP的路由表项里面,把对应关于阻碍的组播表项和出接口给它删除,接收到成员反馈的这样的一个关系报告的流量,依然会在这样的一个组播路由表项里面存在,为它去推送组播数据流量,所以会发现IGMPv1的组成员离开机制,可以说是非常简陋的,因迷它是采取定时器的这样的一个状态。