back to topotato report
topotato coverage report
Current view: top level - ospfd - ospf_abr.c (source / functions) Hit Total Coverage
Test: test_ospf_topo1.py::OSPFTopo1Test Lines: 400 929 43.1 %
Date: 2023-02-24 18:38:32 Functions: 23 45 51.1 %

          Line data    Source code
       1             : /*
       2             :  * OSPF ABR functions.
       3             :  * Copyright (C) 1999, 2000 Alex Zinin, Toshiaki Takada
       4             :  *
       5             :  * This file is part of GNU Zebra.
       6             :  *
       7             :  * GNU Zebra is free software; you can redistribute it and/or modify it
       8             :  * under the terms of the GNU General Public License as published by the
       9             :  * Free Software Foundation; either version 2, or (at your option) any
      10             :  * later version.
      11             :  *
      12             :  * GNU Zebra is distributed in the hope that it will be useful, but
      13             :  * WITHOUT ANY WARRANTY; without even the implied warranty of
      14             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      15             :  * General Public License for more details.
      16             :  *
      17             :  * You should have received a copy of the GNU General Public License along
      18             :  * with this program; see the file COPYING; if not, write to the Free Software
      19             :  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
      20             :  */
      21             : 
      22             : 
      23             : #include <zebra.h>
      24             : 
      25             : #include "thread.h"
      26             : #include "memory.h"
      27             : #include "linklist.h"
      28             : #include "prefix.h"
      29             : #include "if.h"
      30             : #include "table.h"
      31             : #include "vty.h"
      32             : #include "filter.h"
      33             : #include "plist.h"
      34             : #include "log.h"
      35             : 
      36             : #include "ospfd/ospfd.h"
      37             : #include "ospfd/ospf_interface.h"
      38             : #include "ospfd/ospf_ism.h"
      39             : #include "ospfd/ospf_asbr.h"
      40             : #include "ospfd/ospf_lsa.h"
      41             : #include "ospfd/ospf_lsdb.h"
      42             : #include "ospfd/ospf_neighbor.h"
      43             : #include "ospfd/ospf_nsm.h"
      44             : #include "ospfd/ospf_spf.h"
      45             : #include "ospfd/ospf_route.h"
      46             : #include "ospfd/ospf_ia.h"
      47             : #include "ospfd/ospf_flood.h"
      48             : #include "ospfd/ospf_abr.h"
      49             : #include "ospfd/ospf_ase.h"
      50             : #include "ospfd/ospf_zebra.h"
      51             : #include "ospfd/ospf_dump.h"
      52             : #include "ospfd/ospf_errors.h"
      53             : 
      54           0 : static struct ospf_area_range *ospf_area_range_new(struct prefix_ipv4 *p)
      55             : {
      56           0 :         struct ospf_area_range *range;
      57             : 
      58           0 :         range = XCALLOC(MTYPE_OSPF_AREA_RANGE, sizeof(struct ospf_area_range));
      59           0 :         range->addr = p->prefix;
      60           0 :         range->masklen = p->prefixlen;
      61           0 :         range->cost_config = OSPF_AREA_RANGE_COST_UNSPEC;
      62             : 
      63           0 :         return range;
      64             : }
      65             : 
      66           0 : static void ospf_area_range_free(struct ospf_area_range *range)
      67             : {
      68           0 :         XFREE(MTYPE_OSPF_AREA_RANGE, range);
      69             : }
      70             : 
      71           0 : static void ospf_area_range_add(struct ospf_area *area,
      72             :                                 struct ospf_area_range *range)
      73             : {
      74           0 :         struct route_node *rn;
      75           0 :         struct prefix_ipv4 p;
      76             : 
      77           0 :         p.family = AF_INET;
      78           0 :         p.prefixlen = range->masklen;
      79           0 :         p.prefix = range->addr;
      80           0 :         apply_mask_ipv4(&p);
      81             : 
      82           0 :         rn = route_node_get(area->ranges, (struct prefix *)&p);
      83           0 :         if (rn->info)
      84           0 :                 route_unlock_node(rn);
      85             :         else
      86           0 :                 rn->info = range;
      87           0 : }
      88             : 
      89           0 : static void ospf_area_range_delete(struct ospf_area *area,
      90             :                                    struct route_node *rn)
      91             : {
      92           0 :         struct ospf_area_range *range = rn->info;
      93             : 
      94           0 :         if (range->specifics != 0)
      95           0 :                 ospf_delete_discard_route(area->ospf, area->ospf->new_table,
      96           0 :                                           (struct prefix_ipv4 *)&rn->p);
      97             : 
      98           0 :         ospf_area_range_free(range);
      99           0 :         rn->info = NULL;
     100           0 :         route_unlock_node(rn);
     101           0 :         route_unlock_node(rn);
     102           0 : }
     103             : 
     104           0 : struct ospf_area_range *ospf_area_range_lookup(struct ospf_area *area,
     105             :                                                struct prefix_ipv4 *p)
     106             : {
     107           0 :         struct route_node *rn;
     108             : 
     109           0 :         rn = route_node_lookup(area->ranges, (struct prefix *)p);
     110           0 :         if (rn) {
     111           0 :                 route_unlock_node(rn);
     112           0 :                 return rn->info;
     113             :         }
     114             :         return NULL;
     115             : }
     116             : 
     117           0 : struct ospf_area_range *ospf_area_range_lookup_next(struct ospf_area *area,
     118             :                                                     struct in_addr *range_net,
     119             :                                                     int first)
     120             : {
     121           0 :         struct route_node *rn;
     122           0 :         struct prefix_ipv4 p;
     123           0 :         struct ospf_area_range *find;
     124             : 
     125           0 :         p.family = AF_INET;
     126           0 :         p.prefixlen = IPV4_MAX_BITLEN;
     127           0 :         p.prefix = *range_net;
     128           0 :         apply_mask_ipv4(&p);
     129             : 
     130           0 :         if (first)
     131           0 :                 rn = route_top(area->ranges);
     132             :         else {
     133           0 :                 rn = route_node_get(area->ranges, (struct prefix *)&p);
     134           0 :                 rn = route_next(rn);
     135             :         }
     136             : 
     137           0 :         for (; rn; rn = route_next(rn))
     138           0 :                 if (rn->info)
     139             :                         break;
     140             : 
     141           0 :         if (rn && rn->info) {
     142           0 :                 find = rn->info;
     143           0 :                 *range_net = rn->p.u.prefix4;
     144           0 :                 route_unlock_node(rn);
     145           0 :                 return find;
     146             :         }
     147             :         return NULL;
     148             : }
     149             : 
     150          63 : static struct ospf_area_range *ospf_area_range_match(struct ospf_area *area,
     151             :                                                      struct prefix_ipv4 *p)
     152             : {
     153          63 :         struct route_node *node;
     154             : 
     155          63 :         node = route_node_match(area->ranges, (struct prefix *)p);
     156          63 :         if (node) {
     157           0 :                 route_unlock_node(node);
     158           0 :                 return node->info;
     159             :         }
     160             :         return NULL;
     161             : }
     162             : 
     163          34 : struct ospf_area_range *ospf_area_range_match_any(struct ospf *ospf,
     164             :                                                   struct prefix_ipv4 *p)
     165             : {
     166          34 :         struct ospf_area_range *range;
     167          34 :         struct ospf_area *area;
     168          34 :         struct listnode *node;
     169             : 
     170         102 :         for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area))
     171          34 :                 if ((range = ospf_area_range_match(area, p)))
     172           0 :                         return range;
     173             : 
     174             :         return NULL;
     175             : }
     176             : 
     177           0 : int ospf_area_range_active(struct ospf_area_range *range)
     178             : {
     179           0 :         return range->specifics;
     180             : }
     181             : 
     182         146 : static int ospf_area_actively_attached(struct ospf_area *area)
     183             : {
     184         146 :         return area->act_ints;
     185             : }
     186             : 
     187           0 : int ospf_area_range_set(struct ospf *ospf, struct in_addr area_id,
     188             :                         struct prefix_ipv4 *p, int advertise)
     189             : {
     190           0 :         struct ospf_area *area;
     191           0 :         struct ospf_area_range *range;
     192             : 
     193           0 :         area = ospf_area_get(ospf, area_id);
     194           0 :         if (area == NULL)
     195             :                 return 0;
     196             : 
     197           0 :         range = ospf_area_range_lookup(area, p);
     198           0 :         if (range != NULL) {
     199           0 :                 if (!CHECK_FLAG(advertise, OSPF_AREA_RANGE_ADVERTISE))
     200           0 :                         range->cost_config = OSPF_AREA_RANGE_COST_UNSPEC;
     201           0 :                 if ((CHECK_FLAG(range->flags, OSPF_AREA_RANGE_ADVERTISE)
     202           0 :                      && !CHECK_FLAG(advertise, OSPF_AREA_RANGE_ADVERTISE))
     203           0 :                     || (!CHECK_FLAG(range->flags, OSPF_AREA_RANGE_ADVERTISE)
     204           0 :                         && CHECK_FLAG(advertise, OSPF_AREA_RANGE_ADVERTISE)))
     205           0 :                         ospf_schedule_abr_task(ospf);
     206             :         } else {
     207           0 :                 range = ospf_area_range_new(p);
     208           0 :                 ospf_area_range_add(area, range);
     209           0 :                 ospf_schedule_abr_task(ospf);
     210             :         }
     211             : 
     212           0 :         if (CHECK_FLAG(advertise, OSPF_AREA_RANGE_ADVERTISE))
     213           0 :                 SET_FLAG(range->flags, OSPF_AREA_RANGE_ADVERTISE);
     214             :         else {
     215           0 :                 UNSET_FLAG(range->flags, OSPF_AREA_RANGE_ADVERTISE);
     216           0 :                 range->cost_config = OSPF_AREA_RANGE_COST_UNSPEC;
     217             :         }
     218             : 
     219             :         return 1;
     220             : }
     221             : 
     222           0 : int ospf_area_range_cost_set(struct ospf *ospf, struct in_addr area_id,
     223             :                              struct prefix_ipv4 *p, uint32_t cost)
     224             : {
     225           0 :         struct ospf_area *area;
     226           0 :         struct ospf_area_range *range;
     227             : 
     228           0 :         area = ospf_area_get(ospf, area_id);
     229           0 :         if (area == NULL)
     230             :                 return 0;
     231             : 
     232           0 :         range = ospf_area_range_lookup(area, p);
     233           0 :         if (range == NULL)
     234             :                 return 0;
     235             : 
     236           0 :         if (range->cost_config != cost) {
     237           0 :                 range->cost_config = cost;
     238           0 :                 if (ospf_area_range_active(range))
     239           0 :                         ospf_schedule_abr_task(ospf);
     240             :         }
     241             : 
     242             :         return 1;
     243             : }
     244             : 
     245           0 : int ospf_area_range_unset(struct ospf *ospf, struct in_addr area_id,
     246             :                           struct prefix_ipv4 *p)
     247             : {
     248           0 :         struct ospf_area *area;
     249           0 :         struct route_node *rn;
     250             : 
     251           0 :         area = ospf_area_lookup_by_area_id(ospf, area_id);
     252           0 :         if (area == NULL)
     253             :                 return 0;
     254             : 
     255           0 :         rn = route_node_lookup(area->ranges, (struct prefix *)p);
     256           0 :         if (rn == NULL)
     257             :                 return 0;
     258             : 
     259           0 :         if (ospf_area_range_active(rn->info))
     260           0 :                 ospf_schedule_abr_task(ospf);
     261             : 
     262           0 :         ospf_area_range_delete(area, rn);
     263             : 
     264           0 :         return 1;
     265             : }
     266             : 
     267           0 : int ospf_area_range_substitute_set(struct ospf *ospf, struct in_addr area_id,
     268             :                                    struct prefix_ipv4 *p, struct prefix_ipv4 *s)
     269             : {
     270           0 :         struct ospf_area *area;
     271           0 :         struct ospf_area_range *range;
     272             : 
     273           0 :         area = ospf_area_get(ospf, area_id);
     274           0 :         range = ospf_area_range_lookup(area, p);
     275             : 
     276           0 :         if (range != NULL) {
     277           0 :                 if (!CHECK_FLAG(range->flags, OSPF_AREA_RANGE_ADVERTISE)
     278             :                     || !CHECK_FLAG(range->flags, OSPF_AREA_RANGE_SUBSTITUTE))
     279           0 :                         ospf_schedule_abr_task(ospf);
     280             :         } else {
     281           0 :                 range = ospf_area_range_new(p);
     282           0 :                 ospf_area_range_add(area, range);
     283           0 :                 ospf_schedule_abr_task(ospf);
     284             :         }
     285             : 
     286           0 :         SET_FLAG(range->flags, OSPF_AREA_RANGE_ADVERTISE);
     287           0 :         SET_FLAG(range->flags, OSPF_AREA_RANGE_SUBSTITUTE);
     288           0 :         range->subst_addr = s->prefix;
     289           0 :         range->subst_masklen = s->prefixlen;
     290             : 
     291           0 :         return 1;
     292             : }
     293             : 
     294           0 : int ospf_area_range_substitute_unset(struct ospf *ospf, struct in_addr area_id,
     295             :                                      struct prefix_ipv4 *p)
     296             : {
     297           0 :         struct ospf_area *area;
     298           0 :         struct ospf_area_range *range;
     299             : 
     300           0 :         area = ospf_area_lookup_by_area_id(ospf, area_id);
     301           0 :         if (area == NULL)
     302             :                 return 0;
     303             : 
     304           0 :         range = ospf_area_range_lookup(area, p);
     305           0 :         if (range == NULL)
     306             :                 return 0;
     307             : 
     308           0 :         if (CHECK_FLAG(range->flags, OSPF_AREA_RANGE_SUBSTITUTE))
     309           0 :                 if (ospf_area_range_active(range))
     310           0 :                         ospf_schedule_abr_task(ospf);
     311             : 
     312           0 :         UNSET_FLAG(range->flags, OSPF_AREA_RANGE_SUBSTITUTE);
     313           0 :         range->subst_addr.s_addr = INADDR_ANY;
     314           0 :         range->subst_masklen = 0;
     315             : 
     316           0 :         return 1;
     317             : }
     318             : 
     319          43 : int ospf_act_bb_connection(struct ospf *ospf)
     320             : {
     321          43 :         struct ospf_interface *oi;
     322          43 :         struct listnode *node;
     323          43 :         int full_nbrs = 0;
     324             : 
     325          43 :         if (ospf->backbone == NULL)
     326             :                 return 0;
     327             : 
     328         172 :         for (ALL_LIST_ELEMENTS_RO(ospf->backbone->oiflist, node, oi)) {
     329          86 :                 struct ospf_neighbor *nbr;
     330          86 :                 struct route_node *rn;
     331             : 
     332         280 :                 for (rn = route_top(oi->nbrs); rn; rn = route_next(rn)) {
     333         194 :                         nbr = rn->info;
     334         194 :                         if (!nbr)
     335          54 :                                 continue;
     336             : 
     337         140 :                         if (nbr->state == NSM_Full
     338         100 :                             || OSPF_GR_IS_ACTIVE_HELPER(nbr))
     339          40 :                                 full_nbrs++;
     340             :                 }
     341             :         }
     342             : 
     343             :         return full_nbrs;
     344             : }
     345             : 
     346             : /* Determine whether this router is elected translator or not for area */
     347           0 : static int ospf_abr_nssa_am_elected(struct ospf_area *area)
     348             : {
     349           0 :         struct route_node *rn;
     350           0 :         struct ospf_lsa *lsa;
     351           0 :         struct router_lsa *rlsa;
     352           0 :         struct in_addr *best = NULL;
     353             : 
     354           0 :         LSDB_LOOP (ROUTER_LSDB(area), rn, lsa) {
     355             :                 /* sanity checks */
     356           0 :                 if (!lsa || (lsa->data->type != OSPF_ROUTER_LSA)
     357           0 :                     || IS_LSA_SELF(lsa))
     358           0 :                         continue;
     359             : 
     360           0 :                 rlsa = (struct router_lsa *)lsa->data;
     361             : 
     362             :                 /* ignore non-ABR routers */
     363           0 :                 if (!IS_ROUTER_LSA_BORDER(rlsa))
     364           0 :                         continue;
     365             : 
     366             :                 /* Router has Nt flag - always translate */
     367           0 :                 if (IS_ROUTER_LSA_NT(rlsa)) {
     368           0 :                         if (IS_DEBUG_OSPF_NSSA)
     369           0 :                                 zlog_debug("%s: router %pI4 asserts Nt",
     370             :                                            __func__, &lsa->data->id);
     371           0 :                         return 0;
     372             :                 }
     373             : 
     374           0 :                 if (best == NULL)
     375           0 :                         best = &lsa->data->id;
     376           0 :                 else if (IPV4_ADDR_CMP(&best->s_addr, &lsa->data->id.s_addr)
     377             :                          < 0)
     378           0 :                         best = &lsa->data->id;
     379             :         }
     380             : 
     381           0 :         if (IS_DEBUG_OSPF_NSSA)
     382           0 :                 zlog_debug("%s: best electable ABR is: %pI4", __func__, best);
     383             : 
     384           0 :         if (best == NULL)
     385             :                 return 1;
     386             : 
     387           0 :         if (IPV4_ADDR_CMP(&best->s_addr, &area->ospf->router_id.s_addr) < 0)
     388             :                 return 1;
     389             :         else
     390             :                 return 0;
     391             : }
     392             : 
     393             : /* Check NSSA ABR status
     394             :  * assumes there are nssa areas
     395             :  */
     396           0 : void ospf_abr_nssa_check_status(struct ospf *ospf)
     397             : {
     398           0 :         struct ospf_area *area;
     399           0 :         struct listnode *lnode, *nnode;
     400             : 
     401           0 :         for (ALL_LIST_ELEMENTS(ospf->areas, lnode, nnode, area)) {
     402           0 :                 uint8_t old_state = area->NSSATranslatorState;
     403             : 
     404           0 :                 if (area->external_routing != OSPF_AREA_NSSA)
     405           0 :                         continue;
     406             : 
     407           0 :                 if (IS_DEBUG_OSPF(nssa, NSSA))
     408           0 :                         zlog_debug("%s: checking area %pI4", __func__,
     409             :                                    &area->area_id);
     410             : 
     411           0 :                 if (!IS_OSPF_ABR(area->ospf)) {
     412           0 :                         if (IS_DEBUG_OSPF(nssa, NSSA))
     413           0 :                                 zlog_debug("%s: not ABR", __func__);
     414           0 :                         area->NSSATranslatorState =
     415             :                                 OSPF_NSSA_TRANSLATE_DISABLED;
     416             :                 } else {
     417           0 :                         switch (area->NSSATranslatorRole) {
     418           0 :                         case OSPF_NSSA_ROLE_NEVER:
     419             :                                 /* We never Translate Type-7 LSA. */
     420             :                                 /* TODO: check previous state and flush? */
     421           0 :                                 if (IS_DEBUG_OSPF(nssa, NSSA))
     422           0 :                                         zlog_debug("%s: never translate",
     423             :                                                    __func__);
     424           0 :                                 area->NSSATranslatorState =
     425             :                                         OSPF_NSSA_TRANSLATE_DISABLED;
     426           0 :                                 break;
     427             : 
     428           0 :                         case OSPF_NSSA_ROLE_ALWAYS:
     429             :                                 /* We always translate if we are an ABR
     430             :                                  * TODO: originate new LSAs if state change?
     431             :                                  * or let the nssa abr task take care of it?
     432             :                                  */
     433           0 :                                 if (IS_DEBUG_OSPF(nssa, NSSA))
     434           0 :                                         zlog_debug("%s: translate always",
     435             :                                                    __func__);
     436           0 :                                 area->NSSATranslatorState =
     437             :                                         OSPF_NSSA_TRANSLATE_ENABLED;
     438           0 :                                 break;
     439             : 
     440           0 :                         case OSPF_NSSA_ROLE_CANDIDATE:
     441             :                                 /* We are a candidate for Translation */
     442           0 :                                 if (ospf_abr_nssa_am_elected(area) > 0) {
     443           0 :                                         area->NSSATranslatorState =
     444             :                                                 OSPF_NSSA_TRANSLATE_ENABLED;
     445           0 :                                         if (IS_DEBUG_OSPF(nssa, NSSA))
     446           0 :                                                 zlog_debug(
     447             :                                                         "%s: elected translator",
     448             :                                                         __func__);
     449             :                                 } else {
     450           0 :                                         area->NSSATranslatorState =
     451             :                                                 OSPF_NSSA_TRANSLATE_DISABLED;
     452           0 :                                         if (IS_DEBUG_OSPF(nssa, NSSA))
     453           0 :                                                 zlog_debug("%s: not elected",
     454             :                                                            __func__);
     455             :                                 }
     456             :                                 break;
     457             :                         }
     458             :                 }
     459             :                 /* RFC3101, 3.1:
     460             :                  * All NSSA border routers must set the E-bit in the Type-1
     461             :                  * router-LSAs
     462             :                  * of their directly attached non-stub areas, even when they are
     463             :                  * not
     464             :                  * translating.
     465             :                  */
     466           0 :                 if (old_state != area->NSSATranslatorState) {
     467           0 :                         if (old_state == OSPF_NSSA_TRANSLATE_DISABLED)
     468           0 :                                 ospf_asbr_status_update(ospf,
     469           0 :                                                         ++ospf->redistribute);
     470           0 :                         else if (area->NSSATranslatorState
     471             :                                  == OSPF_NSSA_TRANSLATE_DISABLED)
     472           0 :                                 ospf_asbr_status_update(ospf,
     473           0 :                                                         --ospf->redistribute);
     474             :                 }
     475             :         }
     476           0 : }
     477             : 
     478             : /* Check area border router status. */
     479         114 : void ospf_check_abr_status(struct ospf *ospf)
     480             : {
     481         114 :         struct ospf_area *area;
     482         114 :         struct listnode *node, *nnode;
     483         114 :         int bb_configured = 0;
     484         114 :         int bb_act_attached = 0;
     485         114 :         int areas_configured = 0;
     486         114 :         int areas_act_attached = 0;
     487         114 :         uint8_t new_flags = ospf->flags;
     488             : 
     489         114 :         if (IS_DEBUG_OSPF_EVENT)
     490         114 :                 zlog_debug("%s: Start", __func__);
     491             : 
     492         374 :         for (ALL_LIST_ELEMENTS(ospf->areas, node, nnode, area)) {
     493         146 :                 if (listcount(area->oiflist)) {
     494         129 :                         areas_configured++;
     495             : 
     496         129 :                         if (OSPF_IS_AREA_BACKBONE(area))
     497          80 :                                 bb_configured = 1;
     498             :                 }
     499             : 
     500         146 :                 if (ospf_area_actively_attached(area)) {
     501         109 :                         areas_act_attached++;
     502             : 
     503         109 :                         if (OSPF_IS_AREA_BACKBONE(area))
     504          68 :                                 bb_act_attached = 1;
     505             :                 }
     506             :         }
     507             : 
     508         114 :         if (IS_DEBUG_OSPF_EVENT) {
     509         114 :                 zlog_debug("%s: looked through areas", __func__);
     510         114 :                 zlog_debug("%s: bb_configured: %d", __func__, bb_configured);
     511         114 :                 zlog_debug("%s: bb_act_attached: %d", __func__,
     512             :                            bb_act_attached);
     513         114 :                 zlog_debug("%s: areas_configured: %d", __func__,
     514             :                            areas_configured);
     515         114 :                 zlog_debug("%s: areas_act_attached: %d", __func__,
     516             :                            areas_act_attached);
     517             :         }
     518             : 
     519         114 :         switch (ospf->abr_type) {
     520           0 :         case OSPF_ABR_SHORTCUT:
     521             :         case OSPF_ABR_STAND:
     522           0 :                 if (areas_act_attached > 1)
     523           0 :                         SET_FLAG(new_flags, OSPF_FLAG_ABR);
     524             :                 else
     525           0 :                         UNSET_FLAG(new_flags, OSPF_FLAG_ABR);
     526             :                 break;
     527             : 
     528           0 :         case OSPF_ABR_IBM:
     529           0 :                 if ((areas_act_attached > 1) && bb_configured)
     530           0 :                         SET_FLAG(new_flags, OSPF_FLAG_ABR);
     531             :                 else
     532           0 :                         UNSET_FLAG(new_flags, OSPF_FLAG_ABR);
     533             :                 break;
     534             : 
     535         114 :         case OSPF_ABR_CISCO:
     536         114 :                 if ((areas_configured > 1) && bb_act_attached)
     537          23 :                         SET_FLAG(new_flags, OSPF_FLAG_ABR);
     538             :                 else
     539          91 :                         UNSET_FLAG(new_flags, OSPF_FLAG_ABR);
     540             :                 break;
     541             :         default:
     542             :                 break;
     543             :         }
     544             : 
     545         114 :         if (new_flags != ospf->flags) {
     546           4 :                 ospf_spf_calculate_schedule(ospf, SPF_FLAG_ABR_STATUS_CHANGE);
     547           4 :                 if (IS_DEBUG_OSPF_EVENT)
     548           4 :                         zlog_debug("%s: new router flags: %x", __func__,
     549             :                                    new_flags);
     550           4 :                 ospf->flags = new_flags;
     551           4 :                 ospf_router_lsa_update(ospf);
     552             :         }
     553         114 : }
     554             : 
     555           0 : static void ospf_abr_update_aggregate(struct ospf_area_range *range,
     556             :                                       struct ospf_route * or,
     557             :                                       struct ospf_area *area)
     558             : {
     559           0 :         if (IS_DEBUG_OSPF_EVENT)
     560           0 :                 zlog_debug("%s: Start", __func__);
     561             : 
     562           0 :         if (CHECK_FLAG(area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED)
     563           0 :             && (range->cost != OSPF_STUB_MAX_METRIC_SUMMARY_COST)) {
     564           0 :                 range->cost = OSPF_STUB_MAX_METRIC_SUMMARY_COST;
     565           0 :                 if (IS_DEBUG_OSPF_EVENT)
     566           0 :                         zlog_debug("%s: use summary max-metric 0x%08x",
     567             :                                    __func__, range->cost);
     568           0 :         } else if (range->cost_config != OSPF_AREA_RANGE_COST_UNSPEC) {
     569           0 :                 if (IS_DEBUG_OSPF_EVENT)
     570           0 :                         zlog_debug("%s: use configured cost %d", __func__,
     571             :                                    range->cost_config);
     572             : 
     573           0 :                 range->cost = range->cost_config;
     574             :         } else {
     575           0 :                 if (range->specifics == 0) {
     576           0 :                         if (IS_DEBUG_OSPF_EVENT)
     577           0 :                                 zlog_debug("%s: use or->cost %d", __func__,
     578             :                                            or->cost);
     579             : 
     580           0 :                         range->cost = or->cost; /* 1st time get 1st cost */
     581             :                 }
     582             : 
     583           0 :                 if (or->cost > range->cost) {
     584           0 :                         if (IS_DEBUG_OSPF_EVENT)
     585           0 :                                 zlog_debug("%s: update to %d", __func__,
     586             :                                                 or->cost);
     587             : 
     588           0 :                         range->cost = or->cost;
     589             :                 }
     590             :         }
     591             : 
     592           0 :         range->specifics++;
     593           0 : }
     594             : 
     595           2 : static void set_metric(struct ospf_lsa *lsa, uint32_t metric)
     596             : {
     597           2 :         struct summary_lsa *header;
     598           2 :         uint8_t *mp;
     599           2 :         metric = htonl(metric);
     600           2 :         mp = (uint8_t *)&metric;
     601           2 :         mp++;
     602           2 :         header = (struct summary_lsa *)lsa->data;
     603           2 :         memcpy(header->metric, mp, 3);
     604             : }
     605             : 
     606             : /* ospf_abr_translate_nssa */
     607           0 : static int ospf_abr_translate_nssa(struct ospf_area *area, struct ospf_lsa *lsa)
     608             : {
     609             :         /* Incoming Type-7 or later aggregated Type-7
     610             :          *
     611             :          * LSA is skipped if P-bit is off.
     612             :          * LSA is aggregated if within range.
     613             :          *
     614             :          * The Type-7 is translated, Installed/Approved as a Type-5 into
     615             :          * global LSDB, then Flooded through AS
     616             :          *
     617             :          *  Later, any Unapproved Translated Type-5's are flushed/discarded
     618             :          */
     619             : 
     620           0 :         struct ospf_lsa *old = NULL, *new = NULL;
     621           0 :         struct as_external_lsa *ext7;
     622           0 :         struct prefix_ipv4 p;
     623             : 
     624           0 :         if (!CHECK_FLAG(lsa->data->options, OSPF_OPTION_NP)) {
     625           0 :                 if (IS_DEBUG_OSPF_NSSA)
     626           0 :                         zlog_debug("%s: LSA Id %pI4, P-bit off, NO Translation",
     627             :                                    __func__, &lsa->data->id);
     628           0 :                 return 1;
     629             :         }
     630             : 
     631           0 :         if (IS_DEBUG_OSPF_NSSA)
     632           0 :                 zlog_debug("%s: LSA Id %pI4, TRANSLATING 7 to 5", __func__,
     633             :                            &lsa->data->id);
     634             : 
     635           0 :         ext7 = (struct as_external_lsa *)(lsa->data);
     636           0 :         p.prefix = lsa->data->id;
     637           0 :         p.prefixlen = ip_masklen(ext7->mask);
     638             : 
     639           0 :         if (ext7->e[0].fwd_addr.s_addr == OSPF_DEFAULT_DESTINATION) {
     640           0 :                 if (IS_DEBUG_OSPF_NSSA)
     641           0 :                         zlog_debug(
     642             :                                 "%s: LSA Id %pI4, Forward address is 0, NO Translation",
     643             :                                 __func__, &lsa->data->id);
     644           0 :                 return 1;
     645             :         }
     646             : 
     647             :         /* try find existing AS-External LSA for this prefix */
     648           0 :         old = ospf_external_info_find_lsa(area->ospf, &p);
     649             : 
     650           0 :         if (CHECK_FLAG(lsa->flags, OSPF_LSA_IN_MAXAGE)) {
     651             :                 /* if type-7 is removed, remove old translated type-5 lsa */
     652           0 :                 if (old) {
     653           0 :                         UNSET_FLAG(old->flags, OSPF_LSA_APPROVED);
     654           0 :                         if (IS_DEBUG_OSPF_NSSA)
     655           0 :                                 zlog_debug(
     656             :                                         "%s: remove old translated LSA id %pI4",
     657             :                                         __func__, &old->data->id);
     658             :                 }
     659             :                 /* if type-7 is removed and type-5 does not exist, do not
     660             :                  * originate */
     661           0 :                 return 1;
     662             :         }
     663             : 
     664           0 :         if (old && CHECK_FLAG(old->flags, OSPF_LSA_APPROVED)) {
     665           0 :                 if (IS_DEBUG_OSPF_NSSA)
     666           0 :                         zlog_debug(
     667             :                                 "%s: found old translated LSA Id %pI4, refreshing",
     668             :                                 __func__, &old->data->id);
     669             : 
     670             :                 /* refresh */
     671           0 :                 new = ospf_translated_nssa_refresh(area->ospf, lsa, old);
     672           0 :                 if (!new) {
     673           0 :                         if (IS_DEBUG_OSPF_NSSA)
     674           0 :                                 zlog_debug(
     675             :                                         "%s: could not refresh translated LSA Id %pI4",
     676             :                                         __func__, &old->data->id);
     677             :                 }
     678             :         } else {
     679             :                 /* no existing external route for this LSA Id
     680             :                  * originate translated LSA
     681             :                  */
     682             : 
     683           0 :                 if (ospf_translated_nssa_originate(area->ospf, lsa, old)
     684             :                     == NULL) {
     685           0 :                         if (IS_DEBUG_OSPF_NSSA)
     686           0 :                                 zlog_debug(
     687             :                                         "%s: Could not translate Type-7 for %pI4 to Type-5",
     688             :                                         __func__, &lsa->data->id);
     689           0 :                         return 1;
     690             :                 }
     691             :         }
     692             : 
     693             :         /* Area where Aggregate testing will be inserted, just like summary
     694             :            advertisements */
     695             :         /* ospf_abr_check_nssa_range (p_arg, lsa-> cost, lsa -> area); */
     696             : 
     697             :         return 0;
     698             : }
     699             : 
     700           0 : static void ospf_abr_translate_nssa_range(struct prefix_ipv4 *p, uint32_t cost)
     701             : {
     702             :         /* The Type-7 is created from the aggregated prefix and forwarded
     703             :            for lsa installation and flooding... to be added... */
     704           0 : }
     705             : 
     706          29 : void ospf_abr_announce_network_to_area(struct prefix_ipv4 *p, uint32_t cost,
     707             :                                        struct ospf_area *area)
     708             : {
     709          29 :         struct ospf_lsa *lsa, *old = NULL;
     710          29 :         struct summary_lsa *sl = NULL;
     711          29 :         uint32_t full_cost;
     712             : 
     713          29 :         if (IS_DEBUG_OSPF_EVENT)
     714          29 :                 zlog_debug("%s: Start", __func__);
     715             : 
     716          29 :         if (CHECK_FLAG(area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED))
     717             :                 full_cost = OSPF_STUB_MAX_METRIC_SUMMARY_COST;
     718             :         else
     719          29 :                 full_cost = cost;
     720             : 
     721          58 :         old = ospf_lsa_lookup_by_prefix(area->lsdb, OSPF_SUMMARY_LSA, p,
     722          29 :                                         area->ospf->router_id);
     723          29 :         if (old) {
     724          23 :                 if (IS_DEBUG_OSPF_EVENT)
     725          23 :                         zlog_debug("%s: old summary found", __func__);
     726             : 
     727          23 :                 sl = (struct summary_lsa *)old->data;
     728             : 
     729          23 :                 if (IS_DEBUG_OSPF_EVENT)
     730          23 :                         zlog_debug("%s: old metric: %d, new metric: %d",
     731             :                                    __func__, GET_METRIC(sl->metric), cost);
     732             : 
     733          23 :                 if ((GET_METRIC(sl->metric) == full_cost)
     734          23 :                     && ((old->flags & OSPF_LSA_IN_MAXAGE) == 0)) {
     735             :                         /* unchanged. simply reapprove it */
     736          21 :                         if (IS_DEBUG_OSPF_EVENT)
     737          21 :                                 zlog_debug("%s: old summary approved",
     738             :                                            __func__);
     739          21 :                         SET_FLAG(old->flags, OSPF_LSA_APPROVED);
     740             :                 } else {
     741             :                         /* LSA is changed, refresh it */
     742           2 :                         if (IS_DEBUG_OSPF_EVENT)
     743           2 :                                 zlog_debug("%s: refreshing summary", __func__);
     744           2 :                         set_metric(old, full_cost);
     745           2 :                         lsa = ospf_lsa_refresh(area->ospf, old);
     746             : 
     747           2 :                         if (!lsa) {
     748           0 :                                 flog_warn(EC_OSPF_LSA_MISSING,
     749             :                                           "%s: Could not refresh %pFX to %pI4",
     750             :                                           __func__, (struct prefix *)p,
     751             :                                           &area->area_id);
     752           0 :                                 return;
     753             :                         }
     754             : 
     755           2 :                         SET_FLAG(lsa->flags, OSPF_LSA_APPROVED);
     756             :                         /* This will flood through area. */
     757             :                 }
     758             :         } else {
     759           6 :                 if (IS_DEBUG_OSPF_EVENT)
     760           6 :                         zlog_debug("%s: creating new summary", __func__);
     761           6 :                 lsa = ospf_summary_lsa_originate(p, full_cost, area);
     762             :                 /* This will flood through area. */
     763             : 
     764           6 :                 if (!lsa) {
     765           0 :                         flog_warn(EC_OSPF_LSA_MISSING,
     766             :                                   "%s: Could not originate %pFX to %pi4",
     767             :                                   __func__, (struct prefix *)p,
     768             :                                   &area->area_id);
     769           0 :                         return;
     770             :                 }
     771             : 
     772           6 :                 SET_FLAG(lsa->flags, OSPF_LSA_APPROVED);
     773           6 :                 if (IS_DEBUG_OSPF_EVENT)
     774           6 :                         zlog_debug("%s: flooding new version of summary",
     775             :                                    __func__);
     776             :         }
     777             : 
     778          29 :         if (IS_DEBUG_OSPF_EVENT)
     779          29 :                 zlog_debug("%s: Stop", __func__);
     780             : }
     781             : 
     782          34 : static int ospf_abr_nexthops_belong_to_area(struct ospf_route * or,
     783             :                                             struct ospf_area *area)
     784             : {
     785          34 :         struct listnode *node, *nnode;
     786          34 :         struct ospf_path *path;
     787          34 :         struct ospf_interface *oi;
     788             : 
     789         102 :         for (ALL_LIST_ELEMENTS_RO(or->paths, node, path))
     790         116 :                 for (ALL_LIST_ELEMENTS_RO(area->oiflist, nnode, oi))
     791          48 :                         if (oi->ifp && oi->ifp->ifindex == path->ifindex)
     792             :                                 return 1;
     793             : 
     794             :         return 0;
     795             : }
     796             : 
     797          29 : static int ospf_abr_should_accept(struct prefix_ipv4 *p, struct ospf_area *area)
     798             : {
     799          29 :         if (IMPORT_NAME(area)) {
     800           0 :                 if (IMPORT_LIST(area) == NULL)
     801           0 :                         IMPORT_LIST(area) =
     802           0 :                                 access_list_lookup(AFI_IP, IMPORT_NAME(area));
     803             : 
     804           0 :                 if (IMPORT_LIST(area))
     805           0 :                         if (access_list_apply(IMPORT_LIST(area), p)
     806             :                             == FILTER_DENY)
     807             :                                 return 0;
     808             :         }
     809             : 
     810             :         return 1;
     811             : }
     812             : 
     813          29 : static int ospf_abr_plist_in_check(struct ospf_area *area,
     814             :                                    struct ospf_route * or,
     815             :                                    struct prefix_ipv4 *p)
     816             : {
     817          29 :         if (PREFIX_NAME_IN(area)) {
     818           0 :                 if (PREFIX_LIST_IN(area) == NULL)
     819           0 :                         PREFIX_LIST_IN(area) = prefix_list_lookup(
     820             :                                 AFI_IP, PREFIX_NAME_IN(area));
     821           0 :                 if (PREFIX_LIST_IN(area))
     822           0 :                         if (prefix_list_apply(PREFIX_LIST_IN(area), p)
     823             :                             != PREFIX_PERMIT)
     824             :                                 return 0;
     825             :         }
     826             :         return 1;
     827             : }
     828             : 
     829          29 : static int ospf_abr_plist_out_check(struct ospf_area *area,
     830             :                                     struct ospf_route * or,
     831             :                                     struct prefix_ipv4 *p)
     832             : {
     833          29 :         if (PREFIX_NAME_OUT(area)) {
     834           0 :                 if (PREFIX_LIST_OUT(area) == NULL)
     835           0 :                         PREFIX_LIST_OUT(area) = prefix_list_lookup(
     836             :                                 AFI_IP, PREFIX_NAME_OUT(area));
     837           0 :                 if (PREFIX_LIST_OUT(area))
     838           0 :                         if (prefix_list_apply(PREFIX_LIST_OUT(area), p)
     839             :                             != PREFIX_PERMIT)
     840             :                                 return 0;
     841             :         }
     842             :         return 1;
     843             : }
     844             : 
     845          29 : static void ospf_abr_announce_network(struct ospf *ospf, struct prefix_ipv4 *p,
     846             :                                       struct ospf_route * or)
     847             : {
     848          29 :         struct ospf_area_range *range;
     849          29 :         struct ospf_area *area, *or_area;
     850          29 :         struct listnode *node;
     851             : 
     852          29 :         if (IS_DEBUG_OSPF_EVENT)
     853          29 :                 zlog_debug("%s: Start", __func__);
     854             : 
     855          29 :         or_area = ospf_area_lookup_by_area_id(ospf, or->u.std.area_id);
     856          29 :         assert(or_area);
     857             : 
     858         116 :         for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) {
     859          58 :                 if (IS_DEBUG_OSPF_EVENT)
     860          58 :                         zlog_debug("%s: looking at area %pI4", __func__,
     861             :                                    &area->area_id);
     862             : 
     863          58 :                 if (IPV4_ADDR_SAME(& or->u.std.area_id, &area->area_id))
     864          29 :                         continue;
     865             : 
     866          29 :                 if (ospf_abr_nexthops_belong_to_area(or, area))
     867           0 :                         continue;
     868             : 
     869          29 :                 if (!ospf_abr_should_accept(p, area)) {
     870           0 :                         if (IS_DEBUG_OSPF_EVENT)
     871           0 :                                 zlog_debug(
     872             :                                         "%s: prefix %pFX was denied by import-list",
     873             :                                         __func__, p);
     874           0 :                         continue;
     875             :                 }
     876             : 
     877          29 :                 if (!ospf_abr_plist_in_check(area, or, p)) {
     878           0 :                         if (IS_DEBUG_OSPF_EVENT)
     879           0 :                                 zlog_debug(
     880             :                                         "%s: prefix %pFX was denied by prefix-list",
     881             :                                         __func__, p);
     882           0 :                         continue;
     883             :                 }
     884             : 
     885          29 :                 if (area->external_routing != OSPF_AREA_DEFAULT
     886           0 :                     && area->no_summary) {
     887           0 :                         if (IS_DEBUG_OSPF_EVENT)
     888           0 :                                 zlog_debug(
     889             :                                         "%s: area %pI4 is stub and no_summary",
     890             :                                         __func__, &area->area_id);
     891           0 :                         continue;
     892             :                 }
     893             : 
     894          29 :                 if (or->path_type == OSPF_PATH_INTER_AREA) {
     895           0 :                         if (IS_DEBUG_OSPF_EVENT)
     896           0 :                                 zlog_debug(
     897             :                                         "%s: this is inter-area route to %pFX",
     898             :                                         __func__, p);
     899             : 
     900           0 :                         if (!OSPF_IS_AREA_BACKBONE(area))
     901           0 :                                 ospf_abr_announce_network_to_area(p, or->cost,
     902             :                                                                   area);
     903             :                 }
     904             : 
     905          29 :                 if (or->path_type == OSPF_PATH_INTRA_AREA) {
     906          29 :                         if (IS_DEBUG_OSPF_EVENT)
     907          29 :                                 zlog_debug(
     908             :                                         "%s: this is intra-area route to %pFX",
     909             :                                         __func__, p);
     910          29 :                         if ((range = ospf_area_range_match(or_area, p))
     911           0 :                             && !ospf_area_is_transit(area))
     912           0 :                                 ospf_abr_update_aggregate(range, or, area);
     913             :                         else
     914          29 :                                 ospf_abr_announce_network_to_area(p, or->cost,
     915             :                                                                   area);
     916             :                 }
     917             :         }
     918          29 : }
     919             : 
     920          29 : static int ospf_abr_should_announce(struct ospf *ospf, struct prefix_ipv4 *p,
     921             :                                     struct ospf_route * or)
     922             : {
     923          29 :         struct ospf_area *area;
     924             : 
     925          29 :         area = ospf_area_lookup_by_area_id(ospf, or->u.std.area_id);
     926             : 
     927          29 :         assert(area);
     928             : 
     929          29 :         if (EXPORT_NAME(area)) {
     930           0 :                 if (EXPORT_LIST(area) == NULL)
     931           0 :                         EXPORT_LIST(area) =
     932           0 :                                 access_list_lookup(AFI_IP, EXPORT_NAME(area));
     933             : 
     934           0 :                 if (EXPORT_LIST(area))
     935           0 :                         if (access_list_apply(EXPORT_LIST(area), p)
     936             :                             == FILTER_DENY)
     937             :                                 return 0;
     938             :         }
     939             : 
     940             :         return 1;
     941             : }
     942             : 
     943           0 : static void ospf_abr_process_nssa_translates(struct ospf *ospf)
     944             : {
     945             :         /* Scan through all NSSA_LSDB records for all areas;
     946             : 
     947             :            If P-bit is on, translate all Type-7's to 5's and aggregate or
     948             :            flood install as approved in Type-5 LSDB with XLATE Flag on
     949             :            later, do same for all aggregates...  At end, DISCARD all
     950             :            remaining UNAPPROVED Type-5's (Aggregate is for future ) */
     951           0 :         struct listnode *node;
     952           0 :         struct ospf_area *area;
     953           0 :         struct route_node *rn;
     954           0 :         struct ospf_lsa *lsa;
     955             : 
     956           0 :         if (IS_DEBUG_OSPF_NSSA)
     957           0 :                 zlog_debug("%s: Start", __func__);
     958             : 
     959           0 :         for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) {
     960           0 :                 if (!area->NSSATranslatorState)
     961           0 :                         continue; /* skip if not translator */
     962             : 
     963           0 :                 if (area->external_routing != OSPF_AREA_NSSA)
     964           0 :                         continue; /* skip if not Nssa Area */
     965             : 
     966           0 :                 if (IS_DEBUG_OSPF_NSSA)
     967           0 :                         zlog_debug("%s(): looking at area %pI4", __func__,
     968             :                                    &area->area_id);
     969             : 
     970           0 :                 LSDB_LOOP (NSSA_LSDB(area), rn, lsa)
     971           0 :                         ospf_abr_translate_nssa(area, lsa);
     972             :         }
     973             : 
     974           0 :         if (IS_DEBUG_OSPF_NSSA)
     975           0 :                 zlog_debug("%s: Stop", __func__);
     976           0 : }
     977             : 
     978           9 : static void ospf_abr_process_network_rt(struct ospf *ospf,
     979             :                                         struct route_table *rt)
     980             : {
     981           9 :         struct ospf_area *area;
     982           9 :         struct ospf_route * or ;
     983           9 :         struct route_node *rn;
     984             : 
     985           9 :         if (IS_DEBUG_OSPF_EVENT)
     986           9 :                 zlog_debug("%s: Start", __func__);
     987             : 
     988          58 :         for (rn = route_top(rt); rn; rn = route_next(rn)) {
     989          49 :                 if ((or = rn->info) == NULL)
     990          20 :                         continue;
     991             : 
     992          29 :                 if (!(area = ospf_area_lookup_by_area_id(ospf,
     993             :                                                          or->u.std.area_id))) {
     994           0 :                         if (IS_DEBUG_OSPF_EVENT)
     995           0 :                                 zlog_debug(
     996             :                                 "%s: area %pI4 no longer exists", __func__,
     997             :                                                 &or->u.std.area_id);
     998           0 :                         continue;
     999             :                 }
    1000             : 
    1001          29 :                 if (IS_DEBUG_OSPF_EVENT)
    1002          29 :                         zlog_debug("%s: this is a route to %pFX", __func__,
    1003             :                                    &rn->p);
    1004          29 :                 if (or->path_type >= OSPF_PATH_TYPE1_EXTERNAL) {
    1005           0 :                         if (IS_DEBUG_OSPF_EVENT)
    1006           0 :                                 zlog_debug(
    1007             :                                         "%s: this is an External router, skipping",
    1008             :                                         __func__);
    1009           0 :                         continue;
    1010             :                 }
    1011             : 
    1012          29 :                 if (or->cost >= OSPF_LS_INFINITY) {
    1013           0 :                         if (IS_DEBUG_OSPF_EVENT)
    1014           0 :                                 zlog_debug(
    1015             :                                         "%s: this route's cost is infinity, skipping",
    1016             :                                         __func__);
    1017           0 :                         continue;
    1018             :                 }
    1019             : 
    1020          29 :                 if (or->type == OSPF_DESTINATION_DISCARD) {
    1021           0 :                         if (IS_DEBUG_OSPF_EVENT)
    1022           0 :                                 zlog_debug(
    1023             :                                         "%s: this is a discard entry, skipping",
    1024             :                                         __func__);
    1025           0 :                         continue;
    1026             :                 }
    1027             : 
    1028          29 :                 if (
    1029             :                         or->path_type == OSPF_PATH_INTRA_AREA
    1030          29 :                                   && !ospf_abr_should_announce(
    1031          29 :                                              ospf, (struct prefix_ipv4 *)&rn->p,
    1032             :                                              or)) {
    1033           0 :                         if (IS_DEBUG_OSPF_EVENT)
    1034           0 :                                 zlog_debug("%s: denied by export-list",
    1035             :                                            __func__);
    1036           0 :                         continue;
    1037             :                 }
    1038             : 
    1039          29 :                 if (
    1040          29 :                         or->path_type == OSPF_PATH_INTRA_AREA
    1041          29 :                                   && !ospf_abr_plist_out_check(
    1042             :                                              area, or,
    1043          29 :                                              (struct prefix_ipv4 *)&rn->p)) {
    1044           0 :                         if (IS_DEBUG_OSPF_EVENT)
    1045           0 :                                 zlog_debug("%s: denied by prefix-list",
    1046             :                                            __func__);
    1047           0 :                         continue;
    1048             :                 }
    1049             : 
    1050          29 :                 if ((or->path_type == OSPF_PATH_INTER_AREA)
    1051           0 :                     && !OSPF_IS_AREA_ID_BACKBONE(or->u.std.area_id)) {
    1052           0 :                         if (IS_DEBUG_OSPF_EVENT)
    1053           0 :                                 zlog_debug(
    1054             :                                         "%s: this route is not backbone one, skipping",
    1055             :                                         __func__);
    1056           0 :                         continue;
    1057             :                 }
    1058             : 
    1059             : 
    1060          29 :                 if ((ospf->abr_type == OSPF_ABR_CISCO)
    1061          29 :                     || (ospf->abr_type == OSPF_ABR_IBM))
    1062             : 
    1063          29 :                         if (!ospf_act_bb_connection(ospf) &&
    1064          16 :                             or->path_type != OSPF_PATH_INTRA_AREA) {
    1065           0 :                                 if (IS_DEBUG_OSPF_EVENT)
    1066           0 :                                         zlog_debug(
    1067             :                                                 "%s: ALT ABR: No BB connection, skip not intra-area routes",
    1068             :                                                 __func__);
    1069           0 :                                 continue;
    1070             :                         }
    1071             : 
    1072          29 :                 if (IS_DEBUG_OSPF_EVENT)
    1073          29 :                         zlog_debug("%s: announcing", __func__);
    1074          29 :                 ospf_abr_announce_network(ospf, (struct prefix_ipv4 *)&rn->p,
    1075             :                                           or);
    1076             :         }
    1077             : 
    1078           9 :         if (IS_DEBUG_OSPF_EVENT)
    1079           9 :                 zlog_debug("%s: Stop", __func__);
    1080           9 : }
    1081             : 
    1082           5 : static void ospf_abr_announce_rtr_to_area(struct prefix_ipv4 *p, uint32_t cost,
    1083             :                                           struct ospf_area *area)
    1084             : {
    1085           5 :         struct ospf_lsa *lsa, *old = NULL;
    1086           5 :         struct summary_lsa *slsa = NULL;
    1087             : 
    1088           5 :         if (IS_DEBUG_OSPF_EVENT)
    1089           5 :                 zlog_debug("%s: Start", __func__);
    1090             : 
    1091          10 :         old = ospf_lsa_lookup_by_prefix(area->lsdb, OSPF_ASBR_SUMMARY_LSA, p,
    1092           5 :                                         area->ospf->router_id);
    1093           5 :         if (old) {
    1094           2 :                 if (IS_DEBUG_OSPF_EVENT)
    1095           2 :                         zlog_debug("%s: old summary found", __func__);
    1096           2 :                 slsa = (struct summary_lsa *)old->data;
    1097             : 
    1098           2 :                 if (IS_DEBUG_OSPF_EVENT)
    1099           2 :                         zlog_debug("%s: old metric: %d, new metric: %d",
    1100             :                                    __func__, GET_METRIC(slsa->metric), cost);
    1101             :         }
    1102             : 
    1103           2 :         if (old && (GET_METRIC(slsa->metric) == cost)
    1104           2 :             && ((old->flags & OSPF_LSA_IN_MAXAGE) == 0)) {
    1105           2 :                 if (IS_DEBUG_OSPF_EVENT)
    1106           2 :                         zlog_debug("%s: old summary approved", __func__);
    1107           2 :                 SET_FLAG(old->flags, OSPF_LSA_APPROVED);
    1108             :         } else {
    1109           3 :                 if (IS_DEBUG_OSPF_EVENT)
    1110           3 :                         zlog_debug("%s: 2.2", __func__);
    1111             : 
    1112           3 :                 if (old) {
    1113           0 :                         set_metric(old, cost);
    1114           0 :                         lsa = ospf_lsa_refresh(area->ospf, old);
    1115             :                 } else
    1116           3 :                         lsa = ospf_summary_asbr_lsa_originate(p, cost, area);
    1117           3 :                 if (!lsa) {
    1118           0 :                         flog_warn(EC_OSPF_LSA_MISSING,
    1119             :                                   "%s: Could not refresh/originate %pFX to %pI4",
    1120             :                                   __func__, (struct prefix *)p,
    1121             :                                   &area->area_id);
    1122           0 :                         return;
    1123             :                 }
    1124             : 
    1125           3 :                 if (IS_DEBUG_OSPF_EVENT)
    1126           3 :                         zlog_debug("%s: flooding new version of summary",
    1127             :                                    __func__);
    1128             : 
    1129             :                 /*
    1130             :                 zlog_info ("ospf_abr_announce_rtr_to_area(): creating new
    1131             :                 summary");
    1132             :                 lsa = ospf_summary_asbr_lsa (p, cost, area, old); */
    1133             : 
    1134           3 :                 SET_FLAG(lsa->flags, OSPF_LSA_APPROVED);
    1135             :                 /* ospf_flood_through_area (area, NULL, lsa);*/
    1136             :         }
    1137             : 
    1138           5 :         if (IS_DEBUG_OSPF_EVENT)
    1139           5 :                 zlog_debug("%s: Stop", __func__);
    1140             : }
    1141             : 
    1142             : 
    1143           5 : static void ospf_abr_announce_rtr(struct ospf *ospf, struct prefix_ipv4 *p,
    1144             :                                   struct ospf_route * or)
    1145             : {
    1146           5 :         struct listnode *node;
    1147           5 :         struct ospf_area *area;
    1148             : 
    1149           5 :         if (IS_DEBUG_OSPF_EVENT)
    1150           5 :                 zlog_debug("%s: Start", __func__);
    1151             : 
    1152          20 :         for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) {
    1153          10 :                 if (IS_DEBUG_OSPF_EVENT)
    1154          10 :                         zlog_debug("%s: looking at area %pI4", __func__,
    1155             :                                    &area->area_id);
    1156             : 
    1157          10 :                 if (IPV4_ADDR_SAME(& or->u.std.area_id, &area->area_id))
    1158           5 :                         continue;
    1159             : 
    1160           5 :                 if (ospf_abr_nexthops_belong_to_area(or, area))
    1161           0 :                         continue;
    1162             : 
    1163             :                 /* RFC3101: Do not generate ASBR type 4 LSA if NSSA ABR */
    1164           5 :                 if (or->u.std.external_routing == OSPF_AREA_NSSA) {
    1165           0 :                         if (IS_DEBUG_OSPF_EVENT)
    1166           0 :                                 zlog_debug(
    1167             :                                         "%s: do not generate LSA Type-4 %pI4 from NSSA",
    1168             :                                         __func__, &p->prefix);
    1169           0 :                         continue;
    1170             :                 }
    1171             : 
    1172           5 :                 if (area->external_routing != OSPF_AREA_DEFAULT) {
    1173           0 :                         if (IS_DEBUG_OSPF_EVENT)
    1174           0 :                                 zlog_debug(
    1175             :                                         "%s: area %pI4 doesn't support external routing",
    1176             :                                         __func__, &area->area_id);
    1177           0 :                         continue;
    1178             :                 }
    1179             : 
    1180           5 :                 if (or->path_type == OSPF_PATH_INTER_AREA) {
    1181           0 :                         if (IS_DEBUG_OSPF_EVENT)
    1182           0 :                                 zlog_debug(
    1183             :                                         "%s: this is inter-area route to %pI4",
    1184             :                                         __func__, &p->prefix);
    1185           0 :                         if (!OSPF_IS_AREA_BACKBONE(area))
    1186           0 :                                 ospf_abr_announce_rtr_to_area(p, or->cost,
    1187             :                                                               area);
    1188             :                 }
    1189             : 
    1190           5 :                 if (or->path_type == OSPF_PATH_INTRA_AREA) {
    1191           5 :                         if (IS_DEBUG_OSPF_EVENT)
    1192           5 :                                 zlog_debug(
    1193             :                                         "%s: this is intra-area route to %pI4",
    1194             :                                         __func__, &p->prefix);
    1195           5 :                         ospf_abr_announce_rtr_to_area(p, or->cost, area);
    1196             :                 }
    1197             :         }
    1198             : 
    1199           5 :         if (IS_DEBUG_OSPF_EVENT)
    1200           5 :                 zlog_debug("%s: Stop", __func__);
    1201           5 : }
    1202             : 
    1203           9 : static void ospf_abr_process_router_rt(struct ospf *ospf,
    1204             :                                        struct route_table *rt)
    1205             : {
    1206           9 :         struct ospf_route * or ;
    1207           9 :         struct route_node *rn;
    1208           9 :         struct list *l;
    1209             : 
    1210           9 :         if (IS_DEBUG_OSPF_EVENT)
    1211           9 :                 zlog_debug("%s: Start", __func__);
    1212             : 
    1213          16 :         for (rn = route_top(rt); rn; rn = route_next(rn)) {
    1214           7 :                 struct listnode *node, *nnode;
    1215           7 :                 char flag = 0;
    1216           7 :                 struct ospf_route *best = NULL;
    1217             : 
    1218           7 :                 if (rn->info == NULL)
    1219           2 :                         continue;
    1220             : 
    1221           5 :                 l = rn->info;
    1222             : 
    1223           5 :                 if (IS_DEBUG_OSPF_EVENT)
    1224           5 :                         zlog_debug("%s: this is a route to %pI4", __func__,
    1225             :                                    &rn->p.u.prefix4);
    1226             : 
    1227          10 :                 for (ALL_LIST_ELEMENTS(l, node, nnode, or)) {
    1228           5 :                         if (!ospf_area_lookup_by_area_id(ospf,
    1229             :                                                          or->u.std.area_id)) {
    1230           0 :                                 if (IS_DEBUG_OSPF_EVENT)
    1231           0 :                                         zlog_debug(
    1232             :                                                 "%s: area %pI4 no longer exists", __func__,
    1233             :                                                 &or->u.std.area_id);
    1234           0 :                                 continue;
    1235             :                         }
    1236             : 
    1237             : 
    1238           5 :                         if (!CHECK_FLAG(or->u.std.flags, ROUTER_LSA_EXTERNAL)) {
    1239           0 :                                 if (IS_DEBUG_OSPF_EVENT)
    1240           0 :                                         zlog_debug(
    1241             :                                                 "%s: This is not an ASBR, skipping",
    1242             :                                                 __func__);
    1243           0 :                                 continue;
    1244             :                         }
    1245             : 
    1246           5 :                         if (!flag) {
    1247           5 :                                 best = ospf_find_asbr_route(
    1248           5 :                                         ospf, rt, (struct prefix_ipv4 *)&rn->p);
    1249           5 :                                 flag = 1;
    1250             :                         }
    1251             : 
    1252           5 :                         if (best == NULL)
    1253           0 :                                 continue;
    1254             : 
    1255           5 :                         if (or != best) {
    1256           0 :                                 if (IS_DEBUG_OSPF_EVENT)
    1257           0 :                                         zlog_debug(
    1258             :                                                 "%s: This route is not the best among possible, skipping",
    1259             :                                                 __func__);
    1260           0 :                                 continue;
    1261             :                         }
    1262             : 
    1263           5 :                         if (
    1264           5 :                                 or->path_type == OSPF_PATH_INTER_AREA
    1265           0 :                                           && !OSPF_IS_AREA_ID_BACKBONE(
    1266             :                                                      or->u.std.area_id)) {
    1267           0 :                                 if (IS_DEBUG_OSPF_EVENT)
    1268           0 :                                         zlog_debug(
    1269             :                                                 "%s: This route is not a backbone one, skipping",
    1270             :                                                 __func__);
    1271           0 :                                 continue;
    1272             :                         }
    1273             : 
    1274           5 :                         if (or->cost >= OSPF_LS_INFINITY) {
    1275           0 :                                 if (IS_DEBUG_OSPF_EVENT)
    1276           0 :                                         zlog_debug(
    1277             :                                                 "%s: This route has LS_INFINITY metric, skipping",
    1278             :                                                 __func__);
    1279           0 :                                 continue;
    1280             :                         }
    1281             : 
    1282           5 :                         if (ospf->abr_type == OSPF_ABR_CISCO
    1283           5 :                             || ospf->abr_type == OSPF_ABR_IBM)
    1284           5 :                                 if (!ospf_act_bb_connection(ospf) &&
    1285           1 :                                     or->path_type != OSPF_PATH_INTRA_AREA) {
    1286           0 :                                         if (IS_DEBUG_OSPF_EVENT)
    1287           0 :                                                 zlog_debug(
    1288             :                                                         "%s: ALT ABR: No BB connection, skip not intra-area routes",
    1289             :                                                         __func__);
    1290           0 :                                         continue;
    1291             :                                 }
    1292             : 
    1293           5 :                         ospf_abr_announce_rtr(ospf,
    1294           5 :                                               (struct prefix_ipv4 *)&rn->p, or);
    1295             :                 }
    1296             :         }
    1297             : 
    1298           9 :         if (IS_DEBUG_OSPF_EVENT)
    1299           9 :                 zlog_debug("%s: Stop", __func__);
    1300           9 : }
    1301             : 
    1302             : static void
    1303           0 : ospf_abr_unapprove_translates(struct ospf *ospf) /* For NSSA Translations */
    1304             : {
    1305           0 :         struct ospf_lsa *lsa;
    1306           0 :         struct route_node *rn;
    1307             : 
    1308           0 :         if (IS_DEBUG_OSPF_NSSA)
    1309           0 :                 zlog_debug("%s: Start", __func__);
    1310             : 
    1311             :         /* NSSA Translator is not checked, because it may have gone away,
    1312             :           and we would want to flush any residuals anyway */
    1313             : 
    1314           0 :         LSDB_LOOP (EXTERNAL_LSDB(ospf), rn, lsa)
    1315           0 :                 if (CHECK_FLAG(lsa->flags, OSPF_LSA_LOCAL_XLT)) {
    1316           0 :                         UNSET_FLAG(lsa->flags, OSPF_LSA_APPROVED);
    1317           0 :                         if (IS_DEBUG_OSPF_NSSA)
    1318           0 :                                 zlog_debug("%s: approved unset on link id %pI4",
    1319             :                                            __func__, &lsa->data->id);
    1320             :                 }
    1321             : 
    1322           0 :         if (IS_DEBUG_OSPF_NSSA)
    1323           0 :                 zlog_debug("%s: Stop", __func__);
    1324           0 : }
    1325             : 
    1326           9 : static void ospf_abr_unapprove_summaries(struct ospf *ospf)
    1327             : {
    1328           9 :         struct listnode *node;
    1329           9 :         struct ospf_area *area;
    1330           9 :         struct route_node *rn;
    1331           9 :         struct ospf_lsa *lsa;
    1332             : 
    1333           9 :         if (IS_DEBUG_OSPF_EVENT)
    1334           9 :                 zlog_debug("%s: Start", __func__);
    1335             : 
    1336          36 :         for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) {
    1337          18 :                 if (IS_DEBUG_OSPF_EVENT)
    1338          18 :                         zlog_debug("%s: considering area %pI4", __func__,
    1339             :                                    &area->area_id);
    1340          58 :                 LSDB_LOOP (SUMMARY_LSDB(area), rn, lsa)
    1341          28 :                         if (ospf_lsa_is_self_originated(ospf, lsa)) {
    1342          28 :                                 if (IS_DEBUG_OSPF_EVENT)
    1343          28 :                                         zlog_debug(
    1344             :                                                 "%s: approved unset on summary link id %pI4",
    1345             :                                                 __func__, &lsa->data->id);
    1346          28 :                                 UNSET_FLAG(lsa->flags, OSPF_LSA_APPROVED);
    1347             :                         }
    1348             : 
    1349          23 :                 LSDB_LOOP (ASBR_SUMMARY_LSDB(area), rn, lsa)
    1350           4 :                         if (ospf_lsa_is_self_originated(ospf, lsa)) {
    1351           4 :                                 if (IS_DEBUG_OSPF_EVENT)
    1352           4 :                                         zlog_debug(
    1353             :                                                 "%s: approved unset on asbr-summary link id %pI4",
    1354             :                                                 __func__, &lsa->data->id);
    1355           4 :                                 UNSET_FLAG(lsa->flags, OSPF_LSA_APPROVED);
    1356             :                         }
    1357             :         }
    1358             : 
    1359           9 :         if (IS_DEBUG_OSPF_EVENT)
    1360           9 :                 zlog_debug("%s: Stop", __func__);
    1361           9 : }
    1362             : 
    1363           9 : static void ospf_abr_prepare_aggregates(struct ospf *ospf)
    1364             : {
    1365           9 :         struct listnode *node;
    1366           9 :         struct route_node *rn;
    1367           9 :         struct ospf_area_range *range;
    1368           9 :         struct ospf_area *area;
    1369             : 
    1370           9 :         if (IS_DEBUG_OSPF_EVENT)
    1371           9 :                 zlog_debug("%s: Start", __func__);
    1372             : 
    1373          36 :         for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) {
    1374          18 :                 for (rn = route_top(area->ranges); rn; rn = route_next(rn))
    1375           0 :                         if ((range = rn->info) != NULL) {
    1376           0 :                                 range->cost = 0;
    1377           0 :                                 range->specifics = 0;
    1378             :                         }
    1379             :         }
    1380             : 
    1381           9 :         if (IS_DEBUG_OSPF_EVENT)
    1382           9 :                 zlog_debug("%s: Stop", __func__);
    1383           9 : }
    1384             : 
    1385           9 : static void ospf_abr_announce_aggregates(struct ospf *ospf)
    1386             : {
    1387           9 :         struct ospf_area *area, *ar;
    1388           9 :         struct ospf_area_range *range;
    1389           9 :         struct route_node *rn;
    1390           9 :         struct prefix p;
    1391           9 :         struct listnode *node, *n;
    1392             : 
    1393           9 :         if (IS_DEBUG_OSPF_EVENT)
    1394           9 :                 zlog_debug("%s: Start", __func__);
    1395             : 
    1396          36 :         for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) {
    1397          18 :                 if (IS_DEBUG_OSPF_EVENT)
    1398          18 :                         zlog_debug("%s: looking at area %pI4", __func__,
    1399             :                                    &area->area_id);
    1400             : 
    1401          18 :                 for (rn = route_top(area->ranges); rn; rn = route_next(rn))
    1402           0 :                         if ((range = rn->info)) {
    1403           0 :                                 if (!CHECK_FLAG(range->flags,
    1404             :                                                 OSPF_AREA_RANGE_ADVERTISE)) {
    1405           0 :                                         if (IS_DEBUG_OSPF_EVENT)
    1406           0 :                                                 zlog_debug(
    1407             :                                                         "%s: discarding suppress-ranges",
    1408             :                                                         __func__);
    1409           0 :                                         continue;
    1410             :                                 }
    1411             : 
    1412           0 :                                 p.family = AF_INET;
    1413           0 :                                 p.u.prefix4 = range->addr;
    1414           0 :                                 p.prefixlen = range->masklen;
    1415             : 
    1416           0 :                                 if (IS_DEBUG_OSPF_EVENT)
    1417           0 :                                         zlog_debug("%s: this is range: %pFX",
    1418             :                                                    __func__, &p);
    1419             : 
    1420           0 :                                 if (CHECK_FLAG(range->flags,
    1421             :                                                OSPF_AREA_RANGE_SUBSTITUTE)) {
    1422           0 :                                         p.family = AF_INET;
    1423           0 :                                         p.u.prefix4 = range->subst_addr;
    1424           0 :                                         p.prefixlen = range->subst_masklen;
    1425             :                                 }
    1426             : 
    1427           0 :                                 if (range->specifics) {
    1428           0 :                                         if (IS_DEBUG_OSPF_EVENT)
    1429           0 :                                                 zlog_debug("%s: active range",
    1430             :                                                            __func__);
    1431             : 
    1432           0 :                                         for (ALL_LIST_ELEMENTS_RO(ospf->areas,
    1433             :                                                                   n, ar)) {
    1434           0 :                                                 if (ar == area)
    1435           0 :                                                         continue;
    1436             : 
    1437             :                                                 /* We do not check nexthops
    1438             :                                                    here, because
    1439             :                                                    intra-area routes can be
    1440             :                                                    associated with
    1441             :                                                    one area only */
    1442             : 
    1443             :                                                 /* backbone routes are not
    1444             :                                                    summarized
    1445             :                                                    when announced into transit
    1446             :                                                    areas */
    1447             : 
    1448           0 :                                                 if (ospf_area_is_transit(ar)
    1449           0 :                                                     && OSPF_IS_AREA_BACKBONE(
    1450             :                                                                area)) {
    1451           0 :                                                         if (IS_DEBUG_OSPF_EVENT)
    1452           0 :                                                                 zlog_debug(
    1453             :                 "%s: Skipping announcement of BB aggregate into a transit area",
    1454             :                                                                         __func__);
    1455           0 :                                                         continue;
    1456             :                                                 }
    1457           0 :                                                 ospf_abr_announce_network_to_area(
    1458             :                                                         (struct prefix_ipv4
    1459             :                                                                  *)&p,
    1460             :                                                         range->cost, ar);
    1461             :                                         }
    1462             :                                 }
    1463             :                         }
    1464             :         }
    1465             : 
    1466           9 :         if (IS_DEBUG_OSPF_EVENT)
    1467           9 :                 zlog_debug("%s: Stop", __func__);
    1468           9 : }
    1469             : 
    1470             : static void
    1471           0 : ospf_abr_send_nssa_aggregates(struct ospf *ospf) /* temporarily turned off */
    1472             : {
    1473           0 :         struct listnode *node;  /*, n; */
    1474           0 :         struct ospf_area *area; /*, *ar; */
    1475           0 :         struct route_node *rn;
    1476           0 :         struct ospf_area_range *range;
    1477           0 :         struct prefix_ipv4 p;
    1478             : 
    1479           0 :         if (IS_DEBUG_OSPF_NSSA)
    1480           0 :                 zlog_debug("%s: Start", __func__);
    1481             : 
    1482           0 :         for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) {
    1483           0 :                 if (!area->NSSATranslatorState)
    1484           0 :                         continue;
    1485             : 
    1486           0 :                 if (IS_DEBUG_OSPF_NSSA)
    1487           0 :                         zlog_debug("%s: looking at area %pI4", __func__,
    1488             :                                    &area->area_id);
    1489             : 
    1490           0 :                 for (rn = route_top(area->ranges); rn; rn = route_next(rn)) {
    1491           0 :                         if (rn->info == NULL)
    1492           0 :                                 continue;
    1493             : 
    1494           0 :                         range = rn->info;
    1495             : 
    1496           0 :                         if (!CHECK_FLAG(range->flags,
    1497             :                                         OSPF_AREA_RANGE_ADVERTISE)) {
    1498           0 :                                 if (IS_DEBUG_OSPF_NSSA)
    1499           0 :                                         zlog_debug(
    1500             :                                                 "%s: discarding suppress-ranges",
    1501             :                                                 __func__);
    1502           0 :                                 continue;
    1503             :                         }
    1504             : 
    1505           0 :                         p.family = AF_INET;
    1506           0 :                         p.prefix = range->addr;
    1507           0 :                         p.prefixlen = range->masklen;
    1508             : 
    1509           0 :                         if (IS_DEBUG_OSPF_NSSA)
    1510           0 :                                 zlog_debug("%s: this is range: %pFX", __func__,
    1511             :                                            &p);
    1512             : 
    1513           0 :                         if (CHECK_FLAG(range->flags,
    1514             :                                        OSPF_AREA_RANGE_SUBSTITUTE)) {
    1515           0 :                                 p.family = AF_INET;
    1516           0 :                                 p.prefix = range->subst_addr;
    1517           0 :                                 p.prefixlen = range->subst_masklen;
    1518             :                         }
    1519             : 
    1520           0 :                         if (range->specifics) {
    1521           0 :                                 if (IS_DEBUG_OSPF_NSSA)
    1522           0 :                                         zlog_debug("%s: active range",
    1523             :                                                    __func__);
    1524             : 
    1525             :                                 /* Fetch LSA-Type-7 from aggregate prefix, and
    1526             :                                  * then
    1527             :                                  *  translate, Install (as Type-5), Approve, and
    1528             :                                  * Flood
    1529             :                                  */
    1530           0 :                                 ospf_abr_translate_nssa_range(&p, range->cost);
    1531             :                         }
    1532             :                 } /* all area ranges*/
    1533             :         }        /* all areas */
    1534             : 
    1535           0 :         if (IS_DEBUG_OSPF_NSSA)
    1536           0 :                 zlog_debug("%s: Stop", __func__);
    1537           0 : }
    1538             : 
    1539           9 : static void ospf_abr_announce_stub_defaults(struct ospf *ospf)
    1540             : {
    1541           9 :         struct listnode *node;
    1542           9 :         struct ospf_area *area;
    1543           9 :         struct prefix_ipv4 p;
    1544             : 
    1545           9 :         if (!IS_OSPF_ABR(ospf))
    1546           0 :                 return;
    1547             : 
    1548           9 :         if (IS_DEBUG_OSPF_EVENT)
    1549           9 :                 zlog_debug("%s: Start", __func__);
    1550             : 
    1551           9 :         p.family = AF_INET;
    1552           9 :         p.prefix.s_addr = OSPF_DEFAULT_DESTINATION;
    1553           9 :         p.prefixlen = 0;
    1554             : 
    1555          36 :         for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) {
    1556          18 :                 if (IS_DEBUG_OSPF_EVENT)
    1557          18 :                         zlog_debug("%s: looking at area %pI4", __func__,
    1558             :                                    &area->area_id);
    1559             : 
    1560          36 :                 if ((area->external_routing != OSPF_AREA_STUB)
    1561          18 :                     && (area->external_routing != OSPF_AREA_NSSA))
    1562          18 :                         continue;
    1563             : 
    1564           0 :                 if (OSPF_IS_AREA_BACKBONE(area))
    1565           0 :                         continue; /* Sanity Check */
    1566             : 
    1567           0 :                 if (IS_DEBUG_OSPF_EVENT)
    1568           0 :                         zlog_debug("%s: announcing 0.0.0.0/0 to area %pI4",
    1569             :                                    __func__, &area->area_id);
    1570           0 :                 ospf_abr_announce_network_to_area(&p, area->default_cost, area);
    1571             :         }
    1572             : 
    1573           9 :         if (IS_DEBUG_OSPF_EVENT)
    1574           9 :                 zlog_debug("%s: Stop", __func__);
    1575             : }
    1576             : 
    1577           0 : static int ospf_abr_remove_unapproved_translates_apply(struct ospf *ospf,
    1578             :                                                        struct ospf_lsa *lsa)
    1579             : {
    1580           0 :         if (CHECK_FLAG(lsa->flags, OSPF_LSA_LOCAL_XLT)
    1581             :             && !CHECK_FLAG(lsa->flags, OSPF_LSA_APPROVED)) {
    1582           0 :                 zlog_info("%s: removing unapproved translates, ID: %pI4",
    1583             :                           __func__, &lsa->data->id);
    1584             : 
    1585             :                 /* FLUSH THROUGHOUT AS */
    1586           0 :                 ospf_lsa_flush_as(ospf, lsa);
    1587             : 
    1588             :                 /* DISCARD from LSDB  */
    1589             :         }
    1590           0 :         return 0;
    1591             : }
    1592             : 
    1593           0 : static void ospf_abr_remove_unapproved_translates(struct ospf *ospf)
    1594             : {
    1595           0 :         struct route_node *rn;
    1596           0 :         struct ospf_lsa *lsa;
    1597             : 
    1598             :         /* All AREA PROCESS should have APPROVED necessary LSAs */
    1599             :         /* Remove any left over and not APPROVED */
    1600           0 :         if (IS_DEBUG_OSPF_NSSA)
    1601           0 :                 zlog_debug("%s: Start", __func__);
    1602             : 
    1603           0 :         LSDB_LOOP (EXTERNAL_LSDB(ospf), rn, lsa)
    1604           0 :                 ospf_abr_remove_unapproved_translates_apply(ospf, lsa);
    1605             : 
    1606           0 :         if (IS_DEBUG_OSPF_NSSA)
    1607           0 :                 zlog_debug("%s: Stop", __func__);
    1608           0 : }
    1609             : 
    1610           9 : static void ospf_abr_remove_unapproved_summaries(struct ospf *ospf)
    1611             : {
    1612           9 :         struct listnode *node;
    1613           9 :         struct ospf_area *area;
    1614           9 :         struct route_node *rn;
    1615           9 :         struct ospf_lsa *lsa;
    1616             : 
    1617           9 :         if (IS_DEBUG_OSPF_EVENT)
    1618           9 :                 zlog_debug("%s: Start", __func__);
    1619             : 
    1620          36 :         for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) {
    1621          18 :                 if (IS_DEBUG_OSPF_EVENT)
    1622          18 :                         zlog_debug("%s: looking at area %pI4", __func__,
    1623             :                                    &area->area_id);
    1624             : 
    1625          68 :                 LSDB_LOOP (SUMMARY_LSDB(area), rn, lsa)
    1626          34 :                         if (ospf_lsa_is_self_originated(ospf, lsa))
    1627          34 :                                 if (!CHECK_FLAG(lsa->flags, OSPF_LSA_APPROVED))
    1628           5 :                                         ospf_lsa_flush_area(lsa, area);
    1629             : 
    1630          27 :                 LSDB_LOOP (ASBR_SUMMARY_LSDB(area), rn, lsa)
    1631           7 :                         if (ospf_lsa_is_self_originated(ospf, lsa))
    1632           7 :                                 if (!CHECK_FLAG(lsa->flags, OSPF_LSA_APPROVED))
    1633           2 :                                         ospf_lsa_flush_area(lsa, area);
    1634             :         }
    1635             : 
    1636           9 :         if (IS_DEBUG_OSPF_EVENT)
    1637           9 :                 zlog_debug("%s: Stop", __func__);
    1638           9 : }
    1639             : 
    1640           9 : static void ospf_abr_manage_discard_routes(struct ospf *ospf)
    1641             : {
    1642           9 :         struct listnode *node, *nnode;
    1643           9 :         struct route_node *rn;
    1644           9 :         struct ospf_area *area;
    1645           9 :         struct ospf_area_range *range;
    1646             : 
    1647          36 :         for (ALL_LIST_ELEMENTS(ospf->areas, node, nnode, area))
    1648          18 :                 for (rn = route_top(area->ranges); rn; rn = route_next(rn))
    1649           0 :                         if ((range = rn->info) != NULL)
    1650           0 :                                 if (CHECK_FLAG(range->flags,
    1651             :                                                OSPF_AREA_RANGE_ADVERTISE)) {
    1652           0 :                                         if (range->specifics)
    1653           0 :                                                 ospf_add_discard_route(
    1654             :                                                         ospf, ospf->new_table,
    1655             :                                                         area,
    1656             :                                                         (struct prefix_ipv4
    1657           0 :                                                                  *)&rn->p);
    1658             :                                         else
    1659           0 :                                                 ospf_delete_discard_route(
    1660             :                                                         ospf, ospf->new_table,
    1661             :                                                         (struct prefix_ipv4
    1662           0 :                                                                  *)&rn->p);
    1663             :                                 }
    1664           9 : }
    1665             : 
    1666             : /* This is the function taking care about ABR NSSA, i.e.  NSSA
    1667             :    Translator, -LSA aggregation and flooding. For all NSSAs
    1668             : 
    1669             :    Any SELF-AS-LSA is in the Type-5 LSDB and Type-7 LSDB.  These LSA's
    1670             :    are refreshed from the Type-5 LSDB, installed into the Type-7 LSDB
    1671             :    with the P-bit set.
    1672             : 
    1673             :    Any received Type-5s are legal for an ABR, else illegal for IR.
    1674             :    Received Type-7s are installed, by area, with incoming P-bit.  They
    1675             :    are flooded; if the Elected NSSA Translator, then P-bit off.
    1676             : 
    1677             :    Additionally, this ABR will place "translated type-7's" into the
    1678             :    Type-5 LSDB in order to keep track of APPROVAL or not.
    1679             : 
    1680             :    It will scan through every area, looking for Type-7 LSAs with P-Bit
    1681             :    SET. The Type-7's are either AS-FLOODED & 5-INSTALLED or
    1682             :    AGGREGATED.  Later, the AGGREGATED LSAs are AS-FLOODED &
    1683             :    5-INSTALLED.
    1684             : 
    1685             :    5-INSTALLED is into the Type-5 LSDB; Any UNAPPROVED Type-5 LSAs
    1686             :    left over are FLUSHED and DISCARDED.
    1687             : 
    1688             :    For External Calculations, any NSSA areas use the Type-7 AREA-LSDB,
    1689             :    any ABR-non-NSSA areas use the Type-5 GLOBAL-LSDB. */
    1690             : 
    1691           0 : static void ospf_abr_nssa_task(struct ospf *ospf) /* called only if any_nssa */
    1692             : {
    1693           0 :         if (ospf->gr_info.restart_in_progress)
    1694             :                 return;
    1695             : 
    1696           0 :         if (IS_DEBUG_OSPF_NSSA)
    1697           0 :                 zlog_debug("Check for NSSA-ABR Tasks():");
    1698             : 
    1699           0 :         if (!IS_OSPF_ABR(ospf))
    1700             :                 return;
    1701             : 
    1702           0 :         if (!ospf->anyNSSA)
    1703             :                 return;
    1704             : 
    1705             :         /* Each area must confirm TranslatorRole */
    1706           0 :         if (IS_DEBUG_OSPF_NSSA)
    1707           0 :                 zlog_debug("%s: Start", __func__);
    1708             : 
    1709             :         /* For all Global Entries flagged "local-translate", unset APPROVED */
    1710           0 :         if (IS_DEBUG_OSPF_NSSA)
    1711           0 :                 zlog_debug("%s: unapprove translates", __func__);
    1712             : 
    1713           0 :         ospf_abr_unapprove_translates(ospf);
    1714             : 
    1715             :         /* RESET all Ranges in every Area, same as summaries */
    1716           0 :         if (IS_DEBUG_OSPF_NSSA)
    1717           0 :                 zlog_debug("%s: NSSA initialize aggregates", __func__);
    1718           0 :         ospf_abr_prepare_aggregates(ospf); /*TURNED OFF just for now */
    1719             : 
    1720             :         /* For all NSSAs, Type-7s, translate to 5's, INSTALL/FLOOD, or
    1721             :          *  Aggregate as Type-7
    1722             :          * Install or Approve in Type-5 Global LSDB
    1723             :          */
    1724           0 :         if (IS_DEBUG_OSPF_NSSA)
    1725           0 :                 zlog_debug("%s: process translates", __func__);
    1726           0 :         ospf_abr_process_nssa_translates(ospf);
    1727             : 
    1728             :         /* Translate/Send any "ranged" aggregates, and also 5-Install and
    1729             :          *  Approve
    1730             :          * Scan Type-7's for aggregates, translate to Type-5's,
    1731             :          *  Install/Flood/Approve
    1732             :          */
    1733           0 :         if (IS_DEBUG_OSPF_NSSA)
    1734           0 :                 zlog_debug("%s: send NSSA aggregates", __func__);
    1735           0 :         ospf_abr_send_nssa_aggregates(ospf); /*TURNED OFF FOR NOW */
    1736             : 
    1737             :         /* Send any NSSA defaults as Type-5
    1738             :          *if (IS_DEBUG_OSPF_NSSA)
    1739             :          * zlog_debug ("ospf_abr_nssa_task(): announce nssa defaults");
    1740             :          *ospf_abr_announce_nssa_defaults (ospf);
    1741             :          * havnt a clue what above is supposed to do.
    1742             :          */
    1743             : 
    1744             :         /* Flush any unapproved previous translates from Global Data Base */
    1745           0 :         if (IS_DEBUG_OSPF_NSSA)
    1746           0 :                 zlog_debug("%s: remove unapproved translates", __func__);
    1747           0 :         ospf_abr_remove_unapproved_translates(ospf);
    1748             : 
    1749           0 :         ospf_abr_manage_discard_routes(ospf); /* same as normal...discard */
    1750             : 
    1751           0 :         if (IS_DEBUG_OSPF_NSSA)
    1752           0 :                 zlog_debug("%s: Stop", __func__);
    1753             : }
    1754             : 
    1755             : /* This is the function taking care about ABR stuff, i.e.
    1756             :    summary-LSA origination and flooding. */
    1757           9 : void ospf_abr_task(struct ospf *ospf)
    1758             : {
    1759           9 :         if (ospf->gr_info.restart_in_progress)
    1760             :                 return;
    1761             : 
    1762           9 :         if (IS_DEBUG_OSPF_EVENT)
    1763           9 :                 zlog_debug("%s: Start", __func__);
    1764             : 
    1765           9 :         if (ospf->new_table == NULL || ospf->new_rtrs == NULL) {
    1766           0 :                 if (IS_DEBUG_OSPF_EVENT)
    1767           0 :                         zlog_debug("%s: Routing tables are not yet ready",
    1768             :                                    __func__);
    1769           0 :                 return;
    1770             :         }
    1771             : 
    1772           9 :         if (IS_DEBUG_OSPF_EVENT)
    1773           9 :                 zlog_debug("%s: unapprove summaries", __func__);
    1774           9 :         ospf_abr_unapprove_summaries(ospf);
    1775             : 
    1776           9 :         if (IS_DEBUG_OSPF_EVENT)
    1777           9 :                 zlog_debug("%s: prepare aggregates", __func__);
    1778           9 :         ospf_abr_prepare_aggregates(ospf);
    1779             : 
    1780           9 :         if (IS_OSPF_ABR(ospf)) {
    1781           9 :                 if (IS_DEBUG_OSPF_EVENT)
    1782           9 :                         zlog_debug("%s: process network RT", __func__);
    1783           9 :                 ospf_abr_process_network_rt(ospf, ospf->new_table);
    1784             : 
    1785           9 :                 if (IS_DEBUG_OSPF_EVENT)
    1786           9 :                         zlog_debug("%s: process router RT", __func__);
    1787           9 :                 ospf_abr_process_router_rt(ospf, ospf->new_rtrs);
    1788             : 
    1789           9 :                 if (IS_DEBUG_OSPF_EVENT)
    1790           9 :                         zlog_debug("%s: announce aggregates", __func__);
    1791           9 :                 ospf_abr_announce_aggregates(ospf);
    1792             : 
    1793           9 :                 if (IS_DEBUG_OSPF_EVENT)
    1794           9 :                         zlog_debug("%s: announce stub defaults", __func__);
    1795           9 :                 ospf_abr_announce_stub_defaults(ospf);
    1796             :         }
    1797             : 
    1798           9 :         if (IS_DEBUG_OSPF_EVENT)
    1799           9 :                 zlog_debug("%s: remove unapproved summaries", __func__);
    1800           9 :         ospf_abr_remove_unapproved_summaries(ospf);
    1801             : 
    1802           9 :         ospf_abr_manage_discard_routes(ospf);
    1803             : 
    1804           9 :         if (IS_DEBUG_OSPF_EVENT)
    1805           9 :                 zlog_debug("%s: Stop", __func__);
    1806             : }
    1807             : 
    1808           0 : static void ospf_abr_task_timer(struct thread *thread)
    1809             : {
    1810           0 :         struct ospf *ospf = THREAD_ARG(thread);
    1811             : 
    1812           0 :         ospf->t_abr_task = 0;
    1813             : 
    1814           0 :         if (IS_DEBUG_OSPF_EVENT)
    1815           0 :                 zlog_debug("Running ABR task on timer");
    1816             : 
    1817           0 :         ospf_check_abr_status(ospf);
    1818           0 :         ospf_abr_nssa_check_status(ospf);
    1819             : 
    1820           0 :         ospf_abr_task(ospf);
    1821           0 :         ospf_abr_nssa_task(ospf); /* if nssa-abr, then scan Type-7 LSDB */
    1822           0 : }
    1823             : 
    1824           6 : void ospf_schedule_abr_task(struct ospf *ospf)
    1825             : {
    1826           6 :         if (IS_DEBUG_OSPF_EVENT)
    1827           6 :                 zlog_debug("Scheduling ABR task");
    1828             : 
    1829           6 :         thread_add_timer(master, ospf_abr_task_timer, ospf, OSPF_ABR_TASK_DELAY,
    1830             :                          &ospf->t_abr_task);
    1831           6 : }

Generated by: LCOV version v1.16-topotato