]> git.puffer.fish Git - matthieu/frr.git/commitdiff
lib: Isolate nexthop_group functions to nexthop_group.c
authorDonald Sharp <sharpd@cumulusnetworks.com>
Fri, 26 Jan 2018 15:12:35 +0000 (10:12 -0500)
committerDonald Sharp <sharpd@cumulusnetworks.com>
Fri, 9 Mar 2018 16:07:41 +0000 (11:07 -0500)
Also modify `struct route_entry` to use nexthop_groups.
Move ALL_NEXTHOPS loop to nexthop_group.h

Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
20 files changed:
lib/nexthop.c
lib/nexthop.h
lib/nexthop_group.c [new file with mode: 0644]
lib/nexthop_group.h [new file with mode: 0644]
lib/subdir.am
tests/lib/test_nexthop_iter.c
zebra/redistribute.c
zebra/rib.h
zebra/rt_netlink.c
zebra/rt_socket.c
zebra/zebra_fpm_netlink.c
zebra/zebra_fpm_protobuf.c
zebra/zebra_mpls.c
zebra/zebra_pw.c
zebra/zebra_rib.c
zebra/zebra_rnh.c
zebra/zebra_snmp.c
zebra/zebra_static.c
zebra/zebra_vty.c
zebra/zserv.c

index 6809a014691b902eff06e9d8625d9c5ef2d806bc..cee34e85c72ff17b3caf1095bd2b88ad53ef625d 100644 (file)
@@ -143,49 +143,6 @@ struct nexthop *nexthop_new(void)
        return XCALLOC(MTYPE_NEXTHOP, sizeof(struct nexthop));
 }
 
