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

网络

开发平台:

Unix_Linux

  1. /*
  2.  * Copyright (C) 2003 Yasuhiro Ohara
  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 
  18.  * Free Software Foundation, Inc., 59 Temple Place - Suite 330, 
  19.  * Boston, MA 02111-1307, USA.  
  20.  */
  21. #include <zebra.h>
  22. #include "memory.h"
  23. #include "log.h"
  24. #include "command.h"
  25. #include "prefix.h"
  26. #include "table.h"
  27. #include "vty.h"
  28. #include "ospf6_proto.h"
  29. #include "ospf6_lsa.h"
  30. #include "ospf6_lsdb.h"
  31. #include "ospf6d.h"
  32. struct ospf6_lsdb *
  33. ospf6_lsdb_create (void *data)
  34. {
  35.   struct ospf6_lsdb *lsdb;
  36.   lsdb = XCALLOC (MTYPE_OSPF6_LSDB, sizeof (struct ospf6_lsdb));
  37.   if (lsdb == NULL)
  38.     {
  39.       zlog_warn ("Can't malloc lsdb");
  40.       return NULL;
  41.     }
  42.   memset (lsdb, 0, sizeof (struct ospf6_lsdb));
  43.   lsdb->data = data;
  44.   lsdb->table = route_table_init ();
  45.   return lsdb;
  46. }
  47. void
  48. ospf6_lsdb_delete (struct ospf6_lsdb *lsdb)
  49. {
  50.   ospf6_lsdb_remove_all (lsdb);
  51.   route_table_finish (lsdb->table);
  52.   XFREE (MTYPE_OSPF6_LSDB, lsdb);
  53. }
  54. static void
  55. ospf6_lsdb_set_key (struct prefix_ipv6 *key, void *value, int len)
  56. {
  57.   assert (key->prefixlen % 8 == 0);
  58.   memcpy ((caddr_t) &key->prefix + key->prefixlen / 8,
  59.           (caddr_t) value, len);
  60.   key->family = AF_INET6;
  61.   key->prefixlen += len * 8;
  62. }
  63. #ifndef NDEBUG
  64. static void
  65. _lsdb_count_assert (struct ospf6_lsdb *lsdb)
  66. {
  67.   struct ospf6_lsa *debug;
  68.   int num = 0;
  69.   for (debug = ospf6_lsdb_head (lsdb); debug;
  70.        debug = ospf6_lsdb_next (debug))
  71.     num++;
  72.   if (num == lsdb->count)
  73.     return;
  74.   zlog_info ("PANIC !! lsdb[%p]->count = %d, real = %d",
  75.              lsdb, lsdb->count, num);
  76.   for (debug = ospf6_lsdb_head (lsdb); debug;
  77.        debug = ospf6_lsdb_next (debug))
  78.     zlog_info ("%p %p %s lsdb[%p]", debug->prev, debug->next, debug->name,
  79.                debug->lsdb);
  80.   zlog_info ("DUMP END");
  81.   assert (num == lsdb->count);
  82. }
  83. #define ospf6_lsdb_count_assert(t) (_lsdb_count_assert (t))
  84. #else /*NDEBUG*/
  85. #define ospf6_lsdb_count_assert(t) ((void) 0)
  86. #endif /*NDEBUG*/
  87. void
  88. ospf6_lsdb_add (struct ospf6_lsa *lsa, struct ospf6_lsdb *lsdb)
  89. {
  90.   struct prefix_ipv6 key;
  91.   struct route_node *current, *nextnode, *prevnode;
  92.   struct ospf6_lsa *next, *prev, *old = NULL;
  93.   memset (&key, 0, sizeof (key));
  94.   ospf6_lsdb_set_key (&key, &lsa->header->type, sizeof (lsa->header->type));
  95.   ospf6_lsdb_set_key (&key, &lsa->header->adv_router,
  96.                       sizeof (lsa->header->adv_router));
  97.   ospf6_lsdb_set_key (&key, &lsa->header->id, sizeof (lsa->header->id));
  98.   current = route_node_get (lsdb->table, (struct prefix *) &key);
  99.   old = current->info;
  100.   current->info = lsa;
  101.   ospf6_lsa_lock (lsa);
  102.   if (old)
  103.     {
  104.       if (old->prev)
  105.         old->prev->next = lsa;
  106.       if (old->next)
  107.         old->next->prev = lsa;
  108.       lsa->next = old->next;
  109.       lsa->prev = old->prev;
  110.     }
  111.   else
  112.     {
  113.       /* next link */
  114.       nextnode = current;
  115.       route_lock_node (nextnode);
  116.       do {
  117.         nextnode = route_next (nextnode);
  118.       } while (nextnode && nextnode->info == NULL);
  119.       if (nextnode == NULL)
  120.         lsa->next = NULL;
  121.       else
  122.         {
  123.           next = nextnode->info;
  124.           lsa->next = next;
  125.           next->prev = lsa;
  126.           route_unlock_node (nextnode);
  127.         }
  128.       /* prev link */
  129.       prevnode = current;
  130.       route_lock_node (prevnode);
  131.       do {
  132.         prevnode = route_prev (prevnode);
  133.       } while (prevnode && prevnode->info == NULL);
  134.       if (prevnode == NULL)
  135.         lsa->prev = NULL;
  136.       else
  137.         {
  138.           prev = prevnode->info;
  139.           lsa->prev = prev;
  140.           prev->next = lsa;
  141.           route_unlock_node (prevnode);
  142.         }
  143.       lsdb->count++;
  144.     }
  145.   if (old)
  146.     {
  147.       if (OSPF6_LSA_IS_CHANGED (old, lsa))
  148.         {
  149.           if (OSPF6_LSA_IS_MAXAGE (lsa))
  150.             {
  151.               if (lsdb->hook_remove)
  152.                 {
  153.                   (*lsdb->hook_remove) (old);
  154.                   (*lsdb->hook_remove) (lsa);
  155.                 }
  156.             }
  157.           else if (OSPF6_LSA_IS_MAXAGE (old))
  158.             {
  159.               if (lsdb->hook_add)
  160.                 (*lsdb->hook_add) (lsa);
  161.             }
  162.           else
  163.             {
  164.               if (lsdb->hook_remove)
  165.                 (*lsdb->hook_remove) (old);
  166.               if (lsdb->hook_add)
  167.                 (*lsdb->hook_add) (lsa);
  168.             }
  169.         }
  170.     }
  171.   else if (OSPF6_LSA_IS_MAXAGE (lsa))
  172.     {
  173.       if (lsdb->hook_remove)
  174.         (*lsdb->hook_remove) (lsa);
  175.     }
  176.   else
  177.     {
  178.       if (lsdb->hook_add)
  179.         (*lsdb->hook_add) (lsa);
  180.     }
  181.   if (old)
  182.     ospf6_lsa_unlock (old);
  183. #if 0
  184.   ospf6_lsdb_count_assert (lsdb);
  185. #endif
  186. }
  187. void
  188. ospf6_lsdb_remove (struct ospf6_lsa *lsa, struct ospf6_lsdb *lsdb)
  189. {
  190.   struct route_node *node;
  191.   struct prefix_ipv6 key;
  192.   memset (&key, 0, sizeof (key));
  193.   ospf6_lsdb_set_key (&key, &lsa->header->type, sizeof (lsa->header->type));
  194.   ospf6_lsdb_set_key (&key, &lsa->header->adv_router,
  195.                       sizeof (lsa->header->adv_router));
  196.   ospf6_lsdb_set_key (&key, &lsa->header->id, sizeof (lsa->header->id));
  197.   node = route_node_lookup (lsdb->table, (struct prefix *) &key);
  198.   assert (node && node->info == lsa);
  199.   if (lsa->prev)
  200.     lsa->prev->next = lsa->next;
  201.   if (lsa->next)
  202.     lsa->next->prev = lsa->prev;
  203.   node->info = NULL;
  204.   lsdb->count--;
  205.   if (lsdb->hook_remove)
  206.     (*lsdb->hook_remove) (lsa);
  207.   ospf6_lsa_unlock (lsa);
  208.   route_unlock_node (node);
  209.   ospf6_lsdb_count_assert (lsdb);
  210. }
  211. struct ospf6_lsa *
  212. ospf6_lsdb_lookup (u_int16_t type, u_int32_t id, u_int32_t adv_router,
  213.                    struct ospf6_lsdb *lsdb)
  214. {
  215.   struct route_node *node;
  216.   struct prefix_ipv6 key;
  217.   if (lsdb == NULL)
  218.     return NULL;
  219.   memset (&key, 0, sizeof (key));
  220.   ospf6_lsdb_set_key (&key, &type, sizeof (type));
  221.   ospf6_lsdb_set_key (&key, &adv_router, sizeof (adv_router));
  222.   ospf6_lsdb_set_key (&key, &id, sizeof (id));
  223.   node = route_node_lookup (lsdb->table, (struct prefix *) &key);
  224.   if (node == NULL || node->info == NULL)
  225.     return NULL;
  226.   return (struct ospf6_lsa *) node->info;
  227. }
  228. /* Macro version of check_bit (). */
  229. #define CHECK_BIT(X,P) ((((u_char *)(X))[(P) / 8]) >> (7 - ((P) % 8)) & 1)
  230. struct ospf6_lsa *
  231. ospf6_lsdb_lookup_next (u_int16_t type, u_int32_t id, u_int32_t adv_router,
  232.                         struct ospf6_lsdb *lsdb)
  233. {
  234.   struct route_node *node;
  235.   struct route_node *matched = NULL;
  236.   struct prefix_ipv6 key;
  237.   struct prefix *p;
  238.   if (lsdb == NULL)
  239.     return NULL;
  240.   memset (&key, 0, sizeof (key));
  241.   ospf6_lsdb_set_key (&key, &type, sizeof (type));
  242.   ospf6_lsdb_set_key (&key, &adv_router, sizeof (adv_router));
  243.   ospf6_lsdb_set_key (&key, &id, sizeof (id));
  244.   p = (struct prefix *) &key;
  245.   {
  246.     char buf[64];
  247.     prefix2str (p, buf, sizeof (buf));
  248.     zlog_info ("lsdb_lookup_next: key: %s", buf);
  249.   }
  250.   node = lsdb->table->top;
  251.   /* walk down tree. */
  252.   while (node && node->p.prefixlen <= p->prefixlen &&
  253.          prefix_match (&node->p, p))
  254.     {
  255.       matched = node;
  256.       node = node->link[CHECK_BIT(&p->u.prefix, node->p.prefixlen)];
  257.     }
  258.   if (matched)
  259.     node = matched;
  260.   else
  261.     node = lsdb->table->top;
  262.   route_lock_node (node);
  263.   /* skip to real existing entry */
  264.   while (node && node->info == NULL)
  265.     node = route_next (node);
  266.   if (! node)
  267.     return NULL;
  268.   if (prefix_same (&node->p, p))
  269.     {
  270.       struct route_node *prev = node;
  271.       struct ospf6_lsa *lsa_prev;
  272.       struct ospf6_lsa *lsa_next;
  273.       node = route_next (node);
  274.       while (node && node->info == NULL)
  275.         node = route_next (node);
  276.       lsa_prev = prev->info;
  277.       lsa_next = (node ? node->info : NULL);
  278.       assert (lsa_prev);
  279.       assert (lsa_prev->next == lsa_next);
  280.       if (lsa_next)
  281.         assert (lsa_next->prev == lsa_prev);
  282.       zlog_info ("lsdb_lookup_next: assert OK with previous LSA");
  283.     }
  284.   if (! node)
  285.     return NULL;
  286.   route_unlock_node (node);
  287.   return (struct ospf6_lsa *) node->info;
  288. }
  289. /* Iteration function */
  290. struct ospf6_lsa *
  291. ospf6_lsdb_head (struct ospf6_lsdb *lsdb)
  292. {
  293.   struct route_node *node;
  294.   node = route_top (lsdb->table);
  295.   if (node == NULL)
  296.     return NULL;
  297.   /* skip to the existing lsdb entry */
  298.   while (node && node->info == NULL)
  299.     node = route_next (node);
  300.   if (node == NULL)
  301.     return NULL;
  302.   route_unlock_node (node);
  303.   if (node->info)
  304.     ospf6_lsa_lock ((struct ospf6_lsa *) node->info);
  305.   return (struct ospf6_lsa *) node->info;
  306. }
  307. struct ospf6_lsa *
  308. ospf6_lsdb_next (struct ospf6_lsa *lsa)
  309. {
  310.   struct ospf6_lsa *next = lsa->next;
  311.   ospf6_lsa_unlock (lsa);
  312.   if (next)
  313.     ospf6_lsa_lock (next);
  314.   return next;
  315. }
  316. struct ospf6_lsa *
  317. ospf6_lsdb_type_router_head (u_int16_t type, u_int32_t adv_router,
  318.                              struct ospf6_lsdb *lsdb)
  319. {
  320.   struct route_node *node;
  321.   struct prefix_ipv6 key;
  322.   struct ospf6_lsa *lsa;
  323.   memset (&key, 0, sizeof (key));
  324.   ospf6_lsdb_set_key (&key, &type, sizeof (type));
  325.   ospf6_lsdb_set_key (&key, &adv_router, sizeof (adv_router));
  326.   node = lsdb->table->top;
  327.   /* Walk down tree. */
  328.   while (node && node->p.prefixlen <= key.prefixlen &&
  329.  prefix_match (&node->p, (struct prefix *) &key))
  330.     node = node->link[CHECK_BIT(&key.prefix, node->p.prefixlen)];
  331.   if (node)
  332.     route_lock_node (node);
  333.   while (node && node->info == NULL)
  334.     node = route_next (node);
  335.   if (node == NULL)
  336.     return NULL;
  337.   else
  338.     route_unlock_node (node);
  339.   if (! prefix_match ((struct prefix *) &key, &node->p))
  340.     return NULL;
  341.   lsa = node->info;
  342.   ospf6_lsa_lock (lsa);
  343.   return lsa;
  344. }
  345. struct ospf6_lsa *
  346. ospf6_lsdb_type_router_next (u_int16_t type, u_int32_t adv_router,
  347.                              struct ospf6_lsa *lsa)
  348. {
  349.   struct ospf6_lsa *next = lsa->next;
  350.   if (next)
  351.     {
  352.       if (next->header->type != type ||
  353.           next->header->adv_router != adv_router)
  354.         next = NULL;
  355.     }
  356.   if (next)
  357.     ospf6_lsa_lock (next);
  358.   ospf6_lsa_unlock (lsa);
  359.   return next;
  360. }
  361. struct ospf6_lsa *
  362. ospf6_lsdb_type_head (u_int16_t type, struct ospf6_lsdb *lsdb)
  363. {
  364.   struct route_node *node;
  365.   struct prefix_ipv6 key;
  366.   struct ospf6_lsa *lsa;
  367.   memset (&key, 0, sizeof (key));
  368.   ospf6_lsdb_set_key (&key, &type, sizeof (type));
  369.   /* Walk down tree. */
  370.   node = lsdb->table->top;
  371.   while (node && node->p.prefixlen <= key.prefixlen &&
  372.  prefix_match (&node->p, (struct prefix *) &key))
  373.     node = node->link[CHECK_BIT(&key.prefix, node->p.prefixlen)];
  374.   if (node)
  375.     route_lock_node (node);
  376.   while (node && node->info == NULL)
  377.     node = route_next (node);
  378.   if (node == NULL)
  379.     return NULL;
  380.   else
  381.     route_unlock_node (node);
  382.   if (! prefix_match ((struct prefix *) &key, &node->p))
  383.     return NULL;
  384.   lsa = node->info;
  385.   ospf6_lsa_lock (lsa);
  386.   return lsa;
  387. }
  388. struct ospf6_lsa *
  389. ospf6_lsdb_type_next (u_int16_t type, struct ospf6_lsa *lsa)
  390. {
  391.   struct ospf6_lsa *next = lsa->next;
  392.   if (next)
  393.     {
  394.       if (next->header->type != type)
  395.         next = NULL;
  396.     }
  397.   if (next)
  398.     ospf6_lsa_lock (next);
  399.   ospf6_lsa_unlock (lsa);
  400.   return next;
  401. }
  402. void
  403. ospf6_lsdb_remove_all (struct ospf6_lsdb *lsdb)
  404. {
  405.   struct ospf6_lsa *lsa;
  406.   for (lsa = ospf6_lsdb_head (lsdb); lsa; lsa = ospf6_lsdb_next (lsa))
  407.     ospf6_lsdb_remove (lsa, lsdb);
  408. }
  409. void
  410. ospf6_lsdb_show (struct vty *vty, int level,
  411.                  u_int16_t *type, u_int32_t *id, u_int32_t *adv_router,
  412.                  struct ospf6_lsdb *lsdb)
  413. {
  414.   struct ospf6_lsa *lsa;
  415.   void (*showfunc) (struct vty *, struct ospf6_lsa *) = NULL;
  416.   if (level == OSPF6_LSDB_SHOW_LEVEL_NORMAL)
  417.     showfunc = ospf6_lsa_show_summary;
  418.   else if (level == OSPF6_LSDB_SHOW_LEVEL_DETAIL)
  419.     showfunc = ospf6_lsa_show;
  420.   else if (level == OSPF6_LSDB_SHOW_LEVEL_INTERNAL)
  421.     showfunc = ospf6_lsa_show_internal;
  422.   else if (level == OSPF6_LSDB_SHOW_LEVEL_DUMP)
  423.     showfunc = ospf6_lsa_show_dump;
  424.   if (type && id && adv_router)
  425.     {
  426.       lsa = ospf6_lsdb_lookup (*type, *id, *adv_router, lsdb);
  427.       if (lsa)
  428.         {
  429.           if (level == OSPF6_LSDB_SHOW_LEVEL_NORMAL)
  430.             ospf6_lsa_show (vty, lsa);
  431.           else
  432.             (*showfunc) (vty, lsa);
  433.         }
  434.       return;
  435.     }
  436.   if (level == OSPF6_LSDB_SHOW_LEVEL_NORMAL)
  437.     ospf6_lsa_show_summary_header (vty);
  438.   if (type && adv_router)
  439.     lsa = ospf6_lsdb_type_router_head (*type, *adv_router, lsdb);
  440.   else if (type)
  441.     lsa = ospf6_lsdb_type_head (*type, lsdb);
  442.   else
  443.     lsa = ospf6_lsdb_head (lsdb);
  444.   while (lsa)
  445.     {
  446.       if ((! adv_router || lsa->header->adv_router == *adv_router) &&
  447.           (! id || lsa->header->id == *id))
  448.         (*showfunc) (vty, lsa);
  449.       if (type && adv_router)
  450.         lsa = ospf6_lsdb_type_router_next (*type, *adv_router, lsa);
  451.       else if (type)
  452.         lsa = ospf6_lsdb_type_next (*type, lsa);
  453.       else
  454.         lsa = ospf6_lsdb_next (lsa);
  455.     }
  456. }
  457. /* Decide new Link State ID to originate.
  458.    note return value is network byte order */
  459. u_int32_t
  460. ospf6_new_ls_id (u_int16_t type, u_int32_t adv_router,
  461.                  struct ospf6_lsdb *lsdb)
  462. {
  463.   struct ospf6_lsa *lsa;
  464.   u_int32_t id = 1;
  465.   for (lsa = ospf6_lsdb_type_router_head (type, adv_router, lsdb); lsa;
  466.        lsa = ospf6_lsdb_type_router_next (type, adv_router, lsa))
  467.     {
  468.       if (ntohl (lsa->header->id) < id)
  469.         continue;
  470.       if (ntohl (lsa->header->id) > id)
  471.         break;
  472.       id++;
  473.     }
  474.   return ((u_int32_t) htonl (id));
  475. }
  476. /* Decide new LS sequence number to originate.
  477.    note return value is network byte order */
  478. u_int32_t
  479. ospf6_new_ls_seqnum (u_int16_t type, u_int32_t id, u_int32_t adv_router,
  480.                      struct ospf6_lsdb *lsdb)
  481. {
  482.   struct ospf6_lsa *lsa;
  483.   signed long seqnum = 0;
  484.   /* if current database copy not found, return InitialSequenceNumber */
  485.   lsa = ospf6_lsdb_lookup (type, id, adv_router, lsdb);
  486.   if (lsa == NULL)
  487.     seqnum = INITIAL_SEQUENCE_NUMBER;
  488.   else
  489.     seqnum = (signed long) ntohl (lsa->header->seqnum) + 1;
  490.   return ((u_int32_t) htonl (seqnum));
  491. }