isisd: cleanup SPF scheduling

- SPF is now per level only (no more per family)
 - t_spf and pending removed from struct spftree and moved to
   spf_timer field in struct isis_area
 - show isis summary output changed to accomodate the per level SPF
 - isis_spf_schedule6 and isis_run_spf6_lx functions are removed,
   isis_run_spf_lx now calls isis_run_spf for both INET and INET6
 - lsp related functions now call isis_spf_schedule only
This commit is contained in:
Stephane Litkowski 2017-02-20 10:51:47 +01:00 committed by Christian Franke
parent c1d0d21f98
commit 5475ecf7c5
6 changed files with 37 additions and 137 deletions

View File

@ -156,7 +156,6 @@ lsp_destroy (struct isis_lsp *lsp)
}
isis_spf_schedule (lsp->area, lsp->level);
isis_spf_schedule6 (lsp->area, lsp->level);
if (lsp->pdu)
stream_free (lsp->pdu);
@ -425,7 +424,6 @@ lsp_inc_seqnum (struct isis_lsp *lsp, u_int32_t seq_num)
ntohs (lsp->lsp_header->pdu_len) - 12, 12);
isis_spf_schedule (lsp->area, lsp->level);
isis_spf_schedule6 (lsp->area, lsp->level);
return;
}
@ -640,7 +638,6 @@ lsp_insert (struct isis_lsp *lsp, dict_t * lspdb)
if (lsp->lsp_header->seq_num != 0)
{
isis_spf_schedule (lsp->area, lsp->level);
isis_spf_schedule6 (lsp->area, lsp->level);
}
}

View File

