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 <sworley@cumulusnetworks.com>
This commit is contained in:
Stephen Worley 2019-10-23 16:49:07 -04:00
parent e1292378e2
commit 80286aa564
3 changed files with 82 additions and 57 deletions

View File

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

View File

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

View File

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