pimd: Add Handler for Receive (*,G) join for (S,G,rpt)

According to Figure 5( Downstream per-interface (S,G,rpt)
state when we receive a (*,G) we need to move (S,G,rpt)
children of the (*,G) into different states.  This
implements that.

Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
This commit is contained in:
Donald Sharp 2016-11-08 15:26:48 -05:00
parent 53e39e140d
commit 220d8a49e6
3 changed files with 69 additions and 8 deletions

View File

@ -725,19 +725,21 @@ void pim_ifchannel_join_add(struct interface *ifp,
THREAD_OFF(ch->t_ifjoin_expiry_timer);
break;
case PIM_IFJOIN_PRUNE:
zlog_debug ("PIM_IFJOIN_PRUNE: NOT PROGRAMMED YET");
if (source_flags & PIM_ENCODE_RPT_BIT)
pim_ifchannel_ifjoin_switch(__PRETTY_FUNCTION__, ch, PIM_IFJOIN_NOINFO);
break;
case PIM_IFJOIN_PRUNE_PENDING:
zassert(!ch->t_ifjoin_expiry_timer);
zassert(ch->t_ifjoin_prune_pending_timer);
THREAD_OFF(ch->t_ifjoin_prune_pending_timer);
pim_ifchannel_ifjoin_switch(__PRETTY_FUNCTION__, ch, PIM_IFJOIN_JOIN);
if (source_flags & PIM_ENCODE_RPT_BIT)
pim_ifchannel_ifjoin_switch(__PRETTY_FUNCTION__, ch, PIM_IFJOIN_NOINFO);
else
{
THREAD_OFF(ch->t_ifjoin_prune_pending_timer);
pim_ifchannel_ifjoin_switch(__PRETTY_FUNCTION__, ch, PIM_IFJOIN_JOIN);
}
break;
case PIM_IFJOIN_PRUNE_TMP:
zlog_debug ("PIM_IFJOIN_PRUNE_TMP: Not Programmed yet");
break;
case PIM_IFJOIN_PRUNE_PENDING_TMP:
zlog_debug ("PIM_IFJOIN_PRUNE_PENDING_TMP: Not Programmed yet");
break;
}
@ -1072,3 +1074,51 @@ pim_ifchannel_scan_forward_start (struct interface *new_ifp)
}
}
}
/*
* Downstream per-interface (S,G,rpt) state machine
* states that we need to move (S,G,rpt) items
* into different states at the start of the
* reception of a *,G join as well, when
* we get End of Message
*/
void
pim_ifchannel_set_star_g_join_state (struct pim_ifchannel *ch, int eom)
{
struct pim_ifchannel *child;
struct listnode *ch_node;
if (PIM_DEBUG_PIM_TRACE)
zlog_debug ("%s: %s %s eom: %d", __PRETTY_FUNCTION__,
pim_ifchannel_ifjoin_name(ch->ifjoin_state),
pim_str_sg_dump(&ch->sg), eom);
if (!ch->sources)
return;
for (ALL_LIST_ELEMENTS_RO (ch->sources, ch_node, child))
{
if (!PIM_IF_FLAG_TEST_S_G_RPT(child->flags))
continue;
switch (child->ifjoin_state)
{
case PIM_IFJOIN_NOINFO:
case PIM_IFJOIN_JOIN:
break;
case PIM_IFJOIN_PRUNE:
if (!eom)
child->ifjoin_state = PIM_IFJOIN_PRUNE_TMP;
break;
case PIM_IFJOIN_PRUNE_PENDING:
if (!eom)
child->ifjoin_state = PIM_IFJOIN_PRUNE_PENDING_TMP;
break;
case PIM_IFJOIN_PRUNE_TMP:
case PIM_IFJOIN_PRUNE_PENDING_TMP:
if (eom)
child->ifjoin_state = PIM_IFJOIN_NOINFO;
break;
}
}
}

View File

@ -150,6 +150,7 @@ void pim_ifchannel_update_my_assert_metric(struct pim_ifchannel *ch);
void pim_ifchannel_update_assert_tracking_desired(struct pim_ifchannel *ch);
void pim_ifchannel_scan_forward_start (struct interface *new_ifp);
void pim_ifchannel_set_star_g_join_state (struct pim_ifchannel *ch, int eom);
int pim_ifchannel_compare (struct pim_ifchannel *ch1, struct pim_ifchannel *ch2);
#endif /* PIM_IFCHANNEL_H */

View File

@ -292,6 +292,7 @@ int pim_joinprune_recv(struct interface *ifp,
uint16_t msg_num_joined_sources;
uint16_t msg_num_pruned_sources;
int source;
struct pim_ifchannel *ch = NULL;
memset (&sg, 0, sizeof (struct prefix_sg));
addr_offset = pim_parse_addr_group (&sg,
@ -347,6 +348,13 @@ int pim_joinprune_recv(struct interface *ifp,
msg_upstream_addr.u.prefix4,
&sg,
msg_source_flags);
if (sg.src.s_addr == INADDR_ANY)
{
ch = pim_ifchannel_find (ifp, &sg);
if (ch)
pim_ifchannel_set_star_g_join_state (ch, 0);
}
}
/* Scan pruned sources */
@ -365,7 +373,9 @@ int pim_joinprune_recv(struct interface *ifp,
&sg,
msg_source_flags);
}
if (ch)
pim_ifchannel_set_star_g_join_state (ch, 1);
ch = NULL;
} /* scan groups */
return 0;