draft-ietf-pim-sm-v2-new-01.txt   draft-ietf-pim-sm-v2-new-02.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-01.txt Mark Handley/ACIRI draft-ietf-pim-sm-v2-new-02.txt Mark Handley/ACIRI
Hugh Holbrook/Cisco Hugh Holbrook/Cisco
Isidor Kouvelas/Cisco Isidor Kouvelas/Cisco
24 November 2000 2 March 2001
Expires: May 2001 Expires: September 2001
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 16 skipping to change at page 3, line 16
1. Introduction. . . . . . . . . . . . . . . . . . . . . . . . . . . 5 1. Introduction. . . . . . . . . . . . . . . . . . . . . . . . . . . 5
2. Terminology . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 2. Terminology . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
2.1. Definitions. . . . . . . . . . . . . . . . . . . . . . . . . . 5 2.1. Definitions. . . . . . . . . . . . . . . . . . . . . . . . . . 5
2.2. Pseudocode Notation. . . . . . . . . . . . . . . . . . . . . . 6 2.2. Pseudocode Notation. . . . . . . . . . . . . . . . . . . . . . 6
3. PIM-SM Protocol Overview. . . . . . . . . . . . . . . . . . . . . 7 3. PIM-SM Protocol Overview. . . . . . . . . . . . . . . . . . . . . 7
4. Protocol Specification. . . . . . . . . . . . . . . . . . . . . . 12 4. Protocol Specification. . . . . . . . . . . . . . . . . . . . . . 12
4.1. PIM Protocol State . . . . . . . . . . . . . . . . . . . . . . 12 4.1. PIM Protocol State . . . . . . . . . . . . . . . . . . . . . . 12
4.1.1. General Purpose State . . . . . . . . . . . . . . . . . . . 13 4.1.1. General Purpose State . . . . . . . . . . . . . . . . . . . 13
4.1.2. (*,*,RP) State. . . . . . . . . . . . . . . . . . . . . . . 14 4.1.2. (*,*,RP) State. . . . . . . . . . . . . . . . . . . . . . . 14
4.1.3. (*,G) State . . . . . . . . . . . . . . . . . . . . . . . . 15 4.1.3. (*,G) State . . . . . . . . . . . . . . . . . . . . . . . . 14
4.1.4. (S,G) State . . . . . . . . . . . . . . . . . . . . . . . . 16 4.1.4. (S,G) State . . . . . . . . . . . . . . . . . . . . . . . . 16
4.1.5. (S,G,rpt) State . . . . . . . . . . . . . . . . . . . . . . 18 4.1.5. (S,G,rpt) State . . . . . . . . . . . . . . . . . . . . . . 18
4.1.6. State Summarization Macros. . . . . . . . . . . . . . . . . 19 4.1.6. State Summarization Macros. . . . . . . . . . . . . . . . . 19
4.2. Data Packet Forwarding Rules . . . . . . . . . . . . . . . . . 23 4.2. Data Packet Forwarding Rules . . . . . . . . . . . . . . . . . 23
4.2.1. Setting and Clearing the (S,G) SPT bit. . . . . . . . . . . 25 4.2.1. Setting and Clearing the (S,G) SPT bit. . . . . . . . . . . 25
4.3. PIM Register Messages. . . . . . . . . . . . . . . . . . . . . 27 4.3. PIM Register Messages. . . . . . . . . . . . . . . . . . . . . 26
4.3.1. Sending Register Messages from the DR . . . . . . . . . . . 27 4.3.1. Sending Register Messages from the DR . . . . . . . . . . . 26
4.3.2. Receiving Register Messages at the RP . . . . . . . . . . . 29 4.3.2. Receiving Register Messages at the RP . . . . . . . . . . . 30
4.4. PIM Join/Prune Messages. . . . . . . . . . . . . . . . . . . . 31 4.4. PIM Join/Prune Messages. . . . . . . . . . . . . . . . . . . . 31
4.4.1. Receiving (*,*,RP) Join/Prune Messages. . . . . . . . . . . 31 4.4.1. Receiving (*,*,RP) Join/Prune Messages. . . . . . . . . . . 31
4.4.2. Receiving (*,G) Join/Prune Messages . . . . . . . . . . . . 34 4.4.2. Receiving (*,G) Join/Prune Messages . . . . . . . . . . . . 35
4.4.3. Receiving (S,G) Join/Prune Messages . . . . . . . . . . . . 38 4.4.3. Receiving (S,G) Join/Prune Messages . . . . . . . . . . . . 39
4.4.4. Receiving (S,G,rpt) Join/Prune Messages . . . . . . . . . . 42 4.4.4. Receiving (S,G,rpt) Join/Prune Messages . . . . . . . . . . 43
4.4.5. Sending (*,*,RP) Join/Prune Messages. . . . . . . . . . . . 47 4.4.5. Sending (*,*,RP) Join/Prune Messages. . . . . . . . . . . . 48
4.4.6. Sending (*,G) Join/Prune Messages . . . . . . . . . . . . . 52 4.4.6. Sending (*,G) Join/Prune Messages . . . . . . . . . . . . . 53
4.4.7. Sending (S,G) Join/Prune Messages . . . . . . . . . . . . . 56 4.4.7. Sending (S,G) Join/Prune Messages . . . . . . . . . . . . . 57
4.4.8. (S,G,rpt) Periodic Messages . . . . . . . . . . . . . . . . 61 4.4.8. (S,G,rpt) Periodic Messages . . . . . . . . . . . . . . . . 62
4.4.9. State Machine for (S,G,rpt) Triggered 4.4.9. State Machine for (S,G,rpt) Triggered
Messages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62 Messages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
4.5. PIM Assert Messages. . . . . . . . . . . . . . . . . . . . . . 66 4.5. PIM Assert Messages. . . . . . . . . . . . . . . . . . . . . . 67
4.5.1. (S,G) Assert Message State Machine. . . . . . . . . . . . . 66 4.5.1. (S,G) Assert Message State Machine. . . . . . . . . . . . . 67
4.5.2. (*,G) Assert Message State Machine. . . . . . . . . . . . . 73 4.5.2. (*,G) Assert Message State Machine. . . . . . . . . . . . . 74
4.5.3. Assert Metrics. . . . . . . . . . . . . . . . . . . . . . . 79 4.5.3. Assert Metrics. . . . . . . . . . . . . . . . . . . . . . . 80
4.5.4. AssertCancel Messages . . . . . . . . . . . . . . . . . . . 81 4.5.4. AssertCancel Messages . . . . . . . . . . . . . . . . . . . 82
4.5.5. Assert State Macros . . . . . . . . . . . . . . . . . . . . 81 4.5.5. Assert State Macros . . . . . . . . . . . . . . . . . . . . 82
4.6. Designated Routers (DR) and Hello Messages . . . . . . . . . . 83 4.6. Designated Routers (DR) and Hello Messages . . . . . . . . . . 84
4.6.1. Sending Hello Messages. . . . . . . . . . . . . . . . . . . 83 4.6.1. Sending Hello Messages. . . . . . . . . . . . . . . . . . . 84
4.6.2. DR Election . . . . . . . . . . . . . . . . . . . . . . . . 84 4.6.2. DR Election . . . . . . . . . . . . . . . . . . . . . . . . 85
4.7. PIM Bootstrap and RP Discovery . . . . . . . . . . . . . . . . 86 4.7. PIM Bootstrap and RP Discovery . . . . . . . . . . . . . . . . 87
4.7.1. Overview of RP Discovery. . . . . . . . . . . . . . . . . . 86 4.7.1. Group-to-RP Mapping . . . . . . . . . . . . . . . . . . . . 88
4.7.2. Bootstrap Router Election and RP-Set 4.7.2. Hash Function . . . . . . . . . . . . . . . . . . . . . . . 89
Distribution . . . . . . . . . . . . . . . . . . . . . . . . . . . 87 4.8. Source-Specific Multicast. . . . . . . . . . . . . . . . . . . 90
4.7.3. Sending Candidate-RP-Advertisements . . . . . . . . . . . . 92
4.7.4. Receiving Candidate-RP-Advertisements at
the BSR and Creating the RP-Set. . . . . . . . . . . . . . . . . . 93
4.7.5. Receiving and Using the RP-Set. . . . . . . . . . . . . . . 94
4.8. Source-Specific Multicast. . . . . . . . . . . . . . . . . . . 95
4.8.1. Protocol Modifications for SSM destination 4.8.1. Protocol Modifications for SSM destination
addresses. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95 addresses. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90
4.8.2. PIM-SSM-only Routers. . . . . . . . . . . . . . . . . . . . 96 4.8.2. PIM-SSM-only Routers. . . . . . . . . . . . . . . . . . . . 91
4.9. PIM Packet Formats . . . . . . . . . . . . . . . . . . . . . . 97 4.9. PIM Packet Formats . . . . . . . . . . . . . . . . . . . . . . 92
4.9.1. Encoded Source and Group Address Formats. . . . . . . . . . 98 4.9.1. Encoded Source and Group Address Formats. . . . . . . . . . 93
4.9.2. Hello Message Format. . . . . . . . . . . . . . . . . . . . 101 4.9.2. Hello Message Format. . . . . . . . . . . . . . . . . . . . 96
4.9.3. Register Message Format . . . . . . . . . . . . . . . . . . 104 4.9.3. Register Message Format . . . . . . . . . . . . . . . . . . 99
4.9.4. Register-Stop Message Format. . . . . . . . . . . . . . . . 105 4.9.4. Register-Stop Message Format. . . . . . . . . . . . . . . . 100
4.9.5. Join/Prune Message Format . . . . . . . . . . . . . . . . . 105 4.9.5. Join/Prune Message Format . . . . . . . . . . . . . . . . . 101
4.9.6. Bootstrap Message Format. . . . . . . . . . . . . . . . . . 109 4.9.5.1. Group Set Source List Rules. . . . . . . . . . . . . . . 104
4.9.7. Assert Message Format . . . . . . . . . . . . . . . . . . . 112 4.9.5.2. Group Set Fragmentation. . . . . . . . . . . . . . . . . 107
4.9.8. Candidate-RP-Advertisement Format . . . . . . . . . . . . . 113 4.9.6. Assert Message Format . . . . . . . . . . . . . . . . . . . 108
4.10. PIM Timers. . . . . . . . . . . . . . . . . . . . . . . . . . 114 4.10. PIM Timers. . . . . . . . . . . . . . . . . . . . . . . . . . 109
4.11. Timer Values. . . . . . . . . . . . . . . . . . . . . . . . . 116 4.11. Timer Values. . . . . . . . . . . . . . . . . . . . . . . . . 110
5. IANA Considerations . . . . . . . . . . . . . . . . . . . . . . . 122 5. IANA Considerations . . . . . . . . . . . . . . . . . . . . . . . 115
5.1. PIM Address Family . . . . . . . . . . . . . . . . . . . . . . 122 5.1. PIM Address Family . . . . . . . . . . . . . . . . . . . . . . 115
5.2. PIM Hello Options. . . . . . . . . . . . . . . . . . . . . . . 123 5.2. PIM Hello Options. . . . . . . . . . . . . . . . . . . . . . . 116
6. Security Considerations . . . . . . . . . . . . . . . . . . . . . 123 6. Security Considerations . . . . . . . . . . . . . . . . . . . . . 116
7. Authors' Addresses. . . . . . . . . . . . . . . . . . . . . . . . 123 7. Authors' Addresses. . . . . . . . . . . . . . . . . . . . . . . . 116
8. Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . . . 124 8. Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . . . 117
9. References. . . . . . . . . . . . . . . . . . . . . . . . . . . . 124 9. References. . . . . . . . . . . . . . . . . . . . . . . . . . . . 117
10. Index. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125 10. Index. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119
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 6, line 5 skipping to change at page 6, line 5
can discover who the senders are, and start to receive traffic can discover who the senders are, and start to receive traffic
destined for the group. destined for the group.
Designated Router (DR): Designated Router (DR):
A shared-media LAN like Ethernet may have multiple PIM-SM routers A shared-media LAN like Ethernet may have multiple PIM-SM routers
connected to it. If the LAN has directly connected hosts, then a connected to it. If the LAN has directly connected hosts, then a
single one of these routers, the DR, will act on behalf of those single one of these routers, the DR, will act on behalf of those
hosts with respect to the PIM-SM protocol. A single DR is elected hosts with respect to the PIM-SM protocol. A single DR is elected
per LAN using a simple election process. per LAN using a simple election process.
MRIB Multicast Routing Information Base. This is the multicast | MRIB Multicast Routing Information Base. This is the multicast
topology table, which is typically derived from the unicast | topology table, which is typically derived from the unicast
routing table, or routing protocols such as MBGP that carry | routing table, or routing protocols such as MBGP that carry
multicast-specific topology information. In PIM-SM this is used | multicast-specific topology information. In PIM-SM this is used
to make decisions regarding where to forward Join/Prune messages. | to make decisions regarding where to forward Join/Prune messages.
RPF Neighbor RPF Neighbor
RPF stands for "Reverse Path Forwarding". The RPF Neighbor of a RPF stands for "Reverse Path Forwarding". The RPF Neighbor of a
router with respect to an address is the neighbor that the MRIB router with respect to an address is the neighbor that the MRIB
indicates should be used to forward packets to that address. In indicates should be used to forward packets to that address. In
the case of a PIM-SM multicast group, the RPF neighbor is the the case of a PIM-SM multicast group, the RPF neighbor is the
router that a Join message for that group would be directed to, in router that a Join message for that group would be directed to, in
the absence of modifying Assert state. the absence of modifying Assert state.
TIB Tree Information Base. This is the collection of state at a PIM TIB Tree Information Base. This is the collection of state at a PIM
skipping to change at page 8, line 5 skipping to change at page 8, line 5
In phase one, a multicast receiver expresses its interest in receiving In phase one, a multicast receiver expresses its interest in receiving
traffic destined for a multicast group. Typically it does this using traffic destined for a multicast group. Typically it does this using
IGMP [3], but other mechanisms might also serve this purpose. One of IGMP [3], but other mechanisms might also serve this purpose. One of
the receiver's local routers is elected as the Designated Router (DR) the receiver's local routers is elected as the Designated Router (DR)
for that subnet. On receiving the receiver's expression of interest, for that subnet. On receiving the receiver's expression of interest,
the DR then sends a PIM Join message towards the RP for that multicast the DR then sends a PIM Join message towards the RP for that multicast
group. This Join message is known as a (*,G) Join because it joins group. This Join message is known as a (*,G) Join because it joins
group G for all sources to that group. The (*,G) Join travels hop-by- group G for all sources to that group. The (*,G) Join travels hop-by-
hop towards the RP for the group, and in each router it passes through, | hop towards the RP for the group, and in each router it passes through,
multicast tree state for group G is instantiated. Eventually the (*,G) | multicast tree state for group G is instantiated. Eventually the (*,G)
Join either reaches the RP, or reaches a router that already has (*,G) | Join either reaches the RP, or reaches a router that already has (*,G)
Join state for that group. When many receivers join the group, their | Join state for that group. When many receivers join the group, their
Join messages converge on the RP, and form a distribution tree for group | Join messages converge on the RP, and form a distribution tree for group
G that is rooted at the RP. This is known as the RP Tree (RPT), and is | G that is rooted at the RP. This is known as the RP Tree (RPT), and is
also known as the shared tree because it is shared by all sources | also known as the shared tree because it is shared by all sources
sending to that group. Join messages are resent periodically so long as | sending to that group. Join messages are resent periodically so long as
the receiver remains in the group. When all receivers on a leaf-network | the receiver remains in the group. When all receivers on a leaf-network
leave the group, the DR will send a PIM (*,G) Prune message towards the | leave the group, the DR will send a PIM (*,G) Prune message towards the
RP for that multicast group. However if the prune message is not sent | RP for that multicast group. However if the prune message is not sent
for any reason, the state will eventually time out. | for any reason, the state will eventually time out.
A multicast data sender just starts sending data destined for a A multicast data sender just starts sending data destined for a
multicast group. The sender's local router (DR) takes those data multicast group. The sender's local router (DR) takes those data
packets, unicast-encapsulates them, and sends them directly to the RP. packets, unicast-encapsulates them, and sends them directly to the RP.
The RP receives these encapsulated data packets, decapsulates them, and The RP receives these encapsulated data packets, decapsulates them, and
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
skipping to change at page 8, line 46 skipping to change at page 8, line 46
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
increased latency is undesirable. increased latency is undesirable.
Although Register-encapsulation may continue indefinitely, for these Although Register-encapsulation may continue indefinitely, for these
reasons, the RP will normally choose to switch to native forwarding. To | reasons, the RP will normally choose to switch to native forwarding. To
do this, when the RP receives a register-encapsulated data packet from | do this, when the RP receives a register-encapsulated data packet from
source S on group G, it will normally initiate an (S,G) source-specific | source S on group G, it will normally initiate an (S,G) source-specific
Join towards S. This join message travels hop-by-hop towards S, | Join towards S. This join message travels hop-by-hop towards S,
instantiating (S,G) multicast tree state in the routers along the path. | instantiating (S,G) multicast tree state in the routers along the path.
(S,G) multicast tree state is used only to forward packets for group G | (S,G) multicast tree state is used only to forward packets for group G
if those packets come from source S. Eventually the Join message | if those packets come from source S. Eventually the Join message
reaches S's subnet or a router that already has (S,G) multicast tree | reaches S's subnet or a router that already has (S,G) multicast tree
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
Register-Stop 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
skipping to change at page 10, line 25 skipping to change at page 10, line 25
Source-specific Joins Source-specific Joins
IGMPv3 permits a receiver to join a group and specify that it only wants IGMPv3 permits a receiver to join a group and specify that it only wants
to receive traffic for a group if that traffic comes from a particular to receive traffic for a group if that traffic comes from a particular
source. If a receiver does this, and no other receiver on the LAN source. If a receiver does this, and no other receiver on the LAN
requires all the traffic for the group, then the DR may omit performing requires all the traffic for the group, then the DR may omit performing
a (*,G) join to set up the shared tree, and instead issue a source- a (*,G) join to set up the shared tree, and instead issue a source-
specific (S,G) join only. specific (S,G) join only.
The range of multicast addresses from 232.0.0.0 to 232.255.255.255 is | The range of multicast addresses from 232.0.0.0 to 232.255.255.255 is
currently set aside for source-specific multicast in IPv4. For groups | currently set aside for source-specific multicast in IPv4. For groups
in this range, receivers should only issue source-specific IGMPv3 joins. | in this range, receivers should only issue source-specific IGMPv3 joins.
If a PIM router receives a non-source-specific join for a group in this If a PIM router receives a non-source-specific join for a group in this
range, it should ignore it, as described in Section 4.8. range, it should ignore it, as described in Section 4.8.
Source-specific Prunes Source-specific Prunes
IGMPv3 also permits a receiver to join a group and specify that it only IGMPv3 also permits a receiver to join a group and specify that it only
wants to receive traffic for a group if that traffic does not come from wants to receive traffic for a group if that traffic does not come from
a specific source or sources. In this case, the DR will perform a (*,G) a specific source or sources. In this case, the DR will perform a (*,G)
join as normal, but may combine this with an (S,G,rpt) prune for each of join as normal, but may combine this with an (S,G,rpt) prune for each of
the sources the receiver does not wish to receive. the sources the receiver does not wish to receive.
skipping to change at page 11, line 35 skipping to change at page 11, line 35
router has (S,G) state, then in favor of the router with the best metric router has (S,G) state, then in favor of the router with the best metric
to the RP for RP trees, or the best metric to the source to source- to the RP for RP trees, or the best metric to the source to source-
specific trees. specific trees.
These Assert messages are also received by the downstream routers on the These Assert messages are also received by the downstream routers on the
LAN, and these cause subsequent join messages to be sent to the upstream LAN, and these cause subsequent join messages to be sent to the upstream
router that won the Assert. router that won the Assert.
RP Discovery RP Discovery
PIM-SM routers need to know the address of the RP for each group for PIM-SM routers need to know the address of the RP for each group for |
which they have (*,G) state. This address is obtained through a which they have (*,G) state. This address is obtained either through a |
bootstrap mechanism. bootstrap mechanism or through static configuration. |
One router in each PIM domain is elected the Bootstrap Router (BSR) One dynamic way to do this is to use the Bootstrap Router (BSR) |
through a simple election process. All the routers in the domain that mechanism [4]. One router in each PIM domain is elected the Bootstrap |
are configured to be candidates to be RPs periodically unicast their Router through a simple election process. All the routers in the domain |
candidacy to the BSR. From the candidates, the BSR picks an RP-set, and that are configured to be candidates to be RPs periodically unicast |
periodically announces this set in a bootstrap message. Bootstrap their candidacy to the BSR. From the candidates, the BSR picks an RP- |
messages are flooded hop-by-hop throughout the domain until all routers set, and periodically announces this set in a bootstrap message. |
in the domain know the RP-Set. Bootstrap messages are flooded hop-by-hop throughout the domain until |
all routers in the domain know the RP-Set. |
To map a group to an RP, a router hashes the group address into the RP- To map a group to an RP, a router hashes the group address into the RP-
set using an order-preserving hash function (one that minimizes changes set using an order-preserving hash function (one that minimizes changes
if the RP set changes). The resulting RP is the one that it uses as the if the RP set changes). The resulting RP is the one that it uses as the
RP for that group. RP for that group.
4. Protocol Specification 4. Protocol Specification
The specification of PIM-SM is broken into several parts: The specification of PIM-SM is broken into several parts:
skipping to change at page 12, line 23 skipping to change at page 12, line 23
o Section 4.3 specifies the PIM Register generation and processing o Section 4.3 specifies the PIM Register generation and processing
rules. rules.
o Section 4.4 specifies the PIM Join/Prune generation and processing o Section 4.4 specifies the PIM Join/Prune generation and processing
rules. rules.
o Section 4.5 specifies the PIM Assert generation and processing rules. o Section 4.5 specifies the PIM Assert generation and processing rules.
o Designated Router (DR) election is specified in Section 4.6. o Designated Router (DR) election is specified in Section 4.6.
o Section 4.7 specifies the Bootstrap and RP discovery mechanisms. o Section 4.7 specifies the RP discovery mechanisms. |
o The subset of PIM required to support Source-Specific Multicast, PIM- o The subset of PIM required to support Source-Specific Multicast, PIM-
SSM, is described in Section 4.8. SSM, is described in Section 4.8.
o PIM packet formats are specified in Section 4.9. o PIM packet formats are specified in Section 4.9.
o A summary of PIM-SM timers and their default values is given in o A summary of PIM-SM timers and their default values is given in
Section 4.10. Section 4.10.
4.1. PIM Protocol State 4.1. PIM Protocol State
This section specifies all the protocol state that a PIM implementation This section specifies all the protocol state that a PIM implementation
should maintain in order to function correctly. We term this state the should maintain in order to function correctly. We term this state the
Tree Information Base or TIB, as it holds the state of all the multicast | Tree Information Base or TIB, as it holds the state of all the multicast
distribution trees at this router. In this specification we define PIM | distribution trees at this router. In this specification we define PIM
mechanisms in terms of the TIB. However, only a very simple | mechanisms in terms of the TIB. However, only a very simple
implementation would actually implement packet forwarding operations in | implementation would actually implement packet forwarding operations in
terms of this state. Most implementations will use this state to build | terms of this state. Most implementations will use this state to build
a multicast forwarding table, which would then be updated when the | a multicast forwarding table, which would then be updated when the
relevant state in the TIB changes. | relevant state in the TIB changes.
Although we specify precisely the state to be kept, this does not mean Although we specify precisely the state to be kept, this does not mean
that an implementation of PIM-SM needs to hold the state in this form. that an implementation of PIM-SM needs to hold the state in this form.
This is actually an abstract state definition, which is needed in order This is actually an abstract state definition, which is needed in order
to specify the router's behavior. A PIM-SM implementation is free to to specify the router's behavior. A PIM-SM implementation is free to
hold whatever internal state it requires, and will still be conformant hold whatever internal state it requires, and will still be conformant
with this specification so long as it results in the same externally with this specification so long as it results in the same externally
visible protocol behavior as an abstract router that holds the following visible protocol behavior as an abstract router that holds the following
state. state.
We divide TIB state into four sections: | We divide TIB state into four sections:
(*,*,RP) state | (*,*,RP) state
State that maintains per-RP trees, for all groups served by a given | State that maintains per-RP trees, for all groups served by a given
RP. | RP.
(*,G) state (*,G) state
State that maintains the RP tree for G. State that maintains the RP tree for G.
(S,G) state (S,G) state
State that maintains a source-specific tree for source S and group State that maintains a source-specific tree for source S and group
G. G.
(S,G,rpt) state (S,G,rpt) state
State that maintains source-specific information about source S on State that maintains source-specific information about source S on
skipping to change at page 13, line 34 skipping to change at page 13, line 34
The state that should be kept is described below. Of course, The state that should be kept is described below. Of course,
implementations will only maintain state when it is relevant to implementations will only maintain state when it is relevant to
forwarding operations - for example, the "NoInfo" state might be assumed forwarding operations - for example, the "NoInfo" state might be assumed
from the lack of other state information, rather than being held from the lack of other state information, rather than being held
explicitly. explicitly.
4.1.1. General Purpose State 4.1.1. General Purpose State
A router holds the following non-group-specific state: A router holds the following non-group-specific state:
Bootstrap State:
o Bootstrap Router's IP Address
o BSR Priority
o Bootstrap Timer (BST)
RP Set
For each interface: For each interface:
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
skipping to change at page 14, line 14 skipping to change at page 14, line 5
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
Bootstrap state is described in section 4.7, the RP Set is described in Designated Router state is described in section 4.6. |
section 4.7.5, and Designated Router state is described in section 4.6.
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: |
For each interface: |
PIM (*,*,RP) Join/Prune State: | (*,*,RP) state:
For each interface:
o State: One of {"NoInfo" (NI), "Join" (J), | PIM (*,*,RP) Join/Prune State:
"PrunePending" (PP)} |
o Prune Pending Timer (PPT) | o State: One of {"NoInfo" (NI), "Join" (J),
"PrunePending" (PP)}
o Join/Prune Expiry Timer (ET) | o Prune Pending Timer (PPT)
Not interface specific: | o Join/Prune Expiry Timer (ET)
o Upstream Join/Prune Timer (JT) | Not interface specific:
o Last RPF Neighbor towards RP that was used | o Upstream Join/Prune Timer (JT)
PIM (*,*,RP) Join/Prune state is the result of receiving PIM (*,*,RP) | o Last RPF Neighbor towards RP that was used
Join/Prune messages on this interface, and is specified in section |
4.4.1. |
The upstream (*,*,RP) Join/Prune timer is used to send out periodic | PIM (*,*,RP) Join/Prune state is the result of receiving PIM (*,*,RP)
Join(*,*,RP) messages, and to override Prune(*,*,RP) messages from peers | Join/Prune messages on this interface, and is specified in section
on an upstream LAN interface. | 4.4.1.
The last RPF neighbor towards the RP is stored because if the MRIB | The upstream (*,*,RP) Join/Prune timer is used to send out periodic
changes then the RPF neighbor towards the RP may change. If it does so, | Join(*,*,RP) messages, and to override Prune(*,*,RP) messages from peers
then we need to trigger a new Join(*,*,RP) to the new upstream neighbor | on an upstream LAN interface.
and a Prune(*,*,RP) to the old upstream neighbor. Similarly, if a |
router detects through a changed GenID in a Hello message that the |
upstream neighbor towards the RP has rebooted, then it should re- | The last RPF neighbor towards the RP is stored because if the MRIB
instantiate state by sending a Join(*,*,RP). These mechanisms are | changes then the RPF neighbor towards the RP may change. If it does so,
specified in Section 4.4.5. | 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
router detects through a changed GenID in a Hello message that the
upstream neighbor towards the RP has rebooted, then it should re-
instantiate state by sending a Join(*,*,RP). These mechanisms are
specified in Section 4.4.5.
4.1.3. (*,G) State 4.1.3. (*,G) State
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"}
skipping to change at page 16, line 22 skipping to change at page 16, line 10
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.5.2. assert messages on this interface. It is specified in section 4.5.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.7.5) then state must be torn down and rebuilt for groups whose RP 4.7) 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
4.4.6. 4.4.6.
skipping to change at page 17, line 30 skipping to change at page 17, line 17
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. This information is used by the pim_include(S,G) macro | for this group. This information is used by the pim_include(S,G) macro
described in section 4.1.6. | 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.4.2. The state is used by the macros that calculate the outgoing 4.4.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.4.7) that is used in deciding whether a Join(S,G) (defined in section 4.4.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.5.1. assert messages on this interface. It is specified in section 4.5.1.
skipping to change at page 19, line 4 skipping to change at page 18, line 38
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
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. This | router won a (*,G) assert on this interface for this group. This
information is used by the pim_exclude(S,G) macro described in section | information is used by the pim_exclude(S,G) macro described in section
4.1.6. 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.4.4. The state is used by the macros that calculate the outgoing 4.4.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.4.8. 4.4.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.4.9. specified in section 4.4.9.
skipping to change at page 19, line 44 skipping to change at page 19, line 31
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
example, the immediate_olist(S,G) is the olist that would be built if example, the immediate_olist(S,G) is the olist that would be built if
the router only had (S,G) state and no (*,G) or (S,G,rpt) state. In the router only had (S,G) state and no (*,G) or (S,G,rpt) state. In
contrast, the "inherited" olist inherits state from other types. For contrast, the "inherited" olist inherits state from other types. For
example, the inherited_olist(S,G) is the olist that is relevant for example, the inherited_olist(S,G) is the olist that is relevant for
forwarding a packet from S to G using both source-specific and group- forwarding a packet from S to G using both source-specific and group-
specific state. specific state.
There is no immediate_olist(S,G,rpt) as (S,G,rpt) state is negative | There is no immediate_olist(S,G,rpt) as (S,G,rpt) state is negative
state - it removes interfaces in the (*,G) olist from the olist that is | state - it removes interfaces in the (*,G) olist from the olist that is
actually used to forward traffic. The inherited_olist(S,G,rpt) is | actually used to forward traffic. The inherited_olist(S,G,rpt) is
therefore the olist that would be used for a packet from S to G | therefore the olist that would be used for a packet from S to G
forwarding on the RP tree. It is a strict subset of | forwarding on the RP tree. It is a strict subset of
immediate_olist(*,G). | immediate_olist(*,G).
Generally speaking, the inherited olists are used for forwarding, and Generally speaking, the inherited olists are used for forwarding, and
the immediate_olists are used to make decisions about state maintenance. the immediate_olists are used to make decisions about state maintenance.
immediate_olist(*,*,RP)= | immediate_olist(*,*,RP)=
joins(*,*,RP) | joins(*,*,RP)
immediate_olist(*,G) =
joins(*,G) (+) pim_include(*,G) (-) lost_assert(*,G)
immediate_olist(*,G) = |
joins(*,G) (+) pim_include(*,G) (-) lost_assert(*,G) |
immediate_olist(S,G) = immediate_olist(S,G) =
joins(S,G) (+) pim_include(S,G) (-) lost_assert(S,G) joins(S,G) (+) pim_include(S,G) (-) lost_assert(S,G)
inherited_olist(S,G,rpt) = | inherited_olist(S,G,rpt) =
( joins(*,*,RP(G)) (+) joins(*,G) (-) prunes(S,G,rpt) ) | ( 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(S,G,rpt) ) (-) ( lost_assert(*,G) (+) lost_assert(S,G,rpt) )
inherited_olist(S,G) = inherited_olist(S,G) =
inherited_olist(S,G,rpt) (+) immediate_olist(S,G) inherited_olist(S,G,rpt) (+) immediate_olist(S,G)
The macros pim_include(*,G) and pim_include(S,G) indicate the interfaces The macros pim_include(*,G) and pim_include(S,G) indicate the interfaces
to which traffic might be forwarded because of hosts that are local to which traffic might be forwarded because of hosts that are local
members on that interface. Note that normally only the DR cares about members on that interface. Note that normally only the DR cares about
local membership, but when an assert happens, the assert winner takes local membership, but when an assert happens, the assert winner takes
over responsibility for forwarding traffic to local members that have over responsibility for forwarding traffic to local members that have
requested traffic on a group or source/group pair. requested traffic on a group or source/group pair.
pim_include(*,G) = pim_include(*,G) =
{ all interfaces I such that: | { all interfaces I such that:
( ( I_am_DR( I ) AND lost_assert(*,G,I) == FALSE ) | ( ( I_am_DR( I ) AND lost_assert(*,G,I) == FALSE )
OR AssertWinner(*,G,I) == me ) OR AssertWinner(*,G,I) == me )
AND local_receiver_include(*,G,I) } AND local_receiver_include(*,G,I) }
pim_include(S,G) = pim_include(S,G) =
{ all interfaces I such that: | { all interfaces I such that:
( (I_am_DR( I ) AND lost_assert(S,G,I) == FALSE ) | ( (I_am_DR( I ) AND lost_assert(S,G,I) == FALSE )
OR AssertWinner(S,G,I) == me ) OR AssertWinner(S,G,I) == me )
AND local_receiver_include(S,G,I) } | AND local_receiver_include(S,G,I) }
pim_exclude(S,G) = |
{ all interfaces I such that: |
( (I_am_DR( I ) AND lost_assert(S,G,I) == FALSE ) |
OR AssertWinner(S,G,I) == me ) |
AND local_receiver_exclude(S,G,I) } |
The clause "local_receiver_include(S,G,I)" is true if the IGMP module or | pim_exclude(S,G) =
other local membership mechanism has determined that there are local | { all interfaces I such that:
members on interface I that desire to receive traffic sent specifically | ( (I_am_DR( I ) AND lost_assert(S,G,I) == FALSE )
OR AssertWinner(S,G,I) == me )
AND local_receiver_exclude(S,G,I) }
by S to G. "local_receiver_include(*,G,I)" is true if the IGMP module | The clause "local_receiver_include(S,G,I)" is true if the IGMP module or
or other local membership mechanism has determined that there are local | other local membership mechanism has determined that there are local
members on interface I that desire to receive all traffic sent to G. | members on interface I that desire to receive traffic sent specifically
"local_receiver_exclude(S,G,I) is true if local_receiver_include(*,G,I) | by S to G. "local_receiver_include(*,G,I)" is true if the IGMP module
is true but none of the local members desire to receive traffic from S. | or other local membership mechanism has determined that 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 local_receiver_include(*,G,I)
is true but none of the local members 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 Joined or | DownstreamJPState(*,*,RP,I) is either Joined or
PrunePending } | PrunePending }
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.4.1. | section 4.4.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 Joined or PrunePending } DownstreamJPState(*,G,I) is either Joined or PrunePending }
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.4.2. section 4.4.2.
skipping to change at page 21, line 49 skipping to change at page 21, line 43
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.4.3. section 4.4.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,I) is Pruned or PruneTmp } DownstreamJPState(S,G,I) is Pruned or PruneTmp }
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.5.5. lost_assert(*,G,I) is defined in Section 4.5.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
router has received (*,G) joins but has lost an (S,G) assert. The macro router has received (*,G) joins but has lost an (S,G) assert. The macro
lost_assert(S,G,rpt,I) is defined in Section 4.5.5. lost_assert(S,G,rpt,I) is defined in Section 4.5.5.
lost_assert(S,G,rpt) = | lost_assert(S,G,rpt) =
{ all interfaces I such that { all interfaces I such that
lost_assert(S,G,rpt,I) == TRUE } lost_assert(S,G,rpt,I) == TRUE }
The set "lost_assert(S,G)" is the set of all interfaces on which the | The set "lost_assert(S,G)" is the set of all interfaces on which the
router has received (S,G) joins but has lost an (S,G) assert. The macro router has received (S,G) joins but has lost an (S,G) assert. The macro
lost_assert(S,G,I) is defined in Section 4.5.5. lost_assert(S,G,I) is defined in Section 4.5.5.
lost_assert(S,G) = | lost_assert(S,G) =
{ all interfaces I such that { all interfaces I such that
lost_assert(S,G,I) == TRUE } lost_assert(S,G,I) == TRUE }
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))) ) {
skipping to change at page 23, line 17 skipping to change at page 23, line 10
} else { } else {
return MRIB.next_hop( S ) return 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.4.8). | messages that we send to RPF'(*,G) (See Section 4.4.8).
The function MRIB.next_hop( S ) returns the next-hop PIM neighbor toward | The function MRIB.next_hop( S ) returns the next-hop PIM neighbor toward
the host S, as indicated by the current MRIB. If S is directly | the host S, as indicated by the current MRIB. If S is directly
adjacent, then MRIB.next_hop( S ) returns NULL. At the RP for G, | adjacent, then MRIB.next_hop( S ) returns NULL. At the RP for G,
MRIB.next_hop( RP(G )) returns NULL. | MRIB.next_hop( RP(G )) returns NULL.
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.5.1) for (S,G) on Interface I is in "I am Assert Loser" state. | section 4.5.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.5.2) for (*,G) on Interface I is in "I am Assert Loser" state. | section 4.5.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
skipping to change at page 24, line 13 skipping to change at page 24, line 4
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 refresh the (S,G) state keepalive timer. we refresh 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. | just build an outgoing interface list for the packet.
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 on a 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: 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)
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) AND SPTbit(S,G) == FALSE) {
oiflist = inherited_olist(S,G,rpt) | oiflist = inherited_olist(S,G,rpt)
} 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
} | }
} | }
oiflist = oiflist (-) iif | oiflist = oiflist (-) iif
forward packet on all interfaces in oiflist | forward packet on all interfaces in oiflist
This pseudocode employs several "macro" definitions: This pseudocode employs several "macro" definitions:
directly_connected(S) is TRUE if the source S is on any subnet that is directly_connected(S) is TRUE if the source S is on any subnet that is
directly connected to this router (or for packets originating on this directly connected to this router (or for packets originating on this
router). router).
inherited_olist(S,G) and inherited_olist(S,G,rpt) are defined in Section inherited_olist(S,G) and inherited_olist(S,G,rpt) are defined in Section
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.1. Update_SPTbit(S,G,iif) 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.4.7. 4.4.7.
Keepalive_Period is defined in Section 4.10. Keepalive_Period is defined in Section 4.10.
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. Setting and Clearing the (S,G) SPT bit 4.2.1. Setting and Clearing the (S,G) SPT bit
The (S,G) SPTbit is used to distinguish whether to forward on | The (S,G) SPTbit is used to distinguish whether to forward on
(*,*,RP)/(*,G) or on (S,G) state. When switching from the RP tree to | (*,*,RP)/(*,G) or on (S,G) state. When switching from the RP tree to
the source tree, there is a transition period when data is arriving due the source tree, there is a transition period when data is arriving due
to upstream (*,*,RP)/(*,G) state while upstream (S,G) state is being | to upstream (*,*,RP)/(*,G) state while upstream (S,G) state is being
established during which time a router should continue to forward only | established during which time a router should continue to forward only
on (*,*,RP)/(*,G) state. This prevents temporary black-holes that would | on (*,*,RP)/(*,G) state. This prevents temporary black-holes that would
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)
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 sees an | Additionally a router sets SPTbit(S,G) to TRUE when it sees an
Assert(S,G) on RPF_interface(S). | Assert(S,G) on RPF_interface(S).
JoinDesired(S,G) is defined in Section 4.4.7, and indicates whether we JoinDesired(S,G) is defined in Section 4.4.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
SPT is a no-op. SPT is a no-op.
2. The RPF interface to S is different from the RPF interface to the 2. The RPF interface to S is different from the RPF interface to the
RP. The packet arrived on RPF_interface(S), and so the SPT must RP. The packet arrived on RPF_interface(S), and so the SPT must
have been completed. have been completed.
3. No-one wants the packet on the RP tree. 3. No-one wants the packet on the RP tree.
4. RPF'(S,G) == RPF'(*,G). In this case the router will never be able 4. RPF'(S,G) == RPF'(*,G). In this case the router will never be able
to tell if the SPT has been completed, so it should just switch to tell if the SPT has been completed, so it should just switch
immediately. immediately.
In the case where the RPF interface is the same for the RP and for S, In the case where the RPF interface is the same for the RP and for S,
but RPF'(S,G) and RPF'(*,G) differ, then we wait for an Assert(S,G) but RPF'(S,G) and RPF'(*,G) differ, then we wait for an Assert(S,G)
which indicates that the upstream router with (S,G) state believes the | which indicates that the upstream router with (S,G) state believes the
SPT has been completed. However item (3) above is needed because there | SPT has been completed. However item (3) above is needed because there
may not be any (*,G) state to trigger an Assert(S,G) to happen. | may not be any (*,G) state to trigger an Assert(S,G) to happen.
The SPT bit is cleared in the (S,G) upstream state machine (see Section | The SPT bit is cleared in the (S,G) upstream state machine (see Section
4.4.7) when JoinDesired(S,G) becomes FALSE. | 4.4.7) when JoinDesired(S,G) becomes FALSE.
4.3. PIM Register Messages 4.3. 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 to the source. DR will resume encapsulating packets to the RP. |
4.3.1. Sending Register Messages from the DR 4.3.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 specified in Section 4.2. forwarding rules 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)
skipping to change at page 29, line 12 skipping to change at page 29, line 7
(*) The RegisterStopTimer is set to a random value chosen uniformly from (*) The RegisterStopTimer is set to a random value chosen uniformly from
the interval ( 0.5 * Register_Suppression_Time, 1.5 * 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 is Subtracting off register_probe_time is a bit unnecessary because it is
really small compared to register suppression timeout, but was in the really small compared to register suppression timeout, but was in the
old spec and is kept for compatibility. old spec and is kept for compatibility.
(**) The RegisterStopTimer is set to register_probe_time. (**) The RegisterStopTimer is set to register_probe_time.
The macro "CouldRegister" in the state machine is defined as: | The macro "CouldRegister" in the state machine is defined as:
Bool CouldRegister(S,G) { | Bool CouldRegister(S,G) {
return ( I_am_DR( RPF_interface(S) ) AND | return ( I_am_DR( RPF_interface(S) ) AND
KeepaliveTimer(S,G) is running AND | KeepaliveTimer(S,G) is running AND
DirectlyConnected(S) == TRUE ) | DirectlyConnected(S) == TRUE )
} | }
Note that on reception of a packet at the DR from a directly connected Note that on reception of a packet at the DR from a directly connected
source, KeepaliveTimer(S,G) needs to be set by the packet forwarding | source, KeepaliveTimer(S,G) needs to be set by the packet forwarding
rules before computing CouldRegister(S,G) in the register state machine, | rules before computing CouldRegister(S,G) in the register state machine,
or the first packet from a source won't be registered. or the first packet from a source won't be registered.
Handling RegisterStop(*,G) Messages at the DR Encapsulating data packets in the Register Tunnel |
An RP MAY send a RegisterStop message with the source address set to Conceptually, the Register Tunnel is an interface with a smaller MTU |
all-zeros. This was the normal course of action in RFC 2326 when the than the underlying IP interface towards the RP. IP fragmentation on |
packets forwarded on the Register Tunnel is performed based upon this |
smaller MTU. The encapsulating DR may perform Path-MTU Discovery to the |
RP to determine the effective MTU of the tunnel. |
In IPv6, an ICMP Fragmentation Required message may be sent by the |
encapsulating DR. |
Just like any forwarded packet, the TTL of the original data packet is |
decremented before it is encapsulated in the Register Tunnel. |
Handling RegisterStop(*,G) Messages at the DR |
An old RP might send a RegisterStop message with the source address set |
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 RegisterStop(*,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 RegisterStop(*,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 RegisterStop(*,G) should be treated as a RegisterStop(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) to sources that become active after the
RegisterStop(*,G) was received. RegisterStop(*,G) was received.
4.3.2. Receiving Register Messages at the RP 4.3.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) ) {
restart KeepaliveTimer(S,G) | restart KeepaliveTimer(S,G)
if(( inherited_olist(S,G) == NULL ) OR SPTbit(S,G)) { | if(( inherited_olist(S,G) == NULL ) OR SPTbit(S,G)) {
send RegisterStop(S,G) to outer.src | send RegisterStop(S,G) to outer.src
} else { | } else {
if( ! pkt.NullRegisterBit ) { | if( ! 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 RegisterStop(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
is the RP for the group. is the RP for the group.
Note (*): This may block traffic from S for Register_Suppression_Time if Note (*): This may block traffic from S for Register_Suppression_Time if
skipping to change at page 31, line 5 skipping to change at page 31, line 9
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. This may cause the upstream (S,G) state
machine to trigger a join if the inherited_olist(S,G) is not NULL; 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 Register-Stop 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 |
decremented after it is decapsulated from the Register Tunnel. |
4.4. PIM Join/Prune Messages 4.4. PIM Join/Prune Messages
A PIM Join/Prune message consists of a list of groups and a list of A PIM Join/Prune message consists of a list of groups and a list of
Joined and Pruned sources for each group. When processing a received Joined and Pruned sources for each group. When processing a received
Join/Prune message, each Joined or Pruned source for a Group is Join/Prune message, each Joined or Pruned source for a Group is
effectively considered individually, and applies to one or more of the effectively considered individually, and applies to one or more of the
following state machines. When considering a Join/Prune message whose following state machines. When considering a Join/Prune message whose
PIM Destination field addresses this router, (*,*,RP) Joins and Prunes | PIM Destination field addresses this router, (*,*,RP) Joins and Prunes
can affect the (*,*,RP) and (S,G,rpt) downstream state machines, (*,G) | can affect the (*,*,RP) and (S,G,rpt) downstream state machines, (*,G)
Joins and Prunes can affect both the (*,G) and (S,G,rpt) downstream Joins and Prunes can affect both the (*,G) and (S,G,rpt) downstream
state machines, while (S,G) and (S,G,rpt) Joins and Prunes can only state machines, while (S,G) and (S,G,rpt) Joins and Prunes can only
affect their respective downstream state machines. When considering a affect their respective downstream state machines. When considering a
Join/Prune message whose PIM Destination field addresses another router, Join/Prune message whose PIM Destination field addresses another router,
most Join or Prune messages could affect each upstream state machine. most Join or Prune messages could affect each upstream state machine.
(... it's possible to enumerate this ...) XXX (... it's possible to enumerate this ...) XXX
4.4.1. Receiving (*,*,RP) Join/Prune Messages 4.4.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
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.4.4) or the router lost an assert on this | (see Section 4.4.4) or the router lost an assert on this
interface. | interface.
PrunePending (PP) | PrunePending (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 PrunePending 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 group. | to NoInfo for this group.
PrunePendingTimer (PPT) | PrunePendingTimer (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 PrunePendingTimer causes the interface state to
revert to NoInfo for this group. | revert to NoInfo for this group.
+-----------------------------------+ | +-----------------------------------+
| Figures omitted from text version | | | Figures omitted from text version |
+-----------------------------------+ | +-----------------------------------+
Figure 2: Downstream (*,*,RP) per-interface state-machine | Figure 2: Downstream (*,*,RP) per-interface state-machine
In tabular form, the per-interface (*,*,RP) state-machine is: | In tabular form, the per-interface (*,*,RP) state-machine is:
+-------------------+----------------------------------------------------|------------| +-------------+--------------------------------------------------------+
| | Event | | | Event |
| +-------------------+---------------+---------------+|------------| | +-------------+--------------+--------------+------------+
Prev State | Receive | Receive | Prune | Expiry Timer || |Prev State |Receive |Receive |Prune |Expiry Timer|
| Join(*,*,RP) | Prune(*,*,RP)| Pending | Expires || | |Join(*,*,RP) |Prune(*,*,RP) |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 Expiry | start Prune || || | |Join (J) |restart |start Prune | | |
| Timer | Pending Timer || || | | |Expiry Timer |Pending Timer | | |
+-------------------+-------------------+---------------+---------------+-------------| +-------------+-------------+--------------+--------------+------------+
| +> J state +> PP state +> NI state +> NI state| | | |-> J state |-> PP state |-> NI state |-> NI state |
Prune Pending (PP) |restart Expiry || Send Prune- ||| | | |restart | |Send Prune- | |
| Timer; stop Prune || Echo(*,*,RP) ||| | |Prune |Expiry | |Echo(*,*,RP) | |
| Pending Timer || | || | |Pending (PP) |Timer; stop | | | |
+-------------------+-------------------+---------------+---------------+-------------| | |Prune | | | |
| |Pending | | | |
The transition events "Receive Join(*,*,RP)" and "Receive Prune(*,*,RP)" | | |Timer | | | |
imply receiving a Join or Prune targeted to this router's address on the | +-------------+-------------+--------------+--------------+------------+
received interface. If the destination address is not correct, these |
state transitions in this state machine must not occur, although seeing |
such a packet may cause state transitions in other state machines. | The transition events "Receive Join(*,*,RP)" and "Receive Prune(*,*,RP)"
imply receiving a Join or Prune targeted to this router's address on the
received interface. If the destination address is not correct, these
state transitions in this state machine must not occur, although seeing
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 packet | should be the same as the source address it chose for the hello packet
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 0.0.0.0 destination address are also | recommend that PIM messages with a 0.0.0.0 destination address are also
accepted. | 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 IP | A Join(*,*,RP) is received on interface I with its IP
destination set to the router's address on I. | destination 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 Expiry Timer (ET) is | transitions to the Join state. The Expiry Timer (ET) is
started, and set to the HoldTime from the triggering Join | started, and set to the HoldTime from the triggering |
message. | Join/Prune message. |
Transitions from Join State | Transitions from Join State
When in Join state, the following events may trigger a transition: | When in Join state, the following events may trigger a transition:
Receive Join(*,*,RP) | Receive Join(*,*,RP)
A Join(*,*,RP) is received on interface I with its IP | A Join(*,*,RP) is received on interface I with its IP
destination set to the router's address on I. | destination set to the router's address on I.
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 |
the HoldTime from the triggering Join message. | maximum of its current value and the HoldTime from the |
triggering Join/Prune message. |
Receive Prune(*,*,RP) | Receive Prune(*,*,RP)
A Prune(*,*,RP) is received on interface I with its IP | A Prune(*,*,RP) is received on interface I with its IP
destination set to the router's address on I. | destination 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 PrunePending state. The PrunePending timer
is started; it is set to the J/P_Override_Interval if the | is started; it is set to the J/P_Override_Interval if the
router has more than one neighbor on that interface; otherwise | router has more than one neighbor on that interface; otherwise
it is set 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 (*,*,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 |
transitions to the NoInfo state. |
Transitions from PrunePending State | The (*,*,RP) downstream state machine on interface I
transitions to the NoInfo state.
When in PrunePending state, the following events may trigger a | Transitions from PrunePending State
transition: |
Receive Join(*,*,RP) | When in PrunePending state, the following events may trigger a
A Join(*,*,RP) is received on interface I with its IP | transition:
destination set to the router's address on I. |
The (*,*,RP) downstream state machine on interface I | Receive Join(*,*,RP)
transitions to the Join state. The PrunePending timer is | A Join(*,*,RP) is received on interface I with its IP
destination set to the router's address on I.
The (*,*,RP) downstream state machine on interface I
transitions to the Join state. The PrunePending timer is
canceled (without triggering an expiry event). The Expiry | canceled (without triggering an expiry event). The Expiry |
Timer is restarted, and set to the HoldTime from the | Timer is restarted, set to maximum of its current value and |
triggering Join 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 | PrunePending Timer Expires
The PrunePending Timer for the (*,*,RP) downstream state | The PrunePending 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 to itself on a LAN. Its purpose | sent by the upstream router to itself on a LAN. By "to |
is to add additional reliability so that if a Prune that | itself" we mean that the Upstream Neighbor Address field of |
should have been overridden by another router is lost locally | the enclosing Join/Prune message is set to the address of the |
on the LAN, then the PruneEcho may be received and cause the | sending router. Its purpose is to add additional reliability |
override to happen. A PruneEcho(*,*,RP) need not be sent on a | so that if a Prune that should have been overridden by another |
point-to-point interface. | router is lost locally on the LAN, then the PruneEcho may be
received and cause the override to happen. A
PruneEcho(*,*,RP) need not be sent on a point-to-point
interface.
4.4.2. Receiving (*,G) Join/Prune Messages 4.4.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 Join
or Prune should be silently dropped. If a router has no RP information 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 (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). 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.4.4) there is also (S,G,rpt) prune information (see Section 4.4.4)
or the router lost an assert on this interface. or the router lost an assert on this interface.
PrunePending (PP) PrunePending (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 PrunePending 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 ExpiryTimer causes the interface state to revert
to NoInfo for this group. to NoInfo for this group.
PrunePendingTimer (PPT) PrunePendingTimer (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 PrunePendingTimer causes the interface state to revert
to NoInfo for this group. to NoInfo for this group.
skipping to change at page 36, line 47 skipping to change at page 37, line 47
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 packet should be the same as the source address it chose for the hello packet
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 0.0.0.0 destination address are also recommend that PIM messages with a 0.0.0.0 destination address are also
accepted. 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 IP destination | A Join(*,G) is received on interface I with its IP destination
set to the router's address on I. | set to the router's address on I.
The (*,G) downstream state machine on interface I transitions |
to the Join state. The Expiry Timer (ET) is started, and set |
to the HoldTime from the triggering Join message. |
Transitions from Join State | The (*,G) downstream state machine on interface I transitions
to the Join state. The Expiry Timer (ET) is started, and set
to the HoldTime from the triggering Join/Prune message. |
When in Join state, the following events may trigger a transition: | Transitions from Join State
Receive Join(*,G) | When in Join state, the following events may trigger a transition:
A Join(*,G) is received on interface I with its IP destination |
set to the router's address on I. |
The (*,G) downstream state machine on interface I remains in | Receive Join(*,G)
Join state, and the Expiry Timer (ET) is restarted, set to the | A Join(*,G) is received on interface I with its IP destination
HoldTime from the triggering Join message. | set to the router's address on I.
Receive Prune(*,G) | The (*,G) downstream state machine on interface I remains in
A Prune(*,G) is received on interface I with its IP | Join state, and the Expiry Timer (ET) is restarted, set to |
destination set to the router's address on I. | maximum of its current value and the HoldTime from the |
triggering Join/Prune message. |
The (*,G) downstream state machine on interface I transitions | Receive Prune(*,G)
to the PrunePending state. The PrunePending timer is started; | A Prune(*,G) is received on interface I with its IP
it is set to the J/P_Override_Interval if the router has more | destination set to the router's address on I.
than one neighbor on that interface; otherwise it is set to |
zero causing it to expire immediately. |
Expiry Timer Expires | The (*,G) downstream state machine on interface I transitions
The Expiry Timer for the (*,G) downstream state machine on | to the PrunePending state. The PrunePending timer is started;
interface I expires. | it is set to the J/P_Override_Interval if the router has more
than one neighbor on that interface; otherwise it is set to
zero causing it to expire immediately.
The (*,G) downstream state machine on interface I transitions | Expiry Timer Expires
to the NoInfo state. | The Expiry Timer for the (*,G) downstream state machine on
interface I expires.
Transitions from PrunePending State | The (*,G) downstream state machine on interface I transitions
to the NoInfo state.
When in PrunePending state, the following events may trigger a | Transitions from PrunePending State
transition: |
Receive Join(*,G) | When in PrunePending state, the following events may trigger a
A Join(*,G) is received on interface I with its IP destination | transition:
set to the router's address on I. |
The (*,G) downstream state machine on interface I transitions | Receive Join(*,G)
to the Join state. The PrunePending timer is canceled | A Join(*,G) is received on interface I with its IP destination
set to the router's address on I.
The (*,G) downstream state machine on interface I transitions
to the Join state. The PrunePending timer is canceled
(without triggering an expiry event). The Expiry Timer is | (without triggering an expiry event). The Expiry Timer is |
restarted, and set to the HoldTime from the triggering Join | restarted, set to maximum of its current value and the |
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 | PrunePending Timer Expires |
The PrunePending Timer for the (*,G) downstream state machine | The PrunePending 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 to itself on a LAN. Its purpose is to add upstream router to itself on a LAN. By "to itself" we mean |
additional reliability so that if a Prune that should have that the Upstream Neighbor Address field of the enclosing |
been overridden by another router is lost locally on the LAN, Join/Prune message is set to the address of the sending |
then the PruneEcho may be received and cause the override to router. Its purpose is to add additional reliability so that |
happen. A PruneEcho(*,G) need not be sent on a point-to-point if a Prune that should have been overridden by another router |
interface. is lost locally on the LAN, then the PruneEcho may be received
and cause the override to happen. A PruneEcho(*,G) need not
be sent on a point-to-point interface.
4.4.3. Receiving (S,G) Join/Prune Messages 4.4.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
skipping to change at page 40, line 13 skipping to change at page 41, line 41
+-------------++-------------+-------------+-------------+--------------+ +-------------++-------------+-------------+-------------+--------------+
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 packet should be the same as the source address it chose for the hello packet
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 0.0.0.0 destination address are also | recommend that PIM messages with a 0.0.0.0 destination address are also
accepted. 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 IP destination | A Join(S,G) is received on interface I with its IP destination
set to the router's address on I. | 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 Expiry Timer (ET) is started, and set | to the Join state. The Expiry Timer (ET) is started, and set
to the HoldTime from the triggering Join message. | to the HoldTime from the triggering Join/Prune message. |
Transitions from Join State | Transitions from Join State
When in Join state, the following events may trigger a transition: | When in Join state, the following events may trigger a transition:
Receive Join(S,G) | Receive Join(S,G)
A Join(S,G) is received on interface I with its IP destination | A Join(S,G) is received on interface I with its IP destination
set to the router's address on I. | set to the router's address on I.
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 the | Join state, and the Expiry Timer (ET) is restarted, set to |
HoldTime from the triggering Join message. | maximum of its current value and the HoldTime from the |
triggering Join/Prune message. |
Receive Prune(S,G) | Receive Prune(S,G)
A Prune(S,G) is received on interface I with its IP | A Prune(S,G) is received on interface I with its IP
destination set to the router's address on I. | destination 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 PrunePending state. The PrunePending timer is started;
it is set to the J/P_Override_Interval if the router has more | it is set to the J/P_Override_Interval 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.
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 PrunePending State
When in PrunePending state, the following events may trigger a | When in PrunePending 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 IP destination | A Join(S,G) is received on interface I with its IP destination
set to the router's address on I. | 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 PrunePending timer is canceled
(without triggering an expiry event). The Expiry Timer is | (without triggering an expiry event). The Expiry Timer is |
restarted, and set to the HoldTime from the triggering Join | restarted, set to maximum of its current value and the |
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 | PrunePending Timer Expires |
The PrunePending Timer for the (S,G) downstream state machine | The PrunePending 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 to itself on a LAN. Its purpose is to add upstream router to itself on a LAN. By "to itself" we mean |
additional reliability so that if a Prune that should have that the Upstream Neighbor Address field of the enclosing |
been overridden by another router is lost locally on the LAN, Join/Prune message is set to the address of the sending |
then the PruneEcho may be received and cause the override to router. Its purpose is to add additional reliability so that |
happen. A PruneEcho(S,G) need not be sent on a point-to-point if a Prune that should have been overridden by another router |
interface. is lost locally on the LAN, then the PruneEcho may be received
and cause the override to happen. A PruneEcho(S,G) need not
be sent on a point-to-point interface.
4.4.4. Receiving (S,G,rpt) Join/Prune Messages 4.4.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.
skipping to change at page 44, line 49 skipping to change at page 45, line 49
|(P') | | Expiry | | | | |(P') | | Expiry | | | |
| | | Timer | | | | | | | Timer | | | |
+-------+----------------+----------+---------+--------+-------+--------+ +-------+----------------+----------+---------+--------+-------+--------+
|Temp. |error |error +> PP |-> NI |n/a |n/a | |Temp. |error |error +> PP |-> NI |n/a |n/a |
|Prune | | state |state | | | |Prune | | state |state | | |
|Pending| | restart | | | | |Pending| | restart | | | |
|(PP') | | Expiry | | | | |(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)",
"Receive Join(*,G)" and "Receive Join(*,*,RP(G))" imply receiving a Join | "Receive Join(*,G)" and "Receive Join(*,*,RP(G))" imply receiving a Join
or Prune targeted to this router's address on the received interface. | or Prune targeted to this router's address on the received interface.
If the destination address is not correct, these state transitions in If the destination address is not correct, these state transitions in
this state machine must not occur, although seeing such a packet may this state machine must not occur, although seeing such a packet may
cause state transitions in other state machines. 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 packet should be the same as the source address it chose for the hello packet
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 0.0.0.0 destination address are also | recommend that PIM messages with a 0.0.0.0 destination address are also
accepted. | 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 IP | A Prune(S,G,rpt) is received on interface I with its IP
destination set to the router's address on I. | destination 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 PrunePending state. The Expiry Timer (ET)
is started, and set to the HoldTime from the triggering Join | is started, and set to the HoldTime from the triggering |
message. The PrunePending timer is started; it is set to the | Join/Prune message. The PrunePending timer is started; it is |
J/P_Override_Interval if the router has more than one neighbor | set to the J/P_Override_Interval if the router has more than
on that interface; otherwise it is set to zero causing it to | one neighbor on that interface; otherwise it is set to zero
expire immediately. | causing it to expire immediately.
Transitions from PrunePending State | Transitions from PrunePending State
When in PrunePending (PP) state, the following events may trigger a | When in PrunePending (PP) state, the following events may trigger a
transition: | transition:
Receive Join(*,G) or Join(*,*,RP(G)) | Receive Join(*,G) or Join(*,*,RP(G))
A Join(*,*,RP(G)) or Join(*,G) is received on interface I with | A Join(*,*,RP(G)) or Join(*,G) is received on interface I with
its IP destination set to the router's address on I. | its IP destination 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 Temp. PrunePending state whilst the remainder | transitions to Temp. PrunePending state whilst the remainder
of the compound Join/Prune message containing the | of the compound Join/Prune message containing the
Join(*,*,RP(G)) or Join(*,G) is processed. | Join(*,*,RP(G)) or Join(*,G) is processed.
Receive Join(S,G,rpt) | Receive Join(S,G,rpt)
A Join(S,G,rpt) is received on interface I with its IP | A Join(S,G,rpt) is received on interface I with its IP
destination set to the router's address on I. | destination 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 | PrunePending Timer Expires
The PrunePending Timer for the (S,G,rpt) downstream state | The PrunePending 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 Pruned state.
Transitions from Pruned State | Transitions from Pruned State
When in Pruned (P) state, the following events may trigger a transition: | When in Pruned (P) state, the following events may trigger a transition:
Receive Join(*,G) or Join(*,*,RP(G)) | Receive Join(*,G) or Join(*,*,RP(G))
A Join(*,*,RP(G)) or Join(*,G) is received on interface I with | A Join(*,*,RP(G)) or Join(*,G) is received on interface I with
its IP destination set to the router's address on I. | its IP destination 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 Temp. Pruned state whilst the remainder of the | transitions to Temp. Pruned state whilst the remainder of the
compound Join/Prune message containing the Join(*,*,RP(G)) or | compound Join/Prune message containing the Join(*,*,RP(G)) or
Join(*,G) is processed. | Join(*,G) is processed.
Receive Join(S,G,rpt) | Receive Join(S,G,rpt)
A Join(S,G,rpt) is received on interface I with its IP | A Join(S,G,rpt) is received on interface I with its IP
destination set to the router's address on I. | destination 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 IP | A Prune(S,G,rpt) is received on interface I with its IP
destination set to the router's address on I. | destination 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 Pruned state. The Expiry Timer (ET) is restarted, set to |
the HoldTime from the triggering Join message. | maximum of its current value and the HoldTime from the |
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 Temp. PrunePending State | Transitions from Temp. PrunePending State
When in Temp. PrunePending (PP') state and processing a compound | When in Temp. PrunePending (PP') state and processing a compound
Join/Prune 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 PrunePending state. The Expiry Timer |
(ET) is restarted, set to the HoldTime from the Join/Prune | (ET) is restarted, set to maximum of its current value and the |
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 Temp. Pruned State | Transitions from Temp. Pruned State
When in Temp. Pruned (P') state and processing a compound Join/Prune | When in Temp. Pruned (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 Pruned state. The Expiry Timer (ET) |
is restarted, set to the HoldTime from the Join/Prune message. | is restarted, set to maximum of its current value and the |
HoldTime from the triggering Join/Prune message. |
End of Message |
The end of the compound Join/Prune message is reached. |
The (S,G,rpt) downstream state machine on interface I | End of Message
transitions to the NoInfo state. ET and PPT are canceled. | The end of the compound Join/Prune message is reached.
Notes: | The (S,G,rpt) downstream state machine on interface I
transitions to the NoInfo state. ET and PPT are canceled.
Receiving a Prune(*,*,RP(G)) or Prune(*,G) does not affect the (S,G,rpt) | Notes:
downstream state machine. |
The HoldTime from the Join/Prune message must be larger than the Receiving a Prune(*,*,RP(G)) or Prune(*,G) does not affect the (S,G,rpt)
J/P_Override_Interval. downstream state machine.
4.4.5. Sending (*,*,RP) Join/Prune Messages 4.4.5. Sending (*,*,RP) Join/Prune Messages
The per-interface state-machines for (*,*,RP) hold join state from | The per-interface state-machines for (*,*,RP) 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(*,*,RP) upstream towards the RP. | needs to propagate a Join(*,*,RP) upstream towards the RP.
If a router wishes to propagate a Join(*,*,RP) upstream, it must also | If a router wishes to propagate a Join(*,*,RP) upstream, it must also
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
immediately. Finally, if it sees the Generation ID (see Section 4.6) of
be prepared to override that prune by sending a Join(*,*,RP) almost | the correct upstream neighbor change, it knows that the upstream
immediately. Finally, if it sees the Generation ID (see Section 4.6) of | neighbor has lost state, and it should be prepared to refresh the state
the correct upstream neighbor change, it knows that the upstream | by sending a Join(*,*,RP) almost immediately.
neighbor has lost state, and it should be prepared to refresh the state |
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 only contains two states: | The upstream (*,*,RP) 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 would like
to join the RP tree for this group. | to join the RP tree for this group.
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). | MRIB.next_hop(RP).
+-----------------------------------+ | +-----------------------------------+
| Figures omitted from text version | | | Figures omitted from text version |
+-----------------------------------+ | +-----------------------------------+
Figure 6: Upstream (*,*,RP) state-machine | Figure 6: Upstream (*,*,RP) state-machine
In tabular form, the state machine is: | In tabular form, the state machine is:
+----------------------+------------------------------------------------+| +-------------------+---------------------------------------------------+
| | Event || | | Event |
Prev State +-------------------------+----------------------+| | Prev State +--------------------------+------------------------+
| |JoinDesired(*,*,RP)| JoinDesired(*,*,RP)| || | | JoinDesired(*,*,RP) | JoinDesired(*,*,RP) |
| |->True | ->False | || | | ->True | ->False |
+----------------------+-------------------------+----------------------+| +-------------------+--------------------------+------------------------+
| |-> J state | + || | | -> J state | - |
NotJoined (NJ) | |Send Join(*,*,RP); Set | | || | NotJoined (NJ) | Send Join(*,*,RP); | |
| |Timer to t_periodic | | || | | Set Timer to | |
+----------------------+-------------------------+----------------------+| | | t_periodic | |
Joined (J) | |- +> NJ state | || +-------------------+--------------------------+------------------------+
| | Send Prune(*,*,RP) || | Joined (J) | - | -> NJ state |
+----------------------+-------------------------+----------------------+| | | | Send Prune(*,*,RP) |
+-------------------+--------------------------+------------------------+
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 | to |
| |MRIB.next_hop(RP)| |MRIB.next_hop(RP)| || | | MRIB.next_hop(RP) | MRIB.next_hop(RP) |
+-------------------+----------------------+----------------------------+| +-----------------+---------------------+-------------------------------+
|Send | |Increase Timer to | |Decrease Timer to | || | Send | Increase Timer to | Decrease Timer to |
|Join(*,*,RP); | |t_suppressed | |t_override | || | Join(*,*,RP); | t_suppressed | t_override |
|Set Timer to | | | || | Set Timer to | | |
|t_periodic | | | || | t_periodic | | |
+-------------------+----------------------+----------------------------+| +-----------------+---------------------+-------------------------------+
+-----------------------------------------------------------------------+| +-----------------------------------------------------------------------+
| In Joined (J) State || | In Joined (J) State |
+-----------------------------------+-----------------------------------+| +-----------------------------------+-----------------------------------+
| topology change wrt | | MRIB.next_hop(RP) GenID | || | topology change wrt | MRIB.next_hop(RP) GenID |
| MRIB.next_hop(RP) | | changes | || | MRIB.next_hop(RP) | changes |
+-----------------------------------+-----------------------------------+| +-----------------------------------+-----------------------------------+
| Send Join(*,*,RP) to new | | Decrease Timer to | || | Send Join(*,*,RP) to new | Decrease Timer to |
| next hop; Send | | t_override | || | next hop; Send | t_override |
| Prune(*,*,RP) to old next | | || | Prune(*,*,RP) to old | |
| hop; set Timer to | | || | next hop; set Timer to | |
| t_periodic | | || | t_periodic | |
+-----------------------------------+-----------------------------------+| +-----------------------------------+-----------------------------------+
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
} | }
JoinDesired(*,*,RP) is true when the router has received (*,*,RP) Joins | JoinDesired(*,*,RP) is true when the router has received (*,*,RP) Joins
from any downstream interface. Note that although JoinDesired is true, | from any downstream interface. Note that although JoinDesired is true,
the router's sending of a Join(*,*,RP) message may be suppressed by | the router's sending of a Join(*,*,RP) message may be suppressed by
another router sending a Join(*,*,RP) onto the upstream interface. | another router sending a Join(*,*,RP) onto the upstream interface.
Transitions from NotJoined State | Transitions from NotJoined State
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 MRIB.next_hop(RP). Set the Join Timer (JT)
to expire after t_periodic seconds. | 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 MRIB.next_hop(RP). Cancel the Join Timer
(JT). | (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 MRIB.next_hop(RP). Restart the Join Timer (JT) to expire
after t_periodic seconds. | 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 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.
If the Join Timer is set to expire in less than t_suppressed | If the Join Timer is set to expire in less than t_suppressed
seconds, reset it so that it expires after t_suppressed | seconds, reset it so that it expires after t_suppressed
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_suppressed seconds, leave it unchanged. | t_suppressed 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 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.
Topology Change wrt MRIB.next_hop(RP) | Topology Change wrt MRIB.next_hop(RP)
A route changed in the routing base stored in the MRIB so that | A route changed in the routing base stored in the MRIB so that
the next hop towards the RP is a different neighbor from | the next hop towards the RP is a different neighbor from
before. | before.
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 Prune(*,*,RP) to the old upstream neighbor, which is the
old value of MRIB.next_hop(RP). Send Join(*,*,RP) to the new | old value of MRIB.next_hop(RP). Send Join(*,*,RP) to the new
upstream neighbor which is the new value of MRIB.next_hop(RP). | upstream neighbor which is the new value of MRIB.next_hop(RP).
Set the Join Timer (JT) to expire after t_periodic seconds. | 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.
4.4.6. Sending (*,G) Join/Prune Messages | 4.4.6. Sending (*,G) Join/Prune Messages
The per-interface state-machines for (*,G) hold join state from | The per-interface state-machines for (*,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(*,G) upstream towards the RP. needs to propagate a Join(*,G) upstream towards the RP.
If a router wishes to propagate a Join(*,G) upstream, it must also watch | If a router wishes to propagate a Join(*,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(*,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.6) of immediately. Finally, if it sees the Generation ID (see Section 4.6) 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 In addition if the MRIB changes to indicate that the next hop towards
skipping to change at page 52, line 37 skipping to change at page 53, line 37
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 would like
to join the RP tree for this group. to join 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).
+-----------------------------------+ +-----------------------------------+
| Figures omitted from text version | | Figures omitted from text version |
+-----------------------------------+ +-----------------------------------+
Figure 7: Upstream (*,G) state-machine Figure 7: Upstream (*,G) state-machine
In tabular form, the state machine is: In tabular form, the state machine is:
+---------------------+-------------------------------------------------+ +---------------------+-------------------------------------------------+
skipping to change at page 54, line 8 skipping to change at page 55, line 8
| Send Join(*,G) to new | Decrease Timer to | | Send Join(*,G) to new | Decrease Timer to |
| next hop; Send | t_override | | next hop; Send | t_override |
| Prune(*,G) to old next | | | Prune(*,G) to old next | |
| hop; set Timer to | | | hop; set Timer to | |
| t_periodic | | | t_periodic | |
+----------------------------------+------------------------------------+ +----------------------------------+------------------------------------+
This state machine uses the following macro: This state machine uses the following macro:
bool JoinDesired(*,G) { bool JoinDesired(*,G) {
if immediate_olist(*,G) != NULL | if immediate_olist(*,G) != NULL
return TRUE | return TRUE
else | else
return FALSE | return FALSE
} | }
JoinDesired(*,G) is true when the router has forwarding state that would | JoinDesired(*,G) is true when the router has forwarding state that would
cause it to forward traffic for G using shared tree state. Note that cause it to forward traffic for G using shared tree state. Note that
although JoinDesired is true, the router's sending of a Join(*,G) although JoinDesired is true, the router's sending of a Join(*,G)
message may be suppressed by another router sending a Join(*,G) onto the message may be suppressed by another router sending a Join(*,G) onto the
upstream interface. upstream interface.
Transitions from NotJoined State Transitions from NotJoined State
When the upstream (*,G) state-machine is in NotJoined state, the When the upstream (*,G) state-machine is in NotJoined state, the
following event may trigger a state transition: following event may trigger a state transition:
skipping to change at page 57, line 6 skipping to change at page 58, line 6
Not Joined Not Joined
The downstream state machines and IGMP information do not indicate The downstream state machines and IGMP information do not indicate
that the router needs to join the shortest-path tree for this that the router needs to join the shortest-path tree for this
(S,G). (S,G).
Joined Joined
The downstream state machines and IGMP information indicate that The downstream state machines and IGMP information indicate that
the router should join the shortest-path tree for this (S,G). the router should join the shortest-path tree for 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 toward S, RPF'(S,G).
+-----------------------------------+ +-----------------------------------+
| Figures omitted from text version | | Figures omitted from text version |
+-----------------------------------+ +-----------------------------------+
Figure 8: Upstream (S,G) state-machine Figure 8: Upstream (S,G) state-machine
In tabular form, the state machine is: In tabular form, the state machine is:
+--------------------++-------------------------------------------------+ +--------------------++-------------------------------------------------+
skipping to change at page 58, line 44 skipping to change at page 59, line 44
+----------------------+-------------------------+----------------------+ +----------------------+-------------------------+----------------------+
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
The downstream state for (S,G) has changed so that at least | The downstream state for (S,G) has changed so that at least
one interface is in inherited_olist(S,G), making | one interface is in inherited_olist(S,G), making
JoinDesired(S,G) become True. | JoinDesired(S,G) become True.
The upstream (S,G) state machine transitions to Joined state. | The upstream (S,G) state machine transitions to Joined state.
Send Join(S,G) to the appropriate upstream neighbor, which is | Send Join(S,G) to the appropriate upstream neighbor, which is
RPF'(S,G). Set the Join Timer (JT) to expire after t_periodic | RPF'(S,G). Set the Join Timer (JT) to expire after t_periodic
seconds. | seconds.
Transitions from Joined State | Transitions from Joined State
When the upstream (S,G) state-machine is in Joined state, the following | When the upstream (S,G) state-machine is in Joined state, the following
events may trigger state transitions: | events may trigger state transitions:
JoinDesired(S,G) becomes False | JoinDesired(S,G) becomes False
The downstream state for (S,G) has changed so no interface is | The downstream state for (S,G) has changed so no interface is
in inherited_olist(S,G), making JoinDesired(S,G) become False. | in inherited_olist(S,G), making JoinDesired(S,G) become False.
The upstream (S,G) state machine transitions to NotJoined | The upstream (S,G) state machine transitions to NotJoined
state. Send Prune(S,G) to the appropriate upstream neighbor, | state. Send Prune(S,G) to the appropriate upstream neighbor,
which is RPF'(S,G). Cancel the Join Timer (JT). | which is RPF'(S,G). 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(S,G) | Join(S,G)
Send Join(S,G) to the appropriate upstream neighbor, which is | Send Join(S,G) to the appropriate upstream neighbor, which is
RPF'(S,G). Restart the Join Timer (JT) to expire after | RPF'(S,G). Restart the Join Timer (JT) to expire after
t_periodic seconds. | t_periodic seconds.
See Join(S,G) to RPF'(S,G) | See Join(S,G) to RPF'(S,G)
This event is only relevant if RPF_interface(S) is a shared | This event is only relevant if RPF_interface(S) is a shared
medium. This router sees another router on RPF_interface(S) | medium. This router sees another router on RPF_interface(S)
send a Join(S,G) to RPF'(S,G). This causes this router to | send a Join(S,G) to RPF'(S,G). This causes this router to
suppress its own Join. | suppress its own Join.
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 less than t_suppressed | the Join Timer is set to expire in less than t_suppressed
seconds, reset it so that it expires after t_suppressed | seconds, reset it so that it expires after t_suppressed
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_suppressed seconds, leave it unchanged. | t_suppressed seconds, leave it unchanged.
See Prune(S,G) to RPF'(S,G) |
This event is only relevant if RPF_interface(S) is a shared |
medium. This router sees another router on RPF_interface(S) |
send a Prune(S,G) to RPF'(S,G). As this router is in Joined |
state, it must override the Prune after a short random |
interval. |
The upstream (S,G) state machine remains in Joined state. If | See Prune(S,G) to RPF'(S,G)
the Join Timer is set to expire in more than t_override | This event is only relevant if RPF_interface(S) is a shared
seconds, reset it so that it expires after t_override seconds. | medium. This router sees another router on RPF_interface(S)
send a Prune(S,G) to RPF'(S,G). As this router is in Joined
state, it must override the Prune after a short random
interval.
See Prune(S,G,rpt) to RPF'(S,G) | The upstream (S,G) state machine remains in Joined state. If
This event is only relevant if RPF_interface(S) is a shared | the Join Timer is set to expire in more than t_override
medium. This router sees another router on RPF_interface(S) | seconds, reset it so that it expires after t_override seconds.
send a Prune(S,G,rpt) to RPF'(S,G). If the upstream router is |
an RFC 2362 compliant PIM router, then the Prune(S,G,rpt) will |
cause it to stop forwarding. For backwards compatibility, |
this router should override the prune so that forwarding |
continues. |
The upstream (S,G) state machine remains in Joined state. If | See Prune(S,G,rpt) to RPF'(S,G)
the Join Timer is set to expire in more than t_override | This event is only relevant if RPF_interface(S) is a shared
seconds, reset it so that it expires after t_override seconds. | medium. This router sees another router on RPF_interface(S)
send a Prune(S,G,rpt) to RPF'(S,G). If the upstream router is
an RFC 2362 compliant PIM router, then the Prune(S,G,rpt) will
cause it to stop forwarding. For backwards compatibility,
this router should override the prune so that forwarding
continues.
See Prune(*,G) to RPF'(S,G) | The upstream (S,G) state machine remains in Joined state. If
This event is only relevant if RPF_interface(S) is a shared | the Join Timer is set to expire in more than t_override
medium. This router sees another router on RPF_interface(S) | seconds, reset it so that it expires after t_override seconds.
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 |
it to stop forwarding. For backwards compatibility, this |
router should override the prune so that forwarding continues. |
The upstream (S,G) state machine remains in Joined state. If | See Prune(*,G) to RPF'(S,G)
the Join Timer is set to expire in more than t_override | This event is only relevant if RPF_interface(S) is a shared
seconds, reset it so that it expires after t_override seconds. | medium. This router sees another router on RPF_interface(S)
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
it to stop forwarding. For backwards compatibility, this
router should override the prune so that forwarding continues.
RPF'(S,G) changes | The upstream (S,G) state machine remains in Joined state. If
The current net hop towards the RP changes due an Assert(S,G) | the Join Timer is set to expire in more than t_override
on the RPF_interface(S). | seconds, reset it so that it expires after t_override seconds.
The upstream (S,G) state machine remains in Joined state. If | RPF'(S,G) changes
the Join Timer is set to expire in more than t_override | The current net hop towards the RP changes due an Assert(S,G)
seconds, reset it so that it expires after t_override seconds. | on the RPF_interface(S).
If the Join Timer is set to expire in less than t_override |
seconds, leave it unchanged. |
Topology Change wrt MRIB.next_hop(S) | The upstream (S,G) state machine remains in Joined state. If
A route changed in the routing base stored in the MRIB so that | the Join Timer is set to expire in more than t_override
the next hop towards S is a different neighbor from before. | seconds, reset it so that it expires after t_override seconds.
If the Join Timer is set to expire in less than t_override
seconds, leave it unchanged.
The upstream (S,G) state machine remains in Joined state. | Topology Change wrt MRIB.next_hop(S)
Send Prune(S,G) to the old upstream neighbor, which is the old | A route changed in the routing base stored in the MRIB so that
value of RPF'(S,G). Send Join(S,G) to the new upstream | the next hop towards S is a different neighbor from before.
neighbor which is the new value of RPF(S,G). Note that the |
Join goes to RPF(S,G) and not RPF'(S,G) 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'(S,G) GenID changes | The upstream (S,G) state machine remains in Joined state.
The Generation ID of the router that is RPF'(S,G) changes. | Send Prune(S,G) to the old upstream neighbor, which is the old
This normally means that this neighbor has lost state, and so | value of RPF'(S,G). Send Join(S,G) to the new upstream
the state must be refreshed. | neighbor which is the new value of RPF(S,G). Note that the
Join goes to RPF(S,G) and not RPF'(S,G) 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.
The upstream (S,G) state machine remains in Joined state. If | RPF'(S,G) GenID changes
the Join Timer is set to expire in more than t_override | The Generation ID of the router that is RPF'(S,G) changes.
seconds, reset it so that it expires after t_override seconds. | This normally means that this neighbor has lost state, and so
the state must be refreshed.
The upstream (S,G) state machine remains in Joined state. If
the Join Timer is set to expire in more than t_override
seconds, reset it so that it expires after t_override seconds.
4.4.8. (S,G,rpt) Periodic Messages 4.4.8. (S,G,rpt) Periodic Messages
(S,G,rpt) Joins and Prunes are (S,G) Joins or Prunes sent on the RP tree (S,G,rpt) Joins and Prunes are (S,G) Joins or Prunes sent on the RP tree
with the RPT bit set, either to modify the results of (*,G) Joins, or to with the RPT bit set, either to modify the results of (*,G) Joins, or to
override the behavior of other upstream LAN peers. The next section override the behavior of other upstream LAN peers. The next section
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).
skipping to change at page 62, line 10 skipping to change at page 63, line 10
# 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.
4.4.9. State Machine for (S,G,rpt) Triggered Messages 4.4.9. State Machine for (S,G,rpt) Triggered Messages
The state machine for (S,G,rpt) triggered messages is required per-(S,G) | The state machine for (S,G,rpt) triggered messages is required per-(S,G)
when there is (*,G) or (*,*,RP) join state at a router, and the router | when there is (*,G) or (*,*,RP) join state at a router, and the router
or any of its upstream LAN peers wishes to prune S off the RP tree. | or any of its upstream LAN peers wishes to prune S off the RP tree.
There are three states in the state-machine. One of the states is when |
there is neither (*,G) nor (*,*,RP(G)) join state at this router. If |
there is (*,G) or (*,*,RP(G)) join state at the router, then the state |
machine must be at one of the other two states: |
Pruned(S,G,rpt) | There are three states in the state-machine. One of the states is when
(*,G) or (*,*,RP(G)) Joined, but (S,G,rpt) pruned | there is neither (*,G) nor (*,*,RP(G)) join state at this router. If
there is (*,G) or (*,*,RP(G)) join state at the router, then the state
machine must be at one of the other two states:
NotPruned(S,G,rpt) | Pruned(S,G,rpt)
(*,G) or (*,*,RP(G)) Joined, and (S,G,rpt) not pruned | (*,G) or (*,*,RP(G)) Joined, but (S,G,rpt) pruned
RPTNotJoined(G) | NotPruned(S,G,rpt)
neither (*,G) nor (*,*,RP(G)) has not been joined. | (*,G) or (*,*,RP(G)) Joined, and (S,G,rpt) not pruned
In addition there is an (S,G,rpt) Override Timer, OT(S,G,rpt), which is | RPTNotJoined(G)
used to delay triggered Join(S,G,rpt) messages to prevent implosions of | neither (*,G) nor (*,*,RP(G)) has not been joined.
triggered messages. |
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
triggered messages.
+-----------------------------------+ +-----------------------------------+
| Figures omitted from text version | | Figures omitted from text version |
+-----------------------------------+ +-----------------------------------+
Figure 9: Upstream (S,G,rpt) state-machine for triggered messages Figure 9: Upstream (S,G,rpt) state-machine for triggered messages
In tabular form, the state machine is: In tabular form, the state machine is:
+-------------++---------------------------------------------------------------+ +-------------++---------------------------------------------------------------+
skipping to change at page 63, line 43 skipping to change at page 64, line 43
|expires |(S,G,rpt) to | (S,G,rpt) to |(S,G) to | (S,G,rpt) -> | |expires |(S,G,rpt) to | (S,G,rpt) to |(S,G) to | (S,G,rpt) -> |
| |RPF' | RPF' |RPF' | RPF' (*,G) | | |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 = | stop OT |OT timer = | OT timer = | |Send Join |OT timer = | stop OT |OT timer = | OT timer = |
|(S,G,rpt); |min(timer, | timer |min(timer, | min(timer, | |(S,G,rpt); |min(timer, | timer |min(timer, | min(timer, |
|Stop OT |t_po) | |t_po) | t_po) | |Stop OT |t_po) | |t_po) | t_po) |
|timer | | | | | |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, t_po) = | running timer to have an infinite value (e.g. min(not-running, t_po) =
t_po). | t_po).
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)))
} | }
RPTJoinDesired(G) is true when the router has forwarding state that | RPTJoinDesired(G) is true when the router has forwarding state that
would cause it to forward traffic for G using either (*,G) or (*,*,RP) | would cause it to forward traffic for G using either (*,G) or (*,*,RP)
shared tree state. | shared tree state.
bool PruneDesired(S,G,rpt) { | bool PruneDesired(S,G,rpt) {
return ( RPTJoinDesired(G) AND | return ( RPTJoinDesired(G) AND
( inherited_olist(S,G,rpt) == NULL | ( inherited_olist(S,G,rpt) == NULL
OR (SPTbit(S,G)==TRUE | OR (SPTbit(S,G)==TRUE
AND (RPF'(*,G) != RPF'(S,G)) ))) | AND (RPF'(*,G) != RPF'(S,G)) )))
} | }
PruneDesired(S,G,rpt) can only be true if RPTJoinDesired(G) is true. If | PruneDesired(S,G,rpt) can only be true if RPTJoinDesired(G) is true. If
RPTJoinDesired(G) is true, then PruneDesired(S,G,rpt) is true if either | RPTJoinDesired(G) is true, then PruneDesired(S,G,rpt) is true if either
there are no outgoing interfaces that S would be forwarded on, or if the | there are no outgoing interfaces that S would be forwarded on, or if the
router has active (S,G) forwarding state but RPF'(*,G) != RPF'(S,G). | router has active (S,G) forwarding state but RPF'(*,G) != RPF'(S,G).
The state machine contains the following transition events: | The state machine contains the following transition events:
See Join(S,G,rpt) to RPF'(S,G,rpt) | See Join(S,G,rpt) to RPF'(S,G,rpt)
This event is only relevant in the "Not Pruned" state. | This event is only relevant in the "Not Pruned" state.
The router sees a Join(S,G,rpt) from someone else to RPF'(S,G,rpt), | The router sees a Join(S,G,rpt) from someone else to RPF'(S,G,rpt),
which is the correct upstream neighbor. If we're in "NotPruned" | which is the correct upstream neighbor. If we're in "NotPruned"
state and the (S,G,rpt) override timer is running, then this is | state and the (S,G,rpt) override timer is running, then this is
because we have been triggered to send our own Join(S,G,rpt) to | because we have been triggered to send our own Join(S,G,rpt) to
RPF'(S,G,rpt). Someone else beat us to it, so there's no need to | RPF'(S,G,rpt). Someone else beat us to it, so there's no need to
send our own Join. | send our own Join.
The action is to cancel the override timer. The action is to cancel the override timer.
See Prune(S,G,rpt) to RPF'(S,G,rpt) See Prune(S,G,rpt) to RPF'(S,G,rpt)
This event is only relevant in the "NotPruned" state. This event is only relevant in the "NotPruned" state.
The router sees a Prune(S,G,rpt) from someone else to to The router sees a Prune(S,G,rpt) from someone else to to
RPF'(S,G,rpt), which is the correct upstream neighbor. If we're in RPF'(S,G,rpt), which is the correct upstream neighbor. If we're in
the "NotPruned" state, then we want to continue to receive traffic the "NotPruned" state, then we want to continue to receive traffic
from S destined for G, and that traffic is being supplied by from S destined for G, and that traffic is being supplied by
RPF'(S,G,rpt). Thus we need to override the Prune. RPF'(S,G,rpt). Thus we need to override the Prune.
The action is to set the (S,G,rpt) time to the randomized prune- | The action is to set the (S,G,rpt) time to the randomized prune-
override interval. However if the override timer is already | override interval. However if the override timer is already
running, we only set the timer if doing so would set it to a lower | running, we only set the timer if doing so would set it to a lower
value. At the end of this interval, if no-one else has sent a | value. At the end of this interval, if no-one else has sent a
Join, then we will do so. | Join, then we will do so.
See Prune(S,G) to RPF'(S,G,rpt) See Prune(S,G) to RPF'(S,G,rpt)
This event is only relevant in the "NotPruned" state. This event is only relevant in the "NotPruned" state.
This transition and action are the same as the above transition and This transition and action are the same as the above transition and
action, except that the Prune does not have the RPT bit set. This action, except that the Prune does not have the RPT bit set. This
transition is necessary to be compatible with existing routers that transition is necessary to be compatible with existing routers that
don't maintain separate (S,G) and (S,G,rpt) state. don't maintain separate (S,G) and (S,G,rpt) state.
The (S,G,rpt) prune override timer expires The (S,G,rpt) prune override timer expires
This event is only relevant in the "NotPruned" state. This event is only relevant in the "NotPruned" state.
When the override timer expires, we must send a Join(S,G,rpt) to | When the override timer expires, we must send a Join(S,G,rpt) to
RPF'(S,G,rpt) to override the Prune message that caused the timer RPF'(S,G,rpt) to override the Prune message that caused the timer
to be running. We only send this if RPF'(S,G,rpt) equals RPF'(*,G) to be running. We only send this if RPF'(S,G,rpt) equals RPF'(*,G)
- if this were not the case, then the Join might be sent to a - if this were not the case, then the Join might be sent to a
router that does not have (*,G) or (*,*,RP(G)) Join state, and so | router that does not have (*,G) or (*,*,RP(G)) Join state, and so
the behavior would not be well defined. If RPF'(S,G,rpt) is not | the behavior would not be well defined. If RPF'(S,G,rpt) is not
the same as RPF'(*,G), then it may stop forwarding S. However, if | the same as RPF'(*,G), then it may stop forwarding S. However, if
this happens, then the router will send an AssertCancel(S,G), which | this happens, then the router will send an AssertCancel(S,G), which
would then cause RPF'(S,G,rpt) to become equal to RPF'(*,G) (see | would then cause RPF'(S,G,rpt) to become equal to RPF'(*,G) (see
below). | below).
RPF'(S,G,rpt) changes to become equal to RPF'(*,G) RPF'(S,G,rpt) changes to become equal to RPF'(*,G)
This event is only relevant in the "NotPruned" state. This event is only relevant in the "NotPruned" state.
RPF'(S,G,rpt) can only be different from RPF'(*,G) if an (S,G) RPF'(S,G,rpt) can only be different from RPF'(*,G) if an (S,G)
Assert has happened, which means that traffic from S is arriving on Assert has happened, which means that traffic from S is arriving on
the SPT, and so Prune(S,G,rpt) will have been sent to RPF'(*,G). the SPT, and so Prune(S,G,rpt) will have been sent to RPF'(*,G).
When RPF'(S,G,rpt) changes to become equal to RPF'(*,G), we need to When RPF'(S,G,rpt) changes to become equal to RPF'(*,G), we need to
trigger a Join(S,G,rpt) to RPF'(*,G) to cause that router to start trigger a Join(S,G,rpt) to RPF'(*,G) to cause that router to start
forwarding S again. forwarding S again.
The action is to set the (S,G,rpt) override timer to the randomized | The action is to set the (S,G,rpt) override timer to the randomized
prune-override interval. However if the timer is already running, prune-override interval. However if the timer is already running,
we only set the timer if doing so would set it to a lower value. we only set the timer if doing so would set it to a lower value.
At the end of this interval, if no-one else has sent a Join, then At the end of this interval, if no-one else has sent a Join, then
we will do so. we will do so.
PruneDesired(S,G,rpt)->TRUE PruneDesired(S,G,rpt)->TRUE
See macro above. See macro above.
The router wishes to receive traffic for G, but does not wish to The router wishes to receive traffic for G, but does not wish to
receive traffic from S destined for G. This causes the router to receive traffic from S destined for G. This causes the router to
transition into the Pruned state. transition into the Pruned state.
If the router was previously in NotPruned state, then the action is If the router was previously in NotPruned state, then the action is
to send a Prune(S,G,rpt) to RPF'(S,G,rpt). If the router was to send a Prune(S,G,rpt) to RPF'(S,G,rpt). If the router was
previously in RPTNotJoined(G) state, then there is no need to | previously in RPTNotJoined(G) state, then there is no need to
trigger an action in this state machine because sending a | trigger an action in this state machine because sending a
Prune(S,G,rpt) is handled by the rules for sending the Join(*,G) or Prune(S,G,rpt) is handled by the rules for sending the Join(*,G) or
Join(*,*,RP). Join(*,*,RP).
PruneDesired(S,G,rpt)->FALSE PruneDesired(S,G,rpt)->FALSE
See macro above. This transition is only relevant in the "Pruned" See macro above. This transition is only relevant in the "Pruned"
state. state.
If the router is in the Pruned(S,G,rpt) state, and If the router is in the Pruned(S,G,rpt) state, and
PruneDesired(S,G,rpt) changes to FALSE, this could be because the | PruneDesired(S,G,rpt) changes to FALSE, this could be because the
router no longer has RPTJoinDesired(G) true, or it now wishes to | router no longer has RPTJoinDesired(G) true, or it now wishes to
receive traffic from S again. If it is the former, then this | receive traffic from S again. If it is the former, then this
transition should not happen, but instead the | transition should not happen, but instead the
"RPTJoinDesired(G)->FALSE" transition should happen. Thus this | "RPTJoinDesired(G)->FALSE" transition should happen. Thus this
transition should be interpreted as "PruneDesired(S,G,rpt)->FALSE | transition should be interpreted as "PruneDesired(S,G,rpt)->FALSE
AND RPTJoinDesired(G)==TRUE" | AND RPTJoinDesired(G)==TRUE"
The action is to send a Join(S,G,rpt) to RPF'(S,G,rpt). The action is to send a Join(S,G,rpt) to RPF'(S,G,rpt).
RPTJoinDesired(G)->FALSE RPTJoinDesired(G)->FALSE
The router no longer wishes to receive any traffic destined for G The router no longer wishes to receive any traffic destined for G
on the RP Tree. This causes a transition to the RPTNotJoined(G) | on the RP Tree. This causes a transition to the RPTNotJoined(G)
state. Any actions are handled by the appropriate upstream state | state. Any actions are handled by the appropriate upstream state
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. PIM Assert Messages 4.5. PIM Assert Messages
4.5.1. (S,G) Assert Message State Machine 4.5.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.
I am Assert Winner (W) I am Assert Winner (W)
This router has won an (S,G) assert on interface I. It is now | This router has won an (S,G) assert on interface I. It is now
responsible for forwarding traffic from S destined for G out of | responsible for forwarding traffic from S destined for G out of
interface I. Irrespective of whether it is the DR for I, while a interface I. Irrespective of whether it is the DR for I, while a
router is the assert winner, it is also responsible for forwarding router is the assert winner, it is also responsible for forwarding
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
skipping to change at page 69, line 24 skipping to change at page 70, line 24
| [Actions A5] | [Actions A5] | [Actions A5] | [Actions A2] | | [Actions A5] | [Actions A5] | [Actions A5] | [Actions A2] |
+----------------+-----------------+-----------------+------------------+ +----------------+-----------------+-----------------+------------------+
Note that for reasons of compactness, "AssTrDes(S,G,I)" is used in the Note that for reasons of compactness, "AssTrDes(S,G,I)" is used in the
state-machine table to refer to AssertTrackingDesired(S,G,I). state-machine table to refer to AssertTrackingDesired(S,G,I).
Terminology: Terminology:
A "preferred assert" is one with a better metric than the current A "preferred assert" is one with a better metric than the current
winner. winner.
An "inferior assert" is one with a worse metric than | An "inferior assert" is one with a worse metric than
my_assert_metric(S,G,I). | my_assert_metric(S,G,I).
The state machine uses the following macros: The state machine uses the following macros:
CouldAssert(S,G,I) = | CouldAssert(S,G,I) =
SPTbit(S,G)==TRUE | SPTbit(S,G)==TRUE
AND (RPF_interface(S) != I) | AND (RPF_interface(S) != I)
AND (I in ( ( joins(*,G) (-) prunes(S,G,rpt) ) | AND (I in ( ( 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) (+) pim_include(S,G) ) ) | (+) joins(S,G) (+) pim_include(S,G) ) )
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(*,G) (-) prunes(S,G,rpt) ) (I in ( ( 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) (+) pim_include(S,G) ) ) (+) joins(S,G) (+) pim_include(S,G) ) )
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)==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
information received on I that might cause the router to be interested | information received on I that might cause the router to be interested
in asserts on I. | 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.
The last three lines account for the fact that a router must keep track | The last three lines account for the fact that a router must keep track
of assert information on upstream interfaces in order to send joins and | of assert information on upstream interfaces in order to send joins and
prunes to the proper neighbor. | prunes to the proper neighbor.
Transitions from NoInfo State Transitions from NoInfo State
When in NoInfo state, the following events may trigger transitions: | When in NoInfo state, the following events may trigger transitions:
Receive Inferior Assert with RPTbit cleared Receive Inferior Assert with RPTbit cleared
An assert is received for (S,G) with the RPT bit cleared that An assert is received for (S,G) with the RPT bit cleared that
is inferior to our own assert metric. The RPT bit cleared is inferior to our own assert metric. The RPT bit cleared
indicates that the sender of the assert had (S,G) forwarding indicates that the sender of the assert had (S,G) forwarding
state on this interface. If the assert is inferior to our state on this interface. If the assert is inferior to our
metric, then we must also have (S,G) forwarding state as (S,G) metric, then we must also have (S,G) forwarding state as (S,G)
asserts beat (*,G) asserts, and so we should be the assert asserts beat (*,G) asserts, and so we should be the assert
winner. We transition to the "I am Assert Winner" state, and winner. We transition to the "I am Assert Winner" state, and
perform Actions A1 (below). perform Actions A1 (below).
skipping to change at page 71, line 5 skipping to change at page 71, line 42
(it's a (*,G) assert). CouldAssert(S,G,I) is TRUE only if we (it's a (*,G) assert). CouldAssert(S,G,I) is TRUE only if we
have (S,G) forwarding state on this interface, so we should be have (S,G) forwarding state on this interface, so we should be
the assert winner. We transition to the "I am Assert Winner" the assert winner. We transition to the "I am Assert Winner"
state, and perform Actions A1 (below). state, and perform Actions A1 (below).
An (S,G) data packet arrives on interface I, AND An (S,G) data packet arrives on interface I, AND
CouldAssert(S,G,I)==TRUE CouldAssert(S,G,I)==TRUE
An (S,G) data packet arrived on an downstream interface which An (S,G) data packet arrived on an downstream interface which
is in our (S,G) outgoing interface list. We optimistically is in our (S,G) outgoing interface list. We optimistically
assume that we will be the assert winner for this (S,G), and assume that we will be the assert winner for this (S,G), and
so we transition to the "I am Assert Winner" state, and | so we transition to the "I am Assert Winner" state, and
perform Actions A1 (below) which will initiate the assert | perform Actions A1 (below) which will initiate the assert
negotiation for (S,G). | negotiation for (S,G).
Receive Preferred Assert with RPT bit clear AND Receive Preferred Assert with RPT bit clear AND
AssertTrackingDesired(S,G,I)==TRUE AssertTrackingDesired(S,G,I)==TRUE
We're interested in (S,G) Asserts, either because I is a We're interested in (S,G) Asserts, either because I is a
downstream interface for which we have (S,G) or (*,G) downstream interface for which we have (S,G) or (*,G)
forwarding state, or because I is the upstream interface for S forwarding state, or because I is the upstream interface for S
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 A2 |
(below). | We transition to "I am Assert Loser" and perform actions A2
(below).
Transitions from Winner State Transitions from 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 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 timer (Action A3 below). Note that the assert
winner's timer is engineered to expire shortly before timers winner's timer is engineered to expire shortly before timers
on assert losers; this prevents unnecessary thrashing of the on assert losers; this prevents unnecessary thrashing of the
forwarder and periodic flooding of duplicate packets. 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). 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) which could cause transitions in the upstream | JoinDesired(S,G) which could cause transitions in the upstream
(S,G) state machine. (S,G) state machine.
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
make CouldAssert(S,G,I) become false. We can no longer make CouldAssert(S,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). This includes to NoInfo state and perform actions A4 (below). This includes
sending a "cancelling assert" with an infinite metric. sending a "cancelling assert" with an infinite metric.
Transitions from Loser State Transitions from Loser State
skipping to change at page 72, line 34 skipping to change at page 73, line 22
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. state, deleting the (S,G) assert information.
AssertTrackingDesired(S,G,I)->FALSE AssertTrackingDesired(S,G,I)->FALSE
AssertTrackingDesired(S,G,I) becomes FALSE. Our forwarding AssertTrackingDesired(S,G,I) becomes FALSE. Our forwarding
state has changed so that (S,G) Asserts on interface I are no state has changed so that (S,G) Asserts on interface I are no
longer of interest to us. We transition to the NoInfo state, longer of interest to us. We transition to the NoInfo state,
deleting the (S,G) assert information. deleting the (S,G) assert information.
My metric becomes better than the assert winner's metric My metric becomes better than the assert winner's metric
My routing metrics have changed so that now my assert metric my_assert_metric(S,G,I) has changed so that now my assert |
for (S,G) is better than the metric we have stored for current metric for (S,G) is better than the metric we have stored for |
assert winner. We transition to NoInfo state, delete this current assert winner. This might happen the underlying |
(S,G) assert state, and allow the normal PIM Join/Prune routing metric changes, or when when CouldAssert(S,G,I) |
mechanisms to operate. Usually we will eventually re-assert becomes true; for example, when SPTbit(S,G) becomes true. We |
and win when data packets from S have started flowing again. transition to NoInfo state, delete this (S,G) assert state, |
and allow the normal PIM Join/Prune mechanisms to operate. |
Usually we will eventually re-assert and win when data packets |
from S have started flowing again. |
RPF interface changed away from interface I RPF interface changed away from 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, delete this (S,G) assert not. We transition to NoInfo state, delete this (S,G) assert
state. state.
Receive Join(S,G) Receive Join(S,G)
We receive a Join(S,G) directed to my IP address in interface We receive a Join(S,G) directed to my IP address in interface
I. The action is to transition to NoInfo state, and delete I. The action is to transition to NoInfo state, and delete
this (S,G) assert state, and allow the normal PIM Join/Prune this (S,G) assert state, and allow the normal PIM Join/Prune
skipping to change at page 73, line 12 skipping to change at page 74, line 4
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 timer to (Assert_Time - Assert_Override_Interval)
Store self as AssertWinner Store self as AssertWinner
A2: Store new assert winner
A2: Store new assert winner |
Set timer to Assert_Time Set timer to Assert_Time
A3: Send Assert(S,G) A3: Send Assert(S,G)
Set timer to (Assert_Time - Assert_Override_Interval) Set timer to (Assert_Time - Assert_Override_Interval)
A4: Send AssertCancel(S,G) A4: Send AssertCancel(S,G)
Delete assert info Delete assert info
A5: Delete assert info A5: Delete assert info
skipping to change at page 74, line 8 skipping to change at page 74, line 45
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.
It is important to note that no transition occurs in the (*,G) state | It is important to note that no transition occurs in the (*,G) state
machine as a result of receiving an assert message if the (S,G) assert machine as a result of receiving an assert message if the (S,G) assert
state machine for the relevant S and G is not in the "NoInfo" state. state machine for the relevant S and G is not in the "NoInfo" state.
+-----------------------------------+ +-----------------------------------+
| Figures omitted from text version | | Figures omitted from text version |
+-----------------------------------+ +-----------------------------------+
Figure 11: (*,G) Assert State-machine Figure 11: (*,G) Assert State-machine
In tabular form the state machine is: In tabular form the state machine is:
skipping to change at page 76, line 7 skipping to change at page 77, line 7
| my_metric -> | RPF interface | Receive Join(*,G) | | my_metric -> | RPF interface | Receive Join(*,G) |
| better than | stops being I | or Join(*,*,RP(G)) | | better than | stops being I | or Join(*,*,RP(G)) |
| Winner's metric | | on Interface I | | Winner's metric | | on Interface I |
+----------------------+----------------------+-------------------------+ +----------------------+----------------------+-------------------------+
| -> NI state | -> NI state | -> NI State | | -> NI state | -> NI state | -> NI State |
| [Actions A5] | [Actions A5] | [Actions A5] | | [Actions A5] | [Actions A5] | [Actions A5] |
+----------------------+----------------------+-------------------------+ +----------------------+----------------------+-------------------------+
The state machine uses the following macros: The state machine uses the following macros:
CouldAssert(*,G,I) = | CouldAssert(*,G,I) =
( I in ( joins(*,G) (+) joins(*,*,RP(G)) | ( I in ( joins(*,G) (+) joins(*,*,RP(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
(*,G) or (*,*,RP(G) join state, or local members that requested any | (*,G) or (*,*,RP(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) OR | CouldAssert(*,G) OR
( RPF_interface(RP(G)) == I AND RPTJoinDesired(G) ) | ( RPF_interface(RP(G)) == I AND RPTJoinDesired(G) )
AssertTrackingDesired(*,G,I) is true on any interface on which an (*,G) AssertTrackingDesired(*,G,I) is true on any interface on which an (*,G)
assert might affect our behavior. assert might affect our behavior.
Note that for reasons of compactness, "AssTrDes(*,G,I)" is used in the Note that for reasons of compactness, "AssTrDes(*,G,I)" is used in the
state-machine table to refer to AssertTrackingDesired(*,G,I). state-machine table to refer to AssertTrackingDesired(*,G,I).
Terminology: Terminology:
A "preferred assert" is one with a better metric than the current A "preferred assert" is one with a better metric than the current
winner. winner.
An "inferior assert" is one with a worse metric than | An "inferior assert" is one with a worse metric than
my_assert_metric(S,G). | my_assert_metric(S,G).
Transitions from NoInfo State Transitions from NoInfo State
When in NoInfo state, the following events trigger transitions, but only | When in NoInfo state, the following events trigger transitions, but only
if the (S,G) assert state machine is in NoInfo state: | if the (S,G) assert state machine is in NoInfo state:
Receive Inferior Assert with RPTbit set AND Receive Inferior Assert with RPTbit set AND
CouldAssert(*,G,I)==TRUE CouldAssert(*,G,I)==TRUE
An Inferior (*,G) assert is received for G on Interface I. If An Inferior (*,G) assert is received for G on Interface I. If
CouldAssert(*,G,I) is TRUE, then I is our downstream CouldAssert(*,G,I) is TRUE, then I is our downstream
interface, and we have (*,G) forwarding state on this interface, and we have (*,G) forwarding state on this
interface, so we should be the assert winner. We transition interface, so we should be the assert winner. We transition
to the "I am Assert Winner" state, and perform Actions A1 to the "I am Assert Winner" state, and perform Actions A1
(below). (below).
skipping to change at page 77, line 13 skipping to change at page 78, line 13
transition to the "I am Assert Winner" state, and perform transition to the "I am Assert Winner" state, and perform
Actions A1 (below). Actions A1 (below).
Receive Preferred Assert with RPT bit set AND Receive Preferred Assert with RPT bit set AND
AssertTrackingDesired(*,G,I)==TRUE AssertTrackingDesired(*,G,I)==TRUE
We're interested in (*,G) Asserts, either because I is a We're interested in (*,G) Asserts, either because I is a
downstream interface for which we have (*,G) forwarding state, downstream interface for which we have (*,G) forwarding state,
or because I is the upstream interface for RP(G) and we have or because I is the upstream interface for RP(G) and we have
(*,G) forwarding state. We get a (*,G) Assert that has a (*,G) forwarding state. We get a (*,G) Assert that has a
better metric than our own, so we do not win the Assert. We better metric than our own, so we do not win the Assert. We
transition to "I am Assert Loser" and perform actions A2 | transition to "I am Assert Loser" and perform actions A2
(below). | (below).
Transitions from Winner State Transitions from 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 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 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 timer (Action A3
below). 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 Loser State Transitions from Loser State
When in "I am Assert Loser" state, the following events trigger | When in "I am Assert Loser" 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 Preferred Assert Receive Preferred Assert
We receive a (*,G) assert that is better than that of the We receive a (*,G) assert that is better than that of the
current assert winner. We stay in Loser state, and perform current assert winner. We stay in Loser state, and perform
actions A2 below. actions A2 below.
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 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, and allow the normal state, delete this (*,G) assert state, and allow 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 for G have 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 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. and delete this (*,G) assert info.
AssertTrackingDesired(*,G,I)->FALSE AssertTrackingDesired(*,G,I)->FALSE
AssertTrackingDesired(*,G,I) becomes FALSE. Our forwarding AssertTrackingDesired(*,G,I) becomes FALSE. Our forwarding
state has changed so that (*,G) Asserts on interface I are no state has changed so that (*,G) Asserts on interface I are no
longer of interest to us. We transition to NoInfo state and longer of interest to us. We transition to NoInfo state and
delete this (*,G) assert info. delete this (*,G) assert info.
My metric becomes better than the assert winner's metric My metric becomes better than the assert winner's metric
My routing metrics have changed so that now my assert metric My routing metric, rpt_assert_metric(G,I), has changed so that |
for (*,G) is better than the metric we have stored for current now my assert metric for (*,G) is better than the metric we |
assert winner. We transition to NoInfo state, and delete this have stored for current assert winner. We transition to |
(*,G) assert state, and allow the normal PIM Join/Prune NoInfo state, and delete this (*,G) assert state, and allow |
mechanisms to operate. Usually we will eventually re-assert the normal PIM Join/Prune mechanisms to operate. Usually we |
and win when data packets for G have started flowing again. will eventually re-assert and win when data packets for G have |
started flowing again. |
RPF interface changed away from interface I RPF interface changed away from interface I
Interface I used to be the RPF interface for RP(G), and now it Interface I used to be the RPF interface for RP(G), and now it
is not. We transition to NoInfo state, and delete this (*,G) is not. We transition to NoInfo state, and delete this (*,G)
assert state. | assert state.
Receive Join(*,G) or Join(*,*,RP(G)) | Receive Join(*,G) or Join(*,*,RP(G))
We receive a Join(*,G) or a Join(*,*,RP(G)) directed to my IP | We receive a Join(*,G) or a Join(*,*,RP(G)) directed to my IP
address in interface I. The action is to transition to NoInfo | address in interface I. The action is to transition to NoInfo
state, and delete this (*,G) assert state, and allow the | state, and delete this (*,G) assert state, and allow the
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 timer to (Assert_Time - Assert_Override_Interval)
Store self as AssertWinner(*,G) Store self as AssertWinner(*,G)
A2: Store new AssertWinner(*,G) | A2: Store new AssertWinner(*,G)
Set timer to assert_time Set timer to assert_time
A3: Send Assert(*,G) A3: Send Assert(*,G)
Set timer to (Assert_Time - Assert_Override_Interval) Set timer to (Assert_Time - Assert_Override_Interval)
A4: Send AssertCancel(*,G) A4: Send AssertCancel(*,G)
Delete assert info Delete assert info
A5: Delete assert info A5: Delete assert info
skipping to change at page 79, line 41 skipping to change at page 80, line 44
Assert metrics are defined as: Assert metrics are defined as:
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 IP address of the router that
sourced the Assert message is used as a tie-breaker, with the highest IP | sourced the Assert message is used as a tie-breaker, with the highest IP
address winning. 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,G,I) | return spt_assert_metric(S,G,I)
} else if( CouldAssert(*,G,I) == TRUE ) { | } else if( CouldAssert(*,G,I) == TRUE ) {
return rpt_assert_metric(G,I) | return rpt_assert_metric(G,I)
} else { | } else {
return infinite_assert_metric() | return infinite_assert_metric()
} | }
} | }
spt_assert_metric(S,I) gives the assert metric we use if we're sending | spt_assert_metric(S,I) gives the assert metric we use if we're sending
an assert based on active (S,G) forwarding state: | an assert based on active (S,G) forwarding state:
assert_metric | assert_metric
spt_assert_metric(S,I) { | spt_assert_metric(S,I) {
return {0,MRIB.pref(S),MRIB.metric(S),my_ip_address(I)} | return {0,MRIB.pref(S),MRIB.metric(S),my_ip_address(I)}
} | }
rpt_assert_metric(G,I) gives the assert metric we use if we're sending rpt_assert_metric(G,I) gives the assert metric we use if we're sending
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. 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,infinity} return {1,infinity,infinity,infinity}
} }
4.5.4. AssertCancel Messages 4.5.4. AssertCancel Messages
An AssertCancel message is simply an RPT Assert message but with An AssertCancel message is simply an RPT Assert message but with
infinite metric. It is sent by the assert winner when it deletes the infinite metric. It is sent by the assert winner when it deletes the
forwarding state that had caused the assert to occur. Other routers forwarding state that had caused the assert to occur. Other routers
will see this metric, and it will cause any other router that has | will see this metric, and it will cause any other router that has
forwarding state to send its own assert, and to take over forwarding. | forwarding state to send its own assert, and to take over forwarding.
An AssertCancel(S,G) is an infinite metric assert with the RPT bit set An AssertCancel(S,G) is an infinite metric assert with the RPT bit set
that names S as the source. that names S as the source.
An AssertCancel(*,G) is an infinite metric assert with the RPT bit set, An AssertCancel(*,G) is an infinite metric assert with the RPT bit set,
and typically will name RP(G) as the source as it cannot name an and typically will name RP(G) as the source as it cannot name an
appropriate S. appropriate S.
AssertCancel messages are simply an optimization. The original Assert | AssertCancel messages are simply an optimization. The original Assert
timeout mechanism will allow a subnet to eventually become consistent; | timeout mechanism will allow a subnet to eventually become consistent;
the AssertCancel mechanism simply causes faster convergence. No special | the AssertCancel mechanism simply causes faster convergence. No special
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.5.5. Assert State Macros 4.5.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 ) { | if ( RPF_interface(RP) == I OR |
( RPF_interface(S) == I AND SPTbit(S,G) == TRUE ) ) { |
return FALSE | return FALSE |
} else { | } else { |
return ( AssertWinner(S,G,I) != me ) | return ( 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 ) {
return FALSE | return FALSE
} else { | } else {
return ( AssertWinner(S,G,I) != me AND | return ( AssertWinner(S,G,I) != me AND
(AssertWinnerMetric(S,G,I) is better | (AssertWinnerMetric(S,G,I) is better
than spt_assert_metric(S,G,I) ) | than spt_assert_metric(S,G,I) )
} | }
} | }
bool lost_assert(*,G,I) { | bool lost_assert(*,G,I) {
if ( RPF_interface(RP) == I ) { | if ( RPF_interface(RP) == I ) {
return FALSE | return FALSE
} else { | } else {
return ( AssertWinner(*,G,I) != me ) | return ( AssertWinner(*,G,I) != me )
} | }
} | }
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.
Rationale for Assert Rules | Rationale for Assert Rules
The following is a summary of the rules for sending and reacting to | The following is a summary of the rules for sending and reacting to
asserts. It is not intended to be definitive (the state machines and | asserts. It is not intended to be definitive (the state machines and
pseudocode provide the definitive behavior). Instead it provides some | pseudocode provide the definitive behavior). Instead it provides some
rationale for the behavior. | rationale for the behavior.
1. Downstream neighbors send Join(*,G) and Join(S,G) periodic messages | 1. Downstream neighbors send Join(*,G) and Join(S,G) periodic messages
to the appropriate RPF' neighbor, i.e., the RPF neighbor as | to the appropriate RPF' neighbor, i.e., the RPF neighbor as
modified by the assert process. Normal suppression and override | modified by the assert process. Normal suppression and override
rules apply. | rules apply.
This guarantees that all requested traffic will continue to arrive. | This guarantees that all requested traffic will continue to arrive.
This doesn't allow switching back to the "normal" RPF neighbor | This doesn't allow switching back to the "normal" RPF neighbor
until the assert times out, which it won't while data is flowing if | until the assert times out, which it won't while data is flowing if
we are implementing rule 8. we are implementing rule 8.
2. The assert winner for (*,G) acts as the local DR for (*,G) on | 2. The assert winner for (*,G) acts as the local DR for (*,G) on
behalf of IGMP members. | behalf of IGMP members.
This is required to allow a single router to merge PIM and IGMP This is required to allow a single router to merge PIM and IGMP
joins and leaves. Without this, overrides don't work. joins and leaves. Without this, overrides don't work.
3. The assert winner for (S,G) must act as the local DR for (S,G) on 3. The assert winner for (S,G) must act as the local DR for (S,G) on
behalf of IGMPv3 members. behalf of IGMPv3 members.
Same rationale as (2) Same rationale as (2)
4. (S,G) and (*,G) prune overrides are sent to the RPF' neighbor and 4. (S,G) and (*,G) prune overrides are sent to the RPF' neighbor and
skipping to change at page 83, line 14 skipping to change at page 84, line 14
This avoids keeping state alive on (S,G) tree when only (*,G) This avoids keeping state alive on (S,G) tree when only (*,G)
downstream members are left. Also, it avoids sending (S,G,rpt) downstream members are left. Also, it avoids sending (S,G,rpt)
joins to a router that is not on the (*,G) tree. This might be joins to a router that is not on the (*,G) tree. This might be
confusing and could be interpreted as being undefined although confusing and could be interpreted as being undefined although
technically the current spec says to drop such a join. technically the current spec says to drop such a join.
6. An assert loser that receives a Join(S,G) directed to it cancels 6. An assert loser that receives a Join(S,G) directed to it cancels
the (S,G) assert timer. the (S,G) assert timer.
7. An assert loser that receives a Join(*,G) or a Join(*,*,RP(G)) | 7. An assert loser that receives a Join(*,G) or a Join(*,*,RP(G))
directed to it cancels the (*,G) assert timer and all (S,G) assert | directed to it cancels the (*,G) assert timer and all (S,G) assert
timers that do not have corresponding Prune(S,G,rpt) messages in | timers that do not have corresponding Prune(S,G,rpt) messages in
the compound Join/Prune message. | the compound Join/Prune message.
Rules 7 and 8 help convergence during topology changes. Rules 7 and 8 help convergence during topology changes.
8. An assert winner for (*,G) or (S,G) sends a canceling assert when | 8. 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) entry. This | it is about to stop forwarding on a (*,G) or an (S,G) entry. This
rule does not apply to (S,G,rpt). | rule does not apply to (S,G,rpt).
This allow switching back to the shared tree after the last SPT | This allow switching back to the shared tree after the last SPT
router on the lan leaves. We don't want RPT downstream routers to router on the lan leaves. We don't want RPT downstream routers to
keep SPT state alive. keep SPT state alive.
9. [Optionally] re-assert before timing out. 9. [Optionally] re-assert before timing out.
This prevents periodic duplicates. This prevents periodic duplicates.
10. When RPF'(S,G,rpt) changes to be the same as RPF'(*,G) we need to 10. When RPF'(S,G,rpt) changes to be the same as RPF'(*,G) we need to
trigger a Join(S,G,rpt) to RPF(*,G). trigger a Join(S,G,rpt) to RPF(*,G).
skipping to change at page 84, line 6 skipping to change at page 85, line 6
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). A router must record the Hello information Designated Router (DR). A router must record the Hello information
received from each PIM neighbor. received from each PIM neighbor.
Hello messages are sent periodically on each PIM-enabled interface. Hello messages are sent periodically on each PIM-enabled interface.
Hello messages are multicast to address 224.0.0.13 (the ALL-PIM-ROUTERS Hello messages are multicast to address 224.0.0.13 (the ALL-PIM-ROUTERS
group). Hello messages must be sent on all active interfaces, including group). Hello messages must be sent on all active interfaces, including
physical point-to-point links. When PIM is enabled on an interface or a | physical point-to-point links. When PIM is enabled on an interface or a
router first starts, the hello timer is set to a random value between 0 | router first starts, the hello timer is set to a random value between 0
and Hello_Period to prevent synchronization of Hello messages if | and Triggered_Hello_Delay to prevent synchronization of Hello messages |
multiple routers are powered on simultaneously. After the initial if multiple routers are powered on simultaneously. After the initial |
randomized interval, Hello messages must be sent every Hello_Period randomized interval, Hello messages must be sent every Hello_Period
seconds. A single hello timer is used to trigger sending Hello messages seconds. A single hello timer is used to trigger sending Hello messages
on all active interfaces. The hello timer should not be reset except on all active interfaces. The hello timer should not be reset except
when it expires. when it expires.
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
skipping to change at page 84, line 31 skipping to change at page 85, line 31
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.
The Generation Identifier (GenID) Option SHOULD be included in all Hello The Generation Identifier (GenID) Option SHOULD be included in all Hello
messages. The generation ID option contains a randomly generated 32-bit messages. The generation ID option contains a randomly generated 32-bit
value that is regenerated each time PIM forwarding is started or value that is regenerated each time PIM forwarding is started or
restarted on the interface, including when the router itself restarts. restarted on the interface, including when the router itself restarts.
When a Hello message with a new GenID is received from a neighbor, any When a Hello message with a new GenID is received from a neighbor, any
old Hello information about that neighbor SHOULD be discarded and old Hello information about that neighbor SHOULD be discarded and
superseded by the information from the new Hello message. This may superseded by the information from the new Hello message. This may
cause a new DR to be chosen on that interface. cause a new DR to be chosen on that interface. |
When an interface goes down or changes IP address, a Hello message with | To allow new or rebooting routers to learn of PIM neighbors quickly, |
a zero Hold Time should be sent immediately (with the old IP address if | when a Hello message is received from a new neighbor, or a Hello message |
the IP address changed). This will cause PIM neighbors to remove this | with a new GenID is received from an existing neighbor, a new Hello |
neighbor (or its old IP address) immediately. | message should be sent on this interface after a randomized delay |
between 0 and Triggered_Hello_Delay. This triggered message need not |
change the timing of the scheduled periodic message. |
When an interface goes down or changes IP address, a Hello message with
a zero Hold Time should be sent immediately (with the old IP address if
the IP address changed). This will cause PIM neighbors to remove this
neighbor (or its old IP address) immediately.
4.6.2. DR Election 4.6.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.ip_address
skipping to change at page 85, line 38 skipping to change at page 87, line 7
dr = neighbor dr = neighbor
} }
} }
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.ip_address > b.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.ip_address > b.ip_address )
} | }
} | }
The DR election priority is a 32-bit unsigned number and the numerically The DR election priority is a 32-bit unsigned number and the numerically
larger priority is always preferred. A router's idea of the current DR larger priority is always preferred. A router's idea of the current DR
on an interface can change when a PIM-Hello message is received, when a on an interface can change when a PIM-Hello message is received, when a
neighbor times out, or when a router's own dr priority changes. If the neighbor times out, or when a router's own DR priority changes. If the |
router becomes the DR or ceases to be the DR, this will normally cause router becomes the DR or ceases to be the DR, this will normally cause |
the DR Register state-machine to change state. Subsequent actions are the DR Register state-machine to change state. Subsequent actions are
determined by that state-machine. determined by that state-machine.
4.7. PIM Bootstrap and RP Discovery 4.7. PIM Bootstrap and RP Discovery
To obtain the RP information, all routers within a PIM domain collect For correct operation, every PIM router within a PIM domain must be able |
Bootstrap messages. Bootstrap messages are sent hop-by-hop within the to map a particular multicast group address to the same RP. If this is |
domain; the domain's bootstrap router (BSR) is responsible for not the case then black holes may appear, where some receivers in the |
originating the Bootstrap messages. Bootstrap messages are used to carry domain cannot receive some groups. A domain in this context is a |
out a dynamic BSR election when needed and to distribute RP information contiguous set of routers that all implement PIM and are configured to |
in steady state. operate within a common boundary defined by PIM Multicast Border Routers |
(PMBRs). PMBRs connect each PIM domain to the rest of the Internet. |
A domain in this context is a contiguous set of routers that all
implement PIM and are configured to operate within a common boundary
defined by PIM Multicast Border Routers (PMBRs). PMBRs connect each PIM
domain to the rest of the internet.
Routers use a set of available RPs (called the RP-Set) distributed in
Bootstrap messages to get the proper Group to RP mapping. The following
paragraphs give an overview of this process. The mechanism is specified
in Sections 4.7.2 and 4.7.4.
4.7.1. Overview of RP Discovery
A small set of routers from a domain are configured as candidate
bootstrap routers (C-BSRs) and, through a simple election mechanism, a
single BSR is selected for that domain. A set of routers within a domain
are also configured as candidate RPs (C-RPs); typically these will be
the same routers that are configured as C-BSRs. Candidate RPs
periodically unicast Candidate-RP-Advertisement messages (C-RP-Advs) to
the BSR of that domain, advertising their willingness to be an RP. A C-
RP-Adv message includes the address of the advertising C-RP, as well as
an optional list of group addresses and a mask length fields, indicating
the group prefix(es) for which the candidacy is advertised. The BSR then
includes a set of these Candidate-RPs (the RP-Set), along with the
corresponding group prefixes, in Bootstrap messages it periodically
originates. Bootstrap messages are distributed hop-by-hop throughout
the domain.
All the PIM routers in the domain receive and store Bootstrap messages
originated by the BSR. When a DR gets a indication of local membership
from IGMP or a data packet from a directly connected host, for a group
for which it has no forwarding state, the DR uses a hash function to map
the group address to one of the C-RPs whose group-prefix includes the
group (see Section 4.7.5 ). The DR then sends a Join message towards
that RP if the local host joined the group, or it Register-encapsulates
and unicasts the data packet to the RP if the local host sent a packet
to the group.
A Bootstrap message indicates liveness of the RPs included therein. If
an RP is included in the message, then it is tagged as `up' at the
routers; while RPs not included in the message are removed from the list
of RPs over which the hash algorithm acts. Each router continues to use
the contents of the most recently received Bootstrap message from the
BSR until it receives a new Bootstrap message.
If a PIM domain becomes partitioned, each area separated from the old
BSR will elect its own BSR, which will distribute an RP-Set containing
RPs that are reachable within that partition. When the partition heals,
another election will occur automatically and only one of the BSRs will
continue to send out Bootstrap messages. As is expected at the time of a
partition or healing, some disruption in packet delivery may occur. This
time will be on the order of the region's round-trip time and the
bootstrap router timeout value.
4.7.2. Bootstrap Router Election and RP-Set Distribution
For simplicity, bootstrap messages (BSMs) are used in both the BSR
election and the RP-Set distribution mechanisms.
The state-machine for bootstrap messages depends on whether or not a
router has been configured to be a Candidate-BSR. The state-machine for
a C-BSR is given below, followed by the state-machine for a router that
is not configured to be a C-BSR.
Candidate-BSR State Machine
+-----------------------------------+
| Figures omitted from text version |
+-----------------------------------+
Figure 12: State-machine for a candidate BSR
In tabular form this state machine is:
+-------------------++--------------------------------------------------+
| || Event |
| Prev State ++------------------------+-------------------------+
| || Receive Preferred | BS Timer Expires |
| || BSM | |
+-------------------++------------------------+-------------------------+
| || -> C-BSR state | -> P-BSR state |
| Candidate BSR || Forward BSM; Set | Set BS Timer to |
| (C-BSR) || BS Timer to BS | rand_override |
| || Timeout | |
+-------------------++------------------------+-------------------------+
| || -> C-BSR state | -> E-BSR state |
| Pending BSR || Forward BSM; Set | Originate BSM; Set |
| (P-BSR) || BS Timer to BS | BS Timer to BS |
| || Timeout | Period |
+-------------------++------------------------+-------------------------+
| || -> C-BSR state | -> E-BSR state |
| Elected BSR || Forward BSM; Set | Originate BSM; Set |
| (E-BSR) || BS Timer to BS | BS Timer to BS |
| || Timeout | Period |
+-------------------++------------------------+-------------------------+
A candidate-BSR may be in one of three states:
Candidate-BSR (C-BSR)
The router is a candidate to be a BSR, but currently another router
is the preferred BSR.
Pending-BSR (P-BSR)
The router is a candidate to be a BSR. Currently no other router
is the preferred BSR, but this router is not yet the BSR. For
comparisons with incoming BS messages, the router treats itself as
the BSR. This is a temporary state that prevents rapid thrashing
of the choice of BSR during BSR election.
Elected-BSR (E-BSR)
The router is the elected bootstrap router and it must perform all
the BSR functions.
On startup, the initial state is "Pending-BSR", and the BS Timer is
initialized to the BS Timeout value.
In addition, there is a single timer - the bootstrap timer (BS Timer) -
that is used to time out old bootstrap router information, and used in
the election process to terminate P-BSR state.
State-machine for Non-Candidate-BSR Routers
+-----------------------------------+
| Figures omitted from text version |
+-----------------------------------+
Figure 13: State-machine for a router not configured as C-BSR
In tabular form this state machine is:
+-----------------------+-----------------------------------------------+
| | Event |
|Prev State +----------------+----------------+-------------+
| | Receive | Receive BSM |BS Timer |
| | Preferred BSM | |Expires |
+-----------------------+----------------+----------------+-------------+
| | -> AP State | -> AP State |- |
| | Forward BSM; | Forward BSM; | |
|Accept Any (AA) | Store RP-Set; | Store RP-Set; | |
| | Set BS Timer | Set BS Timer | |
| | to BS Timeout | to BS Timeout | |
+-----------------------+----------------+----------------+-------------+
| | -> AP State | - |-> AA State |
| | Forward BSM; | | |
|Accept Preferred (AP) | Store RP-Set; | | |
| | Set BS Timer | | |
| | to BS Timeout | | |
+-----------------------+----------------+----------------+-------------+
A router that is not a candidate-BSR may be in one of two states:
Accept Any (AA)
The router does not know of an active BSR, and will accept the
first bootstrap message it sees as giving the new BSR's identity
and the RP-Set. If the router has an RP-Set cached from an
obsolete bootstrap message, it continues to use it.
Accept Preferred (AP)
The router knows the identity of the current BSR, and is using the
RP-Set provided by that BSR. Only bootstrap messages from that BSR
or from a C-BSR with higher weight than the current BSR will be
accepted.
On startup, the initial state is "Accept Any".
In addition, there is a single timer - the bootstrap timer (BS Timer)
that is used to time out old bootstrap router information.
Bootstrap Message Processing Checks
When a bootstrap message is received, the following initial checks must
be performed:
if (BSM.dst_ip_address == ALL-PIM-ROUTERS group) {
if ( BSM.src_ip_address != RPF_neighbor(BSM.BSR_ip_address) ) {
drop the BS message silently
}
} else if (BSM.dst_ip_address is one of my addresses) {
if ( (BSR state != Accept Any)
OR (DirectlyConnected(BSM.src_ip_address) == FALSE) ) {
#the packet was unicast, but this wasn't
#a quick refresh on startup
drop the BS message silently
}
} else {
drop the BS message silently
}
Basically, the packet must have been sent to the ALL-PIM-ROUTERS group
by the correct upstream router towards the BSR that originated the BS
message, or the router must have no BSR state (it just restarted) and
have received the BS message by unicast from a directly connected
neighbor.
BS State-machine Transition Events
If the bootstrap message passes the initial checks above without being
discarded, then it may cause a state transition event in one of the
above state-machines. For both candidate and non-candidate BSRs, the
following transition events are defined:
Receive Preferred BSM
A bootstrap message is received from a BSR that has greater
than or equal weight than the current BSR. In a router is in
P-BSR state, then it uses its own weight as that of the
current BSR.
The weighting for a BSR is the concatenation in fixed-
precision unsigned arithmetic of the BSR priority field from
the bootstrap message and the IP address of the BSR from the
bootstrap message (with the BSR priority taking the most-
significant bits and the IP address taking the least
significant bits).
Receive BSM
A bootstrap message is received, regardless of BSR weight.
BS State-machine Actions
The state-machines specify actions that include setting the BS timer to
the following values:
BS Period
The periodic interval with which bootstrap messages are
normally sent. The default value is 60 seconds.
BS Timeout
The interval after which bootstrap router state is timed out
if no bootstrap message from that router has been heard. The
default value is 2.5 times the BS Period, which is 150
seconds.
Randomized Override Interval
The randomized interval during which a router avoids sending a
bootstrap message while it waits to see if another router has
a higher bootstrap weight. This interval is to reduce control
message overhead during BSR election. The following
pseudocode is proposed as an efficient implementation of this
"randomized" value:
Delay = 5 + 2 * log_2(1 + bestPriority - myPriority)
+ AddrDelay
where myPriority is the Candidate-BSR's configured priority,
and bestPriority equals:
bestPriority = Max(storedPriority, myPriority)
and AddrDelay is given by the following:
if ( bestPriority == myPriority) {
AddrDelay = log_2(bestAddr - myAddr) / 16
} else {
AddrDelay = 2 - (myAddr / 2^31)
}
where myAddr is the Candidate-BSR's address, and bestAddr is
the stored BSR's address.
In addition to setting the timer, the following actions may be triggered
by state-changes in the state-machines:
Forward BSM
The bootstrap message is forwarded out of all multicast-
capable interfaces except the interface it was received on.
The source IP address of the message is the forwarding
router's IP address on the interface the message is being
forwarded from, the destination address is ALL-PIM-ROUTERS,
and the TTL of the message is set to 1.
Originate BSM
A new bootstrap message is constructed by the BSR, giving the
BSR's address and BSR priority, and containing the BSR's
chosen RP-Set. The message is forwarded out of all multicast-
capable interfaces. The IP source address of the message is
the forwarding router's IP address on the interface the
message is being forwarded from, the destination address is
ALL-PIM-ROUTERS, and the TTL of the message is set to 1.
Store RP Set
The RP-Set from the received bootstrap message is stored and
used by the router to decide the RP for each group that the
router has state for. Storing this RP Set may cause other
state-transitions to occur in the router. The BSR's IP
address and priority from the received bootstrap message are
also stored to be used to decide if future bootstrap messages
are preferred.
In addition to the above state-machine actions, a DR also unicasts a
stored copy of the Bootstrap message to each new PIM neighbor, i.e.,
after the DR receives the neighbor's first Hello message. It does so
even if the new neighbor becomes the DR.
4.7.3. Sending Candidate-RP-Advertisements
Every C-RP periodically unicasts a C-RP-Adv to the BSR for that domain
to inform the BSR of the C-RP's willingness to function as an RP. The
interval for sending these messages is subject to local configuration at
the C-RP, but must be smaller than the HoldTime in the C-RP-Adv.
A Candidate-RP-Advertisement carries a list of group address and group
mask field pairs. This enables the C-RP router to limit the
advertisement to certain prefixes or scopes of groups. If the C-RP
becomes an RP, it may enforce this scope acceptance when receiving
Registers or Join/Prune messages. C-RPs should normally send C-RP-Adv
messages with the `Priority' field set to `0'.
4.7.4. Receiving Candidate-RP-Advertisements at the BSR and Creating A notable exception to this is where a PIM domain is broken up into |
the RP-Set multiple administrative scope regions - these are regions where a border |
has been configured so that a range of multicast groups will not be |
forwarded across that border. For more information on Administratively |
Scoped IP Multicast, see RFC 2365. The modified criteria for admin- |
scoped regions are that the region is convex with respect to forwarding |
based on the MRIB, and that all PIM routers within the scope region map |
scoped groups to the same RP within that region. |
Upon receiving a C-RP-Adv, if the router is not the elected BSR, it This specification does not mandate the use of a single mechanism to |
silently ignores the message. provide routers with the information to perform the group-to-RP mapping. |
Currently three mechanisms are possible, and all three have associated |
problems: |
If the router is the BSR, then it adds the RP address to its local pool Static Configuration |
of candidate RPs. For each C-RP, the BSR holds the following A PIM router MUST support the static configuration of group-to-RP |
information: mappings. Such a mechanism is not robust to failures, but does at |
least provide a basic interoperability mechanism. |
IP address Cisco's Auto-RP |
The IP address of the C-RP. Auto-RP uses a PIM Dense-Mode multicast group to announce group-to- |
RP mappings from a central location. This mechanism is not useful |
if PIM Dense-Mode is not being run in parallel with PIM Sparse- |
Mode, and was only intended for use with PIM Sparse-Mode Version 1. |
No standard specification currently exists. |
Group Prefix and Mask list BootStrap Router (BSR) |
The list of group prefixes and group masks from the C-RP RFC 2362 specifies a bootstrap mechanism based around the automatic |
advertisement. election of a bootstrap router (BSR). Any router in the domain |
that is configured to be a possible RP reports its candidacy to the |
BSR, and then a domain-wide flooding mechanism distributes the |
BSR's chosen set of RPs throughout the domain. As specified in RFC |
2362, BSR is flawed in its handling of admin-scoped regions that |
are smaller than a PIM domain, but the mechanism does work for |
global-scoped groups. |
HoldTime As far as PIM-SM is concerned, the only important requirement is that |
The HoldTime from the C-RP-Adv message. This is included all routers in the domain (or admin scope zone for scoped regions) |
later in the RP-set information in the Bootstrap Message. receive the same set of group-range-to-RP mappings. This may be |
achieved through the use of any of these mechansms, or through |
alternative mechanisms not currently specified. |
C-RP Expiry Timer Any RP address configured or learned MUST be a domain-wide reachable |
The C-RP-Expiry Timer is used to time out the C-RP when the address. |
BSR fails to receive C-RP-Advertisements from it. The expiry
timer is initialized to the HoldTime from the RP's C-RP-Adv,
and is reset to the HoldTime whenever a C-RP-Adv is received
from that C-RP.
C-RP Priority 4.7.1. Group-to-RP Mapping
Do we store this?
When the C-RP Expiry Timer expires, the C-RP is removed from the pool of Using one of the mechanisms described above, a PIM router receives one |
available C-RPs. or more possible group-range-to-RP mappings. Each mapping specifies a |
range of multicast groups (expressed as a group and mask) and the RP to |
which such groups should be mapped. Each mapping may also have an |
associated priority. It is possible to receive multiple mappings all of |
which might match the same multicast group - this is the common case |
with BSR. The algorithm for performing the group-to-RP mapping is as |
follows: |
The BSR uses the pool of C-RPs to construct the RP-Set which is included 1 Perform longest match on group-range to obtain a list of RPs. |
in Bootstrap Messages and sent to all the routers in the PIM domain.
The BSR may apply a local policy to limit the number of Candidate RPs
included in the Bootstrap message. The BSR may override the prefix
indicated in a C-RP-Adv unless the `Priority' field from the C-RP-Adv is
not zero.
The Bootstrap message is subdivided into sets of group-prefix,RP- 2 From this list of matching RPs, find the one with highest priority. |
Count,RP-addresses. For each RP-address, the corresponding HoldTime is Eliminate any RPs from the list that have lower priorities. |
included in the "RP-HoldTime" field. The format of the Bootstrap
message allows `semantic fragmentation', if the length of the original
Bootstrap message exceeds the packet maximum boundaries. However, we
recommend against configuring a large number of routers as C-RPs, to
reduce the semantic fragmentation required.
4.7.5. Receiving and Using the RP-Set 3 If only one RP remains in the list, use that RP. |
When a router receives and stores a new RP-Set, it checks if each of the 4 If multiple RPs are in the list, use the PIM hash function to |
RPs referred to by existing state (i.e., by (*,G), (*,*,RP), or choose one. |
(S,G,rpt) entries) is in the new RP-Set.
If an RP is not in the new RP-set, that RP is considered unreachable and Thus if two or more group-range-to-RP mappings cover a particular group, |
the hash algorithm (see below) is re-performed for each group with the one with the longest mask is the mapping to use. If the mappings |
locally active state that previously hashed to that RP. This will cause have the same mask length, then the one with the highest priority is |
those groups to be distributed among the remaining RPs. chosen. If there is more than one matching entry with the same longest |
mask and the priorities are identical, then a hash function (see Section |
4.7.2) is applied to choose the RP. |
If the new RP-Set contains a RP that was not previously in the RP-Set, This algorithm is invoked by a DR when it needs to determine an RP for a |
the hash value of the new RP is calculated for each group covered by the given group, e.g. upon reception of a packet or IGMP membership |
new C-RP's Group-prefix. Any group for which the new RP's hash value is indication for a group for which the DR does not know the RP. It is |
greater than hash value of the group's previous RP is switched over to invoked by any router that has (*,*,RP) state when a packet is received |
the new RP. for which there is no corresponding (S,G) or (*,G) entry. Furthermore, |
the mapping function is invoked by all routers upon receiving a (*,G) or |
(*,*,RP) Join/Prune message. |
Hash Function Note that if the set of possible group-range-to-RP mappings changes, |
each router will need to check whether any existing groups are affected. |
This may, for example, cause a DR or acting DR to re-join a group, or |
cause it to re-start register encapsulation to the new RP. |
The hash function is used by all routers within a domain, to map a group 4.7.2. Hash Function
to one of the C-RPs from the RP-Set. For a particular group, G, the hash
function uses only those C-RPs whose Group-prefix covers G. The
algorithm takes as input the group address, and the addresses of the
Candidate RPs, and gives as output one RP address to be used.
The hash function is used by all routers within a domain, to map a group |
to one of the RPs from the matching set of group-range-to-RP mappings |
(this set all have the same longest mask length and same highest |
priority). The algorithm takes as input the group address, and the |
addresses of the candidate RPs from the mappings, and gives as output |
one RP address to be used. |
The protocol requires that all routers hash to the same RP within a The protocol requires that all routers hash to the same RP within a
domain (except for transients). The following hash function must be used domain (except for transients). The following hash function must be used
in each router: in each router:
1 For RP addresses in the RP-Set, whose Group-prefix is the longest 1 For RP addresses in the matching group-range-to-RP mappings, |
that covers G, select the RPs with the highest priority (i.e. compute a value: |
lowest `Priority' value), and compute a value:
Value(G,M,C(i))= Value(G,M,C(i))=
(1103515245 * ((1103515245 * (G&M)+12345) XOR C(i)) + 12345) mod 2^31 (1103515245 * ((1103515245 * (G&M)+12345) XOR C(i)) + 12345) mod 2^31
where C(i) is the RP address and M is a hash-mask included in where C(i) is the RP address and M is a hash-mask included in
Bootstrap messages. The hash-mask allows a small number of Bootstrap messages. The hash-mask allows a small number of
consecutive groups (e.g., 4) to always hash to the same RP. For consecutive groups (e.g., 4) to always hash to the same RP. For
instance, hierarchically-encoded data can be sent on consecutive instance, hierarchically-encoded data can be sent on consecutive
group addresses to get the same delay and fate-sharing group addresses to get the same delay and fate-sharing
characteristics. characteristics.
For address families other than IPv4, a 32-bit digest to be used as For address families other than IPv4, a 32-bit digest to be used as |
C(i) must first be derived from the actual RP address. Such a C(i) and G must first be derived from the actual RP or group |
digest method must be used consistently throughout the PIM domain. address. Such a digest method must be used consistently throughout |
For IPv6 addresses, we recommend using the equivalent IPv4 address the PIM domain. For IPv6 addresses, we recommend using the
for an IPv4-compatible address, and the CRC-32 checksum [7] of all equivalent IPv4 address for an IPv4-compatible address, and the |
other IPv6 addresses. exclusive-or of each 32-bit segment of the address for all other |
IPv6 addresses. For example, the digest of the IPv6 address |
3ffe:b00:c18:1::10 would be computed as 0x3ffe0b00 ^ 0x0c180001 ^ |
0x00000000 ^ 0x00000010, where ^ represents the exclusive-or |
operation. |
2 From the RPs with the highest priority (i.e. lowest `Priority' 2 The candidate RP with the highest resulting hash value is then |
value), the candidate with the highest resulting hash value is then
chosen as the RP for that group, and its identity and hash value chosen as the RP for that group, and its identity and hash value
are stored with the entry created. are stored with the entry created.
Ties between RPs having the same hash value and priority, are Ties between RPs having the same hash value are broken in advantage |
broken in advantage of the highest address. of the highest address.
The hash function algorithm is invoked by a DR, upon reception of a
packet, or IGMP membership indication, for a group, for which the DR has
no entry. It is invoked by any router that has (*,*,RP) state when a
packet is received for which there is no corresponding (S,G) or (*,G)
entry. Furthermore, the hash function is invoked by all routers upon
receiving a (*,G) or (*,*,RP) Join/Prune message.
4.8. Source-Specific Multicast 4.8. Source-Specific Multicast
The Source-Specific Multicast (SSM) service model [9] can be implemented | The Source-Specific Multicast (SSM) service model [11] can be
with a strict subset of the PIM-SM protocol mechanisms. Both regular IP | implemented with a strict subset of the PIM-SM protocol mechanisms.
Multicast and SSM semantics can coexist on a single router and both can | Both regular IP Multicast and SSM semantics can coexist on a single
be implemented using the PIM-SM protocol. A range of multicast | router and both can be implemented using the PIM-SM protocol. A range
addresses, currently 232.0.0.0/8 in IPv4, is reserved for SSM, and the | of multicast addresses, currently 232.0.0.0/8 in IPv4, is reserved for
choice of semantics is determined by the multicast group address in both | SSM, and the choice of semantics is determined by the multicast group
data packets and PIM messages. | address in both data packets and PIM messages.
4.8.1. Protocol Modifications for SSM destination addresses | 4.8.1. Protocol Modifications for SSM destination addresses
The following rules override the normal PIM-SM behavior for a multicast | The following rules override the normal PIM-SM behavior for a multicast
address G in the SSM reserved range: | address G in the SSM reserved range:
o A router MUST NOT send a (*,G) Join/Prune message for any reason. | o A router MUST NOT send a (*,G) Join/Prune message for any reason.
o A router MUST NOT send an (S,G,rpt) Join/Prune message for any reason. | o A router MUST NOT send an (S,G,rpt) Join/Prune message for any reason.
o A router MUST NOT send a Register message for any packet that is | o A router MUST NOT send a Register message for any packet that is
destined to an SSM address. | destined to an SSM address.
o A router MUST NOT forward packets based on (*,G) or (S,G,rpt) state. | o A router MUST NOT forward packets based on (*,G) or (S,G,rpt) state.
The (*,G) and (S,G,rpt) -related state summarization macros are NULL | The (*,G) and (S,G,rpt) -related state summarization macros are NULL
for any SSM address, for the purposes of packet forwarding. | for any SSM address, for the purposes of packet forwarding.
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 Register-Stop 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.8.2. PIM-SSM-only Routers | 4.8.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-
Mode that provides SSM forwarding semantics. | Mode that provides SSM forwarding semantics.
A PIM-SSM-only router MUST implement the following portions of this | A PIM-SSM-only router MUST implement the following portions of this
specification: | specification:
o Upstream (S,G) state machine (Section 4.4.7) | o Upstream (S,G) state machine (Section 4.4.7)
o Downstream (S,G) state machine (Section 4.4.3) | o Downstream (S,G) state machine (Section 4.4.3)
o (S,G) Assert state machine (Section 4.5.1) | o (S,G) Assert state machine (Section 4.5.1)
o Hello messages, neighbor discovery and DR election (Section 4.6) | o Hello messages, neighbor discovery and DR election (Section 4.6)
o Packet forwarding rules (Section 4.2) | o Packet forwarding rules (Section 4.2)
A PIM-SSM-only router does not need to implement the following protocol | A PIM-SSM-only router does not need to implement the following protocol
elements: | elements:
o Register state machine (Section 4.3) | o Register state machine (Section 4.3)
o (*,G), (S,G,rpt) and (*,*,RP) Downstream state machines (Sections | o (*,G), (S,G,rpt) and (*,*,RP) Downstream state machines (Sections
4.4.2, 4.4.4, and 4.4.1) | 4.4.2, 4.4.4, and 4.4.1)
o (*,G), (S,G,rpt), and (*,*,RP) Upstream state machines (Sections | o (*,G), (S,G,rpt), and (*,*,RP) Upstream state machines (Sections
4.4.6, 4.4.8, and 4.4.5) | 4.4.6, 4.4.8, and 4.4.5)
o (*,G) Assert state machine (Section 4.5.2) | o (*,G) Assert state machine (Section 4.5.2)
o Bootstrap RP Election (Section 4.7) | o Bootstrap RP Election (Section 4.7)
o Keepalive Timer | o Keepalive Timer
o SptBit (Section 4.2.1) | o SptBit (Section 4.2.1)
The KeepaliveTimer should be treated as always running and SptBit should | The KeepaliveTimer should be treated as always running and SptBit should
be treated as being always set for an SSM address. Additionally, the | be treated as being always set for an SSM address. Additionally, the
Packet forwarding rules of Section 4.2 can be simplified in a PIM-SSM- | Packet forwarding rules of Section 4.2 can be simplified in a PIM-SSM-
only router: | 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.9. PIM Packet Formats 4.9. 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. |
Basically, PIM messages are either unicast (e.g. Registers and PIM messages are either unicast (e.g. Registers and Register-Stop), or |
Register-Stop), or multicast with TTL 1 to `ALL-PIM-ROUTERS' group multicast with TTL 1 to the `ALL-PIM-ROUTERS' group (e.g. Join/Prune, |
`224.0.0.13' (e.g. Join/Prune, Asserts, etc.). Asserts, etc.). The source address used for unicast messages is a |
domain-wide reachable address; the source address used for multicast |
messages is the link-local address of the interface on which the message |
is being sent. |
The IPv4 `ALL-PIM-ROUTERS' group is `224.0.0.13'. The IPv6 `ALL-PIM- |
ROUTERS' group is `ff02::d'. |
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 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
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:
skipping to change at page 98, line 19 skipping to change at page 93, line 29
4 = Bootstrap 4 = Bootstrap
5 = Assert 5 = Assert
6 = Graft (used in PIM-DM only) 6 = Graft (used in PIM-DM only)
7 = Graft-Ack (used in PIM-DM only) 7 = Graft-Ack (used in PIM-DM only)
8 = Candidate-RP-Advertisement 8 = Candidate-RP-Advertisement
Reserved Reserved
Set to zero on transmission. Ignored upon receipt. Set to zero on transmission. Ignored upon receipt.
Checksum Checksum
The checksum is 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 data portion in the Register message. For computing excluding the data portion in the Register message. For computing
the checksum, the checksum field is zeroed. the checksum, the checksum field is zeroed. |
For IPv6, the checksum also includes the IPv6 "pseudo-header", as |
specified in RFC 2460, section 8.1 [8]. This "pseudo-header" is |
prepended to the PIM header for the purposes of calculating the |
checksum. The "Upper-Layer Packet Length" in the pseudo-header is |
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 |
integral number of 16-bit words, the packet is padded with a byte |
of zero before performing the checksum. |
4.9.1. Encoded Source and Group Address Formats 4.9.1. Encoded Source and Group Address Formats
Encoded-Unicast address Encoded-Unicast address
An Encoded-Unicast address takes the following format: An Encoded-Unicast address takes the following format:
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
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Addr Family | Encoding Type | Unicast Address | Addr Family | Encoding Type | Unicast Address
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+... +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+...
Addr Family Addr Family
The PIM address family of the `Unicast Address' field of this The PIM address family of the `Unicast Address' field of this |
address. address.
Values of 0-127 are as assigned by the IANA for Internet Address Values of 0-127 are as assigned by the IANA for Internet Address
Families in [4]. Values 128-250 are reserved to be assigned by the Families in [5]. Values 128-250 are reserved to be assigned by the
IANA for PIM-specific Address Families. Values 251 though 255 are | IANA for PIM-specific Address Families. Values 251 though 255 are
designated for private use. As there is no assignment authority | designated for private use. As there is no assignment authority
for this space, collisions should be expected. for this space, collisions should be expected.
Encoding Type Encoding Type
The type of encoding used within a specific Address Family. The The type of encoding used within a specific Address Family. The
value `0' is reserved for this field, and represents the native value `0' is reserved for this field, and represents the native
encoding of the Address Family. encoding of the Address Family.
Unicast Address Unicast Address
The unicast address as represented by the given Address Family and The unicast address as represented by the given Address Family and
Encoding Type. Encoding Type.
skipping to change at page 99, line 32 skipping to change at page 95, line 14
Addr Family Addr Family
described above. described above.
Encoding Type Encoding Type
described above. described above.
Reserved Reserved
Transmitted as zero. Ignored upon receipt. Transmitted as zero. Ignored upon receipt.
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 group address, describes a range of groups. It is less | with the group address, describes a range of groups. It is less
than or equal to the address length in bits for the given Address | than or equal to the address length in bits for the given Address
Family and Encoding Type. If the message is sent for a single group Family and Encoding Type. If the message is sent for a single group
then the Mask length must equal the address length in bits for the then the Mask length must equal the address length in bits for the
given Address Family and Encoding Type. (e.g. 32 for IPv4 native given Address Family and Encoding Type. (e.g. 32 for IPv4 native
encoding and 128 for IPv6 native encoding). encoding and 128 for IPv6 native encoding).
Group multicast Address Group multicast Address
Contains the group address. Contains the group address.
Encoded-Source address Encoded-Source address
skipping to change at page 100, line 24 skipping to change at page 96, line 6
| Source Address | Source Address
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-... +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-...
Addr Family Addr Family
described above. described above.
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. If 1, the join or prune | W The WC (or WildCard) bit is a 1 bit value for use with PIM |
applies to the (*,G) or (*,*,RP) entry. If 0, the join or prune | Join/Prune messages (see section 4.9.5.1 ). |
applies to the (S,G) entry where S is Source Address. Joins and |
prunes sent towards the RP must have this bit set. |
R The RPT-bit is a 1 bit value. If 1, the information about (S,G) is | R The RPT (or Rendezvous Point Tree) bit is a 1 bit value for use |
sent towards the RP. If 0, the information must be sent toward S, | with PIM Join/Prune messages (see section 4.9.5.1 ). If the WC bit |
where S is the Source Address. | 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 less than or equal to the address length in bits for the | must be less than or equal to the address length in bits for the
given Address Family and Encoding Type. If the message is sent for | given Address Family and Encoding Type. If the message is sent for
a single source then the Mask length must equal the address length | a single source then the Mask length must equal the address length
in bits for the given Address Family and Encoding Type. In version in bits for the given Address Family and Encoding Type. In version
2 of PIM, it is strongly recommended that this field be set to 32 2 of PIM, it is strongly recommended that this field be set to 32
for IPv4 native encoding. for IPv4 native encoding.
Source Address Source Address
The source address. | The source address.
Represented in the form of < WC-bit >< RPT-bit >< Mask length >< Source |
address >: |
A source address could be a host IPv4 native encoding address : |
< 0 >< 0 >< 32 >< 192.1.1.17 > |
A source address could be the RP's IP address : |
< 1 >< 1 >< 32 >< 131.108.13.111 > |
A source address could be an IP address to prune from the RP-tree : |
< 0 >< 1 >< 32 >< 192.1.1.16 > |
4.9.2. Hello Message Format | 4.9.2. Hello Message Format
It is sent periodically by routers on all interfaces. | It is sent periodically by routers on all interfaces.
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 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| OptionType | OptionLength | | | OptionType | OptionLength |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| OptionValue | | | OptionValue |
| ... | | | ... |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| . | | | . |
| . | | | . |
| . | | | . |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| OptionType | OptionLength | | | OptionType | OptionLength |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| OptionValue | | | OptionValue |
| ... | | | ... |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
PIM Version, Type, Reserved, Checksum PIM Version, Type, Reserved, Checksum
Described above. Described above.
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.
The Option fields may contain the following values: The Option fields may contain the following values:
o OptionType 1: Hold Time | o OptionType 1: Hold Time
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 = 1 | Length = 2 | | | Type = 1 | Length = 2 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Hold Time | | | Hold Time |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Hold Time is the amount of time a receiver must keep the neighbor | Hold Time 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. Furthermore, if the Holdtime is with periodic Hello messages. Furthermore, if the Holdtime is
set to `0', the information is timed out immediately. set to `0', the information is timed out immediately.
o OptionType 2 to 16: reserved to be defined in future versions of o OptionType 2 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.6.2. | in the DR election as described in section 4.6.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.
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
[5]. [6].
Unknown options may be ignored. The "Hold Time" option MUST be | Unknown options may be ignored. The "Hold Time" 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.9.3. Register Message Format 4.9.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 |
multicast packet needs to be transmitted on the RP-tree. Source address multicast packet needs to be transmitted on the RP-tree. The IP source |
is set to the address of the DR, destination address is to the RP's address is set to the address of the DR, the destination address to the |
address. RP's address. The IP TTL of the PIM packet is the system's normal |
unicast TTL. |
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 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|B|N| Reserved | |B|N| Reserved2 | |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| | | | |
. Multicast data packet . . Multicast data packet . |
| | | | |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ <span class="insert">|</span>
PIM Version, Type, Reserved, Checksum PIM Version, Type, Reserved, Checksum
Described above. Note that the checksum for Registers is done only Described above. Note that the checksum for Registers is done only
on first 8 bytes of packet, including the PIM header and the next 4 on first 8 bytes of packet, including the PIM header and the next 4
bytes, excluding the data packet portion. For interoperability bytes, excluding the data packet portion. For interoperability
reasons, a message carrying a checksum calculated over the entire | reasons, a message carrying a checksum calculated over the entire
PIM register message should be accepted. | PIM register message should 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
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. | IPv6 data packet must be encapsulated in an IPv6 PIM packet. Note |
that the TTL of the original packet is decremented before |
encapsulation, just like any other packet that is forwarded. In |
addition, the RP decrements the TTL after decapsulating, before |
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.9.4. Register-Stop Message Format 4.9.4. Register-Stop Message Format
A Register-Stop 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 above.
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.9.1. Note that for Register-Stops the | Format described in section 4.9.1. Note that for Register-Stops the
Mask Len field contains the full address length * 8 (e.g. 32 for | Mask Len field contains the full address length * 8 (e.g. 32 for
IPv4 native encoding), if the message is sent for a single group. IPv4 native encoding), if the message is sent for a single group.
Source Address | Source Address
Host address of source from multicast data packet in register. The | Host address of source from multicast data packet in register. The
format for this address is given in the Encoded-Unicast address in | format for this address is given in the Encoded-Unicast address in
section 4.9.1. A special wild card value (0's), can be used to | section 4.9.1. A special wild card value (0's), can be used to
indicate any source. XXX note that "(0's)" doesn't really describe | indicate any source. XXX note that "(0's)" doesn't really describe
what the rest of the field in encoded-unicast-address should be | what the rest of the field in encoded-unicast-address should be
4.9.5. Join/Prune Message Format 4.9.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.
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 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Upstream Neighbor Address (Encoded-Unicast format) | | Upstream Neighbor Address (Encoded-Unicast format) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Reserved | Num groups | Holdtime | | Reserved | Num groups | Holdtime |
skipping to change at page 108, line 12 skipping to change at page 103, line 12
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 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 above.
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.9.1. address is given in the Encoded-Unicast address in section 4.9.1. |
This address should be the link-local address of the upstream |
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 never times out the oif. This may be used with dial- | this message should hold the state until canceled by the |
on-demand links, to avoid keeping the link up with periodic | appropriate cancelling Join/Prune message, or timed out according |
Join/Prune messages. Furthermore, if the Holdtime is set to `0', | to local policy. This may be used with dial-on-demand links, to |
the information is timed out immediately. avoid keeping the link up with periodic Join/Prune messages. |
Note that the HoldTime must be larger than the |
J/P_Override_Interval. |
Number of Groups Number of Groups
The number of multicast group sets contained in the message. The number of multicast group sets contained in the message.
Multicast group address Multicast group address
For format description see Section 4.9.1. A wild card group in the | For format description see Section 4.9.1.
(*,*,RP) join is represented for IPv4 by a 224.0.0.0 in the group |
address field and `4' in the mask length field. A (*,*,RP) join |
also has the WC-bit and the RPT-bit set.
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.9.1. See Encoded-Source-Address format in section 4.9.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. If the Join/Prune message interface this message is sent on. |
boundary exceeds the maximum packet size, then the join and prune
lists for the same group must be included in the same packet.
4.9.6. Bootstrap Message Format 4.9.5.1. Group Set Source List Rules |
The Bootstrap messages are multicast to `ALL-PIM-ROUTERS' group, out all As described above, Join / Prune messages are composed by one or more |
interfaces having PIM neighbors (excluding the one over which the group sets. Each set contains two source lists, the Join Sources and the |
message was received). Bootstrap messages are sent with TTL value of 1. Prune Sources. This section describes the different types of group sets |
Bootstrap messages originate at the BSR, and are forwarded by and source list entries that can exist in a Join / Prune message. |
intermediate routers.
A bootstrap message is divided up into `semantic fragments', if the There are two valid group set types: |
original message exceeds the maximum packet size boundaries. XXX Define |
semantic fragmentation! |
The format of a single `fragment' is given below: |
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
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|PIM Ver| Type | Reserved | Checksum |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Fragment Tag | Hash Mask len | BSR-priority |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| BSR Address (Encoded-Unicast format) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Group Address 1 (Encoded-Group format) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| RP Count 1 | Frag RP Cnt 1 | Reserved |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| RP Address 1 (Encoded-Unicast format) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| RP1 Holdtime | RP1 Priority | Reserved |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| RP Address 2 (Encoded-Unicast format) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| RP2 Holdtime | RP2 Priority | Reserved |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| . |
| . |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| RP Address m (Encoded-Unicast format) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| RPm Holdtime | RPm Priority | Reserved |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Group Address 2 (Encoded-Group format) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| . |
| . |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Group Address n (Encoded-Group format) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| RP Count n | Frag RP Cnt n | Reserved |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| RP Address 1 (Encoded-Unicast format) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| RP1 Holdtime | RP1 Priority | Reserved |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| RP Address 2 (Encoded-Unicast format) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| RP2 Holdtime | RP2 Priority | Reserved |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| . |
| . |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| RP Address m (Encoded-Unicast format) | Wildcard Group Set |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ The wildcard group set is represented by the entire multicast range |
| RPm Holdtime | RPm Priority | Reserved | - the beginning of the multicast address range in the group address |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 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 |
for IPv4. Each wildcard group set may contain one or more (*,*,RP) |
source list entries in either the Join or Prune lists. |
PIM Version, Type, Reserved, Checksum A (*,*,RP) source list entry may only exist in a wildcard group |
Described above. set. When added to a Join source list, this type of source entry |
expresses the routers interest in receiving traffic for all groups |
mapping to the specified RP. When added to a Prune source list a |
(*,*,RP) entry expresses the routers interest to stop receiving |
such traffic. |
Fragment Tag (*,*,RP) source list entries have the Source-Address set to the |
A randomly generated number, acts to distinguish the fragments address of the RP, the Source-Address Mask-Len set to the full |
belonging to different Bootstrap messages; fragments belonging to length of the IP address and both the WC and RPT bits of the |
same Bootstrap message carry the same `Fragment Tag'. Source-Address set to 1. |
Hash Mask len Group Specific Set |
The length (in bits) of the mask to use in the hash function. For For IPv4, a Group Specific Set is represented by a valid IP |
IPv4 we recommend a value of 30. For IPv6 we recommend a value of multicast address in the group address field and the full length of |
126. the IP address in the mask length field of the Multicast Group |
Address. Each group specific set may contain (*,G), (S,G,rpt) and |
(S,G) source list entries in the Join or Prune lists. |
BSR priority (*,G) |
Contains the BSR priority value of the included BSR. This field is The (*,G) source list entry is used in Join / Prune messages |
considered as a high order byte when comparing BSR addresses. sent towards the RP for the specified group. It expresses |
interest (or lack of) in receiving traffic sent to the group |
through the Rendezvous-Point shared tree. There may only be |
one such entry in both the Join and Prune lists of a group |
specific set. |
Unicast BSR Address (*,G) source list entries have the Source-Address set to the |
The address of the bootstrap router for the domain. The format for address of the RP for group G, the Source-Address Mask-Len set |
this address is given in the Encoded-Unicast address in 4.9.1. to the full length of the IP address and have both the WC and |
RPT bits of the Encoded-Source-Address set. |
Group Address 1..n (S,G,rpt) |
The group prefix (address and mask) with which the Candidate RPs The (S,G,rpt) source list entry is used in Join / Prune |
are associated. Format described in section 4.9.1. messages sent towards the RP for the specified group. It |
expresses interest (or lack of) in receiving traffic through |
the shared tree sent by the specified source to this group. |
There may only be one such entry for each source address in |
both the Join and Prune lists of a group specific set. |
RP Count 1..n (S,G,rpt) source list entries have the Source-Address set to |
The number of Candidate RP addresses included in the whole the address of the source S, the Source-Address Mask-Len set |
Bootstrap message for the corresponding group prefix. A router does to the full length of the IP address and have the WC bit clear |
not replace its old RP-Set for a given group prefix until/unless it and the RPT bit set in the Encoded-Source-Address. |
receives `RP-Count' addresses for that prefix; the addresses could
be carried over several fragments. If only part of the RP-Set for
a given group prefix was received, the router discards it, without
updating that specific group prefix's RP-Set.
Frag RP Cnt 1..m (S,G) |
The number of Candidate RP addresses included in this fragment of The (S,G) source list entry is used in Join / Prune messages |
the Bootstrap message, for the corresponding group prefix. The sent towards the specified source. It expresses interest (or |
`Frag RP-Cnt' field facilitates parsing of the RP-Set for a given lack of) in receiving traffic through the shortest path tree |
group prefix, when carried over more than one fragment. sent by the source to the specified group. There may only be |
one such entry for each source address in both the Join and |
Prune lists of a group specific set. |
RP address 1..m (S,G) source list entries have the Source-Address set to the |
The address of the Candidate RPs, for the corresponding group address of the source S, the Source-Address Mask-Len set to |
prefix. The format for these addresses is given in the Encoded- the full length of the IP address and have both the WC and RPT |
Unicast address in section 4.9.1. bits of the Encoded-Source-Address clear. |
RP1..m Holdtime The rules described above are sufficient to prevent invalid combinations |
The Holdtime for the corresponding RP. This field is copied from of source list entries in group-specific sets. There are however a |
the `Holdtime' field of the associated RP stored at the BSR. number of combinations that have a valid interpretation but which are |
not generated by the protocol as described in this specification: |
RP1..m Priority o Combining a (*,G) Join and a (S,G,rpt) Join entry in the same message |
The `Priority' of the corresponding RP and Encoded-Group Address. is redundant as the (*,G) entry covers the information provided by the |
This field is copied from the `Priority' field stored at the BSR | (S,G,rpt) entry. |
when receiving a Candidate-RP-Advertisement. The highest priority |
is `0' (i.e. the lower the value of the `Priority' field, the |
better). Note that the priority is per RP per Group Address. |
4.9.7. Assert Message Format o The same applies for a (*,G) Prunes and (S,G,rpt) Prunes. |
o The combination of a (*,G) Prune and a (S,G,rpt) Join is also not |
generated. (S,G,rpt) Joins are only sent when the router is receiving |
all traffic for a group on the shared tree and it wishes to indicate a |
change for the particular source. As a (*,G) prune indicates that the |
router no longer wishes to receive shared tree traffic, the (S,G,rpt) |
Join is meaningless. |
o As Join / Prune messages are targeted to a single PIM neighbour, |
including both a (S,G) Join and a (S,G,rpt) prune in the same message |
is redundant. The (S,G) Join informs the neighbour that the sender |
wishes to receive the particular source on the shortest path tree. It |
is therefore unnecessary for the router to say that it no longer |
wishes to receive it on the shared tree. |
o The combination of a (S,G) Prune and a (S,G,rpt) Join could possibly |
be used by a router to switch from receiving a particular source on |
the shortest-path tree back to receiving it on the shared tree |
(provided that the RPF neighbor for the shortest-path and shared trees |
is common). However Sparse-Mode PIM does not provide a mechanism for |
switching back to the shared tree. |
The rules are summarised in the table below.
+-----------++-------+--------+------------+------------+--------+-------||
| ||(*,G)J | (*,G)P | (S,G,rpt)J | (S,G,rpt)P | (S,G)J | (S,G)P||
+-----------++-------+--------+------------+------------+--------+--------|
|(*,G)J ||- | no | ? | yes | yes | yes ||
+-----------++-------+--------+------------+------------+--------+--------|
|(*,G)P || | - | ? | ? | yes | yes ||
+-----------++-------+--------+------------+------------+--------+--------|
|(S,G,rpt)J || | | - | no | yes | yes ||
+-----------++-------+--------+------------+------------+--------+--------|
|(S,G,rpt)P || | | | - | ? | ? ||
+-----------++-------+--------+------------+------------+--------+--------|
|(S,G)J || | | | | - | no ||
+-----------++-------+--------+------------+------------+--------+--------|
|(S,G)P || | | | | | - ||
+-----------++-------+--------+------------+------------+--------+--------|
yes Allowed and expected. |
no Combination is not allowed by the protocol and MUST not be |
generated by a router. |
? Combination not expected by the protocol, but well-defined. A |
router MAY accept it but SHOULD not generate it. |
The order of source list entries in a group set source list is not |
important. As a result the table above is symmetric and only entries on |
the upper right half have been specified as entries on the lower left |
are just a mirror. |
4.9.5.2. Group Set Fragmentation |
When building a Join / Prune for a prticular neighbour, a router should |
try and include in the message as much of the information it needs to |
convey to the neighbour as possible. This implies adding one group set |
for each multicast group that has information pending transmission and |
within each set including all relevant source list entries. |