23.7.1 PIM-DM简介
密模式假定组播接收者遍布整个网络且分布密度较大。
初始状态下,路由器洪泛传递多播流量到符合下述条件的接口:
  连接到另一个  PIM-DM  邻居;
  该接口下有直接相连的组成员;
  接口被手工配置为加入一个组。
不需要该组播数据的分支可通过  Prune  消息裁剪掉,但是这种情况大约只能维持三分钟,因为
三分钟后路由器将重新执行  Flood  过程。所以,在使用密模式的网络中,充足的带宽是必要的。在密
模式中,多播状态的创建过程由多播数据的到达触发。当路由器收到由源   S    发往组   G  的多播消息
时,关于源组(S,G)的转发树随即生成,连续的三分钟没有收到该多播消息,  则源组(S,G)的转发树
被删除。密模式只使用源树,不使用共享树,源树的维持很简单,但是当网络结构变化时,可能会导  致
多播信息转发不稳定,临时性丢失数据的情况也可能发生。
 
组播成员用  Graft  消息来通知路由器它对某个刚刚被裁剪掉的组播数据的请求,根据前面的  介
绍,我们知道这不是必须的,因为成员只要耐心的等上至多三分钟,下一次  Flood  就可以  满足它的
要求,但是  Graft  机制可以减少这一延迟。如果两台路由器都转发同样的(S,G)多播流到一个公共的
多路访问局域网,重复流量将会出现,  Assert  机制将最终决定其中一台路由器的转发行为停止以避免
重复流量出现。
 
如果路由器从一个非RPF接口(到达该多播源的单播数据途经接口以外的所有其它接口)  收到了多
播数据,且这个接口是点对点类型,那么  Prune  消息将立即发送给上游路由器。 (如果不是  P2P  接口,
将由  Assert  机制做出最终裁定。)
当一个非  RPF  点对点接口不断收到多播数据时,速率限制  Prune  消息将被发送,
当一个  RPF点对点接口不再需要一组多播数据时也会发送速率限制  Prune  消息。
 
下图是最初的网络,所以的路由器都有(S,G)记录,多播数据被  Flood  传送。
 
接下来所有路由器通过其不需要该多播数据的接口向上游路由器发送  Prune  消息。
 
 
下图是最终形成的转发树,因为只有图中最下方的网络中存在多播的接收者,但是这种局面只能
维持三分钟,三分钟后,新一轮的  Flood&Prune  过程将再次发生。
 
 
23.7.2 PIM消息格式
PIM  各种数据包格式,其中包括:
Packet Headers(包头)        Hello Messages(问候消息)
Join/Prunes(加入/剪裁)      Grafts/Graft Acks(嫁接/嫁接应答)
Asserts(裁定)          PIM Registers(PIM  注册)//仅在PIM-SM中使用
PIM Register-Stop(PIM  注册停止)     //仅在PIM-SM中使用
 
上图中显示的是  PIM  版本  1  中的数据包头格式及主要字段的含义,PIM  版本  1  使用  IGMP协
议向  224.0.0.2(All Routers)发送  TTL=1  的数据包,这意味着控制信息不会跨越路由器传递。
 
 
上图是PIM版本2的包头,它与版本1最大的区别在于它不再依靠IGMP协议传送,而使用协议号为
103  的  PIM  专用协议,TTL=1  的  PIM  协议包发往  224.0.0.13(All PIM Routers)。
 
下面的各种数据包我们将只介绍  PIM  版本  2  的格式。
 
