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

📄 ospf_opaque.c

📁 router source code for the ospdf.
💻 C
📖 第 1 页 / 共 5 页
字号:
  return &lsa;}static intospf_opaque_type9_lsa_reoriginate_timer (struct thread *t){  struct opaque_info_per_type *oipt;  struct ospf_opaque_functab *functab;  struct ospf *top;  struct ospf_interface *oi;  int rc = -1;  oipt = THREAD_ARG (t);  oipt->t_opaque_lsa_self = NULL;  if ((functab = oipt->functab) == NULL  ||   functab->lsa_originator == NULL)    {      zlog_warn ("ospf_opaque_type9_lsa_reoriginate_timer: No associated function?");      goto out;    }  oi = (struct ospf_interface *) oipt->owner;  if ((top = oi_to_top (oi)) == NULL)    {      zlog_warn ("ospf_opaque_type9_lsa_reoriginate_timer: Something wrong?");      goto out;    }  if (! CHECK_FLAG (top->config, OSPF_OPAQUE_CAPABLE)  ||  ! ospf_if_is_enable (oi)  ||    ospf_nbr_count_opaque_capable (oi) == 0)    {      if (IS_DEBUG_OSPF_EVENT)        zlog_info ("Suspend re-origination of Type-9 Opaque-LSAs (opaque-type=%u) for a while...", oipt->opaque_type);          oipt->status = PROC_SUSPEND;      rc = 0;      goto out;    }  if (IS_DEBUG_OSPF_EVENT)    zlog_info ("Timer[Type9-LSA]: Re-originate Opaque-LSAs (opaque-type=%u) for OI (%s)", oipt->opaque_type, IF_NAME (oi));  rc = (* functab->lsa_originator)(oi);out:  return rc;}static intospf_opaque_type10_lsa_reoriginate_timer (struct thread *t){  struct opaque_info_per_type *oipt;  struct ospf_opaque_functab *functab;  listnode node;  struct ospf *top;  struct ospf_area *area;  struct ospf_interface *oi;  int n, rc = -1;  oipt = THREAD_ARG (t);  oipt->t_opaque_lsa_self = NULL;  if ((functab = oipt->functab) == NULL  ||   functab->lsa_originator == NULL)    {      zlog_warn ("ospf_opaque_type10_lsa_reoriginate_timer: No associated function?");      goto out;    }  area = (struct ospf_area *) oipt->owner;  if (area == NULL || (top = area->ospf) == NULL)    {      zlog_warn ("ospf_opaque_type10_lsa_reoriginate_timer: Something wrong?");      goto out;    }  /* There must be at least one "opaque-capable, full-state" neighbor. */  n = 0;  for (node = listhead (area->oiflist); node; nextnode (node))    {      if ((oi = getdata (node)) == NULL)        continue;      if ((n = ospf_nbr_count_opaque_capable (oi)) > 0)        break;    }  if (n == 0 || ! CHECK_FLAG (top->config, OSPF_OPAQUE_CAPABLE))    {      if (IS_DEBUG_OSPF_EVENT)        zlog_info ("Suspend re-origination of Type-10 Opaque-LSAs (opaque-type=%u) for a while...", oipt->opaque_type);      oipt->status = PROC_SUSPEND;      rc = 0;      goto out;    }  if (IS_DEBUG_OSPF_EVENT)    zlog_info ("Timer[Type10-LSA]: Re-originate Opaque-LSAs (opaque-type=%u) for Area %s", oipt->opaque_type, inet_ntoa (area->area_id));  rc = (* functab->lsa_originator)(area);out:  return rc;}static intospf_opaque_type11_lsa_reoriginate_timer (struct thread *t){  struct opaque_info_per_type *oipt;  struct ospf_opaque_functab *functab;  struct ospf *top;  int rc = -1;  oipt = THREAD_ARG (t);  oipt->t_opaque_lsa_self = NULL;  if ((functab = oipt->functab) == NULL  ||   functab->lsa_originator == NULL)    {      zlog_warn ("ospf_opaque_type11_lsa_reoriginate_timer: No associated function?");      goto out;    }  if ((top = (struct ospf *) oipt->owner) == NULL)    {      zlog_warn ("ospf_opaque_type11_lsa_reoriginate_timer: Something wrong?");      goto out;    }  if (! CHECK_FLAG (top->config, OSPF_OPAQUE_CAPABLE))    {      if (IS_DEBUG_OSPF_EVENT)        zlog_info ("Suspend re-origination of Type-11 Opaque-LSAs (opaque-type=%u) for a while...", oipt->opaque_type);          oipt->status = PROC_SUSPEND;      rc = 0;      goto out;    }  if (IS_DEBUG_OSPF_EVENT)    zlog_info ("Timer[Type11-LSA]: Re-originate Opaque-LSAs (opaque-type=%u).", oipt->opaque_type);  rc = (* functab->lsa_originator)(top);out:  return rc;}extern int ospf_lsa_refresh_delay (struct ospf_lsa *); /* ospf_lsa.c */voidospf_opaque_lsa_refresh_schedule (struct ospf_lsa *lsa0){  struct ospf *ospf = ospf;  struct opaque_info_per_type *oipt;  struct opaque_info_per_id *oipi;  struct ospf_lsa *lsa;  int delay;  ospf = ospf_lookup ();  if ((oipt = lookup_opaque_info_by_type (lsa0)) == NULL  ||  (oipi = lookup_opaque_info_by_id (oipt, lsa0)) == NULL)    {      zlog_warn ("ospf_opaque_lsa_refresh_schedule: Invalid parameter?");      goto out;    }  /* Given "lsa0" and current "oipi->lsa" may different, but harmless. */  if ((lsa = oipi->lsa) == NULL)    {      zlog_warn ("ospf_opaque_lsa_refresh_schedule: Something wrong?");      goto out;    }  if (oipi->t_opaque_lsa_self != NULL)    {      if (IS_DEBUG_OSPF_EVENT)        zlog_info ("Type-%u Opaque-LSA has already scheduled to REFRESH: [opaque-type=%u, opaque-id=%x]", lsa->data->type, GET_OPAQUE_TYPE (ntohl (lsa->data->id.s_addr)), GET_OPAQUE_ID (ntohl (lsa->data->id.s_addr)));      goto out;    }  /* Delete this lsa from neighbor retransmit-list. */  switch (lsa->data->type)    {    case OSPF_OPAQUE_LINK_LSA:    case OSPF_OPAQUE_AREA_LSA:      ospf_ls_retransmit_delete_nbr_area (lsa->area, lsa);      break;    case OSPF_OPAQUE_AS_LSA:      ospf_ls_retransmit_delete_nbr_as (ospf, lsa);      break;    default:      zlog_warn ("ospf_opaque_lsa_refresh_schedule: Unexpected LSA-type(%u)", lsa->data->type);      goto out;    }  delay = ospf_lsa_refresh_delay (lsa);  if (IS_DEBUG_OSPF_EVENT)    zlog_info ("Schedule Type-%u Opaque-LSA to REFRESH in %d sec later: [opaque-type=%u, opaque-id=%x]", lsa->data->type, delay, GET_OPAQUE_TYPE (ntohl (lsa->data->id.s_addr)), GET_OPAQUE_ID (ntohl (lsa->data->id.s_addr)));  OSPF_OPAQUE_TIMER_ON (oipi->t_opaque_lsa_self,                        ospf_opaque_lsa_refresh_timer, oipi, delay);out:  return;}static intospf_opaque_lsa_refresh_timer (struct thread *t){  struct opaque_info_per_id *oipi;  struct ospf_opaque_functab *functab;  struct ospf_lsa *lsa;  if (IS_DEBUG_OSPF_EVENT)    zlog_info ("Timer[Opaque-LSA]: (Opaque-LSA Refresh expire)");  oipi = THREAD_ARG (t);  oipi->t_opaque_lsa_self = NULL;  if ((lsa = oipi->lsa) != NULL)    if ((functab = oipi->opqctl_type->functab) != NULL)      if (functab->lsa_refresher != NULL)        (* functab->lsa_refresher)(lsa);  return 0;}voidospf_opaque_lsa_flush_schedule (struct ospf_lsa *lsa0){  struct ospf *ospf = ospf;  struct opaque_info_per_type *oipt;  struct opaque_info_per_id *oipi;  struct ospf_lsa *lsa;  ospf = ospf_lookup ();  if ((oipt = lookup_opaque_info_by_type (lsa0)) == NULL  ||  (oipi = lookup_opaque_info_by_id (oipt, lsa0)) == NULL)    {      zlog_warn ("ospf_opaque_lsa_flush_schedule: Invalid parameter?");      goto out;    }  /* Given "lsa0" and current "oipi->lsa" may different, but harmless. */  if ((lsa = oipi->lsa) == NULL)    {      zlog_warn ("ospf_opaque_lsa_flush_schedule: Something wrong?");      goto out;    }  /* Delete this lsa from neighbor retransmit-list. */  switch (lsa->data->type)    {    case OSPF_OPAQUE_LINK_LSA:    case OSPF_OPAQUE_AREA_LSA:      ospf_ls_retransmit_delete_nbr_area (lsa->area, lsa);      break;    case OSPF_OPAQUE_AS_LSA:      ospf_ls_retransmit_delete_nbr_as (ospf, lsa);      break;    default:      zlog_warn ("ospf_opaque_lsa_flush_schedule: Unexpected LSA-type(%u)", lsa->data->type);      goto out;    }  /* Dequeue listnode entry from the list. */  listnode_delete (oipt->id_list, oipi);  /* Avoid misjudgement in the next lookup. */  if (listcount (oipt->id_list) == 0)    oipt->id_list->head = oipt->id_list->tail = NULL;  /* Disassociate internal control information with the given lsa. */  oipi->lsa = NULL;  free_opaque_info_per_id ((void *) oipi);  /* Force given lsa's age to MaxAge. */  lsa->data->ls_age = htons (OSPF_LSA_MAXAGE);  if (IS_DEBUG_OSPF_EVENT)    zlog_info ("Schedule Type-%u Opaque-LSA to FLUSH: [opaque-type=%u, opaque-id=%x]", lsa->data->type, GET_OPAQUE_TYPE (ntohl (lsa->data->id.s_addr)), GET_OPAQUE_ID (ntohl (lsa->data->id.s_addr)));  /* This lsa will be flushed and removed eventually. */  ospf_lsa_maxage (ospf, lsa);out:  return;}/*------------------------------------------------------------------------* * Followings are control functions to block origination after restart. *------------------------------------------------------------------------*/static void ospf_opaque_exclude_lsa_from_lsreq (struct route_table *nbrs, struct ospf_neighbor *inbr, struct ospf_lsa *lsa);static void ospf_opaque_type9_lsa_rxmt_nbr_check (struct ospf_interface *oi);static void ospf_opaque_type10_lsa_rxmt_nbr_check (struct ospf_area *area);static void ospf_opaque_type11_lsa_rxmt_nbr_check (struct ospf *top);static unsigned long ospf_opaque_nrxmt_self (struct route_table *nbrs, int lsa_type);voidospf_opaque_adjust_lsreq (struct ospf_neighbor *nbr, list lsas){  struct ospf *top;  struct ospf_area *area;  struct ospf_interface *oi;  listnode node1, node2;  struct ospf_lsa *lsa;  if ((top = oi_to_top (nbr->oi)) == NULL)    goto out;  /*   * If an instance of self-originated Opaque-LSA is found in the given   * LSA list, and it is not installed to LSDB yet, exclude it from the   * list "nbr->ls_req". In this way, it is assured that an LSReq message,   * which might be sent in the process of flooding, will not request for   * the LSA to be flushed immediately; otherwise, depending on timing,   * an LSUpd message will carry instances of target LSAs with MaxAge,   * while other LSUpd message might carry old LSA instances (non-MaxAge).   * Obviously, the latter would trigger miserable situations that repeat   * installation and removal of unwanted LSAs indefinitely.   */  for (node1 = listhead (lsas); node1; nextnode (node1))    {      if ((lsa = getdata (node1)) == NULL)        continue;      /* Filter out unwanted LSAs. */      if (! IS_OPAQUE_LSA (lsa->data->type))        continue;      if (! IPV4_ADDR_SAME (&lsa->data->adv_router, &top->router_id))        continue;      /*       * Don't touch an LSA which has MaxAge; two possible cases.       *       *   1) This LSA has originally flushed by myself (received LSUpd       *      message's router-id is equal to my router-id), and flooded       *      back by an opaque-capable router.       *       *   2) This LSA has expired in an opaque-capable router and thus       *      flushed by the router.       */      if (IS_LSA_MAXAGE (lsa))        continue;      /* If the LSA has installed in the LSDB, nothing to do here. */      if (ospf_lsa_lookup_by_header (nbr->oi->area, lsa->data) != NULL)        continue;      /* Ok, here we go. */      switch (lsa->data->type)        {        case OSPF_OPAQUE_LINK_LSA:          oi = nbr->oi;          ospf_opaque_exclude_lsa_from_lsreq (oi->nbrs, nbr, lsa);          break;        case OSPF_OPAQUE_AREA_LSA:          area = nbr->oi->area;          for (node2 = listhead (area->oiflist); node2; nextnode (node2))            {              if ((oi = getdata (node2)) == NULL)                continue;              ospf_opaque_exclude_lsa_from_lsreq (oi->nbrs, nbr, lsa);            }          break;        case OSPF_OPAQUE_AS_LSA:          for (node2 = listhead (top->oiflist); node2; nextnode (node2))            {              if ((oi = getdata (node2)) == NULL)                continue;              ospf_opaque_exclude_lsa_from_lsreq (oi->nbrs, nbr, lsa);            }          break;        default:          break;        }    }out:  return;}static voidospf_opaque_exclude_lsa_from_lsreq (struct route_table *nbrs,                                    struct ospf_neighbor *inbr,                                    struct ospf_lsa *lsa){  struct route_node *rn;  struct ospf_neighbor *onbr;  struct ospf_lsa *ls_req;  for (rn = route_top (nbrs); rn; rn = route_next (rn))    {      if ((onbr = rn->info) == NULL)        continue;      if (onbr == inbr)        continue;      if ((ls_req = ospf_ls_request_lookup (onbr, lsa)) == NULL)        continue;      if (IS_DEBUG_OSPF_EVENT)        zlog_info ("LSA[%s]: Exclude this entry from LSReq to send.", dump_lsa_key (lsa));      ospf_ls_request_delete (onbr, ls_req);/*    ospf_check_nbr_loading (onbr);*//* XXX */    }  return;}voidospf_opaque_self_originated_lsa_received (struct ospf_neighbor *nbr, list lsas){  struct ospf *top;  listnode node, next;  struct ospf_lsa *lsa;  u_char before;  if ((top = oi_to_top (nbr->oi)) == NULL)    goto out;  before = IS_OPAQUE_LSA_ORIGINATION_BLOCKED (top->opaque);  for (node = listhead (lsas); node; node = next)    {      next = node->next;      if ((lsa = getdata (node)) == NULL)        continue;      listnode_delete (lsas, lsa);      /*       * Since these LSA entries are not yet installed into corresponding       * LSDB, just flush them without calling ospf_ls_maxage() afterward.       */      lsa->data->ls_age = htons (OSPF_LSA_MAXAGE);      switch (lsa->data->type)        {        case OSPF_OPAQUE_LINK_LSA:          SET_FLAG (top->opaque, OPAQUE_BLOCK_TYPE_09_LSA_BIT);          ospf_flood_through_area (nbr->oi->area, NULL/*inbr*/, lsa);          break;        case OSPF_OPAQU

⌨️ 快捷键说明

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