tech-invite   World Map     

IETF     RFCs     Groups     SIP     ABNFs    |    3GPP     Specs     Gloss.     Arch.     IMS     UICC    |    Misc.    |    search     info

RFC 7761

 
 
 

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

Part 5 of 7, p. 76 to 98
Prev RFC Part       Next RFC Part

 


prevText      Top      ToC       Page 76 
4.6.  PIM Assert Messages

   Where multiple PIM routers peer over a shared LAN, it is possible for
   more than one upstream router to have valid forwarding state for a
   packet, which can lead to packet duplication (see Section 3.6).  PIM
   does not attempt to prevent this from occurring.  Instead, it detects
   when this has happened and elects a single forwarder amongst the
   upstream routers to prevent further duplication.  This election is
   performed using PIM Assert messages.  Assert messages are also
   received by downstream routers on the LAN, and these cause subsequent
   Join/Prune messages to be sent to the upstream router that won the
   Assert.

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

   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.6.1.  (S,G) Assert Message State Machine

   The (S,G) Assert state machine for interface I is shown in Figure 8.
   There are three states:

      NoInfo (NI)
            This router has no (S,G) assert state on interface I.

      I am Assert Winner (W)
            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 interface I.  Irrespective of whether it is the DR
            for I, while a router is the assert winner, it is also
            responsible for forwarding traffic onto I on behalf of local
            hosts on I that have made membership requests that
            specifically refer to S (and G).

      I am Assert Loser (L)
            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 the DR on I, it is no longer
            responsible for forwarding traffic onto I to satisfy local
            hosts with membership requests that specifically refer to S
            and G.

   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.

Top      Up      ToC       Page 78 
           Figure 8: Per-Interface (S,G) Assert State Machine

+----------------------------------------------------------------------+
|                         In NoInfo (NI) State                         |
+---------------+-------------------+------------------+---------------+
| Receive       |  Receive Assert   |  Data arrives    |  Receive      |
| Inferior      |  with RPTbit      |  from S to G on  |  Acceptable   |
| Assert with   |  set and          |  I and           |  Assert with  |
| RPTbit clear  |  CouldAssert      |  CouldAssert     |  RPTbit clear |
|               |  (S,G,I)          |  (S,G,I)         |  and AssTrDes |
|               |                   |                  |  (S,G,I)      |
+---------------+-------------------+------------------+---------------+
| -> W state    |  -> W state       |  -> W state      |  -> L state   |
| [Actions A1]  |  [Actions A1]     |  [Actions A1]    |  [Actions A6] |
+---------------+-------------------+------------------+---------------+

+----------------------------------------------------------------------+
|                   In I Am Assert Winner (W) State                    |
+----------------+------------------+-----------------+----------------+
| Assert Timer   |   Receive        |  Receive        |  CouldAssert   |
| Expires        |   Inferior       |  Preferred      |  (S,G,I) ->    |
|                |   Assert         |  Assert         |  FALSE         |
+----------------+------------------+-----------------+----------------+
| -> W state     |   -> W state     |  -> L state     |  -> NI state   |
| [Actions A3]   |   [Actions A3]   |  [Actions A2]   |  [Actions A4]  |
+----------------+------------------+-----------------+----------------+

+---------------------------------------------------------------------+
|                   In I Am Assert Loser (L) State                    |
+-------------+-------------+-------------+-------------+-------------+
|Receive      |Receive      |Receive      |Assert Timer |Current      |
|Preferred    |Acceptable   |Inferior     |Expires      |Winner's     |
|Assert       |Assert with  |Assert or    |             |GenID        |
|             |RPTbit clear |Assert       |             |Changes or   |
|             |from Current |Cancel from  |             |NLT Expires  |
|             |Winner       |Current      |             |             |
|             |             |Winner       |             |             |
+-------------+-------------+-------------+-------------+-------------+
|-> L state   |-> L state   |-> NI state  |-> NI state  |-> NI state  |
|[Actions A2] |[Actions A2] |[Actions A5] |[Actions A5] |[Actions A5] |
+-------------+-------------+-------------+-------------+-------------+

