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

📄 ospf_lsa.c

📁 router source code for the ospdf.
💻 C
📖 第 1 页 / 共 5 页
字号:
      link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0, oi->output_cost);    }  else    {       /* Option 2:  We need to include link to a stub	 network regardless of the state of the neighbor */      masklen2ip (oi->address->prefixlen, &mask);      id.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr;      link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0, oi->output_cost);    }  links++;  return links;}/* Describe Broadcast Link. */intlsa_link_broadcast_set (struct stream *s, struct ospf_interface *oi){  struct ospf_neighbor *dr;  struct in_addr id, mask;  /* Describe Type 3 Link. */  if (oi->state == ISM_Waiting)    {      masklen2ip (oi->address->prefixlen, &mask);      id.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr;      link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0, oi->output_cost);      return 1;    }  dr = ospf_nbr_lookup_by_addr (oi->nbrs, &DR (oi));  /* Describe Type 2 link. */  if (dr && (dr->state == NSM_Full ||	     IPV4_ADDR_SAME (&oi->address->u.prefix4, &DR (oi))) &&      ospf_nbr_count (oi, NSM_Full) > 0)    {      link_info_set (s, DR (oi), oi->address->u.prefix4,		     LSA_LINK_TYPE_TRANSIT, 0, oi->output_cost);    }  /* Describe type 3 link. */  else    {      masklen2ip (oi->address->prefixlen, &mask);      id.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr;      link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0, oi->output_cost);    }  return 1;}intlsa_link_loopback_set (struct stream *s, struct ospf_interface *oi){  struct in_addr id, mask;  /* Describe Type 3 Link. */  if (oi->state != ISM_Loopback)    return 0;  mask.s_addr = 0xffffffff;  id.s_addr = oi->address->u.prefix4.s_addr;  link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0, oi->output_cost);  return 1;}/* Describe Virtual Link. */intlsa_link_virtuallink_set (struct stream *s, struct ospf_interface *oi){  struct ospf_neighbor *nbr;  if (oi->state == ISM_PointToPoint)    if ((nbr = ospf_nbr_lookup_ptop (oi)))      if (nbr->state == NSM_Full)	{	  link_info_set (s, nbr->router_id, oi->address->u.prefix4,			 LSA_LINK_TYPE_VIRTUALLINK, 0, oi->output_cost);	  return 1;	}  return 0;}#define lsa_link_nbma_set(S,O)  lsa_link_broadcast_set (S, O)/* This function add for support point-to-multipoint ,see RFC2328   12.4.1.4.*/intlsa_link_ptomp_set (struct stream *s, struct ospf_interface *oi){  int links = 0;  struct route_node *rn;  struct ospf_neighbor *nbr = NULL;  struct in_addr id, mask;  mask.s_addr = 0xffffffff;  id.s_addr = oi->address->u.prefix4.s_addr;  link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0, 0);  links++;  zlog_info ("PointToMultipoint: running ptomultip_set");  /* Search neighbor, */  for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))    if ((nbr = rn->info) != NULL)      /* Ignore myself. */      if (!IPV4_ADDR_SAME (&nbr->router_id, &oi->ospf->router_id))	if (nbr->state == NSM_Full)	  {	    link_info_set (s, nbr->router_id, oi->address->u.prefix4,			   LSA_LINK_TYPE_POINTOPOINT, 0, oi->output_cost);	    links++;	    zlog_info ("PointToMultipoint: set link to %s",		       inet_ntoa(oi->address->u.prefix4));	  }    return links;}/* Set router-LSA link information. */introuter_lsa_link_set (struct stream *s, struct ospf_area *area){  listnode node;  int links = 0;  for (node = listhead (area->oiflist); node; node = nextnode (node))    {      struct ospf_interface *oi = node->data;      struct interface *ifp = oi->ifp;      /* Check interface is up, OSPF is enable. */      if (if_is_up (ifp))	{	  if (oi->state != ISM_Down)	    {	      /* Describe each link. */	      switch (oi->type)		{		case OSPF_IFTYPE_POINTOPOINT:		  links += lsa_link_ptop_set (s, oi);		  break;		case OSPF_IFTYPE_BROADCAST:		  links += lsa_link_broadcast_set (s, oi);		  break;		case OSPF_IFTYPE_NBMA:		  links += lsa_link_nbma_set (s, oi);		  break;		case OSPF_IFTYPE_POINTOMULTIPOINT:		  links += lsa_link_ptomp_set (s, oi);		  break;		case OSPF_IFTYPE_VIRTUALLINK:		  links += lsa_link_virtuallink_set (s, oi);		  break;		case OSPF_IFTYPE_LOOPBACK:		  links += lsa_link_loopback_set (s, oi); 		}	    }	}    }  return links;}/* Set router-LSA body. */voidospf_router_lsa_body_set (struct stream *s, struct ospf_area *area){  unsigned long putp;  u_int16_t cnt;  /* Set flags. */  stream_putc (s, router_lsa_flags (area));  /* Set Zero fields. */  stream_putc (s, 0);  /* Keep pointer to # links. */  putp = s->putp;  /* Forward word */  stream_putw(s, 0);  /* Set all link information. */  cnt = router_lsa_link_set (s, area);  /* Set # of links here. */  stream_putw_at (s, putp, cnt);}/* Create new router-LSA. */struct ospf_lsa *ospf_router_lsa_new (struct ospf_area *area){  struct ospf *ospf = area->ospf;  struct stream *s;  struct lsa_header *lsah;  struct ospf_lsa *new;  int length;  if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))    zlog_info ("LSA[Type1]: Create router-LSA instance");  /* Create a stream for LSA. */  s = stream_new (OSPF_MAX_LSA_SIZE);  lsah = (struct lsa_header *) STREAM_DATA (s);#ifdef HAVE_NSSA  /* Set LSA common header fields. */  lsa_header_set (s, LSA_OPTIONS_GET (area) | LSA_NSSA_GET (area),		  OSPF_ROUTER_LSA, ospf->router_id, ospf->router_id);#else /* ! HAVE_NSSA */  /* Set LSA common header fields. */  lsa_header_set (s, LSA_OPTIONS_GET (area),		  OSPF_ROUTER_LSA, ospf->router_id, ospf->router_id);#endif /* HAVE_NSSA */  /* Set router-LSA body fields. */  ospf_router_lsa_body_set (s, area);  /* Set length. */  length = stream_get_endp (s);  lsah->length = htons (length);  /* Now, create OSPF LSA instance. */  new = ospf_lsa_new ();  new->area = area;  SET_FLAG (new->flags, OSPF_LSA_SELF);  /* Copy LSA data to store, discard stream. */  new->data = ospf_lsa_data_new (length);  memcpy (new->data, lsah, length);  stream_free (s);  return new;}/* Originate Router-LSA. */struct ospf_lsa *ospf_router_lsa_originate (struct ospf_area *area){  struct ospf_lsa *new;  /* Create new router-LSA instance. */  new = ospf_router_lsa_new (area);  /* Sanity check. */  if (new->data->adv_router.s_addr == 0)    {      if (IS_DEBUG_OSPF_EVENT)	zlog_info ("LSA[Type1]: AdvRouter is 0, discard");      ospf_lsa_discard (new);      return NULL;    }  /* Install LSA to LSDB. */  new = ospf_lsa_install (area->ospf, NULL, new);  /* Update LSA origination count. */  area->ospf->lsa_originate_count++;  /* Flooding new LSA through area. */  ospf_flood_through_area (area, NULL, new);  if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))    {      zlog_info ("LSA[Type%d:%s]: Originate router-LSA %p",		 new->data->type, inet_ntoa (new->data->id), new);      ospf_lsa_header_dump (new->data);    }  return new;}/* Refresh router-LSA. */struct ospf_lsa *ospf_router_lsa_refresh (struct ospf_lsa *lsa){  struct ospf_area *area = lsa->area;  struct ospf_lsa *new;  /* Sanity check. */  assert (lsa->data);  /* Delete LSA from neighbor retransmit-list. */  ospf_ls_retransmit_delete_nbr_area (area, lsa);  /* Create new router-LSA instance. */  new = ospf_router_lsa_new (area);  new->data->ls_seqnum = lsa_seqnum_increment (lsa);  ospf_lsa_install (area->ospf, NULL, new);  /* Flood LSA through area. */  ospf_flood_through_area (area, NULL, new);  /* Debug logging. */  if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))    {      zlog_info ("LSA[Type%d:%s]: router-LSA refresh",		 new->data->type, inet_ntoa (new->data->id));      ospf_lsa_header_dump (new->data);    }  return NULL;}intospf_router_lsa_timer (struct thread *t){  struct ospf_area *area;  if (IS_DEBUG_OSPF_EVENT)    zlog_info ("Timer[router-LSA]: (router-LSA Refresh expire)");  area = THREAD_ARG (t);  area->t_router_lsa_self = NULL;  /* Now refresh router-LSA. */  if (area->router_lsa_self)    ospf_router_lsa_refresh (area->router_lsa_self);  /* Newly originate router-LSA. */  else    ospf_router_lsa_originate (area);  return 0;}voidospf_router_lsa_timer_add (struct ospf_area *area){  /* Keep area's self-originated router-LSA. */  struct ospf_lsa *lsa = area->router_lsa_self;  /* Cancel previously scheduled router-LSA timer. */  if (area->t_router_lsa_self)    if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))      zlog_info ("LSA[Type1]: Cancel previous router-LSA timer");  OSPF_TIMER_OFF (area->t_router_lsa_self);  /* If router-LSA is originated previously, check the interval time. */  if (lsa)    {      int delay;      if ((delay = ospf_lsa_refresh_delay (lsa)) > 0)        {	  OSPF_AREA_TIMER_ON (area->t_router_lsa_self,			      ospf_router_lsa_timer, delay);	  return;        }    }  if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))    zlog_info ("LSA[Type1]: Scheduling router-LSA origination right away");  /* Immediately refresh router-LSA. */  OSPF_AREA_TIMER_ON (area->t_router_lsa_self, ospf_router_lsa_timer, 0);}intospf_router_lsa_update_timer (struct thread *thread){  struct ospf *ospf = THREAD_ARG (thread);  listnode node;  if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))    zlog_info ("Timer[router-LSA Update]: (timer expire)");  ospf->t_router_lsa_update = NULL;  for (node = listhead (ospf->areas); node; nextnode (node))    {      struct ospf_area *area = getdata (node);      struct ospf_lsa *lsa = area->router_lsa_self;      struct router_lsa *rl;      char *area_str;      /* Keep Area ID string. */      area_str = AREA_NAME (area);      /* If LSA not exist in this Area, originate new. */      if (lsa == NULL)        {	  if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))	    zlog_info("LSA[Type1]: Create router-LSA for Area %s", area_str);	  ospf_router_lsa_originate (area);        }      /* If router-ID is changed, Link ID must change.	 First flush old LSA, then originate new. */      else if (!IPV4_ADDR_SAME (&lsa->data->id, &ospf->router_id))	{	  if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))	    zlog_info("LSA[Type%d:%s]: Refresh router-LSA for Area %s",		      lsa->data->type, inet_ntoa (lsa->data->id), area_str);	  ospf_lsa_flush_area (lsa, area);	  ospf_lsa_unlock (area->router_lsa_self);	  area->router_lsa_self = NULL;	  /* Refresh router-LSA, (not install) and flood through area. */	  ospf_router_lsa_timer_add (area);	}      else	{	  rl = (struct router_lsa *) lsa->data;	  /* Refresh router-LSA, (not install) and flood through area. */	  if (rl->flags != ospf->flags)	    ospf_router_lsa_timer_add (area);	}    }  return 0;}/* network-LSA related functions. *//* Originate Network-LSA. */voidospf_network_lsa_body_set (struct stream *s, struct ospf_interface *oi){  struct in_addr mask;  struct route_node *rn;  struct ospf_neighbor *nbr;  masklen2ip (oi->address->prefixlen, &mask);  stream_put_ipv4 (s, mask.s_addr);  /* The network-LSA lists those routers that are fully adjacent to    the Designated Router; each fully adjacent router is identified by    its OSPF Router ID.  The Designated Router includes itself in this    list. RFC2328, Section 12.4.2 */  for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))    if ((nbr = rn->info) != NULL)      if (nbr->state == NSM_Full || nbr == oi->nbr_self)	stream_put_ipv4 (s, nbr->router_id.s_addr);}struct ospf_lsa *ospf_network_lsa_new (struct ospf_interface *oi){  struct stream *s;  struct ospf_lsa *new;  struct lsa_header *lsah;  int length;  /* If there are no neighbours on this network (the net is stub),     the router does not originate network-LSA (see RFC 12.4.2) */  if (oi->full_nbrs == 0)    return NULL;    if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))    zlog_info ("LSA[Type2]: Create network-LSA instance");  /* Create new stream for LSA. */  s = stream_new (OSPF_MAX_LSA_SIZE);  lsah = (struct lsa_header *) STREAM_DATA (s);  lsa_header_set (s, (OPTIONS (oi) | LSA_OPTIONS_GET (oi->area)),		  OSPF_NETWORK_LSA, DR (oi), oi->ospf->router_id);  /* Set network-LSA body fields. */  ospf_network_lsa_body_set (s, oi);  /* Set length. */  length = stream_get_endp (s);  lsah->length = htons (length);  /* Create OSPF LSA instance. */  new = ospf_lsa_new ();  new->area = oi->area;  SET_FLAG (new->flags, OSPF_LSA_SELF);  /* Copy LSA to store. */  new->data = ospf_lsa_data_new (length);  memcpy (new->data, lsah, length);  stream_free (s);  return new;}/* Originate network-LSA. */struct ospf_lsa *ospf_network_lsa_originate (struct ospf_interface *oi){  struct ospf_lsa *new;  /* Create new network-LSA instance. */  new = ospf_network_lsa_new (oi);  if (new == NULL)    return NULL;  /* Install LSA to LSDB. */  new = ospf_lsa_install (oi->ospf, oi, new);  /* Update LSA origination count. */  oi->ospf->lsa_originate_count++;  /* Flooding new LSA through area. */  ospf_flood_through_area (oi->area, NULL, new);  if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))    {      zlog_info ("LSA[Type%d:%s]: Originate network-LSA %p",		 new->data->type, inet_ntoa (new->data->id), new);      ospf_lsa_header_dump (new->data);    }  return new;}intospf_network_lsa_refresh (struct ospf_lsa *lsa, struct ospf_interface *oi)

⌨️ 快捷键说明

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