void ospf_if_stream_unset (struct ospf_interface *oi) { struct ospf *ospf = oi->ospf; if (oi->obuf) { ospf_fifo_free (oi->obuf); oi->obuf = NULL; if (oi->on_write_q) { listnode_delete (ospf->oi_write_q, oi); if (list_isempty(ospf->oi_write_q)) OSPF_TIMER_OFF (ospf->t_write); oi->on_write_q = 0; } } if (oi->obuf_hello) { ospf_fifo_free (oi->obuf_hello); oi->obuf_hello = NULL; if (oi->on_write_q_hello) { listnode_delete (ospf->oi_write_q_hello, oi); if (list_isempty(ospf->oi_write_q_hello)) OSPF_TIMER_OFF (ospf->t_write_hello); oi->on_write_q_hello = 0; } } }
int ospf_if_down (struct ospf_interface *oi) { if (oi == NULL) return 0; OSPF_ISM_EVENT_EXECUTE (oi, ISM_InterfaceDown); /* Shutdown packet reception and sending */ ospf_if_stream_unset (oi); OSPF_TIMER_OFF(oi->t_packet_read); OSPF_TIMER_OFF(oi->t_packet_write); return 1; }
void ism_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_DEBUG, "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); }
void ism_change_status (struct ospf_interface *oi, int status) { int old_status; struct ospf_lsa *lsa; /* Logging change of status. */ if (IS_DEBUG_OSPF (ism, ISM_STATUS)) zlog (NULL, LOG_INFO, "ISM[%s]: Status change %s -> %s", IF_NAME (oi), LOOKUP (ospf_ism_status_msg, oi->status), LOOKUP (ospf_ism_status_msg, status)); old_status = oi->status; oi->status = status; oi->status_change++; if (old_status == ISM_Down || status == NSM_Down) ospf_check_abr_status(); /* Originate router-LSA. */ if (oi->area) { if (status == ISM_Down) { if (oi->area->act_ints > 0) oi->area->act_ints--; } else if (old_status == ISM_Down) oi->area->act_ints++; /* schedule router-LSA originate. */ ospf_router_lsa_timer_add (oi->area); } /* Originate network-LSA. */ if (old_status != ISM_DR && status == ISM_DR) ospf_network_lsa_timer_add (oi); else if (old_status == ISM_DR && status != 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; } /* Preserve old status? */ /* Check area border status. */ ospf_check_abr_status (); }
/* Restore an interface to its pre UP state Used from ism_interface_down only */ void ospf_if_cleanup (struct ospf_interface *oi) { struct route_node *rn; struct listnode *node, *nnode; struct ospf_neighbor *nbr; struct ospf_nbr_nbma *nbr_nbma; struct ospf_lsa *lsa; /* oi->nbrs and oi->nbr_nbma should be deleted on InterfaceDown event */ /* delete all static neighbors attached to this interface */ for (ALL_LIST_ELEMENTS (oi->nbr_nbma, node, nnode, nbr_nbma)) { OSPF_POLL_TIMER_OFF (nbr_nbma->t_poll); if (nbr_nbma->nbr) { nbr_nbma->nbr->nbr_nbma = NULL; nbr_nbma->nbr = NULL; } nbr_nbma->oi = NULL; listnode_delete (oi->nbr_nbma, nbr_nbma); } /* send Neighbor event KillNbr to all associated neighbors. */ for (rn = route_top (oi->nbrs); rn; rn = route_next (rn)) if ((nbr = rn->info) != NULL) if (nbr != oi->nbr_self) OSPF_NSM_EVENT_EXECUTE (nbr, NSM_KillNbr); /* Cleanup Link State Acknowlegdment list. */ for (ALL_LIST_ELEMENTS (oi->ls_ack, node, nnode, lsa)) ospf_lsa_unlock (&lsa); /* oi->ls_ack */ list_delete_all_node (oi->ls_ack); oi->crypt_seqnum = 0; /* Empty link state update queue */ ospf_ls_upd_queue_empty (oi); /* Reset pseudo neighbor. */ ospf_nbr_delete (oi->nbr_self); oi->nbr_self = ospf_nbr_new (oi); ospf_nbr_add_self (oi); ospf_lsa_unlock (&oi->network_lsa_self); oi->network_lsa_self = NULL; OSPF_TIMER_OFF (oi->t_network_lsa_self); #ifdef HAVE_GRACEFUL_RESTART THREAD_TIMER_OFF(oi->t_opaque_lsa_refresh); oi->v_opaque_lsa_count = 0 ; #endif }
void nsm_change_state (struct ospf_neighbor *nbr, int state) { struct ospf_interface *oi = nbr->oi; struct ospf_area *vl_area = NULL; u_char old_state; int x; int force = 1; /* Logging change of status. */ if (IS_DEBUG_OSPF (nsm, NSM_STATUS)) zlog_debug ("NSM[%s:%s]: State change %s -> %s", IF_NAME (nbr->oi), inet_ntoa (nbr->router_id), LOOKUP (ospf_nsm_state_msg, nbr->state), LOOKUP (ospf_nsm_state_msg, state)); /* Preserve old status. */ old_state = nbr->state; /* Change to new status. */ nbr->state = state; /* Statistics. */ nbr->state_change++; if (oi->type == OSPF_IFTYPE_VIRTUALLINK) vl_area = ospf_area_lookup_by_area_id (oi->ospf, oi->vl_data->vl_area_id); /* One of the neighboring routers changes to/from the FULL state. */ if ((old_state != NSM_Full && state == NSM_Full) || (old_state == NSM_Full && state != NSM_Full)) { if (state == NSM_Full) { oi->full_nbrs++; oi->area->full_nbrs++; ospf_check_abr_status (oi->ospf); if (oi->type == OSPF_IFTYPE_VIRTUALLINK && vl_area) if (++vl_area->full_vls == 1) ospf_schedule_abr_task (oi->ospf); /* kevinm: refresh any redistributions */ for (x = ZEBRA_ROUTE_SYSTEM; x < ZEBRA_ROUTE_MAX; x++) { if (x == ZEBRA_ROUTE_OSPF || x == ZEBRA_ROUTE_OSPF6) continue; ospf_external_lsa_refresh_type (oi->ospf, x, force); } } else { oi->full_nbrs--; oi->area->full_nbrs--; ospf_check_abr_status (oi->ospf); if (oi->type == OSPF_IFTYPE_VIRTUALLINK && vl_area) if (vl_area->full_vls > 0) if (--vl_area->full_vls == 0) ospf_schedule_abr_task (oi->ospf); /* clear neighbor retransmit list */ if (!ospf_ls_retransmit_isempty (nbr)) ospf_ls_retransmit_clear (nbr); } zlog_info ("nsm_change_state(%s, %s -> %s): " "scheduling new router-LSA origination", inet_ntoa (nbr->router_id), LOOKUP(ospf_nsm_state_msg, old_state), LOOKUP(ospf_nsm_state_msg, state)); ospf_router_lsa_timer_add (oi->area); if (oi->type == OSPF_IFTYPE_VIRTUALLINK) { struct ospf_area *vl_area = ospf_area_lookup_by_area_id (oi->ospf, oi->vl_data->vl_area_id); if (vl_area) ospf_router_lsa_timer_add (vl_area); } /* Originate network-LSA. */ if (oi->state == ISM_DR) { if (oi->network_lsa_self && oi->full_nbrs == 0) { ospf_lsa_flush_area (oi->network_lsa_self, oi->area); ospf_lsa_unlock (oi->network_lsa_self); oi->network_lsa_self = NULL; OSPF_TIMER_OFF (oi->t_network_lsa_self); } else ospf_network_lsa_timer_add (oi); } } #ifdef HAVE_OPAQUE_LSA ospf_opaque_nsm_change (nbr, old_state); #endif /* HAVE_OPAQUE_LSA */ /* Start DD exchange protocol */ if (state == NSM_ExStart) { if (nbr->dd_seqnum == 0) nbr->dd_seqnum = time (NULL); else nbr->dd_seqnum++; nbr->dd_flags = OSPF_DD_FLAG_I|OSPF_DD_FLAG_M|OSPF_DD_FLAG_MS; ospf_db_desc_send (nbr); } /* clear cryptographic sequence number */ if (state == NSM_Down) nbr->crypt_seqnum = 0; /* Generete NeighborChange ISM event. */ #ifdef BUGGY_ISM_TRANSITION if ((old_state < NSM_TwoWay && state >= NSM_TwoWay) || (old_state >= NSM_TwoWay && state < NSM_TwoWay)) OSPF_ISM_EVENT_EXECUTE (oi, ISM_NeighborChange); #else /* BUGGY_ISM_TRANSITION */ switch (oi->state) { case ISM_DROther: case ISM_Backup: case ISM_DR: if ((old_state < NSM_TwoWay && state >= NSM_TwoWay) || (old_state >= NSM_TwoWay && state < NSM_TwoWay)) OSPF_ISM_EVENT_EXECUTE (oi, ISM_NeighborChange); break; default: /* ISM_PointToPoint -> ISM_Down, ISM_Loopback -> ISM_Down, etc. */ break; } #endif /* BUGGY_ISM_TRANSITION */ /* Performance hack. Send hello immideately when some neighbor enter Init state. This whay we decrease neighbor discovery time. Gleb.*/ if (state == NSM_Init) { OSPF_ISM_TIMER_OFF (oi->t_hello); OSPF_ISM_TIMER_ON (oi->t_hello, ospf_hello_timer, 1); } /* Preserve old status? */ }
/* Restore an interface to its pre UP state Used from ism_interface_down only */ void ospf_if_cleanup (struct ospf_interface *oi) { struct route_node *rn; struct listnode *node; struct ospf_neighbor *nbr; /* oi->nbrs and oi->nbr_nbma should be deletete on InterafceDown event */ /* delete all static neighbors attached to this interface */ for (node = listhead (oi->nbr_nbma); node; ) { struct ospf_nbr_nbma *nbr_nbma = getdata (node); nextnode (node); OSPF_POLL_TIMER_OFF (nbr_nbma->t_poll); if (nbr_nbma->nbr) { nbr_nbma->nbr->nbr_nbma = NULL; nbr_nbma->nbr = NULL; } nbr_nbma->oi = NULL; listnode_delete (oi->nbr_nbma, nbr_nbma); } /* send Neighbor event KillNbr to all associated neighbors. */ for (rn = route_top (oi->nbrs); rn; rn = route_next (rn)) if ((nbr = rn->info) != NULL) if (nbr != oi->nbr_self) OSPF_NSM_EVENT_EXECUTE (nbr, NSM_KillNbr); /* Cleanup Link State Acknowlegdment list. */ for (node = listhead (oi->ls_ack); node; nextnode (node)) ospf_lsa_unlock (node->data); list_delete_all_node (oi->ls_ack); oi->crypt_seqnum = 0; /* Empty link state update queue */ ospf_ls_upd_queue_empty (oi); /* Handle pseudo neighbor. */ ospf_nbr_delete (oi->nbr_self); oi->nbr_self = ospf_nbr_new (oi); oi->nbr_self->state = NSM_TwoWay; oi->nbr_self->priority = OSPF_IF_PARAM (oi, priority); switch (oi->area->external_routing) { case OSPF_AREA_DEFAULT: SET_FLAG (oi->nbr_self->options, OSPF_OPTION_E); break; case OSPF_AREA_STUB: UNSET_FLAG (oi->nbr_self->options, OSPF_OPTION_E); break; case OSPF_AREA_NSSA: UNSET_FLAG (oi->nbr_self->options, OSPF_OPTION_E); SET_FLAG (oi->nbr_self->options, OSPF_OPTION_NP); break; } ospf_lsa_unlock (oi->network_lsa_self); oi->network_lsa_self = NULL; OSPF_TIMER_OFF (oi->t_network_lsa_self); }
void nsm_change_status (struct ospf_neighbor *nbr, int status) { int old_status; struct ospf_interface *oi; struct ospf_area *vl_area = NULL; /* Logging change of status. */ if (IS_DEBUG_OSPF (nsm, NSM_STATUS)) zlog_info ("NSM[%s:%s]: Status change %s -> %s", IF_NAME (nbr->oi), inet_ntoa (nbr->router_id), LOOKUP (ospf_nsm_status_msg, nbr->status), LOOKUP (ospf_nsm_status_msg, status)); /* Preserve old status. */ old_status = nbr->status; /* Change to new status. */ nbr->status = status; /* Statistics. */ nbr->state_change++; oi = nbr->oi; if (oi->type == OSPF_IFTYPE_VIRTUALLINK) vl_area = ospf_area_lookup_by_area_id (oi->vl_data->vl_area_id); /* One of the neighboring routers changes to/from the FULL state. */ if ((old_status != NSM_Full && status == NSM_Full) || (old_status == NSM_Full && status != NSM_Full)) { if (status == NSM_Full) { oi->full_nbrs++; oi->area->full_nbrs++; ospf_check_abr_status (); if (oi->type == OSPF_IFTYPE_VIRTUALLINK && vl_area) if (++vl_area->full_vls == 1) ospf_schedule_abr_task (); } else { oi->full_nbrs--; oi->area->full_nbrs--; ospf_check_abr_status (); if (oi->type == OSPF_IFTYPE_VIRTUALLINK && vl_area) if (vl_area->full_vls > 0) if (--vl_area->full_vls == 0) ospf_schedule_abr_task (); /* clear neighbor retransmit list */ if (!ospf_ls_retransmit_isempty (nbr)) ospf_ls_retransmit_clear (nbr); } zlog_info ("nsm_change_status(): " "scheduling new router-LSA origination"); ospf_router_lsa_timer_add (oi->area); if (oi->type == OSPF_IFTYPE_VIRTUALLINK) { struct ospf_area *vl_area = ospf_area_lookup_by_area_id (oi->vl_data->vl_area_id); if (vl_area) ospf_router_lsa_timer_add (vl_area); } /* Originate network-LSA. */ if (oi->status == ISM_DR) { if (oi->network_lsa_self && oi->full_nbrs == 0) { ospf_lsa_flush_area (oi->network_lsa_self, oi->area); ospf_lsa_unlock (oi->network_lsa_self); oi->network_lsa_self = NULL; OSPF_TIMER_OFF (oi->t_network_lsa_self); } else ospf_network_lsa_timer_add (oi); } } /* Start DD exchange protocol */ if (status == NSM_ExStart) { if (nbr->dd_seqnum == 0) nbr->dd_seqnum = time (NULL); else nbr->dd_seqnum++; nbr->dd_flags = OSPF_DD_FLAG_I|OSPF_DD_FLAG_M|OSPF_DD_FLAG_MS; ospf_db_desc_send (nbr); } /* clear cryptographic sequence number */ if (status == NSM_Down) nbr->crypt_seqnum = 0; /* Generete NeighborChange ISM event. */ if ((old_status < NSM_TwoWay && status >= NSM_TwoWay) || (old_status >= NSM_TwoWay && status < NSM_TwoWay)) OSPF_ISM_EVENT_EXECUTE (oi, ISM_NeighborChange); /* Performance hack. Send hello immideately when some neighbor enter Init state. This whay we decrease neighbor discovery time. Gleb.*/ if (status == NSM_Init) { OSPF_ISM_TIMER_OFF (oi->t_hello); OSPF_ISM_TIMER_ON (oi->t_hello, ospf_hello_timer, 1); } /* Preserve old status? */ }
static void ism_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_DEBUG, "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++; #ifdef HAVE_SNMP /* Terminal state or regression */ if ((state == ISM_DR) || (state == ISM_Backup) || (state == ISM_DROther) || (state == ISM_PointToPoint) || (state < old_state)) { /* ospfVirtIfStateChange */ if (oi->type == OSPF_IFTYPE_VIRTUALLINK) ospfTrapVirtIfStateChange (oi); /* ospfIfStateChange */ else ospfTrapIfStateChange (oi); } #endif /* Set multicast memberships appropriately for new state. */ ospf_if_set_multicast(oi); if (old_state == ISM_Down || state == ISM_Down) ospf_check_abr_status (oi->ospf); /* Originate router-LSA. */ 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); }