return "UNKNOWN";
}
-static struct isis_vertex *isis_vertex_new(union isis_N *n,
+static struct isis_vertex *isis_vertex_new(struct isis_spftree *spftree,
+ union isis_N *n,
enum vertextype vtype)
{
struct isis_vertex *vertex;
vertex->Adj_N = list_new();
vertex->parents = list_new();
+ if (spftree->hopcount_metric) {
+ vertex->firsthops = hash_create(isis_vertex_queue_hash_key,
+ isis_vertex_queue_hash_cmp,
+ NULL);
+ }
+
return vertex;
}
zlog_warn("ISIS-Spf: could not find own l%d LSP!",
spftree->level);
- vertex = isis_vertex_new(&n,
+ vertex = isis_vertex_new(spftree, &n,
spftree->area->oldmetric
? VTYPE_NONPSEUDO_IS
: VTYPE_NONPSEUDO_TE_IS);
return vertex;
}
+static void vertex_add_parent_firsthop(struct hash_backet *backet, void *arg)
+{
+ struct isis_vertex *vertex = arg;
+ struct isis_vertex *hop = backet->data;
+
+ hash_get(vertex->firsthops, hop, hash_alloc_intern);
+}
+
+static void vertex_update_firsthops(struct isis_vertex *vertex,
+ struct isis_vertex *parent)
+{
+ if (vertex->d_N <= 2)
+ hash_get(vertex->firsthops, vertex, hash_alloc_intern);
+
+ if (vertex->d_N < 2 || !parent)
+ return;
+
+ hash_iterate(parent->firsthops, vertex_add_parent_firsthop, vertex);
+}
+
/*
* Add a vertex to TENT sorted by cost and by vertextype on tie break situation
*/
assert(isis_find_vertex(&spftree->paths, id, vtype) == NULL);
assert(isis_find_vertex(&spftree->tents, id, vtype) == NULL);
- vertex = isis_vertex_new(id, vtype);
+ vertex = isis_vertex_new(spftree, id, vtype);
vertex->d_N = cost;
vertex->depth = depth;
listnode_add(vertex->parents, parent);
}
+ if (spftree->hopcount_metric)
+ vertex_update_firsthops(vertex, parent);
+
if (parent && parent->Adj_N && listcount(parent->Adj_N) > 0) {
for (ALL_LIST_ELEMENTS_RO(parent->Adj_N, node, parent_adj))
listnode_add(vertex->Adj_N, parent_adj);
if (listnode_lookup(vertex->Adj_N, parent_adj)
== NULL)
listnode_add(vertex->Adj_N, parent_adj);
+ if (spftree->hopcount_metric)
+ vertex_update_firsthops(vertex, parent);
/* 2) */
if (listcount(vertex->Adj_N) > ISIS_MAX_PATH_SPLITS)
remove_excess_adjs(vertex->Adj_N);
isis_spf_preload_tent(spftree, sysid, root);
} else {
isis_vertex_queue_insert(&spftree->tents, isis_vertex_new(
- sysid, VTYPE_NONPSEUDO_TE_IS));
+ spftree, sysid,
+ VTYPE_NONPSEUDO_TE_IS));
}
isis_spf_loop(spftree, sysid);
uint16_t depth; /* The depth in the imaginary tree */
struct list *Adj_N; /* {Adj(N)} next hop or neighbor list */
struct list *parents; /* list of parents for ECMP */
+ struct hash *firsthops; /* first two hops to neighbor */
uint64_t insert_counter;
};
{
list_delete_and_null(&vertex->Adj_N);
list_delete_and_null(&vertex->parents);
+ if (vertex->firsthops) {
+ hash_clean(vertex->firsthops, NULL);
+ hash_free(vertex->firsthops);
+ vertex->firsthops = NULL;
+ }
memset(vertex, 0, sizeof(struct isis_vertex));
XFREE(MTYPE_ISIS_VERTEX, vertex);
static void setup_test_vertices(void)
{
+ struct isis_spftree t = {
+ };
union isis_N nid, nip = {
.ip.dest.family = AF_UNSPEC
};
nip.ip.dest.family = AF_INET;
nip.ip.dest.prefixlen = 24;
inet_pton(AF_INET, "192.168.1.0", &nip.ip.dest.u.prefix4);
- vertices[vertex_count] = isis_vertex_new(&nip, VTYPE_IPREACH_TE);
+ vertices[vertex_count] = isis_vertex_new(&t, &nip, VTYPE_IPREACH_TE);
vertices[vertex_count]->d_N = 20;
vertex_count++;
nip.ip.dest.family = AF_INET;
nip.ip.dest.prefixlen = 24;
inet_pton(AF_INET, "192.168.2.0", &nip.ip.dest.u.prefix4);
- vertices[vertex_count] = isis_vertex_new(&nip, VTYPE_IPREACH_TE);
+ vertices[vertex_count] = isis_vertex_new(&t, &nip, VTYPE_IPREACH_TE);
vertices[vertex_count]->d_N = 20;
vertex_count++;
memset(nid.id, 0, sizeof(nid.id));
nid.id[6] = 1;
- vertices[vertex_count] = isis_vertex_new(&nid, VTYPE_PSEUDO_TE_IS);
+ vertices[vertex_count] = isis_vertex_new(&t, &nid,
+ VTYPE_PSEUDO_TE_IS);
vertices[vertex_count]->d_N = 15;
vertex_count++;
memset(nid.id, 0, sizeof(nid.id));
nid.id[5] = 2;
- vertices[vertex_count] = isis_vertex_new(&nid, VTYPE_NONPSEUDO_TE_IS);
+ vertices[vertex_count] = isis_vertex_new(&t, &nid,
+ VTYPE_NONPSEUDO_TE_IS);
vertices[vertex_count]->d_N = 15;
vertex_count++;
nip.ip.dest.family = AF_INET;
nip.ip.dest.prefixlen = 24;
inet_pton(AF_INET, "192.168.3.0", &nip.ip.dest.u.prefix4);
- vertices[vertex_count] = isis_vertex_new(&nip, VTYPE_IPREACH_TE);
+ vertices[vertex_count] = isis_vertex_new(&t, &nip, VTYPE_IPREACH_TE);
vertices[vertex_count]->d_N = 20;
vertex_count++;
};