Browse Source

Ospf6d merge from Zebra repository with added privs stuff and merged
zclient changes.

hasso 17 years ago
parent
commit
508e53e2ee
59 changed files with 10719 additions and 15152 deletions
  1. 0 1
      ospf6d/.cvsignore
  2. 10 18
      ospf6d/ChangeLog
  3. 8 14
      ospf6d/Makefile.am
  4. 8 0
      ospf6d/README
  5. 0 655
      ospf6d/ospf6_abr.c
  6. 0 56
      ospf6d/ospf6_abr.h
  7. 732 196
      ospf6d/ospf6_area.c
  8. 28 42
      ospf6d/ospf6_area.h
  9. 965 748
      ospf6d/ospf6_asbr.c
  10. 23 49
      ospf6d/ospf6_asbr.h
  11. 0 436
      ospf6d/ospf6_bintree.c
  12. 0 47
      ospf6d/ospf6_bintree.h
  13. 0 748
      ospf6d/ospf6_damp.c
  14. 0 109
      ospf6d/ospf6_damp.h
  15. 0 704
      ospf6d/ospf6_dbex.c
  16. 0 59
      ospf6d/ospf6_dbex.h
  17. 0 315
      ospf6d/ospf6_dump.c
  18. 0 95
      ospf6d/ospf6_dump.h
  19. 0 174
      ospf6d/ospf6_hook.c
  20. 0 87
      ospf6d/ospf6_hook.h
  21. 604 268
      ospf6d/ospf6_interface.c
  22. 60 61
      ospf6d/ospf6_interface.h
  23. 1206 654
      ospf6d/ospf6_intra.c
  24. 126 4
      ospf6d/ospf6_intra.h
  25. 0 519
      ospf6d/ospf6_ism.c
  26. 0 53
      ospf6d/ospf6_ism.h
  27. 0 193
      ospf6d/ospf6_linklist.c
  28. 0 35
      ospf6d/ospf6_linklist.h
  29. 295 433
      ospf6d/ospf6_lsa.c
  30. 170 340
      ospf6d/ospf6_lsa.h
  31. 264 579
      ospf6d/ospf6_lsdb.c
  32. 123 41
      ospf6d/ospf6_lsdb.h
  33. 36 82
      ospf6d/ospf6_main.c
  34. 1638 1536
      ospf6d/ospf6_message.c
  35. 65 127
      ospf6d/ospf6_message.h
  36. 631 386
      ospf6d/ospf6_neighbor.c
  37. 73 96
      ospf6d/ospf6_neighbor.h
  38. 93 269
      ospf6d/ospf6_network.c
  39. 15 23
      ospf6d/ospf6_network.h
  40. 0 391
      ospf6d/ospf6_nsm.c
  41. 0 67
      ospf6d/ospf6_nsm.h
  42. 0 213
      ospf6d/ospf6_prefix.c
  43. 0 83
      ospf6d/ospf6_prefix.h
  44. 54 12
      ospf6d/ospf6_proto.c
  45. 69 23
      ospf6d/ospf6_proto.h
  46. 896 895
      ospf6d/ospf6_route.c
  47. 173 121
      ospf6d/ospf6_route.h
  48. 0 385
      ospf6d/ospf6_routemap.c
  49. 0 27
      ospf6d/ospf6_routemap.h
  50. 438 1248
      ospf6d/ospf6_spf.c
  51. 38 50
      ospf6d/ospf6_spf.h
  52. 444 252
      ospf6d/ospf6_top.c
  53. 19 42
      ospf6d/ospf6_top.h
  54. 0 43
      ospf6d/ospf6_types.h
  55. 265 325
      ospf6d/ospf6_zebra.c
  56. 21 14
      ospf6d/ospf6_zebra.h
  57. 1052 572
      ospf6d/ospf6d.c
  58. 24 26
      ospf6d/ospf6d.conf.sample
  59. 53 111
      ospf6d/ospf6d.h

+ 0 - 1
ospf6d/.cvsignore

@@ -1,5 +1,4 @@
 Makefile
-Makefile.in
 *.o
 *.patch
 ospf6d

+ 10 - 18
ospf6d/ChangeLog

@@ -1,20 +1,17 @@
-2004-05-08 Paul Jakma <paul@dishone.st>
+2004-05-18  Hasso Tepper <hasso@estpak.ee>
 
-	* ospf6_zebra.c: Sync to zclient changes
-	
-2003-08-11  Taisuke Sasaki <sasaki@soft.net.fujitsu.co.jp>
+	* *.*: Merge rewritten ospf6d from Zebra repository.
+	* ospf6_network.c, ospf6_main.c: Merged privs stuff back in.
+	* ospf6_zebra.c: Sync back to zclient changes.
 
-	* ospf6_ism.c: DR Election bug fix.
-	
-2003-05-18 Hasso Tepper <hasso@estpak.ee>
+2003-08-18  Yasuhiro Ohara  <yasu@sfc.wide.ad.jp>
 
-	* ospf6_{dump,interface,zebra}.c,ospf6d.c: show router and interface
-	nodes from ospf6d when using vtysh,  and don't show defaults in
-	interface node (from ^WIND patch).
+	* *.[ch]: rewrite all source code from scratch
+	* ospf6d.h: version 0.9.7
 
-2003-04-23 Hasso Tepper <hasso@estpak.ee>
-          
-        * {ospf6_damp,ospf6d}.c: fix "router xxx" node commands in vtysh
+2003-08-11  Taisuke Sasaki <sasaki@soft.net.fujitsu.co.jp>
+
+        * ospf6_ism.c: DR Election bug fix.
 
 2003-04-25  Yasuhiro Ohara  <yasu@sfc.wide.ad.jp>
 
@@ -22,11 +19,6 @@
 	prefix of the obsolete LSA. It was wrong so fixed.
 	* version: 0.9.6p
 
-2003-04-19 Hasso Tepper <hasso@estpak.ee>
-
-	* rip_routemap.c: sync daemon's route-map commands to have same
-        syntax
-
 2002-11-09  Vincent Jardin  <jardin@6wind.com>
 
 	* ospf6_interface.c: update link-local address on interface creation.

+ 8 - 14
ospf6d/Makefile.am

@@ -8,22 +8,16 @@ noinst_LIBRARIES = libospf6.a
 sbin_PROGRAMS = ospf6d
 
 libospf6_a_SOURCES = \
-	ospf6_dump.c ospf6d.c ospf6_interface.c ospf6_network.c \
-	ospf6_neighbor.c ospf6_message.c ospf6_lsa.c ospf6_spf.c \
-	ospf6_route.c ospf6_zebra.c ospf6_ism.c ospf6_dbex.c \
-	ospf6_lsdb.c ospf6_prefix.c ospf6_top.c ospf6_area.c ospf6_nsm.c \
-	ospf6_routemap.c ospf6_proto.c \
-	ospf6_hook.c ospf6_asbr.c ospf6_bintree.c ospf6_linklist.c \
-	ospf6_abr.c ospf6_intra.c ospf6_damp.c
+	ospf6_network.c ospf6_message.c ospf6_lsa.c ospf6_lsdb.c \
+	ospf6_top.c ospf6_area.c ospf6_interface.c ospf6_neighbor.c \
+	ospf6_flood.c ospf6_route.c ospf6_intra.c ospf6_zebra.c \
+	ospf6_spf.c ospf6_proto.c ospf6_asbr.c ospf6d.c
 
 noinst_HEADERS = \
-	ospf6_area.h ospf6_dump.h ospf6_interface.h ospf6_lsa.h \
-	ospf6_message.h ospf6_neighbor.h ospf6_network.h ospf6_proto.h \
-	ospf6_spf.h ospf6_route.h ospf6_types.h ospf6_zebra.h ospf6d.h \
-	ospf6_ism.h ospf6_dbex.h ospf6_lsdb.h ospf6_prefix.h \
-	ospf6_top.h ospf6_nsm.h ospf6_routemap.h \
-        ospf6_hook.h ospf6_asbr.h ospf6_bintree.h ospf6_linklist.h \
-	ospf6_abr.h ospf6_intra.h ospf6_damp.h
+	ospf6_network.h ospf6_message.h ospf6_lsa.h ospf6_lsdb.h \
+	ospf6_top.h ospf6_area.h ospf6_interface.h ospf6_neighbor.h \
+	ospf6_flood.h ospf6_route.h ospf6_intra.h ospf6_zebra.h \
+	ospf6_spf.h ospf6_proto.h ospf6_asbr.h ospf6d.h
 
 ospf6d_SOURCES = \
 	ospf6_main.c $(libospf6_a_SOURCES)

+ 8 - 0
ospf6d/README

@@ -1,6 +1,14 @@
 
 		  Zebra OSPF daemon for IPv6 network
 
+			     2003/08/18
+
+README for newer code is not yet. General usage should remain
+the same. For further usage, see command helps by typing '?'
+in vty, and then imagin ! ;p) Previous README contents follows.
+
+		  Zebra OSPF daemon for IPv6 network
+
 			     2001/12/20
 
 Zebra OSPF6d is OSPF version 3 daemon which is specified by

+ 0 - 655
ospf6d/ospf6_abr.c

