【RFC3973】PIM-DM

参考文档:RFC3973 PIM-DM 个人学习使用

摘要

本文档规定了协议无关组播 - 密集模式 (PIM-DM)。 PIM-DM 是一种组播路由协议,它使用底层单播路由信息库将组播数据报泛洪到所有组播路由器。修剪消息用于防止之后的消息传播到没有组成员信息的路由器。

1 介绍

该规范为网络上密集分布的组播组定义了组播路由算法。该协议没有单播路由协议常用的拓扑发现机制。它采用与稀疏模式 PIM (PIM-SM) 相同的数据包格式。该协议称为 PIM-Dense Mode。

2 术语

2.1 定义

(1)组播路由信息库(Multicast Routing Information Base,MRIB)

这是组播拓扑表,通常源自单播路由表,或者携带组播特定拓扑信息的路由协议(例如MBGP)。 PIM-DM 使用 MRIB 做出有关 RPF 接口的决策。

(2)树信息库(Tree Information Base,TIB)

这是由 PIM 路由器维护的状态集合,并通过从本地主机接收 PIM 消息和 IGMP 信息来创建。它本质上存储该路由器上所有组播分发树的状态。

(3)反向路径转发(Reverse Path Forwarding,RPF)

RPF 是一种组播转发模式,只有当数据包在单播到达数据源的接口上收到时,数据包才会被转发。

(4)上游接口(Upstream Interface)

朝向数据源的接口,也被称为RFC接口。

(5)下游接口(Downstream Interface)

除上游接口之外的所有接口,包括路由器本身。

(6)(S,G) 对

与 IP 数据包关联的源 S 和目标组 G。

2.2 伪代码表述

我们在本规范的多个地方使用了集合表示法。

(1)A (+) B

是两个集合 A 和 B 的并集。

(2)A (-) B

是集合 A 中不属于集合 B 的元素。

(3)NULL

NULL 是空集或空列表。

此外,我们使用类似 C 的语法:

(1)= 表示变量的赋值

(2)== 表示比较是否相等

(3)!= 表示比较不等式

(4)大括号 { 和 } 用于分组。

3 PIM-DM 协议概述

PIM-DM 假设当源开始发送时,所有下游系统都希望接收组播数据报。最初,组播数据报被洪泛到网络的所有区域。 PIM-DM 使用 RPF 来防止泛洪时组播数据报的循环。如果网络的某些区域没有组成员,PIM-DM 将通过剪枝来修剪转发分支。

剪枝状态的生命周期是有限的。当生命周期到期时,数据将再次沿着先前修剪的分支转发。

剪枝状态与 (S,G) 对相关联。当组 G 的新成员出现在剪枝区域中时,路由器可以“嫁接”到该组的源 S,从而将剪枝分支重新转变为转发分支。

广播数据报并随后修剪不需要的分支,这个过程通常被称为洪泛和剪枝周期,是典型的密集模式协议。

为了最大限度地减少数据报的重复泛洪以及与特定 (S,G) 对相关的后续剪枝,PIM-DM 使用状态刷新消息该消息由直接连接到源的路由器发送,并在整个网络中传播。当路由器在其 RPF 接口上接收到状态刷新消息时,状态刷新消息会导致现有剪枝状态被刷新。

与具有内置拓扑发现机制的组播路由协议(例如,DVMRP)相比,PIM-DM 具有简化的设计,并且没有硬连接到特定的拓扑发现协议中。然而,这种简化确实会带来更多的开销,因为它会导致某些链路上发生洪泛和修剪,如果有足够的拓扑信息,这些是可以避免的;即决定一个接口是否通向特定组的任何下游成员。选择额外的开销有利于通过不依赖于特定的拓扑发现协议而获得的简化和灵活性。

PIM-DM 与 PIM-SM 的不同之处在于两个基本方面: 1) 不传输周期性连接,仅显式触发修剪和嫁接。 2) 没有集合点(RP)。这对于不能容忍单点故障的网络尤其重要。 (RP是共享组播分发树的根)。

4 协议规范

PIM-DM 的规范分为几个部分:

  • 4.1 节详细介绍了存储的协议状态。

  • 4.2 节规定了数据包转发规则。

  • 4.3 节详细说明了 Hello 消息的生成和处理。

  • 4.4 节规定了Join、Prune和Graft的生成和处理规则。

  • 4.5 节规定了状态刷新的生成和转发规则。

  • 4.6 节规定了Assert的生成和处理规则。

  • 4.7 节详细介绍了 PIM-DM 数据包格式。

  • 4.8 节总结了 PIM-DM 定时器及其默认值。

4.1 PIM 协议状态

4.1.1 通用状态

路由器存储以下非特定于组的状态:

对于每个接口:

  • Hello 定时器(HT)

  • 状态刷新能力

  • LAN 延迟已启用

  • 传播延迟 (PD)

  • 覆盖间隔(OI)

  • 邻居状态:

    对于每个邻居:

    • 来自邻居的Hello信息
    • 邻居的 Gen ID
    • 邻居的 LAN 修剪延迟
    • 邻居的覆盖间隔
    • 邻居状态刷新能力
    • 邻居活跃计时器 (NLT)

4.1.2 (S,G) 状态

对于每个源/组对 (S,G),路由器存储以下状态:

对于每个接口:

  • 本地成员:

    • 状态:“NoInfo"或者是"Include”
  • PIM (S,G) 剪枝状态:

    • 状态:“NoInfo”(NI)、“Pruned”(P)、“PrunePending”(PP)之一
    • 剪枝挂起计时器 (PPT)
    • 剪枝计时器 (PT)
  • (S,G) 断言状态:

    • 状态:“NoInfo”(NI)、“I lost Assert”(L)、“I won Assert”(W)之一
    • 断言定时器 (AT)
    • 断言获胜者的 IP 地址
    • 断言获胜者的断言指标

对于上游特定接口:

  • 嫁接/修剪状态:

    • 状态:“NoInfo”(NI)、“Pruned”(P)、“Forwarding”(F)、“AckPending”(AP) 之一
    • 嫁接重试定时器 (GRT)
    • 覆盖计时器 (OT)
    • 剪枝限制定时器 (PLT)
  • 发起人状态:

    • 源活动定时器 (SAT)
    • 状态刷新定时器 (SRT)

4.1.3 状态汇总宏

使用上面定义的状态,定义了以下“宏”,并将在以下部分中的状态机和伪代码的描述中使用它们。

最重要的宏是定义相关状态的传出接口列表(“olist”)的宏。

immediate_olist(S,G) = pim_nbrs (-) prunes(S,G) (+) (pim_include(*,G) (-) pim_exclude(S,G) ) (+) pim_include(S,G) (-) lost_assert(S,G) (-) boundary(G)
olist(S,G) = immediate_olist(S,G) (-) RPF_interface(S)

宏 pim_include(*,G) 和 pim_include(S,G) 表示由于主机是这些接口上的本地成员而可能或可能不将数据转发到的接口。

pim_include(*,G) = {all interfaces I such that: local_receiver_include(*,G,I)} 

pim_include(S,G) = {all interfaces I such that: local_receiver_include(S,G,I)} 

pim_exclude(S,G) = {all interfaces I such that: local_receiver_exclude(S,G,I)}

宏 RPF_interface(S) 返回源 S 的 RPF 接口。也就是说,它返回 MRIB 指示的用于到达 S 的接口。

如果 IGMP 模块或其他本地成员机制已确定接口 I 上存在本地成员接收S专门发送给G的流量,则宏 local_receiver_include(S,G,I) 为 true。

如果 IGMP 模块或其他本地成员机制已确定接口 I 上有本地成员寻求接收发送到 G 的所有流量,则宏 local_receiver_include(*,G,I) 为 true。

如果 local_receiver_include(*,G,I) 为 true,但没有本地成员寻求接收来自 S 的流量,则宏 local_receiver_exclude(S,G,I) 为 true。

pim_nbrs 是路由器上至少有一个活动 PIM 邻居的所有接口

prune(S,G) 是路由器收到 Prune(S,G) 消息的所有接口

