tech-invite   World Map
3GPP     Specs     Glossaries     UICC       IETF     RFCs     Groups     SIP     ABNFs       T+       Search     Home

RFC 4601

 
 
 

Protocol Independent Multicast - Sparse Mode (PIM-SM): Protocol Specification (Revised)

Part 3 of 6, p. 38 to 61
Prev RFC Part       Next RFC Part

 


prevText      Top      Up      ToC       Page 38 
4.4.  PIM Register Messages

   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 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 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 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 DR will resume encapsulating packets
   from the source to the RP.

4.4.1.  Sending Register Messages from the DR

   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 specification, we represent the mechanism to encapsulate packets
   to 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 forwarding rules as specified in Section 4.2.

   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 per-(S,G) Register state machine:

   Join (J)
        The register tunnel is "joined" (the join is actually implicit,
        but the DR acts as if the RP has joined the DR on the tunnel
        interface).

   Prune (P)
        The register tunnel is "pruned" (this occurs when a Register-
        Stop is received).

   Join-Pending (JP)
        The register tunnel is pruned but the DR is contemplating adding
        it back.

   NoInfo (NI)
        No information.  This is the initial state, and the state when
        the router is not the DR.

   In addition, a Register-Stop Timer (RST) is kept if the state machine
   is not in the NoInfo state.

Top      Up      ToC       Page 39 
   Figure 1: Per-(S,G) register state machine at a DR in tabular form

+----------++----------------------------------------------------------+
|          ||                          Event                           |
|          ++----------+-----------+-----------+-----------+-----------+
|Prev State||Register- | Could     | Could     | Register- | RP changed|
|          ||Stop Timer| Register  | Register  | Stop      |           |
|          ||expires   | ->True    | ->False   | received  |           |
+----------++----------+-----------+-----------+-----------+-----------+
|NoInfo    ||-         | -> J state| -         | -         | -         |
|(NI)      ||          | add reg   |           |           |           |
|          ||          | tunnel    |           |           |           |
+----------++----------+-----------+-----------+-----------+-----------+
|          ||-         | -         | -> NI     | -> P state| -> J state|
|          ||          |           | state     |           |           |
|          ||          |           | remove reg| remove reg| update reg|
|Join (J)  ||          |           | tunnel    | tunnel;   | tunnel    |
|          ||          |           |           | set       |           |
|          ||          |           |           | Register- |           |
|          ||          |           |           | Stop      |           |
|          ||          |           |           | Timer(*)  |           |
+----------++----------+-----------+-----------+-----------+-----------+
|          ||-> J state| -         | -> NI     | -> P state| -> J state|
|          ||          |           | state     |           |           |
|Join-     ||add reg   |           |           | set       | add reg   |
|Pending   ||tunnel    |           |           | Register- | tunnel;   |
|(JP)      ||          |           |           | Stop      | cancel    |
|          ||          |           |           | Timer(*)  | Register- |
|          ||          |           |           |           | Stop Timer|
+----------++----------+-----------+-----------+-----------+-----------+
|          ||-> JP     | -         | -> NI     | -         | -> J state|
|          ||state     |           | state     |           |           |
|          ||set       |           |           |           | add reg   |
|Prune (P) ||Register- |           |           |           | tunnel;   |
|          ||Stop      |           |           |           | cancel    |
|          ||Timer(**);|           |           |           | Register- |
|          ||send Null-|           |           |           | Stop Timer|
|          ||Register  |           |           |           |           |
+----------++----------+-----------+-----------+-----------+-----------+

   Notes:

   (*)  The Register-Stop Timer is set to a random value chosen
        uniformly from the interval ( 0.5 * Register_Suppression_Time,
        1.5 * Register_Suppression_Time) minus Register_Probe_Time.

