summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Franke <chris@opensourcerouting.org>2014-01-08 00:40:16 +0100
committerChristian Franke <chris@opensourcerouting.org>2014-01-08 00:49:28 +0100
commit77f2a04099a7fd5107d11a5b0dcd3b0dc73f9bea (patch)
treee33a109fe4310593f2b296ef49f91d4ba6a6ad63
parentb9fb5b5bd7da0be11d92504de4f43bf3734726f4 (diff)
isisd: add a slight delay to lsp_regenerate_schedule
isisd implements a holdoff interval and will refrain from regenerating an lsp if the difference between the current time and its last refresh is less than the holdoff interval, but instead, it will schedule a timer to regenerate the lsp after the holdoff interval has passed. This implementation has one disadvantage in the case where there is a succession of calls to lsp_regenerate_schedule. In such a case, the first call will trigger an immediate regeneration of the lsp, while the other calls will only schedule the regeneration timer. This leads to cases where it takes holdoff interval time for information to propagate, just because the information was only available e.g. at the second call of lsp_regenerate_schedule in such a succession of calls. By not immediately regenerating an lsp if the last generation time is sufficiently long ago, but instead scheduling the regeneration with a very small delay, we allow all information from such a succession of calls to be considered. Signed-off-by: Christian Franke <chris@opensourcerouting.org>
-rw-r--r--isisd/isis_lsp.c51
1 files changed, 27 insertions, 24 deletions
diff --git a/isisd/isis_lsp.c b/isisd/isis_lsp.c
index f2a7923d..9bbba7fc 100644
--- a/isisd/isis_lsp.c
+++ b/isisd/isis_lsp.c
@@ -1741,6 +1741,7 @@ lsp_regenerate_schedule (struct isis_area *area, int level, int all_pseudo)
struct isis_lsp *lsp;
u_char id[ISIS_SYS_ID_LEN + 2];
time_t now, diff;
+ long timeout;
struct listnode *cnode;
struct isis_circuit *circuit;
int lvl;
@@ -1770,20 +1771,20 @@ lsp_regenerate_schedule (struct isis_area *area, int level, int all_pseudo)
THREAD_TIMER_OFF (area->t_lsp_refresh[lvl - 1]);
diff = now - lsp->last_generated;
if (diff < area->lsp_gen_interval[lvl - 1])
+ timeout = 1000 * (area->lsp_gen_interval[lvl - 1] - diff);
+ else
+ timeout = 100;
+
+ area->lsp_regenerate_pending[lvl - 1] = 1;
+ if (lvl == IS_LEVEL_1)
{
- area->lsp_regenerate_pending[lvl - 1] = 1;
- if (lvl == IS_LEVEL_1)
- THREAD_TIMER_ON (master, area->t_lsp_refresh[lvl - 1],
- lsp_l1_refresh, area,
- area->lsp_gen_interval[lvl - 1] - diff);
- else if (lvl == IS_LEVEL_2)
- THREAD_TIMER_ON (master, area->t_lsp_refresh[lvl - 1],
- lsp_l2_refresh, area,
- area->lsp_gen_interval[lvl - 1] - diff);
+ THREAD_TIMER_MSEC_ON(master, area->t_lsp_refresh[lvl - 1],
+ lsp_l1_refresh, area, timeout);
}
- else
+ else if (lvl == IS_LEVEL_2)
{
- lsp_regenerate (area, lvl);
+ THREAD_TIMER_MSEC_ON(master, area->t_lsp_refresh[lvl - 1],
+ lsp_l2_refresh, area, timeout);
}
}
@@ -2100,6 +2101,7 @@ lsp_regenerate_schedule_pseudo (struct isis_circuit *circuit, int level)
struct isis_lsp *lsp;
u_char lsp_id[ISIS_SYS_ID_LEN + 2];
time_t now, diff;
+ long timeout;
int lvl;
if (circuit == NULL ||
@@ -2131,22 +2133,23 @@ lsp_regenerate_schedule_pseudo (struct isis_circuit *circuit, int level)
THREAD_TIMER_OFF (circuit->u.bc.t_refresh_pseudo_lsp[lvl - 1]);
diff = now - lsp->last_generated;
if (diff < circuit->area->lsp_gen_interval[lvl - 1])
+ timeout = 1000 * (circuit->area->lsp_gen_interval[lvl - 1] - diff);
+ else
+ timeout = 100;
+
+ circuit->lsp_regenerate_pending[lvl - 1] = 1;
+
+ if (lvl == IS_LEVEL_1)
{
- circuit->lsp_regenerate_pending[lvl - 1] = 1;
- if (lvl == IS_LEVEL_1)
- THREAD_TIMER_ON (master,
- circuit->u.bc.t_refresh_pseudo_lsp[lvl - 1],
- lsp_l1_refresh_pseudo, circuit,
- circuit->area->lsp_gen_interval[lvl - 1] - diff);
- else if (lvl == IS_LEVEL_2)
- THREAD_TIMER_ON (master,
- circuit->u.bc.t_refresh_pseudo_lsp[lvl - 1],
- lsp_l2_refresh_pseudo, circuit,
- circuit->area->lsp_gen_interval[lvl - 1] - diff);
+ THREAD_TIMER_MSEC_ON(master,
+ circuit->u.bc.t_refresh_pseudo_lsp[lvl - 1],
+ lsp_l1_refresh_pseudo, circuit, timeout);
}
- else
+ else if (lvl == IS_LEVEL_2)
{
- lsp_regenerate_pseudo (circuit, lvl);
+ THREAD_TIMER_MSEC_ON(master,
+ circuit->u.bc.t_refresh_pseudo_lsp[lvl - 1],
+ lsp_l2_refresh_pseudo, circuit, timeout);
}
}