draft-ietf-pim-sm-v2-new-07.txt   draft-ietf-pim-sm-v2-new-08.txt 
Internet Engineering Task Force PIM WG Internet Engineering Task Force PIM WG
INTERNET-DRAFT Bill Fenner/AT&T INTERNET-DRAFT Bill Fenner/AT&T
draft-ietf-pim-sm-v2-new-07.txt Mark Handley/ICIR draft-ietf-pim-sm-v2-new-08.txt Mark Handley/ICIR
Hugh Holbrook/Cisco Hugh Holbrook/Cisco
Isidor Kouvelas/Cisco Isidor Kouvelas/Cisco
2 March 2003 1 October 2003
Expires: September 2003 Expires: April 2004
Protocol Independent Multicast - Sparse Mode (PIM-SM): Protocol Independent Multicast - Sparse Mode (PIM-SM):
Protocol Specification (Revised) Protocol Specification (Revised)
Status of this Document Status of this Document
This document is an Internet-Draft and is in full conformance with all This document is an Internet-Draft and is in full conformance with all
provisions of Section 10 of RFC2026. provisions of Section 10 of RFC2026.
Internet-Drafts are working documents of the Internet Engineering Task Internet-Drafts are working documents of the Internet Engineering Task
skipping to change at page 3, line 26 skipping to change at page 3, line 26
4.1.3. (*,G) State . . . . . . . . . . . . . . . . . . . 16 4.1.3. (*,G) State . . . . . . . . . . . . . . . . . . . 16
4.1.4. (S,G) State . . . . . . . . . . . . . . . . . . . 17 4.1.4. (S,G) State . . . . . . . . . . . . . . . . . . . 17
4.1.5. (S,G,rpt) State . . . . . . . . . . . . . . . . . 19 4.1.5. (S,G,rpt) State . . . . . . . . . . . . . . . . . 19
4.1.6. State Summarization Macros. . . . . . . . . . . . 20 4.1.6. State Summarization Macros. . . . . . . . . . . . 20
4.2. Data Packet Forwarding Rules . . . . . . . . . . . . 25 4.2. Data Packet Forwarding Rules . . . . . . . . . . . . 25
4.2.1. Last hop switchover to the SPT. . . . . . . . . . 27 4.2.1. Last hop switchover to the SPT. . . . . . . . . . 27
4.2.2. Setting and Clearing the (S,G) SPT bit. . . . . . 27 4.2.2. Setting and Clearing the (S,G) SPT bit. . . . . . 27
4.3. Designated Routers (DR) and Hello Messages . . . . . 29 4.3. Designated Routers (DR) and Hello Messages . . . . . 29
4.3.1. Sending Hello Messages. . . . . . . . . . . . . . 29 4.3.1. Sending Hello Messages. . . . . . . . . . . . . . 29
4.3.2. DR Election . . . . . . . . . . . . . . . . . . . 31 4.3.2. DR Election . . . . . . . . . . . . . . . . . . . 31
4.3.3. Reducing Prune Propagation Delay on LANs. . . . . 32 4.3.3. Reducing Prune Propagation Delay on LANs. . . . . 33
4.4. PIM Register Messages. . . . . . . . . . . . . . . . 35 4.3.4. Maintaining Secondary Address Lists . . . . . . . 35
4.4.1. Sending Register Messages from the DR . . . . . . 35 4.4. PIM Register Messages. . . . . . . . . . . . . . . . 36
4.4.2. Receiving Register Messages at the RP . . . . . . 39 4.4.1. Sending Register Messages from the DR . . . . . . 36
4.5. PIM Join/Prune Messages. . . . . . . . . . . . . . . 41 4.4.2. Receiving Register Messages at the RP . . . . . . 41
4.5.1. Receiving (*,*,RP) Join/Prune Messages. . . . . . 42 4.5. PIM Join/Prune Messages. . . . . . . . . . . . . . . 42
4.5.2. Receiving (*,G) Join/Prune Messages . . . . . . . 45 4.5.1. Receiving (*,*,RP) Join/Prune Messages. . . . . . 43
4.5.3. Receiving (S,G) Join/Prune Messages . . . . . . . 49 4.5.2. Receiving (*,G) Join/Prune Messages . . . . . . . 46
4.5.4. Receiving (S,G,rpt) Join/Prune Messages . . . . . 52 4.5.3. Receiving (S,G) Join/Prune Messages . . . . . . . 50
4.5.5. Sending (*,*,RP) Join/Prune Messages. . . . . . . 58 4.5.4. Receiving (S,G,rpt) Join/Prune Messages . . . . . 53
4.5.6. Sending (*,G) Join/Prune Messages . . . . . . . . 62 4.5.5. Sending (*,*,RP) Join/Prune Messages. . . . . . . 59
4.5.7. Sending (S,G) Join/Prune Messages . . . . . . . . 66 4.5.6. Sending (*,G) Join/Prune Messages . . . . . . . . 63
4.5.8. (S,G,rpt) Periodic Messages . . . . . . . . . . . 71 4.5.7. Sending (S,G) Join/Prune Messages . . . . . . . . 68
4.5.8. (S,G,rpt) Periodic Messages . . . . . . . . . . . 73
4.5.9. State Machine for (S,G,rpt) Triggered Mes- 4.5.9. State Machine for (S,G,rpt) Triggered Mes-
sages. . . . . . . . . . . . . . . . . . . . . . . . . . 72 sages. . . . . . . . . . . . . . . . . . . . . . . . . . 74
4.6. PIM Assert Messages. . . . . . . . . . . . . . . . . 76 4.5.10. Background: (*,*,RP) and (S,G,rpt) inter-
4.6.1. (S,G) Assert Message State Machine. . . . . . . . 76 action . . . . . . . . . . . . . . . . . . . . . . . . . 78
4.6.2. (*,G) Assert Message State Machine. . . . . . . . 84 4.6. PIM Assert Messages. . . . . . . . . . . . . . . . . 80
4.6.3. Assert Metrics. . . . . . . . . . . . . . . . . . 91 4.6.1. (S,G) Assert Message State Machine. . . . . . . . 80
4.6.4. AssertCancel Messages . . . . . . . . . . . . . . 92 4.6.2. (*,G) Assert Message State Machine. . . . . . . . 87
4.6.5. Assert State Macros . . . . . . . . . . . . . . . 93 4.6.3. Assert Metrics. . . . . . . . . . . . . . . . . . 94
4.7. PIM Multicast Border Router Behavior . . . . . . . . 96 4.6.4. AssertCancel Messages . . . . . . . . . . . . . . 95
4.7.1. Sources External to the PIM-SM Domain . . . . . . 96 4.6.5. Assert State Macros . . . . . . . . . . . . . . . 96
4.7.2. Sources Internal to the PIM-SM Domain . . . . . . 97 4.7. PIM Multicast Border Router Behavior . . . . . . . . 99
4.8. PIM Bootstrap and RP Discovery . . . . . . . . . . . 98 4.7.1. Sources External to the PIM-SM Domain . . . . . . 100
4.8.1. Group-to-RP Mapping . . . . . . . . . . . . . . . 99 4.7.2. Sources Internal to the PIM-SM Domain . . . . . . 100
4.8.2. Hash Function . . . . . . . . . . . . . . . . . . 100 4.8. PIM Bootstrap and RP Discovery . . . . . . . . . . . 102
4.9. Source-Specific Multicast. . . . . . . . . . . . . . 101 4.8.1. Group-to-RP Mapping . . . . . . . . . . . . . . . 103
4.8.2. Hash Function . . . . . . . . . . . . . . . . . . 104
4.9. Source-Specific Multicast. . . . . . . . . . . . . . 105
4.9.1. Protocol Modifications for SSM destination 4.9.1. Protocol Modifications for SSM destination
addresses. . . . . . . . . . . . . . . . . . . . . . . . 102 addresses. . . . . . . . . . . . . . . . . . . . . . . . 105
4.9.2. PIM-SSM-only Routers. . . . . . . . . . . . . . . 102 4.9.2. PIM-SSM-only Routers. . . . . . . . . . . . . . . 106
4.10. PIM Packet Formats. . . . . . . . . . . . . . . . . 104 4.10. PIM Packet Formats. . . . . . . . . . . . . . . . . 107
4.10.1. Encoded Source and Group Address 4.10.1. Encoded Source and Group Address
Formats. . . . . . . . . . . . . . . . . . . . . . . . . 105 Formats. . . . . . . . . . . . . . . . . . . . . . . . . 108
4.10.2. Hello Message Format . . . . . . . . . . . . . . 108 4.10.2. Hello Message Format . . . . . . . . . . . . . . 112
4.10.3. Register Message Format. . . . . . . . . . . . . 110 4.10.3. Register Message Format. . . . . . . . . . . . . 115
4.10.4. RegisterStop Message Format. . . . . . . . . . . 112 4.10.4. Register-Stop Message Format . . . . . . . . . . 116
4.10.5. Join/Prune Message Format. . . . . . . . . . . . 112 4.10.5. Join/Prune Message Format. . . . . . . . . . . . 117
4.10.5.1. Group Set Source List Rules . . . . . . . . . 115 4.10.5.1. Group Set Source List Rules . . . . . . . . . 120
4.10.5.2. Group Set Fragmentation . . . . . . . . . . . 119 4.10.5.2. Group Set Fragmentation . . . . . . . . . . . 124
4.10.6. Assert Message Format. . . . . . . . . . . . . . 119 4.10.6. Assert Message Format. . . . . . . . . . . . . . 124
4.11. PIM Timers. . . . . . . . . . . . . . . . . . . . . 121 4.11. PIM Timers. . . . . . . . . . . . . . . . . . . . . 126
4.12. Timer Values. . . . . . . . . . . . . . . . . . . . 122 4.12. Timer Values. . . . . . . . . . . . . . . . . . . . 127
5. IANA Considerations . . . . . . . . . . . . . . . . . . 128 5. IANA Considerations . . . . . . . . . . . . . . . . . . 133
5.1. PIM Address Family . . . . . . . . . . . . . . . . . 128 5.1. PIM Address Family . . . . . . . . . . . . . . . . . 133
5.2. PIM Hello Options. . . . . . . . . . . . . . . . . . 129 5.2. PIM Hello Options. . . . . . . . . . . . . . . . . . 134
6. Security Considerations . . . . . . . . . . . . . . . . 129 6. Security Considerations . . . . . . . . . . . . . . . . 134
6.1. Attacks based on forged messages . . . . . . . . . . 129 6.1. Attacks based on forged messages . . . . . . . . . . 134
6.1.1. Forged link-local messages. . . . . . . . . . . . 129 6.1.1. Forged link-local messages. . . . . . . . . . . . 134
6.1.2. Forged unicast messages . . . . . . . . . . . . . 130 6.1.2. Forged unicast messages . . . . . . . . . . . . . 135
6.2. Non-cryptographic Authentication Mechanisms. . . . . 130 6.2. Non-cryptographic Authentication Mechanisms. . . . . 135
6.3. Authentication using IPsec . . . . . . . . . . . . . 131 6.3. Authentication using IPsec . . . . . . . . . . . . . 136
6.3.1. Protecting link-local multicast messages. . . . . 131 6.3.1. Protecting link-local multicast messages. . . . . 136
6.3.2. Protecting unicast messages . . . . . . . . . . . 132 6.3.2. Protecting unicast messages . . . . . . . . . . . 137
6.3.2.1. Register messages. . . . . . . . . . . . . . . 132 6.3.2.1. Register messages. . . . . . . . . . . . . . . 137
6.3.2.2. Register Stop messages . . . . . . . . . . . . 132 6.3.2.2. Register-Stop messages . . . . . . . . . . . . 137
6.4. Denial of Service Attacks. . . . . . . . . . . . . . 133 6.4. Denial of Service Attacks. . . . . . . . . . . . . . 138
7. Authors' Addresses. . . . . . . . . . . . . . . . . . . 133 7. Authors' Addresses. . . . . . . . . . . . . . . . . . . 138
8. Acknowledgments . . . . . . . . . . . . . . . . . . . . 134 8. Acknowledgments . . . . . . . . . . . . . . . . . . . . 139
9. References. . . . . . . . . . . . . . . . . . . . . . . 134 9. References. . . . . . . . . . . . . . . . . . . . . . . 139
10. Index. . . . . . . . . . . . . . . . . . . . . . . . . 136 10. Index. . . . . . . . . . . . . . . . . . . . . . . . . 141
List of Figures List of Figures
Figure 1. Per-(S,G) register state-machine at a DR . . . . 36 Figure 1. Per-(S,G) register state-machine at a DR . . . . 37
Figure 2. Downstream (*,*,RP) per-interface state- Figure 2. Downstream per-interface (*,*,RP) state-
machine. . . . . . . . . . . . . . . . . . . . . . . . . . 42 machine. . . . . . . . . . . . . . . . . . . . . . . . . . 43
Figure 3. Downstream (*,G) per-interface state- Figure 3. Downstream per-interfacce (*,G) state-
machine. . . . . . . . . . . . . . . . . . . . . . . . . . 46 machine. . . . . . . . . . . . . . . . . . . . . . . . . . 47
Figure 4. Downstream per-interface (S,G) state- Figure 4. Downstream per-interface (S,G) state-
machine. . . . . . . . . . . . . . . . . . . . . . . . . . 50 machine. . . . . . . . . . . . . . . . . . . . . . . . . . 51
Figure 5. Downstream per-interface (S,G,rpt) state- Figure 5. Downstream per-interface (S,G,rpt) state-
machine. . . . . . . . . . . . . . . . . . . . . . . . . . 53 machine. . . . . . . . . . . . . . . . . . . . . . . . . . 54
Figure 6. Upstream (*,*,RP) state-machine. . . . . . . . . 58 Figure 6. Upstream (*,*,RP) state-machine. . . . . . . . . 59
Figure 7. Upstream (*,G) state-machine . . . . . . . . . . 62 Figure 7. Upstream (*,G) state-machine . . . . . . . . . . 64
Figure 8. Upstream (S,G) state-machine . . . . . . . . . . 67 Figure 8. Upstream (S,G) state-machine . . . . . . . . . . 69
Figure 9. Upstream (S,G,rpt) state-machine for trig- Figure 9. Upstream (S,G,rpt) state-machine for trig-
gered messages . . . . . . . . . . . . . . . . . . . . . . 72 gered messages . . . . . . . . . . . . . . . . . . . . . . 74
Figure 10. Per-interface (S,G) Assert Figure 10. Per-interface (S,G) Assert
State-machine. . . . . . . . . . . . . . . . . . . . . . . 78 State-machine. . . . . . . . . . . . . . . . . . . . . . . 81
Figure 11. (*,G) Assert State-machine. . . . . . . . . . . 85 Figure 11. Per-interface (*,G) Assert
State-machine. . . . . . . . . . . . . . . . . . . . . . . 88
1. Introduction 1. Introduction
This document specifies a protocol for efficiently routing multicast This document specifies a protocol for efficiently routing multicast
groups that may span wide-area (and inter-domain) internets. This groups that may span wide-area (and inter-domain) internets. This
protocol is called Protocol Independent Multicast - Sparse Mode (PIM-SM) protocol is called Protocol Independent Multicast - Sparse Mode (PIM-SM)
because, although it may use the underlying unicast routing to provide because, although it may use the underlying unicast routing to provide
reverse-path information for multicast tree building, it is not reverse-path information for multicast tree building, it is not
dependent on any particular unicast routing protocol. dependent on any particular unicast routing protocol.
skipping to change at page 8, line 8 skipping to change at page 8, line 8
A (+) B A (+) B
is the union of two sets A and B. is the union of two sets A and B.
A (-) B A (-) B
is the elements of set A that are not in set B. is the elements of set A that are not in set B.
NULL NULL
is the empty set or list. is the empty set or list.
In addition we use C-like syntax: In addition, we use C-like syntax:
= denotes assignment of a variable. = denotes assignment of a variable.
== denotes a comparison for equality. == denotes a comparison for equality.
!= denotes a comparison for inequality. != denotes a comparison for inequality.
Braces { and } are used for grouping. Braces { and } are used for grouping.
3. PIM-SM Protocol Overview 3. PIM-SM Protocol Overview
skipping to change at page 9, line 36 skipping to change at page 9, line 36
forwards them onto the shared tree. The packets then follow the (*,G) forwards them onto the shared tree. The packets then follow the (*,G)
multicast tree state in the routers on the RP Tree, being replicated multicast tree state in the routers on the RP Tree, being replicated
wherever the RP Tree branches, and eventually reaching all the receivers wherever the RP Tree branches, and eventually reaching all the receivers
for that multicast group. The process of encapsulating data packets to for that multicast group. The process of encapsulating data packets to
the RP is called registering, and the encapsulation packets are known as the RP is called registering, and the encapsulation packets are known as
PIM Register packets. PIM Register packets.
At the end of phase one, multicast traffic is flowing encapsulated to At the end of phase one, multicast traffic is flowing encapsulated to
the RP, and then natively over the RP tree to the multicast receivers. the RP, and then natively over the RP tree to the multicast receivers.
Phase Two: Register Stop Phase Two: Register-Stop
Register-encapsulation of data packets is inefficient for two reasons: Register-encapsulation of data packets is inefficient for two reasons:
o Encapsulation and decapsulation may be relatively expensive operations o Encapsulation and decapsulation may be relatively expensive operations
for a router to perform, depending on whether or not the router has for a router to perform, depending on whether or not the router has
appropriate hardware for these tasks. appropriate hardware for these tasks.
o Traveling all the way to the RP, and then back down the shared tree o Traveling all the way to the RP, and then back down the shared tree
may entail the packets traveling a relatively long distance to reach may entail the packets traveling a relatively long distance to reach
receivers that are close to the sender. For some applications, this receivers that are close to the sender. For some applications, this
skipping to change at page 10, line 21 skipping to change at page 10, line 21
state, and then packets from S start to flow following the (S,G) tree state, and then packets from S start to flow following the (S,G) tree
state towards the RP. These data packets may also reach routers with state towards the RP. These data packets may also reach routers with
(*,G) state along the path towards the RP - if so, they can short-cut (*,G) state along the path towards the RP - if so, they can short-cut
onto the RP tree at this point. onto the RP tree at this point.
While the RP is in the process of joining the source-specific tree for While the RP is in the process of joining the source-specific tree for
S, the data packets will continue being encapsulated to the RP. When S, the data packets will continue being encapsulated to the RP. When
packets from S also start to arrive natively at the the RP, the RP will packets from S also start to arrive natively at the the RP, the RP will
be receiving two copies of each of these packets. At this point, the RP be receiving two copies of each of these packets. At this point, the RP
starts to discard the encapsulated copy of these packets, and it sends a starts to discard the encapsulated copy of these packets, and it sends a
RegisterStop message back to S's DR to prevent the DR unnecessarily Register-Stop message back to S's DR to prevent the DR unnecessarily
encapsulating the packets. encapsulating the packets.
At the end of phase 2, traffic will be flowing natively from S along a At the end of phase 2, traffic will be flowing natively from S along a
source-specific tree to the RP, and from there along the shared tree to source-specific tree to the RP, and from there along the shared tree to
the receivers. Where the two trees intersect, traffic may transfer from the receivers. Where the two trees intersect, traffic may transfer from
the source-specific tree to the RP tree, and so avoid taking a long the source-specific tree to the RP tree, and so avoid taking a long
detour via the RP. detour via the RP.
It should be noted that a sender may start sending before or after a It should be noted that a sender may start sending before or after a
receiver joins the group, and thus phase two may happen before the receiver joins the group, and thus phase two may happen before the
skipping to change at page 15, line 9 skipping to change at page 15, line 9
o Suppression state: One of {"Enable", "Disable"} o Suppression state: One of {"Enable", "Disable"}
Neighbor State: Neighbor State:
For each neighbor: For each neighbor:
o Information from neighbor's Hello o Information from neighbor's Hello
o Neighbor's Gen ID. o Neighbor's Gen ID.
o Neighbor liveness timer (NLT) o Neighbor Liveness Timer (NLT)
Designated Router (DR) State: Designated Router (DR) State:
o Designated Router's IP Address o Designated Router's IP Address
o DR's DR Priority o DR's DR Priority
The Override Interval, the Propagation Delay and the Interface The Override Interval, the Propagation Delay and the Interface
suppression state are described in section 4.3.3. Designated Router suppression state are described in Section 4.3.3. Designated Router
state is described in section 4.3. state is described in Section 4.3.
4.1.2. (*,*,RP) State 4.1.2. (*,*,RP) State
For every RP a router keeps the following state: For every RP a router keeps the following state:
(*,*,RP) state: (*,*,RP) state:
For each interface: For each interface:
PIM (*,*,RP) Join/Prune State: PIM (*,*,RP) Join/Prune State:
o State: One of {"NoInfo" (NI), "Join" (J), o State: One of {"NoInfo" (NI), "Join" (J), "Prune-
"PrunePending" (PP)} Pending" (PP)}
o Prune Pending Timer (PPT) o Prune-Pending Timer (PPT)
o Join/Prune Expiry Timer (ET) o Join/Prune Expiry Timer (ET)
Not interface specific: Not interface specific:
o Upstream Join/Prune Timer (JT) o Upstream Join/Prune Timer (JT)
o Last RPF Neighbor towards RP that was used o Last RPF Neighbor towards RP that was used
PIM (*,*,RP) Join/Prune state is the result of receiving PIM (*,*,RP) PIM (*,*,RP) Join/Prune state is the result of receiving PIM (*,*,RP)
Join/Prune messages on this interface, and is specified in section Join/Prune messages on this interface, and is specified in Section
4.5.1. 4.5.1.
The upstream (*,*,RP) Join/Prune timer is used to send out periodic The upstream (*,*,RP) Join/Prune Timer is used to send out periodic
Join(*,*,RP) messages, and to override Prune(*,*,RP) messages from peers Join(*,*,RP) messages, and to override Prune(*,*,RP) messages from peers
on an upstream LAN interface. on an upstream LAN interface.
The last RPF neighbor towards the RP is stored because if the MRIB The last RPF neighbor towards the RP is stored because if the MRIB
changes then the RPF neighbor towards the RP may change. If it does so, changes then the RPF neighbor towards the RP may change. If it does so,
then we need to trigger a new Join(*,*,RP) to the new upstream neighbor then we need to trigger a new Join(*,*,RP) to the new upstream neighbor
and a Prune(*,*,RP) to the old upstream neighbor. Similarly, if a and a Prune(*,*,RP) to the old upstream neighbor. Similarly, if a
router detects through a changed GenID in a Hello message that the router detects through a changed GenID in a Hello message that the
upstream neighbor towards the RP has rebooted, then it should re- upstream neighbor towards the RP has rebooted, then it should re-
skipping to change at page 16, line 24 skipping to change at page 16, line 24
For every group G a router keeps the following state: For every group G a router keeps the following state:
(*,G) state: (*,G) state:
For each interface: For each interface:
Local Membership: Local Membership:
State: One of {"NoInfo", "Include"} State: One of {"NoInfo", "Include"}
PIM (*,G) Join/Prune State: PIM (*,G) Join/Prune State:
o State: One of {"NoInfo" (NI), "Join" (J), o State: One of {"NoInfo" (NI), "Join" (J), "Prune-
"PrunePending" (PP)} Pending" (PP)}
o Prune Pending Timer (PPT) o Prune-Pending Timer (PPT)
o Join/Prune Expiry Timer (ET) o Join/Prune Expiry Timer (ET)
(*,G) Assert Winner State (*,G) Assert Winner State
o State: One of {"NoInfo" (NI), "I lost Assert" (L), o State: One of {"NoInfo" (NI), "I lost Assert" (L),
"I won Assert" (W)} "I won Assert" (W)}
o Assert Timer (AT) o Assert Timer (AT)
skipping to change at page 17, line 10 skipping to change at page 17, line 10
Local membership is the result of the local membership mechanism (such Local membership is the result of the local membership mechanism (such
as IGMP or MLD) running on that interface. It need not be kept if this as IGMP or MLD) running on that interface. It need not be kept if this
router is not the DR on that interface unless this router won a (*,G) router is not the DR on that interface unless this router won a (*,G)
assert on this interface for this group, although implementations may assert on this interface for this group, although implementations may
optionally keep this state in case they become the DR or assert winner. optionally keep this state in case they become the DR or assert winner.
We recommend storing this information if possible, as it reduces latency We recommend storing this information if possible, as it reduces latency
converging to stable operating conditions after a failure causing a converging to stable operating conditions after a failure causing a
change of DR. This information is used by the pim_include(*,G) macro change of DR. This information is used by the pim_include(*,G) macro
described in section 4.1.6. described in Section 4.1.6.
PIM (*,G) Join/Prune state is the result of receiving PIM (*,G) PIM (*,G) Join/Prune state is the result of receiving PIM (*,G)
Join/Prune messages on this interface, and is specified in section Join/Prune messages on this interface, and is specified in Section
4.5.2. The state is used by the macros that calculate the outgoing 4.5.2. The state is used by the macros that calculate the outgoing
interface list in section 4.1.6, and in the JoinDesired(*,G) macro interface list in Section 4.1.6, and in the JoinDesired(*,G) macro
(defined in section 4.5.6) that is used in deciding whether a Join(*,G) (defined in Section 4.5.6) that is used in deciding whether a Join(*,G)
should be sent upstream. should be sent upstream.
(*,G) Assert Winner state is the result of sending or receiving (*,G) (*,G) Assert Winner state is the result of sending or receiving (*,G)
Assert messages on this interface. It is specified in section 4.6.2. Assert messages on this interface. It is specified in Section 4.6.2.
The upstream (*,G) Join/Prune timer is used to send out periodic The upstream (*,G) Join/Prune Timer is used to send out periodic
Join(*,G) messages, and to override Prune(*,G) messages from peers on an Join(*,G) messages, and to override Prune(*,G) messages from peers on an
upstream LAN interface. upstream LAN interface.
The last RP used must be stored because if the RP Set changes (section The last RP used must be stored because if the RP Set changes (Section
4.8) then state must be torn down and rebuilt for groups whose RP 4.8) then state must be torn down and rebuilt for groups whose RP
changes. changes.
The last RPF neighbor towards the RP is stored because if the MRIB The last RPF neighbor towards the RP is stored because if the MRIB
changes then the RPF neighbor towards the RP may change. If it does so, changes then the RPF neighbor towards the RP may change. If it does so,
then we need to trigger a new Join(*,G) to the new upstream neighbor and then we need to trigger a new Join(*,G) to the new upstream neighbor and
a Prune(*,G) to the old upstream neighbor. Similarly, if a router a Prune(*,G) to the old upstream neighbor. Similarly, if a router
detects through a changed GenID in a Hello message that the upstream detects through a changed GenID in a Hello message that the upstream
neighbor towards the RP has rebooted, then it should re-instantiate neighbor towards the RP has rebooted, then it should re-instantiate
state by sending a Join(*,G). These mechanisms are specified in Section state by sending a Join(*,G). These mechanisms are specified in Section
skipping to change at page 18, line 5 skipping to change at page 18, line 5
(S,G) state: (S,G) state:
For each interface: For each interface:
Local Membership: Local Membership:
State: One of {"NoInfo", "Include"} State: One of {"NoInfo", "Include"}
PIM (S,G) Join/Prune State: PIM (S,G) Join/Prune State:
o State: One of {"NoInfo" (NI), "Join" (J), o State: One of {"NoInfo" (NI), "Join" (J), "Prune-
"PrunePending" (PP)} Pending" (PP)}
o Prune Pending Timer (PPT) o Prune-Pending Timer (PPT)
o Join/Prune Expiry Timer (ET) o Join/Prune Expiry Timer (ET)
(S,G) Assert Winner State (S,G) Assert Winner State
o State: One of {"NoInfo" (NI), "I lost Assert" (L), o State: One of {"NoInfo" (NI), "I lost Assert" (L),
"I won Assert" (W)} "I won Assert" (W)}
o Assert Timer (AT) o Assert Timer (AT)
skipping to change at page 18, line 31 skipping to change at page 18, line 31
o Assert winner's Assert Metric o Assert winner's Assert Metric
Not interface specific: Not interface specific:
o Upstream (S,G) Join/Prune Timer (JT) o Upstream (S,G) Join/Prune Timer (JT)
o Last RPF Neighbor towards S that was used o Last RPF Neighbor towards S that was used
o SPT bit (indicates (S,G) state is active) o SPT bit (indicates (S,G) state is active)
o (S,G) KeepAlive Timer (KAT) o (S,G) Keepalive Timer (KAT)
Local membership is the result of the local source-specific membership Local membership is the result of the local source-specific membership
mechanism (such as IGMP version 3) running on that interface and mechanism (such as IGMP version 3) running on that interface and
specifying that this particular source should be included. As stored specifying that this particular source should be included. As stored
here, this state is the resulting state after any IGMPv3 inconsistencies here, this state is the resulting state after any IGMPv3 inconsistencies
have been resolved. It need not be kept if this router is not the DR on have been resolved. It need not be kept if this router is not the DR on
that interface unless this router won a (S,G) assert on this interface that interface unless this router won a (S,G) assert on this interface
for this group. However, we recommend storing this information if for this group. However, we recommend storing this information if
possible, as it reduces latency converging to stable operating possible, as it reduces latency converging to stable operating
conditions after a failure causing a change of DR. This information is conditions after a failure causing a change of DR. This information is
used by the pim_include(S,G) macro described in section 4.1.6. used by the pim_include(S,G) macro described in Section 4.1.6.
PIM (S,G) Join/Prune state is the result of receiving PIM (S,G) PIM (S,G) Join/Prune state is the result of receiving PIM (S,G)
Join/Prune messages on this interface, and is specified in section Join/Prune messages on this interface, and is specified in Section
4.5.2. The state is used by the macros that calculate the outgoing 4.5.2. The state is used by the macros that calculate the outgoing
interface list in section 4.1.6, and in the JoinDesired(S,G) macro interface list in Section 4.1.6, and in the JoinDesired(S,G) macro
(defined in section 4.5.7) that is used in deciding whether a Join(S,G) (defined in Section 4.5.7) that is used in deciding whether a Join(S,G)
should be sent upstream. should be sent upstream.
(S,G) Assert Winner state is the result of sending or receiving (S,G) (S,G) Assert Winner state is the result of sending or receiving (S,G)
Assert messages on this interface. It is specified in section 4.6.1. Assert messages on this interface. It is specified in Section 4.6.1.
The upstream (S,G) Join/Prune timer is used to send out periodic The upstream (S,G) Join/Prune Timer is used to send out periodic
Join(S,G) messages, and to override Prune(S,G) messages from peers on an Join(S,G) messages, and to override Prune(S,G) messages from peers on an
upstream LAN interface. upstream LAN interface.
The last RPF neighbor towards S is stored because if the MRIB changes The last RPF neighbor towards S is stored because if the MRIB changes
then the RPF neighbor towards S may change. If it does so, then we need then the RPF neighbor towards S may change. If it does so, then we need
to trigger a new Join(S,G) to the new upstream neighbor and a Prune(S,G) to trigger a new Join(S,G) to the new upstream neighbor and a Prune(S,G)
to the old upstream neighbor. Similarly, if the router detects through to the old upstream neighbor. Similarly, if the router detects through
a changed GenID in a Hello message that the upstream neighbor towards S a changed GenID in a Hello message that the upstream neighbor towards S
has rebooted, then it should re-instantiate state by sending a has rebooted, then it should re-instantiate state by sending a
Join(S,G). These mechanisms are specified in Section 4.5.7. Join(S,G). These mechanisms are specified in Section 4.5.7.
skipping to change at page 19, line 45 skipping to change at page 19, line 45
(S,G,rpt) state: (S,G,rpt) state:
For each interface: For each interface:
Local Membership: Local Membership:
State: One of {"NoInfo", "Exclude"} State: One of {"NoInfo", "Exclude"}
PIM (S,G,rpt) Join/Prune State: PIM (S,G,rpt) Join/Prune State:
o State: One of {"NoInfo", "Pruned", "PrunePending"} o State: One of {"NoInfo", "Pruned", "Prune-
Pending"}
o Prune Pending Timer (PPT) o Prune-Pending Timer (PPT)
o Join/Prune Expiry Timer (ET) o Join/Prune Expiry Timer (ET)
Not interface specific: Not interface specific:
Upstream (S,G,rpt) Join/Prune State: Upstream (S,G,rpt) Join/Prune State:
o State: One of {"NotJoined(*,G)", o State: One of {"NotJoined(*,G)",
"NotPruned(S,G,rpt)", "Pruned(S,G,rpt)"} "NotPruned(S,G,rpt)", "Pruned(S,G,rpt)"}
o Override Timer (OT) o Override Timer (OT)
Local membership is the result of the local source-specific membership Local membership is the result of the local source-specific membership
skipping to change at page 20, line 22 skipping to change at page 20, line 23
Local membership is the result of the local source-specific membership Local membership is the result of the local source-specific membership
mechanism (such as IGMPv3) running on that interface and specifying that mechanism (such as IGMPv3) running on that interface and specifying that
although there is (*,G) Include state, this particular source should be although there is (*,G) Include state, this particular source should be
excluded. As stored here, this state is the resulting state after any excluded. As stored here, this state is the resulting state after any
IGMPv3 inconsistencies between LAN members have been resolved. It need IGMPv3 inconsistencies between LAN members have been resolved. It need
not be kept if this router is not the DR on that interface unless this not be kept if this router is not the DR on that interface unless this
router won a (*,G) assert on this interface for this group. However, we router won a (*,G) assert on this interface for this group. However, we
recommend storing this information if possible, as it reduces latency recommend storing this information if possible, as it reduces latency
converging to stable operating conditions after a failure causing a converging to stable operating conditions after a failure causing a
change of DR. This information is used by the pim_exclude(S,G) macro change of DR. This information is used by the pim_exclude(S,G) macro
described in section 4.1.6. described in Section 4.1.6.
PIM (S,G,rpt) Join/Prune state is the result of receiving PIM (S,G,rpt) PIM (S,G,rpt) Join/Prune state is the result of receiving PIM (S,G,rpt)
Join/Prune messages on this interface, and is specified in section Join/Prune messages on this interface, and is specified in Section
4.5.4. The state is used by the macros that calculate the outgoing 4.5.4. The state is used by the macros that calculate the outgoing
interface list in section 4.1.6, and in the rules for adding interface list in Section 4.1.6, and in the rules for adding
Prune(S,G,rpt) messages to Join(*,G) messages specified in section Prune(S,G,rpt) messages to Join(*,G) messages specified in Section
4.5.8. 4.5.8.
The upstream (S,G,rpt) Join/Prune state is used along with the Override The upstream (S,G,rpt) Join/Prune state is used along with the Override
Timer to send the correct override messages in response to Join/Prune Timer to send the correct override messages in response to Join/Prune
messages sent by upstream peers on a LAN. This state and behavior are messages sent by upstream peers on a LAN. This state and behavior are
specified in section 4.5.9. specified in Section 4.5.9.
4.1.6. State Summarization Macros 4.1.6. State Summarization Macros
Using this state, we define the following "macro" definitions which we Using this state, we define the following "macro" definitions which we
will use in the descriptions of the state machines and pseudocode in the will use in the descriptions of the state machines and pseudocode in the
following sections. following sections.
The most important macros are those that define the outgoing interface The most important macros are those that define the outgoing interface
list (or "olist") for the relevant state. An olist can be "immediate" list (or "olist") for the relevant state. An olist can be "immediate"
if it is built directly from the state of the relevant type. For if it is built directly from the state of the relevant type. For
skipping to change at page 22, line 16 skipping to change at page 22, line 16
OR AssertWinner(S,G,I) == me ) OR AssertWinner(S,G,I) == me )
AND local_receiver_exclude(S,G,I) } AND local_receiver_exclude(S,G,I) }
The clause "local_receiver_include(S,G,I)" is true if the IGMP/MLD The clause "local_receiver_include(S,G,I)" is true if the IGMP/MLD
module or other local membership mechanism has determined that there are module or other local membership mechanism has determined that there are
local members on interface I that desire to receive traffic sent local members on interface I that desire to receive traffic sent
specifically by S to G. "local_receiver_include(*,G,I)" is true if the specifically by S to G. "local_receiver_include(*,G,I)" is true if the
IGMP/MLD module or other local membership mechanism has determined that IGMP/MLD module or other local membership mechanism has determined that
there are local members on interface I that desire to receive all there are local members on interface I that desire to receive all
traffic sent to G. "local_receiver_exclude(S,G,I) is true if traffic sent to G. "local_receiver_exclude(S,G,I) is true if
local_receiver_include(*,G,I) is true but none of the local members "local_receiver_include(*,G,I)" is true but none of the local members
desire to receive traffic from S. desire to receive traffic from S.
The set "joins(*,*,RP)" is the set of all interfaces on which the router The set "joins(*,*,RP)" is the set of all interfaces on which the router
has received (*,*,RP) Joins: has received (*,*,RP) Joins:
joins(*,*,RP) = joins(*,*,RP) =
{ all interfaces I such that { all interfaces I such that
DownstreamJPState(*,*,RP,I) is either Join or DownstreamJPState(*,*,RP,I) is either Join or
PrunePending } Prune-Pending }
DownstreamJPState(*,*,RP,I) is the state of the finite state machine in DownstreamJPState(*,*,RP,I) is the state of the finite state machine in
section 4.5.1. Section 4.5.1.
The set "joins(*,G)" is the set of all interfaces on which the router The set "joins(*,G)" is the set of all interfaces on which the router
has received (*,G) Joins: has received (*,G) Joins:
joins(*,G) = joins(*,G) =
{ all interfaces I such that { all interfaces I such that
DownstreamJPState(*,G,I) is either Join or PrunePending } DownstreamJPState(*,G,I) is either Join or Prune-Pending }
DownstreamJPState(*,G,I) is the state of the finite state machine in DownstreamJPState(*,G,I) is the state of the finite state machine in
section 4.5.2. Section 4.5.2.
The set "joins(S,G)" is the set of all interfaces on which the router The set "joins(S,G)" is the set of all interfaces on which the router
has received (S,G) Joins: has received (S,G) Joins:
joins(S,G) = joins(S,G) =
{ all interfaces I such that { all interfaces I such that
DownstreamJPState(S,G,I) is either Join or PrunePending } DownstreamJPState(S,G,I) is either Join or Prune-Pending }
DownstreamJPState(S,G,I) is the state of the finite state machine in DownstreamJPState(S,G,I) is the state of the finite state machine in
section 4.5.3. Section 4.5.3.
The set "prunes(S,G,rpt)" is the set of all interfaces on which the The set "prunes(S,G,rpt)" is the set of all interfaces on which the
router has received (*,G) joins and (S,G,rpt) prunes. router has received (*,G) joins and (S,G,rpt) prunes.
prunes(S,G,rpt) = prunes(S,G,rpt) =
{ all interfaces I such that { all interfaces I such that
DownstreamJPState(S,G,rpt,I) is Prune or PruneTmp } DownstreamJPState(S,G,rpt,I) is Prune or PruneTmp }
DownstreamJPState(S,G,rpt,I) is the state of the finite state machine in DownstreamJPState(S,G,rpt,I) is the state of the finite state machine in
section 4.5.4. Section 4.5.4.
The set "lost_assert(*,G)" is the set of all interfaces on which the The set "lost_assert(*,G)" is the set of all interfaces on which the
router has received (*,G) joins but has lost a (*,G) assert. The macro router has received (*,G) joins but has lost a (*,G) assert. The macro
lost_assert(*,G,I) is defined in Section 4.6.5. lost_assert(*,G,I) is defined in Section 4.6.5.
lost_assert(*,G) = lost_assert(*,G) =
{ all interfaces I such that { all interfaces I such that
lost_assert(*,G,I) == TRUE } lost_assert(*,G,I) == TRUE }
The set "lost_assert(S,G,rpt)" is the set of all interfaces on which the The set "lost_assert(S,G,rpt)" is the set of all interfaces on which the
skipping to change at page 24, line 9 skipping to change at page 24, line 9
The following pseudocode macro definitions are also used in many places The following pseudocode macro definitions are also used in many places
in the specification. Basically RPF' is the RPF neighbor towards an RP in the specification. Basically RPF' is the RPF neighbor towards an RP
or source unless a PIM-Assert has overridden the normal choice of or source unless a PIM-Assert has overridden the normal choice of
neighbor. neighbor.
neighbor RPF'(*,G) { neighbor RPF'(*,G) {
if ( I_Am_Assert_Loser(*,G,RPF_interface(RP(G))) ) { if ( I_Am_Assert_Loser(*,G,RPF_interface(RP(G))) ) {
return AssertWinner(*, G, RPF_interface(RP(G)) ) return AssertWinner(*, G, RPF_interface(RP(G)) )
} else { } else {
return MRIB.next_hop( RP(G) ) return NBR( RPF_interface(RP(G)), MRIB.next_hop( RP(G) ) )
} }
} }
neighbor RPF'(S,G,rpt) { neighbor RPF'(S,G,rpt) {
if( I_Am_Assert_Loser(S, G, RPF_interface(RP(G)) ) ) { if( I_Am_Assert_Loser(S, G, RPF_interface(RP(G)) ) ) {
return AssertWinner(S, G, RPF_interface(RP(G)) ) return AssertWinner(S, G, RPF_interface(RP(G)) )
} else { } else {
return RPF'(*,G) return RPF'(*,G)
} }
} }
neighbor RPF'(S,G) { neighbor RPF'(S,G) {
if ( I_Am_Assert_Loser(S, G, RPF_interface(S) )) { if ( I_Am_Assert_Loser(S, G, RPF_interface(S) )) {
return AssertWinner(S, G, RPF_interface(S) ) return AssertWinner(S, G, RPF_interface(S) )
} else { } else {
return MRIB.next_hop( S ) return NBR( RPF_interface(S), MRIB.next_hop( S ) ) )
} }
} }
RPF'(*,G) and RPF'(S,G) indicate the neighbor from which data packets RPF'(*,G) and RPF'(S,G) indicate the neighbor from which data packets
should be coming and to which joins should be sent on the RP tree and should be coming and to which joins should be sent on the RP tree and
SPT respectively. SPT respectively.
RPF'(S,G,rpt) is basically RPF'(*,G) modified by the result of an RPF'(S,G,rpt) is basically RPF'(*,G) modified by the result of an
Assert(S,G) on RPF_interface(RP(G)). In such a case, packets from S Assert(S,G) on RPF_interface(RP(G)). In such a case, packets from S
will be originating from a different router than RPF'(*,G). If we only will be originating from a different router than RPF'(*,G). If we only
have active (*,G) Join state, we need to accept packets from have active (*,G) Join state, we need to accept packets from
RPF'(S,G,rpt), and add a Prune(S,G,rpt) to the periodic Join(*,G) RPF'(S,G,rpt), and add a Prune(S,G,rpt) to the periodic Join(*,G)
messages that we send to RPF'(*,G) (See Section 4.5.8). messages that we send to RPF'(*,G) (See Section 4.5.8).
The function MRIB.next_hop( S ) returns the next-hop PIM neighbor toward The function MRIB.next_hop( S ) returns an address of the next-hop PIM
the host S, as indicated by the current MRIB. If S is directly neighbor toward the host S, as indicated by the current MRIB. If S is
adjacent, then MRIB.next_hop( S ) returns NULL. At the RP for G, directly adjacent, then MRIB.next_hop( S ) returns NULL. At the RP for
MRIB.next_hop( RP(G )) returns NULL. G, MRIB.next_hop( RP(G )) returns NULL.
The function NBR( I, A ) uses information gathered through PIM Hello
messages to map the IP address A of a directly connected PIM neighbor
router on interface I to the primary IP address of the same router
(section 4.3.4). The primary IP address of a neighbor is the link-local
address that it uses as the source of its PIM Hello messages. Note that
a neighbor's IP address may not be unique within the PIM neighbor
database due to scope issues. The address must however be unique amongst
the addresses of all the PIM neighbors on a specific interface.
I_Am_Assert_Loser(S, G, I) is true if the Assert start machine (in I_Am_Assert_Loser(S, G, I) is true if the Assert start machine (in
section 4.6.1) for (S,G) on Interface I is in "I am Assert Loser" state. Section 4.6.1) for (S,G) on Interface I is in "I am Assert Loser" state.
I_Am_Assert_Loser(*, G, I) is true if the Assert start machine (in I_Am_Assert_Loser(*, G, I) is true if the Assert start machine (in
section 4.6.2) for (*,G) on Interface I is in "I am Assert Loser" state. Section 4.6.2) for (*,G) on Interface I is in "I am Assert Loser" state.
4.2. Data Packet Forwarding Rules 4.2. Data Packet Forwarding Rules
The PIM-SM packet forwarding rules are defined below in pseudocode. The PIM-SM packet forwarding rules are defined below in pseudocode.
iif is the incoming interface of the packet. iif is the incoming interface of the packet.
S is the source address of the packet. S is the source address of the packet.
G is the destination address of the packet (group address). G is the destination address of the packet (group address).
RP is the address of the Rendezvous Point for this group. RP is the address of the Rendezvous Point for this group.
RPF_interface(S) is the interface the MRIB indicates would be used RPF_interface(S) is the interface the MRIB indicates would be used
to route packets to S. to route packets to S.
RPF_interface(RP) is the interface the MRIB indicates would be used RPF_interface(RP) is the interface the MRIB indicates would be used
to route packets to RP, except at the RP when it is the to route packets to RP, except at the RP when it is the
decapsulation interface (the "virtual" interface on which register decapsulation interface (the "virtual" interface on which register
packets are received). packets are received).
First, we restart (or start) the Keepalive timer if the source is on a First, we restart (or start) the Keepalive Timer if the source is on a
directly connected subnet. directly connected subnet.
Second, we check to see if the SPT bit should be set because we've now Second, we check to see if the SPT bit should be set because we've now
switched from the RP tree to the SPT. switched from the RP tree to the SPT.
Next we check to see whether the packet should be accepted based on TIB Next we check to see whether the packet should be accepted based on TIB
state and the interface that the packet arrived on. state and the interface that the packet arrived on.
If the packet should be forwarded using (S,G) state, we then build an If the packet should be forwarded using (S,G) state, we then build an
outgoing interface list for the packet. If this list is not empty, then outgoing interface list for the packet. If this list is not empty, then
we restart the (S,G) state keepalive timer. we restart the (S,G) state Keepalive Timer.
If the packet should be forwarded using (*,*,RP) or (*,G) state, then we If the packet should be forwarded using (*,*,RP) or (*,G) state, then we
just build an outgoing interface list for the packet. We also check if just build an outgoing interface list for the packet. We also check if
we should initiate a switch to start receiving this source on a shortest we should initiate a switch to start receiving this source on a shortest
path tree. path tree.
Finally we remove the incoming interface from the outgoing interface Finally we remove the incoming interface from the outgoing interface
list we've created, and if the resulting outgoing interface list is not list we've created, and if the resulting outgoing interface list is not
empty, we forward the packet out of those interfaces. empty, we forward the packet out of those interfaces.
On receipt on a data from S to G on interface iif: On receipt of data from S to G on interface iif:
if( DirectlyConnected(S) == TRUE ) { if( DirectlyConnected(S) == TRUE ) {
set KeepaliveTimer(S,G) to Keepalive_Period set KeepaliveTimer(S,G) to Keepalive_Period
# Note: register state transition may happen as a result # Note: a register state transition may happen as a result
# of restarting KeepaliveTimer, and must be dealt with here. # of restarting KeepaliveTimer, and must be dealt with here.
} }
Update_SPTbit(S,G,iif) Update_SPTbit(S,G,iif)
oiflist = NULL oiflist = NULL
if( iif == RPF_interface(S) AND UpstreamJPState(S,G) == Joined ) { if( iif == RPF_interface(S) AND UpstreamJPState(S,G) == Joined ) {
oiflist = inherited_olist(S,G) oiflist = inherited_olist(S,G)
if( oiflist != NULL ) { if( oiflist != NULL ) {
restart KeepaliveTimer(S,G) restart KeepaliveTimer(S,G)
} }
} else if( iif == RPF_interface(RP) AND SPTbit(S,G) == FALSE) { } else if( iif == RPF_interface(RP(G)) AND SPTbit(S,G) == FALSE) {
oiflist = inherited_olist(S,G,rpt) oiflist = inherited_olist(S,G,rpt)
CheckSwitchToSpt(S,G) CheckSwitchToSpt(S,G)
} else { } else {
# Note: RPF check failed # Note: RPF check failed
if ( SPTbit(S,G) == TRUE AND iif is in inherited_olist(S,G) ) { if ( SPTbit(S,G) == TRUE AND iif is in inherited_olist(S,G) ) {
send Assert(S,G) on iif send Assert(S,G) on iif
} else if ( SPTbit(S,G) == FALSE AND } else if ( SPTbit(S,G) == FALSE AND
iif is in inherited_olist(S,G,rpt) { iif is in inherited_olist(S,G,rpt) {
send Assert(*,G) on iif send Assert(*,G) on iif
} }
skipping to change at page 27, line 5 skipping to change at page 27, line 5
4.1. 4.1.
Basically inherited_olist(S,G) is the outgoing interface list for Basically inherited_olist(S,G) is the outgoing interface list for
packets forwarded on (S,G) state taking into account (*,*,RP) state, packets forwarded on (S,G) state taking into account (*,*,RP) state,
(*,G) state, asserts, etc. (*,G) state, asserts, etc.
inherited_olist(S,G,rpt) is the outgoing interface for packets forwarded inherited_olist(S,G,rpt) is the outgoing interface for packets forwarded
on (*,*,RP) or (*,G) state taking into account (S,G,rpt) prune state, on (*,*,RP) or (*,G) state taking into account (S,G,rpt) prune state,
and asserts, etc. and asserts, etc.
Update_SPTbit(S,G,iif) is defined in section 4.2.2. Update_SPTbit(S,G,iif) is defined in Section 4.2.2.
CheckSwitchToSpt(S,G) is defined in section 4.2.1. CheckSwitchToSpt(S,G) is defined in Section 4.2.1.
UpstreamJPState(S,G) is the state of the finite state machine in section UpstreamJPState(S,G) is the state of the finite state machine in Section
4.5.7. 4.5.7.
Keepalive_Period is defined in Section 4.11. Keepalive_Period is defined in Section 4.11.
Data triggered PIM-Assert messages sent from the above forwarding code Data triggered PIM-Assert messages sent from the above forwarding code
should be rate-limited in a implementation-dependent manner. should be rate-limited in a implementation-dependent manner.
4.2.1. Last hop switchover to the SPT 4.2.1. Last hop switchover to the SPT
In Sparse-Mode PIM, last-hop routers join the shared tree towards the In Sparse-Mode PIM, last-hop routers join the shared tree towards the
skipping to change at page 27, line 31 skipping to change at page 27, line 31
router it has the option of switching to receive the traffic on a router it has the option of switching to receive the traffic on a
shortest path tree (SPT). shortest path tree (SPT).
The decision for a router to switch to the SPT is controlled as follows: The decision for a router to switch to the SPT is controlled as follows:
void void
CheckSwitchToSpt(S,G) { CheckSwitchToSpt(S,G) {
if ( ( pim_include(*,G) (-) pim_exclude(S,G) if ( ( pim_include(*,G) (-) pim_exclude(S,G)
(+) pim_include(S,G) != NULL ) (+) pim_include(S,G) != NULL )
AND SwitchToSptDesired(S,G) ) { AND SwitchToSptDesired(S,G) ) {
restart KeepAliveTimer(S,G); restart KeepaliveTimer(S,G);
} }
} }
SwitchToSptDesired(S,G) is a policy function that is implementation SwitchToSptDesired(S,G) is a policy function that is implementation
defined. An "infinite threshold" policy can be implemented making defined. An "infinite threshold" policy can be implemented making
SwitchToSptDesired(S,G) return false all the time. A "switch on first SwitchToSptDesired(S,G) return false all the time. A "switch on first
packet" policy can be implemented by making SwitchToSptDesired(S,G) packet" policy can be implemented by making SwitchToSptDesired(S,G)
return true once a single packet has been received for the source and return true once a single packet has been received for the source and
group. group.
skipping to change at page 28, line 16 skipping to change at page 28, line 16
be caused by sending a Prune(S,G,rpt) before the upstream (S,G) state be caused by sending a Prune(S,G,rpt) before the upstream (S,G) state
has finished being established. has finished being established.
Thus, when a packet arrives, the (S,G) SPTbit is updated as follows: Thus, when a packet arrives, the (S,G) SPTbit is updated as follows:
void void
Update_SPTbit(S,G,iif) { Update_SPTbit(S,G,iif) {
if ( iif == RPF_interface(S) if ( iif == RPF_interface(S)
AND JoinDesired(S,G) == TRUE AND JoinDesired(S,G) == TRUE
AND ( DirectlyConnected(S) == TRUE AND ( DirectlyConnected(S) == TRUE
OR RPF_interface(S) != RPF_interface(RP) OR RPF_interface(S) != RPF_interface(RP(G))
OR inherited_olist(S,G,rpt) == NULL OR inherited_olist(S,G,rpt) == NULL
OR RPF'(S,G) == RPF'(*,G) ) ) { OR RPF'(S,G) == RPF'(*,G) ) ) {
Set SPTbit(S,G) to TRUE Set SPTbit(S,G) to TRUE
} }
} }
Additionally a router sets SPTbit(S,G) to TRUE when it receives an Additionally a router sets SPTbit(S,G) to TRUE when it receives an
Assert(S,G) on RPF_interface(S). Assert(S,G) on RPF_interface(S) (see Section 4.6.1).
JoinDesired(S,G) is defined in Section 4.5.7, and indicates whether we JoinDesired(S,G) is defined in Section 4.5.7, and indicates whether we
have the appropriate (S,G) Join state to wish to send a Join(S,G) have the appropriate (S,G) Join state to wish to send a Join(S,G)
upstream. upstream.
Basically Update_SPTbit will set the SPT bit if we have the appropriate Basically Update_SPTbit will set the SPT bit if we have the appropriate
(S,G) join state and the packet arrived on the correct upstream (S,G) join state and the packet arrived on the correct upstream
interface for S, and one or more of the following conditions applies: interface for S, and one or more of the following conditions applies:
1. The source is directly connected, in which case the switch to the 1. The source is directly connected, in which case the switch to the
skipping to change at page 29, line 28 skipping to change at page 29, line 28
DR election is performed using Hello messages. Hello messages are also DR election is performed using Hello messages. Hello messages are also
the way that option negotiation takes place in PIM, so that additional the way that option negotiation takes place in PIM, so that additional
functionality can be enabled, or parameters tuned. functionality can be enabled, or parameters tuned.
4.3.1. Sending Hello Messages 4.3.1. Sending Hello Messages
PIM-Hello messages are sent periodically on each PIM-enabled interface. PIM-Hello messages are sent periodically on each PIM-enabled interface.
They allow a router to learn about the neighboring PIM routers on each They allow a router to learn about the neighboring PIM routers on each
interface. Hello messages are also the mechanism used to elect a interface. Hello messages are also the mechanism used to elect a
Designated Router (DR), and to negotiate additional capabilities A Designated Router (DR), and to negotiate additional capabilities. A
router must record the Hello information received from each PIM router must record the Hello information received from each PIM
neighbor. neighbor.
Hello messages MUST be sent on all active interfaces, including physical Hello messages MUST be sent on all active interfaces, including physical
point-to-point links, and are multicast to address 224.0.0.13 (the ALL- point-to-point links, and are multicast to the `ALL-PIM-ROUTERS' group
PIM-ROUTERS group). address (`224.0.0.13' for IPv4 and `ff02::d' for IPv6).
We note that some implementations do not send Hello messages We note that some implementations do not send Hello messages
on point-to-point interfaces. This is non-compliant behavior. on point-to-point interfaces. This is non-compliant behavior.
A compliant PIM router MUST send Hello messages, even on A compliant PIM router MUST send Hello messages, even on
point-to-point interfaces. point-to-point interfaces.
A per interface hello timer (HT(I)) is used to trigger sending Hello A per interface Hello Timer (HT(I)) is used to trigger sending Hello
messages on each active interface. When PIM is enabled on an interface messages on each active interface. When PIM is enabled on an interface
or a router first starts, the hello timer of that interface is set to a or a router first starts, the Hello Timer of that interface is set to a
random value between 0 and Triggered_Hello_Delay. This prevents random value between 0 and Triggered_Hello_Delay. This prevents
synchronization of Hello messages if multiple routers are powered on synchronization of Hello messages if multiple routers are powered on
simultaneously. After the initial randomized interval, Hello messages simultaneously. After the initial randomized interval, Hello messages
must be sent every Hello_Period seconds. The hello timer should not be must be sent every Hello_Period seconds. The Hello Timer should not be
reset except when it expires. reset except when it expires.
Note that neighbors will not accept Join/Prune or Assert messages from a Note that neighbors will not accept Join/Prune or Assert messages from a
router unless they have first heard a Hello message from that router. router unless they have first heard a Hello message from that router.
Thus if a router needs to send a Join/Prune or Assert message on an Thus if a router needs to send a Join/Prune or Assert message on an
interface on which it has not yet sent a Hello message, then it MUST interface on which it has not yet sent a Hello message, then it MUST
immediately send the relevant Hello message without waiting for the immediately send the relevant Hello message without waiting for the
Hello timer to expire, followed by the Join/Prune or Assert message. Hello Timer to expire, followed by the Join/Prune or Assert message.
The DR_Election_Priority Option allows a network administrator to give The DR_Election_Priority Option allows a network administrator to give
preference to a particular router in the DR election process by giving preference to a particular router in the DR election process by giving
it a numerically larger DR Election Priority. The DR_Election_Priority it a numerically larger DR Election Priority. The DR_Election_Priority
Option SHOULD be included in every Hello message, even if no DR election Option SHOULD be included in every Hello message, even if no DR election
priority is explicitly configured on that interface. This is necessary priority is explicitly configured on that interface. This is necessary
because priority-based DR election is only enabled when all neighbors on because priority-based DR election is only enabled when all neighbors on
an interface advertise that they are capable of using the DR Election an interface advertise that they are capable of using the DR Election
Priority Option. The default priority is 1. Priority Option. The default priority is 1.
skipping to change at page 30, line 33 skipping to change at page 30, line 33
that is regenerated each time PIM forwarding is started or restarted on that is regenerated each time PIM forwarding is started or restarted on
the interface, including when the router itself restarts. When a Hello the interface, including when the router itself restarts. When a Hello
message with a new GenID is received from a neighbor, any old Hello message with a new GenID is received from a neighbor, any old Hello
information about that neighbor SHOULD be discarded and superseded by information about that neighbor SHOULD be discarded and superseded by
the information from the new Hello message. This may cause a new DR to the information from the new Hello message. This may cause a new DR to
be chosen on that interface. be chosen on that interface.
The LAN_Prune_Delay Option SHOULD be included in all Hello messages sent The LAN_Prune_Delay Option SHOULD be included in all Hello messages sent
on multi-access LANs. This option advertises a router's capability to on multi-access LANs. This option advertises a router's capability to
use values other than the default for the Propagation_Delay and use values other than the default for the Propagation_Delay and
Override_Interval which affect the setting of the Prune Pending, Override_Interval which affect the setting of the Prune-Pending,
Upstream Join and Override Timers (defined in section 4.11). Upstream Join and Override Timers (defined in Section 4.11).
The Interface_Address_List Option SHOULD be included in all IPv4 Hello
messages and MUST be included in all IPv6 Hello messages. This option
advertises all the secondary addresses associated with the source
interface of the router originating the message.
To allow new or rebooting routers to learn of PIM neighbors quickly, To allow new or rebooting routers to learn of PIM neighbors quickly,
when a Hello message is received from a new neighbor, or a Hello message when a Hello message is received from a new neighbor, or a Hello message
with a new GenID is received from an existing neighbor, a new Hello with a new GenID is received from an existing neighbor, a new Hello
message should be sent on this interface after a randomized delay message should be sent on this interface after a randomized delay
between 0 and Triggered_Hello_Delay. This triggered message need not between 0 and Triggered_Hello_Delay. This triggered message need not
change the timing of the scheduled periodic message. If a router needs change the timing of the scheduled periodic message. If a router needs
to send a Join/Prune to the new neighbor or send an Assert message in to send a Join/Prune to the new neighbor or send an Assert message in
response to an Assert message from the new neighbor before this response to an Assert message from the new neighbor before this
randomized delay has expired, then it MUST immediately send the relevant randomized delay has expired, then it MUST immediately send the relevant
without Hello message without waiting for the Hello timer to expire, Hello message without waiting for the Hello Timer to expire, followed by
followed by the Join/Prune or Assert message. If it does not do this, the Join/Prune or Assert message. If it does not do this, then the new
then the new neighbor will discard the Join/Prune or Assert message. neighbor will discard the Join/Prune or Assert message.
Before an interface goes down or changes IP address, a Hello message Before an interface goes down or changes IP address, a Hello message
with a zero HoldTime should be sent immediately (with the old IP address with a zero HoldTime should be sent immediately (with the old IP address
if the IP address changed). This will cause PIM neighbors to remove if the IP address changed). This will cause PIM neighbors to remove
this neighbor (or its old IP address) immediately. this neighbor (or its old IP address) immediately. After an interface
has changed its IP address, it MUST send a Hello message with its new IP
address.
4.3.2. DR Election 4.3.2. DR Election
When a PIM-Hello message is received on interface I the following When a PIM-Hello message is received on interface I the following
information about the sending neighbor is recorded: information about the sending neighbor is recorded:
neighbor.interface neighbor.interface
The interface on which the Hello message arrived. The interface on which the Hello message arrived.
neighbor.ip_address neighbor.primary_ip_address
The IP address of the PIM neighbor. The IP address that the PIM neighbor used as the source
address of the Hello message.
neighbor.genid neighbor.genid
The Generation ID of the PIM neighbor. The Generation ID of the PIM neighbor.
neighbor.dr_priority neighbor.dr_priority
The DR Priority field of the PIM neighbor if it is present in The DR Priority field of the PIM neighbor if it is present in
the Hello message. the Hello message.
neighbor.dr_priority_present neighbor.dr_priority_present
A flag indicating if the DR Priority field was present in the A flag indicating if the DR Priority field was present in the
skipping to change at page 32, line 11 skipping to change at page 32, line 22
} }
return dr return dr
} }
The function used for comparing DR "metrics" on interface I is: The function used for comparing DR "metrics" on interface I is:
bool bool
dr_is_better(a,b,I) { dr_is_better(a,b,I) {
if( there is a neighbor n on I for which n.dr_priority_present if( there is a neighbor n on I for which n.dr_priority_present
is false ) { is false ) {
return a.ip_address > b.ip_address return a.primary_ip_address > b.primary_ip_address
} else { } else {
return ( a.dr_priority > b.dr_priority ) OR return ( a.dr_priority > b.dr_priority ) OR
( a.dr_priority == b.dr_priority AND ( a.dr_priority == b.dr_priority AND
a.ip_address > b.ip_address ) a.primary_ip_address > b.primary_ip_address )
} }
} }
The trivial function I_am_DR(I) is defined to aid readability: The trivial function I_am_DR(I) is defined to aid readability:
bool bool
I_am_DR(I) { I_am_DR(I) {
return DR(I) == me return DR(I) == me
} }
skipping to change at page 35, line 25 skipping to change at page 35, line 42
} }
for each neighbor on interface I { for each neighbor on interface I {
if ( neighbor.tracking_support == false ) { if ( neighbor.tracking_support == false ) {
return true return true
} }
} }
return false return false
} }
Note that the setting of Suppression_Enabled(I) affects the value of Note that the setting of Suppression_Enabled(I) affects the value of
t_suppressed (see section 4.11). t_suppressed (see Section 4.11).
4.3.4. Maintaining Secondary Address Lists
Communication of a routers interface secondary addresses to its PIM
neighbors is necessary to provide the neighbors with a mechanism for
mapping next_hop information obtained through their MRIB to a primary
address that can be used as a destination for Join/Prune messages. The
mapping is performed through the NBR macro. The primary address of a
PIM neighbor is obtained from the source IP address used in its PIM
Hello messages. Secondary addresses are carried within the Hello message
in an Address List Hello option. The primary address of the source
interface of the router MUST NOT be listed within the Address List Hello
option.
In addition to the information recorded for the DR Election, the
following per neighbor information is obtained from the Address List
Hello option:
neighbor.secondary_address_list
The list of secondary addresses used by the PIM neighbor on
the interface through which the Hello message was transmitted.
When processing a received PIM Hello message containing an Address List
Hello option, the list of secondary addresses in the message completely
replaces any previously associated secondary addresses for that
neighbor. If a received PIM Hello message does not contain an Address
List Hello option then all secondary addresses associated with the
neighbor must be deleted.
All the advertised secondary addresses in received Hello messages must
be checked against those previously advertised by all other PIM
neighbors on that interface. If there is a conflict and the same
secondary address was previously advertised by another neighbor then
only the most recently received mapping MUST be maintained and an error
message SHOULD be logged to the administrator in a rate limited manner.
4.4. PIM Register Messages 4.4. PIM Register Messages
Overview Overview
The Designated Router (DR) on a LAN or point-to-point link encapsulates The Designated Router (DR) on a LAN or point-to-point link encapsulates
multicast packets from local sources to the RP for the relevant group multicast packets from local sources to the RP for the relevant group
unless it recently received a Register Stop message for that (S,G) or unless it recently received a Register-Stop message for that (S,G) or
(*,G) from the RP. When the DR receives a Register Stop message from (*,G) from the RP. When the DR receives a Register-Stop message from
the RP, it starts a Register Stop timer to maintain this state. Just the RP, it starts a Register-Stop Timer to maintain this state. Just
before the Register Stop timer expires, the DR sends a Null-Register before the Register-Stop Timer expires, the DR sends a Null-Register
Message to the RP to allow the RP to refresh the Register Stop Message to the RP to allow the RP to refresh the Register-Stop
information at the DR. If the Register Stop timer actually expires, the information at the DR. If the Register-Stop Timer actually expires, the
DR will resume encapsulating packets from the source to the RP. DR will resume encapsulating packets from the source to the RP.
4.4.1. Sending Register Messages from the DR 4.4.1. Sending Register Messages from the DR
Every PIM-SM router has the capability to be a DR. The state machine Every PIM-SM router has the capability to be a DR. The state machine
below is used to implement Register functionality. For the purposes of below is used to implement Register functionality. For the purposes of
specification, we represent the mechanism to encapsulate packets to the specification, we represent the mechanism to encapsulate packets to the
RP as a Register-Tunnel interface, which is added to or removed from the RP as a Register-Tunnel interface, which is added to or removed from the
(S,G) olist. The tunnel interface then takes part in the normal packet (S,G) olist. The tunnel interface then takes part in the normal packet
forwarding rules is specified in Section 4.2. forwarding rules as specified in Section 4.2.
If register state is maintained, it is maintained only for directly If register state is maintained, it is maintained only for directly
connected sources, and is per-(S,G). There are four states in the DR's connected sources, and is per-(S,G). There are four states in the DR's
per-(S,G) Register state-machine: per-(S,G) Register state-machine:
Join (J) Join (J)
The register tunnel is "joined" (the join is actually implicit, but The register tunnel is "joined" (the join is actually implicit, but
the DR acts as if the RP has joined the DR on the tunnel the DR acts as if the RP has joined the DR on the tunnel
interface). interface).
Prune (P) Prune (P)
The register tunnel is "pruned" (this occurs when a Register Stop The register tunnel is "pruned" (this occurs when a Register-Stop
is received). is received).
Join Pending (JP) Join-Pending (JP)
The register tunnel is pruned but the DR is contemplating adding it The register tunnel is pruned but the DR is contemplating adding it
back. back.
No Info (NI) No Info (NI)
No information. This is the initial state, and the state when the No information. This is the initial state, and the state when the
router is not the DR. router is not the DR.
In addition, a RegisterStop timer (RST) is kept if the state machine in In addition, a Register-Stop Timer (RST) is kept if the state machine is
not in the No Info state. not in the No Info state.
Figure 1: Per-(S,G) register state-machine at a DR in tabular form Figure 1: Per-(S,G) register state-machine at a DR in tabular form
+-----------++------------------------------------------------------------------------------------------+ +-----------++---------------------------------------------------------------+
| || Event | | || Event |
| ++------------------+------------------+----------------------+--------------+--------------+ | ++-----------+------------+------------+------------+------------+
|Prev State ||Register-Stop |Could-Register | Could-Register |Register- |RP changed | |Prev State ||Register- | Could- | Could- | Register- | RP changed |
| ||Timer expires |->True | ->False |Stop | | | ||Stop Timer | Register | Register | Stop | |
| || | | |received | | | ||expires | ->True | ->False | received | |
+-----------++------------------+------------------+----------------------+--------------+--------------+ +-----------++-----------+------------+------------+------------+------------+
|No Info ||- |-> J state | - |- |- | |No Info ||- |-> J state | - |- |- |
|(NI) || |add reg tunnel | | | | |(NI) || | add reg | | | |
+-----------++------------------+------------------+----------------------+--------------+--------------+ | || | tunnel | | | |
| ||- |- | -> NI state |-> P state |-> J state | +-----------++-----------+------------+------------+------------+------------+
| || | | remove reg tunnel |remove |update reg | | ||- | - | -> NI | -> P state | -> J state |
| || | | |tunnel; |tunnel | | || | | state | | |
|Join (J) || | | |set | | | || | | remove reg | remove reg | update reg |
|Join (J) || | | tunnel | tunnel; | tunnel |
| || | | | set | |
| || | | |Register- | | | || | | |Register- | |
| || | | |Stop | | | || | | |Stop | |
| || | | |timer(*) | | | || | | | Timer(*) | |
+-----------++------------------+------------------+----------------------+--------------+--------------+ +-----------++-----------+------------+------------+------------+------------+
| ||-> J state |- | -> NI state |-> P state |-> J state | | ||-> J state | - | -> NI | -> P state | -> J state |
|Join ||add reg tunnel | | remove reg tunnel |set |add reg | | || | | state | | |
|Pending || | | |Register- |tunnel; | |Join- ||add reg | | remove reg | set | add reg |
|Pending ||tunnel | | tunnel | Register- | tunnel; |
|(JP) || | | |Stop |cancel | |(JP) || | | |Stop |cancel |
| || | | |timer(*) |Register- | | || | | | Timer(*) | Register- |
| || | | | |Stop timer | | || | | | | Stop Timer |
+-----------++------------------+------------------+----------------------+--------------+--------------+ +-----------++-----------+------------+------------+------------+------------+
| ||-> JP state |- | -> NI state |- |-> J state | | ||-> JP | - | -> NI | - | -> J state |
| ||set Register- | | remove reg tunnel | |add reg | | ||state | | state | | |
|Prune (P) ||Stop | | | |tunnel; | | ||set | | remove reg | | add reg |
| ||timer(**); | | | |cancel | |Prune (P) ||Register- | | tunnel | | tunnel; |
| ||send null | | | |Register- | | ||Stop | | | | cancel |
| ||register | | | |Stop timer | | ||Timer(**); | | | | Register- |
+-----------++------------------+------------------+----------------------+--------------+--------------+ | ||send Null- | | | | Stop Timer |
| ||Register | | | | |
+-----------++-----------+------------+------------+------------+------------+
Notes: Notes:
(*) The RegisterStopTimer is set to a random value chosen uniformly from (*) The Register-Stop Timer is set to a random value chosen uniformly
the interval ( 0.5 * Register_Suppression_Time, 1.5 * from the interval ( 0.5 * Register_Suppression_Time, 1.5 *
Register_Suppression_Time) minus Register_Probe_Time; Register_Suppression_Time) minus Register_Probe_Time;
Subtracting off Register_Probe_Time is a bit unnecessary because it Subtracting off Register_Probe_Time is a bit unnecessary because it
is really small compared to Register_Suppression_Time, but was in is really small compared to Register_Suppression_Time, but was in
the old spec and is kept for compatibility. the old spec and is kept for compatibility.
(**) The RegisterStopTimer is set to Register_Probe_Time. (**) The Register-Stop Timer is set to Register_Probe_Time.
The following actions are defined: The following actions are defined:
Add Register Tunnel Add Register Tunnel
A Register-Tunnel virtual interface, VI, is created (if it doesn't A Register-Tunnel virtual interface, VI, is created (if it doesn't
already exist) with its encapsulation target being RP(G). already exist) with its encapsulation target being RP(G).
DownstreamJPState(S,G,VI) is set to Join state, causing the tunnel DownstreamJPState(S,G,VI) is set to Join state, causing the tunnel
interface to be added to immediate_olist(S,G). interface to be added to immediate_olist(S,G).
skipping to change at page 39, line 14 skipping to change at page 40, line 19
Encapsulating data packets in the Register Tunnel Encapsulating data packets in the Register Tunnel
Conceptually, the Register Tunnel is an interface with a smaller MTU Conceptually, the Register Tunnel is an interface with a smaller MTU
than the underlying IP interface towards the RP. IP fragmentation on than the underlying IP interface towards the RP. IP fragmentation on
packets forwarded on the Register Tunnel is performed based upon this packets forwarded on the Register Tunnel is performed based upon this
smaller MTU. The encapsulating DR may perform Path-MTU Discovery to the smaller MTU. The encapsulating DR may perform Path-MTU Discovery to the
RP to determine the effective MTU of the tunnel. This smaller MTU takes RP to determine the effective MTU of the tunnel. This smaller MTU takes
both the outer IP header and the PIM register header overhead into both the outer IP header and the PIM register header overhead into
account. If a multicast packet is fragmented on the way into the account. If a multicast packet is fragmented on the way into the
Register Tunnel, each fragment is encapsulated individually so contains Register Tunnel, each fragment is encapsulated individually so it
IP, PIM, and inner IP headers. contains IP, PIM, and inner IP headers.
In IPv6, an ICMP Fragmentation Required message may be sent by the In IPv6, an ICMP Fragmentation Required message may be sent by the
encapsulating DR. encapsulating DR.
Just like any forwarded packet, the TTL of the original data packet is Just like any forwarded packet, the TTL of the original data packet is
decremented before it is encapsulated in the Register Tunnel. decremented before it is encapsulated in the Register Tunnel.
The IP ECN bits should be copied from the original packet to the IP The IP ECN bits should be copied from the original packet to the IP
header of the encapsulating packet. They SHOULD NOT be set header of the encapsulating packet. They SHOULD NOT be set
independently by the encapsulating router. independently by the encapsulating router.
The Diffserv Code Point (DSCP) should be copied from the original packet The Diffserv Code Point (DSCP) should be copied from the original packet
to the IP header of the encapsulating packet. It MAY be set to the IP header of the encapsulating packet. It MAY be set
independently by the encapsulating router, based upon static independently by the encapsulating router, based upon static
configuration or traffic classification. See [2] for more discussion on configuration or traffic classification. See [2] for more discussion on
setting the DSCP on tunnels. setting the DSCP on tunnels.
Handling RegisterStop(*,G) Messages at the DR Handling Register-Stop(*,G) Messages at the DR
An old RP might send a RegisterStop message with the source address set An old RP might send a Register-Stop message with the source address set
to all-zeros. This was the normal course of action in RFC 2326 when the to all-zeros. This was the normal course of action in RFC 2326 when the
Register message matched against (*,G) state at the RP, and was defined Register message matched against (*,G) state at the RP, and was defined
as meaning "stop encapsulating all sources for this group". However, as meaning "stop encapsulating all sources for this group". However,
the behavior of such a RegisterStop(*,G) is ambiguous or incorrect in the behavior of such a Register-Stop(*,G) is ambiguous or incorrect in
some circumstances. some circumstances.
We specify that an RP should not send RegisterStop(*,G) messages, but We specify that an RP should not send Register-Stop(*,G) messages, but
for compatibility, a DR should be able to accept one if it is received. for compatibility, a DR should be able to accept one if it is received.
A RegisterStop(*,G) should be treated as a RegisterStop(S,G) for all A Register-Stop(*,G) should be treated as a Register-Stop(S,G) for all
existing (S,G) Register state machines. A router should not apply a existing (S,G) Register state machines. A router should not apply a
RegisterStop(*,G) to sources that become active after the
RegisterStop(*,G) was received. Register-Stop(*,G) to sources that become active after the Register-
Stop(*,G) was received.
4.4.2. Receiving Register Messages at the RP 4.4.2. Receiving Register Messages at the RP
When an RP receives a Register message, the course of action is decided When an RP receives a Register message, the course of action is decided
according to the following pseudocode: according to the following pseudocode:
packet_arrives_on_rp_tunnel( pkt ) { packet_arrives_on_rp_tunnel( pkt ) {
if( outer.dst is not one of my addresses ) { if( outer.dst is not one of my addresses ) {
drop the packet silently. drop the packet silently.
# note that this should not happen if the lower layer is working # note that this should not happen if the lower layer is working
} }
if( I_am_RP( G ) && outer.dst == RP(G) ) { if( I_am_RP( G ) && outer.dst == RP(G) ) {
if ( SPTbit(S,G) || SwitchToSptDesired(S,G) ) {
restart KeepaliveTimer(S,G) restart KeepaliveTimer(S,G)
if(( inherited_olist(S,G) == NULL ) OR SPTbit(S,G)) { }
send RegisterStop(S,G) to outer.src if ( SPTbit(S,G) ||
} else { ( SwitchToSptDesired(S,G) && ( inherited_olist(S,G) != NULL ))) {
if( ! pkt.NullRegisterBit ) { send Register-Stop(S,G) to outer.src
}
if( !SPTbit(S,G) && ! pkt.NullRegisterBit ) {
decapsulate and pass the inner packet to the normal decapsulate and pass the inner packet to the normal
forwarding path for forwarding on the (*,G) tree. forwarding path for forwarding on the (*,G) tree.
} }
}
} else { } else {
send RegisterStop(S,G) to outer.src send Register-Stop(S,G) to outer.src
# Note (*) # Note (*)
} }
} }
outer.dst is the IP destination address of the encapsulating header. outer.dst is the IP destination address of the encapsulating header.
outer.src is the IP source address of the encapsulating header, i.e., outer.src is the IP source address of the encapsulating header, i.e.,
the DR's address. the DR's address.
I_am_RP(G) is true if the group-to-RP mapping indicates that this router I_am_RP(G) is true if the group-to-RP mapping indicates that this router
skipping to change at page 40, line 49 skipping to change at page 42, line 8
Note (*): This may block traffic from S for Register_Suppression_Time if Note (*): This may block traffic from S for Register_Suppression_Time if
the DR learned about a new group-to-RP mapping before the RP did. the DR learned about a new group-to-RP mapping before the RP did.
However, this doesn't matter unless we figure out some way for the However, this doesn't matter unless we figure out some way for the
RP to also accept (*,G) joins when it doesn't yet realize that it RP to also accept (*,G) joins when it doesn't yet realize that it
is about to become the RP for G. This will all get sorted out once is about to become the RP for G. This will all get sorted out once
the RP learns the new group-to-rp mapping. We decided to do the RP learns the new group-to-rp mapping. We decided to do
nothing about this and just accept the fact that PIM may suffer nothing about this and just accept the fact that PIM may suffer
interrupted (*,G) connectivity following an RP change. interrupted (*,G) connectivity following an RP change.
KeepaliveTimer(S,G) is restarted at the RP when packets arrive on the KeepaliveTimer(S,G) is restarted at the RP when packets arrive on the
proper tunnel interface. This may cause the upstream (S,G) state proper tunnel interface and the RP desires to switch to the SPT or the
machine to trigger a join if the inherited_olist(S,G) is not NULL; SPTbit is already set. This may cause the upstream (S,G) state machine
to trigger a join if the inherited_olist(S,G) is not NULL;
An RP should preserve (S,G) state that was created in response to a An RP should preserve (S,G) state that was created in response to a
Register message for at least ( 3 * Register_Suppression_Time ), Register message for at least ( 3 * Register_Suppression_Time ),
otherwise the RP may stop joining (S,G) before the DR for S has otherwise the RP may stop joining (S,G) before the DR for S has
restarted sending registers. Traffic would then be interrupted until restarted sending registers. Traffic would then be interrupted until
the RegisterStop timer expires at the DR. the Register-Stop Timer expires at the DR.
Thus, at the RP, KeepaliveTimer(S,G) should be restarted to ( 3 * Thus, at the RP, KeepaliveTimer(S,G) should be restarted to ( 3 *
Register_Suppression_Time + Register_Probe_Time ). Register_Suppression_Time + Register_Probe_Time ).
Just like any forwarded packet, the TTL of the original data packet is Just like any forwarded packet, the TTL of the original data packet is
decremented after it is decapsulated from the Register Tunnel. decremented after it is decapsulated from the Register Tunnel.
The IP ECN bits should be copied from the IP header of the Register The IP ECN bits should be copied from the IP header of the Register
packet to the decapsulated packet. packet to the decapsulated packet.
skipping to change at page 41, line 45 skipping to change at page 43, line 4
(*,*,RP), (S,G) and (S,G,rpt) Joins and Prunes can only affect their (*,*,RP), (S,G) and (S,G,rpt) Joins and Prunes can only affect their
respective downstream state machines. When considering a Join/Prune respective downstream state machines. When considering a Join/Prune
message whose PIM Destination field addresses another router, most Join message whose PIM Destination field addresses another router, most Join
or Prune messages could affect each upstream state machine. or Prune messages could affect each upstream state machine.
In general, a PIM Join/Prune message should only be accepted for In general, a PIM Join/Prune message should only be accepted for
processing if it comes from a known PIM neighbor. A PIM router hears processing if it comes from a known PIM neighbor. A PIM router hears
about PIM neighbors through PIM Hello messages. If a router receives a about PIM neighbors through PIM Hello messages. If a router receives a
Join/Prune message from a particular IP source address and it has not Join/Prune message from a particular IP source address and it has not
seen a PIM Hello message from that source address, then the Join/Prune seen a PIM Hello message from that source address, then the Join/Prune
message SHOULD be discarded without further processing. In addition, if message SHOULD be discarded without further processing. In addition, if
the Hello message from a neighbor was authenticated using IPsec AH (see the Hello message from a neighbor was authenticated using IPsec AH (see
section 6.3) then all Join/Prune messages from that neighbor MUST also Section 6.3) then all Join/Prune messages from that neighbor MUST also
be authenticated using IPsec AH. be authenticated using IPsec AH.
We note that some older PIM implementations incorrectly fail to send We note that some older PIM implementations incorrectly fail to send
Hello messages on point-to-point interfaces, so we also RECOMMEND that a Hello messages on point-to-point interfaces, so we also RECOMMEND that a
configuration option be provided to allow interoperation with such older configuration option be provided to allow interoperation with such older
routers, but that this configuration option SHOULD NOT be enabled by routers, but that this configuration option SHOULD NOT be enabled by
default. default.
4.5.1. Receiving (*,*,RP) Join/Prune Messages 4.5.1. Receiving (*,*,RP) Join/Prune Messages
The per-interface state-machine for receiving (*,*,RP) Join/Prune The per-interface state-machine for receiving (*,*,RP) Join/Prune
Messages is given below. There are three states: Messages is given below. There are three states:
NoInfo (NI) NoInfo (NI)
The interface has no (*,*,RP) Join state and no timers The interface has no (*,*,RP) Join state and no timers
skipping to change at page 42, line 24 skipping to change at page 43, line 32
The interface has no (*,*,RP) Join state and no timers The interface has no (*,*,RP) Join state and no timers
running. running.
Join (J) Join (J)
The interface has (*,*,RP) Join state which will cause us to The interface has (*,*,RP) Join state which will cause us to
forward packets destined for any group handled by RP from this forward packets destined for any group handled by RP from this
interface except if there is also (S,G,rpt) prune information interface except if there is also (S,G,rpt) prune information
(see Section 4.5.4) or the router lost an assert on this (see Section 4.5.4) or the router lost an assert on this
interface. interface.
PrunePending (PP) Prune-Pending (PP)
The router has received a Prune(*,*,RP) on this interface from The router has received a Prune(*,*,RP) on this interface from
a downstream neighbor and is waiting to see whether the prune a downstream neighbor and is waiting to see whether the prune
will be overridden by another downstream router. For will be overridden by another downstream router. For
forwarding purposes, the PrunePending state functions exactly forwarding purposes, the Prune-Pending state functions exactly
like the Join state. like the Join state.
In addition the state-machine uses two timers: In addition, the state-machine uses two timers:
ExpiryTimer (ET) ExpiryTimer (ET)
This timer is restarted when a valid Join(*,*,RP) is received. This timer is restarted when a valid Join(*,*,RP) is received.
Expiry of the ExpiryTimer causes the interface state to revert Expiry of the ExpiryTimer causes the interface state to revert
to NoInfo for this RP. to NoInfo for this RP.
PrunePendingTimer (PPT) Prune-Pending Timer (PPT)
This timer is set when a valid Prune(*,*,RP) is received. This timer is set when a valid Prune(*,*,RP) is received.
Expiry of the PrunePendingTimer causes the interface state to Expiry of the Prune-Pending Timer causes the interface state
revert to NoInfo for this RP. to revert to NoInfo for this RP.
Figure 2: Downstream (*,*,RP) per-interface state-machine in tabular form Figure 2: Downstream per-interface (*,*,RP) state-machine in tabular form
+-------------++---------------------------------------------------------+ +-------------++----------------------------------------------------------+
| || Event | | || Event |
| ++-------------+-------------+--------------+--------------+ | ++-------------+--------------+--------------+--------------+
|Prev State ||Receive | Receive | Prune | Expiry Timer | |Prev State ||Receive | Receive | Prune- | Expiry Timer |
| ||Join(*,*,RP) | Prune | Pending | Expires | | ||Join(*,*,RP) | Prune | Pending | Expires |
| || | (*,*,RP) | Timer | | | || | (*,*,RP) | Timer | |
| || | | Expires | | | || | | Expires | |
+-------------++-------------+-------------+--------------+--------------+ +-------------++-------------+--------------+--------------+--------------+
| ||-> J state | -> NI state | - | - | | ||-> J state | -> NI state | - | - |
|NoInfo (NI) ||start Expiry | | | | |NoInfo (NI) ||start Expiry | | | |
| ||Timer | | | | | ||Timer | | | |
+-------------++-------------+-------------+--------------+--------------+ +-------------++-------------+--------------+--------------+--------------+
| ||-> J state | -> PP state | - | -> NI state | | ||-> J state | -> PP state | - | -> NI state |
|Join (J) ||restart | start Prune | | | |Join (J) ||restart | start Prune- | | |
| ||Expiry Timer | Pending | | | | ||Expiry Timer | Pending | | |
| || | Timer | | | | || | Timer | | |
+-------------++-------------+-------------+--------------+--------------+ +-------------++-------------+--------------+--------------+--------------+
| ||-> J state | -> PP state | -> NI state | -> NI state | | ||-> J state | -> PP state | -> NI state | -> NI state |
| ||restart | | Send Prune- | | | ||restart | | Send Prune- | |
|Prune ||Expiry | | Echo(*,*,RP) | | | ||Expiry | | Echo(*,*,RP) | |
|Pending (PP) ||Timer; | | | | |Prune- ||Timer; | | | |
| ||cancel Prune | | | | |Pending (PP) ||cancel | | | |
| ||Prune- | | | |
| ||Pending | | | | | ||Pending | | | |
| ||Timer | | | | | ||Timer | | | |
+-------------++-------------+-------------+--------------+--------------+ +-------------++-------------+--------------+--------------+--------------+
The transition events "Receive Join(*,*,RP)" and "Receive Prune(*,*,RP)" The transition events "Receive Join(*,*,RP)" and "Receive Prune(*,*,RP)"
imply receiving a Join or Prune targeted to this router's address on the imply receiving a Join or Prune targeted to this router's address on the
received interface. If the destination address is not correct, these received interface. If the destination address is not correct, these
state transitions in this state machine must not occur, although seeing state transitions in this state machine must not occur, although seeing
such a packet may cause state transitions in other state machines. such a packet may cause state transitions in other state machines.
On unnumbered interfaces on point-to-point links, the router's address On unnumbered interfaces on point-to-point links, the router's address
should be the same as the source address it chose for the Hello message should be the same as the source address it chose for the Hello message
it sent over that interface. However on point-to-point links we also it sent over that interface. However on point-to-point links we also
recommend that PIM messages with a destination address of all zeros are recommend that PIM Join/Prune messages with a destination address of all
also accepted. zeros are also accepted.
Transitions from NoInfo State Transitions from NoInfo State
When in NoInfo state, the following event may trigger a transition: When in NoInfo state, the following event may trigger a transition:
Receive Join(*,*,RP) Receive Join(*,*,RP)
A Join(*,*,RP) is received on interface I with its Upstream A Join(*,*,RP) is received on interface I with its Upstream
Neighbor Address set to the router's address on I. Neighbor Address set to the router's address on I.
The (*,*,RP) downstream state machine on interface I The (*,*,RP) downstream state machine on interface I
skipping to change at page 44, line 42 skipping to change at page 45, line 42
The (*,*,RP) downstream state machine on interface I remains The (*,*,RP) downstream state machine on interface I remains
in Join state, and the Expiry Timer (ET) is restarted, set to in Join state, and the Expiry Timer (ET) is restarted, set to
maximum of its current value and the HoldTime from the maximum of its current value and the HoldTime from the
triggering Join/Prune message. triggering Join/Prune message.
Receive Prune(*,*,RP) Receive Prune(*,*,RP)
A Prune(*,*,RP) is received on interface I with its Upstream A Prune(*,*,RP) is received on interface I with its Upstream
Neighbor Address set to the router's address on I. Neighbor Address set to the router's address on I.
The (*,*,RP) downstream state machine on interface I The (*,*,RP) downstream state machine on interface I
transitions to the PrunePending state. The PrunePending timer transitions to the Prune-Pending state. The Prune-Pending
is started; it is set to the J/P_Override_Interval(I) if the Timer is started; it is set to the J/P_Override_Interval(I) if
router has more than one neighbor on that interface; otherwise the router has more than one neighbor on that interface;
it is set to zero causing it to expire immediately. otherwise it is set to zero causing it to expire immediately.
Expiry Timer Expires Expiry Timer Expires
The Expiry Timer for the (*,*,RP) downstream state machine on The Expiry Timer for the (*,*,RP) downstream state machine on
interface I expires. interface I expires.
The (*,*,RP) downstream state machine on interface I The (*,*,RP) downstream state machine on interface I
transitions to the NoInfo state. transitions to the NoInfo state.
Transitions from PrunePending State Transitions from Prune-Pending State
When in PrunePending state, the following events may trigger a When in Prune-Pending state, the following events may trigger a
transition: transition:
Receive Join(*,*,RP) Receive Join(*,*,RP)
A Join(*,*,RP) is received on interface I with its Upstream A Join(*,*,RP) is received on interface I with its Upstream
Neighbor Address set to the router's address on I. Neighbor Address set to the router's address on I.
The (*,*,RP) downstream state machine on interface I The (*,*,RP) downstream state machine on interface I
transitions to the Join state. The PrunePending timer is transitions to the Join state. The Prune-Pending Timer is
canceled (without triggering an expiry event). The Expiry canceled (without triggering an expiry event). The Expiry
Timer is restarted, set to maximum of its current value and Timer is restarted, set to maximum of its current value and
the HoldTime from the triggering Join/Prune message. the HoldTime from the triggering Join/Prune message.
Expiry Timer Expires Expiry Timer Expires
The Expiry Timer for the (*,*,RP) downstream state machine on The Expiry Timer for the (*,*,RP) downstream state machine on
interface I expires. interface I expires.
The (*,*,RP) downstream state machine on interface I The (*,*,RP) downstream state machine on interface I
transitions to the NoInfo state. transitions to the NoInfo state.
PrunePending Timer Expires Prune-Pending Timer Expires
The PrunePending Timer for the (*,*,RP) downstream state The Prune-Pending Timer for the (*,*,RP) downstream state
machine on interface I expires. machine on interface I expires.
The (*,*,RP) downstream state machine on interface I The (*,*,RP) downstream state machine on interface I
transitions to the NoInfo state. A PruneEcho(*,*,RP) is sent transitions to the NoInfo state. A PruneEcho(*,*,RP) is sent
onto the subnet connected to interface I. onto the subnet connected to interface I.
The action "Send PruneEcho(*,*,RP)" is triggered when the The action "Send PruneEcho(*,*,RP)" is triggered when the
router stops forwarding on an interface as a result of a router stops forwarding on an interface as a result of a
prune. A PruneEcho(*,*,RP) is simply a Prune(*,*,RP) message prune. A PruneEcho(*,*,RP) is simply a Prune(*,*,RP) message
sent by the upstream router on a LAN with its own address in sent by the upstream router on a LAN with its own address in
the Upstream Neighbor Address field. Its purpose is to add the Upstream Neighbor Address field. Its purpose is to add
additional reliability so that if a Prune that should have additional reliability so that if a Prune that should have
been overridden by another router is lost locally on the LAN, been overridden by another router is lost locally on the LAN,
then the PruneEcho may be received and cause the override to then the PruneEcho may be received and cause the override to
happen. A PruneEcho(*,*,RP) need not be sent on an interface happen. A PruneEcho(*,*,RP) need not be sent on an interface
containing only one PIM neighbor. that contains only a single PIM neighbor during the time this
state machine was in Prune-Pending state.
4.5.2. Receiving (*,G) Join/Prune Messages 4.5.2. Receiving (*,G) Join/Prune Messages
When a router receives a Join(*,G) or Prune(*,G) it must first check to When a router receives a Join(*,G) or Prune(*,G) it must first check to
see whether the RP in the message matches RP(G) (the router's idea of see whether the RP in the message matches RP(G) (the router's idea of
who the RP is). If the RP in the message does not match RP(G) the Join who the RP is). If the RP in the message does not match RP(G) the
or Prune should be silently dropped. If a router has no RP information
(e.g. has not recently received a BSR message) then it may choose to Join(*,G) or Prune(*,G) should be silently dropped. If a router has no
accept Join(*,G) or Prune(*,G) and treat the RP in the message as RP(G). RP information (e.g. has not recently received a BSR message) then it
may choose to accept Join(*,G) or Prune(*,G) and treat the RP in the
message as RP(G).
The per-interface state-machine for receiving (*,G) Join/Prune Messages The per-interface state-machine for receiving (*,G) Join/Prune Messages
is given below. There are three states: is given below. There are three states:
NoInfo (NI) NoInfo (NI)
The interface has no (*,G) Join state and no timers running. The interface has no (*,G) Join state and no timers running.
Join (J) Join (J)
The interface has (*,G) Join state which will cause us to The interface has (*,G) Join state which will cause us to
forward packets destined for G from this interface except if forward packets destined for G from this interface except if
there is also (S,G,rpt) prune information (see Section 4.5.4) there is also (S,G,rpt) prune information (see Section 4.5.4)
or the router lost an assert on this interface. or the router lost an assert on this interface.
PrunePending (PP) Prune-Pending (PP)
The router has received a Prune(*,G) on this interface from a The router has received a Prune(*,G) on this interface from a
downstream neighbor and is waiting to see whether the prune downstream neighbor and is waiting to see whether the prune
will be overridden by another downstream router. For will be overridden by another downstream router. For
forwarding purposes, the PrunePending state functions exactly forwarding purposes, the Prune-Pending state functions exactly
like the Join state. like the Join state.
In addition the state-machine uses two timers: In addition, the state-machine uses two timers:
ExpiryTimer (ET) ExpiryTimer (ET)
This timer is restarted when a valid Join(*,G) is received. This timer is restarted when a valid Join(*,G) is received.
Expiry of the ExpiryTimer causes the interface state to revert Expiry of the Expiry Timer causes the interface state to
to NoInfo for this group. revert to NoInfo for this group.
PrunePendingTimer (PPT) Prune-Pending Timer (PPT)
This timer is set when a valid Prune(*,G) is received. Expiry This timer is set when a valid Prune(*,G) is received. Expiry
of the PrunePendingTimer causes the interface state to revert of the Prune-Pending Timer causes the interface state to
to NoInfo for this group. revert to NoInfo for this group.
Figure 3: Downstream (*,G) per-interface state-machine in tabular form Figure 3: Downstream per-interfacce (*,G) state-machine in tabular form
+-------------++--------------------------------------------------------+ +-------------++---------------------------------------------------------+
| || Event | | || Event |
| ++-------------+-------------+-------------+--------------+ | ++-------------+--------------+-------------+--------------+
|Prev State ||Receive | Receive | Prune | Expiry Timer | |Prev State ||Receive | Receive | Prune- | Expiry Timer |
| ||Join(*,G) | Prune(*,G) | Pending | Expires | | ||Join(*,G) | Prune(*,G) | Pending | Expires |
| || | | Timer | | | || | | Timer | |
| || | | Expires | | | || | | Expires | |
+-------------++-------------+-------------+-------------+--------------+ +-------------++-------------+--------------+-------------+--------------+
| ||-> J state | -> NI state | - | - | | ||-> J state | -> NI state | - | - |
|NoInfo (NI) ||start Expiry | | | | |NoInfo (NI) ||start Expiry | | | |
| ||Timer | | | | | ||Timer | | | |
+-------------++-------------+-------------+-------------+--------------+ +-------------++-------------+--------------+-------------+--------------+
| ||-> J state | -> PP state | - | -> NI state | | ||-> J state | -> PP state | - | -> NI state |
|Join (J) ||restart | start Prune | | | |Join (J) ||restart | start Prune- | | |
| ||Expiry Timer | Pending | | | | ||Expiry Timer | Pending | | |
| || | Timer | | | | || | Timer | | |
+-------------++-------------+-------------+-------------+--------------+ +-------------++-------------+--------------+-------------+--------------+
| ||-> J state | -> PP state | -> NI state | -> NI state | | ||-> J state | -> PP state | -> NI state | -> NI state |
| ||restart | | Send Prune- | | | ||restart | | Send Prune- | |
|Prune ||Expiry | | Echo(*,G) | | | ||Expiry | | Echo(*,G) | |
|Pending (PP) ||Timer; | | | | |Prune- ||Timer; | | | |
| ||cancel Prune | | | | |Pending (PP) ||cancel | | | |
| ||Prune- | | | |
| ||Pending | | | | | ||Pending | | | |
| ||Timer | | | | | ||Timer | | | |
+-------------++-------------+-------------+-------------+--------------+ +-------------++-------------+--------------+-------------+--------------+
The transition events "Receive Join(*,G)" and "Receive Prune(*,G)" imply The transition events "Receive Join(*,G)" and "Receive Prune(*,G)" imply
receiving a Join or Prune targeted to this router's address on the receiving a Join or Prune targeted to this router's address on the
received interface. If the destination address is not correct, these received interface. If the destination address is not correct, these
state transitions in this state machine must not occur, although seeing state transitions in this state machine must not occur, although seeing
such a packet may cause state transitions in other state machines. such a packet may cause state transitions in other state machines.
On unnumbered interfaces on point-to-point links, the router's address On unnumbered interfaces on point-to-point links, the router's address
should be the same as the source address it chose for the Hello message should be the same as the source address it chose for the Hello message
it sent over that interface. However on point-to-point links we also it sent over that interface. However on point-to-point links we also
recommend that PIM messages with a destination address of all zeros are recommend that PIM Join/Prune messages with a destination address of all
also accepted. zeros are also accepted.
Transitions from NoInfo State Transitions from NoInfo State
When in NoInfo state, the following event may trigger a transition: When in NoInfo state, the following event may trigger a transition:
Receive Join(*,G) Receive Join(*,G)
A Join(*,G) is received on interface I with its Upstream A Join(*,G) is received on interface I with its Upstream
Neighbor Address set to the router's address on I. Neighbor Address set to the router's address on I.
The (*,G) downstream state machine on interface I transitions The (*,G) downstream state machine on interface I transitions
skipping to change at page 48, line 27 skipping to change at page 49, line 27
The (*,G) downstream state machine on interface I remains in The (*,G) downstream state machine on interface I remains in
Join state, and the Expiry Timer (ET) is restarted, set to Join state, and the Expiry Timer (ET) is restarted, set to
maximum of its current value and the HoldTime from the maximum of its current value and the HoldTime from the
triggering Join/Prune message. triggering Join/Prune message.
Receive Prune(*,G) Receive Prune(*,G)
A Prune(*,G) is received on interface I with its Upstream A Prune(*,G) is received on interface I with its Upstream
Neighbor Address set to the router's address on I. Neighbor Address set to the router's address on I.
The (*,G) downstream state machine on interface I transitions The (*,G) downstream state machine on interface I transitions
to the PrunePending state. The PrunePending timer is started; to the Prune-Pending state. The Prune-Pending Timer is
it is set to the J/P_Override_Interval(I) if the router has started; it is set to the J/P_Override_Interval(I) if the
more than one neighbor on that interface; otherwise it is set router has more than one neighbor on that interface; otherwise
to zero causing it to expire immediately. it is set to zero causing it to expire immediately.
Expiry Timer Expires Expiry Timer Expires
The Expiry Timer for the (*,G) downstream state machine on The Expiry Timer for the (*,G) downstream state machine on
interface I expires. interface I expires.
The (*,G) downstream state machine on interface I transitions The (*,G) downstream state machine on interface I transitions
to the NoInfo state. to the NoInfo state.
Transitions from PrunePending State Transitions from Prune-Pending State
When in PrunePending state, the following events may trigger a When in Prune-Pending state, the following events may trigger a
transition: transition:
Receive Join(*,G) Receive Join(*,G)
A Join(*,G) is received on interface I with its Upstream A Join(*,G) is received on interface I with its Upstream
Neighbor Address set to the router's address on I. Neighbor Address set to the router's address on I.
The (*,G) downstream state machine on interface I transitions The (*,G) downstream state machine on interface I transitions
to the Join state. The PrunePending timer is canceled to the Join state. The Prune-Pending Timer is canceled
(without triggering an expiry event). The Expiry Timer is (without triggering an expiry event). The Expiry Timer is
restarted, set to maximum of its current value and the restarted, set to maximum of its current value and the
HoldTime from the triggering Join/Prune message. HoldTime from the triggering Join/Prune message.
Expiry Timer Expires Expiry Timer Expires
The Expiry Timer for the (*,G) downstream state machine on The Expiry Timer for the (*,G) downstream state machine on
interface I expires. interface I expires.
The (*,G) downstream state machine on interface I transitions The (*,G) downstream state machine on interface I transitions
to the NoInfo state. to the NoInfo state.
PrunePending Timer Expires Prune-Pending Timer Expires
The PrunePending Timer for the (*,G) downstream state machine The Prune-Pending Timer for the (*,G) downstream state machine
on interface I expires. on interface I expires.
The (*,G) downstream state machine on interface I transitions The (*,G) downstream state machine on interface I transitions
to the NoInfo state. A PruneEcho(*,G) is sent onto the subnet to the NoInfo state. A PruneEcho(*,G) is sent onto the subnet
connected to interface I. connected to interface I.
The action "Send PruneEcho(*,G)" is triggered when the router The action "Send PruneEcho(*,G)" is triggered when the router
stops forwarding on an interface as a result of a prune. A stops forwarding on an interface as a result of a prune. A
PruneEcho(*,G) is simply a Prune(*,G) message sent by the PruneEcho(*,G) is simply a Prune(*,G) message sent by the
upstream router on a LAN with its own address in the Upstream upstream router on a LAN with its own address in the Upstream
Neighbor Address field. Its purpose is to add additional Neighbor Address field. Its purpose is to add additional
reliability so that if a Prune that should have been reliability so that if a Prune that should have been
overridden by another router is lost locally on the LAN, then overridden by another router is lost locally on the LAN, then
the PruneEcho may be received and cause the override to the PruneEcho may be received and cause the override to
happen. A PruneEcho(*,G) need not be sent on an interface happen. A PruneEcho(*,G) need not be sent on an interface
containing only one PIM neighbor. that contains only a single PIM neighbor during the time this
state machine was in Prune-Pending state.
4.5.3. Receiving (S,G) Join/Prune Messages 4.5.3. Receiving (S,G) Join/Prune Messages
The per-interface state machine for receiving (S,G) Join/Prune messages The per-interface state machine for receiving (S,G) Join/Prune messages
is given below, and is almost identical to that for (*,G) messages. is given below, and is almost identical to that for (*,G) messages.
There are three states: There are three states:
NoInfo (NI) NoInfo (NI)
The interface has no (S,G) Join state and no (S,G) timers The interface has no (S,G) Join state and no (S,G) timers
running. running.
Join (J) Join (J)
The interface has (S,G) Join state which will cause us to The interface has (S,G) Join state which will cause us to
forward packets from S destined for G from this interface if forward packets from S destined for G from this interface if
the (S,G) state is active (the SPTbit is set) except if the the (S,G) state is active (the SPTbit is set) except if the
router lost an assert on this interface. router lost an assert on this interface.
PrunePending (PP) Prune-Pending (PP)
The router has received a Prune(S,G) on this interface from a The router has received a Prune(S,G) on this interface from a
downstream neighbor and is waiting to see whether the prune downstream neighbor and is waiting to see whether the prune
will be overridden by another downstream router. For will be overridden by another downstream router. For
forwarding purposes, the PrunePending state functions exactly forwarding purposes, the Prune-Pending state functions exactly
like the Join state. like the Join state.
In addition there are two timers: In addition, there are two timers:
ExpiryTimer (ET) ExpiryTimer (ET)
This timer is set when a valid Join(S,G) is received. Expiry This timer is set when a valid Join(S,G) is received. Expiry
of the ExpiryTimer causes this state machine to revert to of the ExpiryTimer causes this state machine to revert to
NoInfo state. NoInfo state.
PrunePendingTimer (PPT) Prune-Pending Timer (PPT)
This timer is set when a valid Prune(S,G) is received. Expiry This timer is set when a valid Prune(S,G) is received. Expiry
of the PrunePendingTimer this state machine to revert to of the Prune-Pending Timer causes this state machine to revert
NoInfo state. to NoInfo state.
Figure 4: Downstream per-interface (S,G) state-machine in tabular form Figure 4: Downstream per-interface (S,G) state-machine in tabular form
+-------------++--------------------------------------------------------+ +-------------++---------------------------------------------------------+
| || Event | | || Event |
| ++-------------+-------------+-------------+--------------+ | ++-------------+--------------+-------------+--------------+
|Prev State ||Receive | Receive | Prune | Expiry Timer | |Prev State ||Receive | Receive | Prune- | Expiry Timer |
| ||Join(S,G) | Prune(S,G) | Pending | Expires | | ||Join(S,G) | Prune(S,G) | Pending | Expires |
| || | | Timer | | | || | | Timer | |
| || | | Expires | | | || | | Expires | |
+-------------++-------------+-------------+-------------+--------------+ +-------------++-------------+--------------+-------------+--------------+
| ||-> J state | -> NI state | - | - | | ||-> J state | -> NI state | - | - |
|NoInfo (NI) ||start Expiry | | | | |NoInfo (NI) ||start Expiry | | | |
| ||Timer | | | | | ||Timer | | | |
+-------------++-------------+-------------+-------------+--------------+ +-------------++-------------+--------------+-------------+--------------+
| ||-> J state | -> PP state | - | -> NI state | | ||-> J state | -> PP state | - | -> NI state |
|Join (J) ||restart | start Prune | | | |Join (J) ||restart | start Prune- | | |
| ||Expiry Timer | Pending | | | | ||Expiry Timer | Pending | | |
| || | Timer | | | | || | Timer | | |
+-------------++-------------+-------------+-------------+--------------+ +-------------++-------------+--------------+-------------+--------------+
| ||-> J state | -> PP state | -> NI state | -> NI state | | ||-> J state | -> PP state | -> NI state | -> NI state |
| ||restart | | Send Prune- | | | ||restart | | Send Prune- | |
|Prune ||Expiry | | Echo(S,G) | | | ||Expiry | | Echo(S,G) | |
|Pending (PP) ||Timer; | | | | |Prune- ||Timer; | | | |
| ||cancel Prune | | | | |Pending (PP) ||cancel | | | |
| ||Prune- | | | |
| ||Pending | | | | | ||Pending | | | |
| ||Timer | | | | | ||Timer | | | |
+-------------++-------------+-------------+-------------+--------------+ +-------------++-------------+--------------+-------------+--------------+
The transition events "Receive Join(S,G)" and "Receive Prune(S,G)" imply The transition events "Receive Join(S,G)" and "Receive Prune(S,G)" imply
receiving a Join or Prune targeted to this router's address on the receiving a Join or Prune targeted to this router's address on the
received interface. If the destination address is not correct, these received interface. If the destination address is not correct, these
state transitions in this state machine must not occur, although seeing state transitions in this state machine must not occur, although seeing
such a packet may cause state transitions in other state machines. such a packet may cause state transitions in other state machines.
On unnumbered interfaces on point-to-point links, the router's address On unnumbered interfaces on point-to-point links, the router's address
should be the same as the source address it chose for the Hello message should be the same as the source address it chose for the Hello message
it sent over that interface. However on point-to-point links we also it sent over that interface. However on point-to-point links we also
recommend that PIM messages with a destination address of all zeros are recommend that PIM Join/Prune messages with a destination address of all
also accepted. zeros are also accepted.
Transitions from NoInfo State Transitions from NoInfo State
When in NoInfo state, the following event may trigger a transition: When in NoInfo state, the following event may trigger a transition:
Receive Join(S,G) Receive Join(S,G)
A Join(S,G) is received on interface I with its Upstream A Join(S,G) is received on interface I with its Upstream
Neighbor Address set to the router's address on I. Neighbor Address set to the router's address on I.
The (S,G) downstream state machine on interface I transitions The (S,G) downstream state machine on interface I transitions
skipping to change at page 51, line 39 skipping to change at page 52, line 41
The (S,G) downstream state machine on interface I remains in The (S,G) downstream state machine on interface I remains in
Join state, and the Expiry Timer (ET) is restarted, set to Join state, and the Expiry Timer (ET) is restarted, set to
maximum of its current value and the HoldTime from the maximum of its current value and the HoldTime from the
triggering Join/Prune message. triggering Join/Prune message.
Receive Prune(S,G) Receive Prune(S,G)
A Prune(S,G) is received on interface I with its Upstream A Prune(S,G) is received on interface I with its Upstream
Neighbor Address set to the router's address on I. Neighbor Address set to the router's address on I.
The (S,G) downstream state machine on interface I transitions The (S,G) downstream state machine on interface I transitions
to the PrunePending state. The PrunePending timer is started; to the Prune-Pending state. The Prune-Pending Timer is
it is set to the J/P_Override_Interval(I) if the router has started; it is set to the J/P_Override_Interval(I) if the
more than one neighbor on that interface; otherwise it is set router has more than one neighbor on that interface; otherwise
to zero causing it to expire immediately. it is set to zero causing it to expire immediately.
Expiry Timer Expires Expiry Timer Expires
The Expiry Timer for the (S,G) downstream state machine on The Expiry Timer for the (S,G) downstream state machine on
interface I expires. interface I expires.
The (S,G) downstream state machine on interface I transitions The (S,G) downstream state machine on interface I transitions
to the NoInfo state. to the NoInfo state.
Transitions from PrunePending State Transitions from Prune-Pending State
When in PrunePending state, the following events may trigger a When in Prune-Pending state, the following events may trigger a
transition: transition:
Receive Join(S,G) Receive Join(S,G)
A Join(S,G) is received on interface I with its Upstream A Join(S,G) is received on interface I with its Upstream
Neighbor Address set to the router's address on I. Neighbor Address set to the router's address on I.
The (S,G) downstream state machine on interface I transitions The (S,G) downstream state machine on interface I transitions
to the Join state. The PrunePending timer is canceled to the Join state. The Prune-Pending Timer is canceled
(without triggering an expiry event). The Expiry Timer is (without triggering an expiry event). The Expiry Timer is
restarted, set to maximum of its current value and the restarted, set to maximum of its current value and the
HoldTime from the triggering Join/Prune message. HoldTime from the triggering Join/Prune message.
Expiry Timer Expires Expiry Timer Expires
The Expiry Timer for the (S,G) downstream state machine on The Expiry Timer for the (S,G) downstream state machine on
interface I expires. interface I expires.
The (S,G) downstream state machine on interface I transitions The (S,G) downstream state machine on interface I transitions
to the NoInfo state. to the NoInfo state.
PrunePending Timer Expires Prune-Pending Timer Expires
The PrunePending Timer for the (S,G) downstream state machine The Prune-Pending Timer for the (S,G) downstream state machine
on interface I expires. on interface I expires.
The (S,G) downstream state machine on interface I transitions The (S,G) downstream state machine on interface I transitions
to the NoInfo state. A PruneEcho(S,G) is sent onto the subnet to the NoInfo state. A PruneEcho(S,G) is sent onto the subnet
connected to interface I. connected to interface I.
The action "Send PruneEcho(S,G)" is triggered when the router The action "Send PruneEcho(S,G)" is triggered when the router
stops forwarding on an interface as a result of a prune. A stops forwarding on an interface as a result of a prune. A
PruneEcho(S,G) is simply a Prune(S,G) message sent by the PruneEcho(S,G) is simply a Prune(S,G) message sent by the
upstream router on a LAN with its own address in the Upstream upstream router on a LAN with its own address in the Upstream
Neighbor Address field. Its purpose is to add additional Neighbor Address field. Its purpose is to add additional
reliability so that if a Prune that should have been reliability so that if a Prune that should have been
overridden by another router is lost locally on the LAN, then overridden by another router is lost locally on the LAN, then
the PruneEcho may be received and cause the override to the PruneEcho may be received and cause the override to
happen. A PruneEcho(S,G) need not be sent on an interface happen. A PruneEcho(S,G) need not be sent on an interface
containing only one PIM neighbor. that contains only a single PIM neighbor during the time this
state machine was in Prune-Pending state.
4.5.4. Receiving (S,G,rpt) Join/Prune Messages 4.5.4. Receiving (S,G,rpt) Join/Prune Messages
The per-interface state machine for receiving (S,G,rpt) Join/Prune The per-interface state machine for receiving (S,G,rpt) Join/Prune
messages is given below. There are five states: messages is given below. There are five states:
NoInfo (NI) NoInfo (NI)
The interface has no (S,G,rpt) Prune state and no (S,G,rpt) The interface has no (S,G,rpt) Prune state and no (S,G,rpt)
timers running. timers running.
Prune (P) Prune (P)
The interface has (S,G,rpt) Prune state which will cause us The interface has (S,G,rpt) Prune state which will cause us
not to forward packets from S destined for G from this not to forward packets from S destined for G from this
interface even though the interface has active (*,G) Join interface even though the interface has active (*,G) Join
state. When interface I is in this state, the macro state.
prune(S,G,rpt,I) returns true.
PrunePending (PP) Prune-Pending (PP)
The router has received a Prune(S,G,rpt) on this interface The router has received a Prune(S,G,rpt) on this interface
from a downstream neighbor and is waiting to see whether the from a downstream neighbor and is waiting to see whether the
prune will be overridden by another downstream router. For prune will be overridden by another downstream router. For
forwarding purposes, the PrunePending state functions exactly forwarding purposes, the Prune-Pending state functions exactly
like the NoInfo state. like the NoInfo state.
PruneTmp (P') PruneTmp (P')
This state is a transient state which for forwarding purposes This state is a transient state which for forwarding purposes
behaves exactly like the Prune state. A (*,G) Join has been behaves exactly like the Prune state. A (*,G) Join has been
received (which may cancel the (S,G,rpt) Prune). As we parse received (which may cancel the (S,G,rpt) Prune). As we parse
the Join/Prune message from top to bottom, we first enter this the Join/Prune message from top to bottom, we first enter this
state if the message contains a (*,G) Join. Later in the state if the message contains a (*,G) Join. Later in the
message we will normally encounter an (S,G,rpt) prune to re- message we will normally encounter an (S,G,rpt) prune to re-
instate the Prune state. However if we reach the end of the instate the Prune state. However if we reach the end of the
message without encountering such a (S,G,rpt) prune, then we message without encountering such a (S,G,rpt) prune, then we
will revert to NoInfo state in this state machine. will revert to NoInfo state in this state machine.
As no time is spent in this state, no timers can expire. As no time is spent in this state, no timers can expire.
PrunePendingTmp (PP') Prune-Pending-Tmp (PP')
This state is a transient state which is identical to P' This state is a transient state which is identical to P'
except that it is associated with the PP state rather than the except that it is associated with the PP state rather than the
P state. For forwarding purposes, PP' behaves exactly like PP P state. For forwarding purposes, PP' behaves exactly like PP
state. state.
In addition there are two timers: In addition, there are two timers:
ExpiryTimer (ET) ExpiryTimer (ET)
This timer is set when a valid Prune(S,G,rpt) is received. This timer is set when a valid Prune(S,G,rpt) is received.
Expiry of the ExpiryTimer causes this state machine to revert Expiry of the ExpiryTimer causes this state machine to revert
to NoInfo state. to NoInfo state.
PrunePendingTimer (PPT) Prune-Pending Timer (PPT)
This timer is set when a valid Prune(S,G,rpt) is received. This timer is set when a valid Prune(S,G,rpt) is received.
Expiry of the PrunePendingTimer causes this state machine to Expiry of the Prune-Pending Timer causes this state machine to
move on to Prune state. move on to Prune state.
Figure 5: Downstream per-interface (S,G,rpt) state-machine in tabular form Figure 5: Downstream per-interface (S,G,rpt) state-machine in tabular form
+----------++----------------------------------------------------------------+ +----------++----------------------------------------------------------------+
| || Event | | || Event |
| ++----------+-----------+-----------+---------+---------+---------+ | ++----------+-----------+-----------+---------+---------+---------+
|Prev ||Receive | Receive | Receive | End of | Prune | Expiry | |Prev ||Receive | Receive | Receive | End of | Prune- | Expiry |
|State ||Join(*,G) | Join | Prune | Message | Pending | Timer | |State ||Join(*,G) | Join | Prune | Message | Pending | Timer |
| || | (S,G,rpt) | (S,G,rpt) | | Timer | Expires | | || | (S,G,rpt) | (S,G,rpt) | | Timer | Expires |
| || | | | | Expires | | | || | | | | Expires | |
+----------++----------+-----------+-----------+---------+---------+---------+ +----------++----------+-----------+-----------+---------+---------+---------+
| ||- | - | -> PP | - | n/a | n/a | | ||- | - | -> PP | - | n/a | n/a |
| || | | state | | | | | || | | state | | | |
| || | | start | | | | | || | | start | | | |
| || | | Prune | | | | |NoInfo || | | Prune- | | | |
|No Info || | | Pending | | | | |(NI) || | | Pending | | | |
|(NI) || | | Timer; | | | | | || | | Timer; | | | |
| || | | start | | | | | || | | start | | | |
| || | | Expiry | | | | | || | | Expiry | | | |
| || | | Timer | | | | | || | | Timer | | | |
| || | | Timer | | | |
+----------++----------+-----------+-----------+---------+---------+---------+ +----------++----------+-----------+-----------+---------+---------+---------+
| ||-> P' | -> NI | -> P | - | n/a | -> NI | | ||-> P' | -> NI | -> P | - | n/a | -> NI |
|Pruned ||state | state | state | | | state | | ||state | state | state | | | state |
|(P) || | | restart | | | | |Prune (P) || | | restart | | | |
| || | | Expiry | | | | | || | | Expiry | | | |
| || | | Timer | | | | | || | | Timer | | | |
+----------++----------+-----------+-----------+---------+---------+---------+ +----------++----------+-----------+-----------+---------+---------+---------+
|Prune ||-> PP' | -> NI | - | - | -> P | n/a | |Prune- ||-> PP' | -> NI | - | - | -> P | n/a |
|Pending ||state | state | | | state | | |Pending ||state | state | | | state | |
|(PP) || | | | | | | |(PP) || | | | | | |
+----------++----------+-----------+-----------+---------+---------+---------+ +----------++----------+-----------+-----------+---------+---------+---------+
| ||error | error | -> P | -> NI | n/a | n/a | | ||error | error | -> P | -> NI | n/a | n/a |
|Prune Tmp || | | state | state | | | |Prune-Tmp || | | state | state | | |
|(P') || | | restart | | | | |(P') || | | restart | | | |
| || | | Expiry | | | | | || | | Expiry | | | |
| || | | Timer | | | | | || | | Timer | | | |
+----------++----------+-----------+-----------+---------+---------+---------+ +----------++----------+-----------+-----------+---------+---------+---------+
| ||error | error | -> PP | -> NI | n/a | n/a | | ||error | error | -> PP | -> NI | n/a | n/a |
|Prune || | | state | state | | | |Prune- || | | state | state | | |
|Pending || | | restart | | | | |Pending- || | | restart | | | |
|Tmp (PP') || | | Expiry | | | | |Tmp (PP') || | | Expiry | | | |
| || | | Timer | | | | | || | | Timer | | | |
+----------++----------+-----------+-----------+---------+---------+---------+ +----------++----------+-----------+-----------+---------+---------+---------+
The transition events "Receive Join(S,G,rpt)", "Receive Prune(S,G,rpt)", The transition events "Receive Join(S,G,rpt)", "Receive Prune(S,G,rpt)",
and "Receive Join(*,G)" imply receiving a Join or Prune targeted to this and "Receive Join(*,G)" imply receiving a Join or Prune targeted to this
router's address on the received interface. If the destination address router's address on the received interface. If the destination address
is not correct, these state transitions in this state machine must not is not correct, these state transitions in this state machine must not
occur, although seeing such a packet may cause state transitions in occur, although seeing such a packet may cause state transitions in
other state machines. other state machines.
On unnumbered interfaces on point-to-point links, the router's address On unnumbered interfaces on point-to-point links, the router's address
should be the same as the source address it chose for the Hello message should be the same as the source address it chose for the Hello message
it sent over that interface. However on point-to-point links we also it sent over that interface. However on point-to-point links we also
recommend that PIM messages with a destination address of all zeros are recommend that PIM Join/Prune messages with a destination address of all
also accepted. zeros are also accepted.
Transitions from NoInfo State Transitions from NoInfo State
When in NoInfo (NI) state, the following event may trigger a transition: When in NoInfo (NI) state, the following event may trigger a transition:
Receive Prune(S,G,rpt) Receive Prune(S,G,rpt)
A Prune(S,G,rpt) is received on interface I with its Upstream A Prune(S,G,rpt) is received on interface I with its Upstream
Neighbor Address set to the router's address on I. Neighbor Address set to the router's address on I.
The (S,G,rpt) downstream state machine on interface I The (S,G,rpt) downstream state machine on interface I
transitions to the PrunePending state. The Expiry Timer (ET) transitions to the Prune-Pending state. The Expiry Timer (ET)
is started, and set to the HoldTime from the triggering is started, and set to the HoldTime from the triggering
Join/Prune message. The PrunePending timer is started; it is Join/Prune message. The Prune-Pending Timer is started; it is
set to the J/P_Override_Interval(I) if the router has more set to the J/P_Override_Interval(I) if the router has more
than one neighbor on that interface; otherwise it is set to than one neighbor on that interface; otherwise it is set to
zero causing it to expire immediately. zero causing it to expire immediately.
Transitions from PrunePending State Transitions from Prune-Pending State
When in PrunePending (PP) state, the following events may trigger a When in Prune-Pending (PP) state, the following events may trigger a
transition: transition:
Receive Join(*,G) Receive Join(*,G)
A Join(*,G) is received on interface I with its Upstream A Join(*,G) is received on interface I with its Upstream
Neighbor Address set to the router's address on I. Neighbor Address set to the router's address on I.
The (S,G,rpt) downstream state machine on interface I The (S,G,rpt) downstream state machine on interface I
transitions to PrunePendingTmp state whilst the remainder of transitions to Prune-Pending-Tmp state whilst the remainder of
the compound Join/Prune message containing the Join(*,G) is the compound Join/Prune message containing the Join(*,G) is
processed. processed.
Receive Join(S,G,rpt) Receive Join(S,G,rpt)
A Join(S,G,rpt) is received on interface I with its Upstream A Join(S,G,rpt) is received on interface I with its Upstream
Neighbor Address set to the router's address on I. Neighbor Address set to the router's address on I.
The (S,G,rpt) downstream state machine on interface I The (S,G,rpt) downstream state machine on interface I
transitions to NoInfo state. ET and PPT are canceled. transitions to NoInfo state. ET and PPT are canceled.
PrunePending Timer Expires Prune-Pending Timer Expires
The PrunePending Timer for the (S,G,rpt) downstream state The Prune-Pending Timer for the (S,G,rpt) downstream state
machine on interface I expires. machine on interface I expires.
The (S,G,rpt) downstream state machine on interface I The (S,G,rpt) downstream state machine on interface I
transitions to the Pruned state. transitions to the Prune state.
Transitions from Pruned State Transitions from Prune State
When in Pruned (P) state, the following events may trigger a transition: When in Prune (P) state, the following events may trigger a transition:
Receive Join(*,G) Receive Join(*,G)
A Join(*,G) is received on interface I with its Upstream A Join(*,G) is received on interface I with its Upstream
Neighbor Address set to the router's address on I. Neighbor Address set to the router's address on I.
The (S,G,rpt) downstream state machine on interface I The (S,G,rpt) downstream state machine on interface I
transitions to PruneTmp state whilst the remainder of the transitions to PruneTmp state whilst the remainder of the
compound Join/Prune message containing the Join(*,G) is compound Join/Prune message containing the Join(*,G) is
processed. processed.
skipping to change at page 56, line 34 skipping to change at page 57, line 33
Neighbor Address set to the router's address on I. Neighbor Address set to the router's address on I.
The (S,G,rpt) downstream state machine on interface I The (S,G,rpt) downstream state machine on interface I
transitions to NoInfo state. ET and PPT are canceled. transitions to NoInfo state. ET and PPT are canceled.
Receive Prune(S,G,rpt) Receive Prune(S,G,rpt)
A Prune(S,G,rpt) is received on interface I with its Upstream A Prune(S,G,rpt) is received on interface I with its Upstream
Neighbor Address set to the router's address on I. Neighbor Address set to the router's address on I.
The (S,G,rpt) downstream state machine on interface I remains The (S,G,rpt) downstream state machine on interface I remains
in Pruned state. The Expiry Timer (ET) is restarted, set to in Prune state. The Expiry Timer (ET) is restarted, set to
maximum of its current value and the HoldTime from the maximum of its current value and the HoldTime from the
triggering Join/Prune message. triggering Join/Prune message.
Expiry Timer Expires Expiry Timer Expires
The Expiry Timer for the (S,G,rpt) downstream state machine on The Expiry Timer for the (S,G,rpt) downstream state machine on
interface I expires. interface I expires.
The (S,G,rpt) downstream state machine on interface I The (S,G,rpt) downstream state machine on interface I
transitions to the NoInfo state. ET and PPT are canceled. transitions to the NoInfo state. ET and PPT are canceled.
Transitions from PrunePendingTmp State Transitions from Prune-Pending-Tmp State
When in PrunePendingTmp (PP') state and processing a compound Join/Prune When in Prune-Pending-Tmp (PP') state and processing a compound
message, the following events may trigger a transition: Join/Prune message, the following events may trigger a transition:
Receive Prune(S,G,rpt) Receive Prune(S,G,rpt)
The compound Join/Prune message contains a Prune(S,G,rpt). The compound Join/Prune message contains a Prune(S,G,rpt).
The (S,G,rpt) downstream state machine on interface I The (S,G,rpt) downstream state machine on interface I
transitions back to the PrunePending state. The Expiry Timer transitions back to the Prune-Pending state. The Expiry Timer
(ET) is restarted, set to maximum of its current value and the (ET) is restarted, set to maximum of its current value and the
HoldTime from the triggering Join/Prune message. HoldTime from the triggering Join/Prune message.
End of Message End of Message
The end of the compound Join/Prune message is reached. The end of the compound Join/Prune message is reached.
The (S,G,rpt) downstream state machine on interface I The (S,G,rpt) downstream state machine on interface I
transitions to the NoInfo state. ET and PPT are canceled. transitions to the NoInfo state. ET and PPT are canceled.
Transitions from PruneTmp State Transitions from PruneTmp State
When in PruneTmp (P') state and processing a compound Join/Prune When in PruneTmp (P') state and processing a compound Join/Prune
message, the following events may trigger a transition: message, the following events may trigger a transition:
Receive Prune(S,G,rpt) Receive Prune(S,G,rpt)
The compound Join/Prune message contains a Prune(S,G,rpt). The compound Join/Prune message contains a Prune(S,G,rpt).
The (S,G,rpt) downstream state machine on interface I The (S,G,rpt) downstream state machine on interface I
transitions back to the Pruned state. The Expiry Timer (ET) transitions back to the Prune state. The Expiry Timer (ET) is
is restarted, set to maximum of its current value and the restarted, set to maximum of its current value and the
HoldTime from the triggering Join/Prune message. HoldTime from the triggering Join/Prune message.
End of Message End of Message
The end of the compound Join/Prune message is reached. The end of the compound Join/Prune message is reached.
The (S,G,rpt) downstream state machine on interface I The (S,G,rpt) downstream state machine on interface I
transitions to the NoInfo state. ET and PPT are canceled. transitions to the NoInfo state. ET and PPT are canceled.
Notes: Notes:
skipping to change at page 58, line 22 skipping to change at page 59, line 22
watch for messages on its upstream interface from other routers on that watch for messages on its upstream interface from other routers on that
subnet, and these may modify its behavior. If it sees a Join(*,*,RP) to subnet, and these may modify its behavior. If it sees a Join(*,*,RP) to
the correct upstream neighbor, it should suppress its own Join(*,*,RP). the correct upstream neighbor, it should suppress its own Join(*,*,RP).
If it sees a Prune(*,*,RP) to the correct upstream neighbor, it should If it sees a Prune(*,*,RP) to the correct upstream neighbor, it should
be prepared to override that prune by sending a Join(*,*,RP) almost be prepared to override that prune by sending a Join(*,*,RP) almost
immediately. Finally, if it sees the Generation ID (see Section 4.3) of immediately. Finally, if it sees the Generation ID (see Section 4.3) of
the correct upstream neighbor change, it knows that the upstream the correct upstream neighbor change, it knows that the upstream
neighbor has lost state, and it should be prepared to refresh the state neighbor has lost state, and it should be prepared to refresh the state
by sending a Join(*,*,RP) almost immediately. by sending a Join(*,*,RP) almost immediately.
In addition if the MRIB changes to indicate that the next hop towards In addition, if the MRIB changes to indicate that the next hop towards
the RP has changed, the router should prune off from the old next hop, the RP has changed, the router should prune off from the old next hop,
and join towards the new next hop. and join towards the new next hop.
The upstream (*,*,RP) state-machine contains only two states: The upstream (*,*,RP) state-machine contains only two states:
Not Joined Not Joined
The downstream state-machines indicate that the router does not The downstream state-machines indicate that the router does not
need to join the (*,*,RP) tree for this RP. need to join the (*,*,RP) tree for this RP.
Joined Joined
The downstream state-machines indicate that the router would like The downstream state-machines indicate that the router should join
to join the (*,*,RP) tree for this RP. the (*,*,RP) tree for this RP.
In addition, one timer JT(*,*,RP) is kept which is used to trigger the In addition, one timer JT(*,*,RP) is kept which is used to trigger the
sending of a Join(*,*,RP) to the upstream next hop towards the RP, sending of a Join(*,*,RP) to the upstream next hop towards the RP,
MRIB.next_hop(RP). NBR(RPF_interface(RP), MRIB.next_hop(RP)).
Figure 6: Upstream (*,*,RP) state-machine in tabular form Figure 6: Upstream (*,*,RP) state-machine in tabular form
+-------------------+---------------------------------------------------+ +--------------------++-------------------------------------------------+
| | Event | | || Event |
| Prev State +--------------------------+------------------------+ | Prev State ++-------------------------+-----------------------+
| | JoinDesired(*,*,RP) | JoinDesired(*,*,RP) | | || JoinDesired- | JoinDesired- |
| | ->True | ->False | | || (*,*,RP) ->True | (*,*,RP) ->False |
+-------------------+--------------------------+------------------------+ +--------------------++-------------------------+-----------------------+
| | -> J state | - | | || -> J state | - |
| NotJoined (NJ) | Send Join(*,*,RP); | | | NotJoined (NJ) || Send Join(*,*,RP); | |
| | Set Join Timer to | | | || Set Join Timer to | |
| | t_periodic | | | || t_periodic | |
+-------------------+--------------------------+------------------------+ +--------------------++-------------------------+-----------------------+
| Joined (J) | - | -> NJ state | | Joined (J) || - | -> NJ state |
| | | Send Prune(*,*,RP); | | || | Send Prune- |
| | | Cancel Join Timer | | || | (*,*,RP); Cancel |
+-------------------+--------------------------+------------------------+ | || | Join Timer |
+--------------------++-------------------------+-----------------------+
In addition, we have the following transitions which occur within the In addition, we have the following transitions which occur within the
Joined state: Joined state:
+-----------------------------------------------------------------------+ +-----------------------------------------------------------------------+
| In Joined (J) State | | In Joined (J) State |
+-----------------+----------------------+------------------------------+ +-------------------+--------------------+------------------------------+
| Timer Expires | See | See | | Timer Expires | See | See |
| | Join(*,*,RP) | Prune(*,*,RP) | | | Join(*,*,RP) | Prune(*,*,RP) |
| | to | to | | | to MRIB.- | to MRIB.- |
| | MRIB.next_hop(RP) | MRIB.next_hop(RP) | | | next_hop(RP) | next_hop(RP) |
+-----------------+----------------------+------------------------------+ +-------------------+--------------------+------------------------------+
| Send | Increase Join | Decrease Join | | Send | Increase Join | Decrease Join |
| Join(*,*,RP); | Timer to | Timer to | | Join(*,*,RP); | Timer to | Timer to |
| Set Join Timer | t_joinsuppress | t_override | | Set Join Timer | t_joinsuppress | t_override |
| to t_periodic | | | | to t_periodic | | |
+-----------------+----------------------+------------------------------+ +-------------------+--------------------+------------------------------+
+-----------------------------------------------------------------------+ -------------------------------------------------------------------------
| In Joined (J) State | In Joined (J) State
+-----------------------------------+-----------------------------------+ -------------------------------------------------------------------------
| MRIB.next_hop(RP) | MRIB.next_hop(RP) GenID | NBR(RPF_interface(RP), MRIB.next_hop(RP) GenID
| changes | changes | MRIB.next_hop(RP)) changes
+-----------------------------------+-----------------------------------+ changes
| Send Join(*,*,RP) to new | Decrease Join Timer to | -------------------------------------------------------------------------
| next hop; Send | t_override | Send Join(*,*,RP) to new Decrease Join Timer to
| Prune(*,*,RP) to old | | next hop; Send t_override
| next hop; set Join Timer | | Prune(*,*,RP) to old
| to t_periodic | | next hop; set Join Timer
to t_periodic
| | |
| | |
| | |
INTERNET-DRAFT Expires: April 2004 October 2003|
| | |
| | |
+-----------------------------------+-----------------------------------+ +-----------------------------------+-----------------------------------+
This state machine uses the following macro: This state machine uses the following macro:
bool JoinDesired(*,*,RP) { bool JoinDesired(*,*,RP) {
if immediate_olist(*,*,RP) != NULL if immediate_olist(*,*,RP) != NULL
return TRUE return TRUE
else else
return FALSE return FALSE
} }
skipping to change at page 60, line 31 skipping to change at page 61, line 39
When the upstream (*,*,RP) state-machine is in NotJoined state, the When the upstream (*,*,RP) state-machine is in NotJoined state, the
following event may trigger a state transition: following event may trigger a state transition:
JoinDesired(*,*,RP) becomes True JoinDesired(*,*,RP) becomes True
The downstream state for (*,*,RP) has changed so that at least The downstream state for (*,*,RP) has changed so that at least
one interface is in immediate_olist(*,*,RP), making one interface is in immediate_olist(*,*,RP), making
JoinDesired(*,*,RP) become True. JoinDesired(*,*,RP) become True.
The upstream (*,*,RP) state machine transitions to Joined The upstream (*,*,RP) state machine transitions to Joined
state. Send Join(*,*,RP) to the appropriate upstream state. Send Join(*,*,RP) to the appropriate upstream
neighbor, which is MRIB.next_hop(RP). Set the Join Timer (JT) neighbor, which is NBR(RPF_interface(RP), MRIB.next_hop(RP)).
to expire after t_periodic seconds. Set the Join Timer (JT) to expire after t_periodic seconds.
Transitions from Joined State Transitions from Joined State
When the upstream (*,*,RP) state-machine is in Joined state, the When the upstream (*,*,RP) state-machine is in Joined state, the
following events may trigger state transitions: following events may trigger state transitions:
JoinDesired(*,*,RP) becomes False JoinDesired(*,*,RP) becomes False
The downstream state for (*,*,RP) has changed so no interface The downstream state for (*,*,RP) has changed so no interface
is in immediate_olist(*,*,RP), making JoinDesired(*,*,RP) is in immediate_olist(*,*,RP), making JoinDesired(*,*,RP)
become False. become False.
The upstream (*,*,RP) state machine transitions to NotJoined The upstream (*,*,RP) state machine transitions to NotJoined
state. Send Prune(*,*,RP) to the appropriate upstream state. Send Prune(*,*,RP) to the appropriate upstream
neighbor, which is MRIB.next_hop(RP). Cancel the Join Timer neighbor, which is NBR(RPF_interface(RP), MRIB.next_hop(RP)).
(JT). Cancel the Join Timer (JT).
Join Timer Expires Join Timer Expires
The Join Timer (JT) expires, indicating time to send a The Join Timer (JT) expires, indicating time to send a
Join(*,*,RP) Join(*,*,RP)
Send Join(*,*,RP) to the appropriate upstream neighbor, which Send Join(*,*,RP) to the appropriate upstream neighbor, which
is MRIB.next_hop(RP). Restart the Join Timer (JT) to expire is NBR(RPF_interface(RP), MRIB.next_hop(RP)). Restart the
after t_periodic seconds. Join Timer (JT) to expire after t_periodic seconds.
See Join(*,*,RP) to MRIB.next_hop(RP) See Join(*,*,RP) to MRIB.next_hop(RP)
This event is only relevant if RPF_interface(RP) is a shared This event is only relevant if RPF_interface(RP) is a shared
medium. This router sees another router on RPF_interface(RP) medium. This router sees another router on RPF_interface(RP)
send a Join(*,*,RP) to MRIB.next_hop(RP). This causes this send a Join(*,*,RP) to any of the addresses belonging to
NBR(RPF_interface(RP), MRIB.next_hop(RP)). This causes this
router to suppress its own Join. router to suppress its own Join.
The upstream (*,*,RP) state machine remains in Joined state. The upstream (*,*,RP) state machine remains in Joined state.
Let t_joinsuppress be the minimum of t_suppressed and the Let t_joinsuppress be the minimum of t_suppressed and the
HoldTime from the Join/Prune message triggering this event. HoldTime from the Join/Prune message triggering this event.
If the Join Timer is set to expire in less than t_joinsuppress If the Join Timer is set to expire in less than t_joinsuppress
seconds, reset it so that it expires after t_joinsuppress seconds, reset it so that it expires after t_joinsuppress
seconds. If the Join Timer is set to expire in more than seconds. If the Join Timer is set to expire in more than
t_joinsuppress seconds, leave it unchanged. t_joinsuppress seconds, leave it unchanged.
See Prune(*,*,RP) to MRIB.next_hop(RP) See Prune(*,*,RP) to MRIB.next_hop(RP)
This event is only relevant if RPF_interface(RP) is a shared This event is only relevant if RPF_interface(RP) is a shared
medium. This router sees another router on RPF_interface(RP) medium. This router sees another router on RPF_interface(RP)
send a Prune(*,*,RP) to MRIB.next_hop(RP). As this router is send a Prune(*,*,RP) to any of the addresses belonging to
NBR(RPF_interface(RP), MRIB.next_hop(RP)). As this router is
in Joined state, it must override the Prune after a short in Joined state, it must override the Prune after a short
random interval. random interval.
The upstream (*,*,RP) state machine remains in Joined state. The upstream (*,*,RP) state machine remains in Joined state.
If the Join Timer is set to expire in more than t_override If the Join Timer is set to expire in more than t_override
seconds, reset it so that it expires after t_override seconds. seconds, reset it so that it expires after t_override seconds.
If the Join Timer is set to expire in less than t_override If the Join Timer is set to expire in less than t_override
seconds, leave it unchanged. seconds, leave it unchanged.
MRIB.next_hop(RP) changes NBR(RPF_interface(RP), MRIB.next_hop(RP)) changes
A change in the MRIB routing base causes the next hop towards A change in the MRIB routing base causes the next hop towards
the RP to change. the RP to change.
The upstream (*,*,RP) state machine remains in Joined state. The upstream (*,*,RP) state machine remains in Joined state.
Send Prune(*,*,RP) to the old upstream neighbor, which is the Send Join(*,*,RP) to the new upstream neighbor which is the
old value of MRIB.next_hop(RP). Send Join(*,*,RP) to the new new value of NBR(RPF_interface(RP), MRIB.next_hop(RP)). Send
upstream neighbor which is the new value of MRIB.next_hop(RP). Prune(*,*,RP) to the old upstream neighbor, which is the old
Set the Join Timer (JT) to expire after t_periodic seconds. value of NBR(RPF_interface(RP), MRIB.next_hop(RP)). Set the
Join Timer (JT) to expire after t_periodic seconds.
MRIB.next_hop(RP) GenID changes MRIB.next_hop(RP) GenID changes
The Generation ID of the router that is MRIB.next_hop(RP) The Generation ID of the router that is MRIB.next_hop(RP)
changes. This normally means that this neighbor has lost changes. This normally means that this neighbor has lost
state, and so the state must be refreshed. state, and so the state must be refreshed.
The upstream (*,*,RP) state machine remains in Joined state. The upstream (*,*,RP) state machine remains in Joined state.
If the Join Timer is set to expire in more than t_override If the Join Timer is set to expire in more than t_override
seconds, reset it so that it expires after t_override seconds. seconds, reset it so that it expires after t_override seconds.
skipping to change at page 62, line 26 skipping to change at page 63, line 31
for messages on its upstream interface from other routers on that for messages on its upstream interface from other routers on that
subnet, and these may modify its behavior. If it sees a Join(*,G) to subnet, and these may modify its behavior. If it sees a Join(*,G) to
the correct upstream neighbor, it should suppress its own Join(*,G). If the correct upstream neighbor, it should suppress its own Join(*,G). If
it sees a Prune(*,G) to the correct upstream neighbor, it should be it sees a Prune(*,G) to the correct upstream neighbor, it should be
prepared to override that prune by sending a Join(*,G) almost prepared to override that prune by sending a Join(*,G) almost
immediately. Finally, if it sees the Generation ID (see Section 4.3) of immediately. Finally, if it sees the Generation ID (see Section 4.3) of
the correct upstream neighbor change, it knows that the upstream the correct upstream neighbor change, it knows that the upstream
neighbor has lost state, and it should be prepared to refresh the state neighbor has lost state, and it should be prepared to refresh the state
by sending a Join(*,G) almost immediately. by sending a Join(*,G) almost immediately.
In addition if the MRIB changes to indicate that the next hop towards If a (*,G) Assert occurs on the upstream interface, and this changes the
the RP has changed, the router should prune off from the old next hop, this router's idea of the upstream neighbor, it should be prepared to
and join towards the new next hop. ensure that the Assert winner is aware of downstream routers by sending
a Join(*,G) almost immediately.
In addition, if the MRIB changes to indicate that the next hop towards
the RP has changed, and either the upstream interface changes or there
is no Assert winner on the upstream interface, the router should prune
off from the old next hop, and join towards the new next hop.
The upstream (*,G) state-machine only contains two states: The upstream (*,G) state-machine only contains two states:
Not Joined Not Joined
The downstream state-machines indicate that the router does not The downstream state-machines indicate that the router does not
need to join the RP tree for this group. need to join the RP tree for this group.
Joined Joined
The downstream state-machines indicate that the router would like The downstream state-machines indicate that the router should join
to join the RP tree for this group. the RP tree for this group.
In addition, one timer JT(*,G) is kept which is used to trigger the In addition, one timer JT(*,G) is kept which is used to trigger the
sending of a Join(*,G) to the upstream next hop towards the RP, sending of a Join(*,G) to the upstream next hop towards the RP,
RPF'(*,G). RPF'(*,G).
Figure 7: Upstream (*,G) state-machine in tabular form Figure 7: Upstream (*,G) state-machine in tabular form
+--------------------++-------------------------------------------------+ +--------------------++-------------------------------------------------+
| || Event | | || Event |
| Prev State ++------------------------+------------------------+ | Prev State ++------------------------+------------------------+
| || JoinDesired(*,G) | JoinDesired(*,G) | | || JoinDesired(*,G) | JoinDesired(*,G) |
| || ->True | ->False | | || ->True | ->False |
+--------------------++------------------------+------------------------+ +--------------------++------------------------+------------------------+
skipping to change at page 63, line 28 skipping to change at page 65, line 28
| Joined (J) || - | -> NJ state | | Joined (J) || - | -> NJ state |
| || | Send Prune(*,G); | | || | Send Prune(*,G); |
| || | Cancel Join Timer | | || | Cancel Join Timer |
+--------------------++------------------------+------------------------+ +--------------------++------------------------+------------------------+
In addition, we have the following transitions which occur within the In addition, we have the following transitions which occur within the
Joined state: Joined state:
+-----------------------------------------------------------------------+ +-----------------------------------------------------------------------+
| In Joined (J) State | | In Joined (J) State |
+------------+----------------+--------------+------------+-------------+ +-----------------+-----------------+-----------------+-----------------+
|Timer |See |See |RPF'(*,G) | RPF'(*,G) | |Timer Expires | See Join(*,G) | See Prune(*,G) | RPF'(*,G) |
|Expires |Join(*,G) to |Prune(*,G) |changes | changes due | | | to RPF'(*,G) | to RPF'(*,G) | changes due to |
| |RPF'(*,G) |to RPF'(*,G) | | to Assert | | | | | an Assert |
+------------+----------------+--------------+------------+-------------+ +-----------------+-----------------+-----------------+-----------------+
|Send |Increase |Decrease |Decrease | Send | |Send | Increase Join | Decrease Join | Decrease Join |
|Join(*,G); |Join Timer |Join Timer |Join Timer | Join(*,G); | |Join(*,G); Set | Timer to | Timer to | Timer to |
|Set Join |to |to |to | Set Join | |Join Timer to | t_joinsuppress | t_override | t_override |
|Timer to |t_joinsuppress |t_override |t_override | Timer to | |t_periodic | | | |
|t_periodic | | | | t_periodic | +-----------------+-----------------+-----------------+-----------------+
+------------+----------------+--------------+------------+-------------+
+-----------------------------------------------------------------------+ +-----------------------------------------------------------------------+
| In Joined (J) State | | In Joined (J) State |
+----------------------------------+------------------------------------+ +----------------------------------+------------------------------------+
| MRIB.next_hop(RP(G)) | RPF'(*,G) GenID changes | | RPF'(*,G) changes not | RPF'(*,G) GenID changes |
| changes | | | due to an Assert | |
+----------------------------------+------------------------------------+ +----------------------------------+------------------------------------+
| Send Join(*,G) to new | Decrease Join Timer to | | Send Join(*,G) to new | Decrease Join Timer to |
| next hop; Send | t_override | | next hop; Send | t_override |
| Prune(*,G) to old next | | | Prune(*,G) to old next | |
| hop; Set Join Timer to | | | hop; Set Join Timer to | |
| t_periodic | | | t_periodic | |
+----------------------------------+------------------------------------+ +----------------------------------+------------------------------------+
This state machine uses the following macro: This state machine uses the following macro:
skipping to change at page 65, line 36 skipping to change at page 67, line 36
RPF_interface(RP(G)) send a Prune(*,G) to RPF'(*,G). As this RPF_interface(RP(G)) send a Prune(*,G) to RPF'(*,G). As this
router is in Joined state, it must override the Prune after a router is in Joined state, it must override the Prune after a
short random interval. short random interval.
The upstream (*,G) state machine remains in Joined state. If The upstream (*,G) state machine remains in Joined state. If
the Join Timer is set to expire in more than t_override the Join Timer is set to expire in more than t_override
seconds, reset it so that it expires after t_override seconds. seconds, reset it so that it expires after t_override seconds.
If the Join Timer is set to expire in less than t_override If the Join Timer is set to expire in less than t_override
seconds, leave it unchanged. seconds, leave it unchanged.
RPF'(*,G) changes RPF'(*,G) changes due to an Assert
The current next hop towards the RP changes due to an The current next hop towards the RP changes due to an
Assert(*,G) on the RPF_interface(RP(G)). Assert(*,G) on the RPF_interface(RP(G)).
The upstream (*,G) state machine remains in Joined state. If The upstream (*,G) state machine remains in Joined state. If
the Join Timer is set to expire in more than t_override the Join Timer is set to expire in more than t_override
seconds, reset it so that it expires after t_override seconds. seconds, reset it so that it expires after t_override seconds.
If the Join Timer is set to expire in less than t_override If the Join Timer is set to expire in less than t_override
seconds, leave it unchanged. seconds, leave it unchanged.
MRIB.next_hop(RP(G)) changes RPF'(*,G) changes not due to an Assert
An event occurred which caused the next hop towards the RP for An event occurred which caused the next hop towards the RP for
G to change. This may be caused by a change in the MRIB G to change. This may be caused by a change in the MRIB
routing database or by the installation of a different RP-to- routing database. Note that this transition does not occur if
group mapping. Note that this transition should occur even if an Assert is active and the upstream interface does not
RPF'(*,G) is not equal to the new next hop towards RP(G), change.
because it may be that the new neighbor is a better path to
RP(G) than RPF'(*,G); this transition ensures that the better
path is discovered even if an assert occurred previously.
The upstream (*,G) state machine remains in Joined state. The upstream (*,G) state machine remains in Joined state.
Send Prune(*,G) to the old upstream neighbor, which is the old Send Join(*,G) to the new upstream neighbor which is the new
value of RPF'(*,G). Send Join(*,G) to the new upstream value of RPF'(*,G). Send Prune(*,G) to the old upstream
neighbor which is the new value of MRIB.next_hop(RP(G)). Note neighbor, which is the old value of RPF'(*,G). Set the Join
that the Join goes to MRIB.next_hop(RP(G)) and not RPF'(*,G) Timer (JT) to expire after t_periodic seconds.
even if the new neighbor is on the same interface as the old
one because the routing change may cause the assert state to
be incorrect. Set the Join Timer (JT) to expire after
t_periodic seconds.
RPF'(*,G) GenID changes RPF'(*,G) GenID changes
The Generation ID of the router that is RPF'(*,G) changes. The Generation ID of the router that is RPF'(*,G) changes.
This normally means that this neighbor has lost state, and so This normally means that this neighbor has lost state, and so
the state must be refreshed. the state must be refreshed.
The upstream (*,G) state machine remains in Joined state. If The upstream (*,G) state machine remains in Joined state. If
the Join Timer is set to expire in more than t_override the Join Timer is set to expire in more than t_override
seconds, reset it so that it expires after t_override seconds. seconds, reset it so that it expires after t_override seconds.
skipping to change at page 66, line 39 skipping to change at page 68, line 32
The per-interface state-machines for (S,G) hold join state from The per-interface state-machines for (S,G) hold join state from
downstream PIM routers. This state then determines whether a router downstream PIM routers. This state then determines whether a router
needs to propagate a Join(S,G) upstream towards the source. needs to propagate a Join(S,G) upstream towards the source.
If a router wishes to propagate a Join(S,G) upstream, it must also watch If a router wishes to propagate a Join(S,G) upstream, it must also watch
for messages on its upstream interface from other routers on that for messages on its upstream interface from other routers on that
subnet, and these may modify its behavior. If it sees a Join(S,G) to subnet, and these may modify its behavior. If it sees a Join(S,G) to
the correct upstream neighbor, it should suppress its own Join(S,G). If the correct upstream neighbor, it should suppress its own Join(S,G). If
it sees a Prune(S,G), Prune(S,G,rpt), or Prune(*,G) to the correct it sees a Prune(S,G), Prune(S,G,rpt), or Prune(*,G) to the correct
upstream neighbor towards S, it should be prepared to override that upstream neighbor towards S, it should be prepared to override that
prune by scheduling a Join(S,G) to be sent (almost) immediately. prune by scheduling a Join(S,G) to be sent almost immediately. Finally,
Finally, if it sees the Generation ID of its upstream neighbor change, if it sees the Generation ID of its upstream neighbor change, it knows
it knows that the upstream neighbor has lost state, and it should that the upstream neighbor has lost state, and it should refresh the
refresh the state by scheduling a Join(S,G) to be sent (almost) state by scheduling a Join(S,G) to be sent almost immediately.
immediately.
In addition if MRIB changes cause the next hop towards the source to If a (S,G) Assert occurs on the upstream interface, and this changes the
change, the router should send a prune to the old next hop, and a join this router's idea of the upstream neighbor, it should be prepared to
to the new next hop. ensure that the Assert winner is aware of downstream routers by
scheduling a Join(S,G) to be sent almost immediately.
In addition, if MRIB changes cause the next hop towards the source to
change, and either the upstream interface changes or there is no Assert
winner on the upstream interface, the router should send a prune to the
old next hop, and a join to the new next hop.
The upstream (S,G) state-machine only contains two states: The upstream (S,G) state-machine only contains two states:
Not Joined Not Joined
The downstream state machines and local membership information do The downstream state machines and local membership information do
not indicate that the router needs to join the shortest-path tree not indicate that the router needs to join the shortest-path tree
for this (S,G). for this (S,G).
Joined Joined
The downstream state machines and local membership information The downstream state machines and local membership information
indicate that the router should join the shortest-path tree for indicate that the router should join the shortest-path tree for
this (S,G). this (S,G).
In addition, one timer JT(S,G) is kept which is used to trigger the In addition, one timer JT(S,G) is kept which is used to trigger the
sending of a Join(S,G) to the upstream next hop toward S, RPF'(S,G). sending of a Join(S,G) to the upstream next hop towards S, RPF'(S,G).
Figure 8: Upstream (S,G) state-machine in tabular form Figure 8: Upstream (S,G) state-machine in tabular form
+--------------------+--------------------------------------------------+ +--------------------+--------------------------------------------------+
| | Event | | | Event |
| Prev State +-------------------------+------------------------+ | Prev State +-------------------------+------------------------+
| | JoinDesired(S,G) | JoinDesired(S,G) | | | JoinDesired(S,G) | JoinDesired(S,G) |
| | ->True | ->False | | | ->True | ->False |
+--------------------+-------------------------+------------------------+ +--------------------+-------------------------+------------------------+
| NotJoined (NJ) | -> J state | - | | NotJoined (NJ) | -> J state | - |
skipping to change at page 68, line 23 skipping to change at page 70, line 23
| | | | RPF'(S,G) | | | | | RPF'(S,G) |
+-----------------+-----------------+------------------+----------------+ +-----------------+-----------------+------------------+----------------+
| Send | Increase Join | Decrease Join | Decrease Join | | Send | Increase Join | Decrease Join | Decrease Join |
| Join(S,G); Set | Timer to | Timer to | Timer to | | Join(S,G); Set | Timer to | Timer to | Timer to |
| Join Timer to | t_joinsuppress | t_override | t_override | | Join Timer to | t_joinsuppress | t_override | t_override |
| t_periodic | | | | | t_periodic | | | |
+-----------------+-----------------+------------------+----------------+ +-----------------+-----------------+------------------+----------------+
+-----------------------------------------------------------------------+ +-----------------------------------------------------------------------+
| In Joined (J) State | | In Joined (J) State |
+-----------------+-------------------+----------------+----------------+ +-----------------+-----------------+-----------------+-----------------+
|See Prune(*,G) | MRIB.next_hop(S) | RPF'(S,G) | RPF'(S,G) | | See Prune(*,G) | RPF'(S,G) | RPF'(S,G) | RPF'(S,G) |
|to RPF'(S,G) | changes | GenID changes | changes | | to RPF'(S,G) | changes not | GenID changes | changes due to |
+-----------------+-------------------+----------------+----------------+ | | due to an | | an Assert |
| | Assert | | |
+-----------------+-----------------+-----------------+-----------------+
|Decrease Join | Send Join(S,G) | Decrease Join | Decrease Join | |Decrease Join | Send Join(S,G) | Decrease Join | Decrease Join |
|Timer to | to new next hop; | Timer to | Timer to | | Timer to | to new next | Timer to | Timer to |
|t_override | Send Prune(S,G) | t_override | t_override | | t_override | hop; Send | t_override | t_override |
| | to old next hop; | | | | | Prune(S,G) to | | |
| | old next hop; | | |
| | Set Join Timer | | | | | Set Join Timer | | |
| | to t_periodic | | | | | to t_periodic | | |
+-----------------+-------------------+----------------+----------------+ +-----------------+-----------------+-----------------+-----------------+
This state machine uses the following macro: This state machine uses the following macro:
bool JoinDesired(S,G) { bool JoinDesired(S,G) {
return( immediate_olist(S,G) != NULL return( immediate_olist(S,G) != NULL
OR ( KeepaliveTimer(S,G) is running OR ( KeepaliveTimer(S,G) is running
AND inherited_olist(S,G) != NULL ) ) AND inherited_olist(S,G) != NULL ) )
} }
JoinDesired(S,G) is true when the router has forwarding state that would JoinDesired(S,G) is true when the router has forwarding state that would
cause it to forward traffic for G using source tree state. The source cause it to forward traffic for G using source tree state. The source
tree state can either be as a result of active source-specific join tree state can either be as a result of active source-specific join
state, or the (S,G) keepalive timer and active non-source-specific state, or the (S,G) Keepalive Timer and active non-source-specific
state. Note that although JoinDesired is true, the router's sending of a state. Note that although JoinDesired is true, the router's sending of a
Join(S,G) message may be suppressed by another router sending a Join(S,G) message may be suppressed by another router sending a
Join(S,G) onto the upstream interface. Join(S,G) onto the upstream interface.
Transitions from NotJoined State Transitions from NotJoined State
When the upstream (S,G) state-machine is in NotJoined state, the When the upstream (S,G) state-machine is in NotJoined state, the
following event may trigger a state transition: following event may trigger a state transition:
JoinDesired(S,G) becomes True JoinDesired(S,G) becomes True
skipping to change at page 70, line 44 skipping to change at page 72, line 44
medium. This router sees another router on RPF_interface(S) medium. This router sees another router on RPF_interface(S)
send a Prune(*,G) to RPF'(S,G). If the upstream router is an send a Prune(*,G) to RPF'(S,G). If the upstream router is an
RFC 2362 compliant PIM router, then the Prune(*,G) will cause RFC 2362 compliant PIM router, then the Prune(*,G) will cause
it to stop forwarding. For backwards compatibility, this it to stop forwarding. For backwards compatibility, this
router should override the prune so that forwarding continues. router should override the prune so that forwarding continues.
The upstream (S,G) state machine remains in Joined state. If The upstream (S,G) state machine remains in Joined state. If
the Join Timer is set to expire in more than t_override the Join Timer is set to expire in more than t_override
seconds, reset it so that it expires after t_override seconds. seconds, reset it so that it expires after t_override seconds.
RPF'(S,G) changes RPF'(S,G) changes due to an Assert
The current next hop towards S changes due to an Assert(S,G) The current next hop towards S changes due to an Assert(S,G)
on the RPF_interface(S). on the RPF_interface(S).
The upstream (S,G) state machine remains in Joined state. If The upstream (S,G) state machine remains in Joined state. If
the Join Timer is set to expire in more than t_override the Join Timer is set to expire in more than t_override
seconds, reset it so that it expires after t_override seconds. seconds, reset it so that it expires after t_override seconds.
If the Join Timer is set to expire in less than t_override If the Join Timer is set to expire in less than t_override
seconds, leave it unchanged. seconds, leave it unchanged.
MRIB.next_hop(S) changes RPF'(S,G) changes
A change in the routing base stored in the MRIB causes the A change in the routing base stored in the MRIB causes the
next hop towards S to change. next hop towards S to change and there is no (S,G) Assert
active.
The upstream (S,G) state machine remains in Joined state. The upstream (S,G) state machine remains in Joined state.
Send Prune(S,G) to the old upstream neighbor, which is the old Send Join(S,G) to the new upstream neighbor which is the new
value of RPF'(S,G). Send Join(S,G) to the new upstream value of RPF'(S,G). Send Prune(S,G) to the old upstream
neighbor which is the new value of MRIB.next_hop(S). Note neighbor, which is the old value of RPF'(S,G). Set the Join
that the Join goes to MRIB.next_hop(S) and not RPF'(S,G) even Timer (JT) to expire after t_periodic seconds.
if the new neighbor is on the same interface as the old one
because the routing change may cause MRIB.next_hop(S) to have
a better path to S than RPF'(S,G); sending to MRIB.next_hop(S)
ensures that this is discovered. Set the Join Timer (JT) to
expire after t_periodic seconds.
RPF'(S,G) GenID changes RPF'(S,G) GenID changes
The Generation ID of the router that is RPF'(S,G) changes. The Generation ID of the router that is RPF'(S,G) changes.
This normally means that this neighbor has lost state, and so This normally means that this neighbor has lost state, and so
the state must be refreshed. the state must be refreshed.
The upstream (S,G) state machine remains in Joined state. If The upstream (S,G) state machine remains in Joined state. If
the Join Timer is set to expire in more than t_override the Join Timer is set to expire in more than t_override
seconds, reset it so that it expires after t_override seconds. seconds, reset it so that it expires after t_override seconds.
skipping to change at page 72, line 7 skipping to change at page 74, line 7
describes the rules for sending triggered messages. This section describes the rules for sending triggered messages. This section
describes the rules for including an Prune(S,G,rpt) message with a describes the rules for including an Prune(S,G,rpt) message with a
Join(*,G). Join(*,G).
When a router is going to send a Join(*,G), it should use the following When a router is going to send a Join(*,G), it should use the following
pseudocode, for each (S,G) for which it has state, to decide whether to pseudocode, for each (S,G) for which it has state, to decide whether to
include a Prune(S,G,rpt) in the compound Join/Prune message: include a Prune(S,G,rpt) in the compound Join/Prune message:
if( SPTbit(S,G) == TRUE ) { if( SPTbit(S,G) == TRUE ) {
# Note: If receiving (S,G) on the SPT, we only prune off the # Note: If receiving (S,G) on the SPT, we only prune off the
# shared tree if the rpf neighbors differ. # shared tree if the RPF neighbors differ.
if( RPF'(*,G) != RPF'(S,G) ) { if( RPF'(*,G) != RPF'(S,G) ) {
add Prune(S,G,rpt) to compound message add Prune(S,G,rpt) to compound message
} }
} else if ( inherited_olist(S,G,rpt) == NULL ) { } else if ( inherited_olist(S,G,rpt) == NULL ) {
# Note: all (*,G) olist interfaces sent rpt prunes for (S,G). # Note: all (*,G) olist interfaces received RPT prunes for (S,G).
add Prune(S,G,rpt) to compound message add Prune(S,G,rpt) to compound message
} else if ( RPF'(*,G) != RPF'(S,G,rpt) { } else if ( RPF'(*,G) != RPF'(S,G,rpt) {
# Note: we joined the shared tree, but there was an (S,G) assert and # Note: we joined the shared tree, but there was an (S,G) assert and
# the source tree RPF neighbor is different. # the source tree RPF neighbor is different.
add Prune(S,G,rpt) to compound message add Prune(S,G,rpt) to compound message
} }
Note that Join(S,G,rpt) is not normally sent as a periodic message, but Note that Join(S,G,rpt) is not normally sent as a periodic message, but
only as a triggered message. only as a triggered message.
skipping to change at page 72, line 43 skipping to change at page 74, line 43
Pruned(S,G,rpt) Pruned(S,G,rpt)
(*,G) or (*,*,RP(G)) Joined, but (S,G,rpt) pruned (*,G) or (*,*,RP(G)) Joined, but (S,G,rpt) pruned
NotPruned(S,G,rpt) NotPruned(S,G,rpt)
(*,G) or (*,*,RP(G)) Joined, and (S,G,rpt) not pruned (*,G) or (*,*,RP(G)) Joined, and (S,G,rpt) not pruned
RPTNotJoined(G) RPTNotJoined(G)
neither (*,G) nor (*,*,RP(G)) has not been joined. neither (*,G) nor (*,*,RP(G)) has not been joined.
In addition there is an (S,G,rpt) Override Timer, OT(S,G,rpt), which is In addition, there is an (S,G,rpt) Override Timer, OT(S,G,rpt), which is
used to delay triggered Join(S,G,rpt) messages to prevent implosions of used to delay triggered Join(S,G,rpt) messages to prevent implosions of
triggered messages. triggered messages.
Figure 9: Upstream (S,G,rpt) state-machine for triggered messages in Figure 9: Upstream (S,G,rpt) state-machine for triggered messages in
tabular form tabular form
+--------------++------------------------------------------------------------------+ +---------------+-------------------------------------------------------------+
| || Event | | | Event |
| ++-------------+--------------+-------------------+-----------------+ | +----------------+----------------+-------------+-------------+
|Prev State ||PruneDesired | PruneDesired | RPTJoinDesired(G) | inherited_olist | |Prev State | PruneDesired- | PruneDesired- |RPTJoin- | inherited_- |
| ||(S,G,rpt) | (S,G,rpt) | ->False | (S,G,rpt) | | | (S,G,rpt) | (S,G,rpt) |Desired(G) | olist- |
| ||->True | ->False | | ->non-NULL | | | ->True | ->False |->False | (S,G,rpt) |
+--------------++-------------+--------------+-------------------+-----------------+ | | | | | ->non-NULL |
|RPTNotJoined ||-> P state | - | - | -> NP state | +---------------+----------------+----------------+-------------+-------------+
|(G) (NJ) || | | | | |RPTNotJoined | -> P state | - |- | -> NP state |
+--------------++-------------+--------------+-------------------+-----------------+ |(G) (NJ) | | | | |
|Pruned ||- | -> NP state | -> NJ state | - | +---------------+----------------+----------------+-------------+-------------+
|(S,G,rpt) (P) || | Send Join | | | |Pruned | - | -> NP state |-> NJ state | - |
| || | (S,G,rpt) | | | |(S,G,rpt) (P) | | Send Join | | |
+--------------++-------------+--------------+-------------------+-----------------+ | | | (S,G,rpt) | | |
| ||-> P state | - | -> NJ state | - | +---------------+----------------+----------------+-------------+-------------+
|NotPruned ||Send Prune | | Cancel OT timer | | |NotPruned | -> P state | - |-> NJ state | - |
|(S,G,rpt) ||(S,G,rpt); | | | | |(S,G,rpt) | Send Prune | |Cancel OT | |
|(NP) ||Cancel OT | | | | |(NP) | (S,G,rpt); | | | |
| ||timer | | | | | | Cancel OT | | | |
+--------------++-------------+--------------+-------------------+-----------------+ +---------------+----------------+----------------+-------------+-------------+
Additionally, we have the following transitions within the Additionally, we have the following transitions within the
NotPruned(S,G,rpt) state which are all used for prune override behavior. NotPruned(S,G,rpt) state which are all used for prune override behavior.
+-----------------------------------------------------------------------+ +-----------------------------------------------------------------------+
| In NotPruned(S,G,rpt) State | | In NotPruned(S,G,rpt) State |
+------------+--------------+--------------+-------------+--------------+ +-----------+--------------+--------------+--------------+--------------+
|OT timer |See Prune |See Join |See Prune | RPF' | |Override | See Prune | See Join | See Prune | RPF' |
|expires |(S,G,rpt) to |(S,G,rpt) to |(S,G) to | (S,G,rpt) -> | |Timer | (S,G,rpt) to | (S,G,rpt) to | (S,G) to | (S,G,rpt) -> |
| |RPF' |RPF' |RPF' | RPF' (*,G) | |expires | RPF' | RPF' | RPF' | RPF' (*,G) |
| |(S,G,rpt) |(S,G,rpt) |(S,G,rpt) | | | |(S,G,rpt) |(S,G,rpt) |(S,G,rpt) | |
+------------+--------------+--------------+-------------+--------------+ +-----------+--------------+--------------+--------------+--------------+
|Send Join |OT timer = |Cancel OT |OT timer = | OT timer = | |Send Join | OT = min(OT, | Cancel OT | OT = min(OT, | OT = min(OT, |
|(S,G,rpt); |min(timer, |timer |min(timer, | min(timer, | |(S,G,rpt); | t_override) | | t_override) | t_override) |
|Cancel OT |t_override) | |t_override) | t_override) | |Cancel OT | | | | |
|timer | | | | | +-----------+--------------+--------------+--------------+--------------+
+------------+--------------+--------------+-------------+--------------+
Note that the min function in the above state machine considers a non- Note that the min function in the above state machine considers a non-
running timer to have an infinite value (e.g. min(not-running, running timer to have an infinite value (e.g. min(not-running,
t_override) = t_override). t_override) = t_override).
This state machine uses the following macros: This state machine uses the following macros:
bool RPTJoinDesired(G) { bool RPTJoinDesired(G) {
return (JoinDesired(*,G) || JoinDesired(*,*,RP(G))) return (JoinDesired(*,G) || JoinDesired(*,*,RP(G)))
} }
skipping to change at page 77, line 5 skipping to change at page 78, line 48
machine for (*,G) or (*,*,RP). machine for (*,G) or (*,*,RP).
inherited_olist(S,G,rpt) becomes non-NULL inherited_olist(S,G,rpt) becomes non-NULL
This transition is only relevant in the RPTNotJoined(G) state. This transition is only relevant in the RPTNotJoined(G) state.
The router has joined the RP tree (handled by the (*,G) or (*,*,RP) The router has joined the RP tree (handled by the (*,G) or (*,*,RP)
upstream state machine as appropriate), and wants to receive upstream state machine as appropriate), and wants to receive
traffic from S. This does not trigger any events in this state traffic from S. This does not trigger any events in this state
machine, but causes a transition to the NotPruned(S,G,rpt) state. machine, but causes a transition to the NotPruned(S,G,rpt) state.
4.5.10. Background: (*,*,RP) and (S,G,rpt) interaction
In sections 4.5.8 and 4.5.9 the mechanisms for sending periodic and
triggered (S,G,rpt) messages are described. The astute reader will note
that periodic Prune(S,G,rpt) messages are only sent in PIM Join/Prune
messages containing a Join(*,G), whereas it is possible for a triggered
Prune(S,G,rpt) message to be sent when the router has no (*,G) join
state. This may seem like a contradiction, but in fact it is
intentional, and is a side effect of not optimizing (*,*,RP) behavior.
We first note that reception of a Join(*,*,RP) by itself does not cancel
(S,G,rpt) prune state on that interface, whereas receiving a Join(*,G)
by itself does cancel (S,G,rpt) prune state on that interface.
Similarly, reception of a Prune(*,G) on an interface with (*,*,RP) join
state does not by itself prevent forwarding of G using the (*,*,RP)
state - this is because a Prune(*,G) only serves to cancel (*,G) join
state. Conceptually (*,*,RP) state functions "above" the normal (*,G)
and (S,G) mechanisms, and so neither Join(*,*,RP) or Prune(*,*,RP)
messages affect any other state.
The upshot of this is that to prevent forwarding (S,G) on (*,*,RP)
state, a Prune(S,G,rpt) must be used.
We also note that for historical reasons there is no Assert(*,*,RP)
message, so any forwarding contention is resolved using Assert(*,G)
messages.
We now need to consider the interaction between (*,*,RP) state and (*,G)
state. If there is a need for an assert between two upstream routers on
a LAN, we need to ensure that the correct thing happens for all
combinations of (*,*,RP) and (*,G) forwarding state. As there is no
Assert(*,*,RP) message, no router can tell whether the assert winner has
(*,*,RP) state or (*,G) state. Thus a downstream router has to treat
the two the same and send its periodic Prune(S,G,rpt) messages to
RPF'(*,G).
To avoid needing to specify all the complex override rules between
(*,*,RP), (*,G) and (S,G,rpt), we simply require that to prune (S,G) off
the (*,*,RP) tree, a Join(*,G) must also be sent.
If a router is receiving on (*,*,RP) state, and has not yet had (*,G)
state instantiated, it may still need to send a triggered Join(S,G,rpt)
to override a Prune(S,G,rpt) that it sees directed to RPF'(*,G) on its
upstream interface. Hence triggered (S,G,rpt) messages may be sent when
JoinDesired(*,G) is false but JoinDesired(*,*,RP) is true.
Finally we note that there is an unoptimized case when the upstream
router on a LAN already has (*,G) join and (S,G,rpt) prune state caused
by an existing downstream router. If at this time a new Join(*,*,RP) is
sent to the upstream router from a different downstream router, this
will not override the (S,G,rpt) prune state at the upstream router. The
override will not occur until the next time the original downstream
router resends its Prune(S,G,rpt). This case was considered to be not
worth optimizing, as (*,*,RP) state is generally very long lived, and so
any minor delays in getting traffic to a new PMBR seem unimportant.
4.6. PIM Assert Messages 4.6. PIM Assert Messages
Where multiple PIM routers peer over a shared LAN it is possible for Where multiple PIM routers peer over a shared LAN it is possible for
more than one upstream router to have valid forwarding state for a more than one upstream router to have valid forwarding state for a
packet, which can lead to packet duplication (see Section 3 "Multi- packet, which can lead to packet duplication (see Section 3 "Multi-
access LANs"). PIM does not attempt to prevent this from occurring. access LANs"). PIM does not attempt to prevent this from occurring.
Instead it detects when this has happened and elects a single forwarder Instead it detects when this has happened and elects a single forwarder
amongst the upstream routers to prevent further duplication. This amongst the upstream routers to prevent further duplication. This
election is performed using PIM Assert messages. Assert messages are election is performed using PIM Assert messages. Assert messages are
also received by downstream routers on the LAN, and these cause also received by downstream routers on the LAN, and these cause
subsequent Join/Prune messages to be sent to the upstream router that subsequent Join/Prune messages to be sent to the upstream router that
won the Assert. won the Assert.
In general, a PIM Assert message should only be accepted for processing In general, a PIM Assert message should only be accepted for processing
if it comes from a known PIM neighbor. A PIM router hears about PIM if it comes from a known PIM neighbor. A PIM router hears about PIM
neighbors through PIM Hello messages. If a router receives an Assert neighbors through PIM Hello messages. If a router receives an Assert
message from a particular IP source address and it has not seen a PIM message from a particular IP source address and it has not seen a PIM
Hello message from that source address, then the Assert message SHOULD Hello message from that source address, then the Assert message SHOULD
be discarded without further processing. In addition, if the Hello be discarded without further processing. In addition, if the Hello
message from a neighbor was authenticated using IPsec AH (see section message from a neighbor was authenticated using IPsec AH (see Section
6.3) then all Assert messages from that neighbor MUST also be 6.3) then all Assert messages from that neighbor MUST also be
authenticated using IPsec AH. authenticated using IPsec AH.
4.6.1. (S,G) Assert Message State Machine 4.6.1. (S,G) Assert Message State Machine
The (S,G) Assert state machine for interface I is shown in Figure 10. The (S,G) Assert state machine for interface I is shown in Figure 10.
There are three states: There are three states:
NoInfo (NI) NoInfo (NI)
This router has no (S,G) assert state on interface I. This router has no (S,G) assert state on interface I.
skipping to change at page 77, line 51 skipping to change at page 81, line 6
traffic onto I on behalf of local hosts on I that have made traffic onto I on behalf of local hosts on I that have made
membership requests that specifically refer to S (and G). membership requests that specifically refer to S (and G).
I am Assert Loser (L) I am Assert Loser (L)
This router has lost an (S,G) assert on interface I. It must not This router has lost an (S,G) assert on interface I. It must not
forward packets from S destined for G onto interface I. If it is forward packets from S destined for G onto interface I. If it is
the DR on I, it is no longer responsible for forwarding traffic the DR on I, it is no longer responsible for forwarding traffic
onto I to satisfy local hosts with membership requests that onto I to satisfy local hosts with membership requests that
specifically refer to S and G. specifically refer to S and G.
In addition there is also a assert timer (AT) that is used to time out In addition, there is also an Assert Timer (AT) that is used to time out
asserts on the assert losers and to resend asserts on the assert winner. asserts on the assert losers and to resend asserts on the assert winner.
Figure 10: Per-interface (S,G) Assert State-machine in tabular form Figure 10: Per-interface (S,G) Assert State-machine in tabular form
+-----------------------------------------------------------------------+ +-----------------------------------------------------------------------+
| In NoInfo (NI) State | | In NoInfo (NI) State |
+---------------+-------------------+------------------+----------------+ +---------------+-------------------+------------------+----------------+
| Receive | Receive Assert | Data arrives | Receive | | Receive | Receive Assert | Data arrives | Receive |
| Inferior | with RPTbit | from S to G on | Preferred | | Inferior | with RPTbit | from S to G on | Preferred |
| Assert with | set and | I and | Assert with | | Assert with | set and | I and | Assert with |
skipping to change at page 78, line 24 skipping to change at page 81, line 28
| and | (S,G,I) | (S,G,I) | and AssTrDes | | and | (S,G,I) | (S,G,I) | and AssTrDes |
| CouldAssert | | | (S,G,I) | | CouldAssert | | | (S,G,I) |
| (S,G,I) | | | | | (S,G,I) | | | |
+---------------+-------------------+------------------+----------------+ +---------------+-------------------+------------------+----------------+
| -> W state | -> W state | -> W state | -> L state | | -> W state | -> W state | -> W state | -> L state |
| [Actions A1] | [Actions A1] | [Actions A1] | [Actions A6] | | [Actions A1] | [Actions A1] | [Actions A1] | [Actions A6] |
+---------------+-------------------+------------------+----------------+ +---------------+-------------------+------------------+----------------+
+-----------------------------------------------------------------------+ +-----------------------------------------------------------------------+
| In I Am Assert Winner (W) State | | In I Am Assert Winner (W) State |
+-----------------+-----------------+------------------+----------------+ +----------------+------------------+-----------------+-----------------+
| Timer Expires | Receive | Receive | CouldAssert | | Assert Timer | Receive | Receive | CouldAssert |
| | Inferior | Preferred | (S,G,I) -> | | Expires | Inferior | Preferred | (S,G,I) -> |
| | Assert | Assert | FALSE | | | Assert | Assert | FALSE |
+-----------------+-----------------+------------------+----------------+ +----------------+------------------+-----------------+-----------------+
| -> W state | -> W state | -> L state | -> NI state | | -> W state | -> W state | -> L state | -> NI state |
| [Actions A3] | [Actions A3] | [Actions A2] | [Actions A4] | | [Actions A3] | [Actions A3] | [Actions A2] | [Actions A4] |
+-----------------+-----------------+------------------+----------------+ +----------------+------------------+-----------------+-----------------+
+-------------------------------------------------------------------------+ +-------------------------------------------------------------------------+
| In I Am Assert Loser (L) State | | In I Am Assert Loser (L) State |
+-------------+--------------+--------------+--------------+--------------+ +-------------+--------------+--------------+--------------+--------------+
|Receive | Receive | Receive | Timer | Current | |Receive | Receive | Receive | Assert Timer | Current |
|Preferred | Acceptable | Inferior | Expires | Winner's | |Preferred | Acceptable | Inferior | Expires | Winner's |
|Assert | Assert from | Assert from | | GenID | |Assert | Assert from | Assert from | | GenID |
| | Current | Current | | changes | | | Current | Current | | changes |
| | Winner | Winner | | | | | Winner | Winner | | |
+-------------+--------------+--------------+--------------+--------------+ +-------------+--------------+--------------+--------------+--------------+
|-> L state | -> L state | -> NI state | -> NI state | -> NI state | |-> L state | -> L state | -> NI state | -> NI state | -> NI state |
|[Actions A2] | [Actions A2] | [Actions A5] | [Actions A5] | [Actions A5] | |[Actions A2] | [Actions A2] | [Actions A5] | [Actions A5] | [Actions A5] |
+-------------+--------------+--------------+--------------+--------------+ +-------------+--------------+--------------+--------------+--------------+
+-----------------------------------------------------------------------+ +-----------------------------------------------------------------------+
skipping to change at page 80, line 11 skipping to change at page 83, line 11
CouldAssert(S,G,I) is true for downstream interfaces which would be in CouldAssert(S,G,I) is true for downstream interfaces which would be in
the inherited_olist(S,G) if (S,G) assert information was not taken into the inherited_olist(S,G) if (S,G) assert information was not taken into
account. account.
AssertTrackingDesired(S,G,I) = AssertTrackingDesired(S,G,I) =
(I in ( ( joins(*,*,RP(G)) (+) joins(*,G) (-) prunes(S,G,rpt) ) (I in ( ( joins(*,*,RP(G)) (+) joins(*,G) (-) prunes(S,G,rpt) )
(+) ( pim_include(*,G) (-) pim_exclude(S,G) ) (+) ( pim_include(*,G) (-) pim_exclude(S,G) )
(-) lost_assert(*,G) (-) lost_assert(*,G)
(+) joins(S,G) ) ) (+) joins(S,G) ) )
OR (local_receiver_include(S,G,I)==TRUE OR (local_receiver_include(S,G,I)==TRUE
AND (I_am_DR(I) OR AssertWinner(S,G,I) == me)) AND (I_am_DR(I) OR (AssertWinner(S,G,I) == me)))
OR (RPF_interface(S)==I AND JoinDesired(S,G)==TRUE) OR ((RPF_interface(S) == I) AND (JoinDesired(S,G) == TRUE))
OR (RPF_interface(RP)==I AND JoinDesired(*,G)==TRUE OR ((RPF_interface(RP(G)) == I) AND (JoinDesired(*,G) == TRUE)
AND SPTbit(S,G)==FALSE) AND (SPTbit(S,G) == FALSE))
AssertTrackingDesired(S,G,I) is true on any interface in which an (S,G) AssertTrackingDesired(S,G,I) is true on any interface in which an (S,G)
assert might affect our behavior. assert might affect our behavior.
The first three lines of AssertTrackingDesired account for (*,G) join The first three lines of AssertTrackingDesired account for (*,G) join
and local membership information received on I that might cause the and local membership information received on I that might cause the
router to be interested in asserts on I. router to be interested in asserts on I.
The 4th line accounts for (S,G) join information received on I that The 4th line accounts for (S,G) join information received on I that
might cause the router to be interested in asserts on I. might cause the router to be interested in asserts on I.
skipping to change at page 81, line 38 skipping to change at page 84, line 38
and we have (S,G) forwarding state. The received assert that and we have (S,G) forwarding state. The received assert that
has a better metric than our own, so we do not win the Assert. has a better metric than our own, so we do not win the Assert.
We transition to "I am Assert Loser" and perform actions A6 We transition to "I am Assert Loser" and perform actions A6
(below). (below).
Transitions from "I am Assert Winner" State Transitions from "I am Assert Winner" State
When in "I am Assert Winner" state, the following events trigger When in "I am Assert Winner" state, the following events trigger
transitions: transitions:
Timer Expires Assert Timer Expires
The (S,G) assert timer expires. As we're in the Winner state, The (S,G) Assert Timer expires. As we're in the Winner state,
then we must still have (S,G) forwarding state that is then we must still have (S,G) forwarding state that is
actively being kept alive. We re-send the (S,G) Assert and actively being kept alive. We re-send the (S,G) Assert and
restart the timer (Action A3 below). Note that the assert restart the Assert Timer (Action A3 below). Note that the
winner's timer is engineered to expire shortly before timers assert winner's Assert Timer is engineered to expire shortly
on assert losers; this prevents unnecessary thrashing of the before timers on assert losers; this prevents unnecessary
forwarder and periodic flooding of duplicate packets. thrashing of the forwarder and periodic flooding of duplicate
packets.
Receive Inferior Assert Receive Inferior Assert
We receive an (S,G) assert or (*,G) assert mentioning S that We receive an (S,G) assert or (*,G) assert mentioning S that
has a worse metric than our own. Whoever sent the assert is has a worse metric than our own. Whoever sent the assert is
in error, and so we re-send an (S,G) Assert, and restart the in error, and so we re-send an (S,G) Assert, and restart the
timer (Action A3 below). Assert Timer (Action A3 below).
Receive Preferred Assert Receive Preferred Assert
We receive an (S,G) assert that has a better metric than our We receive an (S,G) assert that has a better metric than our
own. We transition to "I am Assert Loser" state and perform own. We transition to "I am Assert Loser" state and perform
actions A2 (below). Note that this may affect the value of actions A2 (below). Note that this may affect the value of
JoinDesired(S,G) and PruneDesired(S,G,rpt) which could cause JoinDesired(S,G) and PruneDesired(S,G,rpt) which could cause
transitions in the upstream (S,G) or (S,G,rpt) state machines. transitions in the upstream (S,G) or (S,G,rpt) state machines.
CouldAssert(S,G,I) -> FALSE CouldAssert(S,G,I) -> FALSE
Our (S,G) forwarding state or RPF interface changed so as to Our (S,G) forwarding state or RPF interface changed so as to
skipping to change at page 82, line 43 skipping to change at page 85, line 44
Receive Inferior Assert from Current Winner Receive Inferior Assert from Current Winner
We receive an assert from the current assert winner that is We receive an assert from the current assert winner that is
worse than our own metric for this group (typically the worse than our own metric for this group (typically the
winner's metric became worse). We transition to NoInfo state, winner's metric became worse). We transition to NoInfo state,
deleting the (S,G) assert information and allowing the normal deleting the (S,G) assert information and allowing the normal
PIM Join/Prune mechanisms to operate. Usually we will PIM Join/Prune mechanisms to operate. Usually we will
eventually re-assert and win when data packets from S have eventually re-assert and win when data packets from S have
started flowing again. started flowing again.
Timer Expires Assert Timer Expires
The (S,G) assert timer expires. We transition to NoInfo The (S,G) Assert Timer expires. We transition to NoInfo
state, deleting the (S,G) assert information (action A5 state, deleting the (S,G) assert information (action A5
below). below).
Current Winner's GenID Changes Current Winner's GenID Changes
We receive a Hello message from the current winner reporting a We receive a Hello message from the current winner reporting a
different GenID from the one it previously reported. This different GenID from the one it previously reported. This
indicates that the current winner's interface or router has indicates that the current winner's interface or router has
gone down and come back up, and so we must assume it no longer gone down and come back up, and so we must assume it no longer
knows it was the winner. We transition to the NoInfo state, knows it was the winner. We transition to the NoInfo state,
deleting this (S,G) assert information (action A5 below). deleting this (S,G) assert information (action A5 below).
skipping to change at page 83, line 24 skipping to change at page 86, line 26
my_assert_metric(S,G,I) has changed so that now my assert my_assert_metric(S,G,I) has changed so that now my assert
metric for (S,G) is better than the metric we have stored for metric for (S,G) is better than the metric we have stored for
current assert winner. This might happen the underlying current assert winner. This might happen the underlying
routing metric changes, or when CouldAssert(S,G,I) becomes routing metric changes, or when CouldAssert(S,G,I) becomes
true; for example, when SPTbit(S,G) becomes true. We true; for example, when SPTbit(S,G) becomes true. We
transition to NoInfo state, delete this (S,G) assert state transition to NoInfo state, delete this (S,G) assert state
(action A5 below), and allow the normal PIM Join/Prune (action A5 below), and allow the normal PIM Join/Prune
mechanisms to operate. Usually we will eventually re-assert mechanisms to operate. Usually we will eventually re-assert
and win when data packets from S have started flowing again. and win when data packets from S have started flowing again.
RPF interface changed away from interface I RPF_interface(S) stops being interface I
Interface I used to be the RPF interface for S, and now it is Interface I used to be the RPF interface for S, and now it is
not. We transition to NoInfo state, deleting this (S,G) not. We transition to NoInfo state, deleting this (S,G)
assert state (action A5 below). assert state (action A5 below).
Receive Join(S,G) on Interface I Receive Join(S,G) on Interface I
We receive a Join(S,G) that has the Upstream Neighbor Address We receive a Join(S,G) that has the Upstream Neighbor Address
field set to one my IP address on interface I. The action is field set to one my IP address on interface I. The action is
to transition to NoInfo state, and delete this (S,G) assert to transition to NoInfo state, and delete this (S,G) assert
state (action A5 below), and allow the normal PIM Join/Prune state (action A5 below), and allow the normal PIM Join/Prune
mechanisms to operate. If whoever sent the Join was in error, mechanisms to operate. If whoever sent the Join was in error,
then the normal assert mechanism will eventually re-apply and then the normal assert mechanism will eventually re-apply and
we will lose the assert again. However whoever sent the we will lose the assert again. However whoever sent the
assert may know that the previous assert winner has died, and assert may know that the previous assert winner has died, and
so we may end up being the new forwarder. so we may end up being the new forwarder.
(S,G) Assert State-machine Actions (S,G) Assert State-machine Actions
A1: Send Assert(S,G) A1: Send Assert(S,G)
Set timer to (Assert_Time - Assert_Override_Interval) Set Assert Timer to (Assert_Time - Assert_Override_Interval)
Store self as AssertWinner(S,G,I) Store self as AssertWinner(S,G,I)
Store spt_assert_metric(S,I) as AssertWinnerMetric(S,G,I) Store spt_assert_metric(S,I) as AssertWinnerMetric(S,G,I)
A2: Store new assert winner as AssertWinner(S,G,I) and assert A2: Store new assert winner as AssertWinner(S,G,I) and assert
winner metric as AssertWinnerMetric(S,G,I). winner metric as AssertWinnerMetric(S,G,I).
Set timer to Assert_Time Set Assert Timer to Assert_Time
A3: Send Assert(S,G) A3: Send Assert(S,G)
Set timer to (Assert_Time - Assert_Override_Interval) Set Assert Timer to (Assert_Time - Assert_Override_Interval)
A4: Send AssertCancel(S,G) A4: Send AssertCancel(S,G)
Delete assert info (AssertWinner(S,G,I) and Delete assert info (AssertWinner(S,G,I) and
AssertWinnerMetric(S,G,I) will then return their default AssertWinnerMetric(S,G,I) will then return their default
values). values).
A5: Delete assert info (AssertWinner(S,G,I) and A5: Delete assert info (AssertWinner(S,G,I) and
AssertWinnerMetric(S,G,I) will then return their default AssertWinnerMetric(S,G,I) will then return their default
values). values).
A6: Store new assert winner as AssertWinner(S,G,I) and assert A6: Store new assert winner as AssertWinner(S,G,I) and assert
winner metric as AssertWinnerMetric(S,G,I). winner metric as AssertWinnerMetric(S,G,I).
Set timer to Assert_Time Set Assert Timer to Assert_Time
If I is RPF_interface(S) set SPTbit(S,G) to TRUE. If I is RPF_interface(S) set SPTbit(S,G) to TRUE.
Note that some of these actions may cause the value of JoinDesired(S,G), Note that some of these actions may cause the value of JoinDesired(S,G),
PruneDesired(S,G,rpt), or RPF'(S,G) to change, which could cause further PruneDesired(S,G,rpt), or RPF'(S,G) to change, which could cause further
transitions in other state machines. transitions in other state machines.
4.6.2. (*,G) Assert Message State Machine 4.6.2. (*,G) Assert Message State Machine
The (*,G) Assert state-machine for interface I is shown in Figure 11. The (*,G) Assert state-machine for interface I is shown in Figure 11.
There are three states: There are three states:
skipping to change at page 84, line 48 skipping to change at page 87, line 48
also responsible for handling the membership requests for G from also responsible for handling the membership requests for G from
local hosts on I. local hosts on I.
I am Assert Loser (L) I am Assert Loser (L)
This router has lost an (*,G) assert on interface I. It must not This router has lost an (*,G) assert on interface I. It must not
forward packets for G onto interface I with the exception of forward packets for G onto interface I with the exception of
traffic from sources for which is has (S,G) "I am Assert Winner" traffic from sources for which is has (S,G) "I am Assert Winner"
state. If it is the DR, it is no longer responsible for handling state. If it is the DR, it is no longer responsible for handling
the membership requests for group G from local hosts on I. the membership requests for group G from local hosts on I.
In addition there is also an assert timer (AT) that is used to time out In addition, there is also an Assert Timer (AT) that is used to time out
asserts on the assert losers and to resend asserts on the assert winner. asserts on the assert losers and to resend asserts on the assert winner.
When an Assert message is received, a PIM implementation must first When an Assert message is received, a PIM implementation must first
match it against the possible events in the (S,G) assert state machine match it against the possible events in the (S,G) assert state machine
and process any transitions and actions, before considering whether the and process any transitions and actions, before considering whether the
Assert message matches against the (*,G) assert state machine. Assert message matches against the (*,G) assert state machine.
It is important to note that NO TRANSITION CAN OCCUR in the (*,G) state It is important to note that NO TRANSITION CAN OCCUR in the (*,G) state
machine as a result of receiving an Assert message unless the (S,G) machine as a result of receiving an Assert message unless the (S,G)
assert state machine for the relevant S and G is in the "NoInfo" state assert state machine for the relevant S and G is in the "NoInfo" state
skipping to change at page 86, line 5 skipping to change at page 89, line 5
the assert would not be processed by the (*,G) assert state machine. the assert would not be processed by the (*,G) assert state machine.
Another example: if the (S,G) assert state machine is in "L" state when Another example: if the (S,G) assert state machine is in "L" state when
an assert message is received, and the assert metric in the message is an assert message is received, and the assert metric in the message is
worse than my_assert_metric(S,G,I), then the (S,G) assert state machine worse than my_assert_metric(S,G,I), then the (S,G) assert state machine
will transition to NoInfo state. In such a case if the (*,G) assert will transition to NoInfo state. In such a case if the (*,G) assert
state machine were in NoInfo state, it might appear that it would state machine were in NoInfo state, it might appear that it would
transition to "W" state, but this is not the case because this message transition to "W" state, but this is not the case because this message
already triggered a transition in the (S,G) assert state machine. already triggered a transition in the (S,G) assert state machine.
Figure 11: (*,G) Assert State-machine in tabular form Figure 11: Per-interface (*,G) Assert State-machine in tabular form
+-----------------------------------------------------------------------+ +-----------------------------------------------------------------------+
| In NoInfo (NI) State | | In NoInfo (NI) State |
+-----------------------+-----------------------+-----------------------+ +-----------------------+-----------------------+-----------------------+
| Receive Inferior | Data arrives for G | Receive Preferred | | Receive Inferior | Data arrives for G | Receive Preferred |
| Assert with RPTbit | and CouldAssert | Assert with RPTbit | | Assert with RPTbit | on I and | Assert with RPTbit |
| set and | (*,G,I) | set and AssTrDes | | set and | CouldAssert | set and AssTrDes |
| CouldAssert(*,G,I) | | (*,G,I) | | CouldAssert(*,G,I) | (*,G,I) | (*,G,I) |
+-----------------------+-----------------------+-----------------------+ +-----------------------+-----------------------+-----------------------+
| -> W state | -> W state | -> L state | | -> W state | -> W state | -> L state |
| [Actions A1] | [Actions A1] | [Actions A2] | | [Actions A1] | [Actions A1] | [Actions A2] |
+-----------------------+-----------------------+-----------------------+ +-----------------------+-----------------------+-----------------------+
+-----------------------------------------------------------------------+ +-----------------------------------------------------------------------+
| In I Am Assert Winner (W) State | | In I Am Assert Winner (W) State |
+-----------------+-----------------+------------------+----------------+ +----------------+------------------+-----------------+-----------------+
| Timer Expires | Receive | Receive | CouldAssert | | Assert Timer | Receive | Receive | CouldAssert |
| | Inferior | Preferred | (*,G,I) -> | | Expires | Inferior | Preferred | (*,G,I) -> |
| | Assert | Assert | FALSE | | | Assert | Assert | FALSE |
+-----------------+-----------------+------------------+----------------+ +----------------+------------------+-----------------+-----------------+
| -> W state | -> W state | -> L state | -> NI state | | -> W state | -> W state | -> L state | -> NI state |
| [Actions A3] | [Actions A3] | [Actions A2] | [Actions A4] | | [Actions A3] | [Actions A3] | [Actions A2] | [Actions A4] |
+-----------------+-----------------+------------------+----------------+ +----------------+------------------+-----------------+-----------------+
+-------------------------------------------------------------------------+ +-------------------------------------------------------------------------+
| In I Am Assert Loser (L) State | | In I Am Assert Loser (L) State |
+-------------+--------------+--------------+--------------+--------------+ +-------------+--------------+--------------+--------------+--------------+
|Receive | Receive | Receive | Timer | Current | |Receive | Receive | Receive | Assert Timer | Current |
|Preferred | Acceptable | Inferior | Expires | Winner's | |Preferred | Acceptable | Inferior | Expires | Winner's |
|Assert | Assert from | Assert from | | GenID | |Assert | Assert from | Assert from | | GenID |
| | Current | Current | | Changes | | | Current | Current | | Changes |
| | Winner | Winner | | | | | Winner | Winner | | |
+-------------+--------------+--------------+--------------+--------------+ +-------------+--------------+--------------+--------------+--------------+
|-> L state | -> L state | -> NI state | -> NI state | -> NI state | |-> L state | -> L state | -> NI state | -> NI state | -> NI state |
|[Actions A2] | [Actions A2] | [Actions A5] | [Actions A5] | [Actions A5] | |[Actions A2] | [Actions A2] | [Actions A5] | [Actions A5] | [Actions A5] |
+-------------+--------------+--------------+--------------+--------------+ +-------------+--------------+--------------+--------------+--------------+
In I Am Assert Loser (L) State +-----------------------------------------------------------------------+
AssTrDes my_metric -> RPF_interface Receive | In I Am Assert Loser (L) State |
(*,G,I) -> better than (RP(G)) stops Join(*,G) or +----------------+----------------+------------------+------------------+
FALSE Winner's being I Join(*,*,RP(G)) | AssTrDes | my_metric -> | RPF_interface | Receive |
metric on Interface I | (*,G,I) -> | better than | (RP(G)) stops | Join(*,G) or |
-> NI state -> NI state -> NI state -> NI State | FALSE | Winner's | being I | Join- |
[Actions A5] [Actions A5] [Actions A5] [Actions A5] | | metric | | (*,*,RP(G)) on |
| | | | Interface I |
| | | | | +----------------+----------------+------------------+------------------+
| | | | | | -> NI state | -> NI state | -> NI state | -> NI State |
| | | | | | [Actions A5] | [Actions A5] | [Actions A5] | [Actions A5] |
INTERNET-DRAFT | Expires: September 2003 | March 2003| +----------------+----------------+------------------+------------------+
| | | | |
| | | | |
+---------------+-----------------+-----------------+-------------------+
The state machine uses the following macros: The state machine uses the following macros:
CouldAssert(*,G,I) = CouldAssert(*,G,I) =
( I in ( joins(*,*,RP(G)) (+) joins(*,G) ( I in ( joins(*,*,RP(G)) (+) joins(*,G)
(+) pim_include(*,G)) ) (+) pim_include(*,G)) )
AND RPF_interface(RP(G)) != I AND (RPF_interface(RP(G)) != I)
CouldAssert(*,G,I) is true on downstream interfaces for which we have CouldAssert(*,G,I) is true on downstream interfaces for which we have
(*,*,RP(G)) or (*,G) join state, or local members that requested any (*,*,RP(G)) or (*,G) join state, or local members that requested any
traffic destined for G. traffic destined for G.
AssertTrackingDesired(*,G,I) = AssertTrackingDesired(*,G,I) =
CouldAssert(*,G) CouldAssert(*,G)
OR (local_receiver_include(*,G,I)==TRUE OR (local_receiver_include(*,G,I)==TRUE
AND (I_am_DR(I) OR AssertWinner(*,G,I) == me)) AND (I_am_DR(I) OR AssertWinner(*,G,I) == me))
OR (RPF_interface(RP(G)) == I AND RPTJoinDesired(G)) OR (RPF_interface(RP(G)) == I AND RPTJoinDesired(G))
skipping to change at page 88, line 33 skipping to change at page 91, line 46
Transitions from "I am Assert Winner" State Transitions from "I am Assert Winner" State
When in "I am Assert Winner" state, the following events trigger When in "I am Assert Winner" state, the following events trigger
transitions, but only if the (S,G) assert state machine is in NoInfo transitions, but only if the (S,G) assert state machine is in NoInfo
state: state:
Receive Inferior Assert Receive Inferior Assert
We receive a (*,G) assert that has a worse metric than our We receive a (*,G) assert that has a worse metric than our
own. Whoever sent the assert has lost, and so we re-send a own. Whoever sent the assert has lost, and so we re-send a
(*,G) Assert, and restart the timer (Action A3 below). (*,G) Assert, and restart the Assert Timer (Action A3 below).
Receive Preferred Assert Receive Preferred Assert
We receive a (*,G) assert that has a better metric than our We receive a (*,G) assert that has a better metric than our
own. We transition to "I am Assert Loser" state and perform own. We transition to "I am Assert Loser" state and perform
actions A2 (below). actions A2 (below).
When in "I am Assert Winner" state, the following events trigger When in "I am Assert Winner" state, the following events trigger
transitions: transitions:
Timer Expires Assert Timer Expires
The (*,G) assert timer expires. As we're in the Winner state, The (*,G) Assert Timer expires. As we're in the Winner state,
then we must still have (*,G) forwarding state that is then we must still have (*,G) forwarding state that is
actively being kept alive. To prevent unnecessary thrashing actively being kept alive. To prevent unnecessary thrashing
of the forwarder and periodic flooding of duplicate packets, of the forwarder and periodic flooding of duplicate packets,
we re-send the (*,G) Assert, and restart the timer (Action A3 we re-send the (*,G) Assert, and restart the Assert Timer
below). (Action A3 below).
CouldAssert(*,G,I) -> FALSE CouldAssert(*,G,I) -> FALSE
Our (*,G) forwarding state or RPF interface changed so as to Our (*,G) forwarding state or RPF interface changed so as to
make CouldAssert(*,G,I) become false. We can no longer make CouldAssert(*,G,I) become false. We can no longer
perform the actions of the assert winner, and so we transition perform the actions of the assert winner, and so we transition
to NoInfo state and perform actions A4 (below). to NoInfo state and perform actions A4 (below).
Transitions from "I am Assert Loser" State Transitions from "I am Assert Loser" State
When in "I am Assert Loser" state, the following events trigger When in "I am Assert Loser" state, the following events trigger
skipping to change at page 89, line 40 skipping to change at page 92, line 51
worse than our own metric for this group (typically because worse than our own metric for this group (typically because
the winner's metric became worse). We transition to NoInfo the winner's metric became worse). We transition to NoInfo
state, delete this (*,G) assert state (action A5), and allow state, delete this (*,G) assert state (action A5), and allow
the normal PIM Join/Prune mechanisms to operate. Usually we the normal PIM Join/Prune mechanisms to operate. Usually we
will eventually re-assert and win when data packets for G have will eventually re-assert and win when data packets for G have
started flowing again. started flowing again.
When in "I am Assert Loser" state, the following events trigger When in "I am Assert Loser" state, the following events trigger
transitions: transitions:
Timer Expires Assert Timer Expires
The (*,G) assert timer expires. We transition to NoInfo state The (*,G) Assert Timer expires. We transition to NoInfo state
and delete this (*,G) assert info (action A5). and delete this (*,G) assert info (action A5).
Current Winner's GenID Changes Current Winner's GenID Changes
We receive a Hello message from the current winner reporting a We receive a Hello message from the current winner reporting a
different GenID from the one it previously reported. This different GenID from the one it previously reported. This
indicates that the current winner's interface or router has indicates that the current winner's interface or router has
gone down and come back up, and so we must assume it no longer gone down and come back up, and so we must assume it no longer
knows it was the winner. We transition to the NoInfo state, knows it was the winner. We transition to the NoInfo state,
deleting the (*,G) assert information (action A5). deleting the (*,G) assert information (action A5).
skipping to change at page 90, line 40 skipping to change at page 93, line 49
normal PIM Join/Prune mechanisms to operate. If whoever sent normal PIM Join/Prune mechanisms to operate. If whoever sent
the Join was in error, then the normal assert mechanism will the Join was in error, then the normal assert mechanism will
eventually re-apply and we will lose the assert again. eventually re-apply and we will lose the assert again.
However whoever sent the assert may know that the previous However whoever sent the assert may know that the previous
assert winner has died, and so we may end up being the new assert winner has died, and so we may end up being the new
forwarder. forwarder.
(*,G) Assert State-machine Actions (*,G) Assert State-machine Actions
A1: Send Assert(*,G) A1: Send Assert(*,G)
Set timer to (Assert_Time - Assert_Override_Interval) Set Assert Timer to (Assert_Time - Assert_Override_Interval)
Store self as AssertWinner(*,G,I). Store self as AssertWinner(*,G,I).
Store rpt_assert_metric(G,I) as AssertWinnerMetric(*,G,I). Store rpt_assert_metric(G,I) as AssertWinnerMetric(*,G,I).
A2: Store new assert winner as AssertWinner(*,G,I) and assert A2: Store new assert winner as AssertWinner(*,G,I) and assert
winner metric as AssertWinnerMetric(*,G,I). winner metric as AssertWinnerMetric(*,G,I).
Set timer to Assert_Time Set Assert Timer to Assert_Time
A3: Send Assert(*,G) A3: Send Assert(*,G)
Set timer to (Assert_Time - Assert_Override_Interval) Set Assert Timer to (Assert_Time - Assert_Override_Interval)
A4: Send AssertCancel(*,G) A4: Send AssertCancel(*,G)
Delete assert info (AssertWinner(*,G,I) and Delete assert info (AssertWinner(*,G,I) and
AssertWinnerMetric(*,G,I) will then return their default AssertWinnerMetric(*,G,I) will then return their default
values). values).
A5: Delete assert info (AssertWinner(*,G,I) and A5: Delete assert info (AssertWinner(*,G,I) and
AssertWinnerMetric(*,G,I) will then return their default AssertWinnerMetric(*,G,I) will then return their default
values). values).
skipping to change at page 91, line 28 skipping to change at page 94, line 38
struct assert_metric { struct assert_metric {
rpt_bit_flag; rpt_bit_flag;
metric_preference; metric_preference;
route_metric; route_metric;
ip_address; ip_address;
}; };
When comparing assert_metrics, the rpt_bit_flag, metric_preference, and When comparing assert_metrics, the rpt_bit_flag, metric_preference, and
route_metric field are compared in order, where the first lower value route_metric field are compared in order, where the first lower value
wins. If all fields are equal, the IP address of the router that wins. If all fields are equal, the primary IP address of the router
sourced the Assert message is used as a tie-breaker, with the highest IP that sourced the Assert message is used as a tie-breaker, with the
address winning. highest IP address winning.
An assert metric for (S,G) to include in (or compare against) an Assert An assert metric for (S,G) to include in (or compare against) an Assert
message sent on interface I should be computed using the following message sent on interface I should be computed using the following
pseudocode: pseudocode:
assert_metric assert_metric
my_assert_metric(S,G,I) { my_assert_metric(S,G,I) {
if( CouldAssert(S,G,I) == TRUE ) { if( CouldAssert(S,G,I) == TRUE ) {
return spt_assert_metric(S,I) return spt_assert_metric(S,I)
} else if( CouldAssert(*,G,I) == TRUE ) { } else if( CouldAssert(*,G,I) == TRUE ) {
skipping to change at page 92, line 24 skipping to change at page 95, line 35
an assert based only on (*,G) forwarding state: an assert based only on (*,G) forwarding state:
assert_metric assert_metric
rpt_assert_metric(G,I) { rpt_assert_metric(G,I) {
return {1,MRIB.pref(RP(G)),MRIB.metric(RP(G)),my_ip_address(I)} return {1,MRIB.pref(RP(G)),MRIB.metric(RP(G)),my_ip_address(I)}
} }
MRIB.pref(X) and MRIB.metric(X) are the routing preference and routing MRIB.pref(X) and MRIB.metric(X) are the routing preference and routing
metrics associated with the route to a particular (unicast) destination metrics associated with the route to a particular (unicast) destination
X, as determined by the MRIB. my_ip_address(I) is simply the router's X, as determined by the MRIB. my_ip_address(I) is simply the router's
IP address that is associated with the local interface I. primary IP address that is associated with the local interface I.
infinite_assert_metric() gives the assert metric we need to send an infinite_assert_metric() gives the assert metric we need to send an
assert but don't match either (S,G) or (*,G) forwarding state: assert but don't match either (S,G) or (*,G) forwarding state:
assert_metric assert_metric
infinite_assert_metric() { infinite_assert_metric() {
return {1,infinity,infinity,0} return {1,infinity,infinity,0}
} }
4.6.4. AssertCancel Messages 4.6.4. AssertCancel Messages
skipping to change at page 93, line 18 skipping to change at page 96, line 29
processing is required for an AssertCancel message, since it is simply processing is required for an AssertCancel message, since it is simply
an Assert message from the current winner. an Assert message from the current winner.
4.6.5. Assert State Macros 4.6.5. Assert State Macros
The macros lost_assert(S,G,rpt,I), lost_assert(S,G,I), and The macros lost_assert(S,G,rpt,I), lost_assert(S,G,I), and
lost_assert(*,G,I) are used in the olist computations of Section 4.1, lost_assert(*,G,I) are used in the olist computations of Section 4.1,
and are defined as: and are defined as:
bool lost_assert(S,G,rpt,I) { bool lost_assert(S,G,rpt,I) {
if ( RPF_interface(RP) == I OR if ( RPF_interface(RP(G)) == I OR
( RPF_interface(S) == I AND SPTbit(S,G) == TRUE ) ) { ( RPF_interface(S) == I AND SPTbit(S,G) == TRUE ) ) {
return FALSE return FALSE
} else { } else {
return ( AssertWinner(S,G,I) != NULL AND return ( AssertWinner(S,G,I) != NULL AND
AssertWinner(S,G,I) != me ) AssertWinner(S,G,I) != me )
} }
} }
bool lost_assert(S,G,I) { bool lost_assert(S,G,I) {
if ( RPF_interface(S) == I ) { if ( RPF_interface(S) == I ) {
skipping to change at page 93, line 40 skipping to change at page 97, line 4
} else { } else {
return ( AssertWinner(S,G,I) != NULL AND return ( AssertWinner(S,G,I) != NULL AND
AssertWinner(S,G,I) != me AND AssertWinner(S,G,I) != me AND
(AssertWinnerMetric(S,G,I) is better (AssertWinnerMetric(S,G,I) is better
than spt_assert_metric(S,I) ) than spt_assert_metric(S,I) )
} }
} }
Note: the term "AssertWinnerMetric(S,G,I) is better than Note: the term "AssertWinnerMetric(S,G,I) is better than
spt_assert_metric(S,I)" is required to correctly handle the transition spt_assert_metric(S,I)" is required to correctly handle the transition
phase when a router has (S,G) join state, but has not yet set the SPT phase when a router has (S,G) join state, but has not yet set the SPT
bit. In this case it needs to ignore the assert state if it will win bit. In this case it needs to ignore the assert state if it will win
the assert once the SPT bit is set. the assert once the SPT bit is set.
bool lost_assert(*,G,I) { bool lost_assert(*,G,I) {
if ( RPF_interface(RP) == I ) { if ( RPF_interface(RP(G)) == I ) {
return FALSE return FALSE
} else { } else {
return ( AssertWinner(*,G,I) != NULL AND return ( AssertWinner(*,G,I) != NULL AND
AssertWinner(*,G,I) != me ) AssertWinner(*,G,I) != me )
} }
} }
AssertWinner(S,G,I) is the IP source address of the Assert(S,G) packet AssertWinner(S,G,I) is the IP source address of the Assert(S,G) packet
that won an Assert. that won an Assert.
AssertWinner(*,G,I) is the IP source address of the Assert(*,G) packet AssertWinner(*,G,I) is the IP source address of the Assert(*,G) packet
that won an Assert. that won an Assert.
AssertWinnerMetric(S,G,I) is the Assert metric of the Assert(S,G) packet AssertWinnerMetric(S,G,I) is the Assert metric of the Assert(S,G) packet
that won an Assert. that won an Assert.
AssertWinnerMetric(*,G,I) is the Assert metric of the Assert(*,G) packet AssertWinnerMetric(*,G,I) is the Assert metric of the Assert(*,G) packet
that won an Assert. that won an Assert.
AssertWinner(S,G,I) defaults to Null and AssertWinnerMetric(S,G,I) AssertWinner(S,G,I) defaults to NULL and AssertWinnerMetric(S,G,I)
defaults to Infinity when in the NoInfo state. defaults to Infinity when in the NoInfo state.
Summary of Assert Rules and Rationale Summary of Assert Rules and Rationale
This section summarizes the key rules for sending and reacting to This section summarizes the key rules for sending and reacting to
asserts and the rationale for these rules. This section is not intended asserts and the rationale for these rules. This section is not intended
to be and should not be treated as a definitive specification of to be and should not be treated as a definitive specification of
protocol behavior. The state machines and pseudocode should be protocol behavior. The state machines and pseudocode should be
consulted for that purpose. Rather, this section is intended to consulted for that purpose. Rather, this section is intended to
document important aspects of a the Assert protocol behavior and to document important aspects of a the Assert protocol behavior and to
skipping to change at page 95, line 33 skipping to change at page 98, line 37
RPF'(S,G,rpt) != RPF'(*,G). RPF'(S,G,rpt) != RPF'(*,G).
Rationale: This avoids keeping state alive on the (S,G) tree when Rationale: This avoids keeping state alive on the (S,G) tree when
only (*,G) downstream members are left. Also, it avoids sending only (*,G) downstream members are left. Also, it avoids sending
(S,G,rpt) joins to a router that is not on the (*,G) tree. This (S,G,rpt) joins to a router that is not on the (*,G) tree. This
behavior might be confusing although this specification does behavior might be confusing although this specification does
indicate that such a join should be dropped. indicate that such a join should be dropped.
6. Behavior: An assert loser that receives a Join(S,G) with an 6. Behavior: An assert loser that receives a Join(S,G) with an
Upstream Neighbor Address that is one of its addresses on that Upstream Neighbor Address that is one of its addresses on that
interface cancels the (S,G) assert timer. interface cancels the (S,G) Assert Timer.
Rationale: This is necessary in order to have rapid convergence in Rationale: This is necessary in order to have rapid convergence in
the event that the downstream router that initially sent a join to the event that the downstream router that initially sent a join to
the prior Assert winner has undergone a topology change. the prior Assert winner has undergone a topology change.
7. Behavior: An assert loser that receives a Join(*,G) or a 7. Behavior: An assert loser that receives a Join(*,G) or a
Join(*,*,RP(G)) with an Upstream Neighbor Address that is one of Join(*,*,RP(G)) with an Upstream Neighbor Address that is one of
its addresses on that interface cancels the (*,G) assert timer and its addresses on that interface cancels the (*,G) Assert Timer and
all (S,G) assert timers that do not have corresponding all (S,G) assert timers that do not have corresponding
Prune(S,G,rpt) messages in the compound Join/Prune message. Prune(S,G,rpt) messages in the compound Join/Prune message.
Rationale: Same as 6. Rationale: Same as 6.
8. Behavior: An assert winner for (*,G) or (S,G) sends a canceling 8. Behavior: An assert winner for (*,G) or (S,G) sends a canceling
assert when it is about to stop forwarding on a (*,G) or an (S,G) assert when it is about to stop forwarding on a (*,G) or an (S,G)
entry. This behavior does not apply to (S,G,rpt). entry. This behavior does not apply to (S,G,rpt).
Rationale: This allows switching back to the shared tree after the Rationale: This allows switching back to the shared tree after the
skipping to change at page 96, line 17 skipping to change at page 99, line 21
routers on the shared tree from keeping SPT state alive. routers on the shared tree from keeping SPT state alive.
9. Behavior: Re-send the assert messages before timing out an assert. 9. Behavior: Re-send the assert messages before timing out an assert.
(This behavior is optional.) (This behavior is optional.)
Rationale: This prevents the periodic duplicates that would Rationale: This prevents the periodic duplicates that would
otherwise occur each time that an assert times out and is then re- otherwise occur each time that an assert times out and is then re-
established. established.
10. Behavior: When RPF'(S,G,rpt) changes to be the same as RPF'(*,G) we 10. Behavior: When RPF'(S,G,rpt) changes to be the same as RPF'(*,G) we
need to trigger a Join(S,G,rpt) to MRIB.next_hop(RP(G)). need to trigger a Join(S,G,rpt) to RPF'(*,G).
Rationale: This allows switching back to the RPT after the last SPT Rationale: This allows switching back to the RPT after the last SPT
member leaves. member leaves.
4.7. PIM Multicast Border Router Behavior 4.7. PIM Multicast Border Router Behavior
In some cases PIM-SM domains will interconnect with non-PIM domains. In In some cases PIM-SM domains will interconnect with non-PIM domains. In
these cases, the border routers of the PIM domain speak PIM-SM on some these cases, the border routers of the PIM domain speak PIM-SM on some
interfaces and speak other multicast routing protocols on other interfaces and speak other multicast routing protocols on other
interfaces. Such routers are termed PIM Multicast Border Routers or interfaces. Such routers are termed PIM Multicast Border Routers or
skipping to change at page 97, line 4 skipping to change at page 100, line 9
external sources, but does not follow RFC 2715. In such cases the external sources, but does not follow RFC 2715. In such cases the
domains are not connected via PMBRs because Join(S,G) messages traverse domains are not connected via PMBRs because Join(S,G) messages traverse
the border between domains. A PMBR is required when no PIM messages can the border between domains. A PMBR is required when no PIM messages can
traverse the border; typically this is because the routing protocol in traverse the border; typically this is because the routing protocol in
the neighboring domain is not PIM-SM. the neighboring domain is not PIM-SM.
4.7.1. Sources External to the PIM-SM Domain 4.7.1. Sources External to the PIM-SM Domain
A PMBR needs to ensure that traffic from multicast sources external to A PMBR needs to ensure that traffic from multicast sources external to
the PIM-SM domain reaches receivers inside the domain. The PMBR will the PIM-SM domain reaches receivers inside the domain. The PMBR will
follow the rules in RFC 2715, such that traffic from external sources follow the rules in RFC 2715, such that traffic from external sources
reaches the PMBR itself. reaches the PMBR itself.
According to RFC 2715, the PIM-SM component of the PMBR will receive an According to RFC 2715, the PIM-SM component of the PMBR will receive an
(S,G) Creation event when data from an (S,G) data packet from an (S,G) Creation event when data from an (S,G) data packet from an
external source first reaches the PMBR. If RPF_interface(S) is not an external source first reaches the PMBR. If RPF_interface(S) is not an
interface in the PIM-SM domain, the packet cannot be originated into the interface in the PIM-SM domain, the packet cannot be originated into the
PIM domain at this router, and the PIM-SM component of the PMBR will not PIM domain at this router, and the PIM-SM component of the PMBR will not
process the packet. Otherwise the PMBR will then act exactly as if it process the packet. Otherwise the PMBR will then act exactly as if it
were the DR for this source (see section 4.4.1 with the following were the DR for this source (see Section 4.4.1 with the following
modifications: modifications:
o The Border-bit is set in all PIM Register message sent for these o The Border-bit is set in all PIM Register message sent for these
sources. sources.
o DirectlyConnected(S) is treated as being TRUE for these sources. o DirectlyConnected(S) is treated as being TRUE for these sources.
o The PIM-SM forwarding rule "iif == RPF_interface(S)" is relaxed to be o The PIM-SM forwarding rule "iif == RPF_interface(S)" is relaxed to be
TRUE if iif is any interface that is not part of the PIM-SM component TRUE if iif is any interface that is not part of the PIM-SM component
of the PMBR (see section 4.2). of the PMBR (see Section 4.2).
4.7.2. Sources Internal to the PIM-SM Domain 4.7.2. Sources Internal to the PIM-SM Domain
A PMBR needs to ensure that traffic from sources inside the PIM-SM A PMBR needs to ensure that traffic from sources inside the PIM-SM
domain reaches receivers outside the domain. Using terminology from RFC domain reaches receivers outside the domain. Using terminology from RFC
2715, there are two possible scenarios for this: 2715, there are two possible scenarios for this:
o Another component of the PMBR is a wildcard receiver. In this case o Another component of the PMBR is a wildcard receiver. In this case
the PIM-SM component of the PMBR must ensure that traffic from all the PIM-SM component of the PMBR must ensure that traffic from all
internal sources reaches the PMBR until it is informed otherwise. internal sources reaches the PMBR until it is informed otherwise.
o No other component of the PMBR is a wildcard receiver. In this case o No other component of the PMBR is a wildcard receiver. In this case
the PMBR will receive explicit information as to which groups or the PMBR will receive explicit information as to which groups or
(source,group) pairs the external domains wish to receive. (source,group) pairs the external domains wish to receive.
In the former case, the PMBR will need to issue send a Join(*,*,RP) to In the former case, the PMBR will need to issue send a Join(*,*,RP) to
all the RPs in the PIM-SM domain. This will cause all traffic in the all the RPs in the PIM-SM domain. This will cause all traffic in the
domain to reach the PMBR. The PMBR may then act as if it were a DR with domain to reach the PMBR. The PMBR may then act as if it were a DR with
directly connected receivers, and trigger the transition to a shortest directly connected receivers, and trigger the transition to a shortest
path tree (see section 4.2.1). path tree (see Section 4.2.1).
In the latter case, the PMBR will not need to send Join(*,*,RP) In the latter case, the PMBR will not need to send Join(*,*,RP)
messages. However the PMBR will still need to act as a DR with directly messages. However the PMBR will still need to act as a DR with directly
connected receivers on behalf of the external receivers in terms of connected receivers on behalf of the external receivers in terms of
being able to switch to the shortest-path tree for internally-reached being able to switch to the shortest-path tree for internally-reached
sources. sources.
According to RFC 2715, the PIM-SM component of the PMBR may receive a According to RFC 2715, the PIM-SM component of the PMBR may receive a
number of alerts generated by events in the external routing components. number of alerts generated by events in the external routing components.
To implement the above behavior, one reasonable way to map these alerts To implement the above behavior, one reasonable way to map these alerts
into PIM-SM state as follows: into PIM-SM state as follows:
o When a PIM-SM component receives an (S,G) Prune alert, it sets o When a PIM-SM component receives an (S,G) Prune alert, it sets
local_receiver_include(S,G,I) to FALSE for the discard interface. local_receiver_include(S,G,I) to FALSE for the discard interface.
skipping to change at page 98, line 38 skipping to change at page 101, line 41
for all RPs in the PIM-SM domain. for all RPs in the PIM-SM domain.
We refer above to the discard interface because the macros and state- We refer above to the discard interface because the macros and state-
machines are interface-specific, but we need to have PIM state that is machines are interface-specific, but we need to have PIM state that is
not associated with any actual PIM-SM interface. Implementors are free not associated with any actual PIM-SM interface. Implementors are free
to implement this in any reasonable manner. to implement this in any reasonable manner.
Note that these state changes will then cause additional PIM-SM state Note that these state changes will then cause additional PIM-SM state
machine transitions in the normal way. machine transitions in the normal way.
These rules are however not sufficent to allow pruning off the (*,*,RP)
tree. Some additional rules provide guidance as to one way this may be
done:
o If the PMBR has joined on the (*,*,RP) tree, then it should set
DownstreamJPState(*,G,I) to TRUE on the discard interface for all
active groups.
o If the router receives a (S,G) prune alert it will need to set
DownstreamJPState(S,G,rpt,I) to PRUNE on the discard interface.
o If the router receives a (*,G) prune alert, it will need to set
DownstreamJPState(S,G,rpt,I) to PRUNE on the discard interface for all
active sources sending to G.
The rationale for this is that there is no way in PIM-SM to prune
traffic off the (*,*,RP) tree, except by Joining the (*,G) tree and then
pruning each source individually.
4.8. PIM Bootstrap and RP Discovery 4.8. PIM Bootstrap and RP Discovery
For correct operation, every PIM router within a PIM domain must be able For correct operation, every PIM router within a PIM domain must be able
to map a particular multicast group address to the same RP. If this is to map a particular multicast group address to the same RP. If this is
not the case then black holes may appear, where some receivers in the not the case then black holes may appear, where some receivers in the
domain cannot receive some groups. A domain in this context is a domain cannot receive some groups. A domain in this context is a
contiguous set of routers that all implement PIM and are configured to contiguous set of routers that all implement PIM and are configured to
operate within a common boundary defined by PIM Multicast Border Routers operate within a common boundary defined by PIM Multicast Border Routers
(PMBRs). PMBRs connect each PIM domain to the rest of the Internet. (PMBRs). PMBRs connect each PIM domain to the rest of the Internet.
skipping to change at page 102, line 36 skipping to change at page 106, line 12
o A router acting as an RP MUST NOT forward any Register-encapsulated o A router acting as an RP MUST NOT forward any Register-encapsulated
packet that has an SSM destination address. packet that has an SSM destination address.
The last two rules are present to deal with "legacy" routers unaware of The last two rules are present to deal with "legacy" routers unaware of
SSM that may be sending (*,G) and (S,G,rpt) Join/Prunes, or Register SSM that may be sending (*,G) and (S,G,rpt) Join/Prunes, or Register
messages for SSM destination addresses. messages for SSM destination addresses.
Additionally: Additionally:
o A router MAY be configured to advertise itself as a Candidate RP for o A router MAY be configured to advertise itself as a Candidate RP for
an SSM address. If so, it SHOULD respond with a RegisterStop message an SSM address. If so, it SHOULD respond with a Register-Stop message
to any Register message containing a packet destined for an SSM to any Register message containing a packet destined for an SSM
address. address.
o A router MAY optimize out the creation and maintenance of (S,G,rpt) o A router MAY optimize out the creation and maintenance of (S,G,rpt)
and (*,G) state for SSM destination addresses -- this state is not and (*,G) state for SSM destination addresses -- this state is not
needed for SSM packets. needed for SSM packets.
4.9.2. PIM-SSM-only Routers 4.9.2. PIM-SSM-only Routers
An implementor may choose to implement only the subset of PIM Sparse- An implementor may choose to implement only the subset of PIM Sparse-
skipping to change at page 103, line 34 skipping to change at page 107, line 11
4.5.6, 4.5.8, and 4.5.5) 4.5.6, 4.5.8, and 4.5.5)
o (*,G) Assert state machine (Section 4.6.2) o (*,G) Assert state machine (Section 4.6.2)
o Bootstrap RP Election (Section 4.8) o Bootstrap RP Election (Section 4.8)
o Keepalive Timer o Keepalive Timer
o SptBit (Section 4.2.2) o SptBit (Section 4.2.2)
The KeepaliveTimer should be treated as always running and SptBit should The Keepalive Timer should be treated as always running and SptBit
be treated as being always set for an SSM address. Additionally, the should be treated as being always set for an SSM address. Additionally,
Packet forwarding rules of Section 4.2 can be simplified in a PIM-SSM- the Packet forwarding rules of Section 4.2 can be simplified in a PIM-
only router: SSM-only router:
if( iif == RPF_interface(S) AND UpstreamJPState(S,G) == Joined ) { if( iif == RPF_interface(S) AND UpstreamJPState(S,G) == Joined ) {
oiflist = inherited_olist(S,G) oiflist = inherited_olist(S,G)
} else if( iif is in inherited_olist(S,G) ) { } else if( iif is in inherited_olist(S,G) ) {
send Assert(S,G) on iif send Assert(S,G) on iif
} }
oiflist = oiflist (-) iif oiflist = oiflist (-) iif
forward packet on all interfaces in oiflist forward packet on all interfaces in oiflist
This is nothing more than the reduction of the normal PIM-SM forwarding This is nothing more than the reduction of the normal PIM-SM forwarding
rule, with all (S,G,rpt) and (*,G) clauses replaced with NULL. rule, with all (S,G,rpt) and (*,G) clauses replaced with NULL.
4.10. PIM Packet Formats 4.10. PIM Packet Formats
This section describes the details of the packet formats for PIM control This section describes the details of the packet formats for PIM control
messages. messages.
All PIM control messages have IP protocol number 103. All PIM control messages have IP protocol number 103.
PIM messages are either unicast (e.g. Registers and RegisterStop), or PIM messages are either unicast (e.g. Registers and Register-Stop), or
multicast with TTL 1 to the `ALL-PIM-ROUTERS' group (e.g. Join/Prune, multicast with TTL 1 to the `ALL-PIM-ROUTERS' group (e.g. Join/Prune,
Asserts, etc.). The source address used for unicast messages is a Asserts, etc.). The source address used for unicast messages is a
domain-wide reachable address; the source address used for multicast domain-wide reachable address; the source address used for multicast
messages is the link-local address of the interface on which the message messages is the link-local address of the interface on which the message
is being sent. is being sent.
The IPv4 `ALL-PIM-ROUTERS' group is `224.0.0.13'. The IPv6 `ALL-PIM- The IPv4 `ALL-PIM-ROUTERS' group is `224.0.0.13'. The IPv6 `ALL-PIM-
ROUTERS' group is `ff02::d'. ROUTERS' group is `ff02::d'.
0 1 2 3 0 1 2 3
skipping to change at page 104, line 37 skipping to change at page 108, line 14
PIM Ver PIM Ver
PIM Version number is 2. PIM Version number is 2.
Type Types for specific PIM messages. PIM Types are: Type Types for specific PIM messages. PIM Types are:
Message Type Destination Message Type Destination
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
0 = Hello Multicast to ALL-PIM-ROUTERS 0 = Hello Multicast to ALL-PIM-ROUTERS
1 = Register Unicast to RP 1 = Register Unicast to RP
2 = RegisterStop Unicast to source of Register packet 2 = Register-Stop Unicast to source of Register packet
3 = Join/Prune Multicast to ALL-PIM-ROUTERS 3 = Join/Prune Multicast to ALL-PIM-ROUTERS
4 = Bootstrap Multicast to ALL-PIM-ROUTERS 4 = Bootstrap Multicast to ALL-PIM-ROUTERS
5 = Assert Multicast to ALL-PIM-ROUTERS 5 = Assert Multicast to ALL-PIM-ROUTERS
6 = Graft (used in PIM-DM only) Multicast to ALL-PIM-ROUTERS 6 = Graft (used in PIM-DM only) Multicast to ALL-PIM-ROUTERS
7 = Graft-Ack (used in PIM-DM only) Unicast to source of Graft packet 7 = Graft-Ack (used in PIM-DM only) Unicast to source of Graft packet
8 = Candidate-RP-Advertisement Unicast to Domain's BSR 8 = Candidate-RP-Advertisement Unicast to Domain's BSR
Reserved Reserved
Set to zero on transmission. Ignored upon receipt. Set to zero on transmission. Ignored upon receipt.
Checksum Checksum
The checksum is a standard IP checksum, i.e. the 16-bit one's The checksum is a standard IP checksum, i.e. the 16-bit one's
complement of the one's complement sum of the entire PIM message, complement of the one's complement sum of the entire PIM message,
excluding the "Multicast data packet" section of the Register excluding the "Multicast data packet" section of the Register
message. For computing the checksum, the checksum field is zeroed. message. For computing the checksum, the checksum field is zeroed.
For IPv6, the checksum also includes the IPv6 "pseudo-header", as For IPv6, the checksum also includes the IPv6 "pseudo-header", as
specified in RFC 2460, section 8.1 [5]. This "pseudo-header" is specified in RFC 2460, Section 8.1 [5]. This "pseudo-header" is
prepended to the PIM header for the purposes of calculating the prepended to the PIM header for the purposes of calculating the
checksum. The "Upper-Layer Packet Length" in the pseudo-header is checksum. The "Upper-Layer Packet Length" in the pseudo-header is
set to the length of the PIM message. The Next Header value used set to the length of the PIM message. The Next Header value used
in the pseudo-header is 103. If the packet's length is not an in the pseudo-header is 103. If the packet's length is not an
integral number of 16-bit words, the packet is padded with a byte integral number of 16-bit words, the packet is padded with a byte
of zero before performing the checksum. of zero before performing the checksum.
4.10.1. Encoded Source and Group Address Formats 4.10.1. Encoded Source and Group Address Formats
Encoded-Unicast address Encoded-Unicast address
skipping to change at page 107, line 33 skipping to change at page 111, line 30
Encoding Type Encoding Type
described above. described above.
Reserved Reserved
Transmitted as zero, ignored on receipt. Transmitted as zero, ignored on receipt.
S The Sparse bit is a 1 bit value, set to 1 for PIM-SM. It is used S The Sparse bit is a 1 bit value, set to 1 for PIM-SM. It is used
for PIM version 1 compatibility. for PIM version 1 compatibility.
W The WC (or WildCard) bit is a 1 bit value for use with PIM W The WC (or WildCard) bit is a 1 bit value for use with PIM
Join/Prune messages (see section 4.10.5.1 ). Join/Prune messages (see Section 4.10.5.1 ).
R The RPT (or Rendezvous Point Tree) bit is a 1 bit value for use R The RPT (or Rendezvous Point Tree) bit is a 1 bit value for use
with PIM Join/Prune messages (see section 4.10.5.1 ). If the WC bit with PIM Join/Prune messages (see Section 4.10.5.1 ). If the WC bit
is 1, the RPT bit MUST be 1. is 1, the RPT bit MUST be 1.
Mask Len Mask Len
The mask length field is 8 bits. The value is the number of The mask length field is 8 bits. The value is the number of
contiguous one bits left justified used as a mask which, combined contiguous one bits left justified used as a mask which, combined
with the Source Address, describes a source subnet. The mask length with the Source Address, describes a source subnet. The mask length
MUST be equal to the mask length in bits for the given Address MUST be equal to the mask length in bits for the given Address
Family and Encoding Type (32 for IPv4 native and 128 for IPv6 Family and Encoding Type (32 for IPv4 native and 128 for IPv6
native). A router SHOULD ignore any messages received with any native). A router SHOULD ignore any messages received with any
other mask length. other mask length.
skipping to change at page 108, line 35 skipping to change at page 112, line 33
| . | | . |
| . | | . |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| OptionType | OptionLength | | OptionType | OptionLength |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| OptionValue | | OptionValue |
| ... | | ... |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
PIM Version, Type, Reserved, Checksum PIM Version, Type, Reserved, Checksum
Described above. Described in Section 4.10.
OptionType OptionType
The type of the option given in the following OptionValue field. The type of the option given in the following OptionValue field.
OptionLength OptionLength
The length of the OptionValue field in bytes. The length of the OptionValue field in bytes.
OptionValue OptionValue
A variable length field, carrying the value of the option. A variable length field, carrying the value of the option.
skipping to change at page 109, line 25 skipping to change at page 113, line 20
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Holdtime is the amount of time a receiver must keep the neighbor Holdtime is the amount of time a receiver must keep the neighbor
reachable, in seconds. If the Holdtime is set to `0xffff', the reachable, in seconds. If the Holdtime is set to `0xffff', the
receiver of this message never times out the neighbor. This may receiver of this message never times out the neighbor. This may
be used with dial-on-demand links, to avoid keeping the link up be used with dial-on-demand links, to avoid keeping the link up
with periodic Hello messages. with periodic Hello messages.
Hello messages with a Holdtime value set to `0' are also sent by Hello messages with a Holdtime value set to `0' are also sent by
a router on an interface about to go down or changing IP address a router on an interface about to go down or changing IP address
(see section 4.3.1). These are effectively goodbye messages and (see Section 4.3.1). These are effectively goodbye messages and
the receiving routers should immediately time out the neighbor the receiving routers should immediately time out the neighbor
information for the sender. information for the sender.
o OptionType 2: LAN Prune Delay o OptionType 2: LAN Prune Delay
0 1 2 3 0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Type = 2 | Length = 4 | | Type = 2 | Length = 4 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
skipping to change at page 110, line 8 skipping to change at page 114, line 4
milliseconds are are used to tune the value of the milliseconds are are used to tune the value of the
Override_Interval(I) and its derived timer values. Section 4.3.3 Override_Interval(I) and its derived timer values. Section 4.3.3
describes how these values affect the behavior of a router. describes how these values affect the behavior of a router.
o OptionType 3 to 16: reserved to be defined in future versions of o OptionType 3 to 16: reserved to be defined in future versions of
this document. this document.
o OptionType 18: deprecated and should not be used. o OptionType 18: deprecated and should not be used.
o OptionType 19: DR Priority o OptionType 19: DR Priority
0 1 2 3 0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Type = 19 | Length = 4 | | Type = 19 | Length = 4 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| DR Priority | | DR Priority |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
DR Priority is a 32-bit unsigned number and should be considered DR Priority is a 32-bit unsigned number and should be considered
in the DR election as described in section 4.3.2. in the DR election as described in Section 4.3.2.
o OptionType 20: Generation ID o OptionType 20: Generation ID
0 1 2 3 0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Type = 20 | Length = 4 | | Type = 20 | Length = 4 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Generation ID | | Generation ID |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Generation ID is a random 32-bit value for the interface on which Generation ID is a random 32-bit value for the interface on which
the Hello message is sent. The Generation ID is regenerated the Hello message is sent. The Generation ID is regenerated
whenever PIM forwarding is started or restarted on the interface. whenever PIM forwarding is started or restarted on the interface.
o OptionType 24: Address List
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Type = 24 | Length = <Variable> |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Secondary Address 1 (Encoded-Unicast format) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Secondary Address N (Encoded-Unicast format) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
The contents of the Address List Hello option are described in
section 4.3.4.
OptionTypes 17 thru 65000 are assigned by the IANA. OptionTypes OptionTypes 17 thru 65000 are assigned by the IANA. OptionTypes
65001 through 65535 are reserved for Private Use, as defined in 65001 through 65535 are reserved for Private Use, as defined in
[13]. [13].
Unknown options may be ignored. The "Holdtime" option MUST be Unknown options may be ignored. The "Holdtime" option MUST be
implemented; the "DR Priority" and "Generation ID" options SHOULD implemented; the "DR Priority" and "Generation ID" options SHOULD
be implemented. be implemented.
4.10.3. Register Message Format 4.10.3. Register Message Format
A Register message is sent by the DR or a PMBR to the RP when a A Register message is sent by the DR or a PMBR to the RP when a
skipping to change at page 111, line 18 skipping to change at page 115, line 26
|PIM Ver| Type | Reserved | Checksum | |PIM Ver| Type | Reserved | Checksum |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|B|N| Reserved2 | |B|N| Reserved2 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| | | |
. Multicast data packet . . Multicast data packet .
| | | |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
PIM Version, Type, Reserved, Checksum PIM Version, Type, Reserved, Checksum
Described above. Note that the checksum for Registers is done only Described in Section 4.10. Note that in order to reduce
on first 8 bytes of the packet, including the PIM header and the encapsulation overhead, the checksum for Registers is done only on
next 4 bytes, excluding the data packet portion. For first 8 bytes of the packet, including the PIM header and the next
interoperability reasons, a message carrying a checksum calculated 4 bytes, excluding the data packet portion. For interoperability
over the entire PIM Register message should also be accepted. reasons, a message carrying a checksum calculated over the entire
PIM Register message should also be accepted.
B The Border bit. If the router is a DR for a source that it is B The Border bit. If the router is a DR for a source that it is
directly connected to, it sets the B bit to 0. If the router is a directly connected to, it sets the B bit to 0. If the router is a
PMBR for a source in a directly connected cloud, it sets the B bit PMBR for a source in a directly connected cloud, it sets the B bit
to 1. to 1.
N The Null-Register bit. Set to 1 by a DR that is probing the RP N The Null-Register bit. Set to 1 by a DR that is probing the RP
before expiring its local Register-Suppression timer. Set to 0 before expiring its local Register-Suppression Timer. Set to 0
otherwise. otherwise.
Reserved2 Reserved2
Transmitted as zero, ignored on receipt. Transmitted as zero, ignored on receipt.
Multicast data packet Multicast data packet
The original packet sent by the source. This packet must be the of The original packet sent by the source. This packet must be the of
the same address family as the encapsulating PIM packet, e.g. an the same address family as the encapsulating PIM packet, e.g. an
IPv6 data packet must be encapsulated in an IPv6 PIM packet. Note IPv6 data packet must be encapsulated in an IPv6 PIM packet. Note
that the TTL of the original packet is decremented before that the TTL of the original packet is decremented before
encapsulation, just like any other packet that is forwarded. In encapsulation, just like any other packet that is forwarded. In
addition, the RP decrements the TTL after decapsulating, before addition, the RP decrements the TTL after decapsulating, before
forwarding the packet down the shared tree. forwarding the packet down the shared tree.
For (S,G) null Registers, the Multicast data packet portion For (S,G) Null-Registers, the Multicast data packet portion
contains only a dummy header with S as the source address, G as the contains only a dummy header with S as the source address, G as the
destination address, and a data length of zero. destination address, and a data length of zero.
4.10.4. RegisterStop Message Format 4.10.4. Register-Stop Message Format
A RegisterStop is unicast from the RP to the sender of the Register A Register-Stop is unicast from the RP to the sender of the Register
message. The IP source address is the address to which the register was message. The IP source address is the address to which the register was
addressed. The IP destination address is the source address of the addressed. The IP destination address is the source address of the
register message. register message.
0 1 2 3 0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|PIM Ver| Type | Reserved | Checksum | |PIM Ver| Type | Reserved | Checksum |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Group Address (Encoded-Group format) | | Group Address (Encoded-Group format) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Source Address (Encoded-Unicast format) | | Source Address (Encoded-Unicast format) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
PIM Version, Type, Reserved, Checksum PIM Version, Type, Reserved, Checksum
Described above. Described in Section 4.10.
Group Address Group Address
The group address from the multicast data packet in the Register. The group address from the multicast data packet in the Register.
Format described in section 4.10.1. Note that for RegisterStops the Format described in Section 4.10.1. Note that for Register-Stops
Mask Len field contains the full address length * 8 (e.g. 32 for the Mask Len field contains the full address length * 8 (e.g. 32
IPv4 native encoding), if the message is sent for a single group. for IPv4 native encoding), if the message is sent for a single
group.
Source Address Source Address
The host address of the source from the multicast data packet in The host address of the source from the multicast data packet in
the register. The format for this address is given in the Encoded- the register. The format for this address is given in the Encoded-
Unicast address in section 4.10.1. A special wild card value Unicast address in Section 4.10.1. A special wild card value
consisting of an address field of all zeroes can be used to consisting of an address field of all zeroes can be used to
indicate any source. indicate any source.
4.10.5. Join/Prune Message Format 4.10.5. Join/Prune Message Format
A Join/Prune message is sent by routers towards upstream sources and A Join/Prune message is sent by routers towards upstream sources and
RPs. Joins are sent to build shared trees (RP trees) or source trees RPs. Joins are sent to build shared trees (RP trees) or source trees
(SPT). Prunes are sent to prune source trees when members leave groups (SPT). Prunes are sent to prune source trees when members leave groups
as well as sources that do not use the shared tree. as well as sources that do not use the shared tree.
skipping to change at page 114, line 8 skipping to change at page 119, line 8
| Pruned Source Address 1 (Encoded-Source format) | | Pruned Source Address 1 (Encoded-Source format) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| . | | . |
| . | | . |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Pruned Source Address n (Encoded-Source format) | | Pruned Source Address n (Encoded-Source format) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
PIM Version, Type, Reserved, Checksum PIM Version, Type, Reserved, Checksum
Described above. Described in Section 4.10.
Unicast Upstream Neighbor Address Unicast Upstream Neighbor Address
The address of the RPF or upstream neighbor. The format for this The address of the RPF or upstream neighbor. The format for this
address is given in the Encoded-Unicast address in section 4.10.1. address is given in the Encoded-Unicast address in Section 4.10.1.
This address should be the link-local address of the upstream This address should be the link-local address of the upstream
neighbor, as obtained from the RPF lookup. neighbor, as obtained from the RPF lookup.
Reserved Reserved
Transmitted as zero, ignored on receipt. Transmitted as zero, ignored on receipt.
Holdtime Holdtime
The amount of time a receiver must keep the Join/Prune state alive, The amount of time a receiver must keep the Join/Prune state alive,
in seconds. If the Holdtime is set to `0xffff', the receiver of in seconds. If the Holdtime is set to `0xffff', the receiver of
this message should hold the state until canceled by the this message should hold the state until canceled by the
skipping to change at page 114, line 44 skipping to change at page 119, line 44
For format description see Section 4.10.1. For format description see Section 4.10.1.
Number of Joined Sources Number of Joined Sources
Number of join source addresses listed for a given group. Number of join source addresses listed for a given group.
Join Source Address 1 .. n Join Source Address 1 .. n
This list contains the sources that the sending router will forward This list contains the sources that the sending router will forward
multicast datagrams for if received on the interface this message multicast datagrams for if received on the interface this message
is sent on. is sent on.
See Encoded-Source-Address format in section 4.10.1. See Encoded-Source-Address format in Section 4.10.1.
Number of Pruned Sources Number of Pruned Sources
Number of prune source addresses listed for a group. Number of prune source addresses listed for a group.
Prune Source Address 1 .. n Prune Source Address 1 .. n
This list contains the sources that the sending router does not This list contains the sources that the sending router does not
want to forward multicast datagrams for when received on the want to forward multicast datagrams for when received on the
interface this message is sent on. interface this message is sent on.
Within one PIM Join/Prune message, all the Multicast Group Addresses, Within one PIM Join/Prune message, all the Multicast Group Addresses,
skipping to change at page 115, line 34 skipping to change at page 120, line 34
group sets. Each set contains two source lists, the Join Sources and the group sets. Each set contains two source lists, the Join Sources and the
Prune Sources. This section describes the different types of group sets Prune Sources. This section describes the different types of group sets
and source list entries that can exist in a Join / Prune message. and source list entries that can exist in a Join / Prune message.
There are two valid group set types: There are two valid group set types:
Wildcard Group Set Wildcard Group Set
The wildcard group set is represented by the entire multicast range The wildcard group set is represented by the entire multicast range
- the beginning of the multicast address range in the group address - the beginning of the multicast address range in the group address
field and the prefix length of the multicast address range in the field and the prefix length of the multicast address range in the
mask length field of the Multicast Group Address, e.g. 224.0.0.0/4 mask length field of the Multicast Group Address, e.g.
for IPv4 or ff00::/8 for IPv6. Each wildcard group set may contain `224.0.0.0/4' for IPv4 or `ff00::/8' for IPv6. Each wildcard group
one or more (*,*,RP) source list entries in either the Join or set may contain one or more (*,*,RP) source list entries in either
Prune lists. the Join or Prune lists.
A (*,*,RP) source list entry may only exist in a wildcard group A (*,*,RP) source list entry may only exist in a wildcard group
set. When added to a Join source list, this type of source entry set. When added to a Join source list, this type of source entry
expresses the router's interest in receiving traffic for all groups expresses the router's interest in receiving traffic for all groups
mapping to the specified RP. When added to a Prune source list a mapping to the specified RP. When added to a Prune source list a
(*,*,RP) entry expresses the router's interest to stop receiving (*,*,RP) entry expresses the router's interest to stop receiving
such traffic. Note that as indicated by the Join/Prune state such traffic. Note that as indicated by the Join/Prune state
machines, such a Join or Prune will NOT override Join/Prune state machines, such a Join or Prune will NOT override Join/Prune state
created using a Group-Specific Set (see below). created using a Group-Specific Set (see below).
skipping to change at page 120, line 20 skipping to change at page 125, line 20
| Group Address (Encoded-Group format) | | Group Address (Encoded-Group format) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Source Address (Encoded-Unicast format) | | Source Address (Encoded-Unicast format) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|R| Metric Preference | |R| Metric Preference |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Metric | | Metric |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
PIM Version, Type, Reserved, Checksum PIM Version, Type, Reserved, Checksum
Described above. Described in Section 4.10.
Group Address Group Address
The group address for which the router wishes to resolve the The group address for which the router wishes to resolve the
forwarding conflict. This is an Encoded-Group address, as forwarding conflict. This is an Encoded-Group address, as
specified in 4.10.1. specified in 4.10.1.
Source Address Source Address
Source address for which the router wishes to resolve the Source address for which the router wishes to resolve the
forwarding conflict. The source address MAY be set to INADDR_ANY forwarding conflict. The source address MAY be set to INADDR_ANY
for (*,G) asserts (see below). The format for this address is for (*,G) asserts (see below). The format for this address is
given in Encoded-Unicast-Address in section 4.10.1. given in Encoded-Unicast-Address in Section 4.10.1.
R RPT-bit is a 1 bit value. The RPT-bit is set to 1 for Assert(*,G) R RPT-bit is a 1 bit value. The RPT-bit is set to 1 for Assert(*,G)
messages and 0 for Assert(S,G) messages. messages and 0 for Assert(S,G) messages.
Metric Preference Metric Preference
Preference value assigned to the unicast routing protocol that Preference value assigned to the unicast routing protocol that
provided the route to the multicast source or Rendezvous-Point. provided the route to the multicast source or Rendezvous-Point.
Metric Metric
The unicast routing table metric associated with the route used to The unicast routing table metric associated with the route used to
skipping to change at page 121, line 25 skipping to change at page 126, line 25
group and source(s) under contention on the shared tree. (*,G) group and source(s) under contention on the shared tree. (*,G)
asserts have the Group-Address field set to the group G. For data asserts have the Group-Address field set to the group G. For data
triggered Asserts the Source-Address field MAY be set to the IP triggered Asserts the Source-Address field MAY be set to the IP
source address of the data packet that triggered the Assert and is source address of the data packet that triggered the Assert and is
set to INADDR_ANY otherwise. The RPT-bit is set to 1, the Metric- set to INADDR_ANY otherwise. The RPT-bit is set to 1, the Metric-
Preference is set to MRIB.pref(RP(G)) and the Metric is set to Preference is set to MRIB.pref(RP(G)) and the Metric is set to
MRIB.metric(RP(G)). MRIB.metric(RP(G)).
4.11. PIM Timers 4.11. PIM Timers
PIM-SM maintains the following timers, as discussed in section 4.1. All PIM-SM maintains the following timers, as discussed in Section 4.1. All
timers are countdown timers - they are set to a value and count down to timers are countdown timers - they are set to a value and count down to
zero, at which point they typically trigger an action. Of course they zero, at which point they typically trigger an action. Of course they
can just as easily be implemented as count-up timers, where the absolute can just as easily be implemented as count-up timers, where the absolute
expiry time is stored and compared against a real-time clock, but the expiry time is stored and compared against a real-time clock, but the
language in this specification assumes that they count downwards to language in this specification assumes that they count downwards to
zero. zero.
Global Timers Global Timers
Per interface (I): Per interface (I):
Hello Timer: HT(I) Hello Timer: HT(I)
Per neighbor (N): Per neighbor (N):
Neighbor liveness Timer: NLT(N,I) Neighbor Liveness Timer: NLT(N,I)
Per active RP (RP): Per active RP (RP):
(*,*,RP) Join Expiry Timer: ET(*,*,RP,I) (*,*,RP) Join Expiry Timer: ET(*,*,RP,I)
(*,*,RP) PrunePending Timer: PPT(*,*,RP,I) (*,*,RP) Prune-Pending Timer: PPT(*,*,RP,I)
Per Group (G): Per Group (G):
(*,G) Join Expiry Timer: ET(*,G,I) (*,G) Join Expiry Timer: ET(*,G,I)
(*,G) PrunePending Timer: PPT(*,G,I) (*,G) Prune-Pending Timer: PPT(*,G,I)
(*,G) Assert Timer: AT(*,G,I) (*,G) Assert Timer: AT(*,G,I)
Per Source (S): Per Source (S):
(S,G) Join Expiry Timer: ET(S,G,I) (S,G) Join Expiry Timer: ET(S,G,I)
(S,G) PrunePending Timer: PPT(S,G,I) (S,G) Prune-Pending Timer: PPT(S,G,I)
(S,G) Assert Timer: AT(S,G,I) (S,G) Assert Timer: AT(S,G,I)
(S,G,rpt) Prune Expiry Timer: ET(S,G,rpt,I) (S,G,rpt) Prune Expiry Timer: ET(S,G,rpt,I)
(S,G,rpt) PrunePending Timer: PPT(S,G,rpt,I) (S,G,rpt) Prune-Pending Timer: PPT(S,G,rpt,I)
Per active RP (RP): Per active RP (RP):
(*,*,RP) Upstream Join Timer: JT(*,*,RP) (*,*,RP) Upstream Join Timer: JT(*,*,RP)
Per Group (G): Per Group (G):
(*,G) Upstream Join Timer: JT(*,G) (*,G) Upstream Join Timer: JT(*,G)
Per Source (S): Per Source (S):
skipping to change at page 122, line 43 skipping to change at page 127, line 43
(S,G) Upstream Join Timer: JT(S,G) (S,G) Upstream Join Timer: JT(S,G)
(S,G) Keepalive Timer: KAT(S,G) (S,G) Keepalive Timer: KAT(S,G)
(S,G,rpt) Upstream Override Timer: OT(S,G,rpt) (S,G,rpt) Upstream Override Timer: OT(S,G,rpt)
At the DRs or relevant Assert Winners only: At the DRs or relevant Assert Winners only:
Per Source,Group pair (S,G): Per Source,Group pair (S,G):
Register Stop Timer: RST(S,G) Register-Stop Timer: RST(S,G)
4.12. Timer Values 4.12. Timer Values
When timers are started or restarted, they are set to default values. When timers are started or restarted, they are set to default values.
This section summarizes those default values. This section summarizes those default values.
Note that protocol events or configuration may change the default value Note that protocol events or configuration may change the default value
of a timer on a specific interface. When timers are initialized in this of a timer on a specific interface. When timers are initialized in this
document the value specific to the interface in context must be used. document the value specific to the interface in context must be used.
Some of the timers listed below (Prune Pending, Upstream Join, Upstream Some of the timers listed below (Prune-Pending, Upstream Join, Upstream
Override) can be set to values which depend on the settings of the Override) can be set to values which depend on the settings of the
Propagation Delay and Override_Interval of the corresponding interface. Propagation Delay and Override_Interval of the corresponding interface.
The default values for these are given below. Note that the value of The default values for these are given below. Note that the value of
both the Propagation Delay and Override Interval of an interface can both the Propagation Delay and Override Interval of an interface can
change as a result of receiving Hello messages on that interface change as a result of receiving Hello messages on that interface
(section 4.3.3). (Section 4.3.3).
Variable Name: Propagation_Delay(I) Variable Name: Propagation_Delay(I)
+--------------------------+-----------------+--------------------------+ +--------------------------+-----------------+--------------------------+
| Value Name | Value | Explanation | | Value Name | Value | Explanation |
+--------------------------+-----------------+--------------------------+ +--------------------------+-----------------+--------------------------+
| LAN_delay_default | 0.5 sec | Expected | | LAN_delay_default | 0.5 sec | Expected |
| | | propagation delay | | | | propagation delay |
| | | over the local | | | | over the local |
| | | link. | | | | link. |
skipping to change at page 124, line 17 skipping to change at page 129, line 17
+----------------------+--------+---------------------------------------+ +----------------------+--------+---------------------------------------+
|Value Name | Value | Explanation | |Value Name | Value | Explanation |
+----------------------+--------+---------------------------------------+ +----------------------+--------+---------------------------------------+
|Hello_Period | 30 sec | Periodic interval for Hello messages. | |Hello_Period | 30 sec | Periodic interval for Hello messages. |
+----------------------+--------+---------------------------------------+ +----------------------+--------+---------------------------------------+
|Triggered_Hello_Delay | 5 sec | Randomized interval for initial Hello | |Triggered_Hello_Delay | 5 sec | Randomized interval for initial Hello |
| | | message on bootup or triggered Hello | | | | message on bootup or triggered Hello |
| | | message to a rebooting neighbor. | | | | message to a rebooting neighbor. |
+----------------------+--------+---------------------------------------+ +----------------------+--------+---------------------------------------+
At system power-up, the timer is initialized to At system power-up, the timer is initialized to rand(0,
rand(0,Triggered_Hello_Delay) to prevent synchronization. When a new or Triggered_Hello_Delay) to prevent synchronization. When a new or
rebooting neighbor is detected, a responding Hello is sent within rebooting neighbor is detected, a responding Hello is sent within
rand(0,Triggered_Hello_Delay). rand(0,Triggered_Hello_Delay).
Timer Name: Neighbor Liveness Timer (NLT(N,I)) Timer Name: Neighbor Liveness Timer (NLT(N,I))
+--------------------------+-----------------------+--------------------+ +--------------------------+-----------------------+--------------------+
| Value Name | Value | Explanation | | Value Name | Value | Explanation |
+--------------------------+-----------------------+--------------------+ +--------------------------+-----------------------+--------------------+
| Default_Hello_Holdtime | 3.5 * Hello_Period | Default holdtime | | Default_Hello_Holdtime | 3.5 * Hello_Period | Default holdtime |
| | | to keep neighbor | | | | to keep neighbor |
skipping to change at page 125, line 5 skipping to change at page 130, line 5
+----------------+-----------------+------------------------------------+ +----------------+-----------------+------------------------------------+
| Value Name | Value | Explanation | | Value Name | Value | Explanation |
+----------------+-----------------+------------------------------------+ +----------------+-----------------+------------------------------------+
| J/P_HoldTime | from message | Holdtime from Join/Prune Message | | J/P_HoldTime | from message | Holdtime from Join/Prune Message |
+----------------+-----------------+------------------------------------+ +----------------+-----------------+------------------------------------+
See details of JT(*,G) for the Holdtime that is included in Join/Prune See details of JT(*,G) for the Holdtime that is included in Join/Prune
Messages. Messages.
Timer Names: Prune Pending Timer (PPT(*,*,RP,I), PPT(*,G,I), PPT(S,G,I), Timer Names: Prune-Pending Timer (PPT(*,*,RP,I), PPT(*,G,I), PPT(S,G,I),
PPT(S,G,rpt,I)) PPT(S,G,rpt,I))
+--------------------------+-----------------------+--------------------+ +----------------------------+-------------------+----------------------+
|Value Name | Value | Explanation | |Value Name | Value | Explanation |
+--------------------------+-----------------------+--------------------+ +----------------------------+-------------------+----------------------+
|J/P_Override_Interval(I) | Default: | Short period after | |J/P_Override_Interval(I) | Default: | Short period after |
| | Propagation_Delay(I) | a join or prune to | | | Propagation_- | a join or prune to |
| | + | allow other | | | Delay(I) + | allow other |
| | Override_Interval(I) | routers on the LAN | | | Override_- | routers on the LAN |
| | | to override the | | | Interval(I) | to override the |
| | | join or prune | | | | join or prune |
+--------------------------+-----------------------+--------------------+ +----------------------------+-------------------+----------------------+
Note that both the Propagation_Delay(I) and the Override_Interval(I) are Note that both the Propagation_Delay(I) and the Override_Interval(I) are
interface specific values that may change when Hello messages are interface specific values that may change when Hello messages are
received. received.
Timer Names: Assert Timer (AT(*,G,I), AT(S,G,I)) Timer Names: Assert Timer (AT(*,G,I), AT(S,G,I))
+---------------------------+----------------------+--------------------+ +---------------------------+----------------------+--------------------+
| Value Name | Value | Explanation | | Value Name | Value | Explanation |
+---------------------------+----------------------+--------------------+ +---------------------------+----------------------+--------------------+
skipping to change at page 126, line 7 skipping to change at page 131, line 7
| | | assert state is | | | | assert state is |
| | | timed out | | | | timed out |
+---------------------------+----------------------+--------------------+ +---------------------------+----------------------+--------------------+
Note that for historical reasons, the Assert message lacks a Holdtime Note that for historical reasons, the Assert message lacks a Holdtime
field. Thus changing the Assert Time from the default value is not field. Thus changing the Assert Time from the default value is not
recommended. recommended.
Timer Names: Upstream Join Timer (JT(*,*,RP), JT(*,G), JT(S,G)) Timer Names: Upstream Join Timer (JT(*,*,RP), JT(*,G), JT(S,G))
+-------------+------------------------+-------------------------------------+ +-------------+--------------------+-------------------------------------+
|Value Name | Value | Explanation | |Value Name | Value | Explanation |
+-------------+------------------------+-------------------------------------+ +-------------+--------------------+-------------------------------------+
|t_periodic | Default: 60 secs | Period between Join/Prune Messages | |t_periodic | Default: 60 secs | Period between Join/Prune Messages |
+-------------+------------------------+-------------------------------------+ +-------------+--------------------+-------------------------------------+
|t_suppressed | rand(1.1 * | Suppression period when someone | |t_suppressed | rand(1.1 * | Suppression period when someone |
| | t_periodic, 1.4 * | else sends a J/P message so we | | | t_periodic, 1.4 * | else sends a J/P message so we |
| | t_periodic) when | don't need to do so. | | | t_periodic) when | don't need to do so. |
| | Suppression_Enabled(I) | | | | Suppression_- | |
| | is true, 0 | | | | Enabled(I) is | |
| | otherwise | | | | true, 0 otherwise | |
+-------------+------------------------+-------------------------------------+ +-------------+--------------------+-------------------------------------+
|t_override | rand(0, | Randomized delay to prevent | |t_override | rand(0, Override_- | Randomized delay to prevent |
| | Override_Interval(I)) | response implosion when sending a | | | Interval(I)) | response implosion when sending a |
| | | join message to override someone | | | | join message to override someone |
| | | else's Prune message. | | | | else's Prune message. |
+-------------+------------------------+-------------------------------------+ +-------------+--------------------+-------------------------------------+
t_periodic may be set to take into account such things as the configured t_periodic may be set to take into account such things as the configured
bandwidth and expected average number of multicast route entries for the bandwidth and expected average number of multicast route entries for the
attached network or link (e.g., the period would be longer for lower- attached network or link (e.g., the period would be longer for lower-
speed links, or for routers in the center of the network that expect to speed links, or for routers in the center of the network that expect to
have a larger number of entries). If the Join/Prune-Period is modified have a larger number of entries). If the Join/Prune-Period is modified
during operation, these changes should be made relatively infrequently during operation, these changes should be made relatively infrequently
and the router should continue to refresh at its previous Join/Prune- and the router should continue to refresh at its previous Join/Prune-
Period for at least Join/Prune-Holdtime, in order to allow the upstream Period for at least Join/Prune-Holdtime, in order to allow the upstream
router to adapt. router to adapt.
skipping to change at page 127, line 16 skipping to change at page 132, line 16
+---------------+---------------------------+---------------------------+ +---------------+---------------------------+---------------------------+
| Value Name | Value | Explanation | | Value Name | Value | Explanation |
+---------------+---------------------------+---------------------------+ +---------------+---------------------------+---------------------------+
| t_override | see Upstream Join Timer | see Upstream Join Timer | | t_override | see Upstream Join Timer | see Upstream Join Timer |
+---------------+---------------------------+---------------------------+ +---------------+---------------------------+---------------------------+
The upstream Override Timer is only ever set to t_override; this value The upstream Override Timer is only ever set to t_override; this value
is defined in the section on Upstream Join Timers. is defined in the section on Upstream Join Timers.
Timer Name: KeepAlive Timer (KAT(S,G)) Timer Name: Keepalive Timer (KAT(S,G))
+-----------------------+------------------------+----------------------+ +-----------------------+------------------------+----------------------+
| Value Name | Value | Explanation | | Value Name | Value | Explanation |
+-----------------------+------------------------+----------------------+ +-----------------------+------------------------+----------------------+
| Keepalive_Period | Default: 210 secs | Period after last | | Keepalive_Period | Default: 210 secs | Period after last |
| | | (S,G) data packet | | | | (S,G) data packet |
| | | during which (S,G) | | | | during which (S,G) |
| | | Join state will be | | | | Join state will be |
| | | maintained even in | | | | maintained even in |
| | | the absence of | | | | the absence of |
| | | (S,G) Join | | | | (S,G) Join |
| | | messages. | | | | messages. |
+-----------------------+------------------------+----------------------+ +-----------------------+------------------------+----------------------+
| RP_Keepalive_Period | ( 3 * Register_ | As | | RP_Keepalive_Period | ( 3 * Register_ | As |
| | Suppression_Time ) | Keepalive_Period, | | | Suppression_Time ) | Keepalive_Period, |
| | + Register_ | but at the RP when | | | + Register_ | but at the RP when |
| | Probe_Time | a RegisterStop is | | | Probe_Time | a Register-Stop is |
| | | sent. | | | | sent. |
+-----------------------+------------------------+----------------------+ +-----------------------+------------------------+----------------------+
The normal keepalive period for the KAT(S,G) defaults to 210 seconds. The normal keepalive period for the KAT(S,G) defaults to 210 seconds.
However at the RP, the keepalive period must be at least the However at the RP, the keepalive period must be at least the
Register_Suppression_Time or the RP may time out the (S,G) state before Register_Suppression_Time or the RP may time out the (S,G) state before
the next Null-Register arrives. Thus the KAT(S,G) is set to the next Null-Register arrives. Thus the KAT(S,G) is set to
max(Keepalive_Period, RP_Keepalive_Period). max(Keepalive_Period, RP_Keepalive_Period).
Timer Name: Register Stop Timer (RST(S,G)) Timer Name: Register-Stop Timer (RST(S,G))
+---------------------------+----------------------+--------------------+ +---------------------------+----------------------+--------------------+
|Value Name |Value | Explanation | |Value Name |Value | Explanation |
+---------------------------+----------------------+--------------------+ +---------------------------+----------------------+--------------------+
|Register_Suppression_Time |Default: 60 seconds | Period during | |Register_Suppression_Time |Default: 60 seconds | Period during |
| | | which a DR stops | | | | which a DR stops |
| | | sending Register- | | | | sending Register- |
| | | encapsulated data | | | | encapsulated data |
| | | to the RP after | | | | to the RP after |
| | | receiving a | | | | receiving a |
| | | RegisterStop | | | | Register-Stop |
| | | message. |
+---------------------------+----------------------+--------------------+ +---------------------------+----------------------+--------------------+
|Register_Probe_Time |Default: 5 seconds | Time before RST | |Register_Probe_Time |Default: 5 seconds | Time before RST |
| | | expires when a DR | | | | expires when a DR |
| | | may send a Null- | | | | may send a Null- |
| | | Register to the RP | | | | Register to the RP |
| | | to cause it to | | | | to cause it to |
| | | resend a | | | | resend a Register- |
| | | RegisterStop | | | | Stop message. |
| | | message. |
+---------------------------+----------------------+--------------------+ +---------------------------+----------------------+--------------------+
5. IANA Considerations 5. IANA Considerations
5.1. PIM Address Family 5.1. PIM Address Family
The PIM Address Family field was chosen to be 8 bits as a tradeoff The PIM Address Family field was chosen to be 8 bits as a tradeoff
between between packet format and use of the IANA assigned numbers. Since when
packet format and use of the IANA assigned numbers. Since when the PIM the PIM packet format was designed only 15 values were assigned for
packet format was designed only 15 values were assigned for Address Address Families, and large numbers of new Address Family values were
Families, and large numbers of new Address Family values were not not envisioned, 8 bits seemed large enough. However, the IANA assigns
envisioned, 8 bits seemed large enough. However, the IANA assigns
Address Families in a 16-bit field. Therefore, the PIM Address Family Address Families in a 16-bit field. Therefore, the PIM Address Family
is allocated as follows: is allocated as follows:
Values 0 through 127 are designated to have the same meaning as Values 0 through 127 are designated to have the same meaning as
IANA-assigned Address Family Numbers [11]. IANA-assigned Address Family Numbers [11].
Values 128 through 250 are designated to be assigned by the IANA Values 128 through 250 are designated to be assigned by the IANA
based upon IESG Approval, as defined in [13]. based upon IESG Approval, as defined in [13].
Values 251 through 255 are designated for Private Use, as defined Values 251 through 255 are designated for Private Use, as defined
skipping to change at page 129, line 25 skipping to change at page 134, line 25
The IPsec authentication header [12] MAY be used to provide data The IPsec authentication header [12] MAY be used to provide data
integrity protection and groupwise data origin authentication of PIM integrity protection and groupwise data origin authentication of PIM
protocol messages. Authentication of PIM messages can protect against protocol messages. Authentication of PIM messages can protect against
unwanted behaviors caused by unauthorized or altered PIM messages. unwanted behaviors caused by unauthorized or altered PIM messages.
6.1. Attacks based on forged messages 6.1. Attacks based on forged messages
The extent of possible damage depends on the type of counterfeit The extent of possible damage depends on the type of counterfeit
messages accepted. We next consider the impact of possible forgeries, messages accepted. We next consider the impact of possible forgeries,
including forged link-local (Join/Prune, Hello, and Assert) and forged including forged link-local (Join/Prune, Hello, and Assert) and forged
unicast (Register and RegisterStop) messages. unicast (Register and Register-Stop) messages.
6.1.1. Forged link-local messages 6.1.1. Forged link-local messages
Join/Prune, Hello, and Assert messages are all sent to the link-local Join/Prune, Hello, and Assert messages are all sent to the link-local
ALL_PIM_ROUTERS multicast addresses, and thus are not forwarded by a ALL_PIM_ROUTERS multicast addresses, and thus are not forwarded by a
compliant router. A forged message of this type can only reach a LAN if compliant router. A forged message of this type can only reach a LAN if
it was sent by a local host or if it was allowed onto the LAN by a it was sent by a local host or if it was allowed onto the LAN by a
compromised or non-compliant router. compromised or non-compliant router.
1. A forged Join/Prune message can cause multicast traffic to be 1. A forged Join/Prune message can cause multicast traffic to be
skipping to change at page 130, line 12 skipping to change at page 135, line 12
receive multicast traffic may be compromised by a forged Hello receive multicast traffic may be compromised by a forged Hello
message. message.
3. By forging an Assert message on a multi-access LAN, an attacker 3. By forging an Assert message on a multi-access LAN, an attacker
could cause the legitimate designated forwarder to stop forwarding could cause the legitimate designated forwarder to stop forwarding
traffic to the LAN. Such a forgery would prevent any hosts traffic to the LAN. Such a forgery would prevent any hosts
downstream of that LAN from receiving traffic. downstream of that LAN from receiving traffic.
6.1.2. Forged unicast messages 6.1.2. Forged unicast messages
Register messages and RegisterStop messages are forwarded by Register messages and Register-Stop messages are forwarded by
intermediate routers to their destination using normal IP forwarding. intermediate routers to their destination using normal IP forwarding.
Without data origin authentication, an attacker who is located anywhere Without data origin authentication, an attacker who is located anywhere
in the network may be able to forge a Register or RegisterStop message. in the network may be able to forge a Register or Register-Stop message.
We consider the effect of a forgery of each of these messages next. We consider the effect of a forgery of each of these messages next.
1 By forging a Register message, an attacker can cause the RP to 1 By forging a Register message, an attacker can cause the RP to
inject forged traffic onto the shared multicast tree. inject forged traffic onto the shared multicast tree.
2 By forging a Register-stop message, an attacker can prevent a 2 By forging a Register-stop message, an attacker can prevent a
legitimate DR from Registering packets to the RP. This can prevent legitimate DR from Registering packets to the RP. This can prevent
local hosts on that LAN from sending multicast packets. local hosts on that LAN from sending multicast packets.
The above two PIM messages are not changed by intermediate routers and The above two PIM messages are not changed by intermediate routers and
need only be examined by the intended receiver. Thus these messages can need only be examined by the intended receiver. Thus these messages can
be authenticated end-to-end, using AH. Attacks on Register and be authenticated end-to-end, using AH. Attacks on Register and
RegisterStop messages do not apply to a PIM-SSM-only implementation, as Register-Stop messages do not apply to a PIM-SSM-only implementation, as
these messages are not required for PIM-SSM. these messages are not required for PIM-SSM.
6.2. Non-cryptographic Authentication Mechanisms 6.2. Non-cryptographic Authentication Mechanisms
A PIM router SHOULD provide an option to limit the set of neighbors from A PIM router SHOULD provide an option to limit the set of neighbors from
which it will accept Join/Prune, Assert, and Hello messages. Either which it will accept Join/Prune, Assert, and Hello messages. Either
static configuration of IP addresses or an IPsec security association static configuration of IP addresses or an IPsec security association
may be used. Furthermore, a PIM router SHOULD NOT accept protocol may be used. Furthermore, a PIM router SHOULD NOT accept protocol
messages from a router from which it has not yet received a valid Hello messages from a router from which it has not yet received a valid Hello
message. message.
A Designated Router MUST NOT register-encapsulate a packet and send it A Designated Router MUST NOT register-encapsulate a packet and send it
to the RP unless the source address of the packet is a legal address for to the RP unless the source address of the packet is a legal address for
the subnet on which the packet was received. Similarly, a Designated the subnet on which the packet was received. Similarly, a Designated
Router SHOULD NOT accept a RegisterStop packet whose IP source address Router SHOULD NOT accept a Register-Stop packet whose IP source address
is not a valid RP address for the local domain. is not a valid RP address for the local domain.
An implementation SHOULD provide a mechanism to allow an RP to restrict An implementation SHOULD provide a mechanism to allow an RP to restrict
the range of source addresses from which it accepts Register- the range of source addresses from which it accepts Register-
encapsulated packets. encapsulated packets.
All options that restrict the range of addresses from which packets are All options that restrict the range of addresses from which packets are
accepted MUST default to allowing all packets. accepted MUST default to allowing all packets.
6.3. Authentication using IPsec 6.3. Authentication using IPsec
skipping to change at page 132, line 8 skipping to change at page 137, line 8
Association Database (SAD) for each router interface. Thus, the Association Database (SAD) for each router interface. Thus, the
selected Security Association for an inbound PIM packet can vary selected Security Association for an inbound PIM packet can vary
depending on the interface on which the packet arrived. This fact depending on the interface on which the packet arrived. This fact
allows the network administrator to use different authentication methods allows the network administrator to use different authentication methods
for each link, even though the destination address is the same for all for each link, even though the destination address is the same for all
link-local PIM packets, regardless of interface. link-local PIM packets, regardless of interface.
6.3.2. Protecting unicast messages 6.3.2. Protecting unicast messages
IPSec can also be used to provide data origin authentication and data IPSec can also be used to provide data origin authentication and data
integrity protection for the Register and RegisterStop unicast messages. integrity protection for the Register and Register-Stop unicast
messages.
6.3.2.1. Register messages 6.3.2.1. Register messages
The Security Policy Database at every PIM router is configured to select The Security Policy Database at every PIM router is configured to select
a Security Association to use when sending PIM Register packets to each a Security Association to use when sending PIM Register packets to each
rendezvous point. rendezvous point.
In the most general mode of operation, the Security Policy Database at In the most general mode of operation, the Security Policy Database at
each DR is configured to select a unique SA and SPI for traffic sent to each DR is configured to select a unique SA and SPI for traffic sent to
each RP. This allows each DR to have a different authentication each RP. This allows each DR to have a different authentication
skipping to change at page 132, line 40 skipping to change at page 137, line 41
select a Security Association (including the authentication algorithm, select a Security Association (including the authentication algorithm,
authentication parameters, and this SPI) when sending Register messages authentication parameters, and this SPI) when sending Register messages
to this RP. to this RP.
By using a single authentication algorithm and associated parameters, By using a single authentication algorithm and associated parameters,
the key distribution problem is simplified. Note however, that this the key distribution problem is simplified. Note however, that this
method has the property that, in order to change the authentication method has the property that, in order to change the authentication
method or authentication key used, all routers in the domain must be method or authentication key used, all routers in the domain must be
updated. updated.
6.3.2.2. Register Stop messages 6.3.2.2. Register-Stop messages
Similarly, the Security Policy Database at each Rendezvous Point should Similarly, the Security Policy Database at each Rendezvous Point should
be configured to choose a Security Association to use when sending be configured to choose a Security Association to use when sending
Register Stop messages. Because Register Stop messages are unicast to Register-Stop messages. Because Register-Stop messages are unicast to
the destination DR, a different Security Association and a potentially the destination DR, a different Security Association and a potentially
unique SPI is required for each DR. unique SPI is required for each DR.
In order to simplify the management problem, it may be acceptable to use In order to simplify the management problem, it may be acceptable to use
the same authentication algorithm and authentication parameters, the same authentication algorithm and authentication parameters,
regardless of the sending RP and regardless of the destination DR. regardless of the sending RP and regardless of the destination DR.
Although a unique Security Association is needed for each DR, the same Although a unique Security Association is needed for each DR, the same
authentication algorithm and authentication algorithm parameters (secret
authentication algorithm and authentication algorithm parameters (secret
key) can be shared by all DRs and by all RPs. key) can be shared by all DRs and by all RPs.
6.4. Denial of Service Attacks 6.4. Denial of Service Attacks
There are a number of possible denial of service attacks against PIM There are a number of possible denial of service attacks against PIM
that can be caused by generating false PIM protocol messages or even by that can be caused by generating false PIM protocol messages or even by
generating data false traffic. Authenticating PIM protocol traffic generating data false traffic. Authenticating PIM protocol traffic
prevents some, but not all of these attacks. Two of the possible prevents some, but not all of these attacks. Two of the possible
attacks include: attacks include:
skipping to change at page 134, line 18 skipping to change at page 139, line 18
kouvelas@cisco.com kouvelas@cisco.com
8. Acknowledgments 8. Acknowledgments
PIM-SM was designed over many years by a large group of people, PIM-SM was designed over many years by a large group of people,
including ideas, comments, and corrections from Deborah Estrin, Dino including ideas, comments, and corrections from Deborah Estrin, Dino
Farinacci, Ahmed Helmy, David Thaler, Steve Deering, Van Jacobson, C. Farinacci, Ahmed Helmy, David Thaler, Steve Deering, Van Jacobson, C.
Liu, Puneet Sharma, Liming Wei, Tom Pusateri, Tony Ballardie, Scott Liu, Puneet Sharma, Liming Wei, Tom Pusateri, Tony Ballardie, Scott
Brim, Jon Crowcroft, Paul Francis, Joel Halpern, Horst Hodel, Polly Brim, Jon Crowcroft, Paul Francis, Joel Halpern, Horst Hodel, Polly
Huang, Stephen Ostrowski, Lixia Zhang, Girish Chandranmenon, Brian Huang, Stephen Ostrowski, Lixia Zhang, Girish Chandranmenon, Brian
Haberman, Hal Sandick, Mike Mroz and Garry Kump. Haberman, Hal Sandick, Mike Mroz, Garry Kump, Pavlin Radoslavov and Mike
Davison.
Thanks are due to the American Licorice Company, for its obscure but Thanks are due to the American Licorice Company, for its obscure but
possibly essential role in the creation of this document. possibly essential role in the creation of this document.
9. References 9. References
[1] T. Bates , R. Chandra , D. Katz , Y. Rekhter, "Multiprotocol [1] T. Bates , R. Chandra , D. Katz , Y. Rekhter, "Multiprotocol
Extensions for BGP-4", RFC 2283 Extensions for BGP-4", RFC 2283
[2] D. Black, "Differentiated Services and Tunnels", RFC 2983. [2] D. Black, "Differentiated Services and Tunnels", RFC 2983.
skipping to change at page 136, line 6 skipping to change at page 141, line 6
[12] S. Kent, R. Atkinson, "Security Architecture for the Internet [12] S. Kent, R. Atkinson, "Security Architecture for the Internet
Protocol.", RFC 2401. Protocol.", RFC 2401.
[13] T. Narten , H. Alvestrand, "Guidelines for Writing an IANA [13] T. Narten , H. Alvestrand, "Guidelines for Writing an IANA
Considerations Section in RFCs", RFC 2434. Considerations Section in RFCs", RFC 2434.
[14] D. Thaler, "Interoperability Rules for Multicast Routing [14] D. Thaler, "Interoperability Rules for Multicast Routing
Protocols", RFC 2715. Protocols", RFC 2715.
10. Index 10. Index
Assert(*,G). . . . . . . . . . . . . . . . . . . . . . . . . . . .26,121 Assert(*,G). . . . . . . . . . . . . . . . . . . . . . . . . . . .26,126
Assert(S,G). . . . . . . . . . . . . . . . . . . . . . . . . . . .26,121 Assert(S,G). . . . . . . . . . . . . . . . . . . . . . . . . . . .26,126
AssertCancel(*,G). . . . . . . . . . . . . . . . . . . . . . . . . 90,92 AssertCancel(*,G). . . . . . . . . . . . . . . . . . . . . . . . . 94,96
AssertCancel(S,G). . . . . . . . . . . . . . . . . . . . . . . .75,84,92 AssertCancel(S,G). . . . . . . . . . . . . . . . . . . . . . . .77,87,96
AssertTimer(*,G,I) . . . . . . . . . . . . . . . . . . . . .16,24,84,125 AssertTimer(*,G,I) . . . . . . . . . . . . . . . . . . . . .16,24,87,130
AssertTimer(S,G,I) . . . . . . . . . . . . . . . . . . . . .18,24,77,125 AssertTimer(S,G,I) . . . . . . . . . . . . . . . . . . . . .18,24,81,130
AssertTrackingDesired(*,G,I) . . . . . . . . . . . . . . . . . .87,88,90 AssertTrackingDesired(*,G,I) . . . . . . . . . . . . . . . . . .90,91,93
AssertTrackingDesired(S,G,I) . . . . . . . . . . . . . . . . 79,79,81,83 AssertTrackingDesired(S,G,I) . . . . . . . . . . . . . . . . 82,82,84,86
AssertWinner(*,G,I). . . . . . . . . . . . . . . . . . . .21,24,87,90,94 AssertWinner(*,G,I). . . . . . . . . . . . . . . . . . . .21,24,90,93,97
AssertWinner(S,G,I). . . . . . . . . . . . . . . . . . 21,24,79,83,93,94 AssertWinner(S,G,I). . . . . . . . . . . . . . . . . . 21,24,82,86,96,97
AssertWinnerMetric(*,G,I). . . . . . . . . . . . . . . . . . . . . 90,94 AssertWinnerMetric(*,G,I). . . . . . . . . . . . . . . . . . . . . 93,97
AssertWinnerMetric(S,G,I). . . . . . . . . . . . . . . . . . . . . 83,94 AssertWinnerMetric(S,G,I). . . . . . . . . . . . . . . . . . . . . 86,97
assert_metric. . . . . . . . . . . . . . . . . . . . . . . . . . . . 91 assert_metric. . . . . . . . . . . . . . . . . . . . . . . . . . . . 94
Assert_Override_Interval . . . . . . . . . . . . . . . . . . . 83,90,125 Assert_Override_Interval . . . . . . . . . . . . . . . . . . . 86,93,130
Assert_Time. . . . . . . . . . . . . . . . . . . . . . . . . . 83,90,125 Assert_Time. . . . . . . . . . . . . . . . . . . . . . . . . . 86,93,130
AT(*,G,I). . . . . . . . . . . . . . . . . . . . . . . .16,24,84,122,125 AT(*,G,I). . . . . . . . . . . . . . . . . . . . . . . .16,24,87,127,130
AT(S,G,I). . . . . . . . . . . . . . . . . . . . . . . .18,24,77,122,125 AT(S,G,I). . . . . . . . . . . . . . . . . . . . . . . .18,24,81,127,130
CheckSwitchToSpt(S,G). . . . . . . . . . . . . . . . . . . . . . . 26,27 CheckSwitchToSpt(S,G). . . . . . . . . . . . . . . . . . . . . . . 26,27
CouldAssert(*,G,I) . . . . . . . . . . . . . . . . . . . .85,87,88,89,91 CouldAssert(*,G,I) . . . . . . . . . . . . . . . . . . . .88,90,91,92,95
CouldAssert(S,G,I) . . . . . . . . . . . . . . . . . . 78,79,81,82,83,91 CouldAssert(S,G,I) . . . . . . . . . . . . . . . . . . 81,82,84,85,86,95
CouldRegister(S,G) . . . . . . . . . . . . . . . . . . . . . . . . 36,38 CouldRegister(S,G) . . . . . . . . . . . . . . . . . . . . . . . . 37,39
Default_Hello_Holdtime . . . . . . . . . . . . . . . . . . . . . . . 31 Default_Hello_Holdtime . . . . . . . . . . . . . . . . . . . . . . . 31
DirectlyConnected(S) . . . . . . . . . . . . . . . . . . .26,26,28,38,97 DirectlyConnected(S) . . . . . . . . . . . . . . . . . . 26,26,28,39,100
DownstreamJPState(*,*,RP,I). . . . . . . . . . . . . . . . . . . . 22,98 DownstreamJPState(*,*,RP,I). . . . . . . . . . . . . . . . . . . .22,101
DownstreamJPState(*,G,I) . . . . . . . . . . . . . . . . . . . . . . 22 DownstreamJPState(*,G,I) . . . . . . . . . . . . . . . . . . . . . . 22
DownstreamJPState(S,G,I) . . . . . . . . . . . . . . . . . . . . . 22,38 DownstreamJPState(S,G,I) . . . . . . . . . . . . . . . . . . . . . 22,39
DownstreamJPState(S,G,rpt,I) . . . . . . . . . . . . . . . . . . . . 23 DownstreamJPState(S,G,rpt,I) . . . . . . . . . . . . . . . . . . . . 23
DR(I). . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31 DR(I). . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
dr_is_better(a,b,I). . . . . . . . . . . . . . . . . . . . . . . . 31,32 dr_is_better(a,b,I). . . . . . . . . . . . . . . . . . . . . . . . 32,32
DR_priority. . . . . . . . . . . . . . . . . . . . . . . . . . . . 31,32 DR_priority. . . . . . . . . . . . . . . . . . . . . . . . . . . . 31,32
ET(*,*,RP,I) . . . . . . . . . . . . . . . . . . . . . . . 15,42,121,124 ET(*,*,RP,I) . . . . . . . . . . . . . . . . . . . . . . . 15,43,126,129
ET(*,G,I). . . . . . . . . . . . . . . . . . . . . . . . . 16,46,122,124 ET(*,G,I). . . . . . . . . . . . . . . . . . . . . . . . . 16,47,127,129
ET(S,G,I). . . . . . . . . . . . . . . . . . . . . . . . . 18,50,122,124 ET(S,G,I). . . . . . . . . . . . . . . . . . . . . . . . . 18,51,127,129
ET(S,G,rpt,I). . . . . . . . . . . . . . . . . . . . . .19,53,55,122,124 ET(S,G,rpt,I). . . . . . . . . . . . . . . . . . . . . .19,54,56,127,129
GenID. . . . . . . . . . . . . . . . . . . 16,17,19,30,59,63,66,68,78,85 GenID. . . . . . . . . . . . . . . . . . . 16,17,19,30,61,65,68,70,81,88
Hash_Function. . . . . . . . . . . . . . . . . . . . . . . . . . .13,101 Hash_Function. . . . . . . . . . . . . . . . . . . . . . . . . . .13,104
Hello_Holdtime . . . . . . . . . . . . . . . . . . . . . . . . . .31,124 Hello_Holdtime . . . . . . . . . . . . . . . . . . . . . . . . . .31,129
Hello_Period . . . . . . . . . . . . . . . . . . . . . . . . . . .29,124 Hello_Period . . . . . . . . . . . . . . . . . . . . . . . . . . .29,129
HT(I). . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .29,124 HT(I). . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .29,129
IGMP . . . . . . . . . . . . . . . . . . . . . . . . . .7,9,17,22,95,100 IGMP . . . . . . . . . . . . . . . . . . . . . . . . . .7,9,17,22,98,104
immediate_olist(*,*,RP). . . . . . . . . . . . . . . . . . . . . . 21,60 immediate_olist(*,*,RP). . . . . . . . . . . . . . . . . . . . . . 21,61
immediate_olist(*,G) . . . . . . . . . . . . . . . . . . . . . . . 21,64 immediate_olist(*,G) . . . . . . . . . . . . . . . . . . . . . . . 21,66
immediate_olist(S,G) . . . . . . . . . . . . . . . . . . . . . .21,38,68 immediate_olist(S,G) . . . . . . . . . . . . . . . . . . . . . .21,39,70
infinite_assert_metric() . . . . . . . . . . . . . . . . . . . . . . 92 infinite_assert_metric() . . . . . . . . . . . . . . . . . . . . . . 95
inherited_olist(S,G) . . . . . . . . . . . . . . . . .21,26,40,68,79,103 inherited_olist(S,G) . . . . . . . . . . . . . . . . .21,26,41,70,82,107
inherited_olist(S,G,rpt) . . . . . . . . . . . . . . . 21,26,28,72,74,76 inherited_olist(S,G,rpt) . . . . . . . . . . . . . . . 21,26,28,74,76,78
I_Am_Assert_Loser(*,G,I) . . . . . . . . . . . . . . . . . . . . . . 24 Interface_Address_List . . . . . . . . . . . . . . . . . . . . . . . 30
I_Am_Assert_Loser(*,G,I) . . . . . . . . . . . . . . . . . . . . . . 24
I_Am_Assert_Loser(S,G,I) . . . . . . . . . . . . . . . . . . . . . . 24 I_Am_Assert_Loser(S,G,I) . . . . . . . . . . . . . . . . . . . . . . 24
I_am_DR(I) . . . . . . . . . . . . . . . . . . . . . . . .21,32,38,79,87 I_am_DR(I) . . . . . . . . . . . . . . . . . . . . . . . .21,32,39,82,90
I_am_RP(G) . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40,40 I_am_RP(G) . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41,41
J/P_Holdtime . . . . . . . . . . . . . .43,48,51,55,61,65,70,114,124,126 J/P_Holdtime . . . . . . . . . . . . . .44,49,52,56,62,67,72,119,129,131
J/P_Override_Interval(I) . . . . . . . . . . . . . . 44,48,51,55,114,125 J/P_Override_Interval(I) . . . . . . . . . . . . . . 45,49,52,56,119,130
JoinDesired(*,*,RP). . . . . . . . . . . . . . . . . . . . . . . . 60,73 JoinDesired(*,*,RP). . . . . . . . . . . . . . . . . . . . . . . . 61,75
JoinDesired(*,G) . . . . . . . . . . . . . . . . . . . . .17,64,73,79,91 JoinDesired(*,G) . . . . . . . . . . . . . . . . . . . . .17,66,75,82,94
JoinDesired(S,G) . . . . . . . . . . . . . . . . . . . 18,28,68,79,82,84 JoinDesired(S,G) . . . . . . . . . . . . . . . . . . . 18,28,70,82,85,87
joins(*,*,RP(G)) . . . . . . . . . . . . . . . . . . . . . . . . . . 21 joins(*,*,RP(G)) . . . . . . . . . . . . . . . . . . . . . . . . . . 21
joins(*,*,RP). . . . . . . . . . . . . . . . . . . . . . . . 21,22,79,87 joins(*,*,RP). . . . . . . . . . . . . . . . . . . . . . . . 21,22,82,90
joins(*,G) . . . . . . . . . . . . . . . . . . . . . . . . . 21,22,79,87 joins(*,G) . . . . . . . . . . . . . . . . . . . . . . . . . 21,22,82,90
joins(S,G) . . . . . . . . . . . . . . . . . . . . . . . . . . .21,22,79 joins(S,G) . . . . . . . . . . . . . . . . . . . . . . . . . . .21,22,82
JT(*,*,RP) . . . . . . . . . . . . . . . . . . . . . . . . 15,58,122,126 JT(*,*,RP) . . . . . . . . . . . . . . . . . . . . . . . . 15,59,127,131
JT(*,G). . . . . . . . . . . . . . . . . . . . . . . . . . 16,62,122,126 JT(*,G). . . . . . . . . . . . . . . . . . . . . . . . . . 16,64,127,131
JT(S,G). . . . . . . . . . . . . . . . . . . . . . . . . . 18,67,122,126 JT(S,G). . . . . . . . . . . . . . . . . . . . . . . . . . 18,69,127,131
KAT(S,G) . . . . . . . . . . . . . . . .18,25,26,27,38,40,68,103,122,127 KAT(S,G) . . . . . . . . . . . . . . . .18,25,26,27,39,41,70,107,127,132
KeepaliveTimer(S,G). . . . . . . . . 18,25,26,26,27,38,40,68,103,122,127 KeepaliveTimer(S,G). . . . . . . . . 18,25,26,26,27,39,41,70,107,127,132
Keepalive_Period . . . . . . . . . . . . . . . . . . . . . . . . .26,127 Keepalive_Period . . . . . . . . . . . . . . . . . . . . . . . . .26,132
LAN_delay_default. . . . . . . . . . . . . . . . . . . . . . . . .34,123 LAN_delay_default. . . . . . . . . . . . . . . . . . . . . . . . .34,128
lan_delay_enabled(I) . . . . . . . . . . . . . . . . . . . . . . . 33,35 lan_delay_enabled(I) . . . . . . . . . . . . . . . . . . . . . . . 33,35
LAN_Prune_Delay. . . . . . . . . . . . . . . . . . . . . . . . . . . 30 LAN_Prune_Delay. . . . . . . . . . . . . . . . . . . . . . . . . . . 30
local_receiver_exclude(S,G,I). . . . . . . . . . . . . . . . . . . . 22 local_receiver_exclude(S,G,I). . . . . . . . . . . . . . . . . . . . 22
local_receiver_include(*,G,I). . . . . . . . . . . . . . . . . .22,87,98 local_receiver_include(*,G,I). . . . . . . . . . . . . . . . . 22,90,101
local_receiver_include(S,G,I). . . . . . . . . . . . . . . . . .22,79,98 local_receiver_include(S,G,I). . . . . . . . . . . . . . . . . . . 22,82
lost_assert(*,G) . . . . . . . . . . . . . . . . . . . . . . . .21,23,79 local_receiver_include(S,G,I). . . . . . . . . . . . . . . . . . . . 101
lost_assert(*,G,I) . . . . . . . . . . . . . . . . . . . . . . .21,23,94 lost_assert(*,G) . . . . . . . . . . . . . . . . . . . . . . . .21,23,82
lost_assert(*,G,I) . . . . . . . . . . . . . . . . . . . . . . .21,23,97
lost_assert(S,G) . . . . . . . . . . . . . . . . . . . . . . . . . 21,23 lost_assert(S,G) . . . . . . . . . . . . . . . . . . . . . . . . . 21,23
lost_assert(S,G,I) . . . . . . . . . . . . . . . . . . . . . . .21,23,93 lost_assert(S,G,I) . . . . . . . . . . . . . . . . . . . . . . .21,23,96
lost_assert(S,G,rpt) . . . . . . . . . . . . . . . . . . . . . . . . 23 lost_assert(S,G,rpt) . . . . . . . . . . . . . . . . . . . . . . . . 23
lost_assert(S,G,rpt,I) . . . . . . . . . . . . . . . . . . . . . . 23,93 lost_assert(S,G,rpt,I) . . . . . . . . . . . . . . . . . . . . . . 23,96
MBGP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7,8 MBGP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7,8
MFIB . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .7,13 MFIB . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .7,13
MLD. . . . . . . . . . . . . . . . . . . . . . . . . . .7,9,17,22,95,100 MLD. . . . . . . . . . . . . . . . . . . . . . . . . . .7,9,17,22,98,104
MRIB . . . . . . . . . . . . . . . 7,8,12,16,19,24,58,61,62,71,92,99,121 MRIB . . . . . . . . . . . . . . .7,8,12,16,19,24,59,62,63,73,95,102,126
MRIB.next_hop(host). . . . . . . . . . . . . . . . .24,24,58,59,63,68,96 MRIB.next_hop(host). . . . . . . . . . . . . . . . . . . . . 24,24,59,61
my_assert_metric(S,G,I). . . . . . . . . . . . . . . . . .79,83,85,87,91 my_assert_metric(S,G,I). . . . . . . . . . . . . . . . . .82,86,88,90,95
NLT(N,I) . . . . . . . . . . . . . . . . . . . . . . . . . 15,31,121,124 NBR(Interface,IP_address). . . . . . . . . . . . . . . . .25,35,59,61,62
OT(S,G,rpt). . . . . . . . . . . . . . . . . . . . . . . . 20,72,122,127 NLT(N,I) . . . . . . . . . . . . . . . . . . . . . . . . . 15,31,126,129
Override_Interval(I) . . . . . . . . . . . . . . 14,30,33,34,109,123,125 OT(S,G,rpt). . . . . . . . . . . . . . . . . . . . . . . . 20,74,127,132