1 /* OSPF SPF calculation.
2 Copyright (C) 1999, 2000 Kunihiro Ishiguro, Toshiaki Takada
4 This file is part of GNU Zebra.
6 GNU Zebra is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
11 GNU Zebra is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Zebra; see the file COPYING. If not, write to the Free
18 Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
31 #include "sockunion.h" /* for inet_ntop () */
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_ia.h"
45 #include "ospfd/ospf_ase.h"
46 #include "ospfd/ospf_abr.h"
47 #include "ospfd/ospf_dump.h"
49 static void ospf_vertex_free (void *);
50 /* List of allocated vertices, to simplify cleanup of SPF.
51 * Not thread-safe obviously. If it ever needs to be, it'd have to be
52 * dynamically allocated at begin of ospf_spf_calculate
54 static struct list vertex_list
= { .del
= ospf_vertex_free
};
56 /* Heap related functions, for the managment of the candidates, to
57 * be used with pqueue. */
59 cmp (void * node1
, void * node2
)
61 struct vertex
* v1
= (struct vertex
*) node1
;
62 struct vertex
* v2
= (struct vertex
*) node2
;
63 if (v1
!= NULL
&& v2
!= NULL
)
65 /* network vertices must be chosen before router vertices of same
66 * cost in order to find all shortest paths
68 if ( ((v1
->distance
- v2
->distance
) == 0)
69 && (v1
->type
!= v2
->type
))
73 case OSPF_VERTEX_NETWORK
:
75 case OSPF_VERTEX_ROUTER
:
80 return (v1
->distance
- v2
->distance
);
86 update_stat (void *node
, int position
)
88 struct vertex
*v
= node
;
90 /* Set the status of the vertex, when its position changes. */
91 *(v
->stat
) = position
;
94 static struct vertex_nexthop
*
95 vertex_nexthop_new (void)
97 return XCALLOC (MTYPE_OSPF_NEXTHOP
, sizeof (struct vertex_nexthop
));
101 vertex_nexthop_free (struct vertex_nexthop
*nh
)
103 XFREE (MTYPE_OSPF_NEXTHOP
, nh
);
106 /* Free the canonical nexthop objects for an area, ie the nexthop objects
107 * attached to the first-hop router vertices, and any intervening network
111 ospf_canonical_nexthops_free (struct vertex
*root
)
113 struct listnode
*node
, *nnode
;
114 struct vertex
*child
;
116 for (ALL_LIST_ELEMENTS (root
->children
, node
, nnode
, child
))
118 struct listnode
*n2
, *nn2
;
119 struct vertex_parent
*vp
;
121 /* router vertices through an attached network each
122 * have a distinct (canonical / not inherited) nexthop
123 * which must be freed.
125 * A network vertex can only have router vertices as its
126 * children, so only one level of recursion is possible.
128 if (child
->type
== OSPF_VERTEX_NETWORK
)
129 ospf_canonical_nexthops_free (child
);
131 /* Free child nexthops pointing back to this root vertex */
132 for (ALL_LIST_ELEMENTS (child
->parents
, n2
, nn2
, vp
))
133 if (vp
->parent
== root
&& vp
->nexthop
)
134 vertex_nexthop_free (vp
->nexthop
);
138 /* TODO: Parent list should be excised, in favour of maintaining only
139 * vertex_nexthop, with refcounts.
141 static struct vertex_parent
*
142 vertex_parent_new (struct vertex
*v
, int backlink
, struct vertex_nexthop
*hop
)
144 struct vertex_parent
*new;
146 new = XMALLOC (MTYPE_OSPF_VERTEX_PARENT
, sizeof (struct vertex_parent
));
152 new->backlink
= backlink
;
158 vertex_parent_free (void *p
)
160 XFREE (MTYPE_OSPF_VERTEX_PARENT
, p
);
163 static struct vertex
*
164 ospf_vertex_new (struct ospf_lsa
*lsa
)
168 new = XCALLOC (MTYPE_OSPF_VERTEX
, sizeof (struct vertex
));
171 new->stat
= &(lsa
->stat
);
172 new->type
= lsa
->data
->type
;
173 new->id
= lsa
->data
->id
;
174 new->lsa
= lsa
->data
;
175 new->children
= list_new ();
176 new->parents
= list_new ();
177 new->parents
->del
= vertex_parent_free
;
179 listnode_add (&vertex_list
, new);
181 if (IS_DEBUG_OSPF_EVENT
)
182 zlog_debug ("%s: Created %s vertex %s", __func__
,
183 new->type
== OSPF_VERTEX_ROUTER
? "Router" : "Network",
184 inet_ntoa (new->lsa
->id
));
189 ospf_vertex_free (void *data
)
191 struct vertex
*v
= data
;
193 if (IS_DEBUG_OSPF_EVENT
)
194 zlog_debug ("%s: Free %s vertex %s", __func__
,
195 v
->type
== OSPF_VERTEX_ROUTER
? "Router" : "Network",
196 inet_ntoa (v
->lsa
->id
));
198 /* There should be no parents potentially holding references to this vertex
199 * Children however may still be there, but presumably referenced by other
202 //assert (listcount (v->parents) == 0);
205 list_delete (v
->children
);
209 list_delete (v
->parents
);
214 XFREE (MTYPE_OSPF_VERTEX
, v
);
218 ospf_vertex_dump(const char *msg
, struct vertex
*v
,
219 int print_parents
, int print_children
)
221 if ( ! IS_DEBUG_OSPF_EVENT
)
224 zlog_debug("%s %s vertex %s distance %u flags %u",
226 v
->type
== OSPF_VERTEX_ROUTER
? "Router" : "Network",
227 inet_ntoa(v
->lsa
->id
),
229 (unsigned int)v
->flags
);
233 struct listnode
*node
;
234 struct vertex_parent
*vp
;
236 for (ALL_LIST_ELEMENTS_RO (v
->parents
, node
, vp
))
242 zlog_debug ("parent %s backlink %d nexthop %s interface %s",
243 inet_ntoa(vp
->parent
->lsa
->id
), vp
->backlink
,
244 inet_ntop(AF_INET
, &vp
->nexthop
->router
, buf1
, BUFSIZ
),
245 vp
->nexthop
->oi
? IF_NAME(vp
->nexthop
->oi
) : "NULL");
252 struct listnode
*cnode
;
255 for (ALL_LIST_ELEMENTS_RO (v
->children
, cnode
, cv
))
256 ospf_vertex_dump(" child:", cv
, 0, 0);
261 /* Add a vertex to the list of children in each of its parents. */
263 ospf_vertex_add_parent (struct vertex
*v
)
265 struct vertex_parent
*vp
;
266 struct listnode
*node
;
268 assert (v
&& v
->parents
);
270 for (ALL_LIST_ELEMENTS_RO (v
->parents
, node
, vp
))
272 assert (vp
->parent
&& vp
->parent
->children
);
274 /* No need to add two links from the same parent. */
275 if (listnode_lookup (vp
->parent
->children
, v
) == NULL
)
276 listnode_add (vp
->parent
->children
, v
);
281 ospf_spf_init (struct ospf_area
*area
)
285 /* Create root node. */
286 v
= ospf_vertex_new (area
->router_lsa_self
);
290 /* Reset ABR and ASBR router counts. */
292 area
->asbr_count
= 0;
295 /* return index of link back to V from W, or -1 if no link found */
297 ospf_lsa_has_link (struct lsa_header
*w
, struct lsa_header
*v
)
299 unsigned int i
, length
;
300 struct router_lsa
*rl
;
301 struct network_lsa
*nl
;
303 /* In case of W is Network LSA. */
304 if (w
->type
== OSPF_NETWORK_LSA
)
306 if (v
->type
== OSPF_NETWORK_LSA
)
309 nl
= (struct network_lsa
*) w
;
310 length
= (ntohs (w
->length
) - OSPF_LSA_HEADER_SIZE
- 4) / 4;
312 for (i
= 0; i
< length
; i
++)
313 if (IPV4_ADDR_SAME (&nl
->routers
[i
], &v
->id
))
318 /* In case of W is Router LSA. */
319 if (w
->type
== OSPF_ROUTER_LSA
)
321 rl
= (struct router_lsa
*) w
;
323 length
= ntohs (w
->length
);
326 i
< ntohs (rl
->links
) && length
>= sizeof (struct router_lsa
);
329 switch (rl
->link
[i
].type
)
331 case LSA_LINK_TYPE_POINTOPOINT
:
332 case LSA_LINK_TYPE_VIRTUALLINK
:
334 if (v
->type
== OSPF_ROUTER_LSA
&&
335 IPV4_ADDR_SAME (&rl
->link
[i
].link_id
, &v
->id
))
340 case LSA_LINK_TYPE_TRANSIT
:
341 /* Network LSA ID. */
342 if (v
->type
== OSPF_NETWORK_LSA
&&
343 IPV4_ADDR_SAME (&rl
->link
[i
].link_id
, &v
->id
))
348 case LSA_LINK_TYPE_STUB
:
349 /* Stub can't lead anywhere, carry on */
359 #define ROUTER_LSA_MIN_SIZE 12
360 #define ROUTER_LSA_TOS_SIZE 4
362 /* Find the next link after prev_link from v to w. If prev_link is
363 * NULL, return the first link from v to w. Ignore stub and virtual links;
364 * these link types will never be returned.
366 static struct router_lsa_link
*
367 ospf_get_next_link (struct vertex
*v
, struct vertex
*w
,
368 struct router_lsa_link
*prev_link
)
372 struct router_lsa_link
*l
;
374 if (prev_link
== NULL
)
375 p
= ((u_char
*) v
->lsa
) + OSPF_LSA_HEADER_SIZE
+ 4;
378 p
= (u_char
*) prev_link
;
379 p
+= (ROUTER_LSA_MIN_SIZE
+
380 (prev_link
->m
[0].tos_count
* ROUTER_LSA_TOS_SIZE
));
383 lim
= ((u_char
*) v
->lsa
) + ntohs (v
->lsa
->length
);
387 l
= (struct router_lsa_link
*) p
;
389 p
+= (ROUTER_LSA_MIN_SIZE
+ (l
->m
[0].tos_count
* ROUTER_LSA_TOS_SIZE
));
391 if (l
->m
[0].type
== LSA_LINK_TYPE_STUB
)
394 /* Defer NH calculation via VLs until summaries from
395 transit areas area confidered */
397 if (l
->m
[0].type
== LSA_LINK_TYPE_VIRTUALLINK
)
400 if (IPV4_ADDR_SAME (&l
->link_id
, &w
->id
))
408 ospf_spf_flush_parents (struct vertex
*w
)
410 struct vertex_parent
*vp
;
411 struct listnode
*ln
, *nn
;
413 /* delete the existing nexthops */
414 for (ALL_LIST_ELEMENTS (w
->parents
, ln
, nn
, vp
))
416 list_delete_node (w
->parents
, ln
);
417 vertex_parent_free (vp
);
422 * Consider supplied next-hop for inclusion to the supplied list of
423 * equal-cost next-hops, adjust list as neccessary.
426 ospf_spf_add_parent (struct vertex
*v
, struct vertex
*w
,
427 struct vertex_nexthop
*newhop
,
428 unsigned int distance
)
430 struct vertex_parent
*vp
;
432 /* we must have a newhop, and a distance */
433 assert (v
&& w
&& newhop
);
436 /* IFF w has already been assigned a distance, then we shouldn't get here
437 * unless callers have determined V(l)->W is shortest / equal-shortest
438 * path (0 is a special case distance (no distance yet assigned)).
441 assert (distance
<= w
->distance
);
443 w
->distance
= distance
;
445 if (IS_DEBUG_OSPF_EVENT
)
447 char buf
[2][INET_ADDRSTRLEN
];
448 zlog_debug ("%s: Adding %s as parent of %s",
450 inet_ntop(AF_INET
, &v
->lsa
->id
, buf
[0], sizeof(buf
[0])),
451 inet_ntop(AF_INET
, &w
->lsa
->id
, buf
[1], sizeof(buf
[1])));
454 /* Adding parent for a new, better path: flush existing parents from W. */
455 if (distance
< w
->distance
)
457 if (IS_DEBUG_OSPF_EVENT
)
458 zlog_debug ("%s: distance %d better than %d, flushing existing parents",
459 __func__
, distance
, w
->distance
);
460 ospf_spf_flush_parents (w
);
461 w
->distance
= distance
;
464 /* new parent is <= existing parents, add it to parent list */
465 vp
= vertex_parent_new (v
, ospf_lsa_has_link (w
->lsa
, v
->lsa
), newhop
);
466 listnode_add (w
->parents
, vp
);
471 /* 16.1.1. Calculate nexthop from root through V (parent) to
472 * vertex W (destination), with given distance from root->W.
474 * The link must be supplied if V is the root vertex. In all other cases
477 * Note that this function may fail, hence the state of the destination
478 * vertex, W, should /not/ be modified in a dependent manner until
479 * this function returns. This function will update the W vertex with the
480 * provided distance as appropriate.
483 ospf_nexthop_calculation (struct ospf_area
*area
, struct vertex
*v
,
484 struct vertex
*w
, struct router_lsa_link
*l
,
485 unsigned int distance
)
487 struct listnode
*node
, *nnode
;
488 struct vertex_nexthop
*nh
;
489 struct vertex_parent
*vp
;
490 struct ospf_interface
*oi
= NULL
;
491 unsigned int added
= 0;
493 if (IS_DEBUG_OSPF_EVENT
)
495 zlog_debug ("ospf_nexthop_calculation(): Start");
496 ospf_vertex_dump("V (parent):", v
, 1, 1);
497 ospf_vertex_dump("W (dest) :", w
, 1, 1);
498 zlog_debug ("V->W distance: %d", distance
);
503 /* 16.1.1 para 4. In the first case, the parent vertex (V) is the
504 root (the calculating router itself). This means that the
505 destination is either a directly connected network or directly
506 connected router. The outgoing interface in this case is simply
507 the OSPF interface connecting to the destination network/router.
510 if (w
->type
== OSPF_VERTEX_ROUTER
)
512 /* l is a link from v to w
513 * l2 will be link from w to v
515 struct router_lsa_link
*l2
= NULL
;
517 /* we *must* be supplied with the link data */
520 if (IS_DEBUG_OSPF_EVENT
)
525 zlog_debug("ospf_nexthop_calculation(): considering link "
526 "type %d link_id %s link_data %s",
528 inet_ntop (AF_INET
, &l
->link_id
, buf1
, BUFSIZ
),
529 inet_ntop (AF_INET
, &l
->link_data
, buf2
, BUFSIZ
));
532 if (l
->m
[0].type
== LSA_LINK_TYPE_POINTOPOINT
)
534 /* If the destination is a router which connects to
535 the calculating router via a Point-to-MultiPoint
536 network, the destination's next hop IP address(es)
537 can be determined by examining the destination's
538 router-LSA: each link pointing back to the
539 calculating router and having a Link Data field
540 belonging to the Point-to-MultiPoint network
541 provides an IP address of the next hop router.
543 At this point l is a link from V to W, and V is the
544 root ("us"). Find the local interface associated
545 with l (its address is in l->link_data). If it
546 is a point-to-multipoint interface, then look through
547 the links in the opposite direction (W to V). If
548 any of them have an address that lands within the
549 subnet declared by the PtMP link, then that link
550 is a constituent of the PtMP link, and its address is
551 a nexthop address for V.
553 oi
= ospf_if_is_configured (area
->ospf
, &l
->link_data
);
554 if (oi
&& oi
->type
== OSPF_IFTYPE_POINTOMULTIPOINT
)
556 struct prefix_ipv4 la
;
559 la
.prefixlen
= oi
->address
->prefixlen
;
561 /* V links to W on PtMP interface
562 - find the interface address on W */
563 while ((l2
= ospf_get_next_link (w
, v
, l2
)))
565 la
.prefix
= l2
->link_data
;
567 if (prefix_cmp ((struct prefix
*) &la
,
569 /* link_data is on our PtMP network */
572 } /* end l is on point-to-multipoint link */
575 /* l is a regular point-to-point link.
576 Look for a link from W to V.
578 while ((l2
= ospf_get_next_link (w
, v
, l2
)))
580 oi
= ospf_if_is_configured (area
->ospf
,
586 if (!IPV4_ADDR_SAME (&oi
->address
->u
.prefix4
,
596 /* found all necessary info to build nexthop */
597 nh
= vertex_nexthop_new ();
599 nh
->router
= l2
->link_data
;
600 ospf_spf_add_parent (v
, w
, nh
, distance
);
604 zlog_info("ospf_nexthop_calculation(): "
605 "could not determine nexthop for link");
606 } /* end point-to-point link from V to W */
607 else if (l
->m
[0].type
== LSA_LINK_TYPE_VIRTUALLINK
)
609 struct ospf_vl_data
*vl_data
;
611 /* VLink implementation limitations:
612 * a) vl_data can only reference one nexthop, so no ECMP
613 * to backbone through VLinks. Though transit-area
614 * summaries may be considered, and those can be ECMP.
615 * b) We can only use /one/ VLink, even if multiple ones
616 * exist this router through multiple transit-areas.
618 vl_data
= ospf_vl_lookup (area
->ospf
, NULL
, l
->link_id
);
621 && CHECK_FLAG (vl_data
->flags
, OSPF_VL_FLAG_APPROVED
))
623 nh
= vertex_nexthop_new ();
624 nh
->oi
= vl_data
->nexthop
.oi
;
625 nh
->router
= vl_data
->nexthop
.router
;
626 ospf_spf_add_parent (v
, w
, nh
, distance
);
630 zlog_info("ospf_nexthop_calculation(): "
631 "vl_data for VL link not found");
632 } /* end virtual-link from V to W */
634 } /* end W is a Router vertex */
637 assert(w
->type
== OSPF_VERTEX_NETWORK
);
638 oi
= ospf_if_is_configured (area
->ospf
, &(l
->link_data
));
641 nh
= vertex_nexthop_new ();
643 nh
->router
.s_addr
= 0;
644 ospf_spf_add_parent (v
, w
, nh
, distance
);
648 zlog_info("ospf_nexthop_calculation(): "
649 "Unknown attached link");
651 } /* end V is the root */
652 /* Check if W's parent is a network connected to root. */
653 else if (v
->type
== OSPF_VERTEX_NETWORK
)
655 /* See if any of V's parents are the root. */
656 for (ALL_LIST_ELEMENTS (v
->parents
, node
, nnode
, vp
))
658 if (vp
->parent
== area
->spf
) /* connects to root? */
660 /* 16.1.1 para 5. ...the parent vertex is a network that
661 * directly connects the calculating router to the destination
662 * router. The list of next hops is then determined by
663 * examining the destination's router-LSA...
666 assert(w
->type
== OSPF_VERTEX_ROUTER
);
667 while ((l
= ospf_get_next_link (w
, v
, l
)))
669 /* ...For each link in the router-LSA that points back to the
670 * parent network, the link's Link Data field provides the IP
671 * address of a next hop router. The outgoing interface to
672 * use can then be derived from the next hop IP address (or
673 * it can be inherited from the parent network).
675 nh
= vertex_nexthop_new ();
676 nh
->oi
= vp
->nexthop
->oi
;
677 nh
->router
= l
->link_data
;
679 ospf_spf_add_parent (v
, w
, nh
, distance
);
687 /* 16.1.1 para 4. If there is at least one intervening router in the
688 * current shortest path between the destination and the root, the
689 * destination simply inherits the set of next hops from the
692 if (IS_DEBUG_OSPF_EVENT
)
693 zlog_debug ("%s: Intervening routers, adding parent(s)", __func__
);
695 for (ALL_LIST_ELEMENTS (v
->parents
, node
, nnode
, vp
))
698 ospf_spf_add_parent (v
, w
, vp
->nexthop
, distance
);
704 /* RFC2328 Section 16.1 (2).
705 * v is on the SPF tree. Examine the links in v's LSA. Update the list
706 * of candidates with any vertices not already on the list. If a lower-cost
707 * path is found to a vertex already on the candidate list, store the new cost.
710 ospf_spf_next (struct vertex
*v
, struct ospf_area
*area
,
711 struct pqueue
* candidate
)
713 struct ospf_lsa
*w_lsa
= NULL
;
716 struct router_lsa_link
*l
= NULL
;
720 /* If this is a router-LSA, and bit V of the router-LSA (see Section
721 A.4.2:RFC2328) is set, set Area A's TransitCapability to TRUE. */
722 if (v
->type
== OSPF_VERTEX_ROUTER
)
724 if (IS_ROUTER_LSA_VIRTUAL ((struct router_lsa
*) v
->lsa
))
725 area
->transit
= OSPF_TRANSIT_TRUE
;
728 if (IS_DEBUG_OSPF_EVENT
)
729 zlog_debug ("%s: Next vertex of %s vertex %s",
731 v
->type
== OSPF_VERTEX_ROUTER
? "Router" : "Network",
732 inet_ntoa(v
->lsa
->id
));
734 p
= ((u_char
*) v
->lsa
) + OSPF_LSA_HEADER_SIZE
+ 4;
735 lim
= ((u_char
*) v
->lsa
) + ntohs (v
->lsa
->length
);
740 unsigned int distance
;
742 /* In case of V is Router-LSA. */
743 if (v
->lsa
->type
== OSPF_ROUTER_LSA
)
745 l
= (struct router_lsa_link
*) p
;
747 p
+= (ROUTER_LSA_MIN_SIZE
+
748 (l
->m
[0].tos_count
* ROUTER_LSA_TOS_SIZE
));
750 /* (a) If this is a link to a stub network, examine the next
751 link in V's LSA. Links to stub networks will be
752 considered in the second stage of the shortest path
754 if ((type
= l
->m
[0].type
) == LSA_LINK_TYPE_STUB
)
757 /* Infinite distance links shouldn't be followed, except
758 * for local links (a stub-routed router still wants to
759 * calculate tree, so must follow its own links).
761 if ((v
!= area
->spf
) && l
->m
[0].metric
>= OSPF_OUTPUT_COST_INFINITE
)
764 /* (b) Otherwise, W is a transit vertex (router or transit
765 network). Look up the vertex W's LSA (router-LSA or
766 network-LSA) in Area A's link state database. */
769 case LSA_LINK_TYPE_POINTOPOINT
:
770 case LSA_LINK_TYPE_VIRTUALLINK
:
771 if (type
== LSA_LINK_TYPE_VIRTUALLINK
)
773 if (IS_DEBUG_OSPF_EVENT
)
774 zlog_debug ("looking up LSA through VL: %s",
775 inet_ntoa (l
->link_id
));
778 w_lsa
= ospf_lsa_lookup (area
, OSPF_ROUTER_LSA
, l
->link_id
,
782 if (IS_DEBUG_OSPF_EVENT
)
783 zlog_debug ("found Router LSA %s", inet_ntoa (l
->link_id
));
786 case LSA_LINK_TYPE_TRANSIT
:
787 if (IS_DEBUG_OSPF_EVENT
)
788 zlog_debug ("Looking up Network LSA, ID: %s",
789 inet_ntoa (l
->link_id
));
790 w_lsa
= ospf_lsa_lookup_by_id (area
, OSPF_NETWORK_LSA
,
793 if (IS_DEBUG_OSPF_EVENT
)
794 zlog_debug ("found the LSA");
797 zlog_warn ("Invalid LSA link type %d", type
);
803 /* In case of V is Network-LSA. */
804 r
= (struct in_addr
*) p
;
805 p
+= sizeof (struct in_addr
);
807 /* Lookup the vertex W's LSA. */
808 w_lsa
= ospf_lsa_lookup_by_id (area
, OSPF_ROUTER_LSA
, *r
);
811 if (IS_DEBUG_OSPF_EVENT
)
812 zlog_debug ("found Router LSA %s", inet_ntoa (w_lsa
->data
->id
));
816 /* (b cont.) If the LSA does not exist, or its LS age is equal
817 to MaxAge, or it does not have a link back to vertex V,
818 examine the next link in V's LSA.[23] */
821 if (IS_DEBUG_OSPF_EVENT
)
822 zlog_debug ("No LSA found");
826 if (IS_LSA_MAXAGE (w_lsa
))
828 if (IS_DEBUG_OSPF_EVENT
)
829 zlog_debug ("LSA is MaxAge");
833 if (ospf_lsa_has_link (w_lsa
->data
, v
->lsa
) < 0 )
835 if (IS_DEBUG_OSPF_EVENT
)
836 zlog_debug ("The LSA doesn't have a link back");
840 /* (c) If vertex W is already on the shortest-path tree, examine
841 the next link in the LSA. */
842 if (w_lsa
->stat
== LSA_SPF_IN_SPFTREE
)
844 if (IS_DEBUG_OSPF_EVENT
)
845 zlog_debug ("The LSA is already in SPF");
849 /* (d) Calculate the link state cost D of the resulting path
850 from the root to vertex W. D is equal to the sum of the link
851 state cost of the (already calculated) shortest path to
852 vertex V and the advertised cost of the link between vertices
855 /* calculate link cost D. */
856 if (v
->lsa
->type
== OSPF_ROUTER_LSA
)
857 distance
= v
->distance
+ ntohs (l
->m
[0].metric
);
858 else /* v is not a Router-LSA */
859 distance
= v
->distance
;
861 /* Is there already vertex W in candidate list? */
862 if (w_lsa
->stat
== LSA_SPF_NOT_EXPLORED
)
864 /* prepare vertex W. */
865 w
= ospf_vertex_new (w_lsa
);
867 /* Calculate nexthop to W. */
868 if (ospf_nexthop_calculation (area
, v
, w
, l
, distance
))
869 pqueue_enqueue (w
, candidate
);
870 else if (IS_DEBUG_OSPF_EVENT
)
871 zlog_debug ("Nexthop Calc failed");
873 else if (w_lsa
->stat
>= 0)
875 /* Get the vertex from candidates. */
876 w
= candidate
->array
[w_lsa
->stat
];
878 /* if D is greater than. */
879 if (w
->distance
< distance
)
884 else if (w
->distance
== distance
)
886 /* Found an equal-cost path to W.
887 * Calculate nexthop of to W from V. */
888 ospf_nexthop_calculation (area
, v
, w
, l
, distance
);
893 /* Found a lower-cost path to W.
894 * nexthop_calculation is conditional, if it finds
895 * valid nexthop it will call spf_add_parents, which
896 * will flush the old parents
898 if (ospf_nexthop_calculation (area
, v
, w
, l
, distance
))
899 /* Decrease the key of the node in the heap.
900 * trickle-sort it up towards root, just in case this
901 * node should now be the new root due the cost change.
902 * (next pqueu_{de,en}queue will fully re-heap the queue).
904 trickle_up (w_lsa
->stat
, candidate
);
906 } /* end W is already on the candidate list */
907 } /* end loop over the links in V's LSA */
911 ospf_spf_dump (struct vertex
*v
, int i
)
913 struct listnode
*cnode
;
914 struct listnode
*nnode
;
915 struct vertex_parent
*parent
;
917 if (v
->type
== OSPF_VERTEX_ROUTER
)
919 if (IS_DEBUG_OSPF_EVENT
)
920 zlog_debug ("SPF Result: %d [R] %s", i
, inet_ntoa (v
->lsa
->id
));
924 struct network_lsa
*lsa
= (struct network_lsa
*) v
->lsa
;
925 if (IS_DEBUG_OSPF_EVENT
)
926 zlog_debug ("SPF Result: %d [N] %s/%d", i
, inet_ntoa (v
->lsa
->id
),
927 ip_masklen (lsa
->mask
));
930 if (IS_DEBUG_OSPF_EVENT
)
931 for (ALL_LIST_ELEMENTS_RO (v
->parents
, nnode
, parent
))
933 zlog_debug (" nexthop %p %s %s",
935 inet_ntoa (parent
->nexthop
->router
),
936 parent
->nexthop
->oi
? IF_NAME(parent
->nexthop
->oi
)
942 for (ALL_LIST_ELEMENTS_RO (v
->children
, cnode
, v
))
943 ospf_spf_dump (v
, i
);
946 /* Second stage of SPF calculation. */
948 ospf_spf_process_stubs (struct ospf_area
*area
, struct vertex
*v
,
949 struct route_table
*rt
)
951 struct listnode
*cnode
, *cnnode
;
952 struct vertex
*child
;
954 if (IS_DEBUG_OSPF_EVENT
)
955 zlog_debug ("ospf_process_stub():processing stubs for area %s",
956 inet_ntoa (area
->area_id
));
957 if (v
->type
== OSPF_VERTEX_ROUTER
)
961 struct router_lsa_link
*l
;
962 struct router_lsa
*rlsa
;
964 if (IS_DEBUG_OSPF_EVENT
)
965 zlog_debug ("ospf_process_stubs():processing router LSA, id: %s",
966 inet_ntoa (v
->lsa
->id
));
967 rlsa
= (struct router_lsa
*) v
->lsa
;
970 if (IS_DEBUG_OSPF_EVENT
)
971 zlog_debug ("ospf_process_stubs(): we have %d links to process",
972 ntohs (rlsa
->links
));
973 p
= ((u_char
*) v
->lsa
) + OSPF_LSA_HEADER_SIZE
+ 4;
974 lim
= ((u_char
*) v
->lsa
) + ntohs (v
->lsa
->length
);
978 l
= (struct router_lsa_link
*) p
;
980 p
+= (ROUTER_LSA_MIN_SIZE
+
981 (l
->m
[0].tos_count
* ROUTER_LSA_TOS_SIZE
));
983 if (l
->m
[0].type
== LSA_LINK_TYPE_STUB
)
984 ospf_intra_add_stub (rt
, l
, v
, area
);
988 ospf_vertex_dump("ospf_process_stubs(): after examining links: ", v
, 1, 1);
990 for (ALL_LIST_ELEMENTS (v
->children
, cnode
, cnnode
, child
))
992 if (CHECK_FLAG (child
->flags
, OSPF_VERTEX_PROCESSED
))
995 ospf_spf_process_stubs (area
, child
, rt
);
997 SET_FLAG (child
->flags
, OSPF_VERTEX_PROCESSED
);
1002 ospf_rtrs_free (struct route_table
*rtrs
)
1004 struct route_node
*rn
;
1005 struct list
*or_list
;
1006 struct ospf_route
*or;
1007 struct listnode
*node
, *nnode
;
1009 if (IS_DEBUG_OSPF_EVENT
)
1010 zlog_debug ("Route: Router Routing Table free");
1012 for (rn
= route_top (rtrs
); rn
; rn
= route_next (rn
))
1013 if ((or_list
= rn
->info
) != NULL
)
1015 for (ALL_LIST_ELEMENTS (or_list
, node
, nnode
, or))
1016 ospf_route_free (or);
1018 list_delete (or_list
);
1020 /* Unlock the node. */
1022 route_unlock_node (rn
);
1024 route_table_finish (rtrs
);
1028 ospf_rtrs_print (struct route_table
*rtrs
)
1030 struct route_node
*rn
;
1031 struct list
*or_list
;
1032 struct listnode
*ln
;
1033 struct listnode
*pnode
;
1034 struct ospf_route
*or;
1035 struct ospf_path
*path
;
1039 if (IS_DEBUG_OSPF_EVENT
)
1040 zlog_debug ("ospf_rtrs_print() start");
1042 for (rn
= route_top (rtrs
); rn
; rn
= route_next (rn
))
1043 if ((or_list
= rn
->info
) != NULL
)
1044 for (ALL_LIST_ELEMENTS_RO (or_list
, ln
, or))
1046 switch (or->path_type
)
1048 case OSPF_PATH_INTRA_AREA
:
1049 if (IS_DEBUG_OSPF_EVENT
)
1050 zlog_debug ("%s [%d] area: %s",
1051 inet_ntop (AF_INET
, &or->id
, buf1
, BUFSIZ
),
1052 or->cost
, inet_ntop (AF_INET
, &or->u
.std
.area_id
,
1055 case OSPF_PATH_INTER_AREA
:
1056 if (IS_DEBUG_OSPF_EVENT
)
1057 zlog_debug ("%s IA [%d] area: %s",
1058 inet_ntop (AF_INET
, &or->id
, buf1
, BUFSIZ
),
1059 or->cost
, inet_ntop (AF_INET
, &or->u
.std
.area_id
,
1066 for (ALL_LIST_ELEMENTS_RO (or->paths
, pnode
, path
))
1068 if (path
->nexthop
.s_addr
== 0)
1070 if (IS_DEBUG_OSPF_EVENT
)
1071 zlog_debug (" directly attached to %s\r\n",
1072 IF_NAME (path
->oi
));
1076 if (IS_DEBUG_OSPF_EVENT
)
1077 zlog_debug (" via %s, %s\r\n",
1078 inet_ntoa (path
->nexthop
), IF_NAME (path
->oi
));
1083 zlog_debug ("ospf_rtrs_print() end");
1086 /* Calculating the shortest-path tree for an area. */
1088 ospf_spf_calculate (struct ospf_area
*area
, struct route_table
*new_table
,
1089 struct route_table
*new_rtrs
)
1091 struct pqueue
*candidate
;
1094 if (IS_DEBUG_OSPF_EVENT
)
1096 zlog_debug ("ospf_spf_calculate: Start");
1097 zlog_debug ("ospf_spf_calculate: running Dijkstra for area %s",
1098 inet_ntoa (area
->area_id
));
1101 /* Check router-lsa-self. If self-router-lsa is not yet allocated,
1102 return this area's calculation. */
1103 if (!area
->router_lsa_self
)
1105 if (IS_DEBUG_OSPF_EVENT
)
1106 zlog_debug ("ospf_spf_calculate: "
1107 "Skip area %s's calculation due to empty router_lsa_self",
1108 inet_ntoa (area
->area_id
));
1112 /* RFC2328 16.1. (1). */
1113 /* Initialize the algorithm's data structures. */
1115 /* This function scans all the LSA database and set the stat field to
1116 * LSA_SPF_NOT_EXPLORED. */
1117 ospf_lsdb_clean_stat (area
->lsdb
);
1118 /* Create a new heap for the candidates. */
1119 candidate
= pqueue_create();
1120 candidate
->cmp
= cmp
;
1121 candidate
->update
= update_stat
;
1123 /* Initialize the shortest-path tree to only the root (which is the
1124 router doing the calculation). */
1125 ospf_spf_init (area
);
1127 /* Set LSA position to LSA_SPF_IN_SPFTREE. This vertex is the root of the
1129 *(v
->stat
) = LSA_SPF_IN_SPFTREE
;
1131 /* Set Area A's TransitCapability to FALSE. */
1132 area
->transit
= OSPF_TRANSIT_FALSE
;
1133 area
->shortcut_capability
= 1;
1137 /* RFC2328 16.1. (2). */
1138 ospf_spf_next (v
, area
, candidate
);
1140 /* RFC2328 16.1. (3). */
1141 /* If at this step the candidate list is empty, the shortest-
1142 path tree (of transit vertices) has been completely built and
1143 this stage of the procedure terminates. */
1144 if (candidate
->size
== 0)
1147 /* Otherwise, choose the vertex belonging to the candidate list
1148 that is closest to the root, and add it to the shortest-path
1149 tree (removing it from the candidate list in the
1151 /* Extract from the candidates the node with the lower key. */
1152 v
= (struct vertex
*) pqueue_dequeue (candidate
);
1153 /* Update stat field in vertex. */
1154 *(v
->stat
) = LSA_SPF_IN_SPFTREE
;
1156 ospf_vertex_add_parent (v
);
1158 /* Note that when there is a choice of vertices closest to the
1159 root, network vertices must be chosen before router vertices
1160 in order to necessarily find all equal-cost paths. */
1161 /* We don't do this at this moment, we should add the treatment
1162 above codes. -- kunihiro. */
1164 /* RFC2328 16.1. (4). */
1165 if (v
->type
== OSPF_VERTEX_ROUTER
)
1166 ospf_intra_add_router (new_rtrs
, v
, area
);
1168 ospf_intra_add_transit (new_table
, v
, area
);
1170 /* RFC2328 16.1. (5). */
1171 /* Iterate the algorithm by returning to Step 2. */
1173 } /* end loop until no more candidate vertices */
1175 if (IS_DEBUG_OSPF_EVENT
)
1177 ospf_spf_dump (area
->spf
, 0);
1178 ospf_route_table_dump (new_table
);
1181 /* Second stage of SPF calculation procedure's */
1182 ospf_spf_process_stubs (area
, area
->spf
, new_table
);
1184 /* Free candidate queue. */
1185 pqueue_delete (candidate
);
1187 ospf_vertex_dump (__func__
, area
->spf
, 0, 1);
1188 /* Free nexthop information, canonical versions of which are attached
1189 * the first level of router vertices attached to the root vertex, see
1190 * ospf_nexthop_calculation.
1192 ospf_canonical_nexthops_free (area
->spf
);
1194 /* Free SPF vertices, but not the list. List has ospf_vertex_free
1197 list_delete_all_node (&vertex_list
);
1199 /* Increment SPF Calculation Counter. */
1200 area
->spf_calculation
++;
1202 quagga_gettime (QUAGGA_CLK_MONOTONIC
, &area
->ospf
->ts_spf
);
1204 if (IS_DEBUG_OSPF_EVENT
)
1205 zlog_debug ("ospf_spf_calculate: Stop. %ld vertices",
1206 mtype_stats_alloc(MTYPE_OSPF_VERTEX
));
1209 /* Timer for SPF calculation. */
1211 ospf_spf_calculate_timer (struct thread
*thread
)
1213 struct ospf
*ospf
= THREAD_ARG (thread
);
1214 struct route_table
*new_table
, *new_rtrs
;
1215 struct ospf_area
*area
;
1216 struct listnode
*node
, *nnode
;
1218 if (IS_DEBUG_OSPF_EVENT
)
1219 zlog_debug ("SPF: Timer (SPF calculation expire)");
1221 ospf
->t_spf_calc
= NULL
;
1223 /* Allocate new table tree. */
1224 new_table
= route_table_init ();
1225 new_rtrs
= route_table_init ();
1227 ospf_vl_unapprove (ospf
);
1229 /* Calculate SPF for each area. */
1230 for (ALL_LIST_ELEMENTS (ospf
->areas
, node
, nnode
, area
))
1232 /* Do backbone last, so as to first discover intra-area paths
1233 * for any back-bone virtual-links
1235 if (ospf
->backbone
&& ospf
->backbone
== area
)
1238 ospf_spf_calculate (area
, new_table
, new_rtrs
);
1241 /* SPF for backbone, if required */
1243 ospf_spf_calculate (ospf
->backbone
, new_table
, new_rtrs
);
1245 ospf_vl_shut_unapproved (ospf
);
1247 ospf_ia_routing (ospf
, new_table
, new_rtrs
);
1249 ospf_prune_unreachable_networks (new_table
);
1250 ospf_prune_unreachable_routers (new_rtrs
);
1252 /* AS-external-LSA calculation should not be performed here. */
1254 /* If new Router Route is installed,
1255 then schedule re-calculate External routes. */
1257 ospf_ase_calculate_schedule (ospf
);
1259 ospf_ase_calculate_timer_add (ospf
);
1261 /* Update routing table. */
1262 ospf_route_install (ospf
, new_table
);
1264 /* Update ABR/ASBR routing table */
1267 /* old_rtrs's node holds linked list of ospf_route. --kunihiro. */
1268 /* ospf_route_delete (ospf->old_rtrs); */
1269 ospf_rtrs_free (ospf
->old_rtrs
);
1272 ospf
->old_rtrs
= ospf
->new_rtrs
;
1273 ospf
->new_rtrs
= new_rtrs
;
1275 if (IS_OSPF_ABR (ospf
))
1276 ospf_abr_task (ospf
);
1278 if (IS_DEBUG_OSPF_EVENT
)
1279 zlog_debug ("SPF: calculation complete");
1284 /* Add schedule for SPF calculation. To avoid frequenst SPF calc, we
1285 set timer for SPF calc. */
1287 ospf_spf_calculate_schedule (struct ospf
*ospf
)
1289 unsigned long delay
, elapsed
, ht
;
1290 struct timeval result
;
1292 if (IS_DEBUG_OSPF_EVENT
)
1293 zlog_debug ("SPF: calculation timer scheduled");
1295 /* OSPF instance does not exist. */
1299 /* SPF calculation timer is already scheduled. */
1300 if (ospf
->t_spf_calc
)
1302 if (IS_DEBUG_OSPF_EVENT
)
1303 zlog_debug ("SPF: calculation timer is already scheduled: %p",
1308 /* XXX Monotic timers: we only care about relative time here. */
1309 result
= tv_sub (recent_relative_time (), ospf
->ts_spf
);
1311 elapsed
= (result
.tv_sec
* 1000) + (result
.tv_usec
/ 1000);
1312 ht
= ospf
->spf_holdtime
* ospf
->spf_hold_multiplier
;
1314 if (ht
> ospf
->spf_max_holdtime
)
1315 ht
= ospf
->spf_max_holdtime
;
1317 /* Get SPF calculation delay time. */
1320 /* Got an event within the hold time of last SPF. We need to
1321 * increase the hold_multiplier, if it's not already at/past
1322 * maximum value, and wasn't already increased..
1324 if (ht
< ospf
->spf_max_holdtime
)
1325 ospf
->spf_hold_multiplier
++;
1327 /* always honour the SPF initial delay */
1328 if ( (ht
- elapsed
) < ospf
->spf_delay
)
1329 delay
= ospf
->spf_delay
;
1331 delay
= ht
- elapsed
;
1335 /* Event is past required hold-time of last SPF */
1336 delay
= ospf
->spf_delay
;
1337 ospf
->spf_hold_multiplier
= 1;
1340 if (IS_DEBUG_OSPF_EVENT
)
1341 zlog_debug ("SPF: calculation timer delay = %ld", delay
);
1344 thread_add_timer_msec (master
, ospf_spf_calculate_timer
, ospf
, delay
);