Esempio n. 1
0
static void
nsm_notice_state_change (struct ospf_neighbor *nbr, int next_state, int event)
{
  /* Logging change of status. */
  if (IS_DEBUG_OSPF (nsm, NSM_STATUS))
    zlog_debug ("NSM[%s:%s]: State change %s -> %s (%s)",
               IF_NAME (nbr->oi), inet_ntoa (nbr->router_id),
               LOOKUP (ospf_nsm_state_msg, nbr->state),
               LOOKUP (ospf_nsm_state_msg, next_state),
               ospf_nsm_event_str [event]);

  /* Optionally notify about adjacency changes */
  if (CHECK_FLAG(nbr->oi->ospf->config, OSPF_LOG_ADJACENCY_CHANGES) &&
      (CHECK_FLAG(nbr->oi->ospf->config, OSPF_LOG_ADJACENCY_DETAIL) ||
       (next_state == NSM_Full) || (next_state < nbr->state)))
    zlog_notice("AdjChg: Nbr %s on %s: %s -> %s (%s)",
                inet_ntoa (nbr->router_id), IF_NAME (nbr->oi),
                LOOKUP (ospf_nsm_state_msg, nbr->state),
                LOOKUP (ospf_nsm_state_msg, next_state),
                ospf_nsm_event_str [event]);

  /* Advance in NSM */
  if (next_state > nbr->state)
    nbr->ts_last_progress = recent_relative_time ();
  else /* regression in NSM */
    {
      nbr->ts_last_regress = recent_relative_time ();
      nbr->last_regress_str = ospf_nsm_event_str [event];
    }

#ifdef HAVE_SNMP
  /* Terminal state or regression */ 
  if ((next_state == NSM_Full) 
      || (next_state == NSM_TwoWay)
      || (next_state < nbr->state))
    {
      /* ospfVirtNbrStateChange */
      if (nbr->oi->type == OSPF_IFTYPE_VIRTUALLINK)
        ospfTrapVirtNbrStateChange(nbr);
      /* ospfNbrStateChange trap  */
      else	
        /* To/From FULL, only managed by DR */
        if (((next_state != NSM_Full) && (nbr->state != NSM_Full)) 
            || (nbr->oi->state == ISM_DR))
          ospfTrapNbrStateChange(nbr);
    }
#endif
}
Esempio n. 2
0
/* Add schedule for SPF calculation.  To avoid frequenst SPF calc, we
   set timer for SPF calc. */
void
ospf6_spf_schedule (struct ospf6 *ospf6, unsigned int reason)
{
  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;

  /* 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);
}