--- embedaddon/quagga/ospfd/ospf_opaque.c 2013/07/21 23:54:40 1.1.1.2 +++ embedaddon/quagga/ospfd/ospf_opaque.c 2016/11/02 10:09:12 1.1.1.3 @@ -27,7 +27,6 @@ #define MTYPE_OPAQUE_INFO_PER_ID 0 #include -#ifdef HAVE_OPAQUE_LSA #include "linklist.h" #include "prefix.h" @@ -62,9 +61,7 @@ * Followings are initialize/terminate functions for Opaque-LSAs handling. *------------------------------------------------------------------------*/ -#ifdef HAVE_OSPF_TE #include "ospfd/ospf_te.h" -#endif /* HAVE_OSPF_TE */ #ifdef SUPPORT_OSPF_API int ospf_apiserver_init (void); @@ -87,10 +84,8 @@ ospf_opaque_init (void) ospf_opaque_register_vty (); ospf_opaque_funclist_init (); -#ifdef HAVE_OSPF_TE if (ospf_mpls_te_init () != 0) exit (1); -#endif /* HAVE_OSPF_TE */ #ifdef SUPPORT_OSPF_API if ((ospf_apiserver_enable) && (ospf_apiserver_init () != 0)) @@ -103,9 +98,7 @@ ospf_opaque_init (void) void ospf_opaque_term (void) { -#ifdef HAVE_OSPF_TE ospf_mpls_te_term (); -#endif /* HAVE_OSPF_TE */ #ifdef SUPPORT_OSPF_API ospf_apiserver_term (); @@ -1311,13 +1304,7 @@ ospf_opaque_lsa_originate_schedule (struct ospf_interf zlog_debug ("ospf_opaque_lsa_originate_schedule: Not operational."); goto out; /* This is not an error. */ } - if (IS_OPAQUE_LSA_ORIGINATION_BLOCKED (top->opaque)) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_opaque_lsa_originate_schedule: Under blockade."); - goto out; /* This is not an error, too. */ - } - + if (delay0 != NULL) delay = *delay0; @@ -1337,10 +1324,10 @@ ospf_opaque_lsa_originate_schedule (struct ospf_interf && oi->t_opaque_lsa_self == NULL) { if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("Schedule Type-9 Opaque-LSA origination in %d sec later.", delay); + zlog_debug ("Schedule Type-9 Opaque-LSA origination in %d ms later.", delay); oi->t_opaque_lsa_self = - thread_add_timer (master, ospf_opaque_type9_lsa_originate, oi, delay); - delay += OSPF_MIN_LS_INTERVAL; + thread_add_timer_msec (master, ospf_opaque_type9_lsa_originate, oi, delay); + delay += top->min_ls_interval; } if (! list_isempty (ospf_opaque_type10_funclist) @@ -1353,11 +1340,11 @@ ospf_opaque_lsa_originate_schedule (struct ospf_interf * again and again. */ if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("Schedule Type-10 Opaque-LSA origination in %d sec later.", delay); + zlog_debug ("Schedule Type-10 Opaque-LSA origination in %d ms later.", delay); area->t_opaque_lsa_self = - thread_add_timer (master, ospf_opaque_type10_lsa_originate, + thread_add_timer_msec (master, ospf_opaque_type10_lsa_originate, area, delay); - delay += OSPF_MIN_LS_INTERVAL; + delay += top->min_ls_interval; } if (! list_isempty (ospf_opaque_type11_funclist) @@ -1370,11 +1357,11 @@ ospf_opaque_lsa_originate_schedule (struct ospf_interf * again and again. */ if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("Schedule Type-11 Opaque-LSA origination in %d sec later.", delay); + zlog_debug ("Schedule Type-11 Opaque-LSA origination in %d ms later.", delay); top->t_opaque_lsa_self = - thread_add_timer (master, ospf_opaque_type11_lsa_originate, + thread_add_timer_msec (master, ospf_opaque_type11_lsa_originate, top, delay); - delay += OSPF_MIN_LS_INTERVAL; + delay += top->min_ls_interval; } /* @@ -1652,7 +1639,7 @@ ospf_opaque_lsa_refresh (struct ospf_lsa *lsa) #define OSPF_OPAQUE_TIMER_ON(T,F,L,V) \ if (!(T)) \ - (T) = thread_add_timer (master, (F), (L), (V)) + (T) = thread_add_timer_msec (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); @@ -1759,13 +1746,7 @@ ospf_opaque_lsa_reoriginate_schedule (void *lsa_type_d zlog_debug ("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_debug ("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); @@ -1806,11 +1787,11 @@ ospf_opaque_lsa_reoriginate_schedule (void *lsa_type_d * 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 */ + delay = top->min_ls_interval; /* XXX */ if (IS_DEBUG_OSPF_EVENT) zlog_debug ("Schedule Type-%u Opaque-LSA to RE-ORIGINATE in %d" - " sec later: [opaque-type=%u]", + " ms later: [opaque-type=%u]", lsa_type, delay, GET_OPAQUE_TYPE (ntohl (lsa->data->id.s_addr))); @@ -2036,7 +2017,7 @@ ospf_opaque_lsa_refresh_schedule (struct ospf_lsa *lsa zlog_debug ("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); + ospf_opaque_lsa_refresh_timer, oipi, delay * 1000); out: return; } @@ -2121,130 +2102,15 @@ 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); - void -ospf_opaque_adjust_lsreq (struct ospf_neighbor *nbr, struct list *lsas) -{ - struct ospf *top; - struct ospf_area *area; - struct ospf_interface *oi; - struct listnode *node1, *nnode1; - struct listnode *node2, *nnode2; - 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 (ALL_LIST_ELEMENTS (lsas, node1, nnode1, lsa)) - { - /* 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 (ALL_LIST_ELEMENTS (area->oiflist, node2, nnode2, oi)) - ospf_opaque_exclude_lsa_from_lsreq (oi->nbrs, nbr, lsa); - break; - case OSPF_OPAQUE_AS_LSA: - for (ALL_LIST_ELEMENTS (top->oiflist, node2, nnode2, oi)) - ospf_opaque_exclude_lsa_from_lsreq (oi->nbrs, nbr, lsa); - break; - default: - break; - } - } - -out: - return; -} - -static void -ospf_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_debug ("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; -} - -void ospf_opaque_self_originated_lsa_received (struct ospf_neighbor *nbr, struct ospf_lsa *lsa) { struct ospf *top; - u_char before; - + if ((top = oi_to_top (nbr->oi)) == NULL) return; - before = IS_OPAQUE_LSA_ORIGINATION_BLOCKED (top->opaque); - /* * Since these LSA entries are not yet installed into corresponding * LSDB, just flush them without calling ospf_ls_maxage() afterward. @@ -2253,193 +2119,21 @@ ospf_opaque_self_originated_lsa_received (struct ospf_ 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_OPAQUE_AREA_LSA: - SET_FLAG (top->opaque, OPAQUE_BLOCK_TYPE_10_LSA_BIT); ospf_flood_through_area (nbr->oi->area, NULL/*inbr*/, lsa); break; case OSPF_OPAQUE_AS_LSA: - SET_FLAG (top->opaque, OPAQUE_BLOCK_TYPE_11_LSA_BIT); ospf_flood_through_as (top, NULL/*inbr*/, lsa); break; default: zlog_warn ("ospf_opaque_self_originated_lsa_received: Unexpected LSA-type(%u)", lsa->data->type); return; } - - ospf_lsa_discard (lsa); /* List "lsas" will be deleted by caller. */ - - if (before == 0 && IS_OPAQUE_LSA_ORIGINATION_BLOCKED (top->opaque)) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("Block Opaque-LSA origination: OFF -> ON"); - } + ospf_lsa_discard (lsa); /* List "lsas" will be deleted by caller. */ } -void -ospf_opaque_ls_ack_received (struct ospf_neighbor *nbr, struct ospf_lsa *lsa) -{ - struct ospf *top; - int delay; - struct ospf_interface *oi; - struct listnode *node, *nnode; - - if ((top = oi_to_top (nbr->oi)) == NULL) - return; - - if (!IS_OPAQUE_LSA_ORIGINATION_BLOCKED (top->opaque)) - return; - - switch (lsa->data->type) - { - case OSPF_OPAQUE_LINK_LSA: - if (CHECK_FLAG (top->opaque, OPAQUE_BLOCK_TYPE_09_LSA_BIT)) - ospf_opaque_type9_lsa_rxmt_nbr_check (nbr->oi); - /* Callback function... */ - break; - case OSPF_OPAQUE_AREA_LSA: - if (CHECK_FLAG (top->opaque, OPAQUE_BLOCK_TYPE_10_LSA_BIT)) - ospf_opaque_type10_lsa_rxmt_nbr_check (nbr->oi->area); - /* Callback function... */ - break; - case OSPF_OPAQUE_AS_LSA: - if (CHECK_FLAG (top->opaque, OPAQUE_BLOCK_TYPE_11_LSA_BIT)) - ospf_opaque_type11_lsa_rxmt_nbr_check (top); - /* Callback function... */ - break; - default: - zlog_warn ("ospf_opaque_ls_ack_received: Unexpected LSA-type(%u)", lsa->data->type); - return; - } - - if (IS_OPAQUE_LSA_ORIGINATION_BLOCKED (top->opaque)) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("Block Opaque-LSA origination: ON -> OFF"); - return; /* Blocking still in progress. */ - } - - if (! CHECK_FLAG (top->config, OSPF_OPAQUE_CAPABLE)) - return; /* Opaque capability condition must have changed. */ - - /* Ok, let's start origination of Opaque-LSAs. */ - delay = OSPF_MIN_LS_INTERVAL; - - for (ALL_LIST_ELEMENTS (top->oiflist, node, nnode, oi)) - { - if (! ospf_if_is_enable (oi) - || ospf_nbr_count_opaque_capable (oi) == 0) - continue; - - ospf_opaque_lsa_originate_schedule (oi, &delay); - } - - return; -} - -static void -ospf_opaque_type9_lsa_rxmt_nbr_check (struct ospf_interface *oi) -{ - unsigned long n; - - n = ospf_opaque_nrxmt_self (oi->nbrs, OSPF_OPAQUE_LINK_LSA); - if (n == 0) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("Self-originated type-9 Opaque-LSAs: OI(%s): Flush completed", IF_NAME (oi)); - - UNSET_FLAG (oi->area->ospf->opaque, OPAQUE_BLOCK_TYPE_09_LSA_BIT); - } - return; -} - -static void -ospf_opaque_type10_lsa_rxmt_nbr_check (struct ospf_area *area) -{ - struct listnode *node; - struct ospf_interface *oi; - unsigned long n = 0; - - for (ALL_LIST_ELEMENTS_RO (area->oiflist, node, oi)) - { - if (area->area_id.s_addr != OSPF_AREA_BACKBONE - && oi->type == OSPF_IFTYPE_VIRTUALLINK) - continue; - - n = ospf_opaque_nrxmt_self (oi->nbrs, OSPF_OPAQUE_AREA_LSA); - if (n > 0) - break; - } - - if (n == 0) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("Self-originated type-10 Opaque-LSAs: AREA(%s): Flush completed", inet_ntoa (area->area_id)); - - UNSET_FLAG (area->ospf->opaque, OPAQUE_BLOCK_TYPE_10_LSA_BIT); - } - - return; -} - -static void -ospf_opaque_type11_lsa_rxmt_nbr_check (struct ospf *top) -{ - struct listnode *node; - struct ospf_interface *oi; - unsigned long n = 0; - - for (ALL_LIST_ELEMENTS_RO (top->oiflist, node, oi)) - { - switch (oi->type) - { - case OSPF_IFTYPE_VIRTUALLINK: - continue; - default: - break; - } - - n = ospf_opaque_nrxmt_self (oi->nbrs, OSPF_OPAQUE_AS_LSA); - if (n > 0) - goto out; - } - - if (n == 0) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("Self-originated type-11 Opaque-LSAs: Flush completed"); - - UNSET_FLAG (top->opaque, OPAQUE_BLOCK_TYPE_11_LSA_BIT); - } - -out: - return; -} - -static unsigned long -ospf_opaque_nrxmt_self (struct route_table *nbrs, int lsa_type) -{ - struct route_node *rn; - struct ospf_neighbor *nbr; - struct ospf *top; - unsigned long n = 0; - - for (rn = route_top (nbrs); rn; rn = route_next (rn)) - { - if ((nbr = rn->info) == NULL) - continue; - if ((top = oi_to_top (nbr->oi)) == NULL) - continue; - if (IPV4_ADDR_SAME (&nbr->router_id, &top->router_id)) - continue; - n += ospf_ls_retransmit_count_self (nbr, lsa_type); - } - - return n; -} - /*------------------------------------------------------------------------* * Followings are util functions; probably be used by Opaque-LSAs only... *------------------------------------------------------------------------*/ @@ -2478,4 +2172,3 @@ oi_to_top (struct ospf_interface *oi) return top; } -#endif /* HAVE_OPAQUE_LSA */