pimd: Only send triggered response after all of *,G message is read

pim was sending a triggered response on every S,G RPT prune information
read.  Suppose we had this in a *,G message:

*,G
  S1, G RPT Prune
  S2, G RPT Prune

We would send two triggered *,G messages upstream.  This leads to over
processing and quickly changing state if S1 or S2 were in different
states.

Modify the code to send just one Triggered *,G upstream after looking
at all S,G state for a *,G.

Ticket: CM-24531
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
This commit is contained in:
Donald Sharp 2019-04-08 18:02:45 -04:00
parent c8d8450442
commit ca6cb21b60

View File

@ -1330,10 +1330,12 @@ void pim_ifchannel_scan_forward_start(struct interface *new_ifp)
void pim_ifchannel_set_star_g_join_state(struct pim_ifchannel *ch, int eom, void pim_ifchannel_set_star_g_join_state(struct pim_ifchannel *ch, int eom,
uint8_t join) uint8_t join)
{ {
bool send_upstream_starg = false;
struct pim_ifchannel *child; struct pim_ifchannel *child;
struct listnode *ch_node, *nch_node; struct listnode *ch_node, *nch_node;
struct pim_instance *pim = struct pim_instance *pim =
((struct pim_interface *)ch->interface->info)->pim; ((struct pim_interface *)ch->interface->info)->pim;
struct pim_upstream *starup = ch->upstream;
if (PIM_DEBUG_PIM_TRACE) if (PIM_DEBUG_PIM_TRACE)
zlog_debug( zlog_debug(
@ -1368,7 +1370,6 @@ void pim_ifchannel_set_star_g_join_state(struct pim_ifchannel *ch, int eom,
if (child->ifjoin_state == PIM_IFJOIN_PRUNE_PENDING_TMP) if (child->ifjoin_state == PIM_IFJOIN_PRUNE_PENDING_TMP)
THREAD_OFF(child->t_ifjoin_prune_pending_timer); THREAD_OFF(child->t_ifjoin_prune_pending_timer);
THREAD_OFF(child->t_ifjoin_expiry_timer); THREAD_OFF(child->t_ifjoin_expiry_timer);
struct pim_upstream *parent = child->upstream->parent;
PIM_IF_FLAG_UNSET_S_G_RPT(child->flags); PIM_IF_FLAG_UNSET_S_G_RPT(child->flags);
child->ifjoin_state = PIM_IFJOIN_NOINFO; child->ifjoin_state = PIM_IFJOIN_NOINFO;
@ -1383,14 +1384,15 @@ void pim_ifchannel_set_star_g_join_state(struct pim_ifchannel *ch, int eom,
&child->upstream->rpf, child->upstream, &child->upstream->rpf, child->upstream,
true); true);
} }
if (parent) send_upstream_starg = true;
pim_jp_agg_single_upstream_send(&parent->rpf,
parent, true);
delete_on_noinfo(child); delete_on_noinfo(child);
break; break;
} }
} }
if (send_upstream_starg)
pim_jp_agg_single_upstream_send(&starup->rpf, starup, true);
} }
unsigned int pim_ifchannel_hash_key(void *arg) unsigned int pim_ifchannel_hash_key(void *arg)