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