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 <sharpd@cumulusnetworks.com>
This commit is contained in:
Donald Sharp 2016-12-07 15:07:55 -05:00
parent be5770d770
commit b5183fd1ae
5 changed files with 47 additions and 23 deletions

View File

@ -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];

View File

@ -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];

View File

@ -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

View File

@ -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);

View File

@ -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