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

📄 ospf_te.c

📁 router source code for the ospdf.
💻 C
📖 第 1 页 / 共 4 页
字号:
/* * This is an implementation of draft-katz-yeung-ospf-traffic-06.txt * Copyright (C) 2001 KDD R&D Laboratories, Inc. * http://www.kddlabs.co.jp/ * * 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. *//***** MTYPE definition is not reflected to "memory.h" yet. *****/#define MTYPE_OSPF_MPLS_TE_LINKPARAMS	0#include <zebra.h>#ifdef HAVE_OSPF_TE#ifndef HAVE_OPAQUE_LSA#error "Wrong configure option"#endif /* HAVE_OPAQUE_LSA */#include "linklist.h"#include "prefix.h"#include "if.h"#include "table.h"#include "memory.h"#include "command.h"#include "vty.h"#include "stream.h"#include "log.h"#include "thread.h"#include "hash.h"#include "sockunion.h"		/* for inet_aton() */#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_flood.h"#include "ospfd/ospf_packet.h"#include "ospfd/ospf_spf.h"#include "ospfd/ospf_dump.h"#include "ospfd/ospf_route.h"#include "ospfd/ospf_ase.h"#include "ospfd/ospf_zebra.h"#include "ospfd/ospf_te.h"/* Following structure are internal use only. */struct ospf_mpls_te{  enum { disabled, enabled } status;  /* List elements are zebra-interfaces (ifp), not ospf-interfaces (oi). */  list iflist;  /* Store Router-TLV in network byte order. */  struct te_tlv_router_addr router_addr;};struct mpls_te_link{  /*   * According to MPLS-TE (draft) specification, 24-bit Opaque-ID field   * is subdivided into 8-bit "unused" field and 16-bit "instance" field.   * In this implementation, each Link-TLV has its own instance.   */  u_int32_t instance;  /* Reference pointer to a Zebra-interface. */  struct interface *ifp;  /* Area info in which this MPLS-TE link belongs to. */  struct ospf_area *area;  /* Flags to manage this link parameters. */  u_int32_t flags;#define LPFLG_LOOKUP_DONE		0x1#define LPFLG_LSA_ENGAGED		0x2#define LPFLG_LSA_FORCED_REFRESH	0x4  /* Store Link-TLV in network byte order. */  struct te_tlv_link link_header;  struct te_link_subtlv_link_type link_type;  struct te_link_subtlv_link_id link_id;  struct te_link_subtlv_lclif_ipaddr *lclif_ipaddr;  struct te_link_subtlv_rmtif_ipaddr *rmtif_ipaddr;  struct te_link_subtlv_te_metric te_metric;  struct te_link_subtlv_max_bw max_bw;  struct te_link_subtlv_max_rsv_bw max_rsv_bw;  struct te_link_subtlv_unrsv_bw unrsv_bw;  struct te_link_subtlv_rsc_clsclr rsc_clsclr;};/* * Global variable to manage Opaque-LSA/MPLS-TE on this node. * Note that all parameter values are stored in network byte order. */static struct ospf_mpls_te OspfMplsTE;enum oifstate {  OI_ANY, OI_DOWN, OI_UP};enum sched_opcode {  REORIGINATE_PER_AREA, REFRESH_THIS_LSA, FLUSH_THIS_LSA};/*------------------------------------------------------------------------* * Followings are initialize/terminate functions for MPLS-TE handling. *------------------------------------------------------------------------*/static int ospf_mpls_te_new_if (struct interface *ifp);static int ospf_mpls_te_del_if (struct interface *ifp);static void ospf_mpls_te_ism_change (struct ospf_interface *oi, int old_status);static void ospf_mpls_te_nsm_change (struct ospf_neighbor *nbr, int old_status);static void ospf_mpls_te_config_write_router (struct vty *vty);static void ospf_mpls_te_config_write_if (struct vty *vty, struct interface *ifp);static void ospf_mpls_te_show_info (struct vty *vty, struct ospf_lsa *lsa);static int ospf_mpls_te_lsa_originate (void *arg);static void ospf_mpls_te_lsa_refresh (struct ospf_lsa *lsa);static void ospf_mpls_te_lsa_schedule (struct mpls_te_link *lp, enum sched_opcode);static void del_mpls_te_link (void *val);static void ospf_mpls_te_register_vty (void);intospf_mpls_te_init (void){  int rc;  rc = ospf_register_opaque_functab (                OSPF_OPAQUE_AREA_LSA,                OPAQUE_TYPE_TRAFFIC_ENGINEERING_LSA,		ospf_mpls_te_new_if,		ospf_mpls_te_del_if,		ospf_mpls_te_ism_change,		ospf_mpls_te_nsm_change,		ospf_mpls_te_config_write_router,		ospf_mpls_te_config_write_if,		NULL,/* ospf_mpls_te_config_write_debug */                ospf_mpls_te_show_info,                ospf_mpls_te_lsa_originate,                ospf_mpls_te_lsa_refresh,		NULL,/* ospf_mpls_te_new_lsa_hook */		NULL /* ospf_mpls_te_del_lsa_hook */);  if (rc != 0)    {      zlog_warn ("ospf_mpls_te_init: Failed to register functions");      goto out;    }  memset (&OspfMplsTE, 0, sizeof (struct ospf_mpls_te));  OspfMplsTE.status = disabled;  OspfMplsTE.iflist = list_new ();  OspfMplsTE.iflist->del = del_mpls_te_link;  ospf_mpls_te_register_vty ();out:  return rc;}voidospf_mpls_te_term (void){  list_delete (OspfMplsTE.iflist);  OspfMplsTE.iflist = NULL;  OspfMplsTE.status = disabled;  ospf_delete_opaque_functab (OSPF_OPAQUE_AREA_LSA,                              OPAQUE_TYPE_TRAFFIC_ENGINEERING_LSA);  return;}/*------------------------------------------------------------------------* * Followings are control functions for MPLS-TE parameters management. *------------------------------------------------------------------------*/static voiddel_mpls_te_link (void *val){  XFREE (MTYPE_OSPF_MPLS_TE_LINKPARAMS, val);  return;}static u_int32_tget_mpls_te_instance_value (){  static u_int32_t seqno = 0;  if (LEGAL_TE_INSTANCE_RANGE (seqno + 1))    seqno += 1;  else    seqno  = 1; /* Avoid zero. */  return seqno;}static struct ospf_interface *lookup_oi_by_ifp (struct interface *ifp,                  struct ospf_area *area, enum oifstate oifstate){  struct ospf_interface *oi = NULL;  struct route_node *rn;  for (rn = route_top (IF_OIFS (ifp)); rn; rn = route_next (rn))    {      if ((oi = rn->info) == NULL)        continue;      switch (oifstate)        {        case OI_ANY:          break;        case OI_DOWN:          if (ospf_if_is_enable (oi))            continue;          break;        case OI_UP:          if (! ospf_if_is_enable (oi))            continue;          break;        default:          zlog_warn ("lookup_oi_by_ifp: Unknown oifstate: %x", oifstate);          goto out;        }      if (area == NULL || oi->area == area)        return oi;    }out:  return NULL;}static struct mpls_te_link *lookup_linkparams_by_ifp (struct interface *ifp){  listnode node;  struct mpls_te_link *lp;  for (node = listhead (OspfMplsTE.iflist); node; nextnode (node))    if ((lp = getdata (node)) != NULL)      if (lp->ifp == ifp)        return lp;  return NULL;}static struct mpls_te_link *lookup_linkparams_by_instance (struct ospf_lsa *lsa){  listnode node;  struct mpls_te_link *lp;  int key = GET_OPAQUE_ID (ntohl (lsa->data->id.s_addr));  for (node = listhead (OspfMplsTE.iflist); node; nextnode (node))    if ((lp = getdata (node)) != NULL)      if (lp->instance == key)        return lp;  zlog_warn ("lookup_linkparams_by_instance: Entry not found: key(%x)", key);  return NULL;}static voidospf_mpls_te_foreach_area (  void (*func)(struct mpls_te_link *lp, enum sched_opcode),  enum sched_opcode sched_opcode){  listnode node, node2;  struct mpls_te_link *lp;  struct ospf_area *area;  for (node = listhead (OspfMplsTE.iflist); node; nextnode (node))    {      if ((lp = getdata (node)) == NULL)        continue;      if ((area = lp->area) == NULL)        continue;      if (lp->flags & LPFLG_LOOKUP_DONE)        continue;      if (func != NULL)        (* func)(lp, sched_opcode);      for (node2 = nextnode (node); node2; nextnode (node2))        if ((lp = getdata (node2)) != NULL)          if (lp->area != NULL)            if (IPV4_ADDR_SAME (&lp->area->area_id, &area->area_id))              lp->flags |= LPFLG_LOOKUP_DONE;    }  for (node = listhead (OspfMplsTE.iflist); node; nextnode (node))    if ((lp = getdata (node)) != NULL)      if (lp->area != NULL)        lp->flags &= ~LPFLG_LOOKUP_DONE;  return;}static voidset_mpls_te_router_addr (struct in_addr ipv4){  OspfMplsTE.router_addr.header.type   = htons (TE_TLV_ROUTER_ADDR);  OspfMplsTE.router_addr.header.length = htons (sizeof (ipv4));  OspfMplsTE.router_addr.value = ipv4;  return;}static voidset_linkparams_link_header (struct mpls_te_link *lp){  struct te_tlv_header *tlvh;  u_int16_t length = 0;  /* TE_LINK_SUBTLV_LINK_TYPE */  if (ntohs (lp->link_type.header.type) != 0)    length += TLV_SIZE (&lp->link_type.header);  /* TE_LINK_SUBTLV_LINK_ID */  if (ntohs (lp->link_id.header.type) != 0)    length += TLV_SIZE (&lp->link_id.header);  /* TE_LINK_SUBTLV_LCLIF_IPADDR */  if ((tlvh = (struct te_tlv_header *) lp->lclif_ipaddr) != NULL  &&  ntohs (tlvh->type) != 0)    length += TLV_SIZE (tlvh);  /* TE_LINK_SUBTLV_RMTIF_IPADDR */  if ((tlvh = (struct te_tlv_header *) lp->rmtif_ipaddr) != NULL  &&  ntohs (tlvh->type) != 0)    length += TLV_SIZE (tlvh);  /* TE_LINK_SUBTLV_TE_METRIC */  if (ntohs (lp->te_metric.header.type) != 0)    length += TLV_SIZE (&lp->te_metric.header);  /* TE_LINK_SUBTLV_MAX_BW */  if (ntohs (lp->max_bw.header.type) != 0)    length += TLV_SIZE (&lp->max_bw.header);  /* TE_LINK_SUBTLV_MAX_RSV_BW */  if (ntohs (lp->max_rsv_bw.header.type) != 0)    length += TLV_SIZE (&lp->max_rsv_bw.header);  /* TE_LINK_SUBTLV_UNRSV_BW */  if (ntohs (lp->unrsv_bw.header.type) != 0)    length += TLV_SIZE (&lp->unrsv_bw.header);  /* TE_LINK_SUBTLV_RSC_CLSCLR */  if (ntohs (lp->rsc_clsclr.header.type) != 0)    length += TLV_SIZE (&lp->rsc_clsclr.header);  lp->link_header.header.type   = htons (TE_TLV_LINK);  lp->link_header.header.length = htons (length);  return;}static voidset_linkparams_link_type (struct ospf_interface *oi, struct mpls_te_link *lp){  lp->link_type.header.type   = htons (TE_LINK_SUBTLV_LINK_TYPE);  lp->link_type.header.length = htons (sizeof (lp->link_type.link_type.value));  switch (oi->type)    {    case OSPF_IFTYPE_POINTOPOINT:      lp->link_type.link_type.value = LINK_TYPE_SUBTLV_VALUE_PTP;      break;    case OSPF_IFTYPE_BROADCAST:    case OSPF_IFTYPE_NBMA:      lp->link_type.link_type.value = LINK_TYPE_SUBTLV_VALUE_MA;      break;    default:      /* Not supported yet. *//* XXX */      lp->link_type.header.type = htons (0);      break;    }  return;}static voidset_linkparams_link_id (struct ospf_interface *oi, struct mpls_te_link *lp){  struct ospf_neighbor *nbr;  int done = 0;  lp->link_id.header.type   = htons (TE_LINK_SUBTLV_LINK_ID);  lp->link_id.header.length = htons (sizeof (lp->link_id.value));  /*   * The Link ID is identical to the contents of the Link ID field   * in the Router LSA for these link types.   */  switch (oi->type)    {    case OSPF_IFTYPE_POINTOPOINT:      /* Take the router ID of the neighbor. */      if ((nbr = ospf_nbr_lookup_ptop (oi))	  && nbr->state == NSM_Full)        {          lp->link_id.value = nbr->router_id;          done = 1;        }      break;    case OSPF_IFTYPE_BROADCAST:    case OSPF_IFTYPE_NBMA:      /* Take the interface address of the designated router. */      if ((nbr = ospf_nbr_lookup_by_addr (oi->nbrs, &DR (oi))) == NULL)        break;      if (nbr->state == NSM_Full      || (IPV4_ADDR_SAME (&oi->address->u.prefix4, &DR (oi))      &&  ospf_nbr_count (oi, NSM_Full) > 0))        {          lp->link_id.value = DR (oi);          done = 1;        }      break;    default:      /* Not supported yet. *//* XXX */      lp->link_id.header.type = htons (0);      break;    }  if (! done)    {      struct in_addr mask;      masklen2ip (oi->address->prefixlen, &mask);      lp->link_id.value.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr;     }  return;}static voidset_linkparams_te_metric (struct mpls_te_link *lp, u_int32_t te_metric){  lp->te_metric.header.type   = htons (TE_LINK_SUBTLV_TE_METRIC);  lp->te_metric.header.length = htons (sizeof (lp->te_metric.value));  lp->te_metric.value = htonl (te_metric);  return;}static voidset_linkparams_max_bw (struct mpls_te_link *lp, float *fp){  lp->max_bw.header.type   = htons (TE_LINK_SUBTLV_MAX_BW);  lp->max_bw.header.length = htons (sizeof (lp->max_bw.value));  htonf (fp, &lp->max_bw.value);  return;}static voidset_linkparams_max_rsv_bw (struct mpls_te_link *lp, float *fp){  lp->max_rsv_bw.header.type   = htons (TE_LINK_SUBTLV_MAX_RSV_BW);  lp->max_rsv_bw.header.length = htons (sizeof (lp->max_rsv_bw.value));  htonf (fp, &lp->max_rsv_bw.value);  return;}static voidset_linkparams_unrsv_bw (struct mpls_te_link *lp, int priority, float *fp)

⌨️ 快捷键说明

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