prunes(S,G) = {所有接口 I 使得 DownstreamPState(S,G,I) 处于修剪状态}

lost_assert(S,G) 集合是路由器在其上丢失(S,G) 断言的所有接口。

boundary(G) = {具有组 G 的管理范围边界的所有接口 I}

RPF’ 是指向源的 RPF 邻居。(RPF接口连接的PIM路由器?)

4.2 数据包转发规则

PIM-DM数据包转发规则的伪代码定义如下。

iif 是数据包的传入接口。 S是数据包的源地址。 G是数据包的目的地址(组地址)。 RPF_interface(S) 是 MRIB 中用于将数据包路由到 S 的接口

首先,必须执行 RPF 检查,以确定是否应根据 TIB 状态和数据包到达的接口接受数据包。未通过 RPF 检查的数据包不得转发,路由器将为数据包中指定的(S,G)对执行断言过程。如果有一个数据包无法找到它到源的路由,那么它将被丢弃。

如果RPF检查通过,则为报文构建出接口列表。如果此列表不为空,则数据包必须转发到所有列出的接口。如果列表为空,则路由器将对数据包中指定的(S,G)对进行剪枝过程。

在接口 iif 上收到从 S 发送到 G 的数据包时:

if (iif == RPF_interface(S) AND UpstreamPState(S,G) != Pruned) {
	oiflist = olist(S,G) 
} 
else { 
    oiflist = NULL 
}

在 oiflist 中的所有接口上转发数据包

该伪代码采用以下“宏”定义:

UpstreamPState(S,G)是4.4.1节中Upstream(S,G)状态机的状态。

4.3 Hello消息

本节介绍Hello消息的生成和处理。

4.3.1 发送Hello消息

PIM-DM 使用 Hello 消息来检测其他 PIM 路由器。 Hello 消息在每个启用 PIM 的接口上定期发送。 Hello 消息被组播到 ALL-PIM-ROUTERS 组。当接口上启用 PIM 或路由器首次启动时,Hello 定时器 (HT) 必须设置为 0 到 Triggered_Hello_Delay 之间的随机值。如果多个路由器同时开机,这会阻止 Hello 消息同步。

在初始 Hello 消息之后,必须在每个 Hello_Period 发送一条 Hello 消息(持续保持Hello关系)。单个 Hello 定时器可用于触发在所有活动接口上发送 Hello 消息。除非超时,否则不应重置 Hello 计时器。

4.3.2 接收Hello消息

当收到 Hello 消息时,接收路由器应记录接收接口、发送者以及已识别选项中包含的任何信息。该信息在 Hello 消息的保持时间字段中保留几秒。如果从特定邻居 N 接收到新的 Hello 消息,则邻居活跃定时器 (NLT(N,I)) 必须重置为新接收到的 Hello 保持时间。如果从新邻居收到 Hello 消息,接收路由器应该在 0 到 Triggered_Hello_Delay 之间的随机延迟后发送自己的 Hello 消息

4.3.3 Hello消息保持时间

Hello 消息中的保持时间应设置为一个可以合理预期的值,该值可以使 Hello 保持活动状态,直到收到新的 Hello 消息。在大多数链接上,这将是 Hello_Period 值的 3.5 倍。

如果保持时间设置为“0xffff”,则接收路由器不得使该 Hello 消息超时(一直保持Hello连接)。此功能可用于按需链接,以避免通过定期的 Hello 消息保持链接。

如果收到“0”的保持时间,则相应的邻居状态立即到期。当 PIM 路由器关闭接口或更改 IP 地址时,应立即发送具有零保持时间的 Hello 消息(如果 IP 地址更改,则发送旧的 IP 地址),以使任何 PIM 邻居立即删除旧信息。

4.3.4 处理路由器故障

如果从具有不同生成 ID (GenID) 的活动邻居收到 Hello 消息,则该邻居已重新启动,并且可能不包含正确的 (S,G) 状态。 Hello 消息应该在发送任何其他消息之前,在 0 到 Triggered_Hello_Delay(参见 4.8)之间的随机延迟之后发送。如果邻居在下游,则路由器可以重播任何(S,G)对的最后状态刷新消息,对于该消息,它是断言获胜者,向下游路由器指示剪枝和断言状态。这些状态刷新消息应该在 Hello 消息之后立即发送出去。如果邻居是(S,G)条目的上游邻居,则路由器可以取消其剪枝限制定时器以允许发送剪枝并在上游路由器中重新建立剪枝状态。

启动时,路由器可以使用在接口上第一个 Hello 消息的 Hello_Period 内收到的任何状态刷新消息来建立状态信息。状态刷新源将是 RPF’(S),所有接口的剪枝状态将根据状态刷新消息中的剪枝指示位进行设置。如果设置了剪枝指示器,路由器应该将 PruneLimitTimer 设置为 Prune_Holdtime,并将所有下游接口上的 PruneTimer 设置为状态刷新间隔的两倍。然后路由器应该按照第 4.5.1 节中的描述传播状态刷新。

4.3.5 减少 LAN 上的剪枝传播延迟

如果 LAN 上的所有路由器都支持 LAN 剪枝延迟选项,则该 LAN 上的 PIM 路由器将使用收到的值来调整该接口上的 J/P_Override_Interval,并且该接口启用 LAN 延迟。

简而言之,为了避免多个下游路由器共享多路访问链路时剪枝覆盖(加入)消息同步,这些消息的发送被延迟一小段随机时间。随机化的周期是可配置的,默认值为 3 秒。

LAN 上的每个路由器在 LAN Prune Delay 选项的 Override Interval 字段中表达其对所需随机化量的看法。当 LAN 上的所有路由器都使用 LAN 剪枝延迟选项时,LAN 上的所有路由器必须将其 Override_Interval 设置为 LAN 上最大的 Override 值。

路由器在 LAN Prune Delay 选项中插入的 LAN Delay 表示链路上预期的消息传播延迟,并且应该由系统管理员进行配置。当链路上的所有路由器都使用 LAN 剪枝延迟选项时,LAN 上的所有路由器必须将传播延迟设置为 LAN 上最大的 LAN 延迟。

PIM 实施者应强制规定此延迟的允许值的下限,以允许在其路由器内调度和处理延迟。此类延迟可能会导致接收到的消息延迟处理,并导致触发的消息晚于预期发送。将此 LAN Prune Delay 设置为过低的值可能会导致临时转发中断,因为在上游邻居停止转发之前下游路由器将无法覆盖邻居的剪枝消息。

4.4 PIM-DM 修剪、加入和嫁接消息

本节介绍 PIM-DM Join、Prune 和 Graft 消息的生成和处理。剪枝消息被发送到 S 的上游邻居,以指示不需要从 S 到组 G 的流量。对于下游路由器A和B,如果A希望继续接收数据而B不想继续接收数据,则A将发送Join响应B的Prune以覆盖Prune。这是 PIM-DM 中唯一使用 Join 消息的情况。最后,使用 Graft 消息将先前剪枝的分支重新加入到树中。

4.4.1 上游Join、Prune 和 Graft消息

下面给出了用于发送 Prune、Graft 和 Join 消息的 Upstream(S,G) 状态机。共有三种状态。

  • Forwarding (F)

这是Upstream(S,G)状态机的起始状态。

如果状态机刚刚启动或者 oiflist(S,G) != NULL,则状态机处于此状态。

上游状态机的正常转发状态

  • Pruned (P)

集合 olist(S,G) 为空。路由器不会转发从 S 发送到组 G 的数据。

出口列表空,不需要转发消息,上游状态机处于剪枝的状态

  • AckPending (AP)

路由器处于 Pruned (P) 状态,但是在 Downstream (S,G)状态机中,这个(S,G)条目的一个输出接口发生了转换,表明从 S 到 G 的流量应该再次被转发。已经向 RPF’(S)发送了 Graft 消息,但是尚未收到 Graft Ack 消息。

上游状态机处于剪枝状态,不进行转发,但是下游接口收到了嫁接请求,则上游接口向RPF邻居发出Graft消息,但是还没有收到ACK时,处于AckPending状态等待ACK

此外,还有三个特定于状态机的计时器:

  • GraftRetry Timer (GRT(S,G))

