📄 ospf_opaque.c
字号:
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 + -