Top      Up      ToC       Page 79 
+----------------------------------------------------------------------+
|                    In I Am Assert Loser (L) State                    |
+----------------+-----------------+------------------+----------------+
| AssTrDes       |  my_metric ->   |  RPF_interface   |  Receive       |
| (S,G,I) ->     |  better than    |  (S) stops       |  Join(S,G) on  |
| FALSE          |  winner's       |  being I         |  interface I   |
|                |  metric         |                  |                |
+----------------+-----------------+------------------+----------------+
| -> NI state    |  -> NI state    |  -> NI state     |  -> NI State   |
| [Actions A5]   |  [Actions A5]   |  [Actions A5]    |  [Actions A5]  |
+----------------+-----------------+------------------+----------------+

   Note that for reasons of compactness, "AssTrDes(S,G,I)" is used in
   the state machine table to refer to AssertTrackingDesired(S,G,I).

   Terminology:

      A "preferred assert" is one with a better metric than the current
      winner.

      An "acceptable assert" is one that has a better metric than
      my_assert_metric(S,G,I).  An assert is never considered acceptable
      if its metric is infinite.

      An "inferior assert" is one with a worse metric than
      my_assert_metric(S,G,I).  An assert is never considered inferior
      if my_assert_metric(S,G,I) is infinite.

   The state machine uses the following macros:

   CouldAssert(S,G,I) =
        SPTbit(S,G)==TRUE
        AND (RPF_interface(S) != I)
        AND (I in ( ( joins(*,G) (-) prunes(S,G,rpt) )
                    (+) ( pim_include(*,G) (-) pim_exclude(S,G) )
                    (-) lost_assert(*,G)
                    (+) joins(S,G) (+) pim_include(S,G) ) )

   CouldAssert(S,G,I) is true for downstream interfaces that would be in
   the inherited_olist(S,G) if (S,G) assert information was not taken
   into account.

Top      Up      ToC       Page 80 
   AssertTrackingDesired(S,G,I) =
        (I in ( joins(*,G) (-) prunes(S,G,rpt)
                (+) ( pim_include(*,G) (-) pim_exclude(S,G) )
                (-) lost_assert(*,G)
                (+) joins(S,G) ) )
        OR (local_receiver_include(S,G,I) == TRUE
            AND (I_am_DR(I) OR (AssertWinner(S,G,I) == me)))
        OR ((RPF_interface(S) == I) AND (JoinDesired(S,G) == TRUE))
        OR ((RPF_interface(RP(G)) == I) AND (JoinDesired(*,G) == TRUE)
            AND (SPTbit(S,G) == FALSE))

   AssertTrackingDesired(S,G,I) is true on any interface in which an
   (S,G) assert might affect the router's behavior on that interface.

   The first three lines of AssertTrackingDesired account for (*,G) join
   and local membership information received on I that might cause the
   router to be interested in asserts on I.

   The 4th line accounts for (S,G) join information received on I that
   might cause the router to be interested in asserts on I.

   The 5th and 6th lines account for (S,G) local membership information
   on I.  Note that we can't use the pim_include(S,G) macro, since it
   uses lost_assert(S,G,I) and would result in the router forgetting
   that it lost an assert if the only reason it was interested was local
   membership.  The AssertWinner(S,G,I) check forces an assert winner to
   keep on being responsible for forwarding as long as local receivers
   are present.  Removing this check would make the assert winner
   give up forwarding as soon as the information that originally caused
   it to forward went away, and the task of forwarding for local
   receivers would revert back to the DR.

   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 prunes to the proper neighbor.

Top      Up      ToC       Page 81 
   Transitions from NoInfo State

   When in NoInfo state, the following events may trigger transitions:

      Receive Inferior Assert with RPTbit cleared
            An assert is received for (S,G) with the RPT bit cleared
            that is inferior to our own assert metric.  The RPT bit
            cleared indicates that the sender of the assert had (S,G)
            forwarding state on this interface.  If the assert is
            inferior to our metric, then we must also have (S,G)
            forwarding state (i.e., CouldAssert(S,G,I)==TRUE) as (S,G)
            asserts have priority over (*,G) asserts, and so we should
            be the assert winner.  We transition to the "I am Assert
            Winner" state and perform Actions A1 (below).

      Receive Assert with RPTbit set AND CouldAssert(S,G,I)==TRUE
            An assert is received for (S,G) on I with the RPT bit set
            (it is a (*,G) assert).  CouldAssert(S,G,I) is TRUE only if
            we have (S,G) forwarding state on this interface, so we
            should be the assert winner.  We transition to the "I am
            Assert Winner" state and perform Actions A1 (below).

      An (S,G) data packet arrives on interface I, AND
         CouldAssert(S,G,I)==TRUE
            An (S,G) data packet arrived on a downstream interface that
            is in our (S,G) outgoing interface list.  We optimistically
            assume that we will be the assert winner for this (S,G), and
            so we transition to the "I am Assert Winner" state and
            perform Actions A1 (below), which will initiate the assert
            negotiation for (S,G).

      Receive Acceptable Assert with RPT bit clear AND
         AssertTrackingDesired(S,G,I)==TRUE
            We're interested in (S,G) Asserts, either because I is a
            downstream interface for which we have (S,G) or (*,G)
            forwarding state, or because I is the upstream interface for
            S and we have (S,G) forwarding state.  The received assert
            has a better metric than our own, so we do not win the
            Assert.  We transition to "I am Assert Loser" and perform
            Actions A6 (below).

