#include "thread.h"
#include "vrf.h"
#include "workqueue.h"
+#include "nexthop_group_private.h"
#include "zebra/zebra_router.h"
#include "zebra/connected.h"
/* 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->ng.nexthop, nexthop);
+ _nexthop_group_add_sorted(&re->ng, nexthop);
re->nexthop_num++;
}
/*
* rib_can_delete_dest
*
- * Returns TRUE if the given dest can be deleted from the table.
+ * Returns true if the given dest can be deleted from the table.
*/
static int rib_can_delete_dest(rib_dest_t *dest)
{
* Garbage collect the rib dest corresponding to the given route node
* if appropriate.
*
- * Returns TRUE if the dest was deleted, FALSE otherwise.
+ * Returns true if the dest was deleted, false otherwise.
*/
int rib_gc_dest(struct route_node *rn)
{
re->status, re->flags, re->distance,
re->metric);
- UNSET_FLAG(re->status, ROUTE_ENTRY_NEXTHOPS_CHANGED);
-
/* Currently selected re. */
if (CHECK_FLAG(re->flags, ZEBRA_FLAG_SELECTED)) {
assert(old_selected == NULL);
continue;
SET_FLAG(re->status, ROUTE_ENTRY_INSTALLED);
+ UNSET_FLAG(re->status, ROUTE_ENTRY_QUEUED);
for (ALL_NEXTHOPS(re->ng, nhop)) {
if (CHECK_FLAG(nhop->flags, NEXTHOP_FLAG_RECURSIVE))
*/
nexthop = nexthop_new();
nexthop->type = NEXTHOP_TYPE_IPV4;
- nexthop_add(&(re->fib_ng.nexthop), nexthop);
+ _nexthop_add(&(re->fib_ng.nexthop), nexthop);
}
done:
afi = (rn->p.family == AF_INET)
? AFI_IP
: (rn->p.family == AF_INET6) ? AFI_IP6 : AFI_MAX;
- if (is_zebra_import_table_enabled(afi, re->table)) {
+ if (is_zebra_import_table_enabled(afi, re->vrf_id, re->table)) {
+ struct zebra_vrf *zvrf = zebra_vrf_lookup_by_id(re->vrf_id);
+
rmap_name = zebra_get_import_table_route_map(afi, re->table);
- zebra_add_import_table_entry(rn, re, rmap_name);
+ zebra_add_import_table_entry(zvrf, rn, re, rmap_name);
} else if (process)
rib_queue_add(rn);
}
afi = (rn->p.family == AF_INET)
? AFI_IP
: (rn->p.family == AF_INET6) ? AFI_IP6 : AFI_MAX;
- if (is_zebra_import_table_enabled(afi, re->table)) {
- zebra_del_import_table_entry(rn, re);
+ if (is_zebra_import_table_enabled(afi, re->vrf_id, re->table)) {
+ struct zebra_vrf *zvrf = zebra_vrf_lookup_by_id(re->vrf_id);
+
+ zebra_del_import_table_entry(zvrf, rn, re);
/* Just clean up if non main table */
if (IS_ZEBRA_DEBUG_RIB) {
char buf[SRCDEST2STR_BUFFER];
bool is_srcdst = src_p && src_p->prefixlen;
char straddr[PREFIX_STRLEN];
char srcaddr[PREFIX_STRLEN];
+ char nhname[PREFIX_STRLEN];
struct nexthop *nexthop;
zlog_debug("%s: dumping RE entry %p for %s%s%s vrf %u", func,
: "",
re->vrf_id);
zlog_debug("%s: uptime == %lu, type == %u, instance == %d, table == %d",
- func, (unsigned long)re->uptime, re->type, re->instance,
+ straddr, (unsigned long)re->uptime, re->type, re->instance,
re->table);
zlog_debug(
"%s: metric == %u, mtu == %u, distance == %u, flags == %u, status == %u",
- func, re->metric, re->mtu, re->distance, re->flags, re->status);
- zlog_debug("%s: nexthop_num == %u, nexthop_active_num == %u", func,
+ straddr, re->metric, re->mtu, re->distance, re->flags, re->status);
+ zlog_debug("%s: nexthop_num == %u, nexthop_active_num == %u", straddr,
re->nexthop_num, re->nexthop_active_num);
for (ALL_NEXTHOPS(re->ng, nexthop)) {
switch (nexthop->type) {
case NEXTHOP_TYPE_BLACKHOLE:
- sprintf(straddr, "Blackhole");
+ sprintf(nhname, "Blackhole");
break;
case NEXTHOP_TYPE_IFINDEX:
ifp = if_lookup_by_index(nexthop->ifindex,
nexthop->vrf_id);
- sprintf(straddr, "%s", ifp ? ifp->name : "Unknown");
+ sprintf(nhname, "%s", ifp ? ifp->name : "Unknown");
break;
case NEXTHOP_TYPE_IPV4:
/* fallthrough */
case NEXTHOP_TYPE_IPV4_IFINDEX:
- inet_ntop(AF_INET, &nexthop->gate, straddr,
+ inet_ntop(AF_INET, &nexthop->gate, nhname,
INET6_ADDRSTRLEN);
break;
case NEXTHOP_TYPE_IPV6:
case NEXTHOP_TYPE_IPV6_IFINDEX:
- inet_ntop(AF_INET6, &nexthop->gate, straddr,
+ inet_ntop(AF_INET6, &nexthop->gate, nhname,
INET6_ADDRSTRLEN);
break;
}
zlog_debug("%s: %s %s[%u] vrf %s(%u) with flags %s%s%s%s%s%s",
- func, (nexthop->rparent ? " NH" : "NH"), straddr,
+ straddr, (nexthop->rparent ? " NH" : "NH"), nhname,
nexthop->ifindex, vrf ? vrf->name : "Unknown",
nexthop->vrf_id,
(CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE)
? "DUPLICATE "
: ""));
}
- zlog_debug("%s: dump complete", func);
+ zlog_debug("%s: dump complete", straddr);
}
/* This is an exported helper to rtm_read() to dump the strange
else
src_buf[0] = '\0';
- if (IS_ZEBRA_DEBUG_RIB)
- zlog_debug("%u:%s%s%s doesn't exist in rib", vrf_id,
- dst_buf,
+ if (IS_ZEBRA_DEBUG_RIB) {
+ struct vrf *vrf = vrf_lookup_by_id(vrf_id);
+
+ zlog_debug("%s[%d]:%s%s%s doesn't exist in rib",
+ vrf->name, table_id, dst_buf,
(src_buf[0] != '\0') ? " from " : "",
src_buf);
+ }
return;
}
RIB_ROUTE_ANY_QUEUED))
continue;
switch (event) {
- case RIB_UPDATE_IF_CHANGE:
- /* Examine all routes that won't get processed by the
- * protocol or
- * triggered by nexthop evaluation (NHT). This would be
- * system,
- * kernel and certain static routes. Note that NHT will
- * get
- * triggered upon an interface event as connected routes
- * always
- * get queued for processing.
- */
- RNODE_FOREACH_RE_SAFE (rn, re, next) {
- struct nexthop *nh;
-
- if (re->type != ZEBRA_ROUTE_SYSTEM
- && re->type != ZEBRA_ROUTE_KERNEL
- && re->type != ZEBRA_ROUTE_CONNECT
- && re->type != ZEBRA_ROUTE_STATIC)
- continue;
-
- if (re->type != ZEBRA_ROUTE_STATIC) {
- SET_FLAG(re->status,
- ROUTE_ENTRY_CHANGED);
- rib_queue_add(rn);
- continue;
- }
-
- for (nh = re->ng.nexthop; nh; nh = nh->next)
- if (!(nh->type == NEXTHOP_TYPE_IPV4
- || nh->type == NEXTHOP_TYPE_IPV6))
- break;
-
- /* If we only have nexthops to a
- * gateway, NHT will
- * take care.
- */
- if (nh) {
- SET_FLAG(re->status,
- ROUTE_ENTRY_CHANGED);
- rib_queue_add(rn);
- }
- }
- break;
-
case RIB_UPDATE_RMAP_CHANGE:
case RIB_UPDATE_OTHER:
/* Right now, examine all routes. Can restrict to a
*
* Get the first vrf id that is greater than the given vrf id if any.
*
- * Returns TRUE if a vrf id was found, FALSE otherwise.
+ * Returns true if a vrf id was found, false otherwise.
*/
static inline int vrf_id_get_next(vrf_id_t vrf_id, vrf_id_t *next_id_p)
{