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

📄 ospf_te.c

📁 router source code for the ospdf.
💻 C
📖 第 1 页 / 共 4 页
字号:
{  /* Note that TLV-length field is the size of array. */  lp->unrsv_bw.header.type   = htons (TE_LINK_SUBTLV_UNRSV_BW);  lp->unrsv_bw.header.length = htons (sizeof (lp->unrsv_bw.value));  htonf (fp, &lp->unrsv_bw.value [priority]);  return;}static voidset_linkparams_rsc_clsclr (struct mpls_te_link *lp, u_int32_t classcolor){  lp->rsc_clsclr.header.type   = htons (TE_LINK_SUBTLV_RSC_CLSCLR);  lp->rsc_clsclr.header.length = htons (sizeof (lp->rsc_clsclr.value));  lp->rsc_clsclr.value = htonl (classcolor);  return;}static voidinitialize_linkparams (struct mpls_te_link *lp){  struct interface *ifp = lp->ifp;  struct ospf_interface *oi;  float fval;  int i;  if ((oi = lookup_oi_by_ifp (ifp, NULL, OI_ANY)) == NULL)    return;  /*   * Try to set initial values those can be derived from   * zebra-interface information.   */  set_linkparams_link_type (oi, lp);  /*   * Linux and *BSD kernel holds bandwidth parameter as an "int" type.   * We may have to reconsider, if "ifp->bandwidth" type changes to float.   */  fval = (float)((ifp->bandwidth ? ifp->bandwidth                                 : OSPF_DEFAULT_BANDWIDTH) * 1000 / 8);  set_linkparams_max_bw (lp, &fval);  set_linkparams_max_rsv_bw (lp, &fval);  for (i = 0; i < 8; i++)    set_linkparams_unrsv_bw (lp, i, &fval);  return;}static intis_mandated_params_set (struct mpls_te_link *lp){  int rc = 0;  if (ntohs (OspfMplsTE.router_addr.header.type) == 0)    goto out;  if (ntohs (lp->link_type.header.type) == 0)    goto out;  if (ntohs (lp->link_id.header.type) == 0)    goto out;  rc = 1;out:  return rc;}/*------------------------------------------------------------------------* * Followings are callback functions against generic Opaque-LSAs handling. *------------------------------------------------------------------------*/static intospf_mpls_te_new_if (struct interface *ifp){  struct mpls_te_link *new;  int rc = -1;  if (lookup_linkparams_by_ifp (ifp) != NULL)    {      zlog_warn ("ospf_mpls_te_new_if: ifp(%p) already in use?", ifp);      rc = 0; /* Do nothing here. */      goto out;    }  if ((new = XMALLOC (MTYPE_OSPF_MPLS_TE_LINKPARAMS,                  sizeof (struct mpls_te_link))) == NULL)    {      zlog_warn ("ospf_mpls_te_new_if: XMALLOC: %s", strerror (errno));      goto out;    }  memset (new, 0, sizeof (struct mpls_te_link));  new->area = NULL;  new->flags = 0;  new->instance = get_mpls_te_instance_value ();  new->ifp = ifp;  initialize_linkparams (new);  listnode_add (OspfMplsTE.iflist, new);  /* Schedule Opaque-LSA refresh. *//* XXX */  rc = 0;out:  return rc;}static intospf_mpls_te_del_if (struct interface *ifp){  struct mpls_te_link *lp;  int rc = -1;  if ((lp = lookup_linkparams_by_ifp (ifp)) != NULL)    {      list iflist = OspfMplsTE.iflist;      /* Dequeue listnode entry from the list. */      listnode_delete (iflist, lp);      /* Avoid misjudgement in the next lookup. */      if (listcount (iflist) == 0)        iflist->head = iflist->tail = NULL;      XFREE (MTYPE_OSPF_MPLS_TE_LINKPARAMS, lp);    }  /* Schedule Opaque-LSA refresh. *//* XXX */  rc = 0;/*out:*/  return rc;}static voidospf_mpls_te_ism_change (struct ospf_interface *oi, int old_state){  struct te_link_subtlv_link_type old_type;  struct te_link_subtlv_link_id   old_id;  struct mpls_te_link *lp;  if ((lp = lookup_linkparams_by_ifp (oi->ifp)) == NULL)    {      zlog_warn ("ospf_mpls_te_ism_change: Cannot get linkparams from OI(%s)?", IF_NAME (oi));      goto out;    }  if (oi->area == NULL || oi->area->ospf == NULL)    {      zlog_warn ("ospf_mpls_te_ism_change: Cannot refer to OSPF from OI(%s)?",IF_NAME (oi));      goto out;    }#ifdef notyet  if ((lp->area != NULL  &&   ! IPV4_ADDR_SAME (&lp->area->area_id, &oi->area->area_id))  || (lp->area != NULL && oi->area == NULL))    {      /* How should we consider this case? */      zlog_warn ("MPLS-TE: Area for OI(%s) has changed to [%s], flush previous LSAs", IF_NAME (oi), oi->area ? inet_ntoa (oi->area->area_id) : "N/A");      ospf_mpls_te_lsa_schedule (lp, FLUSH_THIS_LSA);    }#endif  /* Keep Area information in conbination with linkparams. */  lp->area = oi->area;  switch (oi->state)    {    case ISM_PointToPoint:    case ISM_DROther:    case ISM_Backup:    case ISM_DR:      old_type = lp->link_type;      old_id   = lp->link_id;      set_linkparams_link_type (oi, lp);      set_linkparams_link_id (oi, lp);      if ((ntohs (old_type.header.type) != ntohs (lp->link_type.header.type)      ||   old_type.link_type.value     != lp->link_type.link_type.value)      ||  (ntohs (old_id.header.type)   != ntohs (lp->link_id.header.type)      ||   ntohl (old_id.value.s_addr)  != ntohl (lp->link_id.value.s_addr)))        {          if (lp->flags & LPFLG_LSA_ENGAGED)            ospf_mpls_te_lsa_schedule (lp, REFRESH_THIS_LSA);          else            ospf_mpls_te_lsa_schedule (lp, REORIGINATE_PER_AREA);        }      break;    default:      lp->link_type.header.type = htons (0);      lp->link_id.header.type   = htons (0);      if (lp->flags & LPFLG_LSA_ENGAGED)        ospf_mpls_te_lsa_schedule (lp, FLUSH_THIS_LSA);      break;    }out:  return;}static voidospf_mpls_te_nsm_change (struct ospf_neighbor *nbr, int old_state){  /* So far, nothing to do here. */  return;}/*------------------------------------------------------------------------* * Followings are OSPF protocol processing functions for MPLS-TE. *------------------------------------------------------------------------*/static voidbuild_tlv_header (struct stream *s, struct te_tlv_header *tlvh){  stream_put (s, tlvh, sizeof (struct te_tlv_header));  return;}static voidbuild_router_tlv (struct stream *s){  struct te_tlv_header *tlvh = &OspfMplsTE.router_addr.header;  if (ntohs (tlvh->type) != 0)    {      build_tlv_header (s, tlvh);      stream_put (s, tlvh+1, TLV_BODY_SIZE (tlvh));    }  return;}static voidbuild_link_subtlv_link_type (struct stream *s, struct mpls_te_link *lp){  struct te_tlv_header *tlvh = &lp->link_type.header;  if (ntohs (tlvh->type) != 0)    {      build_tlv_header (s, tlvh);      stream_put (s, tlvh+1, TLV_BODY_SIZE (tlvh));    }  return;}static voidbuild_link_subtlv_link_id (struct stream *s, struct mpls_te_link *lp){  struct te_tlv_header *tlvh = &lp->link_id.header;  if (ntohs (tlvh->type) != 0)    {      build_tlv_header (s, tlvh);      stream_put (s, tlvh+1, TLV_BODY_SIZE (tlvh));    }  return;}static voidbuild_link_subtlv_lclif_ipaddr (struct stream *s, struct mpls_te_link *lp){  struct te_tlv_header *tlvh = (struct te_tlv_header *) lp->lclif_ipaddr;  if (tlvh != NULL && ntohs (tlvh->type) != 0)    {      build_tlv_header (s, tlvh);      stream_put (s, tlvh+1, TLV_BODY_SIZE (tlvh));    }  return;}static voidbuild_link_subtlv_rmtif_ipaddr (struct stream *s, struct mpls_te_link *lp){  struct te_tlv_header *tlvh = (struct te_tlv_header *) lp->rmtif_ipaddr;  if (tlvh != NULL && ntohs (tlvh->type) != 0)    {      build_tlv_header (s, tlvh);      stream_put (s, tlvh+1, TLV_BODY_SIZE (tlvh));    }  return;}static voidbuild_link_subtlv_te_metric (struct stream *s, struct mpls_te_link *lp){  struct te_tlv_header *tlvh = &lp->te_metric.header;  if (ntohs (tlvh->type) != 0)    {      build_tlv_header (s, tlvh);      stream_put (s, tlvh+1, TLV_BODY_SIZE (tlvh));    }  return;}static voidbuild_link_subtlv_max_bw (struct stream *s, struct mpls_te_link *lp){  struct te_tlv_header *tlvh = &lp->max_bw.header;  if (ntohs (tlvh->type) != 0)    {      build_tlv_header (s, tlvh);      stream_put (s, tlvh+1, TLV_BODY_SIZE (tlvh));    }  return;}static voidbuild_link_subtlv_max_rsv_bw (struct stream *s, struct mpls_te_link *lp){  struct te_tlv_header *tlvh = &lp->max_rsv_bw.header;  if (ntohs (tlvh->type) != 0)    {      build_tlv_header (s, tlvh);      stream_put (s, tlvh+1, TLV_BODY_SIZE (tlvh));    }  return;}static voidbuild_link_subtlv_unrsv_bw (struct stream *s, struct mpls_te_link *lp){  struct te_tlv_header *tlvh = &lp->unrsv_bw.header;  if (ntohs (tlvh->type) != 0)    {      build_tlv_header (s, tlvh);      stream_put (s, tlvh+1, TLV_BODY_SIZE (tlvh));    }  return;}static voidbuild_link_subtlv_rsc_clsclr (struct stream *s, struct mpls_te_link *lp){  struct te_tlv_header *tlvh = &lp->rsc_clsclr.header;  if (ntohs (tlvh->type) != 0)    {      build_tlv_header (s, tlvh);      stream_put (s, tlvh+1, TLV_BODY_SIZE (tlvh));    }  return;}static voidbuild_link_tlv (struct stream *s, struct mpls_te_link *lp){  set_linkparams_link_header (lp);  build_tlv_header (s, &lp->link_header.header);  build_link_subtlv_link_type (s, lp);  build_link_subtlv_link_id (s, lp);  build_link_subtlv_lclif_ipaddr (s, lp);  build_link_subtlv_rmtif_ipaddr (s, lp);  build_link_subtlv_te_metric (s, lp);  build_link_subtlv_max_bw (s, lp);  build_link_subtlv_max_rsv_bw (s, lp);  build_link_subtlv_unrsv_bw (s, lp);  build_link_subtlv_rsc_clsclr (s, lp);  return;}static voidospf_mpls_te_lsa_body_set (struct stream *s, struct mpls_te_link *lp){  /*   * The router address TLV is type 1, and ...   *                                      It must appear in exactly one   * Traffic Engineering LSA originated by a router.   */  build_router_tlv (s);  /*   * Only one Link TLV shall be carried in each LSA, allowing for fine   * granularity changes in topology.   */  build_link_tlv (s, lp);  return;}/* Create new opaque-LSA. */static struct ospf_lsa *ospf_mpls_te_lsa_new (struct ospf_area *area, struct mpls_te_link *lp){  struct stream *s;  struct lsa_header *lsah;  struct ospf_lsa *new = NULL;  u_char options, lsa_type;  struct in_addr lsa_id;  u_int32_t tmp;  u_int16_t length;  /* Create a stream for LSA. */  if ((s = stream_new (OSPF_MAX_LSA_SIZE)) == NULL)    {      zlog_warn ("ospf_mpls_te_lsa_new: stream_new() ?");      goto out;    }  lsah = (struct lsa_header *) STREAM_DATA (s);  options  = LSA_OPTIONS_GET (area);#ifdef HAVE_NSSA  options |= LSA_NSSA_GET (area);#endif /* HAVE_NSSA */  options |= OSPF_OPTION_O; /* Don't forget this :-) */  lsa_type = OSPF_OPAQUE_AREA_LSA;  tmp = SET_OPAQUE_LSID (OPAQUE_TYPE_TRAFFIC_ENGINEERING_LSA, lp->instance);  lsa_id.s_addr = htonl (tmp);  if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))    zlog_info ("LSA[Type%d:%s]: Create an Opaque-LSA/MPLS-TE instance", lsa_type, inet_ntoa (lsa_id));  /* Set opaque-LSA header fields. */  lsa_header_set (s, options, lsa_type, lsa_id, area->ospf->router_id);  /* Set opaque-LSA body fields. */  ospf_mpls_te_lsa_body_set (s, lp);  /* Set length. */  length = stream_get_endp (s);  lsah->length = htons (length);  /* Now, create an OSPF LSA instance. */  if ((new = ospf_lsa_new ()) == NULL)    {      zlog_warn ("ospf_mpls_te_lsa_new: ospf_lsa_new() ?");      stream_free (s);      goto out;    }  if ((new->data = ospf_lsa_data_new (length)) == NULL)    {      zlog_warn ("ospf_mpls_te_lsa_new: ospf_lsa_data_new() ?");      ospf_lsa_free (new);      new = NULL;      stream_free (s);      goto out;    }  new->area = area;  SET_FLAG (new->flags, OSPF_LSA_SELF);  memcpy (new->data, lsah, length);  stream_free (s);out:  return new;}static intospf_mpls_te_lsa_originate1 (struct ospf_area *area, struct mpls_te_link *lp){  struct ospf_lsa *new;  int rc = -1;  /* Create new Opaque-LSA/MPLS-TE instance. */  if ((new = ospf_mpls_te_lsa_new (area, lp)) == NULL)    {      zlog_warn ("ospf_mpls_te_lsa_originate1: ospf_mpls_te_lsa_new() ?");      goto out;    }  /* Install this LSA into LSDB. */  if (ospf_lsa_install (area->ospf, NULL/*oi*/, new) == NULL)    {      zlog_warn ("ospf_mpls_te_lsa_originate1: ospf_lsa_install() ?");      ospf_lsa_free (new);      goto out;    }  /* Now this linkparameter entry has associated LSA. */  lp->flags |= LPFLG_LSA_ENGAGED;  /* Update new LSA origination count. */  area->ospf->lsa_originate_count++;  /* Flood new LSA through area. */  ospf_flood_through_area (area, NULL/*nbr*/, new);  if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))    {      char area_id[INET_ADDRSTRLEN];      strcpy (area_id, inet_ntoa (area->area_id));      zlog_info ("LSA[Type%d:%s]: Originate Opaque-LSA/MPLS-TE: Area(%s), Link(%s)", new->data->type, inet_ntoa (new->data->id), area_id, lp->ifp->name);

⌨️ 快捷键说明

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