Top      Up      ToC       Page 82 
   Transitions from "I am Assert Winner" State

   When in "I am Assert Winner" state, the following events trigger
   transitions:

      Assert Timer Expires
            The (S,G) Assert Timer expires.  As we're in the Winner
            state, we must still have (S,G) forwarding state that is
            actively being kept alive.  We resend the (S,G) Assert and
            restart the Assert Timer (Actions A3 below).  Note that the
            assert winner's Assert Timer is engineered to expire shortly
            before timers on assert losers; this prevents unnecessary
            thrashing of the forwarder and periodic flooding of
            duplicate packets.

      Receive Inferior Assert
            We receive an (S,G) assert or (*,G) assert mentioning S that
            has a worse metric than our own.  Whoever sent the assert is
            in error, and so we resend an (S,G) Assert and restart the
            Assert Timer (Actions A3 below).

      Receive Preferred Assert
            We receive an (S,G) assert that has a better metric than our
            own.  We transition to "I am Assert Loser" state and perform
            Actions A2 (below).  Note that this may affect the value of
            JoinDesired(S,G) and PruneDesired(S,G,rpt), which could
            cause transitions in the upstream (S,G) or (S,G,rpt) state
            machines.

      CouldAssert(S,G,I) -> FALSE
            Our (S,G) forwarding state or RPF interface changed so as to
            make CouldAssert(S,G,I) become false.  We can no longer
            perform the actions of the assert winner, and so we
            transition to NoInfo state and perform Actions A4 (below).
            This includes sending a "canceling assert" with an infinite
            metric.

Top      Up      ToC       Page 83 
   Transitions from "I am Assert Loser" State

   When in "I am Assert Loser" state, the following transitions can
   occur:

      Receive Preferred Assert
            We receive an assert that is better than that of the current
            assert winner.  We stay in Loser state and perform
            Actions A2 below.

      Receive Acceptable Assert with RPTbit clear from Current Winner
            We receive an assert from the current assert winner that is
            better than our own metric for this (S,G) (although the
            metric may be worse than the winner's previous metric).  We
            stay in Loser state and perform Actions A2 below.

      Receive Inferior Assert or Assert Cancel from Current Winner
            We receive an assert from the current assert winner that is
            worse than our own metric for this group (typically, because
            the winner's metric became worse or because it is an assert
            cancel).  We transition to NoInfo state, deleting the (S,G)
            assert information and allowing 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.

      Assert Timer Expires
            The (S,G) Assert Timer expires.  We transition to NoInfo
            state, deleting the (S,G) assert information (Actions A5
            below).

      Current Winner's GenID Changes or NLT Expires
            The Neighbor Liveness Timer associated with the current
            winner expires or we receive a Hello message from the
            current winner reporting a different GenID from the one it
            previously reported.  This indicates that the current
            winner's interface or router has gone down (and may have
            come back up), and so we must assume that it no longer knows
            it was the winner.  We transition to the NoInfo state,
            deleting this (S,G) assert information (Actions A5 below).

      AssertTrackingDesired(S,G,I)->FALSE
            AssertTrackingDesired(S,G,I) becomes FALSE.  Our forwarding
            state has changed so that (S,G) Asserts on interface I are
            no longer of interest to us.  We transition to the NoInfo
            state, deleting the (S,G) assert information.

Top      Up      ToC       Page 84 
      My metric becomes better than the assert winner's metric
            my_assert_metric(S,G,I) has changed so that now my assert
            metric for (S,G) is better than the metric we have stored
            for the current assert winner.  This might happen when the
            underlying routing metric changes, or when
            CouldAssert(S,G,I) becomes true, for example, when
            SPTbit(S,G) becomes true.  We transition to NoInfo state,
            delete this (S,G) assert state (Actions A5 below), 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(S) stops being interface I
            Interface I used to be the RPF interface for S, and now it
            is not.  We transition to NoInfo state, deleting this (S,G)
            assert state (Actions A5 below).

      Receive Join(S,G) on Interface I
            We receive a Join(S,G) that has the Upstream Neighbor
            Address field set to my primary IP address on interface I.
            The action is to transition to NoInfo state, delete this
            (S,G) assert state (Actions A5 below), and allow the normal
            PIM Join/Prune mechanisms to operate.  If whoever sent the
            Join was in error, then the normal assert mechanism will
            eventually re-apply, and we will lose the assert again.
            However, whoever sent the assert may know that the previous
            assert winner has died, and so we may end up being the new
            forwarder.

   (S,G) Assert State Machine Actions

      A1: Send Assert(S,G).
          Set Assert Timer to (Assert_Time - Assert_Override_Interval).
          Store self as AssertWinner(S,G,I).
          Store spt_assert_metric(S,I) as AssertWinnerMetric(S,G,I).

      A2: Store new assert winner as AssertWinner(S,G,I) and assert
          winner metric as AssertWinnerMetric(S,G,I).
          Set Assert Timer to Assert_Time.

      A3: Send Assert(S,G).
          Set Assert Timer to (Assert_Time - Assert_Override_Interval).

      A4: Send AssertCancel(S,G).
          Delete assert information (AssertWinner(S,G,I) and
          AssertWinnerMetric(S,G,I) will then return to their default
          values).

Top      Up      ToC       Page 85 
      A5: Delete assert information (AssertWinner(S,G,I) and
          AssertWinnerMetric(S,G,I) will then return to their default
          values).

      A6: Store new assert winner as AssertWinner(S,G,I) and assert
          winner metric as AssertWinnerMetric(S,G,I).
          Set Assert Timer to Assert_Time.
          If (I is RPF_interface(S)) AND (UpstreamJPState(S,G) ==
          Joined) set SPTbit(S,G) to TRUE.

   Note that some of these actions may cause the value of
   JoinDesired(S,G), PruneDesired(S,G,rpt), or RPF'(S,G) to change,
   which could cause further transitions in other state machines.

4.6.2.  (*,G) Assert Message State Machine

   The (*,G) Assert state machine for interface I is shown in Figure 9.
   There are three states:

      NoInfo (NI)
            This router has no (*,G) assert state on interface I.

      I am Assert Winner (W)
            This router has won a (*,G) assert on interface I.  It is
            now responsible for forwarding traffic destined for G onto
            interface I with the exception of traffic for which it has
            (S,G) "I am Assert Loser" state.  Irrespective of whether it
            is the DR for I, it is also responsible for handling the
            membership requests for G from local hosts on I.

      I am Assert Loser (L)
            This router has lost a (*,G) assert on interface I.  It must
            not forward packets for G onto interface I with the
            exception of traffic from sources for which it has (S,G) "I
            am Assert Winner" state.  If it is the DR, it is no longer
            responsible for handling 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 asserts on the assert losers and to resend asserts on the assert
   winner.

   When an Assert message is received with a source address other than
   zero, a PIM implementation must first match it against the possible
   events in the (S,G) assert state machine and process any transitions
   and actions, before considering whether the Assert message matches
   against the (*,G) assert state machine.

Top      Up      ToC       Page 86 
   It is important to note that NO TRANSITION CAN OCCUR in the (*,G)
   state machine as a result of receiving an Assert message unless the
   (S,G) assert state machine for the relevant S and G is in the
   "NoInfo" state after the (S,G) state machine has processed the
   message.  Also, NO TRANSITION CAN OCCUR in the (*,G) state machine as
   a result of receiving an assert message if that message triggers any
   change of state in the (S,G) state machine.  Obviously, when the
   source address in the received message is set to zero, an (S,G) state
   machine for the S and G does not exist and can be assumed to be in
   the "NoInfo" state.

   For example, if both the (S,G) and (*,G) assert state machines are in
   the NoInfo state when an Assert message arrives, and the message
   causes the (S,G) state machine to transition to either "W" or "L"
   state, then the assert will not be processed by the (*,G) assert
   state machine.

   Another example: if the (S,G) assert state machine is in "L" state
   when an assert message is received, and the assert metric in the
   message is worse than my_assert_metric(S,G,I), then the (S,G) assert
   state machine will transition to NoInfo state.  In such a case, if
   the (*,G) assert state machine were in NoInfo state, it might appear
   that it would transition to "W" state, but this is not the case
   because this message already triggered a transition in the (S,G)
   assert state machine.

Top      Up      ToC       Page 87 
           Figure 9: Per-Interface (*,G) Assert State Machine

+----------------------------------------------------------------------+
|                         In NoInfo (NI) State                         |
+-----------------------+-----------------------+----------------------+
| Receive Inferior      |  Data arrives for G   |  Receive Acceptable  |
| Assert with RPTbit    |  on I and             |  Assert with RPTbit  |
| set and               |  CouldAssert          |  set and AssTrDes    |
| CouldAssert(*,G,I)    |  (*,G,I)              |  (*,G,I)             |
+-----------------------+-----------------------+----------------------+
| -> W state            |  -> W state           |  -> L state          |
| [Actions A1]          |  [Actions A1]         |  [Actions A2]        |
+-----------------------+-----------------------+----------------------+

+---------------------------------------------------------------------+
|                    In I Am Assert Winner (W) State                  |
+----------------+-----------------+-----------------+----------------+
| Assert Timer   |  Receive        |  Receive        |  CouldAssert   |
| Expires        |  Inferior       |  Preferred      |  (*,G,I) ->    |
|                |  Assert         |  Assert         |  FALSE         |
+----------------+-----------------+-----------------+----------------+
| -> W state     |  -> W state     |  -> L state     |  -> NI state   |
| [Actions A3]   |  [Actions A3]   |  [Actions A2]   |  [Actions A4]  |
+----------------+-----------------+-----------------+----------------+

+---------------------------------------------------------------------+
|                    In I Am Assert Loser (L) State                   |
+-------------+-------------+-------------+-------------+-------------+
|Receive      |Receive      |Receive      |Assert Timer |Current      |
|Preferred    |Acceptable   |Inferior     |Expires      |Winner's     |
|Assert with  |Assert from  |Assert or    |             |GenID        |
|RPTbit set   |Current      |Assert       |             |Changes or   |
|             |Winner with  |Cancel from  |             |NLT Expires  |
|             |RPTbit set   |Current      |             |             |
|             |             |Winner       |             |             |
+-------------+-------------+-------------+-------------+-------------+
|-> L state   |-> L state   |-> NI state  |-> NI state  |-> NI state  |
|[Actions A2] |[Actions A2] |[Actions A5] |[Actions A5] |[Actions A5] |
+-------------+-------------+-------------+-------------+-------------+

Top      Up      ToC       Page 88 
+----------------------------------------------------------------------+
|                    In I Am Assert Loser (L) State                    |
+----------------+----------------+-----------------+------------------+
| AssTrDes       | my_metric ->   |  RPF_interface  |  Receive         |
| (*,G,I) ->     | better than    |  (RP(G)) stops  |  Join(*,G) on    |
| FALSE          | Winner's       |  being I        |  Interface I     |
|                | metric         |                 |                  |
+----------------+----------------+-----------------+------------------+
| -> NI state    | -> NI state    |  -> NI state    |  -> NI State     |
| [Actions A5]   | [Actions A5]   |  [Actions A5]   |  [Actions A5]    |
+----------------+----------------+-----------------+------------------+

   The state machine uses the following macros:

      CouldAssert(*,G,I) =
          ( I in ( joins(*,G) (+) pim_include(*,G)) )
          AND (RPF_interface(RP(G)) != I)

   CouldAssert(*,G,I) is true on downstream interfaces for which we have
   (*,G) join state, or local members that requested any traffic
   destined for G.

      AssertTrackingDesired(*,G,I) =
          CouldAssert(*,G,I)
          OR (local_receiver_include(*,G,I)==TRUE
              AND (I_am_DR(I) OR AssertWinner(*,G,I) == me))
          OR (RPF_interface(RP(G)) == I AND RPTJoinDesired(G))

   AssertTrackingDesired(*,G,I) is true on any interface on which a
   (*,G) assert might affect the router's behavior on that interface.

   Note that for reasons of compactness, "AssTrDes(*,G,I)" is used in
   the state machine table to refer to AssertTrackingDesired(*,G,I).

   Terminology:

      A "preferred assert" is one with a better metric than the current
      winner.

      An "acceptable assert" is one that has a better metric than
      my_assert_metric(*,G,I).  An assert is never considered acceptable
      if its metric is infinite.

      An "inferior assert" is one with a worse metric than
      my_assert_metric(*,G,I).  An assert is never considered inferior
      if my_assert_metric(*,G,I) is infinite.

