Coverage Report

Created: 2026-01-01 06:18

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