From: Donald Sharp Date: Tue, 8 Nov 2016 20:26:48 +0000 (-0500) Subject: pimd: Add Handler for Receive (*,G) join for (S,G,rpt) X-Git-Tag: frr-3.0-branchpoint~64^2~10^2~114 X-Git-Url: https://git.puffer.fish/?a=commitdiff_plain;h=220d8a49e6fcadae3dbb7f60cf88edca819b8d65;p=mirror%2Ffrr.git 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 --- diff --git a/pimd/pim_ifchannel.c b/pimd/pim_ifchannel.c index 5838bfa63e..3be88553d0 100644 --- a/pimd/pim_ifchannel.c +++ b/pimd/pim_ifchannel.c @@ -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; + + } + } +} diff --git a/pimd/pim_ifchannel.h b/pimd/pim_ifchannel.h index 908d27fd68..b640cfd4df 100644 --- a/pimd/pim_ifchannel.h +++ b/pimd/pim_ifchannel.h @@ -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 */ diff --git a/pimd/pim_join.c b/pimd/pim_join.c index 53c91ab4af..7f5c46004a 100644 --- a/pimd/pim_join.c +++ b/pimd/pim_join.c @@ -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;