Ospf6d merge from Zebra repository with added privs stuff and merged
zclient changes.
diff --git a/ospf6d/ospf6_lsa.c b/ospf6d/ospf6_lsa.c
index 712aa68..13e9a07 100644
--- a/ospf6d/ospf6_lsa.c
+++ b/ospf6d/ospf6_lsa.c
@@ -1,6 +1,5 @@
 /*
- * LSA function
- * Copyright (C) 1999 Yasuhiro Ohara
+ * Copyright (C) 2003 Yasuhiro Ohara
  *
  * This file is part of GNU Zebra.
  *
@@ -23,73 +22,56 @@
 #include <zebra.h>
 
 /* Include other stuffs */
-#include <lib/version.h>
 #include "log.h"
-#include "getopt.h"
 #include "linklist.h"
-#include "thread.h"
 #include "command.h"
 #include "memory.h"
-#include "sockunion.h"
-#include "if.h"
-#include "prefix.h"
-#include "stream.h"
 #include "thread.h"
-#include "filter.h"
-#include "zclient.h"
-#include "table.h"
-#include "plist.h"
 
+#include "ospf6d.h"
 #include "ospf6_proto.h"
-#include "ospf6_prefix.h"
 #include "ospf6_lsa.h"
 #include "ospf6_lsdb.h"
 #include "ospf6_message.h"
-#include "ospf6_dump.h"
 
 #include "ospf6_top.h"
 #include "ospf6_area.h"
 #include "ospf6_interface.h"
 #include "ospf6_neighbor.h"
-#include "ospf6_ism.h"
-#include "ospf6_nsm.h"
-#include "ospf6_dbex.h"
 
-#define HEADER_DEPENDENCY
-#include "ospf6d.h"
-#undef HEADER_DEPENDENCY
+#include "ospf6_flood.h"
 
-/* test LSAs identity */
-static int
-ospf6_lsa_issame (struct ospf6_lsa_header__ *lsh1,
-                  struct ospf6_lsa_header__ *lsh2)
+unsigned char conf_debug_ospf6_lsa = 0;
+
+struct ospf6_lstype ospf6_lstype[OSPF6_LSTYPE_SIZE];
+
+char *ospf6_lstype_str[OSPF6_LSTYPE_SIZE] =
+  {"Unknown", "Router", "Network", "Inter-Prefix", "Inter-Router",
+   "AS-External", "Group-Membership", "Type-7", "Link", "Intra-Prefix"};
+
+char *
+ospf6_lstype_name (u_int16_t type)
 {
-  assert (lsh1 && lsh2);
+  static char buf[8];
+  int index = ntohs (type) & OSPF6_LSTYPE_FCODE_MASK;
 
-  if (lsh1->adv_router != lsh2->adv_router)
-    return 0;
+  if (index < OSPF6_LSTYPE_SIZE && ospf6_lstype_str[index])
+    return ospf6_lstype_str[index];
 
-  if (lsh1->id != lsh2->id)
-    return 0;
-
-  if (lsh1->type != lsh2->type)
-    return 0;
-
-  return 1;
+  snprintf (buf, sizeof (buf), "0x%04hx", ntohs (type));
+  return buf;
 }
 
 /* RFC2328: Section 13.2 */
 int
-ospf6_lsa_differ (struct ospf6_lsa *lsa1,
-                  struct ospf6_lsa *lsa2)
+ospf6_lsa_is_differ (struct ospf6_lsa *lsa1,
+                     struct ospf6_lsa *lsa2)
 {
-  int diff, cmplen;
+  int len;
 
-  if (! ospf6_lsa_issame (lsa1->header, lsa2->header))
-    return 1;
+  assert (OSPF6_LSA_IS_SAME (lsa1, lsa2));
 
-  /* check Options field */
-  /* xxx */
+  /* XXX, Options ??? */
 
   ospf6_lsa_age_current (lsa1);
   ospf6_lsa_age_current (lsa2);
@@ -104,26 +86,26 @@
   if (ntohs (lsa1->header->length) != ntohs (lsa2->header->length))
     return 1;
 
-  cmplen = ntohs (lsa1->header->length) - sizeof (struct ospf6_lsa_header);
-  diff = memcmp (lsa1->header + 1, lsa2->header + 1, cmplen);
-
-  return diff;
+  len = ntohs (lsa1->header->length) - sizeof (struct ospf6_lsa_header);
+  return memcmp (lsa1->header + 1, lsa2->header + 1, len);
 }
 
 int
-ospf6_lsa_match (u_int16_t type, u_int32_t id, u_int32_t adv_router,
-                 struct ospf6_lsa_header *lsh)
+ospf6_lsa_is_changed (struct ospf6_lsa *lsa1,
+                      struct ospf6_lsa *lsa2)
 {
-  if (lsh->advrtr != adv_router)
-    return 0;
+  int length;
 
-  if (lsh->ls_id != id)
-    return 0;
+  if (OSPF6_LSA_IS_MAXAGE (lsa1) ^ OSPF6_LSA_IS_MAXAGE (lsa2))
+    return 1;
+  if (ntohs (lsa1->header->length) != ntohs (lsa2->header->length))
+    return 1;
 
-  if (lsh->type != type)
-    return 0;
+  length = OSPF6_LSA_SIZE (lsa1->header) - sizeof (struct ospf6_lsa_header);
+  assert (length > 0);
 
-  return 1;
+  return memcmp (OSPF6_LSA_HEADER_END (lsa1->header),
+                 OSPF6_LSA_HEADER_END (lsa2->header), length);
 }
 
 /* ospf6 age functions */
@@ -143,7 +125,8 @@
   lsa->birth.tv_usec = now.tv_usec;
   if (ntohs (lsa->header->age) != MAXAGE)
     lsa->expire = thread_add_timer (master, ospf6_lsa_expire, lsa,
-                                    lsa->birth.tv_sec + MAXAGE - now.tv_sec);
+                                    MAXAGE + lsa->birth.tv_sec
+                                    - now.tv_sec);
   else
     lsa->expire = NULL;
   return;
@@ -163,17 +146,14 @@
 
   /* current time */
   if (gettimeofday (&now, (struct timezone *)NULL) < 0)
