blob: 29604c614d89dc9d4460be2dd0d2be60e427030e [file] [log] [blame]
paul718e3742002-12-13 20:15:29 +00001/*
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
49#define DEBUG
50
paul4dadc292005-05-06 21:37:42 +000051static struct ospf_route *
paul718e3742002-12-13 20:15:29 +000052ospf_find_abr_route (struct route_table *rtrs,
53 struct prefix_ipv4 *abr,
54 struct ospf_area *area)
55{
56 struct route_node *rn;
57 struct ospf_route *or;
hasso52dc7ee2004-09-23 19:18:23 +000058 struct listnode *node;
paul718e3742002-12-13 20:15:29 +000059
60 if ((rn = route_node_lookup (rtrs, (struct prefix *) abr)) == NULL)
61 return NULL;
62
63 route_unlock_node (rn);
64
paul1eb8ef22005-04-07 07:30:20 +000065 for (ALL_LIST_ELEMENTS_RO ((struct list *) rn->info, node, or))
66 if (IPV4_ADDR_SAME (&or->u.std.area_id, &area->area_id)
67 && (or->u.std.flags & ROUTER_LSA_BORDER))
68 return or;
paul718e3742002-12-13 20:15:29 +000069
70 return NULL;
71}
72
paul4dadc292005-05-06 21:37:42 +000073static void
paul96735ee2003-08-10 02:51:22 +000074ospf_ia_network_route (struct ospf *ospf, struct route_table *rt,
75 struct prefix_ipv4 *p, struct ospf_route *new_or,
76 struct ospf_route *abr_or)
paul718e3742002-12-13 20:15:29 +000077{
78 struct route_node *rn1;
79 struct ospf_route *or;
80
81 if (IS_DEBUG_OSPF_EVENT)
ajs60925302004-12-08 17:45:02 +000082 zlog_debug ("ospf_ia_network_route(): processing summary route to %s/%d",
paul718e3742002-12-13 20:15:29 +000083 inet_ntoa (p->prefix), p->prefixlen);
84
85 /* Find a route to the same dest */
86 if ((rn1 = route_node_lookup (rt, (struct prefix *) p)))
87 {
88 int res;
89
90 route_unlock_node (rn1);
91
92 if ((or = rn1->info))
93 {
94 if (IS_DEBUG_OSPF_EVENT)
ajs60925302004-12-08 17:45:02 +000095 zlog_debug ("ospf_ia_network_route(): "
paul718e3742002-12-13 20:15:29 +000096 "Found a route to the same network");
97 /* Check the existing route. */
paul96735ee2003-08-10 02:51:22 +000098 if ((res = ospf_route_cmp (ospf, new_or, or)) < 0)
paul718e3742002-12-13 20:15:29 +000099 {
100 /* New route is better, so replace old one. */
101 ospf_route_subst (rn1, new_or, abr_or);
102 }
103 else if (res == 0)
104 {
105 /* New and old route are equal, so next hops can be added. */
106 route_lock_node (rn1);
paul96735ee2003-08-10 02:51:22 +0000107 ospf_route_copy_nexthops (or, abr_or->paths);
paul718e3742002-12-13 20:15:29 +0000108 route_unlock_node (rn1);
109
110 /* new route can be deleted, because existing route has been updated. */
111 ospf_route_free (new_or);
112 }
113 else
114 {
115 /* New route is worse, so free it. */
116 ospf_route_free (new_or);
117 return;
118 }
119 } /* if (or)*/
120 } /*if (rn1)*/
121 else
122 { /* no route */
123 if (IS_DEBUG_OSPF_EVENT)
ajs60925302004-12-08 17:45:02 +0000124 zlog_debug ("ospf_ia_network_route(): add new route to %s/%d",
paul718e3742002-12-13 20:15:29 +0000125 inet_ntoa (p->prefix), p->prefixlen);
126 ospf_route_add (rt, p, new_or, abr_or);
127 }
128}
129
paul4dadc292005-05-06 21:37:42 +0000130static void
paul96735ee2003-08-10 02:51:22 +0000131ospf_ia_router_route (struct ospf *ospf, struct route_table *rtrs,
132 struct prefix_ipv4 *p,
paul718e3742002-12-13 20:15:29 +0000133 struct ospf_route *new_or, struct ospf_route *abr_or)
134{
paul718e3742002-12-13 20:15:29 +0000135 struct ospf_route *or = NULL;
paul96735ee2003-08-10 02:51:22 +0000136 struct route_node *rn;
paul718e3742002-12-13 20:15:29 +0000137 int ret;
138
139 if (IS_DEBUG_OSPF_EVENT)
ajs60925302004-12-08 17:45:02 +0000140 zlog_debug ("ospf_ia_router_route(): considering %s/%d",
paul718e3742002-12-13 20:15:29 +0000141 inet_ntoa (p->prefix), p->prefixlen);
142 /* Find a route to the same dest */
paul96735ee2003-08-10 02:51:22 +0000143 rn = route_node_get (rtrs, (struct prefix *) p);
paul718e3742002-12-13 20:15:29 +0000144
145 if (rn->info == NULL)
146 /* This is a new route */
147 rn->info = list_new ();
148 else
149 {
150 struct ospf_area *or_area;
paul96735ee2003-08-10 02:51:22 +0000151 or_area = ospf_area_lookup_by_area_id (ospf, new_or->u.std.area_id);
paul718e3742002-12-13 20:15:29 +0000152 assert (or_area);
153 /* This is an additional route */
154 route_unlock_node (rn);
paul96735ee2003-08-10 02:51:22 +0000155 or = ospf_find_asbr_route_through_area (rtrs, p, or_area);
paul718e3742002-12-13 20:15:29 +0000156 }
157
158 if (or)
159 {
160 if (IS_DEBUG_OSPF_EVENT)
ajs60925302004-12-08 17:45:02 +0000161 zlog_debug ("ospf_ia_router_route(): "
paul718e3742002-12-13 20:15:29 +0000162 "a route to the same ABR through the same area exists");
163 /* New route is better */
paul96735ee2003-08-10 02:51:22 +0000164 if ((ret = ospf_route_cmp (ospf, new_or, or)) < 0)
paul718e3742002-12-13 20:15:29 +0000165 {
166 listnode_delete (rn->info, or);
167 ospf_route_free (or);
168 /* proceed down */
169 }
170 /* Routes are the same */
171 else if (ret == 0)
172 {
173 if (IS_DEBUG_OSPF_EVENT)
ajs60925302004-12-08 17:45:02 +0000174 zlog_debug ("ospf_ia_router_route(): merging the new route");
paul718e3742002-12-13 20:15:29 +0000175
paul96735ee2003-08-10 02:51:22 +0000176 ospf_route_copy_nexthops (or, abr_or->paths);
paul718e3742002-12-13 20:15:29 +0000177 ospf_route_free (new_or);
178 return;
179 }
180 /* New route is worse */
181 else
182 {
183 if (IS_DEBUG_OSPF_EVENT)
ajs60925302004-12-08 17:45:02 +0000184 zlog_debug ("ospf_ia_router_route(): skipping the new route");
paul718e3742002-12-13 20:15:29 +0000185 ospf_route_free (new_or);
186 return;
187 }
188 }
189
paul96735ee2003-08-10 02:51:22 +0000190 ospf_route_copy_nexthops (new_or, abr_or->paths);
paul718e3742002-12-13 20:15:29 +0000191
192 if (IS_DEBUG_OSPF_EVENT)
ajs60925302004-12-08 17:45:02 +0000193 zlog_debug ("ospf_ia_router_route(): adding the new route");
paul718e3742002-12-13 20:15:29 +0000194
195 listnode_add (rn->info, new_or);
196}
197
198
paul4dadc292005-05-06 21:37:42 +0000199static int
paul96735ee2003-08-10 02:51:22 +0000200process_summary_lsa (struct ospf_area *area, struct route_table *rt,
201 struct route_table *rtrs, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +0000202{
paul96735ee2003-08-10 02:51:22 +0000203 struct ospf *ospf = area->ospf;
paul718e3742002-12-13 20:15:29 +0000204 struct ospf_area_range *range;
205 struct ospf_route *abr_or, *new_or;
206 struct summary_lsa *sl;
207 struct prefix_ipv4 p, abr;
208 u_int32_t metric;
paul718e3742002-12-13 20:15:29 +0000209
paul96735ee2003-08-10 02:51:22 +0000210 if (lsa == NULL)
paul718e3742002-12-13 20:15:29 +0000211 return 0;
212
paul96735ee2003-08-10 02:51:22 +0000213 sl = (struct summary_lsa *) lsa->data;
paul718e3742002-12-13 20:15:29 +0000214
215 if (IS_DEBUG_OSPF_EVENT)
ajs60925302004-12-08 17:45:02 +0000216 zlog_debug ("process_summary_lsa(): LS ID: %s", inet_ntoa (sl->header.id));
paul718e3742002-12-13 20:15:29 +0000217
218 metric = GET_METRIC (sl->metric);
219
220 if (metric == OSPF_LS_INFINITY)
221 return 0;
222
paul96735ee2003-08-10 02:51:22 +0000223 if (IS_LSA_MAXAGE (lsa))
paul718e3742002-12-13 20:15:29 +0000224 return 0;
225
paul96735ee2003-08-10 02:51:22 +0000226 if (ospf_lsa_is_self_originated (area->ospf, lsa))
paul718e3742002-12-13 20:15:29 +0000227 return 0;
228
229 p.family = AF_INET;
230 p.prefix = sl->header.id;
231
232 if (sl->header.type == OSPF_SUMMARY_LSA)
233 p.prefixlen = ip_masklen (sl->mask);
234 else
235 p.prefixlen = IPV4_MAX_BITLEN;
236
237 apply_mask_ipv4 (&p);
238
239 if (sl->header.type == OSPF_SUMMARY_LSA &&
paul96735ee2003-08-10 02:51:22 +0000240 (range = ospf_area_range_match_any (ospf, &p)) &&
paul718e3742002-12-13 20:15:29 +0000241 ospf_area_range_active (range))
242 return 0;
243
paul05e85fa2004-11-12 10:52:19 +0000244 /* XXX: This check seems dubious to me. If an ABR has already decided
245 * to consider summaries received in this area, then why would one wish
246 * to exclude default?
247 */
248 if (IS_OSPF_ABR(ospf) &&
249 ospf->abr_type != OSPF_ABR_STAND &&
paul96735ee2003-08-10 02:51:22 +0000250 area->external_routing != OSPF_AREA_DEFAULT &&
paul718e3742002-12-13 20:15:29 +0000251 p.prefix.s_addr == OSPF_DEFAULT_DESTINATION &&
252 p.prefixlen == 0)
253 return 0; /* Ignore summary default from a stub area */
254
255 abr.family = AF_INET;
256 abr.prefix = sl->header.adv_router;
257 abr.prefixlen = IPV4_MAX_BITLEN;
258 apply_mask_ipv4 (&abr);
259
paul96735ee2003-08-10 02:51:22 +0000260 abr_or = ospf_find_abr_route (rtrs, &abr, area);
paul718e3742002-12-13 20:15:29 +0000261
262 if (abr_or == NULL)
263 return 0;
264
265 new_or = ospf_route_new ();
266 new_or->type = OSPF_DESTINATION_NETWORK;
267 new_or->id = sl->header.id;
268 new_or->mask = sl->mask;
269 new_or->u.std.options = sl->header.options;
270 new_or->u.std.origin = (struct lsa_header *) sl;
271 new_or->cost = abr_or->cost + metric;
paul96735ee2003-08-10 02:51:22 +0000272 new_or->u.std.area_id = area->area_id;
paul96735ee2003-08-10 02:51:22 +0000273 new_or->u.std.external_routing = area->external_routing;
paul718e3742002-12-13 20:15:29 +0000274 new_or->path_type = OSPF_PATH_INTER_AREA;
275
276 if (sl->header.type == OSPF_SUMMARY_LSA)
paul96735ee2003-08-10 02:51:22 +0000277 ospf_ia_network_route (ospf, rt, &p, new_or, abr_or);
paul718e3742002-12-13 20:15:29 +0000278 else
279 {
280 new_or->type = OSPF_DESTINATION_ROUTER;
281 new_or->u.std.flags = ROUTER_LSA_EXTERNAL;
paul96735ee2003-08-10 02:51:22 +0000282 ospf_ia_router_route (ospf, rtrs, &p, new_or, abr_or);
paul718e3742002-12-13 20:15:29 +0000283 }
284
285 return 0;
286}
287
paul4dadc292005-05-06 21:37:42 +0000288static void
paul96735ee2003-08-10 02:51:22 +0000289ospf_examine_summaries (struct ospf_area *area,
paul718e3742002-12-13 20:15:29 +0000290 struct route_table *lsdb_rt,
291 struct route_table *rt,
292 struct route_table *rtrs)
293{
paul96735ee2003-08-10 02:51:22 +0000294 struct ospf_lsa *lsa;
295 struct route_node *rn;
296
297 LSDB_LOOP (lsdb_rt, rn, lsa)
298 process_summary_lsa (area, rt, rtrs, lsa);
paul718e3742002-12-13 20:15:29 +0000299}
300
301int
302ospf_area_is_transit (struct ospf_area *area)
303{
304 return (area->transit == OSPF_TRANSIT_TRUE) ||
305 ospf_full_virtual_nbrs(area); /* Cisco forgets to set the V-bit :( */
306}
307
paul4dadc292005-05-06 21:37:42 +0000308static void
paul96735ee2003-08-10 02:51:22 +0000309ospf_update_network_route (struct ospf *ospf,
310 struct route_table *rt,
paul718e3742002-12-13 20:15:29 +0000311 struct route_table *rtrs,
312 struct summary_lsa *lsa,
313 struct prefix_ipv4 *p,
314 struct ospf_area *area)
315{
316 struct route_node *rn;
317 struct ospf_route *or, *abr_or, *new_or;
318 struct prefix_ipv4 abr;
319 u_int32_t cost;
320
321 abr.family = AF_INET;
322 abr.prefix =lsa->header.adv_router;
323 abr.prefixlen = IPV4_MAX_BITLEN;
324 apply_mask_ipv4 (&abr);
325
326 abr_or = ospf_find_abr_route (rtrs, &abr, area);
327
328 if (abr_or == NULL)
329 {
330 if (IS_DEBUG_OSPF_EVENT)
ajs60925302004-12-08 17:45:02 +0000331 zlog_debug ("ospf_update_network_route(): can't find a route to the ABR");
paul718e3742002-12-13 20:15:29 +0000332 return;
333 }
334
335 cost = abr_or->cost + GET_METRIC (lsa->metric);
336
337 rn = route_node_lookup (rt, (struct prefix *) p);
338
339 if (! rn)
340 {
paul96735ee2003-08-10 02:51:22 +0000341 if (ospf->abr_type != OSPF_ABR_SHORTCUT)
paul718e3742002-12-13 20:15:29 +0000342 return; /* Standard ABR can update only already installed
343 backbone paths */
344 if (IS_DEBUG_OSPF_EVENT)
ajs60925302004-12-08 17:45:02 +0000345 zlog_debug ("ospf_update_network_route(): "
paul718e3742002-12-13 20:15:29 +0000346 "Allowing Shortcut ABR to add new route");
347 new_or = ospf_route_new ();
348 new_or->type = OSPF_DESTINATION_NETWORK;
349 new_or->id = lsa->header.id;
350 new_or->mask = lsa->mask;
351 new_or->u.std.options = lsa->header.options;
352 new_or->u.std.origin = (struct lsa_header *) lsa;
353 new_or->cost = cost;
354 new_or->u.std.area_id = area->area_id;
paul718e3742002-12-13 20:15:29 +0000355 new_or->u.std.external_routing = area->external_routing;
paul718e3742002-12-13 20:15:29 +0000356 new_or->path_type = OSPF_PATH_INTER_AREA;
357 ospf_route_add (rt, p, new_or, abr_or);
358
359 return;
360 }
361 else
362 {
363 route_unlock_node (rn);
364 if (rn->info == NULL)
365 return;
366 }
367
368 or = rn->info;
369
370 if (or->path_type != OSPF_PATH_INTRA_AREA &&
371 or->path_type != OSPF_PATH_INTER_AREA)
372 {
373 if (IS_DEBUG_OSPF_EVENT)
ajs60925302004-12-08 17:45:02 +0000374 zlog_debug ("ospf_update_network_route(): ERR: path type is wrong");
paul718e3742002-12-13 20:15:29 +0000375 return;
376 }
377
paul96735ee2003-08-10 02:51:22 +0000378 if (ospf->abr_type == OSPF_ABR_SHORTCUT)
paul718e3742002-12-13 20:15:29 +0000379 {
380 if (or->path_type == OSPF_PATH_INTRA_AREA &&
381 !OSPF_IS_AREA_ID_BACKBONE (or->u.std.area_id))
382 {
383 if (IS_DEBUG_OSPF_EVENT)
ajs60925302004-12-08 17:45:02 +0000384 zlog_debug ("ospf_update_network_route(): Shortcut: "
paul718e3742002-12-13 20:15:29 +0000385 "this intra-area path is not backbone");
386 return;
387 }
388 }
389 else /* Not Shortcut ABR */
390 {
391 if (!OSPF_IS_AREA_ID_BACKBONE (or->u.std.area_id))
392 {
393 if (IS_DEBUG_OSPF_EVENT)
ajs60925302004-12-08 17:45:02 +0000394 zlog_debug ("ospf_update_network_route(): "
paul718e3742002-12-13 20:15:29 +0000395 "route is not BB-associated");
396 return; /* We can update only BB routes */
397 }
398 }
399
400 if (or->cost < cost)
401 {
402 if (IS_DEBUG_OSPF_EVENT)
ajs60925302004-12-08 17:45:02 +0000403 zlog_debug ("ospf_update_network_route(): new route is worse");
paul718e3742002-12-13 20:15:29 +0000404 return;
405 }
406
407 if (or->cost == cost)
408 {
409 if (IS_DEBUG_OSPF_EVENT)
ajs60925302004-12-08 17:45:02 +0000410 zlog_debug ("ospf_update_network_route(): "
paul718e3742002-12-13 20:15:29 +0000411 "new route is same distance, adding nexthops");
paul96735ee2003-08-10 02:51:22 +0000412 ospf_route_copy_nexthops (or, abr_or->paths);
paul718e3742002-12-13 20:15:29 +0000413 }
414
415 if (or->cost > cost)
416 {
417 if (IS_DEBUG_OSPF_EVENT)
ajs60925302004-12-08 17:45:02 +0000418 zlog_debug ("ospf_update_network_route(): "
paul718e3742002-12-13 20:15:29 +0000419 "new route is better, overriding nexthops");
paul96735ee2003-08-10 02:51:22 +0000420 ospf_route_subst_nexthops (or, abr_or->paths);
paul718e3742002-12-13 20:15:29 +0000421 or->cost = cost;
422
paul96735ee2003-08-10 02:51:22 +0000423 if ((ospf->abr_type == OSPF_ABR_SHORTCUT) &&
paul718e3742002-12-13 20:15:29 +0000424 !OSPF_IS_AREA_ID_BACKBONE (or->u.std.area_id))
425 {
426 or->path_type = OSPF_PATH_INTER_AREA;
427 or->u.std.area_id = area->area_id;
paul718e3742002-12-13 20:15:29 +0000428 or->u.std.external_routing = area->external_routing;
paul718e3742002-12-13 20:15:29 +0000429 /* Note that we can do this only in Shortcut ABR mode,
430 because standard ABR must leave the route type and area
431 unchanged
432 */
433 }
434 }
435}
436
paul4dadc292005-05-06 21:37:42 +0000437static void
paul96735ee2003-08-10 02:51:22 +0000438ospf_update_router_route (struct ospf *ospf,
439 struct route_table *rtrs,
paul718e3742002-12-13 20:15:29 +0000440 struct summary_lsa *lsa,
441 struct prefix_ipv4 *p,
442 struct ospf_area *area)
443{
444 struct ospf_route *or, *abr_or, *new_or;
445 struct prefix_ipv4 abr;
446 u_int32_t cost;
447
448 abr.family = AF_INET;
449 abr.prefix = lsa->header.adv_router;
450 abr.prefixlen = IPV4_MAX_BITLEN;
451 apply_mask_ipv4 (&abr);
452
453 abr_or = ospf_find_abr_route (rtrs, &abr, area);
454
455 if (abr_or == NULL)
456 {
457 if (IS_DEBUG_OSPF_EVENT)
ajs60925302004-12-08 17:45:02 +0000458 zlog_debug ("ospf_update_router_route(): can't find a route to the ABR");
paul718e3742002-12-13 20:15:29 +0000459 return;
460 }
461
462 cost = abr_or->cost + GET_METRIC (lsa->metric);
463
464 /* First try to find a backbone path,
465 because standard ABR can update only BB-associated paths */
466
paul96735ee2003-08-10 02:51:22 +0000467 if ((ospf->backbone == NULL) &&
468 (ospf->abr_type != OSPF_ABR_SHORTCUT))
paul718e3742002-12-13 20:15:29 +0000469
470 /* no BB area, not Shortcut ABR, exiting */
471 return;
472
paul96735ee2003-08-10 02:51:22 +0000473 or = ospf_find_asbr_route_through_area (rtrs, p, ospf->backbone);
paul718e3742002-12-13 20:15:29 +0000474
475 if (or == NULL)
476 {
paul96735ee2003-08-10 02:51:22 +0000477 if (ospf->abr_type != OSPF_ABR_SHORTCUT)
paul718e3742002-12-13 20:15:29 +0000478
479 /* route to ASBR through the BB not found
480 the router is not Shortcut ABR, exiting */
481
482 return;
483 else
484 /* We're a Shortcut ABR*/
485 {
486 /* Let it either add a new router or update the route
487 through the same (non-BB) area. */
488
489 new_or = ospf_route_new ();
490 new_or->type = OSPF_DESTINATION_ROUTER;
491 new_or->id = lsa->header.id;
492 new_or->mask = lsa->mask;
493 new_or->u.std.options = lsa->header.options;
494 new_or->u.std.origin = (struct lsa_header *)lsa;
495 new_or->cost = cost;
496 new_or->u.std.area_id = area->area_id;
paul718e3742002-12-13 20:15:29 +0000497 new_or->u.std.external_routing = area->external_routing;
paul718e3742002-12-13 20:15:29 +0000498 new_or->path_type = OSPF_PATH_INTER_AREA;
499 new_or->u.std.flags = ROUTER_LSA_EXTERNAL;
paul96735ee2003-08-10 02:51:22 +0000500 ospf_ia_router_route (ospf, rtrs, p, new_or, abr_or);
paul718e3742002-12-13 20:15:29 +0000501
502 return;
503 }
504 }
505
506 /* At this point the "or" is always bb-associated */
507
508 if (!(or->u.std.flags & ROUTER_LSA_EXTERNAL))
509 {
510 if (IS_DEBUG_OSPF_EVENT)
ajs60925302004-12-08 17:45:02 +0000511 zlog_debug ("ospf_upd_router_route(): the remote router is not an ASBR");
paul718e3742002-12-13 20:15:29 +0000512 return;
513 }
514
515 if (or->path_type != OSPF_PATH_INTRA_AREA &&
516 or->path_type != OSPF_PATH_INTER_AREA)
517 return;
518
519 if (or->cost < cost)
520 return;
521
522 else if (or->cost == cost)
paul96735ee2003-08-10 02:51:22 +0000523 ospf_route_copy_nexthops (or, abr_or->paths);
paul718e3742002-12-13 20:15:29 +0000524
525 else if (or->cost > cost)
526 {
paul96735ee2003-08-10 02:51:22 +0000527 ospf_route_subst_nexthops (or, abr_or->paths);
paul718e3742002-12-13 20:15:29 +0000528 or->cost = cost;
529
530 /* Even if the ABR runs in Shortcut mode, we can't change
531 the path type and area, because the "or" is always bb-associated
532 at this point and even Shortcut ABR can't change these attributes */
533 }
534}
535
paul4dadc292005-05-06 21:37:42 +0000536static int
paul96735ee2003-08-10 02:51:22 +0000537process_transit_summary_lsa (struct ospf_area *area, struct route_table *rt,
538 struct route_table *rtrs, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +0000539{
paul96735ee2003-08-10 02:51:22 +0000540 struct ospf *ospf = area->ospf;
paul718e3742002-12-13 20:15:29 +0000541 struct summary_lsa *sl;
542 struct prefix_ipv4 p;
543 u_int32_t metric;
paul718e3742002-12-13 20:15:29 +0000544
paul96735ee2003-08-10 02:51:22 +0000545 if (lsa == NULL)
paul718e3742002-12-13 20:15:29 +0000546 return 0;
547
paul96735ee2003-08-10 02:51:22 +0000548 sl = (struct summary_lsa *) lsa->data;
paul718e3742002-12-13 20:15:29 +0000549
550 if (IS_DEBUG_OSPF_EVENT)
ajs60925302004-12-08 17:45:02 +0000551 zlog_debug ("process_transit_summaries(): LS ID: %s",
paul96735ee2003-08-10 02:51:22 +0000552 inet_ntoa (lsa->data->id));
paul718e3742002-12-13 20:15:29 +0000553 metric = GET_METRIC (sl->metric);
554
555 if (metric == OSPF_LS_INFINITY)
556 {
557 if (IS_DEBUG_OSPF_EVENT)
ajs60925302004-12-08 17:45:02 +0000558 zlog_debug ("process_transit_summaries(): metric is infinity, skip");
paul718e3742002-12-13 20:15:29 +0000559 return 0;
560 }
561
paul96735ee2003-08-10 02:51:22 +0000562 if (IS_LSA_MAXAGE (lsa))
paul718e3742002-12-13 20:15:29 +0000563 {
564 if (IS_DEBUG_OSPF_EVENT)
ajs60925302004-12-08 17:45:02 +0000565 zlog_debug ("process_transit_summaries(): This LSA is too old");
paul718e3742002-12-13 20:15:29 +0000566 return 0;
567 }
568
paul96735ee2003-08-10 02:51:22 +0000569 if (ospf_lsa_is_self_originated (area->ospf, lsa))
paul718e3742002-12-13 20:15:29 +0000570 {
571 if (IS_DEBUG_OSPF_EVENT)
ajs60925302004-12-08 17:45:02 +0000572 zlog_debug ("process_transit_summaries(): This LSA is mine, skip");
paul718e3742002-12-13 20:15:29 +0000573 return 0;
574 }
575
576 p.family = AF_INET;
577 p.prefix = sl->header.id;
578
579 if (sl->header.type == OSPF_SUMMARY_LSA)
580 p.prefixlen = ip_masklen (sl->mask);
581 else
582 p.prefixlen = IPV4_MAX_BITLEN;
583
584 apply_mask_ipv4 (&p);
585
586 if (sl->header.type == OSPF_SUMMARY_LSA)
paul96735ee2003-08-10 02:51:22 +0000587 ospf_update_network_route (ospf, rt, rtrs, sl, &p, area);
paul718e3742002-12-13 20:15:29 +0000588 else
paul96735ee2003-08-10 02:51:22 +0000589 ospf_update_router_route (ospf, rtrs, sl, &p, area);
paul718e3742002-12-13 20:15:29 +0000590
591 return 0;
592}
593
paul4dadc292005-05-06 21:37:42 +0000594static void
paul718e3742002-12-13 20:15:29 +0000595ospf_examine_transit_summaries (struct ospf_area *area,
paul718e3742002-12-13 20:15:29 +0000596 struct route_table *lsdb_rt,
597 struct route_table *rt,
598 struct route_table *rtrs)
599{
paul96735ee2003-08-10 02:51:22 +0000600 struct ospf_lsa *lsa;
601 struct route_node *rn;
paul718e3742002-12-13 20:15:29 +0000602
paul96735ee2003-08-10 02:51:22 +0000603 LSDB_LOOP (lsdb_rt, rn, lsa)
604 process_transit_summary_lsa (area, rt, rtrs, lsa);
paul718e3742002-12-13 20:15:29 +0000605}
606
607void
paul96735ee2003-08-10 02:51:22 +0000608ospf_ia_routing (struct ospf *ospf,
609 struct route_table *rt,
paul718e3742002-12-13 20:15:29 +0000610 struct route_table *rtrs)
611{
612 struct ospf_area * area;
613
614 if (IS_DEBUG_OSPF_EVENT)
ajs60925302004-12-08 17:45:02 +0000615 zlog_debug ("ospf_ia_routing():start");
paul718e3742002-12-13 20:15:29 +0000616
paul96735ee2003-08-10 02:51:22 +0000617 if (IS_OSPF_ABR (ospf))
paul718e3742002-12-13 20:15:29 +0000618 {
hasso52dc7ee2004-09-23 19:18:23 +0000619 struct listnode *node;
paul718e3742002-12-13 20:15:29 +0000620 struct ospf_area *area;
621
paul96735ee2003-08-10 02:51:22 +0000622 switch (ospf->abr_type)
paul718e3742002-12-13 20:15:29 +0000623 {
624 case OSPF_ABR_STAND:
625 if (IS_DEBUG_OSPF_EVENT)
ajs60925302004-12-08 17:45:02 +0000626 zlog_debug ("ospf_ia_routing():Standard ABR");
paul718e3742002-12-13 20:15:29 +0000627
paul96735ee2003-08-10 02:51:22 +0000628 if ((area = ospf->backbone))
paul718e3742002-12-13 20:15:29 +0000629 {
hasso52dc7ee2004-09-23 19:18:23 +0000630 struct listnode *node;
paul718e3742002-12-13 20:15:29 +0000631
632 if (IS_DEBUG_OSPF_EVENT)
633 {
ajs60925302004-12-08 17:45:02 +0000634 zlog_debug ("ospf_ia_routing():backbone area found");
635 zlog_debug ("ospf_ia_routing():examining summaries");
paul718e3742002-12-13 20:15:29 +0000636 }
637
638 OSPF_EXAMINE_SUMMARIES_ALL (area, rt, rtrs);
639
paul1eb8ef22005-04-07 07:30:20 +0000640 for (ALL_LIST_ELEMENTS_RO (ospf->areas, node, area))
641 if (area != ospf->backbone)
642 if (ospf_area_is_transit (area))
643 OSPF_EXAMINE_TRANSIT_SUMMARIES_ALL (area, rt, rtrs);
paul718e3742002-12-13 20:15:29 +0000644 }
645 else
646 if (IS_DEBUG_OSPF_EVENT)
ajs60925302004-12-08 17:45:02 +0000647 zlog_debug ("ospf_ia_routing():backbone area NOT found");
paul718e3742002-12-13 20:15:29 +0000648 break;
649 case OSPF_ABR_IBM:
650 case OSPF_ABR_CISCO:
651 if (IS_DEBUG_OSPF_EVENT)
ajs60925302004-12-08 17:45:02 +0000652 zlog_debug ("ospf_ia_routing():Alternative Cisco/IBM ABR");
paul96735ee2003-08-10 02:51:22 +0000653 area = ospf->backbone; /* Find the BB */
paul718e3742002-12-13 20:15:29 +0000654
655 /* If we have an active BB connection */
paul96735ee2003-08-10 02:51:22 +0000656 if (area && ospf_act_bb_connection (ospf))
paul718e3742002-12-13 20:15:29 +0000657 {
658 if (IS_DEBUG_OSPF_EVENT)
659 {
ajs60925302004-12-08 17:45:02 +0000660 zlog_debug ("ospf_ia_routing(): backbone area found");
661 zlog_debug ("ospf_ia_routing(): examining BB summaries");
paul718e3742002-12-13 20:15:29 +0000662 }
663
664 OSPF_EXAMINE_SUMMARIES_ALL (area, rt, rtrs);
665
paul1eb8ef22005-04-07 07:30:20 +0000666 for (ALL_LIST_ELEMENTS_RO (ospf->areas, node, area))
667 if (area != ospf->backbone)
668 if (ospf_area_is_transit (area))
669 OSPF_EXAMINE_TRANSIT_SUMMARIES_ALL (area, rt, rtrs);
paul718e3742002-12-13 20:15:29 +0000670 }
671 else
672 { /* No active BB connection--consider all areas */
673 if (IS_DEBUG_OSPF_EVENT)
ajs60925302004-12-08 17:45:02 +0000674 zlog_debug ("ospf_ia_routing(): "
paul718e3742002-12-13 20:15:29 +0000675 "Active BB connection not found");
paul1eb8ef22005-04-07 07:30:20 +0000676 for (ALL_LIST_ELEMENTS_RO (ospf->areas, node, area))
677 OSPF_EXAMINE_SUMMARIES_ALL (area, rt, rtrs);
paul718e3742002-12-13 20:15:29 +0000678 }
679 break;
680 case OSPF_ABR_SHORTCUT:
681 if (IS_DEBUG_OSPF_EVENT)
ajs60925302004-12-08 17:45:02 +0000682 zlog_debug ("ospf_ia_routing():Alternative Shortcut");
paul96735ee2003-08-10 02:51:22 +0000683 area = ospf->backbone; /* Find the BB */
paul718e3742002-12-13 20:15:29 +0000684
685 /* If we have an active BB connection */
paul96735ee2003-08-10 02:51:22 +0000686 if (area && ospf_act_bb_connection (ospf))
paul718e3742002-12-13 20:15:29 +0000687 {
688 if (IS_DEBUG_OSPF_EVENT)
689 {
ajs60925302004-12-08 17:45:02 +0000690 zlog_debug ("ospf_ia_routing(): backbone area found");
691 zlog_debug ("ospf_ia_routing(): examining BB summaries");
paul718e3742002-12-13 20:15:29 +0000692 }
693 OSPF_EXAMINE_SUMMARIES_ALL (area, rt, rtrs);
694 }
695
paul1eb8ef22005-04-07 07:30:20 +0000696 for (ALL_LIST_ELEMENTS_RO (ospf->areas, node, area))
697 if (area != ospf->backbone)
698 if (ospf_area_is_transit (area) ||
699 ((area->shortcut_configured != OSPF_SHORTCUT_DISABLE) &&
700 ((ospf->backbone == NULL) ||
701 ((area->shortcut_configured == OSPF_SHORTCUT_ENABLE) &&
702 area->shortcut_capability))))
703 OSPF_EXAMINE_TRANSIT_SUMMARIES_ALL (area, rt, rtrs);
paul718e3742002-12-13 20:15:29 +0000704 break;
705 default:
706 break;
707 }
708 }
709 else
710 {
hasso52dc7ee2004-09-23 19:18:23 +0000711 struct listnode *node;
paul718e3742002-12-13 20:15:29 +0000712
713 if (IS_DEBUG_OSPF_EVENT)
ajs60925302004-12-08 17:45:02 +0000714 zlog_debug ("ospf_ia_routing():not ABR, considering all areas");
paul718e3742002-12-13 20:15:29 +0000715
paul1eb8ef22005-04-07 07:30:20 +0000716 for (ALL_LIST_ELEMENTS_RO (ospf->areas, node, area))
717 OSPF_EXAMINE_SUMMARIES_ALL (area, rt, rtrs);
paul718e3742002-12-13 20:15:29 +0000718 }
719}