summaryrefslogtreecommitdiffstats
path: root/isisd
diff options
context:
space:
mode:
authorChristian Franke <chris@opensourcerouting.org>2018-05-10 18:52:17 +0200
committerChristian Franke <chris@opensourcerouting.org>2018-09-05 11:38:13 +0200
commitcbd8e49e3ead018b67f630752a37c44fae0697cc (patch)
treeb7caf2ac4408054be617d344172ec45b4f7d98f2 /isisd
parentfabricd: run a hop-by-hop spf (diff)
downloadfrr-cbd8e49e3ead018b67f630752a37c44fae0697cc.tar.xz
frr-cbd8e49e3ead018b67f630752a37c44fae0697cc.zip
isisd: move spf datastructures to a header, to share with fabricd
By moving the spf datastructures to a header, fabricd can access the results of the spf run for flooding optimization or fabric locality calculation. While this was deemed a sensible choice in this case, when compared with the option of adding a lot of OpenFabric specific code to isis_spf.c, the datastructures should still not be accessed randomly all over the code base. To make this more clear, the new header was called isis_spf_private.h (Think of a friend class) Signed-off-by: Christian Franke <chris@opensourcerouting.org>
Diffstat (limited to 'isisd')
-rw-r--r--isisd/isis_spf.c312
-rw-r--r--isisd/isis_spf_private.h351
-rw-r--r--isisd/subdir.am1
3 files changed, 364 insertions, 300 deletions
diff --git a/isisd/isis_spf.c b/isisd/isis_spf.c
index 1e2052b65..79b310323 100644
--- a/isisd/isis_spf.c
+++ b/isisd/isis_spf.c
@@ -31,14 +31,10 @@
#include "command.h"
#include "memory.h"
#include "prefix.h"
-#include "hash.h"
#include "if.h"
#include "table.h"
#include "spf_backoff.h"
-#include "jhash.h"
-#include "skiplist.h"
#include "srcdest_table.h"
-#include "lib_errors.h"
#include "isis_constants.h"
#include "isis_common.h"
@@ -57,257 +53,10 @@
#include "isis_mt.h"
#include "isis_tlvs.h"
#include "fabricd.h"
+#include "isis_spf_private.h"
DEFINE_MTYPE_STATIC(ISISD, ISIS_SPF_RUN, "ISIS SPF Run Info");
-enum vertextype {
- VTYPE_PSEUDO_IS = 1,
- VTYPE_PSEUDO_TE_IS,
- VTYPE_NONPSEUDO_IS,
- VTYPE_NONPSEUDO_TE_IS,
- VTYPE_ES,
- VTYPE_IPREACH_INTERNAL,
- VTYPE_IPREACH_EXTERNAL,
- VTYPE_IPREACH_TE,
- VTYPE_IP6REACH_INTERNAL,
- VTYPE_IP6REACH_EXTERNAL
-};
-
-#define VTYPE_IS(t) ((t) >= VTYPE_PSEUDO_IS && (t) <= VTYPE_NONPSEUDO_TE_IS)
-#define VTYPE_ES(t) ((t) == VTYPE_ES)
-#define VTYPE_IP(t) ((t) >= VTYPE_IPREACH_INTERNAL && (t) <= VTYPE_IP6REACH_EXTERNAL)
-
-struct prefix_pair {
- struct prefix dest;
- struct prefix_ipv6 src;
-};
-
-/*
- * Triple <N, d(N), {Adj(N)}>
- */
-union isis_N {
- uint8_t id[ISIS_SYS_ID_LEN + 1];
- struct prefix_pair ip;
-};
-struct isis_vertex {
- enum vertextype type;
- union isis_N N;
- uint32_t d_N; /* d(N) Distance from this IS */
- 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 */
- uint64_t insert_counter;
-};
-
-/* Vertex Queue and associated functions */
-
-struct isis_vertex_queue {
- union {
- struct skiplist *slist;
- struct list *list;
- } l;
- struct hash *hash;
- uint64_t insert_counter;
-};
-
-static unsigned isis_vertex_queue_hash_key(void *vp)
-{
- struct isis_vertex *vertex = vp;
-
- if (VTYPE_IP(vertex->type)) {
- uint32_t key;
-
- key = prefix_hash_key(&vertex->N.ip.dest);
- key = jhash_1word(prefix_hash_key(&vertex->N.ip.src), key);
- return key;
- }
-
- return jhash(vertex->N.id, ISIS_SYS_ID_LEN + 1, 0x55aa5a5a);
-}
-
-static int isis_vertex_queue_hash_cmp(const void *a, const void *b)
-{
- const struct isis_vertex *va = a, *vb = b;
-
- if (va->type != vb->type)
- return 0;
-
- if (VTYPE_IP(va->type)) {
- if (prefix_cmp(&va->N.ip.dest, &vb->N.ip.dest))
- return 0;
-
- return prefix_cmp((struct prefix *)&va->N.ip.src,
- (struct prefix *)&vb->N.ip.src) == 0;
- }
-
- return memcmp(va->N.id, vb->N.id, ISIS_SYS_ID_LEN + 1) == 0;
-}
-
-/*
- * Compares vertizes for sorting in the TENT list. Returns true
- * if candidate should be considered before current, false otherwise.
- */
-static int isis_vertex_queue_tent_cmp(void *a, void *b)
-{
- struct isis_vertex *va = a;
- struct isis_vertex *vb = b;
-
- if (va->d_N < vb->d_N)
- return -1;
-
- if (va->d_N > vb->d_N)
- return 1;
-
- if (va->type < vb->type)
- return -1;
-
- if (va->type > vb->type)
- return 1;
-
- if (va->insert_counter < vb->insert_counter)
- return -1;
-
- if (va->insert_counter > vb->insert_counter)
- return 1;
-
- return 0;
-}
-
-static struct skiplist *isis_vertex_queue_skiplist(void)
-{
- return skiplist_new(0, isis_vertex_queue_tent_cmp, NULL);
-}
-
-static void isis_vertex_queue_init(struct isis_vertex_queue *queue,
- const char *name, bool ordered)
-{
- if (ordered) {
- queue->insert_counter = 1;
- queue->l.slist = isis_vertex_queue_skiplist();
- } else {
- queue->insert_counter = 0;
- queue->l.list = list_new();
- }
- queue->hash = hash_create(isis_vertex_queue_hash_key,
- isis_vertex_queue_hash_cmp, name);
-}
-
-static void isis_vertex_del(struct isis_vertex *vertex);
-
-static void isis_vertex_queue_clear(struct isis_vertex_queue *queue)
-{
- hash_clean(queue->hash, NULL);
-
- if (queue->insert_counter) {
- struct isis_vertex *vertex;
- while (0 == skiplist_first(queue->l.slist, NULL,
- (void **)&vertex)) {
- isis_vertex_del(vertex);
- skiplist_delete_first(queue->l.slist);
- }
- queue->insert_counter = 1;
- } else {
- queue->l.list->del = (void (*)(void *))isis_vertex_del;
- list_delete_all_node(queue->l.list);
- queue->l.list->del = NULL;
- }
-}
-
-static void isis_vertex_queue_free(struct isis_vertex_queue *queue)
-{
- isis_vertex_queue_clear(queue);
-
- hash_free(queue->hash);
- queue->hash = NULL;
-
- if (queue->insert_counter) {
- skiplist_free(queue->l.slist);
- queue->l.slist = NULL;
- } else
- list_delete_and_null(&queue->l.list);
-}
-
-static unsigned int isis_vertex_queue_count(struct isis_vertex_queue *queue)
-{
- return hashcount(queue->hash);
-}
-
-static void isis_vertex_queue_append(struct isis_vertex_queue *queue,
- struct isis_vertex *vertex)
-{
- assert(!queue->insert_counter);
-
- listnode_add(queue->l.list, vertex);
-
- struct isis_vertex *inserted;
-
- inserted = hash_get(queue->hash, vertex, hash_alloc_intern);
- assert(inserted == vertex);
-}
-
-static void isis_vertex_queue_insert(struct isis_vertex_queue *queue,
- struct isis_vertex *vertex)
-{
- assert(queue->insert_counter);
- vertex->insert_counter = queue->insert_counter++;
- assert(queue->insert_counter != (uint64_t)-1);
-
- skiplist_insert(queue->l.slist, vertex, vertex);
-
- struct isis_vertex *inserted;
- inserted = hash_get(queue->hash, vertex, hash_alloc_intern);
- assert(inserted == vertex);
-}
-
-static struct isis_vertex *
-isis_vertex_queue_pop(struct isis_vertex_queue *queue)
-{
- assert(queue->insert_counter);
-
- struct isis_vertex *rv;
-
- if (skiplist_first(queue->l.slist, NULL, (void **)&rv))
- return NULL;
-
- skiplist_delete_first(queue->l.slist);
- hash_release(queue->hash, rv);
-
- return rv;
-}
-
-static void isis_vertex_queue_delete(struct isis_vertex_queue *queue,
- struct isis_vertex *vertex)
-{
- assert(queue->insert_counter);
-
- skiplist_delete(queue->l.slist, vertex, vertex);
- hash_release(queue->hash, vertex);
-}
-
-#define ALL_QUEUE_ELEMENTS_RO(queue, node, data) \
- ALL_LIST_ELEMENTS_RO((queue)->l.list, node, data)
-
-
-/* End of vertex queue definitions */
-
-struct isis_spftree {
- struct isis_vertex_queue paths; /* the SPT */
- struct isis_vertex_queue tents; /* TENT */
- struct route_table *route_table;
- struct isis_area *area; /* back pointer to area */
- unsigned int runcount; /* number of runs since uptime */
- time_t last_run_timestamp; /* last run timestamp as wall time for display */
- time_t last_run_monotime; /* last run as monotime for scheduling */
- time_t last_run_duration; /* last run duration in msec */
-
- uint16_t mtid;
- int family;
- int level;
- enum spf_tree_id tree_id;
- bool hopcount_metric;
-};
-
-
/*
* supports the given af ?
*/
@@ -430,20 +179,6 @@ static const char *vid2string(struct isis_vertex *vertex, char *buff, int size)
return "UNKNOWN";
}
-static void isis_vertex_id_init(struct isis_vertex *vertex, union isis_N *n,
- enum vertextype vtype)
-{
- vertex->type = vtype;
-
- if (VTYPE_IS(vtype) || VTYPE_ES(vtype)) {
- memcpy(vertex->N.id, n->id, ISIS_SYS_ID_LEN + 1);
- } else if (VTYPE_IP(vtype)) {
- memcpy(&vertex->N.ip, &n->ip, sizeof(n->ip));
- } else {
- flog_err(LIB_ERR_DEVELOPMENT, "Unknown Vertex Type");
- }
-}
-
static struct isis_vertex *isis_vertex_new(union isis_N *n,
enum vertextype vtype)
{
@@ -459,17 +194,6 @@ static struct isis_vertex *isis_vertex_new(union isis_N *n,
return vertex;
}
-static void isis_vertex_del(struct isis_vertex *vertex)
-{
- list_delete_and_null(&vertex->Adj_N);
- list_delete_and_null(&vertex->parents);
-
- memset(vertex, 0, sizeof(struct isis_vertex));
- XFREE(MTYPE_ISIS_VERTEX, vertex);
-
- return;
-}
-
static void isis_vertex_adj_del(struct isis_vertex *vertex,
struct isis_adjacency *adj)
{
@@ -626,16 +350,6 @@ static struct isis_vertex *isis_spf_add_root(struct isis_spftree *spftree,
return vertex;
}
-static struct isis_vertex *isis_find_vertex(struct isis_vertex_queue *queue,
- union isis_N *n,
- enum vertextype vtype)
-{
- struct isis_vertex querier;
-
- isis_vertex_id_init(&querier, n, vtype);
- return hash_lookup(queue->hash, &querier);
-}
-
/*
* Add a vertex to TENT sorted by cost and by vertextype on tie break situation
*/
@@ -1305,7 +1019,6 @@ static void isis_spf_loop(struct isis_spftree *spftree,
uint8_t *root_sysid)
{
struct isis_vertex *vertex;
- uint8_t lsp_id[ISIS_SYS_ID_LEN + 2];
struct isis_lsp *lsp;
while (isis_vertex_queue_count(&spftree->tents)) {
@@ -1319,19 +1032,18 @@ static void isis_spf_loop(struct isis_spftree *spftree,
#endif /* EXTREME_DEBUG */
add_to_paths(spftree, vertex);
- if (VTYPE_IS(vertex->type)) {
- memcpy(lsp_id, vertex->N.id, ISIS_SYS_ID_LEN + 1);
- LSP_FRAGMENT(lsp_id) = 0;
- lsp = lsp_search(lsp_id, spftree->area->lspdb[spftree->level - 1]);
- if (lsp && lsp->hdr.rem_lifetime != 0) {
- isis_spf_process_lsp(spftree, lsp, vertex->d_N,
- vertex->depth, root_sysid,
- vertex);
- } else {
- zlog_warn("ISIS-Spf: No LSP found for %s",
- rawlspid_print(lsp_id));
- }
+ if (!VTYPE_IS(vertex->type))
+ continue;
+
+ lsp = lsp_for_vertex(spftree, vertex);
+ if (!lsp) {
+ zlog_warn("ISIS-Spf: No LSP found for %s",
+ rawlspid_print(vertex->N.id)); /* FIXME */
+ continue;
}
+
+ isis_spf_process_lsp(spftree, lsp, vertex->d_N, vertex->depth,
+ root_sysid, vertex);
}
}
diff --git a/isisd/isis_spf_private.h b/isisd/isis_spf_private.h
new file mode 100644
index 000000000..3cd6a005b
--- /dev/null
+++ b/isisd/isis_spf_private.h
@@ -0,0 +1,351 @@
+/*
+ * IS-IS Rout(e)ing protocol - isis_spf_private.h
+ *
+ * Copyright (C) 2001,2002 Sampo Saaristo
+ * Tampere University of Technology
+ * Institute of Communications Engineering
+ * Copyright (C) 2017 Christian Franke <chris@opensourcerouting.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public Licenseas 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 ISIS_SPF_PRIVATE_H
+#define ISIS_SPF_PRIVATE_H
+
+#include "hash.h"
+#include "jhash.h"
+#include "skiplist.h"
+#include "lib_errors.h"
+
+enum vertextype {
+ VTYPE_PSEUDO_IS = 1,
+ VTYPE_PSEUDO_TE_IS,
+ VTYPE_NONPSEUDO_IS,
+ VTYPE_NONPSEUDO_TE_IS,
+ VTYPE_ES,
+ VTYPE_IPREACH_INTERNAL,
+ VTYPE_IPREACH_EXTERNAL,
+ VTYPE_IPREACH_TE,
+ VTYPE_IP6REACH_INTERNAL,
+ VTYPE_IP6REACH_EXTERNAL
+};
+
+#define VTYPE_IS(t) ((t) >= VTYPE_PSEUDO_IS && (t) <= VTYPE_NONPSEUDO_TE_IS)
+#define VTYPE_ES(t) ((t) == VTYPE_ES)
+#define VTYPE_IP(t) ((t) >= VTYPE_IPREACH_INTERNAL && (t) <= VTYPE_IP6REACH_EXTERNAL)
+
+struct prefix_pair {
+ struct prefix dest;
+ struct prefix_ipv6 src;
+};
+
+/*
+ * Triple <N, d(N), {Adj(N)}>
+ */
+union isis_N {
+ uint8_t id[ISIS_SYS_ID_LEN + 1];
+ struct prefix_pair ip;
+};
+struct isis_vertex {
+ enum vertextype type;
+ union isis_N N;
+ uint32_t d_N; /* d(N) Distance from this IS */
+ 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 */
+ uint64_t insert_counter;
+};
+
+/* Vertex Queue and associated functions */
+
+struct isis_vertex_queue {
+ union {
+ struct skiplist *slist;
+ struct list *list;
+ } l;
+ struct hash *hash;
+ uint64_t insert_counter;
+};
+
+__attribute__((__unused__))
+static unsigned isis_vertex_queue_hash_key(void *vp)
+{
+ struct isis_vertex *vertex = vp;
+
+ if (VTYPE_IP(vertex->type)) {
+ uint32_t key;
+
+ key = prefix_hash_key(&vertex->N.ip.dest);
+ key = jhash_1word(prefix_hash_key(&vertex->N.ip.src), key);
+ return key;
+ }
+
+ return jhash(vertex->N.id, ISIS_SYS_ID_LEN + 1, 0x55aa5a5a);
+}
+
+__attribute__((__unused__))
+static int isis_vertex_queue_hash_cmp(const void *a, const void *b)
+{
+ const struct isis_vertex *va = a, *vb = b;
+
+ if (va->type != vb->type)
+ return 0;
+
+ if (VTYPE_IP(va->type)) {
+ if (prefix_cmp(&va->N.ip.dest, &vb->N.ip.dest))
+ return 0;
+
+ return prefix_cmp((struct prefix *)&va->N.ip.src,
+ (struct prefix *)&vb->N.ip.src) == 0;
+ }
+
+ return memcmp(va->N.id, vb->N.id, ISIS_SYS_ID_LEN + 1) == 0;
+}
+
+/*
+ * Compares vertizes for sorting in the TENT list. Returns true
+ * if candidate should be considered before current, false otherwise.
+ */
+__attribute__((__unused__))
+static int isis_vertex_queue_tent_cmp(void *a, void *b)
+{
+ struct isis_vertex *va = a;
+ struct isis_vertex *vb = b;
+
+ if (va->d_N < vb->d_N)
+ return -1;
+
+ if (va->d_N > vb->d_N)
+ return 1;
+
+ if (va->type < vb->type)
+ return -1;
+
+ if (va->type > vb->type)
+ return 1;
+
+ if (va->insert_counter < vb->insert_counter)
+ return -1;
+
+ if (va->insert_counter > vb->insert_counter)
+ return 1;
+
+ return 0;
+}
+
+__attribute__((__unused__))
+static struct skiplist *isis_vertex_queue_skiplist(void)
+{
+ return skiplist_new(0, isis_vertex_queue_tent_cmp, NULL);
+}
+
+__attribute__((__unused__))
+static void isis_vertex_queue_init(struct isis_vertex_queue *queue,
+ const char *name, bool ordered)
+{
+ if (ordered) {
+ queue->insert_counter = 1;
+ queue->l.slist = isis_vertex_queue_skiplist();
+ } else {
+ queue->insert_counter = 0;
+ queue->l.list = list_new();
+ }
+ queue->hash = hash_create(isis_vertex_queue_hash_key,
+ isis_vertex_queue_hash_cmp, name);
+}
+
+__attribute__((__unused__))
+static void isis_vertex_del(struct isis_vertex *vertex)
+{
+ list_delete_and_null(&vertex->Adj_N);
+ list_delete_and_null(&vertex->parents);
+
+ memset(vertex, 0, sizeof(struct isis_vertex));
+ XFREE(MTYPE_ISIS_VERTEX, vertex);
+}
+
+__attribute__((__unused__))
+static void isis_vertex_queue_clear(struct isis_vertex_queue *queue)
+{
+ hash_clean(queue->hash, NULL);
+
+ if (queue->insert_counter) {
+ struct isis_vertex *vertex;
+ while (0 == skiplist_first(queue->l.slist, NULL,
+ (void **)&vertex)) {
+ isis_vertex_del(vertex);
+ skiplist_delete_first(queue->l.slist);
+ }
+ queue->insert_counter = 1;
+ } else {
+ queue->l.list->del = (void (*)(void *))isis_vertex_del;
+ list_delete_all_node(queue->l.list);
+ queue->l.list->del = NULL;
+ }
+}
+
+__attribute__((__unused__))
+static void isis_vertex_queue_free(struct isis_vertex_queue *queue)
+{
+ isis_vertex_queue_clear(queue);
+
+ hash_free(queue->hash);
+ queue->hash = NULL;
+
+ if (queue->insert_counter) {
+ skiplist_free(queue->l.slist);
+ queue->l.slist = NULL;
+ } else
+ list_delete_and_null(&queue->l.list);
+}
+
+__attribute__((__unused__))
+static unsigned int isis_vertex_queue_count(struct isis_vertex_queue *queue)
+{
+ return hashcount(queue->hash);
+}
+
+__attribute__((__unused__))
+static void isis_vertex_queue_append(struct isis_vertex_queue *queue,
+ struct isis_vertex *vertex)
+{
+ assert(!queue->insert_counter);
+
+ listnode_add(queue->l.list, vertex);
+
+ struct isis_vertex *inserted;
+
+ inserted = hash_get(queue->hash, vertex, hash_alloc_intern);
+ assert(inserted == vertex);
+}
+
+__attribute__((__unused__))
+static struct isis_vertex *isis_vertex_queue_last(struct isis_vertex_queue *queue)
+{
+ assert(!queue->insert_counter);
+
+ return listgetdata(listtail(queue->l.list));
+}
+
+__attribute__((__unused__))
+static void isis_vertex_queue_insert(struct isis_vertex_queue *queue,
+ struct isis_vertex *vertex)
+{
+ assert(queue->insert_counter);
+ vertex->insert_counter = queue->insert_counter++;
+ assert(queue->insert_counter != (uint64_t)-1);
+
+ skiplist_insert(queue->l.slist, vertex, vertex);
+
+ struct isis_vertex *inserted;
+ inserted = hash_get(queue->hash, vertex, hash_alloc_intern);
+ assert(inserted == vertex);
+}
+
+__attribute__((__unused__))
+static struct isis_vertex *
+isis_vertex_queue_pop(struct isis_vertex_queue *queue)
+{
+ assert(queue->insert_counter);
+
+ struct isis_vertex *rv;
+
+ if (skiplist_first(queue->l.slist, NULL, (void **)&rv))
+ return NULL;
+
+ skiplist_delete_first(queue->l.slist);
+ hash_release(queue->hash, rv);
+
+ return rv;
+}
+
+__attribute__((__unused__))
+static void isis_vertex_queue_delete(struct isis_vertex_queue *queue,
+ struct isis_vertex *vertex)
+{
+ assert(queue->insert_counter);
+
+ skiplist_delete(queue->l.slist, vertex, vertex);
+ hash_release(queue->hash, vertex);
+}
+
+#define ALL_QUEUE_ELEMENTS_RO(queue, node, data) \
+ ALL_LIST_ELEMENTS_RO((queue)->l.list, node, data)
+
+/* End of vertex queue definitions */
+
+struct isis_spftree {
+ struct isis_vertex_queue paths; /* the SPT */
+ struct isis_vertex_queue tents; /* TENT */
+ struct route_table *route_table;
+ struct isis_area *area; /* back pointer to area */
+ unsigned int runcount; /* number of runs since uptime */
+ time_t last_run_timestamp; /* last run timestamp as wall time for display */
+ time_t last_run_monotime; /* last run as monotime for scheduling */
+ time_t last_run_duration; /* last run duration in msec */
+
+ uint16_t mtid;
+ int family;
+ int level;
+ enum spf_tree_id tree_id;
+ bool hopcount_metric;
+};
+
+__attribute__((__unused__))
+static void isis_vertex_id_init(struct isis_vertex *vertex, union isis_N *n,
+ enum vertextype vtype)
+{
+ vertex->type = vtype;
+
+ if (VTYPE_IS(vtype) || VTYPE_ES(vtype)) {
+ memcpy(vertex->N.id, n->id, ISIS_SYS_ID_LEN + 1);
+ } else if (VTYPE_IP(vtype)) {
+ memcpy(&vertex->N.ip, &n->ip, sizeof(n->ip));
+ } else {
+ flog_err(LIB_ERR_DEVELOPMENT, "Unknown Vertex Type");
+ }
+}
+
+__attribute__((__unused__))
+static struct isis_vertex *isis_find_vertex(struct isis_vertex_queue *queue,
+ union isis_N *n,
+ enum vertextype vtype)
+{
+ struct isis_vertex querier;
+
+ isis_vertex_id_init(&querier, n, vtype);
+ return hash_lookup(queue->hash, &querier);
+}
+
+__attribute__((__unused__))
+static struct isis_lsp *lsp_for_vertex(struct isis_spftree *spftree,
+ struct isis_vertex *vertex)
+{
+ uint8_t lsp_id[ISIS_SYS_ID_LEN + 2];
+
+ assert(VTYPE_IS(vertex->type));
+
+ memcpy(lsp_id, vertex->N.id, ISIS_SYS_ID_LEN + 1);
+ LSP_FRAGMENT(lsp_id) = 0;
+
+ dict_t *lspdb = spftree->area->lspdb[spftree->level - 1];
+ struct isis_lsp *lsp = lsp_search(lsp_id, lspdb);
+
+ if (lsp && lsp->hdr.rem_lifetime != 0)
+ return lsp;
+
+ return NULL;
+}
+
+#endif
diff --git a/isisd/subdir.am b/isisd/subdir.am
index cd8bfdbdd..792b0df6c 100644
--- a/isisd/subdir.am
+++ b/isisd/subdir.am
@@ -37,6 +37,7 @@ noinst_HEADERS += \
isisd/isis_route.h \
isisd/isis_routemap.h \
isisd/isis_spf.h \
+ isisd/isis_spf_private.h \
isisd/isis_te.h \
isisd/isis_tlvs.h \
isisd/isis_vty_common.h \