-    zlog_warn ("LSA: gettimeofday failed, may fail ages: %s",
+    zlog_warn ("LSA: gettimeofday failed, may fail LSA AGEs: %s",
                strerror (errno));
 
   /* calculate age */
   ulage = now.tv_sec - lsa->birth.tv_sec;
 
   /* if over MAXAGE, set to it */
-  if (ulage > MAXAGE)
-    age = MAXAGE;
-  else
-    age = ulage;
+  age = (ulage > MAXAGE ? MAXAGE : ulage);
 
   lsa->header->age = htons (age);
   return age;
@@ -189,22 +169,17 @@
   if (age > MAXAGE)
     age = MAXAGE;
   lsa->header->age = htons (age);
-  return;
 }
 
 void
 ospf6_lsa_premature_aging (struct ospf6_lsa *lsa)
 {
   /* log */
-  if (IS_OSPF6_DUMP_LSA)
-    zlog_info ("LSA: Premature aging: %s", lsa->str);
+  if (IS_OSPF6_DEBUG_LSA (ORIGINATE))
+    zlog_info ("LSA: Premature aging: %s", lsa->name);
 
-  if (lsa->expire)
-    thread_cancel (lsa->expire);
-  lsa->expire = (struct thread *) NULL;
-  if (lsa->refresh)
-    thread_cancel (lsa->refresh);
-  lsa->refresh = (struct thread *) NULL;
+  THREAD_OFF (lsa->expire);
+  THREAD_OFF (lsa->refresh);
 
   memset (&lsa->birth, 0, sizeof (struct timeval));
   thread_execute (master, ospf6_lsa_expire, lsa, 0);
@@ -213,7 +188,7 @@
 /* check which is more recent. if a is more recent, return -1;
    if the same, return 0; otherwise(b is more recent), return 1 */
 int
-ospf6_lsa_check_recent (struct ospf6_lsa *a, struct ospf6_lsa *b)
+ospf6_lsa_compare (struct ospf6_lsa *a, struct ospf6_lsa *b)
 {
   signed long seqnuma, seqnumb;
   u_int16_t cksuma, cksumb;
@@ -221,7 +196,7 @@
 
   assert (a && a->header);
   assert (b && b->header);
-  assert (ospf6_lsa_issame (a->header, b->header));
+  assert (OSPF6_LSA_IS_SAME (a, b));
 
   seqnuma = ((signed long) ntohl (a->header->seqnum))
              - (signed long) INITIAL_SEQUENCE_NUMBER;
@@ -229,8 +204,7 @@
              - (signed long) INITIAL_SEQUENCE_NUMBER;
 
   /* compare by sequence number */
-    /* xxx, care about LS sequence number wrapping */
-  recent_reason = "seqnum";
+  /* XXX, LS sequence number wrapping */
   if (seqnuma > seqnumb)
     return -1;
   else if (seqnuma < seqnumb)
@@ -244,188 +218,89 @@
   if (cksuma < cksumb)
     return 0;
 
-  /* Age check */
+  /* Update Age */
   agea = ospf6_lsa_age_current (a);
   ageb = ospf6_lsa_age_current (b);
 
-    /* MaxAge check */
-  recent_reason = "max age";
-  if (agea == OSPF6_LSA_MAXAGE && ageb != OSPF6_LSA_MAXAGE)
+  /* MaxAge check */
+  if (agea == MAXAGE && ageb != MAXAGE)
     return -1;
-  else if (agea != OSPF6_LSA_MAXAGE && ageb == OSPF6_LSA_MAXAGE)
+  else if (agea != MAXAGE && ageb == MAXAGE)
     return 1;
 
-  recent_reason = "age differ";
-  if (agea > ageb && agea - ageb >= OSPF6_LSA_MAXAGEDIFF)
+  /* Age check */
+  if (agea > ageb && agea - ageb >= MAX_AGE_DIFF)
     return 1;
-  else if (agea < ageb && ageb - agea >= OSPF6_LSA_MAXAGEDIFF)
+  else if (agea < ageb && ageb - agea >= MAX_AGE_DIFF)
     return -1;
 
   /* neither recent */
-  recent_reason = "the same instance";
   return 0;
 }
 
-int
-ospf6_lsa_lsd_num (struct ospf6_lsa_header *lsa_header)
+char *
+ospf6_lsa_printbuf (struct ospf6_lsa *lsa, char *buf, int size)
 {
-  int ldnum = 0;
-  u_int16_t len;
-
-  len = ntohs (lsa_header->length);
-  len -= sizeof (struct ospf6_lsa_header);
-  if (lsa_header->type == htons (OSPF6_LSA_TYPE_ROUTER))
-    {
-      len -= sizeof (struct ospf6_router_lsa);
-      ldnum = len / sizeof (struct ospf6_router_lsd);
-    }
-  else /* (lsa_header->type == htons (OSPF6_LSA_TYPE_NETWORK)) */
-    {
-      len -= sizeof (struct ospf6_network_lsa);
-      ldnum = len / sizeof (u_int32_t);
-    }
-
-  return ldnum;
+  char id[16], adv_router[16];
+  inet_ntop (AF_INET, &lsa->header->id, id, sizeof (id));
+  inet_ntop (AF_INET, &lsa->header->adv_router, adv_router,
+             sizeof (adv_router));
+  snprintf (buf, size, "[%s Id:%s Adv:%s]",
+            OSPF6_LSTYPE_NAME (lsa->header->type), id, adv_router);
+  return buf;
 }
 
-void *
-ospf6_lsa_lsd_get (int index, struct ospf6_lsa_header *lsa_header)
+void
+ospf6_lsa_header_print_raw (struct ospf6_lsa_header *header)
 {
-  void *p;
-  struct ospf6_router_lsa *router_lsa;
-  struct ospf6_router_lsd *router_lsd;
-  struct ospf6_network_lsa *network_lsa;
-  struct ospf6_network_lsd *network_lsd;
-
-  if (lsa_header->type == htons (OSPF6_LSA_TYPE_ROUTER))
-    {
-      router_lsa = (struct ospf6_router_lsa *) (lsa_header + 1);
-      router_lsd = (struct ospf6_router_lsd *) (router_lsa + 1);
-      router_lsd += index;
-      p = (void *) router_lsd;
-    }
-  else if (lsa_header->type == htons (OSPF6_LSA_TYPE_NETWORK))
-    {
-      network_lsa = (struct ospf6_network_lsa *) (lsa_header + 1);
-      network_lsd = (struct ospf6_network_lsd *) (network_lsa + 1);
-      network_lsd += index;
-      p = (void *) network_lsd;
-    }
-  else
-    {
-      p = (void *) NULL;
-    }
-
-  return p;
+  char id[16], adv_router[16];
+  inet_ntop (AF_INET, &header->id, id, sizeof (id));
+  inet_ntop (AF_INET, &header->adv_router, adv_router,
+             sizeof (adv_router));
+  zlog_info ("    [%s Id:%s Adv:%s]",
+             OSPF6_LSTYPE_NAME (header->type), id, adv_router);
+  zlog_info ("    Age: %4hu SeqNum: %#08lx Cksum: %04hx Len: %d",
+             ntohs (header->age), (u_long) ntohl (header->seqnum),
+             ntohs (header->checksum), ntohs (header->length));
 }
 
-/* network_lsd <-> router_lsd */
-static int
-ospf6_lsa_lsd_network_reference_match (struct ospf6_network_lsd *network_lsd1,
-                                       struct ospf6_lsa_header *lsa_header1,
-                                       struct ospf6_router_lsd *router_lsd2,
-                                       struct ospf6_lsa_header *lsa_header2)
+void
+ospf6_lsa_header_print (struct ospf6_lsa *lsa)
 {
-  if (network_lsd1->adv_router != lsa_header2->advrtr)
-    return 0;
-  if (router_lsd2->type != OSPF6_ROUTER_LSD_TYPE_TRANSIT_NETWORK)
-    return 0;
-  if (router_lsd2->neighbor_router_id != lsa_header1->advrtr)
-    return 0;
-  if (router_lsd2->neighbor_interface_id != lsa_header1->ls_id)
-    return 0;
-  return 1;
-}
-
-/* router_lsd <-> router_lsd */
-static int
-ospf6_lsa_lsd_router_reference_match (struct ospf6_router_lsd *router_lsd1,
-                                      struct ospf6_lsa_header *lsa_header1,
-                                      struct ospf6_router_lsd *router_lsd2,
-                                      struct ospf6_lsa_header *lsa_header2)
-{
-  if (router_lsd1->type != OSPF6_ROUTER_LSD_TYPE_POINTTOPOINT)
-    return 0;
-  if (router_lsd2->type != OSPF6_ROUTER_LSD_TYPE_POINTTOPOINT)
-    return 0;
-  if (router_lsd1->neighbor_router_id != lsa_header2->advrtr)
-    return 0;
-  if (router_lsd2->neighbor_router_id != lsa_header1->advrtr)
-    return 0;
-  if (router_lsd1->neighbor_interface_id != router_lsd2->interface_id)
-    return 0;
-  if (router_lsd2->neighbor_interface_id != router_lsd1->interface_id)
-    return 0;
-  return 1;
-}
-
-int
-ospf6_lsa_lsd_is_refer_ok (int index1, struct ospf6_lsa_header *lsa_header1,
-                           int index2, struct ospf6_lsa_header *lsa_header2)
-{
-  struct ospf6_router_lsd *r1, *r2;
-  struct ospf6_network_lsd *n;
-
-  r1 = (struct ospf6_router_lsd *) NULL;
-  r2 = (struct ospf6_router_lsd *) NULL;
-  n = (struct ospf6_network_lsd *) NULL;
-  if (lsa_header1->type == htons (OSPF6_LSA_TYPE_ROUTER))
-    r1 = (struct ospf6_router_lsd *) ospf6_lsa_lsd_get (index1, lsa_header1);
-  else
-    n = (struct ospf6_network_lsd *) ospf6_lsa_lsd_get (index1, lsa_header1);
-
-  if (lsa_header2->type == htons (OSPF6_LSA_TYPE_ROUTER))
-    r2 = (struct ospf6_router_lsd *) ospf6_lsa_lsd_get (index2, lsa_header2);
-  else
-    n = (struct ospf6_network_lsd *) ospf6_lsa_lsd_get (index2, lsa_header2);
-
-  if (r1 && r2)
-    return ospf6_lsa_lsd_router_reference_match (r1, lsa_header1,
-                                                 r2, lsa_header2);
-  else if (r1 && n)
-    return ospf6_lsa_lsd_network_reference_match (n, lsa_header2,
-                                                  r1, lsa_header1);
-  else if (n && r2)
-    return ospf6_lsa_lsd_network_reference_match (n, lsa_header1,
-                                                 r2, lsa_header2);
-  return 0;
+  ospf6_lsa_age_current (lsa);
+  ospf6_lsa_header_print_raw (lsa->header);
 }
 
 void
 ospf6_lsa_show (struct vty *vty, struct ospf6_lsa *lsa)
 {
-  char adv_router[64], id[64], type[32];
+  char adv_router[64], id[64];
+  int index;
 
-  assert (lsa);
-  assert (lsa->header);
+  assert (lsa && lsa->header);
 
-  ospf6_lsa_type_string (lsa->header->type, type, sizeof (type));
   inet_ntop (AF_INET, &lsa->header->id, id, sizeof (id));
   inet_ntop (AF_INET, &lsa->header->adv_router,
              adv_router, sizeof (adv_router));
 
   vty_out (vty, "%s", VTY_NEWLINE);
   vty_out (vty, "Age: %4hu Type: %s%s", ospf6_lsa_age_current (lsa),
-           type, VTY_NEWLINE);
+           OSPF6_LSTYPE_NAME (lsa->header->type), VTY_NEWLINE);
   vty_out (vty, "Link State ID: %s%s", id, VTY_NEWLINE);
   vty_out (vty, "Advertising Router: %s%s", adv_router, VTY_NEWLINE);
-  vty_out (vty, "LS Sequence Number: %#lx%s", (u_long)ntohl (lsa->header->seqnum),
-           VTY_NEWLINE);
-  vty_out (vty, "CheckSum: %#hx Length: %hu%s", ntohs (lsa->header->checksum),
+  vty_out (vty, "LS Sequence Number: %#010lx%s",
+           (u_long) ntohl (lsa->header->seqnum), VTY_NEWLINE);
+  vty_out (vty, "CheckSum: %#06hx Length: %hu%s",
+           ntohs (lsa->header->checksum),
            ntohs (lsa->header->length), VTY_NEWLINE);
 
-  {
-    struct ospf6_lsa_slot *slot;
-    slot = ospf6_lsa_slot_get (lsa->header->type);
-    if (slot)
-      {
-        (*slot->func_show) (vty, lsa);
-        vty_out (vty, "%s", VTY_NEWLINE);
-        return;
-      }
-  }
+  index = OSPF6_LSTYPE_INDEX (ntohs (lsa->header->type));
+  if (ospf6_lstype[index].show)
+    (*ospf6_lstype[index].show) (vty, lsa);
+  else
+    vty_out (vty, "%sUnknown LSA type ...%s", VTY_NEWLINE, VTY_NEWLINE);
 
-  vty_out (vty, "%sUnknown LSA type ...%s", VTY_NEWLINE, VTY_NEWLINE);
+  vty_out (vty, "%s", VTY_NEWLINE);
 }
 
 void
@@ -439,25 +314,24 @@
 void
 ospf6_lsa_show_summary (struct vty *vty, struct ospf6_lsa *lsa)
 {
-  char adv_router[16], id[16], type[16];
+  char adv_router[16], id[16];
   struct timeval now, res;
   char duration[16];
 
   assert (lsa);
   assert (lsa->header);
 
-  memset (type, 0, sizeof (type));
-  ospf6_lsa_type_string (lsa->header->type, type, 13);
   inet_ntop (AF_INET, &lsa->header->id, id, sizeof (id));
   inet_ntop (AF_INET, &lsa->header->adv_router, adv_router,
              sizeof (adv_router));
 
   gettimeofday (&now, NULL);
-  ospf6_timeval_sub (&now, &lsa->installed, &res);
-  ospf6_timeval_string_summary (&res, duration, sizeof (duration));
+  timersub (&now, &lsa->installed, &res);
+  timerstring (&res, duration, sizeof (duration));
 
   vty_out (vty, "%-12s %-15s %-15s %4hu %8lx %04hx %4hu %8s%s",
-           type, id, adv_router, ospf6_lsa_age_current (lsa),
+           OSPF6_LSTYPE_NAME (lsa->header->type),
+           id, adv_router, ospf6_lsa_age_current (lsa),
            (u_long) ntohl (lsa->header->seqnum),
            ntohs (lsa->header->checksum), ntohs (lsa->header->length),
            duration, VTY_NEWLINE);
@@ -473,7 +347,7 @@
   end = (char *) lsa->header + ntohs (lsa->header->length);
 
   vty_out (vty, "%s", VTY_NEWLINE);
-  vty_out (vty, "%s:%s", lsa->str, VTY_NEWLINE);
+  vty_out (vty, "%s:%s", lsa->name, VTY_NEWLINE);
 
   for (current = start; current < end; current ++)
     {
@@ -489,149 +363,136 @@
   vty_out (vty, "%s%s", VTY_NEWLINE, VTY_NEWLINE);
 }
 
+void
+ospf6_lsa_show_internal (struct vty *vty, struct ospf6_lsa *lsa)
+{
+  char adv_router[64], id[64];
+
+  assert (lsa && lsa->header);
+
+  inet_ntop (AF_INET, &lsa->header->id, id, sizeof (id));
+  inet_ntop (AF_INET, &lsa->header->adv_router,
+             adv_router, sizeof (adv_router));
+
+  vty_out (vty, "%s", VTY_NEWLINE);
+  vty_out (vty, "Age: %4hu Type: %s%s", ospf6_lsa_age_current (lsa),
+           OSPF6_LSTYPE_NAME (lsa->header->type), VTY_NEWLINE);
+  vty_out (vty, "Link State ID: %s%s", id, VTY_NEWLINE);
+  vty_out (vty, "Advertising Router: %s%s", adv_router, VTY_NEWLINE);
+  vty_out (vty, "LS Sequence Number: %#010lx%s",
+           (u_long) ntohl (lsa->header->seqnum), VTY_NEWLINE);
+  vty_out (vty, "CheckSum: %#06hx Length: %hu%s",
+           ntohs (lsa->header->checksum),
+           ntohs (lsa->header->length), VTY_NEWLINE);
+  vty_out (vty, "    Prev: %p This: %p Next: %p%s",
+           lsa->prev, lsa, lsa->next, VTY_NEWLINE);
+  vty_out (vty, "    Reference count: %ld%s", lsa->refcnt, VTY_NEWLINE);
+  vty_out (vty, "    Reference source: %s (%p) %s",
+           (lsa->refsrc ? lsa->refsrc->name : "None"),
+           lsa->refsrc, VTY_NEWLINE);
+  vty_out (vty, "%s", VTY_NEWLINE);
+}
+
 /* OSPFv3 LSA creation/deletion function */
 
 /* calculate LS sequence number for my new LSA.
    return value is network byte order */
-static signed long
-ospf6_lsa_seqnum_new (u_int16_t type, u_int32_t id, u_int32_t adv_router,
+u_int32_t
+ospf6_lsa_new_seqnum (u_int16_t type, u_int32_t id, u_int32_t adv_router,
                       void *scope)
 {
+  struct ospf6_lsdb *lsdb = NULL;
   struct ospf6_lsa *lsa;
-  signed long seqnum;
+  signed long seqnum = 0;
 
   /* get current database copy */
-  lsa = ospf6_lsdb_lookup (type, id, adv_router, scope);
+  lsdb = ospf6_get_scoped_lsdb (type, scope);
+  if (lsdb == NULL)
+    {
+      zlog_warn ("Can't decide scoped LSDB");
+      return ((u_int32_t) htonl (INITIAL_SEQUENCE_NUMBER));
+    }
 
   /* if current database copy not found, return InitialSequenceNumber */
-  if (!lsa)
+  lsa = ospf6_lsdb_lookup (type, id, adv_router, lsdb);
+  if (lsa == NULL)
     seqnum = INITIAL_SEQUENCE_NUMBER;
   else
     seqnum = (signed long) ntohl (lsa->header->seqnum) + 1;
 
-  return (htonl (seqnum));
+  return ((u_int32_t) htonl (seqnum));
 }
 
-#if 0
-static void
-ospf6_lsa_header_set (u_int16_t type, u_int32_t ls_id, u_int32_t advrtr,
-                      struct ospf6_lsa_header *lsa_header, int bodysize)
-{
-  /* fill LSA header */
-  lsa_header->age = 0;
-  lsa_header->type = type;
-  lsa_header->ls_id = ls_id;
-  lsa_header->advrtr = advrtr;
-  lsa_header->seqnum =
-    ospf6_lsa_seqnum_new (lsa_header->type, lsa_header->ls_id,
-                          lsa_header->advrtr);
-  lsa_header->length = htons (sizeof (struct ospf6_lsa_header) + bodysize);
-
-  /* LSA checksum */
-  ospf6_lsa_checksum (lsa_header);
-}
-#endif /*0*/
-
 struct ospf6_lsa *
-ospf6_lsa_create (struct ospf6_lsa_header *source)
+ospf6_lsa_create (struct ospf6_lsa_header *header)
 {
   struct ospf6_lsa *lsa = NULL;
-  struct ospf6_lsa_header *lsa_header = NULL;
+  struct ospf6_lsa_header *new_header = NULL;
   u_int16_t lsa_size = 0;
-  char buf_router[16], buf_id[16], typebuf[32];
 
-  /* whole length of this LSA */
-  lsa_size = ntohs (source->length);
+  /* size of the entire LSA */
+  lsa_size = ntohs (header->length);   /* XXX vulnerable */
 
   /* allocate memory for this LSA */
-  lsa_header = (struct ospf6_lsa_header *)
+  new_header = (struct ospf6_lsa_header *)
     XMALLOC (MTYPE_OSPF6_LSA, lsa_size);
-  if (! lsa_header)
-    {
-      zlog_err ("Can't allocate memory for LSA Header");
-      return (struct ospf6_lsa *) NULL;
-    }
-  memset (lsa_header, 0, lsa_size);
 
-  /* copy LSA from source */
-  memcpy (lsa_header, source, lsa_size);
+  /* copy LSA from original header */
+  memcpy (new_header, header, lsa_size);
 
   /* LSA information structure */
   /* allocate memory */
   lsa = (struct ospf6_lsa *)
-          XMALLOC (MTYPE_OSPF6_LSA, sizeof (struct ospf6_lsa));
+    XMALLOC (MTYPE_OSPF6_LSA, sizeof (struct ospf6_lsa));
   memset (lsa, 0, sizeof (struct ospf6_lsa));
 
-  lsa->lsa_hdr = (struct ospf6_lsa_hdr *) lsa_header;
-  lsa->header = (struct ospf6_lsa_header__ *) lsa_header;
-
-  lsa->summary = 0; /* this is not LSA summary */
+  lsa->header = (struct ospf6_lsa_header *) new_header;
+  lsa->headeronly = 0; /* this is not header only */
 
   /* dump string */
-  inet_ntop (AF_INET, &lsa->header->id, buf_id, sizeof (buf_id));
-  inet_ntop (AF_INET, &lsa->header->adv_router, buf_router,
-             sizeof (buf_router));
-  snprintf (lsa->str, sizeof (lsa->str), "[%s ID=%s Adv=%s]",
-            ospf6_lsa_type_string (lsa_header->type, typebuf,
-                                   sizeof (typebuf)),
-            buf_id, buf_router);
+  ospf6_lsa_printbuf (lsa, lsa->name, sizeof (lsa->name));
 
   /* calculate birth, expire and refresh of this lsa */
   ospf6_lsa_age_set (lsa);
 
-#ifdef DEBUG
-  if (IS_OSPF6_DUMP_LSA)
-    zlog_info ("Create: %s (%p/%p)", lsa->str, lsa, lsa->header);
-#endif /*DEBUG*/
+  if (IS_OSPF6_DEBUG_LSA (MEMORY))
+    zlog_info ("Create LSA Memory: %s (%p/%p)",
+               lsa->name, lsa, lsa->header);
 
   return lsa;
 }
 
 struct ospf6_lsa *
-ospf6_lsa_summary_create (struct ospf6_lsa_header__ *source)
+ospf6_lsa_create_headeronly (struct ospf6_lsa_header *header)
 {
   struct ospf6_lsa *lsa = NULL;
-  struct ospf6_lsa_header *lsa_header = NULL;
-  u_int16_t lsa_size = 0;
-  char buf_router[16], buf_id[16], typebuf[16];
-
-  /* LSA summary contains LSA Header only */
-  lsa_size = sizeof (struct ospf6_lsa_header);
+  struct ospf6_lsa_header *new_header = NULL;
 
   /* allocate memory for this LSA */
-  lsa_header = (struct ospf6_lsa_header *)
-    XMALLOC (MTYPE_OSPF6_LSA_SUMMARY, lsa_size);
-  memset (lsa_header, 0, lsa_size);
+  new_header = (struct ospf6_lsa_header *)
+    XMALLOC (MTYPE_OSPF6_LSA, sizeof (struct ospf6_lsa_header));
 
-  /* copy LSA from source */
-  memcpy (lsa_header, source, lsa_size);
+  /* copy LSA from original header */
+  memcpy (new_header, header, sizeof (struct ospf6_lsa_header));
 
   /* LSA information structure */
   /* allocate memory */
   lsa = (struct ospf6_lsa *)
-          XMALLOC (MTYPE_OSPF6_LSA_SUMMARY, sizeof (struct ospf6_lsa));
+    XMALLOC (MTYPE_OSPF6_LSA, sizeof (struct ospf6_lsa));
   memset (lsa, 0, sizeof (struct ospf6_lsa));
 
-  lsa->lsa_hdr = (struct ospf6_lsa_hdr *) lsa_header;
-  lsa->header = (struct ospf6_lsa_header__ *) lsa_header;
-  lsa->summary = 1; /* this is LSA summary */
+  lsa->header = (struct ospf6_lsa_header *) new_header;
+  lsa->headeronly = 1; /* this is header only */
 
   /* dump string */
-  inet_ntop (AF_INET, &lsa->header->id, buf_id, sizeof (buf_id));
-  inet_ntop (AF_INET, &lsa->header->adv_router, buf_router,
-             sizeof (buf_router));
-  snprintf (lsa->str, sizeof (lsa->str), "[%s Summary ID=%s Adv=%s]",
-            ospf6_lsa_type_string (lsa->header->type, typebuf,
-                                   sizeof (typebuf)),
-            buf_id, buf_router);
+  ospf6_lsa_printbuf (lsa, lsa->name, sizeof (lsa->name));
 
   /* calculate birth, expire and refresh of this lsa */
   ospf6_lsa_age_set (lsa);
 
-#ifdef DEBUG
-  if (IS_OSPF6_DUMP_LSA)
-    zlog_info ("Create: %s (%p/%p)", lsa->str, lsa, lsa->header);
-#endif /*DEBUG*/
+  if (IS_OSPF6_DEBUG_LSA (MEMORY))
+    zlog_info ("Create LSA (Header-only) Memory: %s (%p/%p)",
+               lsa->name, lsa, lsa->header);
 
   return lsa;
 }
@@ -639,40 +500,48 @@
 void
 ospf6_lsa_delete (struct ospf6_lsa *lsa)
 {
-  /* just to make sure */
-  if (lsa->lock != 0)
-    {
-      zlog_err ("Can't delete %s: lock: %ld", lsa->str, lsa->lock);
-      return;
-    }
+  assert (lsa->lock == 0);
 
   /* cancel threads */
-  if (lsa->expire)
-    thread_cancel (lsa->expire);
-  lsa->expire = (struct thread *) NULL;
-  if (lsa->refresh)
-    thread_cancel (lsa->refresh);
-  lsa->refresh = (struct thread *) NULL;
+  THREAD_OFF (lsa->expire);
+  THREAD_OFF (lsa->refresh);
 
-#ifdef DEBUG
-  if (IS_OSPF6_DUMP_LSA)
-      zlog_info ("Delete %s (%p/%p)", lsa->str, lsa, lsa->header);
-#endif /*DEBUG*/
+  if (IS_OSPF6_DEBUG_LSA (MEMORY))
+    zlog_info ("Delete LSA %s Memory: %s (%p/%p)",
+               (lsa->headeronly ? "(Header-only) " : ""),
+               lsa->name, lsa, lsa->header);
 
   /* do free */
-  if (lsa->summary)
-    XFREE (MTYPE_OSPF6_LSA_SUMMARY, lsa->header);
-  else
-    XFREE (MTYPE_OSPF6_LSA, lsa->header);
-  lsa->header = NULL;
-
-  if (lsa->summary)
-    XFREE (MTYPE_OSPF6_LSA_SUMMARY, lsa);
-  else
-    XFREE (MTYPE_OSPF6_LSA, lsa);
+  XFREE (MTYPE_OSPF6_LSA, lsa->header);
+  XFREE (MTYPE_OSPF6_LSA, lsa);
 }
 
-/* increment reference counter of  struct ospf6_lsa */
+struct ospf6_lsa *
+ospf6_lsa_copy (struct ospf6_lsa *lsa)
+{
+  struct ospf6_lsa *copy = NULL;
+
+  if (IS_OSPF6_DEBUG_LSA (MEMORY))
+    zlog_info ("Create LSA Copy from %s", lsa->name);
+
+  ospf6_lsa_age_current (lsa);
+  if (lsa->headeronly)
+    copy = ospf6_lsa_create_headeronly (lsa->header);
+  else
+    copy = ospf6_lsa_create (lsa->header);
+  assert (copy->lock == 0);
+
+  copy->installed = lsa->installed;
+  copy->originated = lsa->originated;
+  copy->scope = lsa->scope;
+
+  copy->refsrc = lsa;
+  copy->refsrc->refcnt++;
+
+  return copy;
+}
+
+/* increment reference counter of struct ospf6_lsa */
 void
 ospf6_lsa_lock (struct ospf6_lsa *lsa)
 {
@@ -680,163 +549,156 @@
   return;
 }
 
-/* decrement reference counter of  struct ospf6_lsa */
+/* decrement reference counter of struct ospf6_lsa */
 void
 ospf6_lsa_unlock (struct ospf6_lsa *lsa)
 {
   /* decrement reference counter */
-  if (lsa->lock > 0)
-    lsa->lock--;
-  else
-    zlog_warn ("Can't unlock %s: already no lock", lsa->str);
+  assert (lsa->lock > 0);
+  lsa->lock--;
 
-  if (lsa->lock == 0)
-    ospf6_lsa_delete (lsa);
+  if (lsa->lock != 0)
+    return;
+
+  if (lsa->refsrc)
+    lsa->refsrc->refcnt--;
+
+  ospf6_lsa_delete (lsa);
 }
 
 void
-ospf6_lsa_originate (u_int16_t type, u_int32_t id, u_int32_t adv_router,
-                     char *data, int data_len, void *scope)
+ospf6_lsa_originate (struct ospf6_lsa *lsa)
 {
-  char buffer[MAXLSASIZE];
-  struct ospf6_lsa_header *lsa_header;
-  struct ospf6_lsa *lsa;
   struct ospf6_lsa *old;
-
-  assert (data_len <= sizeof (buffer) - sizeof (struct ospf6_lsa_header));
-
-  lsa_header = (struct ospf6_lsa_header *) buffer;
-
-  /* Copy LSA Body */
-  memcpy (buffer + sizeof (struct ospf6_lsa_header), data, data_len);
-
-  /* Fill LSA Header */
-  lsa_header->age = 0;
-  lsa_header->type = type;
-  lsa_header->ls_id = id;
-  lsa_header->advrtr = adv_router;
-  lsa_header->seqnum =
-    ospf6_lsa_seqnum_new (lsa_header->type, lsa_header->ls_id,
-                          lsa_header->advrtr, scope);
-  lsa_header->length = htons (sizeof (struct ospf6_lsa_header) + data_len);
-
-  /* LSA checksum */
-  ospf6_lsa_checksum (lsa_header);
-
-  /* create LSA */
-  lsa = ospf6_lsa_create ((struct ospf6_lsa_header *) buffer);
-  lsa->scope = scope;
+  struct ospf6_lsdb *lsdb = NULL;
 
   /* find previous LSA */
+  lsdb = ospf6_get_scoped_lsdb (lsa->header->type, lsa->scope);
+  if (lsdb == NULL)
+    {
+      zlog_warn ("Can't decide scoped LSDB");
+      ospf6_lsa_delete (lsa);
+      return;
+    }
+
   old = ospf6_lsdb_lookup (lsa->header->type, lsa->header->id,
-                           lsa->header->adv_router, lsa->scope);
+                           lsa->header->adv_router, lsdb);
   if (old)
     {
-      /* Check if this is neither different instance nor refresh, return */
-      if (! CHECK_FLAG (old->flag, OSPF6_LSA_FLAG_REFRESH) &&
-          ! ospf6_lsa_differ (lsa, old))
+      /* If this origination is neither different instance nor refresh,
+         suppress this origination */
+      if (! CHECK_FLAG (old->flag, OSPF6_LSA_REFRESH) &&
+          ! OSPF6_LSA_IS_DIFFER (lsa, old))
         {
-          if (IS_OSPF6_DUMP_LSA)
-            zlog_info ("LSA: Suppress updating %s", lsa->str);
+          if (IS_OSPF6_DEBUG_LSA (ORIGINATE))
+            zlog_info ("Suppress updating LSA: %s", lsa->name);
           ospf6_lsa_delete (lsa);
           return;
         }
     }
 
   lsa->refresh = thread_add_timer (master, ospf6_lsa_refresh, lsa,
-                                   OSPF6_LS_REFRESH_TIME);
-  gettimeofday (&lsa->originated, NULL);
+                                   LS_REFRESH_TIME);
 
-  //if (IS_OSPF6_DUMP_LSA)
-    zlog_info ("LSA: originate %s seq: %#x age: %hu %ld.%06ld",
-               lsa->str, ntohl (lsa->header->seqnum),
-               ospf6_lsa_age_current (lsa),
-               lsa->originated.tv_sec, lsa->originated.tv_usec);
+  if (IS_OSPF6_DEBUG_LSA (ORIGINATE))
+    {
+      zlog_info ("LSA Originate:");
+      ospf6_lsa_header_print (lsa);
+    }
 
-  ospf6_dbex_remove_from_all_retrans_list (lsa);
-  ospf6_dbex_flood (lsa, NULL);
-  ospf6_lsdb_install (lsa);
+  if (old)
+    ospf6_flood_clear (old);
+  ospf6_flood_lsa (lsa, NULL);
+  ospf6_install_lsa (lsa, lsdb);
+}
+
+void
+ospf6_lsa_re_originate (struct ospf6_lsa *lsa)
+{
+  u_int16_t index;
+
+  if (IS_OSPF6_DEBUG_LSA (ORIGINATE))
+    {
+      zlog_info ("LSA Reoriginate:");
+      ospf6_lsa_header_print (lsa);
+    }
+
+  index = OSPF6_LSTYPE_INDEX (ntohs (lsa->header->type));
+  if (ospf6_lstype[index].reoriginate)
+    (*ospf6_lstype[index].reoriginate) (lsa);
+  else
+    ospf6_lsa_premature_aging (lsa);
 }
 
 
-/* ospf6_lsa expired */
+/* ospf6 lsa expiry */
 int
 ospf6_lsa_expire (struct thread *thread)
 {
   struct ospf6_lsa *lsa;
   struct ospf6_lsdb *lsdb = NULL;
-  void (*hook) (struct ospf6_lsa *, struct ospf6_lsa *);
 
   lsa = (struct ospf6_lsa *) THREAD_ARG (thread);
-  assert (lsa && lsa->lsa_hdr);
 
-  /* assertion */
-  assert (IS_LSA_MAXAGE (lsa));
-  assert (!lsa->refresh);
+  assert (lsa && lsa->header);
+  assert (OSPF6_LSA_IS_MAXAGE (lsa));
+  assert (! lsa->refresh);
 
   lsa->expire = (struct thread *) NULL;
 
-  /* log */
-  if (IS_OSPF6_DUMP_LSA)
-    zlog_info ("LSA: Expire: %s", lsa->str);
-
-  if (!lsa->summary)
+  if (IS_OSPF6_DEBUG_LSA (TIMER))
     {
-      /* reflood lsa */
-      ospf6_dbex_flood (lsa, NULL);
-
-      /* get scoped lsdb, call remove hook */
-      if (OSPF6_LSA_IS_SCOPE_LINKLOCAL (ntohs (lsa->header->type)))
-        lsdb = ((struct ospf6_interface *) lsa->scope)->lsdb;
-      else if (OSPF6_LSA_IS_SCOPE_AREA (ntohs (lsa->header->type)))
-        lsdb = ((struct ospf6_area *) lsa->scope)->lsdb;
-      else if (OSPF6_LSA_IS_SCOPE_AS (ntohs (lsa->header->type)))
-        lsdb = ((struct ospf6 *) lsa->scope)->lsdb;
-      else
-        assert (0);
-
-      /* call LSDB hook to re-process LSA */
-      hook = ospf6_lsdb_hook[ntohs (lsa->header->type) &
-                             OSPF6_LSTYPE_CODE_MASK].hook;
-      if (hook)
-        (*hook) (NULL, lsa);
-
-      /* do not free LSA, and do nothing about lslists.
-         wait event (ospf6_lsdb_check_maxage) */
+      zlog_info ("LSA Expire:");
+      ospf6_lsa_header_print (lsa);
     }
 
+  if (lsa->headeronly)
+    return 0;    /* dbexchange will do something ... */
+
+  /* reflood lsa */
+  ospf6_flood_lsa (lsa, NULL);
+
+  /* reinstall lsa */
+  lsdb = ospf6_get_scoped_lsdb (lsa->header->type, lsa->scope);
+  if (lsdb == NULL)
+    {
+      zlog_warn ("Can't decide scoped LSDB: %s", lsa->name);
+      return 0;
+    }
+  if (IS_OSPF6_DEBUG_LSA (DATABASE))
+    zlog_info ("Reinstall MaxAge %s", lsa->name);
+  ospf6_lsdb_add (lsa, lsdb);
+
+  /* schedule maxage remover */
+  ospf6_maxage_remove (ospf6);
+
   return 0;
 }
 
+/* Below will become dummy thread.
+   refresh function must be set individually per each LSAs */
 int
 ospf6_lsa_refresh (struct thread *thread)
 {
   struct ospf6_lsa *lsa;
-  struct ospf6_lsa_slot *slot;
 
   assert (thread);
-  lsa = (struct ospf6_lsa *) THREAD_ARG  (thread);
-  assert (lsa && lsa->lsa_hdr);
+  lsa = (struct ospf6_lsa *) THREAD_ARG (thread);
+  assert (lsa && lsa->header);
 
-  /* this will be used later as flag to decide really originate */
   lsa->refresh = (struct thread *) NULL;
-  SET_FLAG (lsa->flag, OSPF6_LSA_FLAG_REFRESH);
 
-  /* log */
-  if (IS_OSPF6_DUMP_LSA)
-    zlog_info ("LSA Refresh: %s", lsa->str);
+  /* this will be used later to decide really originate or not */
+  SET_FLAG (lsa->flag, OSPF6_LSA_REFRESH);
 
-  slot = ospf6_lsa_slot_get (lsa->header->type);
-  if (slot)
+  if (IS_OSPF6_DEBUG_LSA (ORIGINATE))
     {
-      zlog_info ("LSA Refresh: %s", slot->name);
-      (*slot->func_refresh) (lsa);
-      return 0;
+      zlog_info ("LSA Refresh:");
+      ospf6_lsa_header_print (lsa);
     }
 
-  zlog_warn ("Can't Refresh LSA: Unknown type: %#x",
-             ntohs (lsa->header->type));
-  return 1;
+  ospf6_lsa_re_originate (lsa);
+  return 0;
 }
 
 
@@ -885,1042 +747,205 @@
 }
 
 int
-ospf6_lsa_is_known_type (struct ospf6_lsa_header *lsa_header)
+ospf6_unknown_reoriginate (struct ospf6_lsa *lsa)
 {
-  struct ospf6_lsa_slot *slot;
-
-  slot = ospf6_lsa_slot_get (lsa_header->type);
-  if (slot)
-    return 1;
-  return 0;
-}
-
-struct ospf6_lsa_slot *slot_head = NULL;
-
-struct ospf6_lsa_slot *
-ospf6_lsa_slot_get (u_int16_t type)
-{
-  struct ospf6_lsa_slot *slot;
-
-  for (slot = slot_head; slot; slot = slot->next)
-    {
-      if (slot->type == type)
-        return slot;
-    }
-
-  return NULL;
-}
-
-int
-ospf6_lsa_slot_register (struct ospf6_lsa_slot *src)
-{
-  struct ospf6_lsa_slot *new, *slot;
-
-  slot = ospf6_lsa_slot_get (src->type);
-  if (slot)
-    {
-      if (IS_OSPF6_DUMP_LSA)
-        zlog_info ("LSA: Slot register: already exists: %#x %s",
-                   slot->type, slot->name);
-      return -1;
-    }
-
-  new = (struct ospf6_lsa_slot *)
-    XMALLOC (MTYPE_OSPF6_LSA, sizeof (struct ospf6_lsa_slot));
-  if (! new)
-    {
-      zlog_err ("Can't allocate memory for LSA slot: %s", strerror (errno));
-      return -1;
-    }
-  memset (new, 0, sizeof (struct ospf6_lsa_slot));
-  memcpy (new, src, sizeof (struct ospf6_lsa_slot));
-
-  if (IS_OSPF6_DUMP_LSA)
-    zlog_info ("LSA: Slot register: %#x %s", slot->type, slot->name);
-
-  if (slot_head == NULL)
-    {
-      new->prev = NULL;
-      new->next = NULL;
-      slot_head = new;
-      return 0;
-    }
-
-  slot = slot_head;
-  while (slot->next)
-    slot = slot->next;
-
-  slot->next = new;
-  new->prev = slot;
-
+  ospf6_lsa_premature_aging (lsa);
   return 0;
 }
 
 int
-ospf6_lsa_slot_unregister (u_int16_t type)
+ospf6_unknown_show (struct vty *vty, struct ospf6_lsa *lsa)
 {
-  struct ospf6_lsa_slot *slot;
+  u_char *start, *end, *current;
+  char byte[4];
 
-  slot = ospf6_lsa_slot_get (type);
-  if (slot == NULL)
-    {
-      if (IS_OSPF6_DUMP_LSA)
-        zlog_info ("Registering LSA slot: no such slot: %#x", type);
-      return -1;
-    }
-
-  if (IS_OSPF6_DUMP_LSA)
-    zlog_info ("Unregistering LSA Slot: %#x %s", slot->type, slot->name);
-
-  if (slot->prev)
-    slot->prev->next = slot->next;
-  if (slot->next)
-    slot->next->prev = slot->prev;
-
-  if (slot_head == slot)
-    slot_head = slot->next;
-
-  XFREE (MTYPE_OSPF6_LSA, slot);
-  return 0;
-}
-
-char *
-ospf6_lsa_type_string (u_int16_t type, char *buf, int bufsize)
-{
-  struct ospf6_lsa_slot *slot;
-
-  slot = ospf6_lsa_slot_get (type);
-  if (slot)
-    snprintf (buf, bufsize, "%s", slot->name);
-  else
-    snprintf (buf, bufsize, "Type=0x%04x", ntohs (type));
-
-  return buf;
-}
-
-
-/*******************/
-/* LSA Origination */
-/*******************/
-
-#define CONTINUE_IF_ADDRESS_LINKLOCAL(addr)\
-  if (IN6_IS_ADDR_LINKLOCAL (&(addr)->u.prefix6))\
-    {\
-      char buf[64];\
-      prefix2str (addr, buf, sizeof (buf));\
-      if (IS_OSPF6_DUMP_LSA)\
-        zlog_info ("  Filter out Linklocal: %s", buf);\
-      continue;\
-    }
-
-#define CONTINUE_IF_ADDRESS_UNSPECIFIED(addr)\
-  if (IN6_IS_ADDR_UNSPECIFIED (&(addr)->u.prefix6))\
-    {\
-      char buf[64];\
-      prefix2str (addr, buf, sizeof (buf));\
-      if (IS_OSPF6_DUMP_LSA)\
-        zlog_info ("  Filter out Unspecified: %s", buf);\
-      continue;\
-    }
-
-#define CONTINUE_IF_ADDRESS_LOOPBACK(addr)\
-  if (IN6_IS_ADDR_LOOPBACK (&(addr)->u.prefix6))\
-    {\
-      char buf[64];\
-      prefix2str (addr, buf, sizeof (buf));\
-      if (IS_OSPF6_DUMP_LSA)\
-        zlog_info ("  Filter out Loopback: %s", buf);\
-      continue;\
-    }
-
-#define CONTINUE_IF_ADDRESS_V4COMPAT(addr)\
-  if (IN6_IS_ADDR_V4COMPAT (&(addr)->u.prefix6))\
-    {\
-      char buf[64];\
-      prefix2str (addr, buf, sizeof (buf));\
-      if (IS_OSPF6_DUMP_LSA)\
-        zlog_info ("  Filter out V4Compat: %s", buf);\
-      continue;\
-    }
-
-#define CONTINUE_IF_ADDRESS_V4MAPPED(addr)\
-  if (IN6_IS_ADDR_V4MAPPED (&(addr)->u.prefix6))\
-    {\
-      char buf[64];\
-      prefix2str (addr, buf, sizeof (buf));\
-      if (IS_OSPF6_DUMP_LSA)\
-        zlog_info ("  Filter out V4Mapped: %s", buf);\
-      continue;\
-    }
-
-/******************************/
-/* RFC2740 3.4.3.1 Router-LSA */
-/******************************/
-
-char *
-ospf6_lsa_router_bits_string (u_char router_bits, char *buf, int size)
-{
-  char w, v, e, b;
-
-  w = (router_bits & OSPF6_ROUTER_LSA_BIT_W ? 'W' : '-');
-  v = (router_bits & OSPF6_ROUTER_LSA_BIT_V ? 'V' : '-');
-  e = (router_bits & OSPF6_ROUTER_LSA_BIT_E ? 'E' : '-');
-  b = (router_bits & OSPF6_ROUTER_LSA_BIT_B ? 'B' : '-');
-  snprintf (buf, size, "----%c%c%c%c", w, v, e, b);
-  return buf;
-}
-
-int
-ospf6_lsa_router_show (struct vty *vty, struct ospf6_lsa *lsa)
-{
-  char *start, *end, *current;
-  char buf[32], name[32], bits[32], options[32];
-  struct ospf6_router_lsa *router_lsa;
-  struct ospf6_router_lsd *lsdesc;
-
-  assert (lsa->header);
-
-  router_lsa = (struct ospf6_router_lsa *)
-    ((char *) lsa->header + sizeof (struct ospf6_lsa_header));
-
-  ospf6_lsa_router_bits_string (router_lsa->bits, bits, sizeof (bits));
-  ospf6_options_string (router_lsa->options, options, sizeof (options));
-  vty_out (vty, "    Bits: %s Options: %s%s", bits, options, VTY_NEWLINE);
-
-  start = (char *) router_lsa + sizeof (struct ospf6_router_lsa);
+  start = (char *) lsa->header + sizeof (struct ospf6_lsa_header);
   end = (char *) lsa->header + ntohs (lsa->header->length);
-  for (current = start; current + sizeof (struct ospf6_router_lsd) <= end;
-       current += sizeof (struct ospf6_router_lsd))
+
+  vty_out (vty, "        Unknown contents:%s", VTY_NEWLINE);
+  for (current = start; current < end; current ++)
     {
-      lsdesc = (struct ospf6_router_lsd *) current;
+      if ((current - start) % 16 == 0)
+        vty_out (vty, "%s        ", VTY_NEWLINE);
+      else if ((current - start) % 4 == 0)
+        vty_out (vty, " ");
 
-      if (lsdesc->type == OSPF6_ROUTER_LSD_TYPE_POINTTOPOINT)
-        snprintf (name, sizeof (name), "Point-To-Point");
-      else if (lsdesc->type == OSPF6_ROUTER_LSD_TYPE_TRANSIT_NETWORK)
-        snprintf (name, sizeof (name), "Transit-Network");
-      else if (lsdesc->type == OSPF6_ROUTER_LSD_TYPE_STUB_NETWORK)
-        snprintf (name, sizeof (name), "Stub-Network");
-      else if (lsdesc->type == OSPF6_ROUTER_LSD_TYPE_VIRTUAL_LINK)
-        snprintf (name, sizeof (name), "Virtual-Link");
-      else
-        snprintf (name, sizeof (name), "Unknown (%#x)", lsdesc->type);
-
-      vty_out (vty, "    Type: %s Metric: %d%s",
-               name, ntohs (lsdesc->metric), VTY_NEWLINE);
-      vty_out (vty, "    Interface ID: %s%s",
-               inet_ntop (AF_INET, &lsdesc->interface_id,
-                          buf, sizeof (buf)), VTY_NEWLINE);
-      vty_out (vty, "    Neighbor Interface ID: %s%s",
-               inet_ntop (AF_INET, &lsdesc->neighbor_interface_id,
-                          buf, sizeof (buf)), VTY_NEWLINE);
-      vty_out (vty, "    Neighbor Router ID: %s%s",
-               inet_ntop (AF_INET, &lsdesc->neighbor_router_id,
-                          buf, sizeof (buf)), VTY_NEWLINE);
+      snprintf (byte, sizeof (byte), "%02x", *current);
+      vty_out (vty, "%s", byte);
     }
+
+  vty_out (vty, "%s%s", VTY_NEWLINE, VTY_NEWLINE);
   return 0;
 }
 
-u_long
-ospf6_lsa_has_elasped (u_int16_t type, u_int32_t id,
-                       u_int32_t adv_router, void *scope)
-{
-  struct ospf6_lsa *old;
-  struct timeval now;
-
-  if (adv_router != ospf6->router_id)
-    zlog_info ("LSA: Router-ID changed ?");
-
-  old = ospf6_lsdb_lookup (type, id, adv_router, scope);
-  if (! old)
-    return OSPF6_LSA_MAXAGE;
-
-  gettimeofday (&now, NULL);
-  return ((u_long) SEC_TVDIFF (&now, &old->originated));
-}
-
-int
-ospf6_lsa_originate_router (struct thread *thread)
-{
-  char buffer [MAXLSASIZE];
-  u_int16_t size;
-  struct ospf6_area *o6a;
-  int count;
-  u_int32_t area_id;
-
-  struct ospf6_router_lsa *router_lsa;
-  struct ospf6_router_lsd *router_lsd;
-  listnode i;
-  struct ospf6_interface *o6i;
-  struct ospf6_neighbor *o6n = NULL;
-
-  area_id = (u_int32_t) THREAD_ARG (thread);
-
-  o6a = ospf6_area_lookup (area_id, ospf6);
-  if (! o6a)
-    {
-      inet_ntop (AF_INET, &area_id, buffer, sizeof (buffer));
-      if (IS_OSPF6_DUMP_LSA)
-        zlog_info ("LSA: Update Router-LSA: No such area: %s", buffer);
-      return 0;
-    }
-
-  /* clear thread */
-  o6a->thread_router_lsa = NULL;
-
-  if (IS_OSPF6_DUMP_LSA)
-    zlog_info ("LSA: originate Router-LSA for Area %s", o6a->str);
-
-  size = sizeof (struct ospf6_router_lsa);
-  memset (buffer, 0, sizeof (buffer));
-  router_lsa = (struct ospf6_router_lsa *) buffer;
-
-  OSPF6_OPT_CLEAR_ALL (router_lsa->options);
-  OSPF6_OPT_SET (router_lsa->options, OSPF6_OPT_V6);
-  OSPF6_OPT_SET (router_lsa->options, OSPF6_OPT_E);
-  OSPF6_OPT_CLEAR (router_lsa->options, OSPF6_OPT_MC);
-  OSPF6_OPT_CLEAR (router_lsa->options, OSPF6_OPT_N);
-  OSPF6_OPT_SET (router_lsa->options, OSPF6_OPT_R);
-  OSPF6_OPT_CLEAR (router_lsa->options, OSPF6_OPT_DC);
-
-  OSPF6_ROUTER_LSA_CLEAR_ALL_BITS (router_lsa);
-  OSPF6_ROUTER_LSA_CLEAR (router_lsa, OSPF6_ROUTER_LSA_BIT_B);
-
-  if (ospf6_is_asbr (o6a->ospf6))
-    OSPF6_ROUTER_LSA_SET (router_lsa, OSPF6_ROUTER_LSA_BIT_E);
-  else
-    OSPF6_ROUTER_LSA_CLEAR (router_lsa, OSPF6_ROUTER_LSA_BIT_E);
-
-  OSPF6_ROUTER_LSA_CLEAR (router_lsa, OSPF6_ROUTER_LSA_BIT_V);
-  OSPF6_ROUTER_LSA_CLEAR (router_lsa, OSPF6_ROUTER_LSA_BIT_W);
-
-  /* describe links for each interfaces */
-  router_lsd = (struct ospf6_router_lsd *) (router_lsa + 1);
-  for (i = listhead (o6a->if_list); i; nextnode (i))
-    {
-      o6i = (struct ospf6_interface *) getdata (i);
-      assert (o6i);
-
-      /* Interfaces in state Down or Loopback are not described */
-      if (o6i->state == IFS_DOWN || o6i->state == IFS_LOOPBACK)
-        continue;
-
-      /* Nor are interfaces without any full adjacencies described */
-      count = 0;
-      o6i->foreach_nei (o6i, &count, NBS_FULL, ospf6_count_state);
-      if (count == 0)
-        continue;
-
-      /* Point-to-Point interfaces */
-      if (if_is_pointopoint (o6i->interface))
-        {
-          if (listcount (o6i->neighbor_list) == 0)
-            continue;
-
-          if (listcount (o6i->neighbor_list) != 1)
-            zlog_warn ("LSA: Multiple neighbors on PoinToPoint: %s",
-                       o6i->interface->name);
-
-          o6n = (struct ospf6_neighbor *)
-                   getdata (listhead (o6i->neighbor_list));
-          assert (o6n);
-
-          router_lsd->type = OSPF6_ROUTER_LSD_TYPE_POINTTOPOINT;
-          router_lsd->metric = htons (o6i->cost);
-          router_lsd->interface_id = htonl (o6i->if_id);
-          router_lsd->neighbor_interface_id = htonl (o6n->ifid);
-          router_lsd->neighbor_router_id = o6n->router_id;
-
-          size += sizeof (struct ospf6_router_lsd);
-          router_lsd ++;
-
-          continue;
-        }
-
-      /* Broadcast and NBMA interfaces */
-      if (if_is_broadcast (o6i->interface))
-        {
-          /* If this router is not DR,
-             and If this router not fully adjacent with DR,
-             this interface is not transit yet: ignore. */
-          if (o6i->state != IFS_DR)
-            {
-              o6n = ospf6_neighbor_lookup (o6i->dr, o6i); /* find DR */
-              if (o6n == NULL || o6n->state != NBS_FULL)
-                continue;
-            }
-          else
-            {
-              count = 0;
-              o6i->foreach_nei (o6i, &count, NBS_FULL, ospf6_count_state);
-              if (count == 0)
-                continue;
-            }
-
-          router_lsd->type = OSPF6_ROUTER_LSD_TYPE_TRANSIT_NETWORK;
-          router_lsd->metric = htons (o6i->cost);
-          router_lsd->interface_id = htonl (o6i->if_id);
-          if (o6i->state != IFS_DR)
-            {
-              router_lsd->neighbor_interface_id = htonl (o6n->ifid);
-              router_lsd->neighbor_router_id = o6n->router_id;
-            }
-          else
-            {
-              router_lsd->neighbor_interface_id = htonl (o6i->if_id);
-              router_lsd->neighbor_router_id = o6i->area->ospf6->router_id;
-            }
-
-          size += sizeof (struct ospf6_router_lsd);
-          router_lsd ++;
-
-          continue;
-        }
-
-      /* Virtual links */
-        /* xxx */
-      /* Point-to-Multipoint interfaces */
-        /* xxx */
-    }
-
-  ospf6_lsa_originate (htons (OSPF6_LSA_TYPE_ROUTER),
-                       htonl (0), o6a->ospf6->router_id,
-                       (char *) router_lsa, size, o6a);
-  return 0;
-}
-
-void
-ospf6_lsa_schedule_router (struct ospf6_area *area)
-{
-  u_long elasped_time, time = 0;
-
-  if (area->thread_router_lsa)
-    {
-      if (IS_OSPF6_DUMP_LSA)
-        zlog_info ("LSA: schedule: Router-LSA for Area %s: another thread",
-                   area->str);
-      return;
-    }
-
-  elasped_time =
-    ospf6_lsa_has_elasped (htons (OSPF6_LSA_TYPE_ROUTER), htonl (0),
-                           area->ospf6->router_id, area);
-  if (elasped_time < OSPF6_MIN_LS_INTERVAL)
-    time = (u_long) (OSPF6_MIN_LS_INTERVAL - elasped_time);
-  else
-    time = 0;
-
-  if (IS_OSPF6_DUMP_LSA)
-    zlog_info ("LSA: schedule: Router-LSA for Area %s after %lu sec",
-               area->str, time);
-
-  if (time)
-    area->thread_router_lsa =
-      thread_add_timer (master, ospf6_lsa_originate_router,
-                        (void *) area->area_id, time);
-  else
-    area->thread_router_lsa =
-      thread_add_event (master, ospf6_lsa_originate_router,
-                        (void *) area->area_id, 0);
-}
-
-int
-ospf6_lsa_router_hook_neighbor (void *neighbor)
-{
-  struct ospf6_neighbor *o6n = neighbor;
-  if (o6n->ospf6_interface->area)
-    ospf6_lsa_schedule_router (o6n->ospf6_interface->area);
-  return 0;
-}
-
-int
-ospf6_lsa_router_hook_interface (void *interface)
-{
-  struct ospf6_interface *o6i = interface;
-  if (o6i->area)
-    ospf6_lsa_schedule_router (o6i->area);
-  return 0;
-}
-
-int
-ospf6_lsa_router_hook_area (void *area)
-{
-  struct ospf6_area *o6a = area;
-  ospf6_lsa_schedule_router (o6a);
-  return 0;
-}
-
-int
-ospf6_lsa_router_hook_top (void *ospf6)
-{
-  struct ospf6 *o6 = ospf6;
-  struct ospf6_area *o6a;
-  listnode node;
-
-  for (node = listhead (o6->area_list); node; nextnode (node))
-    {
-      o6a = getdata (node);
-      ospf6_lsa_schedule_router (o6a);
-    }
-  return 0;
-}
-
-int
-ospf6_lsa_router_refresh (void *old)
-{
-  struct ospf6_lsa *lsa = old;
-  struct ospf6_area *o6a;
-
-  o6a = lsa->scope;
-  ospf6_lsa_schedule_router (o6a);
-  return 0;
-}
-
-void
-ospf6_lsa_slot_register_router ()
-{
-  struct ospf6_lsa_slot slot;
-  struct ospf6_hook hook;
-
-  memset (&slot, 0, sizeof (struct ospf6_lsa_slot));
-  slot.type              = htons (OSPF6_LSA_TYPE_ROUTER);
-  slot.name              = "Router";
-  slot.func_show         = ospf6_lsa_router_show;
-  slot.func_refresh      = ospf6_lsa_router_refresh;
-  ospf6_lsa_slot_register (&slot);
-
-  ospf6_lsdb_hook[OSPF6_LSA_TYPE_ROUTER & OSPF6_LSTYPE_CODE_MASK].hook = 
-    ospf6_spf_database_hook;
-
-  memset (&hook, 0, sizeof (hook));
-  hook.name = "OriginateRouter";
-  hook.hook_change  = ospf6_lsa_router_hook_neighbor;
-  ospf6_hook_register (&hook, &neighbor_hook);
-
-  memset (&hook, 0, sizeof (hook));
-  hook.name = "OriginateRouter";
-  hook.hook_change = ospf6_lsa_router_hook_interface;
-  ospf6_hook_register (&hook, &interface_hook);
-
-  memset (&hook, 0, sizeof (hook));
-  hook.name = "OriginateRouter";
-  hook.hook_change      = ospf6_lsa_router_hook_area;
-  ospf6_hook_register (&hook, &area_hook);
-
-  memset (&hook, 0, sizeof (hook));
-  hook.name = "OriginateRouter";
-  hook.hook_change       = ospf6_lsa_router_hook_top;
-  ospf6_hook_register (&hook, &top_hook);
-}
-
-/*******************************/
-/* RFC2740 3.4.3.2 Network-LSA */
-/*******************************/
-
-int
-ospf6_lsa_network_show (struct vty *vty, struct ospf6_lsa *lsa)
-{
-  char *start, *end, *current;
-  struct ospf6_network_lsa *network_lsa;
-  u_int32_t *router_id;
-  char buf[128], options[32];
-
-  assert (lsa->header);
-  network_lsa = (struct ospf6_network_lsa *) (lsa->header + 1);
-  router_id = (u_int32_t *)(network_lsa + 1);
-
-  ospf6_options_string (network_lsa->options, options, sizeof (options));
-  vty_out (vty, "     Options: %s%s", options, VTY_NEWLINE);
-
-  start = (char *) network_lsa + sizeof (struct ospf6_network_lsa);
-  end = (char *) lsa->header + ntohs (lsa->header->length);
-  for (current = start; current + sizeof (u_int32_t) <= end;
-       current += sizeof (u_int32_t))
-    {
-      router_id = (u_int32_t *) current;
-      inet_ntop (AF_INET, router_id, buf, sizeof (buf));
-      vty_out (vty, "     Attached Router: %s%s", buf, VTY_NEWLINE);
-    }
-  return 0;
-}
-
-void
-ospf6_lsa_network_update (char *ifname)
-{
-  char buffer [MAXLSASIZE];
-  u_int16_t size;
-  struct ospf6_lsa *old;
-  struct interface *ifp;
-  struct ospf6_interface *o6i;
-  int count;
-
-  struct ospf6_network_lsa *network_lsa;
-  struct ospf6_neighbor *o6n;
-  u_int32_t *router_id;
-  listnode node;
-
-  ifp = if_lookup_by_name (ifname);
-  if (! ifp)
-    {
-      if (IS_OSPF6_DUMP_LSA)
-        zlog_warn ("Update Network: No such Interface: %s", ifname);
-      return;
-    }
-
-  o6i = (struct ospf6_interface *) ifp->info;
-  if (! o6i || ! o6i->area)
-    {
-      if (IS_OSPF6_DUMP_LSA)
-        zlog_warn ("Update Network: Interface not enabled: %s", ifname);
-      return;
-    }
-
-  /* find previous LSA */
-  old = ospf6_lsdb_lookup (htons (OSPF6_LSA_TYPE_NETWORK),
-                           htonl (o6i->if_id),
-                           o6i->area->ospf6->router_id, o6i->area);
-
-  /* Don't originate Network-LSA if not DR */
-  if (o6i->state != IFS_DR)
-    {
-      if (IS_OSPF6_DUMP_LSA)
-        zlog_info ("Update Network: Interface %s is not DR",
-                   o6i->interface->name);
-      if (old)
-        ospf6_lsa_premature_aging (old);
-      return;
-    }
-
-  /* If none of neighbor is adjacent to us */
-  count = 0;
-  o6i->foreach_nei (o6i, &count, NBS_FULL, ospf6_count_state);
-  if (count == 0)
-    {
-      if (IS_OSPF6_DUMP_LSA)
-        zlog_info ("Update Network: Interface %s is Stub",
-                   o6i->interface->name);
-      if (old)
-        ospf6_lsa_premature_aging (old);
-      return;
-    }
-
-  if (IS_OSPF6_DUMP_LSA)
-    zlog_info ("Update Network: Interface %s", o6i->interface->name);
-
-  /* prepare buffer */
-  memset (buffer, 0, sizeof (buffer));
-  size = sizeof (struct ospf6_network_lsa);
-  network_lsa = (struct ospf6_network_lsa *) buffer;
-  router_id = (u_int32_t *)(network_lsa + 1);
-
-  /* set fields of myself */
-  *router_id++ = o6i->area->ospf6->router_id;
-  size += sizeof (u_int32_t);
-  network_lsa->options[0] |= o6i->area->options[0];
-  network_lsa->options[1] |= o6i->area->options[1];
-  network_lsa->options[2] |= o6i->area->options[2];
-
-  /* Walk through neighbors */
-  for (node = listhead (o6i->neighbor_list); node; nextnode (node))
-    {
-      o6n = (struct ospf6_neighbor *) getdata (node);
-
-      if (o6n->state != NBS_FULL)
-        continue;
-
-      /* set this neighbor's Router-ID to LSA */
-      *router_id++ = o6n->router_id;
-      size += sizeof (u_int32_t);
-
-      /* options field is logical OR */
-      network_lsa->options[0] |= o6n->options[0];
-      network_lsa->options[1] |= o6n->options[1];
-      network_lsa->options[2] |= o6n->options[2];
-    }
-
-  ospf6_lsa_originate (htons (OSPF6_LSA_TYPE_NETWORK),
-                       htonl (o6i->if_id), o6i->area->ospf6->router_id,
-                       (char *) network_lsa, size, o6i->area);
-}
-
-int
-ospf6_lsa_network_hook_neighbor (void *neighbor)
-{
-  struct ospf6_neighbor *o6n = neighbor;
-  ospf6_lsa_network_update (o6n->ospf6_interface->interface->name);
-  return 0;
-}
-
-int
-ospf6_lsa_network_hook_interface (void *interface)
-{
-  struct ospf6_interface *o6i = interface;
-  if (o6i->area)
-    ospf6_lsa_network_update (o6i->interface->name);
-  return 0;
-}
-
-int
-ospf6_lsa_network_refresh (void *old)
-{
-  struct ospf6_lsa *lsa = old;
-  struct interface *ifp;
-
-  ifp = if_lookup_by_index (ntohl (lsa->header->id));
-  if (! ifp)
-    ospf6_lsa_premature_aging (old);
-  else
-    ospf6_lsa_network_update (ifp->name);
-
-  return 0;
-}
-
-void
-ospf6_lsa_slot_register_network ()
-{
-  struct ospf6_lsa_slot slot;
-  struct ospf6_hook hook;
-
-  memset (&slot, 0, sizeof (struct ospf6_lsa_slot));
-  slot.type              = htons (OSPF6_LSA_TYPE_NETWORK);
-  slot.name              = "Network";
-  slot.func_show         = ospf6_lsa_network_show;
-  slot.func_refresh      = ospf6_lsa_network_refresh;
-  ospf6_lsa_slot_register (&slot);
-
-  ospf6_lsdb_hook[OSPF6_LSA_TYPE_NETWORK & OSPF6_LSTYPE_CODE_MASK].hook = 
-    ospf6_spf_database_hook;
-
-  memset (&hook, 0, sizeof (hook));
-  hook.name  = "OriginateNetwork";
-  hook.hook_change  = ospf6_lsa_network_hook_neighbor;
-  ospf6_hook_register (&hook, &neighbor_hook);
-
-  memset (&hook, 0, sizeof (hook));
-  hook.name  = "OriginateNetwork";
-  hook.hook_change = ospf6_lsa_network_hook_interface;
-  ospf6_hook_register (&hook, &interface_hook);
-}
-
-/****************************/
-/* RFC2740 3.4.3.6 Link-LSA */
-/****************************/
-
-int
-ospf6_lsa_link_show (struct vty *vty, struct ospf6_lsa *lsa)
-{
-  char *start, *end, *current;
-  struct ospf6_link_lsa *link_lsa;
-  int prefixnum;
-  struct ospf6_prefix *prefix;
-  char buf[128];
-  struct in6_addr in6;
-
-  assert (lsa->header);
-
-  link_lsa = (struct ospf6_link_lsa *) (lsa->header + 1);
-  prefixnum = ntohl (link_lsa->llsa_prefix_num);
-
-  inet_ntop (AF_INET6, (void *)&link_lsa->llsa_linklocal, buf, sizeof (buf));
-  vty_out (vty, "     LinkLocal Address: %s%s", buf, VTY_NEWLINE);
-  vty_out (vty, "     Number of Prefix: %d%s", prefixnum, VTY_NEWLINE);
-
-  start = (char *) link_lsa + sizeof (struct ospf6_link_lsa);
-  end = (char *) lsa->header + ntohs (lsa->header->length); 
-  for (current = start; current < end; current += OSPF6_PREFIX_SIZE (prefix))
-    {
-      prefix = (struct ospf6_prefix *) current;
-      if (current + OSPF6_PREFIX_SIZE (prefix) > end)
-        {
-          vty_out (vty, "    Trailing %d byte garbage ... Malformed%s",
-                   end - current, VTY_NEWLINE);
-          return -1;
-        }
-
-      ospf6_prefix_options_str (prefix->prefix_options, buf, sizeof (buf));
-      vty_out (vty, "     Prefix Options: %s%s", buf, VTY_NEWLINE);
-      ospf6_prefix_in6_addr (prefix, &in6);
-      inet_ntop (AF_INET6, &in6, buf, sizeof (buf));
-      vty_out (vty, "     Prefix: %s/%d%s",
-               buf, prefix->prefix_length, VTY_NEWLINE);
-    }
-
-  return 0;
-}
-
-
-void
-ospf6_lsa_link_update (char *ifname)
-{
-  char *cp, buffer [MAXLSASIZE], buf[32];
-  u_int16_t size;
-  struct ospf6_lsa *old;
-  struct interface *ifp;
-  struct ospf6_interface *o6i;
-
-  struct ospf6_link_lsa *link_lsa;
-  struct ospf6_prefix *p;
-  list prefix_connected;
-  listnode node;
-  struct connected *c;
-
-  ifp = if_lookup_by_name (ifname);
-  if (! ifp)
-    {
-      if (IS_OSPF6_DUMP_LSA)
-        zlog_info ("Update Link: No such Interface: %s", ifname);
-      return;
-    }
-
-  o6i = (struct ospf6_interface *) ifp->info;
-  if (! o6i || ! o6i->area)
-    {
-      if (IS_OSPF6_DUMP_LSA)
-        zlog_info ("Update Link: Interface not enabled: %s", ifname);
-      return;
-    }
-
-#if 0
-  /* Link-LSA is on Broadcast or NBMA */
-  if (! if_is_broadcast (o6i->interface) /* && ! NBMA xxx */)
-    {
-      return;
-    }
-#endif /*0*/
-
-  /* find previous LSA */
-  old = ospf6_lsdb_lookup (htons (OSPF6_LSA_TYPE_LINK), htonl (o6i->if_id),
-                           ospf6->router_id, o6i->area);
-
-  /* can't make Link-LSA if linklocal address not set */
-  if (! o6i->lladdr)
-    {
-      if (IS_OSPF6_DUMP_LSA)
-        zlog_warn ("Update Link: No Linklocal Address: %s",
-                   o6i->interface->name);
-      if (old)
-        ospf6_lsa_premature_aging (old);
-      return;
-    }
-
-  if (IS_OSPF6_DUMP_LSA)
-    zlog_info ("Update Link: Interface %s", o6i->interface->name);
-
-  if (! ospf6_interface_is_enabled (o6i->interface->ifindex))
-    {
-      if (IS_OSPF6_DUMP_LSA)
-        zlog_info ("  Interface %s not enabled", o6i->interface->name);
-      if (old)
-        ospf6_lsa_premature_aging (old);
-      return;
-    }
-
-  /* check connected prefix */
-  prefix_connected = list_new ();
-  for (node = listhead (o6i->interface->connected); node; nextnode (node))
-    {
-      c = (struct connected *) getdata (node);
-
-      /* filter prefix not IPv6 */
-      if (c->address->family != AF_INET6)
-        continue;
-
-      /* for log */
-      prefix2str (c->address, buf, sizeof (buf));
-
-      CONTINUE_IF_ADDRESS_LINKLOCAL (c->address);
-      CONTINUE_IF_ADDRESS_UNSPECIFIED (c->address);
-      CONTINUE_IF_ADDRESS_LOOPBACK (c->address);
-      CONTINUE_IF_ADDRESS_V4COMPAT (c->address);
-      CONTINUE_IF_ADDRESS_V4MAPPED (c->address);
-
-      /* filter prefix specified by configuration */
-      if (o6i->plist_name)
-        {
-          struct prefix_list *plist;
-          enum prefix_list_type result = PREFIX_PERMIT;
-
-          plist = prefix_list_lookup (AFI_IP6, o6i->plist_name);
-          if (plist)
-            result = prefix_list_apply (plist, c->address);
-          else if (IS_OSPF6_DUMP_LSA)
-            zlog_warn ("Update Intra-Prefix (Stub): "
-                       "Prefix list \"%s\" not found", o6i->plist_name);
-
-          if (result == PREFIX_DENY)
-            {
-              if (IS_OSPF6_DUMP_LSA)
-                zlog_info ("  Filter out Prefix-list %s: %s",
-                           o6i->plist_name, buf);
-              continue;
-            }
-        }
-
-      if (IS_OSPF6_DUMP_LSA)
-        zlog_info ("    Advertise %s", buf);
-
-      /* hold prefix in list. duplicate is filtered in ospf6_prefix_add() */
-      p = ospf6_prefix_create (0, 0, (struct prefix_ipv6 *) c->address);
-      ospf6_prefix_add (prefix_connected, p);
-    }
-
-  /* Note: even if no prefix configured, still we have to create Link-LSA
-     for next-hop resolution */
-
-  memset (buffer, 0, sizeof (buffer));
-  size = sizeof (struct ospf6_link_lsa);
-  link_lsa = (struct ospf6_link_lsa *) buffer;
-
-  /* fill Link LSA and calculate size */
-  link_lsa->llsa_rtr_pri = o6i->priority;
-  link_lsa->llsa_options[0] = o6i->area->options[0];
-  link_lsa->llsa_options[1] = o6i->area->options[1];
-  link_lsa->llsa_options[2] = o6i->area->options[2];
-
-  /* linklocal address */
-  memcpy (&link_lsa->llsa_linklocal, o6i->lladdr, sizeof (struct in6_addr));
-
-#ifdef KAME /* clear ifindex */
-  if (link_lsa->llsa_linklocal.s6_addr[3] & 0x0f)
-    link_lsa->llsa_linklocal.s6_addr[3] &= ~((char)0x0f);
-#endif /* KAME */
-
-  link_lsa->llsa_prefix_num = htonl (listcount (prefix_connected));
-  cp = (char *)(link_lsa + 1);
-  for (node = listhead (prefix_connected); node; nextnode (node))
-    {
-      p = (struct ospf6_prefix *) getdata (node);
-      size += OSPF6_PREFIX_SIZE (p);
-      memcpy (cp, p, OSPF6_PREFIX_SIZE (p));
-      cp += OSPF6_PREFIX_SIZE (p);
-    }
-
-  for (node = listhead (prefix_connected); node; nextnode (node))
-    {
-      p = (struct ospf6_prefix *) getdata (node);
-      ospf6_prefix_delete (p);
-    }
-  list_delete (prefix_connected);
-
-  ospf6_lsa_originate (htons (OSPF6_LSA_TYPE_LINK),
-                       htonl (o6i->if_id), o6i->area->ospf6->router_id,
-                       (char *) link_lsa, size, o6i);
-}
-
-int
-ospf6_lsa_link_hook_interface (void *interface)
-{
-  struct ospf6_interface *o6i = interface;
-  if (o6i->area)
-    ospf6_lsa_link_update (o6i->interface->name);
-  return 0;
-}
-
-int
-ospf6_lsa_link_refresh (void *old)
-{
-  struct ospf6_lsa *lsa = old;
-  struct interface *ifp;
-
-  ifp = if_lookup_by_index (ntohl (lsa->header->id));
-  if (! ifp)
-    ospf6_lsa_premature_aging (old);
-  else
-    ospf6_lsa_link_update (ifp->name);
-
-  return 0;
-}
-
-void
-ospf6_lsa_slot_register_link ()
-{
-  struct ospf6_lsa_slot slot;
-
-  memset (&slot, 0, sizeof (struct ospf6_lsa_slot));
-  slot.type              = htons (OSPF6_LSA_TYPE_LINK);
-  slot.name              = "Link";
-  slot.func_show         = ospf6_lsa_link_show;
-  slot.func_refresh      = ospf6_lsa_link_refresh;
-  slot.hook_interface.name = "OriginateLink";
-  slot.hook_interface.hook_change = ospf6_lsa_link_hook_interface;
-  ospf6_lsa_slot_register (&slot);
-
-  /*
-   * Link LSA handling will be shift in ospf6_intra.c
-   * Currently, only database hook only moved to ospf6_intra.c
-   */
-#if 0
-  ospf6_lsdb_hook[OSPF6_LSA_TYPE_LINK & OSPF6_LSTYPE_CODE_MASK].hook = 
-    ospf6_spf_database_hook;
-#endif /*0*/
-}
-
-int
-ospf6_lsa_add_hook (void *data)
-{
-  struct ospf6_lsa *lsa = data;
-  struct ospf6_lsa_slot *sp;
-
-  sp = ospf6_lsa_slot_get (lsa->header->type);
-  if (sp)
-    {
-      CALL_CHANGE_HOOK (&sp->database_hook, lsa);
-    }
-  else
-    zlog_warn ("Unknown LSA added to database: %s", lsa->str);
-  return 0;
-}
-
-int
-ospf6_lsa_change_hook (void *data)
-{
-  struct ospf6_lsa *lsa = data;
-  struct ospf6_lsa_slot *sp;
-
-  sp = ospf6_lsa_slot_get (lsa->header->type);
-  if (sp)
-    {
-      CALL_CHANGE_HOOK (&sp->database_hook, lsa);
-    }
-  else
-    zlog_warn ("Unknown LSA changed in database: %s", lsa->str);
-  return 0;
-}
-
-int
-ospf6_lsa_remove_hook (void *data)
-{
-  struct ospf6_lsa *lsa = data;
-  struct ospf6_lsa_slot *sp;
-
-  sp = ospf6_lsa_slot_get (lsa->header->type);
-  if (sp)
-    {
-      CALL_REMOVE_HOOK (&sp->database_hook, lsa);
-    }
-  else
-    zlog_warn ("Unknown LSA removed from database: %s", lsa->str);
-  return 0;
-}
-
-/* Initialize LSA slots */
 void
 ospf6_lsa_init ()
 {
-  struct ospf6_hook hook;
+  memset (ospf6_lstype, 0, sizeof (ospf6_lstype));
 
-  slot_head = NULL;
-  ospf6_lsa_slot_register_router ();
-  ospf6_lsa_slot_register_network ();
-  ospf6_lsa_slot_register_link ();
-#if 0
-  ospf6_lsa_slot_register_intra_prefix ();
-  ospf6_lsa_slot_register_as_external ();
-#endif /*0*/
-
-  hook.name = "LSADatabaseHook";
-  hook.hook_add = ospf6_lsa_add_hook;
-  hook.hook_change = ospf6_lsa_change_hook;
-  hook.hook_remove = ospf6_lsa_remove_hook;
-  ospf6_hook_register (&hook, &database_hook);
+  ospf6_lstype[0].name = "Unknown";
+  ospf6_lstype[0].reoriginate = ospf6_unknown_reoriginate;
+  ospf6_lstype[0].show = ospf6_unknown_show;
 }
 
