]> git.puffer.fish Git - mirror/frr.git/commitdiff
2005-10-21 Paul Jakma <paul.jakma@sun.com>
authorpaul <paul>
Fri, 21 Oct 2005 09:23:12 +0000 (09:23 +0000)
committerpaul <paul>
Fri, 21 Oct 2005 09:23:12 +0000 (09:23 +0000)
* (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
ospfd/ospf_dump.c
ospfd/ospf_dump.h
ospfd/ospf_flood.c
ospfd/ospf_packet.c
ospfd/ospf_spf.c
ospfd/ospf_vty.c
ospfd/ospfd.c
ospfd/ospfd.h

index 13faf906cdc58b97e26513754db0ef72951dddfc..76c220aa79e5fe5d9abb5831820d9cd9edf5a2f3 100644 (file)
@@ -1,3 +1,55 @@
+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.
+         
 2005-10-21 Paul Jakma <paul.jakma@sun.com>
 
        * (general) OSPF fast, sub-second hello and 1s dead-interval
index 829c00f7bd4ed4f43f88cf1d7cf862bc305a221b..9ae87a61e7568f07fe294d46929b3594d58c728a 100644 (file)
@@ -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 *
index 81abb75455eed673b3310deaa61d30021a9ff88d..e24244ee0467ae67c2e6a07d25559a7fc54ddb7f 100644 (file)
@@ -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 *);
index a8b7e37a447c2bef228ec7116e22f5dd0c755330..d7ab859e90cd35d385acdd94033ecfac4600181d 100644 (file)
@@ -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)
index 7c29a04a212c640cbc1459c2d0478ed1d693d9e0..8b818d7230ac41ef1cc2c29403f3ab56b2e0ac78 100644 (file)
@@ -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);
            }
index b05117dae31a64d057053dc13adde8ee9cfd5fab..f6260fbda3d9130b78ba286e3f0671fd3ae0954c 100644 (file)
@@ -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);
 }
index 0d0befa7cecb7adad965c65fda6f6126302f9743..5263f15ca72e0c2089aeed6e4158a22afb5ca906 100644 (file)
@@ -2113,41 +2113,97 @@ ALIAS (no_ospf_compatible_rfc1583,
        NO_STR
        "OSPF specific commands\n"
        "Disable the RFC1583Compatibility flag\n")
+\f
+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")
 \f
 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);
index 9161f9cef962c475865baf8c748c9094c4687c43..bf8ca4dcb046125f94379b03b6676b26122b1a6a 100644 (file)
@@ -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)
 {
index b24a1cf79959b77ca457c040313d3e3d9dec261a..38e56b6f5630632c2b150c600a6f7fa224cb5b9b 100644 (file)
@@ -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);