ospf_spf.c
上传用户:xiaozhuqw
上传日期:2009-11-15
资源大小:1338k
文件大小:27k
源码类别:

网络

开发平台:

Unix_Linux

  1. /* OSPF SPF calculation.
  2.    Copyright (C) 1999, 2000 Kunihiro Ishiguro, Toshiaki Takada
  3. This file is part of GNU Zebra.
  4. GNU Zebra is free software; you can redistribute it and/or modify it
  5. under the terms of the GNU General Public License as published by the
  6. Free Software Foundation; either version 2, or (at your option) any
  7. later version.
  8. GNU Zebra is distributed in the hope that it will be useful, but
  9. WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  11. General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with GNU Zebra; see the file COPYING.  If not, write to the Free
  14. Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
  15. 02111-1307, USA.  */
  16. #include <zebra.h>
  17. #include "thread.h"
  18. #include "memory.h"
  19. #include "hash.h"
  20. #include "linklist.h"
  21. #include "prefix.h"
  22. #include "if.h"
  23. #include "table.h"
  24. #include "log.h"
  25. #include "sockunion.h"          /* for inet_ntop () */
  26. #include "ospfd/ospfd.h"
  27. #include "ospfd/ospf_interface.h"
  28. #include "ospfd/ospf_ism.h"
  29. #include "ospfd/ospf_asbr.h"
  30. #include "ospfd/ospf_lsa.h"
  31. #include "ospfd/ospf_lsdb.h"
  32. #include "ospfd/ospf_neighbor.h"
  33. #include "ospfd/ospf_nsm.h"
  34. #include "ospfd/ospf_spf.h"
  35. #include "ospfd/ospf_route.h"
  36. #include "ospfd/ospf_ia.h"
  37. #include "ospfd/ospf_ase.h"
  38. #include "ospfd/ospf_abr.h"
  39. #include "ospfd/ospf_dump.h"
  40. #define DEBUG
  41. struct vertex_nexthop *
  42. vertex_nexthop_new (struct vertex *parent)
  43. {
  44.   struct vertex_nexthop *new;
  45.   new = XCALLOC (MTYPE_OSPF_NEXTHOP, sizeof (struct vertex_nexthop));
  46.   new->parent = parent;
  47.   return new;
  48. }
  49. void
  50. vertex_nexthop_free (struct vertex_nexthop *nh)
  51. {
  52.   XFREE (MTYPE_OSPF_NEXTHOP, nh);
  53. }
  54. struct vertex_nexthop *
  55. vertex_nexthop_dup (struct vertex_nexthop *nh)
  56. {
  57.   struct vertex_nexthop *new;
  58.   new = vertex_nexthop_new (nh->parent);
  59.   new->oi = nh->oi;
  60.   new->router = nh->router;
  61.   return new;
  62. }
  63. struct vertex *
  64. ospf_vertex_new (struct ospf_lsa *lsa)
  65. {
  66.   struct vertex *new;
  67.   new = XMALLOC (MTYPE_OSPF_VERTEX, sizeof (struct vertex));
  68.   memset (new, 0, sizeof (struct vertex));
  69.   new->flags = 0;
  70.   new->type = lsa->data->type;
  71.   new->id = lsa->data->id;
  72.   new->lsa = lsa->data;
  73.   new->distance = 0;
  74.   new->child = list_new ();
  75.   new->nexthop = list_new ();
  76.   return new;
  77. }
  78. void
  79. ospf_vertex_free (struct vertex *v)
  80. {
  81.   listnode node;
  82.   list_delete (v->child);
  83.   if (listcount (v->nexthop) > 0)
  84.     for (node = listhead (v->nexthop); node; nextnode (node))
  85.       vertex_nexthop_free (node->data);
  86.   list_delete (v->nexthop);
  87.   XFREE (MTYPE_OSPF_VERTEX, v);
  88. }
  89. void
  90. ospf_vertex_add_parent (struct vertex *v)
  91. {
  92.   struct vertex_nexthop *nh;
  93.   listnode node;
  94.   for (node = listhead (v->nexthop); node; nextnode (node))
  95.     {
  96.       nh = (struct vertex_nexthop *) getdata (node);
  97.       /* No need to add two links from the same parent. */
  98.       if (listnode_lookup (nh->parent->child, v) == NULL)
  99. listnode_add (nh->parent->child, v);
  100.     }
  101. }
  102. void
  103. ospf_spf_init (struct ospf_area *area)
  104. {
  105.   struct vertex *v;
  106.   /* Create root node. */
  107.   v = ospf_vertex_new (area->router_lsa_self);
  108.   area->spf = v;
  109.   /* Reset ABR and ASBR router counts. */
  110.   area->abr_count = 0;
  111.   area->asbr_count = 0;
  112. }
  113. int
  114. ospf_spf_has_vertex (struct route_table *rv, struct route_table *nv,
  115.                      struct lsa_header *lsa)
  116. {
  117.   struct prefix p;
  118.   struct route_node *rn;
  119.   p.family = AF_INET;
  120.   p.prefixlen = IPV4_MAX_BITLEN;
  121.   p.u.prefix4 = lsa->id;
  122.   if (lsa->type == OSPF_ROUTER_LSA)
  123.     rn = route_node_get (rv, &p);
  124.   else
  125.     rn = route_node_get (nv, &p);
  126.   if (rn->info != NULL)
  127.     {
  128.       route_unlock_node (rn);
  129.       return 1;
  130.     }
  131.   return 0;
  132. }
  133. listnode
  134. ospf_vertex_lookup (list vlist, struct in_addr id, int type)
  135. {
  136.   listnode node;
  137.   struct vertex *v;
  138.   for (node = listhead (vlist); node; nextnode (node))
  139.     {
  140.       v = (struct vertex *) getdata (node);
  141.       if (IPV4_ADDR_SAME (&id, &v->id) && type == v->type)
  142.         return node;
  143.     }
  144.   return NULL;
  145. }
  146. int
  147. ospf_lsa_has_link (struct lsa_header *w, struct lsa_header *v)
  148. {
  149.   int i;
  150.   int length;
  151.   struct router_lsa *rl;
  152.   struct network_lsa *nl;
  153.   /* In case of W is Network LSA. */
  154.   if (w->type == OSPF_NETWORK_LSA)
  155.     {
  156.       if (v->type == OSPF_NETWORK_LSA)
  157.         return 0;
  158.       nl = (struct network_lsa *) w;
  159.       length = (ntohs (w->length) - OSPF_LSA_HEADER_SIZE - 4) / 4;
  160.       
  161.       for (i = 0; i < length; i++)
  162.         if (IPV4_ADDR_SAME (&nl->routers[i], &v->id))
  163.           return 1;
  164.       return 0;
  165.     }
  166.   /* In case of W is Router LSA. */
  167.   if (w->type == OSPF_ROUTER_LSA)
  168.     {
  169.       rl = (struct router_lsa *) w;
  170.       length = ntohs (w->length);
  171.       for (i = 0;
  172.    i < ntohs (rl->links) && length >= sizeof (struct router_lsa);
  173.    i++, length -= 12)
  174.         {
  175.           switch (rl->link[i].type)
  176.             {
  177.             case LSA_LINK_TYPE_POINTOPOINT:
  178.             case LSA_LINK_TYPE_VIRTUALLINK:
  179.               /* Router LSA ID. */
  180.               if (v->type == OSPF_ROUTER_LSA &&
  181.                   IPV4_ADDR_SAME (&rl->link[i].link_id, &v->id))
  182.                 {
  183.                   return 1;
  184.                 }
  185.               break;
  186.             case LSA_LINK_TYPE_TRANSIT:
  187.               /* Network LSA ID. */
  188.               if (v->type == OSPF_NETWORK_LSA &&
  189.                   IPV4_ADDR_SAME (&rl->link[i].link_id, &v->id))
  190.                 {
  191.                   return 1;
  192. }
  193.               break;
  194.             case LSA_LINK_TYPE_STUB:
  195.               /* Not take into count? */
  196.               continue;
  197.             default:
  198.               break;
  199.             }
  200.         }
  201.     }
  202.   return 0;
  203. }
  204. /* Add the nexthop to the list, only if it is unique.
  205.  * If it's not unique, free the nexthop entry.
  206.  */
  207. void
  208. ospf_nexthop_add_unique (struct vertex_nexthop *new, list nexthop)
  209. {
  210.   struct vertex_nexthop *nh;
  211.   listnode node;
  212.   int match;
  213.   match = 0;
  214.   for (node = listhead (nexthop); node; nextnode (node))
  215.     {
  216.       nh = node->data;
  217.       /* Compare the two entries. */
  218.       /* XXX
  219.        * Comparing the parent preserves the shortest path tree
  220.        * structure even when the nexthops are identical.
  221.        */
  222.       if (nh->oi == new->oi &&
  223.   IPV4_ADDR_SAME (&nh->router, &new->router) &&
  224.   nh->parent == new->parent)
  225. {
  226.   match = 1;
  227.   break;
  228. }
  229.     }
  230.   if (!match)
  231.     listnode_add (nexthop, new);
  232.   else
  233.     vertex_nexthop_free (new);
  234. }
  235. /* Merge entries in list b into list a. */
  236. void
  237. ospf_nexthop_merge (list a, list b)
  238. {
  239.   struct listnode *n;
  240.   for (n = listhead (b); n; nextnode (n))
  241.     {
  242.       ospf_nexthop_add_unique (n->data, a);
  243.     }
  244. }
  245. #define ROUTER_LSA_MIN_SIZE 12
  246. #define ROUTER_LSA_TOS_SIZE 4
  247. struct router_lsa_link *
  248. ospf_get_next_link (struct vertex *v, struct vertex *w,
  249.     struct router_lsa_link *prev_link)
  250. {
  251.   u_char *p;
  252.   u_char *lim;
  253.   struct router_lsa_link *l;
  254.   if (prev_link == NULL)
  255.     p = ((u_char *) v->lsa) + 24;
  256.   else
  257.     {
  258.       p = (u_char *)prev_link;
  259.       p += (ROUTER_LSA_MIN_SIZE +
  260.             (prev_link->m[0].tos_count * ROUTER_LSA_TOS_SIZE));
  261.     }
  262.   
  263.   lim = ((u_char *) v->lsa) + ntohs (v->lsa->length);
  264.   while (p < lim)
  265.     {
  266.       l = (struct router_lsa_link *) p;
  267.       p += (ROUTER_LSA_MIN_SIZE +
  268.             (l->m[0].tos_count * ROUTER_LSA_TOS_SIZE));
  269.       if (l->m[0].type == LSA_LINK_TYPE_STUB)
  270.         continue;
  271.       /* Defer NH calculation via VLs until summaries from
  272.          transit areas area confidered             */
  273.       if (l->m[0].type == LSA_LINK_TYPE_VIRTUALLINK)
  274.         continue; 
  275.       if (IPV4_ADDR_SAME (&l->link_id, &w->id))
  276.           return l;
  277.     }
  278.   return NULL;
  279. }
  280. /* Calculate nexthop from root to vertex W. */
  281. void
  282. ospf_nexthop_calculation (struct ospf_area *area,
  283.                           struct vertex *v, struct vertex *w)
  284. {
  285.   listnode node;
  286.   struct vertex_nexthop *nh, *x;
  287.   struct ospf_interface *oi = NULL;
  288.   struct router_lsa_link *l = NULL;
  289.   
  290.     
  291.   if (IS_DEBUG_OSPF_EVENT)
  292.     zlog_info ("ospf_nexthop_calculation(): Start");
  293.   /* W's parent is root. */
  294.   if (v == area->spf)
  295.     {
  296.       if (w->type == OSPF_VERTEX_ROUTER)
  297. {
  298.   while ((l = ospf_get_next_link (v, w, l)))
  299.     {
  300.       struct router_lsa_link *l2 = NULL;
  301.       
  302.       if (l->m[0].type == LSA_LINK_TYPE_POINTOPOINT)
  303. {
  304.   /* Check for PtMP, signified by PtP link V->W
  305.      with link_data our PtMP interface. */
  306.                   oi = ospf_if_is_configured (area->ospf, &l->link_data);
  307.                   if (oi && oi->type == OSPF_IFTYPE_POINTOMULTIPOINT)
  308.     {
  309.       struct prefix_ipv4 la;
  310.       la.prefixlen = oi->address->prefixlen;
  311.       
  312.       /* We link to them on PtMP interface
  313.  - find the interface on w */
  314.       while ((l2 = ospf_get_next_link (w, v, l2)))
  315. {
  316.   la.prefix = l2->link_data;
  317.   
  318.   if (prefix_cmp ((struct prefix *)&la,
  319.   oi->address) == 0)
  320.     /* link_data is on our PtMP network */
  321.     break;
  322. }
  323.     }
  324.   else
  325.     {                                
  326.       while ((l2 = ospf_get_next_link (w, v, l2)))
  327. {
  328.   oi = ospf_if_is_configured (area->ospf,
  329.       &(l2->link_data));
  330.   
  331.   if (oi == NULL)
  332.     continue;
  333.   
  334.   if (!IPV4_ADDR_SAME (&oi->address->u.prefix4,
  335.        &l->link_data))
  336.     continue;
  337.   
  338.   break;
  339. }
  340.     }
  341.   
  342.   if (oi && l2)
  343.     {
  344.       nh = vertex_nexthop_new (v);
  345.       nh->oi = oi;
  346.       nh->router = l2->link_data;
  347.       listnode_add (w->nexthop, nh);
  348.     }
  349. }
  350.     }
  351. }
  352.       else
  353. {
  354.   while ((l = ospf_get_next_link (v, w, l)))
  355.     {
  356.       oi = ospf_if_is_configured (area->ospf, &(l->link_data));
  357.       if (oi)
  358. {
  359.   nh = vertex_nexthop_new (v);
  360.   nh->oi = oi;
  361.   nh->router.s_addr = 0;
  362.   listnode_add (w->nexthop, nh);
  363. }
  364.     }
  365. }
  366.       return;
  367.     }
  368.   /* In case of W's parent is network connected to root. */
  369.   else if (v->type == OSPF_VERTEX_NETWORK)
  370.     {
  371.       for (node = listhead (v->nexthop); node; nextnode (node))
  372.         {
  373.           x = (struct vertex_nexthop *) getdata (node);
  374.           if (x->parent == area->spf)
  375.             {
  376.       while ((l = ospf_get_next_link (w, v, l)))
  377. {
  378.   nh = vertex_nexthop_new (v);
  379.   nh->oi = x->oi;
  380.   nh->router = l->link_data;
  381.   listnode_add (w->nexthop, nh);
  382. }
  383.       return;
  384.     }
  385.         }
  386.     }
  387.   /* Inherit V's nexthop. */
  388.   for (node = listhead (v->nexthop); node; nextnode (node))
  389.     {
  390.       nh = vertex_nexthop_dup (node->data);
  391.       nh->parent = v;
  392.       ospf_nexthop_add_unique (nh, w->nexthop);
  393.     }
  394. }
  395. void
  396. ospf_install_candidate (list candidate, struct vertex *w)
  397. {
  398.   listnode node;
  399.   struct vertex *cw;
  400.   if (list_isempty (candidate))
  401.     {
  402.       listnode_add (candidate, w);
  403.       return;
  404.     }
  405.   /* Install vertex with sorting by distance. */
  406.   for (node = listhead (candidate); node; nextnode (node))
  407.     {
  408.       cw = (struct vertex *) getdata (node);
  409.       if (cw->distance > w->distance)
  410.         {
  411.           list_add_node_prev (candidate, node, w);
  412.           break;
  413.         }
  414.       else if (node->next == NULL)
  415.         {
  416.           list_add_node_next (candidate, node, w);
  417.           break;
  418.         }
  419.     }
  420. }
  421. /* RFC2328 Section 16.1 (2). */
  422. void
  423. ospf_spf_next (struct vertex *v, struct ospf_area *area,
  424.                list candidate, struct route_table *rv,
  425.                struct route_table *nv)
  426. {
  427.   struct ospf_lsa *w_lsa = NULL;
  428.   struct vertex *w, *cw;
  429.   u_char *p;
  430.   u_char *lim;
  431.   struct router_lsa_link *l = NULL;
  432.   struct in_addr *r;
  433.   listnode node;
  434.   int type = 0;
  435.   /* If this is a router-LSA, and bit V of the router-LSA (see Section
  436.      A.4.2:RFC2328) is set, set Area A's TransitCapability to TRUE.  */
  437.   if (v->type == OSPF_VERTEX_ROUTER)
  438.     {
  439.       if (IS_ROUTER_LSA_VIRTUAL ((struct router_lsa *) v->lsa))
  440.         area->transit = OSPF_TRANSIT_TRUE;
  441.     }
  442.   p = ((u_char *) v->lsa) + OSPF_LSA_HEADER_SIZE + 4;
  443.   lim =  ((u_char *) v->lsa) + ntohs (v->lsa->length);
  444.     
  445.   while (p < lim)
  446.     {
  447.       /* In case of V is Router-LSA. */
  448.       if (v->lsa->type == OSPF_ROUTER_LSA)
  449.         {
  450.           l = (struct router_lsa_link *) p;
  451.           p += (ROUTER_LSA_MIN_SIZE + 
  452.                 (l->m[0].tos_count * ROUTER_LSA_TOS_SIZE));
  453.           /* (a) If this is a link to a stub network, examine the next
  454.              link in V's LSA.  Links to stub networks will be
  455.              considered in the second stage of the shortest path
  456.              calculation. */
  457.           if ((type = l->m[0].type) == LSA_LINK_TYPE_STUB)
  458.             continue;
  459.           /* (b) Otherwise, W is a transit vertex (router or transit
  460.              network).  Look up the vertex W's LSA (router-LSA or
  461.              network-LSA) in Area A's link state database. */
  462.           switch (type)
  463.             {
  464.             case LSA_LINK_TYPE_POINTOPOINT:
  465.             case LSA_LINK_TYPE_VIRTUALLINK:
  466.               if (type == LSA_LINK_TYPE_VIRTUALLINK)
  467. {
  468.   if (IS_DEBUG_OSPF_EVENT)
  469.     zlog_info ("looking up LSA through VL: %s",
  470.        inet_ntoa (l->link_id));
  471. }
  472.               w_lsa = ospf_lsa_lookup (area, OSPF_ROUTER_LSA, l->link_id,
  473.                                        l->link_id);
  474.               if (w_lsa)
  475. {
  476.   if (IS_DEBUG_OSPF_EVENT)
  477.   zlog_info("found the LSA");
  478. }
  479.               break;
  480.             case LSA_LINK_TYPE_TRANSIT:
  481.   if (IS_DEBUG_OSPF_EVENT)
  482.               zlog_info ("Looking up Network LSA, ID: %s",
  483.                          inet_ntoa(l->link_id));
  484.               w_lsa = ospf_lsa_lookup_by_id (area, OSPF_NETWORK_LSA,
  485.      l->link_id);
  486.               if (w_lsa)
  487.   if (IS_DEBUG_OSPF_EVENT)
  488.                 zlog_info("found the LSA");
  489.               break;
  490.             default:
  491.       zlog_warn ("Invalid LSA link type %d", type);
  492.               continue;
  493.             }
  494.         }
  495.       else
  496.         {
  497.           /* In case of V is Network-LSA. */
  498.           r = (struct in_addr *) p ;
  499.           p += sizeof (struct in_addr);
  500.           /* Lookup the vertex W's LSA. */
  501.           w_lsa = ospf_lsa_lookup_by_id (area, OSPF_ROUTER_LSA, *r);
  502.         }
  503.       /* (b cont.) If the LSA does not exist, or its LS age is equal
  504.          to MaxAge, or it does not have a link back to vertex V,
  505.          examine the next link in V's LSA.[23] */
  506.       if (w_lsa == NULL)
  507.         continue;
  508.       if (IS_LSA_MAXAGE (w_lsa))
  509.         continue;
  510.       if (! ospf_lsa_has_link (w_lsa->data, v->lsa))
  511.         {
  512.   if (IS_DEBUG_OSPF_EVENT)
  513.   zlog_info ("The LSA doesn't have a link back");
  514.           continue;
  515.         }
  516.       /* (c) If vertex W is already on the shortest-path tree, examine
  517.          the next link in the LSA. */
  518.       if (ospf_spf_has_vertex (rv, nv, w_lsa->data))
  519.         {
  520.   if (IS_DEBUG_OSPF_EVENT)
  521.           zlog_info ("The LSA is already in SPF");
  522.           continue;
  523.         }
  524.       /* (d) Calculate the link state cost D of the resulting path
  525.          from the root to vertex W.  D is equal to the sum of the link
  526.          state cost of the (already calculated) shortest path to
  527.          vertex V and the advertised cost of the link between vertices
  528.          V and W.  If D is: */
  529.       /* prepare vertex W. */
  530.       w = ospf_vertex_new (w_lsa);
  531.       /* calculate link cost D. */
  532.       if (v->lsa->type == OSPF_ROUTER_LSA)
  533.         w->distance = v->distance + ntohs (l->m[0].metric);
  534.       else
  535.         w->distance = v->distance;
  536.       /* Is there already vertex W in candidate list? */
  537.       node = ospf_vertex_lookup (candidate, w->id, w->type);
  538.       if (node == NULL)
  539.         {
  540.           /* Calculate nexthop to W. */
  541.           ospf_nexthop_calculation (area, v, w);
  542.           ospf_install_candidate (candidate, w);
  543.         }
  544.       else
  545.         {
  546.           cw = (struct vertex *) getdata (node);
  547.           /* if D is greater than. */
  548.           if (cw->distance < w->distance)
  549.             {
  550.               ospf_vertex_free (w);
  551.               continue;
  552.             }
  553.           /* equal to. */
  554.           else if (cw->distance == w->distance)
  555.             {
  556.               /* Calculate nexthop to W. */
  557.               ospf_nexthop_calculation (area, v, w);
  558.               ospf_nexthop_merge (cw->nexthop, w->nexthop);
  559.               list_delete_all_node (w->nexthop);
  560.               ospf_vertex_free (w);
  561.             }
  562.           /* less than. */
  563.           else
  564.             {
  565.               /* Calculate nexthop. */
  566.               ospf_nexthop_calculation (area, v, w);
  567.               /* Remove old vertex from candidate list. */
  568.               ospf_vertex_free (cw);
  569.               listnode_delete (candidate, cw);
  570.               /* Install new to candidate. */
  571.               ospf_install_candidate (candidate, w);
  572.             }
  573.         }
  574.     }
  575. }
  576. /* Add vertex V to SPF tree. */
  577. void
  578. ospf_spf_register (struct vertex *v, struct route_table *rv,
  579.    struct route_table *nv)
  580. {
  581.   struct prefix p;
  582.   struct route_node *rn;
  583.   p.family = AF_INET;
  584.   p.prefixlen = IPV4_MAX_BITLEN;
  585.   p.u.prefix4 = v->id;
  586.   if (v->type == OSPF_VERTEX_ROUTER)
  587.     rn = route_node_get (rv, &p);
  588.   else
  589.     rn = route_node_get (nv, &p);
  590.   rn->info = v;
  591. }
  592. void
  593. ospf_spf_route_free (struct route_table *table)
  594. {
  595.   struct route_node *rn;
  596.   struct vertex *v;
  597.   for (rn = route_top (table); rn; rn = route_next (rn))
  598.     {
  599.       if ((v = rn->info))
  600. {
  601.   ospf_vertex_free (v);
  602.   rn->info = NULL;
  603. }
  604.       route_unlock_node (rn);
  605.     }
  606.   route_table_finish (table);
  607. }
  608. void
  609. ospf_spf_dump (struct vertex *v, int i)
  610. {
  611.   listnode cnode;
  612.   listnode nnode;
  613.   struct vertex_nexthop *nexthop;
  614.   if (v->type == OSPF_VERTEX_ROUTER)
  615.     {
  616.       if (IS_DEBUG_OSPF_EVENT)
  617. zlog_info ("SPF Result: %d [R] %s", i, inet_ntoa (v->lsa->id));
  618.     }
  619.   else
  620.     {
  621.       struct network_lsa *lsa = (struct network_lsa *) v->lsa;
  622.       if (IS_DEBUG_OSPF_EVENT)
  623. zlog_info ("SPF Result: %d [N] %s/%d", i, inet_ntoa (v->lsa->id),
  624.    ip_masklen (lsa->mask));
  625.       for (nnode = listhead (v->nexthop); nnode; nextnode (nnode))
  626.         {
  627.           nexthop = getdata (nnode);
  628.   if (IS_DEBUG_OSPF_EVENT)
  629.     zlog_info (" nexthop %s", inet_ntoa (nexthop->router));
  630.         }
  631.     }
  632.   i++;
  633.   for (cnode = listhead (v->child); cnode; nextnode (cnode))
  634.     {
  635.       v = getdata (cnode);
  636.       ospf_spf_dump (v, i);
  637.     }
  638. }
  639. /* Second stage of SPF calculation. */
  640. void
  641. ospf_spf_process_stubs (struct ospf_area *area, struct vertex * v,
  642.                         struct route_table *rt)
  643. {
  644.   listnode cnode;
  645.   struct vertex *child;
  646.   if (IS_DEBUG_OSPF_EVENT)
  647.     zlog_info ("ospf_process_stub():processing stubs for area %s",
  648.        inet_ntoa (area->area_id));
  649.   if (v->type == OSPF_VERTEX_ROUTER)
  650.     {
  651.       u_char *p;
  652.       u_char *lim;
  653.       struct router_lsa_link *l;
  654.       struct router_lsa *rlsa;
  655.   if (IS_DEBUG_OSPF_EVENT)
  656.       zlog_info ("ospf_process_stub():processing router LSA, id: %s",
  657.                  inet_ntoa (v->lsa->id));
  658.       rlsa = (struct router_lsa *) v->lsa;
  659.   if (IS_DEBUG_OSPF_EVENT)
  660.       zlog_info ("ospf_process_stub(): we have %d links to process",
  661.                  ntohs (rlsa->links));
  662.       p = ((u_char *) v->lsa) + 24;
  663.       lim = ((u_char *) v->lsa) + ntohs (v->lsa->length);
  664.       while (p < lim)
  665.         {
  666.           l = (struct router_lsa_link *) p;
  667.           p += (ROUTER_LSA_MIN_SIZE +
  668.                 (l->m[0].tos_count * ROUTER_LSA_TOS_SIZE));
  669.           if (l->m[0].type == LSA_LINK_TYPE_STUB)
  670.             ospf_intra_add_stub (rt, l, v, area);
  671.         }
  672.     }
  673.   if (IS_DEBUG_OSPF_EVENT)
  674.   zlog_info ("children of V:");
  675.   for (cnode = listhead (v->child); cnode; nextnode (cnode))
  676.     {
  677.       child = getdata (cnode);
  678.   if (IS_DEBUG_OSPF_EVENT)
  679.       zlog_info (" child : %s", inet_ntoa (child->id));
  680.     }
  681.   for (cnode = listhead (v->child); cnode; nextnode (cnode))
  682.     {
  683.       child = getdata (cnode);
  684.       if (CHECK_FLAG (child->flags, OSPF_VERTEX_PROCESSED))
  685. continue;
  686.       ospf_spf_process_stubs (area, child, rt);
  687.       SET_FLAG (child->flags, OSPF_VERTEX_PROCESSED);
  688.     }
  689. }
  690. void
  691. ospf_rtrs_free (struct route_table *rtrs)
  692. {
  693.   struct route_node *rn;
  694.   list or_list;
  695.   listnode node;
  696.   if (IS_DEBUG_OSPF_EVENT)
  697.   zlog_info ("Route: Router Routing Table free");
  698.   for (rn = route_top (rtrs); rn; rn = route_next (rn))
  699.     if ((or_list = rn->info) != NULL)
  700.       {
  701. for (node = listhead (or_list); node; nextnode (node))
  702.   ospf_route_free (node->data);
  703. list_delete (or_list);
  704. /* Unlock the node. */
  705. rn->info = NULL;
  706. route_unlock_node (rn);
  707.       }
  708.   route_table_finish (rtrs);
  709. }
  710. void
  711. ospf_rtrs_print (struct route_table *rtrs)
  712. {
  713.   struct route_node *rn;
  714.   list or_list;
  715.   listnode ln;
  716.   listnode pnode;
  717.   struct ospf_route *or;
  718.   struct ospf_path *path;
  719.   char buf1[BUFSIZ];
  720.   char buf2[BUFSIZ];
  721.   if (IS_DEBUG_OSPF_EVENT)
  722.     zlog_info ("ospf_rtrs_print() start");
  723.   for (rn = route_top (rtrs); rn; rn = route_next (rn))
  724.     if ((or_list = rn->info) != NULL)
  725.       for (ln = listhead (or_list); ln; nextnode (ln))
  726.         {
  727.           or = getdata (ln);
  728.           switch (or->path_type)
  729.             {
  730.             case OSPF_PATH_INTRA_AREA:
  731.       if (IS_DEBUG_OSPF_EVENT)
  732. zlog_info ("%s   [%d] area: %s", 
  733.    inet_ntop (AF_INET, &or->id, buf1, BUFSIZ), or->cost,
  734.    inet_ntop (AF_INET, &or->u.std.area_id,
  735.       buf2, BUFSIZ));
  736.               break;
  737.             case OSPF_PATH_INTER_AREA:
  738.       if (IS_DEBUG_OSPF_EVENT)
  739. zlog_info ("%s IA [%d] area: %s", 
  740.    inet_ntop (AF_INET, &or->id, buf1, BUFSIZ), or->cost,
  741.    inet_ntop (AF_INET, &or->u.std.area_id,
  742.       buf2, BUFSIZ));
  743.               break;
  744.             default:
  745.               break;
  746.             }
  747.           for (pnode = listhead (or->path); pnode; nextnode (pnode))
  748.             {
  749.               path = getdata (pnode);
  750.               if (path->nexthop.s_addr == 0)
  751. {
  752.   if (IS_DEBUG_OSPF_EVENT)
  753.     zlog_info ("   directly attached to %srn",
  754.        IF_NAME (path->oi));
  755. }
  756.               else 
  757. {
  758.   if (IS_DEBUG_OSPF_EVENT)
  759.     zlog_info ("   via %s, %srn",
  760.        inet_ntoa (path->nexthop), IF_NAME (path->oi));
  761. }
  762.             }
  763.         }
  764.   zlog_info ("ospf_rtrs_print() end");
  765. }
  766. /* Calculating the shortest-path tree for an area. */
  767. void
  768. ospf_spf_calculate (struct ospf_area *area, struct route_table *new_table, 
  769.                     struct route_table *new_rtrs)
  770. {
  771.   list candidate;
  772.   listnode node;
  773.   struct vertex *v;
  774.   struct route_table *rv;
  775.   struct route_table *nv;
  776.   if (IS_DEBUG_OSPF_EVENT)
  777.     {
  778.       zlog_info ("ospf_spf_calculate: Start");
  779.       zlog_info ("ospf_spf_calculate: running Dijkstra for area %s", 
  780.  inet_ntoa (area->area_id));
  781.     }
  782.   /* Check router-lsa-self.  If self-router-lsa is not yet allocated,
  783.      return this area's calculation. */
  784.   if (! area->router_lsa_self)
  785.     {
  786.       if (IS_DEBUG_OSPF_EVENT)
  787. zlog_info ("ospf_spf_calculate: "
  788.    "Skip area %s's calculation due to empty router_lsa_self",
  789.    inet_ntoa (area->area_id));
  790.       return;
  791.     }
  792.   /* RFC2328 16.1. (1). */
  793.   /* Initialize the algorithm's data structures. */ 
  794.   rv = route_table_init ();
  795.   nv = route_table_init ();
  796.   /* Clear the list of candidate vertices. */ 
  797.   candidate = list_new ();
  798.   /* Initialize the shortest-path tree to only the root (which is the
  799.      router doing the calculation). */
  800.   ospf_spf_init (area);
  801.   v = area->spf;
  802.   ospf_spf_register (v, rv, nv);
  803.   /* Set Area A's TransitCapability to FALSE. */
  804.   area->transit = OSPF_TRANSIT_FALSE;
  805.   area->shortcut_capability = 1;
  806.   for (;;)
  807.     {
  808.       /* RFC2328 16.1. (2). */
  809.       ospf_spf_next (v, area, candidate, rv, nv);
  810.       /* RFC2328 16.1. (3). */
  811.       /* If at this step the candidate list is empty, the shortest-
  812.          path tree (of transit vertices) has been completely built and
  813.          this stage of the procedure terminates. */
  814.       if (listcount (candidate) == 0)
  815.         break;
  816.       /* Otherwise, choose the vertex belonging to the candidate list
  817.          that is closest to the root, and add it to the shortest-path
  818.          tree (removing it from the candidate list in the
  819.          process). */ 
  820.       node = listhead (candidate);
  821.       v = getdata (node);
  822.       ospf_vertex_add_parent (v);
  823.       /* Reveve from the candidate list. */
  824.       listnode_delete (candidate, v);
  825.       /* Add to SPF tree. */
  826.       ospf_spf_register (v, rv, nv);
  827.       /* Note that when there is a choice of vertices closest to the
  828.          root, network vertices must be chosen before router vertices
  829.          in order to necessarily find all equal-cost paths. */
  830.       /* We don't do this at this moment, we should add the treatment
  831.          above codes. -- kunihiro. */
  832.       /* RFC2328 16.1. (4). */
  833.       if (v->type == OSPF_VERTEX_ROUTER)
  834.         ospf_intra_add_router (new_rtrs, v, area);
  835.       else 
  836.         ospf_intra_add_transit (new_table, v, area);
  837.       /* RFC2328 16.1. (5). */
  838.       /* Iterate the algorithm by returning to Step 2. */
  839.     }
  840.   if (IS_DEBUG_OSPF_EVENT)
  841.     {
  842.       ospf_spf_dump (area->spf, 0);
  843.       ospf_route_table_dump (new_table);
  844.     }
  845.   /* Second stage of SPF calculation procedure's  */
  846.   ospf_spf_process_stubs (area, area->spf, new_table);
  847.   /* Free all vertices which allocated for SPF calculation */
  848.   ospf_spf_route_free (rv);
  849.   ospf_spf_route_free (nv);
  850.   /* Free candidate list */
  851.   list_free (candidate);
  852.   /* Increment SPF Calculation Counter. */
  853.   area->spf_calculation++;
  854.   area->ospf->ts_spf = time (NULL);
  855.   if (IS_DEBUG_OSPF_EVENT)
  856.     zlog_info ("ospf_spf_calculate: Stop");
  857. }
  858. /* Timer for SPF calculation. */
  859. int
  860. ospf_spf_calculate_timer (struct thread *thread)
  861. {
  862.   struct ospf *ospf = THREAD_ARG (thread);
  863.   struct route_table *new_table, *new_rtrs;
  864.   listnode node;
  865.   if (IS_DEBUG_OSPF_EVENT)
  866.     zlog_info ("SPF: Timer (SPF calculation expire)");
  867.   
  868.   ospf->t_spf_calc = NULL;
  869.   /* Allocate new table tree. */
  870.   new_table = route_table_init ();
  871.   new_rtrs  = route_table_init ();
  872.   ospf_vl_unapprove (ospf);
  873.   /* Calculate SPF for each area. */
  874.   for (node = listhead (ospf->areas); node; node = nextnode (node))
  875.     ospf_spf_calculate (node->data, new_table, new_rtrs);
  876.   ospf_vl_shut_unapproved (ospf);
  877.   ospf_ia_routing (ospf, new_table, new_rtrs);
  878.   ospf_prune_unreachable_networks (new_table);
  879.   ospf_prune_unreachable_routers (new_rtrs);
  880.   /* AS-external-LSA calculation should not be performed here. */
  881.   /* If new Router Route is installed,
  882.      then schedule re-calculate External routes. */
  883.   if (1)
  884.     ospf_ase_calculate_schedule (ospf);
  885.   ospf_ase_calculate_timer_add (ospf);
  886.   /* Update routing table. */
  887.   ospf_route_install (ospf, new_table);
  888.   /* Update ABR/ASBR routing table */
  889.   if (ospf->old_rtrs)
  890.     {
  891.       /* old_rtrs's node holds linked list of ospf_route. --kunihiro. */
  892.       /* ospf_route_delete (ospf->old_rtrs); */
  893.       ospf_rtrs_free (ospf->old_rtrs);
  894.     }
  895.   ospf->old_rtrs = ospf->new_rtrs;
  896.   ospf->new_rtrs = new_rtrs;
  897.   if (IS_OSPF_ABR (ospf)) 
  898.     ospf_abr_task (ospf);
  899.   if (IS_DEBUG_OSPF_EVENT)
  900.     zlog_info ("SPF: calculation complete");
  901.   return 0;
  902. }
  903. /* Add schedule for SPF calculation.  To avoid frequenst SPF calc, we
  904.    set timer for SPF calc. */
  905. void
  906. ospf_spf_calculate_schedule (struct ospf *ospf)
  907. {
  908.   time_t ht, delay;
  909.   if (IS_DEBUG_OSPF_EVENT)
  910.     zlog_info ("SPF: calculation timer scheduled");
  911.   /* OSPF instance does not exist. */
  912.   if (ospf == NULL)
  913.     return;
  914.   /* SPF calculation timer is already scheduled. */
  915.   if (ospf->t_spf_calc)
  916.     {
  917.       if (IS_DEBUG_OSPF_EVENT)
  918. zlog_info ("SPF: calculation timer is already scheduled: %p",
  919.    ospf->t_spf_calc);
  920.       return;
  921.     }
  922.   ht = time (NULL) - ospf->ts_spf;
  923.   /* Get SPF calculation delay time. */
  924.   if (ht < ospf->spf_holdtime)
  925.     {
  926.       if (ospf->spf_holdtime - ht < ospf->spf_delay)
  927. delay = ospf->spf_delay;
  928.       else
  929. delay = ospf->spf_holdtime - ht;
  930.     }
  931.   else
  932.     delay = ospf->spf_delay;
  933.   if (IS_DEBUG_OSPF_EVENT)
  934.     zlog_info ("SPF: calculation timer delay = %ld", delay);
  935.   ospf->t_spf_calc =
  936.     thread_add_timer (master, ospf_spf_calculate_timer, ospf, delay);
  937. }