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

📄 ospf_opaque.c

📁 router source code for the ospdf.
💻 C
📖 第 1 页 / 共 5 页
字号:
      area->t_opaque_lsa_self =        thread_add_timer (master, ospf_opaque_type10_lsa_originate,                          area, delay);      delay += OSPF_MIN_LS_INTERVAL;    }  if (! list_isempty (ospf_opaque_type11_funclist)  &&    list_isempty (top->opaque_lsa_self)  &&    top->t_opaque_lsa_self == NULL)    {      /*       * One OSPF may contain multiple AREAs, but above 2nd and 3rd       * conditions prevent from scheduling the originate function       * again and again.       */      if (IS_DEBUG_OSPF_EVENT)        zlog_info ("Schedule Type-11 Opaque-LSA origination in %d sec later.", delay);      top->t_opaque_lsa_self =        thread_add_timer (master, ospf_opaque_type11_lsa_originate,                          top, delay);      delay += OSPF_MIN_LS_INTERVAL;    }  /*   * Following section treats a special situation that this node's   * opaque capability has changed as "ON -> OFF -> ON".   */  if (! list_isempty (ospf_opaque_type9_funclist)  &&  ! list_isempty (oi->opaque_lsa_self))    {      for (node = listhead (oi->opaque_lsa_self); node; nextnode (node))        {          if ((oipt = getdata (node))  == NULL /* Something wrong? */          ||   oipt->t_opaque_lsa_self != NULL /* Waiting for a thread call. */          ||   oipt->status == PROC_SUSPEND    /* Cannot originate now. */          ||  ! list_isempty (oipt->id_list))  /* Handler is already active. */              continue;          ospf_opaque_lsa_reoriginate_schedule ((void *) oi,            OSPF_OPAQUE_LINK_LSA, oipt->opaque_type);        }    }  if (! list_isempty (ospf_opaque_type10_funclist)  &&  ! list_isempty (area->opaque_lsa_self))    {      for (node = listhead (area->opaque_lsa_self); node; nextnode (node))        {          if ((oipt = getdata (node))  == NULL /* Something wrong? */          ||   oipt->t_opaque_lsa_self != NULL /* Waiting for a thread call. */          ||   oipt->status == PROC_SUSPEND    /* Cannot originate now. */          ||  ! list_isempty (oipt->id_list))  /* Handler is already active. */            continue;          ospf_opaque_lsa_reoriginate_schedule ((void *) area,            OSPF_OPAQUE_AREA_LSA, oipt->opaque_type);        }    }  if (! list_isempty (ospf_opaque_type11_funclist)  &&  ! list_isempty (top->opaque_lsa_self))    {      for (node = listhead (top->opaque_lsa_self); node; nextnode (node))        {          if ((oipt = getdata (node))  == NULL /* Something wrong? */          ||   oipt->t_opaque_lsa_self != NULL /* Waiting for a thread call. */          ||   oipt->status == PROC_SUSPEND    /* Cannot originate now. */          ||  ! list_isempty (oipt->id_list))  /* Handler is already active. */            continue;          ospf_opaque_lsa_reoriginate_schedule ((void *) top,            OSPF_OPAQUE_AS_LSA, oipt->opaque_type);        }    }  if (delay0 != NULL)    *delay0 = delay;out:  return;}static intospf_opaque_type9_lsa_originate (struct thread *t){  struct ospf_interface *oi;  int rc;  oi = THREAD_ARG (t);  oi->t_opaque_lsa_self = NULL;  if (IS_DEBUG_OSPF_EVENT)    zlog_info ("Timer[Type9-LSA]: Originate Opaque-LSAs for OI %s",                IF_NAME (oi));  rc = opaque_lsa_originate_callback (ospf_opaque_type9_funclist, oi);  return rc;}static intospf_opaque_type10_lsa_originate (struct thread *t){  struct ospf_area *area;  int rc;  area = THREAD_ARG (t);  area->t_opaque_lsa_self = NULL;  if (IS_DEBUG_OSPF_EVENT)    zlog_info ("Timer[Type10-LSA]: Originate Opaque-LSAs for Area %s",                inet_ntoa (area->area_id));  rc = opaque_lsa_originate_callback (ospf_opaque_type10_funclist, area);  return rc;}static intospf_opaque_type11_lsa_originate (struct thread *t){  struct ospf *top;  int rc;  top = THREAD_ARG (t);  top->t_opaque_lsa_self = NULL;  if (IS_DEBUG_OSPF_EVENT)    zlog_info ("Timer[Type11-LSA]: Originate AS-External Opaque-LSAs");  rc = opaque_lsa_originate_callback (ospf_opaque_type11_funclist, top);  return rc;}static voidospf_opaque_lsa_reoriginate_resume (list listtop, void *arg){  listnode node;  struct opaque_info_per_type *oipt;  struct ospf_opaque_functab *functab;  if (listtop == NULL)    goto out;  /*   * Pickup oipt entries those which in SUSPEND status, and give   * them a chance to start re-origination now.   */  for (node = listhead (listtop); node; nextnode (node))    {      if ((oipt = getdata (node)) == NULL      ||   oipt->status != PROC_SUSPEND)          continue;      oipt->status = PROC_NORMAL;      if ((functab = oipt->functab) == NULL      ||   functab->lsa_originator  == NULL)        continue;      if ((* functab->lsa_originator)(arg) != 0)        {          zlog_warn ("ospf_opaque_lsa_reoriginate_resume: Failed (opaque-type=%u)", oipt->opaque_type);          continue;        }    }out:  return;}struct ospf_lsa *ospf_opaque_lsa_install (struct ospf_lsa *lsa, int rt_recalc){  struct ospf_lsa *new = NULL;  struct opaque_info_per_type *oipt;  struct opaque_info_per_id *oipi;  struct ospf *top;  /* Don't take "rt_recalc" into consideration for now. *//* XXX */  if (! IS_LSA_SELF (lsa))    {      new = lsa; /* Don't touch this LSA. */      goto out;    }  if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))    zlog_info ("Install Type-%u Opaque-LSA: [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)));  /* Replace the existing lsa with the new one. */  if ((oipt = lookup_opaque_info_by_type (lsa)) != NULL  &&  (oipi = lookup_opaque_info_by_id (oipt, lsa)) != NULL)    {      ospf_lsa_unlock (oipi->lsa);      oipi->lsa = ospf_lsa_lock (lsa);    }  /* Register the new lsa entry and get its control info. */  else  if ((oipi = register_opaque_lsa (lsa)) == NULL)    {      zlog_warn ("ospf_opaque_lsa_install: register_opaque_lsa() ?");      goto out;    }  /*   * Make use of a common mechanism (ospf_lsa_refresh_walker)   * for periodic refresh of self-originated Opaque-LSAs.   */  switch (lsa->data->type)    {    case OSPF_OPAQUE_LINK_LSA:      if ((top = oi_to_top (lsa->oi)) == NULL)        {          /* Above conditions must have passed. */          zlog_warn ("ospf_opaque_lsa_install: Sonmething wrong?");          goto out;        }      break;    case OSPF_OPAQUE_AREA_LSA:      if (lsa->area == NULL || (top = lsa->area->ospf) == NULL)        {          /* Above conditions must have passed. */          zlog_warn ("ospf_opaque_lsa_install: Sonmething wrong?");          goto out;        }      break;    case OSPF_OPAQUE_AS_LSA:      top = ospf_lookup ();      if (lsa->area != NULL && (top = lsa->area->ospf) == NULL)        {          /* Above conditions must have passed. */          zlog_warn ("ospf_opaque_lsa_install: Sonmething wrong?");          goto out;        }      break;    default:      zlog_warn ("ospf_opaque_lsa_install: Unexpected LSA-type(%u)", lsa->data->type);      goto out;    }  ospf_refresher_register_lsa (top, lsa);  new = lsa;out:  return new;}voidospf_opaque_lsa_refresh (struct ospf_lsa *lsa){  struct ospf *ospf;  struct ospf_opaque_functab *functab;  ospf = ospf_lookup ();  if ((functab = ospf_opaque_functab_lookup (lsa)) == NULL  ||   functab->lsa_refresher == NULL)    {      /*       * Though this LSA seems to have originated on this node, the       * handling module for this "lsa-type and opaque-type" was       * already deleted sometime ago.       * Anyway, this node still has a responsibility to flush this       * LSA from the routing domain.       */      if (IS_DEBUG_OSPF_EVENT)        zlog_info ("LSA[Type%d:%s]: Flush stray Opaque-LSA", lsa->data->type, inet_ntoa (lsa->data->id));      lsa->data->ls_age = htons (OSPF_LSA_MAXAGE);      ospf_lsa_maxage (ospf, lsa);    }  else    (* functab->lsa_refresher)(lsa);  return;}/*------------------------------------------------------------------------* * Followings are re-origination/refresh/flush operations of Opaque-LSAs, * triggered by external interventions (vty session, signaling, etc). *------------------------------------------------------------------------*/#define OSPF_OPAQUE_TIMER_ON(T,F,L,V) \      if (!(T)) \        (T) = thread_add_timer (master, (F), (L), (V))static struct ospf_lsa *pseudo_lsa (struct ospf_interface *oi, struct ospf_area *area, u_char lsa_type, u_char opaque_type);static int ospf_opaque_type9_lsa_reoriginate_timer (struct thread *t);static int ospf_opaque_type10_lsa_reoriginate_timer (struct thread *t);static int ospf_opaque_type11_lsa_reoriginate_timer (struct thread *t);static int ospf_opaque_lsa_refresh_timer (struct thread *t);voidospf_opaque_lsa_reoriginate_schedule (void *lsa_type_dependent,                                      u_char lsa_type, u_char opaque_type){  struct ospf *top;  struct ospf_area dummy, *area = NULL;  struct ospf_interface *oi = NULL;  struct ospf_lsa *lsa;  struct opaque_info_per_type *oipt;  int (* func)(struct thread *t) = NULL;  int delay;  switch (lsa_type)    {    case OSPF_OPAQUE_LINK_LSA:      if ((oi = (struct ospf_interface *) lsa_type_dependent) == NULL)        {          zlog_warn ("ospf_opaque_lsa_reoriginate_schedule: Type-9 Opaque-LSA: Invalid parameter?");	  goto out;        }      if ((top = oi_to_top (oi)) == NULL)        {          zlog_warn ("ospf_opaque_lsa_reoriginate_schedule: OI(%s) -> TOP?", IF_NAME (oi));          goto out;        }      if (! list_isempty (ospf_opaque_type9_funclist)      &&    list_isempty (oi->opaque_lsa_self)      &&    oi->t_opaque_lsa_self != NULL)        {          zlog_warn ("Type-9 Opaque-LSA (opaque_type=%u): Common origination for OI(%s) has already started", opaque_type, IF_NAME (oi));          goto out;        }      func = ospf_opaque_type9_lsa_reoriginate_timer;      break;    case OSPF_OPAQUE_AREA_LSA:      if ((area = (struct ospf_area *) lsa_type_dependent) == NULL)        {          zlog_warn ("ospf_opaque_lsa_reoriginate_schedule: Type-10 Opaque-LSA: Invalid parameter?");          goto out;        }      if ((top = area->ospf) == NULL)        {          zlog_warn ("ospf_opaque_lsa_reoriginate_schedule: AREA(%s) -> TOP?", inet_ntoa (area->area_id));          goto out;        }      if (! list_isempty (ospf_opaque_type10_funclist)      &&    list_isempty (area->opaque_lsa_self)      &&    area->t_opaque_lsa_self != NULL)        {          zlog_warn ("Type-10 Opaque-LSA (opaque_type=%u): Common origination for AREA(%s) has already started", opaque_type, inet_ntoa (area->area_id));          goto out;        }      func = ospf_opaque_type10_lsa_reoriginate_timer;      break;    case OSPF_OPAQUE_AS_LSA:      if ((top = (struct ospf *) lsa_type_dependent) == NULL)        {          zlog_warn ("ospf_opaque_lsa_reoriginate_schedule: Type-11 Opaque-LSA: Invalid parameter?");	  goto out;        }      if (! list_isempty (ospf_opaque_type11_funclist)      &&    list_isempty (top->opaque_lsa_self)      &&    top->t_opaque_lsa_self != NULL)        {          zlog_warn ("Type-11 Opaque-LSA (opaque_type=%u): Common origination has already started", opaque_type);          goto out;        }      /* Fake "area" to pass "ospf" to a lookup function later. */      dummy.ospf = top;      area = &dummy;      func = ospf_opaque_type11_lsa_reoriginate_timer;      break;    default:      zlog_warn ("ospf_opaque_lsa_reoriginate_schedule: Unexpected LSA-type(%u)", lsa_type);      goto out;    }  /* It may not a right time to schedule reorigination now. */  if (! CHECK_FLAG (top->opaque, OPAQUE_OPERATION_READY_BIT))    {      if (IS_DEBUG_OSPF_EVENT)        zlog_info ("ospf_opaque_lsa_reoriginate_schedule: Not operational.");      goto out; /* This is not an error. */    }  if (IS_OPAQUE_LSA_ORIGINATION_BLOCKED (top->opaque))    {      if (IS_DEBUG_OSPF_EVENT)        zlog_info ("ospf_opaque_lsa_reoriginate_schedule: Under blockade.");      goto out; /* This is not an error, too. */    }  /* Generate a dummy lsa to be passed for a lookup function. */  lsa = pseudo_lsa (oi, area, lsa_type, opaque_type);  if ((oipt = lookup_opaque_info_by_type (lsa)) == NULL)    {      struct ospf_opaque_functab *functab;      if ((functab = ospf_opaque_functab_lookup (lsa)) == NULL)        {          zlog_warn ("ospf_opaque_lsa_reoriginate_schedule: No associated function?: lsa_type(%u), opaque_type(%u)", lsa_type, opaque_type);          goto out;        }      if ((oipt = register_opaque_info_per_type (functab, lsa)) == NULL)        {          zlog_warn ("ospf_opaque_lsa_reoriginate_schedule: Cannot get a control info?: lsa_type(%u), opaque_type(%u)", lsa_type, opaque_type);          goto out;        }    }  if (oipt->t_opaque_lsa_self != NULL)    {      if (IS_DEBUG_OSPF_EVENT)        zlog_info ("Type-%u Opaque-LSA has already scheduled to RE-ORIGINATE: [opaque-type=%u]", lsa_type, GET_OPAQUE_TYPE (ntohl (lsa->data->id.s_addr)));      goto out;    }  /*   * Different from initial origination time, in which various conditions   * (opaque capability, neighbor status etc) are assured by caller of   * the originating function "ospf_opaque_lsa_originate_schedule ()",   * it is highly possible that these conditions might not be satisfied   * at the time of re-origination function is to be called.   */  delay = OSPF_MIN_LS_INTERVAL; /* XXX */  if (IS_DEBUG_OSPF_EVENT)    zlog_info ("Schedule Type-%u Opaque-LSA to RE-ORIGINATE in %d sec later: [opaque-type=%u]", lsa_type, delay, GET_OPAQUE_TYPE (ntohl (lsa->data->id.s_addr)));  OSPF_OPAQUE_TIMER_ON (oipt->t_opaque_lsa_self, func, oipt, delay);out:  return;}static struct ospf_lsa *pseudo_lsa (struct ospf_interface *oi, struct ospf_area *area,            u_char lsa_type, u_char opaque_type){  static struct ospf_lsa lsa = { 0 };  static struct lsa_header lsah = { 0 };  u_int32_t tmp;  lsa.oi   = oi;  lsa.area = area;  lsa.data = &lsah;  lsah.type = lsa_type;  tmp = SET_OPAQUE_LSID (opaque_type, 0); /* Opaque-ID is unused here. */  lsah.id.s_addr = htonl (tmp);

⌨️ 快捷键说明

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