ospf 不同状态机起的定时器:
ism:
ospf-ifp
ism_down ->(event:l3-ifp-up)-> ism_waiting -> 等待ism选举【起waiting等待定时器】
nsm->down ->(event:hello-PacketReceived)-> nsm_init 【接收处理hello报文,OSPF_NSM_EVENT_SCHEDULE (nbr,
NSM_OneWayReceived); 知道hello报文发现对端邻居Active Neighbor: 4.4.4.4】 ->
OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_TwoWayReceived);【直到ism选举出来drX/bdrX出来, nsm其状态发生变化】 ->
(adj【bdrX/drX选举成功进入exStart否则进入twoway等待ism选举】 ? NSM_ExStart : NSM_TwoWay); ->
ism选举未成功,nsm状态切换到two-way,等待ism选举。 -> 选举成功进入到nsm-exstart, db-desc报文交互,目的协商
主从关系,协商序列号,同时起db-desc定时器发送,直到nsm-exstart切换到下一个状态则取消其定时器发送db-desc报文。
-> 如果邻居router-id > self-router-id, 则邻居是master. --> 主从关系协商ok,产生self-lsa安装在database中 ->
状态切换到nsm-exchange, 起定期器更新邻居状态数据库LSA
static void
nsm_timer_set (struct ospf_neighbor *nbr)
{
switch (nbr->state)
{
case NSM_Deleted:
case NSM_Down:
OSPF_NSM_TIMER_OFF (nbr->t_inactivity);
OSPF_NSM_TIMER_OFF (nbr->t_hello_reply);
case NSM_Attempt:
case NSM_Init:
case NSM_TwoWay:
OSPF_NSM_TIMER_OFF (nbr->t_db_desc);
OSPF_NSM_TIMER_OFF (nbr->t_ls_upd);
OSPF_NSM_TIMER_OFF (nbr->t_ls_req);
break;
case NSM_ExStart:
OSPF_NSM_TIMER_ON (nbr->t_db_desc, ospf_db_desc_timer, nbr->v_db_desc);
OSPF_NSM_TIMER_OFF (nbr->t_ls_upd);
OSPF_NSM_TIMER_OFF (nbr->t_ls_req);
break;
case NSM_Exchange:
OSPF_NSM_TIMER_ON (nbr->t_ls_upd, ospf_ls_upd_timer, nbr->v_ls_upd);
if (!IS_SET_DD_MS (nbr->dd_flags))
OSPF_NSM_TIMER_OFF (nbr->t_db_desc);
break;
case NSM_Loading:
case NSM_Full:
default:
OSPF_NSM_TIMER_OFF (nbr->t_db_desc);
break;
}
}
static void
ism_timer_set (struct ospf_interface *oi)
{
switch (oi->state)
{
case ISM_Down:
/* First entry point of ospf interface state machine. In this state
interface parameters must be set to initial values, and timers are
reset also. */
OSPF_ISM_TIMER_OFF (oi->t_hello);
OSPF_ISM_TIMER_OFF (oi->t_wait);
OSPF_ISM_TIMER_OFF (oi->t_ls_ack);
break;
case ISM_Loopback:
/* In this state, the interface may be looped back and will be
unavailable for regular data traffic. */
OSPF_ISM_TIMER_OFF (oi->t_hello);
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_MSEC_ON (oi->t_hello, ospf_hello_timer, 1);
if (OSPF_IF_PARAM_CONFIGURED (oi->params, fast_hello))
OSPF_ISM_TIMER_ON (oi->t_wait, ospf_wait_timer, 10);
else
OSPF_ISM_TIMER_ON (oi->t_wait, ospf_wait_timer, (OSPF_IF_PARAM (oi, v_hello)*4));
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_MSEC_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_HELLO_TIMER_ON (oi);
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_HELLO_TIMER_ON (oi);
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_HELLO_TIMER_ON (oi);
OSPF_ISM_TIMER_OFF (oi->t_wait);
OSPF_ISM_TIMER_ON (oi->t_ls_ack, ospf_ls_ack_timer, oi->v_ls_ack);
break;
}
}
NSM: 邻居状态机
ISM 接口状态机
/* Interface State Machine */
struct {
int (*func) (struct ospf_interface *);
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 */
},
};
/* Neighbor State Machine */
struct {
int (*func) (struct ospf_neighbor *);
int next_state;
} NSM [OSPF_NSM_STATE_MAX][OSPF_NSM_EVENT_MAX] =
{
{
/* DependUpon: dummy state. */
{ NULL, NSM_DependUpon }, /* NoEvent */
{ NULL, NSM_DependUpon }, /* PacketReceived */
{ NULL, NSM_DependUpon }, /* Start */
{ NULL, NSM_DependUpon }, /* 2-WayReceived */
{ NULL, NSM_DependUpon }, /* NegotiationDone */
{ NULL, NSM_DependUpon }, /* ExchangeDone */
{ NULL, NSM_DependUpon }, /* BadLSReq */
{ NULL, NSM_DependUpon }, /* LoadingDone */
{ NULL, NSM_DependUpon }, /* AdjOK? */
{ NULL, NSM_DependUpon }, /* SeqNumberMismatch */
{ NULL, NSM_DependUpon }, /* 1-WayReceived */
{ NULL, NSM_DependUpon }, /* KillNbr */
{ NULL, NSM_DependUpon }, /* InactivityTimer */
{ NULL, NSM_DependUpon }, /* LLDown */
},
{
/* Deleted: dummy state. */
{ NULL, NSM_Deleted }, /* NoEvent */
{ NULL, NSM_Deleted }, /* PacketReceived */
{ NULL, NSM_Deleted }, /* Start */
{ NULL, NSM_Deleted }, /* 2-WayReceived */
{ NULL, NSM_Deleted }, /* NegotiationDone */
{ NULL, NSM_Deleted }, /* ExchangeDone */
{ NULL, NSM_Deleted }, /* BadLSReq */
{ NULL, NSM_Deleted }, /* LoadingDone */
{ NULL, NSM_Deleted }, /* AdjOK? */
{ NULL, NSM_Deleted }, /* SeqNumberMismatch */
{ NULL, NSM_Deleted }, /* 1-WayReceived */
{ NULL, NSM_Deleted }, /* KillNbr */
{ NULL, NSM_Deleted }, /* InactivityTimer */
{ NULL, NSM_Deleted }, /* LLDown */
},
{
/* Down: */
{ NULL, NSM_DependUpon }, /* NoEvent */
{ nsm_packet_received, NSM_Init }, /* PacketReceived */
{ nsm_start, NSM_Attempt }, /* Start */
{ NULL, NSM_Down }, /* 2-WayReceived */
{ NULL, NSM_Down }, /* NegotiationDone */
{ NULL, NSM_Down }, /* ExchangeDone */
{ NULL, NSM_Down }, /* BadLSReq */
{ NULL, NSM_Down }, /* LoadingDone */
{ NULL, NSM_Down }, /* AdjOK? */
{ NULL, NSM_Down }, /* SeqNumberMismatch */
{ NULL, NSM_Down }, /* 1-WayReceived */
{ nsm_kill_nbr, NSM_Deleted }, /* KillNbr */
{ nsm_kill_nbr, NSM_Deleted }, /* InactivityTimer */
{ nsm_kill_nbr, NSM_Deleted }, /* LLDown */
},
{
/* Attempt: */
{ NULL, NSM_DependUpon }, /* NoEvent */
{ nsm_packet_received, NSM_Init }, /* PacketReceived */
{ NULL, NSM_Attempt }, /* Start */
{ NULL, NSM_Attempt }, /* 2-WayReceived */
{ NULL, NSM_Attempt }, /* NegotiationDone */
{ NULL, NSM_Attempt }, /* ExchangeDone */
{ NULL, NSM_Attempt }, /* BadLSReq */
{ NULL, NSM_Attempt }, /* LoadingDone */
{ NULL, NSM_Attempt }, /* AdjOK? */
{ NULL, NSM_Attempt }, /* SeqNumberMismatch */
{ NULL, NSM_Attempt }, /* 1-WayReceived */
{ nsm_kill_nbr, NSM_Deleted }, /* KillNbr */
{ nsm_kill_nbr, NSM_Deleted }, /* InactivityTimer */
{ nsm_kill_nbr, NSM_Deleted }, /* LLDown */
},
{
/* Init: */
{ NULL, NSM_DependUpon }, /* NoEvent */
{ nsm_packet_received, NSM_Init }, /* PacketReceived */
{ NULL, NSM_Init }, /* Start */
{ nsm_twoway_received, NSM_DependUpon }, /* 2-WayReceived */
{ NULL, NSM_Init }, /* NegotiationDone */
{ NULL, NSM_Init }, /* ExchangeDone */
{ NULL, NSM_Init }, /* BadLSReq */
{ NULL, NSM_Init }, /* LoadingDone */
{ NULL, NSM_Init }, /* AdjOK? */
{ NULL, NSM_Init }, /* SeqNumberMismatch */
{ NULL, NSM_Init }, /* 1-WayReceived */
{ nsm_kill_nbr, NSM_Deleted }, /* KillNbr */
{ nsm_kill_nbr, NSM_Deleted }, /* InactivityTimer */
{ nsm_kill_nbr, NSM_Deleted }, /* LLDown */
},
{
/* 2-Way: */
{ NULL, NSM_DependUpon }, /* NoEvent */
{ nsm_packet_received, NSM_TwoWay }, /* HelloReceived */
{ NULL, NSM_TwoWay }, /* Start */
{ NULL, NSM_TwoWay }, /* 2-WayReceived */
{ NULL, NSM_TwoWay }, /* NegotiationDone */
{ NULL, NSM_TwoWay }, /* ExchangeDone */
{ NULL, NSM_TwoWay }, /* BadLSReq */
{ NULL, NSM_TwoWay }, /* LoadingDone */
{ nsm_adj_ok, NSM_DependUpon }, /* AdjOK? */
{ NULL, NSM_TwoWay }, /* SeqNumberMismatch */
{ NULL, NSM_Init }, /* 1-WayReceived */
{ nsm_kill_nbr, NSM_Deleted }, /* KillNbr */
{ nsm_kill_nbr, NSM_Deleted }, /* InactivityTimer */
{ nsm_kill_nbr, NSM_Deleted }, /* LLDown */
},
{
/* ExStart: */
{ NULL, NSM_DependUpon }, /* NoEvent */
{ nsm_packet_received, NSM_ExStart }, /* PacaketReceived */
{ NULL, NSM_ExStart }, /* Start */
{ NULL, NSM_ExStart }, /* 2-WayReceived */
{ nsm_negotiation_done, NSM_Exchange }, /* NegotiationDone */
{ NULL, NSM_ExStart }, /* ExchangeDone */
{ NULL, NSM_ExStart }, /* BadLSReq */
{ NULL, NSM_ExStart }, /* LoadingDone */
{ nsm_adj_ok, NSM_DependUpon }, /* AdjOK? */
{ NULL, NSM_ExStart }, /* SeqNumberMismatch */
{ NULL, NSM_Init }, /* 1-WayReceived */
{ nsm_kill_nbr, NSM_Deleted }, /* KillNbr */
{ nsm_kill_nbr, NSM_Deleted }, /* InactivityTimer */
{ nsm_kill_nbr, NSM_Deleted }, /* LLDown */
},
{
/* Exchange: */
{ NULL, NSM_DependUpon }, /* NoEvent */
{ nsm_packet_received, NSM_Exchange }, /* PacketReceived */
{ NULL, NSM_Exchange }, /* Start */
{ NULL, NSM_Exchange }, /* 2-WayReceived */
{ NULL, NSM_Exchange }, /* NegotiationDone */
{ nsm_exchange_done, NSM_DependUpon }, /* ExchangeDone */
{ NULL, NSM_ExStart }, /* BadLSReq */
{ NULL, NSM_Exchange }, /* LoadingDone */
{ nsm_adj_ok, NSM_DependUpon }, /* AdjOK? */
{ NULL, NSM_ExStart }, /* SeqNumberMismatch */
{ NULL, NSM_Init }, /* 1-WayReceived */
{ nsm_kill_nbr, NSM_Deleted }, /* KillNbr */
{ nsm_kill_nbr, NSM_Deleted }, /* InactivityTimer */
{ nsm_kill_nbr, NSM_Deleted }, /* LLDown */
},
{
/* Loading: */
{ NULL, NSM_DependUpon }, /* NoEvent */
{ nsm_packet_received, NSM_Loading }, /* PacketReceived */
{ NULL, NSM_Loading }, /* Start */
{ NULL, NSM_Loading }, /* 2-WayReceived */
{ NULL, NSM_Loading }, /* NegotiationDone */
{ NULL, NSM_Loading }, /* ExchangeDone */
{ NULL, NSM_ExStart }, /* BadLSReq */
{ NULL, NSM_Full }, /* LoadingDone */
{ nsm_adj_ok, NSM_DependUpon }, /* AdjOK? */
{ NULL, NSM_ExStart }, /* SeqNumberMismatch */
{ NULL, NSM_Init }, /* 1-WayReceived */
{ nsm_kill_nbr, NSM_Deleted }, /* KillNbr */
{ nsm_kill_nbr, NSM_Deleted }, /* InactivityTimer */
{ nsm_kill_nbr, NSM_Deleted }, /* LLDown */
},
{ /* Full: */
{ NULL, NSM_DependUpon }, /* NoEvent */
{ nsm_packet_received, NSM_Full }, /* PacketReceived */
{ NULL, NSM_Full }, /* Start */
{ NULL, NSM_Full }, /* 2-WayReceived */
{ NULL, NSM_Full }, /* NegotiationDone */
{ NULL, NSM_Full }, /* ExchangeDone */
{ NULL, NSM_ExStart }, /* BadLSReq */
{ NULL, NSM_Full }, /* LoadingDone */
{ nsm_adj_ok, NSM_DependUpon }, /* AdjOK? */
{ NULL, NSM_ExStart }, /* SeqNumberMismatch */
{ NULL, NSM_Init }, /* 1-WayReceived */
{ nsm_kill_nbr, NSM_Deleted }, /* KillNbr */
{ nsm_kill_nbr, NSM_Deleted }, /* InactivityTimer */
{ nsm_kill_nbr, NSM_Deleted }, /* LLDown */
},
};