Top      Up      ToC       Page 89 
   Transitions from NoInfo State

   When in NoInfo state, the following events trigger transitions, but
   only if the (S,G) assert state machine is in NoInfo state before and
   after consideration of the received message:

      Receive Inferior Assert with RPTbit set AND
         CouldAssert(*,G,I)==TRUE
            An Inferior (*,G) assert is received for G on Interface I.
            If CouldAssert(*,G,I) is TRUE, then I is our downstream
            interface, and we have (*,G) forwarding state on this
            interface, so we should be the assert winner.  We transition
            to the "I am Assert Winner" state and perform Actions A1
            (below).

      A data packet destined for G arrives on interface I, AND
         CouldAssert(*,G,I)==TRUE
            A data packet destined for G arrived on a downstream
            interface that is in our (*,G) outgoing interface list.  We
            therefore believe we should be the forwarder for this (*,G),
            and so we transition to the "I am Assert Winner" state and
            perform Actions A1 (below).

      Receive Acceptable Assert with RPT bit set AND
         AssertTrackingDesired(*,G,I)==TRUE
            We're interested in (*,G) Asserts, either because I is a
            downstream interface for which we have (*,G) forwarding
            state, or because I is the upstream interface for RP(G) and
            we have (*,G) forwarding state.  We get a (*,G) Assert that
            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).

Top      Up      ToC       Page 90 
   Transitions from "I am Assert Winner" State

   When in "I am Assert Winner" state, the following events trigger
   transitions, but only if the (S,G) assert state machine is in NoInfo
   state before and after consideration of the received message:

      Receive Inferior Assert
            We receive a (*,G) assert that has a worse metric than our
            own.  Whoever sent the assert has lost, and so we resend a
            (*,G) Assert and restart the Assert Timer (Actions A3
            below).

      Receive Preferred Assert
            We receive a (*,G) assert that has a better metric than our
            own.  We transition to "I am Assert Loser" state and perform
            Actions A2 (below).

   When in "I am Assert Winner" state, the following events trigger
   transitions:

      Assert Timer Expires
            The (*,G) Assert Timer expires.  As we're in the Winner
            state, then we must still have (*,G) forwarding state that
            is actively being kept alive.  To prevent unnecessary
            thrashing of the forwarder and periodic flooding of
            duplicate packets, we resend the (*,G) Assert and restart
            the Assert Timer (Actions A3 below).

      CouldAssert(*,G,I) -> FALSE
            Our (*,G) forwarding state or RPF interface changed so as to
            make CouldAssert(*,G,I) become false.  We can no longer
            perform the actions of the assert winner, and so we
            transition to NoInfo state and perform Actions A4 (below).

Top      Up      ToC       Page 91 
   Transitions from "I am Assert Loser" State

   When in "I am Assert Loser" state, the following events trigger
   transitions, but only if the (S,G) assert state machine is in NoInfo
   state before and after consideration of the received message:

      Receive Preferred Assert with RPTbit set
            We receive a (*,G) assert that is better than that of the
            current assert winner.  We stay in Loser state and perform
            Actions A2 below.

      Receive Acceptable Assert from Current Winner with RPTbit set
            We receive a (*,G) assert from the current assert winner
            that is better than our own metric for this group (although
            the metric may be worse than the winner's previous metric).
            We stay in Loser state and perform Actions A2 below.

      Receive Inferior Assert or Assert Cancel from Current Winner
            We receive an assert from the current assert winner that is
            worse than our own metric for this group (typically because
            the winner's metric became worse or is now an assert
            cancel).  We transition to NoInfo state, delete this (*,G)
            assert state (Actions A5), and allow the normal PIM
            Join/Prune mechanisms to operate.  Usually, we will
            eventually re-assert and win when data packets for G have
            started flowing again.

   When in "I am Assert Loser" state, the following events trigger
   transitions:

      Assert Timer Expires
            The (*,G) Assert Timer expires.  We transition to NoInfo
            state and delete this (*,G) assert information (Actions A5).

      Current Winner's GenID Changes or NLT Expires
            The Neighbor Liveness Timer associated with the current
            winner expires or we receive a Hello message from the
            current winner reporting a different GenID from the one it
            previously reported.  This indicates that the current
            winner's interface or router has gone down (and may have
            come back up), and so we must assume that it no longer knows
            it was the winner.  We transition to the NoInfo state,
            deleting the (*,G) assert information (Actions A5).

