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