Diff for /embedaddon/quagga/ospf6d/ospf6_spf.c between versions 1.1.1.3 and 1.1.1.4

version 1.1.1.3, 2013/07/21 23:54:40 version 1.1.1.4, 2016/11/02 10:09:11
Line 40 Line 40
 #include "ospf6_intra.h"  #include "ospf6_intra.h"
 #include "ospf6_interface.h"  #include "ospf6_interface.h"
 #include "ospf6d.h"  #include "ospf6d.h"
   #include "ospf6_abr.h"
   
 unsigned char conf_debug_ospf6_spf = 0;  unsigned char conf_debug_ospf6_spf = 0;
   
Line 224  static void Line 225  static void
 ospf6_nexthop_calc (struct ospf6_vertex *w, struct ospf6_vertex *v,  ospf6_nexthop_calc (struct ospf6_vertex *w, struct ospf6_vertex *v,
                     caddr_t lsdesc)                      caddr_t lsdesc)
 {  {
  int i, ifindex;  int i;
   ifindex_t ifindex;
   struct ospf6_interface *oi;    struct ospf6_interface *oi;
   u_int16_t type;    u_int16_t type;
   u_int32_t adv_router;    u_int32_t adv_router;
Line 234  ospf6_nexthop_calc (struct ospf6_vertex *w, struct osp Line 236  ospf6_nexthop_calc (struct ospf6_vertex *w, struct osp
   
   assert (VERTEX_IS_TYPE (ROUTER, w));    assert (VERTEX_IS_TYPE (ROUTER, w));
   ifindex = (VERTEX_IS_TYPE (NETWORK, v) ? v->nexthop[0].ifindex :    ifindex = (VERTEX_IS_TYPE (NETWORK, v) ? v->nexthop[0].ifindex :
             ROUTER_LSDESC_GET_IFID (lsdesc));             /* v is the local router & the interface_id is a local ifindex */
              (ifindex_t) ROUTER_LSDESC_GET_IFID (lsdesc));
   assert (ifindex >= 0);
   
   oi = ospf6_interface_lookup_by_ifindex (ifindex);    oi = ospf6_interface_lookup_by_ifindex (ifindex);
   if (oi == NULL)    if (oi == NULL)
     {      {
Line 377  ospf6_spf_table_finish (struct ospf6_route_table *resu Line 382  ospf6_spf_table_finish (struct ospf6_route_table *resu
     }      }
 }  }
   
   static const char *ospf6_spf_reason_str[] =
     {
       "R+",
       "R-",
       "N+",
       "N-",
       "L+",
       "L-",
       "R*",
       "N*",
     };
   
   void ospf6_spf_reason_string (unsigned int reason, char *buf, int size)
   {
     size_t bit;
     int len = 0;
   
     if (!buf)
       return;
   
     for (bit = 0; bit <= (sizeof(ospf6_spf_reason_str) / sizeof(char *)); bit++)
       {
         if ((reason & (1 << bit)) && (len < size))
           {
             len += snprintf((buf + len), (size - len), "%s%s",
                             (len > 0) ? ", " : "", ospf6_spf_reason_str[bit]);
           }
       }
   }
   
 /* RFC2328 16.1.  Calculating the shortest-path tree for an area */  /* RFC2328 16.1.  Calculating the shortest-path tree for an area */
 /* RFC2740 3.8.1.  Calculating the shortest path tree for an area */  /* RFC2740 3.8.1.  Calculating the shortest path tree for an area */
 void  void
Line 424  ospf6_spf_calculation (u_int32_t router_id, Line 459  ospf6_spf_calculation (u_int32_t router_id,
       if (ospf6_spf_install (v, result_table) < 0)        if (ospf6_spf_install (v, result_table) < 0)
         continue;          continue;
   
         /* Skip overloaded routers */
         if ((OSPF6_LSA_IS_TYPE (ROUTER, v->lsa) &&
              ospf6_router_is_stub_router (v->lsa)))
           continue;
   
       /* For each LS description in the just-added vertex V's LSA */        /* For each LS description in the just-added vertex V's LSA */
       size = (VERTEX_IS_TYPE (ROUTER, v) ?        size = (VERTEX_IS_TYPE (ROUTER, v) ?
               sizeof (struct ospf6_router_lsdesc) :                sizeof (struct ospf6_router_lsdesc) :
Line 506  static int Line 546  static int
 ospf6_spf_calculation_thread (struct thread *t)  ospf6_spf_calculation_thread (struct thread *t)
 {  {
   struct ospf6_area *oa;    struct ospf6_area *oa;
     struct ospf6 *ospf6;
   struct timeval start, end, runtime;    struct timeval start, end, runtime;
     struct listnode *node;
     struct ospf6_route *route;
     int areas_processed = 0;
     char rbuf[32];
   
  oa = (struct ospf6_area *) THREAD_ARG (t);  ospf6 = (struct ospf6 *)THREAD_ARG (t);
  oa->thread_spf_calculation = NULL;  ospf6->t_spf_calc = NULL;
   
   if (IS_OSPF6_DEBUG_SPF (PROCESS))  
     zlog_debug ("SPF calculation for Area %s", oa->name);  
   if (IS_OSPF6_DEBUG_SPF (DATABASE))  
     ospf6_spf_log_database (oa);  
   
   /* execute SPF calculation */    /* execute SPF calculation */
   quagga_gettime (QUAGGA_CLK_MONOTONIC, &start);    quagga_gettime (QUAGGA_CLK_MONOTONIC, &start);
  ospf6_spf_calculation (oa->ospf6->router_id, oa->spf_table, oa);
   for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, node, oa))
     {
 
       if (oa == ospf6->backbone)
         continue;
 
       if (IS_OSPF6_DEBUG_SPF (PROCESS))
         zlog_debug ("SPF calculation for Area %s", oa->name);
       if (IS_OSPF6_DEBUG_SPF (DATABASE))
         ospf6_spf_log_database (oa);
 
       ospf6_spf_calculation (ospf6->router_id, oa->spf_table, oa);
       ospf6_intra_route_calculation (oa);
       ospf6_intra_brouter_calculation (oa);
 
       areas_processed++;
     }
 
   if (ospf6->backbone)
     {
       if (IS_OSPF6_DEBUG_SPF (PROCESS))
         zlog_debug ("SPF calculation for Backbone area %s",
                     ospf6->backbone->name);
       if (IS_OSPF6_DEBUG_SPF (DATABASE))
         ospf6_spf_log_database(ospf6->backbone);
 
       ospf6_spf_calculation(ospf6->router_id, ospf6->backbone->spf_table,
                             ospf6->backbone);
       ospf6_intra_route_calculation(ospf6->backbone);
       ospf6_intra_brouter_calculation(ospf6->backbone);
       areas_processed++;
     }
 
   /* Redo summaries if required */
   for (route = ospf6_route_head (ospf6->route_table); route;
        route = ospf6_route_next (route))
     ospf6_abr_originate_summary(route);
 
   quagga_gettime (QUAGGA_CLK_MONOTONIC, &end);    quagga_gettime (QUAGGA_CLK_MONOTONIC, &end);
   timersub (&end, &start, &runtime);    timersub (&end, &start, &runtime);
   
  if (IS_OSPF6_DEBUG_SPF (PROCESS) || IS_OSPF6_DEBUG_SPF (TIME))  ospf6->ts_spf_duration = runtime;
    zlog_debug ("SPF runtime: %ld sec %ld usec", 
                runtime.tv_sec, runtime.tv_usec); 
   
  ospf6_intra_route_calculation (oa);  ospf6_spf_reason_string(ospf6->spf_reason, rbuf, sizeof(rbuf));
  ospf6_intra_brouter_calculation (oa); 
   
     if (IS_OSPF6_DEBUG_SPF (PROCESS) || IS_OSPF6_DEBUG_SPF (TIME))
       zlog_debug ("SPF runtime: %lld sec %lld usec",
                   (long long)runtime.tv_sec, (long long)runtime.tv_usec);
   
     zlog_info("SPF processing: # Areas: %d, SPF runtime: %lld sec %lld usec, "
               "Reason: %s\n", areas_processed,
               (long long)runtime.tv_sec, (long long)runtime.tv_usec,
               rbuf);
     ospf6->last_spf_reason = ospf6->spf_reason;
     ospf6_reset_spf_reason(ospf6);
   return 0;    return 0;
 }  }
   
   /* Add schedule for SPF calculation.  To avoid frequenst SPF calc, we
      set timer for SPF calc. */
 void  void
ospf6_spf_schedule (struct ospf6_area *oa)ospf6_spf_schedule (struct ospf6 *ospf6, unsigned int reason)
 {  {
  if (oa->thread_spf_calculation)  unsigned long delay, elapsed, ht;
   struct timeval now, result;
 
   ospf6_set_spf_reason(ospf6, reason);
 
   if (IS_OSPF6_DEBUG_SPF(PROCESS) || IS_OSPF6_DEBUG_SPF (TIME))
     {
       char rbuf[32];
       ospf6_spf_reason_string(reason, rbuf, sizeof(rbuf));
       zlog_debug ("SPF: calculation timer scheduled (reason %s)", rbuf);
     }
 
   /* OSPF instance does not exist. */
   if (ospf6 == NULL)
     return;      return;
  oa->thread_spf_calculation =
    thread_add_event (master, ospf6_spf_calculation_thread, oa, 0);  /* SPF calculation timer is already scheduled. */
   if (ospf6->t_spf_calc)
     {
       if (IS_OSPF6_DEBUG_SPF(PROCESS) || IS_OSPF6_DEBUG_SPF (TIME))
         zlog_debug ("SPF: calculation timer is already scheduled: %p",
                     (void *)ospf6->t_spf_calc);
       return;
     }
 
   /* XXX Monotic timers: we only care about relative time here. */
   now = recent_relative_time ();
   timersub (&now, &ospf6->ts_spf, &result);
 
   elapsed = (result.tv_sec * 1000) + (result.tv_usec / 1000);
   ht = ospf6->spf_holdtime * ospf6->spf_hold_multiplier;
 
   if (ht > ospf6->spf_max_holdtime)
     ht = ospf6->spf_max_holdtime;
 
   /* Get SPF calculation delay time. */
   if (elapsed < ht)
     {
       /* 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 < ospf6->spf_max_holdtime)
         ospf6->spf_hold_multiplier++;
 
       /* always honour the SPF initial delay */
       if ( (ht - elapsed) < ospf6->spf_delay)
         delay = ospf6->spf_delay;
       else
         delay = ht - elapsed;
     }
   else
     {
       /* Event is past required hold-time of last SPF */
       delay = ospf6->spf_delay;
       ospf6->spf_hold_multiplier = 1;
     }
 
   if (IS_OSPF6_DEBUG_SPF(PROCESS) || IS_OSPF6_DEBUG_SPF (TIME))
     zlog_debug ("SPF: calculation timer delay = %ld", delay);
 
   zlog_info ("SPF: Scheduled in %ld msec", delay);
 
   ospf6->t_spf_calc =
     thread_add_timer_msec (master, ospf6_spf_calculation_thread, ospf6, delay);
 }  }
   
 void  void
Line 666  DEFUN (no_debug_ospf6_spf_database, Line 814  DEFUN (no_debug_ospf6_spf_database,
   return CMD_SUCCESS;    return CMD_SUCCESS;
 }  }
   
   static int
   ospf6_timers_spf_set (struct vty *vty, unsigned int delay,
                        unsigned int hold,
                        unsigned int max)
   {
     struct ospf6 *ospf = vty->index;
   
     ospf->spf_delay = delay;
     ospf->spf_holdtime = hold;
     ospf->spf_max_holdtime = max;
   
     return CMD_SUCCESS;
   }
   
   DEFUN (ospf6_timers_throttle_spf,
          ospf6_timers_throttle_spf_cmd,
          "timers throttle spf <0-600000> <0-600000> <0-600000>",
          "Adjust routing timers\n"
          "Throttling adaptive timer\n"
          "OSPF6 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 ospf6_timers_spf_set (vty, delay, hold, max);
   }
   
   DEFUN (no_ospf6_timers_throttle_spf,
          no_ospf6_timers_throttle_spf_cmd,
          "no timers throttle spf",
          NO_STR
          "Adjust routing timers\n"
          "Throttling adaptive timer\n"
          "OSPF6 SPF timers\n")
   {
     return ospf6_timers_spf_set (vty,
                                 OSPF_SPF_DELAY_DEFAULT,
                                 OSPF_SPF_HOLDTIME_DEFAULT,
                                 OSPF_SPF_MAX_HOLDTIME_DEFAULT);
   }
   
 int  int
 config_write_ospf6_debug_spf (struct vty *vty)  config_write_ospf6_debug_spf (struct vty *vty)
 {  {
Line 679  config_write_ospf6_debug_spf (struct vty *vty) Line 880  config_write_ospf6_debug_spf (struct vty *vty)
 }  }
   
 void  void
   ospf6_spf_config_write (struct vty *vty)
   {
   
     if (ospf6->spf_delay != OSPF_SPF_DELAY_DEFAULT ||
         ospf6->spf_holdtime != OSPF_SPF_HOLDTIME_DEFAULT ||
         ospf6->spf_max_holdtime != OSPF_SPF_MAX_HOLDTIME_DEFAULT)
       vty_out (vty, " timers throttle spf %d %d %d%s",
                ospf6->spf_delay, ospf6->spf_holdtime,
                ospf6->spf_max_holdtime, VTY_NEWLINE);
   
   }
   
   void
 install_element_ospf6_debug_spf (void)  install_element_ospf6_debug_spf (void)
 {  {
   install_element (ENABLE_NODE, &debug_ospf6_spf_process_cmd);    install_element (ENABLE_NODE, &debug_ospf6_spf_process_cmd);
Line 698  install_element_ospf6_debug_spf (void) Line 912  install_element_ospf6_debug_spf (void)
 void  void
 ospf6_spf_init (void)  ospf6_spf_init (void)
 {  {
     install_element (OSPF6_NODE, &ospf6_timers_throttle_spf_cmd);
     install_element (OSPF6_NODE, &no_ospf6_timers_throttle_spf_cmd);
 }  }
   
   

Removed from v.1.1.1.3  
changed lines
  Added in v.1.1.1.4


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>