Import Upstream version 1.2.2
[quagga-debian.git] / ospfd / ospf_spf.c
1 /* OSPF SPF calculation.
2    Copyright (C) 1999, 2000 Kunihiro Ishiguro, Toshiaki Takada
3
4 This file is part of GNU Zebra.
5
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
9 later version.
10
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.
15
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
19 02111-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 #include "pqueue.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_ia.h"
45 #include "ospfd/ospf_ase.h"
46 #include "ospfd/ospf_abr.h"
47 #include "ospfd/ospf_dump.h"
48
49 /* Variables to ensure a SPF scheduled log message is printed only once */
50
51 static unsigned int spf_reason_flags = 0;
52
53 static void
54 ospf_clear_spf_reason_flags ()
55 {
56   spf_reason_flags = 0;
57 }
58
59 static void 
60 ospf_spf_set_reason (ospf_spf_reason_t reason)
61 {
62   spf_reason_flags |= 1 << reason;
63 }
64
65 static void
66 ospf_get_spf_reason_str (char *buf)
67 {
68   if (!buf)
69    return;
70  
71   buf[0] = '\0';
72   if (spf_reason_flags)
73     {
74       if (spf_reason_flags & SPF_FLAG_ROUTER_LSA_INSTALL)
75         strcat (buf, "R, ");
76       if (spf_reason_flags & SPF_FLAG_NETWORK_LSA_INSTALL)
77         strcat (buf, "N, ");
78       if (spf_reason_flags & SPF_FLAG_SUMMARY_LSA_INSTALL)
79         strcat (buf, "S, ");
80       if (spf_reason_flags & SPF_FLAG_ASBR_SUMMARY_LSA_INSTALL)
81         strcat (buf, "AS, ");
82       if (spf_reason_flags & SPF_FLAG_ABR_STATUS_CHANGE)
83         strcat (buf, "ABR, ");
84       if (spf_reason_flags & SPF_FLAG_ASBR_STATUS_CHANGE)
85         strcat (buf, "ASBR, ");
86       if (spf_reason_flags & SPF_FLAG_MAXAGE)
87         strcat (buf, "M, ");
88       buf[strlen(buf)-2] = '\0'; /* skip the last ", " */
89     }
90 }
91
92 static void ospf_vertex_free (void *);
93 /* List of allocated vertices, to simplify cleanup of SPF.
94  * Not thread-safe obviously. If it ever needs to be, it'd have to be
95  * dynamically allocated at begin of ospf_spf_calculate
96  */
97 static struct list vertex_list = { .del = ospf_vertex_free };
98
99 /* Heap related functions, for the managment of the candidates, to
100  * be used with pqueue. */
101 static int
102 cmp (void * node1 , void * node2)
103 {
104   struct vertex * v1 = (struct vertex *) node1;
105   struct vertex * v2 = (struct vertex *) node2;
106   if (v1 != NULL && v2 != NULL )
107     {
108       /* network vertices must be chosen before router vertices of same
109        * cost in order to find all shortest paths
110        */
111       if ( ((v1->distance - v2->distance) == 0)
112           && (v1->type != v2->type))
113         {
114           switch (v1->type)
115             {
116               case OSPF_VERTEX_NETWORK:
117                 return -1;
118               case OSPF_VERTEX_ROUTER:
119                 return 1;
120             }
121         }
122       else
123         return (v1->distance - v2->distance);
124     }
125   return 0;
126 }
127
128 static void
129 update_stat (void *node , int position)
130 {
131   struct vertex *v = node;
132
133   /* Set the status of the vertex, when its position changes. */
134   *(v->stat) = position;
135 }
136
137 static struct vertex_nexthop *
138 vertex_nexthop_new (void)
139 {
140   return XCALLOC (MTYPE_OSPF_NEXTHOP, sizeof (struct vertex_nexthop));
141 }
142
143 static void
144 vertex_nexthop_free (struct vertex_nexthop *nh)
145 {
146   XFREE (MTYPE_OSPF_NEXTHOP, nh);
147 }
148
149 /* Free the canonical nexthop objects for an area, ie the nexthop objects
150  * attached to the first-hop router vertices, and any intervening network
151  * vertices.
152  */
153 static void
154 ospf_canonical_nexthops_free (struct vertex *root)
155 {
156   struct listnode *node, *nnode;
157   struct vertex *child;
158   
159   for (ALL_LIST_ELEMENTS (root->children, node, nnode, child))
160     {
161       struct listnode *n2, *nn2;
162       struct vertex_parent *vp;
163       
164       /* router vertices through an attached network each
165        * have a distinct (canonical / not inherited) nexthop
166        * which must be freed.
167        *
168        * A network vertex can only have router vertices as its
169        * children, so only one level of recursion is possible.
170        */
171       if (child->type == OSPF_VERTEX_NETWORK)
172         ospf_canonical_nexthops_free (child);
173       
174       /* Free child nexthops pointing back to this root vertex */
175       for (ALL_LIST_ELEMENTS (child->parents, n2, nn2, vp))
176         if (vp->parent == root && vp->nexthop)
177           vertex_nexthop_free (vp->nexthop);
178     }
179 }      
180
181 /* TODO: Parent list should be excised, in favour of maintaining only
182  * vertex_nexthop, with refcounts.
183  */
184 static struct vertex_parent *
185 vertex_parent_new (struct vertex *v, int backlink, struct vertex_nexthop *hop)
186 {
187   struct vertex_parent *new;
188   
189   new = XMALLOC (MTYPE_OSPF_VERTEX_PARENT, sizeof (struct vertex_parent));
190   
191   if (new == NULL)
192     return NULL;
193   
194   new->parent = v;
195   new->backlink = backlink;
196   new->nexthop = hop;
197   return new;
198 }
199
200 static void
201 vertex_parent_free (void *p)
202 {
203   XFREE (MTYPE_OSPF_VERTEX_PARENT, p);
204 }
205
206 static struct vertex *
207 ospf_vertex_new (struct ospf_lsa *lsa)
208 {
209   struct vertex *new;
210
211   new = XCALLOC (MTYPE_OSPF_VERTEX, sizeof (struct vertex));
212
213   new->flags = 0;
214   new->stat = &(lsa->stat);
215   new->type = lsa->data->type;
216   new->id = lsa->data->id;
217   new->lsa = lsa->data;
218   new->children = list_new ();
219   new->parents = list_new ();
220   new->parents->del = vertex_parent_free;
221   
222   listnode_add (&vertex_list, new);
223   
224   if (IS_DEBUG_OSPF_EVENT)
225     zlog_debug ("%s: Created %s vertex %s", __func__,
226                 new->type == OSPF_VERTEX_ROUTER ? "Router" : "Network",
227                 inet_ntoa (new->lsa->id));
228   return new;
229 }
230
231 static void
232 ospf_vertex_free (void *data)
233 {
234   struct vertex *v = data;
235   
236   if (IS_DEBUG_OSPF_EVENT)
237     zlog_debug ("%s: Free %s vertex %s", __func__,
238                 v->type == OSPF_VERTEX_ROUTER ? "Router" : "Network",
239                 inet_ntoa (v->lsa->id));
240   
241   /* There should be no parents potentially holding references to this vertex
242    * Children however may still be there, but presumably referenced by other
243    * vertices
244    */
245   //assert (listcount (v->parents) == 0);
246   
247   if (v->children)
248     list_delete (v->children);
249   v->children = NULL;
250   
251   if (v->parents)
252     list_delete (v->parents);
253   v->parents = NULL;
254   
255   v->lsa = NULL;
256   
257   XFREE (MTYPE_OSPF_VERTEX, v);
258 }
259
260 static void
261 ospf_vertex_dump(const char *msg, struct vertex *v,
262                  int print_parents, int print_children)
263 {
264   if ( ! IS_DEBUG_OSPF_EVENT)
265     return;
266
267   zlog_debug("%s %s vertex %s  distance %u flags %u",
268             msg,
269             v->type == OSPF_VERTEX_ROUTER ? "Router" : "Network",
270             inet_ntoa(v->lsa->id),
271             v->distance,
272             (unsigned int)v->flags);
273
274   if (print_parents)
275     {
276       struct listnode *node;
277       struct vertex_parent *vp;
278       
279       for (ALL_LIST_ELEMENTS_RO (v->parents, node, vp))
280         {
281           char buf1[BUFSIZ];
282           
283           if (vp)
284             {
285               zlog_debug ("parent %s backlink %d nexthop %s  interface %s",
286                          inet_ntoa(vp->parent->lsa->id), vp->backlink,
287                          inet_ntop(AF_INET, &vp->nexthop->router, buf1, BUFSIZ),
288                          vp->nexthop->oi ? IF_NAME(vp->nexthop->oi) : "NULL");
289             }
290         }
291     }
292
293   if (print_children)
294     {
295       struct listnode *cnode;
296       struct vertex *cv;
297       
298       for (ALL_LIST_ELEMENTS_RO (v->children, cnode, cv))
299         ospf_vertex_dump(" child:", cv, 0, 0);
300     }
301 }
302
303
304 /* Add a vertex to the list of children in each of its parents. */
305 static void
306 ospf_vertex_add_parent (struct vertex *v)
307 {
308   struct vertex_parent *vp;
309   struct listnode *node;
310   
311   assert (v && v->parents);
312   
313   for (ALL_LIST_ELEMENTS_RO (v->parents, node, vp))
314     {
315       assert (vp->parent && vp->parent->children);
316       
317       /* No need to add two links from the same parent. */
318       if (listnode_lookup (vp->parent->children, v) == NULL)
319         listnode_add (vp->parent->children, v);
320     }
321 }
322
323 static void
324 ospf_spf_init (struct ospf_area *area)
325 {
326   struct vertex *v;
327   
328   /* Create root node. */
329   v = ospf_vertex_new (area->router_lsa_self);
330   
331   area->spf = v;
332
333   /* Reset ABR and ASBR router counts. */
334   area->abr_count = 0;
335   area->asbr_count = 0;
336 }
337
338 /* return index of link back to V from W, or -1 if no link found */
339 static int
340 ospf_lsa_has_link (struct lsa_header *w, struct lsa_header *v)
341 {
342   unsigned int i, length;
343   struct router_lsa *rl;
344   struct network_lsa *nl;
345
346   /* In case of W is Network LSA. */
347   if (w->type == OSPF_NETWORK_LSA)
348     {
349       if (v->type == OSPF_NETWORK_LSA)
350         return -1;
351
352       nl = (struct network_lsa *) w;
353       length = (ntohs (w->length) - OSPF_LSA_HEADER_SIZE - 4) / 4;
354
355       for (i = 0; i < length; i++)
356         if (IPV4_ADDR_SAME (&nl->routers[i], &v->id))
357           return i;
358       return -1;
359     }
360
361   /* In case of W is Router LSA. */
362   if (w->type == OSPF_ROUTER_LSA)
363     {
364       rl = (struct router_lsa *) w;
365
366       length = ntohs (w->length);
367
368       for (i = 0;
369            i < ntohs (rl->links) && length >= sizeof (struct router_lsa);
370            i++, length -= 12)
371         {
372           switch (rl->link[i].type)
373             {
374             case LSA_LINK_TYPE_POINTOPOINT:
375             case LSA_LINK_TYPE_VIRTUALLINK:
376               /* Router LSA ID. */
377               if (v->type == OSPF_ROUTER_LSA &&
378                   IPV4_ADDR_SAME (&rl->link[i].link_id, &v->id))
379                 {
380                   return i;
381                 }
382               break;
383             case LSA_LINK_TYPE_TRANSIT:
384               /* Network LSA ID. */
385               if (v->type == OSPF_NETWORK_LSA &&
386                   IPV4_ADDR_SAME (&rl->link[i].link_id, &v->id))
387                 {
388                   return i;
389                 }
390               break;
391             case LSA_LINK_TYPE_STUB:
392               /* Stub can't lead anywhere, carry on */
393               continue;
394             default:
395               break;
396             }
397         }
398     }
399   return -1;
400 }
401
402 /* Find the next link after prev_link from v to w.  If prev_link is
403  * NULL, return the first link from v to w.  Ignore stub and virtual links;
404  * these link types will never be returned.
405  */
406 static struct router_lsa_link *
407 ospf_get_next_link (struct vertex *v, struct vertex *w,
408                     struct router_lsa_link *prev_link)
409 {
410   u_char *p;
411   u_char *lim;
412   u_char lsa_type =  LSA_LINK_TYPE_TRANSIT;
413   struct router_lsa_link *l;
414
415   if (w->type == OSPF_VERTEX_ROUTER)
416     lsa_type = LSA_LINK_TYPE_POINTOPOINT;
417
418   if (prev_link == NULL)
419     p = ((u_char *) v->lsa) + OSPF_LSA_HEADER_SIZE + 4;
420   else
421     {
422       p = (u_char *) prev_link;
423       p += (OSPF_ROUTER_LSA_LINK_SIZE +
424             (prev_link->m[0].tos_count * OSPF_ROUTER_LSA_TOS_SIZE));
425     }
426
427   lim = ((u_char *) v->lsa) + ntohs (v->lsa->length);
428
429   while (p < lim)
430     {
431       l = (struct router_lsa_link *) p;
432
433       p += (OSPF_ROUTER_LSA_LINK_SIZE + (l->m[0].tos_count * OSPF_ROUTER_LSA_TOS_SIZE));
434
435       if (l->m[0].type != lsa_type)
436         continue;
437
438       if (IPV4_ADDR_SAME (&l->link_id, &w->id))
439         return l;
440     }
441
442   return NULL;
443 }
444
445 static void
446 ospf_spf_flush_parents (struct vertex *w)
447 {
448   struct vertex_parent *vp;
449   struct listnode *ln, *nn;
450   
451   /* delete the existing nexthops */
452   for (ALL_LIST_ELEMENTS (w->parents, ln, nn, vp))
453     {
454       list_delete_node (w->parents, ln);
455       vertex_parent_free (vp);
456     }
457 }
458
459 /* 
460  * Consider supplied next-hop for inclusion to the supplied list of
461  * equal-cost next-hops, adjust list as neccessary.  
462  */
463 static void
464 ospf_spf_add_parent (struct vertex *v, struct vertex *w,
465                      struct vertex_nexthop *newhop,
466                      unsigned int distance)
467 {
468   struct vertex_parent *vp, *wp;
469   struct listnode *node;
470     
471   /* we must have a newhop, and a distance */
472   assert (v && w && newhop);
473   assert (distance);
474   
475   /* IFF w has already been assigned a distance, then we shouldn't get here
476    * unless callers have determined V(l)->W is shortest / equal-shortest
477    * path (0 is a special case distance (no distance yet assigned)).
478    */
479   if (w->distance)
480     assert (distance <= w->distance);
481   else
482     w->distance = distance;
483   
484   if (IS_DEBUG_OSPF_EVENT)
485     {
486       char buf[2][INET_ADDRSTRLEN];
487       zlog_debug ("%s: Adding %s as parent of %s",
488                 __func__,
489                 inet_ntop(AF_INET, &v->lsa->id, buf[0], sizeof(buf[0])),
490                 inet_ntop(AF_INET, &w->lsa->id, buf[1], sizeof(buf[1])));
491     }           
492
493   /* Adding parent for a new, better path: flush existing parents from W. */
494   if (distance < w->distance)
495     {
496       if (IS_DEBUG_OSPF_EVENT)
497         zlog_debug ("%s: distance %d better than %d, flushing existing parents",
498                     __func__, distance, w->distance);
499       ospf_spf_flush_parents (w);
500       w->distance = distance;
501     }
502   
503   /* new parent is <= existing parents, add it to parent list (if nexthop
504    * not on parent list)
505    */  
506   for (ALL_LIST_ELEMENTS_RO(w->parents, node, wp))
507     {
508       if (memcmp(newhop, wp->nexthop, sizeof(*newhop)) == 0)
509         {
510           if (IS_DEBUG_OSPF_EVENT)
511             zlog_debug ("%s: ... nexthop already on parent list, skipping add", __func__);
512           return;
513         }
514     }
515
516   vp = vertex_parent_new (v, ospf_lsa_has_link (w->lsa, v->lsa), newhop);
517   listnode_add (w->parents, vp);
518
519   return;
520 }
521
522 /* 16.1.1.  Calculate nexthop from root through V (parent) to
523  * vertex W (destination), with given distance from root->W.
524  *
525  * The link must be supplied if V is the root vertex. In all other cases
526  * it may be NULL.
527  *
528  * Note that this function may fail, hence the state of the destination
529  * vertex, W, should /not/ be modified in a dependent manner until
530  * this function returns. This function will update the W vertex with the
531  * provided distance as appropriate.
532  */
533 static unsigned int
534 ospf_nexthop_calculation (struct ospf_area *area, struct vertex *v,
535                           struct vertex *w, struct router_lsa_link *l,
536                           unsigned int distance, int lsa_pos)
537 {
538   struct listnode *node, *nnode;
539   struct vertex_nexthop *nh;
540   struct vertex_parent *vp;
541   struct ospf_interface *oi = NULL;
542   unsigned int added = 0;
543   char buf1[BUFSIZ];
544   char buf2[BUFSIZ];
545
546   if (IS_DEBUG_OSPF_EVENT)
547     {
548       zlog_debug ("ospf_nexthop_calculation(): Start");
549       ospf_vertex_dump("V (parent):", v, 1, 1);
550       ospf_vertex_dump("W (dest)  :", w, 1, 1);
551       zlog_debug ("V->W distance: %d", distance);
552     }
553
554   if (v == area->spf)
555     {      
556       /* 16.1.1 para 4.  In the first case, the parent vertex (V) is the
557          root (the calculating router itself).  This means that the 
558          destination is either a directly connected network or directly
559          connected router.  The outgoing interface in this case is simply 
560          the OSPF interface connecting to the destination network/router.
561       */
562
563       /* we *must* be supplied with the link data */
564       assert (l != NULL);
565       oi = ospf_if_lookup_by_lsa_pos (area, lsa_pos);
566       if (!oi)
567         {
568           zlog_debug("%s: OI not found in LSA: lsa_pos:%d link_id:%s link_data:%s",
569                      __func__, lsa_pos,
570                      inet_ntop (AF_INET, &l->link_id, buf1, BUFSIZ),
571                      inet_ntop (AF_INET, &l->link_data, buf2, BUFSIZ));
572           return 0;
573         }
574
575       if (IS_DEBUG_OSPF_EVENT)
576         {
577           zlog_debug("%s: considering link:%s "
578                      "type:%d link_id:%s link_data:%s",
579                      __func__, oi->ifp->name, l->m[0].type,
580                      inet_ntop (AF_INET, &l->link_id, buf1, BUFSIZ),
581                      inet_ntop (AF_INET, &l->link_data, buf2, BUFSIZ));
582         }
583
584       if (w->type == OSPF_VERTEX_ROUTER)
585         {
586           /* l  is a link from v to w
587            * l2 will be link from w to v
588            */
589           struct router_lsa_link *l2 = NULL;
590
591           if (l->m[0].type == LSA_LINK_TYPE_POINTOPOINT)
592             {
593               struct in_addr nexthop = { .s_addr = 0 };
594
595               /* If the destination is a router which connects to
596                  the calculating router via a Point-to-MultiPoint
597                  network, the destination's next hop IP address(es)
598                  can be determined by examining the destination's
599                  router-LSA: each link pointing back to the
600                  calculating router and having a Link Data field
601                  belonging to the Point-to-MultiPoint network
602                  provides an IP address of the next hop router.
603
604                  At this point l is a link from V to W, and V is the
605                  root ("us"). If it is a point-to-multipoint interface,
606                  then look through the links in the opposite direction (W to V).
607                  If any of them have an address that lands within the
608                  subnet declared by the PtMP link, then that link
609                  is a constituent of the PtMP link, and its address is
610                  a nexthop address for V.
611               */
612               if (oi->type == OSPF_IFTYPE_POINTOPOINT)
613                 {
614                   /* Having nexthop = 0 is tempting, but NOT acceptable.
615                      It breaks AS-External routes with a forwarding address,
616                      since ospf_ase_complete_direct_routes() will mistakenly
617                      assume we've reached the last hop and should place the
618                      forwarding address as nexthop.
619                      Also, users may configure multi-access links in p2p mode,
620                      so we need the IP to ARP the nexthop.
621                   */
622                   struct ospf_neighbor *nbr_w;
623
624                   nbr_w = ospf_nbr_lookup_by_routerid (oi->nbrs, &l->link_id);
625                   if (nbr_w != NULL)
626                     {
627                       added = 1;
628                       nexthop = nbr_w->src;
629                     }
630                 }
631               else if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT)
632                 {
633                   struct prefix_ipv4 la;
634
635                   la.family = AF_INET;
636                   la.prefixlen = oi->address->prefixlen;
637
638                   /* V links to W on PtMP interface
639                      - find the interface address on W */
640                   while ((l2 = ospf_get_next_link (w, v, l2)))
641                     {
642                       la.prefix = l2->link_data;
643
644                       if (prefix_cmp ((struct prefix *) &la,
645                                       oi->address) != 0)
646                         continue;
647                       /* link_data is on our PtMP network */
648                       added = 1;
649                       nexthop = l2->link_data;
650                       break;
651                     }
652                 }
653
654               if (added)
655                 {
656                   /* found all necessary info to build nexthop */
657                   nh = vertex_nexthop_new ();
658                   nh->oi = oi;
659                   nh->router = nexthop;
660                   ospf_spf_add_parent (v, w, nh, distance);
661                   return 1;
662                 }
663               else
664                 zlog_info("%s: could not determine nexthop for link %s",
665                           __func__, oi->ifp->name);
666             } /* end point-to-point link from V to W */
667           else if (l->m[0].type == LSA_LINK_TYPE_VIRTUALLINK)
668             {
669               struct ospf_vl_data *vl_data;
670               
671               /* VLink implementation limitations: 
672                * a) vl_data can only reference one nexthop, so no ECMP
673                *    to backbone through VLinks. Though transit-area 
674                *    summaries may be considered, and those can be ECMP.
675                * b) We can only use /one/ VLink, even if multiple ones
676                *    exist this router through multiple transit-areas.
677                */
678               vl_data = ospf_vl_lookup (area->ospf, NULL, l->link_id);
679               
680               if (vl_data 
681                   && CHECK_FLAG (vl_data->flags, OSPF_VL_FLAG_APPROVED))
682                 {
683                   nh = vertex_nexthop_new ();
684                   nh->oi = vl_data->nexthop.oi;
685                   nh->router = vl_data->nexthop.router;
686                   ospf_spf_add_parent (v, w, nh, distance);
687                   return 1;
688                 }
689               else
690                   zlog_info("ospf_nexthop_calculation(): "
691                             "vl_data for VL link not found");
692             } /* end virtual-link from V to W */
693           return 0;
694         } /* end W is a Router vertex */
695       else
696         {
697           assert(w->type == OSPF_VERTEX_NETWORK);
698
699           nh = vertex_nexthop_new ();
700           nh->oi = oi;
701           nh->router.s_addr = 0; /* Nexthop not required */
702           ospf_spf_add_parent (v, w, nh, distance);
703           return 1;
704         }
705     } /* end V is the root */
706   /* Check if W's parent is a network connected to root. */
707   else if (v->type == OSPF_VERTEX_NETWORK)
708     {
709       /* See if any of V's parents are the root. */
710       for (ALL_LIST_ELEMENTS (v->parents, node, nnode, vp))
711         {
712           if (vp->parent == area->spf) /* connects to root? */
713             {
714               /* 16.1.1 para 5. ...the parent vertex is a network that
715                * directly connects the calculating router to the destination
716                * router.  The list of next hops is then determined by
717                * examining the destination's router-LSA...
718                */
719
720               assert(w->type == OSPF_VERTEX_ROUTER);
721               while ((l = ospf_get_next_link (w, v, l)))
722                 {
723                   /* ...For each link in the router-LSA that points back to the
724                    * parent network, the link's Link Data field provides the IP
725                    * address of a next hop router.  The outgoing interface to
726                    * use can then be derived from the next hop IP address (or 
727                    * it can be inherited from the parent network).
728                    */
729                   nh = vertex_nexthop_new ();
730                   nh->oi = vp->nexthop->oi;
731                   nh->router = l->link_data;
732                   added = 1;
733                   ospf_spf_add_parent (v, w, nh, distance);
734                 }
735               /* Note lack of return is deliberate. See next comment. */
736           }
737         }
738       /* NB: This code is non-trivial.
739        * 
740        * E.g. it is not enough to know that V connects to the root. It is
741        * also important that the while above, looping through all links from
742        * W->V found at least one link, so that we know there is
743        * bi-directional connectivity between V and W (which need not be the
744        * case, e.g.  when OSPF has not yet converged fully).  Otherwise, if
745        * we /always/ return here, without having checked that root->V->-W
746        * actually resulted in a valid nexthop being created, then we we will
747        * prevent SPF from finding/using higher cost paths.
748        *
749        * It is important, if root->V->W has not been added, that we continue
750        * through to the intervening-router nexthop code below.  So as to
751        * ensure other paths to V may be used.  This avoids unnecessary
752        * blackholes while OSPF is convergening.
753        *
754        * I.e. we may have arrived at this function, examining V -> W, via
755        * workable paths other than root -> V, and it's important to avoid
756        * getting "confused" by non-working root->V->W path - it's important
757        * to *not* lose the working non-root paths, just because of a
758        * non-viable root->V->W.
759        *
760        * See also bug #330 (required reading!), and:
761        *
762        * http://blogs.oracle.com/paulj/entry/the_difference_a_line_makes
763        */
764       if (added)
765         return added;
766     }
767
768   /* 16.1.1 para 4.  If there is at least one intervening router in the
769    * current shortest path between the destination and the root, the
770    * destination simply inherits the set of next hops from the
771    * parent.
772    */
773   if (IS_DEBUG_OSPF_EVENT)
774     zlog_debug ("%s: Intervening routers, adding parent(s)", __func__);
775
776   for (ALL_LIST_ELEMENTS (v->parents, node, nnode, vp))
777     {
778       added = 1;
779       ospf_spf_add_parent (v, w, vp->nexthop, distance);
780     }
781   
782   return added;
783 }
784
785 /* RFC2328 Section 16.1 (2).
786  * v is on the SPF tree.  Examine the links in v's LSA.  Update the list
787  * of candidates with any vertices not already on the list.  If a lower-cost
788  * path is found to a vertex already on the candidate list, store the new cost.
789  */
790 static void
791 ospf_spf_next (struct vertex *v, struct ospf_area *area,
792                struct pqueue * candidate)
793 {
794   struct ospf_lsa *w_lsa = NULL;
795   u_char *p;
796   u_char *lim;
797   struct router_lsa_link *l = NULL;
798   struct in_addr *r;
799   int type = 0, lsa_pos=-1, lsa_pos_next=0;
800
801   /* If this is a router-LSA, and bit V of the router-LSA (see Section
802      A.4.2:RFC2328) is set, set Area A's TransitCapability to TRUE.  */
803   if (v->type == OSPF_VERTEX_ROUTER)
804     {
805       if (IS_ROUTER_LSA_VIRTUAL ((struct router_lsa *) v->lsa))
806         area->transit = OSPF_TRANSIT_TRUE;
807     }
808   
809   if (IS_DEBUG_OSPF_EVENT)
810     zlog_debug ("%s: Next vertex of %s vertex %s",
811                 __func__, 
812                 v->type == OSPF_VERTEX_ROUTER ? "Router" : "Network",
813                 inet_ntoa(v->lsa->id));
814   
815   p = ((u_char *) v->lsa) + OSPF_LSA_HEADER_SIZE + 4;
816   lim = ((u_char *) v->lsa) + ntohs (v->lsa->length);
817
818   while (p < lim)
819     {
820       struct vertex *w;
821       unsigned int distance;
822       
823       /* In case of V is Router-LSA. */
824       if (v->lsa->type == OSPF_ROUTER_LSA)
825         {
826           l = (struct router_lsa_link *) p;
827
828           lsa_pos = lsa_pos_next; /* LSA link position */
829           lsa_pos_next++;
830           p += (OSPF_ROUTER_LSA_LINK_SIZE +
831                 (l->m[0].tos_count * OSPF_ROUTER_LSA_TOS_SIZE));
832
833           /* (a) If this is a link to a stub network, examine the next
834              link in V's LSA.  Links to stub networks will be
835              considered in the second stage of the shortest path
836              calculation. */
837           if ((type = l->m[0].type) == LSA_LINK_TYPE_STUB)
838             continue;
839           
840           /* Infinite distance links shouldn't be followed, except
841            * for local links (a stub-routed router still wants to
842            * calculate tree, so must follow its own links).
843            */
844           if ((v != area->spf) && l->m[0].metric >= OSPF_OUTPUT_COST_INFINITE)
845             continue;
846
847           /* (b) Otherwise, W is a transit vertex (router or transit
848              network).  Look up the vertex W's LSA (router-LSA or
849              network-LSA) in Area A's link state database. */
850           switch (type)
851             {
852             case LSA_LINK_TYPE_POINTOPOINT:
853             case LSA_LINK_TYPE_VIRTUALLINK:
854               if (type == LSA_LINK_TYPE_VIRTUALLINK)
855                 {
856                   if (IS_DEBUG_OSPF_EVENT)
857                     zlog_debug ("looking up LSA through VL: %s",
858                                inet_ntoa (l->link_id));
859                 }
860
861               w_lsa = ospf_lsa_lookup (area, OSPF_ROUTER_LSA, l->link_id,
862                                        l->link_id);
863               if (w_lsa)
864                 {
865                   if (IS_DEBUG_OSPF_EVENT)
866                     zlog_debug ("found Router LSA %s", inet_ntoa (l->link_id));
867                 }
868               break;
869             case LSA_LINK_TYPE_TRANSIT:
870               if (IS_DEBUG_OSPF_EVENT)
871                 zlog_debug ("Looking up Network LSA, ID: %s",
872                            inet_ntoa (l->link_id));
873               w_lsa = ospf_lsa_lookup_by_id (area, OSPF_NETWORK_LSA,
874                                              l->link_id);
875               if (w_lsa)
876                 if (IS_DEBUG_OSPF_EVENT)
877                   zlog_debug ("found the LSA");
878               break;
879             default:
880               zlog_warn ("Invalid LSA link type %d", type);
881               continue;
882             }
883         }
884       else
885         {
886           /* In case of V is Network-LSA. */
887           r = (struct in_addr *) p;
888           p += sizeof (struct in_addr);
889
890           /* Lookup the vertex W's LSA. */
891           w_lsa = ospf_lsa_lookup_by_id (area, OSPF_ROUTER_LSA, *r);
892           if (w_lsa)
893             {
894               if (IS_DEBUG_OSPF_EVENT)
895                 zlog_debug ("found Router LSA %s", inet_ntoa (w_lsa->data->id));
896             }
897         }
898
899       /* (b cont.) If the LSA does not exist, or its LS age is equal
900          to MaxAge, or it does not have a link back to vertex V,
901          examine the next link in V's LSA.[23] */
902       if (w_lsa == NULL)
903         {
904           if (IS_DEBUG_OSPF_EVENT)
905             zlog_debug ("No LSA found");
906           continue;
907         }
908
909       if (IS_LSA_MAXAGE (w_lsa))
910         {
911           if (IS_DEBUG_OSPF_EVENT)
912             zlog_debug ("LSA is MaxAge");
913           continue;
914         }
915
916       if (ospf_lsa_has_link (w_lsa->data, v->lsa) < 0 )
917         {
918           if (IS_DEBUG_OSPF_EVENT)
919             zlog_debug ("The LSA doesn't have a link back");
920           continue;
921         }
922
923       /* (c) If vertex W is already on the shortest-path tree, examine
924          the next link in the LSA. */
925       if (w_lsa->stat == LSA_SPF_IN_SPFTREE)
926         {
927           if (IS_DEBUG_OSPF_EVENT)
928             zlog_debug ("The LSA is already in SPF");
929           continue;
930         }
931
932       /* (d) Calculate the link state cost D of the resulting path
933          from the root to vertex W.  D is equal to the sum of the link
934          state cost of the (already calculated) shortest path to
935          vertex V and the advertised cost of the link between vertices
936          V and W.  If D is: */
937
938       /* calculate link cost D. */
939       if (v->lsa->type == OSPF_ROUTER_LSA)
940         distance = v->distance + ntohs (l->m[0].metric);
941       else /* v is not a Router-LSA */
942         distance = v->distance;
943
944       /* Is there already vertex W in candidate list? */
945       if (w_lsa->stat == LSA_SPF_NOT_EXPLORED)
946         {
947           /* prepare vertex W. */
948           w = ospf_vertex_new (w_lsa);
949
950           /* Calculate nexthop to W. */
951           if (ospf_nexthop_calculation (area, v, w, l, distance, lsa_pos))
952             pqueue_enqueue (w, candidate);
953           else if (IS_DEBUG_OSPF_EVENT)
954             zlog_debug ("Nexthop Calc failed");
955         }
956       else if (w_lsa->stat >= 0)
957         {
958           /* Get the vertex from candidates. */
959           w = candidate->array[w_lsa->stat];
960
961           /* if D is greater than. */  
962           if (w->distance < distance)
963             {
964               continue;
965             }
966           /* equal to. */
967           else if (w->distance == distance)
968             {
969               /* Found an equal-cost path to W.  
970                * Calculate nexthop of to W from V. */
971               ospf_nexthop_calculation (area, v, w, l, distance, lsa_pos);
972             }
973            /* less than. */
974           else
975             {
976               /* Found a lower-cost path to W.
977                * nexthop_calculation is conditional, if it finds
978                * valid nexthop it will call spf_add_parents, which
979                * will flush the old parents
980                */
981               if (ospf_nexthop_calculation (area, v, w, l, distance, lsa_pos))
982                 /* Decrease the key of the node in the heap.
983                  * trickle-sort it up towards root, just in case this
984                  * node should now be the new root due the cost change. 
985                  * (next pqueu_{de,en}queue will fully re-heap the queue).
986                  */
987                 trickle_up (w_lsa->stat, candidate);
988             }
989         } /* end W is already on the candidate list */
990     } /* end loop over the links in V's LSA */
991 }
992
993 static void
994 ospf_spf_dump (struct vertex *v, int i)
995 {
996   struct listnode *cnode;
997   struct listnode *nnode;
998   struct vertex_parent *parent;
999
1000   if (v->type == OSPF_VERTEX_ROUTER)
1001     {
1002       if (IS_DEBUG_OSPF_EVENT)
1003         zlog_debug ("SPF Result: %d [R] %s", i, inet_ntoa (v->lsa->id));
1004     }
1005   else
1006     {
1007       struct network_lsa *lsa = (struct network_lsa *) v->lsa;
1008       if (IS_DEBUG_OSPF_EVENT)
1009         zlog_debug ("SPF Result: %d [N] %s/%d", i, inet_ntoa (v->lsa->id),
1010                    ip_masklen (lsa->mask));
1011     }
1012
1013   if (IS_DEBUG_OSPF_EVENT)
1014     for (ALL_LIST_ELEMENTS_RO (v->parents, nnode, parent))
1015       {
1016         zlog_debug (" nexthop %p %s %s", 
1017                     (void *)parent->nexthop,
1018                     inet_ntoa (parent->nexthop->router),
1019                     parent->nexthop->oi ? IF_NAME(parent->nexthop->oi)
1020                                         : "NULL");
1021       }
1022
1023   i++;
1024
1025   for (ALL_LIST_ELEMENTS_RO (v->children, cnode, v))
1026     ospf_spf_dump (v, i);
1027 }
1028
1029 /* Second stage of SPF calculation. */
1030 static void
1031 ospf_spf_process_stubs (struct ospf_area *area, struct vertex *v,
1032                         struct route_table *rt,
1033                         int parent_is_root)
1034 {
1035   struct listnode *cnode, *cnnode;
1036   struct vertex *child;
1037
1038   if (IS_DEBUG_OSPF_EVENT)
1039     zlog_debug ("ospf_process_stub():processing stubs for area %s",
1040                inet_ntoa (area->area_id));
1041   if (v->type == OSPF_VERTEX_ROUTER)
1042     {
1043       u_char *p;
1044       u_char *lim;
1045       struct router_lsa_link *l;
1046       struct router_lsa *rlsa;
1047       int lsa_pos = 0;
1048
1049       if (IS_DEBUG_OSPF_EVENT)
1050         zlog_debug ("ospf_process_stubs():processing router LSA, id: %s",
1051                    inet_ntoa (v->lsa->id));
1052       rlsa = (struct router_lsa *) v->lsa;
1053
1054
1055       if (IS_DEBUG_OSPF_EVENT)
1056         zlog_debug ("ospf_process_stubs(): we have %d links to process",
1057                    ntohs (rlsa->links));
1058       p = ((u_char *) v->lsa) + OSPF_LSA_HEADER_SIZE + 4;
1059       lim = ((u_char *) v->lsa) + ntohs (v->lsa->length);
1060
1061       while (p < lim)
1062         {
1063           l = (struct router_lsa_link *) p;
1064
1065           p += (OSPF_ROUTER_LSA_LINK_SIZE +
1066                 (l->m[0].tos_count * OSPF_ROUTER_LSA_TOS_SIZE));
1067
1068           if (l->m[0].type == LSA_LINK_TYPE_STUB)
1069             ospf_intra_add_stub (rt, l, v, area, parent_is_root, lsa_pos);
1070           lsa_pos++;
1071         }
1072     }
1073
1074   ospf_vertex_dump("ospf_process_stubs(): after examining links: ", v, 1, 1);
1075
1076   for (ALL_LIST_ELEMENTS (v->children, cnode, cnnode, child))
1077     {
1078       if (CHECK_FLAG (child->flags, OSPF_VERTEX_PROCESSED))
1079         continue;
1080       
1081       /* the first level of routers connected to the root
1082        * should have 'parent_is_root' set, including those 
1083        * connected via a network vertex.
1084        */
1085       if (area->spf == v)
1086         parent_is_root = 1;
1087       else if (v->type == OSPF_VERTEX_ROUTER)
1088         parent_is_root = 0;
1089         
1090       ospf_spf_process_stubs (area, child, rt, parent_is_root);
1091
1092       SET_FLAG (child->flags, OSPF_VERTEX_PROCESSED);
1093     }
1094 }
1095
1096 void
1097 ospf_rtrs_free (struct route_table *rtrs)
1098 {
1099   struct route_node *rn;
1100   struct list *or_list;
1101   struct ospf_route *or;
1102   struct listnode *node, *nnode;
1103
1104   if (IS_DEBUG_OSPF_EVENT)
1105     zlog_debug ("Route: Router Routing Table free");
1106
1107   for (rn = route_top (rtrs); rn; rn = route_next (rn))
1108     if ((or_list = rn->info) != NULL)
1109       {
1110         for (ALL_LIST_ELEMENTS (or_list, node, nnode, or))
1111           ospf_route_free (or);
1112
1113         list_delete (or_list);
1114
1115         /* Unlock the node. */
1116         rn->info = NULL;
1117         route_unlock_node (rn);
1118       }
1119   route_table_finish (rtrs);
1120 }
1121
1122 #if 0
1123 static void
1124 ospf_rtrs_print (struct route_table *rtrs)
1125 {
1126   struct route_node *rn;
1127   struct list *or_list;
1128   struct listnode *ln;
1129   struct listnode *pnode;
1130   struct ospf_route *or;
1131   struct ospf_path *path;
1132   char buf1[BUFSIZ];
1133   char buf2[BUFSIZ];
1134
1135   if (IS_DEBUG_OSPF_EVENT)
1136     zlog_debug ("ospf_rtrs_print() start");
1137
1138   for (rn = route_top (rtrs); rn; rn = route_next (rn))
1139     if ((or_list = rn->info) != NULL)
1140       for (ALL_LIST_ELEMENTS_RO (or_list, ln, or))
1141         {
1142           switch (or->path_type)
1143             {
1144             case OSPF_PATH_INTRA_AREA:
1145               if (IS_DEBUG_OSPF_EVENT)
1146                 zlog_debug ("%s   [%d] area: %s",
1147                            inet_ntop (AF_INET, &or->id, buf1, BUFSIZ),
1148                            or->cost, inet_ntop (AF_INET, &or->u.std.area_id,
1149                                                 buf2, BUFSIZ));
1150               break;
1151             case OSPF_PATH_INTER_AREA:
1152               if (IS_DEBUG_OSPF_EVENT)
1153                 zlog_debug ("%s IA [%d] area: %s",
1154                            inet_ntop (AF_INET, &or->id, buf1, BUFSIZ),
1155                            or->cost, inet_ntop (AF_INET, &or->u.std.area_id,
1156                                                 buf2, BUFSIZ));
1157               break;
1158             default:
1159               break;
1160             }
1161
1162           for (ALL_LIST_ELEMENTS_RO (or->paths, pnode, path))
1163             {
1164               if (path->nexthop.s_addr == 0)
1165                 {
1166                   if (IS_DEBUG_OSPF_EVENT)
1167                     zlog_debug ("   directly attached to %s\r\n",
1168                                 ifindex2ifname (path->ifindex));
1169                 }
1170               else
1171                 {
1172                   if (IS_DEBUG_OSPF_EVENT)
1173                     zlog_debug ("   via %s, %s\r\n",
1174                                 inet_ntoa (path->nexthop),
1175                                 ifindex2ifname (path->ifindex));
1176                 }
1177             }
1178         }
1179
1180   zlog_debug ("ospf_rtrs_print() end");
1181 }
1182 #endif
1183
1184 /* Calculating the shortest-path tree for an area. */
1185 static void
1186 ospf_spf_calculate (struct ospf_area *area, struct route_table *new_table,
1187                     struct route_table *new_rtrs)
1188 {
1189   struct pqueue *candidate;
1190   struct vertex *v;
1191   
1192   if (IS_DEBUG_OSPF_EVENT)
1193     {
1194       zlog_debug ("ospf_spf_calculate: Start");
1195       zlog_debug ("ospf_spf_calculate: running Dijkstra for area %s",
1196                  inet_ntoa (area->area_id));
1197     }
1198
1199   /* Check router-lsa-self.  If self-router-lsa is not yet allocated,
1200      return this area's calculation. */
1201   if (!area->router_lsa_self)
1202     {
1203       if (IS_DEBUG_OSPF_EVENT)
1204         zlog_debug ("ospf_spf_calculate: "
1205                    "Skip area %s's calculation due to empty router_lsa_self",
1206                    inet_ntoa (area->area_id));
1207       return;
1208     }
1209
1210   /* RFC2328 16.1. (1). */
1211   /* Initialize the algorithm's data structures. */
1212   
1213   /* This function scans all the LSA database and set the stat field to
1214    * LSA_SPF_NOT_EXPLORED. */
1215   ospf_lsdb_clean_stat (area->lsdb);
1216   /* Create a new heap for the candidates. */ 
1217   candidate = pqueue_create();
1218   candidate->cmp = cmp;
1219   candidate->update = update_stat;
1220
1221   /* Initialize the shortest-path tree to only the root (which is the
1222      router doing the calculation). */
1223   ospf_spf_init (area);
1224   v = area->spf;
1225   /* Set LSA position to LSA_SPF_IN_SPFTREE. This vertex is the root of the
1226    * spanning tree. */
1227   *(v->stat) = LSA_SPF_IN_SPFTREE;
1228
1229   /* Set Area A's TransitCapability to FALSE. */
1230   area->transit = OSPF_TRANSIT_FALSE;
1231   area->shortcut_capability = 1;
1232   
1233   for (;;)
1234     {
1235       /* RFC2328 16.1. (2). */
1236       ospf_spf_next (v, area, candidate);
1237
1238       /* RFC2328 16.1. (3). */
1239       /* If at this step the candidate list is empty, the shortest-
1240          path tree (of transit vertices) has been completely built and
1241          this stage of the procedure terminates. */
1242       if (candidate->size == 0)
1243         break;
1244
1245       /* Otherwise, choose the vertex belonging to the candidate list
1246          that is closest to the root, and add it to the shortest-path
1247          tree (removing it from the candidate list in the
1248          process). */
1249       /* Extract from the candidates the node with the lower key. */
1250       v = (struct vertex *) pqueue_dequeue (candidate);
1251       /* Update stat field in vertex. */
1252       *(v->stat) = LSA_SPF_IN_SPFTREE;
1253
1254       ospf_vertex_add_parent (v);
1255
1256       /* RFC2328 16.1. (4). */
1257       if (v->type == OSPF_VERTEX_ROUTER)
1258         ospf_intra_add_router (new_rtrs, v, area);
1259       else
1260         ospf_intra_add_transit (new_table, v, area);
1261
1262       /* RFC2328 16.1. (5). */
1263       /* Iterate the algorithm by returning to Step 2. */
1264
1265     } /* end loop until no more candidate vertices */
1266
1267   if (IS_DEBUG_OSPF_EVENT)
1268     {
1269       ospf_spf_dump (area->spf, 0);
1270       ospf_route_table_dump (new_table);
1271     }
1272
1273   /* Second stage of SPF calculation procedure's  */
1274   ospf_spf_process_stubs (area, area->spf, new_table, 0);
1275
1276   /* Free candidate queue. */
1277   pqueue_delete (candidate);
1278
1279   ospf_vertex_dump (__func__, area->spf, 0, 1);
1280   /* Free nexthop information, canonical versions of which are attached
1281    * the first level of router vertices attached to the root vertex, see
1282    * ospf_nexthop_calculation.
1283    */
1284   ospf_canonical_nexthops_free (area->spf);
1285
1286   /* Increment SPF Calculation Counter. */
1287   area->spf_calculation++;
1288
1289   quagga_gettime (QUAGGA_CLK_MONOTONIC, &area->ospf->ts_spf);
1290   area->ts_spf = area->ospf->ts_spf;
1291
1292   if (IS_DEBUG_OSPF_EVENT)
1293     zlog_debug ("ospf_spf_calculate: Stop. %zd vertices",
1294                 mtype_stats_alloc(MTYPE_OSPF_VERTEX));
1295
1296   /* Free SPF vertices, but not the list. List has ospf_vertex_free
1297    * as deconstructor.
1298    */
1299   list_delete_all_node (&vertex_list);
1300 }
1301
1302 /* Timer for SPF calculation. */
1303 static int
1304 ospf_spf_calculate_timer (struct thread *thread)
1305 {
1306   struct ospf *ospf = THREAD_ARG (thread);
1307   struct route_table *new_table, *new_rtrs;
1308   struct ospf_area *area;
1309   struct listnode *node, *nnode;
1310   struct timeval start_time, stop_time, spf_start_time;
1311   int areas_processed = 0;
1312   unsigned long ia_time, prune_time, rt_time;
1313   unsigned long abr_time, total_spf_time, spf_time;
1314   char rbuf[32];                /* reason_buf */
1315   
1316   if (IS_DEBUG_OSPF_EVENT)
1317     zlog_debug ("SPF: Timer (SPF calculation expire)");
1318
1319   ospf->t_spf_calc = NULL;
1320
1321   quagga_gettime (QUAGGA_CLK_MONOTONIC, &spf_start_time);
1322   /* Allocate new table tree. */
1323   new_table = route_table_init ();
1324   new_rtrs = route_table_init ();
1325
1326   ospf_vl_unapprove (ospf);
1327
1328   /* Calculate SPF for each area. */
1329   for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
1330     {
1331       /* Do backbone last, so as to first discover intra-area paths
1332        * for any back-bone virtual-links
1333        */
1334       if (ospf->backbone && ospf->backbone == area)
1335         continue;
1336
1337       ospf_spf_calculate (area, new_table, new_rtrs);
1338       areas_processed++;
1339     }
1340
1341   /* SPF for backbone, if required */
1342   if (ospf->backbone)
1343     {
1344       ospf_spf_calculate (ospf->backbone, new_table, new_rtrs);
1345       areas_processed++;
1346     }
1347
1348   quagga_gettime (QUAGGA_CLK_MONOTONIC, &stop_time);
1349   spf_time = timeval_elapsed (stop_time, spf_start_time);
1350
1351   ospf_vl_shut_unapproved (ospf);
1352
1353   start_time = stop_time;       /* saving a call */
1354
1355   ospf_ia_routing (ospf, new_table, new_rtrs);
1356
1357   quagga_gettime (QUAGGA_CLK_MONOTONIC, &stop_time);
1358   ia_time = timeval_elapsed (stop_time, start_time);
1359
1360   quagga_gettime (QUAGGA_CLK_MONOTONIC, &start_time);
1361   ospf_prune_unreachable_networks (new_table);
1362   ospf_prune_unreachable_routers (new_rtrs);
1363
1364   quagga_gettime (QUAGGA_CLK_MONOTONIC, &stop_time);
1365   prune_time = timeval_elapsed (stop_time, start_time);
1366   /* AS-external-LSA calculation should not be performed here. */
1367
1368   /* If new Router Route is installed,
1369      then schedule re-calculate External routes. */
1370   if (1)
1371     ospf_ase_calculate_schedule (ospf);
1372
1373   ospf_ase_calculate_timer_add (ospf);
1374
1375   quagga_gettime (QUAGGA_CLK_MONOTONIC, &start_time);
1376
1377   /* Update routing table. */
1378   ospf_route_install (ospf, new_table);
1379
1380   quagga_gettime (QUAGGA_CLK_MONOTONIC, &stop_time);
1381   rt_time = timeval_elapsed (stop_time, start_time);
1382   /* Update ABR/ASBR routing table */
1383   if (ospf->old_rtrs)
1384     {
1385       /* old_rtrs's node holds linked list of ospf_route. --kunihiro. */
1386       /* ospf_route_delete (ospf->old_rtrs); */
1387       ospf_rtrs_free (ospf->old_rtrs);
1388     }
1389
1390   ospf->old_rtrs = ospf->new_rtrs;
1391   ospf->new_rtrs = new_rtrs;
1392
1393   quagga_gettime (QUAGGA_CLK_MONOTONIC, &start_time);
1394   if (IS_OSPF_ABR (ospf))
1395     ospf_abr_task (ospf);
1396
1397   quagga_gettime (QUAGGA_CLK_MONOTONIC, &stop_time);
1398   abr_time = timeval_elapsed (stop_time, start_time);
1399
1400   quagga_gettime (QUAGGA_CLK_MONOTONIC, &stop_time);
1401   total_spf_time = timeval_elapsed (stop_time, spf_start_time);
1402   ospf->ts_spf_duration.tv_sec = total_spf_time/1000000;
1403   ospf->ts_spf_duration.tv_usec = total_spf_time % 1000000;
1404
1405   ospf_get_spf_reason_str (rbuf);
1406
1407   if (IS_DEBUG_OSPF_EVENT)
1408     {
1409       zlog_info ("SPF Processing Time(usecs): %ld", total_spf_time);
1410       zlog_info ("\t    SPF Time: %ld", spf_time);
1411       zlog_info ("\t   InterArea: %ld", ia_time);
1412       zlog_info ("\t       Prune: %ld", prune_time);
1413       zlog_info ("\tRouteInstall: %ld", rt_time);
1414       if (IS_OSPF_ABR (ospf))
1415         zlog_info ("\t         ABR: %ld (%d areas)",
1416                    abr_time, areas_processed);
1417       zlog_info ("Reason(s) for SPF: %s", rbuf);
1418     }
1419
1420   ospf_clear_spf_reason_flags ();
1421
1422   return 0;
1423 }
1424
1425 /* Add schedule for SPF calculation.  To avoid frequenst SPF calc, we
1426    set timer for SPF calc. */
1427 void
1428 ospf_spf_calculate_schedule (struct ospf *ospf, ospf_spf_reason_t reason)
1429 {
1430   unsigned long delay, elapsed, ht;
1431   struct timeval result;
1432
1433   if (IS_DEBUG_OSPF_EVENT)
1434     zlog_debug ("SPF: calculation timer scheduled");
1435
1436   /* OSPF instance does not exist. */
1437   if (ospf == NULL)
1438     return;
1439   
1440   ospf_spf_set_reason (reason);
1441   
1442   /* SPF calculation timer is already scheduled. */
1443   if (ospf->t_spf_calc)
1444     {
1445       if (IS_DEBUG_OSPF_EVENT)
1446         zlog_debug ("SPF: calculation timer is already scheduled: %p",
1447                     (void *)ospf->t_spf_calc);
1448       return;
1449     }
1450   
1451   /* XXX Monotic timers: we only care about relative time here. */
1452   result = tv_sub (recent_relative_time (), ospf->ts_spf);
1453   
1454   elapsed = (result.tv_sec * 1000) + (result.tv_usec / 1000);
1455   ht = ospf->spf_holdtime * ospf->spf_hold_multiplier;
1456   
1457   if (ht > ospf->spf_max_holdtime)
1458     ht = ospf->spf_max_holdtime;
1459   
1460   /* Get SPF calculation delay time. */
1461   if (elapsed < ht)
1462     {
1463       /* Got an event within the hold time of last SPF. We need to
1464        * increase the hold_multiplier, if it's not already at/past
1465        * maximum value, and wasn't already increased..
1466        */
1467       if (ht < ospf->spf_max_holdtime)
1468         ospf->spf_hold_multiplier++;
1469       
1470       /* always honour the SPF initial delay */
1471       if ( (ht - elapsed) < ospf->spf_delay)
1472         delay = ospf->spf_delay;
1473       else
1474         delay = ht - elapsed;
1475     }
1476   else
1477     {
1478       /* Event is past required hold-time of last SPF */
1479       delay = ospf->spf_delay;
1480       ospf->spf_hold_multiplier = 1;
1481     }
1482   
1483   if (IS_DEBUG_OSPF_EVENT)
1484     zlog_debug ("SPF: calculation timer delay = %ld", delay);
1485
1486   zlog_info ("SPF: Scheduled in %ld msec", delay);
1487
1488   ospf->t_spf_calc =
1489     thread_add_timer_msec (master, ospf_spf_calculate_timer, ospf, delay);
1490 }