From b5183fd1ae63960f83868f0a25d6b82beaf7da22 Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Wed, 7 Dec 2016 15:07:55 -0500 Subject: [PATCH] pimd: Tell ourselves to rescan when we discover an issue When we have network churn and we have an inherited_olist notice when we may have a situation where we need to recalculate the inherited_olist. Signed-off-by: Donald Sharp --- pimd/pim_oil.c | 10 +++++++--- pimd/pim_oil.h | 1 + pimd/pim_upstream.c | 42 +++++++++++++++++++++++++----------------- pimd/pim_upstream.h | 1 + pimd/pim_zebra.c | 16 +++++++++++++--- 5 files changed, 47 insertions(+), 23 deletions(-) diff --git a/pimd/pim_oil.c b/pimd/pim_oil.c index 88ace45ed..44c832434 100644 --- a/pimd/pim_oil.c +++ b/pimd/pim_oil.c @@ -177,9 +177,12 @@ struct channel_oil *pim_channel_oil_add(struct prefix_sg *sg, c_oil = pim_find_channel_oil(sg); if (c_oil) { if (c_oil->oil.mfcc_parent != input_vif_index) - if (PIM_DEBUG_MROUTE) - zlog_debug ("%s: Existing channel oil %s points to %d, modifying to point at %d", - __PRETTY_FUNCTION__, pim_str_sg_dump(sg), c_oil->oil.mfcc_parent, input_vif_index); + { + c_oil->oil_inherited_rescan = 1; + if (PIM_DEBUG_MROUTE) + zlog_debug ("%s: Existing channel oil %s points to %d, modifying to point at %d", + __PRETTY_FUNCTION__, pim_str_sg_dump(sg), c_oil->oil.mfcc_parent, input_vif_index); + } c_oil->oil.mfcc_parent = input_vif_index; ++c_oil->oil_ref_count; return c_oil; @@ -315,6 +318,7 @@ int pim_channel_add_oif(struct channel_oil *channel_oil, TODO T22. */ if (pim_ifp->mroute_vif_index == channel_oil->oil.mfcc_parent) { + channel_oil->oil_inherited_rescan = 1; if (PIM_DEBUG_MROUTE) { char group_str[INET_ADDRSTRLEN]; diff --git a/pimd/pim_oil.h b/pimd/pim_oil.h index 939ef4b3f..64107bfe8 100644 --- a/pimd/pim_oil.h +++ b/pimd/pim_oil.h @@ -71,6 +71,7 @@ struct channel_counts struct channel_oil { struct mfcctl oil; int installed; + int oil_inherited_rescan; int oil_size; int oil_ref_count; time_t oif_creation[MAXVIFS]; diff --git a/pimd/pim_upstream.c b/pimd/pim_upstream.c index 14508ad18..32bc5f574 100644 --- a/pimd/pim_upstream.c +++ b/pimd/pim_upstream.c @@ -1268,24 +1268,8 @@ pim_upstream_start_register_stop_timer (struct pim_upstream *up, int null_regist up, time); } -/* - * For a given upstream, determine the inherited_olist - * and apply it. - * - * inherited_olist(S,G,rpt) = - * ( joins(*,*,RP(G)) (+) joins(*,G) (-) prunes(S,G,rpt) ) - * (+) ( pim_include(*,G) (-) pim_exclude(S,G)) - * (-) ( lost_assert(*,G) (+) lost_assert(S,G,rpt) ) - * - * inherited_olist(S,G) = - * inherited_olist(S,G,rpt) (+) - * joins(S,G) (+) pim_include(S,G) (-) lost_assert(S,G) - * - * return 1 if there are any output interfaces - * return 0 if there are not any output interfaces - */ int -pim_upstream_inherited_olist (struct pim_upstream *up) +pim_upstream_inherited_olist_decide (struct pim_upstream *up) { struct pim_interface *pim_ifp; struct listnode *chnextnode; @@ -1310,6 +1294,30 @@ pim_upstream_inherited_olist (struct pim_upstream *up) } } + return output_intf; +} + +/* + * For a given upstream, determine the inherited_olist + * and apply it. + * + * inherited_olist(S,G,rpt) = + * ( joins(*,*,RP(G)) (+) joins(*,G) (-) prunes(S,G,rpt) ) + * (+) ( pim_include(*,G) (-) pim_exclude(S,G)) + * (-) ( lost_assert(*,G) (+) lost_assert(S,G,rpt) ) + * + * inherited_olist(S,G) = + * inherited_olist(S,G,rpt) (+) + * joins(S,G) (+) pim_include(S,G) (-) lost_assert(S,G) + * + * return 1 if there are any output interfaces + * return 0 if there are not any output interfaces + */ +int +pim_upstream_inherited_olist (struct pim_upstream *up) +{ + int output_intf = pim_upstream_inherited_olist_decide (up); + /* * If we have output_intf switch state to Join and work like normal * If we don't have an output_intf that means we are probably a diff --git a/pimd/pim_upstream.h b/pimd/pim_upstream.h index cc4860a21..026cd7b9d 100644 --- a/pimd/pim_upstream.h +++ b/pimd/pim_upstream.h @@ -162,6 +162,7 @@ void pim_upstream_switch (struct pim_upstream *up, enum pim_upstream_state new_s const char *pim_upstream_state2str (enum pim_upstream_state join_state); +int pim_upstream_inherited_olist_decide (struct pim_upstream *up); int pim_upstream_inherited_olist (struct pim_upstream *up); int pim_upstream_empty_inherited_olist (struct pim_upstream *up); diff --git a/pimd/pim_zebra.c b/pimd/pim_zebra.c index cfce8909d..9d8c07cad 100644 --- a/pimd/pim_zebra.c +++ b/pimd/pim_zebra.c @@ -371,15 +371,25 @@ static void scan_upstream_rpf_cache() continue; if (rpf_result == PIM_RPF_CHANGED) { - + + /* + * We have detected a case where we might need to rescan + * the inherited o_list so do it. + */ + if (up->channel_oil->oil_inherited_rescan) + { + pim_upstream_inherited_olist_decide (up); + up->channel_oil->oil_inherited_rescan = 0; + } + if (up->join_state == PIM_UPSTREAM_JOINED) { /* * If we come up real fast we can be here * where the mroute has not been installed * so install it. */ - if (up->channel_oil && !up->channel_oil->installed) - pim_mroute_add (up->channel_oil, __PRETTY_FUNCTION__); + if (!up->channel_oil->installed) + pim_mroute_add (up->channel_oil, __PRETTY_FUNCTION__); /* RFC 4601: 4.5.7. Sending (S,G) Join/Prune Messages -- 2.39.2