📄 ospf_ism.c
字号:
OSPF_ISM_TIMER_OFF (oi->t_wait); OSPF_ISM_TIMER_OFF (oi->t_ls_ack); break; case ISM_Waiting: /* The router is trying to determine the identity of DRouter and BDRouter. The router begin to receive and send Hello Packets. */ /* send first hello immediately */ OSPF_ISM_TIMER_ON (oi->t_hello, ospf_hello_timer, 1); OSPF_ISM_TIMER_ON (oi->t_wait, ospf_wait_timer, OSPF_IF_PARAM (oi, v_wait)); OSPF_ISM_TIMER_OFF (oi->t_ls_ack); break; case ISM_PointToPoint: /* The interface connects to a physical Point-to-point network or virtual link. The router attempts to form an adjacency with neighboring router. Hello packets are also sent. */ /* send first hello immediately */ OSPF_ISM_TIMER_ON (oi->t_hello, ospf_hello_timer, 1); OSPF_ISM_TIMER_OFF (oi->t_wait); OSPF_ISM_TIMER_ON (oi->t_ls_ack, ospf_ls_ack_timer, oi->v_ls_ack); break; case ISM_DROther: /* The network type of the interface is broadcast or NBMA network, and the router itself is neither Designated Router nor Backup Designated Router. */ OSPF_ISM_TIMER_ON (oi->t_hello, ospf_hello_timer, OSPF_IF_PARAM (oi, v_hello)); OSPF_ISM_TIMER_OFF (oi->t_wait); OSPF_ISM_TIMER_ON (oi->t_ls_ack, ospf_ls_ack_timer, oi->v_ls_ack); break; case ISM_Backup: /* The network type of the interface is broadcast os NBMA network, and the router is Backup Designated Router. */ OSPF_ISM_TIMER_ON (oi->t_hello, ospf_hello_timer, OSPF_IF_PARAM (oi, v_hello)); OSPF_ISM_TIMER_OFF (oi->t_wait); OSPF_ISM_TIMER_ON (oi->t_ls_ack, ospf_ls_ack_timer, oi->v_ls_ack); break; case ISM_DR: /* The network type of the interface is broadcast or NBMA network, and the router is Designated Router. */ OSPF_ISM_TIMER_ON (oi->t_hello, ospf_hello_timer, OSPF_IF_PARAM (oi, v_hello)); OSPF_ISM_TIMER_OFF (oi->t_wait); OSPF_ISM_TIMER_ON (oi->t_ls_ack, ospf_ls_ack_timer, oi->v_ls_ack); break; }}intism_stop (struct ospf_interface *oi){ return 0;}intism_interface_up (struct ospf_interface *oi){ int next_state = 0; /* if network type is point-to-point, Point-to-MultiPoint or virtual link, the state transitions to Point-to-Point. */ if (oi->type == OSPF_IFTYPE_POINTOPOINT || oi->type == OSPF_IFTYPE_POINTOMULTIPOINT || oi->type == OSPF_IFTYPE_VIRTUALLINK) next_state = ISM_PointToPoint; /* Else if the router is not eligible to DR, the state transitions to DROther. */ else if (PRIORITY (oi) == 0) /* router is eligible? */ next_state = ISM_DROther; else /* Otherwise, the state transitions to Waiting. */ next_state = ISM_Waiting; if (oi->type == OSPF_IFTYPE_NBMA) ospf_nbr_nbma_if_update (oi->ospf, oi); /* ospf_ism_event (t); */ return next_state;}intism_loop_ind (struct ospf_interface *oi){ int ret = 0; /* call ism_interface_down. */ /* ret = ism_interface_down (oi); */ return ret;}/* Interface down event handler. */intism_interface_down (struct ospf_interface *oi){ ospf_if_cleanup (oi); return 0;}intism_backup_seen (struct ospf_interface *oi){ return ospf_dr_election (oi);}intism_wait_timer (struct ospf_interface *oi){ return ospf_dr_election (oi);}intism_neighbor_change (struct ospf_interface *oi){ return ospf_dr_election (oi);}intism_ignore (struct ospf_interface *oi){ if (IS_DEBUG_OSPF (ism, ISM_EVENTS)) zlog (NULL, LOG_INFO, "ISM[%s]: ism_ignore called", IF_NAME (oi)); return 0;}/* Interface State Machine */struct { int (*func) (); int next_state;} ISM [OSPF_ISM_STATE_MAX][OSPF_ISM_EVENT_MAX] ={ { /* DependUpon: dummy state. */ { ism_ignore, ISM_DependUpon }, /* NoEvent */ { ism_ignore, ISM_DependUpon }, /* InterfaceUp */ { ism_ignore, ISM_DependUpon }, /* WaitTimer */ { ism_ignore, ISM_DependUpon }, /* BackupSeen */ { ism_ignore, ISM_DependUpon }, /* NeighborChange */ { ism_ignore, ISM_DependUpon }, /* LoopInd */ { ism_ignore, ISM_DependUpon }, /* UnloopInd */ { ism_ignore, ISM_DependUpon }, /* InterfaceDown */ }, { /* Down:*/ { ism_ignore, ISM_DependUpon }, /* NoEvent */ { ism_interface_up, ISM_DependUpon }, /* InterfaceUp */ { ism_ignore, ISM_Down }, /* WaitTimer */ { ism_ignore, ISM_Down }, /* BackupSeen */ { ism_ignore, ISM_Down }, /* NeighborChange */ { ism_loop_ind, ISM_Loopback }, /* LoopInd */ { ism_ignore, ISM_Down }, /* UnloopInd */ { ism_interface_down, ISM_Down }, /* InterfaceDown */ }, { /* Loopback: */ { ism_ignore, ISM_DependUpon }, /* NoEvent */ { ism_ignore, ISM_Loopback }, /* InterfaceUp */ { ism_ignore, ISM_Loopback }, /* WaitTimer */ { ism_ignore, ISM_Loopback }, /* BackupSeen */ { ism_ignore, ISM_Loopback }, /* NeighborChange */ { ism_ignore, ISM_Loopback }, /* LoopInd */ { ism_ignore, ISM_Down }, /* UnloopInd */ { ism_interface_down, ISM_Down }, /* InterfaceDown */ }, { /* Waiting: */ { ism_ignore, ISM_DependUpon }, /* NoEvent */ { ism_ignore, ISM_Waiting }, /* InterfaceUp */ { ism_wait_timer, ISM_DependUpon }, /* WaitTimer */ { ism_backup_seen, ISM_DependUpon }, /* BackupSeen */ { ism_ignore, ISM_Waiting }, /* NeighborChange */ { ism_loop_ind, ISM_Loopback }, /* LoopInd */ { ism_ignore, ISM_Waiting }, /* UnloopInd */ { ism_interface_down, ISM_Down }, /* InterfaceDown */ }, { /* Point-to-Point: */ { ism_ignore, ISM_DependUpon }, /* NoEvent */ { ism_ignore, ISM_PointToPoint }, /* InterfaceUp */ { ism_ignore, ISM_PointToPoint }, /* WaitTimer */ { ism_ignore, ISM_PointToPoint }, /* BackupSeen */ { ism_ignore, ISM_PointToPoint }, /* NeighborChange */ { ism_loop_ind, ISM_Loopback }, /* LoopInd */ { ism_ignore, ISM_PointToPoint }, /* UnloopInd */ { ism_interface_down, ISM_Down }, /* InterfaceDown */ }, { /* DROther: */ { ism_ignore, ISM_DependUpon }, /* NoEvent */ { ism_ignore, ISM_DROther }, /* InterfaceUp */ { ism_ignore, ISM_DROther }, /* WaitTimer */ { ism_ignore, ISM_DROther }, /* BackupSeen */ { ism_neighbor_change, ISM_DependUpon }, /* NeighborChange */ { ism_loop_ind, ISM_Loopback }, /* LoopInd */ { ism_ignore, ISM_DROther }, /* UnloopInd */ { ism_interface_down, ISM_Down }, /* InterfaceDown */ }, { /* Backup: */ { ism_ignore, ISM_DependUpon }, /* NoEvent */ { ism_ignore, ISM_Backup }, /* InterfaceUp */ { ism_ignore, ISM_Backup }, /* WaitTimer */ { ism_ignore, ISM_Backup }, /* BackupSeen */ { ism_neighbor_change, ISM_DependUpon }, /* NeighborChange */ { ism_loop_ind, ISM_Loopback }, /* LoopInd */ { ism_ignore, ISM_Backup }, /* UnloopInd */ { ism_interface_down, ISM_Down }, /* InterfaceDown */ }, { /* DR: */ { ism_ignore, ISM_DependUpon }, /* NoEvent */ { ism_ignore, ISM_DR }, /* InterfaceUp */ { ism_ignore, ISM_DR }, /* WaitTimer */ { ism_ignore, ISM_DR }, /* BackupSeen */ { ism_neighbor_change, ISM_DependUpon }, /* NeighborChange */ { ism_loop_ind, ISM_Loopback }, /* LoopInd */ { ism_ignore, ISM_DR }, /* UnloopInd */ { ism_interface_down, ISM_Down }, /* InterfaceDown */ },}; static char *ospf_ism_event_str[] ={ "NoEvent", "InterfaceUp", "WaitTimer", "BackupSeen", "NeighborChange", "LoopInd", "UnLoopInd", "InterfaceDown",};voidism_change_state (struct ospf_interface *oi, int state){ int old_state; struct ospf_lsa *lsa; /* Logging change of state. */ if (IS_DEBUG_OSPF (ism, ISM_STATUS)) zlog (NULL, LOG_INFO, "ISM[%s]: State change %s -> %s", IF_NAME (oi), LOOKUP (ospf_ism_state_msg, oi->state), LOOKUP (ospf_ism_state_msg, state)); old_state = oi->state; oi->state = state; oi->state_change++; if (old_state == ISM_Down || state == ISM_Down) ospf_check_abr_status (oi->ospf); /* Originate router-LSA. */ if (oi->area) { if (state == ISM_Down) { if (oi->area->act_ints > 0) oi->area->act_ints--; } else if (old_state == ISM_Down) oi->area->act_ints++; /* schedule router-LSA originate. */ ospf_router_lsa_timer_add (oi->area); } /* Originate network-LSA. */ if (old_state != ISM_DR && state == ISM_DR) ospf_network_lsa_timer_add (oi); else if (old_state == ISM_DR && state != ISM_DR) { /* Free self originated network LSA. */ lsa = oi->network_lsa_self; if (lsa) { ospf_lsa_flush_area (lsa, oi->area); OSPF_TIMER_OFF (oi->t_network_lsa_self); } ospf_lsa_unlock (oi->network_lsa_self); oi->network_lsa_self = NULL; }#ifdef HAVE_OPAQUE_LSA ospf_opaque_ism_change (oi, old_state);#endif /* HAVE_OPAQUE_LSA */ /* Check area border status. */ ospf_check_abr_status (oi->ospf);}/* Execute ISM event process. */intospf_ism_event (struct thread *thread){ int event; int next_state; struct ospf_interface *oi; oi = THREAD_ARG (thread); event = THREAD_VAL (thread); /* Call function. */ next_state = (*(ISM [oi->state][event].func))(oi); if (! next_state) next_state = ISM [oi->state][event].next_state; if (IS_DEBUG_OSPF (ism, ISM_EVENTS)) zlog (NULL, LOG_INFO, "ISM[%s]: %s (%s)", IF_NAME (oi), LOOKUP (ospf_ism_state_msg, oi->state), ospf_ism_event_str[event]); /* If state is changed. */ if (next_state != oi->state) ism_change_state (oi, next_state); /* Make sure timer is set. */ ism_timer_set (oi); return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -