⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ospf_nsm.c

📁 router source code for the ospdf.
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * OSPF version 2  Neighbor State Machine * From RFC2328 [OSPF Version 2] * Copyright (C) 1999, 2000 Toshiaki Takada * * This file is part of GNU Zebra. * * GNU Zebra is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2, or (at your option) any * later version. * * GNU Zebra is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GNU Zebra; see the file COPYING.  If not, write to the Free * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA. */#include <zebra.h>#include "thread.h"#include "memory.h"#include "hash.h"#include "linklist.h"#include "prefix.h"#include "if.h"#include "table.h"#include "stream.h"#include "table.h"#include "log.h"#include "ospfd/ospfd.h"#include "ospfd/ospf_interface.h"#include "ospfd/ospf_ism.h"#include "ospfd/ospf_asbr.h"#include "ospfd/ospf_lsa.h"#include "ospfd/ospf_lsdb.h"#include "ospfd/ospf_neighbor.h"#include "ospfd/ospf_nsm.h"#include "ospfd/ospf_network.h"#include "ospfd/ospf_packet.h"#include "ospfd/ospf_dump.h"#include "ospfd/ospf_flood.h"#include "ospfd/ospf_abr.h"void nsm_reset_nbr (struct ospf_neighbor *);/* OSPF NSM Timer functions. */intospf_inactivity_timer (struct thread *thread){  struct ospf_neighbor *nbr;  nbr = THREAD_ARG (thread);  nbr->t_inactivity = NULL;  if (IS_DEBUG_OSPF (nsm, NSM_TIMERS))    zlog (NULL, LOG_DEBUG, "NSM[%s:%s]: Timer (Inactivity timer expire)",	  IF_NAME (nbr->oi), inet_ntoa (nbr->router_id));  OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_InactivityTimer);  return 0;}intospf_db_desc_timer (struct thread *thread){  struct ospf_interface *oi;  struct ospf_neighbor *nbr;  nbr = THREAD_ARG (thread);  nbr->t_db_desc = NULL;  oi = nbr->oi;  if (IS_DEBUG_OSPF (nsm, NSM_TIMERS))    zlog (NULL, LOG_INFO, "NSM[%s:%s]: Timer (DD Retransmit timer expire)",	  IF_NAME (nbr->oi), inet_ntoa (nbr->src));  /* resent last send DD packet. */  assert (nbr->last_send);  ospf_db_desc_resend (nbr);  /* DD Retransmit timer set. */  OSPF_NSM_TIMER_ON (nbr->t_db_desc, ospf_db_desc_timer, nbr->v_db_desc);  return 0;}/* Hook function called after ospf NSM event is occured. */voidnsm_timer_set (struct ospf_neighbor *nbr){  switch (nbr->state)    {    case NSM_Down:      OSPF_NSM_TIMER_OFF (nbr->t_db_desc);      OSPF_NSM_TIMER_OFF (nbr->t_ls_upd);      break;    case NSM_Attempt:      OSPF_NSM_TIMER_OFF (nbr->t_db_desc);      OSPF_NSM_TIMER_OFF (nbr->t_ls_upd);      break;    case NSM_Init:      OSPF_NSM_TIMER_OFF (nbr->t_db_desc);      OSPF_NSM_TIMER_OFF (nbr->t_ls_upd);      break;    case NSM_TwoWay:      OSPF_NSM_TIMER_OFF (nbr->t_db_desc);      OSPF_NSM_TIMER_OFF (nbr->t_ls_upd);      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);      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:      OSPF_NSM_TIMER_OFF (nbr->t_db_desc);      break;    case NSM_Full:      OSPF_NSM_TIMER_OFF (nbr->t_db_desc);      break;    default:      OSPF_NSM_TIMER_OFF (nbr->t_db_desc);      break;    }}/* OSPF NSM functions. */intnsm_ignore (struct ospf_neighbor *nbr){  if (IS_DEBUG_OSPF (nsm, NSM_EVENTS))    zlog (NULL, LOG_INFO, "NSM[%s:%s]: nsm_ignore called",	  IF_NAME (nbr->oi), inet_ntoa (nbr->router_id));  return 0;}intnsm_hello_received (struct ospf_neighbor *nbr){  /* Start or Restart Inactivity Timer. */  OSPF_NSM_TIMER_OFF (nbr->t_inactivity);    OSPF_NSM_TIMER_ON (nbr->t_inactivity, ospf_inactivity_timer,		     nbr->v_inactivity);  if (nbr->oi->type == OSPF_IFTYPE_NBMA && nbr->nbr_nbma)    OSPF_POLL_TIMER_OFF (nbr->nbr_nbma->t_poll);  return 0;}intnsm_start (struct ospf_neighbor *nbr){  nsm_reset_nbr (nbr);  if (nbr->nbr_nbma)      OSPF_POLL_TIMER_OFF (nbr->nbr_nbma->t_poll);  OSPF_NSM_TIMER_OFF (nbr->t_inactivity);    OSPF_NSM_TIMER_ON (nbr->t_inactivity, ospf_inactivity_timer,                     nbr->v_inactivity);  return 0;}intnsm_twoway_received (struct ospf_neighbor *nbr){  struct ospf_interface *oi;  int next_state = NSM_TwoWay;  oi = nbr->oi;  /* These netowork types must be adjacency. */  if (oi->type == OSPF_IFTYPE_POINTOPOINT ||      oi->type == OSPF_IFTYPE_POINTOMULTIPOINT ||      oi->type == OSPF_IFTYPE_VIRTUALLINK)    next_state = NSM_ExStart;  /* Router itself is the DRouter or the BDRouter. */  if (IPV4_ADDR_SAME (&oi->address->u.prefix4, &DR (oi)) ||      IPV4_ADDR_SAME (&oi->address->u.prefix4, &BDR (oi)))    next_state = NSM_ExStart;  /* Neighboring Router is the DRouter or the BDRouter. */  if (IPV4_ADDR_SAME (&nbr->address.u.prefix4, &nbr->d_router) ||      IPV4_ADDR_SAME (&nbr->address.u.prefix4, &nbr->bd_router))    next_state = NSM_ExStart;  return next_state;}intospf_db_summary_count (struct ospf_neighbor *nbr){  return ospf_lsdb_count_all (&nbr->db_sum);}intospf_db_summary_isempty (struct ospf_neighbor *nbr){  return ospf_lsdb_isempty (&nbr->db_sum);}intospf_db_summary_add (struct ospf_neighbor *nbr, struct ospf_lsa *lsa){#ifdef HAVE_OPAQUE_LSA  switch (lsa->data->type)    {    case OSPF_OPAQUE_LINK_LSA:      /* Exclude type-9 LSAs that does not have the same "oi" with "nbr". */      if (lsa->oi != nbr->oi)          return 0;      break;    case OSPF_OPAQUE_AREA_LSA:      /*       * It is assured by the caller function "nsm_negotiation_done()"       * that every given LSA belongs to the same area with "nbr".       */      break;    case OSPF_OPAQUE_AS_LSA:    default:      break;    }#endif /* HAVE_OPAQUE_LSA */#ifdef HAVE_NSSA  /* Stay away from any Local Translated Type-7 LSAs */  if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT))    return 0;#endif /* HAVE_NSSA */  if (IS_LSA_MAXAGE (lsa))    ospf_ls_retransmit_add (nbr, lsa);                        else     ospf_lsdb_add (&nbr->db_sum, lsa);  return 0;}voidospf_db_summary_clear (struct ospf_neighbor *nbr){  struct ospf_lsdb *lsdb;  int i;  lsdb = &nbr->db_sum;  for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)    {      struct route_table *table = lsdb->type[i].db;      struct route_node *rn;      for (rn = route_top (table); rn; rn = route_next (rn))	if (rn->info)	  ospf_lsdb_delete (&nbr->db_sum, rn->info);    }}/* The area link state database consists of the router-LSAs,   network-LSAs and summary-LSAs contained in the area structure,   along with the AS-external-LSAs contained in the global structure.   AS-external-LSAs are omitted from a virtual neighbor's Database   summary list.  AS-external-LSAs are omitted from the Database   summary list if the area has been configured as a stub. */intnsm_negotiation_done (struct ospf_neighbor *nbr){  struct ospf_area *area = nbr->oi->area;  struct ospf_lsa *lsa;  struct route_node *rn;  LSDB_LOOP (ROUTER_LSDB (area), rn, lsa)    ospf_db_summary_add (nbr, lsa);  LSDB_LOOP (NETWORK_LSDB (area), rn, lsa)    ospf_db_summary_add (nbr, lsa);  LSDB_LOOP (SUMMARY_LSDB (area), rn, lsa)    ospf_db_summary_add (nbr, lsa);  LSDB_LOOP (ASBR_SUMMARY_LSDB (area), rn, lsa)    ospf_db_summary_add (nbr, lsa);#ifdef HAVE_OPAQUE_LSA  /* Process only if the neighbor is opaque capable. */  if (CHECK_FLAG (nbr->options, OSPF_OPTION_O))    {      LSDB_LOOP (OPAQUE_LINK_LSDB (area), rn, lsa)	ospf_db_summary_add (nbr, lsa);      LSDB_LOOP (OPAQUE_AREA_LSDB (area), rn, lsa)	ospf_db_summary_add (nbr, lsa);    }#endif /* HAVE_OPAQUE_LSA */  if (nbr->oi->type != OSPF_IFTYPE_VIRTUALLINK      && area->external_routing == OSPF_AREA_DEFAULT)    LSDB_LOOP (EXTERNAL_LSDB (nbr->oi->ospf), rn, lsa)      ospf_db_summary_add (nbr, lsa);#ifdef HAVE_OPAQUE_LSA  if (CHECK_FLAG (nbr->options, OSPF_OPTION_O)      && (nbr->oi->type != OSPF_IFTYPE_VIRTUALLINK	  && area->external_routing == OSPF_AREA_DEFAULT))    LSDB_LOOP (OPAQUE_AS_LSDB (nbr->oi->ospf), rn, lsa)      ospf_db_summary_add (nbr, lsa);#endif /* HAVE_OPAQUE_LSA */  return 0;}intnsm_exchange_done (struct ospf_neighbor *nbr){  if (ospf_ls_request_isempty (nbr))    return NSM_Full;  /* Cancel dd retransmit timer. */  /* OSPF_NSM_TIMER_OFF (nbr->t_db_desc); */  /* Send Link State Request. */  ospf_ls_req_send (nbr);  return NSM_Loading;}intnsm_bad_ls_req (struct ospf_neighbor *nbr){  /* Clear neighbor. */  nsm_reset_nbr (nbr);  return 0;}intnsm_adj_ok (struct ospf_neighbor *nbr){  struct ospf_interface *oi;  int next_state;  int flag = 0;  oi = nbr->oi;  next_state = nbr->state;  /* These netowork types must be adjacency. */  if (oi->type == OSPF_IFTYPE_POINTOPOINT      || oi->type == OSPF_IFTYPE_POINTOMULTIPOINT      || oi->type == OSPF_IFTYPE_VIRTUALLINK)    flag = 1;  /* Router itself is the DRouter or the BDRouter. */  if (IPV4_ADDR_SAME (&oi->address->u.prefix4, &DR (oi))      || IPV4_ADDR_SAME (&oi->address->u.prefix4, &BDR (oi)))    flag = 1;  if (IPV4_ADDR_SAME (&nbr->address.u.prefix4, &DR (oi))      || IPV4_ADDR_SAME (&nbr->address.u.prefix4, &BDR (oi)))    flag = 1;  if (nbr->state == NSM_TwoWay && flag == 1)    next_state = NSM_ExStart;  else if (nbr->state >= NSM_ExStart && flag == 0)    next_state = NSM_TwoWay;  return next_state;}intnsm_seq_number_mismatch (struct ospf_neighbor *nbr){  /* Clear neighbor. */  nsm_reset_nbr (nbr);  return 0;}intnsm_oneway_received (struct ospf_neighbor *nbr){  /* Clear neighbor. */  nsm_reset_nbr (nbr);  return 0;}voidnsm_reset_nbr (struct ospf_neighbor *nbr){  /* Clear Database Summary list. */  if (!ospf_db_summary_isempty (nbr))    ospf_db_summary_clear (nbr);  /* Clear Link State Request list. */  if (!ospf_ls_request_isempty (nbr))    ospf_ls_request_delete_all (nbr);  /* Clear Link State Retransmission list. */  if (!ospf_ls_retransmit_isempty (nbr))    ospf_ls_retransmit_clear (nbr);  /* Cancel thread. */  OSPF_NSM_TIMER_OFF (nbr->t_db_desc);  OSPF_NSM_TIMER_OFF (nbr->t_ls_req);  OSPF_NSM_TIMER_OFF (nbr->t_ls_upd);  OSPF_NSM_TIMER_OFF (nbr->t_hello_reply);#ifdef HAVE_OPAQUE_LSA  if (CHECK_FLAG (nbr->options, OSPF_OPTION_O))    UNSET_FLAG (nbr->options, OSPF_OPTION_O);#endif /* HAVE_OPAQUE_LSA */}intnsm_kill_nbr (struct ospf_neighbor *nbr){  /* call it here because we cannot call it from ospf_nsm_event */  nsm_change_state (nbr, NSM_Down);    /* Reset neighbor. */  nsm_reset_nbr (nbr);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -