forked from Mirror/frr
pimd: send an immediate XG JP message when switching from SPT to RPT
Today we are only pruning the SPT when (S,G) upstream entry switches from Joined toNotJoined. This leaves the source still pruned along the RPT till the next periodic XG join-prune is sent to the RPF(RP). Traffic from the source will be blackholed for this duration. To prevent that we need send a new JP message to RPF(RP) immediately. Signed-off-by: Anuradha Karuppiah <anuradhak@cumulusnetworks.com>
This commit is contained in:
parent
8ff637c8c9
commit
c692bd2ad4
|
@ -338,10 +338,10 @@ void pim_jp_agg_single_upstream_send(struct pim_rpf *rpf,
|
||||||
static bool first = true;
|
static bool first = true;
|
||||||
|
|
||||||
/* skip JP upstream messages if source is directly connected */
|
/* skip JP upstream messages if source is directly connected */
|
||||||
if (!up || !rpf->source_nexthop.interface || pim_if_connected_to_source(
|
if (!up || !rpf->source_nexthop.interface ||
|
||||||
rpf->source_nexthop
|
pim_if_connected_to_source(rpf->source_nexthop.interface,
|
||||||
.interface,
|
up->sg.src) ||
|
||||||
up->sg.src))
|
if_is_loopback_or_vrf(rpf->source_nexthop.interface))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (first) {
|
if (first) {
|
||||||
|
|
|
@ -696,21 +696,47 @@ void pim_upstream_switch(struct pim_instance *pim, struct pim_upstream *up,
|
||||||
join_timer_start(up);
|
join_timer_start(up);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (old_state != new_state)
|
||||||
|
pim_upstream_update_use_rpt(up, true /*update_mroute*/);
|
||||||
} else {
|
} else {
|
||||||
|
bool old_use_rpt;
|
||||||
|
bool new_use_rpt;
|
||||||
|
bool send_xg_jp = false;
|
||||||
|
|
||||||
forward_off(up);
|
forward_off(up);
|
||||||
if (old_state == PIM_UPSTREAM_JOINED)
|
if (old_state == PIM_UPSTREAM_JOINED)
|
||||||
pim_msdp_up_join_state_changed(pim, up);
|
pim_msdp_up_join_state_changed(pim, up);
|
||||||
|
|
||||||
|
if (old_state != new_state) {
|
||||||
|
old_use_rpt =
|
||||||
|
!!PIM_UPSTREAM_FLAG_TEST_USE_RPT(up->flags);
|
||||||
|
pim_upstream_update_use_rpt(up, true /*update_mroute*/);
|
||||||
|
new_use_rpt =
|
||||||
|
!!PIM_UPSTREAM_FLAG_TEST_USE_RPT(up->flags);
|
||||||
|
if (new_use_rpt &&
|
||||||
|
(new_use_rpt != old_use_rpt) &&
|
||||||
|
up->parent)
|
||||||
|
/* we have decided to switch from the SPT back
|
||||||
|
* to the RPT which means we need to cancel
|
||||||
|
* any previously sent SGrpt prunes immediately
|
||||||
|
*/
|
||||||
|
send_xg_jp = true;
|
||||||
|
}
|
||||||
|
|
||||||
/* IHR, Trigger SGRpt on *,G IIF to prune S,G from RPT towards
|
/* IHR, Trigger SGRpt on *,G IIF to prune S,G from RPT towards
|
||||||
RP.
|
RP.
|
||||||
If I am RP for G then send S,G prune to its IIF. */
|
If I am RP for G then send S,G prune to its IIF. */
|
||||||
if (pim_upstream_is_sg_rpt(up) && up->parent
|
if (pim_upstream_is_sg_rpt(up) && up->parent &&
|
||||||
&& !I_am_RP(pim, up->sg.grp)) {
|
!I_am_RP(pim, up->sg.grp))
|
||||||
|
send_xg_jp = true;
|
||||||
|
else
|
||||||
|
pim_jp_agg_single_upstream_send(&up->rpf, up,
|
||||||
|
0 /* prune */);
|
||||||
|
|
||||||
|
if (send_xg_jp) {
|
||||||
if (PIM_DEBUG_PIM_TRACE_DETAIL)
|
if (PIM_DEBUG_PIM_TRACE_DETAIL)
|
||||||
zlog_debug(
|
zlog_debug(
|
||||||
"%s: *,G IIF %s S,G IIF %s ",
|
"re-join RPT; *,G IIF %s S,G IIF %s ",
|
||||||
__PRETTY_FUNCTION__,
|
|
||||||
up->parent->rpf.source_nexthop.interface ?
|
up->parent->rpf.source_nexthop.interface ?
|
||||||
up->parent->rpf.source_nexthop.interface->name
|
up->parent->rpf.source_nexthop.interface->name
|
||||||
: "Unknown",
|
: "Unknown",
|
||||||
|
@ -720,14 +746,9 @@ void pim_upstream_switch(struct pim_instance *pim, struct pim_upstream *up,
|
||||||
pim_jp_agg_single_upstream_send(&up->parent->rpf,
|
pim_jp_agg_single_upstream_send(&up->parent->rpf,
|
||||||
up->parent,
|
up->parent,
|
||||||
1 /* (W,G) Join */);
|
1 /* (W,G) Join */);
|
||||||
} else
|
}
|
||||||
pim_jp_agg_single_upstream_send(&up->rpf, up,
|
|
||||||
0 /* prune */);
|
|
||||||
join_timer_stop(up);
|
join_timer_stop(up);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (old_state != new_state)
|
|
||||||
pim_upstream_update_use_rpt(up, true /*update_mroute*/);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int pim_upstream_compare(void *arg1, void *arg2)
|
int pim_upstream_compare(void *arg1, void *arg2)
|
||||||
|
|
Loading…
Reference in a new issue