Annotation of embedaddon/quagga/ospfd/ospf_abr.c, revision 1.1

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

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>