diff options
author | paul <paul> | 2005-10-21 09:23:12 +0000 |
---|---|---|
committer | paul <paul> | 2005-10-21 09:23:12 +0000 |
commit | d24f6e2a34ca829bd2ff6adb98b49d4d2d9cb737 (patch) | |
tree | 1d2a79a2ec4004f16b1ba3f2f2923ed8796cde83 /ospfd/ospf_spf.c | |
parent | c188c37caaf589a17b22e9889e63ec96f2f57106 (diff) |
2005-10-21 Paul Jakma <paul.jakma@sun.com>
* (general) SPF millisecond resolution timer with adaptive,
linear back-off holdtime. Prettification of ospf_timer_dump.
* ospf_dump.c: (ospf_timeval_dump) new function. The guts of
ospf_timer_dump, but made to be more dynamic in printing out
the relative timeval, sliding the precision printed out
according to the value.
(ospf_timer_dump) guts moved to ospf_timeval_dump.
* ospf_dump.h: export ospf_timeval_dump.
* ospf_flood.c: (ospf_flood) remove gettimeofday, use
the libzebra exported recent_time instead, as it's not
terribly critical to have time exactly right - the dropped
LSA will be retransmited to us if we don't ACK it.
* ospf_packet.c: (ospf_ls_upd_timer) Ditto, but here we're
not transmitting, just putting LSA back on update transmit list.
* ospfd.h: delay and holdtimes should be unsigned.
Add spf_max_holdtime and spf_hold_multiplier.
Update default defines for delay and hold time to be in msec.
(struct ospf) change the SPF timestamp to a struct timeval.
Remove ospf_timers_spf_(un)?set.
* ospfd.c: (ospf_timers_spf_{set,unset}) removed.
(ospf_new) initialise spf_max_holdtime and spf_hold_multiplier
* ospf_spf.c: (ospf_spf_calculate) SPF timestamp is a timeval
now, update with gettimeofday.
(ospf_spf_calculate_schedule) Change SPF timers to millisecond
resolution.
Make the holdtime be adaptive, with a linear increase in
holdtime ever consecutive SPF run which occurs within holdtime
of previous SPF, bounded by spf_max_holdtime.
* ospf_vty.c: Update spf timers commands.
(ospf_timers_spf_set) trivial helper.
(ospf_timers_throttle_spf_cmd) new command to set SPF delay,
initial hold and max hold times with millisecond resolution.
(ospf_timers_spf_cmd) Deprecated. Accept the old values,
convert to msec, truncate to new limits.
(no_ospf_timers_throttle_spf_cmd) set timers to defaults.
(no_ospf_timers_spf_cmd) deprecated form, same as previous.
(show_ip_ospf_cmd) Display SPF parameters and times.
(show_ip_ospf_neighbour_header) Centralise the 'sh ip os ne'
header.
(show_ip_ospf_neighbor_sub) Fix the field widths. Get rid of
the multiple spaces which were making the lines even longer.
(show_ip_ospf_neighbor_cmd) Use show_ip_ospf_neighbour_header
(show_ip_ospf_neighbor_all_cmd) ditto and fix the field
widths for NBMA neighbours.
(show_ip_ospf_neighbor_int) Use header function.
(show_ip_ospf_nbr_nbma_detail_sub) use sizeof for timebuf,
local array - safer.
(show_ip_ospf_neighbor_detail_sub) ditto
(ospf_vty_init) install the new SPF throttle timer commands.
Diffstat (limited to 'ospfd/ospf_spf.c')
-rw-r--r-- | ospfd/ospf_spf.c | 47 |
1 files changed, 34 insertions, 13 deletions
diff --git a/ospfd/ospf_spf.c b/ospfd/ospf_spf.c index b05117da..f6260fbd 100644 --- a/ospfd/ospf_spf.c +++ b/ospfd/ospf_spf.c @@ -1077,7 +1077,7 @@ ospf_spf_calculate (struct ospf_area *area, struct route_table *new_table, /* Increment SPF Calculation Counter. */ area->spf_calculation++; - area->ospf->ts_spf = time (NULL); + gettimeofday (&area->ospf->ts_spf, NULL); if (IS_DEBUG_OSPF_EVENT) zlog_debug ("ospf_spf_calculate: Stop"); @@ -1151,7 +1151,8 @@ ospf_spf_calculate_timer (struct thread *thread) void ospf_spf_calculate_schedule (struct ospf *ospf) { - time_t ht, delay; + unsigned long delay, elapsed, ht; + struct timeval result; if (IS_DEBUG_OSPF_EVENT) zlog_debug ("SPF: calculation timer scheduled"); @@ -1159,7 +1160,7 @@ ospf_spf_calculate_schedule (struct ospf *ospf) /* OSPF instance does not exist. */ if (ospf == NULL) return; - + /* SPF calculation timer is already scheduled. */ if (ospf->t_spf_calc) { @@ -1168,22 +1169,42 @@ ospf_spf_calculate_schedule (struct ospf *ospf) ospf->t_spf_calc); return; } - - ht = time (NULL) - ospf->ts_spf; - + + /* XXX Monotic timers: we only care about relative time here. */ + timersub (&recent_time, &ospf->ts_spf, &result); + + elapsed = (result.tv_sec * 1000) + (result.tv_usec / 1000); + ht = ospf->spf_holdtime * ospf->spf_hold_multiplier; + + if (ht > ospf->spf_max_holdtime) + ht = ospf->spf_max_holdtime; + /* Get SPF calculation delay time. */ - if (ht < ospf->spf_holdtime) + if (elapsed < ht) { - if (ospf->spf_holdtime - ht < ospf->spf_delay) + /* Got an event within the hold time of last SPF. We need to + * increase the hold_multiplier, if it's not already at/past + * maximum value, and wasn't already increased.. + */ + if (ht < ospf->spf_max_holdtime) + ospf->spf_hold_multiplier++; + + /* always honour the SPF initial delay */ + if ( (ht - elapsed) < ospf->spf_delay) delay = ospf->spf_delay; else - delay = ospf->spf_holdtime - ht; + delay = ht - elapsed; } else - delay = ospf->spf_delay; - + { + /* Event is past required hold-time of last SPF */ + delay = ospf->spf_delay; + ospf->spf_hold_multiplier = 1; + } + if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("SPF: calculation timer delay = %ld", (long)delay); + zlog_debug ("SPF: calculation timer delay = %ld", delay); + ospf->t_spf_calc = - thread_add_timer (master, ospf_spf_calculate_timer, ospf, delay); + thread_add_timer_msec (master, ospf_spf_calculate_timer, ospf, delay); } |