summaryrefslogtreecommitdiff
path: root/zebra/zebra_nhg.c
diff options
context:
space:
mode:
Diffstat (limited to 'zebra/zebra_nhg.c')
-rw-r--r--zebra/zebra_nhg.c100
1 files changed, 38 insertions, 62 deletions
diff --git a/zebra/zebra_nhg.c b/zebra/zebra_nhg.c
index f06ff44f20..4f41406a5c 100644
--- a/zebra/zebra_nhg.c
+++ b/zebra/zebra_nhg.c
@@ -49,7 +49,8 @@ DEFINE_MTYPE_STATIC(ZEBRA, NHG_CTX, "Nexthop Group Context");
/* id counter to keep in sync with kernel */
uint32_t id_counter;
-static struct nhg_hash_entry *depends_find(struct nexthop *nh, afi_t afi);
+static struct nhg_hash_entry *depends_find(const struct nexthop *nh,
+ afi_t afi);
static void depends_add(struct nhg_connected_tree_head *head,
struct nhg_hash_entry *depend);
static struct nhg_hash_entry *
@@ -299,13 +300,22 @@ zebra_nhg_connect_depends(struct nhg_hash_entry *nhe,
}
}
-static struct nhg_hash_entry *zebra_nhg_copy(struct nhg_hash_entry *copy,
- uint32_t id)
+struct nhg_hash_entry *zebra_nhg_alloc(void)
{
struct nhg_hash_entry *nhe;
nhe = XCALLOC(MTYPE_NHG, sizeof(struct nhg_hash_entry));
+ return nhe;
+}
+
+static struct nhg_hash_entry *zebra_nhg_copy(const struct nhg_hash_entry *copy,
+ uint32_t id)
+{
+ struct nhg_hash_entry *nhe;
+
+ nhe = zebra_nhg_alloc();
+
nhe->id = id;
nhe->nhg = nexthop_group_new();
@@ -468,7 +478,7 @@ static void handle_recursive_depend(struct nhg_connected_tree_head *nhg_depends,
struct nhg_hash_entry *depend = NULL;
struct nexthop_group resolved_ng = {};
- _nexthop_group_add_sorted(&resolved_ng, nh);
+ nexthop_group_add_sorted(&resolved_ng, nh);
depend = zebra_nhg_rib_find(0, &resolved_ng, afi);
depends_add(nhg_depends, depend);
@@ -582,9 +592,9 @@ zebra_nhg_find_nexthop(uint32_t id, struct nexthop *nh, afi_t afi, int type)
struct nhg_hash_entry *nhe = NULL;
struct nexthop_group nhg = {};
- _nexthop_group_add_sorted(&nhg, nh);
+ nexthop_group_add_sorted(&nhg, nh);
- zebra_nhg_find(&nhe, id, &nhg, NULL, nh->vrf_id, afi, 0);
+ zebra_nhg_find(&nhe, id, &nhg, NULL, nh->vrf_id, afi, type);
return nhe;
}
@@ -1038,25 +1048,24 @@ int zebra_nhg_kernel_del(uint32_t id)
}
/* Some dependency helper functions */
-static struct nhg_hash_entry *depends_find(struct nexthop *nh, afi_t afi)
+static struct nhg_hash_entry *depends_find(const struct nexthop *nh, afi_t afi)
{
- struct nexthop *lookup = NULL;
+ struct nexthop lookup;
struct nhg_hash_entry *nhe = NULL;
if (!nh)
goto done;
- copy_nexthops(&lookup, nh, NULL);
-
- /* Clear it, in case its a group */
- nexthops_free(lookup->next);
- nexthops_free(lookup->prev);
- lookup->next = NULL;
- lookup->prev = NULL;
+ /* Capture a snapshot of this single nh; it might be part of a list,
+ * so we need to make a standalone copy.
+ */
+ memset(&lookup, 0, sizeof(lookup));
+ nexthop_copy(&lookup, nh, NULL);
- nhe = zebra_nhg_find_nexthop(0, lookup, afi, 0);
+ nhe = zebra_nhg_find_nexthop(0, &lookup, afi, 0);
- nexthops_free(lookup);
+ /* The copy may have allocated labels; free them if necessary. */
+ nexthop_del_labels(&lookup);
done:
return nhe;
@@ -1128,12 +1137,8 @@ static void zebra_nhg_free_members(struct nhg_hash_entry *nhe)
nhg_connected_tree_free(&nhe->nhg_dependents);
}
-void zebra_nhg_free(void *arg)
+void zebra_nhg_free(struct nhg_hash_entry *nhe)
{
- struct nhg_hash_entry *nhe = NULL;
-
- nhe = (struct nhg_hash_entry *)arg;
-
if (nhe->refcnt)
zlog_debug("nhe_id=%u hash refcnt=%d", nhe->id, nhe->refcnt);
@@ -1142,6 +1147,11 @@ void zebra_nhg_free(void *arg)
XFREE(MTYPE_NHG, nhe);
}
+void zebra_nhg_hash_free(void *p)
+{
+ zebra_nhg_free((struct nhg_hash_entry *)p);
+}
+
void zebra_nhg_decrement_ref(struct nhg_hash_entry *nhe)
{
nhe->refcnt--;
@@ -1447,7 +1457,7 @@ static int nexthop_active(afi_t afi, struct route_entry *re,
if (match->type == ZEBRA_ROUTE_CONNECT) {
/* Directly point connected route. */
- newhop = match->ng->nexthop;
+ newhop = match->nhe->nhg->nexthop;
if (newhop) {
if (nexthop->type == NEXTHOP_TYPE_IPV4
|| nexthop->type == NEXTHOP_TYPE_IPV6)
@@ -1456,7 +1466,7 @@ static int nexthop_active(afi_t afi, struct route_entry *re,
return 1;
} else if (CHECK_FLAG(re->flags, ZEBRA_FLAG_ALLOW_RECURSION)) {
resolved = 0;
- for (ALL_NEXTHOPS_PTR(match->ng, newhop)) {
+ for (ALL_NEXTHOPS_PTR(match->nhe->nhg, newhop)) {
if (!CHECK_FLAG(match->status,
ROUTE_ENTRY_INSTALLED))
continue;
@@ -1477,7 +1487,7 @@ static int nexthop_active(afi_t afi, struct route_entry *re,
return resolved;
} else if (re->type == ZEBRA_ROUTE_STATIC) {
resolved = 0;
- for (ALL_NEXTHOPS_PTR(match->ng, newhop)) {
+ for (ALL_NEXTHOPS_PTR(match->nhe->nhg, newhop)) {
if (!CHECK_FLAG(match->status,
ROUTE_ENTRY_INSTALLED))
continue;
@@ -1668,7 +1678,7 @@ int nexthop_active_update(struct route_node *rn, struct route_entry *re)
UNSET_FLAG(re->status, ROUTE_ENTRY_CHANGED);
/* Copy over the nexthops in current state */
- nexthop_group_copy(&new_grp, re->ng);
+ nexthop_group_copy(&new_grp, re->nhe->nhg);
for (nexthop = new_grp.nexthop; nexthop; nexthop = nexthop->next) {
@@ -1718,7 +1728,7 @@ int nexthop_active_update(struct route_node *rn, struct route_entry *re)
new_nhe = zebra_nhg_rib_find(0, &new_grp, rt_afi);
- zebra_nhg_re_update_ref(re, new_nhe);
+ route_entry_update_nhe(re, new_nhe);
}
if (curr_active) {
@@ -1744,40 +1754,6 @@ int nexthop_active_update(struct route_node *rn, struct route_entry *re)
return curr_active;
}
-static void zebra_nhg_re_attach_ref(struct route_entry *re,
- struct nhg_hash_entry *new)
-{
- re->ng = new->nhg;
- re->nhe_id = new->id;
-
- zebra_nhg_increment_ref(new);
-}
-
-int zebra_nhg_re_update_ref(struct route_entry *re, struct nhg_hash_entry *new)
-{
- struct nhg_hash_entry *old = NULL;
- int ret = 0;
-
- if (new == NULL) {
- re->ng = NULL;
- goto done;
- }
-
- if (re->nhe_id != new->id) {
- old = zebra_nhg_lookup_id(re->nhe_id);
-
- zebra_nhg_re_attach_ref(re, new);
-
- if (old)
- zebra_nhg_decrement_ref(old);
- } else if (!re->ng)
- /* This is the first time it's being attached */
- zebra_nhg_re_attach_ref(re, new);
-
-done:
- return ret;
-}
-
/* Convert a nhe into a group array */
uint8_t zebra_nhg_nhe2grp(struct nh_grp *grp, struct nhg_hash_entry *nhe,
int max_num)
@@ -1814,7 +1790,7 @@ uint8_t zebra_nhg_nhe2grp(struct nh_grp *grp, struct nhg_hash_entry *nhe,
if (!duplicate) {
grp[i].id = depend->id;
/* We aren't using weights for anything right now */
- grp[i].weight = 0;
+ grp[i].weight = depend->nhg->nexthop->weight;
i++;
}