当向上游发送 Graft 时设置此计时器。如果在定时器超时之前没有收到相应的GraftAck,则发送另一个Graft,并且重置GraftRetry定时器。当接收到 Graft Ack 消息时,计时器停止。该计时器通常设置为 Graft_Retry_Period(参见 4.8)。

  • Override Timer (OT(S,G))

当在上游接口上接收到 Prune(S,G) 且 olist(S,G) != NULL 时,设置此计时器。当定时器超时时,在上游接口上发送Join(S,G)消息。该定时器通常设置为 t_override(参见 4.8)。

类似之前说的A想要退出,但B不想退出,发Join来抑制Prune消息。

  • Prune Limit Timer (PLT(S,G))

该定时器用于对 LAN 上的 Prune 进行速率限制。仅当Upstream(S,G)状态机处于Pruned状态时使用。如果此计时器正在运行,则无法发送修剪。该定时器通常设置为 t_limit(参见 4.8)。

当上游状态机已经是剪枝的状态了,不需要再次发送Prune消息。

在这里插入图片描述
以表格形式,状态机定义如下:
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

4.4.1.1 从Forwarding(F)状态的转换

当Upstream(S,G)状态机处于Forwarding(F)状态时,以下事件可能会触发转换:

  • 数据包到达 RPF_Interface(S) 并且 olist(S,G) == NULL 并且 S 未直接连接

Upstream(S,G) 状态机必须转换到 Pruned § 状态,将 Prune(S,G) 发送到 RPF’(S),并将 PLT(S,G) 设置为 t_limit 秒。

有数据来了,但是下游没人想要,变为剪枝状态

  • 从 RPF’(S) 收到State Refresh(S,G)

Upstream(S,G) 状态机保持转发状态。如果收到的State Refresh的剪枝指示位设置为 1,则该路由器必须在短随机间隔后覆盖上游路由器的修剪状态。如果 OT(S,G) 未运行且剪枝指示符位等于 1,则路由器必须将 OT(S,G) 设置为 t_override 秒。

  • OT(S,G) 过期且 S 未直接连接

OverrideTimer (OT(S,G)) 到期。路由器必须向 RPF’(S) 发送 Join(S,G) 以覆盖先前检测到的剪枝。上游(S,G)状态机保持在转发(F)状态。

  • olist(S,G) -> NULL 且 S 不直接连接

Upstream(S,G) 状态机必须转换到 Pruned § 状态,发送 Prune(S,G) 到 RPF’(S),并将 PLT(S,G) 设置为 t_limit 秒

  • RPF’(S) 更改 且 olist(S,G) 为非 NULL 并且 S 不直接连接

单播路由或断言状态会导致 RPF’(S) 发生变化,包括 RPF_Interface(S) 的变化。 Upstream(S,G) 状态机必须转换到 AckPending (AP) 状态,将 Graft 单播到新的 RPF’(S),并将 GraftRetry 定时器 (GRT(S,G)) 设置为 Graft_Retry_Period。

  • RPF’(S) 更改 且 olist(S,G) 为 NULL

单播路由或断言状态会导致 RPF’(S) 发生变化,包括 RPF_Interface(S) 的变化。上游(S,G)状态机必须转换到剪枝(P)状态。

4.4.1.2 从Pruned§状态的转换

当Upstream(S,G)状态机处于Pruned§状态时,以下事件可能会触发转换:

  • 数据到达 RPF_interface(S) 并且 PLT(S,G) 未运行且 S 未直接连接

LAN 上的另一个路由器需要从 S 发送到 G 的流量,或者先前的剪枝丢失。为了防止响应每个数据包生成 Prune(S,G),使用 PruneLimit 定时器 (PLT(S,G))。一旦 PLT(S,G) 过期,路由器需要发送另一个剪枝以响应未直接从源接收的数据包。 Prune(S,G) 必须发送到 RPF’(S),并且 PLT(S,G) 必须设置为 t_limit。

  • 从 RPF’(S) 收到State Refresh(S,G)

Upstream(S,G) 状态机保持剪枝状态。如果状态刷新将其剪枝指示位设置为零并且 PLT(S,G) 未运行,则必须将Prune(S,G) 发送到 RPF’(S),并且必须将 PLT(S,G) 设置为 t_limit。如果状态刷新的修剪指示位设置为 1,则路由器必须将 PLT(S,G) 重置为 t_limit。

  • olist(S,G)->非 NULL 且 S 不直接连接

olist(S,G) 宏定义的接口集变为非空,表示必须转发从 S 寻址到组 G 的流量。 Upstream(S,G) 状态机必须取消 PLT(S,G),转换到 AckPending (AP) 状态并向 RPF’(S) 单播 Graft 消息。Graft Retry Timer (GRT(S,G)) 必须设置为 Graft_Retry_Period。

  • RPF’(S) 更改 且 olist(S,G) == 非 NULL 且 S 不直接连接

单播路由或断言状态会导致 RPF’(S) 发生变化,包括 RPF_Interface(S) 的变化。 Upstream(S,G)状态机必须取消PLT(S,G),转换到AckPending(AP)状态,发送Graft单播到新的RPF’(S),并设置GraftRetry定时器(GRT(S, G)) 到 Graft_Retry_Period。

  • RPF’(S) 更改 且 olist(S,G) == NULL 且 S 不直接连接

单播路由或断言状态会导致 RPF’(S) 发生变化,包括 RPF_Interface(S) 的变化。 Upstream(S,G) 状态机保持在 Pruned 状态,并且必须取消 PLT(S,G) 定时器。

下游没有接收者,继续保持Pruned,但是上游邻居变了,要取消PLT,发送Prune让新邻居知道自己

  • S 变为直接连接

单播路由发生变化,S 直连。 Upstream(S,G) 状态机保持在 Pruned (P)状态。

4.4.1.3 从AckPending(AP)状态的转换

当Upstream(S,G)状态机处于AckPending(AP)状态时,以下事件可能会触发转换:

  • 从 RPF’(S) 接收State Refresh(S,G),且 剪枝指示器 == 1

Upstream(S,G) 状态机保持在 AckPending 状态。路由器必须在短暂的随机间隔后覆盖上游路由器的剪枝状态。如果 OT(S,G) 未运行且修剪指示符位等于 1,则路由器必须将 OT(S,G) 设置为 t_override 秒。

  • 从 RPF’(S) 接收State Refresh(S,G),剪枝指示器 == 0

路由器必须取消其 GraftRetry Timer(GRT(S,G))并转换到转发(F)状态。

  • OT(S,G) 到期

OverrideTimer (OT(S,G)) 到期。路由器必须向 RPF’(S) 发送 Join(S,G)。 Upstream(S,G) 状态机保持在 AckPending (AP) 状态。

  • olist(S,G) -> NULL

由 olist(S,G) 宏定义的接口集变为空,指示不应再转发从 S 寻址到组 G 的流量。上游(S,G)状态机必须转换到剪枝(P)状态。 Prune(S,G) 必须多播到 RPF_interface(S),并在上游邻居字段中指定 RPF’(S)。必须取消 GraftRetry 定时器 (GRT(S,G)),并且必须将 PLT(S,G) 设置为 t_limit 秒。

下面没人需要了,不需要Graft了,直接变成Prune

  • RPF’(S) 更改 且 olist(S,G) 不为 NULL 并且 S 不直连

单播路由或断言状态会导致 RPF’(S) 发生变化,包括 RPF_Interface(S) 的变化。 Upstream(S,G) 状态机保持在 AckPending (AP) 状态。Graft 必须单播到新的 RPF’(S),并且 GraftRetry Timer (GRT(S,G)) 重置为 Graft_Retry_Period

  • RPF’(S) 更改 且 olist(S,G) == NULL 且 S 不直接连接

单播路由或断言状态会导致 RPF’(S) 发生变化,包括 RPF_Interface(S) 的变化。上游(S,G)状态机必须转换到剪枝(P)状态。必须取消GraftRetry Timer(GRT(S,G))。

  • S 变为直接连接

