File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / quagga / ospfd / ospf_abr.c
Revision 1.1.1.4 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Nov 2 10:09:12 2016 UTC (7 years, 8 months ago) by misho
Branches: quagga, MAIN
CVS tags: v1_0_20160315, HEAD
quagga 1.0.20160315

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

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