case 2.1
DR and BDR become adjacent with all other routers.
nsm_twoway_received() changes nbr state from NSM_Init to NSM_ExStart.
two ways can trigger this function.
ospf_hello
|--OSPF_NSM_EVENT_EXECUTE (nbr, NSM_HelloReceived) (NSM_Down-->NSM_NSM_Init)
|--OSPF_NSM_EVENT_EXECUTE (nbr, NSM_TwoWayReceived) (NSM_Init-->NSM_ExStart)
ospf_db_desc
|--OSPF_NSM_EVENT_EXECUTE (nbr, NSM_TwoWayReceived) (NSM_Init-->NSM_ExStart)
after change to NSM_ExStart, begin to send DD packets.
ospf_nsm_event
|--nsm_twoway_received
|--nsm_change_state
|--ospf_db_desc_send
|--nsm_timer_set
|--OSPF_NSM_TIMER_ON (ospf_db_desc_timer)
case 2.2
ospf_db_desc_send
|--ospf_make_db_desc
case 2.3
ospf_db_desc
case 2.4
ospf_neighbor{}
|--ls_rxmt
|--db_sum
|--ls_req
Negotiation Process refer Page 106 of RFC 2328
Slave router (lower router id) change to NSM_Exchange after received the Initial DD packet from Master.
Master router change to NSM_Exchange after received the ack DD packet from Slave.
OSPF_NSM_EVENT_EXECUTE (nbr, NSM_NegotiationDone) (NSM_ExStart-->NSM_Exchange)
ospf_nsm_event
|--nsm_negotiation_done (add all lsas to database summary list db_sum )
ospf_db_desc
|--ospf_db_desc_proc
|--ospf_ls_request_add (add received lsas to Link State Request list ls_req)
router generates event NSM_ExchangeDone after db_sum is empty.
the slave always generates event NSM_ExchangeDone before the master.
ospf_db_desc_proc
|--OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_ExchangeDone)(NSM_Exchange-->NSM_Loading)
|--nsm_exchange_done
|--ospf_ls_req_send
case 2.5
for router lsa
ospf_ls_upd
|--ospf_lsa_more_recent
|--ospf_flood
|--ospf_lsa_is_self_originated
|--ospf_process_self_originated_lsa
|--ospf_router_lsa_timer_add (for router lsa)
or
|--ospf_schedule_lsa_flush_area (for network lsa)
|--ospf_network_lsa_timer_add
for network lsa and router id is changed.
ospf_ls_upd
|--ospf_lsa_flush_area
case 2.6
ospf_ls_upd
|--ospf_ls_upd_send_lsa (nbr, current, OSPF_SEND_PACKET_DIRECT)
case 2.7
ospf_ls_upd
ospf_ls_req
case 2.8
Part A
Slave dont retransmit the non-initial DD packet.
ospf_db_desc
|--OSPF_NSM_EVENT_EXECUTE (NSM_NegotiationDone) (NSM_ExStart-->NSM_Exchange)
|--nsm_timer_set
|--if (!IS_SET_DD_MS (nbr->dd_flags)) (the router is slave)
|--OSPF_NSM_TIMER_OFF (nbr->t_db_desc)
Part B
ospf_db_desc
|--ospf_db_desc_resend
Part C
nbr->t_db_desc is on when nbr change to NSM_ExStart, and is not off when change to NSM_Exchange if the router is master
case 2.9
ospf_db_desc
ospf_db_desc_proc
case 2.10
ospf_ls_upd
|--ospf_flood
|--ospf_flood_through
|--ospf_flood_through_area (lsa->area, inbr, lsa)
|--ospf_flood_through_interface
|--ospf_ls_upd_send_lsa (oi->nbr_self, lsa, OSPF_SEND_PACKET_INDIRECT)
|--ospf_lsa_install
|--if (lsa_ack_flag)
|--ospf_flood_delayed_lsa_ack (nbr, new)
[note]parameter "inbr" will be used to distinguish the called context whether the given LSA was received from the neighbor, or the flooding for the LSA starts from this node (e.g. the LSA was self-originated, or the LSA is going to be flushed from routing domain)
case 2.11
ospf_ls_upd
|--ospf_flood
|--ospf_flood_through
|--ospf_flood_through_as (lsa->area, inbr, lsa)
|--ospf_flood_through_interface
|--ospf_ls_upd_send_lsa (oi->nbr_self, lsa, OSPF_SEND_PACKET_INDIRECT)
case 2.12
(send router)
(receive |
router) | DR BDR DR Other
------------------------------------------------------------
DR | - delay ack to flood
| allspfrouter implied ack
BDR |delay ack to - no action
|allspfrouter
DR Other |delay ack to delay ack to -
|alldrrouter alldrrouter
[note]
BDR maybe receive new lsa from DR in the following conditions:
1.the new lsa is originated by DR
2.the new lsa is originated by DR Other and flooded by DR
ospf_ls_upd
|--ospf_flood
|--ospf_flood_through
|--ospf_flood_through_area (lsa->area, inbr, lsa)
|--ospf_flood_through_interface
lsa_ack_flag will be true in the following conditions:
1. inbr is DR or BDR
2. the router is BDR.(but in ospf_flood_delayed_lsa_ack() only lsa from DR is acked.)
|--ospf_ls_upd_send_lsa (oi->nbr_self, lsa, OSPF_SEND_PACKET_INDIRECT)
|--ospf_ls_upd_send
|--if (oi->state == ISM_DR || oi->state == ISM_Backup)
|--p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS)
|--p.prefix.s_addr = htonl (OSPF_ALLDROUTERS)
ospf_flood
|--ospf_flood_delayed_lsa_ack (nbr, new)
implied ack is in
ospf_ls_upd
|--ospf_lsa_more_recent() == 0
Part C (BDR will flood it?)
nsm_timer_set
|--OSPF_NSM_TIMER_ON (ospf_ls_upd_timer)
ospf_flood_through_interface
|--ospf_ls_retransmit_add
case 2.13
ospf_router_lsa_refresh
|--ospf_flood_through_area
|--ospf_flood_through_interface (lsa->area, inbr, lsa) (inbr is NULL)
|--ospf_ls_retransmit_add
if RUT and the nbr router are both DR Other, they won't form adjacency and the nbr state is NSM_TwoWay, which is less than NSM_Exchange.
so the new router lsa is not added into ls retransmit list
case 2.14
ospf_ls_upd
|--ospf_flood
|--ospf_flood_through
|--ospf_flood_through_area (lsa->area, inbr, lsa) (inbr is not NULL)
|--ospf_flood_through_interface
|--ospf_ls_retransmit_add
case 2.15
ospf_ls_upd_send_lsa
case 2.16
see case 2.13 and 2.14
ospf_db_desc
|--ospf_db_desc_proc
|--ospf_ls_request_add
|--OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_ExchangeDone)(NSM_Exchange-->NSM_Loading)
|--nsm_exchange_done
|--ospf_ls_req_send
ospf_ls_upd
|--ospf_flood
|--ospf_flood_through
|--ospf_flood_through_area (lsa->area, inbr, lsa) (inbr is not NULL)
|--ospf_flood_through_interface
|--ospf_ls_request_delete
|--ospf_check_nbr_loading
|--OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_LoadingDone)(NSM_Loading-->NSM_Full)
case 2.17
ospf_ls_req
case 2.18
Part A
ospf_ls_req
Part B
higher sequence number is added to ls req list in dd exchange process.
ospf_db_desc
|--ospf_db_desc_proc
|--ospf_ls_request_add
|--ospf_lsdb_add (new_lsa->lock = 2)
|--ospf_lsa_discard (new_lsa->lock = 1)
so if old lsa is received and in the ls req list, NSM_BadLSReq is triggered.
ospf_ls_upd
|--OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq)
case 2.19
ospf_new
|--ospf_lsa_maxage_walker
|--ospf_lsa_maxage_walker_remover
|--ospf_lsa_maxage
|--OSPF_TIMER_ON (ospf_maxage_lsa_remover)
|--ospf_maxage_lsa_remover
|--ospf_flood_through
case 2.20
ospf_new
|--ospf_lsa_refresh_walker
ospf_lsa_install
|--ospf_router_lsa_install
|--OSPF_AREA_TIMER_ON (ospf_router_lsa_timer)
|--ospf_network_lsa_install
|--OSPF_INTERFACE_TIMER_ON (ospf_network_lsa_refresh_timer)
|--ospf_summary_lsa_install
|--ospf_summary_asbr_lsa_install
|--ospf_external_lsa_install
|--ospf_refresher_register_lsa
case 2.21
ospf_ls_upd
|--ospf_flood
|--ospf_flood_through
|--ospf_flood_through_area
|--ospf_flood_through_interface
|--ospf_ls_retransmit_add
|--ospf_ls_retransmit_delete_nbr_area
case 2.22
ospf_db_desc
ospf_ls_upd
ospf_ls_req