单播路由已更改,因此 S 是直连的。必须取消 GraftRetry 定时器,并且上游(S,G)状态机必须转换到转发(F)状态。

  • GraftRetry 定时器到期

此 (S,G) 条目的GraftRetry Timer (GRT(S,G)) 到期。 Upstream(S,G) 状态机保持在 AckPending (AP) 状态。 (S,G) 的另一个Graft消息应该单播到 RPF’(S),并且 GraftRetry 计时器 (GRT(S,G)) 重置为 Graft_Retry_Period。

4.4.2 下游剪枝、加入和移植消息

下面给出了接口 I 上接收 Prune、Join 和 Graft 消息的 Prune Downstream state machine。该状态机必须始终在上游接口上处于 NoInfo 状态。它包含三个状态。

  • NoInfo(NI)

接口没有(S,G) Prune 状态,并且Prune 定时器(PT(S,G,I)) 和PrunePending 定时器((PPT(S,G,I)) 都没有运行。

  • PrunePending(PP)

路由器已在此接口上收到来自下游邻居的剪枝(S,G),并正在等待查看该剪枝是否会被另一个下游路由器覆盖。出于转发目的,PrunePending 状态的功能与 NoInfo 状态完全相同。

  • Pruned(P)

路由器已在此接口上收到来自下游邻居的 Prune(S,G),并且该 Prune 未被覆盖。从 S 发送到组 G 的数据不再在此接口上转发。

此外,还有两个定时器:

  • PrunePending Timer (PPT(S,G,I))

当收到有效的 Prune(S,G) 时设置此计时器。 PrunePending 计时器 (PPT(S,G,I)) 到期会导致接口转换为 Pruned 状态。

  • Prune Timer (PT(S,G,I))

当 PrunePending Timer (PT(S,G,I)) 到期时设置该定时器。Prune Timer (PT(S,G,I)) 到期导致接口转换到 NoInfo (NI) 状态,从而允许从 S 寻址到组 G 的数据在接口上转发。

从这里也可以看出来,DM模式是推模式,在一段时间的Prune状态之后,会自动变为接收数据状态。

在这里插入图片描述

以表格形式表示,状态机如下:

在这里插入图片描述

4.4.2.1 从NoInfo状态的转换

当 Prune(S,G) Downstream 状态机处于 NoInfo (NI) 状态时,以下事件可能会触发转换:

  • 接收 Prune(S,G)

接口 I 上接收到 Prune(S,G),其上游邻居字段设置为 I 上的路由器地址。接口 I 上的 Prune(S,G) 下游状态机必须转换到 PrunePending (PP) 状态。如果路由器在 I 上有多个邻居,则 PrunePending 计时器 (PPT(S,G,I)) 必须设置为 J/P_Override_Interval。如果路由器在接口 I 上只有一个邻居,则应设置 PPT(S ,G,I) 为零,有效地立即转换到Pruned §状态。

如果只有一个下游邻居,直接变为Prune即可,因为不会再有Join抑制消息了

  • 接收 Graft(S,G)

接口 I 上接收到 Graft(S,G),其上游邻居字段设置为 I 上的路由器地址。接口 I 上的 Prune(S,G) 下游状态机保持在 NoInfo (NI) 状态。 GraftAck(S,G) 必须单播到 Graft(S,G) 消息的发起者

收到graft要回ACK

4.4.2.2 从PrunePending(PP)状态的转换

当 Prune(S,G) 下游状态机处于 PrunePending (PP) 状态时,以下事件可能会触发转换。

  • 接收 Join(S,G)

接口 I 上收到 Join(S,G),且上游邻居字段设置为 I 上的路由器地址。接口 I 上的 Prune(S,G) 下游状态机必须转换到 NoInfo (NI) 状态。 PrunePending 计时器 (PPT(S,G,I)) 必须取消

上游邻居字段是I,说明发送者是I的下游。收到了join抑制。取消PP,继续发送

  • 收到 Graft(S,G)

接口 I 上接收到 Graft(S,G),其上游邻居字段设置为 I 上的路由器地址。接口 I 上的 Prune(S,G) 下游状态机必须转换到 NoInfo (NI) 状态并且必须单播发送给 Graft 发起者的 Graft Ack 消息。 PrunePending 定时器 (PPT(S,G,I)) 必须被取消。

收到Graft就要回ACK

  • PPT(S,G,I) 过期

PrunePending Timer (PPT(S,G,I)) 到期,表明没有邻居覆盖之前的 Prune(S,G) 消息。接口 I 上的 Prune(S,G) 下游状态机必须转换到 Pruned § 状态。修剪定时器 (PT(S,G,I)) 启动,并且必须初始化为接收到的 Prune_Hold_Time 减去 J/P_Override_Interval。如果 I 有多个 PIM 邻居,则必须在 I 上发送 PruneEcho(S,G)。

PruneEcho(S,G) 只是上游路由器向 LAN 多播的 Prune(S,G) 消息,其自身作为上游邻居。其目的是增加额外的可靠性,以便如果本应覆盖 Prune 的 Join 在 LAN 本地丢失,则可以接收 PruneEcho(S,G) 并触发新的 Join 消息。 PruneEcho(S,G) 在只有一个 PIM 邻居的接口上是可选的。此外,路由器必须评估上游(S,G)状态机中任何可能的转换。

  • RPF_Interface(S) 变为接口 I

S 的上游接口已更改。接口 I 上的 Prune(S,G) 下游状态机必须转换到 NoInfo (NI) 状态。 PrunePending 定时器 (PPT(S,G,I)) 必须被取消。

4.4.2.3 从Prune(P)状态的转换

当 Prune(S,G) Downstream 状态机处于 Pruned 状态时,以下事件可能会触发转换。

  • 收到Prune(S,G)

接口 I 上接收到 Prune(S,G),其上游邻居字段设置为 I 上的路由器地址。接口 I 上的 Prune(S,G) 下游状态机保持在 Pruned (P)状态。如果Prune Timer(PT(S,G,I))大于当前值,则应将其重置为剪枝(S,G)消息中包含的保持时间。

  • 收到Join(S,G)

在接口 I 上接收到 Join(S,G),并将上游邻居字段设置为 I 上的路由器地址。接口 I 上的 Prune(S,G) 下游状态机必须转换到 NoInfo (NI) 状态。Prune Timer(PT(S,G,I)) 必须取消。路由器必须评估Upstream(S,G)状态机中任何可能的转换。

  • 收到Graft(S,G)

接口 I 上接收到 Graft(S,G),其上游邻居字段设置为 I 上的路由器地址。接口 I 上的 Prune(S,G) Downstream state machine 必须转换为 NoInfo (NI) 状态并发送将 Ack回Graft消息发送者。Prune Timer (PT(S,G,I)) 必须取消。路由器必须评估上游(S,G)状态机中任何可能的转换。

  • PT(S,G,I) 到期

Prune Timer (PT(S,G,I))到期,表明又到了将 S 发送到组 G 的数据洪泛到接口 I 的时间了。接口 I 上的Prune(S,G) Downstream状态机必须转换为无信息 (NI) 状态。路由器必须评估上游(S,G)状态机中任何可能的转换。

剪枝的持续时间到了,继续变成NI接收数据

  • RPF_Interface(S) 变为接口 I

S 的上游接口已更改。接口 I 上的 Prune(S,G) 下游状态机必须转换到 NoInfo (NI) 状态。 PruneTimer (PT(S,G,I)) 必须被取消。

  • 向接口 I 发送状态刷新(S,G)

路由器已经刷新了接口 I 上的Prune(S,G)。路由器必须将Prune Timer(PT(S,G,I))重置为接口 I 上收到的活动剪枝的保持时间。使用的保持时间应该是最大的活跃时间,但可能是最近收到的活跃修剪保留时间。

4.5 状态刷新

本节描述状态 state refresh 的主要部分。

4.5.1 状态刷新消息转发

当收到状态刷新消息SRM时,按照以下伪代码进行转发

if (iif != RPF_interface(S)) 
	return; 
if (RPF’(S) != srcaddr(SRM)) 
	return; 
if (StateRefreshRateLimit(S,G) == TRUE) 
	return; 
	
for each interface I in pim_nbrs { 
	if (TTL(SRM) == 0 OR (TTL(SRM) - 1) < Threshold(I)) 
		continue; /* Out of TTL, skip this interface */ 
	if (boundary(I,G)) 
		continue; /* This interface is scope boundary, skip it */ 
	if (I == iif) 
		continue; /* This is the incoming interface, skip it */ 
	if (lost_assert(S,G,I) == TRUE) 
		continue; /* Let the Assert Winner do State Refresh */ 
	Copy SRM to SRM’; /* Make a copy of SRM to forward */ 
	if (I contained in prunes(S,G)) { 
		set Prune Indicator bit of SRM’ to 1; 
		if StateRefreshCapable(I) == TRUE 
			set PT(S,G) to largest active holdtime read from a Prune message accepted on I;
	} 
		else { 
			set Prune Indicator bit of SRM’ to 0; 		  
		} 
	set srcaddr(SRM’) to my_addr(I); 
	set TTL of SRM’ to TTL(SRM) - 1; 
	set metric of SRM’ to metric of unicast route used to reach S; 
	set pref of SRM’ to preference of unicast route used to reach S; 
	set mask of SRM’ to mask of route used to reach S; 
	if (AssertState == NoInfo) { 
		set Assert Override of SRM’ to 1; 
	} 
	else { 
		set Assert Override of SRM’ to 0; 
    } 
    transmit SRM’ on I;
}

上面的伪代码采用以下宏定义。

如果在接口 I 上配置了组 G 的管理范围边界,则 Boundary(I,G) 为 TRUE。
如果接口上的所有邻居都使用状态刷新选项,则 StateRefreshCapable(I) 为 TRUE。
如果自上次收到 StateRefresh(S,G) 以来经过的时间小于配置的 RefreshLimitInterval,则 StateRefreshRateLimit(S,G) 为 TRUE。
TTL(SRM) 返回状态刷新消息 SRM 中包含的 TTL。这与 IP 标头中包含的 TTL 不同。
Threshold(I) 返回数据包在接口 I 上传输之前必须具有的最小 TTL。
srcaddr(SRM) 返回状态刷新消息 SRM 的网络协议(例如 IPv4)标头中包含的源地址。
my_addr(I) 返回该节点在接口 I 上的网络(例如 IPv4)地址。

4.5.2 状态刷新消息发起

本节描述状态刷新消息的起源。这些消息由直接连接到源的 PIM-DM 路由器定期生成。 PIM-DM 路由器中的每个 (S,G) 条目都存在一个Origination(S,G) state machine。

Origination(S,G) 状态机具有以下状态:

  • NotOriginator(NO)

这是 Origination(S,G) 状态机的起始状态。在此状态下,路由器不会为(S,G)对发起状态刷新消息。

  • Originator(O)

处于此状态时,路由器将定期发起状态刷新消息。只有直接连接到 S 的路由器才能转换到此状态。

此外,还有两个状态机特定定时器:

  • State Refresh Timer (SRT(S,G))

该定时器控制何时生成状态刷新消息。当 Origination(S,G) 状态机转换到 O 状态时,计时器被初始设置。当 Origination(S,G) 状态机转换为 NO 状态时,它被取消。该计时器通常设置为 StateRefreshInterval(参见 4.8)。

  • Source Active Timer (SAT(S,G))

当 Origination(S,G) 状态机转换到 O 状态时首先设置此计时器,并在收到从 S 发送到组 G 的每个数据包时重置该计时器。当它到期时,Origination(S,G) 状态机转换到 NO 状态。该计时器通常设置为 SourceLifetime(参见 4.8)。
在这里插入图片描述

以表格形式,状态机定义如下:
在这里插入图片描述

4.5.2.1 从 NotOriginator (NO) 状态的转换

当 Originating(S,G) 状态机处于 NotOriginator (NO) 状态时,以下事件可能会触发转换:

  • 从直接连接的源 S 接收到的发送至组 G 的数据包

路由器必须转换到发起者 (O) 状态,将 SAT(S,G) 设置为 SourceLifetime,并将 SRT(S,G) 设置为 StateRefreshInterval。路由器应该记录数据包的 TTL,以便在状态刷新消息中使用。

4.5.2.2 从Originator (O) 状态的转换

当 Originating(S,G) 状态机处于 Originator (O) 状态时,以下事件可能会触发转换:

  • 接收从 S 发往 G 的数据包

路由器保持在发起者 (O) 状态,并且必须将 SAT(S,G) 重置为 SourceLifetime。如果数据包的 TTL 大于先前记录的 TTL,路由器应该增加其记录的 TTL 以匹配数据包的 TTL。路由器可以根据特定于实现的采样策略记录 TTL,以避免检查它处理的每个多播数据包的 TTL。

  • SRT(S,G) 到期

路由器保持在发起者 (O) 状态,并且必须将 SRT(S,G) 重置为 StateRefreshInterval。路由器还必须生成用于传输的状态刷新消息,如状态刷新转发规则(第 4.5.1 节)中所述,但 TTL 除外。

如果从S到G的数据包的TTL正在被记录,则每个状态刷新消息的TTL被设置为记录的最高的TTL。否则,TTL 将设置为配置的状态刷新 TTL。让 I 表示正在发送状态刷新消息的接口。如果 Prune(S,G) 下游状态机处于 Pruned § 状态,则在通过 I 发送的状态刷新消息中,PruneIndicator 位必须设置为 1。否则,Prune-Indicator 位必须设置为0。

  • SAT(S,G) 过期

路由器必须取消 SRT(S,G) 计时器并转换到 NotOriginator (NO) 状态。

  • S不再直接连接

路由器必须转换到 NotOriginator (NO) 状态并取消 SAT(S,G) 和 SRT(S,G)。

4.6 PIM 断言消息

4.6.1 断言度量指标

Assert metrics 定义如下:

struct assert_metric { 
	metric_preference; 
	route_metric; 
	ip_address; 
};

当比较assert_metrics时,metric_preference和route_metric字段按顺序比较,第一个较低的值获胜。如果所有字段都相等,则发出断言消息的路由器的 IP 地址将用作决胜局,最高的 IP 地址获胜。

IP肯定是不等的,所以肯定有一个获胜者

应使用以下伪代码计算在接口 I 上发送的断言消息中的(S,G)的 Assert metric:

assert_metric 
my_assert_metric(S,G,I) { 
	if (CouldAssert(S,G,I) == TRUE) { 
		return spt_assert_metric(S,G,I) 
	} 
	else { 
		return infinite_assert_metric() 
	} 
}

spt_assert_metric(S,I) 给出了我们在活动 (S,G) 转发状态时,发送断言使用的Assert metric:

assert_metric 
spt_assert_metric(S,I) { 
	return {0,MRIB.pref(S),MRIB.metric(S),my_addr(I)} 
}

MRIB.pref(X) 和 MRIB.metric(X) 是与到特定(单播)目的地 X 的路由相关联的路由偏好和路由度量,由 MRIB 确定。 my_addr(I) 只是与本地接口 I 关联的路由器网络(例如 IP)地址。

infinite_assert_metric() 给出了我们发送断言所需的断言度量,但与 (S,G) 转发状态不匹配:

assert_metric infinite_assert_metric() { 
	return {1,infinity,infinity,0} 
}

4.6.2 断言取消消息

AssertCancel(S,G) 消息只是具有infinite metric的 (S,G) 的断言消息。

并不是新的消息格式,只是infinity的断言消息

当断言获胜者将其上游接口更改为该接口时,它会发送此消息。其他路由器将看到此指标,导致具有转发状态的路由器发送自己的断言并重新建立断言获胜者。

之前断言获胜者不再工作,重新选举

4.6.3 断言状态宏

宏lost_assert(S,G,I),用于第4.1.3节的olist计算,定义如下:

bool lost_assert(S,G,I) { 
	if ( RPF_interface(S) == I ) { 
		return FALSE 
	} 
	else { 
		return (AssertWinner(S,G,I) != me AND 				(AssertWinnerMetric(S,G,I) is better than spt_assert_metric(S,G,I))) 
	} 
}

当处于 NoInfo 状态时,AssertWinner(S,G,I) 默认为 NULL,AssertWinnerMetric(S,G,I) 默认为 Infinity。

4.6.4 (S,G) 断言消息状态机

接口 I 的 (S,G) Assert 状态机如图 4 所示。共有三种状态:

  • NoInfo (NI)

该路由器在接口 I 上没有 (S,G) 断言状态。

  • I am Assert Winner (W)

该路由器已在接口 I 上赢得了 (S,G) 断言。它现在负责通过接口 I 转发从 S 发往 G 的流量。

  • I am Assert Loser (L)

该路由器在接口 I 上丢失了 (S,G) 断言。它不得将从 S 发往 G 的数据包转发到接口 I。

此外,Assert Timer(AT(S,G,I))用于使断言状态超时。

在这里插入图片描述

术语:

“preferred assert”是指比当前获胜者具有更好指标的断言。

“inferior assert”是指比 my_assert_metric(S,G,I) 更差的断言。

状态机使用以下宏:

CouldAssert(S,G,I) = (RPF_interface(S) != I)
4.6.4.1 从 NoInfo 状态的转换

在NoInfo状态下,以下事件可能会触发转换:

  • (S,G)数据包到达下游接口I

(S,G)数据包到达下游接口。乐观地假设该路由器将成为此(S,G)的断言获胜者。 Assert 状态机必须转换到“I am Assert Winner”状态,发送 Assert(S,G) 到接口 I,将自己的地址和度量存储为 Assert Winner,并设置 Assert_Timer (AT(S,G, I) 到 Assert_Time,从而启动 (S,G) 的 Assert 协商。

  • 接收(Inferior Assert 或 State Refresh) 且CouldAssert(S,G,I)==TRUE

收到的 (S,G) 断言或状态刷新低于我们在接口 I 上自己的断言度量。断言状态机必须转换到“I am Assert Winner”状态,发送断言(S,G) 到接口I,将自己的地址和度量存储为Assert Winner,并将Assert Timer(AT(S,G,I))设置为Assert_Time。

  • 接收Preferred Assert 或 State Refresh

收到的断言或状态刷新具有比该路由器更好的度量,因此断言状态机必须转换到“I am Assert Loser”状态并存储断言获胜者的地址和度量。

如果在断言中收到度量,则路由器必须将断言定时器 (AT(S,G,I)) 设置为 Assert_Time。

如果在状态刷新中接收到度量,则路由器必须将断言定时器(AT(S,G,I))设置为接收到的状态刷新间隔的三倍。

如果 CouldAssert(S,G,I) == TRUE,则路由器还必须向断言获胜者多播一个 Prune(S,G),其剪枝保持时间等于断言计时器,并评估其 Upstream(S,G) 中的任何变化) 状态机

4.6.4.2 从 Winner 状态的转换

当处于“I am Assert Winner”状态时,以下事件会触发转换:

  • (S,G)数据包到达下游接口I

(S,G)数据包到达下游接口。 Assert 状态机保持在“I am Assert Winner”状态。路由器必须向接口 I 发送 Assert(S,G) 并将 Assert Timer (AT(S,G,I)) 设置为 Assert_Time。

  • 接收 Inferior Assert 或者 State Refresh

收到的 (S,G) 断言包含 S 的度量,该度量比该路由器的 S 度量更差。无论谁发送该断言,都是错误的。路由器必须向接口 I 发送 Assert(S,G) 并将 Assert Timer (AT(S,G,I)) 重置为 Assert_Time。

  • 接收Preferred Assert 或者 State Refresh

收到一个 (S,G) 断言或状态刷新,其度量比该路由器在接口 I 上的 S 度量更好。断言状态机必须转换到“I am Assert Loser”状态并存储新的断言获胜者的地址和度量。

如果在断言中收到度量,则路由器必须将断言定时器 (AT(S,G,I)) 设置为 Assert_Time。

如果在状态刷新中收到度量,则路由器必须将断言定时器 (AT(S,G,I)) 设置为状态刷新间隔的三倍。

路由器还必须向断言获胜者多播Prune(S,G),Prune保持时间等于断言定时器,并评估其上游(S,G)状态机中的任何变化。

  • 发送状态刷新

路由器正在接口 I 上发送状态刷新(S,G)消息。路由器必须将断言定时器(AT(S,G,I))设置为状态刷新(S,G)中包含的状态刷新间隔的三倍) 信息。

  • AT(S,G,I) 到期

