if (CHECK_FLAG(nh->flags, NEXTHOP_FLAG_ACTIVE))
SET_FLAG(newnhe->flags, NEXTHOP_GROUP_VALID);
- if (nh->next == NULL) {
+ if (nh->next == NULL && newnhe->id < zclient_get_nhg_lower_bound()) {
if (CHECK_FLAG(nh->flags, NEXTHOP_FLAG_RECURSIVE)) {
/* Single recursive nexthop */
handle_recursive_depend(&newnhe->nhg_depends,
recursive = true;
}
} else {
+ /* Proto-owned are groups by default */
/* List of nexthops */
for (nh = newnhe->nhg.nexthop; nh; nh = nh->next) {
if (IS_ZEBRA_DEBUG_NHG_DETAIL)
zebra_nhg_set_invalid(nhe);
}
-
-static void zebra_nhg_release(struct nhg_hash_entry *nhe)
+static void zebra_nhg_release_all_deps(struct nhg_hash_entry *nhe)
{
- if (IS_ZEBRA_DEBUG_NHG_DETAIL)
- zlog_debug("%s: nhe %p (%u)", __func__, nhe, nhe->id);
-
/* Remove it from any lists it may be on */
zebra_nhg_depends_release(nhe);
zebra_nhg_dependents_release(nhe);
if (nhe->ifp)
if_nhg_dependents_del(nhe->ifp, nhe);
+}
+
+static void zebra_nhg_release(struct nhg_hash_entry *nhe)
+{
+ if (IS_ZEBRA_DEBUG_NHG_DETAIL)
+ zlog_debug("%s: nhe %p (%u)", __func__, nhe, nhe->id);
+
+ zebra_nhg_release_all_deps(nhe);
/*
* If its not zebra owned, we didn't store it here and have to be
}
if (CHECK_FLAG(nhe->flags, NEXTHOP_GROUP_VALID)
- && !CHECK_FLAG(nhe->flags, NEXTHOP_GROUP_INSTALLED)
+ && (!CHECK_FLAG(nhe->flags, NEXTHOP_GROUP_INSTALLED)
+ || nhe->id >= zclient_get_nhg_lower_bound())
&& !CHECK_FLAG(nhe->flags, NEXTHOP_GROUP_QUEUED)) {
/* Change its type to us since we are installing it */
if (!ZEBRA_NHG_CREATED(nhe))
struct nexthop_group *nhg, afi_t afi)
{
struct nhg_hash_entry lookup;
- struct nhg_hash_entry *new;
+ struct nhg_hash_entry *new, *old;
struct nhg_connected *rb_node_dep = NULL;
zebra_nhe_init(&lookup, afi, nhg->nexthop);
lookup.id = id;
lookup.type = type;
+ old = zebra_nhg_lookup_id(id);
+
+ if (old) {
+ /*
+ * This is a replace, just release NHE from ID for now, The
+ * depends/dependents may still be used in the replacement.
+ */
+ hash_release(zrouter.nhgs_id, old);
+ }
+
new = zebra_nhg_rib_find_nhe(&lookup, afi);
+ if (old) {
+ /* Now release depends/dependents in old one */
+ zebra_nhg_release_all_deps(old);
+ }
+
if (!new)
return NULL;
}
if (IS_ZEBRA_DEBUG_NHG_DETAIL)
- zlog_debug("%s: added nhe %p (%u), vrf %d, type %s", __func__,
- new, new->id, new->vrf_id,
- zebra_route_string(new->type));
+ zlog_debug("%s: %s nhe %p (%u), vrf %d, type %s", __func__,
+ (old ? "replaced" : "added"), new, new->id,
+ new->vrf_id, zebra_route_string(new->type));
return new;
}