+
+
+DEFUN (debug_ospf6_lsa_sendrecv,
+       debug_ospf6_lsa_sendrecv_cmd,
+       "debug ospf6 lsa (send|recv|originate|timer|database|memory|all)",
+       DEBUG_STR
+       OSPF6_STR
+       "Debug Link State Advertisements (LSAs)\n"
+       "Debug Sending LSAs\n"
+       "Debug Receiving LSAs\n"
+       "Debug Originating LSAs\n"
+       "Debug Timer Event of LSAs\n"
+       "Debug LSA Database\n"
+       "Debug Memory of LSAs\n"
+       "Debug LSAs all\n"
+      )
+{
+  unsigned char level = 0;
+
+  if (argc)
+    {
+      if (! strncmp (argv[0], "s", 1))
+        level = OSPF6_DEBUG_LSA_SEND;
+      else if (! strncmp (argv[0], "r", 1))
+        level = OSPF6_DEBUG_LSA_RECV;
+      else if (! strncmp (argv[0], "o", 1))
+        level = OSPF6_DEBUG_LSA_ORIGINATE;
+      else if (! strncmp (argv[0], "t", 1))
+        level = OSPF6_DEBUG_LSA_TIMER;
+      else if (! strncmp (argv[0], "d", 1))
+        level = OSPF6_DEBUG_LSA_DATABASE;
+      else if (! strncmp (argv[0], "m", 1))
+        level = OSPF6_DEBUG_LSA_MEMORY;
+      else if (! strncmp (argv[0], "a", 1))
+        {
+          level = OSPF6_DEBUG_LSA_SEND | OSPF6_DEBUG_LSA_RECV |
+                  OSPF6_DEBUG_LSA_ORIGINATE | OSPF6_DEBUG_LSA_TIMER |
+                  OSPF6_DEBUG_LSA_DATABASE | OSPF6_DEBUG_LSA_MEMORY;
+        }
+    }
+  else
+    {
+      level = OSPF6_DEBUG_LSA_SEND | OSPF6_DEBUG_LSA_RECV |
+              OSPF6_DEBUG_LSA_ORIGINATE | OSPF6_DEBUG_LSA_TIMER;
+    }
+
+  OSPF6_DEBUG_LSA_ON (level);
+  return CMD_SUCCESS;
+}
+
+ALIAS (debug_ospf6_lsa_sendrecv,
+       debug_ospf6_lsa_cmd,
+       "debug ospf6 lsa",
+       NO_STR
+       DEBUG_STR
+       OSPF6_STR
+       "Debug Link State Advertisements (LSAs)\n"
+      );
+
+DEFUN (no_debug_ospf6_lsa_sendrecv,
+       no_debug_ospf6_lsa_sendrecv_cmd,
+       "no debug ospf6 lsa (send|recv|originate|timer|database|memory|all)",
+       NO_STR
+       DEBUG_STR
+       OSPF6_STR
+       "Debug Link State Advertisements (LSAs)\n"
+       "Debug Sending LSAs\n"
+       "Debug Receiving LSAs\n"
+       "Debug Originating LSAs\n"
+       "Debug Timer Event of LSAs\n"
+       "Debug LSA Database\n"
+       "Debug Memory of LSAs\n"
+       "Debug LSAs all\n"
+      )
+{
+  unsigned char level = 0;
+
+  if (argc)
+    {
+      if (! strncmp (argv[0], "s", 1))
+        level = OSPF6_DEBUG_LSA_SEND;
+      else if (! strncmp (argv[0], "r", 1))
+        level = OSPF6_DEBUG_LSA_RECV;
+      else if (! strncmp (argv[0], "o", 1))
+        level = OSPF6_DEBUG_LSA_ORIGINATE;
+      else if (! strncmp (argv[0], "t", 1))
+        level = OSPF6_DEBUG_LSA_TIMER;
+      else if (! strncmp (argv[0], "d", 1))
+        level = OSPF6_DEBUG_LSA_DATABASE;
+      else if (! strncmp (argv[0], "m", 1))
+        level = OSPF6_DEBUG_LSA_MEMORY;
+      else if (! strncmp (argv[0], "a", 1))
+        {
+          level = OSPF6_DEBUG_LSA_SEND | OSPF6_DEBUG_LSA_RECV |
+                  OSPF6_DEBUG_LSA_ORIGINATE | OSPF6_DEBUG_LSA_TIMER |
+                  OSPF6_DEBUG_LSA_DATABASE | OSPF6_DEBUG_LSA_MEMORY;
+        }
+    }
+  else
+    {
+      level = OSPF6_DEBUG_LSA_SEND | OSPF6_DEBUG_LSA_RECV |
+              OSPF6_DEBUG_LSA_ORIGINATE | OSPF6_DEBUG_LSA_TIMER;
+    }
+
+  OSPF6_DEBUG_LSA_OFF (level);
+  return CMD_SUCCESS;
+}
+
+ALIAS (no_debug_ospf6_lsa_sendrecv,
+       no_debug_ospf6_lsa_cmd,
+       "no debug ospf6 lsa",
+       NO_STR
+       DEBUG_STR
+       OSPF6_STR
+       "Debug Link State Advertisements (LSAs)\n"
+      );
+
+int
+config_write_ospf6_debug_lsa (struct vty *vty)
+{
+  if (conf_debug_ospf6_lsa == OSPF6_DEBUG_LSA_ALL)
+    vty_out (vty, "debug ospf6 lsa all%s", VTY_NEWLINE);
+  else
+    {
+      if (conf_debug_ospf6_lsa == OSPF6_DEBUG_LSA_DEFAULT)
+        vty_out (vty, "debug ospf6 lsa%s", VTY_NEWLINE);
+      else
+        {
+          if (IS_OSPF6_DEBUG_LSA (SEND))
+            vty_out (vty, "debug ospf6 lsa send%s", VTY_NEWLINE);
+          if (IS_OSPF6_DEBUG_LSA (RECV))
+            vty_out (vty, "debug ospf6 lsa recv%s", VTY_NEWLINE);
+          if (IS_OSPF6_DEBUG_LSA (ORIGINATE))
+            vty_out (vty, "debug ospf6 lsa originate%s", VTY_NEWLINE);
+          if (IS_OSPF6_DEBUG_LSA (TIMER))
+            vty_out (vty, "debug ospf6 lsa timer%s", VTY_NEWLINE);
+        }
+
+      if (IS_OSPF6_DEBUG_LSA (DATABASE))
+        vty_out (vty, "debug ospf6 lsa database%s", VTY_NEWLINE);
+      if (IS_OSPF6_DEBUG_LSA (MEMORY))
+        vty_out (vty, "debug ospf6 lsa memory%s", VTY_NEWLINE);
+    }
+
+  return 0;
+}
+
+void
+install_element_ospf6_debug_lsa ()
+{
+  install_element (ENABLE_NODE, &debug_ospf6_lsa_cmd);
+  install_element (ENABLE_NODE, &debug_ospf6_lsa_sendrecv_cmd);
+  install_element (ENABLE_NODE, &no_debug_ospf6_lsa_cmd);
+  install_element (ENABLE_NODE, &no_debug_ospf6_lsa_sendrecv_cmd);
+  install_element (CONFIG_NODE, &debug_ospf6_lsa_cmd);
+  install_element (CONFIG_NODE, &debug_ospf6_lsa_sendrecv_cmd);
+  install_element (CONFIG_NODE, &no_debug_ospf6_lsa_cmd);
+  install_element (CONFIG_NODE, &no_debug_ospf6_lsa_sendrecv_cmd);
+}
+
+