/*
 * 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 "log.h"
#include "memory.h"
#include "thread.h"
#include "linklist.h"
#include "vty.h"
#include "command.h"

#include "ospf6d.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_intra.h"

unsigned char conf_debug_ospf6_neighbor = 0;

char *ospf6_neighbor_state_str[] =
{ "None", "Down", "Attempt", "Init", "Twoway", "ExStart", "ExChange",
  "Loading", "Full", NULL };

int
ospf6_neighbor_cmp (void *va, void *vb)
{
  struct ospf6_neighbor *ona = (struct ospf6_neighbor *) va;
  struct ospf6_neighbor *onb = (struct ospf6_neighbor *) vb;
  return (ntohl (ona->router_id) - ntohl (onb->router_id));
}

struct ospf6_neighbor *
ospf6_neighbor_lookup (u_int32_t router_id,
                       struct ospf6_interface *oi)
{
  listnode n;
  struct ospf6_neighbor *on;

  for (n = listhead (oi->neighbor_list); n; nextnode (n))
    {
      on = (struct ospf6_neighbor *) getdata (n);
      if (on->router_id == router_id)
        return on;
    }
  return (struct ospf6_neighbor *) NULL;
}

/* create ospf6_neighbor */
struct ospf6_neighbor *
ospf6_neighbor_create (u_int32_t router_id, struct ospf6_interface *oi)
{
  struct ospf6_neighbor *on;
  char buf[16];

  on = (struct ospf6_neighbor *)
    XMALLOC (MTYPE_OSPF6_NEIGHBOR, sizeof (struct ospf6_neighbor));
  if (on == NULL)
    {
      zlog_warn ("neighbor: malloc failed");
      return NULL;
    }

  memset (on, 0, sizeof (struct ospf6_neighbor));
  inet_ntop (AF_INET, &router_id, buf, sizeof (buf));
  snprintf (on->name, sizeof (on->name), "%s%%%s",
            buf, oi->interface->name);
  on->ospf6_if = oi;
  on->state = OSPF6_NEIGHBOR_DOWN;
  gettimeofday (&on->last_changed, (struct timezone *) NULL);
  on->router_id = router_id;

  on->summary_list = ospf6_lsdb_create ();
  on->request_list = ospf6_lsdb_create ();
  on->retrans_list = ospf6_lsdb_create ();

  on->dbdesc_list = ospf6_lsdb_create ();
  on->lsreq_list = ospf6_lsdb_create ();
  on->lsupdate_list = ospf6_lsdb_create ();
  on->lsack_list = ospf6_lsdb_create ();

  listnode_add_sort (oi->neighbor_list, on);
  return on;
}

void
ospf6_neighbor_delete (struct ospf6_neighbor *on)
{
  ospf6_lsdb_remove_all (on->summary_list);
  ospf6_lsdb_remove_all (on->request_list);
  ospf6_lsdb_remove_all (on->retrans_list);

  ospf6_lsdb_remove_all (on->dbdesc_list);
  ospf6_lsdb_remove_all (on->lsreq_list);
  ospf6_lsdb_remove_all (on->lsupdate_list);
  ospf6_lsdb_remove_all (on->lsack_list);

  ospf6_lsdb_delete (on->summary_list);
  ospf6_lsdb_delete (on->request_list);
  ospf6_lsdb_delete (on->retrans_list);

  ospf6_lsdb_delete (on->dbdesc_list);
  ospf6_lsdb_delete (on->lsreq_list);
  ospf6_lsdb_delete (on->lsupdate_list);
  ospf6_lsdb_delete (on->lsack_list);

  THREAD_OFF (on->inactivity_timer);

  THREAD_OFF (on->thread_send_dbdesc);
  THREAD_OFF (on->thread_send_lsreq);
  THREAD_OFF (on->thread_send_lsupdate);
  THREAD_OFF (on->thread_send_lsack);

  XFREE (MTYPE_OSPF6_NEIGHBOR, on);
}

