Subject: [pim] RFC4601 - When and how send RP's Join to S?

From: Holger Kummert <[email-masked]>
Date: Mon, 17 Mar 2014 17:31:45 +0100

Hello,

I'm currently working on an improvement of an OpenSource 
Multicast-implementation (xorp). Since no one from the development team
seems to be available I hope that I can get some advice here.

Assume an already built up RP-tree from the receiver to the RP.
Now a registration message from S is received by RP.

RFC4601 says about this case in section 3.2:
"... when the RP receives a register-encapsulated data packet
  from source S on group G, it will normally initiate an (S,G) source-
  specific Join towards S."

But unfortunately this source-specific Join towards S does not appear
in the pseudocode in section "4.4.2 Receiving Register Messages at the 
RP". It is simply not mentioned.
So my question is:

According to the pseudocode in section 4.4.2, when and how should
the RP send the Join to S?

Thanks in advance,
Holger

---

From: Rishabh Parekh <[email-masked]>
Date: Mon, 17 Mar 2014 11:15:36 -0700

Holger,
(S,G) Join at the RP is triggered by certain actions specified in Section
4.4.2. First of all, although section 4.4.2 does not explicitly state this,
an implementation is expected to create a (S,G) state for the inner
encapsulated flow once the Register message has passed all the validity
checks.

Once the (S,G) state is created the following pseudo-code:

    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;
    }

starts the KAT timer for (S,G) which in turn would set the
JoinDesired(S,G) (Section 4.5.7) to TRUE (assuming inherited_olist !=
NULL)

 bool JoinDesired(S,G) {
         return( immediate_olist(S,G) != NULL
                 OR ( KeepaliveTimer(S,G) is running
                      AND inherited_olist(S,G) != NULL ) )
 }

JoinDesired(S,G) going to TRUE would trigger the "JoinDesired(S,G) ->
TRUE' transition in Upstream (S,G) state machine in 4.5.7 and one of
the resultant actions is '
Send Join(S,G)'

Hope that clears it up,

-Rishabh

On Mon, Mar 17, 2014 at 9:31 AM, Holger Kummert
<[email-masked]>wrote:

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

---

From: Holger Kummert <[email-masked]>
Date: Fri, 21 Mar 2014 16:46:37 +0100

Hello Rishabh,

thank you for your explanation.
I changed the implementation following your advice and now both
Register-Stop and Join messages are sent towards S.

Wouldn't it be helpful if the pseudocode section in 4.4.2  would be
extended with something like

         if ( does_not_exist(S,G) ) {
               create(S,G);
         }

just before the already existing code

         if ( SPTbit(S,G) OR
               ( SwitchToSptDesired(S,G) AND
                 ( inherited_olist(S,G) == NULL ))) { ...
?

Holger

Am 17.03.2014 19:15, schrieb Rishabh Parekh:
> Holger,
> (S,G) Join at the RP is triggered by certain actions specified in
> Section 4.4.2. First of all, although section 4.4.2 does not explicitly
> state this, an implementation is expected to create a (S,G) state for
> the inner encapsulated flow once the Register message has passed all the
> validity checks.
>
> starts the KAT timer for (S,G) which in turn would set the JoinDesired(S,G) (Section 4.5.7) to TRUE (assuming inherited_olist != NULL)
>
>   bool JoinDesired(S,G) {
> JoinDesired(S,G) going to TRUE would trigger the "JoinDesired(S,G) -> TRUE' transition in Upstream (S,G) state machine in 4.5.7 and one of the resultant actions is '
> Send Join(S,G)'
>
> Hope that clears it up,
>
> -Rishabh
>

---

From: Rishabh Parekh <[email-masked]>
Date: Sat, 22 Mar 2014 08:22:00 -0700

Holger,
IETF documents are not intended to serve as an implementation design
specification and hence omit things like state maintenance. However, you
can infer some things an implementation has to do by looking at the
psuedo-code; you just need to read between the lines in a manner of
speaking. For example, in section 4.4.2 pseudo-code, the use of SPTbit (via
SPTbit(S,G)), which is a property of (S,G) state specified in Section
4.1.4, implies that (S,G) state needs to be created if it does exists.

You also have to keep in mind that all pseudo-code mentioned in the RFC is
not meant for literal implementation. For example, typical implementations
will not directly implement the forwarding logic specified in Section 4,2
due to separation between control and data planes. However, they are
expected to implement the effective behavior described in that section. If
an RFCs were to provide direct implementation guidelines, you can imagine
the sheer enormity of the task required to cater to all the different
possible implementation environments.

Finally, you can always put a question to the WG mailing list, as you did,
when you have a doubt. Most of the time, you will get a (hopefully) helpful
response.

-Rishabh

On Fri, Mar 21, 2014 at 8:46 AM, Holger Kummert
<[email-masked]>wrote:

>> JoinDesired(S,G) (Section 4.5.7) to TRUE (assuming inherited_olist != NULL)
>>
>>   bool JoinDesired(S,G) {
>> TRUE' transition in Upstream (S,G) state machine in 4.5.7 and one of the
>> resultant actions is '
>> Send Join(S,G)'
>>
>> Hope that clears it up,
>>
>> -Rishabh
>>
>>
>