(S,G) 断言定时器 (AT(S,G,I)) 到期。断言状态机必须转换到 NoInfo (NI) 状态。

  • CouldAssert(S,G,I) -> FALSE

该路由器的 RPF 接口发生更改,使得 CouldAssert(S,G,I) 为 false。该路由器不能再执行 Assert 获胜者的操作,因此 Assert 状态机必须转换到 NoInfo (NI) 状态,向接口 I 发送 AssertCancel(S,G),取消 Assert Timer (AT(S,G, I)),并删除自己作为断言获胜者的身份。

4.6.4.3 从 Loser 状态的转换

当处于“I am Assert Loser”状态时,可能会发生以下转换:

  • 从当前获胜者处接收Inferior Assert 或 State Refresh

从当前断言获胜者收到的断言或状态刷新比该路由器的 S 度量更差(通常,是获胜者的度量变差)。断言状态机必须转换到 NoInfo (NI) 状态并取消 AT(S,G,I)。

路由器必须删除之前的断言获胜者的地址和度量,并评估任何可能的到其上游(S,G)状态机的转换。

通常,当来自 S 的数据包再次开始流动时,该路由器最终将重新断言并获胜。

  • 接收Preferred Assert 或 State Refresh

收到的断言或状态刷新的指标优于或等于当前断言获胜者的指标。