static void
ospf6_neighbor_state_change (u_char next_state, struct ospf6_neighbor *on)
{
  u_char prev_state;

  prev_state = on->state;
  on->state = next_state;

  if (prev_state == next_state)
    return;

  gettimeofday (&on->last_changed, (struct timezone *) NULL);

  /* log */
  if (IS_OSPF6_DEBUG_NEIGHBOR (STATE))
    {
      zlog_info ("Neighbor state change %s: [%s]->[%s]", on->name,
                 ospf6_neighbor_state_str[prev_state],
                 ospf6_neighbor_state_str[next_state]);
    }

  if (prev_state == OSPF6_NEIGHBOR_FULL || next_state == OSPF6_NEIGHBOR_FULL)
    {
      OSPF6_ROUTER_LSA_SCHEDULE (on->ospf6_if->area);
      if (on->ospf6_if->state == OSPF6_INTERFACE_DR)
        {
          OSPF6_NETWORK_LSA_SCHEDULE (on->ospf6_if);
          OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT (on->ospf6_if);
          OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB (on->ospf6_if->area);
        }
    }

#ifdef XXX
  if (prev_state == NBS_FULL || next_state == NBS_FULL)
    nbs_full_change (on->ospf6_interface);

  /* check for LSAs that already reached MaxAge */
  if ((prev_state == OSPF6_NEIGHBOR_EXCHANGE ||
       prev_state == OSPF6_NEIGHBOR_LOADING) &&
      (next_state != OSPF6_NEIGHBOR_EXCHANGE &&
       next_state != OSPF6_NEIGHBOR_LOADING))
    {
      ospf6_maxage_remover ();
    }
#endif /*XXX*/

}

/* RFC2328 section 10.4 */
int
need_adjacency (struct ospf6_neighbor *on)
{
  if (on->ospf6_if->state == OSPF6_INTERFACE_POINTTOPOINT ||
      on->ospf6_if->state == OSPF6_INTERFACE_DR ||
      on->ospf6_if->state == OSPF6_INTERFACE_BDR)
    return 1;

  if (on->ospf6_if->drouter == on->router_id ||
      on->ospf6_if->bdrouter == on->router_id)
    return 1;

  return 0;
}

int
hello_received (struct thread *thread)
{
  struct ospf6_neighbor *on;

  on = (struct ospf6_neighbor *) THREAD_ARG (thread);
  assert (on);

  if (IS_OSPF6_DEBUG_NEIGHBOR (EVENT))
    zlog_info ("Neighbor Event %s: *HelloReceived*", on->name);

  /* reset Inactivity Timer */
  THREAD_OFF (on->inactivity_timer);
  on->inactivity_timer = thread_add_timer (master, inactivity_timer, on,
                                           on->ospf6_if->dead_interval);

  if (on->state <= OSPF6_NEIGHBOR_DOWN)
    ospf6_neighbor_state_change (OSPF6_NEIGHBOR_INIT, on);

  return 0;
}

int
twoway_received (struct thread *thread)
{
  struct ospf6_neighbor *on;

  on = (struct ospf6_neighbor *) THREAD_ARG (thread);
  assert (on);

  if (on->state > OSPF6_NEIGHBOR_INIT)
    return 0;

  if (IS_OSPF6_DEBUG_NEIGHBOR (EVENT))
    zlog_info ("Neighbor Event %s: *2Way-Received*", on->name);

  thread_add_event (master, neighbor_change, on->ospf6_if, 0);

  if (! need_adjacency (on))
    {
      ospf6_neighbor_state_change (OSPF6_NEIGHBOR_TWOWAY, on);
      return 0;
    }

  ospf6_neighbor_state_change (OSPF6_NEIGHBOR_EXSTART, on);
  SET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MSBIT);
  SET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MBIT);
  SET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_IBIT);

  THREAD_OFF (on->thread_send_dbdesc);
  on->thread_send_dbdesc =
    thread_add_event (master, ospf6_dbdesc_send, on, 0);

  return 0;
}

