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>
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)
{
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);
--- /dev/null
+/*
+ * 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);
+ }
+}
--- /dev/null
+/*
+ * 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
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 \
lib/mpls.h \
lib/network.h \
lib/nexthop.h \
+ lib/nexthop_group.h \
lib/ns.h \
lib/openbsd-queue.h \
lib/openbsd-tree.h \
* 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 */
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);
}
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;
}
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);
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);
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;
}
#include "table.h"
#include "queue.h"
#include "nexthop.h"
+#include "nexthop_group.h"
#include "vrf.h"
#include "if.h"
#include "mpls.h"
struct route_entry *prev;
/* Nexthop structure */
- struct nexthop *nexthop;
+ struct nexthop_group ng;
/* Tag */
route_tag_t tag;
/* 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))
/* 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:
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;
#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;
#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;
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;
* 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;
* 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;
|| !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) {
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;
}
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:
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;
* 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",
/* 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++;
}
*/
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++;
}
if (nexthop->prev)
nexthop->prev->next = nexthop->next;
else
- re->nexthop = nexthop->next;
+ re->ng.nexthop = nexthop->next;
re->nexthop_num--;
}
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)
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;
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;
} 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;
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;
/* 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))
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;
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;
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;
*/
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);
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)) {
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;
}
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);
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;
/* 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)
/* 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);
}
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,
/* 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.*/
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;
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;
}
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);
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));
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;
* 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);
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) {
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;
* 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:
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)
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);
}
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;
}
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))
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
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;
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))
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);
}
{
struct nexthop *nexthop;
- nexthop = (*re)->nexthop;
+ nexthop = (*re)->ng.nexthop;
if (nexthop) {
pnt = (u_char *)&nexthop->gate.ipv4;
for (i = 0; i < 4; i++)
if (!np)
return NULL;
- nexthop = re->nexthop;
+ nexthop = re->ng.nexthop;
if (!nexthop)
return NULL;
}
/* 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;
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",
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))
}
/* 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)
* 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]++;
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;
* 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);
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;
}
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;
}
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;
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;
}
return 0;
stream_failure:
- nexthops_free(re->nexthop);
+ nexthops_free(re->ng.nexthop);
XFREE(MTYPE_RE, re);
return -1;
}
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;
}
return 0;
stream_failure:
- nexthops_free(re->nexthop);
+ nexthops_free(re->ng.nexthop);
XFREE(MTYPE_RE, re);
return -1;
}
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;
}
return 0;
stream_failure:
- nexthops_free(re->nexthop);
+ nexthops_free(re->ng.nexthop);
XFREE(MTYPE_RE, re);
return -1;