Assert 状态机保持 Loser (L) 状态。如果在断言中收到度量,则路由器必须将断言定时器 (AT(S,G,I)) 设置为 Assert_Time。

如果在状态刷新中接收到度量,则路由器必须将断言定时器(AT(S,G,I))设置为接收到的状态刷新间隔的三倍。

如果度量值比当前的 Assert Winner 更好,则路由器必须存储新的 Assert Winner 的地址和度量值,并且如果 CouldAssert(S,G,I) == TRUE,则路由器必须多播 Prune(S,G)给新的断言获胜者。

  • AT(S,G,I) 到期

(S,G) Assert Timer (AT(S,G,I)) 到期。断言状态机必须转换到 NoInfo (NI) 状态。路由器必须删除断言获胜者的地址和度量。如果 CouldAssert == TRUE,路由器必须评估任何可能的到其 Upstream(S,G) 状态机的转换。

  • CouldAssert -> FALSE

CouldAssert 已变为 FALSE,因为接口 I 已成为 S 的 RPF 接口。Assert 状态机必须转换到 NoInfo (NI) 状态,取消 AT(S,G,I),并删除有关 I 上的 Assert Winner 的信息。

  • CouldAssert -> TRUE

CouldAssert 已变为 TRUE,因为接口 I 曾经是 S 的 RPF 接口,而现在不是。断言状态机必须转换到 NoInfo (NI) 状态,取消 AT(S,G,I),并删除有关 I 上的断言获胜者的信息。

  • 当前Assert Winner 的 NeighborLiveness Timer到期

当前断言获胜者的 NeighborLiveness 计时器 (NLT(N,I)) 已过期。断言状态机必须转换到 NoInfo (NI) 状态,删除断言获胜者的地址和度量,并评估任何可能的到其上游 (S,G) 状态机的转换。

  • 接收 Prune(S,G)、Join(S,G) 或 Graft(S,G)

在接口 I 上接收到 Prune(S,G)、Join(S,G) 或 Graft(S,G) 消息,其上游邻居地址设置为 I 上的路由器地址。路由器必须发送 Assert(S, G) 在接收接口I上发起Assert协商。 Assert 状态机保持在 Assert Loser(L) 状态。如果接收到 Graft(S,G),路由器必须用 GraftAck(S,G) 进行响应。

4.6.5 断言规则的基本原理

