首先要强调一下组播的应用环境,组播的目的是为多客户端传输数据的时候尽量节约带宽资源,只在必要的时候才将数据帧复制,所以对于组播来讲,天生就是来对付“一对多”这样的网络需求的。
建立模型时可以认为在网络的末节有一台Server,另一末节有客户,中间是网云,那么应用组播会是这样的情景:Server与第一跳路由器之间没有运行的协议,靠Server具体的应用程序来驱动。
中间网云中的路由器要运行组播路由协议来识别和传输组播数据包,目前应用最广泛的的是PIM协议。
最后一跳路由器和组成员之间运行IGMP协议,以确定组成员的加入和退出。
关于PIM的RPF检测,是组播利用单播路由表进行的防环路机制,当一个组播数据包来,我查看其中的Source地址所属的网段在单播路由表中是通过哪一个接口进入我这台路由器的,我会记录下来,当再来组播数据包时,凡不是从我这个接口进来的,我出于安全考虑,丢弃。
IGMP是一个独立于PIM的协议,是最后一跳路由器和PC商议组播的语言,目前应用最普遍的事IGMP V2,路由器会在接口上维护组播成员关系表,每60s 发送一个查询,通告自己组播路由表中的组的地址,有兴趣的PC会给予回应,路由器记录其信息。
域间组播协议解析(OIL---Outgoing Interface List IIL---Incoming InterfaceList)PIM-DM (只支持源树,不支持共享树)PIM-DM 密集模式是以“推”的形式把数据发出去,所有运行PIM-DM协议的路由器在一开始没有组播数据驱动时只是形成邻居,选举DR,组播路由表中只有(*,224.0.1.40)这个条目,是协议本身的产物。
当Server有组播数据流发出,会泛洪开来,每传到一个路由器,这个路由器都会先建立一个父条目(*,G),(*,G)条目不用于数据转发,所以他的IIL为空,而且这个条目会将所有运行PIM的接口和与组成员相连的接口放入自己的OIL 中。
然后再建立他的一个子条目(S,G),子条目会拷贝下来(*,G)的整个OIL,但显然(S,G)条目是要用来转发的,所以会进行修订,将接受到组播数据流的接口从OIL中剔除,放入到IIL中,事实上IIL也只能有一个,因为要遵循RPF规则。
一个(S,G)条目-----> 针对一个Group -----> 1个IIL -----> N个OIL在DM模式,由于针对每一个源,为每个Server建立一个SPT(最短路径树)。
我认为在最初一个组播数据流来到最后一跳路由器时,他会查到Group地址然后将其通告给PC,这是第一次通告,之后每60s周期性通告一次,如果有资格报告,就会将其记录在(*,G)的OIL中,这样在生成(S,G)的那一刻就可以确定有组成员存在,不会向上发送剪枝信息。
当OIL为空时,该条目设置为P,触发向上发送剪枝消息,特别是(S,G)条目在修订OIL后有可能出现NULL的情况;当OIL由空指向非空,设置为C,出发向上发送嫁接消息。
一个(*,G)条目是3 mins,当所有的(S,G)条目都消失时才进入记时。
一个(S,G)条目时限是3 mins,条目中OIL的接口也有时限,后面跟着超时时间。
注意,一个处于“Forward/Dense”模式的接口是没有超时时限的,即为00:00:00,在“Prune/Dense”模式下才会出现超时然后进入Forward状态。
当一个接口的PIM邻居列表上增加一个新邻居时,该接口在所有(S,G)的OIL中重置为“Forward/Dense”状态。
盲目泛洪和剪枝是DM的特点也是缺点,剪枝即使完成,泛洪3mins后又会重新泛洪一次再剪枝。
剪枝从末节路由器开始,当OIL为空时即向上游路由器发送剪枝信息,点到点的链路不会有问题,而在多路访问的网络中,上游路由器在收到这个剪枝信息时会等待3s(成为剪枝延迟时间),因为在多路访问的环境下,其他下游路由器也会收到这个剪枝信息,,他们可能还是需要转发的,所以会将其否决,一旦有否决,上游路由器不会将自己的这个接口剪裁掉。
Assert机制的触发条件是:路由器竟然从(S,G)条目OIL中的接口收到了组播数据包,这个在以太网环境中比较常见,两台上游路由器由于彼此收到组播数据包会触发Assert机制进行竞争,比较AD和Metric,更接近源的胜出,另一个被剪裁,不过实际上过程要复杂很多。
PIM-SM(推荐使用的模式,源树与共享树的结合)(*,G)条目记录了RP到每个组成员的最短路径。
稀疏模式是采用“拉”的模式来运行,首先要定义一个RP(Rendezvous Point),整个网络都知道RP的地址,Source和RP之间通过单播(将组播数据包封装在单播中)进行注册,RP收到后会向源发送(S,G)加入消息,建立SPT,当SPT稳定后(RP这时会意识到自己正在通过SPT成功的接收SG条目,SG项会设为T),RP会向Source发送停止注册的信息,同时建立(S,G)条目。
RP和组成员之间建立(*,G)条目,这样源不必知道有谁要加入,组成员也没有SG条目,唯一可以联系的就是RP,RP维护源表和组成员表,所以定义好RP,无论是源先发数据,还是组成员先发送请求都没有关系,都会在RP那里记录下来。
当然,如果是源先注册,那么在共享树没有形成之前,RP会丢弃来自源的数据包,并让第一跳路由器停止注册,当(*,G)条目形成的时候,RP会向Source 发出(S,G)加入消息;如果是组成员先注册,那么数据包流动从源发送数据的那一刻开始。
当Source在RP注册过后,RP会转发组播数据流到组成员,在到达最后一跳路由器的时候,会有些特点,最后一跳路由器的(*,G)中设置了C标志,即代表有直连组成员,那么针对这样的路由器Cisco设置了一个SPT-Threshosd 阈值,凡是向下发数据给组成员的速率超过了这个值,就会将(*,G)条目标记为J,当再一次收到一个组播数据包时,就会去除(*,G)中的J标记并将条目删除,记录Source创建(S,G),并向上游路由器发送(S,G)请求消息,每一台上游路由器都会添加这个(S,G)条目,但是直到shared tree和spt 的分界点路由器才会向RP发送(S,G)RP位剪枝消息,因为有规则“当(S,G)项的RPF 邻居于(*,G)项的RPF邻居不同时(即IIL项不同),路由器将向共享树发送一个(S,G)RP位剪枝消息”,而在此之前的上游路由器两个条目的RPF邻居都是一样的,直到分界点路由器才会出现差异,毕竟这之后选择的道路不一样了。
收到这样一个剪枝消息后,路由器会创建一个(S,G)状态项,设置RP位为R,从(*,G)中拷贝下来OIL,删除接受到该剪枝信息的接口(因为以后都不会再联系了),然后重新计算(S,G)的RPF信息,包括邻居和接口。
以下是PIM-SM的一些规则:稀疏模式(*,G)最初的创建是来自下游PIM邻居的(*,G)加入信息,或者一个希望加入组的的IGMP report,该条目的入口总是指向RP共享树。
稀疏模式(S,G)的创建是在接受到一条(S,G)加入信息或剪枝信息或者上一跳路由器切换到SPT 或者不可预料的(S,G)到达时(*,G)不存在或者在RP上接受到一条注册信息。
从OIL中添加一个表项的原因通过该接口收到一个适当的(S,G)或(*,G)加入消息或者该接口存在一个组成员。
从OIL中删除一个表项的原因通过该接口收到一个适当的(S,G)或(*,G)剪枝消息且不被否决或者计时器超时。
当(S,G)项的RPF邻居于(*,G)项的RPF邻居不同时(即IIL项不同),路由器将向共享树发送一个(S,G)RP位剪枝消息,也就是说该剪裁消息从共享树和SPT的分支点开始。
PIM-SM中剪枝的问题共享树的剪枝:当叶节点路由器没有直连组成员时,会简单的向共享树的上游路由器发送(S,G)Prune,上游路由器收到后就将其从OIL中清除,如果这个动作使得OIL为空,则(*,G)被标记为P(pruned),并向上发送(*,G)Prune。
源树的剪枝:源树的剪枝不是指Source和RP之间的SPT,而是Switchover以后形成的SPT的键值,其基本流程和共享树一样,需要明确的是(S,G)Prunes 是不会一跳跳延SPT向上发送的,到上游路由器就终止了。
Auto-RP和BSR为了省去在每台路由器上配置RP地址的麻烦,Cisco和IETF分别定义了Auto-RP和BSR来自动的配置RP地址。
Auto-RPAuto-RP有两个重要角色,备选RP和映射代理(MA,Mapping Agent),两个重要的组播地址,224.0.1.39和224.0.1.40。
机制是这样:所有配置上ip pim send-rp-announce interface scope ttl [group-list acl] 这条命令的路由器成为备选RP,并向224.0.1.39宣告自己是RP,其RP通知消息包括制定接口的IP地址(通常是环回口)以及组的范围,也就是说可以只在一些特定的组中是RP。
Router通过配置ip pim send-rp-discovery scope ttl 成为MA,并加入到224.0.1.39这个组(或者说监听这个地址),他接收所有备选RP的RP通知消息,并建立缓存表来存储这些信息,指定拥有最高IP地址的那个成为RP,然后将选举结果通过224.0.1.40通过出去,每60s通告一次。
这里就和OSPF中DR机制是一样的,DR通过大地址通告,DRother就得听着;DRother通过小地址上报,DRother通过监听小地址接收。
当MA要实现冗余时,每个MA都独立工作,只不过最后选举出来的RP是相同的一台路由器,因为选举机制是一样的;当然RP的备份,只要有两个Router 去竞争就好了,会形成主从关系。
Auto-RP会引发经典的鸡和鸡蛋的问题,如果在稀疏模式下网络,并且所有路由器均通过224.0.1.40了解RP信息,如果不知道RP的IP地址,怎么能加入到(*,224.0.1.40)共享树呢,如果不加入共享树,怎么能了解RP的IP地址呢?解决方案之一是在每台路由器上打下命令:ip pim rp-address 10.1.1.1 group-list 10access-list 10 permit 224.0.1.40access-list 10 deny any即有10.1.1.1这台router来引导大家发现224.0.1.40这个地址,这样一来不仅配置更加麻烦,还担心10.1.1.1会随时挂掉。
所以好的解决方案是在每台Router的接口上启用S-D-M,即密集-稀疏模式,该模式可以在密集和稀疏模式之间进行切换,切换的出发点是RP是否存在,如果Router没有该组的RP信息,那么就启动密集模式。