上图是版本  2  的  Hello  包格式。这个  Hello  包用来建立和维持邻居关系,每个  PIM  路由器
要周期性的发送这个包向邻居  PIM  路由器通告自己的存在。
Hello  包当中有很多  TLV(Type、Length、Vaule),常用的有以下几种:  
Holdtime(保持时间)收不到来自邻居设备的  Hello  包时,认为邻居不存在之前可以等待的时间。
DR Prioirty(DR  优先级)在子网中选择  DR  时使用。
Generation  ID(衍生  ID)一个随机的  32  位的值,用于决定检测到失败后多长时间需要重新激活邻
居关系。
 
 
上图是  PIM  加入/剪裁消息包,Upstream    Neighbor    Address(上游邻居地址)用来记录  RPF路径
中上游路由器的单播地址,Holdtime  表示此信息包的失效时间,Num.Groups  用来表示此包中包含的
.组的数量,Group List  中记录加入/剪裁组列表。
 
 
上图中显示的是  Group List  部分的内容,每一个多播组一个条目,其中详细记录了欲加入或剪裁
的多播源列表。后面要介绍的  Graft/Graft-ACK  消息包中也包含这一部分。图中的组地  址和源地址都
采用了特殊的编码形式,其中可以包含多种地址类型,虽然我们只介绍基于
IP  地址的  PIM  协议。
Graft/Graft-ACK  消息包格式与前面介绍的  Join/Prune  消息包的格式完全相同,不再列出。  与其
它包不同的是,它是所有  PIM  消息包中惟一要求可靠传输的消息包(需要确认)。
 
 
上图是  Assert  包的格式,当网络中存在多播消息转发的冗余路径时,Assert  机制用来裁定哪一
路由器保持转发,比较的原则是:路由协议不同时比较  Metric Preference(通常是管理距离),路由协
议相同时比较  Metric,度量值相同时则比较IP地址(IP地址高者胜出)。
 
 
上面是仅在  PIM    SM  中采用的  Register  消息包格式,DR(多播源的下一跳路由器)用它来向  RP
注册多播的发送,以便通过它将多播消息沿共享树传递到每一个多播接收者,DR  会  持续发送这个消
息直到收到来自  RP  的  Register-Stop  消息。
下面图中显示的就是  Register-Stop  消息包的格式,当  RP  已经加入到达  DR  的源树并从  SPF所
确定的路径接收到来自特定源的多播数据时,用它来通知  DR  停止发送注册消息。
 
23.7.3 PIM邻居发现
路由器通过周期性的查询(缺省  30  秒)来发现  PIM  邻居路由器的存在,对于多路访问网络,  这
种查询消息发现  224.0.0.2(All-Routers)。对于多路访问网络,还要选举  DR,IP  地址最高的路由器成为
DR。在疏模式中,DR负责为多路访问网段上的主机向  RP  发送  Join  消息,在密模式中,DR  的选举
没有意义。
 
.上图中显示的是  show  ip pim neighbor  命令的输出,我们可以清楚的看到上面五条记录中的
路由器和这台路由器同属于一个多路访问网络,171.68.0.91  因为有最高的  IP  地址而成为DR。
 
23.7.4 PIM状态
从单个路由器的角度看,PIM的状态表现为它对多播分布树的理解,从整个多播网络来看,PIM
的状态则表现为整个多播流量在网络中的传递情况。对于每个路由器,多播的传递情况通过多播路由
表来体现,我们可能通过命令  show ip mroute查看。
 
所有条目以(*,G)或(S,G)的形式存在。  每个条目中包含  RPF、OIL  等信息。源接口为通过  RPF
确定的到达多播源的最近路径的出口,地址为上游路由器的接口地址。OIL(Outgoing    Interface List  流
出接口列表)记录从流入接口进来的多播数据需要转送的所有接口。
(*,G)条目是多播路由器里的缺省条目,通常指向所有运行  PIM  的接口。做为所有(S,  G)条目
的父条目,当直连接口下的一台主机发出  Join  消息而又没有相应的多播源时,(*,  G)条目被创建。
因为这种条目并不反映真正的多播消息转发,所以  Incoming  interface  为空,  OIL  列表中包含所有连
有PIM-DM邻居路由器或多播组成员的接口,我们也可以使用命令ip  igmp  static-group  <group>静
态指定一个接口连于某多播组成员。(S,G)条目与具体的多播源组有关,用于指导路由器如何转发始
自特定源的多播数据。IIF  为  RPF  接口或与多播源相连接口,OIL  最初与(*,G)条目的  OIL  相同,并
根据  Flood&Prune过程中收到的  Join/Prune  消息做适当的改变。
 
23.7.5 PIM DM Flooding
多播数据包(128.9.160.43,224.2.127.254)经路由器  rtr-a  的  S0  口到达,路由器在产生
(128.9.160.43,224.2.127.254)转发条目前会先产生(*,224.2.127.254)条目,其OIL包括所有支持多播的
端口,(  128.9.160.43  ,  224.2.127.254  )条目的OIL复制于(*,224.2.127.254)(除去入口  S0),于是
128.9.160.43发出的所有到达  224.2.127.254  的多播数据经S0进入后洪泛传递到S1和S3端口。
 
对于路由器rtr-b,只有S0口参与多播活动,所以其转发表中(128.9.160.43,224.2.127.254)条目的
OIL为空,于是该记录带有P标志,rtr-b向rtr-a发送针对该源组的Prune消息.
 
