From d24f6e2a34ca829bd2ff6adb98b49d4d2d9cb737 Mon Sep 17 00:00:00 2001 From: paul Date: Fri, 21 Oct 2005 09:23:12 +0000 Subject: 2005-10-21 Paul Jakma * (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. --- ospfd/ChangeLog | 52 +++++++++++++++ ospfd/ospf_dump.c | 83 ++++++++++++++++------- ospfd/ospf_dump.h | 1 + ospfd/ospf_flood.c | 6 +- ospfd/ospf_packet.c | 4 +- ospfd/ospf_spf.c | 47 +++++++++---- ospfd/ospf_vty.c | 185 +++++++++++++++++++++++++++++++++++++--------------- ospfd/ospfd.c | 20 +----- ospfd/ospfd.h | 15 +++-- 9 files changed, 293 insertions(+), 120 deletions(-) diff --git a/ospfd/ChangeLog b/ospfd/ChangeLog index 13faf906..76c220aa 100644 --- a/ospfd/ChangeLog +++ b/ospfd/ChangeLog @@ -1,3 +1,55 @@ +2005-10-21 Paul Jakma + + * (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. + 2005-10-21 Paul Jakma * (general) OSPF fast, sub-second hello and 1s dead-interval diff --git a/ospfd/ospf_dump.c b/ospfd/ospf_dump.c index 829c00f7..9ae87a61 100644 --- a/ospfd/ospf_dump.c +++ b/ospfd/ospf_dump.c @@ -230,45 +230,82 @@ ospf_nbr_state_message (struct ospf_neighbor *nbr, char *buf, size_t size) } const char * -ospf_timer_dump (struct thread *t, char *buf, size_t size) +ospf_timeval_dump (struct timeval *t, char *buf, size_t size) { - struct timeval now, result; - unsigned long h, m, s, ms; - + /* Making formatted timer strings. */ +#define MINUTE_IN_SECONDS 60 +#define HOUR_IN_SECONDS (60*MINUTE_IN_SECONDS) +#define DAY_IN_SECONDS (24*HOUR_IN_SECONDS) +#define WEEK_IN_SECONDS (7*DAY_IN_SECONDS) + unsigned long w, d, h, m, s, ms; + if (!t) return "inactive"; - - h = m = s = ms = 0; - memset (buf, 0, size); - - gettimeofday (&now, NULL); - timersub (&t->u.sands, &now, &result); + w = d = h = m = s = ms = 0; + memset (buf, 0, size); - ms = result.tv_usec / 1000; + ms = t->tv_usec / 1000; if (ms >= 1000) { - result.tv_sec = ms / 1000; - ms =- result.tv_sec * 1000; + t->tv_sec = ms / 1000; + ms =- t->tv_sec * 1000; + } + + if (t->tv_sec > WEEK_IN_SECONDS) + { + w = t->tv_sec / WEEK_IN_SECONDS; + t->tv_sec -= w * WEEK_IN_SECONDS; } - if (result.tv_sec >= 3600) + + if (t->tv_sec > DAY_IN_SECONDS) { - h = result.tv_sec / 3600; - result.tv_sec -= h * 3600; + d = t->tv_sec / DAY_IN_SECONDS; + t->tv_sec -= d * DAY_IN_SECONDS; } - - if (result.tv_sec >= 60) + + if (t->tv_sec >= HOUR_IN_SECONDS) { - m = result.tv_sec / 60; - result.tv_sec -= m * 60; + h = t->tv_sec / HOUR_IN_SECONDS; + t->tv_sec -= h * HOUR_IN_SECONDS; } - - snprintf (buf, size, "%02ld:%02ld:%02ld.%03ld", h, m, result.tv_sec, ms); - + + if (t->tv_sec >= MINUTE_IN_SECONDS) + { + m = t->tv_sec / MINUTE_IN_SECONDS; + t->tv_sec -= m * MINUTE_IN_SECONDS; + } + + if (w > 99) + snprintf (buf, size, "%ldw%1ldd", w, d); + else if (w) + snprintf (buf, size, "%ldw%1ldd%02ldh", w, d, h); + else if (d) + snprintf (buf, size, "%1ldd%02ldh%02ldm", d, h, m); + else if (h) + snprintf (buf, size, "%ldh%02ldm%02lds", h, m, t->tv_sec); + else if (m) + snprintf (buf, size, "%ldm%02lds", m, t->tv_sec); + else + snprintf (buf, size, "%ld.%03lds", t->tv_sec, ms); + return buf; } +const char * +ospf_timer_dump (struct thread *t, char *buf, size_t size) +{ + struct timeval result; + + if (!t) + return "inactive"; + + timersub (&t->u.sands, &recent_time, &result); + + return ospf_timeval_dump (&result, buf, size); +} + #define OSPF_OPTION_STR_MAXLEN 24 char * diff --git a/ospfd/ospf_dump.h b/ospfd/ospf_dump.h index 81abb754..e24244ee 100644 --- a/ospfd/ospf_dump.h +++ b/ospfd/ospf_dump.h @@ -131,6 +131,7 @@ extern const char *ospf_if_name_string (struct ospf_interface *); extern void ospf_nbr_state_message (struct ospf_neighbor *, char *, size_t); extern char *ospf_options_dump (u_char); extern const char *ospf_timer_dump (struct thread *, char *, size_t); +extern const char *ospf_timeval_dump (struct timeval *, char *, size_t); extern void ospf_ip_header_dump (struct ip *); extern void ospf_packet_dump (struct stream *); extern void ospf_lsa_header_dump (struct lsa_header *); diff --git a/ospfd/ospf_flood.c b/ospfd/ospf_flood.c index a8b7e37a..d7ab859e 100644 --- a/ospfd/ospf_flood.c +++ b/ospfd/ospf_flood.c @@ -238,7 +238,6 @@ ospf_flood (struct ospf *ospf, struct ospf_neighbor *nbr, struct ospf_lsa *current, struct ospf_lsa *new) { struct ospf_interface *oi; - struct timeval now; int lsa_ack_flag; /* Type-7 LSA's will be flooded throughout their native NSSA area, @@ -254,9 +253,6 @@ ospf_flood (struct ospf *ospf, struct ospf_neighbor *nbr, lsa_ack_flag = 0; oi = nbr->oi; - /* Get current time. */ - gettimeofday (&now, NULL); - /* If there is already a database copy, and if the database copy was received via flooding and installed less than MinLSArrival seconds ago, discard the new LSA @@ -272,7 +268,7 @@ ospf_flood (struct ospf *ospf, struct ospf_neighbor *nbr, "while local one is initial instance."); ; /* Accept this LSA for quick LSDB resynchronization. */ } - else if (tv_cmp (tv_sub (now, current->tv_recv), + else if (tv_cmp (tv_sub (recent_time, current->tv_recv), int2tv (OSPF_MIN_LS_ARRIVAL)) < 0) { if (IS_DEBUG_OSPF_EVENT) diff --git a/ospfd/ospf_packet.c b/ospfd/ospf_packet.c index 7c29a04a..8b818d72 100644 --- a/ospfd/ospf_packet.c +++ b/ospfd/ospf_packet.c @@ -417,10 +417,8 @@ ospf_ls_upd_timer (struct thread *thread) struct list *update; struct ospf_lsdb *lsdb; int i; - struct timeval now; int retransmit_interval; - gettimeofday (&now, NULL); retransmit_interval = OSPF_IF_PARAM (nbr->oi, retransmit_interval); lsdb = &nbr->ls_rxmt; @@ -443,7 +441,7 @@ ospf_ls_upd_timer (struct thread *thread) fired. This is a small tweak to what is in the RFC, but it will cut out out a lot of retransmit traffic - MAG */ - if (tv_cmp (tv_sub (now, lsa->tv_recv), + if (tv_cmp (tv_sub (recent_time, lsa->tv_recv), int2tv (retransmit_interval)) >= 0) listnode_add (update, rn->info); } 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); } diff --git a/ospfd/ospf_vty.c b/ospfd/ospf_vty.c index 0d0befa7..5263f15c 100644 --- a/ospfd/ospf_vty.c +++ b/ospfd/ospf_vty.c @@ -2113,41 +2113,97 @@ ALIAS (no_ospf_compatible_rfc1583, NO_STR "OSPF specific commands\n" "Disable the RFC1583Compatibility flag\n") + +static int +ospf_timers_spf_set (struct vty *vty, unsigned int delay, + unsigned int hold, + unsigned int max) +{ + struct ospf *ospf = vty->index; + + ospf->spf_delay = delay; + ospf->spf_holdtime = hold; + ospf->spf_max_holdtime = max; + + return CMD_SUCCESS; +} -DEFUN (ospf_timers_spf, +DEFUN (ospf_timers_throttle_spf, + ospf_timers_throttle_spf_cmd, + "timers throttle spf <0-600000> <0-600000> <0-600000>", + "Adjust routing timers\n" + "Throttling adaptive timer\n" + "OSPF SPF timers\n" + "Delay (msec) from first change received till SPF calculation\n" + "Initial hold time (msec) between consecutive SPF calculations\n" + "Maximum hold time (msec)\n") +{ + unsigned int delay, hold, max; + + if (argc != 3) + { + vty_out (vty, "Insufficient arguments%s", VTY_NEWLINE); + return CMD_WARNING; + } + + VTY_GET_INTEGER_RANGE ("SPF delay timer", delay, argv[0], 0, 600000); + VTY_GET_INTEGER_RANGE ("SPF hold timer", hold, argv[1], 0, 600000); + VTY_GET_INTEGER_RANGE ("SPF max-hold timer", max, argv[2], 0, 600000); + + return ospf_timers_spf_set (vty, delay, hold, max); +} + +DEFUN_DEPRECATED (ospf_timers_spf, ospf_timers_spf_cmd, "timers spf <0-4294967295> <0-4294967295>", "Adjust routing timers\n" "OSPF SPF timers\n" - "Delay between receiving a change to SPF calculation\n" - "Hold time between consecutive SPF calculations\n") + "Delay (s) between receiving a change to SPF calculation\n" + "Hold time (s) between consecutive SPF calculations\n") { - struct ospf *ospf = vty->index; - u_int32_t delay, hold; - + unsigned int delay, hold; + + if (argc != 2) + { + vty_out (vty, "Insufficient number of arguments%s", VTY_NEWLINE); + return CMD_WARNING; + } + VTY_GET_INTEGER ("SPF delay timer", delay, argv[0]); VTY_GET_INTEGER ("SPF hold timer", hold, argv[1]); - - ospf_timers_spf_set (ospf, delay, hold); - - return CMD_SUCCESS; + + /* truncate down the second values if they're greater than 600000ms */ + if (delay > (600000 / 1000)) + delay = 600000; + else if (delay == 0) + /* 0s delay was probably specified because of lack of ms resolution */ + delay = OSPF_SPF_DELAY_DEFAULT; + if (hold > (600000 / 1000)) + hold = 600000; + + return ospf_timers_spf_set (vty, delay * 1000, hold * 1000, hold * 1000); } -DEFUN (no_ospf_timers_spf, - no_ospf_timers_spf_cmd, - "no timers spf", +DEFUN (no_ospf_timers_throttle_spf, + no_ospf_timers_throttle_spf_cmd, + "no timers throttle spf", NO_STR "Adjust routing timers\n" + "Throttling adaptive timer\n" "OSPF SPF timers\n") { - struct ospf *ospf = vty->index; - - ospf->spf_delay = OSPF_SPF_DELAY_DEFAULT; - ospf->spf_holdtime = OSPF_SPF_HOLDTIME_DEFAULT; - - return CMD_SUCCESS; + return ospf_timers_spf_set (vty, + OSPF_SPF_DELAY_DEFAULT, + OSPF_SPF_HOLDTIME_DEFAULT, + OSPF_SPF_MAX_HOLDTIME_DEFAULT); } +ALIAS_DEPRECATED (no_ospf_timers_throttle_spf, + no_ospf_timers_spf_cmd, + "no timers spf", + NO_STR + "Adjust routing timers\n" + "OSPF SPF timers\n") DEFUN (ospf_neighbor, ospf_neighbor_cmd, @@ -2521,6 +2577,8 @@ DEFUN (show_ip_ospf, struct listnode *node, *nnode; struct ospf_area * area; struct ospf *ospf; + struct timeval result; + char timebuf[13]; /* XX:XX:XX.XXX(nul) */ /* Check OSPF is enable. */ ospf = ospf_lookup (); @@ -2551,9 +2609,23 @@ DEFUN (show_ip_ospf, #endif /* HAVE_OPAQUE_LSA */ /* Show SPF timers. */ - vty_out (vty, " SPF schedule delay %d secs, Hold time between two SPFs %d secs%s", - ospf->spf_delay, ospf->spf_holdtime, VTY_NEWLINE); - + vty_out (vty, " Initial SPF scheduling delay %d millisec(s)%s" + " Minimum hold time between consecutive SPFs %d millisec(s)%s" + " Maximum hold time between consecutive SPFs %d millisec(s)%s" + " Hold time multiplier is currently %d%s", + ospf->spf_delay, VTY_NEWLINE, + ospf->spf_holdtime, VTY_NEWLINE, + ospf->spf_max_holdtime, VTY_NEWLINE, + ospf->spf_hold_multiplier, VTY_NEWLINE); + timersub (&recent_time, &ospf->ts_spf, &result); + vty_out (vty, " SPF algorithm last executed %s ago%s", + ospf_timeval_dump (&result, timebuf, sizeof (timebuf)), + VTY_NEWLINE); + vty_out (vty, " SPF timer %s%s%s", + (ospf->t_spf_calc ? "due in " : "is "), + ospf_timer_dump (ospf->t_spf_calc, timebuf, sizeof (timebuf)), + VTY_NEWLINE); + /* Show refresh parameters. */ vty_out (vty, " Refresh timer %d secs%s", ospf->lsa_refresh_interval, VTY_NEWLINE); @@ -2757,13 +2829,23 @@ DEFUN (show_ip_ospf_interface, return CMD_SUCCESS; } +static void +show_ip_ospf_neighbour_header (struct vty *vty) +{ + vty_out (vty, "%s%15s %3s %-15s %9s %-15s %-20s %5s %5s %5s%s", + VTY_NEWLINE, + "Neighbor ID", "Pri", "State", "Dead Time", + "Address", "Interface", "RXmtL", "RqstL", "DBsmL", + VTY_NEWLINE); +} + static void show_ip_ospf_neighbor_sub (struct vty *vty, struct ospf_interface *oi) { struct route_node *rn; struct ospf_neighbor *nbr; char msgbuf[16]; - char timebuf[9]; + char timebuf[14]; for (rn = route_top (oi->nbrs); rn; rn = route_next (rn)) if ((nbr = rn->info)) @@ -2775,15 +2857,20 @@ show_ip_ospf_neighbor_sub (struct vty *vty, struct ospf_interface *oi) ospf_nbr_state_message (nbr, msgbuf, 16); if (nbr->state == NSM_Attempt && nbr->router_id.s_addr == 0) - vty_out (vty, "%-15s %3d %-15s %8s ", - "-", nbr->priority, - msgbuf, ospf_timer_dump (nbr->t_inactivity, timebuf, 9)); - else - vty_out (vty, "%-15s %3d %-15s %8s ", - inet_ntoa (nbr->router_id), nbr->priority, - msgbuf, ospf_timer_dump (nbr->t_inactivity, timebuf, 9)); + vty_out (vty, "%-15s %3d %-15s ", + "-", nbr->priority, + msgbuf); + else + vty_out (vty, "%-15s %3d %-15s ", + inet_ntoa (nbr->router_id), nbr->priority, + msgbuf); + + vty_out (vty, "%9s ", + ospf_timer_dump (nbr->t_inactivity, timebuf, + sizeof(timebuf))); + vty_out (vty, "%-15s ", inet_ntoa (nbr->src)); - vty_out (vty, "%-15s %5ld %5ld %5d%s", + vty_out (vty, "%-20s %5ld %5ld %5d%s", IF_NAME (oi), ospf_ls_retransmit_count (nbr), ospf_ls_request_count (nbr), ospf_db_summary_count (nbr), VTY_NEWLINE); @@ -2809,10 +2896,7 @@ DEFUN (show_ip_ospf_neighbor, return CMD_SUCCESS; } - /* Show All neighbors. */ - vty_out (vty, "%sNeighbor ID Pri State Dead " - "Time Address Interface RXmtL " - "RqstL DBsmL%s", VTY_NEWLINE, VTY_NEWLINE); + show_ip_ospf_neighbour_header (vty); for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi)) show_ip_ospf_neighbor_sub (vty, oi); @@ -2838,12 +2922,9 @@ DEFUN (show_ip_ospf_neighbor_all, vty_out (vty, " OSPF Routing Process not enabled%s", VTY_NEWLINE); return CMD_SUCCESS; } - - /* Show All neighbors. */ - vty_out (vty, "%sNeighbor ID Pri State Dead " - "Time Address Interface RXmtL " - "RqstL DBsmL%s", VTY_NEWLINE, VTY_NEWLINE); - + + show_ip_ospf_neighbour_header (vty); + for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi)) { struct listnode *nbr_node; @@ -2857,9 +2938,9 @@ DEFUN (show_ip_ospf_neighbor_all, if (nbr_nbma->nbr == NULL || nbr_nbma->nbr->state == NSM_Down) { - vty_out (vty, "%-15s %3d %-15s %8s ", + vty_out (vty, "%-15s %3d %-15s %9s ", "-", nbr_nbma->priority, "Down", "-"); - vty_out (vty, "%-15s %-15s %5d %5d %5d%s", + vty_out (vty, "%-15s %-20s %5d %5d %5d%s", inet_ntoa (nbr_nbma->addr), IF_NAME (oi), 0, 0, 0, VTY_NEWLINE); } @@ -2895,11 +2976,9 @@ DEFUN (show_ip_ospf_neighbor_int, vty_out (vty, " OSPF Routing Process not enabled%s", VTY_NEWLINE); return CMD_SUCCESS; } - - vty_out (vty, "%sNeighbor ID Pri State Dead " - "Time Address Interface RXmtL " - "RqstL DBsmL%s", VTY_NEWLINE, VTY_NEWLINE); - + + show_ip_ospf_neighbour_header (vty); + for (rn = route_top (IF_OIFS (ifp)); rn; rn = route_next (rn)) { struct ospf_interface *oi = rn->info; @@ -2939,7 +3018,8 @@ show_ip_ospf_nbr_nbma_detail_sub (struct vty *vty, struct ospf_interface *oi, /* Show poll-interval timer. */ vty_out (vty, " Poll timer due in %s%s", - ospf_timer_dump (nbr_nbma->t_poll, timebuf, 9), VTY_NEWLINE); + ospf_timer_dump (nbr_nbma->t_poll, timebuf, sizeof(timebuf)), + VTY_NEWLINE); /* Show poll-interval timer thread. */ vty_out (vty, " Thread Poll Timer %s%s", @@ -2979,7 +3059,8 @@ show_ip_ospf_neighbor_detail_sub (struct vty *vty, struct ospf_interface *oi, ospf_options_dump (nbr->options), VTY_NEWLINE); /* Show Router Dead interval timer. */ vty_out (vty, " Dead timer due in %s%s", - ospf_timer_dump (nbr->t_inactivity, timebuf, 9), VTY_NEWLINE); + ospf_timer_dump (nbr->t_inactivity, timebuf, sizeof (timebuf)), + VTY_NEWLINE); /* Show Database Summary list. */ vty_out (vty, " Database Summary List %d%s", ospf_db_summary_count (nbr), VTY_NEWLINE); @@ -7966,7 +8047,9 @@ ospf_vty_init (void) install_element (OSPF_NODE, &ospf_timers_spf_cmd); install_element (OSPF_NODE, &no_ospf_timers_spf_cmd); - + install_element (OSPF_NODE, &ospf_timers_throttle_spf_cmd); + install_element (OSPF_NODE, &no_ospf_timers_throttle_spf_cmd); + install_element (OSPF_NODE, &ospf_refresh_timer_cmd); install_element (OSPF_NODE, &no_ospf_refresh_timer_val_cmd); install_element (OSPF_NODE, &no_ospf_refresh_timer_cmd); diff --git a/ospfd/ospfd.c b/ospfd/ospfd.c index 9161f9ce..bf8ca4dc 100644 --- a/ospfd/ospfd.c +++ b/ospfd/ospfd.c @@ -185,6 +185,8 @@ ospf_new (void) /* SPF timer value init. */ new->spf_delay = OSPF_SPF_DELAY_DEFAULT; new->spf_holdtime = OSPF_SPF_HOLDTIME_DEFAULT; + new->spf_max_holdtime = OSPF_SPF_MAX_HOLDTIME_DEFAULT; + new->spf_hold_multiplier = 1; /* MaxAge init. */ new->maxage_lsa = list_new (); @@ -1212,24 +1214,6 @@ ospf_area_import_list_unset (struct ospf *ospf, struct ospf_area * area) return 1; } -int -ospf_timers_spf_set (struct ospf *ospf, u_int32_t delay, u_int32_t hold) -{ - ospf->spf_delay = delay; - ospf->spf_holdtime = hold; - - return 1; -} - -int -ospf_timers_spf_unset (struct ospf *ospf) -{ - ospf->spf_delay = OSPF_SPF_DELAY_DEFAULT; - ospf->spf_holdtime = OSPF_SPF_HOLDTIME_DEFAULT; - - return 1; -} - int ospf_timers_refresh_set (struct ospf *ospf, int interval) { diff --git a/ospfd/ospfd.h b/ospfd/ospfd.h index b24a1cf7..38e56b6f 100644 --- a/ospfd/ospfd.h +++ b/ospfd/ospfd.h @@ -88,8 +88,9 @@ #define OSPF_AUTH_CMD_NOTSEEN -2 /* OSPF SPF timer values. */ -#define OSPF_SPF_DELAY_DEFAULT 1 -#define OSPF_SPF_HOLDTIME_DEFAULT 1 +#define OSPF_SPF_DELAY_DEFAULT 200 +#define OSPF_SPF_HOLDTIME_DEFAULT 1000 +#define OSPF_SPF_MAX_HOLDTIME_DEFAULT 10000 /* OSPF interface default values. */ #define OSPF_OUTPUT_COST_DEFAULT 10 @@ -191,8 +192,10 @@ struct ospf #define OPAQUE_BLOCK_TYPE_11_LSA_BIT (1 << 3) #endif /* HAVE_OPAQUE_LSA */ - int spf_delay; /* SPF delay time. */ - int spf_holdtime; /* SPF hold time. */ + unsigned int spf_delay; /* SPF delay time. */ + unsigned int spf_holdtime; /* SPF hold time. */ + unsigned int spf_max_holdtime; /* SPF maximum-holdtime */ + unsigned int spf_hold_multiplier; /* Adaptive multiplier for hold time */ int default_originate; /* Default information originate. */ #define DEFAULT_ORIGINATE_NONE 0 #define DEFAULT_ORIGINATE_ZEBRA 1 @@ -231,7 +234,7 @@ struct ospf prefix is LSA's adv. network*/ /* Time stamps. */ - time_t ts_spf; /* SPF calculation time stamp. */ + struct timeval ts_spf; /* SPF calculation time stamp. */ struct list *maxage_lsa; /* List of MaxAge LSA for deletion. */ int redistribute; /* Num of redistributed protocols. */ @@ -557,8 +560,6 @@ extern int ospf_area_import_list_set (struct ospf *, struct ospf_area *, extern int ospf_area_import_list_unset (struct ospf *, struct ospf_area *); extern int ospf_area_shortcut_set (struct ospf *, struct ospf_area *, int); extern int ospf_area_shortcut_unset (struct ospf *, struct ospf_area *); -extern int ospf_timers_spf_set (struct ospf *, u_int32_t, u_int32_t); -extern int ospf_timers_spf_unset (struct ospf *); extern int ospf_timers_refresh_set (struct ospf *, int); extern int ospf_timers_refresh_unset (struct ospf *); extern int ospf_nbr_nbma_set (struct ospf *, struct in_addr); -- cgit v1.2.1