Subject: [pim] Error in PIM-SM forwarding rules

From: James Lingard <[email-masked]>
Date: Fri, 23 Jan 2004 15:39:46 -0000

Hi,

I am new to PIM and have recently been studying the PIM-SM draft.  I believe
that there may be an error in the forwarding rules in the current draft
(draft-ietf-pim-sm-v2-new-08.txt, Section 4.2), which could cause a router
with only (*,G) forwarding state to incorrectly stop forwarding traffic from
a particular source.

The problem is with the clause

  'if( iif == RPF_interface(S) AND UpstreamJPState(S,G) == Joined )'

Why is the second test 'UpstreamJPState(S,G) == Joined' and not 'SPTbit(S,G)
== TRUE'?  It appears that as they stand the rules would cause a router with
only (*,G) forwarding state to stop forwarding traffic from S if SPTbit(S,G)
were set to TRUE.  This may happen in the following scenario.

Suppose that all of the following are true.

- RPF_interface(RP(G)) == RPF_interface(S)
- JoinDesired(*,G) == TRUE
- JoinDesired(S,G) == FALSE
- (S,G) Assert state-machine is in NoInfo state

If now a Preferred (S,G) Assert is received on RPF_interface(RP(G)), the
(S,G) Assert state-machine will switch to the "I Am Assert Loser" state,
performing Actions A6 which cause SPTbit(S,G) to be set to TRUE.  Once this
has happened, any (S,G) traffic received on RPF_interface(RP(G)) will not be
forwarded, because neither

  'iif == RPF_interface(S) AND UpstreamJPState(S,G) == Joined'

nor

  'iif == RPF_interface(RP(G)) AND SPTbit(S,G) == FALSE'

will be true.  Moreover, this isn't a transient problem but will continue
until either SPTbit(S,G) is reset to FALSE or JoinDesired(S,G) becomes TRUE,
which may be some time in the future.

Is it intentional that SPTbit(S,G) could be TRUE while JoinDesired(S,G) is
FALSE?  If this is intentional, then the forwarding rules need to be changed
by replacing 'UpstreamJPState(S,G) == Joined' with 'SPTbit(S,G) == TRUE' in
the place described above.  If this is not intentional, then the rules for
setting SPTbit(S,G) in the (S,G) Assert state-machine must be amended so
that this situation cannot occur.

Please let me know if I'm missing something, or if this genuinely is an
error.

Thanks,
James.

---
James Lingard
Network Protocols Group
Data Connection Ltd (DCL)
Tel: +44 20 8366 1177
Fax: +44 20 8363 1039
Email: [email-masked]
Web: http://www.dataconnection.com/

_______________________________________________
pim mailing list
[email-masked]
https://www1.ietf.org/mailman/listinfo/pim

---

From: John Zwiebel <[email-masked]>
Date: Fri, 23 Jan 2004 09:00:15 -0800

On Jan 23, 2004, at 7:39 AM, James Lingard wrote:

> were set to TRUE.

If a router has only (*,G) state then this line would be false and you'd
fall through to the next elseif which defines how to forward on the
shared tree.

You can't set the SPT bit until after you've received traffic on the
(S,G) because that is when you can decide to start sending the (S,G,R)
prunes to stop that traffic from coming down the shared tree.

---

From: John Zwiebel <[email-masked]>
Date: Fri, 23 Jan 2004 09:00:15 -0800

---

From: Mark Handley <[email-masked]>
Date: Fri, 23 Jan 2004 16:20:11 +0000

>forwarded, because neither...

The rules for transitioning from "NoInfo" to "I Am Assert Loser" state are:

     Receive Preferred 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 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 A6.

Ok, so taking a look at AssertTrackingDesired(S,G,I):

  AssertTrackingDesired(S,G,I) =
     (I in ( ( joins(*,*,RP(G)) (+) 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))

The first clause (I in ...) only applies to downstream interfaces,
which isn't the case here.  local_receiver_include is false.
JoinDesired(S,G) is false because the keepalivetimer isn't
running. SPTbit(S,G) is false.  

So AssertTrackingDesired will be false.  We won't track this assert.
As we won't track the assert, SPTbit won't be set.

Thus I don't think the problem you describe can happen, at least not
in the way you suggest.  Of course I could have overlooked something...

Cheers,
	Mark

---

From: Mark Handley <[email-masked]>
Date: Fri, 23 Jan 2004 16:20:11 +0000

Cheers,
	Mark