int
negotiation_done (struct thread *thread)
{
  struct ospf6_neighbor *on;
  struct ospf6_lsa *lsa;

  on = (struct ospf6_neighbor *) THREAD_ARG (thread);
  assert (on);

  if (on->state != OSPF6_NEIGHBOR_EXSTART)
    return 0;

  if (IS_OSPF6_DEBUG_NEIGHBOR (EVENT))
    zlog_info ("Neighbor Event %s: *NegotiationDone*", on->name);

  /* clear ls-list */
  ospf6_lsdb_remove_all (on->summary_list);
  ospf6_lsdb_remove_all (on->request_list);
  ospf6_lsdb_remove_all (on->retrans_list);

  /* Interface scoped LSAs */
  for (lsa = ospf6_lsdb_head (on->ospf6_if->lsdb); lsa;
       lsa = ospf6_lsdb_next (lsa))
    {
      if (IS_OSPF6_DEBUG_LSA (DATABASE))
        zlog_info ("Add copy of %s to %s of %s", lsa->name,
                   (OSPF6_LSA_IS_MAXAGE (lsa) ? "retrans_list" :
                    "summary_list"), on->name);
      if (OSPF6_LSA_IS_MAXAGE (lsa))
        ospf6_lsdb_add (ospf6_lsa_copy (lsa), on->retrans_list);
      else
        ospf6_lsdb_add (ospf6_lsa_copy (lsa), on->summary_list);
    }

  /* Area scoped LSAs */
  for (lsa = ospf6_lsdb_head (on->ospf6_if->area->lsdb); lsa;
       lsa = ospf6_lsdb_next (lsa))
    {
      if (IS_OSPF6_DEBUG_LSA (DATABASE))
        zlog_info ("Add copy of %s to %s of %s", lsa->name,
                   (OSPF6_LSA_IS_MAXAGE (lsa) ? "retrans_list" :
                    "summary_list"), on->name);
      if (OSPF6_LSA_IS_MAXAGE (lsa))
        ospf6_lsdb_add (ospf6_lsa_copy (lsa), on->retrans_list);
      else
        ospf6_lsdb_add (ospf6_lsa_copy (lsa), on->summary_list);
    }

  /* AS scoped LSAs */
  for (lsa = ospf6_lsdb_head (on->ospf6_if->area->ospf6->lsdb); lsa;
       lsa = ospf6_lsdb_next (lsa))
    {
      if (IS_OSPF6_DEBUG_LSA (DATABASE))
        zlog_info ("Add copy of %s to %s of %s", lsa->name,
                   (OSPF6_LSA_IS_MAXAGE (lsa) ? "retrans_list" :
                    "summary_list"), on->name);
      if (OSPF6_LSA_IS_MAXAGE (lsa))
        ospf6_lsdb_add (ospf6_lsa_copy (lsa), on->retrans_list);
      else
        ospf6_lsdb_add (ospf6_lsa_copy (lsa), on->summary_list);
    }

  UNSET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_IBIT);
  ospf6_neighbor_state_change (OSPF6_NEIGHBOR_EXCHANGE, on);

  return 0;
}

int
exchange_done (struct thread *thread)
{
  struct ospf6_neighbor *on;

  on = (struct ospf6_neighbor *) THREAD_ARG (thread);
  assert (on);

  if (on->state != OSPF6_NEIGHBOR_EXCHANGE)
    return 0;

  if (IS_OSPF6_DEBUG_NEIGHBOR (EVENT))
    zlog_info ("Neighbor Event %s: *ExchangeDone*", on->name);

  THREAD_OFF (on->thread_send_dbdesc);
  ospf6_lsdb_remove_all (on->dbdesc_list);

/* XXX
  thread_add_timer (master, ospf6_neighbor_last_dbdesc_release, on,
                    on->ospf6_if->dead_interval);
*/

  if (on->request_list->count == 0)
    ospf6_neighbor_state_change (OSPF6_NEIGHBOR_FULL, on);
  else
    ospf6_neighbor_state_change (OSPF6_NEIGHBOR_LOADING, on);

  return 0;
}

int
loading_done (struct thread *thread)
{
  struct ospf6_neighbor *on;

  on = (struct ospf6_neighbor *) THREAD_ARG (thread);
  assert (on);

  if (on->state != OSPF6_NEIGHBOR_LOADING)
    return 0;

  if (IS_OSPF6_DEBUG_NEIGHBOR (EVENT))
    zlog_info ("Neighbor Event %s: *LoadingDone*", on->name);

  assert (on->request_list->count == 0);

  ospf6_neighbor_state_change (OSPF6_NEIGHBOR_FULL, on);

  return 0;
}

int
adj_ok (struct thread *thread)
{
  struct ospf6_neighbor *on;

  on = (struct ospf6_neighbor *) THREAD_ARG (thread);
  assert (on);

  if (IS_OSPF6_DEBUG_NEIGHBOR (EVENT))
    zlog_info ("Neighbor Event %s: *AdjOK?*", on->name);

  if (on->state == OSPF6_NEIGHBOR_TWOWAY && need_adjacency (on))
    {
      ospf6_neighbor_state_change (OSPF6_NEIGHBOR_EXSTART, on);
      SET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MSBIT);
      SET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MBIT);
      SET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_IBIT);

      THREAD_OFF (on->thread_send_dbdesc);
      on->thread_send_dbdesc =
        thread_add_event (master, ospf6_dbdesc_send, on, 0);

    }
  else if (on->state >= OSPF6_NEIGHBOR_EXSTART &&
           ! need_adjacency (on))
    {
      ospf6_neighbor_state_change (OSPF6_NEIGHBOR_TWOWAY, on);
      ospf6_lsdb_remove_all (on->summary_list);
      ospf6_lsdb_remove_all (on->request_list);
      ospf6_lsdb_remove_all (on->retrans_list);
    }

  return 0;
}

int
seqnumber_mismatch (struct thread *thread)
{
  struct ospf6_neighbor *on;

  on = (struct ospf6_neighbor *) THREAD_ARG (thread);
  assert (on);

  if (on->state < OSPF6_NEIGHBOR_EXCHANGE)
    return 0;

  if (IS_OSPF6_DEBUG_NEIGHBOR (EVENT))
    zlog_info ("Neighbor Event %s: *SeqNumberMismatch*", on->name);

  ospf6_neighbor_state_change (OSPF6_NEIGHBOR_EXSTART, on);
  SET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MSBIT);
  SET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MBIT);
  SET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_IBIT);

  ospf6_lsdb_remove_all (on->summary_list);
  ospf6_lsdb_remove_all (on->request_list);
  ospf6_lsdb_remove_all (on->retrans_list);

  THREAD_OFF (on->thread_send_dbdesc);
  on->thread_send_dbdesc =
    thread_add_event (master, ospf6_dbdesc_send, on, 0);

  return 0;
}

int
bad_lsreq (struct thread *thread)
{
  struct ospf6_neighbor *on;

  on = (struct ospf6_neighbor *) THREAD_ARG (thread);
  assert (on);

  if (on->state < OSPF6_NEIGHBOR_EXCHANGE)
    return 0;

  if (IS_OSPF6_DEBUG_NEIGHBOR (EVENT))
    zlog_info ("Neighbor Event %s: *BadLSReq*", on->name);

  ospf6_neighbor_state_change (OSPF6_NEIGHBOR_EXSTART, on);
  SET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MSBIT);
  SET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MBIT);
  SET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_IBIT);

  ospf6_lsdb_remove_all (on->summary_list);
  ospf6_lsdb_remove_all (on->request_list);
  ospf6_lsdb_remove_all (on->retrans_list);

  THREAD_OFF (on->thread_send_dbdesc);
  on->thread_send_dbdesc =
    thread_add_event (master, ospf6_dbdesc_send, on, 0);

  return 0;
}

int
oneway_received (struct thread *thread)
{
  struct ospf6_neighbor *on;

  on = (struct ospf6_neighbor *) THREAD_ARG (thread);
  assert (on);

  if (on->state < OSPF6_NEIGHBOR_TWOWAY)
    return 0;

  if (IS_OSPF6_DEBUG_NEIGHBOR (EVENT))
    zlog_info ("Neighbor Event %s: *1Way-Received*", on->name);

  ospf6_neighbor_state_change (OSPF6_NEIGHBOR_INIT, on);
  thread_add_event (master, neighbor_change, on->ospf6_if, 0);

  ospf6_lsdb_remove_all (on->summary_list);
  ospf6_lsdb_remove_all (on->request_list);
  ospf6_lsdb_remove_all (on->retrans_list);

  THREAD_OFF (on->thread_send_dbdesc);
  THREAD_OFF (on->thread_send_lsreq);
  THREAD_OFF (on->thread_send_lsupdate);
  THREAD_OFF (on->thread_send_lsack);

  return 0;
}

int
inactivity_timer (struct thread *thread)
{
  struct ospf6_neighbor *on;

  on = (struct ospf6_neighbor *) THREAD_ARG (thread);
  assert (on);

  if (IS_OSPF6_DEBUG_NEIGHBOR (EVENT))
    zlog_info ("Neighbor Event %s: *InactivityTimer*", on->name);

  on->inactivity_timer = NULL;
  on->drouter = on->prev_drouter = 0;
  on->bdrouter = on->prev_bdrouter = 0;

  ospf6_neighbor_state_change (OSPF6_NEIGHBOR_DOWN, on);
  thread_add_event (master, neighbor_change, on->ospf6_if, 0);

  listnode_delete (on->ospf6_if->neighbor_list, on);
  ospf6_neighbor_delete (on);

  return 0;
}



/* vty functions */
/* show neighbor structure */
void
ospf6_neighbor_show (struct vty *vty, struct ospf6_neighbor *on)
{
  char router_id[16];
  char duration[16];
  struct timeval now, res;
  char nstate[16];
  char deadtime[16];
  long h, m, s;

  /* Router-ID (Name) */
  inet_ntop (AF_INET, &on->router_id, router_id, sizeof (router_id));
#ifdef HAVE_GETNAMEINFO
  {
  }
#endif /*HAVE_GETNAMEINFO*/

  gettimeofday (&now, NULL);

  /* Dead time */
  h = m = s = 0;
  if (on->inactivity_timer)
    {
      s = on->inactivity_timer->u.sands.tv_sec - now.tv_sec;
      h = s / 3600;
      s -= h * 3600;
      m = s / 60;
      s -= m * 60;
    }
  snprintf (deadtime, sizeof (deadtime), "%02ld:%02ld:%02ld", h, m, s);

  /* Neighbor State */
  if (if_is_pointopoint (on->ospf6_if->interface))
    snprintf (nstate, sizeof (nstate), "PointToPoint");
  else
    {
      if (on->router_id == on->drouter)
        snprintf (nstate, sizeof (nstate), "DR");
      else if (on->router_id == on->bdrouter)
        snprintf (nstate, sizeof (nstate), "BDR");
      else
        snprintf (nstate, sizeof (nstate), "DROther");
    }

  /* Duration */
  timersub (&now, &on->last_changed, &res);
  timerstring (&res, duration, sizeof (duration));

  /*
  vty_out (vty, "%-15s %3d %11s %6s/%-12s %11s %s[%s]%s",
           "Neighbor ID", "Pri", "DeadTime", "State", "", "Duration",
           "I/F", "State", VTY_NEWLINE);
  */

  vty_out (vty, "%-15s %3d %11s %6s/%-12s %11s %s[%s]%s",
           router_id, on->priority, deadtime,
           ospf6_neighbor_state_str[on->state], nstate, duration,
           on->ospf6_if->interface->name,
           ospf6_interface_state_str[on->ospf6_if->state], VTY_NEWLINE);
}

void
ospf6_neighbor_show_drchoice (struct vty *vty, struct ospf6_neighbor *on)
{
  char router_id[16];
  char drouter[16], bdrouter[16];
  char duration[16];
  struct timeval now, res;

/*
    vty_out (vty, "%-15s %6s/%-11s %-15s %-15s %s[%s]%s",
             "RouterID", "State", "Duration", "DR", "BDR", "I/F",
             "State", VTY_NEWLINE);
*/

  inet_ntop (AF_INET, &on->router_id, router_id, sizeof (router_id));
  inet_ntop (AF_INET, &on->drouter, drouter, sizeof (drouter));
  inet_ntop (AF_INET, &on->bdrouter, bdrouter, sizeof (bdrouter));

  gettimeofday (&now, NULL);
  timersub (&now, &on->last_changed, &res);
  timerstring (&res, duration, sizeof (duration));

  vty_out (vty, "%-15s %6s/%-11s %-15s %-15s %s[%s]%s",
           router_id, ospf6_neighbor_state_str[on->state],
           duration, drouter, bdrouter, on->ospf6_if->interface->name,
           ospf6_interface_state_str[on->ospf6_if->state],
           VTY_NEWLINE);
}

void
ospf6_neighbor_show_detail (struct vty *vty, struct ospf6_neighbor *on)
{
  char drouter[16], bdrouter[16];
  char linklocal_addr[64], duration[32];
  struct timeval now, res;
  struct ospf6_lsa *lsa;

  inet_ntop (AF_INET6, &on->linklocal_addr, linklocal_addr,
             sizeof (linklocal_addr));
  inet_ntop (AF_INET, &on->drouter, drouter, sizeof (drouter));
  inet_ntop (AF_INET, &on->bdrouter, bdrouter, sizeof (bdrouter));

  gettimeofday (&now, NULL);
  timersub (&now, &on->last_changed, &res);
  timerstring (&res, duration, sizeof (duration));

  vty_out (vty, " Neighbor %s%s", on->name,
           VTY_NEWLINE);
  vty_out (vty, "    Area %s via interface %s (ifindex %d)%s",
           on->ospf6_if->area->name,
           on->ospf6_if->interface->name,
           on->ospf6_if->interface->ifindex,
           VTY_NEWLINE);
  vty_out (vty, "    His IfIndex: %d Link-local address: %s%s",
           on->ifindex, linklocal_addr,
           VTY_NEWLINE);
  vty_out (vty, "    State %s for a duration of %s%s",
           ospf6_neighbor_state_str[on->state], duration,
           VTY_NEWLINE);
  vty_out (vty, "    His choice of DR/BDR %s/%s, Priority %d%s",
           drouter, bdrouter, on->priority,
           VTY_NEWLINE);
  vty_out (vty, "    DbDesc status: %s%s%s SeqNum: %#lx%s",
           (CHECK_FLAG (on->dbdesc_bits, OSPF6_DBDESC_IBIT) ? "Initial " : ""),
           (CHECK_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MBIT) ? "More " : ""),
           (CHECK_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MSBIT) ?
            "Master" : "Slave"), (u_long) ntohl (on->dbdesc_seqnum),
           VTY_NEWLINE);

  vty_out (vty, "    Summary-List: %d LSAs%s", on->summary_list->count,
           VTY_NEWLINE);
  for (lsa = ospf6_lsdb_head (on->summary_list); lsa;
       lsa = ospf6_lsdb_next (lsa))
    vty_out (vty, "      %s%s", lsa->name, VTY_NEWLINE);

  vty_out (vty, "    Request-List: %d LSAs%s", on->request_list->count,
           VTY_NEWLINE);
  for (lsa = ospf6_lsdb_head (on->request_list); lsa;
       lsa = ospf6_lsdb_next (lsa))
    vty_out (vty, "      %s%s", lsa->name, VTY_NEWLINE);

  vty_out (vty, "    Retrans-List: %d LSAs%s", on->retrans_list->count,
           VTY_NEWLINE);
  for (lsa = ospf6_lsdb_head (on->retrans_list); lsa;
       lsa = ospf6_lsdb_next (lsa))
    vty_out (vty, "      %s%s", lsa->name, VTY_NEWLINE);

  timerclear (&res);
  if (on->thread_send_dbdesc)
    timersub (&on->thread_send_dbdesc->u.sands, &now, &res);
  timerstring (&res, duration, sizeof (duration));
  vty_out (vty, "    %d Pending LSAs for DbDesc in Time %s [thread %s]%s",
           on->dbdesc_list->count, duration,
           (on->thread_send_dbdesc ? "on" : "off"),
           VTY_NEWLINE);
  for (lsa = ospf6_lsdb_head (on->dbdesc_list); lsa;
       lsa = ospf6_lsdb_next (lsa))
    vty_out (vty, "      %s%s", lsa->name, VTY_NEWLINE);

  timerclear (&res);
  if (on->thread_send_lsreq)
    timersub (&on->thread_send_lsreq->u.sands, &now, &res);
  timerstring (&res, duration, sizeof (duration));
  vty_out (vty, "    %d Pending LSAs for LSReq in Time %s [thread %s]%s",
           on->lsreq_list->count, duration,
           (on->thread_send_lsreq ? "on" : "off"),
           VTY_NEWLINE);
  for (lsa = ospf6_lsdb_head (on->lsreq_list); lsa;
       lsa = ospf6_lsdb_next (lsa))
    vty_out (vty, "      %s%s", lsa->name, VTY_NEWLINE);

  timerclear (&res);
  if (on->thread_send_lsupdate)
    timersub (&on->thread_send_lsupdate->u.sands, &now, &res);
  timerstring (&res, duration, sizeof (duration));
  vty_out (vty, "    %d Pending LSAs for LSUpdate in Time %s [thread %s]%s",
           on->lsupdate_list->count, duration,
           (on->thread_send_lsupdate ? "on" : "off"),
           VTY_NEWLINE);
  for (lsa = ospf6_lsdb_head (on->lsupdate_list); lsa;
       lsa = ospf6_lsdb_next (lsa))
    vty_out (vty, "      %s%s", lsa->name, VTY_NEWLINE);

  timerclear (&res);
  if (on->thread_send_lsack)
    timersub (&on->thread_send_lsack->u.sands, &now, &res);
  timerstring (&res, duration, sizeof (duration));
  vty_out (vty, "    %d Pending LSAs for LSAck in Time %s [thread %s]%s",
           on->lsack_list->count, duration,
           (on->thread_send_lsack ? "on" : "off"),
           VTY_NEWLINE);
  for (lsa = ospf6_lsdb_head (on->lsack_list); lsa;
       lsa = ospf6_lsdb_next (lsa))
    vty_out (vty, "      %s%s", lsa->name, VTY_NEWLINE);

}

DEFUN (show_ipv6_ospf6_neighbor,
       show_ipv6_ospf6_neighbor_cmd,
       "show ipv6 ospf6 neighbor",
       SHOW_STR
       IP6_STR
       OSPF6_STR
       "Neighbor list\n"
      )
{
  struct ospf6_neighbor *on;
  struct ospf6_interface *oi;
  struct ospf6_area *oa;
  listnode i, j, k;
  void (*showfunc) (struct vty *, struct ospf6_neighbor *);

  OSPF6_CMD_CHECK_RUNNING ();
  showfunc = ospf6_neighbor_show;

  if (argc)
    {
      if (! strncmp (argv[0], "de", 2))
        showfunc = ospf6_neighbor_show_detail;
      else if (! strncmp (argv[0], "dr", 2))
        showfunc = ospf6_neighbor_show_drchoice;
    }

  if (showfunc == ospf6_neighbor_show)
    vty_out (vty, "%-15s %3s %11s %6s/%-12s %11s %s[%s]%s",
             "Neighbor ID", "Pri", "DeadTime", "State", "IfState", "Duration",
             "I/F", "State", VTY_NEWLINE);
  else if (showfunc == ospf6_neighbor_show_drchoice)
    vty_out (vty, "%-15s %6s/%-11s %-15s %-15s %s[%s]%s",
             "RouterID", "State", "Duration", "DR", "BDR", "I/F",
             "State", VTY_NEWLINE);

  for (i = listhead (ospf6->area_list); i; nextnode (i))
    {
      oa = (struct ospf6_area *) getdata (i);
      for (j = listhead (oa->if_list); j; nextnode (j))
        {
          oi = (struct ospf6_interface *) getdata (j);
          for (k = listhead (oi->neighbor_list); k; nextnode (k))
            {
              on = (struct ospf6_neighbor *) getdata (k);
              (*showfunc) (vty, on);
            }
        }
    }
  return CMD_SUCCESS;
}

ALIAS (show_ipv6_ospf6_neighbor,
       show_ipv6_ospf6_neighbor_detail_cmd,
       "show ipv6 ospf6 neighbor (detail|drchoice)",
       SHOW_STR
       IP6_STR
       OSPF6_STR
       "Neighbor list\n"
       "Display details\n"
       "Display DR choices\n"
      );

DEFUN (show_ipv6_ospf6_neighbor_one,
       show_ipv6_ospf6_neighbor_one_cmd,
       "show ipv6 ospf6 neighbor A.B.C.D",
       SHOW_STR
       IP6_STR
       OSPF6_STR
       "Neighbor list\n"
       "Specify Router-ID as IPv4 address notation\n"
      )
{
  struct ospf6_neighbor *on;
  struct ospf6_interface *oi;
  struct ospf6_area *oa;
  listnode i, j, k;
  void (*showfunc) (struct vty *, struct ospf6_neighbor *);
  u_int32_t router_id;

  OSPF6_CMD_CHECK_RUNNING ();
  showfunc = ospf6_neighbor_show_detail;

  if ((inet_pton (AF_INET, argv[0], &router_id)) != 1)
    {
      vty_out (vty, "Router-ID is not parsable: %s%s", argv[0],
               VTY_NEWLINE);
      return CMD_SUCCESS;
    }

  for (i = listhead (ospf6->area_list); i; nextnode (i))
    {
      oa = (struct ospf6_area *) getdata (i);
      for (j = listhead (oa->if_list); j; nextnode (j))
        {
          oi = (struct ospf6_interface *) getdata (j);
          for (k = listhead (oi->neighbor_list); k; nextnode (k))
            {
              on = (struct ospf6_neighbor *) getdata (k);
              if (on->router_id == router_id)
                (*showfunc) (vty, on);
            }
        }
    }
  return CMD_SUCCESS;
}

void
ospf6_neighbor_init ()
{
  install_element (VIEW_NODE, &show_ipv6_ospf6_neighbor_cmd);
  install_element (VIEW_NODE, &show_ipv6_ospf6_neighbor_detail_cmd);
  install_element (ENABLE_NODE, &show_ipv6_ospf6_neighbor_cmd);
  install_element (ENABLE_NODE, &show_ipv6_ospf6_neighbor_detail_cmd);
}

DEFUN (debug_ospf6_neighbor,
       debug_ospf6_neighbor_cmd,
       "debug ospf6 neighbor",
       DEBUG_STR
       OSPF6_STR
       "Debug OSPFv3 Neighbor\n"
      )
{
  unsigned char level = 0;
  if (argc)
    {
      if (! strncmp (argv[0], "s", 1))
        level = OSPF6_DEBUG_NEIGHBOR_STATE;
      if (! strncmp (argv[0], "e", 1))
        level = OSPF6_DEBUG_NEIGHBOR_EVENT;
    }
  else
    level = OSPF6_DEBUG_NEIGHBOR_STATE | OSPF6_DEBUG_NEIGHBOR_EVENT;

  OSPF6_DEBUG_NEIGHBOR_ON (level);
  return CMD_SUCCESS;
}

ALIAS (debug_ospf6_neighbor,
       debug_ospf6_neighbor_detail_cmd,
       "debug ospf6 neighbor (state|event)",
       DEBUG_STR
       OSPF6_STR
       "Debug OSPFv3 Neighbor\n"
       "Debug OSPFv3 Neighbor State Change\n"
       "Debug OSPFv3 Neighbor Event\n"
      );

DEFUN (no_debug_ospf6_neighbor,
       no_debug_ospf6_neighbor_cmd,
       "no debug ospf6 neighbor",
       NO_STR
       DEBUG_STR
       OSPF6_STR
       "Debug OSPFv3 Neighbor\n"
      )
{
  unsigned char level = 0;
  if (argc)
    {
      if (! strncmp (argv[0], "s", 1))
        level = OSPF6_DEBUG_NEIGHBOR_STATE;
      if (! strncmp (argv[0], "e", 1))
        level = OSPF6_DEBUG_NEIGHBOR_EVENT;
    }
  else
    level = OSPF6_DEBUG_NEIGHBOR_STATE | OSPF6_DEBUG_NEIGHBOR_EVENT;

  OSPF6_DEBUG_NEIGHBOR_OFF (level);
  return CMD_SUCCESS;
}

ALIAS (no_debug_ospf6_neighbor,
       no_debug_ospf6_neighbor_detail_cmd,
       "no debug ospf6 neighbor (state|event)",
       NO_STR
       DEBUG_STR
       OSPF6_STR
       "Debug OSPFv3 Neighbor\n"
       "Debug OSPFv3 Neighbor State Change\n"
       "Debug OSPFv3 Neighbor Event\n"
      );

int
config_write_ospf6_debug_neighbor (struct vty *vty)
{
  if (IS_OSPF6_DEBUG_NEIGHBOR (STATE) &&
      IS_OSPF6_DEBUG_NEIGHBOR (EVENT))
    vty_out (vty, "debug ospf6 neighbor%s", VTY_NEWLINE);
  else if (IS_OSPF6_DEBUG_NEIGHBOR (STATE))
    vty_out (vty, "debug ospf6 neighbor state%s", VTY_NEWLINE);
  else if (IS_OSPF6_DEBUG_NEIGHBOR (EVENT))
    vty_out (vty, "debug ospf6 neighbor event%s", VTY_NEWLINE);
  return 0;
}

void
install_element_ospf6_debug_neighbor ()
{
  install_element (ENABLE_NODE, &debug_ospf6_neighbor_cmd);
  install_element (ENABLE_NODE, &debug_ospf6_neighbor_detail_cmd);
  install_element (ENABLE_NODE, &no_debug_ospf6_neighbor_cmd);
  install_element (ENABLE_NODE, &no_debug_ospf6_neighbor_detail_cmd);
  install_element (CONFIG_NODE, &debug_ospf6_neighbor_cmd);
  install_element (CONFIG_NODE, &debug_ospf6_neighbor_detail_cmd);
  install_element (CONFIG_NODE, &no_debug_ospf6_neighbor_cmd);
  install_element (CONFIG_NODE, &no_debug_ospf6_neighbor_detail_cmd);
}