@@ -1,655 +0,0 @@
-/*
- * Copyright (C) 2001 Yasuhiro Ohara
- *
- * This file is part of GNU Zebra.
- *
- * GNU Zebra is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2, or (at your option) any
- * later version.
- *
- * GNU Zebra is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GNU Zebra; see the file COPYING.  If not, write to the 
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330, 
- * Boston, MA 02111-1307, USA.  
- */
-
-#include "ospf6d.h"
-
-#include "ospf6_dump.h"
-#include "ospf6_abr.h"
-
-static int abr_index;
-#define IS_OSPF6_DUMP_ABR (ospf6_dump_is_on (abr_index))
-
-#define ADD    0
-#define CHANGE 1
-#define REMOVE 2
-
-/* Inter-Area-Prefix-LSA Calculation */
-
-static struct ospf6_route_req *
-ospf6_abr_entry_lookup (struct ospf6_route_req *abr_entry,
-                        u_int32_t router_id, struct ospf6_area *area)
-{
-  struct prefix_ls abr_id;
-  char router_string[32];
-
-  inet_ntop (AF_INET, &router_id, router_string, sizeof (router_string));
-
-  //zlog_info ("ABR:   Finding router %s in area %s", router_string, area->str);
-
-  memset (&abr_id, 0, sizeof (abr_id));
-  abr_id.family = AF_UNSPEC;
-  abr_id.prefixlen = 64; /* xxx */
-  abr_id.id.s_addr = htonl (0);
-  abr_id.adv_router.s_addr = router_id;
-
-  ospf6_route_lookup (abr_entry, (struct prefix *) &abr_id,
-                      area->table_topology);
-
-  if (ospf6_route_end (abr_entry))
-    {
-      if (IS_OSPF6_DUMP_ABR)
-        zlog_info ("ABR:   Router %s not found in area %s",
-                   router_string, area->str);
-      return NULL;
-    }
-
-  if (abr_entry->path.area_id != area->area_id)
-    {
-      if (IS_OSPF6_DUMP_ABR)
-        zlog_info ("ABR: ABR area id mismatch");
-      return NULL;
-    }
-
-  if (! CHECK_FLAG (abr_entry->path.router_bits, OSPF6_ROUTER_LSA_BIT_B))
-    {
-      if (IS_OSPF6_DUMP_ABR)
-        zlog_info ("ABR: ABR entry's B bit off");
-      return NULL;
-    }
-
-  return abr_entry;
-}
-
-static int
-ospf6_abr_prefix_lsa_to_route (struct ospf6_lsa *lsa,
-                               struct ospf6_route_req *request)
-{
-  struct ospf6_inter_area_prefix_lsa *iep;
-  struct ospf6_route_req abr_entry;
-
-  if (lsa->header->type != htons (OSPF6_LSA_TYPE_INTER_PREFIX))
-    {
-      if (IS_OSPF6_DUMP_ABR)
-        zlog_info ("ABR: LSA type mismatch");
-      return -1;
-    }
-
-  if (IS_LSA_MAXAGE (lsa))
-    {
-      if (IS_OSPF6_DUMP_ABR)
-        zlog_info ("ABR: LSA MaxAge");
-      return -1;
-    }
-
-  if (! ospf6_abr_entry_lookup (&abr_entry, lsa->header->adv_router,
-                                (struct ospf6_area *) lsa->scope))
-    {
-      if (IS_OSPF6_DUMP_ABR)
-        zlog_info ("ABR: ABR check failed");
-      return -1;
-    }
-
-  iep = OSPF6_LSA_HEADER_END (lsa->header);
-
-  memset (request, 0, sizeof (struct ospf6_route_req));
-  request->route.type = OSPF6_DEST_TYPE_NETWORK;
-  request->route.prefix.family = AF_INET6;
-  request->route.prefix.prefixlen = iep->prefix.prefix_length;
-  ospf6_prefix_in6_addr (&iep->prefix, &request->route.prefix.u.prefix6);
-
-  request->path.cost = abr_entry.path.cost +
-                      (ntohl (iep->metric) & ntohl (0x000fffff));
-  request->path.type = OSPF6_PATH_TYPE_INTER;
-  request->path.origin.type = lsa->header->type;
-  request->path.origin.id = lsa->header->id;
-  request->path.origin.adv_router = lsa->header->adv_router;
-  memcpy (&request->nexthop.address, &abr_entry.nexthop.address,
-          sizeof (request->nexthop.address));
-  request->nexthop.ifindex = abr_entry.nexthop.ifindex;
-
-  return 0;
-}
-
-void
-ospf6_abr_prefix_lsa_add (struct ospf6_lsa *lsa)
-{
-  struct ospf6_route_req request;
-  int ret;
-
-  if (IS_OSPF6_DUMP_ABR)
-    zlog_info ("ABR: Calculate %s", lsa->str);
-
-  ret = ospf6_abr_prefix_lsa_to_route (lsa, &request);
-  if (ret < 0)
-    return;
-
-  if (IS_OSPF6_DUMP_ABR)
-    zlog_info ("ABR: Inter Area Route add for %s", lsa->str);
-
-  ospf6_route_add (&request, ospf6->route_table);
-}
-
-void
-ospf6_abr_prefix_lsa_remove (struct ospf6_lsa *lsa)
-{
-  struct ospf6_inter_area_prefix_lsa *iep;
-  struct prefix_ipv6 prefix6;
-  struct ospf6_route_req request;
-
-  iep = OSPF6_LSA_HEADER_END (lsa->header);
-
-  prefix6.family = AF_INET6;
-  prefix6.prefixlen = iep->prefix.prefix_length;
-  ospf6_prefix_in6_addr (&iep->prefix, &prefix6.prefix);
-
-  if (IS_OSPF6_DUMP_ABR)
-    zlog_info ("ABR: Inter Area Route remove for %s", lsa->str);
-
-  for (ospf6_route_lookup (&request, (struct prefix *) &prefix6,
-                           ospf6->route_table);
-       ! ospf6_route_end (&request);
-       ospf6_route_next (&request))
-   {
-     if (memcmp (&prefix6, &request.route.prefix, sizeof (prefix6)))
-       break;
-     if (request.path.origin.type != htons (OSPF6_LSA_TYPE_INTER_PREFIX) ||
-         request.path.origin.adv_router != lsa->header->adv_router ||
-         request.path.origin.id != lsa->header->id)
-       continue;
-
-     ospf6_route_remove (&request, ospf6->route_table);
-   }
-}
-
-static int
-ospf6_abr_router_lsa_to_route (struct ospf6_lsa *lsa,
-                               struct ospf6_route_req *request)
-{
-  struct ospf6_inter_area_router_lsa *ier;
-  struct ospf6_route_req abr_entry;
-
-  if (lsa->header->type != htons (OSPF6_LSA_TYPE_INTER_ROUTER))
-    {
-      if (IS_OSPF6_DUMP_ABR)
-        zlog_info ("ABR: LSA type mismatch");
-      return -1;
-    }
-
-  if (IS_LSA_MAXAGE (lsa))
-    {
-      if (IS_OSPF6_DUMP_ABR)
-        zlog_info ("ABR: LSA MaxAge");
-      return -1;
-    }
-
-  if (! ospf6_abr_entry_lookup (&abr_entry, lsa->header->adv_router,
-                                (struct ospf6_area *) lsa->scope))
-    {
-      if (IS_OSPF6_DUMP_ABR)
-        zlog_info ("ABR: Advertising router check failed");
-      return -1;
-    }
-
-  ier = OSPF6_LSA_HEADER_END (lsa->header);
-
-  memset (request, 0, sizeof (struct ospf6_route_req));
-  request->route.type = OSPF6_DEST_TYPE_ROUTER;
-  request->route.prefix.family = AF_UNSPEC;
-  request->route.prefix.prefixlen = 64; /* XXX */
-  ((struct prefix_ls *) &request->route.prefix)->adv_router.s_addr
-    = ier->router_id;
-
-  request->path.cost = abr_entry.path.cost +
-                      (ntohl (ier->metric & htonl (0x000fffff)));
-  request->path.type = OSPF6_PATH_TYPE_INTER;
-  request->path.origin.type = lsa->header->type;
-  request->path.origin.id = lsa->header->id;
-  request->path.origin.adv_router = lsa->header->adv_router;
-  SET_FLAG (request->path.router_bits, OSPF6_ROUTER_LSA_BIT_E);
-  request->path.capability[0] = ier->options[0];
-  request->path.capability[1] = ier->options[1];
-  request->path.capability[2] = ier->options[2];
-
-  memcpy (&request->nexthop.address, &abr_entry.nexthop.address,
-          sizeof (request->nexthop.address));
-  request->nexthop.ifindex = abr_entry.nexthop.ifindex;
-
-  return 0;
-}
-
-void
-ospf6_abr_router_lsa_add (struct ospf6_lsa *lsa)
-{
-  struct ospf6_route_req request;
-  int ret;
-
-  if (IS_OSPF6_DUMP_ABR)
-    zlog_info ("ABR: Calculate %s", lsa->str);
-
-  ret = ospf6_abr_router_lsa_to_route (lsa, &request);
-  if (ret < 0)
-    return;
-
-  if (IS_OSPF6_DUMP_ABR)
-    zlog_info ("ABR: Inter Area Router add for %s", lsa->str);
-
-  ospf6_route_add (&request, ospf6->topology_table);
-}
-
-void
-ospf6_abr_router_lsa_remove (struct ospf6_lsa *lsa)
-{
-  struct ospf6_inter_area_router_lsa *ier;
-  struct prefix_ls prefix_ls;
-  struct ospf6_route_req request;
-
-  ier = OSPF6_LSA_HEADER_END (lsa->header);
-
-  memset (&prefix_ls, 0, sizeof (prefix_ls));
-  prefix_ls.family = AF_INET6;
-  prefix_ls.prefixlen = 64; /* XXX */
-  prefix_ls.adv_router.s_addr = ier->router_id;
-
-  if (IS_OSPF6_DUMP_ABR)
-    zlog_info ("ABR: Inter Area Route remove for %s", lsa->str);
-
-  for (ospf6_route_lookup (&request, (struct prefix *) &prefix_ls,
-                           ospf6->route_table);
-       ! ospf6_route_end (&request);
-       ospf6_route_next (&request))
-   {
-     if (memcmp (&prefix_ls, &request.route.prefix, sizeof (prefix_ls)))
-       break;
-     if (request.path.origin.type != htons (OSPF6_LSA_TYPE_INTER_ROUTER) ||
-         request.path.origin.adv_router != lsa->header->adv_router ||
-         request.path.origin.id != lsa->header->id)
-       continue;
-
-     ospf6_route_remove (&request, ospf6->route_table);
-   }
-}
-
-
-void
-ospf6_abr_abr_entry_add (struct ospf6_route_req *abr_entry)
-{
-  struct ospf6_lsdb_node node;
-  struct prefix_ls *abr_id;
-  struct ospf6_route_req request;
-  struct ospf6_area *area;
-
-  if (IS_OSPF6_DUMP_ABR)
-    zlog_info ("ABR: New Area Border Router found");
-
-  area = ospf6_area_lookup (abr_entry->path.area_id, ospf6);
-  if (! area)
-    {
-      if (IS_OSPF6_DUMP_ABR)
-        zlog_info ("ABR: Can't find associated area");
-      return;
-    }
-
-  abr_id = (struct prefix_ls *) &abr_entry->route.prefix;
-  if (! ospf6_abr_entry_lookup (&request, abr_id->adv_router.s_addr, area))
-    {
-      if (IS_OSPF6_DUMP_ABR)
-        zlog_info ("ABR: back check failed");
-      return;
-    }
-
-  /* for each inter-prefix LSA this ABR originated */
-  for (ospf6_lsdb_type_router (&node, htons (OSPF6_LSA_TYPE_INTER_PREFIX),
-                               abr_id->adv_router.s_addr, area->lsdb);
-       ! ospf6_lsdb_is_end (&node);
-       ospf6_lsdb_next (&node))
-    ospf6_abr_prefix_lsa_add (node.lsa);
-
-  /* for each inter-router LSA this ABR originated */
-  for (ospf6_lsdb_type_router (&node, htons (OSPF6_LSA_TYPE_INTER_ROUTER),
-                               abr_id->adv_router.s_addr, area->lsdb);
-       ! ospf6_lsdb_is_end (&node);
-       ospf6_lsdb_next (&node))
-    ospf6_abr_router_lsa_add (node.lsa);
-}
-
-void
-ospf6_abr_abr_entry_remove (struct ospf6_route_req *abr_entry)
-{
-  struct ospf6_lsdb_node node;
-  struct prefix_ls *abr_id;
-  struct ospf6_area *area;
-
-  if (IS_OSPF6_DUMP_ABR)
-    zlog_info ("ABR: Area Border Router removed");
-
-  abr_id = (struct prefix_ls *) &abr_entry->route.prefix;
-
-  area = ospf6_area_lookup (abr_entry->path.area_id, ospf6);
-  if (! area)
-    {
-      if (IS_OSPF6_DUMP_ABR)
-        zlog_info ("ABR: Can't find associated area");
-      return;
-    }
-
-  /* for each inter-prefix LSA this ABR originated */
-  for (ospf6_lsdb_type_router (&node, htons (OSPF6_LSA_TYPE_INTER_PREFIX),
-                               abr_id->adv_router.s_addr, area->lsdb);
-       ! ospf6_lsdb_is_end (&node);
-       ospf6_lsdb_next (&node))
-    ospf6_abr_prefix_lsa_remove (node.lsa);
-
-  /* for each inter-router LSA this ABR originated */
-  for (ospf6_lsdb_type_router (&node, htons (OSPF6_LSA_TYPE_INTER_ROUTER),
-                               abr_id->adv_router.s_addr, area->lsdb);
-       ! ospf6_lsdb_is_end (&node);
-       ospf6_lsdb_next (&node))
-    ospf6_abr_router_lsa_remove (node.lsa);
-}
-
-/* Inter-Area-Prefix-LSA Origination */
-
-static void
-ospf6_abr_prefix_lsa_update_add (struct ospf6_route_req *request,
-                                 struct ospf6_area *area)
-{
-  char buffer [MAXLSASIZE];
-  u_int16_t size;
-  struct ospf6_inter_area_prefix_lsa *iep;
-  char *p;
-
-  if (IS_OSPF6_DUMP_ABR)
-    zlog_info ("Update Inter-Prefix for %s: ID: %lu",
-               area->str, (u_long) ntohl (request->route_id));
-
-  /* prepare buffer */
-  memset (buffer, 0, sizeof (buffer));
-  size = sizeof (struct ospf6_inter_area_prefix_lsa);
-  iep = (struct ospf6_inter_area_prefix_lsa *) buffer;
-  p = (char *) (iep + 1);
-
-  /* prefixlen */
-  iep->prefix.prefix_length = request->route.prefix.prefixlen;
-
-  /* PrefixOptions */
-  iep->prefix.prefix_options = request->path.prefix_options;
-
-  /* set Prefix */
-  memcpy (p, &request->route.prefix.u.prefix6,
-          OSPF6_PREFIX_SPACE (request->route.prefix.prefixlen));
-  ospf6_prefix_apply_mask (&iep->prefix);
-  size += OSPF6_PREFIX_SPACE (request->route.prefix.prefixlen);
-
-  ospf6_lsa_originate (htons (OSPF6_LSA_TYPE_INTER_PREFIX),
-                       htonl (request->route_id), ospf6->router_id,
-                       (char *) iep, size, area);
-}
-
-static void
-ospf6_abr_prefix_lsa_update_remove (struct ospf6_route_req *request,
-                                    struct ospf6_area *area)
-{
-  struct ospf6_lsa *lsa;
-  lsa = ospf6_lsdb_lookup_lsdb (htons (OSPF6_LSA_TYPE_INTER_PREFIX),
-                                htonl (request->route_id),
-                                ospf6->router_id, area->lsdb);
-  if (lsa)
-    ospf6_lsa_premature_aging (lsa);
-}
-
-static void
-ospf6_abr_prefix_lsa_update (int type, struct ospf6_route_req *request)
-{
-  struct ospf6_route_req route, target;
-  listnode node;
-  struct ospf6_area *area;
-  struct ospf6_interface *o6i;
-
-  if (request->route.type != OSPF6_DEST_TYPE_NETWORK)
-    return;
-
-  /* assert this is best path; if not, return */
-  ospf6_route_lookup (&route, &request->route.prefix, request->table);
-  if (memcmp (&route.path, &request->path, sizeof (route.path)))
-    return;
-
-  if (target.path.cost >= LS_INFINITY ||
-      target.path.cost_e2 >= LS_INFINITY)
-    {
-      if (IS_OSPF6_DUMP_ABR)
-        zlog_info ("ABR: Exceeds LS Infinity, ignore");
-      return;
-    }
-
-  ospf6_route_lookup (&target, &request->route.prefix, request->table);
-  if (type == REMOVE)
-    {
-      ospf6_route_next (&route);
-      if (! memcmp (&route.route, &request->route, sizeof (route.route)))
-        {
-          type = ADD;
-          ospf6_route_next (&target);
-        }
-    }
-
-  for (node = listhead (ospf6->area_list); node; nextnode (node))
-    {
-      area = getdata (node);
-
-      if (target.path.area_id == area->area_id)
-        continue;
-
-      o6i = ospf6_interface_lookup_by_index (target.nexthop.ifindex);
-      if (o6i && o6i->area && o6i->area->area_id == area->area_id)
-        {
-          zlog_info ("ABR: Logical equivalent of split horizon, skip for %s",
-                     area->str);
-          continue;
-        }
-
-      if (area->area_id == ntohs (0) && /* Backbone */
-          target.path.type != OSPF6_PATH_TYPE_INTRA)
-        continue;
-
-      /* XXX, stub area check */
-
-      /* XXX, aggregate */
-        /* if either the area of the route or the area trying to
-           advertise is backbone, do not aggregate */
-
-      if (type == ADD)
-        ospf6_abr_prefix_lsa_update_add (&target, area);
-      else
-        ospf6_abr_prefix_lsa_update_remove (&target, area);
-    }
-}
-
-void
-ospf6_abr_route_add (struct ospf6_route_req *request)
-{
-  ospf6_abr_prefix_lsa_update (ADD, request);
-}
-
-void
-ospf6_abr_route_remove (struct ospf6_route_req *request)
-{
-  ospf6_abr_prefix_lsa_update (REMOVE, request);
-}
-
-int
-ospf6_abr_prefix_lsa_refresh (void *data)
-{
-  struct ospf6_lsa *lsa = data;
-  struct ospf6_inter_area_prefix_lsa *ier;
-  struct prefix_ipv6 prefix6;
-  struct ospf6_route_req route;
-
-  ier = OSPF6_LSA_HEADER_END (lsa->header);
-  memset (&prefix6, 0, sizeof (prefix6));
-  prefix6.family = AF_INET6;
-  prefix6.prefixlen = ier->prefix.prefix_length;
-  ospf6_prefix_in6_addr (&ier->prefix, &prefix6.prefix);
-
-  ospf6_route_lookup (&route, (struct prefix *) &prefix6,
-                      ospf6->route_table);
-  assert (! ospf6_route_end (&route));
-
-  ospf6_abr_prefix_lsa_update (ADD, &route);
-  return 0;
-}
-
-int
-ospf6_abr_prefix_lsa_show (struct vty *vty, struct ospf6_lsa *lsa)
-{
-  struct ospf6_inter_area_prefix_lsa *ier;
-  char prefix[128];
-
-  assert (lsa->header);
-  ier = OSPF6_LSA_HEADER_END (lsa->header);
-
-  ospf6_prefix_string (&ier->prefix, prefix, sizeof (prefix));
-
-  vty_out (vty, "     Metric: %d%s",
-           ntohl (ier->metric & htonl (0x000fffff)), VTY_NEWLINE);
-  vty_out (vty, "     Prefix: %s%s", prefix, VTY_NEWLINE);
-
-  return 0;
-}
-
-int
-ospf6_abr_prefix_lsa_hook_add (void *data)
-{
-  struct ospf6_lsa *lsa = data;
-  ospf6_abr_prefix_lsa_add (lsa);
-  return 0;
-}
-
-int
-ospf6_abr_prefix_lsa_hook_remove (void *data)
-{
-  struct ospf6_lsa *lsa = data;
-  ospf6_abr_prefix_lsa_remove (lsa);
-  return 0;
-}
-
-void
-ospf6_abr_database_hook_inter_prefix (struct ospf6_lsa *old,
-                                      struct ospf6_lsa *new)
-{
-  if (old)
-    ospf6_abr_prefix_lsa_hook_remove (old);
-  if (new && ! IS_LSA_MAXAGE (new))
-    ospf6_abr_prefix_lsa_hook_add (new);
-}
-
-void
-ospf6_abr_register_inter_prefix ()
-{
-  struct ospf6_lsa_slot slot;
-
-  memset (&slot, 0, sizeof (slot));
-  slot.type         = htons (OSPF6_LSA_TYPE_INTER_PREFIX);
-  slot.name         = "Inter-Prefix";
-  slot.func_show    = ospf6_abr_prefix_lsa_show;
-  slot.func_refresh = ospf6_abr_prefix_lsa_refresh;
-  ospf6_lsa_slot_register (&slot);
-
-  ospf6_lsdb_hook[OSPF6_LSA_TYPE_INTER_PREFIX & OSPF6_LSTYPE_CODE_MASK].hook = 
-    ospf6_abr_database_hook_inter_prefix;
-}
-
-int
-ospf6_abr_router_lsa_hook_add (void *data)
-{
-  struct ospf6_lsa *lsa = data;
-  ospf6_abr_router_lsa_add (lsa);
-  return 0;
-}
-
-int
-ospf6_abr_router_lsa_hook_remove (void *data)
-{
-  struct ospf6_lsa *lsa = data;
-  ospf6_abr_router_lsa_remove (lsa);
-  return 0;
-}
-
-int
-ospf6_abr_router_lsa_show (struct vty *vty, struct ospf6_lsa *lsa)
-{
-  return 0;
-}
-
-int
-ospf6_abr_router_lsa_refresh (void *data)
-{
-  return 0;
-}
-
-void
-ospf6_abr_database_hook_inter_router (struct ospf6_lsa *old,
-                                      struct ospf6_lsa *new)
-{
-  if (old)
-    ospf6_abr_router_lsa_hook_remove (old);
-  if (new && ! IS_LSA_MAXAGE (new))
-    ospf6_abr_router_lsa_hook_add (new);
-}
-
-void
-ospf6_abr_register_inter_router ()
-{
-  struct ospf6_lsa_slot slot;
-
-  memset (&slot, 0, sizeof (slot));
-  slot.type         = htons (OSPF6_LSA_TYPE_INTER_ROUTER);
-  slot.name         = "Inter-Router";
-  slot.func_show    = ospf6_abr_router_lsa_show;
-  slot.func_refresh = ospf6_abr_router_lsa_refresh;
-  ospf6_lsa_slot_register (&slot);
-
-  ospf6_lsdb_hook[OSPF6_LSA_TYPE_INTER_ROUTER & OSPF6_LSTYPE_CODE_MASK].hook = 
-    ospf6_abr_database_hook_inter_router;
-}
-
-void
-ospf6_abr_inter_route_calculation (struct ospf6_area *area)
-{
-  struct ospf6_lsdb_node node;
-
-  /* for each inter-prefix LSA */
-  for (ospf6_lsdb_type (&node, htons (OSPF6_LSA_TYPE_INTER_PREFIX),
-                        area->lsdb);
-       ! ospf6_lsdb_is_end (&node);
-       ospf6_lsdb_next (&node))
-    ospf6_abr_prefix_lsa_add (node.lsa);
-}
-
-void
-ospf6_abr_init ()
-{
-  abr_index = ospf6_dump_install ("abr", "Area Border Router Function\n");
-
-  ospf6_abr_register_inter_prefix ();
-  ospf6_abr_register_inter_router ();
-}
-
-

+ 0 - 56
ospf6d/ospf6_abr.h

@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 2001 Yasuhiro Ohara
- *
- * This file is part of GNU Zebra.
- *
- * GNU Zebra is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2, or (at your option) any
- * later version.
- *
- * GNU Zebra is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GNU Zebra; see the file COPYING.  If not, write to the 
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330, 
- * Boston, MA 02111-1307, USA.  
- */
-
-#ifndef OSPF6_ABR_H
-#define OSPF6_ABR_H
-
-/* Inter-Area-Prefix-LSA */
-struct ospf6_inter_area_prefix_lsa
-{
-  u_int32_t metric;           /* 12bits reserved, 20bits metric */
-  struct ospf6_prefix prefix; /* followed by one address prefix */
-};
-
-/* Inter-Area-Router-LSA */
-struct ospf6_inter_area_router_lsa
-{
-  u_char reserved;
-  u_char options[3];      /* Optional Capability */
-  u_int32_t metric;       /* 12bits reserved, 20bits metric */
-  u_int32_t router_id;    /* Destination Router ID */
-};
-
-void ospf6_abr_prefix_lsa_add (struct ospf6_lsa *);
-void ospf6_abr_prefix_lsa_remove (struct ospf6_lsa *);
-void ospf6_abr_prefix_lsa_change (struct ospf6_lsa *, struct ospf6_lsa *);
-
-void ospf6_abr_abr_entry_add (struct ospf6_route_req *);
-void ospf6_abr_abr_entry_remove (struct ospf6_route_req *);
-
-void ospf6_abr_route_add (struct ospf6_route_req *);
-void ospf6_abr_route_remove (struct ospf6_route_req *);
-
-void ospf6_abr_inter_route_calculation (struct ospf6_area *);
-
-void ospf6_abr_init ();
-
-#endif /* OSPF6_ABR_H */
-

+ 732 - 196
ospf6d/ospf6_area.c

@@ -1,6 +1,5 @@
 /*
- * OSPF6 Area Data Structure
- * Copyright (C) 1999-2002 Yasuhiro Ohara
+ * Copyright (C) 2003 Yasuhiro Ohara
  *
  * This file is part of GNU Zebra.
  *
@@ -20,313 +19,850 @@
  * Boston, MA 02111-1307, USA.  
  */
 
+#include <zebra.h>
+
+#include "log.h"
+#include "memory.h"
+#include "linklist.h"
+#include "thread.h"
+#include "vty.h"
+#include "command.h"
+#include "if.h"
+#include "prefix.h"
+#include "table.h"
+
 #include "ospf6d.h"
+#include "ospf6_proto.h"
+#include "ospf6_lsa.h"
+#include "ospf6_lsdb.h"
+#include "ospf6_route.h"
+#include "ospf6_spf.h"
+#include "ospf6_top.h"
+#include "ospf6_area.h"
+#include "ospf6_interface.h"
+#include "ospf6_intra.h"
 
-static int area_index;
-#define IS_OSPF6_DUMP_AREA (ospf6_dump_is_on (area_index))
+int
+ospf6_area_cmp (void *va, void *vb)
+{
+  struct ospf6_area *oa = (struct ospf6_area *) va;
+  struct ospf6_area *ob = (struct ospf6_area *) vb;
+  return (ntohl (oa->area_id) - ntohl (ob->area_id));
+}
 
-static void
-ospf6_area_foreach_interface (struct ospf6_area *o6a, void *arg, int val,
-                              void (*func) (void *, int, void *))
+int
+ospf6_area_is_stub (struct ospf6_area *o6a)
 {
-  listnode node;
-  struct ospf6_interface *o6i;
+  if (OSPF6_OPT_ISSET (o6a->options, OSPF6_OPT_E))
+    return 0;
+  return 1;
+}
 
-  for (node = listhead (o6a->if_list); node; nextnode (node))
+/* schedule routing table recalculation */
+void
+ospf6_area_lsdb_hook_add (struct ospf6_lsa *lsa)
+{
+  struct ospf6_area *oa;
+
+  oa = (struct ospf6_area *) lsa->scope;
+  switch (ntohs (lsa->header->type))
     {
-      o6i = (struct ospf6_interface *) getdata (node);
-      (*func) (arg, val, o6i);
+    case OSPF6_LSTYPE_ROUTER:
+    case OSPF6_LSTYPE_NETWORK:
+      ospf6_spf_schedule (oa);
+      break;
+
+    case OSPF6_LSTYPE_INTRA_PREFIX:
+      ospf6_intra_prefix_lsa_add (lsa);
+      break;
+
+    case OSPF6_LSTYPE_INTER_PREFIX:
+    case OSPF6_LSTYPE_INTER_ROUTER:
+      break;
+
+    default:
+      if (IS_OSPF6_DEBUG_LSA (RECV))
+	zlog_info ("Unknown LSA in Area %s's lsdb", oa->name);
+      break;
     }
 }
 
-static void
-ospf6_area_foreach_neighbor (struct ospf6_area *o6a, void *arg, int val,
-                             void (*func) (void *, int, void *))
+void
+ospf6_area_lsdb_hook_remove (struct ospf6_lsa *lsa)
 {
-  listnode node;
-  struct ospf6_interface *o6i;
+  struct ospf6_area *oa;
 
-  for (node = listhead (o6a->if_list); node; nextnode (node))
+  oa = (struct ospf6_area *) lsa->scope;
+  switch (ntohs (lsa->header->type))
     {
-      o6i = (struct ospf6_interface *) getdata (node);
-      (*o6i->foreach_nei) (o6i, arg, val, func);
+    case OSPF6_LSTYPE_ROUTER:
+    case OSPF6_LSTYPE_NETWORK:
+      ospf6_spf_schedule (oa);
+      break;
+
+    case OSPF6_LSTYPE_INTRA_PREFIX:
+      ospf6_intra_prefix_lsa_remove (lsa);
+      break;
+
+    case OSPF6_LSTYPE_INTER_PREFIX:
+    case OSPF6_LSTYPE_INTER_ROUTER:
+      break;
+
+    default:
+      if (IS_OSPF6_DEBUG_LSA (RECV))
+	zlog_info ("Unknown LSA in Area %s's lsdb", oa->name);
+      break;
     }
 }
 
-static int
-ospf6_area_maxage_remover (struct thread *t)
+void
+ospf6_area_route_hook_add (struct ospf6_route *route)
 {
-  int count;
-  struct ospf6_area *o6a = (struct ospf6_area *) THREAD_ARG (t);
-
-  o6a->maxage_remover = (struct thread *) NULL;
-
-  count = 0;
-  o6a->foreach_nei (o6a, &count, NBS_EXCHANGE, ospf6_count_state);
-  o6a->foreach_nei (o6a, &count, NBS_LOADING, ospf6_count_state);
-  if (count != 0)
-    return 0;
-
-  ospf6_lsdb_remove_maxage (o6a->lsdb);
-  return 0;
+  struct ospf6_route *copy = ospf6_route_copy (route);
+  ospf6_route_add (copy, ospf6->route_table);
 }
 
 void
