mirror of
https://git.proxmox.com/git/mirror_frr
synced 2026-01-27 22:48:19 +00:00
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:
parent
53e39e140d
commit
220d8a49e6
@ -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;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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 */
|
||||
|
||||
@ -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;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user