diff options
Diffstat (limited to 'isisd/isis_route.c')
| -rw-r--r-- | isisd/isis_route.c | 99 |
1 files changed, 71 insertions, 28 deletions
diff --git a/isisd/isis_route.c b/isisd/isis_route.c index 7b761f5cda..fa06572555 100644 --- a/isisd/isis_route.c +++ b/isisd/isis_route.c @@ -46,6 +46,7 @@ #include "isis_pdu.h" #include "isis_lsp.h" #include "isis_spf.h" +#include "isis_spf_private.h" #include "isis_route.h" #include "isis_zebra.h" @@ -158,6 +159,17 @@ static void adjinfo2nexthop(int family, struct list *nexthops, } } +static void isis_route_add_dummy_nexthops(struct isis_route_info *rinfo, + const uint8_t *sysid) +{ + struct isis_nexthop *nh; + + nh = XCALLOC(MTYPE_ISIS_NEXTHOP, sizeof(struct isis_nexthop)); + memcpy(nh->sysid, sysid, sizeof(nh->sysid)); + isis_sr_nexthop_reset(&nh->sr); + listnode_add(rinfo->nexthops, nh); +} + static struct isis_route_info *isis_route_info_new(struct prefix *prefix, struct prefix_ipv6 *src_p, uint32_t cost, @@ -165,13 +177,25 @@ static struct isis_route_info *isis_route_info_new(struct prefix *prefix, struct list *adjacencies) { struct isis_route_info *rinfo; - struct isis_adjacency *adj; + struct isis_vertex_adj *vadj; struct listnode *node; rinfo = XCALLOC(MTYPE_ISIS_ROUTE_INFO, sizeof(struct isis_route_info)); rinfo->nexthops = list_new(); - for (ALL_LIST_ELEMENTS_RO(adjacencies, node, adj)) { + for (ALL_LIST_ELEMENTS_RO(adjacencies, node, vadj)) { + struct isis_spf_adj *sadj = vadj->sadj; + struct isis_adjacency *adj = sadj->adj; + + /* + * Create dummy nexthops when running SPF on a testing + * environment. + */ + if (CHECK_FLAG(im->options, F_ISIS_UNIT_TEST)) { + isis_route_add_dummy_nexthops(rinfo, sadj->id); + continue; + } + /* check for force resync this route */ if (CHECK_FLAG(adj->circuit->flags, ISIS_CIRCUIT_FLAPPED_AFTER_SPF)) @@ -215,41 +239,51 @@ static void isis_route_info_delete(struct isis_route_info *route_info) XFREE(MTYPE_ISIS_ROUTE_INFO, route_info); } -static int isis_route_info_same_attrib(struct isis_route_info *new, - struct isis_route_info *old) -{ - if (new->cost != old->cost) - return 0; - if (new->depth != old->depth) - return 0; - - return 1; -} - static int isis_route_info_same(struct isis_route_info *new, - struct isis_route_info *old, uint8_t family) + struct isis_route_info *old, char *buf, + size_t buf_size) { struct listnode *node; struct isis_nexthop *nexthop; - if (!CHECK_FLAG(old->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED)) + if (new->cost != old->cost) { + if (buf) + snprintf(buf, buf_size, "cost (old: %u, new: %u)", + old->cost, new->cost); return 0; + } - if (CHECK_FLAG(new->flag, ISIS_ROUTE_FLAG_ZEBRA_RESYNC)) + if (new->depth != old->depth) { + if (buf) + snprintf(buf, buf_size, "depth (old: %u, new: %u)", + old->depth, new->depth); return 0; + } - if (!isis_route_info_same_attrib(new, old)) + if (new->nexthops->count != old->nexthops->count) { + if (buf) + snprintf(buf, buf_size, "nhops num (old: %u, new: %u)", + old->nexthops->count, new->nexthops->count); return 0; + } - for (ALL_LIST_ELEMENTS_RO(new->nexthops, node, nexthop)) + for (ALL_LIST_ELEMENTS_RO(new->nexthops, node, nexthop)) { if (!nexthoplookup(old->nexthops, nexthop->family, &nexthop->ip, - nexthop->ifindex)) + nexthop->ifindex)) { + if (buf) + snprintf(buf, buf_size, + "new nhop"); /* TODO: print nhop */ return 0; + } + } - for (ALL_LIST_ELEMENTS_RO(old->nexthops, node, nexthop)) - if (!nexthoplookup(new->nexthops, nexthop->family, &nexthop->ip, - nexthop->ifindex)) - return 0; + /* only the resync flag needs to be checked */ + if (CHECK_FLAG(new->flag, ISIS_ROUTE_FLAG_ZEBRA_RESYNC) + != CHECK_FLAG(old->flag, ISIS_ROUTE_FLAG_ZEBRA_RESYNC)) { + if (buf) + snprintf(buf, buf_size, "resync flag"); + return 0; + } return 1; } @@ -265,9 +299,8 @@ struct isis_route_info *isis_route_create(struct prefix *prefix, struct route_node *route_node; struct isis_route_info *rinfo_new, *rinfo_old, *route_info = NULL; char buff[PREFIX2STR_BUFFER]; - uint8_t family; + char change_buf[64]; - family = prefix->family; /* for debugs */ prefix2str(prefix, buff, sizeof(buff)); @@ -287,19 +320,25 @@ struct isis_route_info *isis_route_create(struct prefix *prefix, UNSET_FLAG(route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED); } else { route_unlock_node(route_node); +#ifdef EXTREME_DEBUG if (IS_DEBUG_RTE_EVENTS) zlog_debug("ISIS-Rte (%s) route already exists: %s", area->area_tag, buff); - if (isis_route_info_same(rinfo_new, rinfo_old, family)) { +#endif /* EXTREME_DEBUG */ + if (isis_route_info_same(rinfo_new, rinfo_old, change_buf, + sizeof(change_buf))) { +#ifdef EXTREME_DEBUG if (IS_DEBUG_RTE_EVENTS) zlog_debug("ISIS-Rte (%s) route unchanged: %s", area->area_tag, buff); +#endif /* EXTREME_DEBUG */ isis_route_info_delete(rinfo_new); route_info = rinfo_old; } else { if (IS_DEBUG_RTE_EVENTS) - zlog_debug("ISIS-Rte (%s) route changed: %s", - area->area_tag, buff); + zlog_debug( + "ISIS-Rte (%s): route changed: %s, change: %s", + area->area_tag, buff, change_buf); isis_route_info_delete(rinfo_old); route_info = rinfo_new; UNSET_FLAG(route_info->flag, @@ -377,7 +416,9 @@ static void _isis_route_verify_table(struct isis_area *area, { struct route_node *rnode, *drnode; struct isis_route_info *rinfo; +#ifdef EXTREME_DEBUG char buff[SRCDEST2STR_BUFFER]; +#endif /* EXTREME_DEBUG */ for (rnode = route_top(table); rnode; rnode = srcdest_route_next(rnode)) { @@ -392,6 +433,7 @@ static void _isis_route_verify_table(struct isis_area *area, (const struct prefix **)&dst_p, (const struct prefix **)&src_p); +#ifdef EXTREME_DEBUG if (IS_DEBUG_RTE_EVENTS) { srcdest2str(dst_p, src_p, buff, sizeof(buff)); zlog_debug( @@ -410,6 +452,7 @@ static void _isis_route_verify_table(struct isis_area *area, : "inactive"), buff); } +#endif /* EXTREME_DEBUG */ isis_route_update(area, dst_p, src_p, rinfo); |
