diff options
Diffstat (limited to 'ospfd/ospf_abr.c')
-rw-r--r-- | ospfd/ospf_abr.c | 3105 |
1 files changed, 1541 insertions, 1564 deletions
diff --git a/ospfd/ospf_abr.c b/ospfd/ospf_abr.c index aa4909314..6af4a2ece 100644 --- a/ospfd/ospf_abr.c +++ b/ospfd/ospf_abr.c @@ -8,12 +8,12 @@ * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2, or (at your option) any * later version. - * + * * GNU Zebra is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with GNU Zebra; see the file COPYING. If not, write to the Free * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA @@ -51,1667 +51,1648 @@ #include "ospfd/ospf_zebra.h" #include "ospfd/ospf_dump.h" -static struct ospf_area_range * -ospf_area_range_new (struct prefix_ipv4 *p) +static struct ospf_area_range *ospf_area_range_new(struct prefix_ipv4 *p) { - struct ospf_area_range *range; + struct ospf_area_range *range; - range = XCALLOC (MTYPE_OSPF_AREA_RANGE, sizeof (struct ospf_area_range)); - range->addr = p->prefix; - range->masklen = p->prefixlen; - range->cost_config = OSPF_AREA_RANGE_COST_UNSPEC; + range = XCALLOC(MTYPE_OSPF_AREA_RANGE, sizeof(struct ospf_area_range)); + range->addr = p->prefix; + range->masklen = p->prefixlen; + range->cost_config = OSPF_AREA_RANGE_COST_UNSPEC; - return range; + return range; } -static void -ospf_area_range_free (struct ospf_area_range *range) +static void ospf_area_range_free(struct ospf_area_range *range) { - XFREE (MTYPE_OSPF_AREA_RANGE, range); + XFREE(MTYPE_OSPF_AREA_RANGE, range); } -static void -ospf_area_range_add (struct ospf_area *area, struct ospf_area_range *range) +static void ospf_area_range_add(struct ospf_area *area, + struct ospf_area_range *range) { - struct route_node *rn; - struct prefix_ipv4 p; - - p.family = AF_INET; - p.prefixlen = range->masklen; - p.prefix = range->addr; - - rn = route_node_get (area->ranges, (struct prefix *)&p); - if (rn->info) - route_unlock_node (rn); - else - rn->info = range; + struct route_node *rn; + struct prefix_ipv4 p; + + p.family = AF_INET; + p.prefixlen = range->masklen; + p.prefix = range->addr; + + rn = route_node_get(area->ranges, (struct prefix *)&p); + if (rn->info) + route_unlock_node(rn); + else + rn->info = range; } -static void -ospf_area_range_delete (struct ospf_area *area, struct route_node *rn) +static void ospf_area_range_delete(struct ospf_area *area, + struct route_node *rn) { - struct ospf_area_range *range = rn->info; + struct ospf_area_range *range = rn->info; - if (range->specifics != 0) - ospf_delete_discard_route (area->ospf->new_table, - (struct prefix_ipv4 *) &rn->p); + if (range->specifics != 0) + ospf_delete_discard_route(area->ospf->new_table, + (struct prefix_ipv4 *)&rn->p); - ospf_area_range_free (range); - rn->info = NULL; - route_unlock_node (rn); - route_unlock_node (rn); + ospf_area_range_free(range); + rn->info = NULL; + route_unlock_node(rn); + route_unlock_node(rn); } -struct ospf_area_range * -ospf_area_range_lookup (struct ospf_area *area, struct prefix_ipv4 *p) +struct ospf_area_range *ospf_area_range_lookup(struct ospf_area *area, + struct prefix_ipv4 *p) { - struct route_node *rn; - - rn = route_node_lookup (area->ranges, (struct prefix *)p); - if (rn) - { - route_unlock_node (rn); - return rn->info; - } - return NULL; + struct route_node *rn; + + rn = route_node_lookup(area->ranges, (struct prefix *)p); + if (rn) { + route_unlock_node(rn); + return rn->info; + } + return NULL; } -struct ospf_area_range * -ospf_area_range_lookup_next (struct ospf_area *area, - struct in_addr *range_net, - int first) +struct ospf_area_range *ospf_area_range_lookup_next(struct ospf_area *area, + struct in_addr *range_net, + int first) { - struct route_node *rn; - struct prefix_ipv4 p; - struct ospf_area_range *find; - - p.family = AF_INET; - p.prefixlen = IPV4_MAX_BITLEN; - p.prefix = *range_net; - - if (first) - rn = route_top (area->ranges); - else - { - rn = route_node_get (area->ranges, (struct prefix *) &p); - rn = route_next (rn); - } - - for (; rn; rn = route_next (rn)) - if (rn->info) - break; - - if (rn && rn->info) - { - find = rn->info; - *range_net = rn->p.u.prefix4; - route_unlock_node (rn); - return find; - } - return NULL; + struct route_node *rn; + struct prefix_ipv4 p; + struct ospf_area_range *find; + + p.family = AF_INET; + p.prefixlen = IPV4_MAX_BITLEN; + p.prefix = *range_net; + + if (first) + rn = route_top(area->ranges); + else { + rn = route_node_get(area->ranges, (struct prefix *)&p); + rn = route_next(rn); + } + + for (; rn; rn = route_next(rn)) + if (rn->info) + break; + + if (rn && rn->info) { + find = rn->info; + *range_net = rn->p.u.prefix4; + route_unlock_node(rn); + return find; + } + return NULL; } -static struct ospf_area_range * -ospf_area_range_match (struct ospf_area *area, struct prefix_ipv4 *p) +static struct ospf_area_range *ospf_area_range_match(struct ospf_area *area, + struct prefix_ipv4 *p) { - struct route_node *node; - - node = route_node_match (area->ranges, (struct prefix *) p); - if (node) - { - route_unlock_node (node); - return node->info; - } - return NULL; + struct route_node *node; + + node = route_node_match(area->ranges, (struct prefix *)p); + if (node) { + route_unlock_node(node); + return node->info; + } + return NULL; } -struct ospf_area_range * -ospf_area_range_match_any (struct ospf *ospf, struct prefix_ipv4 *p) +struct ospf_area_range *ospf_area_range_match_any(struct ospf *ospf, + struct prefix_ipv4 *p) { - struct ospf_area_range *range; - struct ospf_area *area; - struct listnode *node; + struct ospf_area_range *range; + struct ospf_area *area; + struct listnode *node; - for (ALL_LIST_ELEMENTS_RO (ospf->areas, node, area)) - if ((range = ospf_area_range_match (area, p))) - return range; + for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) + if ((range = ospf_area_range_match(area, p))) + return range; - return NULL; + return NULL; } -int -ospf_area_range_active (struct ospf_area_range *range) +int ospf_area_range_active(struct ospf_area_range *range) { - return range->specifics; + return range->specifics; } -static int -ospf_area_actively_attached (struct ospf_area *area) +static int ospf_area_actively_attached(struct ospf_area *area) { - return area->act_ints; + return area->act_ints; } -int -ospf_area_range_set (struct ospf *ospf, struct in_addr area_id, - struct prefix_ipv4 *p, int advertise) +int ospf_area_range_set(struct ospf *ospf, struct in_addr area_id, + struct prefix_ipv4 *p, int advertise) { - struct ospf_area *area; - struct ospf_area_range *range; - - area = ospf_area_get (ospf, area_id); - if (area == NULL) - return 0; - - range = ospf_area_range_lookup (area, p); - if (range != NULL) - { - if ((CHECK_FLAG (range->flags, OSPF_AREA_RANGE_ADVERTISE) - && !CHECK_FLAG (advertise, OSPF_AREA_RANGE_ADVERTISE)) - || (!CHECK_FLAG (range->flags, OSPF_AREA_RANGE_ADVERTISE) - && CHECK_FLAG (advertise, OSPF_AREA_RANGE_ADVERTISE))) - ospf_schedule_abr_task (ospf); - } - else - { - range = ospf_area_range_new (p); - ospf_area_range_add (area, range); - ospf_schedule_abr_task (ospf); - } - - if (CHECK_FLAG (advertise, OSPF_AREA_RANGE_ADVERTISE)) - SET_FLAG (range->flags, OSPF_AREA_RANGE_ADVERTISE); - else - UNSET_FLAG (range->flags, OSPF_AREA_RANGE_ADVERTISE); - - return 1; + struct ospf_area *area; + struct ospf_area_range *range; + + area = ospf_area_get(ospf, area_id); + if (area == NULL) + return 0; + + range = ospf_area_range_lookup(area, p); + if (range != NULL) { + if ((CHECK_FLAG(range->flags, OSPF_AREA_RANGE_ADVERTISE) + && !CHECK_FLAG(advertise, OSPF_AREA_RANGE_ADVERTISE)) + || (!CHECK_FLAG(range->flags, OSPF_AREA_RANGE_ADVERTISE) + && CHECK_FLAG(advertise, OSPF_AREA_RANGE_ADVERTISE))) + ospf_schedule_abr_task(ospf); + } else { + range = ospf_area_range_new(p); + ospf_area_range_add(area, range); + ospf_schedule_abr_task(ospf); + } + + if (CHECK_FLAG(advertise, OSPF_AREA_RANGE_ADVERTISE)) + SET_FLAG(range->flags, OSPF_AREA_RANGE_ADVERTISE); + else + UNSET_FLAG(range->flags, OSPF_AREA_RANGE_ADVERTISE); + + return 1; } -int -ospf_area_range_cost_set (struct ospf *ospf, struct in_addr area_id, - struct prefix_ipv4 *p, u_int32_t cost) +int ospf_area_range_cost_set(struct ospf *ospf, struct in_addr area_id, + struct prefix_ipv4 *p, u_int32_t cost) { - struct ospf_area *area; - struct ospf_area_range *range; + struct ospf_area *area; + struct ospf_area_range *range; - area = ospf_area_get (ospf, area_id); - if (area == NULL) - return 0; + area = ospf_area_get(ospf, area_id); + if (area == NULL) + return 0; - range = ospf_area_range_lookup (area, p); - if (range == NULL) - return 0; + range = ospf_area_range_lookup(area, p); + if (range == NULL) + return 0; - if (range->cost_config != cost) - { - range->cost_config = cost; - if (ospf_area_range_active (range)) - ospf_schedule_abr_task (ospf); - } + if (range->cost_config != cost) { + range->cost_config = cost; + if (ospf_area_range_active(range)) + ospf_schedule_abr_task(ospf); + } - return 1; + return 1; } -int -ospf_area_range_unset (struct ospf *ospf, struct in_addr area_id, - struct prefix_ipv4 *p) +int ospf_area_range_unset(struct ospf *ospf, struct in_addr area_id, + struct prefix_ipv4 *p) { - struct ospf_area *area; - struct route_node *rn; + struct ospf_area *area; + struct route_node *rn; - area = ospf_area_lookup_by_area_id (ospf, area_id); - if (area == NULL) - return 0; + area = ospf_area_lookup_by_area_id(ospf, area_id); + if (area == NULL) + return 0; - rn = route_node_lookup (area->ranges, (struct prefix*)p); - if (rn == NULL) - return 0; + rn = route_node_lookup(area->ranges, (struct prefix *)p); + if (rn == NULL) + return 0; - if (ospf_area_range_active (rn->info)) - ospf_schedule_abr_task (ospf); + if (ospf_area_range_active(rn->info)) + ospf_schedule_abr_task(ospf); - ospf_area_range_delete (area, rn); + ospf_area_range_delete(area, rn); - return 1; + return 1; } -int -ospf_area_range_substitute_set (struct ospf *ospf, struct in_addr area_id, - struct prefix_ipv4 *p, struct prefix_ipv4 *s) +int ospf_area_range_substitute_set(struct ospf *ospf, struct in_addr area_id, + struct prefix_ipv4 *p, struct prefix_ipv4 *s) { - struct ospf_area *area; - struct ospf_area_range *range; - - area = ospf_area_get (ospf, area_id); - range = ospf_area_range_lookup (area, p); - - if (range != NULL) - { - if (!CHECK_FLAG (range->flags, OSPF_AREA_RANGE_ADVERTISE) || - !CHECK_FLAG (range->flags, OSPF_AREA_RANGE_SUBSTITUTE)) - ospf_schedule_abr_task (ospf); - } - else - { - range = ospf_area_range_new (p); - ospf_area_range_add (area, range); - ospf_schedule_abr_task (ospf); - } - - SET_FLAG (range->flags, OSPF_AREA_RANGE_ADVERTISE); - SET_FLAG (range->flags, OSPF_AREA_RANGE_SUBSTITUTE); - range->subst_addr = s->prefix; - range->subst_masklen = s->prefixlen; - - return 1; + struct ospf_area *area; + struct ospf_area_range *range; + + area = ospf_area_get(ospf, area_id); + range = ospf_area_range_lookup(area, p); + + if (range != NULL) { + if (!CHECK_FLAG(range->flags, OSPF_AREA_RANGE_ADVERTISE) + || !CHECK_FLAG(range->flags, OSPF_AREA_RANGE_SUBSTITUTE)) + ospf_schedule_abr_task(ospf); + } else { + range = ospf_area_range_new(p); + ospf_area_range_add(area, range); + ospf_schedule_abr_task(ospf); + } + + SET_FLAG(range->flags, OSPF_AREA_RANGE_ADVERTISE); + SET_FLAG(range->flags, OSPF_AREA_RANGE_SUBSTITUTE); + range->subst_addr = s->prefix; + range->subst_masklen = s->prefixlen; + + return 1; } -int -ospf_area_range_substitute_unset (struct ospf *ospf, struct in_addr area_id, - struct prefix_ipv4 *p) +int ospf_area_range_substitute_unset(struct ospf *ospf, struct in_addr area_id, + struct prefix_ipv4 *p) { - struct ospf_area *area; - struct ospf_area_range *range; + struct ospf_area *area; + struct ospf_area_range *range; - area = ospf_area_lookup_by_area_id (ospf, area_id); - if (area == NULL) - return 0; + area = ospf_area_lookup_by_area_id(ospf, area_id); + if (area == NULL) + return 0; - range = ospf_area_range_lookup (area, p); - if (range == NULL) - return 0; + range = ospf_area_range_lookup(area, p); + if (range == NULL) + return 0; - if (CHECK_FLAG (range->flags, OSPF_AREA_RANGE_SUBSTITUTE)) - if (ospf_area_range_active (range)) - ospf_schedule_abr_task (ospf); + if (CHECK_FLAG(range->flags, OSPF_AREA_RANGE_SUBSTITUTE)) + if (ospf_area_range_active(range)) + ospf_schedule_abr_task(ospf); - UNSET_FLAG (range->flags, OSPF_AREA_RANGE_SUBSTITUTE); - range->subst_addr.s_addr = 0; - range->subst_masklen = 0; + UNSET_FLAG(range->flags, OSPF_AREA_RANGE_SUBSTITUTE); + range->subst_addr.s_addr = 0; + range->subst_masklen = 0; - return 1; + return 1; } -int -ospf_act_bb_connection (struct ospf *ospf) +int ospf_act_bb_connection(struct ospf *ospf) { - if (ospf->backbone == NULL) - return 0; + if (ospf->backbone == NULL) + return 0; - return ospf->backbone->full_nbrs; + return ospf->backbone->full_nbrs; } /* Determine whether this router is elected translator or not for area */ -static int -ospf_abr_nssa_am_elected (struct ospf_area *area) +static int ospf_abr_nssa_am_elected(struct ospf_area *area) { - struct route_node *rn; - struct ospf_lsa *lsa; - struct router_lsa *rlsa; - struct in_addr *best = NULL; - - LSDB_LOOP ( ROUTER_LSDB (area), rn, lsa) - { - /* sanity checks */ - if (!lsa - || (lsa->data->type != OSPF_ROUTER_LSA) - || IS_LSA_SELF (lsa)) - continue; - - rlsa = (struct router_lsa *) lsa->data; - - /* ignore non-ABR routers */ - if (!IS_ROUTER_LSA_BORDER (rlsa)) - continue; - - /* Router has Nt flag - always translate */ - if (IS_ROUTER_LSA_NT (rlsa)) - { - if (IS_DEBUG_OSPF_NSSA) - zlog_debug ("ospf_abr_nssa_am_elected: " - "router %s asserts Nt", - inet_ntoa (lsa->data->id) ); - return 0; - } - - if (best == NULL) - best = &lsa->data->id; - else - if (IPV4_ADDR_CMP (&best->s_addr, &lsa->data->id.s_addr) < 0) - best = &lsa->data->id; - } - - if (IS_DEBUG_OSPF_NSSA) - zlog_debug ("ospf_abr_nssa_am_elected: best electable ABR is: %s", - (best) ? inet_ntoa (*best) : "<none>" ); - - if (best == NULL) - return 1; - - if (IPV4_ADDR_CMP (&best->s_addr, &area->ospf->router_id.s_addr) < 0) - return 1; - else - return 0; + struct route_node *rn; + struct ospf_lsa *lsa; + struct router_lsa *rlsa; + struct in_addr *best = NULL; + + LSDB_LOOP(ROUTER_LSDB(area), rn, lsa) + { + /* sanity checks */ + if (!lsa || (lsa->data->type != OSPF_ROUTER_LSA) + || IS_LSA_SELF(lsa)) + continue; + + rlsa = (struct router_lsa *)lsa->data; + + /* ignore non-ABR routers */ + if (!IS_ROUTER_LSA_BORDER(rlsa)) + continue; + + /* Router has Nt flag - always translate */ + if (IS_ROUTER_LSA_NT(rlsa)) { + if (IS_DEBUG_OSPF_NSSA) + zlog_debug( + "ospf_abr_nssa_am_elected: " + "router %s asserts Nt", + inet_ntoa(lsa->data->id)); + return 0; + } + + if (best == NULL) + best = &lsa->data->id; + else if (IPV4_ADDR_CMP(&best->s_addr, &lsa->data->id.s_addr) + < 0) + best = &lsa->data->id; + } + + if (IS_DEBUG_OSPF_NSSA) + zlog_debug( + "ospf_abr_nssa_am_elected: best electable ABR is: %s", + (best) ? inet_ntoa(*best) : "<none>"); + + if (best == NULL) + return 1; + + if (IPV4_ADDR_CMP(&best->s_addr, &area->ospf->router_id.s_addr) < 0) + return 1; + else + return 0; } /* Check NSSA ABR status * assumes there are nssa areas */ -static void -ospf_abr_nssa_check_status (struct ospf *ospf) +static void ospf_abr_nssa_check_status(struct ospf *ospf) { - struct ospf_area *area; - struct listnode *lnode, *nnode; - - for (ALL_LIST_ELEMENTS (ospf->areas, lnode, nnode, area)) - { - u_char old_state = area->NSSATranslatorState; - - if (area->external_routing != OSPF_AREA_NSSA) - continue; - - if (IS_DEBUG_OSPF (nssa, NSSA)) - zlog_debug ("ospf_abr_nssa_check_status: " - "checking area %s", - inet_ntoa (area->area_id)); - - if (!IS_OSPF_ABR (area->ospf)) - { - if (IS_DEBUG_OSPF (nssa, NSSA)) - zlog_debug ("ospf_abr_nssa_check_status: " - "not ABR"); - area->NSSATranslatorState = OSPF_NSSA_TRANSLATE_DISABLED; - } - else - { - switch (area->NSSATranslatorRole) - { - case OSPF_NSSA_ROLE_NEVER: - /* We never Translate Type-7 LSA. */ - /* TODO: check previous state and flush? */ - if (IS_DEBUG_OSPF (nssa, NSSA)) - zlog_debug ("ospf_abr_nssa_check_status: " - "never translate"); - area->NSSATranslatorState = OSPF_NSSA_TRANSLATE_DISABLED; - break; - - case OSPF_NSSA_ROLE_ALWAYS: - /* We always translate if we are an ABR - * TODO: originate new LSAs if state change? - * or let the nssa abr task take care of it? - */ - if (IS_DEBUG_OSPF (nssa, NSSA)) - zlog_debug ("ospf_abr_nssa_check_status: " - "translate always"); - area->NSSATranslatorState = OSPF_NSSA_TRANSLATE_ENABLED; - break; - - case OSPF_NSSA_ROLE_CANDIDATE: - /* We are a candidate for Translation */ - if (ospf_abr_nssa_am_elected (area) > 0) - { - area->NSSATranslatorState = OSPF_NSSA_TRANSLATE_ENABLED; - if (IS_DEBUG_OSPF (nssa, NSSA)) - zlog_debug ("ospf_abr_nssa_check_status: " - "elected translator"); - } - else - { - area->NSSATranslatorState = OSPF_NSSA_TRANSLATE_DISABLED; - if (IS_DEBUG_OSPF (nssa, NSSA)) - zlog_debug ("ospf_abr_nssa_check_status: " "not elected"); - } - break; - } - } - /* RFC3101, 3.1: - * All NSSA border routers must set the E-bit in the Type-1 router-LSAs - * of their directly attached non-stub areas, even when they are not - * translating. - */ - if (old_state != area->NSSATranslatorState) - { - if (old_state == OSPF_NSSA_TRANSLATE_DISABLED) - ospf_asbr_status_update (ospf, ++ospf->redistribute); - else if (area->NSSATranslatorState == OSPF_NSSA_TRANSLATE_DISABLED) - ospf_asbr_status_update (ospf, --ospf->redistribute); + struct ospf_area *area; + struct listnode *lnode, *nnode; + + for (ALL_LIST_ELEMENTS(ospf->areas, lnode, nnode, area)) { + u_char old_state = area->NSSATranslatorState; + + if (area->external_routing != OSPF_AREA_NSSA) + continue; + + if (IS_DEBUG_OSPF(nssa, NSSA)) + zlog_debug( + "ospf_abr_nssa_check_status: " + "checking area %s", + inet_ntoa(area->area_id)); + + if (!IS_OSPF_ABR(area->ospf)) { + if (IS_DEBUG_OSPF(nssa, NSSA)) + zlog_debug( + "ospf_abr_nssa_check_status: " + "not ABR"); + area->NSSATranslatorState = + OSPF_NSSA_TRANSLATE_DISABLED; + } else { + switch (area->NSSATranslatorRole) { + case OSPF_NSSA_ROLE_NEVER: + /* We never Translate Type-7 LSA. */ + /* TODO: check previous state and flush? */ + if (IS_DEBUG_OSPF(nssa, NSSA)) + zlog_debug( + "ospf_abr_nssa_check_status: " + "never translate"); + area->NSSATranslatorState = + OSPF_NSSA_TRANSLATE_DISABLED; + break; + + case OSPF_NSSA_ROLE_ALWAYS: + /* We always translate if we are an ABR + * TODO: originate new LSAs if state change? + * or let the nssa abr task take care of it? + */ + if (IS_DEBUG_OSPF(nssa, NSSA)) + zlog_debug( + "ospf_abr_nssa_check_status: " + "translate always"); + area->NSSATranslatorState = + OSPF_NSSA_TRANSLATE_ENABLED; + break; + + case OSPF_NSSA_ROLE_CANDIDATE: + /* We are a candidate for Translation */ + if (ospf_abr_nssa_am_elected(area) > 0) { + area->NSSATranslatorState = + OSPF_NSSA_TRANSLATE_ENABLED; + if (IS_DEBUG_OSPF(nssa, NSSA)) + zlog_debug( + "ospf_abr_nssa_check_status: " + "elected translator"); + } else { + area->NSSATranslatorState = + OSPF_NSSA_TRANSLATE_DISABLED; + if (IS_DEBUG_OSPF(nssa, NSSA)) + zlog_debug( + "ospf_abr_nssa_check_status: " + "not elected"); + } + break; + } + } + /* RFC3101, 3.1: + * All NSSA border routers must set the E-bit in the Type-1 + * router-LSAs + * of their directly attached non-stub areas, even when they are + * not + * translating. + */ + if (old_state != area->NSSATranslatorState) { + if (old_state == OSPF_NSSA_TRANSLATE_DISABLED) + ospf_asbr_status_update(ospf, + ++ospf->redistribute); + else if (area->NSSATranslatorState + == OSPF_NSSA_TRANSLATE_DISABLED) + ospf_asbr_status_update(ospf, + --ospf->redistribute); + } } - } } /* Check area border router status. */ -void -ospf_check_abr_status (struct ospf *ospf) +void ospf_check_abr_status(struct ospf *ospf) { - struct ospf_area *area; - struct listnode *node, *nnode; - int bb_configured = 0; - int bb_act_attached = 0; - int areas_configured = 0; - int areas_act_attached = 0; - u_char new_flags = ospf->flags; - - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_check_abr_status(): Start"); - - for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area)) - { - if (listcount (area->oiflist)) - { - areas_configured++; - - if (OSPF_IS_AREA_BACKBONE (area)) - bb_configured = 1; + struct ospf_area *area; + struct listnode *node, *nnode; + int bb_configured = 0; + int bb_act_attached = 0; + int areas_configured = 0; + int areas_act_attached = 0; + u_char new_flags = ospf->flags; + + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("ospf_check_abr_status(): Start"); + + for (ALL_LIST_ELEMENTS(ospf->areas, node, nnode, area)) { + if (listcount(area->oiflist)) { + areas_configured++; + + if (OSPF_IS_AREA_BACKBONE(area)) + bb_configured = 1; + } + + if (ospf_area_actively_attached(area)) { + areas_act_attached++; + + if (OSPF_IS_AREA_BACKBONE(area)) + bb_act_attached = 1; + } } - if (ospf_area_actively_attached (area)) - { - areas_act_attached++; - - if (OSPF_IS_AREA_BACKBONE (area)) - bb_act_attached = 1; + if (IS_DEBUG_OSPF_EVENT) { + zlog_debug("ospf_check_abr_status(): looked through areas"); + zlog_debug("ospf_check_abr_status(): bb_configured: %d", + bb_configured); + zlog_debug("ospf_check_abr_status(): bb_act_attached: %d", + bb_act_attached); + zlog_debug("ospf_check_abr_status(): areas_configured: %d", + areas_configured); + zlog_debug("ospf_check_abr_status(): areas_act_attached: %d", + areas_act_attached); + } + + switch (ospf->abr_type) { + case OSPF_ABR_SHORTCUT: + case OSPF_ABR_STAND: + if (areas_act_attached > 1) + SET_FLAG(new_flags, OSPF_FLAG_ABR); + else + UNSET_FLAG(new_flags, OSPF_FLAG_ABR); + break; + + case OSPF_ABR_IBM: + if ((areas_act_attached > 1) && bb_configured) + SET_FLAG(new_flags, OSPF_FLAG_ABR); + else + UNSET_FLAG(new_flags, OSPF_FLAG_ABR); + break; + + case OSPF_ABR_CISCO: + if ((areas_configured > 1) && bb_act_attached) + SET_FLAG(new_flags, OSPF_FLAG_ABR); + else + UNSET_FLAG(new_flags, OSPF_FLAG_ABR); + break; + default: + break; + } + + if (new_flags != ospf->flags) { + ospf_spf_calculate_schedule(ospf, SPF_FLAG_ABR_STATUS_CHANGE); + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_check_abr_status(): new router flags: %x", + new_flags); + ospf->flags = new_flags; + ospf_router_lsa_update(ospf); } - } - - if (IS_DEBUG_OSPF_EVENT) - { - zlog_debug ("ospf_check_abr_status(): looked through areas"); - zlog_debug ("ospf_check_abr_status(): bb_configured: %d", bb_configured); - zlog_debug ("ospf_check_abr_status(): bb_act_attached: %d", - bb_act_attached); - zlog_debug ("ospf_check_abr_status(): areas_configured: %d", - areas_configured); - zlog_debug ("ospf_check_abr_status(): areas_act_attached: %d", - areas_act_attached); - } - - switch (ospf->abr_type) - { - case OSPF_ABR_SHORTCUT: - case OSPF_ABR_STAND: - if (areas_act_attached > 1) - SET_FLAG (new_flags, OSPF_FLAG_ABR); - else - UNSET_FLAG (new_flags, OSPF_FLAG_ABR); - break; - - case OSPF_ABR_IBM: - if ((areas_act_attached > 1) && bb_configured) - SET_FLAG (new_flags, OSPF_FLAG_ABR); - else - UNSET_FLAG (new_flags, OSPF_FLAG_ABR); - break; - - case OSPF_ABR_CISCO: - if ((areas_configured > 1) && bb_act_attached) - SET_FLAG (new_flags, OSPF_FLAG_ABR); - else - UNSET_FLAG (new_flags, OSPF_FLAG_ABR); - break; - default: - break; - } - - if (new_flags != ospf->flags) - { - ospf_spf_calculate_schedule (ospf, SPF_FLAG_ABR_STATUS_CHANGE); - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_check_abr_status(): new router flags: %x",new_flags); - ospf->flags = new_flags; - ospf_router_lsa_update (ospf); - } } -static void -ospf_abr_update_aggregate (struct ospf_area_range *range, - struct ospf_route *or, struct ospf_area *area) +static void ospf_abr_update_aggregate(struct ospf_area_range *range, + struct ospf_route * or, + struct ospf_area *area) { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_update_aggregate(): Start"); - - if (CHECK_FLAG (area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED) && - (range->cost != OSPF_STUB_MAX_METRIC_SUMMARY_COST)) - { - range->cost = OSPF_STUB_MAX_METRIC_SUMMARY_COST; - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_update_aggregate(): use summary max-metric 0x%08x", - range->cost); - } - else if (range->cost_config != OSPF_AREA_RANGE_COST_UNSPEC) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_update_aggregate(): use configured cost %d", - range->cost_config); - - range->cost = range->cost_config; - } - else - { - if (range->specifics == 0) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_update_aggregate(): use or->cost %d", - or->cost); + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("ospf_abr_update_aggregate(): Start"); - range->cost = or->cost; /* 1st time get 1st cost */ - } + if (CHECK_FLAG(area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED) + && (range->cost != OSPF_STUB_MAX_METRIC_SUMMARY_COST)) { + range->cost = OSPF_STUB_MAX_METRIC_SUMMARY_COST; + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_abr_update_aggregate(): use summary max-metric 0x%08x", + range->cost); + } else if (range->cost_config != OSPF_AREA_RANGE_COST_UNSPEC) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_abr_update_aggregate(): use configured cost %d", + range->cost_config); + + range->cost = range->cost_config; + } else { + if (range->specifics == 0) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_abr_update_aggregate(): use or->cost %d", + or->cost); - if (or->cost > range->cost) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_update_aggregate(): update to %d", or->cost); + range->cost = or->cost; /* 1st time get 1st cost */ + } - range->cost = or->cost; - } - } + if (or->cost > range->cost) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_abr_update_aggregate(): update to %d", + or->cost); + + range->cost = or->cost; + } + } - range->specifics++; + range->specifics++; } -static void -set_metric (struct ospf_lsa *lsa, u_int32_t metric) +static void set_metric(struct ospf_lsa *lsa, u_int32_t metric) { - struct summary_lsa *header; - u_char *mp; - metric = htonl (metric); - mp = (u_char *) &metric; - mp++; - header = (struct summary_lsa *) lsa->data; - memcpy(header->metric, mp, 3); + struct summary_lsa *header; + u_char *mp; + metric = htonl(metric); + mp = (u_char *)&metric; + mp++; + header = (struct summary_lsa *)lsa->data; + memcpy(header->metric, mp, 3); } /* ospf_abr_translate_nssa */ -static int -ospf_abr_translate_nssa (struct ospf_area *area, struct ospf_lsa *lsa) +static int ospf_abr_translate_nssa(struct ospf_area *area, struct ospf_lsa *lsa) { - /* Incoming Type-7 or later aggregated Type-7 - * - * LSA is skipped if P-bit is off. - * LSA is aggregated if within range. - * - * The Type-7 is translated, Installed/Approved as a Type-5 into - * global LSDB, then Flooded through AS - * - * Later, any Unapproved Translated Type-5's are flushed/discarded - */ - - struct ospf_lsa *old = NULL, - *new = NULL; - struct as_external_lsa *ext7; - struct prefix_ipv4 p; - - if (! CHECK_FLAG (lsa->data->options, OSPF_OPTION_NP)) - { - if (IS_DEBUG_OSPF_NSSA) - zlog_debug ("ospf_abr_translate_nssa(): LSA Id %s, P-bit off, NO Translation", - inet_ntoa (lsa->data->id)); - return 1; - } - - if (IS_DEBUG_OSPF_NSSA) - zlog_debug ("ospf_abr_translate_nssa(): LSA Id %s, TRANSLATING 7 to 5", - inet_ntoa (lsa->data->id)); - - ext7 = (struct as_external_lsa *)(lsa->data); - p.prefix = lsa->data->id; - p.prefixlen = ip_masklen (ext7->mask); - - if (ext7->e[0].fwd_addr.s_addr == OSPF_DEFAULT_DESTINATION) - { - if (IS_DEBUG_OSPF_NSSA) - zlog_debug ("ospf_abr_translate_nssa(): LSA Id %s, " - "Forward address is 0, NO Translation", - inet_ntoa (lsa->data->id)); - return 1; - } - - /* try find existing AS-External LSA for this prefix */ - - old = ospf_external_info_find_lsa (area->ospf, &p); - - if (old) - { - if (IS_DEBUG_OSPF_NSSA) - zlog_debug ("ospf_abr_translate_nssa(): " - "found old translated LSA Id %s, refreshing", - inet_ntoa (old->data->id)); - - /* refresh */ - new = ospf_translated_nssa_refresh (area->ospf, lsa, old); - if (!new) - { - if (IS_DEBUG_OSPF_NSSA) - zlog_debug ("ospf_abr_translate_nssa(): " - "could not refresh translated LSA Id %s", - inet_ntoa (old->data->id)); - } - } - else - { - /* no existing external route for this LSA Id - * originate translated LSA - */ - - if ((new = ospf_translated_nssa_originate (area->ospf, lsa)) - == NULL) - { - if (IS_DEBUG_OSPF_NSSA) - zlog_debug ("ospf_abr_translate_nssa(): Could not translate " - "Type-7 for %s to Type-5", - inet_ntoa (lsa->data->id)); - return 1; - } - } - - /* Area where Aggregate testing will be inserted, just like summary - advertisements */ - /* ospf_abr_check_nssa_range (p_arg, lsa-> cost, lsa -> area); */ - - return 0; + /* Incoming Type-7 or later aggregated Type-7 + * + * LSA is skipped if P-bit is off. + * LSA is aggregated if within range. + * + * The Type-7 is translated, Installed/Approved as a Type-5 into + * global LSDB, then Flooded through AS + * + * Later, any Unapproved Translated Type-5's are flushed/discarded + */ + + struct ospf_lsa *old = NULL, *new = NULL; + struct as_external_lsa *ext7; + struct prefix_ipv4 p; + + if (!CHECK_FLAG(lsa->data->options, OSPF_OPTION_NP)) { + if (IS_DEBUG_OSPF_NSSA) + zlog_debug( + "ospf_abr_translate_nssa(): LSA Id %s, P-bit off, NO Translation", + inet_ntoa(lsa->data->id)); + return 1; + } + + if (IS_DEBUG_OSPF_NSSA) + zlog_debug( + "ospf_abr_translate_nssa(): LSA Id %s, TRANSLATING 7 to 5", + inet_ntoa(lsa->data->id)); + + ext7 = (struct as_external_lsa *)(lsa->data); + p.prefix = lsa->data->id; + p.prefixlen = ip_masklen(ext7->mask); + + if (ext7->e[0].fwd_addr.s_addr == OSPF_DEFAULT_DESTINATION) { + if (IS_DEBUG_OSPF_NSSA) + zlog_debug( + "ospf_abr_translate_nssa(): LSA Id %s, " + "Forward address is 0, NO Translation", + inet_ntoa(lsa->data->id)); + return 1; + } + + /* try find existing AS-External LSA for this prefix */ + + old = ospf_external_info_find_lsa(area->ospf, &p); + + if (old) { + if (IS_DEBUG_OSPF_NSSA) + zlog_debug( + "ospf_abr_translate_nssa(): " + "found old translated LSA Id %s, refreshing", + inet_ntoa(old->data->id)); + + /* refresh */ + new = ospf_translated_nssa_refresh(area->ospf, lsa, old); + if (!new) { + if (IS_DEBUG_OSPF_NSSA) + zlog_debug( + "ospf_abr_translate_nssa(): " + "could not refresh translated LSA Id %s", + inet_ntoa(old->data->id)); + } + } else { + /* no existing external route for this LSA Id + * originate translated LSA + */ + + if ((new = ospf_translated_nssa_originate(area->ospf, lsa)) + == NULL) { + if (IS_DEBUG_OSPF_NSSA) + zlog_debug( + "ospf_abr_translate_nssa(): Could not translate " + "Type-7 for %s to Type-5", + inet_ntoa(lsa->data->id)); + return 1; + } + } + + /* Area where Aggregate testing will be inserted, just like summary + advertisements */ + /* ospf_abr_check_nssa_range (p_arg, lsa-> cost, lsa -> area); */ + + return 0; } -static void -ospf_abr_translate_nssa_range (struct prefix_ipv4 *p, u_int32_t cost) +static void ospf_abr_translate_nssa_range(struct prefix_ipv4 *p, u_int32_t cost) { - /* The Type-7 is created from the aggregated prefix and forwarded - for lsa installation and flooding... to be added... */ + /* The Type-7 is created from the aggregated prefix and forwarded + for lsa installation and flooding... to be added... */ } -void -ospf_abr_announce_network_to_area (struct prefix_ipv4 *p, u_int32_t cost, - struct ospf_area *area) +void ospf_abr_announce_network_to_area(struct prefix_ipv4 *p, u_int32_t cost, + struct ospf_area *area) { - struct ospf_lsa *lsa, *old = NULL; - struct summary_lsa *sl = NULL; - u_int32_t full_cost; - - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_announce_network_to_area(): Start"); - - if (CHECK_FLAG (area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED)) - full_cost = OSPF_STUB_MAX_METRIC_SUMMARY_COST; - else - full_cost = cost; - - old = ospf_lsa_lookup_by_prefix (area->lsdb, OSPF_SUMMARY_LSA, - (struct prefix_ipv4 *) p, - area->ospf->router_id); - if (old) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_announce_network_to_area(): old summary found"); - - sl = (struct summary_lsa *) old->data; - - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_announce_network_to_area(): " - "old metric: %d, new metric: %d", - GET_METRIC (sl->metric), cost); - - if ((GET_METRIC (sl->metric) == full_cost) && - ((old->flags & OSPF_LSA_IN_MAXAGE) == 0)) - { - /* unchanged. simply reapprove it */ - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_announce_network_to_area(): " - "old summary approved"); - SET_FLAG (old->flags, OSPF_LSA_APPROVED); - } - else - { - /* LSA is changed, refresh it */ - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_announce_network_to_area(): " - "refreshing summary"); - set_metric (old, full_cost); - lsa = ospf_lsa_refresh (area->ospf, old); - - if (!lsa) - { - char buf[PREFIX2STR_BUFFER]; - - prefix2str ((struct prefix *) p, buf, sizeof(buf)); - zlog_warn ("%s: Could not refresh %s to %s", - __func__, - buf, - inet_ntoa (area->area_id)); - return; - } - - SET_FLAG (lsa->flags, OSPF_LSA_APPROVED); - /* This will flood through area. */ - } - } - else - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_announce_network_to_area(): " - "creating new summary"); - lsa = ospf_summary_lsa_originate ( (struct prefix_ipv4 *)p, full_cost, area); - /* This will flood through area. */ - - if (!lsa) - { - char buf[PREFIX2STR_BUFFER]; - - prefix2str ((struct prefix *)p, buf, sizeof(buf)); - zlog_warn ("%s: Could not originate %s to %s", - __func__, - buf, - inet_ntoa (area->area_id)); - return; + struct ospf_lsa *lsa, *old = NULL; + struct summary_lsa *sl = NULL; + u_int32_t full_cost; + + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("ospf_abr_announce_network_to_area(): Start"); + + if (CHECK_FLAG(area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED)) + full_cost = OSPF_STUB_MAX_METRIC_SUMMARY_COST; + else + full_cost = cost; + + old = ospf_lsa_lookup_by_prefix(area->lsdb, OSPF_SUMMARY_LSA, + (struct prefix_ipv4 *)p, + area->ospf->router_id); + if (old) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_abr_announce_network_to_area(): old summary found"); + + sl = (struct summary_lsa *)old->data; + + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_abr_announce_network_to_area(): " + "old metric: %d, new metric: %d", + GET_METRIC(sl->metric), cost); + + if ((GET_METRIC(sl->metric) == full_cost) + && ((old->flags & OSPF_LSA_IN_MAXAGE) == 0)) { + /* unchanged. simply reapprove it */ + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_abr_announce_network_to_area(): " + "old summary approved"); + SET_FLAG(old->flags, OSPF_LSA_APPROVED); + } else { + /* LSA is changed, refresh it */ + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_abr_announce_network_to_area(): " + "refreshing summary"); + set_metric(old, full_cost); + lsa = ospf_lsa_refresh(area->ospf, old); + + if (!lsa) { + char buf[PREFIX2STR_BUFFER]; + + prefix2str((struct prefix *)p, buf, + sizeof(buf)); + zlog_warn("%s: Could not refresh %s to %s", + __func__, buf, + inet_ntoa(area->area_id)); + return; + } + + SET_FLAG(lsa->flags, OSPF_LSA_APPROVED); + /* This will flood through area. */ + } + } else { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_abr_announce_network_to_area(): " + "creating new summary"); + lsa = ospf_summary_lsa_originate((struct prefix_ipv4 *)p, + full_cost, area); + /* This will flood through area. */ + + if (!lsa) { + char buf[PREFIX2STR_BUFFER]; + + prefix2str((struct prefix *)p, buf, sizeof(buf)); + zlog_warn("%s: Could not originate %s to %s", __func__, + buf, inet_ntoa(area->area_id)); + return; + } + + SET_FLAG(lsa->flags, OSPF_LSA_APPROVED); + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_abr_announce_network_to_area(): " + "flooding new version of summary"); } - - SET_FLAG (lsa->flags, OSPF_LSA_APPROVED); - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_announce_network_to_area(): " - "flooding new version of summary"); - } - - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_announce_network_to_area(): Stop"); + + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("ospf_abr_announce_network_to_area(): Stop"); } -static int -ospf_abr_nexthops_belong_to_area (struct ospf_route *or, - struct ospf_area *area) +static int ospf_abr_nexthops_belong_to_area(struct ospf_route * or, + struct ospf_area *area) { - struct listnode *node, *nnode; - struct ospf_path *path; - struct ospf_interface *oi; + struct listnode *node, *nnode; + struct ospf_path *path; + struct ospf_interface *oi; - for (ALL_LIST_ELEMENTS_RO (or->paths, node, path)) - for (ALL_LIST_ELEMENTS_RO (area->oiflist, nnode, oi)) - if (oi->ifp && oi->ifp->ifindex == path->ifindex) - return 1; + for (ALL_LIST_ELEMENTS_RO(or->paths, node, path)) + for (ALL_LIST_ELEMENTS_RO(area->oiflist, nnode, oi)) + if (oi->ifp && oi->ifp->ifindex == path->ifindex) + return 1; - return 0; + return 0; } -static int -ospf_abr_should_accept (struct prefix_ipv4 *p, struct ospf_area *area) +static int ospf_abr_should_accept(struct prefix_ipv4 *p, struct ospf_area *area) { - if (IMPORT_NAME (area)) - { - if (IMPORT_LIST (area) == NULL) - IMPORT_LIST (area) = access_list_lookup (AFI_IP, IMPORT_NAME (area)); - - if (IMPORT_LIST (area)) - if (access_list_apply (IMPORT_LIST (area), p) == FILTER_DENY) - return 0; - } + if (IMPORT_NAME(area)) { + if (IMPORT_LIST(area) == NULL) + IMPORT_LIST(area) = + access_list_lookup(AFI_IP, IMPORT_NAME(area)); + + if (IMPORT_LIST(area)) + if (access_list_apply(IMPORT_LIST(area), p) + == FILTER_DENY) + return 0; + } - return 1; + return 1; } -static int -ospf_abr_plist_in_check (struct ospf_area *area, struct ospf_route *or, - struct prefix_ipv4 *p) +static int ospf_abr_plist_in_check(struct ospf_area *area, + struct ospf_route * or, + struct prefix_ipv4 *p) { - if (PREFIX_NAME_IN (area)) - { - if (PREFIX_LIST_IN (area) == NULL) - PREFIX_LIST_IN (area) = prefix_list_lookup (AFI_IP, - PREFIX_NAME_IN (area)); - if (PREFIX_LIST_IN (area)) - if (prefix_list_apply (PREFIX_LIST_IN (area), p) != PREFIX_PERMIT) - return 0; - } - return 1; + if (PREFIX_NAME_IN(area)) { + if (PREFIX_LIST_IN(area) == NULL) + PREFIX_LIST_IN(area) = prefix_list_lookup( + AFI_IP, PREFIX_NAME_IN(area)); + if (PREFIX_LIST_IN(area)) + if (prefix_list_apply(PREFIX_LIST_IN(area), p) + != PREFIX_PERMIT) + return 0; + } + return 1; } -static int -ospf_abr_plist_out_check (struct ospf_area *area, struct ospf_route *or, - struct prefix_ipv4 *p) +static int ospf_abr_plist_out_check(struct ospf_area *area, + struct ospf_route * or, + struct prefix_ipv4 *p) { - if (PREFIX_NAME_OUT (area)) - { - if (PREFIX_LIST_OUT (area) == NULL) - PREFIX_LIST_OUT (area) = prefix_list_lookup (AFI_IP, - PREFIX_NAME_OUT (area)); - if (PREFIX_LIST_OUT (area)) - if (prefix_list_apply (PREFIX_LIST_OUT (area), p) != PREFIX_PERMIT) - return 0; - } - return 1; + if (PREFIX_NAME_OUT(area)) { + if (PREFIX_LIST_OUT(area) == NULL) + PREFIX_LIST_OUT(area) = prefix_list_lookup( + AFI_IP, PREFIX_NAME_OUT(area)); + if (PREFIX_LIST_OUT(area)) + if (prefix_list_apply(PREFIX_LIST_OUT(area), p) + != PREFIX_PERMIT) + return 0; + } + return 1; } -static void -ospf_abr_announce_network (struct ospf *ospf, - struct prefix_ipv4 *p, struct ospf_route *or) +static void ospf_abr_announce_network(struct ospf *ospf, struct prefix_ipv4 *p, + struct ospf_route * or) { - struct ospf_area_range *range; - struct ospf_area *area, *or_area; - struct listnode *node; + struct ospf_area_range *range; + struct ospf_area *area, *or_area; + struct listnode *node; - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_announce_network(): Start"); + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("ospf_abr_announce_network(): Start"); - or_area = ospf_area_lookup_by_area_id (ospf, or->u.std.area_id); - assert (or_area); + or_area = ospf_area_lookup_by_area_id(ospf, or->u.std.area_id); + assert(or_area); - for (ALL_LIST_ELEMENTS_RO (ospf->areas, node, area)) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_announce_network(): looking at area %s", - inet_ntoa (area->area_id)); + for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_abr_announce_network(): looking at area %s", + inet_ntoa(area->area_id)); - if (IPV4_ADDR_SAME (&or->u.std.area_id, &area->area_id)) - continue; + if (IPV4_ADDR_SAME(& or->u.std.area_id, &area->area_id)) + continue; - if (ospf_abr_nexthops_belong_to_area (or, area)) - continue; + if (ospf_abr_nexthops_belong_to_area(or, area)) + continue; - if (!ospf_abr_should_accept (p, area)) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_announce_network(): " - "prefix %s/%d was denied by import-list", - inet_ntoa (p->prefix), p->prefixlen); - continue; - } + if (!ospf_abr_should_accept(p, area)) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_abr_announce_network(): " + "prefix %s/%d was denied by import-list", + inet_ntoa(p->prefix), p->prefixlen); + continue; + } + + if (!ospf_abr_plist_in_check(area, or, p)) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_abr_announce_network(): " + "prefix %s/%d was denied by prefix-list", + inet_ntoa(p->prefix), p->prefixlen); + continue; + } + + if (area->external_routing != OSPF_AREA_DEFAULT + && area->no_summary) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_abr_announce_network(): " + "area %s is stub and no_summary", + inet_ntoa(area->area_id)); + continue; + } + + if (or->path_type == OSPF_PATH_INTER_AREA) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_abr_announce_network(): this is " + "inter-area route to %s/%d", + inet_ntoa(p->prefix), p->prefixlen); - if (!ospf_abr_plist_in_check (area, or, p)) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_announce_network(): " - "prefix %s/%d was denied by prefix-list", - inet_ntoa (p->prefix), p->prefixlen); - continue; + if (!OSPF_IS_AREA_BACKBONE(area)) + ospf_abr_announce_network_to_area(p, or->cost, + area); + } + + if (or->path_type == OSPF_PATH_INTRA_AREA) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_abr_announce_network(): " + "this is intra-area route to %s/%d", + inet_ntoa(p->prefix), p->prefixlen); + if ((range = ospf_area_range_match(or_area, p)) + && !ospf_area_is_transit(area)) + ospf_abr_update_aggregate(range, or, area); + else + ospf_abr_announce_network_to_area(p, or->cost, + area); + } } +} - if (area->external_routing != OSPF_AREA_DEFAULT && area->no_summary) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_announce_network(): " - "area %s is stub and no_summary", - inet_ntoa (area->area_id)); - continue; +static int ospf_abr_should_announce(struct ospf *ospf, struct prefix_ipv4 *p, + struct ospf_route * or) +{ + struct ospf_area *area; + + area = ospf_area_lookup_by_area_id(ospf, or->u.std.area_id); + + assert(area); + + if (EXPORT_NAME(area)) { + if (EXPORT_LIST(area) == NULL) + EXPORT_LIST(area) = + access_list_lookup(AFI_IP, EXPORT_NAME(area)); + + if (EXPORT_LIST(area)) + if (access_list_apply(EXPORT_LIST(area), p) + == FILTER_DENY) + return 0; } - if (or->path_type == OSPF_PATH_INTER_AREA) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_announce_network(): this is " - "inter-area route to %s/%d", - inet_ntoa (p->prefix), p->prefixlen); + return 1; +} - if (!OSPF_IS_AREA_BACKBONE (area)) - ospf_abr_announce_network_to_area (p, or->cost, area); +static void ospf_abr_process_nssa_translates(struct ospf *ospf) +{ + /* Scan through all NSSA_LSDB records for all areas; + + If P-bit is on, translate all Type-7's to 5's and aggregate or + flood install as approved in Type-5 LSDB with XLATE Flag on + later, do same for all aggregates... At end, DISCARD all + remaining UNAPPROVED Type-5's (Aggregate is for future ) */ + struct listnode *node; + struct ospf_area *area; + struct route_node *rn; + struct ospf_lsa *lsa; + + if (IS_DEBUG_OSPF_NSSA) + zlog_debug("ospf_abr_process_nssa_translates(): Start"); + + for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) { + if (!area->NSSATranslatorState) + continue; /* skip if not translator */ + + if (area->external_routing != OSPF_AREA_NSSA) + continue; /* skip if not Nssa Area */ + + if (IS_DEBUG_OSPF_NSSA) + zlog_debug( + "ospf_abr_process_nssa_translates(): " + "looking at area %s", + inet_ntoa(area->area_id)); + + LSDB_LOOP(NSSA_LSDB(area), rn, lsa) + ospf_abr_translate_nssa(area, lsa); } - if (or->path_type == OSPF_PATH_INTRA_AREA) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_announce_network(): " - "this is intra-area route to %s/%d", - inet_ntoa (p->prefix), p->prefixlen); - if ((range = ospf_area_range_match (or_area, p)) - && !ospf_area_is_transit (area)) - ospf_abr_update_aggregate (range, or, area); - else - ospf_abr_announce_network_to_area (p, or->cost, area); - } - } + if (IS_DEBUG_OSPF_NSSA) + zlog_debug("ospf_abr_process_nssa_translates(): Stop"); } -static int -ospf_abr_should_announce (struct ospf *ospf, - struct prefix_ipv4 *p, struct ospf_route *or) +static void ospf_abr_process_network_rt(struct ospf *ospf, + struct route_table *rt) { - struct ospf_area *area; + struct ospf_area *area; + struct ospf_route * or ; + struct route_node *rn; - area = ospf_area_lookup_by_area_id (ospf, or->u.std.area_id); + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("ospf_abr_process_network_rt(): Start"); - assert (area); - - if (EXPORT_NAME (area)) - { - if (EXPORT_LIST (area) == NULL) - EXPORT_LIST (area) = access_list_lookup (AFI_IP, EXPORT_NAME (area)); + for (rn = route_top(rt); rn; rn = route_next(rn)) { + if ((or = rn->info) == NULL) + continue; - if (EXPORT_LIST (area)) - if (access_list_apply (EXPORT_LIST (area), p) == FILTER_DENY) - return 0; - } + if (!(area = ospf_area_lookup_by_area_id(ospf, + or->u.std.area_id))) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_abr_process_network_rt(): area %s no longer exists", + inet_ntoa(or->u.std.area_id)); + continue; + } - return 1; -} + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_abr_process_network_rt(): this is a route to %s/%d", + inet_ntoa(rn->p.u.prefix4), rn->p.prefixlen); + if (or->path_type >= OSPF_PATH_TYPE1_EXTERNAL) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_abr_process_network_rt(): " + "this is an External router, skipping"); + continue; + } -static void -ospf_abr_process_nssa_translates (struct ospf *ospf) -{ - /* Scan through all NSSA_LSDB records for all areas; - - If P-bit is on, translate all Type-7's to 5's and aggregate or - flood install as approved in Type-5 LSDB with XLATE Flag on - later, do same for all aggregates... At end, DISCARD all - remaining UNAPPROVED Type-5's (Aggregate is for future ) */ - struct listnode *node; - struct ospf_area *area; - struct route_node *rn; - struct ospf_lsa *lsa; - - if (IS_DEBUG_OSPF_NSSA) - zlog_debug ("ospf_abr_process_nssa_translates(): Start"); - - for (ALL_LIST_ELEMENTS_RO (ospf->areas, node, area)) - { - if (! area->NSSATranslatorState) - continue; /* skip if not translator */ - - if (area->external_routing != OSPF_AREA_NSSA) - continue; /* skip if not Nssa Area */ - - if (IS_DEBUG_OSPF_NSSA) - zlog_debug ("ospf_abr_process_nssa_translates(): " - "looking at area %s", inet_ntoa (area->area_id)); - - LSDB_LOOP (NSSA_LSDB (area), rn, lsa) - ospf_abr_translate_nssa (area, lsa); - } - - if (IS_DEBUG_OSPF_NSSA) - zlog_debug ("ospf_abr_process_nssa_translates(): Stop"); + if (or->cost >= OSPF_LS_INFINITY) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_abr_process_network_rt():" + " this route's cost is infinity, skipping"); + continue; + } -} + if (or->type == OSPF_DESTINATION_DISCARD) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_abr_process_network_rt():" + " this is a discard entry, skipping"); + continue; + } + + if ( + or->path_type == OSPF_PATH_INTRA_AREA + && !ospf_abr_should_announce( + ospf, (struct prefix_ipv4 *)&rn->p, + or)) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_abr_process_network_rt(): denied by export-list"); + continue; + } + + if ( + or->path_type == OSPF_PATH_INTRA_AREA + && !ospf_abr_plist_out_check( + area, or, + (struct prefix_ipv4 *)&rn->p)) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_abr_process_network_rt(): denied by prefix-list"); + continue; + } -static void -ospf_abr_process_network_rt (struct ospf *ospf, - struct route_table *rt) -{ - struct ospf_area *area; - struct ospf_route *or; - struct route_node *rn; + if ((or->path_type == OSPF_PATH_INTER_AREA) + && !OSPF_IS_AREA_ID_BACKBONE(or->u.std.area_id)) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_abr_process_network_rt():" + " this is route is not backbone one, skipping"); + continue; + } - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_process_network_rt(): Start"); - for (rn = route_top (rt); rn; rn = route_next (rn)) - { - if ((or = rn->info) == NULL) - continue; + if ((ospf->abr_type == OSPF_ABR_CISCO) + || (ospf->abr_type == OSPF_ABR_IBM)) - if (!(area = ospf_area_lookup_by_area_id (ospf, or->u.std.area_id))) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_process_network_rt(): area %s no longer exists", - inet_ntoa (or->u.std.area_id)); - continue; - } + if (!ospf_act_bb_connection(ospf) && + or->path_type != OSPF_PATH_INTRA_AREA) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_abr_process_network_rt(): ALT ABR: " + "No BB connection, skip not intra-area routes"); + continue; + } - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_process_network_rt(): this is a route to %s/%d", - inet_ntoa (rn->p.u.prefix4), rn->p.prefixlen); - if (or->path_type >= OSPF_PATH_TYPE1_EXTERNAL) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_process_network_rt(): " - "this is an External router, skipping"); - continue; + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("ospf_abr_process_network_rt(): announcing"); + ospf_abr_announce_network(ospf, (struct prefix_ipv4 *)&rn->p, + or); } - if (or->cost >= OSPF_LS_INFINITY) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_process_network_rt():" - " this route's cost is infinity, skipping"); - continue; - } + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("ospf_abr_process_network_rt(): Stop"); +} - if (or->type == OSPF_DESTINATION_DISCARD) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_process_network_rt():" - " this is a discard entry, skipping"); - continue; - } +static void ospf_abr_announce_rtr_to_area(struct prefix_ipv4 *p, u_int32_t cost, + struct ospf_area *area) +{ + struct ospf_lsa *lsa, *old = NULL; + struct summary_lsa *slsa = NULL; - if (or->path_type == OSPF_PATH_INTRA_AREA && - !ospf_abr_should_announce (ospf, (struct prefix_ipv4 *) &rn->p, or)) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug("ospf_abr_process_network_rt(): denied by export-list"); - continue; - } + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("ospf_abr_announce_rtr_to_area(): Start"); - if (or->path_type == OSPF_PATH_INTRA_AREA && - !ospf_abr_plist_out_check (area, or, (struct prefix_ipv4 *) &rn->p)) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug("ospf_abr_process_network_rt(): denied by prefix-list"); - continue; - } + old = ospf_lsa_lookup_by_prefix(area->lsdb, OSPF_ASBR_SUMMARY_LSA, p, + area->ospf->router_id); + if (old) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_abr_announce_rtr_to_area(): old summary found"); + slsa = (struct summary_lsa *)old->data; - if ((or->path_type == OSPF_PATH_INTER_AREA) && - !OSPF_IS_AREA_ID_BACKBONE (or->u.std.area_id)) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_process_network_rt():" - " this is route is not backbone one, skipping"); - continue; + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_abr_announce_network_to_area(): " + "old metric: %d, new metric: %d", + GET_METRIC(slsa->metric), cost); } + if (old && (GET_METRIC(slsa->metric) == cost) + && ((old->flags & OSPF_LSA_IN_MAXAGE) == 0)) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_abr_announce_rtr_to_area(): old summary approved"); + SET_FLAG(old->flags, OSPF_LSA_APPROVED); + } else { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("ospf_abr_announce_rtr_to_area(): 2.2"); + + if (old) { + set_metric(old, cost); + lsa = ospf_lsa_refresh(area->ospf, old); + } else + lsa = ospf_summary_asbr_lsa_originate(p, cost, area); + if (!lsa) { + char buf[PREFIX2STR_BUFFER]; + + prefix2str((struct prefix *)p, buf, sizeof(buf)); + zlog_warn("%s: Could not refresh/originate %s to %s", + __func__, buf, inet_ntoa(area->area_id)); + return; + } - if ((ospf->abr_type == OSPF_ABR_CISCO) || - (ospf->abr_type == OSPF_ABR_IBM)) + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_abr_announce_rtr_to_area(): " + "flooding new version of summary"); - if (!ospf_act_bb_connection (ospf) && - or->path_type != OSPF_PATH_INTRA_AREA) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_process_network_rt(): ALT ABR: " - "No BB connection, skip not intra-area routes"); - continue; - } + /* + zlog_info ("ospf_abr_announce_rtr_to_area(): creating new + summary"); + lsa = ospf_summary_asbr_lsa (p, cost, area, old); */ - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_process_network_rt(): announcing"); - ospf_abr_announce_network (ospf, (struct prefix_ipv4 *)&rn->p, or); - } + SET_FLAG(lsa->flags, OSPF_LSA_APPROVED); + /* ospf_flood_through_area (area, NULL, lsa);*/ + } - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_process_network_rt(): Stop"); + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("ospf_abr_announce_rtr_to_area(): Stop"); } -static void -ospf_abr_announce_rtr_to_area (struct prefix_ipv4 *p, u_int32_t cost, - struct ospf_area *area) + +static void ospf_abr_announce_rtr(struct ospf *ospf, struct prefix_ipv4 *p, + struct ospf_route * or) { - struct ospf_lsa *lsa, *old = NULL; - struct summary_lsa *slsa = NULL; - - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_announce_rtr_to_area(): Start"); - - old = ospf_lsa_lookup_by_prefix (area->lsdb, OSPF_ASBR_SUMMARY_LSA, - p, area->ospf->router_id); - if (old) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_announce_rtr_to_area(): old summary found"); - slsa = (struct summary_lsa *) old->data; - - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_announce_network_to_area(): " - "old metric: %d, new metric: %d", - GET_METRIC (slsa->metric), cost); - } - - if (old && (GET_METRIC (slsa->metric) == cost) && - ((old->flags & OSPF_LSA_IN_MAXAGE) == 0)) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_announce_rtr_to_area(): old summary approved"); - SET_FLAG (old->flags, OSPF_LSA_APPROVED); - } - else - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_announce_rtr_to_area(): 2.2"); - - if (old) - { - set_metric (old, cost); - lsa = ospf_lsa_refresh (area->ospf, old); + struct listnode *node; + struct ospf_area *area; + + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("ospf_abr_announce_rtr(): Start"); + + for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_abr_announce_rtr(): looking at area %s", + inet_ntoa(area->area_id)); + + if (IPV4_ADDR_SAME(& or->u.std.area_id, &area->area_id)) + continue; + + if (ospf_abr_nexthops_belong_to_area(or, area)) + continue; + + if (area->external_routing != OSPF_AREA_DEFAULT) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_abr_announce_rtr(): " + "area %s doesn't support external routing", + inet_ntoa(area->area_id)); + continue; + } + + if (or->path_type == OSPF_PATH_INTER_AREA) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_abr_announce_rtr(): " + "this is inter-area route to %s", + inet_ntoa(p->prefix)); + if (!OSPF_IS_AREA_BACKBONE(area)) + ospf_abr_announce_rtr_to_area(p, or->cost, + area); + } + + if (or->path_type == OSPF_PATH_INTRA_AREA) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_abr_announce_rtr(): " + "this is intra-area route to %s", + inet_ntoa(p->prefix)); + ospf_abr_announce_rtr_to_area(p, or->cost, area); + } } - else - lsa = ospf_summary_asbr_lsa_originate (p, cost, area); - if (!lsa) - { - char buf[PREFIX2STR_BUFFER]; - - prefix2str ((struct prefix *)p, buf, sizeof(buf)); - zlog_warn ("%s: Could not refresh/originate %s to %s", - __func__, - buf, - inet_ntoa (area->area_id)); - return; - } - - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_announce_rtr_to_area(): " - "flooding new version of summary"); - - /* - zlog_info ("ospf_abr_announce_rtr_to_area(): creating new summary"); - lsa = ospf_summary_asbr_lsa (p, cost, area, old); */ - - SET_FLAG (lsa->flags, OSPF_LSA_APPROVED); - /* ospf_flood_through_area (area, NULL, lsa);*/ - } - - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_announce_rtr_to_area(): Stop"); -} + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("ospf_abr_announce_rtr(): Stop"); +} -static void -ospf_abr_announce_rtr (struct ospf *ospf, - struct prefix_ipv4 *p, struct ospf_route *or) +static void ospf_abr_process_router_rt(struct ospf *ospf, + struct route_table *rt) { - struct listnode *node; - struct ospf_area *area; + struct ospf_route * or ; + struct route_node *rn; + struct list *l; - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_announce_rtr(): Start"); + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("ospf_abr_process_router_rt(): Start"); - for (ALL_LIST_ELEMENTS_RO (ospf->areas, node, area)) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_announce_rtr(): looking at area %s", - inet_ntoa (area->area_id)); + for (rn = route_top(rt); rn; rn = route_next(rn)) { + struct listnode *node, *nnode; + char flag = 0; + struct ospf_route *best = NULL; - if (IPV4_ADDR_SAME (&or->u.std.area_id, &area->area_id)) - continue; + if (rn->info == NULL) + continue; - if (ospf_abr_nexthops_belong_to_area (or, area)) - continue; + l = rn->info; - if (area->external_routing != OSPF_AREA_DEFAULT) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_announce_rtr(): " - "area %s doesn't support external routing", - inet_ntoa(area->area_id)); - continue; + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_abr_process_router_rt(): this is a route to %s", + inet_ntoa(rn->p.u.prefix4)); + + for (ALL_LIST_ELEMENTS(l, node, nnode, or)) { + if (!ospf_area_lookup_by_area_id(ospf, + or->u.std.area_id)) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_abr_process_router_rt(): area %s no longer exists", + inet_ntoa(or->u.std.area_id)); + continue; + } + + + if (!CHECK_FLAG(or->u.std.flags, ROUTER_LSA_EXTERNAL)) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_abr_process_router_rt(): " + "This is not an ASBR, skipping"); + continue; + } + + if (!flag) { + best = ospf_find_asbr_route( + ospf, rt, (struct prefix_ipv4 *)&rn->p); + flag = 1; + } + + if (best == NULL) + continue; + + if (or != best) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_abr_process_router_rt(): " + "This route is not the best among possible, skipping"); + continue; + } + + if ( + or->path_type == OSPF_PATH_INTER_AREA + && !OSPF_IS_AREA_ID_BACKBONE( + or->u.std.area_id)) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_abr_process_router_rt(): " + "This route is not a backbone one, skipping"); + continue; + } + + if (or->cost >= OSPF_LS_INFINITY) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_abr_process_router_rt(): " + "This route has LS_INFINITY metric, skipping"); + continue; + } + + if (ospf->abr_type == OSPF_ABR_CISCO + || ospf->abr_type == OSPF_ABR_IBM) + if (!ospf_act_bb_connection(ospf) && + or->path_type != OSPF_PATH_INTRA_AREA) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_abr_process_network_rt(): ALT ABR: " + "No BB connection, skip not intra-area routes"); + continue; + } + + ospf_abr_announce_rtr(ospf, + (struct prefix_ipv4 *)&rn->p, or); + } } - if (or->path_type == OSPF_PATH_INTER_AREA) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_announce_rtr(): " - "this is inter-area route to %s", inet_ntoa (p->prefix)); - if (!OSPF_IS_AREA_BACKBONE (area)) - ospf_abr_announce_rtr_to_area (p, or->cost, area); - } + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("ospf_abr_process_router_rt(): Stop"); +} - if (or->path_type == OSPF_PATH_INTRA_AREA) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_announce_rtr(): " - "this is intra-area route to %s", inet_ntoa (p->prefix)); - ospf_abr_announce_rtr_to_area (p, or->cost, area); +static void +ospf_abr_unapprove_translates(struct ospf *ospf) /* For NSSA Translations */ +{ + struct ospf_lsa *lsa; + struct route_node *rn; + + if (IS_DEBUG_OSPF_NSSA) + zlog_debug("ospf_abr_unapprove_translates(): Start"); + + /* NSSA Translator is not checked, because it may have gone away, + and we would want to flush any residuals anyway */ + + LSDB_LOOP(EXTERNAL_LSDB(ospf), rn, lsa) + if (CHECK_FLAG(lsa->flags, OSPF_LSA_LOCAL_XLT)) { + UNSET_FLAG(lsa->flags, OSPF_LSA_APPROVED); + if (IS_DEBUG_OSPF_NSSA) + zlog_debug( + "ospf_abr_unapprove_translates(): " + "approved unset on link id %s", + inet_ntoa(lsa->data->id)); } - } - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_announce_rtr(): Stop"); + if (IS_DEBUG_OSPF_NSSA) + zlog_debug("ospf_abr_unapprove_translates(): Stop"); } -static void -ospf_abr_process_router_rt (struct ospf *ospf, struct route_table *rt) +static void ospf_abr_unapprove_summaries(struct ospf *ospf) { - struct ospf_route *or; - struct route_node *rn; - struct list *l; + struct listnode *node; + struct ospf_area *area; + struct route_node *rn; + struct ospf_lsa *lsa; - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_process_router_rt(): Start"); + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("ospf_abr_unapprove_summaries(): Start"); - for (rn = route_top (rt); rn; rn = route_next (rn)) - { - struct listnode *node, *nnode; - char flag = 0; - struct ospf_route *best = NULL; + for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_abr_unapprove_summaries(): " + "considering area %s", + inet_ntoa(area->area_id)); + LSDB_LOOP(SUMMARY_LSDB(area), rn, lsa) + if (ospf_lsa_is_self_originated(ospf, lsa)) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_abr_unapprove_summaries(): " + "approved unset on summary link id %s", + inet_ntoa(lsa->data->id)); + UNSET_FLAG(lsa->flags, OSPF_LSA_APPROVED); + } + + LSDB_LOOP(ASBR_SUMMARY_LSDB(area), rn, lsa) + if (ospf_lsa_is_self_originated(ospf, lsa)) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_abr_unapprove_summaries(): " + "approved unset on asbr-summary link id %s", + inet_ntoa(lsa->data->id)); + UNSET_FLAG(lsa->flags, OSPF_LSA_APPROVED); + } + } - if (rn->info == NULL) - continue; + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("ospf_abr_unapprove_summaries(): Stop"); +} - l = rn->info; +static void ospf_abr_prepare_aggregates(struct ospf *ospf) +{ + struct listnode *node; + struct route_node *rn; + struct ospf_area_range *range; + struct ospf_area *area; + + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("ospf_abr_prepare_aggregates(): Start"); + + for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) { + for (rn = route_top(area->ranges); rn; rn = route_next(rn)) + if ((range = rn->info) != NULL) { + range->cost = 0; + range->specifics = 0; + } + } - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_process_router_rt(): this is a route to %s", - inet_ntoa (rn->p.u.prefix4)); + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("ospf_abr_prepare_aggregates(): Stop"); +} - for (ALL_LIST_ELEMENTS (l, node, nnode, or)) - { - if (!ospf_area_lookup_by_area_id (ospf, or->u.std.area_id)) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_process_router_rt(): area %s no longer exists", - inet_ntoa (or->u.std.area_id)); - continue; - } - - - if (!CHECK_FLAG (or->u.std.flags, ROUTER_LSA_EXTERNAL)) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_process_router_rt(): " - "This is not an ASBR, skipping"); - continue; - } - - if (!flag) - { - best = ospf_find_asbr_route (ospf, rt, - (struct prefix_ipv4 *) &rn->p); - flag = 1; - } - - if (best == NULL) - continue; - - if (or != best) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_process_router_rt(): " - "This route is not the best among possible, skipping"); - continue; - } - - if (or->path_type == OSPF_PATH_INTER_AREA && - !OSPF_IS_AREA_ID_BACKBONE (or->u.std.area_id)) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_process_router_rt(): " - "This route is not a backbone one, skipping"); - continue; - } - - if (or->cost >= OSPF_LS_INFINITY) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_process_router_rt(): " - "This route has LS_INFINITY metric, skipping"); - continue; - } - - if (ospf->abr_type == OSPF_ABR_CISCO - || ospf->abr_type == OSPF_ABR_IBM) - if (!ospf_act_bb_connection (ospf) - && or->path_type != OSPF_PATH_INTRA_AREA) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug("ospf_abr_process_network_rt(): ALT ABR: " - "No BB connection, skip not intra-area routes"); - continue; - } - - ospf_abr_announce_rtr (ospf, (struct prefix_ipv4 *) &rn->p, or); +static void ospf_abr_announce_aggregates(struct ospf *ospf) +{ + struct ospf_area *area, *ar; + struct ospf_area_range *range; + struct route_node *rn; + struct prefix p; + struct listnode *node, *n; - } + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("ospf_abr_announce_aggregates(): Start"); - } + for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_abr_announce_aggregates(): looking at area %s", + inet_ntoa(area->area_id)); + + for (rn = route_top(area->ranges); rn; rn = route_next(rn)) + if ((range = rn->info)) { + if (!CHECK_FLAG(range->flags, + OSPF_AREA_RANGE_ADVERTISE)) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_abr_announce_aggregates():" + " discarding suppress-ranges"); + continue; + } + + p.family = AF_INET; + p.u.prefix4 = range->addr; + p.prefixlen = range->masklen; + + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_abr_announce_aggregates():" + " this is range: %s/%d", + inet_ntoa(p.u.prefix4), + p.prefixlen); + + if (CHECK_FLAG(range->flags, + OSPF_AREA_RANGE_SUBSTITUTE)) { + p.family = AF_INET; + p.u.prefix4 = range->subst_addr; + p.prefixlen = range->subst_masklen; + } + + if (range->specifics) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_abr_announce_aggregates(): active range"); + + for (ALL_LIST_ELEMENTS_RO(ospf->areas, + n, ar)) { + if (ar == area) + continue; + + /* We do not check nexthops + here, because + intra-area routes can be + associated with + one area only */ + + /* backbone routes are not + summarized + when announced into transit + areas */ + + if (ospf_area_is_transit(ar) + && OSPF_IS_AREA_BACKBONE( + area)) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_abr_announce_aggregates(): Skipping " + "announcement of BB aggregate into" + " a transit area"); + continue; + } + ospf_abr_announce_network_to_area( + (struct prefix_ipv4 + *)&p, + range->cost, ar); + } + } + } + } - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_process_router_rt(): Stop"); + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("ospf_abr_announce_aggregates(): Stop"); } static void -ospf_abr_unapprove_translates (struct ospf *ospf) /* For NSSA Translations */ +ospf_abr_send_nssa_aggregates(struct ospf *ospf) /* temporarily turned off */ { - struct ospf_lsa *lsa; - struct route_node *rn; - - if (IS_DEBUG_OSPF_NSSA) - zlog_debug ("ospf_abr_unapprove_translates(): Start"); - - /* NSSA Translator is not checked, because it may have gone away, - and we would want to flush any residuals anyway */ - - LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa) - if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT)) - { - UNSET_FLAG (lsa->flags, OSPF_LSA_APPROVED); - if (IS_DEBUG_OSPF_NSSA) - zlog_debug ("ospf_abr_unapprove_translates(): " - "approved unset on link id %s", - inet_ntoa (lsa->data->id)); - } - - if (IS_DEBUG_OSPF_NSSA) - zlog_debug ("ospf_abr_unapprove_translates(): Stop"); + struct listnode *node; /*, n; */ + struct ospf_area *area; /*, *ar; */ + struct route_node *rn; + struct ospf_area_range *range; + struct prefix_ipv4 p; + + if (IS_DEBUG_OSPF_NSSA) + zlog_debug("ospf_abr_send_nssa_aggregates(): Start"); + + for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) { + if (!area->NSSATranslatorState) + continue; + + if (IS_DEBUG_OSPF_NSSA) + zlog_debug( + "ospf_abr_send_nssa_aggregates(): looking at area %s", + inet_ntoa(area->area_id)); + + for (rn = route_top(area->ranges); rn; rn = route_next(rn)) { + if (rn->info == NULL) + continue; + + range = rn->info; + + if (!CHECK_FLAG(range->flags, + OSPF_AREA_RANGE_ADVERTISE)) { + if (IS_DEBUG_OSPF_NSSA) + zlog_debug( + "ospf_abr_send_nssa_aggregates():" + " discarding suppress-ranges"); + continue; + } + + p.family = AF_INET; + p.prefix = range->addr; + p.prefixlen = range->masklen; + + if (IS_DEBUG_OSPF_NSSA) + zlog_debug( + "ospf_abr_send_nssa_aggregates():" + " this is range: %s/%d", + inet_ntoa(p.prefix), p.prefixlen); + + if (CHECK_FLAG(range->flags, + OSPF_AREA_RANGE_SUBSTITUTE)) { + p.family = AF_INET; + p.prefix = range->subst_addr; + p.prefixlen = range->subst_masklen; + } + + if (range->specifics) { + if (IS_DEBUG_OSPF_NSSA) + zlog_debug( + "ospf_abr_send_nssa_aggregates(): active range"); + + /* Fetch LSA-Type-7 from aggregate prefix, and + * then + * translate, Install (as Type-5), Approve, and + * Flood + */ + ospf_abr_translate_nssa_range(&p, range->cost); + } + } /* all area ranges*/ + } /* all areas */ + + if (IS_DEBUG_OSPF_NSSA) + zlog_debug("ospf_abr_send_nssa_aggregates(): Stop"); } -static void -ospf_abr_unapprove_summaries (struct ospf *ospf) +static void ospf_abr_announce_stub_defaults(struct ospf *ospf) { - struct listnode *node; - struct ospf_area *area; - struct route_node *rn; - struct ospf_lsa *lsa; - - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_unapprove_summaries(): Start"); - - for (ALL_LIST_ELEMENTS_RO (ospf->areas, node, area)) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_unapprove_summaries(): " - "considering area %s", - inet_ntoa (area->area_id)); - LSDB_LOOP (SUMMARY_LSDB (area), rn, lsa) - if (ospf_lsa_is_self_originated (ospf, lsa)) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_unapprove_summaries(): " - "approved unset on summary link id %s", - inet_ntoa (lsa->data->id)); - UNSET_FLAG (lsa->flags, OSPF_LSA_APPROVED); - } - - LSDB_LOOP (ASBR_SUMMARY_LSDB (area), rn, lsa) - if (ospf_lsa_is_self_originated (ospf, lsa)) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_unapprove_summaries(): " - "approved unset on asbr-summary link id %s", - inet_ntoa (lsa->data->id)); - UNSET_FLAG (lsa->flags, OSPF_LSA_APPROVED); - } - } - - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_unapprove_summaries(): Stop"); -} + struct listnode *node; + struct ospf_area *area; + struct prefix_ipv4 p; -static void -ospf_abr_prepare_aggregates (struct ospf *ospf) -{ - struct listnode *node; - struct route_node *rn; - struct ospf_area_range *range; - struct ospf_area *area; - - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_prepare_aggregates(): Start"); - - for (ALL_LIST_ELEMENTS_RO (ospf->areas, node, area)) - { - for (rn = route_top (area->ranges); rn; rn = route_next (rn)) - if ((range = rn->info) != NULL) - { - range->cost = 0; - range->specifics = 0; - } - } - - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_prepare_aggregates(): Stop"); -} + if (!IS_OSPF_ABR(ospf)) + return; -static void -ospf_abr_announce_aggregates (struct ospf *ospf) -{ - struct ospf_area *area, *ar; - struct ospf_area_range *range; - struct route_node *rn; - struct prefix p; - struct listnode *node, *n; - - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_announce_aggregates(): Start"); - - for (ALL_LIST_ELEMENTS_RO (ospf->areas, node, area)) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_announce_aggregates(): looking at area %s", - inet_ntoa (area->area_id)); - - for (rn = route_top (area->ranges); rn; rn = route_next (rn)) - if ((range = rn->info)) - { - if (!CHECK_FLAG (range->flags, OSPF_AREA_RANGE_ADVERTISE)) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_announce_aggregates():" - " discarding suppress-ranges"); - continue; - } - - p.family = AF_INET; - p.u.prefix4 = range->addr; - p.prefixlen = range->masklen; - - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_announce_aggregates():" - " this is range: %s/%d", - inet_ntoa (p.u.prefix4), p.prefixlen); - - if (CHECK_FLAG (range->flags, OSPF_AREA_RANGE_SUBSTITUTE)) - { - p.family = AF_INET; - p.u.prefix4 = range->subst_addr; - p.prefixlen = range->subst_masklen; - } - - if (range->specifics) - { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("ospf_abr_announce_stub_defaults(): Start"); + + p.family = AF_INET; + p.prefix.s_addr = OSPF_DEFAULT_DESTINATION; + p.prefixlen = 0; + + for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) { if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_announce_aggregates(): active range"); + zlog_debug( + "ospf_abr_announce_stub_defaults(): looking at area %s", + inet_ntoa(area->area_id)); - for (ALL_LIST_ELEMENTS_RO (ospf->areas, n, ar)) - { - if (ar == area) - continue; + if ((area->external_routing != OSPF_AREA_STUB) + && (area->external_routing != OSPF_AREA_NSSA)) + continue; - /* We do not check nexthops here, because - intra-area routes can be associated with - one area only */ + if (OSPF_IS_AREA_BACKBONE(area)) + continue; /* Sanity Check */ - /* backbone routes are not summarized - when announced into transit areas */ + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_abr_announce_stub_defaults(): " + "announcing 0.0.0.0/0 to area %s", + inet_ntoa(area->area_id)); + ospf_abr_announce_network_to_area(&p, area->default_cost, area); + } - if (ospf_area_is_transit (ar) && - OSPF_IS_AREA_BACKBONE (area)) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_announce_aggregates(): Skipping " - "announcement of BB aggregate into" - " a transit area"); - continue; - } - ospf_abr_announce_network_to_area ((struct prefix_ipv4 *)&p, range->cost, ar); - } - } - } - } - - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_announce_aggregates(): Stop"); + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("ospf_abr_announce_stub_defaults(): Stop"); } -static void -ospf_abr_send_nssa_aggregates (struct ospf *ospf) /* temporarily turned off */ +static int ospf_abr_remove_unapproved_translates_apply(struct ospf *ospf, + struct ospf_lsa *lsa) { - struct listnode *node; /*, n; */ - struct ospf_area *area; /*, *ar; */ - struct route_node *rn; - struct ospf_area_range *range; - struct prefix_ipv4 p; + if (CHECK_FLAG(lsa->flags, OSPF_LSA_LOCAL_XLT) + && !CHECK_FLAG(lsa->flags, OSPF_LSA_APPROVED)) { + zlog_info( + "ospf_abr_remove_unapproved_translates(): " + "removing unapproved translates, ID: %s", + inet_ntoa(lsa->data->id)); - if (IS_DEBUG_OSPF_NSSA) - zlog_debug ("ospf_abr_send_nssa_aggregates(): Start"); + /* FLUSH THROUGHOUT AS */ + ospf_lsa_flush_as(ospf, lsa); - for (ALL_LIST_ELEMENTS_RO (ospf->areas, node, area)) - { - if (! area->NSSATranslatorState) - continue; - - if (IS_DEBUG_OSPF_NSSA) - zlog_debug ("ospf_abr_send_nssa_aggregates(): looking at area %s", - inet_ntoa (area->area_id)); - - for (rn = route_top (area->ranges); rn; rn = route_next (rn)) - { - if (rn->info == NULL) - continue; - - range = rn->info; - - if (!CHECK_FLAG (range->flags, OSPF_AREA_RANGE_ADVERTISE)) - { - if (IS_DEBUG_OSPF_NSSA) - zlog_debug ("ospf_abr_send_nssa_aggregates():" - " discarding suppress-ranges"); - continue; - } - - p.family = AF_INET; - p.prefix = range->addr; - p.prefixlen = range->masklen; - - if (IS_DEBUG_OSPF_NSSA) - zlog_debug ("ospf_abr_send_nssa_aggregates():" - " this is range: %s/%d", - inet_ntoa (p.prefix), p.prefixlen); - - if (CHECK_FLAG (range->flags, OSPF_AREA_RANGE_SUBSTITUTE)) - { - p.family = AF_INET; - p.prefix = range->subst_addr; - p.prefixlen = range->subst_masklen; - } - - if (range->specifics) - { - if (IS_DEBUG_OSPF_NSSA) - zlog_debug ("ospf_abr_send_nssa_aggregates(): active range"); - - /* Fetch LSA-Type-7 from aggregate prefix, and then - * translate, Install (as Type-5), Approve, and Flood - */ - ospf_abr_translate_nssa_range (&p, range->cost); - } - } /* all area ranges*/ - } /* all areas */ - - if (IS_DEBUG_OSPF_NSSA) - zlog_debug ("ospf_abr_send_nssa_aggregates(): Stop"); + /* DISCARD from LSDB */ + } + return 0; } -static void -ospf_abr_announce_stub_defaults (struct ospf *ospf) +static void ospf_abr_remove_unapproved_translates(struct ospf *ospf) { - struct listnode *node; - struct ospf_area *area; - struct prefix_ipv4 p; - - if (! IS_OSPF_ABR (ospf)) - return; - - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_announce_stub_defaults(): Start"); - - p.family = AF_INET; - p.prefix.s_addr = OSPF_DEFAULT_DESTINATION; - p.prefixlen = 0; - - for (ALL_LIST_ELEMENTS_RO (ospf->areas, node, area)) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_announce_stub_defaults(): looking at area %s", - inet_ntoa (area->area_id)); - - if ( (area->external_routing != OSPF_AREA_STUB) - && (area->external_routing != OSPF_AREA_NSSA) - ) - continue; - - if (OSPF_IS_AREA_BACKBONE (area)) - continue; /* Sanity Check */ - - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_announce_stub_defaults(): " - "announcing 0.0.0.0/0 to area %s", - inet_ntoa (area->area_id)); - ospf_abr_announce_network_to_area (&p, area->default_cost, area); - } - - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_announce_stub_defaults(): Stop"); -} + struct route_node *rn; + struct ospf_lsa *lsa; -static int -ospf_abr_remove_unapproved_translates_apply (struct ospf *ospf, - struct ospf_lsa *lsa) -{ - if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT) - && ! CHECK_FLAG (lsa->flags, OSPF_LSA_APPROVED)) - { - zlog_info ("ospf_abr_remove_unapproved_translates(): " - "removing unapproved translates, ID: %s", - inet_ntoa (lsa->data->id)); - - /* FLUSH THROUGHOUT AS */ - ospf_lsa_flush_as (ospf, lsa); - - /* DISCARD from LSDB */ - } - return 0; -} + /* All AREA PROCESS should have APPROVED necessary LSAs */ + /* Remove any left over and not APPROVED */ + if (IS_DEBUG_OSPF_NSSA) + zlog_debug("ospf_abr_remove_unapproved_translates(): Start"); -static void -ospf_abr_remove_unapproved_translates (struct ospf *ospf) -{ - struct route_node *rn; - struct ospf_lsa *lsa; - - /* All AREA PROCESS should have APPROVED necessary LSAs */ - /* Remove any left over and not APPROVED */ - if (IS_DEBUG_OSPF_NSSA) - zlog_debug ("ospf_abr_remove_unapproved_translates(): Start"); - - LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa) - ospf_abr_remove_unapproved_translates_apply (ospf, lsa); - - if (IS_DEBUG_OSPF_NSSA) - zlog_debug ("ospf_abr_remove_unapproved_translates(): Stop"); + LSDB_LOOP(EXTERNAL_LSDB(ospf), rn, lsa) + ospf_abr_remove_unapproved_translates_apply(ospf, lsa); + + if (IS_DEBUG_OSPF_NSSA) + zlog_debug("ospf_abr_remove_unapproved_translates(): Stop"); } -static void -ospf_abr_remove_unapproved_summaries (struct ospf *ospf) +static void ospf_abr_remove_unapproved_summaries(struct ospf *ospf) { - struct listnode *node; - struct ospf_area *area; - struct route_node *rn; - struct ospf_lsa *lsa; - - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_remove_unapproved_summaries(): Start"); - - for (ALL_LIST_ELEMENTS_RO (ospf->areas, node, area)) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_remove_unapproved_summaries(): " - "looking at area %s", inet_ntoa (area->area_id)); - - LSDB_LOOP (SUMMARY_LSDB (area), rn, lsa) - if (ospf_lsa_is_self_originated (ospf, lsa)) - if (!CHECK_FLAG (lsa->flags, OSPF_LSA_APPROVED)) - ospf_lsa_flush_area (lsa, area); - - LSDB_LOOP (ASBR_SUMMARY_LSDB (area), rn, lsa) - if (ospf_lsa_is_self_originated (ospf, lsa)) - if (!CHECK_FLAG (lsa->flags, OSPF_LSA_APPROVED)) - ospf_lsa_flush_area (lsa, area); - } - - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_remove_unapproved_summaries(): Stop"); + struct listnode *node; + struct ospf_area *area; + struct route_node *rn; + struct ospf_lsa *lsa; + + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("ospf_abr_remove_unapproved_summaries(): Start"); + + for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_abr_remove_unapproved_summaries(): " + "looking at area %s", + inet_ntoa(area->area_id)); + + LSDB_LOOP(SUMMARY_LSDB(area), rn, lsa) + if (ospf_lsa_is_self_originated(ospf, lsa)) + if (!CHECK_FLAG(lsa->flags, OSPF_LSA_APPROVED)) + ospf_lsa_flush_area(lsa, area); + + LSDB_LOOP(ASBR_SUMMARY_LSDB(area), rn, lsa) + if (ospf_lsa_is_self_originated(ospf, lsa)) + if (!CHECK_FLAG(lsa->flags, OSPF_LSA_APPROVED)) + ospf_lsa_flush_area(lsa, area); + } + + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("ospf_abr_remove_unapproved_summaries(): Stop"); } -static void -ospf_abr_manage_discard_routes (struct ospf *ospf) +static void ospf_abr_manage_discard_routes(struct ospf *ospf) { - struct listnode *node, *nnode; - struct route_node *rn; - struct ospf_area *area; - struct ospf_area_range *range; - - for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area)) - for (rn = route_top (area->ranges); rn; rn = route_next (rn)) - if ((range = rn->info) != NULL) - if (CHECK_FLAG (range->flags, OSPF_AREA_RANGE_ADVERTISE)) - { - if (range->specifics) - ospf_add_discard_route (ospf->new_table, area, - (struct prefix_ipv4 *) &rn->p); - else - ospf_delete_discard_route (ospf->new_table, - (struct prefix_ipv4 *) &rn->p); - } + struct listnode *node, *nnode; + struct route_node *rn; + struct ospf_area *area; + struct ospf_area_range *range; + + for (ALL_LIST_ELEMENTS(ospf->areas, node, nnode, area)) + for (rn = route_top(area->ranges); rn; rn = route_next(rn)) + if ((range = rn->info) != NULL) + if (CHECK_FLAG(range->flags, + OSPF_AREA_RANGE_ADVERTISE)) { + if (range->specifics) + ospf_add_discard_route( + ospf->new_table, area, + (struct prefix_ipv4 + *)&rn->p); + else + ospf_delete_discard_route( + ospf->new_table, + (struct prefix_ipv4 + *)&rn->p); + } } /* This is the function taking care about ABR NSSA, i.e. NSSA @@ -1739,146 +1720,142 @@ ospf_abr_manage_discard_routes (struct ospf *ospf) For External Calculations, any NSSA areas use the Type-7 AREA-LSDB, any ABR-non-NSSA areas use the Type-5 GLOBAL-LSDB. */ -static void -ospf_abr_nssa_task (struct ospf *ospf) /* called only if any_nssa */ +static void ospf_abr_nssa_task(struct ospf *ospf) /* called only if any_nssa */ { - if (IS_DEBUG_OSPF_NSSA) - zlog_debug ("Check for NSSA-ABR Tasks():"); - - if (! IS_OSPF_ABR (ospf)) - return; - - if (! ospf->anyNSSA) - return; - - /* Each area must confirm TranslatorRole */ - if (IS_DEBUG_OSPF_NSSA) - zlog_debug ("ospf_abr_nssa_task(): Start"); - - /* For all Global Entries flagged "local-translate", unset APPROVED */ - if (IS_DEBUG_OSPF_NSSA) - zlog_debug ("ospf_abr_nssa_task(): unapprove translates"); - - ospf_abr_unapprove_translates (ospf); - - /* RESET all Ranges in every Area, same as summaries */ - if (IS_DEBUG_OSPF_NSSA) - zlog_debug ("ospf_abr_nssa_task(): NSSA initialize aggregates"); - ospf_abr_prepare_aggregates (ospf); /*TURNED OFF just for now */ - - /* For all NSSAs, Type-7s, translate to 5's, INSTALL/FLOOD, or - * Aggregate as Type-7 - * Install or Approve in Type-5 Global LSDB - */ - if (IS_DEBUG_OSPF_NSSA) - zlog_debug ("ospf_abr_nssa_task(): process translates"); - ospf_abr_process_nssa_translates (ospf); - - /* Translate/Send any "ranged" aggregates, and also 5-Install and - * Approve - * Scan Type-7's for aggregates, translate to Type-5's, - * Install/Flood/Approve - */ - if (IS_DEBUG_OSPF_NSSA) - zlog_debug("ospf_abr_nssa_task(): send NSSA aggregates"); - ospf_abr_send_nssa_aggregates (ospf); /*TURNED OFF FOR NOW */ - - /* Send any NSSA defaults as Type-5 - *if (IS_DEBUG_OSPF_NSSA) - * zlog_debug ("ospf_abr_nssa_task(): announce nssa defaults"); - *ospf_abr_announce_nssa_defaults (ospf); - * havnt a clue what above is supposed to do. - */ - - /* Flush any unapproved previous translates from Global Data Base */ - if (IS_DEBUG_OSPF_NSSA) - zlog_debug ("ospf_abr_nssa_task(): remove unapproved translates"); - ospf_abr_remove_unapproved_translates (ospf); - - ospf_abr_manage_discard_routes (ospf); /* same as normal...discard */ - - if (IS_DEBUG_OSPF_NSSA) - zlog_debug ("ospf_abr_nssa_task(): Stop"); + if (IS_DEBUG_OSPF_NSSA) + zlog_debug("Check for NSSA-ABR Tasks():"); + + if (!IS_OSPF_ABR(ospf)) + return; + + if (!ospf->anyNSSA) + return; + + /* Each area must confirm TranslatorRole */ + if (IS_DEBUG_OSPF_NSSA) + zlog_debug("ospf_abr_nssa_task(): Start"); + + /* For all Global Entries flagged "local-translate", unset APPROVED */ + if (IS_DEBUG_OSPF_NSSA) + zlog_debug("ospf_abr_nssa_task(): unapprove translates"); + + ospf_abr_unapprove_translates(ospf); + + /* RESET all Ranges in every Area, same as summaries */ + if (IS_DEBUG_OSPF_NSSA) + zlog_debug("ospf_abr_nssa_task(): NSSA initialize aggregates"); + ospf_abr_prepare_aggregates(ospf); /*TURNED OFF just for now */ + + /* For all NSSAs, Type-7s, translate to 5's, INSTALL/FLOOD, or + * Aggregate as Type-7 + * Install or Approve in Type-5 Global LSDB + */ + if (IS_DEBUG_OSPF_NSSA) + zlog_debug("ospf_abr_nssa_task(): process translates"); + ospf_abr_process_nssa_translates(ospf); + + /* Translate/Send any "ranged" aggregates, and also 5-Install and + * Approve + * Scan Type-7's for aggregates, translate to Type-5's, + * Install/Flood/Approve + */ + if (IS_DEBUG_OSPF_NSSA) + zlog_debug("ospf_abr_nssa_task(): send NSSA aggregates"); + ospf_abr_send_nssa_aggregates(ospf); /*TURNED OFF FOR NOW */ + + /* Send any NSSA defaults as Type-5 + *if (IS_DEBUG_OSPF_NSSA) + * zlog_debug ("ospf_abr_nssa_task(): announce nssa defaults"); + *ospf_abr_announce_nssa_defaults (ospf); + * havnt a clue what above is supposed to do. + */ + + /* Flush any unapproved previous translates from Global Data Base */ + if (IS_DEBUG_OSPF_NSSA) + zlog_debug( + "ospf_abr_nssa_task(): remove unapproved translates"); + ospf_abr_remove_unapproved_translates(ospf); + + ospf_abr_manage_discard_routes(ospf); /* same as normal...discard */ + + if (IS_DEBUG_OSPF_NSSA) + zlog_debug("ospf_abr_nssa_task(): Stop"); } /* This is the function taking care about ABR stuff, i.e. summary-LSA origination and flooding. */ -void -ospf_abr_task (struct ospf *ospf) +void ospf_abr_task(struct ospf *ospf) { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_task(): Start"); - - if (ospf->new_table == NULL || ospf->new_rtrs == NULL) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_task(): Routing tables are not yet ready"); - return; - } - - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_task(): unapprove summaries"); - ospf_abr_unapprove_summaries (ospf); - - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_task(): prepare aggregates"); - ospf_abr_prepare_aggregates (ospf); - - if (IS_OSPF_ABR (ospf)) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_task(): process network RT"); - ospf_abr_process_network_rt (ospf, ospf->new_table); - - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_task(): process router RT"); - ospf_abr_process_router_rt (ospf, ospf->new_rtrs); - - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_task(): announce aggregates"); - ospf_abr_announce_aggregates (ospf); - - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_task(): announce stub defaults"); - ospf_abr_announce_stub_defaults (ospf); - } - - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_task(): remove unapproved summaries"); - ospf_abr_remove_unapproved_summaries (ospf); - - ospf_abr_manage_discard_routes (ospf); - - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_task(): Stop"); + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("ospf_abr_task(): Start"); + + if (ospf->new_table == NULL || ospf->new_rtrs == NULL) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_abr_task(): Routing tables are not yet ready"); + return; + } + + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("ospf_abr_task(): unapprove summaries"); + ospf_abr_unapprove_summaries(ospf); + + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("ospf_abr_task(): prepare aggregates"); + ospf_abr_prepare_aggregates(ospf); + + if (IS_OSPF_ABR(ospf)) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("ospf_abr_task(): process network RT"); + ospf_abr_process_network_rt(ospf, ospf->new_table); + + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("ospf_abr_task(): process router RT"); + ospf_abr_process_router_rt(ospf, ospf->new_rtrs); + + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("ospf_abr_task(): announce aggregates"); + ospf_abr_announce_aggregates(ospf); + + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("ospf_abr_task(): announce stub defaults"); + ospf_abr_announce_stub_defaults(ospf); + } + + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("ospf_abr_task(): remove unapproved summaries"); + ospf_abr_remove_unapproved_summaries(ospf); + + ospf_abr_manage_discard_routes(ospf); + + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("ospf_abr_task(): Stop"); } -static int -ospf_abr_task_timer (struct thread *thread) +static int ospf_abr_task_timer(struct thread *thread) { - struct ospf *ospf = THREAD_ARG (thread); + struct ospf *ospf = THREAD_ARG(thread); - ospf->t_abr_task = 0; + ospf->t_abr_task = 0; - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("Running ABR task on timer"); + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("Running ABR task on timer"); - ospf_check_abr_status (ospf); - ospf_abr_nssa_check_status (ospf); + ospf_check_abr_status(ospf); + ospf_abr_nssa_check_status(ospf); - ospf_abr_task (ospf); - ospf_abr_nssa_task (ospf); /* if nssa-abr, then scan Type-7 LSDB */ + ospf_abr_task(ospf); + ospf_abr_nssa_task(ospf); /* if nssa-abr, then scan Type-7 LSDB */ - return 0; + return 0; } -void -ospf_schedule_abr_task (struct ospf *ospf) +void ospf_schedule_abr_task(struct ospf *ospf) { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("Scheduling ABR task"); + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("Scheduling ABR task"); - if (ospf->t_abr_task == NULL) - ospf->t_abr_task = thread_add_timer (master, ospf_abr_task_timer, - ospf, OSPF_ABR_TASK_DELAY); + if (ospf->t_abr_task == NULL) + ospf->t_abr_task = thread_add_timer(master, ospf_abr_task_timer, + ospf, OSPF_ABR_TASK_DELAY); } |