下面总结了Assert消息的生成和处理规则。它并不是确定的(状态机和伪代码提供确定的行为)。相反,它为该行为提供了一些理由。

  1. (S,G) 的断言获胜者必须代表所有下游成员充当 (S,G) 的本地转发者。
  2. PIM 消息定向到 RPF’ 的邻居,而不是常规 RPF 邻居。
  3. 收到指向它的 Prune(S,G)、Join(S,G) 或 Graft(S,G) 的 Assert 失败者发起新的 Assert 协商,以便下游路由器可以纠正其 RPF’(S) 。
  4. (S,G) 的断言获胜者在即将停止转发 (S,G) 条目时发送取消断言。示例:如果路由器被关闭,则会发送canceling assert。

4.7 PIM 数据包格式

所有 PIM-DM 数据包使用与 PIM-SM 数据包相同的格式。如果出现差异,PIM-SM [4] 应被视为最终规范。所有 PIM 控制消息的 IP 协议号为 103。所有 PIM-DM 消息必须以 TTL 为 1 发送。除Graft和Graft Ack 消息之外的所有 PIM-DM 消息必须发送到 ALL-PIM-ROUTERS 组。Graft消息应该单播到 RPF’(S)。Graft Ack 消息必须单播到 Graft 的发送者。

IPv4 ALL-PIM-ROUTERS 组是 224.0.0.13。 IPv6 ALL-PIM-ROUTERS 组是“ff02::d”。

4.7.1 PIM Header

所有 PIM 控制消息都具有以下标头:
在这里插入图片描述

  • PIM Ver

PIM 版本号为 2。

  • Type

特定 PIM 消息的类型。可用类型如下:

0 = Hello 
1 = Register (PIM-SM only) 
2 = Register Stop (PIM-SM only) 
3 = Join/Prune 
4 = Bootstrap (PIM-SM only) 
5 = Assert 
6 = Graft 
7 = Graft Ack 
8 = Candidate RP Advertisement (PIM-SM only) 
9 = State Refresh
  • Reserved

传输时设置为零。收到后忽略。

  • Checksum

校验和为标准IP校验和;即整个 PIM 消息的补码和的 16 位补码。为了计算校验和,校验和字段被清零。

4.7.2 编码单播地址

编码单播地址具有以下格式:

在这里插入图片描述

  • Addr Family

该地址的“单播地址”字段的 PIM 地址族。值 0 - 127 由 IANA 在 [9] 中为互联网地址族分配。值 128 - 250 保留由 IANA 为 PIM 特定地址族分配。值 251 - 255 指定供私人使用。由于该空间没有分配权限;应该预料到会发生碰撞。

  • Encoding Type

与特定地址族一起使用的编码类型。值“0”为此字段保留,表示地址族的本机编码。

  • Unicast Address

由给定地址族和编码类型表示的单播地址。

4.7.3 编码组地址

编码组地址具有以下格式:

在这里插入图片描述

  • Addr Family
  • Encoding Type
  • B

指示组范围应使用双向 PIM [16]。传输为零;收到后忽略。

  • Reserved

传输为零。收到后忽略。

  • Z

指示组范围是管理范围区域。这仅在Bootstrap Router Mechanism中使用。对于所有其他目的,该位被设置为零并在接收时被忽略。

  • Mask Len

掩码长度字段为8位。该值是用作掩码的连续左对齐一位的数量,它与地址相结合,描述了地址范围。

它小于或等于给定地址族和编码类型的地址长度(以位为单位)。如果针对单个地址发送消息,则掩码长度必须等于地址长度。 PIM-DM 路由器必须仅发送单个地址。

  • Group Multicast Address

多播组的地址。

4.7.4 编码源地址

编码源地址具有以下格式:

在这里插入图片描述

  • Addr Family

  • Encoding Type

  • Rsrvd

保留的。传输为零。收到后忽略。

  • S

Sparse位。对于 PIM-DM 设置为 0。收到后忽略。

  • W

Wild Card位。对于 PIM-DM 设置为 0。收到后忽略。

  • R

Rendezvous Point Tree位。对于 PIM-DM 设置为 0。收到后忽略。

  • Mask Len

如上所述。 PIM-DM 路由器必须仅发送单个源地址。

  • Source Address

源地址。

4.7.5 Hello 消息格式

根据 PIM-SM 的定义,PIM Hello 消息具有以下格式:
在这里插入图片描述

  • PIM Ver

  • Type

  • Reserved

  • Checksum

  • Option Type

选项值字段中给出的选项类型。可用类型如下:

valuetype
0Reserved
1Hello Hold Time
2LAN Prune Delay
3 - 16Reserved
17To be assigned by IANA
18Deprecated and SHOULD NOT be used
19DR Priority (PIM-SM Only)
20Generation ID
21State Refresh Capable
22Bidir Capable
23 - 65000To be assigned by IANA
65001 - 65535Reserved for Private Use

未知的选项应该被忽略。

4.7.5.1 Hello Hold Time Option

在这里插入图片描述

保持时间是接收方必须保持邻居可达的秒数。如果保持时间设置为“0xffff”,则该消息的接收方永远不会使邻居超时。这可以与拨号请求链路一起使用,以避免通过定期的 Hello 消息来保持链路连通。此外,如果 Holdtime 设置为“0”,则信息立即超时。 PIM-DM 路由器必须使用 Hello Hold Time 选项。

4.7.5.2 LAN Prune Delay Option

在这里插入图片描述

LAN_Prune_Delay 选项用于调整多路访问 LAN 上的修剪传播延迟。 T 位由 PIM-SM 使用,并且应由 PIM-DM 路由器设置为 0,并在收到时忽略。 LAN 延迟和覆盖间隔字段是以毫秒为单位的时间间隔,用于调整 J/P 覆盖间隔的值及其派生的计时器值。第 4.3.5 节描述了这些值如何影响路由器的行为。 LAN 修剪延迟应该由 PIM-DM 路由器使用。

4.7.5.3 Generation ID Option

在这里插入图片描述

Generation ID 是发送 Hello 消息的接口的随机值。每当在接口上启动或重新启动 PIM 转发时,都会重新生成 Generation ID。 Generation ID 选项可以由 PIM-DM 路由器使用。

4.7.5.4 State Refresh Capable Option

在这里插入图片描述

Interval 字段是路由器配置的状态刷新间隔(以秒为单位)。保留字段设置为零并在收到时被忽略。支持状态刷新的选项必须由支持状态刷新的 PIM-DM 路由器使用。

4.7.6 加入/剪枝消息格式

PIM Join/Prune 消息,如 PIM-SM 中定义,具有以下格式:

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

  • PIM Ver
  • Type
  • Reserved
  • Checksum
  • Upstream Neighbor Address

上游邻居的地址。该地址的格式在第 4.7.2 节的编码单播地址中给出。 PIM-DM 路由器必须将此字段设置为 RPF 下一跳。

  • Reserved

传输为零。收到后忽略。

  • Hold Time

接收 PIM-DM 路由器必须保持Prune状态活动的秒数,除非被Join 或 Graft 删除。如果保持时间为“0xffff”,则接收方不得删除 Prune 状态,除非收到相应的 Join 或 Graft 消息。 Join 消息中的 Hold Time 被忽略。

  • Number of Groups

消息中包含的组播组集合的数量。

  • Multicast Group Address

4.7.3 节中给出的编码多播地址格式的多播组地址。

  • Number of Joined Sources

为给定组列出的 Join 源地址的数量。

  • Number of Pruned Sources

为给定组列出的 Prune 源地址的数量。

  • Join Source Address 1…n

该列表包含发送路由器希望继续接收该接口上给定组的多播消息的源。地址使用第 4.7.4 节中给出的编码源地址格式。

  • Prune Source Address 1…n

此列表包含发送路由器不希望在此接口上接收给定组的多播消息的源。地址使用第 4.7.4 节中给出的编码源地址格式。

4.7.7 断言消息格式

PIM 断言消息,如 PIM-SM 中定义,具有以下格式:

在这里插入图片描述

  • PIM Ver
  • Type
  • Reserved
  • Checksum
  • Multicast Group Address

4.7.3 节中给出的编码多播地址格式的多播组地址。

  • Source Address