-ospf6_area_schedule_maxage_remover (void *arg, int val, void *obj)
+ospf6_area_route_hook_remove (struct ospf6_route *route)
 {
-  struct ospf6_area *o6a = (struct ospf6_area *) obj;
+  struct ospf6_route *copy;
 
-  if (o6a->maxage_remover != NULL)
-    return;
-
-  o6a->maxage_remover =
-    thread_add_event (master, ospf6_area_maxage_remover, o6a, 0);
+  copy = ospf6_route_lookup_identical (route, ospf6->route_table);
+  if (copy)
+    ospf6_route_remove (copy, ospf6->route_table);
 }
 
-int
-ospf6_area_is_stub (struct ospf6_area *o6a)
+/* Make new area structure */
+struct ospf6_area *
+ospf6_area_create (u_int32_t area_id, struct ospf6 *o)
 {
-  if (OSPF6_OPT_ISSET (o6a->options, OSPF6_OPT_E))
-    return 0;
-  return 1;
+  struct ospf6_area *oa;
+
+  oa = XCALLOC (MTYPE_OSPF6_AREA, sizeof (struct ospf6_area));
+
+  inet_ntop (AF_INET, &area_id, oa->name, sizeof (oa->name));
+  oa->area_id = area_id;
+  oa->if_list = list_new ();
+
+  oa->lsdb = ospf6_lsdb_create ();
+  oa->lsdb->hook_add = ospf6_area_lsdb_hook_add;
+  oa->lsdb->hook_remove = ospf6_area_lsdb_hook_remove;
+
+  oa->spf_table = ospf6_route_table_create ();
+  oa->route_table = ospf6_route_table_create ();
+  oa->route_table->hook_add = ospf6_area_route_hook_add;
+  oa->route_table->hook_remove = ospf6_area_route_hook_remove;
+
+  /* set default options */
+  OSPF6_OPT_SET (oa->options, OSPF6_OPT_V6);
+  OSPF6_OPT_SET (oa->options, OSPF6_OPT_E);
+  OSPF6_OPT_SET (oa->options, OSPF6_OPT_R);
+
+  oa->ospf6 = o;
+  listnode_add_sort (o->area_list, oa);
+
+  return oa;
 }
 
-int
-ospf6_area_is_transit (struct ospf6_area *o6a)
+void
+ospf6_area_delete (struct ospf6_area *oa)
 {
-  return 0;
-}
+  listnode n;
+  struct ospf6_interface *oi;
 
-
+  /* ospf6 interface list */
+  for (n = listhead (oa->if_list); n; nextnode (n))
+    {
+      oi = (struct ospf6_interface *) getdata (n);
+      ospf6_interface_delete (oi);
+    }
+  list_delete (oa->if_list);
 
-void
-ospf6_area_route_add (void *data)
+  ospf6_lsdb_delete (oa->lsdb);
+  ospf6_route_table_delete (oa->spf_table);
+  ospf6_route_table_delete (oa->route_table);
+
+#if 0
+  ospf6_spftree_delete (oa->spf_tree);
+  ospf6_route_table_delete (oa->topology_table);
+#endif /*0*/
+
+  THREAD_OFF (oa->thread_spf_calculation);
+  THREAD_OFF (oa->thread_route_calculation);
+
+  listnode_delete (oa->ospf6->area_list, oa);
+  oa->ospf6 = NULL;
+
+  /* free area */
+  XFREE (MTYPE_OSPF6_AREA, oa);
+}
+
+struct ospf6_area *
+ospf6_area_lookup (u_int32_t area_id, struct ospf6 *ospf6)
 {
-  struct ospf6_route_req *route = data;
-  struct in6_addr local;
+  struct ospf6_area *oa;
+  listnode n;
 
-  inet_pton (AF_INET6, "::1", &local);
-  if (! memcmp (&route->nexthop.address, &local, sizeof (struct in6_addr)))
+  for (n = listhead (ospf6->area_list); n; nextnode (n))
     {
-      if (IS_OSPF6_DUMP_AREA)
-        zlog_info ("AREA: Self-originated route add, ignore");
-      return;
+      oa = (struct ospf6_area *) getdata (n);
+      if (oa->area_id == area_id)
+        return oa;
     }
 
-  ospf6_route_add (route, ospf6->route_table);
+  return (struct ospf6_area *) NULL;
 }
 
 void
-ospf6_area_route_remove (void *data)
+ospf6_area_enable (struct ospf6_area *oa)
 {
-  struct ospf6_route_req *route = data;
-  struct in6_addr local;
+  listnode i;
+  struct ospf6_interface *oi;
 
-  inet_pton (AF_INET6, "::1", &local);
-  if (! memcmp (&route->nexthop.address, &local, sizeof (struct in6_addr)))
+  UNSET_FLAG (oa->flag, OSPF6_AREA_DISABLE);
+
+  for (i = listhead (oa->if_list); i; nextnode (i))
     {
-      if (IS_OSPF6_DUMP_AREA)
-        zlog_info ("AREA: Self-originated route remove, ignore");
-      return;
+      oi = (struct ospf6_interface *) getdata (i);
+      ospf6_interface_enable (oi);
     }
-
-  ospf6_route_remove (route, ospf6->route_table);
 }
 
-/* Make new area structure */
-struct ospf6_area *
-ospf6_area_create (u_int32_t area_id)
+void
+ospf6_area_disable (struct ospf6_area *oa)
 {
-  struct ospf6_area *o6a;
-  char namebuf[64];
+  listnode i;
+  struct ospf6_interface *oi;
 
-  /* allocate memory */
-  o6a = XCALLOC (MTYPE_OSPF6_AREA, sizeof (struct ospf6_area));
+  SET_FLAG (oa->flag, OSPF6_AREA_DISABLE);
 
-  /* initialize */
-  inet_ntop (AF_INET, &area_id, o6a->str, sizeof (o6a->str));
-  o6a->area_id = area_id;
-  o6a->if_list = list_new ();
+  for (i = listhead (oa->if_list); i; nextnode (i))
+    {
+      oi = (struct ospf6_interface *) getdata (i);
+      ospf6_interface_disable (oi);
+    }
+}
 
-  o6a->lsdb = ospf6_lsdb_create ();
-  o6a->spf_tree = ospf6_spftree_create ();
+
+void
+ospf6_area_show (struct vty *vty, struct ospf6_area *oa)
+{
+  listnode i;
+  struct ospf6_interface *oi;
 
-  snprintf (namebuf, sizeof (namebuf), "Area %s's route table", o6a->str);
-  o6a->route_table = ospf6_route_table_create (namebuf);
-  o6a->route_table->hook_add = ospf6_area_route_add;
-  o6a->route_table->hook_change = ospf6_area_route_add;
-  o6a->route_table->hook_remove = ospf6_area_route_remove;
+  vty_out (vty, " Area %s%s", oa->name, VTY_NEWLINE);
+  vty_out (vty, "     Number of Area scoped LSAs is %u%s",
+           oa->lsdb->count, VTY_NEWLINE);
 
-  snprintf (namebuf, sizeof (namebuf), "Area %s's topology table", o6a->str);
-  o6a->table_topology = ospf6_route_table_create (namebuf);
-  o6a->table_topology->hook_add = ospf6_intra_topology_add;
-  o6a->table_topology->hook_change = ospf6_intra_topology_add;
-  o6a->table_topology->hook_remove = ospf6_intra_topology_remove;
+  vty_out (vty, "     Interface attached to this area:");
+  for (i = listhead (oa->if_list); i; nextnode (i))
+    {
+      oi = (struct ospf6_interface *) getdata (i);
+      vty_out (vty, " %s", oi->interface->name);
+    }
+  vty_out (vty, "%s", VTY_NEWLINE);
+}
 
-  /* xxx, set options */
-  OSPF6_OPT_SET (o6a->options, OSPF6_OPT_V6);
-  OSPF6_OPT_SET (o6a->options, OSPF6_OPT_E);
-  OSPF6_OPT_SET (o6a->options, OSPF6_OPT_R);
 
-  o6a->foreach_if = ospf6_area_foreach_interface;
-  o6a->foreach_nei = ospf6_area_foreach_neighbor;
+#define OSPF6_CMD_AREA_LOOKUP(str, oa)                             \
+{                                                                  \
+  u_int32_t area_id = 0;                                           \
+  if (inet_pton (AF_INET, str, &area_id) != 1)                     \
+    {                                                              \
+      vty_out (vty, "Malformed Area-ID: %s%s", str, VTY_NEWLINE);  \
+      return CMD_SUCCESS;                                          \
+    }                                                              \
+  oa = ospf6_area_lookup (area_id, ospf6);                         \
+  if (oa == NULL)                                                  \
+    {                                                              \
+      vty_out (vty, "No such Area: %s%s", str, VTY_NEWLINE);       \
+      return CMD_SUCCESS;                                          \
+    }                                                              \
+}
 
-  return o6a;
+DEFUN (show_ipv6_ospf6_area_route_intra,
+       show_ipv6_ospf6_area_route_intra_cmd,
+       "show ipv6 ospf6 area A.B.C.D route intra-area",
+       SHOW_STR
+       IP6_STR
+       OSPF6_STR
+       OSPF6_AREA_STR
+       OSPF6_AREA_ID_STR
+       ROUTE_STR
+       "Display Intra-Area routes\n"
+       )
+{
+  struct ospf6_area *oa;
+  OSPF6_CMD_AREA_LOOKUP (argv[0], oa);
+  argc--;
+  argv++;
+  return ospf6_route_table_show (vty, argc, argv, oa->route_table);
 }
 
-void
-ospf6_area_bind_top (struct ospf6_area *o6a, struct ospf6 *o6)
+ALIAS (show_ipv6_ospf6_area_route_intra,
+       show_ipv6_ospf6_area_route_intra_detail_cmd,
+       "show ipv6 ospf6 area A.B.C.D route intra-area (X::X|X::X/M|detail)",
+       SHOW_STR
+       IP6_STR
+       OSPF6_STR
+       OSPF6_AREA_STR
+       OSPF6_AREA_ID_STR
+       ROUTE_STR
+       "Display Intra-Area routes\n"
+       "Specify IPv6 address\n"
+       "Specify IPv6 prefix\n"
+       "Detailed information\n"
+       );
+
+DEFUN (show_ipv6_ospf6_area_route_intra_match,
+       show_ipv6_ospf6_area_route_intra_match_cmd,
+       "show ipv6 ospf6 area A.B.C.D route intra-area X::X/M match",
+       SHOW_STR
+       IP6_STR
+       OSPF6_STR
+       ROUTE_STR
+       "Display Intra-Area routes\n"
+       OSPF6_AREA_STR
+       OSPF6_AREA_ID_STR
+       "Specify IPv6 prefix\n"
+       "Display routes which match the specified route\n"
+       )
 {
-  o6a->ospf6 = o6;
-  CALL_CHANGE_HOOK (&area_hook, o6a);
-  return;
+  char *sargv[CMD_ARGC_MAX];
+  int i, sargc;
+  struct ospf6_area *oa;
+
+  OSPF6_CMD_AREA_LOOKUP (argv[0], oa);
+  argc--;
+  argv++;
+
+  /* copy argv to sargv and then append "match" */
+  for (i = 0; i < argc; i++)
+    sargv[i] = argv[i];
+  sargc = argc;
+  sargv[sargc++] = "match";
+  sargv[sargc] = NULL;
+
+  return ospf6_route_table_show (vty, sargc, sargv, oa->route_table);
 }
 
-void
-ospf6_area_delete (struct ospf6_area *o6a)
+DEFUN (show_ipv6_ospf6_area_route_intra_match_detail,
+       show_ipv6_ospf6_area_route_intra_match_detail_cmd,
+       "show ipv6 ospf6 area A.B.C.D route intra-area X::X/M match detail",
+       SHOW_STR
+       IP6_STR
+       OSPF6_STR
+       OSPF6_AREA_STR
+       OSPF6_AREA_ID_STR
+       ROUTE_STR
+       "Display Intra-Area routes\n"
+       "Specify IPv6 prefix\n"
+       "Display routes which match the specified route\n"
+       "Detailed information\n"
+       )
 {
-  listnode n;
-  struct ospf6_interface *o6i;
+  char *sargv[CMD_ARGC_MAX];
+  int i, sargc;
+  struct ospf6_area *oa;
+
+  OSPF6_CMD_AREA_LOOKUP (argv[0], oa);
+  argc--;
+  argv++;
+
+  /* copy argv to sargv and then append "match" and "detail" */
+  for (i = 0; i < argc; i++)
+    sargv[i] = argv[i];
+  sargc = argc;
+  sargv[sargc++] = "match";
+  sargv[sargc++] = "detail";
+  sargv[sargc] = NULL;
+
+  return ospf6_route_table_show (vty, sargc, sargv, oa->route_table);
+}
 
-  CALL_REMOVE_HOOK (&area_hook, o6a);
+DEFUN (show_ipv6_ospf6_route_intra,
+       show_ipv6_ospf6_route_intra_cmd,
+       "show ipv6 ospf6 route intra-area",
+       SHOW_STR
+       IP6_STR
+       OSPF6_STR
+       ROUTE_STR
+       "Display Intra-Area routes\n"
+       )
+{
+  listnode node;
+  struct ospf6_area *oa;
 
-  /* ospf6 interface list */
-  for (n = listhead (o6a->if_list); n; nextnode (n))
+  for (node = listhead (ospf6->area_list); node; nextnode (node))
     {
-      o6i = (struct ospf6_interface *) getdata (n);
-      /* ospf6_interface_delete (o6i); */
+      oa = (struct ospf6_area *) getdata (node);
+      vty_out (vty, "Area %s%s", oa->name, VTY_NEWLINE);
+      ospf6_route_table_show (vty, argc, argv, oa->route_table);
     }
-  list_delete (o6a->if_list);
 
-  /* terminate LSDB */
-  ospf6_lsdb_remove_all (o6a->lsdb);
+  return CMD_SUCCESS;
+}
 
