]> git.proxmox.com Git - mirror_frr.git/commitdiff
zebra: Abstract the RB nodes/add dependents tree
authorStephen Worley <sworley@cumulusnetworks.com>
Tue, 14 May 2019 01:13:02 +0000 (18:13 -0700)
committerStephen Worley <sworley@cumulusnetworks.com>
Fri, 25 Oct 2019 15:13:39 +0000 (11:13 -0400)
Create a nhg_depenents tree that will function as a way
to get back pointers for NHE's depending on it.

Abstract the RB nodes into nhg_connected for both depends and
dependents. This same struct is used for both.

Signed-off-by: Stephen Worley <sworley@cumulusnetworks.com>
zebra/rt_netlink.c
zebra/zebra_dplane.c
zebra/zebra_nhg.c
zebra/zebra_nhg.h
zebra/zebra_rib.c
zebra/zebra_vty.c

index f7e72e243ff33ea7e2f704c97006992cafd90fc7..bdf613cef4d4d3a009b7b235daa9376c499a4081 100644 (file)
@@ -2225,14 +2225,14 @@ static struct nexthop *netlink_nexthop_process_nh(struct rtattr **tb,
  * netlink_nexthop_process_group() - Iterate over nhmsg nexthop group
  *
  * @tb:                        Netlink RTA data
- * @nhg_depends:       Tree head of nexthops in the group (depends)
+ * @nhg_depends:       Tree head of nexthops in the group
  * @nhg:               Nexthop group struct
  *
  * Return:     Count of nexthops in the group
  */
 static int netlink_nexthop_process_group(struct rtattr **tb,
                                         struct nexthop_group *nhg,
-                                        struct nhg_depends_head *nhg_depends)
+                                        struct nhg_connected_head *nhg_depends)
 {
        int count = 0;
        struct nexthop_grp *n_grp = NULL;
@@ -2251,7 +2251,7 @@ static int netlink_nexthop_process_group(struct rtattr **tb,
        zlog_debug("Nexthop group type: %d",
                   *((uint16_t *)RTA_DATA(tb[NHA_GROUP_TYPE])));
 
-       zebra_nhg_depends_head_init(nhg_depends);
+       zebra_nhg_connected_head_init(nhg_depends);
 
        for (int i = 0; i < count; i++) {
                /* We do not care about nexthop_grp.weight at
@@ -2261,7 +2261,7 @@ static int netlink_nexthop_process_group(struct rtattr **tb,
                 */
                depend = zebra_nhg_lookup_id(n_grp[i].id);
                if (depend) {
-                       zebra_nhg_depends_head_add(nhg_depends, depend);
+                       zebra_nhg_connected_head_add(nhg_depends, depend);
                        /*
                         * If this is a nexthop with its own group
                         * dependencies, add them as well. Not sure its
@@ -2304,7 +2304,7 @@ int netlink_nexthop_change(struct nlmsghdr *h, ns_id_t ns_id, int startup)
        struct nexthop_group *nhg = NULL;
        struct nexthop *nh = NULL;
        /* If its a group, tree head of nexthops */
-       struct nhg_depends_head nhg_depends = {0};
+       struct nhg_connected_head nhg_depends = {0};
        /* Count of nexthops in group array */
        int dep_count = 0;
        /* struct that goes into our tables */
@@ -2449,6 +2449,7 @@ int netlink_nexthop_change(struct nlmsghdr *h, ns_id_t ns_id, int startup)
                                        EC_ZEBRA_DUPLICATE_NHG_MESSAGE,
                                        "Nexthop Group from kernel with ID (%d) is a duplicate, ignoring",
                                        id);
+                               zebra_nhg_connected_head_free(&nhg_depends);
                        }
                }
                if (ifp) {
index 170f7cfe64a12831d650146c46d651a13a33dc35..e4890319d9dd67c304f114e266c989dba6dab7ad 100644 (file)
@@ -1569,10 +1569,11 @@ static int dplane_ctx_nexthop_init(struct zebra_dplane_ctx *ctx,
        nexthop_group_copy(&(ctx->u.rinfo.nhe.ng), nhe->nhg);
 
        if (!zebra_nhg_depends_is_empty(nhe)) {
-               struct nhg_depend *rb_node_dep = NULL;
+               struct nhg_connected *rb_node_dep = NULL;
                uint8_t i = 0;
 
-               RB_FOREACH (rb_node_dep, nhg_depends_head, &nhe->nhg_depends) {
+               RB_FOREACH (rb_node_dep, nhg_connected_head,
+                           &nhe->nhg_depends) {
                        ctx->u.rinfo.nhe.depends_info[i].id =
                                rb_node_dep->nhe->id;
                        /* We aren't using weights for anything right now */
index 56f8c9d85233bba2550fc9b1fea778b9680545fc..d3204bdf4852082368b7e47faf7fbb6d6998606f 100644 (file)
 #include "zebra_dplane.h"
 
 DEFINE_MTYPE_STATIC(ZEBRA, NHG, "Nexthop Group Entry");
-DEFINE_MTYPE_STATIC(ZEBRA, NHG_DEPEND, "Nexthop Group Dependency");
+DEFINE_MTYPE_STATIC(ZEBRA, NHG_CONNECTED, "Nexthop Group Connected");
 
-static int zebra_nhg_depend_cmp(const struct nhg_depend *dep1,
-                               const struct nhg_depend *dep2);
+static int zebra_nhg_connected_cmp(const struct nhg_connected *dep1,
+                                  const struct nhg_connected *dep2);
 
-RB_GENERATE(nhg_depends_head, nhg_depend, depend, zebra_nhg_depend_cmp);
+RB_GENERATE(nhg_connected_head, nhg_connected, nhg_entry,
+           zebra_nhg_connected_cmp);
 
-static void nhg_depend_free(struct nhg_depend *dep)
+static void nhg_connected_free(struct nhg_connected *dep)
 {
-       XFREE(MTYPE_NHG_DEPEND, dep);
+       XFREE(MTYPE_NHG_CONNECTED, dep);
 }
 
-static struct nhg_depend *nhg_depend_new(struct nhg_hash_entry *nhe)
+static struct nhg_connected *nhg_connected_new(struct nhg_hash_entry *nhe)
 {
-       struct nhg_depend *new = NULL;
+       struct nhg_connected *new = NULL;
 
-       new = XCALLOC(MTYPE_NHG_DEPEND, sizeof(struct nhg_depend));
+       new = XCALLOC(MTYPE_NHG_CONNECTED, sizeof(struct nhg_connected));
        new->nhe = nhe;
 
        return new;
 }
 
-static uint8_t zebra_nhg_depends_head_count(const struct nhg_depends_head *head)
+static uint8_t zebra_nhg_connected_count(const struct nhg_connected_head *head)
 {
-       struct nhg_depend *rb_node_dep = NULL;
+       struct nhg_connected *rb_node_dep = NULL;
        uint8_t i = 0;
 
-       RB_FOREACH (rb_node_dep, nhg_depends_head, head) {
+       RB_FOREACH (rb_node_dep, nhg_connected_head, head) {
                i++;
        }
        return i;
@@ -77,52 +78,69 @@ static uint8_t zebra_nhg_depends_head_count(const struct nhg_depends_head *head)
 
 uint8_t zebra_nhg_depends_count(const struct nhg_hash_entry *nhe)
 {
-       return zebra_nhg_depends_head_count(&nhe->nhg_depends);
+       return zebra_nhg_connected_count(&nhe->nhg_depends);
 }
 
-static bool zebra_nhg_depends_head_is_empty(const struct nhg_depends_head *head)
+static bool
+zebra_nhg_connected_head_is_empty(const struct nhg_connected_head *head)
 {
-       return RB_EMPTY(nhg_depends_head, head);
+       return RB_EMPTY(nhg_connected_head, head);
 }
 
-/**
- * zebra_nhg_depends_is_empty() - Are there any dependencies
- *
- * @nhe:       Nexthop group hash entry
- *
- * Return:     True if empty, False otherwise
- */
 bool zebra_nhg_depends_is_empty(const struct nhg_hash_entry *nhe)
 {
-       return zebra_nhg_depends_head_is_empty(&nhe->nhg_depends);
+       return zebra_nhg_connected_head_is_empty(&nhe->nhg_depends);
 }
 
-void zebra_nhg_depends_head_del(struct nhg_depends_head *head,
-                         struct nhg_hash_entry *depend)
+void zebra_nhg_connected_head_del(struct nhg_connected_head *head,
+                                 struct nhg_hash_entry *depend)
 {
-       struct nhg_depend lookup = {};
-       struct nhg_depend *removed = NULL;
+       struct nhg_connected lookup = {};
+       struct nhg_connected *removed = NULL;
 
        lookup.nhe = depend;
 
-       removed = RB_REMOVE(nhg_depends_head, head, &lookup);
+       removed = RB_REMOVE(nhg_connected_head, head, &lookup);
 
-       nhg_depend_free(removed);
+       nhg_connected_free(removed);
 }
 
-// TODO: Refactor this for use with dependents as well
-void zebra_nhg_depends_head_add(struct nhg_depends_head *head,
-                         struct nhg_hash_entry *depend)
+void zebra_nhg_connected_head_add(struct nhg_connected_head *head,
+                                 struct nhg_hash_entry *depend)
 {
-       struct nhg_depend *new = NULL;
+       struct nhg_connected *new = NULL;
+
+       new = nhg_connected_new(depend);
+
+       RB_INSERT(nhg_connected_head, head, new);
+}
 
-       new = nhg_depend_new(depend);
+/**
+ * zebra_nhg_dependents_del() - Delete a dependent from the nhg_hash_entry
+ *
+ * @from:      Nexthop group hash entry we are deleting from
+ * @dependent: Dependent we are deleting
+ */
+void zebra_nhg_dependents_del(struct nhg_hash_entry *from,
+                             struct nhg_hash_entry *dependent)
+{
+       zebra_nhg_connected_head_del(&from->nhg_dependents, dependent);
+}
 
-       RB_INSERT(nhg_depends_head, head, new);
+/**
+ * zebra_nhg_dependents_add() - Add a new dependent to the nhg_hash_entry
+ *
+ * @to:                Nexthop group hash entry we are adding to
+ * @dependent: Dependent we are adding
+ */
+void zebra_nhg_dependents_add(struct nhg_hash_entry *to,
+                             struct nhg_hash_entry *dependent)
+{
+       zebra_nhg_connected_head_add(&to->nhg_dependents, dependent);
 }
 
 /**
- * zebra_nhg_depend_del() - Delete a dependency from the nhg_hash_entry
+ * zebra_nhg_depends_del() - Delete a dependency from the nhg_hash_entry
  *
  * @from:      Nexthop group hash entry we are deleting from
  * @depend:    Dependency we are deleting
@@ -130,7 +148,10 @@ void zebra_nhg_depends_head_add(struct nhg_depends_head *head,
 void zebra_nhg_depends_del(struct nhg_hash_entry *from,
                           struct nhg_hash_entry *depend)
 {
-       zebra_nhg_depends_head_del(&from->nhg_depends, depend);
+       zebra_nhg_connected_head_del(&from->nhg_depends, depend);
+
+       /* Delete from the dependent tree */
+       zebra_nhg_dependents_del(depend, from);
 }
 
 /**
@@ -142,17 +163,12 @@ void zebra_nhg_depends_del(struct nhg_hash_entry *from,
 void zebra_nhg_depends_add(struct nhg_hash_entry *to,
                           struct nhg_hash_entry *depend)
 {
-       zebra_nhg_depends_head_add(&to->nhg_depends, depend);
+       zebra_nhg_connected_head_add(&to->nhg_depends, depend);
 }
 
-/**
- * zebra_nhg_depends_head_init() - Helper to init the RB tree head directly
- *
- * @head:      RB nhg_depends_head struct
- */
-void zebra_nhg_depends_head_init(struct nhg_depends_head *head)
+void zebra_nhg_connected_head_init(struct nhg_connected_head *head)
 {
-       RB_INIT(nhg_depends_head, head);
+       RB_INIT(nhg_connected_head, head);
 }
 
 /**
@@ -162,7 +178,7 @@ void zebra_nhg_depends_head_init(struct nhg_depends_head *head)
  */
 void zebra_nhg_depends_init(struct nhg_hash_entry *nhe)
 {
-       zebra_nhg_depends_head_init(&nhe->nhg_depends);
+       zebra_nhg_connected_head_init(&nhe->nhg_depends);
 }
 
 
@@ -180,7 +196,7 @@ void zebra_nhg_depends_init(struct nhg_hash_entry *nhe)
 static bool zebra_nhg_depends_equal(const struct nhg_hash_entry *nhe1,
                                    const struct nhg_hash_entry *nhe2)
 {
-       struct nhg_depend *rb_node_dep = NULL;
+       struct nhg_connected *rb_node_dep = NULL;
 
        if (zebra_nhg_depends_is_empty(nhe1)
            && zebra_nhg_depends_is_empty(nhe2))
@@ -192,8 +208,9 @@ static bool zebra_nhg_depends_equal(const struct nhg_hash_entry *nhe1,
                && !zebra_nhg_depends_is_empty(nhe1)))
                return false;
 
-       RB_FOREACH (rb_node_dep, nhg_depends_head, &nhe1->nhg_depends) {
-               if (!RB_FIND(nhg_depends_head, &nhe2->nhg_depends, rb_node_dep))
+       RB_FOREACH (rb_node_dep, nhg_connected_head, &nhe1->nhg_depends) {
+               if (!RB_FIND(nhg_connected_head, &nhe2->nhg_depends,
+                            rb_node_dep))
                        return false;
        }
 
@@ -242,6 +259,8 @@ static void *zebra_nhg_alloc(void *arg)
 {
        struct nhg_hash_entry *nhe;
        struct nhg_hash_entry *copy = arg;
+       struct nhg_connected *rb_node_dep = NULL;
+
 
        nhe = XCALLOC(MTYPE_NHG, sizeof(struct nhg_hash_entry));
 
@@ -260,6 +279,13 @@ static void *zebra_nhg_alloc(void *arg)
        nhe->dplane_ref = zebra_router_get_next_sequence();
        nhe->ifp = NULL;
 
+       /* Attach backpointer to anything that it depends on */
+       if (!zebra_nhg_depends_is_empty(nhe)) {
+               RB_FOREACH (rb_node_dep, nhg_connected_head,
+                           &nhe->nhg_depends) {
+                       zebra_nhg_dependents_add(rb_node_dep->nhe, nhe);
+               }
+       }
 
        /* Add to id table as well */
        zebra_nhg_insert_id(nhe);
@@ -336,8 +362,8 @@ static int zebra_nhg_cmp(const struct nhg_hash_entry *nhe1,
        return nhe1->id - nhe2->id;
 }
 
-static int zebra_nhg_depend_cmp(const struct nhg_depend *dep1,
-                               const struct nhg_depend *dep2)
+static int zebra_nhg_connected_cmp(const struct nhg_connected *dep1,
+                                  const struct nhg_connected *dep2)
 {
        return zebra_nhg_cmp(dep1->nhe, dep2->nhe);
 }
@@ -375,7 +401,7 @@ static int zebra_nhg_depend_cmp(const struct nhg_depend *dep1,
  */
 struct nhg_hash_entry *zebra_nhg_find(struct nexthop_group *nhg,
                                      vrf_id_t vrf_id, afi_t afi, uint32_t id,
-                                     struct nhg_depends_head *nhg_depends,
+                                     struct nhg_connected_head *nhg_depends,
                                      bool is_kernel_nh)
 {
        /* lock for getiing and setting the id */
@@ -449,15 +475,15 @@ struct nhg_hash_entry *zebra_nhg_find_nexthop(struct nexthop *nh, afi_t afi)
        return nhe;
 }
 
-void zebra_nhg_depends_free(struct nhg_depends_head *head)
+void zebra_nhg_connected_head_free(struct nhg_connected_head *head)
 {
-       struct nhg_depend *rb_node_dep = NULL;
-       struct nhg_depend *tmp = NULL;
+       struct nhg_connected *rb_node_dep = NULL;
+       struct nhg_connected *tmp = NULL;
 
-       if (!zebra_nhg_depends_head_is_empty(head)) {
-               RB_FOREACH_SAFE (rb_node_dep, nhg_depends_head, head, tmp) {
-                       RB_REMOVE(nhg_depends_head, head, rb_node_dep);
-                       nhg_depend_free(rb_node_dep);
+       if (!zebra_nhg_connected_head_is_empty(head)) {
+               RB_FOREACH_SAFE (rb_node_dep, nhg_connected_head, head, tmp) {
+                       RB_REMOVE(nhg_connected_head, head, rb_node_dep);
+                       nhg_connected_free(rb_node_dep);
                }
        }
 }
@@ -470,10 +496,19 @@ void zebra_nhg_depends_free(struct nhg_depends_head *head)
  * @nhg_depends:       Nexthop group dependency tree head
  */
 void zebra_nhg_free_group_depends(struct nexthop_group **nhg,
-                                 struct nhg_depends_head *head)
+                                 struct nhg_connected_head *head)
 {
+       // TODO
+       //
+       //
+       // FIX THIS NAMING
+       //
+       //
+       //
+       //
+       //
        if (head)
-               zebra_nhg_depends_free(head);
+               zebra_nhg_connected_head_free(head);
 
        if (nhg)
                nexthop_group_free_delete(nhg);
@@ -489,6 +524,9 @@ void zebra_nhg_free_group_depends(struct nexthop_group **nhg,
 void zebra_nhg_free_members(struct nhg_hash_entry *nhe)
 {
        zebra_nhg_free_group_depends(&nhe->nhg, &nhe->nhg_depends);
+
+       // TODO: Fixup this function
+       zebra_nhg_connected_head_free(&nhe->nhg_dependents);
 }
 
 /**
@@ -544,9 +582,10 @@ static void zebra_nhg_uninstall_release(struct nhg_hash_entry *nhe)
 void zebra_nhg_decrement_ref(struct nhg_hash_entry *nhe)
 {
        if (!zebra_nhg_depends_is_empty(nhe)) {
-               struct nhg_depend *rb_node_dep = NULL;
+               struct nhg_connected *rb_node_dep = NULL;
 
-               RB_FOREACH (rb_node_dep, nhg_depends_head, &nhe->nhg_depends) {
+               RB_FOREACH (rb_node_dep, nhg_connected_head,
+                           &nhe->nhg_depends) {
                        zebra_nhg_decrement_ref(rb_node_dep->nhe);
                }
        }
@@ -566,9 +605,10 @@ void zebra_nhg_decrement_ref(struct nhg_hash_entry *nhe)
 void zebra_nhg_increment_ref(struct nhg_hash_entry *nhe)
 {
        if (!zebra_nhg_depends_is_empty(nhe)) {
-               struct nhg_depend *rb_node_dep = NULL;
+               struct nhg_connected *rb_node_dep = NULL;
 
-               RB_FOREACH (rb_node_dep, nhg_depends_head, &nhe->nhg_depends) {
+               RB_FOREACH (rb_node_dep, nhg_connected_head,
+                           &nhe->nhg_depends) {
                        zebra_nhg_increment_ref(rb_node_dep->nhe);
                }
        }
index 1cc1c47e32142d3680caf48165bae5c1922b263c..4aa59e7530a45b1b8c39532cc18455ba0c43b093 100644 (file)
@@ -69,7 +69,7 @@ struct nhg_hash_entry {
         * Using a rb tree here to make lookups
         * faster with ID's.
         */
-       RB_HEAD(nhg_depends_head, nhg_depend) nhg_depends;
+       RB_HEAD(nhg_connected_head, nhg_connected) nhg_depends, nhg_dependents;
 /*
  * Is this nexthop group valid, ie all nexthops are fully resolved.
  * What is fully resolved?  It's a nexthop that is either self contained
@@ -90,28 +90,33 @@ struct nhg_hash_entry {
 #define NEXTHOP_GROUP_QUEUED 0x4
 };
 
-/* Abstraction for dependency tree */
-struct nhg_depend {
-       RB_ENTRY(nhg_depend) depend;
+/* Abstraction for connected trees */
+struct nhg_connected {
+       RB_ENTRY(nhg_connected) nhg_entry;
        struct nhg_hash_entry *nhe;
 };
 
-RB_PROTOTYPE(nhg_depends_head, nhg_depend, depend, zebra_nhg_depend_cmp);
+RB_PROTOTYPE(nhg_connected_head, nhg_connected, nhg_entry,
+            zebra_nhg_connected_cmp);
 
 void zebra_nhg_init(void);
 void zebra_nhg_terminate(void);
 
 extern uint8_t zebra_nhg_depends_count(const struct nhg_hash_entry *nhe);
 extern bool zebra_nhg_depends_is_empty(const struct nhg_hash_entry *nhe);
-extern void zebra_nhg_depends_head_del(struct nhg_depends_head *head,
-                                      struct nhg_hash_entry *depend);
-extern void zebra_nhg_depends_head_add(struct nhg_depends_head *head,
-                                      struct nhg_hash_entry *depend);
+extern void zebra_nhg_connected_head_del(struct nhg_connected_head *head,
+                                        struct nhg_hash_entry *nhe);
+extern void zebra_nhg_connected_head_add(struct nhg_connected_head *head,
+                                        struct nhg_hash_entry *nhe);
+extern void zebra_nhg_dependents_del(struct nhg_hash_entry *from,
+                                    struct nhg_hash_entry *dependent);
+extern void zebra_nhg_dependents_add(struct nhg_hash_entry *to,
+                                    struct nhg_hash_entry *dependent);
 extern void zebra_nhg_depends_del(struct nhg_hash_entry *from,
                                  struct nhg_hash_entry *depend);
 extern void zebra_nhg_depends_add(struct nhg_hash_entry *to,
                                  struct nhg_hash_entry *depend);
-extern void zebra_nhg_depends_head_init(struct nhg_depends_head *head);
+extern void zebra_nhg_connected_head_init(struct nhg_connected_head *head);
 extern void zebra_nhg_depends_init(struct nhg_hash_entry *nhe);
 extern void zebra_nhg_depends_copy(struct nhg_hash_entry *to,
                                   struct nhg_hash_entry *from);
@@ -128,16 +133,16 @@ extern bool zebra_nhg_hash_id_equal(const void *arg1, const void *arg2);
 
 extern struct nhg_hash_entry *
 zebra_nhg_find(struct nexthop_group *nhg, vrf_id_t vrf_id, afi_t afi,
-              uint32_t id, struct nhg_depends_head *nhg_depends,
+              uint32_t id, struct nhg_connected_head *nhg_depends,
               bool is_kernel_nh);
 
 extern struct nhg_hash_entry *zebra_nhg_find_nexthop(struct nexthop *nh,
                                                     afi_t afi);
 
 
-void zebra_nhg_depends_free(struct nhg_depends_head *head);
+void zebra_nhg_connected_head_free(struct nhg_connected_head *head);
 void zebra_nhg_free_group_depends(struct nexthop_group **nhg,
-                                 struct nhg_depends_head *head);
+                                 struct nhg_connected_head *head);
 void zebra_nhg_free_members(struct nhg_hash_entry *nhe);
 void zebra_nhg_free(void *arg);
 void zebra_nhg_release(struct nhg_hash_entry *nhe);
index 957b7e14f4167354b275919dd5295fd5661f04d4..7015ff77de705a99149f17ee4c4d8d01598ab9e0 100644 (file)
@@ -2638,7 +2638,7 @@ int rib_add_multipath(afi_t afi, safi_t safi, struct prefix *p,
        struct route_node *rn;
        struct route_entry *same = NULL;
        struct nhg_hash_entry *nhe = NULL;
-       struct nhg_depends_head nhg_depends = {0};
+       struct nhg_connected_head nhg_depends = {0};
        /* Default to route afi */
        afi_t nhg_afi = afi;
        int ret = 0;
@@ -2667,7 +2667,7 @@ int rib_add_multipath(afi_t afi, safi_t safi, struct prefix *p,
                struct nexthop lookup = {0};
                struct nhg_hash_entry *depend = NULL;
 
-               zebra_nhg_depends_head_init(&nhg_depends);
+               zebra_nhg_connected_head_init(&nhg_depends);
 
                for (ALL_NEXTHOPS_PTR(re->ng, nh)) {
                        lookup = *nh;
@@ -2675,7 +2675,7 @@ int rib_add_multipath(afi_t afi, safi_t safi, struct prefix *p,
                        lookup.next = NULL;
                        /* Use the route afi here, since a single nh */
                        depend = zebra_nhg_find_nexthop(&lookup, afi);
-                       zebra_nhg_depends_head_add(&nhg_depends, depend);
+                       zebra_nhg_connected_head_add(&nhg_depends, depend);
                }
 
                /* change the afi for group */
@@ -2698,7 +2698,7 @@ int rib_add_multipath(afi_t afi, safi_t safi, struct prefix *p,
                        EC_ZEBRA_TABLE_LOOKUP_FAILED,
                        "Zebra failed to find or create a nexthop hash entry for id=%u in a route entry",
                        re->nhe_id);
-               zebra_nhg_depends_free(&nhg_depends);
+               zebra_nhg_connected_head_free(&nhg_depends);
        }
 
 
index 106cd6b027b9c0b9d8ed45d2578d009cd3d9adc6..cd099da37e9d6202c2975dd44df19c957101f42b 100644 (file)
@@ -1111,6 +1111,7 @@ static void show_nexthop_group_cmd_helper(struct vty *vty,
 
        for (ALL_LIST_ELEMENTS_RO(list, node, nhe)) {
                struct nexthop *nhop;
+               struct nhg_connected *rb_node_dep = NULL;
 
                if (afi && nhe->afi != afi)
                        continue;
@@ -1128,14 +1129,21 @@ static void show_nexthop_group_cmd_helper(struct vty *vty,
                                nhe->ifp->ifindex);
 
                if (!zebra_nhg_depends_is_empty(nhe)) {
-                       struct nhg_depend *rb_node_dep = NULL;
 
                        vty_out(vty, "\tDepends:");
-                       RB_FOREACH (rb_node_dep, nhg_depends_head,
+                       RB_FOREACH (rb_node_dep, nhg_connected_head,
                                    &nhe->nhg_depends) {
                                vty_out(vty, " (%u)", rb_node_dep->nhe->id);
                        }
                        vty_out(vty, "\n");
+
+               } else {
+                       vty_out(vty, "\tDependents:");
+                       RB_FOREACH (rb_node_dep, nhg_connected_head,
+                                   &nhe->nhg_dependents) {
+                               vty_out(vty, " (%u)", rb_node_dep->nhe->id);
+                       }
+                       vty_out(vty, "\n");
                }
 
                for (ALL_NEXTHOPS_PTR(nhe->nhg, nhop)) {