blob: 916e9800899b8878b88734195a444e0fa9e85f05 [file] [log] [blame]
paul718e3742002-12-13 20:15:29 +00001/* OSPF SPF calculation.
2 Copyright (C) 1999, 2000 Kunihiro Ishiguro, Toshiaki Takada
3
4This file is part of GNU Zebra.
5
6GNU Zebra is free software; you can redistribute it and/or modify it
7under the terms of the GNU General Public License as published by the
8Free Software Foundation; either version 2, or (at your option) any
9later version.
10
11GNU Zebra is distributed in the hope that it will be useful, but
12WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GNU Zebra; see the file COPYING. If not, write to the Free
18Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
1902111-1307, USA. */
20
21#include <zebra.h>
22
23#include "thread.h"
24#include "memory.h"
25#include "hash.h"
26#include "linklist.h"
27#include "prefix.h"
28#include "if.h"
29#include "table.h"
30#include "log.h"
31#include "sockunion.h" /* for inet_ntop () */
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_ia.h"
44#include "ospfd/ospf_ase.h"
45#include "ospfd/ospf_abr.h"
46#include "ospfd/ospf_dump.h"
47
48#define DEBUG
49
50struct vertex_nexthop *
51vertex_nexthop_new (struct vertex *parent)
52{
53 struct vertex_nexthop *new;
54
55 new = XCALLOC (MTYPE_OSPF_NEXTHOP, sizeof (struct vertex_nexthop));
56 new->parent = parent;
57
58 return new;
59}
60
61void
62vertex_nexthop_free (struct vertex_nexthop *nh)
63{
64 XFREE (MTYPE_OSPF_NEXTHOP, nh);
65}
66
67struct vertex_nexthop *
68vertex_nexthop_dup (struct vertex_nexthop *nh)
69{
70 struct vertex_nexthop *new;
71
72 new = vertex_nexthop_new (nh->parent);
73
74 new->oi = nh->oi;
75 new->router = nh->router;
76
77 return new;
78}
paul718e3742002-12-13 20:15:29 +000079
paul0c0f9cd2003-06-06 23:27:04 +000080
paul718e3742002-12-13 20:15:29 +000081struct vertex *
82ospf_vertex_new (struct ospf_lsa *lsa)
83{
84 struct vertex *new;
85
86 new = XMALLOC (MTYPE_OSPF_VERTEX, sizeof (struct vertex));
87 memset (new, 0, sizeof (struct vertex));
88
89 new->flags = 0;
90 new->type = lsa->data->type;
91 new->id = lsa->data->id;
92 new->lsa = lsa->data;
93 new->distance = 0;
94 new->child = list_new ();
95 new->nexthop = list_new ();
pauld355bfa2004-04-08 07:43:45 +000096 new->backlink = -1;
paul718e3742002-12-13 20:15:29 +000097
98 return new;
99}
100
101void
102ospf_vertex_free (struct vertex *v)
103{
104 listnode node;
105
106 list_delete (v->child);
107
108 if (listcount (v->nexthop) > 0)
109 for (node = listhead (v->nexthop); node; nextnode (node))
110 vertex_nexthop_free (node->data);
111
112 list_delete (v->nexthop);
113
114 XFREE (MTYPE_OSPF_VERTEX, v);
115}
116
117void
118ospf_vertex_add_parent (struct vertex *v)
119{
120 struct vertex_nexthop *nh;
121 listnode node;
122
123 for (node = listhead (v->nexthop); node; nextnode (node))
124 {
125 nh = (struct vertex_nexthop *) getdata (node);
126
127 /* No need to add two links from the same parent. */
128 if (listnode_lookup (nh->parent->child, v) == NULL)
paul0c0f9cd2003-06-06 23:27:04 +0000129 listnode_add (nh->parent->child, v);
paul718e3742002-12-13 20:15:29 +0000130 }
131}
132
133void
134ospf_spf_init (struct ospf_area *area)
135{
136 struct vertex *v;
137
138 /* Create root node. */
139 v = ospf_vertex_new (area->router_lsa_self);
140
141 area->spf = v;
142
143 /* Reset ABR and ASBR router counts. */
144 area->abr_count = 0;
145 area->asbr_count = 0;
146}
147
148int
149ospf_spf_has_vertex (struct route_table *rv, struct route_table *nv,
150 struct lsa_header *lsa)
151{
152 struct prefix p;
153 struct route_node *rn;
154
155 p.family = AF_INET;
156 p.prefixlen = IPV4_MAX_BITLEN;
157 p.u.prefix4 = lsa->id;
158
159 if (lsa->type == OSPF_ROUTER_LSA)
160 rn = route_node_get (rv, &p);
161 else
162 rn = route_node_get (nv, &p);
163
164 if (rn->info != NULL)
165 {
166 route_unlock_node (rn);
167 return 1;
168 }
169 return 0;
170}
171
172listnode
173ospf_vertex_lookup (list vlist, struct in_addr id, int type)
174{
175 listnode node;
176 struct vertex *v;
177
178 for (node = listhead (vlist); node; nextnode (node))
179 {
180 v = (struct vertex *) getdata (node);
181 if (IPV4_ADDR_SAME (&id, &v->id) && type == v->type)
182 return node;
183 }
184
185 return NULL;
186}
187
pauld355bfa2004-04-08 07:43:45 +0000188/* return index of link back to V from W, or -1 if no link found */
paul718e3742002-12-13 20:15:29 +0000189int
190ospf_lsa_has_link (struct lsa_header *w, struct lsa_header *v)
191{
192 int i;
193 int length;
194 struct router_lsa *rl;
195 struct network_lsa *nl;
196
197 /* In case of W is Network LSA. */
198 if (w->type == OSPF_NETWORK_LSA)
199 {
200 if (v->type == OSPF_NETWORK_LSA)
pauld355bfa2004-04-08 07:43:45 +0000201 return -1;
paul718e3742002-12-13 20:15:29 +0000202
203 nl = (struct network_lsa *) w;
204 length = (ntohs (w->length) - OSPF_LSA_HEADER_SIZE - 4) / 4;
paul0c0f9cd2003-06-06 23:27:04 +0000205
paul718e3742002-12-13 20:15:29 +0000206 for (i = 0; i < length; i++)
207 if (IPV4_ADDR_SAME (&nl->routers[i], &v->id))
pauld355bfa2004-04-08 07:43:45 +0000208 return i;
209 return -1;
paul718e3742002-12-13 20:15:29 +0000210 }
211
212 /* In case of W is Router LSA. */
213 if (w->type == OSPF_ROUTER_LSA)
214 {
215 rl = (struct router_lsa *) w;
216
217 length = ntohs (w->length);
218
219 for (i = 0;
paul0c0f9cd2003-06-06 23:27:04 +0000220 i < ntohs (rl->links) && length >= sizeof (struct router_lsa);
221 i++, length -= 12)
paul718e3742002-12-13 20:15:29 +0000222 {
223 switch (rl->link[i].type)
224 {
225 case LSA_LINK_TYPE_POINTOPOINT:
226 case LSA_LINK_TYPE_VIRTUALLINK:
227 /* Router LSA ID. */
228 if (v->type == OSPF_ROUTER_LSA &&
229 IPV4_ADDR_SAME (&rl->link[i].link_id, &v->id))
230 {
pauld355bfa2004-04-08 07:43:45 +0000231 return i;
paul718e3742002-12-13 20:15:29 +0000232 }
233 break;
234 case LSA_LINK_TYPE_TRANSIT:
235 /* Network LSA ID. */
236 if (v->type == OSPF_NETWORK_LSA &&
237 IPV4_ADDR_SAME (&rl->link[i].link_id, &v->id))
238 {
pauld355bfa2004-04-08 07:43:45 +0000239 return i;
paul0c0f9cd2003-06-06 23:27:04 +0000240 }
paul718e3742002-12-13 20:15:29 +0000241 break;
242 case LSA_LINK_TYPE_STUB:
243 /* Not take into count? */
244 continue;
245 default:
246 break;
247 }
248 }
249 }
pauld355bfa2004-04-08 07:43:45 +0000250 return -1;
paul718e3742002-12-13 20:15:29 +0000251}
252
253/* Add the nexthop to the list, only if it is unique.
254 * If it's not unique, free the nexthop entry.
255 */
256void
257ospf_nexthop_add_unique (struct vertex_nexthop *new, list nexthop)
258{
259 struct vertex_nexthop *nh;
260 listnode node;
261 int match;
262
263 match = 0;
264 for (node = listhead (nexthop); node; nextnode (node))
265 {
266 nh = node->data;
267
268 /* Compare the two entries. */
269 /* XXX
270 * Comparing the parent preserves the shortest path tree
271 * structure even when the nexthops are identical.
272 */
273 if (nh->oi == new->oi &&
paul0c0f9cd2003-06-06 23:27:04 +0000274 IPV4_ADDR_SAME (&nh->router, &new->router) &&
275 nh->parent == new->parent)
276 {
277 match = 1;
278 break;
279 }
paul718e3742002-12-13 20:15:29 +0000280 }
281
282 if (!match)
283 listnode_add (nexthop, new);
284 else
285 vertex_nexthop_free (new);
286}
287
288/* Merge entries in list b into list a. */
289void
290ospf_nexthop_merge (list a, list b)
291{
292 struct listnode *n;
293
294 for (n = listhead (b); n; nextnode (n))
295 {
296 ospf_nexthop_add_unique (n->data, a);
297 }
298}
299
300#define ROUTER_LSA_MIN_SIZE 12
301#define ROUTER_LSA_TOS_SIZE 4
302
303struct router_lsa_link *
304ospf_get_next_link (struct vertex *v, struct vertex *w,
paul0c0f9cd2003-06-06 23:27:04 +0000305 struct router_lsa_link *prev_link)
paul718e3742002-12-13 20:15:29 +0000306{
307 u_char *p;
308 u_char *lim;
309 struct router_lsa_link *l;
310
311 if (prev_link == NULL)
312 p = ((u_char *) v->lsa) + 24;
313 else
314 {
paul0c0f9cd2003-06-06 23:27:04 +0000315 p = (u_char *) prev_link;
paul718e3742002-12-13 20:15:29 +0000316 p += (ROUTER_LSA_MIN_SIZE +
317 (prev_link->m[0].tos_count * ROUTER_LSA_TOS_SIZE));
318 }
paul0c0f9cd2003-06-06 23:27:04 +0000319
paul718e3742002-12-13 20:15:29 +0000320 lim = ((u_char *) v->lsa) + ntohs (v->lsa->length);
321
322 while (p < lim)
323 {
324 l = (struct router_lsa_link *) p;
325
paul0c0f9cd2003-06-06 23:27:04 +0000326 p += (ROUTER_LSA_MIN_SIZE + (l->m[0].tos_count * ROUTER_LSA_TOS_SIZE));
paul718e3742002-12-13 20:15:29 +0000327
328 if (l->m[0].type == LSA_LINK_TYPE_STUB)
329 continue;
330
331 /* Defer NH calculation via VLs until summaries from
332 transit areas area confidered */
333
334 if (l->m[0].type == LSA_LINK_TYPE_VIRTUALLINK)
paul0c0f9cd2003-06-06 23:27:04 +0000335 continue;
paul718e3742002-12-13 20:15:29 +0000336
337 if (IPV4_ADDR_SAME (&l->link_id, &w->id))
paul0c0f9cd2003-06-06 23:27:04 +0000338 return l;
paul718e3742002-12-13 20:15:29 +0000339 }
340
341 return NULL;
342}
343
paulbf9392c2003-06-06 23:23:36 +0000344/* Consider supplied next-hop for inclusion to the supplied list
345 * of next-hops, adjust list as neccessary
346 */
paul0c0f9cd2003-06-06 23:27:04 +0000347void
348ospf_spf_consider_nexthop (struct list *nexthops,
349 struct vertex_nexthop *newhop)
paulbf9392c2003-06-06 23:23:36 +0000350{
351 struct listnode *nnode;
352 struct vertex_nexthop *hop;
paul0c0f9cd2003-06-06 23:27:04 +0000353
paulbf9392c2003-06-06 23:23:36 +0000354 LIST_LOOP (nexthops, hop, nnode)
paul0c0f9cd2003-06-06 23:27:04 +0000355 {
356 assert (hop->oi);
357 /* weed out hops with higher cost than the newhop */
358 if (hop->oi->output_cost > newhop->oi->output_cost)
359 {
360 /* delete the existing nexthop */
361 listnode_delete (nexthops, hop);
362 vertex_nexthop_free (hop);
363 }
364 else if (hop->oi->output_cost < newhop->oi->output_cost)
365 {
366 return;
367 }
368 }
369
paulbf9392c2003-06-06 23:23:36 +0000370 /* new hop is <= existing hops, add it */
paul0c0f9cd2003-06-06 23:27:04 +0000371 listnode_add (nexthops, newhop);
paulbf9392c2003-06-06 23:23:36 +0000372
373 return;
374}
375
paul718e3742002-12-13 20:15:29 +0000376/* Calculate nexthop from root to vertex W. */
377void
378ospf_nexthop_calculation (struct ospf_area *area,
379 struct vertex *v, struct vertex *w)
380{
381 listnode node;
382 struct vertex_nexthop *nh, *x;
383 struct ospf_interface *oi = NULL;
384 struct router_lsa_link *l = NULL;
paul0c0f9cd2003-06-06 23:27:04 +0000385
386
paul718e3742002-12-13 20:15:29 +0000387 if (IS_DEBUG_OSPF_EVENT)
388 zlog_info ("ospf_nexthop_calculation(): Start");
389
390 /* W's parent is root. */
391 if (v == area->spf)
392 {
393 if (w->type == OSPF_VERTEX_ROUTER)
paul0c0f9cd2003-06-06 23:27:04 +0000394 {
395 while ((l = ospf_get_next_link (v, w, l)))
396 {
397 struct router_lsa_link *l2 = NULL;
398
399 if (l->m[0].type == LSA_LINK_TYPE_POINTOPOINT)
400 {
401 /* Check for PtMP, signified by PtP link V->W
402 with link_data our PtMP interface. */
paul68980082003-03-25 05:07:42 +0000403 oi = ospf_if_is_configured (area->ospf, &l->link_data);
paul7afa08d2002-12-13 20:59:45 +0000404 if (oi && oi->type == OSPF_IFTYPE_POINTOMULTIPOINT)
paul0c0f9cd2003-06-06 23:27:04 +0000405 {
406 struct prefix_ipv4 la;
407 la.prefixlen = oi->address->prefixlen;
408 /* We link to them on PtMP interface
409 - find the interface on w */
410 while ((l2 = ospf_get_next_link (w, v, l2)))
411 {
412 la.prefix = l2->link_data;
413
414 if (prefix_cmp ((struct prefix *) &la,
415 oi->address) == 0)
416 /* link_data is on our PtMP network */
417 break;
418 }
419 }
420 else
421 {
422 while ((l2 = ospf_get_next_link (w, v, l2)))
423 {
424 oi = ospf_if_is_configured (area->ospf,
425 &(l2->link_data));
426
427 if (oi == NULL)
428 continue;
429
430 if (!IPV4_ADDR_SAME (&oi->address->u.prefix4,
431 &l->link_data))
432 continue;
433
434 break;
435 }
436 }
437
438 if (oi && l2)
439 {
440 nh = vertex_nexthop_new (v);
441 nh->oi = oi;
442 nh->router = l2->link_data;
443 ospf_spf_consider_nexthop (w->nexthop, nh);
444 }
445 }
446 }
447 }
paul718e3742002-12-13 20:15:29 +0000448 else
paul0c0f9cd2003-06-06 23:27:04 +0000449 {
450 while ((l = ospf_get_next_link (v, w, l)))
451 {
452 oi = ospf_if_is_configured (area->ospf, &(l->link_data));
453 if (oi)
454 {
455 nh = vertex_nexthop_new (v);
456 nh->oi = oi;
457 nh->router.s_addr = 0;
458 listnode_add (w->nexthop, nh);
459 }
460 }
461 }
paul718e3742002-12-13 20:15:29 +0000462 return;
463 }
464 /* In case of W's parent is network connected to root. */
465 else if (v->type == OSPF_VERTEX_NETWORK)
466 {
467 for (node = listhead (v->nexthop); node; nextnode (node))
468 {
469 x = (struct vertex_nexthop *) getdata (node);
470 if (x->parent == area->spf)
471 {
paul0c0f9cd2003-06-06 23:27:04 +0000472 while ((l = ospf_get_next_link (w, v, l)))
473 {
474 nh = vertex_nexthop_new (v);
475 nh->oi = x->oi;
476 nh->router = l->link_data;
477 listnode_add (w->nexthop, nh);
478 }
479 return;
480 }
paul718e3742002-12-13 20:15:29 +0000481 }
482 }
483
484 /* Inherit V's nexthop. */
485 for (node = listhead (v->nexthop); node; nextnode (node))
486 {
487 nh = vertex_nexthop_dup (node->data);
488 nh->parent = v;
489 ospf_nexthop_add_unique (nh, w->nexthop);
490 }
491}
492
493void
494ospf_install_candidate (list candidate, struct vertex *w)
495{
496 listnode node;
497 struct vertex *cw;
498
499 if (list_isempty (candidate))
500 {
501 listnode_add (candidate, w);
502 return;
503 }
504
505 /* Install vertex with sorting by distance. */
506 for (node = listhead (candidate); node; nextnode (node))
507 {
508 cw = (struct vertex *) getdata (node);
509 if (cw->distance > w->distance)
510 {
511 list_add_node_prev (candidate, node, w);
512 break;
513 }
514 else if (node->next == NULL)
515 {
516 list_add_node_next (candidate, node, w);
517 break;
518 }
519 }
520}
521
522/* RFC2328 Section 16.1 (2). */
523void
524ospf_spf_next (struct vertex *v, struct ospf_area *area,
paul0c0f9cd2003-06-06 23:27:04 +0000525 list candidate, struct route_table *rv, struct route_table *nv)
paul718e3742002-12-13 20:15:29 +0000526{
527 struct ospf_lsa *w_lsa = NULL;
528 struct vertex *w, *cw;
529 u_char *p;
530 u_char *lim;
531 struct router_lsa_link *l = NULL;
532 struct in_addr *r;
533 listnode node;
534 int type = 0;
535
536 /* If this is a router-LSA, and bit V of the router-LSA (see Section
537 A.4.2:RFC2328) is set, set Area A's TransitCapability to TRUE. */
538 if (v->type == OSPF_VERTEX_ROUTER)
539 {
540 if (IS_ROUTER_LSA_VIRTUAL ((struct router_lsa *) v->lsa))
541 area->transit = OSPF_TRANSIT_TRUE;
542 }
543
544 p = ((u_char *) v->lsa) + OSPF_LSA_HEADER_SIZE + 4;
paul0c0f9cd2003-06-06 23:27:04 +0000545 lim = ((u_char *) v->lsa) + ntohs (v->lsa->length);
546
paul718e3742002-12-13 20:15:29 +0000547 while (p < lim)
548 {
pauld355bfa2004-04-08 07:43:45 +0000549 int link = -1; /* link index for w's back link */
550
paul718e3742002-12-13 20:15:29 +0000551 /* In case of V is Router-LSA. */
552 if (v->lsa->type == OSPF_ROUTER_LSA)
553 {
554 l = (struct router_lsa_link *) p;
555
paul0c0f9cd2003-06-06 23:27:04 +0000556 p += (ROUTER_LSA_MIN_SIZE +
paul718e3742002-12-13 20:15:29 +0000557 (l->m[0].tos_count * ROUTER_LSA_TOS_SIZE));
558
559 /* (a) If this is a link to a stub network, examine the next
560 link in V's LSA. Links to stub networks will be
561 considered in the second stage of the shortest path
562 calculation. */
563 if ((type = l->m[0].type) == LSA_LINK_TYPE_STUB)
564 continue;
565
566 /* (b) Otherwise, W is a transit vertex (router or transit
567 network). Look up the vertex W's LSA (router-LSA or
568 network-LSA) in Area A's link state database. */
569 switch (type)
570 {
571 case LSA_LINK_TYPE_POINTOPOINT:
572 case LSA_LINK_TYPE_VIRTUALLINK:
573 if (type == LSA_LINK_TYPE_VIRTUALLINK)
paul0c0f9cd2003-06-06 23:27:04 +0000574 {
575 if (IS_DEBUG_OSPF_EVENT)
576 zlog_info ("looking up LSA through VL: %s",
577 inet_ntoa (l->link_id));
578 }
paul718e3742002-12-13 20:15:29 +0000579
580 w_lsa = ospf_lsa_lookup (area, OSPF_ROUTER_LSA, l->link_id,
581 l->link_id);
582 if (w_lsa)
paul0c0f9cd2003-06-06 23:27:04 +0000583 {
584 if (IS_DEBUG_OSPF_EVENT)
585 zlog_info ("found the LSA");
586 }
paul718e3742002-12-13 20:15:29 +0000587 break;
588 case LSA_LINK_TYPE_TRANSIT:
paul0c0f9cd2003-06-06 23:27:04 +0000589 if (IS_DEBUG_OSPF_EVENT)
paul718e3742002-12-13 20:15:29 +0000590
paul0c0f9cd2003-06-06 23:27:04 +0000591 zlog_info ("Looking up Network LSA, ID: %s",
592 inet_ntoa (l->link_id));
paul718e3742002-12-13 20:15:29 +0000593 w_lsa = ospf_lsa_lookup_by_id (area, OSPF_NETWORK_LSA,
paul0c0f9cd2003-06-06 23:27:04 +0000594 l->link_id);
paul718e3742002-12-13 20:15:29 +0000595 if (w_lsa)
paul0c0f9cd2003-06-06 23:27:04 +0000596 if (IS_DEBUG_OSPF_EVENT)
597 zlog_info ("found the LSA");
paul718e3742002-12-13 20:15:29 +0000598 break;
599 default:
paul0c0f9cd2003-06-06 23:27:04 +0000600 zlog_warn ("Invalid LSA link type %d", type);
paul718e3742002-12-13 20:15:29 +0000601 continue;
602 }
603 }
604 else
605 {
606 /* In case of V is Network-LSA. */
paul0c0f9cd2003-06-06 23:27:04 +0000607 r = (struct in_addr *) p;
paul718e3742002-12-13 20:15:29 +0000608 p += sizeof (struct in_addr);
609
610 /* Lookup the vertex W's LSA. */
611 w_lsa = ospf_lsa_lookup_by_id (area, OSPF_ROUTER_LSA, *r);
612 }
613
614 /* (b cont.) If the LSA does not exist, or its LS age is equal
615 to MaxAge, or it does not have a link back to vertex V,
616 examine the next link in V's LSA.[23] */
617 if (w_lsa == NULL)
618 continue;
619
620 if (IS_LSA_MAXAGE (w_lsa))
621 continue;
622
pauld355bfa2004-04-08 07:43:45 +0000623 if ( (link = ospf_lsa_has_link (w_lsa->data, v->lsa)) < 0 )
paul718e3742002-12-13 20:15:29 +0000624 {
paul0c0f9cd2003-06-06 23:27:04 +0000625 if (IS_DEBUG_OSPF_EVENT)
626 zlog_info ("The LSA doesn't have a link back");
paul718e3742002-12-13 20:15:29 +0000627 continue;
628 }
629
630 /* (c) If vertex W is already on the shortest-path tree, examine
631 the next link in the LSA. */
632 if (ospf_spf_has_vertex (rv, nv, w_lsa->data))
633 {
paul0c0f9cd2003-06-06 23:27:04 +0000634 if (IS_DEBUG_OSPF_EVENT)
635 zlog_info ("The LSA is already in SPF");
paul718e3742002-12-13 20:15:29 +0000636 continue;
637 }
638
639 /* (d) Calculate the link state cost D of the resulting path
640 from the root to vertex W. D is equal to the sum of the link
641 state cost of the (already calculated) shortest path to
642 vertex V and the advertised cost of the link between vertices
643 V and W. If D is: */
644
645 /* prepare vertex W. */
646 w = ospf_vertex_new (w_lsa);
647
pauld355bfa2004-04-08 07:43:45 +0000648 /* Save W's back link index number, for use by virtual links */
649 w->backlink = link;
650
paul718e3742002-12-13 20:15:29 +0000651 /* calculate link cost D. */
652 if (v->lsa->type == OSPF_ROUTER_LSA)
653 w->distance = v->distance + ntohs (l->m[0].metric);
654 else
655 w->distance = v->distance;
656
657 /* Is there already vertex W in candidate list? */
658 node = ospf_vertex_lookup (candidate, w->id, w->type);
659 if (node == NULL)
660 {
661 /* Calculate nexthop to W. */
662 ospf_nexthop_calculation (area, v, w);
663
664 ospf_install_candidate (candidate, w);
665 }
666 else
667 {
668 cw = (struct vertex *) getdata (node);
669
670 /* if D is greater than. */
671 if (cw->distance < w->distance)
672 {
673 ospf_vertex_free (w);
674 continue;
675 }
676 /* equal to. */
677 else if (cw->distance == w->distance)
678 {
679 /* Calculate nexthop to W. */
680 ospf_nexthop_calculation (area, v, w);
681 ospf_nexthop_merge (cw->nexthop, w->nexthop);
682 list_delete_all_node (w->nexthop);
683 ospf_vertex_free (w);
684 }
685 /* less than. */
686 else
687 {
688 /* Calculate nexthop. */
689 ospf_nexthop_calculation (area, v, w);
690
691 /* Remove old vertex from candidate list. */
692 ospf_vertex_free (cw);
693 listnode_delete (candidate, cw);
694
695 /* Install new to candidate. */
696 ospf_install_candidate (candidate, w);
697 }
698 }
699 }
700}
701
702/* Add vertex V to SPF tree. */
703void
704ospf_spf_register (struct vertex *v, struct route_table *rv,
paul0c0f9cd2003-06-06 23:27:04 +0000705 struct route_table *nv)
paul718e3742002-12-13 20:15:29 +0000706{
707 struct prefix p;
708 struct route_node *rn;
709
710 p.family = AF_INET;
711 p.prefixlen = IPV4_MAX_BITLEN;
712 p.u.prefix4 = v->id;
713
714 if (v->type == OSPF_VERTEX_ROUTER)
715 rn = route_node_get (rv, &p);
716 else
717 rn = route_node_get (nv, &p);
718
719 rn->info = v;
720}
721
722void
723ospf_spf_route_free (struct route_table *table)
724{
725 struct route_node *rn;
726 struct vertex *v;
727
728 for (rn = route_top (table); rn; rn = route_next (rn))
729 {
730 if ((v = rn->info))
paul0c0f9cd2003-06-06 23:27:04 +0000731 {
732 ospf_vertex_free (v);
733 rn->info = NULL;
734 }
paul718e3742002-12-13 20:15:29 +0000735
736 route_unlock_node (rn);
737 }
738
739 route_table_finish (table);
740}
741
742void
743ospf_spf_dump (struct vertex *v, int i)
744{
745 listnode cnode;
746 listnode nnode;
747 struct vertex_nexthop *nexthop;
748
749 if (v->type == OSPF_VERTEX_ROUTER)
750 {
751 if (IS_DEBUG_OSPF_EVENT)
paul0c0f9cd2003-06-06 23:27:04 +0000752 zlog_info ("SPF Result: %d [R] %s", i, inet_ntoa (v->lsa->id));
paul718e3742002-12-13 20:15:29 +0000753 }
754 else
755 {
756 struct network_lsa *lsa = (struct network_lsa *) v->lsa;
757 if (IS_DEBUG_OSPF_EVENT)
paul0c0f9cd2003-06-06 23:27:04 +0000758 zlog_info ("SPF Result: %d [N] %s/%d", i, inet_ntoa (v->lsa->id),
759 ip_masklen (lsa->mask));
paul718e3742002-12-13 20:15:29 +0000760
761 for (nnode = listhead (v->nexthop); nnode; nextnode (nnode))
762 {
763 nexthop = getdata (nnode);
paul0c0f9cd2003-06-06 23:27:04 +0000764 if (IS_DEBUG_OSPF_EVENT)
765 zlog_info (" nexthop %s", inet_ntoa (nexthop->router));
paul718e3742002-12-13 20:15:29 +0000766 }
767 }
768
769 i++;
770
771 for (cnode = listhead (v->child); cnode; nextnode (cnode))
772 {
773 v = getdata (cnode);
774 ospf_spf_dump (v, i);
775 }
776}
777
778/* Second stage of SPF calculation. */
779void
paul0c0f9cd2003-06-06 23:27:04 +0000780ospf_spf_process_stubs (struct ospf_area *area, struct vertex *v,
paul718e3742002-12-13 20:15:29 +0000781 struct route_table *rt)
782{
783 listnode cnode;
784 struct vertex *child;
785
786 if (IS_DEBUG_OSPF_EVENT)
787 zlog_info ("ospf_process_stub():processing stubs for area %s",
paul0c0f9cd2003-06-06 23:27:04 +0000788 inet_ntoa (area->area_id));
paul718e3742002-12-13 20:15:29 +0000789 if (v->type == OSPF_VERTEX_ROUTER)
790 {
791 u_char *p;
792 u_char *lim;
793 struct router_lsa_link *l;
794 struct router_lsa *rlsa;
795
paul0c0f9cd2003-06-06 23:27:04 +0000796 if (IS_DEBUG_OSPF_EVENT)
797 zlog_info ("ospf_process_stub():processing router LSA, id: %s",
798 inet_ntoa (v->lsa->id));
paul718e3742002-12-13 20:15:29 +0000799 rlsa = (struct router_lsa *) v->lsa;
800
801
paul0c0f9cd2003-06-06 23:27:04 +0000802 if (IS_DEBUG_OSPF_EVENT)
803 zlog_info ("ospf_process_stub(): we have %d links to process",
804 ntohs (rlsa->links));
paul718e3742002-12-13 20:15:29 +0000805 p = ((u_char *) v->lsa) + 24;
806 lim = ((u_char *) v->lsa) + ntohs (v->lsa->length);
807
808 while (p < lim)
809 {
810 l = (struct router_lsa_link *) p;
811
812 p += (ROUTER_LSA_MIN_SIZE +
813 (l->m[0].tos_count * ROUTER_LSA_TOS_SIZE));
814
815 if (l->m[0].type == LSA_LINK_TYPE_STUB)
816 ospf_intra_add_stub (rt, l, v, area);
817 }
818 }
819
820 if (IS_DEBUG_OSPF_EVENT)
paul0c0f9cd2003-06-06 23:27:04 +0000821 zlog_info ("children of V:");
paul718e3742002-12-13 20:15:29 +0000822 for (cnode = listhead (v->child); cnode; nextnode (cnode))
823 {
824 child = getdata (cnode);
paul0c0f9cd2003-06-06 23:27:04 +0000825 if (IS_DEBUG_OSPF_EVENT)
826 zlog_info (" child : %s", inet_ntoa (child->id));
paul718e3742002-12-13 20:15:29 +0000827 }
828
829 for (cnode = listhead (v->child); cnode; nextnode (cnode))
830 {
831 child = getdata (cnode);
832
833 if (CHECK_FLAG (child->flags, OSPF_VERTEX_PROCESSED))
paul0c0f9cd2003-06-06 23:27:04 +0000834 continue;
paul718e3742002-12-13 20:15:29 +0000835
836 ospf_spf_process_stubs (area, child, rt);
837
838 SET_FLAG (child->flags, OSPF_VERTEX_PROCESSED);
839 }
840}
841
842void
843ospf_rtrs_free (struct route_table *rtrs)
844{
845 struct route_node *rn;
846 list or_list;
847 listnode node;
848
849 if (IS_DEBUG_OSPF_EVENT)
paul0c0f9cd2003-06-06 23:27:04 +0000850 zlog_info ("Route: Router Routing Table free");
paul718e3742002-12-13 20:15:29 +0000851
852 for (rn = route_top (rtrs); rn; rn = route_next (rn))
853 if ((or_list = rn->info) != NULL)
854 {
paul0c0f9cd2003-06-06 23:27:04 +0000855 for (node = listhead (or_list); node; nextnode (node))
856 ospf_route_free (node->data);
paul718e3742002-12-13 20:15:29 +0000857
paul0c0f9cd2003-06-06 23:27:04 +0000858 list_delete (or_list);
paul718e3742002-12-13 20:15:29 +0000859
paul0c0f9cd2003-06-06 23:27:04 +0000860 /* Unlock the node. */
861 rn->info = NULL;
862 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +0000863 }
864 route_table_finish (rtrs);
865}
866
867void
868ospf_rtrs_print (struct route_table *rtrs)
869{
870 struct route_node *rn;
871 list or_list;
872 listnode ln;
873 listnode pnode;
874 struct ospf_route *or;
875 struct ospf_path *path;
876 char buf1[BUFSIZ];
877 char buf2[BUFSIZ];
878
879 if (IS_DEBUG_OSPF_EVENT)
880 zlog_info ("ospf_rtrs_print() start");
881
882 for (rn = route_top (rtrs); rn; rn = route_next (rn))
883 if ((or_list = rn->info) != NULL)
884 for (ln = listhead (or_list); ln; nextnode (ln))
885 {
886 or = getdata (ln);
887
888 switch (or->path_type)
889 {
890 case OSPF_PATH_INTRA_AREA:
paul0c0f9cd2003-06-06 23:27:04 +0000891 if (IS_DEBUG_OSPF_EVENT)
892 zlog_info ("%s [%d] area: %s",
893 inet_ntop (AF_INET, &or->id, buf1, BUFSIZ),
894 or->cost, inet_ntop (AF_INET, &or->u.std.area_id,
895 buf2, BUFSIZ));
paul718e3742002-12-13 20:15:29 +0000896 break;
897 case OSPF_PATH_INTER_AREA:
paul0c0f9cd2003-06-06 23:27:04 +0000898 if (IS_DEBUG_OSPF_EVENT)
899 zlog_info ("%s IA [%d] area: %s",
900 inet_ntop (AF_INET, &or->id, buf1, BUFSIZ),
901 or->cost, inet_ntop (AF_INET, &or->u.std.area_id,
902 buf2, BUFSIZ));
paul718e3742002-12-13 20:15:29 +0000903 break;
904 default:
905 break;
906 }
907
paul96735ee2003-08-10 02:51:22 +0000908 for (pnode = listhead (or->paths); pnode; nextnode (pnode))
paul718e3742002-12-13 20:15:29 +0000909 {
910 path = getdata (pnode);
911 if (path->nexthop.s_addr == 0)
paul0c0f9cd2003-06-06 23:27:04 +0000912 {
913 if (IS_DEBUG_OSPF_EVENT)
914 zlog_info (" directly attached to %s\r\n",
915 IF_NAME (path->oi));
916 }
917 else
918 {
919 if (IS_DEBUG_OSPF_EVENT)
920 zlog_info (" via %s, %s\r\n",
921 inet_ntoa (path->nexthop), IF_NAME (path->oi));
922 }
paul718e3742002-12-13 20:15:29 +0000923 }
924 }
925
926 zlog_info ("ospf_rtrs_print() end");
927}
928
929/* Calculating the shortest-path tree for an area. */
930void
paul0c0f9cd2003-06-06 23:27:04 +0000931ospf_spf_calculate (struct ospf_area *area, struct route_table *new_table,
paul718e3742002-12-13 20:15:29 +0000932 struct route_table *new_rtrs)
933{
934 list candidate;
935 listnode node;
936 struct vertex *v;
937 struct route_table *rv;
938 struct route_table *nv;
939
940 if (IS_DEBUG_OSPF_EVENT)
941 {
942 zlog_info ("ospf_spf_calculate: Start");
paul0c0f9cd2003-06-06 23:27:04 +0000943 zlog_info ("ospf_spf_calculate: running Dijkstra for area %s",
944 inet_ntoa (area->area_id));
paul718e3742002-12-13 20:15:29 +0000945 }
946
947 /* Check router-lsa-self. If self-router-lsa is not yet allocated,
948 return this area's calculation. */
paul0c0f9cd2003-06-06 23:27:04 +0000949 if (!area->router_lsa_self)
paul718e3742002-12-13 20:15:29 +0000950 {
951 if (IS_DEBUG_OSPF_EVENT)
paul0c0f9cd2003-06-06 23:27:04 +0000952 zlog_info ("ospf_spf_calculate: "
953 "Skip area %s's calculation due to empty router_lsa_self",
954 inet_ntoa (area->area_id));
paul718e3742002-12-13 20:15:29 +0000955 return;
956 }
957
958 /* RFC2328 16.1. (1). */
paul0c0f9cd2003-06-06 23:27:04 +0000959 /* Initialize the algorithm's data structures. */
paul718e3742002-12-13 20:15:29 +0000960 rv = route_table_init ();
961 nv = route_table_init ();
962
paul0c0f9cd2003-06-06 23:27:04 +0000963 /* Clear the list of candidate vertices. */
paul718e3742002-12-13 20:15:29 +0000964 candidate = list_new ();
965
966 /* Initialize the shortest-path tree to only the root (which is the
967 router doing the calculation). */
968 ospf_spf_init (area);
969 v = area->spf;
970 ospf_spf_register (v, rv, nv);
971
972 /* Set Area A's TransitCapability to FALSE. */
973 area->transit = OSPF_TRANSIT_FALSE;
974 area->shortcut_capability = 1;
975
976 for (;;)
977 {
978 /* RFC2328 16.1. (2). */
979 ospf_spf_next (v, area, candidate, rv, nv);
980
981 /* RFC2328 16.1. (3). */
982 /* If at this step the candidate list is empty, the shortest-
983 path tree (of transit vertices) has been completely built and
984 this stage of the procedure terminates. */
985 if (listcount (candidate) == 0)
986 break;
987
988 /* Otherwise, choose the vertex belonging to the candidate list
989 that is closest to the root, and add it to the shortest-path
990 tree (removing it from the candidate list in the
paul0c0f9cd2003-06-06 23:27:04 +0000991 process). */
paul718e3742002-12-13 20:15:29 +0000992 node = listhead (candidate);
993 v = getdata (node);
994 ospf_vertex_add_parent (v);
995
996 /* Reveve from the candidate list. */
997 listnode_delete (candidate, v);
998
999 /* Add to SPF tree. */
1000 ospf_spf_register (v, rv, nv);
1001
1002 /* Note that when there is a choice of vertices closest to the
1003 root, network vertices must be chosen before router vertices
1004 in order to necessarily find all equal-cost paths. */
1005 /* We don't do this at this moment, we should add the treatment
1006 above codes. -- kunihiro. */
1007
1008 /* RFC2328 16.1. (4). */
1009 if (v->type == OSPF_VERTEX_ROUTER)
1010 ospf_intra_add_router (new_rtrs, v, area);
paul0c0f9cd2003-06-06 23:27:04 +00001011 else
paul718e3742002-12-13 20:15:29 +00001012 ospf_intra_add_transit (new_table, v, area);
1013
1014 /* RFC2328 16.1. (5). */
1015 /* Iterate the algorithm by returning to Step 2. */
1016 }
1017
1018 if (IS_DEBUG_OSPF_EVENT)
1019 {
1020 ospf_spf_dump (area->spf, 0);
1021 ospf_route_table_dump (new_table);
1022 }
1023
1024 /* Second stage of SPF calculation procedure's */
1025 ospf_spf_process_stubs (area, area->spf, new_table);
1026
1027 /* Free all vertices which allocated for SPF calculation */
1028 ospf_spf_route_free (rv);
1029 ospf_spf_route_free (nv);
1030
1031 /* Free candidate list */
1032 list_free (candidate);
1033
1034 /* Increment SPF Calculation Counter. */
1035 area->spf_calculation++;
1036
paul68980082003-03-25 05:07:42 +00001037 area->ospf->ts_spf = time (NULL);
paul718e3742002-12-13 20:15:29 +00001038
1039 if (IS_DEBUG_OSPF_EVENT)
1040 zlog_info ("ospf_spf_calculate: Stop");
1041}
1042
1043/* Timer for SPF calculation. */
1044int
paul68980082003-03-25 05:07:42 +00001045ospf_spf_calculate_timer (struct thread *thread)
paul718e3742002-12-13 20:15:29 +00001046{
paul68980082003-03-25 05:07:42 +00001047 struct ospf *ospf = THREAD_ARG (thread);
paul718e3742002-12-13 20:15:29 +00001048 struct route_table *new_table, *new_rtrs;
paul718e3742002-12-13 20:15:29 +00001049 listnode node;
1050
1051 if (IS_DEBUG_OSPF_EVENT)
1052 zlog_info ("SPF: Timer (SPF calculation expire)");
paul0c0f9cd2003-06-06 23:27:04 +00001053
paul718e3742002-12-13 20:15:29 +00001054 ospf->t_spf_calc = NULL;
1055
1056 /* Allocate new table tree. */
1057 new_table = route_table_init ();
paul0c0f9cd2003-06-06 23:27:04 +00001058 new_rtrs = route_table_init ();
paul718e3742002-12-13 20:15:29 +00001059
paul68980082003-03-25 05:07:42 +00001060 ospf_vl_unapprove (ospf);
paul718e3742002-12-13 20:15:29 +00001061
1062 /* Calculate SPF for each area. */
1063 for (node = listhead (ospf->areas); node; node = nextnode (node))
1064 ospf_spf_calculate (node->data, new_table, new_rtrs);
1065
paul68980082003-03-25 05:07:42 +00001066 ospf_vl_shut_unapproved (ospf);
paul718e3742002-12-13 20:15:29 +00001067
paul68980082003-03-25 05:07:42 +00001068 ospf_ia_routing (ospf, new_table, new_rtrs);
paul718e3742002-12-13 20:15:29 +00001069
1070 ospf_prune_unreachable_networks (new_table);
1071 ospf_prune_unreachable_routers (new_rtrs);
1072
1073 /* AS-external-LSA calculation should not be performed here. */
1074
1075 /* If new Router Route is installed,
1076 then schedule re-calculate External routes. */
1077 if (1)
paul68980082003-03-25 05:07:42 +00001078 ospf_ase_calculate_schedule (ospf);
paul718e3742002-12-13 20:15:29 +00001079
paul68980082003-03-25 05:07:42 +00001080 ospf_ase_calculate_timer_add (ospf);
paul718e3742002-12-13 20:15:29 +00001081
1082 /* Update routing table. */
paul68980082003-03-25 05:07:42 +00001083 ospf_route_install (ospf, new_table);
paul718e3742002-12-13 20:15:29 +00001084
1085 /* Update ABR/ASBR routing table */
paul68980082003-03-25 05:07:42 +00001086 if (ospf->old_rtrs)
paul718e3742002-12-13 20:15:29 +00001087 {
1088 /* old_rtrs's node holds linked list of ospf_route. --kunihiro. */
paul68980082003-03-25 05:07:42 +00001089 /* ospf_route_delete (ospf->old_rtrs); */
1090 ospf_rtrs_free (ospf->old_rtrs);
paul718e3742002-12-13 20:15:29 +00001091 }
1092
paul68980082003-03-25 05:07:42 +00001093 ospf->old_rtrs = ospf->new_rtrs;
1094 ospf->new_rtrs = new_rtrs;
paul718e3742002-12-13 20:15:29 +00001095
paul0c0f9cd2003-06-06 23:27:04 +00001096 if (IS_OSPF_ABR (ospf))
paul68980082003-03-25 05:07:42 +00001097 ospf_abr_task (ospf);
paul718e3742002-12-13 20:15:29 +00001098
1099 if (IS_DEBUG_OSPF_EVENT)
1100 zlog_info ("SPF: calculation complete");
1101
1102 return 0;
1103}
1104
1105/* Add schedule for SPF calculation. To avoid frequenst SPF calc, we
1106 set timer for SPF calc. */
1107void
paul68980082003-03-25 05:07:42 +00001108ospf_spf_calculate_schedule (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00001109{
1110 time_t ht, delay;
1111
1112 if (IS_DEBUG_OSPF_EVENT)
1113 zlog_info ("SPF: calculation timer scheduled");
1114
1115 /* OSPF instance does not exist. */
paul68980082003-03-25 05:07:42 +00001116 if (ospf == NULL)
paul718e3742002-12-13 20:15:29 +00001117 return;
1118
1119 /* SPF calculation timer is already scheduled. */
paul68980082003-03-25 05:07:42 +00001120 if (ospf->t_spf_calc)
paul718e3742002-12-13 20:15:29 +00001121 {
1122 if (IS_DEBUG_OSPF_EVENT)
paul0c0f9cd2003-06-06 23:27:04 +00001123 zlog_info ("SPF: calculation timer is already scheduled: %p",
1124 ospf->t_spf_calc);
paul718e3742002-12-13 20:15:29 +00001125 return;
1126 }
1127
paul68980082003-03-25 05:07:42 +00001128 ht = time (NULL) - ospf->ts_spf;
paul718e3742002-12-13 20:15:29 +00001129
1130 /* Get SPF calculation delay time. */
paul68980082003-03-25 05:07:42 +00001131 if (ht < ospf->spf_holdtime)
paul718e3742002-12-13 20:15:29 +00001132 {
paul68980082003-03-25 05:07:42 +00001133 if (ospf->spf_holdtime - ht < ospf->spf_delay)
paul0c0f9cd2003-06-06 23:27:04 +00001134 delay = ospf->spf_delay;
paul718e3742002-12-13 20:15:29 +00001135 else
paul0c0f9cd2003-06-06 23:27:04 +00001136 delay = ospf->spf_holdtime - ht;
paul718e3742002-12-13 20:15:29 +00001137 }
1138 else
paul68980082003-03-25 05:07:42 +00001139 delay = ospf->spf_delay;
paul718e3742002-12-13 20:15:29 +00001140
1141 if (IS_DEBUG_OSPF_EVENT)
hassofa2b17e2004-03-04 17:45:00 +00001142 zlog_info ("SPF: calculation timer delay = %ld", (long)delay);
paul68980082003-03-25 05:07:42 +00001143 ospf->t_spf_calc =
1144 thread_add_timer (master, ospf_spf_calculate_timer, ospf, delay);
paul718e3742002-12-13 20:15:29 +00001145}