summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnuradha Karuppiah <anuradhak@cumulusnetworks.com>2019-11-15 12:01:46 -0800
committerAnuradha Karuppiah <anuradhak@cumulusnetworks.com>2019-11-15 14:16:08 -0800
commitc692bd2ad42e941d0d63a149daaed1a331d47cd0 (patch)
tree883a8a04947d3aa61d5adb2519dd7d197e4e6ab9
parent8ff637c8c99357afe0df174863160fbf486b491b (diff)
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>
-rw-r--r--pimd/pim_jp_agg.c8
-rw-r--r--pimd/pim_upstream.c41
2 files changed, 35 insertions, 14 deletions
diff --git a/pimd/pim_jp_agg.c b/pimd/pim_jp_agg.c
index e1473bfe3b..5f9e166810 100644
--- a/pimd/pim_jp_agg.c
+++ b/pimd/pim_jp_agg.c
@@ -338,10 +338,10 @@ void pim_jp_agg_single_upstream_send(struct pim_rpf *rpf,
static bool first = true;
/* skip JP upstream messages if source is directly connected */
- if (!up || !rpf->source_nexthop.interface || pim_if_connected_to_source(
- rpf->source_nexthop
- .interface,
- up->sg.src))
+ if (!up || !rpf->source_nexthop.interface ||
+ pim_if_connected_to_source(rpf->source_nexthop.interface,
+ up->sg.src) ||
+ if_is_loopback_or_vrf(rpf->source_nexthop.interface))
return;
if (first) {
diff --git a/pimd/pim_upstream.c b/pimd/pim_upstream.c
index 53da58e8fe..4d0a63b915 100644
--- a/pimd/pim_upstream.c
+++ b/pimd/pim_upstream.c
@@ -696,21 +696,47 @@ void pim_upstream_switch(struct pim_instance *pim, struct pim_upstream *up,
join_timer_start(up);
}
}
+ if (old_state != new_state)
+ pim_upstream_update_use_rpt(up, true /*update_mroute*/);
} else {
+ bool old_use_rpt;
+ bool new_use_rpt;
+ bool send_xg_jp = false;
forward_off(up);
if (old_state == PIM_UPSTREAM_JOINED)
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
RP.
If I am RP for G then send S,G prune to its IIF. */
- if (pim_upstream_is_sg_rpt(up) && up->parent
- && !I_am_RP(pim, up->sg.grp)) {
+ if (pim_upstream_is_sg_rpt(up) && up->parent &&
+ !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)
zlog_debug(
- "%s: *,G IIF %s S,G IIF %s ",
- __PRETTY_FUNCTION__,
+ "re-join RPT; *,G IIF %s S,G IIF %s ",
up->parent->rpf.source_nexthop.interface ?
up->parent->rpf.source_nexthop.interface->name
: "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,
up->parent,
1 /* (W,G) Join */);
- } else
- pim_jp_agg_single_upstream_send(&up->rpf, up,
- 0 /* prune */);
+ }
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)