第 4.7.2 节中给出的编码单播地址格式的源地址。

  • R

Rendezvous Point Tree 位。对于 PIM-DM 设置为 0。收到后忽略。

  • Metric Preference

分配给向源提供路由的单播路由协议的优先级值。

  • Metric

到源的单播路由的开销度量。该度量单位适用于所使用的单播路由协议。

4.7.8 Graft 消息格式

PIM Graft 消息使用与 Join/Prune 消息相同的格式,只是 Type 字段设置为 6。源地址必须位于消息的 Join 部分。当接收到 Graft 时,Hold Time 字段应该为零并且应该被忽略。

4.7.9 Graft Ack消息格式

PIM 嫁接确认消息在格式上与接收到的嫁接消息相同,只是类型字段设置为 7。上游邻居地址字段应设置为嫁接消息的发送者,并且在接收时应被忽略。

4.7.10 状态刷新消息格式

PIM 状态刷新消息具有以下格式:

在这里插入图片描述

  • PIM Ver
  • Type
  • Reserved
  • Checksum
  • Multicast Group Address

4.7.3 节中给出的编码多播地址格式的多播组地址。

  • Source Address

数据源的地址采用第 4.7.2 节中给出的编码单播地址格式。

  • Originator Address

第 4.7.2 节中给出的编码单播地址格式中的第一跳路由器的地址。

  • R

Rendezvous Point Tree 位。对于 PIM-DM 设置为 0。收到后忽略。

  • Metric Preference

分配给提供到源的路由的单播路由协议的优先级值

  • Metric

到源的单播路由的开销度量。该度量单位适用于所使用的单播路由协议。

  • Masklen

到源的单播路由的地址掩码长度。

  • TTL

状态刷新消息的生存时间。每次转发消息时递减。请注意,这与 IP 标头 TTL 不同,后者始终设置为 1。

  • P

剪枝指示标志。如果要在 Pruned 接口上发送状态刷新,则必须将其设置为 1。否则,它必须设置为 0。

  • N

立即剪枝标志。状态刷新发起者应在每三个状态刷新消息上将其设置为 1,并且在收到时应将其忽略。这是为了与早期版本的状态刷新兼容。

  • O

断言覆盖标志。如果断言定时器 (AT(S,G)) 未运行,则 LAN 上的上游路由器应将其设置为 1,并且在收到时应将其忽略。这是为了与早期版本的状态刷新兼容。

  • Reserved

设置为零并在收到时忽略。

  • Interval

由 originating 路由器设置为此(S,G)对的连续状态刷新消息之间的间隔(以秒为单位)。

4.8 PIM-DM 定时器

PIM-DM 维护以下定时器。所有计时器都是倒计时器——它们被设置为一个值并倒数到零,此时它们通常会触发一个操作。当然,它们可以像向上计数计时器一样容易地实现,其中存储绝对到期时间并与实时时钟进行比较,但本规范中的语言假设它们向下计数到零。

全局计时器
Hello Timer: HT
Per interface (I):
	Per neighbor (N):
		Neighbor Liveness Timer: NLT(N,I)
		
	Per (S,G) Pair:
		(S,G) Assert Timer: AT(S,G,I)
		(S,G) Prune Timer: PT(S,G,I)
		(S,G) PrunePending Timer: PPT(S,G,I)
		
	Per (S,G) Pair:
		(S,G) Graft Retry Timer: GRT(S,G)
		(S,G) Upstream Override Timer: OT(S,G)
		(S,G) Prune Limit Timer: PLT(S,G)
		(S,G) Source Active Timer: SAT(S,G)
		(S,G) State Refresh Timer: SRT(S,G)

当计时器值启动或重新启动时,它们将设置为默认值。下表总结了这些默认值。

在这里插入图片描述

  • Hello_Period:hello 消息的周期性间隔
  • Triggered_Hello_Delay:启动时初始 Hello 消息的随机间隔或向重新启动的邻居触发的 Hello 消息

Hello 消息每隔 Hello_Period 秒在每个活动接口上发送一次。系统上电时,定时器被初始化为 rand(0,Triggered_Hello_Delay) 以防止同步。当检测到新的或重新启动的邻居时,会在 rand(0,Triggered_Hello_Delay) 内发送响应的 Hello

在这里插入图片描述

  • Hello Holdtime:Hello 消息的保持时间

在这里插入图片描述

  • Prune后的短时间内允许 LAN 上的其他路由器发送加入

J/P_Override_Interval 是接口的 Override_Interval (OI(I)) 和 Propagation_Delay (PD(I)) 之和。如果 LAN 上的所有路由器都使用 LAN Prune Delay 选项,则两个参数都必须设置为 LAN 上的最大值。否则,Override_Interval (OI(I)) 必须设置为 2.5 秒,Propagation_Delay (PD(I)) 必须设置为 0.5 秒。

在这里插入图片描述

  • Prune Holdtime:从 Prune 消息中读取的保持时间

在这里插入图片描述

  • Assert Time:最后一次断言之后、断言状态超时之前的时间段

请注意,由于历史原因,Assert 消息缺少 Holdtime 字段。因此,不建议更改默认值的断言时间。如果 LAN 的所有成员都启用状态刷新,则断言时间将是收到的 RefreshInterval(S,G) 的三倍。

在这里插入图片描述

  • Graft_Retry_Period:在没有收到GraftAck消息的情况下,重传Graft消息之前的时间

在这里插入图片描述

  • t_override:发送 join 消息以覆盖其他人的 prune 时,随机延迟以防止响应内爆

t_override 是 0 和接口的 Override_Interval (OI(I)) 之间的随机值。如果 LAN 上的所有路由器都使用 LAN Prune Delay 选项,则 Override_Interval (OI(I)) 必须设置为 LAN 上的最大值。否则,Override_Interval (OI(I)) 必须设置为 2.5 秒。

在这里插入图片描述

  • t_limit:用于防止 LAN 上的 Prune 风暴

在这里插入图片描述

  • SourceLifetime:直连路由器收到组播消息后持续发送状态刷新消息的时间段

直连源的路由器每收到一次组播消息会重置这个定时器,在210s内会自己发状态刷新消息。

在这里插入图片描述

  • RefreshInterval:连续状态刷新消息之间的间隔

5 协议交互注意事项

PIM-DM 被设计为独立于底层单播路由协议,并且仅在执行 RPF 检查所需的范围内进行交互。通常假设多播区域和自治系统边界将对应于单播路由的相同边界,尽管本规范并不排除不遵循此假设的部署。

5.1 PIM-SM 相互作用

PIM-DM 并不打算与 PIM-SM 直接交互,尽管它们共享通用的数据包格式。特别需要注意的是,路由器无法根据Hello 消息来区分PIM-DM 邻居和PIM-SM 邻居。

如果 PIM-DM 路由器成为 PIM-SM 路由器的邻居,则两者将有效地形成单工链路,PIM-DM 路由器将所有组播消息发送到 PIM-SM 路由器,而 PIM-SM 路由器则将所有组播消息发送到 PIM-SM 路由器。不向 PIM-DM 路由器发送多播消息。

通用数据包格式允许混合 PIM-SM/DM 实现,当已知会合点时将使用 PIM-SM,而当未知会合点时将使用 PIM-DM。这种实现超出了本文档的范围。

5.2 IGMP 交互

在所有情况下,PIM-DM 都会将收到的组播数据包转发到相邻主机组成员,除非 PIM-DM 路由器在该接口上处于断言失败者状态。请注意,不允许使用 PIM 修剪消息来阻止将消息传递到具有组成员的网络。

PIM-DM 路由器可以使用 PIM-SM [14] 中描述的 DR 优先级选项来选择 IGMP v1 查询器。

5.3 源特定组播 (SSM) 交互

PIM-DM 没有对 SSM [15] 做出特殊考虑。协议中的所有 Prunes 和 Grafts 均针对特定来源,因此无需进行额外检查。

5.4 组播组范围边界交互

尽管多播组范围边界通常与路由区域边界相同,但是可以想象,可以针对特定多播组来划分路由区域。 PIM-DM 路由器不得跨特定组的范围边界发送任何有关该组的消息。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值