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