diff options
-rw-r--r-- | pimd/pim_mroute.c | 33 | ||||
-rw-r--r-- | pimd/pim_upstream.c | 11 |
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__); } } } |