Merge svn revisions 1208, 1222 and 1228 from Zebra cvs.
diff --git a/ospf6d/ChangeLog b/ospf6d/ChangeLog
index 27593b3..044d1fa 100644
--- a/ospf6d/ChangeLog
+++ b/ospf6d/ChangeLog
@@ -49,6 +49,15 @@
 	
 2004-10-06  Yasuhiro Ohara  <yasu@sfc.wide.ad.jp>
 
+	* ospf6_snmp.c: add partial support for SNMP
+	(i.e. ospfv3AreaLsdbTable).
+	* OSPFv3-MIB.txt: Net-SNMP translate Unsigned32 range
+	(0..'FFFFFFFF'h) incorrectly to (0..-1). Those parts for
+	Unsigned32 range are changed to (0..4294967295).
+	Also, doubtful 'not-accessible's are changed to read-only.
+
+2004-10-06  Yasuhiro Ohara  <yasu@sfc.wide.ad.jp>
+
 	* ospf6_snmp.[ch], OSPFV3-MIB.txt: start supporting SNMP.
 	it follows draft-ietf-ospf-ospfv3-mib-08.txt, but change
 	OSPFv3 tree to {experimental 102} based on
diff --git a/ospf6d/OSPFV3-MIB.txt b/ospf6d/OSPFv3-MIB.txt
similarity index 98%
rename from ospf6d/OSPFV3-MIB.txt
rename to ospf6d/OSPFv3-MIB.txt
index ee66cff..80e6cb2 100644
--- a/ospf6d/OSPFV3-MIB.txt
+++ b/ospf6d/OSPFv3-MIB.txt
@@ -1,7 +1,7 @@
 OSPFV3-MIB DEFINITIONS ::= BEGIN 
  
 IMPORTS 
-        MODULE-IDENTITY, OBJECT-TYPE, mib-2, 
+        MODULE-IDENTITY, OBJECT-TYPE, mib-2, experimental,
         Counter32, Gauge32, Integer32, IpAddress, 
         Unsigned32 
                 FROM SNMPv2-SMI 
@@ -45,7 +45,7 @@
          REVISION "200404081200Z" 
          DESCRIPTION -- RFC Editor assigns RFC xxxx 
              "Initial version, published as RFC xxxx" 
-         ::= { mib-2 xx } -- IANA assigns xx 
+         ::= { experimental 102 } -- IANA assigns xx 
  
 -- Texual conventions 
  
@@ -62,7 +62,7 @@
             "The range of intervals in seconds that a routers hello 
             must have not been seen before a neighbor declares the 
             router down" 
-         SYNTAX        Integer32 (1..ÆFFFFÆh) 
+         SYNTAX        Integer32 (1..'FFFF'h) 
 
  
 -- Top-level structure of MIB 
@@ -420,7 +420,7 @@
  
 ospfv3AreaId OBJECT-TYPE 
         SYNTAX          AreaID 
-        MAX-ACCESS      not-accessible 
+        MAX-ACCESS      read-only 
         STATUS          current 
         DESCRIPTION 
             "A 32-bit integer uniquely identifying an area. 
@@ -654,8 +654,8 @@
         } 
  
 ospfv3AsLsdbType OBJECT-TYPE 
-        SYNTAX          Unsigned32(0..'FFFFFFFF'h) 
-        MAX-ACCESS      not-accessible 
+        SYNTAX          Unsigned32 (0..4294967295)
+        MAX-ACCESS      read-only 
         STATUS          current 
         DESCRIPTION 
             "The type of the link state advertisement. 
@@ -666,7 +666,7 @@
  
 ospfv3AsLsdbRouterId OBJECT-TYPE 
         SYNTAX          RouterID 
-        MAX-ACCESS      not-accessible 
+        MAX-ACCESS      read-only 
         STATUS          current 
         DESCRIPTION 
             "The 32 bit number that uniquely identifies the 
@@ -677,7 +677,7 @@
  
 ospfv3AsLsdbLsid OBJECT-TYPE 
         SYNTAX          IpAddress 
-        MAX-ACCESS      not-accessible 
+        MAX-ACCESS      read-only 
         STATUS          current 
         DESCRIPTION 
             "The Link State ID is an LS Type Specific field 
@@ -806,7 +806,7 @@
  
 ospfv3AreaLsdbAreaId OBJECT-TYPE 
         SYNTAX          AreaID 
-        MAX-ACCESS      not-accessible 
+        MAX-ACCESS      read-only 
         STATUS          current 
         DESCRIPTION 
             "The 32 bit identifier of the Area from which the 
@@ -816,8 +816,8 @@
         ::= { ospfv3AreaLsdbEntry 1 } 
  
 ospfv3AreaLsdbType OBJECT-TYPE 
-        SYNTAX          Unsigned32(0..'FFFFFFFF'h) 
-        MAX-ACCESS      not-accessible 
+        SYNTAX          Unsigned32 (0..4294967295)
+        MAX-ACCESS      read-only 
         STATUS          current 
         DESCRIPTION 
             "The type  of  the  link  state  advertisement. 
@@ -828,7 +828,7 @@
  
 ospfv3AreaLsdbRouterId OBJECT-TYPE 
         SYNTAX          RouterID 
-        MAX-ACCESS      not-accessible 
+        MAX-ACCESS      read-only 
         STATUS          current 
         DESCRIPTION 
             "The 32 bit number that uniquely identifies the 
@@ -839,7 +839,7 @@
  
 ospfv3AreaLsdbLsid OBJECT-TYPE 
         SYNTAX          IpAddress 
-        MAX-ACCESS      not-accessible 
+        MAX-ACCESS      read-only 
         STATUS          current 
         DESCRIPTION 
             "The Link State ID is an LS Type Specific field 
@@ -967,7 +967,7 @@
  
 ospfv3LinkLsdbIfIndex OBJECT-TYPE 
         SYNTAX         InterfaceIndex 
-        MAX-ACCESS     not-accessible 
+        MAX-ACCESS     read-only 
         STATUS         current 
         DESCRIPTION 
             "The identifier of the link from which the LSA 
@@ -977,8 +977,8 @@
         ::= { ospfv3LinkLsdbEntry 1 } 
  
 ospfv3LinkLsdbType OBJECT-TYPE 
-        SYNTAX          Unsigned32(0..'FFFFFFFF'h) 
-        MAX-ACCESS      not-accessible 
+        SYNTAX          Unsigned32 (0..4294967295)
+        MAX-ACCESS      read-only 
         STATUS          current 
         DESCRIPTION 
             "The type of the link state advertisement. 
@@ -989,7 +989,7 @@
  
 ospfv3LinkLsdbRouterId OBJECT-TYPE 
         SYNTAX          RouterID 
-        MAX-ACCESS      not-accessible 
+        MAX-ACCESS      read-only 
         STATUS          current 
         DESCRIPTION 
             "The 32 bit number that uniquely identifies the 
@@ -1000,7 +1000,7 @@
  
 ospfv3LinkLsdbLsid OBJECT-TYPE 
         SYNTAX        IpAddress 
-        MAX-ACCESS    not-accessible 
+        MAX-ACCESS    read-only 
         STATUS        current 
         DESCRIPTION 
             "The Link State ID is an LS Type Specific field 
@@ -1125,7 +1125,7 @@
  
 ospfv3HostAddressType OBJECT-TYPE 
         SYNTAX          InetAddressType 
-        MAX-ACCESS      not-accessible 
+        MAX-ACCESS      read-only 
         STATUS          current 
         DESCRIPTION 
             "The address type of ospfv3HostAddress. Only IPv6 
@@ -1138,7 +1138,7 @@
  
 ospfv3HostAddress OBJECT-TYPE 
         SYNTAX          InetAddress (SIZE (16)) 
-        MAX-ACCESS      not-accessible 
+        MAX-ACCESS      read-only 
         STATUS          current 
         DESCRIPTION 
             "The IPv6 Address of the Host. Must be a Global 
@@ -1259,7 +1259,7 @@
  
 ospfv3IfIndex OBJECT-TYPE 
         SYNTAX          InterfaceIndex 
-        MAX-ACCESS      not-accessible 
+        MAX-ACCESS      read-only 
         STATUS          current 
         DESCRIPTION 
             "The interface index of this OSPFv3 interface. 
@@ -1608,7 +1608,7 @@
  
 ospfv3VirtIfAreaId OBJECT-TYPE 
         SYNTAX          AreaID 
-        MAX-ACCESS      not-accessible 
+        MAX-ACCESS      read-only 
         STATUS          current 
         DESCRIPTION 
             "The  Transit  Area  that  the   Virtual   Link 
@@ -1617,7 +1617,7 @@
  
 ospfv3VirtIfNeighbor OBJECT-TYPE 
         SYNTAX          RouterID 
-        MAX-ACCESS      not-accessible 
+        MAX-ACCESS      read-only 
         STATUS          current 
         DESCRIPTION 
             "The Router ID of the Virtual Neighbor." 
@@ -1805,7 +1805,7 @@
  
 ospfv3NbrIfIndex OBJECT-TYPE 
         SYNTAX          InterfaceIndex 
-        MAX-ACCESS      not-accessible 
+        MAX-ACCESS      read-only 
         STATUS          current 
         DESCRIPTION 
             "The local link ID of the link over which the 
@@ -1814,7 +1814,7 @@
  
 ospfv3NbrRtrId OBJECT-TYPE 
         SYNTAX          RouterID 
-        MAX-ACCESS      not-accessible 
+        MAX-ACCESS      read-only 
         STATUS          current 
         DESCRIPTION 
             "A 32-bit integer (represented as a type  IpAd- 
@@ -2018,7 +2018,7 @@
  
 ospfv3NbmaNbrIfIndex OBJECT-TYPE 
         SYNTAX          InterfaceIndex 
-        MAX-ACCESS      not-accessible 
+        MAX-ACCESS      read-only 
         STATUS          current 
         DESCRIPTION 
             "The local link ID of the link over which the 
@@ -2027,7 +2027,7 @@
  
 ospfv3NbmaNbrAddressType OBJECT-TYPE 
         SYNTAX          InetAddressType 
-        MAX-ACCESS      not-accessible 
+        MAX-ACCESS      read-only 
         STATUS          current 
         DESCRIPTION 
             "The address type of ospfv3NbrAddress. Only IPv6 
@@ -2036,7 +2036,7 @@
  
 ospfv3NbmaNbrAddress OBJECT-TYPE 
         SYNTAX          InetAddress (SIZE (16)) 
-        MAX-ACCESS      not-accessible 
+        MAX-ACCESS      read-only 
         STATUS          current 
         DESCRIPTION 
             "The IPv6 address of the neighbor associated with 
@@ -2173,7 +2173,7 @@
  
 ospfv3VirtNbrArea OBJECT-TYPE 
         SYNTAX          AreaID 
-        MAX-ACCESS      not-accessible 
+        MAX-ACCESS      read-only 
         STATUS          current 
         DESCRIPTION 
             "The Transit Area Identifier." 
@@ -2181,7 +2181,7 @@
  
 ospfv3VirtNbrRtrId OBJECT-TYPE 
         SYNTAX          RouterID 
-        MAX-ACCESS      not-accessible 
+        MAX-ACCESS      read-only 
         STATUS          current 
         DESCRIPTION 
             "A  32-bit  integer  uniquely  identifying  the 
@@ -2378,7 +2378,7 @@
  
 ospfv3AreaAggregateAreaID OBJECT-TYPE 
         SYNTAX          AreaID 
-        MAX-ACCESS      not-accessible 
+        MAX-ACCESS      read-only 
         STATUS          current 
         DESCRIPTION 
             "The Area the Address Aggregate is to be  found 
@@ -2392,7 +2392,7 @@
                         interAreaPrefixLsa(8195), -- 0x2003 
                         nssaExternalLsa(8199)     -- 0x2007 
                         } 
-        MAX-ACCESS      not-accessible 
+        MAX-ACCESS      read-only 
         STATUS          current 
         DESCRIPTION 
             "The type of the Address Aggregate.  This field 
@@ -2405,7 +2405,7 @@
  
 ospfv3AreaAggregatePrefixType OBJECT-TYPE 
         SYNTAX          InetAddressType 
-        MAX-ACCESS      not-accessible 
+        MAX-ACCESS      read-only 
         STATUS          current 
         DESCRIPTION 
             "The prefix type of ospfv3AreaAggregatePrefix. Only 
@@ -2414,7 +2414,7 @@
  
 ospfv3AreaAggregatePrefix OBJECT-TYPE 
         SYNTAX          InetAddress (SIZE (0..16)) 
-        MAX-ACCESS      not-accessible 
+        MAX-ACCESS      read-only 
         STATUS          current 
         DESCRIPTION 
             "The IPv6 Prefix." 
@@ -2425,7 +2425,7 @@
 ospfv3AreaAggregatePrefixLength OBJECT-TYPE 
         SYNTAX          InetAddressPrefixLength (3..128) 
         UNITS           "bits" 
-        MAX-ACCESS      not-accessible 
+        MAX-ACCESS      read-only 
         STATUS          current 
         DESCRIPTION 
             "The length of the prefix (in bits). A prefix can 
diff --git a/ospf6d/ospf6_lsa.c b/ospf6d/ospf6_lsa.c
index 48f79af..4d3287d 100644
--- a/ospf6d/ospf6_lsa.c
+++ b/ospf6d/ospf6_lsa.c
@@ -97,6 +97,9 @@
   else
     handler = vector_slot (ospf6_lsa_handler_vector, index);
 
+  if (handler == NULL)
+    handler = &unknown_handler;
+
   return handler;
 }
 
diff --git a/ospf6d/ospf6_lsa.h b/ospf6d/ospf6_lsa.h
index c23d6f7..014d423 100644
--- a/ospf6d/ospf6_lsa.h
+++ b/ospf6d/ospf6_lsa.h
@@ -148,6 +148,10 @@
   u_char debug;
 };
 
+extern struct ospf6_lsa_handler unknown_handler;
+#define OSPF6_LSA_IS_KNOWN(type) \
+  (ospf6_get_lsa_handler (type) != &unknown_handler ? 1 : 0)
+
 /* Macro for LSA Origination */
 /* addr is (struct prefix *) */
 #define CONTINUE_IF_ADDRESS_LINKLOCAL(debug,addr)      \
@@ -236,6 +240,8 @@
                                    u_int32_t adv_router, void *scope);
 
 void ospf6_install_lsa_handler (struct ospf6_lsa_handler *handler);
+struct ospf6_lsa_handler *ospf6_get_lsa_handler (u_int16_t type);
+
 void ospf6_lsa_init ();
 void ospf6_lsa_cmd_init ();
 
diff --git a/ospf6d/ospf6_lsdb.c b/ospf6d/ospf6_lsdb.c
index d20e9a1..aad6cfc 100644
--- a/ospf6d/ospf6_lsdb.c
+++ b/ospf6d/ospf6_lsdb.c
@@ -258,6 +258,81 @@
   return (struct ospf6_lsa *) node->info;
 }
 
+/* Macro version of check_bit (). */
+#define CHECK_BIT(X,P) ((((u_char *)(X))[(P) / 8]) >> (7 - ((P) % 8)) & 1)
+
+struct ospf6_lsa *
+ospf6_lsdb_lookup_next (u_int16_t type, u_int32_t id, u_int32_t adv_router,
+                        struct ospf6_lsdb *lsdb)
+{
+  struct route_node *node;
+  struct route_node *matched = NULL;
+  struct prefix_ipv6 key;
+  struct prefix *p;
+
+  if (lsdb == NULL)
+    return NULL;
+
+  memset (&key, 0, sizeof (key));
+  ospf6_lsdb_set_key (&key, &type, sizeof (type));
+  ospf6_lsdb_set_key (&key, &adv_router, sizeof (adv_router));
+  ospf6_lsdb_set_key (&key, &id, sizeof (id));
+  p = (struct prefix *) &key;
+
+  {
+    char buf[64];
+    prefix2str (p, buf, sizeof (buf));
+    zlog_info ("lsdb_lookup_next: key: %s", buf);
+  }
+
+  node = lsdb->table->top;
+  /* walk down tree. */
+  while (node && node->p.prefixlen <= p->prefixlen &&
+         prefix_match (&node->p, p))
+    {
+      matched = node;
+      node = node->link[CHECK_BIT(&p->u.prefix, node->p.prefixlen)];
+    }
+
+  if (matched)
+    node = matched;
+  else
+    node = lsdb->table->top;
+  route_lock_node (node);
+
+  /* skip to real existing entry */
+  while (node && node->info == NULL)
+    node = route_next (node);
+
+  if (! node)
+    return NULL;
+
+  if (prefix_same (&node->p, p))
+    {
+      struct route_node *prev = node;
+      struct ospf6_lsa *lsa_prev;
+      struct ospf6_lsa *lsa_next;
+
+      node = route_next (node);
+      while (node && node->info == NULL)
+        node = route_next (node);
+
+      lsa_prev = prev->info;
+      lsa_next = (node ? node->info : NULL);
+      assert (lsa_prev);
+      assert (lsa_prev->next == lsa_next);
+      if (lsa_next)
+        assert (lsa_next->prev == lsa_prev);
+      zlog_info ("lsdb_lookup_next: assert OK with previous LSA");
+    }
+
+  if (! node)
+    return NULL;
+
+  route_unlock_node (node);
+  return (struct ospf6_lsa *) node->info;
+}
+
 /* Iteration function */
 struct ospf6_lsa *
 ospf6_lsdb_head (struct ospf6_lsdb *lsdb)
@@ -292,9 +367,6 @@
   return next;
 }
 
-/* Macro version of check_bit (). */
-#define CHECK_BIT(X,P) ((((u_char *)(X))[(P) / 8]) >> (7 - ((P) % 8)) & 1)
-
 struct ospf6_lsa *
 ospf6_lsdb_type_router_head (u_int16_t type, u_int32_t adv_router,
                              struct ospf6_lsdb *lsdb)
diff --git a/ospf6d/ospf6_lsdb.h b/ospf6d/ospf6_lsdb.h
index d32f78d..6330b91 100644
--- a/ospf6d/ospf6_lsdb.h
+++ b/ospf6d/ospf6_lsdb.h
@@ -53,9 +53,12 @@
 struct ospf6_lsdb *ospf6_lsdb_create (void *data);
 void ospf6_lsdb_delete (struct ospf6_lsdb *lsdb);
 
-struct ospf6_lsa *ospf6_lsdb_lookup (u_int16_t type, u_int32_t id,
-                                     u_int32_t adv_router,
-                                     struct ospf6_lsdb *lsdb);
+struct ospf6_lsa *
+ospf6_lsdb_lookup (u_int16_t type, u_int32_t id, u_int32_t adv_router,
+                   struct ospf6_lsdb *lsdb);
+struct ospf6_lsa *
+ospf6_lsdb_lookup_next (u_int16_t type, u_int32_t id,
+                        u_int32_t adv_router, struct ospf6_lsdb *lsdb);
 
 void ospf6_lsdb_add (struct ospf6_lsa *lsa, struct ospf6_lsdb *lsdb);
 void ospf6_lsdb_remove (struct ospf6_lsa *lsa, struct ospf6_lsdb *lsdb);
diff --git a/ospf6d/ospf6_snmp.c b/ospf6d/ospf6_snmp.c
index edc8bc4..ae88a9f 100644
--- a/ospf6d/ospf6_snmp.c
+++ b/ospf6d/ospf6_snmp.c
@@ -76,6 +76,30 @@
 /* OSPFv3 MIB Area Table values. */
 #define OSPFv3AREAID                     1
 #define OSPFv3IMPORTASEXTERN             2
+#define OSPFv3AREASPFRUNS                3
+#define OSPFv3AREABDRRTRCOUNT            4
+#define OSPFv3AREAASBDRRTRCOUNT          5
+#define OSPFv3AREASCOPELSACOUNT          6
+#define OSPFv3AREASCOPELSACKSUMSUM       7
+#define OSPFv3AREASUMMARY                8
+#define OSPFv3AREASTATUS                 9
+#define OSPFv3STUBMETRIC                10
+#define OSPFv3AREANSSATRANSLATORROLE    11
+#define OSPFv3AREANSSATRANSLATORSTATE   12
+#define OSPFv3AREANSSATRANSLATORSTABILITYINTERVAL    13
+#define OSPFv3AREANSSATRANSLATOREVENTS  14
+#define OSPFv3AREASTUBMETRICTYPE        15
+
+/* OSPFv3 MIB Area Lsdb Table values. */
+#define OSPFv3AREALSDBAREAID             1
+#define OSPFv3AREALSDBTYPE               2
+#define OSPFv3AREALSDBROUTERID           3
+#define OSPFv3AREALSDBLSID               4
+#define OSPFv3AREALSDBSEQUENCE           5
+#define OSPFv3AREALSDBAGE                6
+#define OSPFv3AREALSDBCHECKSUM           7
+#define OSPFv3AREALSDBADVERTISEMENT      8
+#define OSPFv3AREALSDBTYPEKNOWN          9
 
 /* SYNTAX Status from OSPF-MIB. */
 #define OSPF_STATUS_ENABLED  1
@@ -105,6 +129,7 @@
 /* Hook functions. */
 static u_char *ospfv3GeneralGroup ();
 static u_char *ospfv3AreaEntry ();
+static u_char *ospfv3AreaLsdbEntry ();
 
 struct variable ospfv3_variables[] =
 {
@@ -155,8 +180,54 @@
   /* OSPFv3 Area Data Structure */
   {OSPFv3AREAID,                IPADDRESS, RONLY,  ospfv3AreaEntry,
    4, {1, 2, 1, 1}},
-  {OSPFv3IMPORTASEXTERN,        INTEGER,   RONLY,  ospfv3AreaEntry,
+  {OSPFv3IMPORTASEXTERN,        INTEGER,   RWRITE, ospfv3AreaEntry,
    4, {1, 2, 1, 2}},
+  {OSPFv3AREASPFRUNS,           COUNTER,   RONLY,  ospfv3AreaEntry,
+   4, {1, 2, 1, 3}},
+  {OSPFv3AREABDRRTRCOUNT,       GAUGE,     RONLY,  ospfv3AreaEntry,
+   4, {1, 2, 1, 4}},
+  {OSPFv3AREAASBDRRTRCOUNT,     GAUGE,     RONLY,  ospfv3AreaEntry,
+   4, {1, 2, 1, 5}},
+  {OSPFv3AREASCOPELSACOUNT,     GAUGE,     RONLY,  ospfv3AreaEntry,
+   4, {1, 2, 1, 6}},
+  {OSPFv3AREASCOPELSACKSUMSUM,  INTEGER,   RONLY,  ospfv3AreaEntry,
+   4, {1, 2, 1, 7}},
+  {OSPFv3AREASUMMARY,           INTEGER,   RWRITE, ospfv3AreaEntry,
+   4, {1, 2, 1, 8}},
+  {OSPFv3AREASTATUS,            INTEGER,   RWRITE, ospfv3AreaEntry,
+   4, {1, 2, 1, 9}},
+  {OSPFv3STUBMETRIC,            INTEGER,   RWRITE, ospfv3AreaEntry,
+   4, {1, 2, 1, 10}},
+  {OSPFv3AREANSSATRANSLATORROLE, INTEGER,  RWRITE, ospfv3AreaEntry,
+   4, {1, 2, 1, 11}},
+  {OSPFv3AREANSSATRANSLATORSTATE, INTEGER, RONLY,  ospfv3AreaEntry,
+   4, {1, 2, 1, 12}},
+  {OSPFv3AREANSSATRANSLATORSTABILITYINTERVAL, INTEGER, RWRITE, ospfv3AreaEntry,
+   4, {1, 2, 1, 13}},
+  {OSPFv3AREANSSATRANSLATOREVENTS, COUNTER, RONLY, ospfv3AreaEntry,
+   4, {1, 2, 1, 14}},
+  {OSPFv3AREASTUBMETRICTYPE,    INTEGER, RWRITE, ospfv3AreaEntry,
+   4, {1, 2, 1, 15}},
+
+  {OSPFv3AREALSDBAREAID,        IPADDRESS, RONLY,  ospfv3AreaLsdbEntry,
+   4, {1, 4, 1, 1}},
+  {OSPFv3AREALSDBTYPE,          GAUGE,     RONLY,  ospfv3AreaLsdbEntry,
+   4, {1, 4, 1, 2}},
+  {OSPFv3AREALSDBROUTERID,      IPADDRESS, RONLY,  ospfv3AreaLsdbEntry,
+   4, {1, 4, 1, 3}},
+  {OSPFv3AREALSDBLSID,          IPADDRESS, RONLY,  ospfv3AreaLsdbEntry,
+   4, {1, 4, 1, 4}},
+  {OSPFv3AREALSDBSEQUENCE,      INTEGER,   RONLY,  ospfv3AreaLsdbEntry,
+   4, {1, 4, 1, 5}},
+  {OSPFv3AREALSDBAGE,           INTEGER,   RONLY,  ospfv3AreaLsdbEntry,
+   4, {1, 4, 1, 6}},
+  {OSPFv3AREALSDBCHECKSUM,      INTEGER,   RONLY,  ospfv3AreaLsdbEntry,
+   4, {1, 4, 1, 7}},
+  {OSPFv3AREALSDBADVERTISEMENT, STRING,    RONLY,  ospfv3AreaLsdbEntry,
+   4, {1, 4, 1, 8}},
+  {OSPFv3AREALSDBTYPEKNOWN,     INTEGER,   RONLY,  ospfv3AreaLsdbEntry,
+   4, {1, 4, 1, 9}},
+
 };
 
 static u_char *
@@ -287,6 +358,169 @@
   return NULL;
 }
 
+static u_char *
+ospfv3AreaLsdbEntry (struct variable *v, oid *name, size_t *length,
+                     int exact, size_t *var_len, WriteMethod **write_method)
+{
+  struct ospf6_lsa *lsa = NULL;
+  struct in_addr area_id;
+  u_int16_t type;
+  struct in_addr id;
+  struct in_addr adv_router;
+  int len;
+  oid *offset;
+  int offsetlen;
+  char a[16], b[16], c[16];
+  struct ospf6_area *oa;
+  listnode node;
+
+  memset (&area_id, 0, sizeof (struct in_addr));
+  type = 0;
+  memset (&id, 0, sizeof (struct in_addr));
+  memset (&adv_router, 0, sizeof (struct in_addr));
+
+  /* Check OSPFv3 instance. */
+  if (ospf6 == NULL)
+    return NULL;
+
+  /* Get variable length. */
+  offset = name + v->namelen;
+  offsetlen = *length - v->namelen;
+
+#define OSPFV3_AREA_LSDB_ENTRY_EXACT_OFFSET \
+  (IN_ADDR_SIZE + 1 + IN_ADDR_SIZE + IN_ADDR_SIZE)
+
+  if (exact && offsetlen != OSPFV3_AREA_LSDB_ENTRY_EXACT_OFFSET)
+    return NULL;
+
+  /* Parse area-id */
+  len = (offsetlen < IN_ADDR_SIZE ? offsetlen : IN_ADDR_SIZE);
+  if (len)
+    oid2in_addr (offset, len, &area_id);
+  offset += len;
+  offsetlen -= len;
+
+  /* Parse type */
+  len = (offsetlen < 1 ? offsetlen : 1);
+  if (len)
+    type = htons (*offset);
+  offset += len;
+  offsetlen -= len;
+
+  /* Parse Router-ID */
+  len = (offsetlen < IN_ADDR_SIZE ? offsetlen : IN_ADDR_SIZE);
+  if (len)
+    oid2in_addr (offset, len, &adv_router);
+  offset += len;
+  offsetlen -= len;
+
+  /* Parse LS-ID */
+  len = (offsetlen < IN_ADDR_SIZE ? offsetlen : IN_ADDR_SIZE);
+  if (len)
+    oid2in_addr (offset, len, &id);
+  offset += len;
+  offsetlen -= len;
+
+  inet_ntop (AF_INET, &area_id, a, sizeof (a));
+  inet_ntop (AF_INET, &adv_router, b, sizeof (b));
+  inet_ntop (AF_INET, &id, c, sizeof (c));
+  zlog_info ("SNMP access by lsdb: area=%s exact=%d length=%d magic=%d"
+             " type=%#x adv_router=%s id=%s",
+             a, exact, *length, v->magic, ntohs (type), b, c);
+
+  if (exact)
+    {
+      oa = ospf6_area_lookup (area_id.s_addr, ospf6);
+      lsa = ospf6_lsdb_lookup (type, id.s_addr, adv_router.s_addr, oa->lsdb);
+    }
+  else
+    {
+      for (node = listhead (ospf6->area_list); node; nextnode (node))
+        {
+          oa = (struct ospf6_area *) getdata (node);
+
+          if (lsa)
+            continue;
+          if (ntohl (oa->area_id) < ntohl (area_id.s_addr))
+            continue;
+
+          lsa = ospf6_lsdb_lookup_next (type, id.s_addr, adv_router.s_addr,
+                                        oa->lsdb);
+          if (! lsa)
+            {
+              type = 0;
+              memset (&id, 0, sizeof (struct in_addr));
+              memset (&adv_router, 0, sizeof (struct in_addr));
+            }
+        }
+    }
+
+  if (! lsa)
+    {
+      zlog_info ("SNMP respond: No LSA to return");
+      return NULL;
+    }
+  oa = OSPF6_AREA (lsa->lsdb->data);
+
+  zlog_info ("SNMP respond: area: %s lsa: %s", oa->name, lsa->name);
+
+  /* Add Index (AreaId, Type, RouterId, Lsid) */
+  *length = v->namelen + OSPFV3_AREA_LSDB_ENTRY_EXACT_OFFSET;
+  offset = name + v->namelen;
+  oid_copy_addr (offset, (struct in_addr *) &oa->area_id, IN_ADDR_SIZE);
+  offset += IN_ADDR_SIZE;
+  *offset = ntohs (lsa->header->type);
+  offset++;
+  oid_copy_addr (offset, (struct in_addr *) &lsa->header->adv_router,
+                 IN_ADDR_SIZE);
+  offset += IN_ADDR_SIZE;
+  oid_copy_addr (offset, (struct in_addr *) &lsa->header->id, IN_ADDR_SIZE);
+  offset += IN_ADDR_SIZE;
+
+  /* Return the current value of the variable */
+  switch (v->magic)
+    {
+    case OSPFv3AREALSDBAREAID:        /* 1 */
+      area_id.s_addr = OSPF6_AREA (lsa->lsdb->data)->area_id;
+      return SNMP_IPADDRESS (area_id);
+      break;
+    case OSPFv3AREALSDBTYPE:          /* 2 */
+      return SNMP_INTEGER (ntohs (lsa->header->type));
+      break;
+    case OSPFv3AREALSDBROUTERID:      /* 3 */
+      adv_router.s_addr = lsa->header->adv_router;
+      return SNMP_IPADDRESS (adv_router);
+      break;
+    case OSPFv3AREALSDBLSID:          /* 4 */
+      id.s_addr = lsa->header->id;
+      return SNMP_IPADDRESS (id);
+      break;
+    case OSPFv3AREALSDBSEQUENCE:      /* 5 */
+      return SNMP_INTEGER (lsa->header->seqnum);
+      break;
+    case OSPFv3AREALSDBAGE:           /* 6 */
+      ospf6_lsa_age_current (lsa);
+      return SNMP_INTEGER (lsa->header->age);
+      break;
+    case OSPFv3AREALSDBCHECKSUM:      /* 7 */
+      return SNMP_INTEGER (lsa->header->checksum);
+      break;
+    case OSPFv3AREALSDBADVERTISEMENT: /* 8 */
+      *var_len = ntohs (lsa->header->length);
+      return (u_char *) lsa->header;
+      break;
+    case OSPFv3AREALSDBTYPEKNOWN:     /* 9 */
+      return SNMP_INTEGER (OSPF6_LSA_IS_KNOWN (lsa->header->type) ?
+                           SNMP_TRUE : SNMP_FALSE);
+      break;
+    default:
+      return NULL;
+      break;
+    }
+  return NULL;
+}
+
+
 /* Register OSPFv3-MIB. */
 void
 ospf6_snmp_init (struct thread_master *master)
diff --git a/ospf6d/ospf6_spf.c b/ospf6d/ospf6_spf.c
index 4f3af7c..4010a5e 100644
--- a/ospf6d/ospf6_spf.c
+++ b/ospf6d/ospf6_spf.c
@@ -487,6 +487,32 @@
   pqueue_delete (candidate_list);
 }
 
+void
+ospf6_spf_log_database (struct ospf6_area *oa)
+{
+  char *p, *end, buffer[256];
+  struct listnode *node;
+  struct ospf6_interface *oi;
+
+  p = buffer;
+  end = buffer + sizeof (buffer);
+
+  snprintf (p, end - p, "SPF on DB (#LSAs):");
+  p = (buffer + strlen (buffer) < end ? buffer + strlen (buffer) : end);
+  snprintf (p, end - p, " Area %s: %d", oa->name, oa->lsdb->count);
+  p = (buffer + strlen (buffer) < end ? buffer + strlen (buffer) : end);
+
+  for (node = listhead (oa->if_list); node; nextnode (node))
+    {
+      oi = (struct ospf6_interface *) getdata (node);
+      snprintf (p, end - p, " I/F %s: %d",
+                oi->interface->name, oi->lsdb->count);
+      p = (buffer + strlen (buffer) < end ? buffer + strlen (buffer) : end);
+    }
+
+  zlog_info ("%s", buffer);
+}
+
 int
 ospf6_spf_calculation_thread (struct thread *t)
 {
@@ -496,20 +522,20 @@
   oa = (struct ospf6_area *) THREAD_ARG (t);
   oa->thread_spf_calculation = NULL;
 
-  if (IS_OSPF6_DEBUG_SPF (PROCESS) || IS_OSPF6_DEBUG_SPF (TIME))
-    zlog_info ("SPF calculation for area %s", oa->name);
+  if (IS_OSPF6_DEBUG_SPF (PROCESS))
+    zlog_info ("SPF calculation for Area %s", oa->name);
+  if (IS_OSPF6_DEBUG_SPF (DATABASE))
+    ospf6_spf_log_database (oa);
 
   /* execute SPF calculation */
   gettimeofday (&start, (struct timezone *) NULL);
   ospf6_spf_calculation (oa->ospf6->router_id, oa->spf_table, oa);
   gettimeofday (&end, (struct timezone *) NULL);
+  timersub (&end, &start, &runtime);
 
   if (IS_OSPF6_DEBUG_SPF (PROCESS) || IS_OSPF6_DEBUG_SPF (TIME))
-    {
-      timersub (&end, &start, &runtime);
-      zlog_info ("SPF calculation for area %s: runtime %ld sec %ld usec",
-                 oa->name, runtime.tv_sec, runtime.tv_usec);
-    }
+    zlog_info ("SPF runtime: %ld sec %ld usec",
+               runtime.tv_sec, runtime.tv_usec);
 
   ospf6_intra_route_calculation (oa);
   ospf6_intra_brouter_calculation (oa);
@@ -588,6 +614,21 @@
   return CMD_SUCCESS;
 }
 
+DEFUN (debug_ospf6_spf_database,
+       debug_ospf6_spf_database_cmd,
+       "debug ospf6 spf database",
+       DEBUG_STR
+       OSPF6_STR
+       "Debug SPF Calculation\n"
+       "Log number of LSAs at SPF Calculation time\n"
+      )
+{
+  unsigned char level = 0;
+  level = OSPF6_DEBUG_SPF_DATABASE;
+  OSPF6_DEBUG_SPF_ON (level);
+  return CMD_SUCCESS;
+}
+
 DEFUN (no_debug_ospf6_spf_process,
        no_debug_ospf6_spf_process_cmd,
        "no debug ospf6 spf process",
@@ -620,6 +661,22 @@
   return CMD_SUCCESS;
 }
 
+DEFUN (no_debug_ospf6_spf_database,
+       no_debug_ospf6_spf_database_cmd,
+       "no debug ospf6 spf database",
+       NO_STR
+       DEBUG_STR
+       OSPF6_STR
+       "Debug SPF Calculation\n"
+       "Quit Logging number of LSAs at SPF Calculation time\n"
+      )
+{
+  unsigned char level = 0;
+  level = OSPF6_DEBUG_SPF_DATABASE;
+  OSPF6_DEBUG_SPF_OFF (level);
+  return CMD_SUCCESS;
+}
+
 int
 config_write_ospf6_debug_spf (struct vty *vty)
 {
@@ -627,6 +684,8 @@
     vty_out (vty, "debug ospf6 spf process%s", VNL);
   if (IS_OSPF6_DEBUG_SPF (TIME))
     vty_out (vty, "debug ospf6 spf time%s", VNL);
+  if (IS_OSPF6_DEBUG_SPF (DATABASE))
+    vty_out (vty, "debug ospf6 spf database%s", VNL);
   return 0;
 }
 
@@ -635,12 +694,16 @@
 {
   install_element (ENABLE_NODE, &debug_ospf6_spf_process_cmd);
   install_element (ENABLE_NODE, &debug_ospf6_spf_time_cmd);
+  install_element (ENABLE_NODE, &debug_ospf6_spf_database_cmd);
   install_element (ENABLE_NODE, &no_debug_ospf6_spf_process_cmd);
   install_element (ENABLE_NODE, &no_debug_ospf6_spf_time_cmd);
+  install_element (ENABLE_NODE, &no_debug_ospf6_spf_database_cmd);
   install_element (CONFIG_NODE, &debug_ospf6_spf_process_cmd);
   install_element (CONFIG_NODE, &debug_ospf6_spf_time_cmd);
+  install_element (CONFIG_NODE, &debug_ospf6_spf_database_cmd);
   install_element (CONFIG_NODE, &no_debug_ospf6_spf_process_cmd);
   install_element (CONFIG_NODE, &no_debug_ospf6_spf_time_cmd);
+  install_element (CONFIG_NODE, &no_debug_ospf6_spf_database_cmd);
 }
 
 void
diff --git a/ospf6d/ospf6_spf.h b/ospf6d/ospf6_spf.h
index c9e031b..728eec5 100644
--- a/ospf6d/ospf6_spf.h
+++ b/ospf6d/ospf6_spf.h
@@ -26,6 +26,7 @@
 extern unsigned char conf_debug_ospf6_spf;
 #define OSPF6_DEBUG_SPF_PROCESS   0x01
 #define OSPF6_DEBUG_SPF_TIME      0x02
+#define OSPF6_DEBUG_SPF_DATABASE  0x04
 #define OSPF6_DEBUG_SPF_ON(level) \
   (conf_debug_ospf6_spf |= (level))
 #define OSPF6_DEBUG_SPF_OFF(level) \