-/* Add nexthop to the end of a nexthop list.  */
-void nexthop_add(struct nexthop **target, struct nexthop *nexthop)
-{
-       struct nexthop *last;
-
-       for (last = *target; last && last->next; last = last->next)
-               ;
-       if (last)
-               last->next = nexthop;
-       else
-               *target = nexthop;
-       nexthop->prev = last;
-}
-
-void copy_nexthops(struct nexthop **tnh, struct nexthop *nh,
-                  struct nexthop *rparent)
-{
-       struct nexthop *nexthop;
-       struct nexthop *nh1;
-
-       for (nh1 = nh; nh1; nh1 = nh1->next) {
-               nexthop = nexthop_new();
-               nexthop->vrf_id = nh1->vrf_id;
-               nexthop->ifindex = nh1->ifindex;
-               nexthop->type = nh1->type;
-               nexthop->flags = nh1->flags;
-               memcpy(&nexthop->gate, &nh1->gate, sizeof(nh1->gate));
-               memcpy(&nexthop->src, &nh1->src, sizeof(nh1->src));
-               memcpy(&nexthop->rmap_src, &nh1->rmap_src,
-                      sizeof(nh1->rmap_src));
-               nexthop->rparent = rparent;
-               if (nh1->nh_label)
-                       nexthop_add_labels(nexthop, nh1->nh_label_type,
-                                          nh1->nh_label->num_labels,
-                                          &nh1->nh_label->label[0]);
-               nexthop_add(tnh, nexthop);
-
-               if (CHECK_FLAG(nh1->flags, NEXTHOP_FLAG_RECURSIVE))
-                       copy_nexthops(&nexthop->resolved, nh1->resolved,
-                                     nexthop);
-       }
-}
-
 /* Free nexthop. */
 void nexthop_free(struct nexthop *nexthop)
 {
index 0be949688f5c81754e9343b7ad550caf80a1102f..0ca8a0063aebb7b843e359627e91e4c70956239f 100644 (file)
@@ -109,24 +109,8 @@ struct nexthop {
        struct mpls_label_stack *nh_label;
 };
 
-/* The following for loop allows to iterate over the nexthop
- * structure of routes.
- *
- * head:      The pointer to the first nexthop in the chain.
- *
- * nexthop:   The pointer to the current nexthop, either in the
- *            top-level chain or in a resolved chain.
- */
-#define ALL_NEXTHOPS(head, nexthop)                                            \
-       (nexthop) = (head);                                                    \
-       (nexthop);                                                             \
-       (nexthop) = nexthop_next(nexthop)
-
 struct nexthop *nexthop_new(void);
-void nexthop_add(struct nexthop **target, struct nexthop *nexthop);
 
-void copy_nexthops(struct nexthop **tnh, struct nexthop *nh,
-                  struct nexthop *rparent);
 void nexthop_free(struct nexthop *nexthop);
 void nexthops_free(struct nexthop *nexthop);
 
diff --git a/lib/nexthop_group.c b/lib/nexthop_group.c
new file mode 100644 (file)
index 0000000..8bdc585
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * Nexthop Group structure definition.
+ * Copyright (C) 2018 Cumulus Networks, Inc.
+ *                    Donald Sharp
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; see the file COPYING; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#include <zebra.h>
+
+#include <nexthop.h>
+#include <nexthop_group.h>
+
+/* Add nexthop to the end of a nexthop list.  */
+void nexthop_add(struct nexthop **target, struct nexthop *nexthop)
+{
+       struct nexthop *last;
+
+       for (last = *target; last && last->next; last = last->next)
+               ;
+       if (last)
+               last->next = nexthop;
+       else
+               *target = nexthop;
+       nexthop->prev = last;
+}
+
+void copy_nexthops(struct nexthop **tnh, struct nexthop *nh,
+                  struct nexthop *rparent)
+{
+       struct nexthop *nexthop;
+       struct nexthop *nh1;
+
+       for (nh1 = nh; nh1; nh1 = nh1->next) {
+               nexthop = nexthop_new();
+               nexthop->vrf_id = nh1->vrf_id;
+               nexthop->ifindex = nh1->ifindex;
+               nexthop->type = nh1->type;
+               nexthop->flags = nh1->flags;
+               memcpy(&nexthop->gate, &nh1->gate, sizeof(nh1->gate));
+               memcpy(&nexthop->src, &nh1->src, sizeof(nh1->src));
+               memcpy(&nexthop->rmap_src, &nh1->rmap_src,
+                      sizeof(nh1->rmap_src));
+               nexthop->rparent = rparent;
+               if (nh1->nh_label)
+                       nexthop_add_labels(nexthop, nh1->nh_label_type,
+                                          nh1->nh_label->num_labels,
+                                          &nh1->nh_label->label[0]);
+               nexthop_add(tnh, nexthop);
+
+               if (CHECK_FLAG(nh1->flags, NEXTHOP_FLAG_RECURSIVE))
+                       copy_nexthops(&nexthop->resolved, nh1->resolved,
+                                     nexthop);
+       }
+}
diff --git a/lib/nexthop_group.h b/lib/nexthop_group.h
new file mode 100644 (file)
index 0000000..2690095
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * Nexthop Group structure definition.
+ * Copyright (C) 2018 Cumulus Networks, Inc.
+ *                    Donald Sharp
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; see the file COPYING; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __NEXTHOP_GROUP__
+#define __NEXTHOP_GROUP__
+
+/*
+ * What is a nexthop group?
+ *
+ * A nexthop group is a collection of nexthops that make up
+ * the ECMP path for the route.
+ *
+ * This module provides a proper abstraction to this idea.
+ */
+struct nexthop_group {
+       struct nexthop *nexthop;
+};
+
+void nexthop_add(struct nexthop **target, struct nexthop *nexthop);
+void copy_nexthops(struct nexthop **tnh, struct nexthop *nh,
+                  struct nexthop *rparent);
+
+/* The following for loop allows to iterate over the nexthop
+ * structure of routes.
+ *
+ * head:      The pointer to the first nexthop in the chain.
+ *
+ * nexthop:   The pointer to the current nexthop, either in the
+ *            top-level chain or in a resolved chain.
+ */
+#define ALL_NEXTHOPS(head, nhop)                                       \
+       (nhop) = (head.nexthop);                                        \
+       (nhop);                                                         \
+       (nhop) = nexthop_next(nhop)
+#endif
index c8da5a2a8c18692b1c0fa3a5fb485886b0a1ced6..5001b3cecf07919ad79c18eda6ea4c13f2b0fc54 100644 (file)
@@ -45,6 +45,7 @@ lib_libfrr_la_SOURCES = \
        lib/nexthop.c \
        lib/netns_linux.c \
        lib/netns_other.c \
+       lib/nexthop_group.c \
        lib/openbsd-tree.c \
        lib/pid_output.c \
        lib/plist.c \
@@ -124,6 +125,7 @@ pkginclude_HEADERS += \
        lib/mpls.h \
        lib/network.h \
        lib/nexthop.h \
+       lib/nexthop_group.h \
        lib/ns.h \
        lib/openbsd-queue.h \
        lib/openbsd-tree.h \
index 8d7353d4dcd11abe35050471d8944d0d60652536..f21f3bbb33d3117ec6a4c62c780f6512ef760ac4 100644 (file)
@@ -60,7 +60,7 @@ static void str_appendf(char **buf, const char *format, ...)
  * and its expected representation */
 struct nexthop_chain {
        /* Head of the chain */
-       struct nexthop *head;
+       struct nexthop_group head;
        /* Last nexthop in top chain */
        struct nexthop *current_top;
        /* Last nexthop in current recursive chain */
@@ -85,12 +85,12 @@ static void nexthop_chain_add_top(struct nexthop_chain *nc)
        nh = calloc(sizeof(*nh), 1);
        assert(nh);
 
-       if (nc->head) {
+       if (nc->head.nexthop) {
                nc->current_top->next = nh;
                nh->prev = nc->current_top;
                nc->current_top = nh;
        } else {
-               nc->head = nc->current_top = nh;
+               nc->head.nexthop = nc->current_top = nh;
        }
        nc->current_recursive = NULL;
        str_appendf(&nc->repr, "%p\n", nh);
@@ -166,8 +166,8 @@ static void nexthop_clear_recursive(struct nexthop *tcur)
 }
 static void nexthop_chain_clear(struct nexthop_chain *nc)
 {
-       nexthop_clear_recursive(nc->head);
-       nc->head = nc->current_top = nc->current_recursive = NULL;
+       nexthop_clear_recursive(nc->head.nexthop);
+       nc->head.nexthop = nc->current_top = nc->current_recursive = NULL;
        free(nc->repr);
        nc->repr = NULL;
 }
index c03d755b2a41600eb62a26965f85cce5d65d064e..a7b2361ac68dfd636510bbbf8d8b14189072d5cb 100644 (file)
@@ -519,8 +519,8 @@ int zebra_add_import_table_entry(struct route_node *rn, struct route_entry *re,
        afi = family2afi(rn->p.family);
        if (rmap_name)
                ret = zebra_import_table_route_map_check(
-                       afi, re->type, &rn->p, re->nexthop, re->vrf_id, re->tag,
-                       rmap_name);
+                       afi, re->type, &rn->p, re->ng.nexthop, re->vrf_id,
+                       re->tag, rmap_name);
 
        if (ret != RMAP_MATCH) {
                zebra_del_import_table_entry(rn, re);
@@ -552,7 +552,7 @@ int zebra_add_import_table_entry(struct route_node *rn, struct route_entry *re,
        newre->nexthop_num = 0;
        newre->uptime = time(NULL);
        newre->instance = re->table;
-       route_entry_copy_nexthops(newre, re->nexthop);
+       route_entry_copy_nexthops(newre, re->ng.nexthop);
 
        rib_add_multipath(afi, SAFI_UNICAST, &p, NULL, newre);
 
@@ -568,8 +568,8 @@ int zebra_del_import_table_entry(struct route_node *rn, struct route_entry *re)
        prefix_copy(&p, &rn->p);
 
        rib_delete(afi, SAFI_UNICAST, re->vrf_id, ZEBRA_ROUTE_TABLE, re->table,
-                  re->flags, &p, NULL, re->nexthop, zebrad.rtm_table_default,
-                  re->metric, false, NULL);
+                  re->flags, &p, NULL, re->ng.nexthop,
+                  zebrad.rtm_table_default, re->metric, false, NULL);
 
        return 0;
 }
index 5f03f1a1316fb3295b38bef62adf7098adde5860..5dd444dce013fc9ceb0f5de399fe30bb1ddeded1 100644 (file)
@@ -29,6 +29,7 @@
 #include "table.h"
 #include "queue.h"
 #include "nexthop.h"
+#include "nexthop_group.h"
 #include "vrf.h"
 #include "if.h"
 #include "mpls.h"
@@ -43,7 +44,7 @@ struct route_entry {
        struct route_entry *prev;
 
        /* Nexthop structure */
-       struct nexthop *nexthop;
+       struct nexthop_group ng;
 
        /* Tag */
        route_tag_t tag;
index e95665feb4e808780ef3f28d255f22b2ebaee24a..2b758c58d84af71bdacb9fabb98f3fada0fd939b 100644 (file)
@@ -1398,7 +1398,7 @@ static int netlink_route_multipath(int cmd, struct prefix *p,
        /* Count overall nexthops so we can decide whether to use singlepath
         * or multipath case. */
        nexthop_num = 0;
-       for (ALL_NEXTHOPS(re->nexthop, nexthop)) {
+       for (ALL_NEXTHOPS(re->ng, nexthop)) {
                if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
                        continue;
                if (cmd == RTM_NEWROUTE && !NEXTHOP_IS_ACTIVE(nexthop->flags))
@@ -1413,7 +1413,7 @@ static int netlink_route_multipath(int cmd, struct prefix *p,
        /* Singlepath case. */
        if (nexthop_num == 1 || multipath_num == 1) {
                nexthop_num = 0;
-               for (ALL_NEXTHOPS(re->nexthop, nexthop)) {
+               for (ALL_NEXTHOPS(re->ng, nexthop)) {
                        /*
                         * So we want to cover 2 types of blackhole
                         * routes here:
@@ -1513,7 +1513,7 @@ static int netlink_route_multipath(int cmd, struct prefix *p,
                rtnh = RTA_DATA(rta);
 
                nexthop_num = 0;
-               for (ALL_NEXTHOPS(re->nexthop, nexthop)) {
+               for (ALL_NEXTHOPS(re->ng, nexthop)) {
                        if (nexthop_num >= multipath_num)
                                break;
 
index 1aa402672ea61365298480e2290b9fc9f9ddb74e..433faf789afe925b9017cc1cafea30ae5eb123a1 100644 (file)
@@ -123,7 +123,7 @@ static int kernel_rtm_ipv4(int cmd, struct prefix *p, struct route_entry *re)
 #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
 
        /* Make gateway. */
-       for (ALL_NEXTHOPS(re->nexthop, nexthop)) {
+       for (ALL_NEXTHOPS(re->ng, nexthop)) {
                if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
                        continue;
 
@@ -303,7 +303,7 @@ static int kernel_rtm_ipv6(int cmd, struct prefix *p, struct route_entry *re)
 #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
 
        /* Make gateway. */
-       for (ALL_NEXTHOPS(re->nexthop, nexthop)) {
+       for (ALL_NEXTHOPS(re->ng, nexthop)) {
                if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
                        continue;
 
index 27c789137263b48533a4d92068d510dbab50d947..97a0e142fb336e8235747e7443ec8cfee3be45d2 100644 (file)
@@ -249,7 +249,7 @@ static int netlink_route_info_fill(netlink_route_info_t *ri, int cmd,
        ri->rtm_type = RTN_UNICAST;
        ri->metric = &re->metric;
 
-       for (ALL_NEXTHOPS(re->nexthop, nexthop)) {
+       for (ALL_NEXTHOPS(re->ng, nexthop)) {
                if (ri->num_nhs >= multipath_num)
                        break;
 
index b850f1fb1e12f3ad3c862a9199c3c2b700273c93..e661b6efc77748065d9b17c1b73b2e364475c813 100644 (file)
@@ -170,7 +170,7 @@ static Fpm__AddRoute *create_add_route_message(qpb_allocator_t *allocator,
         * Figure out the set of nexthops to be added to the message.
         */
        num_nhs = 0;
-       for (ALL_NEXTHOPS(re->nexthop, nexthop)) {
+       for (ALL_NEXTHOPS(re->ng, nexthop)) {
                if (num_nhs >= multipath_num)
                        break;
 
index 2dc98127f565e78ed15ed3aecc1af49cd003c6a4..0af06806d3481bc2c6572000c1401a7eff227cd9 100644 (file)
@@ -182,7 +182,7 @@ static int lsp_install(struct zebra_vrf *zvrf, mpls_label_t label,
         * the label advertised by the recursive nexthop (plus we don't have the
         * logic yet to push multiple labels).
         */
-       for (nexthop = re->nexthop; nexthop; nexthop = nexthop->next) {
+       for (nexthop = re->ng.nexthop; nexthop; nexthop = nexthop->next) {
                /* Skip inactive and recursive entries. */
                if (!CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE))
                        continue;
@@ -637,7 +637,7 @@ static int nhlfe_nexthop_active_ipv4(zebra_nhlfe_t *nhlfe,
                    || !CHECK_FLAG(match->flags, ZEBRA_FLAG_SELECTED))
                        continue;
 
-               for (match_nh = match->nexthop; match_nh;
+               for (match_nh = match->ng.nexthop; match_nh;
                     match_nh = match_nh->next) {
                        if (match->type == ZEBRA_ROUTE_CONNECT
                            || nexthop->ifindex == match_nh->ifindex) {
@@ -688,10 +688,10 @@ static int nhlfe_nexthop_active_ipv6(zebra_nhlfe_t *nhlfe,
                        break;
        }
 
-       if (!match || !match->nexthop)
+       if (!match || !match->ng.nexthop)
                return 0;
 
-       nexthop->ifindex = match->nexthop->ifindex;
+       nexthop->ifindex = match->ng.nexthop->ifindex;
        return 1;
 }
 
@@ -2286,7 +2286,7 @@ int mpls_ftn_update(int add, struct zebra_vrf *zvrf, enum lsp_types_t type,
        if (re == NULL)
                return -1;
 
-       for (nexthop = re->nexthop; nexthop; nexthop = nexthop->next) {
+       for (nexthop = re->ng.nexthop; nexthop; nexthop = nexthop->next) {
                switch (nexthop->type) {
                case NEXTHOP_TYPE_IPV4:
                case NEXTHOP_TYPE_IPV4_IFINDEX:
@@ -2504,7 +2504,7 @@ void mpls_ldp_ftn_uninstall_all(struct zebra_vrf *zvrf, int afi)
        for (rn = route_top(table); rn; rn = route_next(rn)) {
                update = 0;
                RNODE_FOREACH_RE (rn, re) {
-                       for (nexthop = re->nexthop; nexthop;
+                       for (nexthop = re->ng.nexthop; nexthop;
                             nexthop = nexthop->next) {
                                if (nexthop->nh_label_type != ZEBRA_LSP_LDP)
                                        continue;
index 96bee36be6eaba3de0e7c8b211f79b10b5ed8ebe..68ad69397f7dfd55503d3baae1cb47ee39b56330 100644 (file)
@@ -256,7 +256,7 @@ static int zebra_pw_check_reachability(struct zebra_pw *pw)
         * Need to ensure that there's a label binding for all nexthops.
         * Otherwise, ECMP for this route could render the pseudowire unusable.
         */
-       for (ALL_NEXTHOPS(re->nexthop, nexthop)) {
+       for (ALL_NEXTHOPS(re->ng, nexthop)) {
                if (!nexthop->nh_label) {
                        if (IS_ZEBRA_DEBUG_PW)
                                zlog_warn("%s: unlabeled route for %s",
index c5906f5829c86a5b5a617ea40dda8372a704a0ca..1204da92fb3b608eb5e8c46dd37ba79162a08ec0 100644 (file)
@@ -183,7 +183,7 @@ int zebra_check_addr(struct prefix *p)
 /* Add nexthop to the end of a rib node's nexthop list */
 void route_entry_nexthop_add(struct route_entry *re, struct nexthop *nexthop)
 {
-       nexthop_add(&re->nexthop, nexthop);
+       nexthop_add(&re->ng.nexthop, nexthop);
        re->nexthop_num++;
 }
 
@@ -193,8 +193,8 @@ void route_entry_nexthop_add(struct route_entry *re, struct nexthop *nexthop)
  */
 void route_entry_copy_nexthops(struct route_entry *re, struct nexthop *nh)
 {
-       assert(!re->nexthop);
-       copy_nexthops(&re->nexthop, nh, NULL);
+       assert(!re->ng.nexthop);
+       copy_nexthops(&re->ng.nexthop, nh, NULL);
        for (struct nexthop *nexthop = nh; nexthop; nexthop = nexthop->next)
                re->nexthop_num++;
 }
@@ -207,7 +207,7 @@ void route_entry_nexthop_delete(struct route_entry *re, struct nexthop *nexthop)
        if (nexthop->prev)
                nexthop->prev->next = nexthop->next;
        else
-               re->nexthop = nexthop->next;
+               re->ng.nexthop = nexthop->next;
        re->nexthop_num--;
 }
 
@@ -507,7 +507,7 @@ static int nexthop_active(afi_t afi, struct route_entry *re,
 
                if (match->type == ZEBRA_ROUTE_CONNECT) {
                        /* Directly point connected route. */
-                       newhop = match->nexthop;
+                       newhop = match->ng.nexthop;
                        if (newhop) {
                                if (nexthop->type == NEXTHOP_TYPE_IPV4
                                    || nexthop->type == NEXTHOP_TYPE_IPV6)
@@ -516,7 +516,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(match->nexthop, newhop)) {
+                       for (ALL_NEXTHOPS(match->ng, newhop)) {
                                if (!CHECK_FLAG(newhop->flags,
                                                NEXTHOP_FLAG_FIB))
                                        continue;
@@ -539,7 +539,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(match->nexthop, newhop)) {
+                       for (ALL_NEXTHOPS(match->ng, newhop)) {
                                if (!CHECK_FLAG(newhop->flags,
                                                NEXTHOP_FLAG_FIB))
                                        continue;
@@ -610,7 +610,7 @@ struct route_entry *rib_match(afi_t afi, safi_t safi, vrf_id_t vrf_id,
                } else {
                        if (match->type != ZEBRA_ROUTE_CONNECT) {
                                int found = 0;
-                               for (ALL_NEXTHOPS(match->nexthop, newhop))
+                               for (ALL_NEXTHOPS(match->ng, newhop))
                                        if (CHECK_FLAG(newhop->flags,
                                                       NEXTHOP_FLAG_FIB)) {
                                                found = 1;
@@ -733,7 +733,7 @@ struct route_entry *rib_lookup_ipv4(struct prefix_ipv4 *p, vrf_id_t vrf_id)
        if (match->type == ZEBRA_ROUTE_CONNECT)
                return match;
 
-       for (ALL_NEXTHOPS(match->nexthop, nexthop))
+       for (ALL_NEXTHOPS(match->ng, nexthop))
                if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB))
                        return match;
 
@@ -793,7 +793,7 @@ int rib_lookup_ipv4_route(struct prefix_ipv4 *p, union sockunion *qgate,
 
        /* Ok, we have a cood candidate, let's check it's nexthop list... */
        nexthops_active = 0;
-       for (ALL_NEXTHOPS(match->nexthop, nexthop))
+       for (ALL_NEXTHOPS(match->ng, nexthop))
                if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB)) {
                        nexthops_active = 1;
                        if (nexthop->gate.ipv4.s_addr == sockunion2ip(qgate))
@@ -959,7 +959,7 @@ static int nexthop_active_update(struct route_node *rn, struct route_entry *re,
        re->nexthop_active_num = 0;
        UNSET_FLAG(re->status, ROUTE_ENTRY_CHANGED);
 
-       for (nexthop = re->nexthop; nexthop; nexthop = nexthop->next) {
+       for (nexthop = re->ng.nexthop; nexthop; nexthop = nexthop->next) {
                /* No protocol daemon provides src and so we're skipping
                 * tracking it */
                prev_src = nexthop->rmap_src;
@@ -1003,7 +1003,7 @@ int zebra_rib_labeled_unicast(struct route_entry *re)
        if (re->type != ZEBRA_ROUTE_BGP)
                return 0;
 
-       for (ALL_NEXTHOPS(re->nexthop, nexthop))
+       for (ALL_NEXTHOPS(re->ng, nexthop))
                if (!nexthop->nh_label || !nexthop->nh_label->num_labels)
                        return 0;
 
@@ -1023,7 +1023,7 @@ void kernel_route_rib_pass_fail(struct route_node *rn, struct prefix *p,
        switch (res) {
        case SOUTHBOUND_INSTALL_SUCCESS:
                dest->selected_fib = re;
-               for (ALL_NEXTHOPS(re->nexthop, nexthop)) {
+               for (ALL_NEXTHOPS(re->ng, nexthop)) {
                        if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
                                continue;
 
@@ -1056,7 +1056,7 @@ void kernel_route_rib_pass_fail(struct route_node *rn, struct prefix *p,
                 */
                if (dest->selected_fib == re)
                        dest->selected_fib = NULL;
-               for (ALL_NEXTHOPS(re->nexthop, nexthop))
+               for (ALL_NEXTHOPS(re->ng, nexthop))
                        UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB);
 
                zsend_route_notify_owner(re, p, ZAPI_ROUTE_REMOVED);
@@ -1089,15 +1089,15 @@ void rib_install_kernel(struct route_node *rn, struct route_entry *re,
        srcdest_rnode_prefixes(rn, &p, &src_p);
 
        if (info->safi != SAFI_UNICAST) {
-               for (ALL_NEXTHOPS(re->nexthop, nexthop))
+               for (ALL_NEXTHOPS(re->ng, nexthop))
                        SET_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB);
                return;
        } else {
                struct nexthop *prev;
 
-               for (ALL_NEXTHOPS(re->nexthop, nexthop)) {
-                       UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_DUPLICATE);
-                       for (ALL_NEXTHOPS(re->nexthop, prev)) {
+               for (ALL_NEXTHOPS(re->ng, nexthop)) {
+                       UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_DUPLICATE);
+                       for (ALL_NEXTHOPS(re->ng, prev)) {
                                if (prev == nexthop)
                                        break;
                                if (nexthop_same_firsthop(nexthop, prev)) {
@@ -1138,7 +1138,7 @@ void rib_uninstall_kernel(struct route_node *rn, struct route_entry *re)
        srcdest_rnode_prefixes(rn, &p, &src_p);
 
        if (info->safi != SAFI_UNICAST) {
-               for (ALL_NEXTHOPS(re->nexthop, nexthop))
+               for (ALL_NEXTHOPS(re->ng, nexthop))
                        UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB);
                return;
        }
@@ -1388,7 +1388,7 @@ static void rib_process_update_fib(struct zebra_vrf *zvrf,
                                        if (!RIB_SYSTEM_ROUTE(old))
                                                rib_uninstall_kernel(rn, old);
                                } else {
-                                       for (nexthop = old->nexthop; nexthop;
+                                       for (nexthop = old->ng.nexthop; nexthop;
                                             nexthop = nexthop->next)
                                                UNSET_FLAG(nexthop->flags,
                                                           NEXTHOP_FLAG_FIB);
@@ -1444,7 +1444,7 @@ static void rib_process_update_fib(struct zebra_vrf *zvrf,
                if (!RIB_SYSTEM_ROUTE(new)) {
                        bool in_fib = false;
 
-                       for (ALL_NEXTHOPS(new->nexthop, nexthop))
+                       for (ALL_NEXTHOPS(new->ng, nexthop))
                                if (CHECK_FLAG(nexthop->flags,
                                               NEXTHOP_FLAG_FIB)) {
                                        in_fib = true;
@@ -1676,13 +1676,16 @@ static void rib_process(struct route_node *rn)
 
        /* Redistribute SELECTED entry */
        if (old_selected != new_selected || selected_changed) {
-               struct nexthop *nexthop;
+               struct nexthop *nexthop = NULL;
 
                /* Check if we have a FIB route for the destination, otherwise,
                 * don't redistribute it */
-               for (ALL_NEXTHOPS(new_fib ? new_fib->nexthop : NULL, nexthop)) {
-                       if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB)) {
-                               break;
+               if (new_fib) {
+                       for (ALL_NEXTHOPS(new_fib->ng, nexthop)) {
+                               if (CHECK_FLAG(nexthop->flags,
+                                              NEXTHOP_FLAG_FIB)) {
+                                       break;
+                               }
                        }
                }
                if (!nexthop)
@@ -2116,9 +2119,9 @@ void rib_unlink(struct route_node *rn, struct route_entry *re)
 
        /* free RE and nexthops */
        if (re->type == ZEBRA_ROUTE_STATIC)
-               zebra_deregister_rnh_static_nexthops(re->vrf_id, re->nexthop,
+               zebra_deregister_rnh_static_nexthops(re->vrf_id, re->ng.nexthop,
                                                     rn);
-       nexthops_free(re->nexthop);
+       nexthops_free(re->ng.nexthop);
        XFREE(MTYPE_RE, re);
 }
 
@@ -2182,7 +2185,7 @@ void _route_entry_dump(const char *func, union prefixconstptr pp,
        zlog_debug("%s: nexthop_num == %u, nexthop_active_num == %u", func,
                   re->nexthop_num, re->nexthop_active_num);
 
-       for (ALL_NEXTHOPS(re->nexthop, nexthop)) {
+       for (ALL_NEXTHOPS(re->ng, nexthop)) {
                inet_ntop(p->family, &nexthop->gate, straddr, INET6_ADDRSTRLEN);
                zlog_debug("%s: %s %s[%u] with flags %s%s%s", func,
                           (nexthop->rparent ? "  NH" : "NH"), straddr,
@@ -2357,7 +2360,7 @@ int rib_add_multipath(afi_t afi, safi_t safi, struct prefix *p,
 
        /* If this route is kernel route, set FIB flag to the route. */
        if (RIB_SYSTEM_ROUTE(re))
-               for (nexthop = re->nexthop; nexthop; nexthop = nexthop->next)
+               for (nexthop = re->ng.nexthop; nexthop; nexthop = nexthop->next)
                        SET_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB);
 
        /* Link new re to node.*/
@@ -2443,7 +2446,7 @@ void rib_delete(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
                        continue;
                if (re->type == ZEBRA_ROUTE_KERNEL && re->metric != metric)
                        continue;
-               if (re->type == ZEBRA_ROUTE_CONNECT && (rtnh = re->nexthop)
+               if (re->type == ZEBRA_ROUTE_CONNECT && (rtnh = re->ng.nexthop)
                    && rtnh->type == NEXTHOP_TYPE_IFINDEX && nh) {
                        if (rtnh->ifindex != nh->ifindex)
                                continue;
@@ -2456,7 +2459,7 @@ void rib_delete(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
                                same = re;
                                break;
                        }
-                       for (ALL_NEXTHOPS(re->nexthop, rtnh))
+                       for (ALL_NEXTHOPS(re->ng, rtnh))
                                if (nexthop_same_no_recurse(rtnh, nh)) {
                                        same = re;
                                        break;
@@ -2493,7 +2496,7 @@ void rib_delete(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
                        }
                        if (allow_delete) {
                                /* Unset flags. */
-                               for (rtnh = fib->nexthop; rtnh;
+                               for (rtnh = fib->ng.nexthop; rtnh;
                                     rtnh = rtnh->next)
                                        UNSET_FLAG(rtnh->flags,
                                                   NEXTHOP_FLAG_FIB);
@@ -2547,7 +2550,7 @@ void rib_delete(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
                if (CHECK_FLAG(flags, ZEBRA_FLAG_EVPN_ROUTE)) {
                        struct nexthop *tmp_nh;
 
-                       for (ALL_NEXTHOPS(re->nexthop, tmp_nh)) {
+                       for (ALL_NEXTHOPS(re->ng, tmp_nh)) {
                                struct ipaddr vtep_ip;
 
                                memset(&vtep_ip, 0, sizeof(struct ipaddr));
@@ -2642,7 +2645,7 @@ static void rib_update_table(struct route_table *table,
                                        continue;
                                }
 
-                               for (nh = re->nexthop; nh; nh = nh->next)
+                               for (nh = re->ng.nexthop; nh; nh = nh->next)
                                        if (!(nh->type == NEXTHOP_TYPE_IPV4
                                              || nh->type == NEXTHOP_TYPE_IPV6))
                                                break;
@@ -2759,7 +2762,7 @@ static void rib_sweep_table(struct route_table *table)
                         * to a different spot (ie startup )
                         * this decision needs to be revisited
                         */
-                       for (ALL_NEXTHOPS(re->nexthop, nexthop))
+                       for (ALL_NEXTHOPS(re->ng, nexthop))
                                SET_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB);
 
                        rib_uninstall_kernel(rn, re);
index 1e9fe875e10a88d2add5c75f93addf1e416cf672..dd3fe17702c0a2113b63958f3b7cb13de449c9b5 100644 (file)
@@ -355,7 +355,8 @@ static int zebra_rnh_apply_nht_rmap(int family, struct route_node *prn,
        rmap_family = (family == AF_INET) ? AFI_IP : AFI_IP6;
 
        if (prn && re) {
-               for (nexthop = re->nexthop; nexthop; nexthop = nexthop->next) {
+               for (nexthop = re->ng.nexthop; nexthop;
+                    nexthop = nexthop->next) {
                        ret = zebra_nht_route_map_check(rmap_family, proto,
                                                        &prn->p, re, nexthop);
                        if (ret != RMAP_DENYMATCH) {
@@ -428,7 +429,7 @@ static void zebra_rnh_eval_import_check_entry(vrf_id_t vrfid, int family,
        struct nexthop *nexthop;
 
        if (re && (rnh->state == NULL)) {
-               for (ALL_NEXTHOPS(re->nexthop, nexthop))
+               for (ALL_NEXTHOPS(re->ng, nexthop))
                        if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB)) {
                                state_changed = 1;
                                break;
@@ -559,7 +560,7 @@ static void zebra_rnh_process_static_routes(vrf_id_t vrfid, int family,
                         * be having multiple. We care here only about
                         * registered nexthops.
                         */
-                       for (nexthop = sre->nexthop; nexthop;
+                       for (nexthop = sre->ng.nexthop; nexthop;
                             nexthop = nexthop->next) {
                                switch (nexthop->type) {
                                case NEXTHOP_TYPE_IPV4:
@@ -673,7 +674,7 @@ zebra_rnh_resolve_nexthop_entry(vrf_id_t vrfid, int family,
                                if (re->type == ZEBRA_ROUTE_NHRP) {
                                        struct nexthop *nexthop;
 
-                                       for (nexthop = re->nexthop; nexthop;
+                                       for (nexthop = re->ng.nexthop; nexthop;
                                             nexthop = nexthop->next)
                                                if (nexthop->type
                                                    == NEXTHOP_TYPE_IFINDEX)
@@ -925,8 +926,8 @@ static void free_state(vrf_id_t vrf_id, struct route_entry *re,
                return;
 
        /* free RE and nexthops */
-       zebra_deregister_rnh_static_nexthops(vrf_id, re->nexthop, rn);
-       nexthops_free(re->nexthop);
+       zebra_deregister_rnh_static_nexthops(vrf_id, re->ng.nexthop, rn);
+       nexthops_free(re->ng.nexthop);
        XFREE(MTYPE_RE, re);
 }
 
@@ -949,7 +950,7 @@ static void copy_state(struct rnh *rnh, struct route_entry *re,
        state->metric = re->metric;
        state->vrf_id = re->vrf_id;
 
-       route_entry_copy_nexthops(state, re->nexthop);
+       route_entry_copy_nexthops(state, re->ng.nexthop);
        rnh->state = state;
 }
 
@@ -1022,7 +1023,7 @@ static int send_client(struct rnh *rnh, struct zserv *client, rnh_type_t type,
                num = 0;
                nump = stream_get_endp(s);
                stream_putc(s, 0);
-               for (nexthop = re->nexthop; nexthop; nexthop = nexthop->next)
+               for (nexthop = re->ng.nexthop; nexthop; nexthop = nexthop->next)
                        if ((CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB)
                             || CHECK_FLAG(nexthop->flags,
                                           NEXTHOP_FLAG_RECURSIVE))
@@ -1115,7 +1116,7 @@ static void print_rnh(struct route_node *rn, struct vty *vty)
        if (rnh->state) {
                vty_out(vty, " resolved via %s\n",
                        zebra_route_string(rnh->state->type));
-               for (nexthop = rnh->state->nexthop; nexthop;
+               for (nexthop = rnh->state->ng.nexthop; nexthop;
                     nexthop = nexthop->next)
                        print_nh(nexthop, vty);
        } else
index 48218effd1090283aea0c2fd96db4827e7f68494..3ab208d30b545edde7eade49f45e2e093c49032b 100644 (file)
@@ -285,8 +285,8 @@ static void check_replace(struct route_node *np2, struct route_entry *re2,
                return;
        }
 
-       if (in_addr_cmp((u_char *)&(*re)->nexthop->gate.ipv4,
-                       (u_char *)&re2->nexthop->gate.ipv4)
+       if (in_addr_cmp((u_char *)&(*re)->ng.nexthop->gate.ipv4,
+                       (u_char *)&re2->ng.nexthop->gate.ipv4)
            <= 0)
                return;
 
@@ -370,9 +370,9 @@ static void get_fwtable_route_node(struct variable *v, oid objid[],
                for (*np = route_top(table); *np; *np = route_next(*np)) {
                        if (!in_addr_cmp(&(*np)->p.u.prefix, (u_char *)&dest)) {
                                RNODE_FOREACH_RE (*np, *re) {
-                                       if (!in_addr_cmp((u_char *)&(*re)
-                                                                ->nexthop->gate
-                                                                .ipv4,
+                                       if (!in_addr_cmp(
+                                                   (u_char *)&(*re)
+                                                   ->ng.nexthop->gate.ipv4,
                                                         (u_char *)&nexthop))
                                                if (proto
                                                    == proto_trans((*re)->type))
@@ -404,9 +404,10 @@ static void get_fwtable_route_node(struct variable *v, oid objid[],
                                if ((policy < policy2)
                                    || ((policy == policy2) && (proto < proto2))
                                    || ((policy == policy2) && (proto == proto2)
-                                       && (in_addr_cmp((u_char *)&re2->nexthop
-                                                               ->gate.ipv4,
-                                                       (u_char *)&nexthop)
+                                       && (in_addr_cmp(
+                                                   (u_char *)&re2->ng.nexthop
+                                                   ->gate.ipv4,
+                                                   (u_char *)&nexthop)
                                            >= 0)))
                                        check_replace(np2, re2, np, re);
                        }
@@ -430,7 +431,7 @@ static void get_fwtable_route_node(struct variable *v, oid objid[],
        {
                struct nexthop *nexthop;
 
-               nexthop = (*re)->nexthop;
+               nexthop = (*re)->ng.nexthop;
                if (nexthop) {
                        pnt = (u_char *)&nexthop->gate.ipv4;
                        for (i = 0; i < 4; i++)
@@ -459,7 +460,7 @@ static u_char *ipFwTable(struct variable *v, oid objid[], size_t *objid_len,
        if (!np)
                return NULL;
 
-       nexthop = re->nexthop;
+       nexthop = re->ng.nexthop;
        if (!nexthop)
                return NULL;
 
index b4c5b70da04dcee936f242611d629a01c2b7f811..f3921790a6c97e2b24c19c0448a6f98cac4cac6e 100644 (file)
@@ -300,7 +300,7 @@ void static_uninstall_route(afi_t afi, safi_t safi, struct prefix *p,
        }
 
        /* Lookup nexthop. */
-       for (nexthop = re->nexthop; nexthop; nexthop = nexthop->next)
+       for (nexthop = re->ng.nexthop; nexthop; nexthop = nexthop->next)
                if (static_nexthop_same(nexthop, si))
                        break;
 
index 582ff3110bef5a3a595961d4ff428df5547cee19..9fe3c707bb1367f5e68daa940c12e79ecffb7869 100644 (file)
@@ -743,7 +743,7 @@ static void vty_show_ip_route_detail(struct vty *vty, struct route_node *rn,
                                tm->tm_hour);
                vty_out(vty, " ago\n");
 
-               for (ALL_NEXTHOPS(re->nexthop, nexthop)) {
+               for (ALL_NEXTHOPS(re->ng, nexthop)) {
                        char addrstr[32];
 
                        vty_out(vty, "  %c%s",
@@ -922,7 +922,7 @@ static void vty_show_ip_route(struct vty *vty, struct route_node *rn,
 
                json_object_string_add(json_route, "uptime", buf);
 
-               for (ALL_NEXTHOPS(re->nexthop, nexthop)) {
+               for (ALL_NEXTHOPS(re->ng, nexthop)) {
                        json_nexthop = json_object_new_object();
 
                        if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_DUPLICATE))
@@ -1088,8 +1088,8 @@ static void vty_show_ip_route(struct vty *vty, struct route_node *rn,
        }
 
        /* Nexthop information. */
-       for (ALL_NEXTHOPS(re->nexthop, nexthop)) {
-               if (nexthop == re->nexthop) {
+       for (ALL_NEXTHOPS(re->ng, nexthop)) {
+               if (nexthop == re->ng.nexthop) {
                        /* Prefix information. */
                        len = vty_out(vty, "%c", zebra_route_char(re->type));
                        if (re->instance)
@@ -1842,7 +1842,7 @@ static void vty_show_ip_route_summary_prefix(struct vty *vty,
                         * In case of ECMP, count only once.
                         */
                        cnt = 0;
-                       for (nexthop = re->nexthop; (!cnt && nexthop);
+                       for (nexthop = re->ng.nexthop; (!cnt && nexthop);
                             nexthop = nexthop->next) {
                                cnt++;
                                rib_cnt[ZEBRA_ROUTE_TOTAL]++;
index d245e097244a1ae14d19b3d6a30bda58815302d5..0485aadde1ba78a23465d2a42ca3f63b2f8df580 100644 (file)
@@ -616,7 +616,7 @@ int zsend_redistribute_route(int cmd, struct zserv *client, struct prefix *p,
                SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP);
                api.nexthop_num = re->nexthop_active_num;
        }
-       for (nexthop = re->nexthop; nexthop; nexthop = nexthop->next) {
+       for (nexthop = re->ng.nexthop; nexthop; nexthop = nexthop->next) {
                if (!CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE))
                        continue;
 
@@ -978,7 +978,7 @@ static int zsend_ipv4_nexthop_lookup_mrib(struct zserv *client,
                 * we
                 * are looking up. Therefore, we will just iterate over the top
                 * chain of nexthops. */
-               for (nexthop = re->nexthop; nexthop; nexthop = nexthop->next)
+               for (nexthop = re->ng.nexthop; nexthop; nexthop = nexthop->next)
                        if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE))
                                num += zsend_write_nexthop(s, nexthop);
 
@@ -1236,7 +1236,7 @@ static int zread_route_add(struct zserv *client, u_short length,
                                zlog_warn(
                                        "%s: Nexthops Specified: %d but we failed to properly create one",
                                        __PRETTY_FUNCTION__, api.nexthop_num);
-                               nexthops_free(re->nexthop);
+                               nexthops_free(re->ng.nexthop);
                                XFREE(MTYPE_RE, re);
                                return -1;
                        }
@@ -1268,7 +1268,7 @@ static int zread_route_add(struct zserv *client, u_short length,
        if (afi != AFI_IP6 && CHECK_FLAG(api.message, ZAPI_MESSAGE_SRCPFX)) {
                zlog_warn("%s: Received SRC Prefix but afi is not v6",
                          __PRETTY_FUNCTION__);
-               nexthops_free(re->nexthop);
+               nexthops_free(re->ng.nexthop);
                XFREE(MTYPE_RE, re);
                return -1;
        }
@@ -1437,7 +1437,7 @@ static int zread_ipv4_add(struct zserv *client, u_short length,
                                zlog_warn(
                                        "%s: Please use ZEBRA_ROUTE_ADD if you want to pass v6 nexthops",
                                        __PRETTY_FUNCTION__);
-                               nexthops_free(re->nexthop);
+                               nexthops_free(re->ng.nexthop);
                                XFREE(MTYPE_RE, re);
                                return -1;
                                break;
@@ -1448,7 +1448,7 @@ static int zread_ipv4_add(struct zserv *client, u_short length,
                                zlog_warn(
                                        "%s: Specified nexthop type: %d does not exist",
                                        __PRETTY_FUNCTION__, nexthop_type);
-                               nexthops_free(re->nexthop);
+                               nexthops_free(re->ng.nexthop);
                                XFREE(MTYPE_RE, re);
                                return -1;
                        }
@@ -1488,7 +1488,7 @@ static int zread_ipv4_add(struct zserv *client, u_short length,
        return 0;
 
 stream_failure:
-       nexthops_free(re->nexthop);
+       nexthops_free(re->ng.nexthop);
        XFREE(MTYPE_RE, re);
        return -1;
 }
@@ -1654,7 +1654,7 @@ static int zread_ipv4_route_ipv6_nexthop_add(struct zserv *client,
                                zlog_warn(
                                        "%s: Please use ZEBRA_ROUTE_ADD if you want to pass non v6 nexthops",
                                        __PRETTY_FUNCTION__);
-                               nexthops_free(re->nexthop);
+                               nexthops_free(re->ng.nexthop);
                                XFREE(MTYPE_RE, re);
                                return -1;
                        }
@@ -1717,7 +1717,7 @@ static int zread_ipv4_route_ipv6_nexthop_add(struct zserv *client,
        return 0;
 
 stream_failure:
-       nexthops_free(re->nexthop);
+       nexthops_free(re->ng.nexthop);
        XFREE(MTYPE_RE, re);
        return -1;
 }
@@ -1850,7 +1850,7 @@ static int zread_ipv6_add(struct zserv *client, u_short length,
                                zlog_warn(
                                        "%s: Please use ZEBRA_ROUTE_ADD if you want to pass non v6 nexthops",
                                        __PRETTY_FUNCTION__);
-                               nexthops_free(re->nexthop);
+                               nexthops_free(re->ng.nexthop);
                                XFREE(MTYPE_RE, re);
                                return -1;
                        }
@@ -1911,7 +1911,7 @@ static int zread_ipv6_add(struct zserv *client, u_short length,
        return 0;
 
 stream_failure:
-       nexthops_free(re->nexthop);
+       nexthops_free(re->ng.nexthop);
        XFREE(MTYPE_RE, re);
 
        return -1;