-  /* spf tree terminate */
-  /* xxx */
+ALIAS (show_ipv6_ospf6_route_intra,
+       show_ipv6_ospf6_route_intra_detail_cmd,
+       "show ipv6 ospf6 route intra-area (X::X|X::X/M|detail|summary)",
+       SHOW_STR
+       IP6_STR
+       OSPF6_STR
+       ROUTE_STR
+       "Display Intra-Area routes\n"
+       "Specify IPv6 address\n"
+       "Specify IPv6 prefix\n"
+       "Detailed information\n"
+       "Summary of route table\n"
+       );
 
-  /* threads */
-  if (o6a->spf_calc)
-    thread_cancel (o6a->spf_calc);
-  o6a->spf_calc = (struct thread *) NULL;
-  if (o6a->route_calc)
-    thread_cancel (o6a->route_calc);
-  o6a->route_calc = (struct thread *) NULL;
+DEFUN (show_ipv6_ospf6_route_intra_match,
+       show_ipv6_ospf6_route_intra_match_cmd,
+       "show ipv6 ospf6 route intra-area X::X/M match",
+       SHOW_STR
+       IP6_STR
+       OSPF6_STR
+       ROUTE_STR
+       "Display Intra-Area routes\n"
+       "Specify IPv6 prefix\n"
+       "Display routes which match the specified route\n"
+       )
+{
+  char *sargv[CMD_ARGC_MAX];
+  int i, sargc;
+  listnode node;
+  struct ospf6_area *oa;
 
-  /* new */
-  ospf6_route_table_delete (o6a->route_table);
+  /* copy argv to sargv and then append "match" */
+  for (i = 0; i < argc; i++)
+    sargv[i] = argv[i];
+  sargc = argc;
+  sargv[sargc++] = "match";
+  sargv[sargc] = NULL;
 
-  ospf6_spftree_delete (o6a->spf_tree);
-  ospf6_route_table_delete (o6a->table_topology);
+  for (node = listhead (ospf6->area_list); node; nextnode (node))
+    {
+      oa = (struct ospf6_area *) getdata (node);
+      ospf6_route_table_show (vty, sargc, sargv, oa->route_table);
+    }
 
-  /* free area */
-  XFREE (MTYPE_OSPF6_AREA, o6a);
+  return CMD_SUCCESS;
 }
 
-struct ospf6_area *
-ospf6_area_lookup (u_int32_t area_id, struct ospf6 *o6)
+DEFUN (show_ipv6_ospf6_route_intra_match_detail,
+       show_ipv6_ospf6_route_intra_match_detail_cmd,
+       "show ipv6 ospf6 route intra-area X::X/M match detail",
+       SHOW_STR
+       IP6_STR
+       OSPF6_STR
+       ROUTE_STR
+       "Display Intra-Area routes\n"
+       "Specify IPv6 prefix\n"
+       "Display routes which match the specified route\n"
+       "Detailed information\n"
+       )
 {
-  struct ospf6_area *o6a;
-  listnode n;
+  char *sargv[CMD_ARGC_MAX];
+  int i, sargc;
+  listnode node;
+  struct ospf6_area *oa;
 
-  for (n = listhead (o6->area_list); n; nextnode (n))
+  /* copy argv to sargv and then append "match" and "detail" */
+  for (i = 0; i < argc; i++)
+    sargv[i] = argv[i];
+  sargc = argc;
+  sargv[sargc++] = "match";
+  sargv[sargc++] = "detail";
+  sargv[sargc] = NULL;
+
+  for (node = listhead (ospf6->area_list); node; nextnode (node))
     {
-      o6a = (struct ospf6_area *) getdata (n);
-      if (o6a->area_id == area_id)
-        return o6a;
+      oa = (struct ospf6_area *) getdata (node);
+      ospf6_route_table_show (vty, sargc, sargv, oa->route_table);
     }
 
-  return (struct ospf6_area *) NULL;
+  return CMD_SUCCESS;
 }
 
-void
-ospf6_area_show (struct vty *vty, struct ospf6_area *o6a)
+DEFUN (show_ipv6_ospf6_spf_tree,
+       show_ipv6_ospf6_spf_tree_cmd,
+       "show ipv6 ospf6 spf tree",
+       SHOW_STR
+       IP6_STR
+       OSPF6_STR
+       "Shortest Path First caculation\n"
+       "Show SPF tree\n")
 {
-  listnode i;
-  struct ospf6_interface *o6i;
+  listnode node;
+  struct ospf6_area *oa;
+  struct ospf6_vertex *root;
+  struct ospf6_route *route;
+  struct prefix prefix;
 
-  vty_out (vty, " Area %s%s", o6a->str, VTY_NEWLINE);
-  vty_out (vty, "     Number of Area scoped LSAs is %u%s",
-           o6a->lsdb->count, VTY_NEWLINE);
+  ospf6_linkstate_prefix (ospf6->router_id, htonl (0), &prefix);
+  for (node = listhead (ospf6->area_list); node; nextnode (node))
+    {
+      oa = (struct ospf6_area *) getdata (node);
+      route = ospf6_route_lookup (&prefix, oa->spf_table);
+      if (route == NULL)
+        {
+          vty_out (vty, "LS entry for root not found in area %s%s",
+                   oa->name, VTY_NEWLINE);
+          continue;
+        }
+      root = (struct ospf6_vertex *) route->route_option;
+      ospf6_spf_display_subtree (vty, "", 0, root);
+    }
+
+  return CMD_SUCCESS;
+}
+
+DEFUN (show_ipv6_ospf6_area_spf_tree,
+       show_ipv6_ospf6_area_spf_tree_cmd,
+       "show ipv6 ospf6 area A.B.C.D spf tree",
+       SHOW_STR
+       IP6_STR
+       OSPF6_STR
+       OSPF6_AREA_STR
+       OSPF6_AREA_ID_STR
+       "Shortest Path First caculation\n"
+       "Show SPF tree\n")
+{
+  u_int32_t area_id;
+  struct ospf6_area *oa;
+  struct ospf6_vertex *root;
+  struct ospf6_route *route;
+  struct prefix prefix;
 
-  ospf6_spf_statistics_show (vty, o6a->spf_tree);
+  ospf6_linkstate_prefix (ospf6->router_id, htonl (0), &prefix);
 
-  vty_out (vty, "     Interface attached to this area:");
-  for (i = listhead (o6a->if_list); i; nextnode (i))
+  if (inet_pton (AF_INET, argv[0], &area_id) != 1)
     {
-      o6i = (struct ospf6_interface *) getdata (i);
-      vty_out (vty, " %s", o6i->interface->name);
+      vty_out (vty, "Malformed Area-ID: %s%s", argv[0], VTY_NEWLINE);
+      return CMD_SUCCESS;
+    }
+  oa = ospf6_area_lookup (area_id, ospf6);
+  if (oa == NULL)
+    {
+      vty_out (vty, "No such Area: %s%s", argv[0], VTY_NEWLINE);
+      return CMD_SUCCESS;
     }
-  vty_out (vty, "%s", VTY_NEWLINE);
 
-  for (i = listhead (o6a->if_list); i; nextnode (i))
+  route = ospf6_route_lookup (&prefix, oa->spf_table);
+  if (route == NULL)
     {
-      o6i = (struct ospf6_interface *) getdata (i);
-      if (listcount (o6i->neighbor_list) != 0)
-        ospf6_interface_statistics_show (vty, o6i);
+      vty_out (vty, "LS entry for root not found in area %s%s",
+               oa->name, VTY_NEWLINE);
+      return CMD_SUCCESS;
     }
+  root = (struct ospf6_vertex *) route->route_option;
+  ospf6_spf_display_subtree (vty, "", 0, root);
+
+  return CMD_SUCCESS;
 }
 
-void
-ospf6_area_statistics_show (struct vty *vty, struct ospf6_area *o6a)
+DEFUN (show_ipv6_ospf6_area_spf_table,
+       show_ipv6_ospf6_area_spf_table_cmd,
+       "show ipv6 ospf6 area A.B.C.D spf table",
+       SHOW_STR
+       IP6_STR
+       OSPF6_STR
+       OSPF6_AREA_STR
+       OSPF6_AREA_ID_STR
+       "Shortest Path First caculation\n"
+       "Show table contains SPF result\n"
+       )
 {
-#if 0
-  listnode node;
-  struct ospf6_interface *o6i;
+  u_int32_t area_id;
+  struct ospf6_area *oa;
 
-  vty_out (vty, "  Statistics of Area %s%s", o6a->str, VTY_NEWLINE);
-#endif
+  if (inet_pton (AF_INET, argv[0], &area_id) != 1)
+    {
+      vty_out (vty, "Malformed Area-ID: %s%s", argv[0], VTY_NEWLINE);
+      return CMD_SUCCESS;
+    }
+  oa = ospf6_area_lookup (area_id, ospf6);
+  if (oa == NULL)
+    {
+      vty_out (vty, "No such Area: %s%s", argv[0], VTY_NEWLINE);
+      return CMD_SUCCESS;
+    }
+
+  argc--;
+  argv++;
+
+  ospf6_lsentry_table_show (vty, argc, argv, oa->spf_table);
+  return CMD_SUCCESS;
 }
 
