summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--pimd/pim_mroute.c33
-rw-r--r--pimd/pim_upstream.c11
2 files changed, 42 insertions, 2 deletions
diff --git a/pimd/pim_mroute.c b/pimd/pim_mroute.c
index 6fa95d4b6..a2e6aabcf 100644
--- a/pimd/pim_mroute.c
+++ b/pimd/pim_mroute.c
@@ -1015,12 +1015,39 @@ static int pim_upstream_mroute_update(struct channel_oil *c_oil,
return pim_mroute_add(c_oil, name);
}
+/* IIF associated with SGrpt entries are re-evaluated when the parent
+ * (*,G) entries IIF changes
+ */
+static void pim_upstream_all_sources_iif_update(struct pim_upstream *up)
+{
+ struct listnode *listnode;
+ struct pim_upstream *child;
+
+ for (ALL_LIST_ELEMENTS_RO(up->sources, listnode,
+ child)) {
+ if (PIM_UPSTREAM_FLAG_TEST_USE_RPT(child->flags))
+ pim_upstream_mroute_iif_update(child->channel_oil,
+ __func__);
+ }
+}
+
/* In the case of "PIM state machine" added mroutes an upstream entry
* must be present to decide on the SPT-forwarding vs. RPT-forwarding.
*/
int pim_upstream_mroute_add(struct channel_oil *c_oil, const char *name)
{
- c_oil->oil.mfcc_parent = pim_upstream_get_mroute_iif(c_oil, name);
+ vifi_t iif;
+
+ iif = pim_upstream_get_mroute_iif(c_oil, name);
+
+ if (c_oil->oil.mfcc_parent != iif) {
+ c_oil->oil.mfcc_parent = iif;
+ if (c_oil->oil.mfcc_origin.s_addr == INADDR_ANY &&
+ c_oil->up)
+ pim_upstream_all_sources_iif_update(c_oil->up);
+ } else {
+ c_oil->oil.mfcc_parent = iif;
+ }
return pim_upstream_mroute_update(c_oil, name);
}
@@ -1040,6 +1067,10 @@ int pim_upstream_mroute_iif_update(struct channel_oil *c_oil, const char *name)
}
c_oil->oil.mfcc_parent = iif;
+ if (c_oil->oil.mfcc_origin.s_addr == INADDR_ANY &&
+ c_oil->up)
+ pim_upstream_all_sources_iif_update(c_oil->up);
+
if (PIM_DEBUG_MROUTE_DETAIL)
zlog_debug("%s(%s) %s mroute iif update %d",
__func__, name,
diff --git a/pimd/pim_upstream.c b/pimd/pim_upstream.c
index ee9fece51..316209c55 100644
--- a/pimd/pim_upstream.c
+++ b/pimd/pim_upstream.c
@@ -78,8 +78,13 @@ static void pim_upstream_remove_children(struct pim_instance *pim,
child = pim_upstream_del(pim, child,
__PRETTY_FUNCTION__);
}
- if (child)
+ if (child) {
child->parent = NULL;
+ if (PIM_UPSTREAM_FLAG_TEST_USE_RPT(child->flags))
+ pim_upstream_mroute_iif_update(
+ child->channel_oil,
+ __func__);
+ }
}
list_delete(&up->sources);
}
@@ -109,6 +114,10 @@ static void pim_upstream_find_new_children(struct pim_instance *pim,
&& (child != up)) {
child->parent = up;
listnode_add_sort(up->sources, child);
+ if (PIM_UPSTREAM_FLAG_TEST_USE_RPT(child->flags))
+ pim_upstream_mroute_iif_update(
+ child->channel_oil,
+ __func__);
}
}
}