23.7.6 PIM  裁剪
 
 
对于多播源组(128.9.160.43,224.2.127.254),rtr-b是叶节点,在它的下面没有任何接收者,于是
rtr-b  通过  S0口向rtr-a发送针对多播源组(128.9.160.43,224.2.127.254)的  Prune  消息,rtr-a  收到此消
息后从多播源组(128.9.160.43,224.2.127.254)的  OIL中修剪掉了  S3  端口。下图是修剪之后的rtr-a的多
播路由表,S3  口已经被标志为  Prune/Dense。
 
 
叶节点rtr-b不需要(S,G)源组的数据包,向rtr-a发送Prune消息,rtr-a在做修剪之前会等待一小段
时间,以确定该网段上是否还有其它的接收者存在, rtr-c  收到来自rtr-b的修剪消息后马上会向  rtr-a  发
送  Join消息,rtr-a  收到  Join  消息后中止了  Prune  行为。  这种机制可以保证多播接收者对多播数据
的接收不被中断,但是在下图所示的网络中却给我们带来麻烦,因为修剪行为在12秒才会发生。
 
23.7.7 PIM  嫁接
下图中,最开始的时候rtr-b和rtr-c的下面都没有任何源组(S,G)的接收者,于是它们发送Prune消
息到  rtr-a,在这一多播流被修剪之后,rtr-b  的下面的  Rcvr A  发出了针对源组(S,G)的Join消息。如果
rtr-b不发送  Graft  消息,那么Rcvr A  要等  3  分钟之后  rtr-a  再次Flood的时候才能收到  这组多播数据,
为了减少这一延时,rtr-b  向  rtr-a  发送Graft消息,请求重新向其发送源组(S,  G)的数据。
 
 
看起来似乎可以了,但问题是rtr-c会不会发送Prune消息到rtr-a,基于一个源组的Prune消息只会
在该条目创建且  OIL为空的时候发送一次,所以rtr-c只会在3分钟之后,rtr-a  再次  向其发送Flood的多
播消息时发送一次,但这不会中断rtr-b的接收,因为rtr-b在收到rtr-c的Prune消息后会立刻向rtr-a  发送
Join  消息覆盖掉  rtr-c  的  Prune  消息。
 
23.7.7 PIM  仲裁机制
 
如果不采取措施,C  所连接的接收者会收到两份重复的多播数据。路由器A和B都可以发现这个异
常情况,因为它们从一个属于(S,G)的  OIL  的接口收到了该源组的数据!这将触发仲裁过程的发生。
 
两台路由器会发出仲裁包,经过对管理距离,度量值以及  IP  地址的比较后,路由器  B  胜出,   路
由器  A  将其  E0  口从源组(S,G)的路由条目中裁减掉。
 
 
如果在多路访问网段上没有直接的多播接收者,仲裁的胜出者会向多路访问网段发出Prune消息
以检测该网段上是否还有其它路由器需要这一多播数据流,因为路由器  C  连有接收者,它会发出  Join
消息覆盖掉  Prune  消息,转发得以保持。  关于仲裁我们还有需要注意的地方,看下图:
 
 
路由器  C  的上游路由器指向了路由器B,但是路由器B在仲裁中失败了。
如果C不修改它的记录将上游路由器指向  A  的话,接下来的一段时间里它向上游路由器发出的
Joins,Prunes  或  Grafts  消息都不能对多播消息转发进行有效的控制。好在路由器  C  可  以听到  A  和
B  之间的仲裁信息并能就此作出正确的响应,如下图:
 
 
the Loser不能得知这一情况,直到3分钟之后才会重新打开Prune的端口,也就是说,图左侧的接
收者将有近3分钟的时间接收不到该多播数据流。
23.7.8 PIM  状态维持
密模式PIM的多播转发信息靠反复的  Flood&Prune  过程来维护,接收到多播数据包会复位(S,G)
超时计时器,超时计时器如果减到0,则相应条目会被删除,所有被  Prune  掉的端口在3分钟后会被
Flood过程重新启动,不需要的转发会再次被Prune掉。
 
23.7.9 PIM  密模式回顾
下图是最初的情况,所有的路由器向所有的端口  Flood  多播流量。
 
第一个修剪发生在上图所示部分,路由器C与B之间的多播信息没有经过RPF检验,因为C到达上面
的多播源所走的路径是经由  A,C与B之间的流量被减裁掉。
 
 
第二个修剪发生在上图所示部分,C和D形成了多播转发的冗余路径,经过仲裁过程,其中的一个
会成为胜利者。
 
第三个修剪发生在下图所示部分,原因很简单,因为路由器  I  没有与任何接收者相连。
 
 
E在收到它右侧的路由器的修剪消息后,向C发出修剪消息,但C不会做出修剪,因为该网段上直
接连有一个接收者。
 
 
类似的情况出现在上图中,G不需要该组播消息,向F发出修剪消息,但是H需要,所以它在收到
了G的  Prune  消息后向F发出的  Join  消息,覆盖掉了G的  Prune  消息。
 
路由器I下面网段出现了新的接收者,于是路由器I向路由器E发出Grant消息,E重新开始向路由器
I的转发。