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

📄 ospf_flood.c

📁 router source code for the ospdf.
💻 C
📖 第 1 页 / 共 3 页
字号:
  return 0;}/* OSPF LSA flooding -- RFC2328 Section 13.3. */intospf_flood_through_interface (struct ospf_interface *oi,			      struct ospf_neighbor *inbr,			      struct ospf_lsa *lsa){  struct ospf *ospf = oi->ospf;  struct ospf_neighbor *onbr;  struct route_node *rn;  int retx_flag;  if (IS_DEBUG_OSPF_EVENT)    zlog_info ("ospf_flood_through_interface(): "	       "considering int %s, INBR(%s), LSA[%s]",	       IF_NAME (oi), inbr ? inet_ntoa (inbr->router_id) : "NULL",               dump_lsa_key (lsa));  if (!ospf_if_is_enable (oi))    return 0;  /* Remember if new LSA is aded to a retransmit list. */  retx_flag = 0;  /* Each of the neighbors attached to this interface are examined,     to determine whether they must receive the new LSA.  The following     steps are executed for each neighbor: */  for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))    {      struct ospf_lsa *ls_req;       if (rn->info == NULL)	continue;      onbr = rn->info;      if (IS_DEBUG_OSPF_EVENT)	zlog_info ("ospf_flood_through_interface(): considering nbr %s (%s)",		   inet_ntoa (onbr->router_id),                   LOOKUP (ospf_nsm_state_msg, onbr->state));      /* If the neighbor is in a lesser state than Exchange, it	 does not participate in flooding, and the next neighbor	 should be examined. */      if (onbr->state < NSM_Exchange)	continue;      /* If the adjacency is not yet full (neighbor state is	 Exchange or Loading), examine the Link state request	 list associated with this adjacency.  If there is an	 instance of the new LSA on the list, it indicates that	 the neighboring router has an instance of the LSA	 already.  Compare the new LSA to the neighbor's copy: */      if (onbr->state < NSM_Full)	{	  if (IS_DEBUG_OSPF_EVENT)	    zlog_info ("ospf_flood_through_interface(): nbr adj is not Full");	  ls_req = ospf_ls_request_lookup (onbr, lsa);	  if (ls_req != NULL)	    {	      int ret;	      ret = ospf_lsa_more_recent (ls_req, lsa);	      /* The new LSA is less recent. */	      if (ret > 0)		continue;	      /* The two copies are the same instance, then delete		 the LSA from the Link state request list. */	      else if (ret == 0)		{		  ospf_ls_request_delete (onbr, ls_req);		  ospf_check_nbr_loading (onbr);		  continue;		}	      /* The new LSA is more recent.  Delete the LSA		 from the Link state request list. */	      else		{		  ospf_ls_request_delete (onbr, ls_req);		  ospf_check_nbr_loading (onbr);		}	    }	}#ifdef HAVE_OPAQUE_LSA      if (IS_OPAQUE_LSA (lsa->data->type))        {          if (! CHECK_FLAG (onbr->options, OSPF_OPTION_O))            {              if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))                zlog_info ("Skip this neighbor: Not Opaque-capable.");              continue;            }          if (IS_OPAQUE_LSA_ORIGINATION_BLOCKED (ospf->opaque)          &&  IS_LSA_SELF (lsa)          &&  onbr->state == NSM_Full)            {              /* Small attempt to reduce unnecessary retransmission. */              if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))                zlog_info ("Skip this neighbor: Initial flushing done.");              continue;            }        }#endif /* HAVE_OPAQUE_LSA */      /* If the new LSA was received from this neighbor,	 examine the next neighbor. */#ifdef ORIGINAL_CODING      if (inbr)	if (IPV4_ADDR_SAME (&inbr->router_id, &onbr->router_id))	  continue;#else /* ORIGINAL_CODING */      if (inbr)        {          /*           * Triggered by LSUpd message parser "ospf_ls_upd ()".           * E.g., all LSAs handling here is received via network.           */          if (IPV4_ADDR_SAME (&inbr->router_id, &onbr->router_id))            {              if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))                zlog_info ("Skip this neighbor: inbr == onbr");              continue;            }        }      else        {          /*           * Triggered by MaxAge remover, so far.           * NULL "inbr" means flooding starts from this node.           */          if (IPV4_ADDR_SAME (&lsa->data->adv_router, &onbr->router_id))            {              if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))                zlog_info ("Skip this neighbor: lsah->adv_router == onbr");              continue;            }        }#endif /* ORIGINAL_CODING */      /* Add the new LSA to the Link state retransmission list	 for the adjacency. The LSA will be retransmitted	 at intervals until an acknowledgment is seen from	 the neighbor. */      ospf_ls_retransmit_add (onbr, lsa);      retx_flag = 1;    }  /* If in the previous step, the LSA was NOT added to any of     the Link state retransmission lists, there is no need to     flood the LSA out the interface. */  if (retx_flag == 0)     {      return (inbr && inbr->oi == oi);    }  /* if we've received the lsa on this interface we need to perform     additional checking */  if (inbr && (inbr->oi == oi))    {      /* If the new LSA was received on this interface, and it was	 received from either the Designated Router or the Backup	 Designated Router, chances are that all the neighbors have	 received the LSA already. */      if (NBR_IS_DR (inbr) || NBR_IS_BDR (inbr))	{#ifdef HAVE_NSSA	  if (IS_DEBUG_OSPF_NSSA)	    zlog_info ("ospf_flood_through_interface(): "		       "DR/BDR NOT SEND to int %s", IF_NAME (oi));#endif /* HAVE_NSSA */	  return 1;	}	        /* If the new LSA was received on this interface, and the	 interface state is Backup, examine the next interface.  The	 Designated Router will do the flooding on this interface.	 However, if the Designated Router fails the router will	 end up retransmitting the updates. */      if (oi->state == ISM_Backup)	{#ifdef HAVE_NSSA	  if (IS_DEBUG_OSPF_NSSA)	    zlog_info ("ospf_flood_through_interface(): "		       "ISM_Backup NOT SEND to int %s", IF_NAME (oi));#endif /* HAVE_NSSA */	  return 1;	}    }  /* The LSA must be flooded out the interface. Send a Link State     Update packet (including the new LSA as contents) out the     interface.  The LSA's LS age must be incremented by InfTransDelay     (which	must be	> 0) when it is copied into the outgoing Link     State Update packet (until the LS age field reaches the maximum     value of MaxAge). */#ifdef HAVE_NSSA  if (IS_DEBUG_OSPF_NSSA)    zlog_info ("ospf_flood_through_interface(): "	       "DR/BDR sending upd to int %s", IF_NAME (oi));#else /* ! HAVE_NSSA */  if (IS_DEBUG_OSPF_EVENT)    zlog_info ("ospf_flood_through_interface(): "	       "sending upd to int %s", IF_NAME (oi));#endif /* HAVE_NSSA */  /*  RFC2328  Section 13.3      On non-broadcast networks, separate	Link State Update      packets must be sent, as unicasts, to each adjacent	neighbor      (i.e., those in state Exchange or greater).	 The destination      IP addresses for these packets are the neighbors' IP      addresses.   */  if (oi->type == OSPF_IFTYPE_NBMA)    {      struct route_node *rn;      struct ospf_neighbor *nbr;      for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))        if ((nbr = rn->info) != NULL)	  if (nbr != oi->nbr_self && nbr->state >= NSM_Exchange)	    ospf_ls_upd_send_lsa (nbr, lsa, OSPF_SEND_PACKET_DIRECT);    }  else    ospf_ls_upd_send_lsa (oi->nbr_self, lsa, OSPF_SEND_PACKET_INDIRECT);  return 0;}intospf_flood_through_area (struct ospf_area *area,			 struct ospf_neighbor *inbr, struct ospf_lsa *lsa){  listnode node;  int lsa_ack_flag = 0;  /* All other types are specific to a single area (Area A).  The     eligible interfaces are all those interfaces attaching to the     Area A.  If Area A is the backbone, this includes all the virtual     links.  */  for (node = listhead (area->oiflist); node; nextnode (node))    {      struct ospf_interface *oi = getdata (node);      if (area->area_id.s_addr != OSPF_AREA_BACKBONE &&	  oi->type ==  OSPF_IFTYPE_VIRTUALLINK) 	continue;#ifdef HAVE_OPAQUE_LSA      if ((lsa->data->type == OSPF_OPAQUE_LINK_LSA) && (lsa->oi != oi))        {          /*           * Link local scoped Opaque-LSA should only be flooded           * for the link on which the LSA has received.           */          if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))            zlog_info ("Type-9 Opaque-LSA: lsa->oi(%p) != oi(%p)", lsa->oi, oi);          continue;        }#endif /* HAVE_OPAQUE_LSA */      if (ospf_flood_through_interface (oi, inbr, lsa))	lsa_ack_flag = 1;    }  return (lsa_ack_flag);}intospf_flood_through_as (struct ospf *ospf, struct ospf_neighbor *inbr,		       struct ospf_lsa *lsa){  listnode node;  int lsa_ack_flag;  lsa_ack_flag = 0;  /* The incoming LSA is type 5 or type 7  (AS-EXTERNAL or AS-NSSA )    Divert the Type-5 LSA's to all non-NSSA/STUB areas    Divert the Type-7 LSA's to all NSSA areas     AS-external-LSAs are flooded throughout the entire AS, with the     exception of stub areas (see Section 3.6).  The eligible     interfaces are all the router's interfaces, excluding virtual     links and those interfaces attaching to stub areas.  */#ifdef HAVE_NSSA  if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT)) /* Translated from 7  */    if (IS_DEBUG_OSPF_NSSA)      zlog_info ("Flood/AS: NSSA TRANSLATED LSA");#endif /* HAVE_NSSA */  for (node = listhead (ospf->areas); node; nextnode (node))    {      int continue_flag = 0;      struct ospf_area *area = getdata (node);      listnode if_node;      switch (area->external_routing)	{	  /* Don't send AS externals into stub areas.  Various types             of support for partial stub areas can be implemented             here.  NSSA's will receive Type-7's that have areas             matching the originl LSA. */	case OSPF_AREA_NSSA:	/* Sending Type 5 or 7 into NSSA area */#ifdef HAVE_NSSA	  /* Type-7, flood NSSA area */          if (lsa->data->type == OSPF_AS_NSSA_LSA	      && area == lsa->area)	    continue_flag = 0;          else	    continue_flag = 1;  /* Skip this NSSA area for Type-5's et al */          break;#endif /* HAVE_NSSA */	case OSPF_AREA_TYPE_MAX:	case OSPF_AREA_STUB:	  continue_flag = 1;	/* Skip this area. */	  break;	case OSPF_AREA_DEFAULT:	default:#ifdef HAVE_NSSA	  /* No Type-7 into normal area */          if (lsa->data->type == OSPF_AS_NSSA_LSA) 	    continue_flag = 1; /* skip Type-7 */          else#endif /* HAVE_NSSA */	    continue_flag = 0;	/* Do this area. */	  break;	}            /* Do continue for above switch.  Saves a big if then mess */

⌨️ 快捷键说明

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