/*
 * Copyright (C) 2003 Yasuhiro Ohara
 *
 * This file is part of GNU Zebra.
 *
 * GNU Zebra is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation; either version 2, or (at your option) any
 * later version.
 *
 * GNU Zebra is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Zebra; see the file COPYING.  If not, write to the 
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330, 
 * Boston, MA 02111-1307, USA.  
 */

#include <zebra.h>

/* Include other stuffs */
#include "log.h"
#include "linklist.h"
#include "command.h"
#include "memory.h"
#include "thread.h"

#include "ospf6_proto.h"
#include "ospf6_lsa.h"
#include "ospf6_lsdb.h"
#include "ospf6_message.h"

#include "ospf6_top.h"
#include "ospf6_area.h"
#include "ospf6_interface.h"
#include "ospf6_neighbor.h"

#include "ospf6_flood.h"
#include "ospf6d.h"

unsigned char conf_debug_ospf6_lsa = 0;

struct ospf6_lsa_handler *ospf6_lsa_handler[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)
{
  static char buf[8];
  int index = OSPF6_LSTYPE_INDEX (type);

  if (ospf6_lsa_handler[index])
    return ospf6_lsa_handler[index]->name;

  snprintf (buf, sizeof (buf), "0x%04hx", ntohs (type));
  return buf;
}

/* RFC2328: Section 13.2 */
int
ospf6_lsa_is_differ (struct ospf6_lsa *lsa1,
                     struct ospf6_lsa *lsa2)
{
  int len;

  assert (OSPF6_LSA_IS_SAME (lsa1, lsa2));

  /* XXX, Options ??? */

  ospf6_lsa_age_current (lsa1);
  ospf6_lsa_age_current (lsa2);
  if (ntohs (lsa1->header->age) == MAXAGE &&
      ntohs (lsa2->header->age) != MAXAGE)
    return 1;
  if (ntohs (lsa1->header->age) != MAXAGE &&
      ntohs (lsa2->header->age) == MAXAGE)
    return 1;

  /* compare body */
  if (ntohs (lsa1->header->length) != ntohs (lsa2->header->length))
    return 1;

  len = ntohs (lsa1->header->length) - sizeof (struct ospf6_lsa_header);
  return memcmp (lsa1->header + 1, lsa2->header + 1, len);
}

int
ospf6_lsa_is_changed (struct ospf6_lsa *lsa1,
                      struct ospf6_lsa *lsa2)
{
  int length;

  if (OSPF6_LSA_IS_MAXAGE (lsa1) ^ OSPF6_LSA_IS_MAXAGE (lsa2))
    return 1;
  if (ntohs (lsa1->header->length) != ntohs (lsa2->header->length))
    return 1;

  length = OSPF6_LSA_SIZE (lsa1->header) - sizeof (struct ospf6_lsa_header);
  assert (length > 0);

  return memcmp (OSPF6_LSA_HEADER_END (lsa1->header),
                 OSPF6_LSA_HEADER_END (lsa2->header), length);
}

/* ospf6 age functions */
/* calculate birth */
static void
ospf6_lsa_age_set (struct ospf6_lsa *lsa)
{
  struct timeval now;

  assert (lsa && lsa->header);

  if (gettimeofday (&now, (struct timezone *)NULL) < 0)
    zlog_warn ("LSA: gettimeofday failed, may fail LSA AGEs: %s",
               strerror (errno));

  lsa->birth.tv_sec = now.tv_sec - ntohs (lsa->header->age);
  lsa->birth.tv_usec = now.tv_usec;

  return;
}

/* this function calculates current age from its birth,
   then update age field of LSA header. return value is current age */
u_int16_t
ospf6_lsa_age_current (struct ospf6_lsa *lsa)
{
  struct timeval now;
  u_int32_t ulage;
  u_int16_t age;

  assert (lsa);
  assert (lsa->header);

  /* current time */
  if (gettimeofday (&now, (struct timezone *)NULL) < 0)
    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 */
  age = (ulage > MAXAGE ? MAXAGE : ulage);

  lsa->header->age = htons (age);
  return age;
}

/* update age field of LSA header with adding InfTransDelay */
void
ospf6_lsa_age_update_to_send (struct ospf6_lsa *lsa, u_int32_t transdelay)
{
  unsigned short age;

  age = ospf6_lsa_age_current (lsa) + transdelay;
  if (age > MAXAGE)
    age = MAXAGE;
  lsa->header->age = htons (age);
}

void
ospf6_lsa_premature_aging (struct ospf6_lsa *lsa)
{
  /* log */
  if (IS_OSPF6_DEBUG_LSA (ORIGINATE))
    zlog_info ("LSA: Premature aging: %s", lsa->name);

  THREAD_OFF (lsa->expire);
  THREAD_OFF (lsa->refresh);

  memset (&lsa->birth, 0, sizeof (struct timeval));
  thread_execute (master, ospf6_lsa_expire, lsa, 0);
}

/* 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_compare (struct ospf6_lsa *a, struct ospf6_lsa *b)
{
  signed long seqnuma, seqnumb;
  u_int16_t cksuma, cksumb;
  u_int16_t agea, ageb;

  assert (a && a->header);
  assert (b && b->header);
  assert (OSPF6_LSA_IS_SAME (a, b));

  seqnuma = ((signed long) ntohl (a->header->seqnum))
             - (signed long) INITIAL_SEQUENCE_NUMBER;
  seqnumb = ((signed long) ntohl (b->header->seqnum))
             - (signed long) INITIAL_SEQUENCE_NUMBER;

  /* compare by sequence number */
  /* XXX, LS sequence number wrapping */
  if (seqnuma > seqnumb)
    return -1;
  else if (seqnuma < seqnumb)
    return 1;

  /* Checksum */
  cksuma = ntohs (a->header->checksum);
  cksumb = ntohs (b->header->checksum);
  if (cksuma > cksumb)
    return -1;
  if (cksuma < cksumb)
    return 0;

  /* Update Age */
  agea = ospf6_lsa_age_current (a);
  ageb = ospf6_lsa_age_current (b);

  /* MaxAge check */
  if (agea == MAXAGE && ageb != MAXAGE)
    return -1;
  else if (agea != MAXAGE && ageb == MAXAGE)
    return 1;

  /* Age check */
  if (agea > ageb && agea - ageb >= MAX_AGE_DIFF)
    return 1;
  else if (agea < ageb && ageb - agea >= MAX_AGE_DIFF)
    return -1;

  /* neither recent */
  return 0;
}

char *
ospf6_lsa_printbuf (struct ospf6_lsa *lsa, char *buf, int size)
{
  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_header_print_raw (struct ospf6_lsa_header *header)
{
  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));
}

void
ospf6_lsa_header_print (struct ospf6_lsa *lsa)
{
  ospf6_lsa_age_current (lsa);
  ospf6_lsa_header_print_raw (lsa->header);
}

void
ospf6_lsa_show_summary_header (struct vty *vty)
{
  vty_out (vty, "%-12s %-15s %-15s %4s %8s %4s %4s %-8s%s",
           "Type", "LSId", "AdvRouter", "Age", "SeqNum",
           "Cksm", "Len", "Duration", VNL);
}

void
ospf6_lsa_show_summary (struct vty *vty, struct ospf6_lsa *lsa)
{
  char adv_router[16], id[16];
  struct timeval now, res;
  char duration[16];

  assert (lsa);
  assert (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));

  gettimeofday (&now, NULL);
  timersub (&now, &lsa->installed, &res);
  timerstring (&res, duration, sizeof (duration));

  vty_out (vty, "%-12s %-15s %-15s %4hu %8lx %04hx %4hu %8s%s",
           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, VNL);
}

void
ospf6_lsa_show_dump (struct vty *vty, struct ospf6_lsa *lsa)
{
  u_char *start, *end, *current;
  char byte[4];

  start = (char *) lsa->header;
  end = (char *) lsa->header + ntohs (lsa->header->length);

  vty_out (vty, "%s", VNL);
  vty_out (vty, "%s:%s", lsa->name, VNL);

  for (current = start; current < end; current ++)
    {
      if ((current - start) % 16 == 0)
        vty_out (vty, "%s        ", VNL);
      else if ((current - start) % 4 == 0)
        vty_out (vty, " ");

      snprintf (byte, sizeof (byte), "%02x", *current);
      vty_out (vty, "%s", byte);
    }

  vty_out (vty, "%s%s", VNL, VNL);
  return;
}

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", VNL);
  vty_out (vty, "Age: %4hu Type: %s%s", ospf6_lsa_age_current (lsa),
           OSPF6_LSTYPE_NAME (lsa->header->type), VNL);
  vty_out (vty, "Link State ID: %s%s", id, VNL);
  vty_out (vty, "Advertising Router: %s%s", adv_router, VNL);
  vty_out (vty, "LS Sequence Number: %#010lx%s",
           (u_long) ntohl (lsa->header->seqnum), VNL);
  vty_out (vty, "CheckSum: %#06hx Length: %hu%s",
           ntohs (lsa->header->checksum),
           ntohs (lsa->header->length), VNL);
  vty_out (vty, "    Prev: %p This: %p Next: %p%s",
           lsa->prev, lsa, lsa->next, VNL);
  vty_out (vty, "%s", VNL);
  return;
}

void
ospf6_lsa_show (struct vty *vty, struct ospf6_lsa *lsa)
{
  char adv_router[64], id[64];
  int index;

  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, "Age: %4hu Type: %s%s", ospf6_lsa_age_current (lsa),
           OSPF6_LSTYPE_NAME (lsa->header->type), VNL);
  vty_out (vty, "Link State ID: %s%s", id, VNL);
  vty_out (vty, "Advertising Router: %s%s", adv_router, VNL);
  vty_out (vty, "LS Sequence Number: %#010lx%s",
           (u_long) ntohl (lsa->header->seqnum), VNL);
  vty_out (vty, "CheckSum: %#06hx Length: %hu%s",
           ntohs (lsa->header->checksum),
           ntohs (lsa->header->length), VNL);

  index = OSPF6_LSTYPE_INDEX (lsa->header->type);
  if (ospf6_lsa_handler[index]->show)
    (*ospf6_lsa_handler[index]->show) (vty, lsa);
  else
    {
      ospf6_lsa_show_dump (vty, lsa);
      vty_out (vty, "%sUnknown LSA type ...%s", VNL, VNL);
    }

  vty_out (vty, "%s", VNL);
}

/* OSPFv3 LSA creation/deletion function */
struct ospf6_lsa *
ospf6_lsa_create (struct ospf6_lsa_header *header)
{
  struct ospf6_lsa *lsa = NULL;
  struct ospf6_lsa_header *new_header = NULL;
  u_int16_t lsa_size = 0;

  /* size of the entire LSA */
  lsa_size = ntohs (header->length);   /* XXX vulnerable */

  /* allocate memory for this LSA */
  new_header = (struct ospf6_lsa_header *)
    XMALLOC (MTYPE_OSPF6_LSA, 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));
  memset (lsa, 0, sizeof (struct ospf6_lsa));

  lsa->header = (struct ospf6_lsa_header *) new_header;

  /* dump string */
  ospf6_lsa_printbuf (lsa, lsa->name, sizeof (lsa->name));

  /* calculate birth of this lsa */
  ospf6_lsa_age_set (lsa);

  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_create_headeronly (struct ospf6_lsa_header *header)
{
  struct ospf6_lsa *lsa = NULL;
  struct ospf6_lsa_header *new_header = NULL;

  /* allocate memory for this LSA */
  new_header = (struct ospf6_lsa_header *)
    XMALLOC (MTYPE_OSPF6_LSA, sizeof (struct ospf6_lsa_header));

  /* 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, sizeof (struct ospf6_lsa));
  memset (lsa, 0, sizeof (struct ospf6_lsa));

  lsa->header = (struct ospf6_lsa_header *) new_header;
  SET_FLAG (lsa->flag, OSPF6_LSA_HEADERONLY);

  /* dump string */
  ospf6_lsa_printbuf (lsa, lsa->name, sizeof (lsa->name));

  /* calculate birth of this lsa */
  ospf6_lsa_age_set (lsa);

  if (IS_OSPF6_DEBUG_LSA (MEMORY))
    zlog_info ("Create LSA (Header-only) Memory: %s (%p/%p)",
               lsa->name, lsa, lsa->header);

  return lsa;
}

void
ospf6_lsa_delete (struct ospf6_lsa *lsa)
{
  assert (lsa->lock == 0);

  /* cancel threads */
  THREAD_OFF (lsa->expire);
  THREAD_OFF (lsa->refresh);

  if (IS_OSPF6_DEBUG_LSA (MEMORY))
    zlog_info ("Delete LSA %s Memory: %s (%p/%p)",
               (CHECK_FLAG (lsa->flag, OSPF6_LSA_HEADERONLY) ?
                "(Header-only) " : ""), lsa->name, lsa, lsa->header);

  /* do free */
  XFREE (MTYPE_OSPF6_LSA, lsa->header);
  XFREE (MTYPE_OSPF6_LSA, 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 (CHECK_FLAG (lsa->flag, OSPF6_LSA_HEADERONLY))
    copy = ospf6_lsa_create_headeronly (lsa->header);
  else
    copy = ospf6_lsa_create (lsa->header);
  assert (copy->lock == 0);

  copy->birth = lsa->birth;
  copy->originated = lsa->originated;
  copy->received = lsa->received;
  copy->installed = lsa->installed;
  copy->lsdb = lsa->lsdb;

  return copy;
}

/* increment reference counter of struct ospf6_lsa */
void
ospf6_lsa_lock (struct ospf6_lsa *lsa)
{
  lsa->lock++;
  return;
}

/* decrement reference counter of struct ospf6_lsa */
void
ospf6_lsa_unlock (struct ospf6_lsa *lsa)
{
  /* decrement reference counter */
  assert (lsa->lock > 0);
  lsa->lock--;

  if (lsa->lock != 0)
    return;

  ospf6_lsa_delete (lsa);
}


/* ospf6 lsa expiry */
int
ospf6_lsa_expire (struct thread *thread)
{
  struct ospf6_lsa *lsa;

  lsa = (struct ospf6_lsa *) THREAD_ARG (thread);

  assert (lsa && lsa->header);
  assert (OSPF6_LSA_IS_MAXAGE (lsa));
  assert (! lsa->refresh);

  lsa->expire = (struct thread *) NULL;

  if (IS_OSPF6_DEBUG_LSA (TIMER))
    {
      zlog_info ("LSA Expire:");
      ospf6_lsa_header_print (lsa);
    }

  if (CHECK_FLAG (lsa->flag, OSPF6_LSA_HEADERONLY))
    return 0;    /* dbexchange will do something ... */

  /* reflood lsa */
  ospf6_flood (NULL, lsa);

  /* reinstall lsa */
  if (IS_OSPF6_DEBUG_LSA (DATABASE))
    zlog_info ("Reinstall MaxAge %s", lsa->name);
  ospf6_install_lsa (lsa);

  /* schedule maxage remover */
  ospf6_maxage_remove (ospf6);

  return 0;
}

int
ospf6_lsa_refresh (struct thread *thread)
{
  struct ospf6_lsa *old, *self, *new;
  struct ospf6_lsdb *lsdb_self;

  assert (thread);
  old = (struct ospf6_lsa *) THREAD_ARG (thread);
  assert (old && old->header);

  old->refresh = (struct thread *) NULL;

  lsdb_self = ospf6_get_scoped_lsdb_self (old);
  self = ospf6_lsdb_lookup (old->header->type, old->header->id,
                            old->header->adv_router, lsdb_self);
  if (self == NULL)
    {
      if (IS_OSPF6_DEBUG_LSA (ORIGINATE))
        zlog_info ("Refresh: could not find self LSA, flush %s", old->name);
      ospf6_lsa_premature_aging (old);
      return 0;
    }

  /* Reset age, increment LS sequence number. */
  self->header->age = htons (0);
  self->header->seqnum =
    ospf6_new_ls_seqnum (self->header->type, self->header->id,
                         self->header->adv_router, old->lsdb);
  ospf6_lsa_checksum (self->header);

  new = ospf6_lsa_create (self->header);
  new->lsdb = old->lsdb;
  new->refresh = thread_add_timer (master, ospf6_lsa_refresh, new,
                                   LS_REFRESH_TIME);

  /* store it in the LSDB for self-originated LSAs */
  ospf6_lsdb_add (ospf6_lsa_copy (new), lsdb_self);

  if (IS_OSPF6_DEBUG_LSA (ORIGINATE))
    {
      zlog_info ("LSA Refresh:");
      ospf6_lsa_header_print (new);
    }

  ospf6_flood_clear (old);
  ospf6_flood (NULL, new);
  ospf6_install_lsa (new);

  return 0;
}



/* enhanced Fletcher checksum algorithm, RFC1008 7.2 */
#define MODX                4102
#define LSA_CHECKSUM_OFFSET   15

unsigned short
ospf6_lsa_checksum (struct ospf6_lsa_header *lsa_header)
{
  u_char *sp, *ep, *p, *q;
  int c0 = 0, c1 = 0;
  int x, y;
  u_int16_t length;

  lsa_header->checksum = 0;
  length = ntohs (lsa_header->length) - 2;
  sp = (char *) &lsa_header->type;

  for (ep = sp + length; sp < ep; sp = q)
    {
      q = sp + MODX;
      if (q > ep)
        q = ep;
      for (p = sp; p < q; p++)
        {
          c0 += *p;
          c1 += c0;
        }
      c0 %= 255;
      c1 %= 255;
    }

  /* r = (c1 << 8) + c0; */
  x = ((length - LSA_CHECKSUM_OFFSET) * c0 - c1) % 255;
  if (x <= 0)
    x += 255;
  y = 510 - c0 - x;
  if (y > 255)
    y -= 255;

  lsa_header->checksum = htons ((x << 8) + y);

  return (lsa_header->checksum);
}

int
ospf6_unknown_lsa_show (struct vty *vty, struct ospf6_lsa *lsa)
{
  u_char *start, *end, *current;
  char byte[4];

  start = (char *) lsa->header + sizeof (struct ospf6_lsa_header);
  end = (char *) lsa->header + ntohs (lsa->header->length);

  vty_out (vty, "        Unknown contents:%s", VNL);
  for (current = start; current < end; current ++)
    {
      if ((current - start) % 16 == 0)
        vty_out (vty, "%s        ", VNL);
      else if ((current - start) % 4 == 0)
        vty_out (vty, " ");

      snprintf (byte, sizeof (byte), "%02x", *current);
      vty_out (vty, "%s", byte);
    }

  vty_out (vty, "%s%s", VNL, VNL);
  return 0;
}

void
ospf6_install_lsa_handler (struct ospf6_lsa_handler *handler)
{
  /* might need to adjust dynamic array length ... */
  int index = OSPF6_LSTYPE_INDEX (htons (handler->type));
  ospf6_lsa_handler[index] = handler;
}

struct ospf6_lsa_handler unknown_handler =
{
  OSPF6_LSTYPE_UNKNOWN,
  "Unknown",
  ospf6_unknown_lsa_show
};

void
ospf6_lsa_init ()
{
  memset (ospf6_lsa_handler, 0, sizeof (ospf6_lsa_handler));
  ospf6_install_lsa_handler (&unknown_handler);
}



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", VNL);
  else
    {
      if (conf_debug_ospf6_lsa == OSPF6_DEBUG_LSA_DEFAULT)
        vty_out (vty, "debug ospf6 lsa%s", VNL);
      else
        {
          if (IS_OSPF6_DEBUG_LSA (SEND))
            vty_out (vty, "debug ospf6 lsa send%s", VNL);
          if (IS_OSPF6_DEBUG_LSA (RECV))
            vty_out (vty, "debug ospf6 lsa recv%s", VNL);
          if (IS_OSPF6_DEBUG_LSA (ORIGINATE))
            vty_out (vty, "debug ospf6 lsa originate%s", VNL);
          if (IS_OSPF6_DEBUG_LSA (TIMER))
            vty_out (vty, "debug ospf6 lsa timer%s", VNL);
        }

      if (IS_OSPF6_DEBUG_LSA (DATABASE))
        vty_out (vty, "debug ospf6 lsa database%s", VNL);
      if (IS_OSPF6_DEBUG_LSA (MEMORY))
        vty_out (vty, "debug ospf6 lsa memory%s", VNL);
    }

  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);
}