Top      Up      ToC       Page 40 
        Subtracting off Register_Probe_Time is a bit unnecessary because
        it is really small compared to Register_Suppression_Time, but
        this was in the old spec and is kept for compatibility.

   (**) The Register-Stop Timer is set to Register_Probe_Time.

   The following three actions are defined:

   Add Register Tunnel

      A Register-Tunnel virtual interface, VI, is created (if it doesn't
      already exist) with its encapsulation target being RP(G).
      DownstreamJPState(S,G,VI) is set to Join state, causing the tunnel
      interface to be added to immediate_olist(S,G) and
      inherited_olist(S,G).

   Remove Register Tunnel

      VI is the Register-Tunnel virtual interface with encapsulation
      target of RP(G).  DownstreamJPState(S,G,VI) is set to NoInfo
      state, causing the tunnel interface to be removed from
      immediate_olist(S,G) and inherited_olist(S,G).  If
      DownstreamJPState(S,G,VI) is NoInfo for all (S,G), then VI can be
      deleted.

   Update Register Tunnel

      This action occurs when RP(G) changes.

      VI_old is the Register-Tunnel virtual interface with encapsulation
      target old_RP(G).  A Register-Tunnel virtual interface, VI_new, is
      created (if it doesn't already exist) with its encapsulation
      target being new_RP(G).  DownstreamJPState(S,G,VI_old) is set to
      NoInfo state and DownstreamJPState(S,G,VI_new) is set to Join
      state.  If DownstreamJPState(S,G,VI_old) is NoInfo for all (S,G),
      then VI_old can be deleted.

      Note that we cannot simply change the encapsulation target of
      VI_old because not all groups using that encapsulation tunnel will
      have moved to the same new RP.

Top      Up      ToC       Page 41 
   CouldRegister(S,G)

      The macro "CouldRegister" in the state machine is defined as:

      bool CouldRegister(S,G) {
         return ( I_am_DR( RPF_interface(S) ) AND
                  KeepaliveTimer(S,G) is running AND
                  DirectlyConnected(S) == TRUE )
      }

      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 rules before computing CouldRegister(S,G) in the
      register state machine, or the first packet from a source won't be
      registered.

   Encapsulating Data Packets in the Register Tunnel

      Conceptually, the Register Tunnel is an interface with a smaller
      MTU 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.  Fragmentation for the smaller MTU should take
      both the outer IP header and the PIM register header overhead into
      account.  If a multicast packet is fragmented on the way into the
      Register Tunnel, each fragment is encapsulated individually so it
      contains IP, PIM, and inner IP headers.

      In IPv6, the DR MUST perform Path MTU discovery, and an ICMP
      Packet Too Big message MUST be sent by the encapsulating DR if it
      receives a packet that will not fit in the effective MTU of the
      tunnel.  If the MTU between the DR and the RP results in the
      effective tunnel MTU being smaller than 1280 (the IPv6 minimum
      MTU), the DR MUST send Fragmentation Required messages with an MTU
      value of 1280 and MUST fragment its PIM register messages as
      required, using an IPv6 fragmentation header between the outer
      IPv6 header and the PIM Register header.

      The TTL of a forwarded data packet is decremented before it is
      encapsulated in the Register Tunnel.  The encapsulating packet
      uses the normal TTL that the router would use for any locally-
      generated IP packet.

      The IP ECN bits should be copied from the original packet to the
      IP header of the encapsulating packet.  They SHOULD NOT be set
      independently by the encapsulating router.

Top      Up      ToC       Page 42 
      The Diffserv Code Point (DSCP) should be copied from the original
      packet to the IP header of the encapsulating packet.  It MAY be
      set independently by the encapsulating router, based upon static
      configuration or traffic classification.  See [12] for more
      discussion on setting the DSCP on tunnels.

   Handling Register-Stop(*,G) Messages at the DR

      An old RP might send a Register-Stop message with the source
      address set to all zeros.  This was the normal course of action in
      RFC 2362 when the Register message matched against (*,G) state at
      the RP, and it was defined as meaning "stop encapsulating all
      sources for this group".  However, the behavior of such a
      Register-Stop(*,G) is ambiguous or incorrect in some
      circumstances.

      We specify that an RP should not send Register-Stop(*,G) messages,
      but for compatibility, a DR should be able to accept one if it is
      received.

      A Register-Stop(*,G) should be treated as a Register-Stop(S,G) for
      all (S,G) Register state machines that are not in the NoInfo
      state.  A router should not apply a Register-Stop(*,G) to sources
      that become active after the Register-Stop(*,G) was received.

Top      Up      ToC       Page 43 
4.4.2.  Receiving Register Messages at the RP

   When an RP receives a Register message, the course of action is
   decided according to the following pseudocode:

   packet_arrives_on_rp_tunnel( pkt ) {
       if( outer.dst is not one of my addresses ) {
           drop the packet silently.
           # Note: this may be a spoofing attempt
       }
       if( I_am_RP(G) AND outer.dst == RP(G) ) {
             sentRegisterStop = FALSE;
             if ( register.borderbit == TRUE ) {
                  if ( PMBR(S,G) == unknown ) {
                       PMBR(S,G) = outer.src
                  } else if ( outer.src != PMBR(S,G) ) {
                       send Register-Stop(S,G) to outer.src
                       drop the packet silently.
                  }
             }
             if ( SPTbit(S,G) OR
              ( SwitchToSptDesired(S,G) AND
                ( inherited_olist(S,G) == NULL ))) {
               send Register-Stop(S,G) to outer.src
               sentRegisterStop = TRUE;
             }
             if ( SPTbit(S,G) OR SwitchToSptDesired(S,G) ) {
                  if ( sentRegisterStop == TRUE ) {
                       set KeepaliveTimer(S,G) to RP_Keepalive_Period;
                  } else {
                       set KeepaliveTimer(S,G) to Keepalive_Period;
                  }
             }
             if( !SPTbit(S,G) AND ! pkt.NullRegisterBit ) {
                  decapsulate and forward the inner packet to
                  inherited_olist(S,G,rpt) # Note (+)
             }
       } else {
           send Register-Stop(S,G) to outer.src
           # Note (*)
       }
   }

   outer.dst is the IP destination address of the encapsulating header.

   outer.src is the IP source address of the encapsulating header, i.e.,
   the DR's address.

Top      Up      ToC       Page 44 
   I_am_RP(G) is true if the group-to-RP mapping indicates that this
   router is the RP for the group.

   Note (*): This may block traffic from S for Register_Suppression_Time
      if the DR learned about a new group-to-RP mapping before the RP
      did.  However, this doesn't matter unless we figure out some way
      for the RP also to 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 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
      interrupted (*,G) connectivity following an RP change.

   Note (+): Implementations are advised not to make this a special
      case, but to arrange that this path rejoin the normal packet
      forwarding path.  All of the appropriate actions from the "On
      receipt of data from S to G on interface iif" pseudocode in
      Section 4.2 should be performed.

   KeepaliveTimer(S,G) is restarted at the RP when packets arrive on the
   proper tunnel interface and the RP desires to switch to the SPT or
   the SPTbit is already set.  This may cause the upstream (S,G) state
   machine to trigger a join if the inherited_olist(S,G) is not NULL.

   An RP should preserve (S,G) state that was created in response to a
   Register message for at least ( 3 * Register_Suppression_Time );
   otherwise, the RP may stop joining (S,G) before the DR for S has
   restarted sending registers.  Traffic would then be interrupted until
   the Register-Stop Timer expires at the DR.

   Thus, at the RP, KeepaliveTimer(S,G) should be restarted to ( 3 *
   Register_Suppression_Time + Register_Probe_Time ).

   When forwarding a packet from the Register Tunnel, the TTL of the
   original data packet is decremented after it is decapsulated.

   The IP ECN bits should be copied from the IP header of the Register
   packet to the decapsulated packet.

   The Diffserv Code Point (DSCP) should be copied from the IP header of
   the Register packet to the decapsulated packet.  The RP MAY retain
   the DSCP of the inner packet or re-classify the packet and apply a
   different DSCP.  Scenarios where each of these might be useful are
   discussed in [12].

Top      Up      ToC       Page 45 
4.5.  PIM Join/Prune Messages

   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
   Join/Prune message, each Joined or Pruned source for a Group is
   effectively considered individually, and applies to one or more of
   the following state machines.  When considering a Join/Prune message
   whose Upstream Neighbor Address field addresses this router, (*,G)
   Joins and Prunes can affect both the (*,G) and (S,G,rpt) downstream
   state machines, while (*,*,RP), (S,G), and (S,G,rpt) Joins and Prunes
   can only affect their respective downstream state machines.  When
   considering a Join/Prune message whose Upstream Neighbor Address
   field addresses another router, most Join or Prune messages could
   affect each upstream state machine.

   In general, a PIM Join/Prune message should only be accepted for
   processing if it comes from a known PIM neighbor.  A PIM router hears
   about PIM neighbors through PIM Hello messages.  If a router receives
   a Join/Prune message from a particular IP source address and it has
   not seen a PIM Hello message from that source address, then the
   Join/Prune message SHOULD be discarded without further processing.
   In addition, if the Hello message from a neighbor was authenticated
   using IPsec AH (see Section 6.3), then all Join/Prune messages from
   that neighbor MUST also be authenticated using IPsec AH.

   We note that some older PIM implementations incorrectly fail to send
   Hello messages on point-to-point interfaces, so we also RECOMMEND
   that a configuration option be provided to allow interoperation with
   such older routers, but that this configuration option SHOULD NOT be
   enabled by default.

4.5.1.  Receiving (*,*,RP) Join/Prune Messages

   The per-interface state machine for receiving (*,*,RP) Join/Prune
   Messages is given below.  There are three states:

     NoInfo (NI)
          The interface has no (*,*,RP) Join state and no timers
          running.

     Join (J)
          The interface has (*,*,RP) Join state, which will cause the
          router to forward packets destined for any group handled by RP
          from this interface except if there is also (S,G,rpt) prune
          information (see Section 4.5.4) or the router lost an assert
          on this interface.

Top      Up      ToC       Page 46 
     Prune-Pending (PP)
          The router has received a Prune(*,*,RP) on this interface from
          a downstream neighbor and is waiting to see whether the prune
          will be overridden by another downstream router.  For
          forwarding purposes, the Prune-Pending state functions exactly
          like the Join state.

   In addition, the state machine uses two timers:

     ExpiryTimer (ET)
          This timer is restarted when a valid Join(*,*,RP) is received.
          Expiry of the ExpiryTimer causes the interface state to revert
          to NoInfo for this RP.

     Prune-Pending Timer (PPT)
          This timer is set when a valid Prune(*,*,RP) is received.
          Expiry of the Prune-Pending Timer causes the interface state
          to revert to NoInfo for this RP.

       Figure 2: Downstream per-interface (*,*,RP) state machine
                            in tabular form

+------------++--------------------------------------------------------+
|            ||                          Event                         |
|            ++-------------+-------------+--------------+-------------+
|Prev State  ||Receive      | Receive     | Prune-       | Expiry Timer|
|            ||Join(*,*,RP) | Prune       | Pending      | Expires     |
|            ||             | (*,*,RP)    | Timer        |             |
|            ||             |             | Expires      |             |
+------------++-------------+-------------+--------------+-------------+
|            ||-> J state   | -> NI state | -            | -           |
|NoInfo (NI) ||start Expiry |             |              |             |
|            ||Timer        |             |              |             |
+------------++-------------+-------------+--------------+-------------+
|            ||-> J state   | -> PP state | -            | -> NI state |
|Join (J)    ||restart      | start Prune-|              |             |
|            ||Expiry Timer | Pending     |              |             |
|            ||             | Timer       |              |             |
+------------++-------------+-------------+--------------+-------------+
|Prune-      ||-> J state   | -> PP state | -> NI state  | -> NI state |
|Pending (PP)||restart      |             | Send Prune-  |             |
|            ||Expiry Timer |             | Echo(*,*,RP) |             |
+------------++-------------+-------------+--------------+-------------+

Top      Up      ToC       Page 47 
   The transition events "Receive Join(*,*,RP)" and "Receive
   Prune(*,*,RP)" imply receiving a Join or Prune targeted to this
   router's primary IP address on the received interface.  If the
   upstream neighbor address field 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 should be the same as the source address it chose for the
   Hello message it sent over that interface.  However, on point-to-
   point links we also recommend that for backwards compatibility PIM
   Join/Prune messages with an upstream neighbor address field of all
   zeros are also accepted.

   Transitions from NoInfo State

   When in NoInfo state, the following event may trigger a transition:

     Receive Join(*,*,RP)
          A Join(*,*,RP) is received on interface I with its Upstream
          Neighbor Address set to the router's primary IP address on I.

          The (*,*,RP) 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.

          Note that it is possible to receive a Join(*,*,RP) message for
          an RP for which we do not have information telling us that it
          is an RP.  In the case of (*,*,RP) state, so long as we have a
          route to the RP, this will not cause a problem, and the
          transition should still take place.

   Transitions from Join State

   When in Join state, the following events may trigger a transition:

     Receive Join(*,*,RP)
          A Join(*,*,RP) is received on interface I with its Upstream
          Neighbor Address set to the router's primary IP address on I.

          The (*,*,RP) downstream state machine on interface I remains
          in Join state, and the Expiry Timer (ET) is restarted, set to
          maximum of its current value and the HoldTime from the
          triggering Join/Prune message.

Top      Up      ToC       Page 48 
     Receive Prune(*,*,RP)
          A Prune(*,*,RP) is received on interface I with its Upstream
          Neighbor Address set to the router's primary IP address on I.

          The (*,*,RP) downstream state machine on interface I
          transitions to the Prune-Pending state.  The Prune-Pending
          Timer is started.  It is set to the J/P_Override_Interval(I)
          if the router has more than one neighbor on that interface;
          otherwise, it is set to zero, causing it to expire
          immediately.

     Expiry Timer Expires
          The Expiry Timer for the (*,*,RP) downstream state machine on
          interface I expires.

          The (*,*,RP) downstream state machine on interface I
          transitions to the NoInfo state.

   Transitions from Prune-Pending State

   When in Prune-Pending state, the following events may trigger a
   transition:

     Receive Join(*,*,RP)
          A Join(*,*,RP) is received on interface I with its Upstream
          Neighbor Address set to the router's primary IP address on I.

          The (*,*,RP) downstream state machine on interface I
          transitions to the Join state.  The Prune-Pending Timer is
          canceled (without triggering an expiry event).  The Expiry
          Timer is restarted, set to maximum of its current value and
          the HoldTime from the triggering Join/Prune message.

     Expiry Timer Expires
          The Expiry Timer for the (*,*,RP) downstream state machine on
          interface I expires.

          The (*,*,RP) downstream state machine on interface I
          transitions to the NoInfo state.

     Prune-Pending Timer Expires
          The Prune-Pending Timer for the (*,*,RP) downstream state
          machine on interface I expires.

          The (*,*,RP) downstream state machine on interface I
          transitions to the NoInfo state.  A PruneEcho(*,*,RP) is sent
          onto the subnet connected to interface I.

Top      Up      ToC       Page 49 
          The action "Send PruneEcho(*,*,RP)" is triggered when the
          router stops forwarding on an interface as a result of a
          prune.  A PruneEcho(*,*,RP) is simply a Prune(*,*,RP) message
          sent by the upstream router on a LAN with its own address in
          the Upstream Neighbor Address field.  Its purpose is to add
          additional reliability so that if a Prune that should have
          been overridden by another 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 an interface
          that contains only a single PIM neighbor during the time this
          state machine was in Prune-Pending state.

4.5.2.  Receiving (*,G) Join/Prune Messages

   When a router receives a Join(*,G), it must first check to 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(*,G) should be silently dropped.  (Note that other source list
   entries, such as (S,G,rpt) or (S,G), in the same Group-Specific Set
   should still be processed.)  If a router has no RP information (e.g.,
   has not recently received a BSR message), then it may choose to
   accept Join(*,G) and treat the RP in the message as RP(G).  Received
   Prune(*,G) messages are processed even if the RP in the message does
   not match RP(G).

   The per-interface state machine for receiving (*,G) Join/Prune
   Messages is given below.  There are three states:

     NoInfo (NI)
          The interface has no (*,G) Join state and no timers running.

     Join (J)
          The interface has (*,G) Join state, which will cause the
          router to forward packets destined for G from this interface
          except if there is also (S,G,rpt) prune information (see
          Section 4.5.4) or the router lost an assert on this interface.

     Prune-Pending (PP)
          The router has received a Prune(*,G) on this interface from a
          downstream neighbor and is waiting to see whether the prune
          will be overridden by another downstream router.  For
          forwarding purposes, the Prune-Pending state functions exactly
          like the Join state.

Top      Up      ToC       Page 50 
   In addition, the state machine uses two timers:

     Expiry Timer (ET)
          This timer is restarted when a valid Join(*,G) is received.
          Expiry of the Expiry Timer causes the interface state to
          revert to NoInfo for this group.

     Prune-Pending Timer (PPT)
          This timer is set when a valid Prune(*,G) is received.  Expiry
          of the Prune-Pending Timer causes the interface state to
          revert to NoInfo for this group.

 Figure 3: Downstream per-interface (*,G) state machine in tabular form

+------------++--------------------------------------------------------+
|            ||                         Event                          |
|            ++-------------+--------------+-------------+-------------+
|Prev State  ||Receive      | Receive      | Prune-      | Expiry Timer|
|            ||Join(*,G)    | Prune(*,G)   | Pending     | Expires     |
|            ||             |              | Timer       |             |
|            ||             |              | Expires     |             |
+------------++-------------+--------------+-------------+-------------+
|            ||-> J state   | -> NI state  | -           | -           |
|NoInfo (NI) ||start Expiry |              |             |             |
|            ||Timer        |              |             |             |
+------------++-------------+--------------+-------------+-------------+
|            ||-> J state   | -> PP state  | -           | -> NI state |
|Join (J)    ||restart      | start Prune- |             |             |
|            ||Expiry Timer | Pending      |             |             |
|            ||             | Timer        |             |             |
+------------++-------------+--------------+-------------+-------------+
|Prune-      ||-> J state   | -> PP state  | -> NI state | -> NI state |
|Pending (PP)||restart      |              | Send Prune- |             |
|            ||Expiry Timer |              | Echo(*,G)   |             |
+------------++-------------+--------------+-------------+-------------+

   The transition events "Receive Join(*,G)" and "Receive Prune(*,G)"
   imply receiving a Join or Prune targeted to this router's primary IP
   address on the received interface.  If the upstream neighbor address
   field 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 should be the same as the source address it chose for the
   Hello message it sent over that interface.  However, on point-to-

Top      Up      ToC       Page 51 
   point links we also recommend that for backwards compatibility PIM
   Join/Prune messages with an upstream neighbor address field of all
   zeros are also accepted.

   Transitions from NoInfo State

   When in NoInfo state, the following event may trigger a transition:

     Receive Join(*,G)
          A Join(*,G) is received on interface I with its Upstream
          Neighbor Address set to the router's primary IP 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/Prune message.

   Transitions from Join State

   When in Join state, the following events may trigger a transition:

     Receive Join(*,G)
          A Join(*,G) is received on interface I with its Upstream
          Neighbor Address set to the router's primary IP address on I.

          The (*,G) downstream state machine on interface I remains in
          Join state, and the Expiry Timer (ET) is restarted, set to
          maximum of its current value and the HoldTime from the
          triggering Join/Prune message.

     Receive Prune(*,G)
          A Prune(*,G) is received on interface I with its Upstream
          Neighbor Address set to the router's primary IP address on I.

          The (*,G) downstream state machine on interface I transitions
          to the Prune-Pending state.  The Prune-Pending Timer is
          started.  It is set to the J/P_Override_Interval(I) if the
          router has more than one neighbor on that interface;
          otherwise, it is set to zero, causing it to expire
          immediately.

     Expiry Timer Expires
          The Expiry Timer for the (*,G) downstream state machine on
          interface I expires.

          The (*,G) downstream state machine on interface I transitions
          to the NoInfo state.

Top      Up      ToC       Page 52 
   Transitions from Prune-Pending State

   When in Prune-Pending state, the following events may trigger a
   transition:

     Receive Join(*,G)
          A Join(*,G) is received on interface I with its Upstream
          Neighbor Address set to the router's primary IP address on I.

          The (*,G) downstream state machine on interface I transitions
          to the Join state.  The Prune-Pending Timer is canceled
          (without triggering an expiry event).  The Expiry Timer is
          restarted, set to maximum of its current value and the
          HoldTime from the triggering Join/Prune message.

     Expiry Timer Expires
          The Expiry Timer for the (*,G) downstream state machine on
          interface I expires.

          The (*,G) downstream state machine on interface I transitions
          to the NoInfo state.

     Prune-Pending Timer Expires
          The Prune-Pending Timer for the (*,G) downstream state machine
          on interface I expires.

          The (*,G) downstream state machine on interface I transitions
          to the NoInfo state.  A PruneEcho(*,G) is sent onto the subnet
          connected to interface I.

          The action "Send PruneEcho(*,G)" is triggered when the router
          stops forwarding on an interface as a result of a prune.  A
          PruneEcho(*,G) is simply a Prune(*,G) message sent by the
          upstream router on a LAN with its own address in the Upstream
          Neighbor Address field.  Its purpose is to add additional
          reliability so that if a Prune that should have been
          overridden by another router 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 an interface
          that contains only a single PIM neighbor during the time this
          state machine was in Prune-Pending state.

Top      Up      ToC       Page 53 
4.5.3.  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.  There are three states:

     NoInfo (NI)
          The interface has no (S,G) Join state and no (S,G) timers
          running.

     Join (J)
          The interface has (S,G) Join state, which will cause the
          router to forward packets from S destined for G from this
          interface if the (S,G) state is active (the SPTbit is set)
          except if the router lost an assert on this interface.

     Prune-Pending (PP)
          The router has received a Prune(S,G) on this interface from a
          downstream neighbor and is waiting to see whether the prune
          will be overridden by another downstream router.  For
          forwarding purposes, the Prune-Pending state functions exactly
          like the Join state.

   In addition, there are two timers:

     Expiry Timer (ET)
          This timer is set when a valid Join(S,G) is received.  Expiry
          of the Expiry Timer causes this state machine to revert to
          NoInfo state.

     Prune-Pending Timer (PPT)
          This timer is set when a valid Prune(S,G) is received.  Expiry
          of the Prune-Pending Timer causes this state machine to revert
          to NoInfo state.

Top      Up      ToC       Page 54 
 Figure 4: Downstream per-interface (S,G) state machine in tabular form

+------------++--------------------------------------------------------+
|            ||                         Event                          |
|            ++-------------+--------------+-------------+-------------+
|Prev State  ||Receive      | Receive      | Prune-      | Expiry Timer|
|            ||Join(S,G)    | Prune(S,G)   | Pending     | Expires     |
|            ||             |              | Timer       |             |
|            ||             |              | Expires     |             |
+------------++-------------+--------------+-------------+-------------+
|            ||-> J state   | -> NI state  | -           | -           |
|NoInfo (NI) ||start Expiry |              |             |             |
|            ||Timer        |              |             |             |
+------------++-------------+--------------+-------------+-------------+
|            ||-> J state   | -> PP state  | -           | -> NI state |
|Join (J)    ||restart      | start Prune- |             |             |
|            ||Expiry Timer | Pending      |             |             |
|            ||             | Timer        |             |             |
+------------++-------------+--------------+-------------+-------------+
|Prune-      ||-> J state   | -> PP state  | -> NI state | -> NI state |
|Pending (PP)||restart      |              | Send Prune- |             |
|            ||Expiry Timer |              | Echo(S,G)   |             |
+------------++-------------+--------------+-------------+-------------+

   The transition events "Receive Join(S,G)" and "Receive Prune(S,G)"
   imply receiving a Join or Prune targeted to this router's primary IP
   address on the received interface.  If the upstream neighbor address
   field 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 should be the same as the source address it chose for the
   Hello message it sent over that interface.  However, on point-to-
   point links we also recommend that for backwards compatibility PIM
   Join/Prune messages with an upstream neighbor address field of all
   zeros are also accepted.

   Transitions from NoInfo State

   When in NoInfo state, the following event may trigger a transition:

     Receive Join(S,G)
          A Join(S,G) is received on interface I with its Upstream
          Neighbor Address set to the router's primary IP address on I.

Top      Up      ToC       Page 55 
          The (S,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.

   Transitions from Join State

   When in Join state, the following events may trigger a transition:

     Receive Join(S,G)
          A Join(S,G) is received on interface I with its Upstream
          Neighbor Address set to the router's primary IP address on I.

          The (S,G) downstream state machine on interface I remains in
          Join state, and the Expiry Timer (ET) is restarted, set to
          maximum of its current value and the HoldTime from the
          triggering Join/Prune message.

     Receive Prune(S,G)
          A Prune(S,G) is received on interface I with its Upstream
          Neighbor Address set to the router's primary IP address on I.

          The (S,G) downstream state machine on interface I transitions
          to the Prune-Pending state.  The Prune-Pending Timer is
          started.  It is set to the J/P_Override_Interval(I) if the
          router has more than one neighbor on that interface;
          otherwise, it is set to zero, causing it to expire
          immediately.

     Expiry Timer Expires
          The Expiry Timer for the (S,G) downstream state machine on
          interface I expires.

          The (S,G) downstream state machine on interface I transitions
          to the NoInfo state.

   Transitions from Prune-Pending State

   When in Prune-Pending state, the following events may trigger a
   transition:

     Receive Join(S,G)
          A Join(S,G) is received on interface I with its Upstream
          Neighbor Address set to the router's primary IP address on I.

Top      Up      ToC       Page 56 
          The (S,G) downstream state machine on interface I transitions
          to the Join state.  The Prune-Pending Timer is canceled
          (without triggering an expiry event).  The Expiry Timer is
          restarted, set to maximum of its current value and the
          HoldTime from the triggering Join/Prune message.

     Expiry Timer Expires
          The Expiry Timer for the (S,G) downstream state machine on
          interface I expires.

          The (S,G) downstream state machine on interface I transitions
          to the NoInfo state.

     Prune-Pending Timer Expires
          The Prune-Pending Timer for the (S,G) downstream state machine
          on interface I expires.

          The (S,G) downstream state machine on interface I transitions
          to the NoInfo state.  A PruneEcho(S,G) is sent onto the subnet
          connected to interface I.

          The action "Send PruneEcho(S,G)" is triggered when the router
          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
          upstream router on a LAN with its own address in the Upstream
          Neighbor Address field.  Its purpose is to add additional
          reliability so that if a Prune that should have been
          overridden by another router 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 an interface
          that contains only a single PIM neighbor during the time this
          state machine was in Prune-Pending state.

4.5.4.  Receiving (S,G,rpt) Join/Prune Messages

   The per-interface state machine for receiving (S,G,rpt) Join/Prune
   messages is given below.  There are five states:

     NoInfo (NI)
          The interface has no (S,G,rpt) Prune state and no (S,G,rpt)
          timers running.

     Prune (P)
          The interface has (S,G,rpt) Prune state, which will cause the
          router not to forward packets from S destined for G from this
          interface even though the interface has active (*,G) Join
          state.

Top      Up      ToC       Page 57 
     Prune-Pending (PP)
          The router has received a Prune(S,G,rpt) on this interface
          from a downstream neighbor and is waiting to see whether the
          prune will be overridden by another downstream router.  For
          forwarding purposes, the Prune-Pending state functions exactly
          like the NoInfo state.

     PruneTmp (P')
          This state is a transient state that for forwarding purposes
          behaves exactly like the Prune state.  A (*,G) Join has been
          received (which may cancel the (S,G,rpt) Prune).  As we parse
          the Join/Prune message from top to bottom, we first enter this
          state if the message contains a (*,G) Join.  Later in the
          message, we will normally encounter an (S,G,rpt) prune to
          reinstate the Prune state.  However, if we reach the end of
          the message without encountering such a (S,G,rpt) prune, then
          we will revert to NoInfo state in this state machine.

          As no time is spent in this state, no timers can expire.

     Prune-Pending-Tmp (PP')
          This state is a transient state that is identical to P' except
          that it is associated with the PP state rather than the P
          state.  For forwarding purposes, PP' behaves exactly like PP
          state.

   In addition, there are two timers:

     Expiry Timer (ET)
          This timer is set when a valid Prune(S,G,rpt) is received.
          Expiry of the Expiry Timer causes this state machine to revert
          to NoInfo state.

     Prune-Pending Timer (PPT)
          This timer is set when a valid Prune(S,G,rpt) is received.
          Expiry of the Prune-Pending Timer causes this state machine to
          move on to Prune state.

Top      Up      ToC       Page 58 
      Figure 5: Downstream per-interface (S,G,rpt) state machine
                            in tabular form

+----------++----------------------------------------------------------+
|          ||                          Event                           |
|          ++---------+----------+----------+--------+--------+--------+
|Prev      ||Receive  | Receive  | Receive  | End of | Prune- | Expiry |
|State     ||Join(*,G)| Join     | Prune    | Message| Pending| Timer  |
|          ||         | (S,G,rpt)| (S,G,rpt)|        | Timer  | Expires|
|          ||         |          |          |        | Expires|        |
+----------++---------+----------+----------+--------+--------+--------+
|          ||-        | -        | -> PP    | -      | -      | -      |
|          ||         |          | state    |        |        |        |
|          ||         |          | start    |        |        |        |
|NoInfo    ||         |          | Prune-   |        |        |        |
|(NI)      ||         |          | Pending  |        |        |        |
|          ||         |          | Timer;   |        |        |        |
|          ||         |          | start    |        |        |        |
|          ||         |          | Expiry   |        |        |        |
|          ||         |          | Timer    |        |        |        |
+----------++---------+----------+----------+--------+--------+--------+
|          ||-> P'    | -> NI    | -> P     | -      | -      | -> NI  |
|          ||state    | state    | state    |        |        | state  |
|Prune (P) ||         |          | restart  |        |        |        |
|          ||         |          | Expiry   |        |        |        |
|          ||         |          | Timer    |        |        |        |
+----------++---------+----------+----------+--------+--------+--------+
|Prune-    ||-> PP'   | -> NI    | -        | -      | -> P   | -      |
|Pending   ||state    | state    |          |        | state  |        |
|(PP)      ||         |          |          |        |        |        |
+----------++---------+----------+----------+--------+--------+--------+
|          ||-        | -        | -> P     | -> NI  | -      | -      |
|PruneTmp  ||         |          | state    | state  |        |        |
|(P')      ||         |          | restart  |        |        |        |
|          ||         |          | Expiry   |        |        |        |
|          ||         |          | Timer    |        |        |        |
+----------++---------+----------+----------+--------+--------+--------+
|          ||-        | -        | -> PP    | -> NI  | -      | -      |
|Prune-    ||         |          | state    | state  |        |        |
|Pending-  ||         |          | restart  |        |        |        |
|Tmp (PP') ||         |          | Expiry   |        |        |        |
|          ||         |          | Timer    |        |        |        |
+----------++---------+----------+----------+--------+--------+--------+

   The transition events "Receive Join(S,G,rpt)", "Receive
   Prune(S,G,rpt)", and "Receive Join(*,G)" imply receiving a Join or
   Prune targeted to this router's primary IP address on the received
   interface.  If the upstream neighbor address field is not correct,

Top      Up      ToC       Page 59 
   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 should be the same as the source address it chose for the
   Hello message it sent over that interface.  However, on point-to-
   point links we also recommend that PIM Join/Prune messages with an
   upstream neighbor address field of all zeros are also accepted.

   Transitions from NoInfo State

   When in NoInfo (NI) state, the following event may trigger a
   transition:

     Receive Prune(S,G,rpt)
          A Prune(S,G,rpt) is received on interface I with its Upstream
          Neighbor Address set to the router's primary IP address on I.

          The (S,G,rpt) downstream state machine on interface I
          transitions to the Prune-Pending state.  The Expiry Timer (ET)
          is started and set to the HoldTime from the triggering
          Join/Prune message.  The Prune-Pending Timer is started.  It
          is set to the J/P_Override_Interval(I) if the router has more
          than one neighbor on that interface; otherwise, it is set to
          zero, causing it to expire immediately.

   Transitions from Prune-Pending State

   When in Prune-Pending (PP) state, the following events may trigger a
   transition:

     Receive Join(*,G)
          A Join(*,G) is received on interface I with its Upstream
          Neighbor Address set to the router's primary IP address on I.

          The (S,G,rpt) downstream state machine on interface I
          transitions to Prune-Pending-Tmp state whilst the remainder of
          the compound Join/Prune message containing the Join(*,G) is
          processed.

     Receive Join(S,G,rpt)
          A Join(S,G,rpt) is received on interface I with its Upstream
          Neighbor Address set to the router's primary IP address on I.

          The (S,G,rpt) downstream state machine on interface I
          transitions to NoInfo state.  ET and PPT are canceled.

Top      Up      ToC       Page 60 
     Prune-Pending Timer Expires
          The Prune-Pending Timer for the (S,G,rpt) downstream state
          machine on interface I expires.

          The (S,G,rpt) downstream state machine on interface I
          transitions to the Prune state.

   Transitions from Prune State

   When in Prune (P) state, the following events may trigger a
   transition:

     Receive Join(*,G)
          A Join(*,G) is received on interface I with its Upstream
          Neighbor Address set to the router's primary IP address on I.

          The (S,G,rpt) downstream state machine on interface I
          transitions to PruneTmp state whilst the remainder of the
          compound Join/Prune message containing the Join(*,G) is
          processed.

     Receive Join(S,G,rpt)
          A Join(S,G,rpt) is received on interface I with its Upstream
          Neighbor Address set to the router's primary IP address on I.

          The (S,G,rpt) downstream state machine on interface I
          transitions to NoInfo state.  ET and PPT are canceled.

     Receive Prune(S,G,rpt)
          A Prune(S,G,rpt) is received on interface I with its Upstream
          Neighbor Address set to the router's primary IP address on I.

          The (S,G,rpt) downstream state machine on interface I remains
          in Prune state.  The Expiry Timer (ET) is restarted, set to
          maximum of its current value and the HoldTime from the
          triggering Join/Prune message.

     Expiry Timer Expires
          The Expiry Timer for the (S,G,rpt) downstream state machine on
          interface I expires.

          The (S,G,rpt) downstream state machine on interface I
          transitions to the NoInfo state.

   Transitions from Prune-Pending-Tmp State

   When in Prune-Pending-Tmp (PP') state and processing a compound
   Join/Prune message, the following events may trigger a transition:

Top      Up      ToC       Page 61 
     Receive 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
          transitions back to the Prune-Pending state.  The Expiry Timer
          (ET) 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
          transitions to the NoInfo state.  ET and PPT are canceled.

   Transitions from PruneTmp State

   When in PruneTmp (P') state and processing a compound Join/Prune
   message, the following events may trigger a transition:

     Receive 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
          transitions back to the Prune state.  The Expiry Timer (ET) 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
          transitions to the NoInfo state.  ET is canceled.

   Notes:

   Receiving a Prune(*,G) does not affect the (S,G,rpt) downstream state
   machine.

   Receiving a Join(*,*,RP) does not affect the (S,G,rpt) downstream
   state machine.  If a router has originated Join(*,*,RP) and pruned a
   source off it using Prune(S,G,rpt), then to receive that source again
   it should explicitly re-join using Join(S,G,rpt) or Join(*,G).  In
   some LAN topologies it is possible for a router sending a new
   Join(*,*,RP) to have to wait as much as a Join/Prune Interval before
   noticing that it needs to override a neighbor's preexisting
   Prune(S,G,rpt).  This is considered acceptable, as (*,*,RP) state is
   intended to be used only in long-lived and persistent scenarios.


Next RFC Part