-DEFUN (show_ipv6_ospf6_area_route,
-       show_ipv6_ospf6_area_route_cmd,
-       "show ipv6 ospf6 area A.B.C.D route",
+ALIAS (show_ipv6_ospf6_area_spf_table,
+       show_ipv6_ospf6_area_spf_table_1_cmd,
+       "show ipv6 ospf6 area A.B.C.D spf table (A.B.C.D|A.B.C.D/M|detail)",
        SHOW_STR
        IP6_STR
        OSPF6_STR
        OSPF6_AREA_STR
        OSPF6_AREA_ID_STR
-       ROUTE_STR
+       "Shortest Path First caculation\n"
+       "Show table contains SPF result\n"
+       "Specify Router-ID\n"
+       "Display multiple entry by specifying match-prefix of Router-ID\n"
+       "Display Detail\n"
+       );
+
+ALIAS (show_ipv6_ospf6_area_spf_table,
+       show_ipv6_ospf6_area_spf_table_2_cmd,
+       "show ipv6 ospf6 area A.B.C.D spf table (A.B.C.D|*) (A.B.C.D|A.B.C.D/M|detail)",
+       SHOW_STR
+       IP6_STR
+       OSPF6_STR
+       OSPF6_AREA_STR
+       OSPF6_AREA_ID_STR
+       "Shortest Path First caculation\n"
+       "Show table contains SPF result\n"
+       "Specify Router-ID\n"
+       "Wildcard Router-ID\n"
+       "Specify Link State ID\n"
+       "Display multiple entry by specifying match-prefix of Link State ID\n"
+       "Display Detail\n"
+       );
+
+DEFUN (show_ipv6_ospf6_area_spf_table_3,
+       show_ipv6_ospf6_area_spf_table_3_cmd,
+       "show ipv6 ospf6 area A.B.C.D spf table (A.B.C.D|*) A.B.C.D/M detail",
+       SHOW_STR
+       IP6_STR
+       OSPF6_STR
+       OSPF6_AREA_STR
+       OSPF6_AREA_ID_STR
+       "Shortest Path First caculation\n"
+       "Show table contains SPF result\n"
+       "Specify Router-ID\n"
+       "Wildcard Router-ID\n"
+       "Display multiple entry by specifying match-prefix of Link State ID\n"
+       "Display Detail\n"
        )
 {
-  struct ospf6_area *o6a;
   u_int32_t area_id;
+  struct ospf6_area *oa;
+  char *sargv[CMD_ARGC_MAX];
+  int i, sargc;
 
-  OSPF6_CMD_CHECK_RUNNING ();
-
-  inet_pton (AF_INET, argv[0], &area_id);
-  o6a = ospf6_area_lookup (area_id, ospf6);
+  if (inet_pton (AF_INET, argv[0], &area_id) != 1)
+    {
+      vty_out (vty, "Malformed Area-ID: %s%s", argv[0], VTY_NEWLINE);
+      return CMD_SUCCESS;
+    }
+  oa = ospf6_area_lookup (area_id, ospf6);
+  if (oa == NULL)
+    {
+      vty_out (vty, "No such Area: %s%s", argv[0], VTY_NEWLINE);
+      return CMD_SUCCESS;
+    }
 
-  if (! o6a)
-    return CMD_SUCCESS;
+  argc--;
+  argv++;
 
-  argc -= 1;
-  argv += 1;
+  /* copy argv to sargv and then append "detail" */
+  for (i = 0; i < argc; i++)
+    sargv[i] = argv[i];
+  sargc = argc;
+  sargv[sargc++] = "detail";
+  sargv[sargc] = NULL;
 
-  return ospf6_route_table_show (vty, argc, argv, o6a->route_table);
+  ospf6_lsentry_table_show (vty, sargc, sargv, oa->spf_table);
+  return CMD_SUCCESS;
 }
 
-ALIAS (show_ipv6_ospf6_area_route,
-       show_ipv6_ospf6_area_route_prefix_cmd,
-       "show ipv6 ospf6 area A.B.C.D route (X::X|detail)",
+DEFUN (show_ipv6_ospf6_spf_table,
+       show_ipv6_ospf6_spf_table_cmd,
+       "show ipv6 ospf6 spf table",
        SHOW_STR
        IP6_STR
        OSPF6_STR
-       OSPF6_AREA_STR
-       OSPF6_AREA_ID_STR
-       ROUTE_STR
-       "Specify IPv6 address\n"
-       "Detailed information\n"
+       "Shortest Path First caculation\n"
+       "Show table contains SPF result\n"
        )
+{
+  listnode node;
+  struct ospf6_area *oa;
 
-void
-ospf6_area_init ()
+  for (node = listhead (ospf6->area_list); node; nextnode (node))
+    {
+      oa = (struct ospf6_area *) getdata (node);
+      ospf6_lsentry_table_show (vty, argc, argv, oa->spf_table);
+    }
+
+  return CMD_SUCCESS;
+}
+
+ALIAS (show_ipv6_ospf6_spf_table,
+       show_ipv6_ospf6_spf_table_1_cmd,
+       "show ipv6 ospf6 spf table (A.B.C.D|A.B.C.D/M|detail)",
+       SHOW_STR
+       IP6_STR
+       OSPF6_STR
+       "Shortest Path First caculation\n"
+       "Show table contains SPF result\n"
+       "Specify Router-ID\n"
+       "Display multiple entry by specifying match-prefix of Router-ID\n"
+       "Display Detail\n"
+       );
+
+ALIAS (show_ipv6_ospf6_spf_table,
+       show_ipv6_ospf6_spf_table_2_cmd,
+       "show ipv6 ospf6 spf table (A.B.C.D|A.B.C.D/M|*) (A.B.C.D|A.B.C.D/M|detail)",
+       SHOW_STR
+       IP6_STR
+       OSPF6_STR
+       "Shortest Path First caculation\n"
+       "Show table contains SPF result\n"
+       "Specify Router-ID\n"
+       "Display multiple entry by specifying match-prefix of Router-ID\n"
+       "Wildcard Router-ID\n"
+       "Specify Link State ID\n"
+       "Display multiple entry by specifying match-prefix of Link State ID\n"
+       "Display Detail\n"
+       );
+
+DEFUN (show_ipv6_ospf6_spf_table_3,
+       show_ipv6_ospf6_spf_table_3_cmd,
+       "show ipv6 ospf6 spf table (A.B.C.D|*) A.B.C.D/M detail",
+       SHOW_STR
+       IP6_STR
+       OSPF6_STR
+       "Shortest Path First caculation\n"
+       "Show table contains SPF result\n"
+       "Specify Router-ID\n"
+       "Wildcard Router-ID\n"
+       "Display multiple entry by specifying match-prefix of Link State ID\n"
+       "Display Detail\n"
+       )
 {
-  area_index = ospf6_dump_install ("area", "Area information\n");
+  listnode node;
+  struct ospf6_area *oa;
+  char *sargv[CMD_ARGC_MAX];
+  int i, sargc;
+
+  /* copy argv to sargv and then append "detail" */
+  for (i = 0; i < argc; i++)
+    sargv[i] = argv[i];
+  sargc = argc;
+  sargv[sargc++] = "detail";
+  sargv[sargc] = NULL;
+
+  for (node = listhead (ospf6->area_list); node; nextnode (node))
+    {
+      oa = (struct ospf6_area *) getdata (node);
+      ospf6_lsentry_table_show (vty, sargc, sargv, oa->spf_table);
+    }
 
-  install_element (VIEW_NODE, &show_ipv6_ospf6_area_route_cmd);
-  install_element (VIEW_NODE, &show_ipv6_ospf6_area_route_prefix_cmd);
-  install_element (ENABLE_NODE, &show_ipv6_ospf6_area_route_cmd);
-  install_element (ENABLE_NODE, &show_ipv6_ospf6_area_route_prefix_cmd);
+  return CMD_SUCCESS;
 }
 
+DEFUN (show_ipv6_ospf6_simulate_spf_tree_root,
+       show_ipv6_ospf6_simulate_spf_tree_root_cmd,
+       "show ipv6 ospf6 simulate spf-tree A.B.C.D area A.B.C.D",
+       SHOW_STR
+       IP6_STR
+       OSPF6_STR
+       "Shortest Path First caculation\n"
+       "Show SPF tree\n"
+       "Specify root's router-id to calculate another router's SPF tree\n")
+{
+  u_int32_t area_id;
+  struct ospf6_area *oa;
+  struct ospf6_vertex *root;
+  struct ospf6_route *route;
+  struct prefix prefix;
+  u_int32_t router_id;
+  struct ospf6_route_table *spf_table;
+  unsigned char tmp_debug_ospf6_spf = 0;
+
+  inet_pton (AF_INET, argv[0], &router_id);
+  ospf6_linkstate_prefix (router_id, htonl (0), &prefix);
+
+  if (inet_pton (AF_INET, argv[1], &area_id) != 1)
+    {
+      vty_out (vty, "Malformed Area-ID: %s%s", argv[1], VTY_NEWLINE);
+      return CMD_SUCCESS;
+    }
+  oa = ospf6_area_lookup (area_id, ospf6);
+  if (oa == NULL)
+    {
+      vty_out (vty, "No such Area: %s%s", argv[1], VTY_NEWLINE);
+      return CMD_SUCCESS;
+    }
+
+  tmp_debug_ospf6_spf = conf_debug_ospf6_spf;
+  conf_debug_ospf6_spf = 0;
+
+  spf_table = ospf6_route_table_create ();
+  ospf6_spf_calculation (router_id, spf_table, oa);
+
+  conf_debug_ospf6_spf = tmp_debug_ospf6_spf;
+
+  route = ospf6_route_lookup (&prefix, spf_table);
+  if (route == NULL)
+    {
+      ospf6_spf_table_finish (spf_table);
+      ospf6_route_table_delete (spf_table);
+      return CMD_SUCCESS;
+    }
+  root = (struct ospf6_vertex *) route->route_option;
+  ospf6_spf_display_subtree (vty, "", 0, root);
 
+  ospf6_spf_table_finish (spf_table);
+  ospf6_route_table_delete (spf_table);
+
+  return CMD_SUCCESS;
+}
+
+void
+ospf6_area_init ()
+{
+  install_element (VIEW_NODE, &show_ipv6_ospf6_spf_tree_cmd);
+  install_element (VIEW_NODE, &show_ipv6_ospf6_spf_table_cmd);
+  install_element (VIEW_NODE, &show_ipv6_ospf6_spf_table_1_cmd);
+  install_element (VIEW_NODE, &show_ipv6_ospf6_spf_table_2_cmd);
+  install_element (VIEW_NODE, &show_ipv6_ospf6_spf_table_3_cmd);
+  install_element (VIEW_NODE, &show_ipv6_ospf6_area_spf_tree_cmd);
+  install_element (VIEW_NODE, &show_ipv6_ospf6_area_spf_table_cmd);
+  install_element (VIEW_NODE, &show_ipv6_ospf6_area_spf_table_1_cmd);
+  install_element (VIEW_NODE, &show_ipv6_ospf6_area_spf_table_2_cmd);
+  install_element (VIEW_NODE, &show_ipv6_ospf6_area_spf_table_3_cmd);
+
+  install_element (VIEW_NODE, &show_ipv6_ospf6_route_intra_cmd);
+  install_element (VIEW_NODE, &show_ipv6_ospf6_route_intra_detail_cmd);
+  install_element (VIEW_NODE, &show_ipv6_ospf6_route_intra_match_cmd);
+  install_element (VIEW_NODE, &show_ipv6_ospf6_route_intra_match_detail_cmd);
+  install_element (VIEW_NODE, &show_ipv6_ospf6_area_route_intra_cmd);
+  install_element (VIEW_NODE, &show_ipv6_ospf6_area_route_intra_detail_cmd);
+  install_element (VIEW_NODE, &show_ipv6_ospf6_area_route_intra_match_cmd);
+  install_element (VIEW_NODE, &show_ipv6_ospf6_area_route_intra_match_detail_cmd);
+
+  install_element (VIEW_NODE, &show_ipv6_ospf6_simulate_spf_tree_root_cmd);
+
+  install_element (ENABLE_NODE, &show_ipv6_ospf6_spf_tree_cmd);
+  install_element (ENABLE_NODE, &show_ipv6_ospf6_spf_table_cmd);
+  install_element (ENABLE_NODE, &show_ipv6_ospf6_spf_table_1_cmd);
+  install_element (ENABLE_NODE, &show_ipv6_ospf6_spf_table_2_cmd);
+  install_element (ENABLE_NODE, &show_ipv6_ospf6_spf_table_3_cmd);
+  install_element (ENABLE_NODE, &show_ipv6_ospf6_area_spf_tree_cmd);
+  install_element (ENABLE_NODE, &show_ipv6_ospf6_area_spf_table_cmd);
+  install_element (ENABLE_NODE, &show_ipv6_ospf6_area_spf_table_1_cmd);
+  install_element (ENABLE_NODE, &show_ipv6_ospf6_area_spf_table_2_cmd);
+  install_element (ENABLE_NODE, &show_ipv6_ospf6_area_spf_table_3_cmd);
+
+  install_element (ENABLE_NODE, &show_ipv6_ospf6_route_intra_cmd);
+  install_element (ENABLE_NODE, &show_ipv6_ospf6_route_intra_detail_cmd);
+  install_element (ENABLE_NODE, &show_ipv6_ospf6_route_intra_match_cmd);
+  install_element (ENABLE_NODE, &show_ipv6_ospf6_route_intra_match_detail_cmd);
+  install_element (ENABLE_NODE, &show_ipv6_ospf6_area_route_intra_cmd);
+  install_element (ENABLE_NODE, &show_ipv6_ospf6_area_route_intra_detail_cmd);
+  install_element (ENABLE_NODE, &show_ipv6_ospf6_area_route_intra_match_cmd);
+  install_element (ENABLE_NODE, &show_ipv6_ospf6_area_route_intra_match_detail_cmd);
+
+  install_element (ENABLE_NODE, &show_ipv6_ospf6_simulate_spf_tree_root_cmd);
+}

+ 28 - 42
ospf6d/ospf6_area.h

@@ -1,6 +1,5 @@
 /*
- * OSPF6 Area Data Structure
- * Copyright (C) 1999 Yasuhiro Ohara
+ * Copyright (C) 2003 Yasuhiro Ohara
  *
  * This file is part of GNU Zebra.
  *
@@ -23,67 +22,54 @@
 #ifndef OSPF_AREA_H
 #define OSPF_AREA_H
 
-/* This file defines area parameters and data structures. */
-
-#define OSPF6_AREA_RANGE_ADVERTISE     0
-#define OSPF6_AREA_RANGE_NOT_ADVERTISE 1
-
-#include "ospf6_spf.h"
 #include "ospf6_top.h"
 
 struct ospf6_area
 {
-  char            str[16];
-
-  struct ospf6   *ospf6;      /* back pointer */
-  u_int32_t       area_id;
-  u_char          options[3]; /* OSPF Option including ExternalCapability */
+  /* Reference to Top data structure */
+  struct ospf6 *ospf6;
 
-  list            if_list; /* OSPF interface to this area */
+  /* Area-ID */
+  u_int32_t area_id;
 
-  struct ospf6_lsdb *lsdb;
+  /* Area-ID string */
+  char name[16];
 
-  struct thread  *spf_calc;
-  struct thread  *route_calc;
-  int             stat_spf_execed;
-  int             stat_route_execed;
+  /* flag */
+  u_char flag;
 
-  struct route_table *table; /* new route table */
+  /* OSPF Option */
+  u_char options[3];
 
-  struct prefix_ipv6 area_range;
-  struct ospf6_spftree *spf_tree;
+  /* OSPF interface list */
+  list if_list;
 
+  struct ospf6_lsdb        *lsdb;
+  struct ospf6_route_table *spf_table;
   struct ospf6_route_table *route_table;
-  struct ospf6_route_table *table_topology;
 
-  void (*foreach_if)  (struct ospf6_area *, void *, int,
-                       void (*func) (void *, int, void *));
-  void (*foreach_nei) (struct ospf6_area *, void *, int,
-                       void (*func) (void *, int, void *));
-
-  struct thread *maxage_remover;
+  struct thread  *thread_spf_calculation;
+  struct thread  *thread_route_calculation;
 
   struct thread *thread_router_lsa;
+  struct thread *thread_intra_prefix_lsa;
+  u_int32_t router_lsa_size_limit;
 };
 
+#define OSPF6_AREA_DISABLE 0x01
+#define OSPF6_AREA_STUB    0x02
 
 /* prototypes */
-
-int
-ospf6_area_count_neighbor_in_state (u_char state, struct ospf6_area *o6a);
-
-void
-ospf6_area_schedule_maxage_remover (void *arg, int val, void *obj);
-
+int ospf6_area_cmp (void *va, void *vb);
 int ospf6_area_is_stub (struct ospf6_area *o6a);
-int ospf6_area_is_transit (struct ospf6_area *o6a);
-struct ospf6_area *ospf6_area_lookup (u_int32_t, struct ospf6 *);
-struct ospf6_area *ospf6_area_create (u_int32_t);
+struct ospf6_area *ospf6_area_create (u_int32_t, struct ospf6 *);
 void ospf6_area_delete (struct ospf6_area *);
-void ospf6_area_show (struct vty *, struct ospf6_area *);
-void
-ospf6_area_statistics_show (struct vty *vty, struct ospf6_area *o6a);
+struct ospf6_area *ospf6_area_lookup (u_int32_t, struct ospf6 *);
+
+void ospf6_area_enable (struct ospf6_area *);
+void ospf6_area_disable (struct ospf6_area *);
 
+void ospf6_area_show (struct vty *, struct ospf6_area *);
 void ospf6_area_init ();
 
 #endif /* OSPF_AREA_H */

File diff suppressed because it is too large
+ 965 - 748
ospf6d/ospf6_asbr.c


+ 23 - 49
ospf6d/ospf6_asbr.h

@@ -22,53 +22,29 @@
 #ifndef OSPF6_ASBR_H
 #define OSPF6_ASBR_H
 
-#include "thread.h"
+/* Debug option */
+extern unsigned char conf_debug_ospf6_asbr;
+#define OSPF6_DEBUG_ASBR_ON() \
+  (conf_debug_ospf6_asbr = 1)
+#define OSPF6_DEBUG_ASBR_OFF() \
+  (conf_debug_ospf6_asbr = 0)
+#define IS_OSPF6_DEBUG_ASBR \
+  (conf_debug_ospf6_asbr)
 
 struct ospf6_external_info
 {
-  int is_removed;
-  struct thread *thread_originate;
-
-  struct ospf6_external_route *route;
-
-  struct ospf6_external_info *prev;
-  struct ospf6_external_info *next;
-
-  /* external route type */
+  /* External route type */
   int type;
 
-  /* external route ifindex */
-  int ifindex;
-
-  /* LS-ID */
+  /* Originating Link State ID */
   u_int32_t id;
 
-  /* nexthops */
-  u_int nexthop_num;
-  struct in6_addr *nexthop;
-
-  u_int8_t  prefix_options;
-
-  u_int8_t  metric_type;
-  u_int32_t metric;
   struct in6_addr forwarding;
   /* u_int32_t tag; */
 };
 
-struct ospf6_external_route
-{
-  struct route_node *node;
-
-  /* prefix */
-  struct prefix prefix;
-
-  /* external information */
-  struct ospf6_external_info *info_head;
-  struct ospf6_external_info *info_tail;
-};
-
 /* AS-External-LSA */
-struct ospf6_lsa_as_external
+struct ospf6_as_external_lsa
 {
   u_int32_t bits_metric;
 
@@ -87,26 +63,24 @@ struct ospf6_lsa_as_external
   { (E)->bits_metric &= htonl (0xff000000); \
     (E)->bits_metric |= htonl (0x00ffffff) & htonl (C); }
 
-void ospf6_asbr_routemap_update ();
-
-int ospf6_redistribute_config_write (struct vty *vty);
-void ospf6_redistribute_show_config (struct vty *vty);
+void ospf6_asbr_lsa_add (struct ospf6_lsa *lsa);
+void ospf6_asbr_lsa_remove (struct ospf6_lsa *lsa);
+void ospf6_asbr_lsentry_add (struct ospf6_route *asbr_entry);
+void ospf6_asbr_lsentry_remove (struct ospf6_route *asbr_entry);
 
+int ospf6_asbr_is_asbr (struct ospf6 *o);
 void
-ospf6_asbr_route_add (int type, int ifindex, struct prefix *prefix,
-                      u_int nexthop_num, struct in6_addr *nexthop);
+ospf6_asbr_redistribute_add (int type, int ifindex, struct prefix *prefix,
+                             u_int nexthop_num, struct in6_addr *nexthop);
 void
-ospf6_asbr_route_remove (int type, int ifindex, struct prefix *prefix);
-
-void ospf6_asbr_external_lsa_add (struct ospf6_lsa *lsa);
-void ospf6_asbr_external_lsa_remove (struct ospf6_lsa *lsa);
-void ospf6_asbr_external_lsa_change (struct ospf6_lsa *old,
-                                     struct ospf6_lsa *new);
+ospf6_asbr_redistribute_remove (int type, int ifindex, struct prefix *prefix);
 
-void ospf6_asbr_asbr_entry_add (struct ospf6_route_req *topo_entry);
-void ospf6_asbr_asbr_entry_remove (struct ospf6_route_req *topo_entry);
+int ospf6_redistribute_config_write (struct vty *vty);
 
 void ospf6_asbr_init ();
 
+int config_write_ospf6_debug_asbr (struct vty *vty);
+void install_element_ospf6_debug_asbr ();
+
 #endif /* OSPF6_ASBR_H */
 

+ 0 - 436
ospf6d/ospf6_bintree.c

@@ -1,436 +0,0 @@
-
-#include <zebra.h>
-#include "ospf6_bintree.h"
-
-static struct bintree_node *
-bintree_lookup_node_min (struct bintree_node *subroot)
-{
-  struct bintree_node *node;
-
-  if (subroot == NULL)
-    return NULL;
-
-  node = subroot;
-  while (node->bl_left)
-    node = node->bl_left;
-  return node;
-}
-
-static struct bintree_node *
-bintree_lookup_node_max (struct bintree_node *subroot)
-{
-  struct bintree_node *node;
-
-  assert (subroot != NULL);
-  node = subroot;
-  while (node->bl_right)
-    node = node->bl_right;
-  return node;
-}
-
-void *
-bintree_lookup (void *data, struct bintree *tree)
-{
-  int cmp;
-  struct bintree_node *node;
-
-  node = tree->root;
-
-  while (node)
-    {
-      if (tree->cmp)
-        cmp = (*tree->cmp) (node->data, data);
-      else
-        cmp = (node->data - data);
-
-      if (cmp == 0)
-        break;
-
-      if (cmp > 0)
-        node = node->bl_left;
-      else /* if (cmp < 0) */
-        node = node->bl_right;
-    }
-
-  if (node)
-    return node->data;
-
-  return NULL;
-}
-
-void *
-bintree_lookup_min (struct bintree *tree)
-{
-  struct bintree_node *node;
-  node = bintree_lookup_node_min (tree->root);
-  if (node == NULL)
-    return NULL;
-  return node->data;
-}
-
-void *
-bintree_lookup_max (struct bintree *tree)
-{
-  struct bintree_node *node;
-  node = bintree_lookup_node_max (tree->root);
-  if (node == NULL)
-    return NULL;
-  return node->data;
-}
-
-int
-bintree_add (void *data, struct bintree *tree)
-{
-  int cmp = 0;
-  struct bintree_node *node, *parent;
-
-  node = tree->root;
-  parent = NULL;
-
-  while (node)
-    {
-      if (tree->cmp)
-        cmp = (*tree->cmp) (node->data, data);
-      else
-        cmp = (node->data - data);
-
-      if (cmp == 0)
-        break;
-
-      parent = node;
-      if (cmp > 0)
-        node = node->bl_left;
-      else /* if (cmp < 0) */
-        node = node->bl_right;
-    }
-
-  if (node)
-    return -1;
-
-  node = malloc (sizeof (struct bintree_node));
-  memset (node, 0, sizeof (struct bintree_node));
-  node->tree = tree;
-  node->data = data;
-
-  if (parent)
-    {
-      node->parent = parent;
-
-      assert (cmp != 0);
-      if (cmp > 0)
-        {
-          node->parent_link = BL_LEFT;
-          parent->bl_left = node;
-        }
-      else /* if (cmp < 0) */
-        {
-          node->parent_link = BL_RIGHT;
-          parent->bl_right = node;
-        }
-    }
-  else
-    tree->root = node;
-
-  tree->count++;
-  return 0;
-}
-
-static void
-bintree_remove_nochild (struct bintree_node *node)
-{
-  assert (node->bl_left == NULL && node->bl_right == NULL);
-
-  if (node->parent == NULL)
-    node->tree->root = NULL;
-  else
-    node->parent->link[node->parent_link] = NULL;
-}
-
-static void
-bintree_remove_onechild (struct bintree_node *node)
-{
-  assert ((node->bl_left == NULL && node->bl_right != NULL) ||
-          (node->bl_left != NULL && node->bl_right == NULL));
-
-  if (node->bl_left)
-    {
-      if (node->parent == NULL)
-        {
-          node->tree->root = node->bl_left;
-          node->bl_left->parent = NULL;
-        }
-      else
-        {
-          node->parent->link[node->parent_link] = node->bl_left;
-          node->bl_left->parent = node->parent;
-          node->bl_left->parent_link = node->parent_link;
-        }
-    }
-  else if (node->bl_right)
-    {
-      if (node->parent == NULL)
-        {
-          node->tree->root = node->bl_right;
-          node->bl_right->parent = NULL;
-        }
-      else
-        {
-          node->parent->link[node->parent_link] = node->bl_right;
-          node->bl_right->parent = node->parent;
-          node->bl_right->parent_link = node->parent_link;
-        }
-    }
-  else
-    assert (0);
-}
-
-int
-bintree_remove (void *data, struct bintree *tree)
-{
-  int cmp;
-  struct bintree_node *node;
-
-  node = tree->root;
-
-  while (node)
-    {
-      if (tree->cmp)
-        cmp = (*tree->cmp) (node->data, data);
-      else
-        cmp = (node->data - data);
-
-      if (cmp == 0)
-        break;
-
-      if (cmp > 0)
-        node = node->bl_left;
-      else /* if (cmp < 0) */
-        node = node->bl_right;
-    }
-
-  if (node == NULL)
-    return -1;
-
-  if (node->bl_left == NULL && node->bl_right == NULL)
-    {
-      bintree_remove_nochild (node);
-      free (node);
-      tree->count--;
-      return 0;
-    }
-
-  if ((node->bl_left == NULL && node->bl_right != NULL) ||
-      (node->bl_left != NULL && node->bl_right == NULL))
-    {
-      bintree_remove_onechild (node);
-      free (node);
-      tree->count--;
-      return 0;
-    }
-
-  if (node->bl_left != NULL && node->bl_right != NULL)
-    {
-      struct bintree_node *successor;
-
-      /* find successor of the removing node */
-      successor = bintree_lookup_node_min (node->bl_right);
-
-      /* remove successor from tree */
-      if (successor->bl_right)
-        bintree_remove_onechild (successor);
-      else
-        bintree_remove_nochild (successor);
-
-      /* swap removing node with successor */
-      successor->parent = node->parent;
-      successor->parent_link = node->parent_link;
-      successor->bl_left = node->bl_left;
-      successor->bl_right = node->bl_right;
-
-      /* if the successor was the node->bl_right itself,
-         bintree_remove_**child may touch node->bl_right,
-         so only the successor->bl_right may be NULL
-         by above assignment */
-      successor->bl_left->parent = successor;
-      if (successor->bl_right)
-        successor->bl_right->parent = successor;
-
-      if (successor->parent == NULL)
-        tree->root = successor;
-      else
-        successor->parent->link[successor->parent_link] = successor;
-
-      free (node);
-      tree->count--;
-      return 0;
-    }
-
-  /* not reached */
-  return -1;
-}
-
-/* in-order traversal */
-
-void
-bintree_head (struct bintree *tree, struct bintree_node *node)
-{
-  struct bintree_node *head;
-
-  head = bintree_lookup_node_min (tree->root);
-  if (head == NULL)
-    {
-      node->parent = NULL;
-      node->bl_left = NULL;
-      node->bl_right = NULL;
-      node->data = NULL;
-      return;
-    }
-
-  node->tree = head->tree;
-  node->parent = head->parent;
-  node->parent_link = head->parent_link;
-  node->bl_left = head->bl_left;
-  node->bl_right = head->bl_right;
-  node->data = head->data;
-}
-
-int
-bintree_end (struct bintree_node *node)
-{
-  if (node->parent || node->bl_left || node->bl_right || node->data)
-    return 0;
-  return 1;
-}
-
-#define GOTO_PROCED_SUBTREE_TOP(node) \
-  while (node->parent && node->parent->bl_right && \
-         node->parent->bl_right->data == node->data) \
-    { \
-      node->data = node->parent->data; \
-      node->bl_left = node->parent->bl_left; \
-      node->bl_right = node->parent->bl_right; \
-      node->parent_link = node->parent->parent_link; \
-      node->parent = node->parent->parent; \
-    }
-
-void
-bintree_next (struct bintree_node *node)
-{
-  struct bintree_node *next = NULL;
-
-  /* if node have just been removed, current point should have just been
-     replaced with its successor. that certainly  will not be processed
-     yet, so process it */
-  if (node->parent == NULL)
-    {
-      if (node->tree->root == NULL)
-        {
-          assert (node->tree->count == 0);
-          node->parent = NULL;
-          node->bl_left = NULL;
-          node->bl_right = NULL;
-          node->data = NULL;
-          return;
-        }
-      else if (node->tree->root->data != node->data)
-        next = node->tree->root;
-    }
-  else if (node->parent->link[node->parent_link] == NULL)
-    {
-      if (node->parent_link == BL_LEFT)
-        next = node->parent;
-      else
-        {
-          GOTO_PROCED_SUBTREE_TOP (node);
-          next = node->parent;
-        }
-    }
-  else if (node->parent->link[node->parent_link]->data != node->data)
-    next = node->parent->link[node->parent_link];
-
-  if (next == NULL)
-    {
-      if (node->bl_right)
-        next = bintree_lookup_node_min (node->bl_right);
-      else
-        {
-          GOTO_PROCED_SUBTREE_TOP (node);
-          next = node->parent;
-        }
-    }
-
-  if (next)
-    {
-      node->tree = next->tree;
-      node->parent = next->parent;
-      node->parent_link = next->parent_link;
-      node->bl_left = next->bl_left;
-      node->bl_right = next->bl_right;
-      node->data = next->data;
-    }
-  else
-    {
-      node->parent = NULL;
-      node->bl_left = NULL;
-      node->bl_right = NULL;
-      node->data = NULL;
-    }
-}
-
-struct bintree *
-bintree_create ()
-{
-  struct bintree *tree;
-
-  tree = malloc (sizeof (struct bintree));
-  memset (tree, 0, sizeof (struct bintree));
-
-  return tree;
-}
-
-void
-bintree_delete (struct bintree *tree)
-{
-  struct bintree_node node;
-
-  for (bintree_head (tree, &node); ! bintree_end (&node);
-       bintree_next (&node))
-    bintree_remove (node.data, tree);
-
-  assert (tree->count == 0);
-  free (tree);
-}
-
-int indent_num = 0;
-
-void
-bintree_print_sub (void (*print) (int, void *), struct bintree_node *subroot)
-{
-  if (subroot == NULL)
-    return;
-
-  if (subroot->bl_right)
-    {
-      indent_num++;
-      bintree_print_sub (print, subroot->bl_right);
-      indent_num--;
-    }
-
-  (*print) (indent_num, subroot->data);
-
-  if (subroot->bl_left)
-    {
-      indent_num++;
-      bintree_print_sub (print, subroot->bl_left);
-      indent_num--;
-    }
-}
-
-void
-bintree_print (void (*print) (int, void *), struct bintree *tree)
-{
-  indent_num = 0;
-  bintree_print_sub (print, tree->root);
-}
-
-

+ 0 - 47
ospf6d/ospf6_bintree.h

@@ -1,47 +0,0 @@
-
-#ifndef _BINTREE_H_
-#define _BINTREE_H_
-
-struct bintree_node
-{
-  struct bintree *tree;
-
-  struct bintree_node *parent;
-  int parent_link;
-
-#define BL_LEFT  0
-#define BL_RIGHT 1
-#define BL_MAX   2
-  struct bintree_node *link[BL_MAX];
-#define bl_left  link[BL_LEFT]
-#define bl_right link[BL_RIGHT]
-
-  void *data;
-};
-
-struct bintree
-{
-  int count;
-  struct bintree_node *root;
-
-  int  (*cmp)   (void *, void *);
-};
-
-void *bintree_lookup (void *data, struct bintree *tree);
-void *bintree_lookup_min (struct bintree *tree);
-void *bintree_lookup_max (struct bintree *tree);
-
-int   bintree_add (void *data, struct bintree *tree);
-int   bintree_remove (void *data, struct bintree *tree);
-
-void bintree_head (struct bintree *tree, struct bintree_node *node);
-int  bintree_end (struct bintree_node *node);
-void bintree_next (struct bintree_node *node);
-
-struct bintree *bintree_create ();
-void bintree_delete (struct bintree *);
-
-void bintree_print (void (*print) (int, void *), struct bintree *);
-
-#endif /*_BINTREE_H_*/
-

+ 0 - 748
ospf6d/ospf6_damp.c

@@ -1,748 +0,0 @@
-/*
- * OSPF flap dampening by Manav Bhatia
- * Copyright (C) 2002 
- * 
- * This file is part of GNU Zebra.
- * 
- * GNU Zebra is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2, or (at your option) any
- * later version.
- * 
- * GNU Zebra is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with GNU Zebra; see the file COPYING.  If not, write to the Free
- * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.  
- */
-
-#include <zebra.h>
-#include <math.h>
-
-#include "log.h"
-#include "prefix.h"
-#include "thread.h"
-#include "table.h"
-#include "command.h"
-#include "vty.h"
-
-extern struct thread_master *master;
-
-#include "ospf6_damp.h"
-
-#ifdef HAVE_OSPF6_DAMP
-
-#define DELTA_REUSE         10 /* Time granularity for reuse lists */
-#define DELTA_T              5 /* Time granularity for decay arrays */
-#define DEFAULT_HALF_LIFE   60 /* (sec)     1 min */
-
-#define DEFAULT_PENALTY   1000
-#define DEFAULT_REUSE      750
-#define DEFAULT_SUPPRESS  2000
-
-#define REUSE_LIST_SIZE    256
-#define REUSE_ARRAY_SIZE  1024
-
-/* Global variable to access damping configuration */
-struct ospf6_damp_config damp_config;
-struct ospf6_damp_config *dc = &damp_config;
-u_int reuse_array_offset = 0;
-struct route_table *damp_info_table[OSPF6_DAMP_TYPE_MAX];
-struct thread *ospf6_reuse_thread = NULL;
-
-int ospf6_damp_debug = 0;
-#define IS_OSPF6_DEBUG_DAMP (ospf6_damp_debug)
-
-static struct ospf6_damp_info *
-ospf6_damp_lookup (u_short type, struct prefix *name)
-{
-  struct route_node *node;
-
-  node = route_node_lookup (damp_info_table[type], name);
-  if (node && node->info)
-    return (struct ospf6_damp_info *) node->info;
-  return NULL;
-}
-
-static struct ospf6_damp_info *
-ospf6_damp_create (u_short type, struct prefix *name)
-{
-  struct route_node *node;
-  struct ospf6_damp_info *di;
-  char namebuf[64];
-
-  di = ospf6_damp_lookup (type, name);
-  if (di)
-    return di;
-
-  if (IS_OSPF6_DEBUG_DAMP)
-    {
-      prefix2str (name, namebuf, sizeof (namebuf));
-      zlog_info ("DAMP: create: type: %d, name: %s", type, namebuf);
-    }
-
-  di = (struct ospf6_damp_info *)
-    malloc (sizeof (struct ospf6_damp_info));
-  memset (di, 0, sizeof (struct ospf6_damp_info));
-  di->type = type;
-  prefix_copy (&di->name, name);
-
-  node = route_node_get (damp_info_table[type], name);
-  node->info = di;
-
-  return di;
-}
-
-static void
-ospf6_damp_delete (u_short type, struct prefix *name)
-{
-  struct route_node *node;
-  struct ospf6_damp_info *di;
-  char namebuf[64];
-
-  node = route_node_lookup (damp_info_table[type], name);
-  if (! node || ! node->info)
-    return;
-
-  di = node->info;
-
-  if (IS_OSPF6_DEBUG_DAMP)
-    {
-      prefix2str (&di->name, namebuf, sizeof (namebuf));
-      zlog_info ("DAMP: delete: type: %d, name: %s",
-                 di->type, namebuf);
-    }
-
-  node->info = NULL;
-  free (di);
-}
-
-/* compute and fill the configuration parameter */
-void
-ospf6_damp_init_config (u_int half_life, u_int reuse,
-                        u_int suppress, u_int t_hold)
-{
-  int i;
-  double max_ratio, max_ratio1, max_ratio2;
-
-  dc->half_life = half_life ? half_life : DEFAULT_HALF_LIFE;
-  dc->reuse     = reuse     ? reuse     : DEFAULT_REUSE;
-  dc->suppress  = suppress  ? suppress  : DEFAULT_SUPPRESS;
-  dc->t_hold    = t_hold    ? t_hold    : 4 * dc->half_life;
-
-  /* Initialize system-wide params */
-  dc->delta_t = DELTA_T;
-  dc->delta_reuse = DELTA_REUSE;
-  dc->default_penalty = DEFAULT_PENALTY;
-  dc->reuse_index_array_size = REUSE_ARRAY_SIZE;
-
-  /* ceiling is the maximum penalty a route may attain */
-  /* ceiling = reuse * 2^(T-hold/half-life) */
-  dc->ceiling = (int)
-    (dc->reuse * (pow (2, (double) dc->t_hold / dc->half_life)));
-
-  /* Decay-array computations */
-  /* decay_array_size = decay memory/time granularity */
-  dc->decay_array_size = ceil ((double) dc->t_hold / dc->delta_t);
-  dc->decay_array = malloc (sizeof (double) * (dc->decay_array_size));
-
-  /* Each i-th element is per tick delay raised to the i-th power */
-  dc->decay_array[0] = 1.0;
-  dc->decay_array[1] = exp ((1.0 / (dc->half_life / dc->delta_t)) * log (0.5));
-  for (i = 2; i < dc->decay_array_size; i++)
-    dc->decay_array[i] = dc->decay_array[i - 1] * dc->decay_array[1];
-
-  /* Reuse-list computations (reuse queue head array ?) */
-  dc->reuse_list_size = ceil ((double) dc->t_hold / dc->delta_reuse) + 1;
-  if (dc->reuse_list_size == 0 || dc->reuse_list_size > REUSE_LIST_SIZE)
-    dc->reuse_list_size = REUSE_LIST_SIZE;
-  dc->reuse_list_array = (struct ospf6_damp_info **)
-    malloc (dc->reuse_list_size * sizeof (struct ospf6_reuse_list *));
-  memset (dc->reuse_list_array, 0x00,
-          dc->reuse_list_size * sizeof (struct ospf6_reuse_list *));
-
-  /* Reuse-array computations */
-  dc->reuse_index_array = malloc (sizeof (int) * dc->reuse_index_array_size);
-
-  /*
-   * This is the maximum ratio between the current value of the penalty and
-   * the reuse value which can be indexed by the reuse array. It will be 
-   * limited by the ceiling or by the amount of time that the reuse list 
-   * covers 
-   */
-  max_ratio1 = (double) dc->ceiling / dc->reuse;
-  max_ratio2 = exp ((double) dc->t_hold / dc->half_life) * log10 (2.0);
-  max_ratio = (max_ratio2 != 0 && max_ratio2 < max_ratio1 ?
-               max_ratio2 : max_ratio1);
-
-  /*
-   * reuse array is just an estimator and we need something
-   * to use the full array 
-   */
-  dc->scale_factor = (double) dc->reuse_index_array_size / (max_ratio - 1);
-
-  for (i = 0; i < dc->reuse_index_array_size; i++)
-    {
-      dc->reuse_index_array[i] = (int)
-        (((double) dc->half_life / dc->delta_reuse) *
-         log10 (1.0 / (dc->reuse * (1.0 + ((double) i / dc->scale_factor))))
-         / log10 (0.5));
-    }
-
-  dc->enabled = ON;
-}
-
-static double
-ospf6_damp_decay (time_t tdiff)
-{
-  int index = tdiff / dc->delta_t;
-
-  if (index >= dc->decay_array_size)
-    return 0;
-
-  return dc->decay_array[index];
-}
-
-static int
-ospf6_damp_reuse_index (int penalty)
-{
-  int index;
-
-  index = (int) (((double) penalty / dc->reuse - 1.0) * dc->scale_factor);
-
-  if (index >= dc->reuse_index_array_size)
-    index = dc->reuse_index_array_size - 1;
-
-  return (dc->reuse_index_array[index] - dc->reuse_index_array[0]);
-}
-
-static int
-ospf6_reuse_list_lookup (struct ospf6_damp_info *di)
-{
-  struct ospf6_damp_info *info;
-
-  for (info = dc->reuse_list_array[di->index]; info; info = info->next)
-    {
-      if (info == di)
-        return 1;
-    }
-  return 0;
-}
-
-static void
-ospf6_reuse_list_remove (struct ospf6_damp_info *di)
-{
-  if (di->prev)
-    di->prev->next = di->next;
-  else
-    dc->reuse_list_array[di->index] = di->next;
-  if (di->next)
-    di->next->prev = di->prev;
-
-  di->index = -1;
-  di->prev = NULL;
-  di->next = NULL;
-}
-
-static void
-ospf6_reuse_list_add (struct ospf6_damp_info *di)
-{
-  /* set the index of reuse-array */
-  di->index = (reuse_array_offset + (ospf6_damp_reuse_index (di->penalty)))
-              % dc->reuse_list_size;
-
-  /* insert to the head of the reuse list */
-  di->next = dc->reuse_list_array[di->index];
-  if (di->next)
-    di->next->prev = di;
-  di->prev = NULL;
-  dc->reuse_list_array[di->index] = di;
-}
-
-/* When we quit damping for a target, we should execute proper event
-   which have been postponed during damping */
-static void
-ospf6_damp_stop (struct ospf6_damp_info *di)
-{
-  time_t t_now;
-  char namebuf[64];
-  struct timeval now;
-
-  if (IS_OSPF6_DEBUG_DAMP)
-    {
-      t_now = time (NULL);
-      prefix2str (&di->name, namebuf, sizeof (namebuf));
-      gettimeofday (&now, NULL);
-      zlog_info ("DAMP: %lu.%06lu stop damping: %ld: type: %d, name: %s",
-                 now.tv_sec, now.tv_usec,
-                 (long)t_now, di->type, namebuf);
-    }
-
-  /* set flag indicates that we're damping this target */
-  di->damping = OFF;
-
-  /* if the target's current status differ from that it should be,
-     execute the proper event to repair his status */
-  if (di->target_status != di->event_type)
-    {
-      (*(di->event)) (di->target);
-      di->target_status = di->event_type;
-
-      di->event = NULL;
-      di->event_type = event_none;
-    }
-}
-
-/* ospf6_reuse_timer is called every DELTA_REUSE seconds.
-   Each route in the current reuse-list is evaluated
-   and is used or requeued */
-int
-ospf6_damp_reuse_timer (struct thread *t)
-{
-  struct ospf6_damp_info *di, *next;
-  time_t t_now, t_diff;
-  char namebuf[64];
-  struct timeval now;
-
-  /* Restart the reuse timer */
-  ospf6_reuse_thread =
-    thread_add_timer (master, ospf6_damp_reuse_timer, NULL, dc->delta_reuse);
-
-  t_now = time (NULL);
-
-  /* get the damp info list head */
-  di = dc->reuse_list_array[reuse_array_offset];
-  dc->reuse_list_array[reuse_array_offset] = NULL;