From 80286aa564601dda7430ea8c96b2f9fd9867ee0b Mon Sep 17 00:00:00 2001 From: Stephen Worley Date: Wed, 23 Oct 2019 16:49:07 -0400 Subject: [PATCH] zebra: Re-work zebra_nhg_*_valid APIs Re-work the validity setting and checking APIs for nhg_hash_entry's to make them clearer. Further, they were originally only beings set on ifdown and install. Extended their use into releasing entries and to account for setting the validity of a recursive dependent. Signed-off-by: Stephen Worley --- zebra/interface.c | 45 +++++++++++------------ zebra/zebra_nhg.c | 92 +++++++++++++++++++++++++++++------------------ zebra/zebra_nhg.h | 2 +- 3 files changed, 82 insertions(+), 57 deletions(-) diff --git a/zebra/interface.c b/zebra/interface.c index 76d5d2a2463a..daa93e36d1c4 100644 --- a/zebra/interface.c +++ b/zebra/interface.c @@ -189,17 +189,31 @@ static int if_zebra_new_hook(struct interface *ifp) return 0; } -static void if_nhg_dependents_release(struct interface *ifp) +static void if_nhg_dependents_check_valid(struct nhg_hash_entry *nhe) { - if (!if_nhg_dependents_is_empty(ifp)) { - struct nhg_connected *rb_node_dep = NULL; - struct zebra_if *zif = (struct zebra_if *)ifp->info; + zebra_nhg_check_valid(nhe); + if (!CHECK_FLAG(nhe->flags, NEXTHOP_GROUP_VALID)) + /* Assuming uninstalled as well here */ + UNSET_FLAG(nhe->flags, NEXTHOP_GROUP_INSTALLED); +} - frr_each(nhg_connected_tree, &zif->nhg_dependents, - rb_node_dep) { - rb_node_dep->nhe->ifp = NULL; - zebra_nhg_set_invalid(rb_node_dep->nhe); - } +static void if_down_nhg_dependents(const struct interface *ifp) +{ + struct nhg_connected *rb_node_dep = NULL; + struct zebra_if *zif = (struct zebra_if *)ifp->info; + + frr_each(nhg_connected_tree, &zif->nhg_dependents, rb_node_dep) + if_nhg_dependents_check_valid(rb_node_dep->nhe); +} + +static void if_nhg_dependents_release(const struct interface *ifp) +{ + struct nhg_connected *rb_node_dep = NULL; + struct zebra_if *zif = (struct zebra_if *)ifp->info; + + frr_each(nhg_connected_tree, &zif->nhg_dependents, rb_node_dep) { + rb_node_dep->nhe->ifp = NULL; /* Null it out */ + if_nhg_dependents_check_valid(rb_node_dep->nhe); } } @@ -998,19 +1012,6 @@ bool if_nhg_dependents_is_empty(const struct interface *ifp) return false; } -static void if_down_nhg_dependents(const struct interface *ifp) -{ - if (!if_nhg_dependents_is_empty(ifp)) { - struct nhg_connected *rb_node_dep = NULL; - struct zebra_if *zif = (struct zebra_if *)ifp->info; - - frr_each(nhg_connected_tree, &zif->nhg_dependents, - rb_node_dep) { - zebra_nhg_set_invalid(rb_node_dep->nhe); - } - } -} - /* Interface is up. */ void if_up(struct interface *ifp) { diff --git a/zebra/zebra_nhg.c b/zebra/zebra_nhg.c index 418c1102bdb0..3ec764c5d390 100644 --- a/zebra/zebra_nhg.c +++ b/zebra/zebra_nhg.c @@ -246,13 +246,12 @@ void zebra_nhg_dependents_init(struct nhg_hash_entry *nhe) /* Release this nhe from anything depending on it */ static void zebra_nhg_dependents_release(struct nhg_hash_entry *nhe) { - if (!zebra_nhg_dependents_is_empty(nhe)) { - struct nhg_connected *rb_node_dep = NULL; + struct nhg_connected *rb_node_dep = NULL; - frr_each_safe(nhg_connected_tree, &nhe->nhg_dependents, - rb_node_dep) { - zebra_nhg_depends_del(rb_node_dep->nhe, nhe); - } + frr_each_safe(nhg_connected_tree, &nhe->nhg_dependents, rb_node_dep) { + zebra_nhg_depends_del(rb_node_dep->nhe, nhe); + /* recheck validity of the dependent */ + zebra_nhg_check_valid(rb_node_dep->nhe); } } @@ -687,6 +686,48 @@ static void zebra_nhg_set_unhashable(struct nhg_hash_entry *nhe) nhe->id); } +static void zebra_nhg_set_valid(struct nhg_hash_entry *nhe) +{ + struct nhg_connected *rb_node_dep; + + SET_FLAG(nhe->flags, NEXTHOP_GROUP_VALID); + + frr_each(nhg_connected_tree, &nhe->nhg_dependents, rb_node_dep) + zebra_nhg_set_valid(rb_node_dep->nhe); +} + +static void zebra_nhg_set_invalid(struct nhg_hash_entry *nhe) +{ + struct nhg_connected *rb_node_dep; + + UNSET_FLAG(nhe->flags, NEXTHOP_GROUP_VALID); + + /* Update validity of nexthops depending on it */ + frr_each(nhg_connected_tree, &nhe->nhg_dependents, rb_node_dep) + zebra_nhg_check_valid(rb_node_dep->nhe); +} + +void zebra_nhg_check_valid(struct nhg_hash_entry *nhe) +{ + struct nhg_connected *rb_node_dep = NULL; + bool valid = false; + + /* If anthing else in the group is valid, the group is valid */ + frr_each(nhg_connected_tree, &nhe->nhg_depends, rb_node_dep) { + if (CHECK_FLAG(rb_node_dep->nhe->flags, NEXTHOP_GROUP_VALID)) { + valid = true; + goto done; + } + } + +done: + if (valid) + zebra_nhg_set_valid(nhe); + else + zebra_nhg_set_invalid(nhe); +} + + static void zebra_nhg_release(struct nhg_hash_entry *nhe) { /* Remove it from any lists it may be on */ @@ -711,6 +752,15 @@ static void zebra_nhg_handle_uninstall(struct nhg_hash_entry *nhe) zebra_nhg_free(nhe); } +static void zebra_nhg_handle_install(struct nhg_hash_entry *nhe) +{ + /* Update validity of groups depending on it */ + struct nhg_connected *rb_node_dep; + + frr_each_safe(nhg_connected_tree, &nhe->nhg_dependents, rb_node_dep) + zebra_nhg_set_valid(rb_node_dep->nhe); +} + /* * The kernel/other program has changed the state of a nexthop object we are * using. @@ -1083,34 +1133,6 @@ void zebra_nhg_increment_ref(struct nhg_hash_entry *nhe) nhg_connected_tree_increment_ref(&nhe->nhg_depends); } -void zebra_nhg_set_invalid(struct nhg_hash_entry *nhe) -{ - if (!zebra_nhg_depends_is_empty(nhe) - && !CHECK_FLAG(nhe->flags, NEXTHOP_GROUP_RECURSIVE)) { - struct nhg_connected *rb_node_dep = NULL; - - /* If anthing else in the group is valid, the group is valid */ - frr_each(nhg_connected_tree, &nhe->nhg_depends, rb_node_dep) { - if (CHECK_FLAG(rb_node_dep->nhe->flags, - NEXTHOP_GROUP_VALID)) - return; - } - } - - UNSET_FLAG(nhe->flags, NEXTHOP_GROUP_VALID); - /* Assuming uninstalled as well here */ - UNSET_FLAG(nhe->flags, NEXTHOP_GROUP_INSTALLED); - - if (!zebra_nhg_dependents_is_empty(nhe)) { - struct nhg_connected *rb_node_dep = NULL; - - frr_each(nhg_connected_tree, &nhe->nhg_dependents, - rb_node_dep) { - zebra_nhg_set_invalid(rb_node_dep->nhe); - } - } -} - void zebra_nhg_set_if(struct nhg_hash_entry *nhe, struct interface *ifp) { nhe->ifp = ifp; @@ -1799,6 +1821,7 @@ void zebra_nhg_install_kernel(struct nhg_hash_entry *nhe) break; case ZEBRA_DPLANE_REQUEST_SUCCESS: SET_FLAG(nhe->flags, NEXTHOP_GROUP_INSTALLED); + zebra_nhg_handle_install(nhe); break; } } @@ -1870,6 +1893,7 @@ void zebra_nhg_dplane_result(struct zebra_dplane_ctx *ctx) if (status == ZEBRA_DPLANE_REQUEST_SUCCESS) { SET_FLAG(nhe->flags, NEXTHOP_GROUP_VALID); SET_FLAG(nhe->flags, NEXTHOP_GROUP_INSTALLED); + zebra_nhg_handle_install(nhe); } else flog_err( EC_ZEBRA_DP_INSTALL_FAIL, diff --git a/zebra/zebra_nhg.h b/zebra/zebra_nhg.h index 82f54a3a63f3..e636c0f2d2ea 100644 --- a/zebra/zebra_nhg.h +++ b/zebra/zebra_nhg.h @@ -249,7 +249,7 @@ void zebra_nhg_free(void *arg); void zebra_nhg_decrement_ref(struct nhg_hash_entry *nhe); void zebra_nhg_increment_ref(struct nhg_hash_entry *nhe); -void zebra_nhg_set_invalid(struct nhg_hash_entry *nhe); +void zebra_nhg_check_valid(struct nhg_hash_entry *nhe); void zebra_nhg_set_if(struct nhg_hash_entry *nhe, struct interface *ifp); extern int nexthop_active_update(struct route_node *rn, struct route_entry *re);