Top      Up      ToC       Page 92 
      AssertTrackingDesired(*,G,I)->FALSE
            AssertTrackingDesired(*,G,I) becomes FALSE.  Our forwarding
            state has changed so that (*,G) Asserts on interface I are
            no longer of interest to us.  We transition to NoInfo state
            and delete this (*,G) assert information (Actions A5).

      My metric becomes better than the assert winner's metric
            My routing metric, rpt_assert_metric(G,I), has changed so
            that now my assert metric for (*,G) is better than the
            metric we have stored for the current assert winner.  We
            transition to NoInfo state, delete this (*,G) assert state
            (Actions A5), and allow the normal PIM Join/Prune mechanisms
            to operate.  Usually, we will eventually re-assert and win
            when data packets for G have started flowing again.

      RPF_interface(RP(G)) stops being interface I
            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) assert state (Actions A5).

      Receive Join(*,G) on interface I
            We receive a Join(*,G) that has the Upstream Neighbor
            Address field set to my primary IP address on interface I.
            The action is to transition to NoInfo state, delete this
            (*,G) assert state (Actions A5), and allow the normal PIM
            Join/Prune mechanisms to operate.  If whoever sent the Join
            was in error, then the normal assert mechanism will
            eventually re-apply, and we will lose the assert again.
            However, whoever sent the assert may know that the previous
            assert winner has died, so we may end up being the new
            forwarder.

   (*,G) Assert State Machine Actions

      A1: Send Assert(*,G).
          Set Assert Timer to (Assert_Time - Assert_Override_Interval).
          Store self as AssertWinner(*,G,I).
          Store rpt_assert_metric(G,I) as AssertWinnerMetric(*,G,I).

      A2: Store new assert winner as AssertWinner(*,G,I) and assert
          winner metric as AssertWinnerMetric(*,G,I).
          Set Assert Timer to Assert_Time.

      A3: Send Assert(*,G).
          Set Assert Timer to (Assert_Time - Assert_Override_Interval).

Top      Up      ToC       Page 93 
      A4: Send AssertCancel(*,G).
          Delete assert information (AssertWinner(*,G,I) and
          AssertWinnerMetric(*,G,I) will then return to their default
          values).

      A5: Delete assert information (AssertWinner(*,G,I) and
          AssertWinnerMetric(*,G,I) will then return to their default
          values).

   Note that some of these actions may cause the value of
   JoinDesired(*,G) or RPF'(*,G) to change, which could cause further
   transitions in other state machines.

4.6.3.  Assert Metrics

   Assert metrics are defined as:

     struct assert_metric {
       rpt_bit_flag;
       metric_preference;
       route_metric;
       ip_address;
     };

   When comparing assert_metrics, the rpt_bit_flag, metric_preference,
   and route_metric fields are compared in order, where the first lower
   value wins.  If all fields are equal, the primary IP address of the
   router that sourced the Assert message is used as a tie-breaker, with
   the highest IP address winning.

   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 pseudocode:

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