@ -50,9 +50,6 @@
#include "isis_route.h"
#include "isis_csm.h"
int isis_run_spf_l1 (struct thread *thread);
int isis_run_spf_l2 (struct thread *thread);
/* 7.2.7 */
static void
remove_excess_adjs (struct list *adjs)
@ -266,14 +263,12 @@ isis_spftree_new (struct isis_area *area)
tree->last_run_timestamp = 0;
tree->last_run_duration = 0;
tree->runcount = 0;
tree->pending = 0;
return tree;
}
void
isis_spftree_del (struct isis_spftree *spftree)
{
THREAD_TIMER_OFF (spftree->t_spf);
spftree->tents->del = (void (*)(void *)) isis_vertex_del;
list_delete (spftree->tents);
@ -1240,7 +1235,6 @@ isis_run_spf (struct isis_area *area, int level, int family, u_char *sysid)
out:
isis_route_validate (area);
spftree->pending = 0;
spftree->runcount++;
spftree->last_run_timestamp = time (NULL);
monotime(&time_now);
@ -1248,11 +1242,10 @@ out:
end_time = (end_time * 1000000) + time_now.tv_usec;
spftree->last_run_duration = end_time - start_time;
return retval;
}
int
static int
isis_run_spf_l1 (struct thread *thread)
{
struct isis_area *area;
@ -1261,8 +1254,7 @@ isis_run_spf_l1 (struct thread *thread)
area = THREAD_ARG (thread);
assert (area);
area->spftree[0]->t_spf = NULL;
area->spftree[0]->pending = 0;
area->spf_timer[0] = NULL;
if (!(area->is_type & IS_LEVEL_1))
{
@ -1277,11 +1269,13 @@ isis_run_spf_l1 (struct thread *thread)
if (area->ip_circuits)
retval = isis_run_spf (area, 1, AF_INET, isis->sysid);
if (area->ipv6_circuits)
retval = isis_run_spf (area, 1, AF_INET6, isis->sysid);
return retval;
}
int
static int
isis_run_spf_l2 (struct thread *thread)
{
struct isis_area *area;
@ -1290,8 +1284,7 @@ isis_run_spf_l2 (struct thread *thread)
area = THREAD_ARG (thread);
assert (area);
area->spftree[1]->t_spf = NULL;
area->spftree[1]->pending = 0;
area->spf_timer[1] = NULL;
if (!(area->is_type & IS_LEVEL_2))
{
@ -1305,6 +1298,8 @@ isis_run_spf_l2 (struct thread *thread)
if (area->ip_circuits)
retval = isis_run_spf (area, 2, AF_INET, isis->sysid);
if (area->ipv6_circuits)
retval = isis_run_spf (area, 2, AF_INET6, isis->sysid);
return retval;
}
@ -1323,128 +1318,36 @@ isis_spf_schedule (struct isis_area *area, int level)
zlog_debug ("ISIS-Spf (%s) L%d SPF schedule called, lastrun %d sec ago",
area->area_tag, level, diff);
if (spftree->pending)
if (area->spf_timer[level -1])
return ISIS_OK;
THREAD_TIMER_OFF (spftree->t_spf);
/* 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);
{
int retval = ISIS_OK;
if (area->ip_circuits)
retval = isis_run_spf (area, level, AF_INET, isis->sysid);
if (area->ipv6_circuits)
retval = isis_run_spf (area, level, AF_INET6, isis->sysid);
return retval;
}
if (level == 1)
THREAD_TIMER_ON (master, spftree->t_spf, isis_run_spf_l1, area,
THREAD_TIMER_ON (master, area->spf_timer[0], isis_run_spf_l1, area,
area->min_spf_interval[0] - diff);
else
THREAD_TIMER_ON (master, spftree->t_spf, isis_run_spf_l2, area,
THREAD_TIMER_ON (master, area->spf_timer[1], isis_run_spf_l2, area,
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, area->min_spf_interval[level-1] - diff);
spftree->pending = 1;
return ISIS_OK;
}
static int
isis_run_spf6_l1 (struct thread *thread)
{
struct isis_area *area;
int retval = ISIS_OK;
area = THREAD_ARG (thread);
assert (area);
area->spftree6[0]->t_spf = NULL;
area->spftree6[0]->pending = 0;
if (!(area->is_type & IS_LEVEL_1))
{
if (isis->debugs & DEBUG_SPF_EVENTS)
zlog_warn ("ISIS-SPF (%s) area does not share level", area->area_tag);
return ISIS_WARNING;
}
if (isis->debugs & DEBUG_SPF_EVENTS)
zlog_debug ("ISIS-Spf (%s) L1 SPF needed, periodic SPF", area->area_tag);
if (area->ipv6_circuits)
retval = isis_run_spf (area, 1, AF_INET6, isis->sysid);
return retval;
}
static int
isis_run_spf6_l2 (struct thread *thread)
{
struct isis_area *area;
int retval = ISIS_OK;
area = THREAD_ARG (thread);
assert (area);
area->spftree6[1]->t_spf = NULL;
area->spftree6[1]->pending = 0;
if (!(area->is_type & IS_LEVEL_2))
{
if (isis->debugs & DEBUG_SPF_EVENTS)
zlog_warn ("ISIS-SPF (%s) area does not share level", area->area_tag);
return ISIS_WARNING;
}
if (isis->debugs & DEBUG_SPF_EVENTS)
zlog_debug ("ISIS-Spf (%s) L2 SPF needed, periodic SPF.", area->area_tag);
if (area->ipv6_circuits)
retval = isis_run_spf (area, 2, AF_INET6, isis->sysid);
return retval;
}
int
isis_spf_schedule6 (struct isis_area *area, int level)
{
int retval = ISIS_OK;
struct isis_spftree *spftree = area->spftree6[level - 1];
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 %lld sec ago",
area->area_tag, level, (long long)diff);
if (spftree->pending)
return ISIS_OK;
THREAD_TIMER_OFF (spftree->t_spf);
/* 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
THREAD_TIMER_ON (master, spftree->t_spf, isis_run_spf6_l2, area,
area->min_spf_interval[1] - diff);
if (isis->debugs & DEBUG_SPF_EVENTS)
zlog_debug ("ISIS-Spf (%s) L%d SPF scheduled %lld sec from now",
area->area_tag, level,
(long long)(area->min_spf_interval[level-1] - diff));
spftree->pending = 1;
return retval;
}
static void
isis_print_paths (struct vty *vty, struct list *paths, u_char *root_sysid)
{

View File

@ -60,11 +60,9 @@ struct isis_vertex
struct isis_spftree
{
struct thread *t_spf; /* spf threads */
struct list *paths; /* the SPT */
struct list *tents; /* TENT */
struct isis_area *area; /* back pointer to area */
int pending; /* already scheduled */
unsigned int runcount; /* number of runs since uptime */
time_t last_run_timestamp; /* last run timestamp for scheduling */
time_t last_run_duration; /* last run duration in msec */
@ -80,5 +78,4 @@ void spftree_area_adj_del (struct isis_area *area,
struct isis_adjacency *adj);
int isis_spf_schedule (struct isis_area *area, int level);
void isis_spf_cmds_init (void);
int isis_spf_schedule6 (struct isis_area *area, int level);
#endif /* _ZEBRA_ISIS_SPF_H */

View File

@ -22,7 +22,8 @@
*/
#include <zebra.h>
#include <command.h>
#include "command.h"
#include "isis_circuit.h"
#include "isis_csm.h"

View File

@ -245,6 +245,9 @@ isis_area_destroy (struct vty *vty, const char *area_tag)
spftree_area_del (area);
THREAD_TIMER_OFF(area->spf_timer[0]);
THREAD_TIMER_OFF(area->spf_timer[1]);
/* invalidate and validate would delete all routes from zebra */
isis_route_invalidate (area);
isis_route_validate (area);
@ -1327,14 +1330,16 @@ DEFUN (show_isis_summary,
vty_out (vty, " Level-%d:%s", level, VTY_NEWLINE);
spftree = area->spftree[level - 1];
if (spftree->pending)
vty_out (vty, " IPv4 SPF: (pending)%s", VTY_NEWLINE);
if (area->spf_timer[level - 1])
vty_out (vty, " SPF: (pending)%s", VTY_NEWLINE);
else
vty_out (vty, " IPv4 SPF:%s", VTY_NEWLINE);
vty_out (vty, " SPF:%s", VTY_NEWLINE);
vty_out (vty, " minimum interval : %d%s",
area->min_spf_interval[level - 1], VTY_NEWLINE);
vty_out (vty, " minimum interval : %d",
area->min_spf_interval[level - 1]);
vty_out (vty, VTY_NEWLINE);
vty_out (vty, " IPv4 route computation:%s", VTY_NEWLINE);
vty_out (vty, " last run elapsed : ");
vty_out_timestr(vty, spftree->last_run_timestamp);
vty_out (vty, "%s", VTY_NEWLINE);
@ -1346,13 +1351,7 @@ DEFUN (show_isis_summary,
spftree->runcount, VTY_NEWLINE);
spftree = area->spftree6[level - 1];
if (spftree->pending)
vty_out (vty, " IPv6 SPF: (pending)%s", VTY_NEWLINE);
else
vty_out (vty, " IPv6 SPF:%s", VTY_NEWLINE);
vty_out (vty, " minimum interval : %d%s",
area->min_spf_interval[level - 1], VTY_NEWLINE);
vty_out (vty, " IPv6 route computation:%s", VTY_NEWLINE);
vty_out (vty, " last run elapsed : ");
vty_out_timestr(vty, spftree->last_run_timestamp);
@ -1651,6 +1650,7 @@ area_resign_level (struct isis_area *area, int level)
isis_spftree_del (area->spftree6[level - 1]);
area->spftree6[level - 1] = NULL;
}
THREAD_TIMER_OFF(area->spf_timer[level - 1]);
if (area->route_table[level - 1])
{
route_table_finish (area->route_table[level - 1]);

View File

@ -127,6 +127,8 @@ struct isis_area
[ZEBRA_ROUTE_MAX + 1][ISIS_LEVELS];
struct route_table *ext_reach[REDIST_PROTOCOL_COUNT][ISIS_LEVELS];
struct thread *spf_timer[ISIS_LEVELS];
QOBJ_FIELDS
};
DECLARE_QOBJ_TYPE(isis_area)