summaryrefslogtreecommitdiff
path: root/isisd/isis_spf.c
diff options
context:
space:
mode:
authorSubbaiah Venkata <svenkata@google.com>2012-03-27 23:48:05 -0700
committerAvneesh Sachdev <avneesh@opensourcerouting.org>2012-04-07 13:54:37 -0700
commite38e0df01ad305ad48ecf816b52fa99fd3f2a4e1 (patch)
treead565c3d656c0d5b74a1a3a80f1774bef938b1b4 /isisd/isis_spf.c
parent3f045a08812525505e165deea99a79447b44506b (diff)
isisd: couple of bug fixes
Diffstat (limited to 'isisd/isis_spf.c')
-rw-r--r--isisd/isis_spf.c84
1 files changed, 52 insertions, 32 deletions
diff --git a/isisd/isis_spf.c b/isisd/isis_spf.c
index a91742b6..198104a9 100644
--- a/isisd/isis_spf.c
+++ b/isisd/isis_spf.c
@@ -274,7 +274,8 @@ isis_spftree_new (struct isis_area *area)
tree->tents = list_new ();
tree->paths = list_new ();
tree->area = area;
- tree->lastrun = 0;
+ tree->last_run_timestamp = 0;
+ tree->last_run_duration = 0;
tree->runcount = 0;
tree->pending = 0;
return tree;
@@ -408,12 +409,16 @@ spftree_area_adj_del (struct isis_area *area, struct isis_adjacency *adj)
static struct isis_lsp *
isis_root_system_lsp (struct isis_area *area, int level, u_char *sysid)
{
+ struct isis_lsp *lsp;
u_char lspid[ISIS_SYS_ID_LEN + 2];
memcpy (lspid, sysid, ISIS_SYS_ID_LEN);
LSP_PSEUDO_ID (lspid) = 0;
LSP_FRAGMENT (lspid) = 0;
- return (lsp_search (lspid, area->lspdb[level - 1]));
+ lsp = lsp_search (lspid, area->lspdb[level - 1]);
+ if (lsp && lsp->lsp_header->rem_lifetime != 0)
+ return lsp;
+ return NULL;
}
/*
@@ -1021,7 +1026,7 @@ isis_spf_preload_tent (struct isis_spftree *spftree, int level,
LSP_PSEUDO_ID (lsp_id) = 0;
LSP_FRAGMENT (lsp_id) = 0;
lsp = lsp_search (lsp_id, spftree->area->lspdb[level - 1]);
- if (!lsp)
+ if (lsp == NULL || lsp->lsp_header->rem_lifetime == 0)
zlog_warn ("ISIS-Spf: No LSP %s found for IS adjacency "
"L%d on %s (ID %u)",
rawlspid_print (lsp_id), level,
@@ -1171,6 +1176,13 @@ isis_run_spf (struct isis_area *area, int level, int family, u_char *sysid)
u_char lsp_id[ISIS_SYS_ID_LEN + 2];
struct isis_lsp *lsp;
struct route_table *table = NULL;
+ struct timespec time_now;
+ unsigned long long start_time, end_time;
+
+ /* Get time that can't roll backwards. */
+ clock_gettime(CLOCK_MONOTONIC, &time_now);
+ start_time = time_now.tv_sec;
+ start_time = (start_time * 1000000) + (time_now.tv_nsec / 1000);
if (family == AF_INET)
spftree = area->spftree[level - 1];
@@ -1237,7 +1249,7 @@ isis_run_spf (struct isis_area *area, int level, int family, u_char *sysid)
memcpy (lsp_id, vertex->N.id, ISIS_SYS_ID_LEN + 1);
LSP_FRAGMENT (lsp_id) = 0;
lsp = lsp_search (lsp_id, area->lspdb[level - 1]);
- if (lsp)
+ if (lsp && lsp->lsp_header->rem_lifetime != 0)
{
if (LSP_PSEUDO_ID (lsp_id))
{
@@ -1263,9 +1275,14 @@ isis_run_spf (struct isis_area *area, int level, int family, u_char *sysid)
out:
isis_route_validate (area);
- spftree->lastrun = time (NULL);
- spftree->runcount++;
spftree->pending = 0;
+ spftree->runcount++;
+ spftree->last_run_timestamp = time (NULL);
+ clock_gettime(CLOCK_MONOTONIC, &time_now);
+ end_time = time_now.tv_sec;
+ end_time = (end_time * 1000000) + (time_now.tv_nsec / 1000);
+ spftree->last_run_duration = end_time - start_time;
+
return retval;
}
@@ -1332,7 +1349,7 @@ isis_spf_schedule (struct isis_area *area, int level)
{
struct isis_spftree *spftree = area->spftree[level - 1];
time_t now = time (NULL);
- int diff = now - spftree->lastrun;
+ int diff = now - spftree->last_run_timestamp;
assert (diff >= 0);
assert (area->is_type & level);
@@ -1346,20 +1363,20 @@ isis_spf_schedule (struct isis_area *area, int level)
THREAD_TIMER_OFF (spftree->t_spf);
- /* wait MINIMUM_SPF_INTERVAL before doing the SPF */
- if (diff >= MINIMUM_SPF_INTERVAL)
+ /* wait configured min_spf_interval before doing the SPF */
+ if (diff >= area->min_spf_interval[level-1])
return isis_run_spf (area, level, AF_INET, isis->sysid);
if (level == 1)
THREAD_TIMER_ON (master, spftree->t_spf, isis_run_spf_l1, area,
- MINIMUM_SPF_INTERVAL - diff);
+ area->min_spf_interval[0] - diff);
else
THREAD_TIMER_ON (master, spftree->t_spf, isis_run_spf_l2, area,
- MINIMUM_SPF_INTERVAL - diff);
+ area->min_spf_interval[1] - diff);
if (isis->debugs & DEBUG_SPF_EVENTS)
zlog_debug ("ISIS-Spf (%s) L%d SPF scheduled %d sec from now",
- area->area_tag, level, MINIMUM_SPF_INTERVAL - diff);
+ area->area_tag, level, area->min_spf_interval[level-1] - diff);
spftree->pending = 1;
@@ -1428,34 +1445,37 @@ isis_spf_schedule6 (struct isis_area *area, int level)
{
int retval = ISIS_OK;
struct isis_spftree *spftree = area->spftree6[level - 1];
- time_t diff, now = time (NULL);
+ time_t now = time (NULL);
+ time_t diff = now - spftree->last_run_timestamp;
+
+ assert (diff >= 0);
+ assert (area->is_type & level);
+
+ if (isis->debugs & DEBUG_SPF_EVENTS)
+ zlog_debug ("ISIS-Spf (%s) L%d SPF schedule called, lastrun %d sec ago",
+ area->area_tag, level, diff);
if (spftree->pending)
- return retval;
+ return ISIS_OK;
THREAD_TIMER_OFF (spftree->t_spf);
- /* FIXME: let's wait MINIMUM_SPF_INTERVAL before doing the SPF */
- if (now - isis->uptime < MINIMUM_SPF_INTERVAL || isis->uptime == 0)
- diff = 0;
+ /* wait configured min_spf_interval before doing the SPF */
+ if (diff >= area->min_spf_interval[level-1])
+ return isis_run_spf (area, level, AF_INET6, isis->sysid);
+
+ if (level == 1)
+ THREAD_TIMER_ON (master, spftree->t_spf, isis_run_spf6_l1, area,
+ area->min_spf_interval[0] - diff);
else
- diff = now - spftree->lastrun;
+ THREAD_TIMER_ON (master, spftree->t_spf, isis_run_spf6_l2, area,
+ area->min_spf_interval[1] - diff);
- if (diff < MINIMUM_SPF_INTERVAL)
- {
- if (level == 1)
- THREAD_TIMER_ON (master, spftree->t_spf, isis_run_spf6_l1, area,
- MINIMUM_SPF_INTERVAL - diff);
- else
- THREAD_TIMER_ON (master, spftree->t_spf, isis_run_spf6_l2, area,
- MINIMUM_SPF_INTERVAL - diff);
+ if (isis->debugs & DEBUG_SPF_EVENTS)
+ zlog_debug ("ISIS-Spf (%s) L%d SPF scheduled %d sec from now",
+ area->area_tag, level, area->min_spf_interval[level-1] - diff);
- spftree->pending = 1;
- }
- else
- {
- retval = isis_run_spf (area, level, AF_INET6, isis->sysid);
- }
+ spftree->pending = 1;
return retval;
}