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

📄 ospf_opaque.c

📁 router source code for the ospdf.
💻 C
📖 第 1 页 / 共 5 页
字号:
 * Opaque-LSA control information per opaque-type. * Single Opaque-Type may have multiple instances; each of them will be * identified by their opaque-id. */struct opaque_info_per_type{  u_char lsa_type;  u_char opaque_type;  enum { PROC_NORMAL, PROC_SUSPEND } status;  /*   * Thread for (re-)origination scheduling for this opaque-type.   *   * Initial origination of Opaque-LSAs is controlled by generic   * Opaque-LSA handling module so that same opaque-type entries are   * called all at once when certain conditions are met.   * However, there might be cases that some Opaque-LSA clients need   * to (re-)originate their own Opaque-LSAs out-of-sync with others.   * This thread is prepared for that specific purpose.   */  struct thread *t_opaque_lsa_self;  /*   * Backpointer to an "owner" which is LSA-type dependent.   *   type-9:  struct ospf_interface   *   type-10: struct ospf_area   *   type-11: struct ospf   */  void *owner;  /* Collection of callback functions for this opaque-type. */  struct ospf_opaque_functab *functab;  /* List of Opaque-LSA control informations per opaque-id. */  list id_list;};/* Opaque-LSA control information per opaque-id. */struct opaque_info_per_id{  u_int32_t opaque_id;  /* Thread for refresh/flush scheduling for this opaque-type/id. */  struct thread *t_opaque_lsa_self;  /* Backpointer to Opaque-LSA control information per opaque-type. */  struct opaque_info_per_type *opqctl_type;  /* Here comes an actual Opaque-LSA entry for this opaque-type/id. */  struct ospf_lsa *lsa;};static struct opaque_info_per_type *register_opaque_info_per_type (struct ospf_opaque_functab *functab, struct ospf_lsa *new);static struct opaque_info_per_type *lookup_opaque_info_by_type (struct ospf_lsa *lsa);static struct opaque_info_per_id *register_opaque_info_per_id (struct opaque_info_per_type *oipt, struct ospf_lsa *new);static struct opaque_info_per_id *lookup_opaque_info_by_id (struct opaque_info_per_type *oipt, struct ospf_lsa *lsa);static struct opaque_info_per_id *register_opaque_lsa (struct ospf_lsa *new);static struct opaque_info_per_type *register_opaque_info_per_type (struct ospf_opaque_functab *functab,                               struct ospf_lsa *new){  struct ospf *top;  struct opaque_info_per_type *oipt;  if ((oipt = XCALLOC (MTYPE_OPAQUE_INFO_PER_TYPE,		       sizeof (struct opaque_info_per_type))) == NULL)    {      zlog_warn ("register_opaque_info_per_type: XMALLOC: %s", strerror (errno));      goto out;    }  switch (new->data->type)    {    case OSPF_OPAQUE_LINK_LSA:      oipt->owner = new->oi;      listnode_add (new->oi->opaque_lsa_self, oipt);      break;    case OSPF_OPAQUE_AREA_LSA:      oipt->owner = new->area;      listnode_add (new->area->opaque_lsa_self, oipt);      break;    case OSPF_OPAQUE_AS_LSA:      top = ospf_lookup ();      if (new->area != NULL && (top = new->area->ospf) == NULL)        {          free_opaque_info_per_type ((void *) oipt);          oipt = NULL;          goto out; /* This case may not exist. */        }      oipt->owner = top;      listnode_add (top->opaque_lsa_self, oipt);      break;    default:      zlog_warn ("register_opaque_info_per_type: Unexpected LSA-type(%u)", new->data->type);      free_opaque_info_per_type ((void *) oipt);      oipt = NULL;      goto out; /* This case may not exist. */    }  oipt->lsa_type = new->data->type;  oipt->opaque_type = GET_OPAQUE_TYPE (ntohl (new->data->id.s_addr));  oipt->status = PROC_NORMAL;  oipt->t_opaque_lsa_self = NULL;  oipt->functab = functab;  functab->oipt = oipt;  oipt->id_list = list_new ();  oipt->id_list->del = free_opaque_info_per_id;out:  return oipt;}static voidfree_opaque_info_per_type (void *val){  struct opaque_info_per_type *oipt = (struct opaque_info_per_type *) val;  struct opaque_info_per_id *oipi;  struct ospf_lsa *lsa;  listnode node;  /* Control information per opaque-id may still exist. */  for (node = listhead (oipt->id_list); node; nextnode (node))    {      if ((oipi = getdata (node)) == NULL)        continue;      if ((lsa = oipi->lsa) == NULL)        continue;      if (IS_LSA_MAXAGE (lsa))        continue;      ospf_opaque_lsa_flush_schedule (lsa);    }  /* Remove "oipt" from its owner's self-originated LSA list. */  switch (oipt->lsa_type)    {    case OSPF_OPAQUE_LINK_LSA:      {        struct ospf_interface *oi = (struct ospf_interface *)(oipt->owner);        listnode_delete (oi->opaque_lsa_self, oipt);        break;      }    case OSPF_OPAQUE_AREA_LSA:      {        struct ospf_area *area = (struct ospf_area *)(oipt->owner);        listnode_delete (area->opaque_lsa_self, oipt);        break;      }    case OSPF_OPAQUE_AS_LSA:      {        struct ospf *top = (struct ospf *)(oipt->owner);        listnode_delete (top->opaque_lsa_self, oipt);        break;      }    default:      zlog_warn ("free_opaque_info_per_type: Unexpected LSA-type(%u)", oipt->lsa_type);      break; /* This case may not exist. */    }  OSPF_TIMER_OFF (oipt->t_opaque_lsa_self);  list_delete (oipt->id_list);  XFREE (MTYPE_OPAQUE_INFO_PER_TYPE, oipt);  return;}static struct opaque_info_per_type *lookup_opaque_info_by_type (struct ospf_lsa *lsa){  struct ospf *top;  struct ospf_area *area;  struct ospf_interface *oi;  list listtop = NULL;  listnode node;  struct opaque_info_per_type *oipt = NULL;  u_char key = GET_OPAQUE_TYPE (ntohl (lsa->data->id.s_addr));  switch (lsa->data->type)    {    case OSPF_OPAQUE_LINK_LSA:      if ((oi = lsa->oi) != NULL)        listtop = oi->opaque_lsa_self;      else        zlog_warn ("Type-9 Opaque-LSA: Reference to OI is missing?");      break;    case OSPF_OPAQUE_AREA_LSA:      if ((area = lsa->area) != NULL)        listtop = area->opaque_lsa_self;      else        zlog_warn ("Type-10 Opaque-LSA: Reference to AREA is missing?");      break;    case OSPF_OPAQUE_AS_LSA:      top = ospf_lookup ();      if ((area = lsa->area) != NULL && (top = area->ospf) == NULL)        {          zlog_warn ("Type-11 Opaque-LSA: Reference to OSPF is missing?");          break; /* Unlikely to happen. */        }      listtop = top->opaque_lsa_self;      break;    default:      zlog_warn ("lookup_opaque_info_by_type: Unexpected LSA-type(%u)", lsa->data->type);      break;    }  if (listtop != NULL)    for (node = listhead (listtop); node; nextnode (node))      if ((oipt = getdata (node)) != NULL)        if (oipt->opaque_type == key)          return oipt;  return NULL;}static struct opaque_info_per_id *register_opaque_info_per_id (struct opaque_info_per_type *oipt,                             struct ospf_lsa *new){  struct opaque_info_per_id *oipi;  if ((oipi = XCALLOC (MTYPE_OPAQUE_INFO_PER_ID,		       sizeof (struct opaque_info_per_id))) == NULL)    {      zlog_warn ("register_opaque_info_per_id: XMALLOC: %s", strerror (errno));      goto out;    }  oipi->opaque_id = GET_OPAQUE_ID (ntohl (new->data->id.s_addr));  oipi->t_opaque_lsa_self = NULL;  oipi->opqctl_type = oipt;  oipi->lsa = ospf_lsa_lock (new);  listnode_add (oipt->id_list, oipi);out:  return oipi;}static voidfree_opaque_info_per_id (void *val){  struct opaque_info_per_id *oipi = (struct opaque_info_per_id *) val;  OSPF_TIMER_OFF (oipi->t_opaque_lsa_self);  if (oipi->lsa != NULL)    ospf_lsa_unlock (oipi->lsa);  XFREE (MTYPE_OPAQUE_INFO_PER_ID, oipi);  return;}static struct opaque_info_per_id *lookup_opaque_info_by_id (struct opaque_info_per_type *oipt,                          struct ospf_lsa *lsa){  listnode node;  struct opaque_info_per_id   *oipi;  u_int32_t key = GET_OPAQUE_ID (ntohl (lsa->data->id.s_addr));  for (node = listhead (oipt->id_list); node; nextnode (node))    if ((oipi = getdata (node)) != NULL)      if (oipi->opaque_id == key)        return oipi;  return NULL;}static struct opaque_info_per_id *register_opaque_lsa (struct ospf_lsa *new){  struct ospf_opaque_functab *functab;  struct opaque_info_per_type *oipt;  struct opaque_info_per_id *oipi = NULL;  if ((functab = ospf_opaque_functab_lookup (new)) == NULL)    goto out;  if ((oipt = lookup_opaque_info_by_type (new)) == NULL  &&  (oipt = register_opaque_info_per_type (functab, new)) == NULL)    goto out;  if ((oipi = register_opaque_info_per_id (oipt, new)) == NULL)    goto out;out:  return oipi;}/*------------------------------------------------------------------------* * Followings are (vty) configuration functions for Opaque-LSAs handling. *------------------------------------------------------------------------*/DEFUN (capability_opaque,       capability_opaque_cmd,       "capability opaque",       "Enable specific OSPF feature\n"       "Opaque LSA\n"){  struct ospf *ospf = (struct ospf *) vty->index;  /* Turn on the "master switch" of opaque-lsa capability. */  if (!CHECK_FLAG (ospf->config, OSPF_OPAQUE_CAPABLE))    {      if (IS_DEBUG_OSPF_EVENT)        zlog_info ("Opaque capability: OFF -> ON");      SET_FLAG (ospf->config, OSPF_OPAQUE_CAPABLE);      ospf_renegotiate_optional_capabilities (ospf);    }  return CMD_SUCCESS;}ALIAS (capability_opaque,       ospf_opaque_capable_cmd,       "ospf opaque-lsa",       "OSPF specific commands\n"       "Enable the Opaque-LSA capability (rfc2370)\n");DEFUN (no_capability_opaque,       no_capability_opaque_cmd,       "no capability opaque",       NO_STR       "Enable specific OSPF feature\n"       "Opaque LSA\n"){  struct ospf *ospf = (struct ospf *) vty->index;  /* Turn off the "master switch" of opaque-lsa capability. */  if (CHECK_FLAG (ospf->config, OSPF_OPAQUE_CAPABLE))    {      if (IS_DEBUG_OSPF_EVENT)        zlog_info ("Opaque capability: ON -> OFF");      UNSET_FLAG (ospf->config, OSPF_OPAQUE_CAPABLE);      ospf_renegotiate_optional_capabilities (ospf);    }  return CMD_SUCCESS;}ALIAS (no_capability_opaque,       no_ospf_opaque_capable_cmd,       "no ospf opaque-lsa",       NO_STR       "OSPF specific commands\n"       "Disable the Opaque-LSA capability (rfc2370)\n");static voidospf_opaque_register_vty (void){  install_element (OSPF_NODE, &capability_opaque_cmd);  install_element (OSPF_NODE, &no_capability_opaque_cmd);  install_element (OSPF_NODE, &ospf_opaque_capable_cmd);  install_element (OSPF_NODE, &no_ospf_opaque_capable_cmd);  return;}/*------------------------------------------------------------------------* * Followings are collection of user-registered function callers. *------------------------------------------------------------------------*/static intopaque_lsa_new_if_callback (list funclist, struct interface *ifp){  listnode node;  struct ospf_opaque_functab *functab;  int rc = -1;  for (node = listhead (funclist); node; nextnode (node))    if ((functab = getdata (node)) != NULL)      if (functab->new_if_hook != NULL)        if ((* functab->new_if_hook)(ifp) != 0)          goto out;  rc = 0;out:  return rc;}static intopaque_lsa_del_if_callback (list funclist, struct interface *ifp){  listnode node;  struct ospf_opaque_functab *functab;  int rc = -1;  for (node = listhead (funclist); node; nextnode (node))    if ((functab = getdata (node)) != NULL)      if (functab->del_if_hook != NULL)        if ((* functab->del_if_hook)(ifp) != 0)          goto out;  rc = 0;out:  return rc;}static voidopaque_lsa_ism_change_callback (list funclist,                                struct ospf_interface *oi, int old_status){  listnode node;  struct ospf_opaque_functab *functab;  for (node = listhead (funclist); node; nextnode (node))    if ((functab = getdata (node)) != NULL)      if (functab->ism_change_hook != NULL)        (* functab->ism_change_hook)(oi, old_status);  return;}static voidopaque_lsa_nsm_change_callback (list funclist,                                struct ospf_neighbor *nbr, int old_status){  listnode node;  struct ospf_opaque_functab *functab;  for (node = listhead (funclist); node; nextnode (node))    if ((functab = getdata (node)) != NULL)      if (functab->nsm_change_hook != NULL)        (* functab->nsm_change_hook)(nbr, old_status);  return;}static voidopaque_lsa_config_write_router_callback (list funclist, struct vty *vty){  listnode node;  struct ospf_opaque_functab *functab;  for (node = listhead (funclist); node; nextnode (node))    if ((functab = getdata (node)) != NULL)      if (functab->config_write_router != NULL)        (* functab->config_write_router)(vty);  return;}static voidopaque_lsa_config_write_if_callback (list funclist,                                     struct vty *vty, struct interface *ifp){  listnode node;  struct ospf_opaque_functab *functab;  for (node = listhead (funclist); node; nextnode (node))    if ((functab = getdata (node)) != NULL)      if (functab->config_write_if != NULL)        (* functab->config_write_if)(vty, ifp);  return;}

⌨️ 快捷键说明

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