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

📄 ospf_lsa.c

📁 router source code for the ospdf.
💻 C
📖 第 1 页 / 共 5 页
字号:
  if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))    {      zlog_info ("LSA[Type%d:%s]: AS-external-LSA refresh",		 new->data->type, inet_ntoa (new->data->id));      ospf_lsa_header_dump (new->data);    }  return;}/* LSA installation functions. *//* Install router-LSA to an area. */struct ospf_lsa *ospf_router_lsa_install (struct ospf *ospf,			 struct ospf_lsa *new, int rt_recalc){  struct ospf_area *area = new->area;  /* RFC 2328 Section 13.2 Router-LSAs and network-LSAs     The entire routing table must be recalculated, starting with     the shortest path calculations for each area (not just the     area whose link-state database has changed).   */  if (rt_recalc)    ospf_spf_calculate_schedule (ospf);  if (IS_LSA_SELF (new))    {      /* Set router-LSA refresh timer. */      OSPF_TIMER_OFF (area->t_router_lsa_self);      OSPF_AREA_TIMER_ON (area->t_router_lsa_self,			  ospf_router_lsa_timer, OSPF_LS_REFRESH_TIME);            /* Set self-originated router-LSA. */      ospf_lsa_unlock (area->router_lsa_self);      area->router_lsa_self = ospf_lsa_lock (new);      if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))	zlog_info("LSA[Type%d]: ID %s is self-originated",		  new->data->type, inet_ntoa (new->data->id));    }  return new;}#define OSPF_INTERFACE_TIMER_ON(T,F,V) \	if (!(T)) \	  (T) = thread_add_timer (master, (F), oi, (V))/* Install network-LSA to an area. */struct ospf_lsa *ospf_network_lsa_install (struct ospf *ospf,			  struct ospf_interface *oi, 			  struct ospf_lsa *new,			  int rt_recalc){  /* RFC 2328 Section 13.2 Router-LSAs and network-LSAs     The entire routing table must be recalculated, starting with     the shortest path calculations for each area (not just the     area whose link-state database has changed).   */  if (rt_recalc)    ospf_spf_calculate_schedule (ospf);  /* We supposed that when LSA is originated by us, we pass the int     for which it was originated. If LSA was received by flooding,     the RECEIVED flag is set, so we do not link the LSA to the int. */  if (IS_LSA_SELF (new) && !CHECK_FLAG (new->flags, OSPF_LSA_RECEIVED))    {      /* Set LSRefresh timer. */      OSPF_TIMER_OFF (oi->t_network_lsa_self);      OSPF_INTERFACE_TIMER_ON (oi->t_network_lsa_self,			       ospf_network_lsa_refresh_timer,			       OSPF_LS_REFRESH_TIME);      ospf_lsa_unlock (oi->network_lsa_self);      oi->network_lsa_self = ospf_lsa_lock (new);    }  return new;}/* Install summary-LSA to an area. */struct ospf_lsa *ospf_summary_lsa_install (struct ospf *ospf, struct ospf_lsa *new,			  int rt_recalc){  if (rt_recalc && !IS_LSA_SELF (new))    {      /* RFC 2328 Section 13.2 Summary-LSAs	 The best route to the destination described by the summary-	 LSA must be recalculated (see Section 16.5).  If this	 destination is an AS boundary router, it may also be	 necessary to re-examine all the AS-external-LSAs.      */#if 0      /* This doesn't exist yet... */      ospf_summary_incremental_update(new); */#else /* #if 0 */      ospf_spf_calculate_schedule (ospf);#endif /* #if 0 */       if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))	zlog_info ("ospf_summary_lsa_install(): SPF scheduled");    }  if (IS_LSA_SELF (new))    ospf_refresher_register_lsa (ospf, new);  return new;}/* Install ASBR-summary-LSA to an area. */struct ospf_lsa *ospf_summary_asbr_lsa_install (struct ospf *ospf, struct ospf_lsa *new,			       int rt_recalc){  if (rt_recalc && !IS_LSA_SELF (new))    {      /* RFC 2328 Section 13.2 Summary-LSAs	 The best route to the destination described by the summary-	 LSA must be recalculated (see Section 16.5).  If this	 destination is an AS boundary router, it may also be	 necessary to re-examine all the AS-external-LSAs.      */#if 0      /* These don't exist yet... */      ospf_summary_incremental_update(new);      /* Isn't this done by the above call? 	 - RFC 2328 Section 16.5 implies it should be */      /* ospf_ase_calculate_schedule(); */#else  /* #if 0 */      ospf_spf_calculate_schedule (ospf);#endif /* #if 0 */    }  /* register LSA to refresh-list. */  if (IS_LSA_SELF (new))    ospf_refresher_register_lsa (ospf, new);  return new;}/* Install AS-external-LSA. */struct ospf_lsa *ospf_external_lsa_install (struct ospf *ospf, struct ospf_lsa *new,			   int rt_recalc){  ospf_ase_register_external_lsa (new, ospf);  /* If LSA is not self-originated, calculate an external route. */  if (rt_recalc)    {      /* RFC 2328 Section 13.2 AS-external-LSAs            The best route to the destination described by the AS-            external-LSA must be recalculated (see Section 16.6).      */      if (!IS_LSA_SELF (new))	ospf_ase_incremental_update (ospf, new);    }#ifdef HAVE_NSSA  /* There is no point to register selforiginate Type-7 LSA for   * refreshing. We rely on refreshing Type-5 LSA's */  if (IS_LSA_SELF (new) && (new->data->type == OSPF_AS_NSSA_LSA))    return new;#endif /* HAVE_NSSA */  /* Register self-originated LSA to refresh queue. */  if (IS_LSA_SELF (new))    ospf_refresher_register_lsa (ospf, new);  return new;}voidospf_discard_from_db (struct ospf *ospf,		      struct ospf_lsdb *lsdb, struct ospf_lsa *lsa){  struct ospf_lsa *old;    old = ospf_lsdb_lookup (lsdb, lsa);  if (!old)    return;  if (old->refresh_list >= 0)    ospf_refresher_unregister_lsa (ospf, old);  switch (old->data->type)    {    case OSPF_AS_EXTERNAL_LSA:#ifdef HAVE_OPAQUE_LSA    case OSPF_OPAQUE_AS_LSA:#endif /* HAVE_OPAQUE_LSA */      ospf_ls_retransmit_delete_nbr_as (ospf, old);      ospf_ase_unregister_external_lsa (old, ospf);      break;#ifdef HAVE_NSSA    case OSPF_AS_NSSA_LSA:      ospf_ls_retransmit_delete_nbr_area (old->area, old);      ospf_ase_unregister_external_lsa (old, ospf);    break;#endif /* HAVE_NSSA */    default:      ospf_ls_retransmit_delete_nbr_area (old->area, old);      break;    }  ospf_lsa_maxage_delete (ospf, old);  ospf_lsa_discard (old);}struct ospf_lsa *ospf_lsa_install (struct ospf *ospf, struct ospf_interface *oi,		  struct ospf_lsa *lsa){  struct ospf_lsa *new = NULL;  struct ospf_lsa *old = NULL;  struct ospf_lsdb *lsdb = NULL;  int rt_recalc;  /* Set LSDB. */  switch (lsa->data->type)    {#ifdef HAVE_NSSA      /* kevinm */    case OSPF_AS_NSSA_LSA:      if (lsa->area)	lsdb = lsa->area->lsdb;      else	lsdb = ospf->lsdb;      break;#endif /* HAVE_NSSA */    case OSPF_AS_EXTERNAL_LSA:#ifdef HAVE_OPAQUE_LSA    case OSPF_OPAQUE_AS_LSA:#endif /* HAVE_OPAQUE_LSA */      lsdb = ospf->lsdb;      break;    default:      lsdb = lsa->area->lsdb;      break;    }  assert (lsdb);  /*  RFC 2328 13.2.  Installing LSAs in the database        Installing a new LSA in the database, either as the result of        flooding or a newly self-originated LSA, may cause the OSPF        routing table structure to be recalculated.  The contents of the        new LSA should be compared to the old instance, if present.  If        there is no difference, there is no need to recalculate the        routing table. When comparing an LSA to its previous instance,        the following are all considered to be differences in contents:            o   The LSA's Options field has changed.            o   One of the LSA instances has LS age set to MaxAge, and                the other does not.            o   The length field in the LSA header has changed.            o   The body of the LSA (i.e., anything outside the 20-byte                LSA header) has changed. Note that this excludes changes                in LS Sequence Number and LS Checksum.  */  /* Look up old LSA and determine if any SPF calculation or incremental     update is needed */  old = ospf_lsdb_lookup (lsdb, lsa);  /* Do comparision and record if recalc needed. */  rt_recalc = 0;  if (  old == NULL || ospf_lsa_different(old, lsa))    rt_recalc = 1;  /* discard old LSA from LSDB */  if (old != NULL)    ospf_discard_from_db (ospf, lsdb, lsa);  /* Insert LSA to LSDB. */  ospf_lsdb_add (lsdb, lsa);  lsa->lsdb = lsdb;  /* Calculate Checksum if self-originated?. */  if (IS_LSA_SELF (lsa))    ospf_lsa_checksum (lsa->data);  /* Do LSA specific installation process. */  switch (lsa->data->type)    {    case OSPF_ROUTER_LSA:      new = ospf_router_lsa_install (ospf, lsa, rt_recalc);      break;    case OSPF_NETWORK_LSA:      assert (oi);      new = ospf_network_lsa_install (ospf, oi, lsa, rt_recalc);      break;    case OSPF_SUMMARY_LSA:      new = ospf_summary_lsa_install (ospf, lsa, rt_recalc);      break;    case OSPF_ASBR_SUMMARY_LSA:      new = ospf_summary_asbr_lsa_install (ospf, lsa, rt_recalc);      break;    case OSPF_AS_EXTERNAL_LSA:      new = ospf_external_lsa_install (ospf, lsa, rt_recalc);      break;#ifdef HAVE_OPAQUE_LSA    case OSPF_OPAQUE_LINK_LSA:      if (IS_LSA_SELF (lsa))	lsa->oi = oi; /* Specify outgoing ospf-interface for this LSA. */      else	; /* Incoming "oi" for this LSA has set at LSUpd reception. */      /* Fallthrough */    case OSPF_OPAQUE_AREA_LSA:    case OSPF_OPAQUE_AS_LSA:      new = ospf_opaque_lsa_install (lsa, rt_recalc);      break;#endif /* HAVE_OPAQUE_LSA */    default: /* NSSA, or type-6,8,9....nothing special */#ifdef HAVE_NSSA      new = ospf_external_lsa_install (ospf, lsa, rt_recalc);#endif /* HAVE_NSSA */      break;    }  if (new == NULL)    return new;  /* Installation failed, cannot proceed further -- endo. */  /* Debug logs. */  if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))    {      char area_str[INET_ADDRSTRLEN];      switch (lsa->data->type)        {        case OSPF_AS_EXTERNAL_LSA:#ifdef HAVE_OPAQUE_LSA        case OSPF_OPAQUE_AS_LSA:#endif /* HAVE_OPAQUE_LSA */#ifdef HAVE_NSSA	case OSPF_AS_NSSA_LSA:#endif /* HAVE_NSSA */          zlog_info ("LSA[%s]: Install %s",                 dump_lsa_key (new),                 LOOKUP (ospf_lsa_type_msg, new->data->type));          break;        default:	  strcpy (area_str, inet_ntoa (new->area->area_id));          zlog_info ("LSA[%s]: Install %s to Area %s",                 dump_lsa_key (new),                 LOOKUP (ospf_lsa_type_msg, new->data->type), area_str);          break;        }    }  /* If received LSA' ls_age is MaxAge, set LSA on MaxAge LSA list. */  if (IS_LSA_MAXAGE (new) && !IS_LSA_SELF (new))    {      if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))	zlog_info ("LSA[Type%d:%s]: Install LSA, MaxAge",		   new->data->type, inet_ntoa (new->data->id));      ospf_lsa_maxage (ospf, lsa);    }  return new;}intospf_check_nbr_status (struct ospf *ospf){  listnode node;  for (node = listhead (ospf->oiflist); node; node = nextnode (node))    {      struct ospf_interface *oi = getdata (node);      struct route_node *rn;      struct ospf_neighbor *nbr;      if (ospf_if_is_enable (oi))	for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))          if ((nbr = rn->info) != NULL)	    if (nbr->state == NSM_Exchange || nbr->state == NSM_Loading)	      {		route_unlock_node (rn);		return 0;	      }    }  return 1;}#ifdef ORIGINAL_CODING/* This function flood the maxaged LSA to DR. */voidospf_maxage_flood (struct ospf_lsa *lsa){  switch (lsa->data->type)    {    case OSPF_ROUTER_LSA:    case OSPF_NETWORK_LSA:    case OSPF_SUMMARY_LSA:    case OSPF_ASBR_SUMMARY_LSA:#ifdef HAVE_NSSA    case OSPF_AS_NSSA_LSA:#endif /* HAVE_NSSA */#ifdef HAVE_OPAQUE_LSA    case OSPF_OPAQUE_LINK_LSA:    case OSPF_OPAQUE_AREA_LSA:#endif /* HAVE_OPAQUE_LSA */      ospf_flood_through_area (lsa->area, NULL, lsa);      break;    case OSPF_AS_EXTERNAL_LSA:#ifdef HAVE_OPAQUE_LSA    case OSPF_OPAQUE_AS_LSA:#endif /* HAVE_OPAQUE_LSA */      ospf_flood_through_as (NULL, lsa);      break;    default:      break;    }}#endif /* ORIGINAL_CODING */intospf_maxage_lsa_remover (struct thread *thread){  struct ospf *ospf = THREAD_ARG (thread);  listnode node;  listnode next;  int reschedule = 0;  ospf->t_maxage = NULL;  if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))    zlog_info ("LSA[MaxAge]: remover Start");  reschedule = !ospf_check_nbr_status (ospf);  if (!reschedule)    for (node = listhead (ospf->maxage_lsa); node; node = next)      {        struct ospf_lsa *lsa = getdata (node);        next = node->next;        if (lsa->retransmit_counter > 0)          {            reschedule = 1;            continue;          }        /* Remove LSA from the LSDB */        if (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF))          if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))            zlog_info ("LSA[Type%d:%s]: This LSA is self-originated: ",                       lsa->data->type, inet_ntoa (lsa->data->id));        if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))          zlog_info ("LSA[Type%d:%s]: MaxAge LSA removed from list",                     lsa->data->type, inet_ntoa (lsa->data->id));	/* Flood max age LSA. */#ifdef ORIGINAL_CODING	ospf_maxage_flood (lsa);#else /* ORIGINAL_CODING */        ospf_flood_through (ospf, NULL, lsa);#endif /* ORIGINAL_CODING */	/* Remove from lsdb. */        ospf_discard_from_db (ospf, lsa->lsdb, lsa);        ospf_lsdb_delete (lsa->lsdb, lsa);      }  /*    A MaxAge LSA must be removed immediately from the router's link        state database as soon as both a) it is no longer contained on any        neighbor Link state retransmission lists and b) none of the router's        neighbors are in states Exchange or Loading. */  if (reschedule)    OSPF_TIMER_ON (ospf->t_maxage, ospf_maxage_lsa_remover, 2);  return 0;}intospf_lsa_maxage_exist (struct ospf *ospf, struct ospf_lsa *new){  listnode node;  for (node = listhead (ospf->maxage_lsa); node; nextnode (node))    if (((struct ospf_lsa *) node->data) == new)      return 1;  return 0;}voidospf_lsa_maxage_delete (struct ospf *ospf, struct ospf_lsa *lsa){  listnode n;  if ((n = listnode_lookup (ospf->maxage_lsa, lsa)))    {      list_delete_node (ospf->maxage_lsa, n);      ospf_lsa_unl

⌨️ 快捷键说明

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