示例#1
0
文件: ospf_nsm.c 项目: OPSF/uClinux
/* Execute NSM event process. */
int
ospf_nsm_event (struct thread *thread)
{
  int event;
  int next_state;
  struct ospf_neighbor *nbr;
  struct in_addr router_id;
  int old_state;
  struct ospf_interface *oi;

  nbr = THREAD_ARG (thread);
  event = THREAD_VAL (thread);
  router_id = nbr->router_id;

  old_state = nbr->state;
  oi = nbr->oi ;
  
  /* Call function. */
  next_state = (*(NSM [nbr->state][event].func))(nbr);

  /* When event is NSM_KillNbr or InactivityTimer, the neighbor is
     deleted. */
  if (event == NSM_KillNbr || event == NSM_InactivityTimer)
    {
      if (IS_DEBUG_OSPF (nsm, NSM_EVENTS))
	zlog_debug ("NSM[%s:%s]: neighbor deleted",
		   IF_NAME (oi), inet_ntoa (router_id));

      /* Timers are canceled in ospf_nbr_free, moreover we cannot call
         nsm_timer_set here because nbr is freed already!!!*/
      /*nsm_timer_set (nbr);*/

      return 0;
    }

  if (! next_state)
    next_state = NSM [nbr->state][event].next_state;

  if (IS_DEBUG_OSPF (nsm, NSM_EVENTS))
    zlog_debug ("NSM[%s:%s]: %s (%s)", IF_NAME (oi),
	       inet_ntoa (nbr->router_id),
	       LOOKUP (ospf_nsm_state_msg, nbr->state),
	       ospf_nsm_event_str [event]);
  
  /* If state is changed. */
  if (next_state != nbr->state)
    nsm_change_state (nbr, next_state);

  /* Make sure timer is set. */
  nsm_timer_set (nbr);

  return 0;
}
示例#2
0
/* Execute NSM event process. */
int
ospf_nsm_event (struct thread *thread)
{
  int event;
  int next_state;
  struct ospf_neighbor *nbr;

  nbr = THREAD_ARG (thread);
  event = THREAD_VAL (thread);

  if (IS_DEBUG_OSPF (nsm, NSM_EVENTS))
    zlog_debug ("NSM[%s:%s]: %s (%s)", IF_NAME (nbr->oi),
	       inet_ntoa (nbr->router_id),
	       LOOKUP (ospf_nsm_state_msg, nbr->state),
	       ospf_nsm_event_str [event]);
  
  next_state = NSM [nbr->state][event].next_state;

  /* Call function. */
  if (NSM [nbr->state][event].func != NULL)
    {
      int func_state = (*(NSM [nbr->state][event].func))(nbr);
      
      if (NSM [nbr->state][event].next_state == NSM_DependUpon)
        next_state = func_state;
      else if (func_state)
        {
          /* There's a mismatch between the FSM tables and what an FSM
           * action/state-change function returned. State changes which
           * do not have conditional/DependUpon next-states should not
           * try set next_state.
           */
          zlog_warn ("NSM[%s:%s]: %s (%s): "
                     "Warning: action tried to change next_state to %s",
                     IF_NAME (nbr->oi), inet_ntoa (nbr->router_id),
                     LOOKUP (ospf_nsm_state_msg, nbr->state),
                     ospf_nsm_event_str [event],
                     LOOKUP (ospf_nsm_state_msg, func_state));
        }
    }

  assert (next_state != NSM_DependUpon);
  
  /* If state is changed. */
  if (next_state != nbr->state)
    {
      nsm_notice_state_change (nbr, next_state, event);
      nsm_change_state (nbr, next_state);
    }

  /* Make sure timer is set. */
  nsm_timer_set (nbr);

  /* When event is NSM_KillNbr, InactivityTimer or LLDown, the neighbor
   * is deleted.
   *
   * Rather than encode knowledge here of which events lead to NBR
   * delete, we take our cue from the NSM table, via the dummy
   * 'Deleted' neighbour state.
   */
  if (nbr->state == NSM_Deleted)
    ospf_nbr_delete (nbr);

  return 0;
}