pimd: Modify the Prune Pending Timer Pop to not assert

So there exist conditions where we can start the Prune
Pending Timer and receive other packets that cause
us to not stop the pending timer.  This was
due to a missread of the state machine.

Additionally when the prune pending timer pops and
we are not in prune pending state, note the fact
and move on with our life instead of crashing and burning

Ticket: CM-13851
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
Reviewed-by:
This commit is contained in:
Donald Sharp 2016-12-01 20:32:03 -05:00
parent 36e466fe98
commit 1e3a513213

View File

@ -511,19 +511,26 @@ static int on_ifjoin_prune_pending_timer(struct thread *t)
ch->t_ifjoin_prune_pending_timer = NULL; ch->t_ifjoin_prune_pending_timer = NULL;
zassert(ch->ifjoin_state == PIM_IFJOIN_PRUNE_PENDING); if (ch->ifjoin_state == PIM_IFJOIN_PRUNE_PENDING)
{
/* Send PruneEcho(S,G) ? */
ifp = ch->interface;
pim_ifp = ifp->info;
send_prune_echo = (listcount(pim_ifp->pim_neighbor_list) > 1);
/* Send PruneEcho(S,G) ? */ ifjoin_to_noinfo(ch);
ifp = ch->interface; /* from here ch may have been deleted */
pim_ifp = ifp->info;
send_prune_echo = (listcount(pim_ifp->pim_neighbor_list) > 1);
ifjoin_to_noinfo(ch); if (send_prune_echo)
/* from here ch may have been deleted */ pim_joinprune_send (ifp, pim_ifp->primary_address,
ch->upstream, 0);
if (send_prune_echo) }
pim_joinprune_send (ifp, pim_ifp->primary_address, else
ch->upstream, 0); {
zlog_warn("%s: IFCHANNEL%s Prune Pending Timer Popped while in %s state",
__PRETTY_FUNCTION__, pim_str_sg_dump (&ch->sg),
pim_ifchannel_ifjoin_name (ch->ifjoin_state));
}
return 0; return 0;
} }
@ -724,13 +731,14 @@ void pim_ifchannel_join_add(struct interface *ifp,
pim_ifchannel_ifjoin_switch(__PRETTY_FUNCTION__, ch, PIM_IFJOIN_NOINFO); pim_ifchannel_ifjoin_switch(__PRETTY_FUNCTION__, ch, PIM_IFJOIN_NOINFO);
break; break;
case PIM_IFJOIN_PRUNE_PENDING: case PIM_IFJOIN_PRUNE_PENDING:
THREAD_OFF(ch->t_ifjoin_prune_pending_timer);
if (source_flags & PIM_ENCODE_RPT_BIT) 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); THREAD_OFF(ch->t_ifjoin_expiry_timer);
pim_ifchannel_ifjoin_switch(__PRETTY_FUNCTION__, ch, PIM_IFJOIN_JOIN); pim_ifchannel_ifjoin_switch(__PRETTY_FUNCTION__, ch, PIM_IFJOIN_NOINFO);
} }
else
pim_ifchannel_ifjoin_switch(__PRETTY_FUNCTION__, ch, PIM_IFJOIN_JOIN);
break; break;
case PIM_IFJOIN_PRUNE_TMP: case PIM_IFJOIN_PRUNE_TMP:
break; break;