Top      Up      ToC       Page 94 
   spt_assert_metric(S,I) gives the assert metric we use if we're
   sending an assert based on active (S,G) forwarding state:

     assert_metric
     spt_assert_metric(S,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 an assert based only on (*,G) forwarding state:

     assert_metric
     rpt_assert_metric(G,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 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 primary IP address that is associated with the local
   interface I.

   infinite_assert_metric() is an assert metric that the router uses for
   an Assert that does not match either (S,G) or (*,G) forwarding state:

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

4.6.4.  AssertCancel Messages

   An AssertCancel message is simply an RPT Assert message but with an
   infinite metric.  It is sent by the assert winner when it deletes the
   forwarding state that had caused the assert to occur.  Other routers
   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.

   An AssertCancel(S,G) is an infinite metric assert with the RPT bit
   set that names S as the source.

   An AssertCancel(*,G) is an infinite metric assert with the RPT bit
   set and the source set to zero.

Top      Up      ToC       Page 95 
   AssertCancel messages are simply an optimization.  The original
   Assert timeout mechanism will allow a subnet to eventually become
   consistent; the AssertCancel mechanism simply causes faster
   convergence.  No special processing is required for an AssertCancel
   message, since it is simply an Assert message from the current
   winner.

4.6.5.  Assert State Macros

   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
   and are defined as:

     bool lost_assert(S,G,rpt,I) {
       if ( RPF_interface(RP(G)) == I  OR
            ( RPF_interface(S) == I AND SPTbit(S,G) == TRUE ) ) {
          return FALSE
       } else {
          return ( AssertWinner(S,G,I) != NULL AND
                   AssertWinner(S,G,I) != me )
       }
     }

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

   Note: The term "AssertWinnerMetric(S,G,I) is better than
   spt_assert_metric(S,I)" is required to correctly handle the
   transition phase when a router has (S,G) join state but has not yet
   set the SPTbit.  In this case, it needs to ignore the assert state if
   it will win the assert once the SPTbit is set.

     bool lost_assert(*,G,I) {
       if ( RPF_interface(RP(G)) == I ) {
          return FALSE
       } else {
          return ( AssertWinner(*,G,I) != NULL AND
                   AssertWinner(*,G,I) != me )
       }
     }

Top      Up      ToC       Page 96 
   AssertWinner(S,G,I) is the IP source address of the Assert(S,G)
   packet that won an Assert.

   AssertWinner(*,G,I) is the IP source address of the Assert(*,G)
   packet that won an Assert.

   AssertWinnerMetric(S,G,I) is the Assert metric of the Assert(S,G)
   packet that won an Assert.

   AssertWinnerMetric(*,G,I) is the Assert metric of the Assert(*,G)
   packet that won an Assert.

   AssertWinner(S,G,I) defaults to NULL and AssertWinnerMetric(S,G,I)
   defaults to Infinity when in the NoInfo state.

   Summary of Assert Rules and Rationale

   This section summarizes the key rules for sending and reacting to
   asserts and the rationale for these rules.  This section is not
   intended to be and should not be treated as a definitive
   specification of protocol behavior.  The state machines and
   pseudocode should be consulted for that purpose.  Rather, this
   section is intended to document important aspects of the Assert
   protocol behavior and to provide information that may prove helpful
   to the reader in understanding and implementing this part of the
   protocol.

   1.  Behavior: Downstream neighbors send Join(*,G) and Join(S,G)
       periodic messages to the appropriate RPF' neighbor, i.e., the RPF
       neighbor as modified by the assert process.  They are not always
       sent to the RPF neighbor as indicated by the MRIB.  Normal
       suppression and override rules apply.

       Rationale: By sending the periodic and triggered Join messages to
       the RPF' neighbor instead of the RPF neighbor, the downstream
       router avoids re-triggering the Assert process with every Join.
       A side effect of sending Joins to the Assert winner is that
       traffic will not switch back to the "normal" RPF neighbor until
       the Assert times out.  This will not happen until data stops
       flowing, if item 8, below, is implemented.

   2.  Behavior: The assert winner for (*,G) acts as the local DR for
       (*,G) on behalf of IGMP/MLD members.

       Rationale: This is required to allow a single router to merge
       PIM and IGMP/MLD joins and leaves.  Without this, overrides
       don't work.

Top      Up      ToC       Page 97 
   3.  Behavior: The assert winner for (S,G) acts as the local DR for
       (S,G) on behalf of IGMPv3 members.

       Rationale: Same rationale as for item 2.

   4.  Behavior: (S,G) and (*,G) prune overrides are sent to the RPF'
       neighbor and not to the regular RPF neighbor.

       Rationale: Same rationale as for item 1.

   5.  Behavior: An (S,G,rpt) prune override is not sent (at all) if
       RPF'(S,G,rpt) != RPF'(*,G).

       Rationale: This avoids keeping state alive on the (S,G) tree when
       only (*,G) downstream members are left.  Also, it avoids sending
       (S,G,rpt) joins to a router that is not on the (*,G) tree.  This
       behavior might be confusing, although this specification does
       indicate that such a join SHOULD be dropped.

   6.  Behavior: An assert loser that receives a Join(S,G) with an
       Upstream Neighbor Address that is its primary IP address on that
       interface expires the (S,G) Assert Timer.

       Rationale: This is necessary in order to have rapid convergence
       in the event that the downstream router that initially sent a
       join to the prior Assert winner has undergone a topology change.

   7.  Behavior: An assert loser that receives a Join(*,G) with an
       Upstream Neighbor Address that is its primary IP address on that
       interface expires the (*,G) Assert Timer and all (S,G) assert
       timers that do not have corresponding Prune(S,G,rpt) messages in
       the compound Join/Prune message.

       Rationale: Same rationale as for item 6.

   8.  Behavior: An assert winner for (*,G) or (S,G) sends a canceling
       assert when it is about to stop forwarding on a (*,G) or an (S,G)
       entry.  This behavior does not apply to (S,G,rpt).

       Rationale: This allows switching back to the shared tree after
       the last SPT router on the LAN leaves.  Doing this prevents
       downstream routers on the shared tree from keeping SPT state
       alive.

Top      Up      ToC       Page 98 
   9.  Behavior: Resend the assert messages before timing out an assert.
       (This behavior is optional.)

       Rationale: This prevents the periodic duplicates that would
       otherwise occur each time that an assert times out and is then
       re-established.

   10. Behavior: When RPF'(S,G,rpt) changes to be the same as RPF'(*,G),
       we need to trigger a Join(S,G,rpt) to RPF'(*,G).

       Rationale: This allows switching back to the RPT after the last
       SPT member leaves.



(page 98 continued on part 6)

Next RFC Part