back to topotato report
topotato coverage report
Current view: top level - ospfd - ospf_ia.c (source / functions) Hit Total Coverage
Test: aggregated run ( view descriptions ) Lines: 115 328 35.1 %
Date: 2023-02-24 19:38:44 Functions: 7 11 63.6 %

          Line data    Source code
       1             : /*
       2             :  * OSPF inter-area routing.
       3             :  * Copyright (C) 1999, 2000 Alex Zinin, Toshiaki Takada
       4             :  *
       5             :  * This file is part of GNU Zebra.
       6             :  *
       7             :  * GNU Zebra is free software; you can redistribute it and/or modify it
       8             :  * under the terms of the GNU General Public License as published by the
       9             :  * Free Software Foundation; either version 2, or (at your option) any
      10             :  * later version.
      11             :  *
      12             :  * GNU Zebra is distributed in the hope that it will be useful, but
      13             :  * WITHOUT ANY WARRANTY; without even the implied warranty of
      14             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      15             :  * General Public License for more details.
      16             :  *
      17             :  * You should have received a copy of the GNU General Public License along
      18             :  * with this program; see the file COPYING; if not, write to the Free Software
      19             :  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
      20             :  */
      21             : 
      22             : 
      23             : #include <zebra.h>
      24             : 
      25             : #include "thread.h"
      26             : #include "memory.h"
      27             : #include "hash.h"
      28             : #include "linklist.h"
      29             : #include "prefix.h"
      30             : #include "table.h"
      31             : #include "log.h"
      32             : 
      33             : #include "ospfd/ospfd.h"
      34             : #include "ospfd/ospf_interface.h"
      35             : #include "ospfd/ospf_ism.h"
      36             : #include "ospfd/ospf_asbr.h"
      37             : #include "ospfd/ospf_lsa.h"
      38             : #include "ospfd/ospf_lsdb.h"
      39             : #include "ospfd/ospf_neighbor.h"
      40             : #include "ospfd/ospf_nsm.h"
      41             : #include "ospfd/ospf_spf.h"
      42             : #include "ospfd/ospf_route.h"
      43             : #include "ospfd/ospf_ase.h"
      44             : #include "ospfd/ospf_abr.h"
      45             : #include "ospfd/ospf_ia.h"
      46             : #include "ospfd/ospf_dump.h"
      47             : 
      48          47 : static struct ospf_route *ospf_find_abr_route(struct route_table *rtrs,
      49             :                                               struct prefix_ipv4 *abr,
      50             :                                               struct ospf_area *area)
      51             : {
      52          47 :         struct route_node *rn;
      53          47 :         struct ospf_route * or ;
      54          47 :         struct listnode *node;
      55             : 
      56          47 :         if ((rn = route_node_lookup(rtrs, (struct prefix *)abr)) == NULL)
      57             :                 return NULL;
      58             : 
      59          18 :         route_unlock_node(rn);
      60             : 
      61          36 :         for (ALL_LIST_ELEMENTS_RO((struct list *)rn->info, node, or))
      62          18 :                 if (IPV4_ADDR_SAME(& or->u.std.area_id, &area->area_id)
      63          18 :                     && (or->u.std.flags & ROUTER_LSA_BORDER))
      64          18 :                         return or ;
      65             : 
      66             :         return NULL;
      67             : }
      68             : 
      69          13 : static void ospf_ia_network_route(struct ospf *ospf, struct route_table *rt,
      70             :                                   struct prefix_ipv4 *p,
      71             :                                   struct ospf_route *new_or,
      72             :                                   struct ospf_route *abr_or)
      73             : {
      74          13 :         struct route_node *rn1;
      75          13 :         struct ospf_route * or ;
      76             : 
      77          13 :         if (IS_DEBUG_OSPF_EVENT)
      78          13 :                 zlog_debug("%s: processing summary route to %pFX", __func__, p);
      79             : 
      80             :         /* Find a route to the same dest */
      81          13 :         if ((rn1 = route_node_lookup(rt, (struct prefix *)p))) {
      82           0 :                 int res;
      83             : 
      84           0 :                 route_unlock_node(rn1);
      85             : 
      86           0 :                 if ((or = rn1->info)) {
      87           0 :                         if (IS_DEBUG_OSPF_EVENT)
      88           0 :                                 zlog_debug(
      89             :                                         "%s: Found a route to the same network",
      90             :                                         __func__);
      91             :                         /* Check the existing route. */
      92           0 :                         if ((res = ospf_route_cmp(ospf, new_or, or)) < 0) {
      93             :                                 /* New route is better, so replace old one. */
      94           0 :                                 ospf_route_subst(rn1, new_or, abr_or);
      95           0 :                         } else if (res == 0) {
      96             :                                 /* New and old route are equal, so next hops can
      97             :                                  * be added. */
      98           0 :                                 route_lock_node(rn1);
      99           0 :                                 ospf_route_copy_nexthops(or, abr_or->paths);
     100           0 :                                 route_unlock_node(rn1);
     101             : 
     102             :                                 /* new route can be deleted, because existing
     103             :                                  * route has been updated. */
     104           0 :                                 ospf_route_free(new_or);
     105             :                         } else {
     106             :                                 /* New route is worse, so free it. */
     107           0 :                                 ospf_route_free(new_or);
     108           0 :                                 return;
     109             :                         }
     110             :                 } /* if (or)*/
     111             :         }        /*if (rn1)*/
     112             :         else {    /* no route */
     113          13 :                 if (IS_DEBUG_OSPF_EVENT)
     114          13 :                         zlog_debug("%s: add new route to %pFX", __func__, p);
     115          13 :                 ospf_route_add(rt, p, new_or, abr_or);
     116             :         }
     117             : }
     118             : 
     119           5 : static void ospf_ia_router_route(struct ospf *ospf, struct route_table *rtrs,
     120             :                                  struct prefix_ipv4 *p,
     121             :                                  struct ospf_route *new_or,
     122             :                                  struct ospf_route *abr_or)
     123             : {
     124           5 :         struct ospf_route * or = NULL;
     125           5 :         struct route_node *rn;
     126           5 :         int ret;
     127             : 
     128           5 :         if (IS_DEBUG_OSPF_EVENT)
     129           5 :                 zlog_debug("%s: considering %pFX", __func__, p);
     130             : 
     131             :         /* Find a route to the same dest */
     132           5 :         rn = route_node_get(rtrs, (struct prefix *)p);
     133             : 
     134           5 :         if (rn->info == NULL)
     135             :                 /* This is a new route */
     136           5 :                 rn->info = list_new();
     137             :         else {
     138           0 :                 struct ospf_area *or_area;
     139           0 :                 or_area = ospf_area_lookup_by_area_id(ospf,
     140             :                                                       new_or->u.std.area_id);
     141           0 :                 assert(or_area);
     142             :                 /* This is an additional route */
     143           0 :                 route_unlock_node(rn);
     144           0 :                 or = ospf_find_asbr_route_through_area(rtrs, p, or_area);
     145             :         }
     146             : 
     147           5 :         if (or) {
     148           0 :                 if (IS_DEBUG_OSPF_EVENT)
     149           0 :                         zlog_debug(
     150             :                                 "%s: a route to the same ABR through the same area exists",
     151             :                                 __func__);
     152             :                 /* New route is better */
     153           0 :                 if ((ret = ospf_route_cmp(ospf, new_or, or)) < 0) {
     154           0 :                         listnode_delete(rn->info, or);
     155           0 :                         ospf_route_free(or);
     156             :                         /* proceed down */
     157             :                 }
     158             :                 /* Routes are the same */
     159           0 :                 else if (ret == 0) {
     160           0 :                         if (IS_DEBUG_OSPF_EVENT)
     161           0 :                                 zlog_debug("%s: merging the new route",
     162             :                                            __func__);
     163             : 
     164           0 :                         ospf_route_copy_nexthops(or, abr_or->paths);
     165           0 :                         ospf_route_free(new_or);
     166           0 :                         return;
     167             :                 }
     168             :                 /* New route is worse */
     169             :                 else {
     170           0 :                         if (IS_DEBUG_OSPF_EVENT)
     171           0 :                                 zlog_debug("%s: skipping the new route",
     172             :                                            __func__);
     173           0 :                         ospf_route_free(new_or);
     174           0 :                         return;
     175             :                 }
     176             :         }
     177             : 
     178           5 :         ospf_route_copy_nexthops(new_or, abr_or->paths);
     179             : 
     180           5 :         if (IS_DEBUG_OSPF_EVENT)
     181           5 :                 zlog_debug("%s: adding the new route", __func__);
     182             : 
     183           5 :         listnode_add(rn->info, new_or);
     184             : }
     185             : 
     186             : 
     187          86 : static int process_summary_lsa(struct ospf_area *area, struct route_table *rt,
     188             :                                struct route_table *rtrs, struct ospf_lsa *lsa)
     189             : {
     190          86 :         struct ospf *ospf = area->ospf;
     191          86 :         struct ospf_area_range *range;
     192          86 :         struct ospf_route *abr_or, *new_or;
     193          86 :         struct summary_lsa *sl;
     194          86 :         struct prefix_ipv4 p, abr;
     195          86 :         uint32_t metric;
     196             : 
     197          86 :         if (lsa == NULL)
     198             :                 return 0;
     199             : 
     200          86 :         sl = (struct summary_lsa *)lsa->data;
     201             : 
     202          86 :         if (IS_DEBUG_OSPF_EVENT)
     203          86 :                 zlog_debug("%s: LS ID: %pI4", __func__, &sl->header.id);
     204             : 
     205          86 :         metric = GET_METRIC(sl->metric);
     206             : 
     207          86 :         if (metric == OSPF_LS_INFINITY)
     208             :                 return 0;
     209             : 
     210          86 :         if (IS_LSA_MAXAGE(lsa))
     211          13 :                 return 0;
     212             : 
     213          73 :         if (ospf_lsa_is_self_originated(area->ospf, lsa))
     214             :                 return 0;
     215             : 
     216          47 :         p.family = AF_INET;
     217          47 :         p.prefix = sl->header.id;
     218             : 
     219          47 :         if (sl->header.type == OSPF_SUMMARY_LSA)
     220          34 :                 p.prefixlen = ip_masklen(sl->mask);
     221             :         else
     222          13 :                 p.prefixlen = IPV4_MAX_BITLEN;
     223             : 
     224          47 :         apply_mask_ipv4(&p);
     225             : 
     226          47 :         if (sl->header.type == OSPF_SUMMARY_LSA
     227          34 :             && (range = ospf_area_range_match_any(ospf, &p))
     228           0 :             && ospf_area_range_active(range))
     229             :                 return 0;
     230             : 
     231             :         /* XXX: This check seems dubious to me. If an ABR has already decided
     232             :          * to consider summaries received in this area, then why would one wish
     233             :          * to exclude default?
     234             :          */
     235          47 :         if (IS_OSPF_ABR(ospf) && ospf->abr_type != OSPF_ABR_STAND
     236           0 :             && area->external_routing != OSPF_AREA_DEFAULT
     237           0 :             && p.prefix.s_addr == OSPF_DEFAULT_DESTINATION && p.prefixlen == 0)
     238             :                 return 0; /* Ignore summary default from a stub area */
     239             : 
     240          47 :         abr.family = AF_INET;
     241          47 :         abr.prefix = sl->header.adv_router;
     242          47 :         abr.prefixlen = IPV4_MAX_BITLEN;
     243          47 :         apply_mask_ipv4(&abr);
     244             : 
     245          47 :         abr_or = ospf_find_abr_route(rtrs, &abr, area);
     246             : 
     247          47 :         if (abr_or == NULL)
     248             :                 return 0;
     249             : 
     250          18 :         new_or = ospf_route_new();
     251          18 :         new_or->type = OSPF_DESTINATION_NETWORK;
     252          18 :         new_or->id = sl->header.id;
     253          18 :         new_or->mask = sl->mask;
     254          18 :         new_or->u.std.options = sl->header.options;
     255          18 :         new_or->u.std.origin = (struct lsa_header *)sl;
     256          18 :         new_or->cost = abr_or->cost + metric;
     257          18 :         new_or->u.std.area_id = area->area_id;
     258          18 :         new_or->u.std.external_routing = area->external_routing;
     259          18 :         new_or->path_type = OSPF_PATH_INTER_AREA;
     260             : 
     261          18 :         if (sl->header.type == OSPF_SUMMARY_LSA)
     262          13 :                 ospf_ia_network_route(ospf, rt, &p, new_or, abr_or);
     263             :         else {
     264           5 :                 new_or->type = OSPF_DESTINATION_ROUTER;
     265           5 :                 new_or->u.std.flags = ROUTER_LSA_EXTERNAL;
     266           5 :                 ospf_ia_router_route(ospf, rtrs, &p, new_or, abr_or);
     267             :         }
     268             : 
     269             :         return 0;
     270             : }
     271             : 
     272         104 : static void ospf_examine_summaries(struct ospf_area *area,
     273             :                                    struct route_table *lsdb_rt,
     274             :                                    struct route_table *rt,
     275             :                                    struct route_table *rtrs)
     276             : {
     277         104 :         struct ospf_lsa *lsa;
     278         104 :         struct route_node *rn;
     279             : 
     280         226 :         LSDB_LOOP (lsdb_rt, rn, lsa)
     281          86 :                 process_summary_lsa(area, rt, rtrs, lsa);
     282         104 : }
     283             : 
     284           3 : int ospf_area_is_transit(struct ospf_area *area)
     285             : {
     286           3 :         return (area->transit == OSPF_TRANSIT_TRUE)
     287           3 :                || ospf_full_virtual_nbrs(
     288             :                           area); /* Cisco forgets to set the V-bit :( */
     289             : }
     290             : 
     291           0 : static void ospf_update_network_route(struct ospf *ospf, struct route_table *rt,
     292             :                                       struct route_table *rtrs,
     293             :                                       struct summary_lsa *lsa,
     294             :                                       struct prefix_ipv4 *p,
     295             :                                       struct ospf_area *area)
     296             : {
     297           0 :         struct route_node *rn;
     298           0 :         struct ospf_route * or, *abr_or, *new_or;
     299           0 :         struct prefix_ipv4 abr;
     300           0 :         uint32_t cost;
     301             : 
     302           0 :         abr.family = AF_INET;
     303           0 :         abr.prefix = lsa->header.adv_router;
     304           0 :         abr.prefixlen = IPV4_MAX_BITLEN;
     305           0 :         apply_mask_ipv4(&abr);
     306             : 
     307           0 :         abr_or = ospf_find_abr_route(rtrs, &abr, area);
     308             : 
     309           0 :         if (abr_or == NULL) {
     310           0 :                 if (IS_DEBUG_OSPF_EVENT)
     311           0 :                         zlog_debug("%s: can't find a route to the ABR",
     312             :                                    __func__);
     313           0 :                 return;
     314             :         }
     315             : 
     316           0 :         cost = abr_or->cost + GET_METRIC(lsa->metric);
     317             : 
     318           0 :         rn = route_node_lookup(rt, (struct prefix *)p);
     319             : 
     320           0 :         if (!rn) {
     321           0 :                 if (ospf->abr_type != OSPF_ABR_SHORTCUT)
     322             :                         return; /* Standard ABR can update only already
     323             :                                    installed
     324             :                                    backbone paths */
     325           0 :                 if (IS_DEBUG_OSPF_EVENT)
     326           0 :                         zlog_debug("%s: Allowing Shortcut ABR to add new route",
     327             :                                    __func__);
     328           0 :                 new_or = ospf_route_new();
     329           0 :                 new_or->type = OSPF_DESTINATION_NETWORK;
     330           0 :                 new_or->id = lsa->header.id;
     331           0 :                 new_or->mask = lsa->mask;
     332           0 :                 new_or->u.std.options = lsa->header.options;
     333           0 :                 new_or->u.std.origin = (struct lsa_header *)lsa;
     334           0 :                 new_or->cost = cost;
     335           0 :                 new_or->u.std.area_id = area->area_id;
     336           0 :                 new_or->u.std.external_routing = area->external_routing;
     337           0 :                 new_or->path_type = OSPF_PATH_INTER_AREA;
     338           0 :                 ospf_route_add(rt, p, new_or, abr_or);
     339             : 
     340           0 :                 return;
     341             :         } else {
     342           0 :                 route_unlock_node(rn);
     343           0 :                 if (rn->info == NULL)
     344             :                         return;
     345             :         }
     346             : 
     347           0 :         or = rn->info;
     348             : 
     349           0 :         if (or->path_type != OSPF_PATH_INTRA_AREA &&
     350             :             or->path_type != OSPF_PATH_INTER_AREA) {
     351           0 :                 if (IS_DEBUG_OSPF_EVENT)
     352           0 :                         zlog_debug("%s: ERR: path type is wrong", __func__);
     353           0 :                 return;
     354             :         }
     355             : 
     356           0 :         if (ospf->abr_type == OSPF_ABR_SHORTCUT) {
     357           0 :                 if (
     358             :                         or->path_type == OSPF_PATH_INTRA_AREA
     359           0 :                                   && !OSPF_IS_AREA_ID_BACKBONE(
     360             :                                              or->u.std.area_id)) {
     361           0 :                         if (IS_DEBUG_OSPF_EVENT)
     362           0 :                                 zlog_debug(
     363             :                                         "%s: Shortcut: this intra-area path is not backbone",
     364             :                                         __func__);
     365           0 :                         return;
     366             :                 }
     367             :         } else /* Not Shortcut ABR */
     368             :         {
     369           0 :                 if (!OSPF_IS_AREA_ID_BACKBONE(or->u.std.area_id)) {
     370           0 :                         if (IS_DEBUG_OSPF_EVENT)
     371           0 :                                 zlog_debug("%s: route is not BB-associated",
     372             :                                            __func__);
     373           0 :                         return; /* We can update only BB routes */
     374             :                 }
     375             :         }
     376             : 
     377           0 :         if (or->cost < cost) {
     378           0 :                 if (IS_DEBUG_OSPF_EVENT)
     379           0 :                         zlog_debug("%s: new route is worse", __func__);
     380           0 :                 return;
     381             :         }
     382             : 
     383           0 :         if (or->cost == cost) {
     384           0 :                 if (IS_DEBUG_OSPF_EVENT)
     385           0 :                         zlog_debug(
     386             :                                 "%s: new route is same distance, adding nexthops",
     387             :                                 __func__);
     388           0 :                 ospf_route_copy_nexthops(or, abr_or->paths);
     389             :         }
     390             : 
     391           0 :         if (or->cost > cost) {
     392           0 :                 if (IS_DEBUG_OSPF_EVENT)
     393           0 :                         zlog_debug(
     394             :                                 "%s: new route is better, overriding nexthops",
     395             :                                 __func__);
     396           0 :                 ospf_route_subst_nexthops(or, abr_or->paths);
     397           0 :                 or->cost = cost;
     398             : 
     399           0 :                 if ((ospf->abr_type == OSPF_ABR_SHORTCUT)
     400           0 :                     && !OSPF_IS_AREA_ID_BACKBONE(or->u.std.area_id)) {
     401           0 :                         or->path_type = OSPF_PATH_INTER_AREA;
     402           0 :                         or->u.std.area_id = area->area_id;
     403           0 :                         or->u.std.external_routing = area->external_routing;
     404             :                         /* Note that we can do this only in Shortcut ABR mode,
     405             :                            because standard ABR must leave the route type and
     406             :                            area
     407             :                            unchanged
     408             :                         */
     409             :                 }
     410             :         }
     411             : }
     412             : 
     413           0 : static void ospf_update_router_route(struct ospf *ospf,
     414             :                                      struct route_table *rtrs,
     415             :                                      struct summary_lsa *lsa,
     416             :                                      struct prefix_ipv4 *p,
     417             :                                      struct ospf_area *area)
     418             : {
     419           0 :         struct ospf_route * or, *abr_or, *new_or;
     420           0 :         struct prefix_ipv4 abr;
     421           0 :         uint32_t cost;
     422             : 
     423           0 :         abr.family = AF_INET;
     424           0 :         abr.prefix = lsa->header.adv_router;
     425           0 :         abr.prefixlen = IPV4_MAX_BITLEN;
     426           0 :         apply_mask_ipv4(&abr);
     427             : 
     428           0 :         abr_or = ospf_find_abr_route(rtrs, &abr, area);
     429             : 
     430           0 :         if (abr_or == NULL) {
     431           0 :                 if (IS_DEBUG_OSPF_EVENT)
     432           0 :                         zlog_debug("%s: can't find a route to the ABR",
     433             :                                    __func__);
     434           0 :                 return;
     435             :         }
     436             : 
     437           0 :         cost = abr_or->cost + GET_METRIC(lsa->metric);
     438             : 
     439             :         /* First try to find a backbone path,
     440             :            because standard ABR can update only BB-associated paths */
     441             : 
     442           0 :         if ((ospf->backbone == NULL) && (ospf->abr_type != OSPF_ABR_SHORTCUT))
     443             :                 return; /* no BB area, not Shortcut ABR, exiting */
     444             : 
     445             :         /* find the backbone route, if possible */
     446           0 :         if ((ospf->backbone == NULL)
     447           0 :             || !(or = ospf_find_asbr_route_through_area(rtrs, p,
     448             :                                                         ospf->backbone))) {
     449           0 :                 if (ospf->abr_type != OSPF_ABR_SHORTCUT)
     450             : 
     451             :                         /* route to ASBR through the BB not found
     452             :                            the router is not Shortcut ABR, exiting */
     453             : 
     454             :                         return;
     455             :                 else
     456             :                 /* We're a Shortcut ABR*/
     457             :                 {
     458             :                         /* Let it either add a new router or update the route
     459             :                            through the same (non-BB) area. */
     460             : 
     461           0 :                         new_or = ospf_route_new();
     462           0 :                         new_or->type = OSPF_DESTINATION_ROUTER;
     463           0 :                         new_or->id = lsa->header.id;
     464           0 :                         new_or->mask = lsa->mask;
     465           0 :                         new_or->u.std.options = lsa->header.options;
     466           0 :                         new_or->u.std.origin = (struct lsa_header *)lsa;
     467           0 :                         new_or->cost = cost;
     468           0 :                         new_or->u.std.area_id = area->area_id;
     469           0 :                         new_or->u.std.external_routing = area->external_routing;
     470           0 :                         new_or->path_type = OSPF_PATH_INTER_AREA;
     471           0 :                         new_or->u.std.flags = ROUTER_LSA_EXTERNAL;
     472           0 :                         ospf_ia_router_route(ospf, rtrs, p, new_or, abr_or);
     473             : 
     474           0 :                         return;
     475             :                 }
     476             :         }
     477             : 
     478             :         /* At this point the "or" is always bb-associated */
     479             : 
     480           0 :         if (!(or->u.std.flags & ROUTER_LSA_EXTERNAL)) {
     481           0 :                 if (IS_DEBUG_OSPF_EVENT)
     482           0 :                         zlog_debug("%s: the remote router is not an ASBR",
     483             :                                    __func__);
     484           0 :                 return;
     485             :         }
     486             : 
     487           0 :         if (or->path_type != OSPF_PATH_INTRA_AREA &&
     488             :             or->path_type != OSPF_PATH_INTER_AREA)
     489             :                 return;
     490             : 
     491           0 :         if (or->cost < cost)
     492             :                 return;
     493             : 
     494           0 :         else if (or->cost == cost)
     495           0 :                 ospf_route_copy_nexthops(or, abr_or->paths);
     496             : 
     497           0 :         else if (or->cost > cost) {
     498           0 :                 ospf_route_subst_nexthops(or, abr_or->paths);
     499           0 :                 or->cost = cost;
     500             : 
     501             :                 /* Even if the ABR runs in Shortcut mode, we can't change
     502             :                    the path type and area, because the "or" is always
     503             :                    bb-associated
     504             :                    at this point and even Shortcut ABR can't change these
     505             :                    attributes */
     506             :         }
     507             : }
     508             : 
     509           0 : static int process_transit_summary_lsa(struct ospf_area *area,
     510             :                                        struct route_table *rt,
     511             :                                        struct route_table *rtrs,
     512             :                                        struct ospf_lsa *lsa)
     513             : {
     514           0 :         struct ospf *ospf = area->ospf;
     515           0 :         struct summary_lsa *sl;
     516           0 :         struct prefix_ipv4 p;
     517           0 :         uint32_t metric;
     518             : 
     519           0 :         if (lsa == NULL)
     520             :                 return 0;
     521             : 
     522           0 :         sl = (struct summary_lsa *)lsa->data;
     523             : 
     524           0 :         if (IS_DEBUG_OSPF_EVENT)
     525           0 :                 zlog_debug("%s: LS ID: %pI4", __func__, &lsa->data->id);
     526           0 :         metric = GET_METRIC(sl->metric);
     527             : 
     528           0 :         if (metric == OSPF_LS_INFINITY) {
     529           0 :                 if (IS_DEBUG_OSPF_EVENT)
     530           0 :                         zlog_debug("%s: metric is infinity, skip", __func__);
     531           0 :                 return 0;
     532             :         }
     533             : 
     534           0 :         if (IS_LSA_MAXAGE(lsa)) {
     535           0 :                 if (IS_DEBUG_OSPF_EVENT)
     536           0 :                         zlog_debug("%s: This LSA is too old", __func__);
     537           0 :                 return 0;
     538             :         }
     539             : 
     540           0 :         if (ospf_lsa_is_self_originated(area->ospf, lsa)) {
     541           0 :                 if (IS_DEBUG_OSPF_EVENT)
     542           0 :                         zlog_debug("%s: This LSA is mine, skip", __func__);
     543           0 :                 return 0;
     544             :         }
     545             : 
     546           0 :         p.family = AF_INET;
     547           0 :         p.prefix = sl->header.id;
     548             : 
     549           0 :         if (sl->header.type == OSPF_SUMMARY_LSA)
     550           0 :                 p.prefixlen = ip_masklen(sl->mask);
     551             :         else
     552           0 :                 p.prefixlen = IPV4_MAX_BITLEN;
     553             : 
     554           0 :         apply_mask_ipv4(&p);
     555             : 
     556           0 :         if (sl->header.type == OSPF_SUMMARY_LSA)
     557           0 :                 ospf_update_network_route(ospf, rt, rtrs, sl, &p, area);
     558             :         else
     559           0 :                 ospf_update_router_route(ospf, rtrs, sl, &p, area);
     560             : 
     561             :         return 0;
     562             : }
     563             : 
     564           0 : static void ospf_examine_transit_summaries(struct ospf_area *area,
     565             :                                            struct route_table *lsdb_rt,
     566             :                                            struct route_table *rt,
     567             :                                            struct route_table *rtrs)
     568             : {
     569           0 :         struct ospf_lsa *lsa;
     570           0 :         struct route_node *rn;
     571             : 
     572           0 :         LSDB_LOOP (lsdb_rt, rn, lsa)
     573           0 :                 process_transit_summary_lsa(area, rt, rtrs, lsa);
     574           0 : }
     575             : 
     576          49 : void ospf_ia_routing(struct ospf *ospf, struct route_table *rt,
     577             :                      struct route_table *rtrs)
     578             : {
     579          49 :         struct listnode *node;
     580          49 :         struct ospf_area *area;
     581             : 
     582          49 :         if (IS_DEBUG_OSPF_EVENT)
     583          49 :                 zlog_debug("%s:start", __func__);
     584             : 
     585          49 :         if (IS_OSPF_ABR(ospf)) {
     586           9 :                 switch (ospf->abr_type) {
     587           0 :                 case OSPF_ABR_STAND:
     588           0 :                         if (IS_DEBUG_OSPF_EVENT)
     589           0 :                                 zlog_debug("%s:Standard ABR", __func__);
     590             : 
     591           0 :                         if ((area = ospf->backbone)) {
     592           0 :                                 if (IS_DEBUG_OSPF_EVENT) {
     593           0 :                                         zlog_debug(
     594             :                                                 "%s:backbone area found, examining summaries",
     595             :                                                 __func__);
     596             :                                 }
     597             : 
     598           0 :                                 OSPF_EXAMINE_SUMMARIES_ALL(area, rt, rtrs);
     599             : 
     600           0 :                                 for (ALL_LIST_ELEMENTS_RO(ospf->areas, node,
     601             :                                                           area))
     602           0 :                                         if (area != ospf->backbone)
     603           0 :                                                 if (ospf_area_is_transit(area))
     604           0 :                                                         OSPF_EXAMINE_TRANSIT_SUMMARIES_ALL(
     605             :                                                                 area, rt, rtrs);
     606           0 :                         } else if (IS_DEBUG_OSPF_EVENT)
     607           0 :                                 zlog_debug("%s:backbone area NOT found",
     608             :                                            __func__);
     609             :                         break;
     610           9 :                 case OSPF_ABR_IBM:
     611             :                 case OSPF_ABR_CISCO:
     612           9 :                         if (IS_DEBUG_OSPF_EVENT)
     613           9 :                                 zlog_debug("%s:Alternative Cisco/IBM ABR",
     614             :                                            __func__);
     615           9 :                         area = ospf->backbone; /* Find the BB */
     616             : 
     617             :                         /* If we have an active BB connection */
     618           9 :                         if (area && ospf_act_bb_connection(ospf)) {
     619           3 :                                 if (IS_DEBUG_OSPF_EVENT) {
     620           3 :                                         zlog_debug(
     621             :                                                 "%s: backbone area found, examining BB summaries",
     622             :                                                 __func__);
     623             :                                 }
     624             : 
     625           3 :                                 OSPF_EXAMINE_SUMMARIES_ALL(area, rt, rtrs);
     626             : 
     627          12 :                                 for (ALL_LIST_ELEMENTS_RO(ospf->areas, node,
     628             :                                                           area))
     629           6 :                                         if (area != ospf->backbone)
     630           3 :                                                 if (ospf_area_is_transit(area))
     631           0 :                                                         OSPF_EXAMINE_TRANSIT_SUMMARIES_ALL(
     632             :                                                                 area, rt, rtrs);
     633             :                         } else { /* No active BB connection--consider all areas
     634             :                                     */
     635           6 :                                 if (IS_DEBUG_OSPF_EVENT)
     636           6 :                                         zlog_debug(
     637             :                                                 "%s: Active BB connection not found",
     638             :                                                 __func__);
     639          24 :                                 for (ALL_LIST_ELEMENTS_RO(ospf->areas, node,
     640             :                                                           area))
     641          12 :                                         OSPF_EXAMINE_SUMMARIES_ALL(area, rt,
     642             :                                                                    rtrs);
     643             :                         }
     644             :                         break;
     645           0 :                 case OSPF_ABR_SHORTCUT:
     646           0 :                         if (IS_DEBUG_OSPF_EVENT)
     647           0 :                                 zlog_debug("%s:Alternative Shortcut", __func__);
     648           0 :                         area = ospf->backbone; /* Find the BB */
     649             : 
     650             :                         /* If we have an active BB connection */
     651           0 :                         if (area && ospf_act_bb_connection(ospf)) {
     652           0 :                                 if (IS_DEBUG_OSPF_EVENT) {
     653           0 :                                         zlog_debug(
     654             :                                                 "%s: backbone area found, examining BB summaries",
     655             :                                                 __func__);
     656             :                                 }
     657           0 :                                 OSPF_EXAMINE_SUMMARIES_ALL(area, rt, rtrs);
     658             :                         }
     659             : 
     660           0 :                         for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area))
     661           0 :                                 if (area != ospf->backbone)
     662           0 :                                         if (ospf_area_is_transit(area)
     663           0 :                                             || ((area->shortcut_configured
     664             :                                                  != OSPF_SHORTCUT_DISABLE)
     665           0 :                                                 && ((ospf->backbone == NULL)
     666           0 :                                                     || ((area->shortcut_configured
     667             :                                                          == OSPF_SHORTCUT_ENABLE)
     668           0 :                                                         && area->shortcut_capability))))
     669           0 :                                                 OSPF_EXAMINE_TRANSIT_SUMMARIES_ALL(
     670             :                                                         area, rt, rtrs);
     671             :                         break;
     672             :                 default:
     673             :                         break;
     674             :                 }
     675             :         } else {
     676          40 :                 if (IS_DEBUG_OSPF_EVENT)
     677          40 :                         zlog_debug("%s:not ABR, considering all areas",
     678             :                                    __func__);
     679             : 
     680         117 :                 for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area))
     681          37 :                         OSPF_EXAMINE_SUMMARIES_ALL(area, rt, rtrs);
     682             :         }
     683          49 : }

Generated by: LCOV version v1.16-topotato