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

#include "ospf6d.h"

int
is_ospf6_message_dump (u_char type)
{
  if (type > OSPF6_MESSAGE_TYPE_LSACK)
    type = OSPF6_MESSAGE_TYPE_UNKNOWN;

  switch (type)
    {
      case OSPF6_MESSAGE_TYPE_UNKNOWN:
          return 1;
        break;
      case OSPF6_MESSAGE_TYPE_HELLO:
        if (IS_OSPF6_DUMP_HELLO)
          return 1;
        break;
      case OSPF6_MESSAGE_TYPE_DBDESC:
        if (IS_OSPF6_DUMP_DBDESC)
          return 1;
        break;
      case OSPF6_MESSAGE_TYPE_LSREQ:
        if (IS_OSPF6_DUMP_LSREQ)
          return 1;
        break;
      case OSPF6_MESSAGE_TYPE_LSUPDATE:
        if (IS_OSPF6_DUMP_LSUPDATE)
          return 1;
        break;
      case OSPF6_MESSAGE_TYPE_LSACK:
        if (IS_OSPF6_DUMP_LSACK)
          return 1;
        break;
      default:
        break;
    }
  return 0;
}
#define IS_OSPF6_DUMP_MESSAGE(x) (is_ospf6_message_dump(x))

char *ospf6_message_type_string[] =
{
  "Unknown", "Hello", "DbDesc", "LSReq", "LSUpdate", "LSAck", NULL
};

void
ospf6_message_log_lsa_header (struct ospf6_lsa_header *lsa_header)
{
  char buf_id[16], buf_router[16], typebuf[32];

  inet_ntop (AF_INET, &lsa_header->advrtr, buf_router, sizeof (buf_router));
  inet_ntop (AF_INET, &lsa_header->ls_id, buf_id, sizeof (buf_id));
  zlog_info ("   [%s ID=%s Adv=%s]",
             ospf6_lsa_type_string (lsa_header->type, typebuf,
                                    sizeof (typebuf)),
             buf_id, buf_router);
  zlog_info ("    Age=%hu SeqNum=%#lx Cksum=%#hx Len=%hu",
             ntohs (lsa_header->age), (u_long)ntohl (lsa_header->seqnum),
             ntohs (lsa_header->checksum), ntohs (lsa_header->length));
}

static void
ospf6_message_log_unknown (struct iovec *message)
{
  zlog_info ("Message:  Unknown");
}

static void
ospf6_message_log_hello (struct iovec *message)
{
  struct ospf6_header *ospf6_header;
  u_int16_t length_left;
  struct ospf6_hello *hello;
  char dr_str[16], bdr_str[16];
  char *start, *end, *current;

  /* calculate length */
  ospf6_header = (struct ospf6_header *) message[0].iov_base;
  length_left = ntohs (ospf6_header->len) - sizeof (struct ospf6_header);
  length_left = (length_left < iov_totallen (message) - sizeof (struct ospf6_header) ?
                 length_left : iov_totallen (message) - sizeof (struct ospf6_header));

  hello = (struct ospf6_hello *) message[1].iov_base;

  inet_ntop (AF_INET, &hello->dr, dr_str, sizeof (dr_str));
  inet_ntop (AF_INET, &hello->bdr, bdr_str, sizeof (bdr_str));

  zlog_info ("    IFID:%ld Priority:%d Option:%s",
             (u_long)ntohl (hello->interface_id), hello->rtr_pri, "xxx");
  zlog_info ("    HelloInterval:%hu Deadinterval:%hu",
             ntohs (hello->hello_interval),
             ntohs (hello->router_dead_interval));
  zlog_info ("    DR:%s BDR:%s", dr_str, bdr_str);

  start = (char *) (hello + 1);
  if (start >= (char *) message[1].iov_base + message[1].iov_len)
    start = message[2].iov_base;
  end = (char *) start + (length_left - sizeof (struct ospf6_hello));

  for (current = start; current < end; current += sizeof (u_int32_t))
    {
      char neighbor[16];
      inet_ntop (AF_INET, current, neighbor, sizeof (neighbor));
      zlog_info ("    Neighbor: %s", neighbor);
    }
}

static void
ospf6_message_log_dbdesc (struct iovec *message)
{
  struct ospf6_header *ospf6_header;
  u_int16_t length_left;
  struct ospf6_dbdesc *dbdesc;
  int i;
  char buffer[16];
  struct ospf6_lsa_header *lsa_header;

  /* calculate length */
  ospf6_header = (struct ospf6_header *) message[0].iov_base;
  length_left = ntohs (ospf6_header->len) - sizeof (struct ospf6_header);
  length_left = (length_left < iov_totallen (message) - sizeof (struct ospf6_header) ?
                 length_left : iov_totallen (message) - sizeof (struct ospf6_header));

  dbdesc = (struct ospf6_dbdesc *) message[1].iov_base;
  ospf6_options_string (dbdesc->options, buffer, sizeof (buffer));

  zlog_info ("    Option:%s IFMTU:%hu", buffer, ntohs (dbdesc->ifmtu));
  zlog_info ("    Bits:%s%s%s SeqNum:%#lx",
             (DD_IS_IBIT_SET (dbdesc->bits) ? "I" : "-"),
             (DD_IS_MBIT_SET (dbdesc->bits) ? "M" : "-"),
             (DD_IS_MSBIT_SET (dbdesc->bits) ? "m" : "s"),
             (u_long)ntohl (dbdesc->seqnum));

  for (lsa_header = (struct ospf6_lsa_header *) (dbdesc + 1);
       (char *)(lsa_header + 1) <= (char *)(message[1].iov_base + message[1].iov_len) &&
       (char *)(lsa_header + 1) <= (char *)dbdesc + length_left;
       lsa_header++)
    ospf6_message_log_lsa_header (lsa_header);

  length_left -= message[1].iov_len;
  for (i = 2; message[i].iov_base; i++)
    {
      for (lsa_header = (struct ospf6_lsa_header *) message[i].iov_base;
           (char *)(lsa_header + 1) <= (char *) (message[i].iov_base +
                                                 message[i].iov_len) &&
           (char *)(lsa_header + 1) <= (char *) (message[i].iov_base + length_left);
           lsa_header++)
        ospf6_message_log_lsa_header (lsa_header);
      length_left -= message[i].iov_len;
    }
}

static void
ospf6_message_log_lsreq (struct iovec *message)
{
  struct ospf6_header *ospf6_header;
  u_int16_t length_left;
  int i;
  struct ospf6_lsreq *lsreq;
  char buf_router[16], buf_id[16], buf_type[16];

  /* calculate length */
  ospf6_header = (struct ospf6_header *) message[0].iov_base;
  length_left = ntohs (ospf6_header->len) - sizeof (struct ospf6_header);
  length_left = (length_left < iov_totallen (message) - sizeof (struct ospf6_header) ?
                 length_left : iov_totallen (message) - sizeof (struct ospf6_header));

  for (i = 1; message[i].iov_base; i++)
    {
      for (lsreq = (struct ospf6_lsreq *) message[i].iov_base;
           (char *)(lsreq + 1) <= (char *) (message[i].iov_base + message[i].iov_len) &&
           (char *)(lsreq + 1) <= (char *) (message[i].iov_base + length_left);
           lsreq++)
        {
          inet_ntop (AF_INET, &lsreq->adv_router, buf_router, sizeof (buf_router));
          inet_ntop (AF_INET, &lsreq->id, buf_id, sizeof (buf_id));
          zlog_info ("    [%s ID=%s Adv=%s]",
                     ospf6_lsa_type_string (lsreq->type, buf_type,
                                            sizeof (buf_type)),
                     buf_id, buf_router);
        }
      length_left -= message[i].iov_len;
    }
}

static void
ospf6_message_log_lsupdate (struct iovec *message)
{
  struct ospf6_header *ospf6_header;
  u_int16_t length_left;
  int i, lsanum;
  struct ospf6_lsupdate *lsupdate;
  struct ospf6_lsa_header *lsa_header;

  /* calculate length */
  ospf6_header = (struct ospf6_header *) message[0].iov_base;
  length_left = ntohs (ospf6_header->len) - sizeof (struct ospf6_header);
  length_left = (length_left < iov_totallen (message) - sizeof (struct ospf6_header) ?
                 length_left : iov_totallen (message) - sizeof (struct ospf6_header));

  lsupdate = (struct ospf6_lsupdate *) message[1].iov_base;
  lsanum = ntohl (lsupdate->lsupdate_num);

  zlog_info ("    Number of LSA: #%d", lsanum);

  for (lsa_header = (struct ospf6_lsa_header *) (lsupdate + 1);
       (char *)lsa_header < (char *)(message[1].iov_base + message[1].iov_len) &&
       (char *)lsa_header < (char *)(message[1].iov_base + length_left);
       lsa_header = OSPF6_LSA_NEXT (lsa_header))
    ospf6_message_log_lsa_header (lsa_header);
  length_left -= message[1].iov_len;

  for (i = 2; message[i].iov_base; i++)
    {

      for (lsa_header = (struct ospf6_lsa_header *) message[i].iov_base;
           (char *)lsa_header < (char *) (message[i].iov_base + message[i].iov_len) &&
           (char *)lsa_header < (char *) (message[i].iov_base + length_left);
           lsa_header = OSPF6_LSA_NEXT (lsa_header))
        ospf6_message_log_lsa_header (lsa_header);
      length_left -= message[i].iov_len;
    }
}

static void
ospf6_message_log_lsack (struct iovec *message)
{
  struct ospf6_header *ospf6_header;
  u_int16_t length_left;
  struct ospf6_lsa_header *lsa_header;
  int i;

  /* calculate length */
  ospf6_header = (struct ospf6_header *) message[0].iov_base;
  length_left = ntohs (ospf6_header->len) - sizeof (struct ospf6_header);
  length_left = (length_left < iov_totallen (message) - sizeof (struct ospf6_header) ?
                 length_left : iov_totallen (message) - sizeof (struct ospf6_header));

  for (i = 1; message[i].iov_base; i++)
    {
      for (lsa_header = (struct ospf6_lsa_header *) message[i].iov_base;
           (char *)(lsa_header + 1) <= (char *) (message[i].iov_base +
                                                 message[i].iov_len) &&
           (char *)(lsa_header + 1) <= (char *) (message[i].iov_base + length_left);
           lsa_header++)
        ospf6_message_log_lsa_header (lsa_header);
      length_left -= message[i].iov_len;
    }
}

struct {
  void (*message_log) (struct iovec *);
} ospf6_message_log_body [] =
{
  {ospf6_message_log_unknown},
  {ospf6_message_log_hello},
  {ospf6_message_log_dbdesc},
  {ospf6_message_log_lsreq},
  {ospf6_message_log_lsupdate},
  {ospf6_message_log_lsack},
};

static void
ospf6_message_log (struct iovec *message)
{
  struct ospf6_header *o6h;
  char router_id[16], area_id[16];
  u_char type;

  assert (message[0].iov_len == sizeof (struct ospf6_header));
  o6h = (struct ospf6_header *) message[0].iov_base;

  inet_ntop (AF_INET, &o6h->router_id, router_id, sizeof (router_id));
  inet_ntop (AF_INET, &o6h->area_id, area_id, sizeof (area_id));

  zlog_info ("    OSPFv%d Type:%d Len:%hu RouterID:%s",
             o6h->version, o6h->type, ntohs (o6h->len), router_id);
  zlog_info ("    AreaID:%s Cksum:%hx InstanceID:%d",
             area_id, ntohs (o6h->cksum), o6h->instance_id);

  type = (OSPF6_MESSAGE_TYPE_UNKNOWN < o6h->type &&
          o6h->type <= OSPF6_MESSAGE_TYPE_LSACK ?
          o6h->type : OSPF6_MESSAGE_TYPE_UNKNOWN);
  (* ospf6_message_log_body[type].message_log) (&message[0]);
}

int
ospf6_opt_is_mismatch (unsigned char opt, char *options1, char *options2)
{
  return (OSPF6_OPT_ISSET (options1, opt) ^ OSPF6_OPT_ISSET (options2, opt));
}


void
ospf6_process_unknown (struct iovec *message,
                       struct in6_addr *src,
                       struct in6_addr *dst,
                       struct ospf6_interface *o6i,
                       u_int32_t router_id)
{
  zlog_warn ("unknown message type, drop");
}

void
ospf6_process_hello (struct iovec *message,
                     struct in6_addr *src,
                     struct in6_addr *dst,
                     struct ospf6_interface *o6i,
                     u_int32_t router_id)
{
  struct ospf6_header *ospf6_header;
  u_int16_t length;
  struct ospf6_hello *hello;
  char changes = 0;
#define CHANGE_RTRPRI (1 << 0)
#define CHANGE_DR     (1 << 1)
#define CHANGE_BDR    (1 << 2)
  int twoway = 0, backupseen = 0, nbchange = 0;
  u_int32_t *router_id_ptr;
  int i, seenrtrnum = 0, router_id_space = 0;
  char strbuf[64];
  struct ospf6_neighbor *o6n = NULL;

  /* assert interface */
  assert (o6i);

  /* caluculate length */
  ospf6_header = (struct ospf6_header *) message[0].iov_base;
  length = ntohs (ospf6_header->len) - sizeof (struct ospf6_header);
  length = (length < message[1].iov_len ? length : message[1].iov_len);

  /* set hello pointer */
  hello = (struct ospf6_hello *) message[1].iov_base;

  /* find neighbor. if cannot be found, create */
  o6n = ospf6_neighbor_lookup (router_id, o6i);
  if (!o6n)
    {
      o6n = ospf6_neighbor_create (router_id, o6i);
      o6n->ifid = ntohl (hello->interface_id);
      o6n->prevdr = o6n->dr = hello->dr;
      o6n->prevbdr = o6n->bdr = hello->bdr;
      o6n->priority = hello->rtr_pri;
      memcpy (&o6n->hisaddr, src, sizeof (struct in6_addr));
    }

  /* HelloInterval check */
  if (ntohs (hello->hello_interval) != o6i->hello_interval)
    {
      zlog_warn ("HelloInterval mismatch with %s", o6n->str);
      return;
    }

  /* RouterDeadInterval check */
  if (ntohs (hello->router_dead_interval)
      != o6i->dead_interval)
    {
      zlog_warn ("RouterDeadInterval mismatch with %s", o6n->str);
      return;
    }

  /* check options */
  /* Ebit */
  if (ospf6_opt_is_mismatch (OSPF6_OPT_E, hello->options, o6i->area->options))
    {
      zlog_warn ("Ebit mismatch with %s", o6n->str);
      return;
    }

  /* RouterPriority set */
  if (o6n->priority != hello->rtr_pri)
    {
      o6n->priority = hello->rtr_pri;
      if (IS_OSPF6_DUMP_HELLO)
        zlog_info ("%s: RouterPriority changed", o6n->str);
      changes |= CHANGE_RTRPRI;
    }

  /* DR set */
  if (o6n->dr != hello->dr)
    {
      /* save previous dr, set current */
      o6n->prevdr = o6n->dr;
      o6n->dr = hello->dr;
      inet_ntop (AF_INET, &o6n->dr, strbuf, sizeof (strbuf));
      if (IS_OSPF6_DUMP_HELLO)
        zlog_info ("%s declare %s as DR", o6n->str, strbuf);
      changes |= CHANGE_DR;
    }

  /* BDR set */
  if (o6n->bdr != hello->bdr)
    {
      /* save previous bdr, set current */
      o6n->prevbdr = o6n->bdr;
      o6n->bdr = hello->bdr;
      inet_ntop (AF_INET, &o6n->bdr, strbuf, sizeof (strbuf));
      if (IS_OSPF6_DUMP_HELLO)
        zlog_info ("%s declare %s as BDR", o6n->str, strbuf);
      changes |= CHANGE_BDR;
    }

  /* TwoWay check */
  router_id_space = length - sizeof (struct ospf6_hello);
  seenrtrnum = router_id_space / sizeof (u_int32_t);
  router_id_ptr = (u_int32_t *) (hello + 1);
  for (i = 0; i < seenrtrnum; i++)
    {
      if (*router_id_ptr == o6i->area->ospf6->router_id)
        twoway++;
      router_id_ptr++;
    }

  /* execute neighbor events */
  thread_execute (master, hello_received, o6n, 0);
  if (twoway)
    thread_execute (master, twoway_received, o6n, 0);
  else
    thread_execute (master, oneway_received, o6n, 0);

  /* BackupSeen check */
  if (o6i->state == IFS_WAITING)
    {
      if (hello->dr == hello->bdr &&
          hello->dr == o6n->router_id)
        zlog_warn ("*** DR Election of %s is illegal", o6n->str);

      if (hello->bdr == o6n->router_id)
        backupseen++;
      else if (hello->dr == o6n->router_id && hello->bdr == 0)
        backupseen++;
    }

  /* NeighborChange check */
  if (changes & CHANGE_RTRPRI)
    nbchange++;
  if (changes & CHANGE_DR)
    if (o6n->prevdr == o6n->router_id || o6n->dr == o6n->router_id)
      nbchange++;
  if (changes & CHANGE_BDR)
    if (o6n->prevbdr == o6n->router_id || o6n->bdr == o6n->router_id)
      nbchange++;

  /* schedule interface events */
  if (backupseen)
    thread_add_event (master, backup_seen, o6i, 0);
  if (nbchange)
    thread_add_event (master, neighbor_change, o6i, 0);

  return;
}

int
ospf6_dbdesc_is_master (struct ospf6_neighbor *o6n)
{
  char buf[128];

  if (o6n->router_id == ospf6->router_id)
    {
      inet_ntop (AF_INET6, &o6n->hisaddr, buf, sizeof (buf));
      zlog_warn ("Message: Neighbor router-id conflicts: %s: %s",
                 o6n->str, buf);
      return -1;
    }
  else if (ntohl (o6n->router_id) > ntohl (ospf6->router_id))
    return 0;
  return 1;
}

int
ospf6_dbdesc_is_duplicate (struct ospf6_dbdesc *received,
                           struct ospf6_dbdesc *last_received)
{
  if (memcmp (received->options, last_received->options, 3) != 0)
    return 0;
  if (received->ifmtu != last_received->ifmtu)
    return 0;
  if (received->bits != last_received->bits)
    return 0;
  if (received->seqnum != last_received->seqnum)
    return 0;
  return 1;
}

void
ospf6_process_dbdesc_master (struct iovec *message, struct ospf6_neighbor *o6n)
{
  struct ospf6_header *ospf6_header;
  u_int16_t length, lsa_count;
  struct ospf6_dbdesc *dbdesc;
  struct ospf6_lsa_header *lsa_header;

  /* caluculate length */
  ospf6_header = (struct ospf6_header *) message[0].iov_base;
  length = ntohs (ospf6_header->len) - sizeof (struct ospf6_header);
  length = (length < message[1].iov_len ? length : message[1].iov_len);

  /* set database description pointer */
  dbdesc = (struct ospf6_dbdesc *) message[1].iov_base;

  switch (o6n->state)
    {
      case NBS_DOWN:
      case NBS_ATTEMPT:
      case NBS_TWOWAY:
        if (IS_OSPF6_DUMP_DBDESC)
          zlog_info ("DbDesc from %s Ignored: state less than Init",
                     o6n->str);
        return;

      case NBS_INIT:
        thread_execute (master, twoway_received, o6n, 0);
        if (o6n->state != NBS_EXSTART)
          {
            if (IS_OSPF6_DUMP_DBDESC)
              zlog_info ("DbDesc from %s Ignored: state less than ExStart",
                         o6n->str);
            return;
          }
        /* else fall through to ExStart */
      case NBS_EXSTART:
        if (DDBIT_IS_SLAVE (dbdesc->bits) &&
            !DDBIT_IS_INITIAL (dbdesc->bits) &&
            ntohl (dbdesc->seqnum) == o6n->dbdesc_seqnum)
          {
            ospf6_neighbor_dbex_init (o6n);

            if (o6n->thread_rxmt_dbdesc)
              thread_cancel (o6n->thread_rxmt_dbdesc);
            o6n->thread_rxmt_dbdesc = (struct thread *) NULL;

            thread_add_event (master, negotiation_done, o6n, 0);
          }
        else
          {
            if (IS_OSPF6_DUMP_DBDESC)
              zlog_info ("  negotiation failed with %s", o6n->str);
            return;
          }
        break;

      case NBS_EXCHANGE:
        /* duplicate dbdesc dropped by master */
        if (!memcmp (dbdesc, &o6n->last_dd,
                     sizeof (struct ospf6_dbdesc)))
          {
            if (IS_OSPF6_DUMP_DBDESC)
              zlog_info ("  duplicate dbdesc, drop");
            return;
          }

        /* check Initialize bit and Master/Slave bit */
        if (DDBIT_IS_INITIAL (dbdesc->bits))
          {
            if (IS_OSPF6_DUMP_DBDESC)
              zlog_info ("Initialize bit mismatch");
            thread_add_event (master, seqnumber_mismatch, o6n, 0);
            return;
          }
        if (DDBIT_IS_MASTER (dbdesc->bits))
          {
            if (IS_OSPF6_DUMP_DBDESC)
              zlog_info ("Master/Slave bit mismatch");
            thread_add_event (master, seqnumber_mismatch, o6n, 0);
            return;
          }

        /* dbdesc option check */
        if (memcmp (dbdesc->options, o6n->last_dd.options,
                    sizeof (dbdesc->options)))
          {
            if (IS_OSPF6_DUMP_DBDESC)
              zlog_info ("dbdesc option field changed");
            thread_add_event (master, seqnumber_mismatch, o6n, 0);
            return;
          }

        /* dbdesc sequence number check */
        if (ntohl (dbdesc->seqnum) != o6n->dbdesc_seqnum)
          {
            if (IS_OSPF6_DUMP_DBDESC)
              zlog_warn ("*** dbdesc seqnumber mismatch: %d expected",
                         o6n->dbdesc_seqnum);
            thread_add_event (master, seqnumber_mismatch, o6n, 0);
            return;
          }
        break;

      case NBS_LOADING:
      case NBS_FULL:
        /* duplicate dbdesc dropped by master */
        if (ospf6_dbdesc_is_duplicate (dbdesc, &o6n->last_dd))
          {
            if (IS_OSPF6_DUMP_DBDESC)
              zlog_info ("  duplicate dbdesc, drop");
            return;
          }
        else
          {
            if (IS_OSPF6_DUMP_DBDESC)
              zlog_info ("  not duplicate dbdesc in state %s",
                         ospf6_neighbor_state_string[o6n->state]);
            thread_add_event (master, seqnumber_mismatch, o6n, 0);
            return;
          }
        break; /* not reached */

      default:
        assert (0);
        break; /* not reached */
    }

  /* process LSA headers */
  lsa_count = 0;
  for (lsa_header = (struct ospf6_lsa_header *) (dbdesc + 1);
       (char *)(lsa_header + 1) <= (char *)dbdesc + length;
       lsa_header++)
    {
      if (ospf6_dbex_check_dbdesc_lsa_header (lsa_header, o6n) < 0)
        {
          thread_add_event (master, seqnumber_mismatch, o6n, 0);
          return;
        }
      lsa_count ++;
    }

  /* increment dbdesc seqnum */
  o6n->dbdesc_seqnum++;

  /* cancel transmission/retransmission thread */
  if (o6n->thread_send_dbdesc)
    thread_cancel (o6n->thread_send_dbdesc);
  o6n->thread_send_dbdesc = (struct thread *) NULL;
  if (o6n->thread_rxmt_dbdesc)
    thread_cancel (o6n->thread_rxmt_dbdesc);
  o6n->thread_rxmt_dbdesc = (struct thread *) NULL;

  /* more bit check */
  if (!DD_IS_MBIT_SET (dbdesc->bits) && !DD_IS_MBIT_SET (o6n->dbdesc_bits))
    thread_add_event (master, exchange_done, o6n, 0);
  else
    o6n->thread_send_dbdesc =
      thread_add_event (master, ospf6_send_dbdesc, o6n, 0);

  /* save last received dbdesc */
  memcpy (&o6n->last_dd, dbdesc, sizeof (struct ospf6_dbdesc));

  /* statistics */
  o6n->lsa_receive[OSPF6_MESSAGE_TYPE_DBDESC] += lsa_count;

  return;
}

void
ospf6_process_dbdesc_slave (struct iovec *message, struct ospf6_neighbor *o6n)
{
  struct ospf6_header *ospf6_header;
  u_int16_t length, lsa_count;
  struct ospf6_dbdesc *dbdesc;
  struct ospf6_lsa_header *lsa_header;

  /* caluculate length */
  ospf6_header = (struct ospf6_header *) message[0].iov_base;
  length = ntohs (ospf6_header->len) - sizeof (struct ospf6_header);
  length = (length < message[1].iov_len ? length : message[1].iov_len);

  /* set database description pointer */
  dbdesc = (struct ospf6_dbdesc *) message[1].iov_base;

  switch (o6n->state)
    {
      case NBS_DOWN:
      case NBS_ATTEMPT:
      case NBS_TWOWAY:
        return;
      case NBS_INIT:
        thread_execute (master, twoway_received, o6n, 0);
        if (o6n->state != NBS_EXSTART)
          {
            return;
          }
        /* else fall through to ExStart */
      case NBS_EXSTART:
        if (DD_IS_IBIT_SET (dbdesc->bits) &&
            DD_IS_MBIT_SET (dbdesc->bits) &&
            DD_IS_MSBIT_SET (dbdesc->bits))
          {
            /* Master/Slave bit set to slave */
            DD_MSBIT_CLEAR (o6n->dbdesc_bits);
            /* Initialize bit clear */
            DD_IBIT_CLEAR (o6n->dbdesc_bits);
            /* sequence number set to master's */
            o6n->dbdesc_seqnum = ntohl (dbdesc->seqnum);
            ospf6_neighbor_dbex_init (o6n);

            if (o6n->thread_rxmt_dbdesc)
              thread_cancel (o6n->thread_rxmt_dbdesc);
            o6n->thread_rxmt_dbdesc = (struct thread *) NULL;

            thread_add_event (master, negotiation_done, o6n, 0);
          }
        else
          {
            if (IS_OSPF6_DUMP_DBDESC)
              zlog_info ("negotiation failed");
            return;
          }
        break;

      case NBS_EXCHANGE:
        /* duplicate dbdesc dropped by master */
        if (!memcmp (dbdesc, &o6n->last_dd,
                     sizeof (struct ospf6_dbdesc)))
          {
            if (IS_OSPF6_DUMP_DBDESC)
              zlog_info ("  duplicate dbdesc, retransmit dbdesc");

            if (o6n->thread_rxmt_dbdesc)
              thread_cancel (o6n->thread_rxmt_dbdesc);
            o6n->thread_rxmt_dbdesc =
              thread_add_event (master, ospf6_send_dbdesc_rxmt, o6n, 0);

            return;
          }

        /* check Initialize bit and Master/Slave bit */
        if (DDBIT_IS_INITIAL (dbdesc->bits))
          {
            if (IS_OSPF6_DUMP_DBDESC)
              zlog_info ("Initialize bit mismatch");
            thread_add_event (master, seqnumber_mismatch, o6n, 0);
            return;
          }
        if (DDBIT_IS_SLAVE (dbdesc->bits))
          {
            if (IS_OSPF6_DUMP_DBDESC)
              zlog_info ("Master/Slave bit mismatch");
            thread_add_event (master, seqnumber_mismatch, o6n, 0);
            return;
          }

        /* dbdesc option check */
        if (memcmp (dbdesc->options, o6n->last_dd.options,
                    sizeof (dbdesc->options)))
          {
            if (IS_OSPF6_DUMP_DBDESC)
              zlog_info ("dbdesc option field changed");
            thread_add_event (master, seqnumber_mismatch, o6n, 0);
            return;
          }

        /* dbdesc sequence number check */
        if (ntohl (dbdesc->seqnum) != o6n->dbdesc_seqnum + 1)
          {
            if (IS_OSPF6_DUMP_DBDESC)
              zlog_warn ("*** dbdesc seqnumber mismatch: %d expected",
                         o6n->dbdesc_seqnum + 1);
            thread_add_event (master, seqnumber_mismatch, o6n, 0);
            return;
          }
        break;

      case NBS_LOADING:
      case NBS_FULL:
        /* duplicate dbdesc cause slave to retransmit */
        if (ospf6_dbdesc_is_duplicate (dbdesc, &o6n->last_dd))
          {
            if (IS_OSPF6_DUMP_DBDESC)
              zlog_info ("  duplicate dbdesc, retransmit");

            if (o6n->thread_rxmt_dbdesc)
              thread_cancel (o6n->thread_rxmt_dbdesc);
            o6n->thread_rxmt_dbdesc =
              thread_add_event (master, ospf6_send_dbdesc_rxmt, o6n, 0);

            return;
          }
        else
          {
            if (IS_OSPF6_DUMP_DBDESC)
              zlog_info ("  not duplicate dbdesc in state %s",
                         ospf6_neighbor_state_string[o6n->state]);
            thread_add_event (master, seqnumber_mismatch, o6n, 0);
            return;
          }
        break; /* not reached */

      default:
        assert (0);
        break; /* not reached */
    }

  /* process LSA headers */
  lsa_count = 0;
  for (lsa_header = (struct ospf6_lsa_header *) (dbdesc + 1);
       (char *)(lsa_header + 1) <= (char *)dbdesc + length;
       lsa_header++)
    {
      if (ospf6_dbex_check_dbdesc_lsa_header (lsa_header, o6n) < 0)
        {
          thread_add_event (master, seqnumber_mismatch, o6n, 0);
          return;
        }
      lsa_count ++;
    }

  /* set dbdesc seqnum to master's */
  o6n->dbdesc_seqnum = ntohl (dbdesc->seqnum);

  if (o6n->thread_send_dbdesc)
    thread_cancel (o6n->thread_send_dbdesc);
  o6n->thread_send_dbdesc =
    thread_add_event (master, ospf6_send_dbdesc, o6n, 0);

  /* save last received dbdesc */
  memcpy (&o6n->last_dd, dbdesc, sizeof (struct ospf6_dbdesc));

  /* statistics */
  o6n->lsa_receive[OSPF6_MESSAGE_TYPE_DBDESC] += lsa_count;

  return;
}

void
ospf6_process_dbdesc (struct iovec *message,
                      struct in6_addr *src,
                      struct in6_addr *dst,
                      struct ospf6_interface *o6i,
                      u_int32_t router_id)
{
  struct ospf6_header *ospf6_header;
  u_int16_t length;
  struct ospf6_neighbor *o6n;
  struct ospf6_dbdesc *dbdesc;
  int Im_master = 0;

  /* assert interface */
  assert (o6i);

  /* caluculate length */
  ospf6_header = (struct ospf6_header *) message[0].iov_base;
  length = ntohs (ospf6_header->len) - sizeof (struct ospf6_header);
  length = (length < message[1].iov_len ? length : message[1].iov_len);

  /* set database description pointer */
  dbdesc = (struct ospf6_dbdesc *) message[1].iov_base;

  /* find neighbor. if cannot be found, reject this message */
  o6n = ospf6_neighbor_lookup (router_id, o6i);
  if (!o6n)
    {
      if (IS_OSPF6_DUMP_DBDESC)
        zlog_info ("neighbor not found, reject");
      return;
    }

  if (memcmp (src, &o6n->hisaddr, sizeof (struct in6_addr)))
    {
      if (IS_OSPF6_DUMP_MESSAGE (ospf6_header->type))
        zlog_info ("From Secondary I/F of the neighbor: ignore");
      return;
    }

  /* interface mtu check */
    /* xxx */

  /* check am I master */
  Im_master = ospf6_dbdesc_is_master (o6n);
  if (Im_master < 0)
    {
      return; /* can't decide which is master, return */
    }

  if (Im_master)
    ospf6_process_dbdesc_master (message, o6n);
  else
    ospf6_process_dbdesc_slave (message, o6n);

  return;
}

void
ospf6_process_lsreq (struct iovec *message,
                     struct in6_addr *src,
                     struct in6_addr *dst,
                     struct ospf6_interface *o6i,
                     u_int32_t router_id)
{
  struct ospf6_header *ospf6_header;
  u_int16_t length;
  struct ospf6_neighbor *o6n;
  struct ospf6_lsreq *lsreq;
  struct iovec response[OSPF6_MESSAGE_IOVEC_SIZE];
  struct ospf6_lsa *lsa;
  unsigned long lsanum = 0;
  struct ospf6_lsupdate lsupdate;
  char buf_id[16], buf_router[16], buf_type[16];

  /* assert interface */
  assert (o6i);

  /* caluculate length */
  ospf6_header = (struct ospf6_header *) message[0].iov_base;
  length = ntohs (ospf6_header->len) - sizeof (struct ospf6_header);
  length = (length < message[1].iov_len ? length : message[1].iov_len);

  /* find neighbor. if cannot be found, reject this message */
  o6n = ospf6_neighbor_lookup (router_id, o6i);
  if (!o6n)
    {
      if (IS_OSPF6_DUMP_LSREQ)
        zlog_info ("  neighbor not found, reject");
      return;
    }

  if (memcmp (src, &o6n->hisaddr, sizeof (struct in6_addr)))
    {
      if (IS_OSPF6_DUMP_MESSAGE (ospf6_header->type))
        zlog_info ("From Secondary I/F of the neighbor: ignore");
      return;
    }

  /* In states other than ExChange, Loading, or Full, the packet
     should be ignored. */
  if (o6n->state != NBS_EXCHANGE && o6n->state != NBS_LOADING
      && o6n->state != NBS_FULL)
    {
      if (IS_OSPF6_DUMP_LSREQ)
        zlog_info ("  neighbor state less than Exchange, reject");
      return;
    }

  /* Initialize response LSUpdate packet */
  OSPF6_MESSAGE_CLEAR (response);
  memset (&lsupdate, 0, sizeof (struct ospf6_lsupdate));
  OSPF6_MESSAGE_ATTACH (response, &lsupdate, sizeof (struct ospf6_lsupdate));

  /* process each request */
  lsanum = 0;
  for (lsreq = (struct ospf6_lsreq *) message[1].iov_base;
       (char *)(lsreq + 1) <= (char *)(message[1].iov_base + length);
       lsreq++)
    {
      inet_ntop (AF_INET, &lsreq->adv_router, buf_router, sizeof (buf_router));
      inet_ntop (AF_INET, &lsreq->id, buf_id, sizeof (buf_id));

      /* find instance of database copy */
      lsa = ospf6_lsdb_lookup (lsreq->type, lsreq->id, lsreq->adv_router,
                               ospf6_lsa_get_scope (lsreq->type, o6i));

      if (!lsa)
        {
          if (IS_OSPF6_DUMP_LSREQ)
            zlog_info ("BadLSReq: %s requests [%s ID=%s Adv=%s] not found",
                       o6n->str, ospf6_lsa_type_string (lsreq->type, buf_type,
                                                        sizeof (buf_type)),
                       buf_id, buf_router);
          thread_add_event (master, bad_lsreq, o6n, 0);
          return;
        }

      /* I/F MTU check */
      if (sizeof (struct ospf6_header) + sizeof (struct ospf6_lsupdate)
          + iov_totallen (response) + ntohs (lsa->header->length)
          > o6i->ifmtu)
        break;

      OSPF6_MESSAGE_ATTACH (response, lsa->header, ntohs (lsa->header->length));
      lsanum++;
    }

  /* send response LSUpdate to this request */
  if (lsanum)
    {
      lsupdate.lsupdate_num = htonl (lsanum);

      ospf6_message_send (OSPF6_MESSAGE_TYPE_LSUPDATE, response,
                          &o6n->hisaddr, o6i->if_id);
    }

  /* statistics */
  o6n->lsa_receive[OSPF6_MESSAGE_TYPE_LSREQ]
    += length / sizeof (struct ospf6_lsreq);
}

void
ospf6_process_lsupdate (struct iovec *message,
                        struct in6_addr *src,
                        struct in6_addr *dst,
                        struct ospf6_interface *o6i,
                        u_int32_t router_id)
{
  struct ospf6_header *ospf6_header;
  u_int16_t length;
  struct ospf6_lsupdate *lsupdate;
  struct ospf6_neighbor *o6n;
  unsigned long lsanum;
  struct ospf6_lsa_header *lsa_header;

  /* assert interface */
  assert (o6i);

  /* caluculate length */
  ospf6_header = (struct ospf6_header *) message[0].iov_base;
  length = ntohs (ospf6_header->len) - sizeof (struct ospf6_header);
  length = (length < message[1].iov_len ? length : message[1].iov_len);

  /* find neighbor. if cannot be found, reject this message */
  o6n = ospf6_neighbor_lookup (router_id, o6i);
  if (! o6n)
    {
      if (IS_OSPF6_DUMP_LSUPDATE)
        zlog_info ("  neighbor not found, reject");
      return;
    }

  if (memcmp (src, &o6n->hisaddr, sizeof (struct in6_addr)))
    {
      if (IS_OSPF6_DUMP_MESSAGE (ospf6_header->type))
        zlog_info ("From Secondary I/F of the neighbor: ignore");
      return;
    }

  /* if neighbor state less than ExChange, reject this message */
  if (o6n->state < NBS_EXCHANGE)
    {
      if (IS_OSPF6_DUMP_LSUPDATE)
        zlog_info ("  neighbor state less than Exchange, reject");
      return;
    }

  /* set linkstate update pointer */
  lsupdate = (struct ospf6_lsupdate *) message[1].iov_base;

  /* save linkstate update info */
  lsanum = ntohl (lsupdate->lsupdate_num);

  /* statistics */
  o6n->ospf6_stat_received_lsa += lsanum;
  o6n->ospf6_stat_received_lsupdate++;

  /* RFC2328 Section 10.9: When the neighbor responds to these requests
     with the proper Link State Update packet(s), the Link state request
     list is truncated and a new Link State Request packet is sent. */

  /* process LSAs */
  for (lsa_header = (struct ospf6_lsa_header *) (lsupdate + 1);
       lsanum && (char *)lsa_header < (char *)lsupdate + length;
       lsanum--)
    {
      ospf6_dbex_receive_lsa (lsa_header, o6n);
      lsa_header = OSPF6_LSA_NEXT (lsa_header);
    }

  /* send new Link State Request packet if this LS Update packet
     can be recognized as a response to our previous LS request */
  if (! IN6_IS_ADDR_MULTICAST(dst) &&
      (o6n->state == NBS_EXCHANGE || o6n->state == NBS_LOADING))
    thread_add_event (master, ospf6_send_lsreq, o6n, 0);

  return;
}

void
ospf6_process_lsack (struct iovec *message,
                     struct in6_addr *src,
                     struct in6_addr *dst,
                     struct ospf6_interface *o6i,
                     u_int32_t router_id)
{
  struct ospf6_header *ospf6_header;
  u_int16_t length;
  struct ospf6_neighbor *o6n;
  struct ospf6_lsa_header *lsa_header;
  struct ospf6_lsa *lsa, *copy, *rem;

  /* assert interface */
  assert (o6i);

  /* caluculate length */
  ospf6_header = (struct ospf6_header *) message[0].iov_base;
  length = ntohs (ospf6_header->len) - sizeof (struct ospf6_header);
  length = (length < message[1].iov_len ? length : message[1].iov_len);

  /* find neighbor. if cannot be found, reject this message */
  o6n = ospf6_neighbor_lookup (router_id, o6i);
  if (!o6n)
    {
      if (IS_OSPF6_DUMP_LSACK)
        zlog_info ("LSACK: neighbor not found, reject");
      return;
    }

  if (memcmp (src, &o6n->hisaddr, sizeof (struct in6_addr)))
    {
      if (IS_OSPF6_DUMP_LSACK)
        zlog_info ("LSACK: From Secondary I/F of the neighbor: ignore");
      return;
    }

  /* if neighbor state less than ExChange, reject this message */
  if (o6n->state < NBS_EXCHANGE)
    {
      if (IS_OSPF6_DUMP_LSACK)
        zlog_info ("LSACK: neighbor state less than Exchange, reject");
      return;
    }

  /* process each LSA header */
  for (lsa_header = (struct ospf6_lsa_header *) message[1].iov_base;
       (char *)(lsa_header + 1) <= (char *)(message[1].iov_base + length);
       lsa_header++)
    {
      /* find database copy */
      copy = ospf6_lsdb_lookup (lsa_header->type, lsa_header->ls_id,
                                lsa_header->advrtr,
                                ospf6_lsa_get_scope (lsa_header->type, o6i));

      /* if no database copy */
      if (!copy)
        {
          if (IS_OSPF6_DUMP_LSACK)
            zlog_info ("LSACK: no database copy, ignore");
          continue;
        }

      /* if not on his retrans list */
      rem = ospf6_lsdb_lookup_lsdb (copy->header->type, copy->header->id,
                                    copy->header->adv_router,
                                    o6n->retrans_list);
      if (rem == NULL)
        {
          if (IS_OSPF6_DUMP_LSACK)
            zlog_info ("LSACK: not on %s's retranslist, ignore", o6n->str);
          continue;
        }

      /* create temporary LSA from Ack message */
      lsa = ospf6_lsa_summary_create ((struct ospf6_lsa_header__ *) lsa_header);

      /* if the same instance, remove from retrans list.
         else, log and ignore */
      if (ospf6_lsa_check_recent (lsa, copy) == 0)
        ospf6_neighbor_retrans_remove (rem, o6n);
      else
        {
          /* Log the questionable acknowledgement,
             and examine the next one. */
          zlog_info ("LSACK: questionable acknowledge: %s", copy->str);
          zlog_info ("LSACK:   received: seq: %#x age: %hu",
                     ntohl (lsa->header->seqnum),
                     ntohs (lsa->header->age));
          zlog_info ("LSACK:   instance: seq: %#x age: %hu",
                     ntohl (copy->header->seqnum),
                     ospf6_lsa_age_current (copy));
        }

      /* release temporary LSA from Ack message */
      ospf6_lsa_delete (lsa);
    }

  ospf6_maxage_remover ();
  return;
}

struct {
  void (*process) (struct iovec *, struct in6_addr *, struct in6_addr *,
                   struct ospf6_interface *, u_int32_t);
} ospf6_message_process_type [] =
{
  {ospf6_process_unknown},
  {ospf6_process_hello},
  {ospf6_process_dbdesc},
  {ospf6_process_lsreq},
  {ospf6_process_lsupdate},
  {ospf6_process_lsack}
};

/* process ospf6 protocol header. then, call next process function
   for each message type */
static void 
ospf6_message_process (struct iovec *message,
                       struct in6_addr *src,
                       struct in6_addr *dst,
                       struct ospf6_interface *o6i)
{
  struct ospf6_header *ospf6_header = NULL;
  u_char type;
  u_int32_t router_id;
  char srcname[64];

  assert (o6i);
  assert (src);
  assert (dst);

  /* set ospf6_hdr pointer to head of buffer */
  ospf6_header = (struct ospf6_header *) message[0].iov_base;

  /* version check */
  if (ospf6_header->version != OSPF6_VERSION)
    {
      if (IS_OSPF6_DUMP_MESSAGE (ospf6_header->type))
        zlog_info ("version mismatch, drop");
      return;
    }

  /* area id check */
  if (ospf6_header->area_id != o6i->area->area_id)
    {
      if (ospf6_header->area_id == 0)
        {
          if (IS_OSPF6_DUMP_MESSAGE (ospf6_header->type))
            zlog_info ("virtual link not yet, drop");
          return;
        }

      if (IS_OSPF6_DUMP_MESSAGE (ospf6_header->type))
        zlog_info ("area id mismatch, drop");
      return;
    }

  /* instance id check */
  if (ospf6_header->instance_id != o6i->instance_id)
    {
      if (IS_OSPF6_DUMP_MESSAGE (ospf6_header->type))
        zlog_info ("instance id mismatch, drop");
      return;
    }

  /* message type check */
  type = (ospf6_header->type >= OSPF6_MESSAGE_TYPE_MAX ?
          OSPF6_MESSAGE_TYPE_UNKNOWN : ospf6_header->type);

  /* log */
  if (IS_OSPF6_DUMP_MESSAGE (type))
    {
      char srcname[64], dstname[64];
      inet_ntop (AF_INET6, dst, dstname, sizeof (dstname));
      inet_ntop (AF_INET6, src, srcname, sizeof (srcname));
      zlog_info ("Receive %s on %s",
                 ospf6_message_type_string[type], o6i->interface->name);
      zlog_info ("    %s -> %s", srcname, dstname);
      ospf6_message_log (message);
    }

  /* router id check */
  router_id = ospf6_header->router_id;
  if (ospf6_header->router_id == o6i->area->ospf6->router_id)
    {
      inet_ntop (AF_INET6, src, srcname, sizeof (srcname));
      zlog_warn ("*** Router-ID mismatch: from %s on %s",
                 srcname, o6i->interface->name);
      return;
    }

  /* octet statistics relies on some asumption:
       on ethernet, no IPv6 Extention header, etc */
#define OSPF6_IP6_HEADER_SIZE   40
#define OSPF6_ETHER_HEADER_SIZE 14
  o6i->message_stat[type].recv++;
  o6i->message_stat[type].recv_octet += ntohs (ospf6_header->len)
    + OSPF6_IP6_HEADER_SIZE + OSPF6_ETHER_HEADER_SIZE;

  /* futher process */
  (*ospf6_message_process_type[type].process) (&message[0], src, dst, o6i, router_id);

  return;
}

int
ospf6_receive (struct thread *thread)
{
  int sockfd;
  struct in6_addr src, dst;
  unsigned int ifindex;
  struct iovec message[OSPF6_MESSAGE_IOVEC_SIZE];
  struct ospf6_header ospf6_header;
  char buffer[OSPF6_MESSAGE_RECEIVE_BUFSIZE];
  struct ospf6_interface *o6i;
  unsigned char type;

  /* get socket */
  sockfd = THREAD_FD (thread);

  /* add next read thread */
  thread_add_read (master, ospf6_receive, NULL, sockfd);

  /* initialize */
  OSPF6_MESSAGE_CLEAR (message);
  memset (&ospf6_header, 0, sizeof (struct ospf6_header));

  OSPF6_MESSAGE_ATTACH (message, &ospf6_header, sizeof (struct ospf6_header));
  OSPF6_MESSAGE_ATTACH (message, buffer, OSPF6_MESSAGE_RECEIVE_BUFSIZE);

  /* receive message */
  ospf6_recvmsg (&src, &dst, &ifindex, message);

  type = (OSPF6_MESSAGE_TYPE_UNKNOWN < ospf6_header.type &&
          ospf6_header.type <= OSPF6_MESSAGE_TYPE_LSACK ?
          ospf6_header.type : OSPF6_MESSAGE_TYPE_UNKNOWN);
  o6i = ospf6_interface_lookup_by_index (ifindex);
  if (!o6i || !o6i->area)
    {
      //zlog_warn ("*** received interface ospf6 disabled");
      return 0;
    }

  /* if not passive, process message */
  if (! CHECK_FLAG (o6i->flag, OSPF6_INTERFACE_FLAG_PASSIVE))
    ospf6_message_process (message, &src, &dst, o6i);
  else if (IS_OSPF6_DUMP_MESSAGE (type))
    zlog_info ("Ignore message on passive interface %s",
               o6i->interface->name);

  return 0;
}


/* send section */
int
ospf6_message_length (struct iovec *message)
{
  int i, length = 0;
  for (i = 0; i < OSPF6_MESSAGE_IOVEC_SIZE; i++)
    {
      if (message[i].iov_base == NULL && message[i].iov_len == 0)
        break;
      length += message[i].iov_len;
    }
  return length;
}
#define OSPF6_MESSAGE_LENGTH(msg) \
(ospf6_message_length (msg))

void
ospf6_message_send (unsigned char type, struct iovec *msg,
                    struct in6_addr *dst, u_int ifindex)
{
  struct ospf6_interface *o6i;
  struct ospf6_header ospf6_header;
  char dst_name[64], src_name[64];
  struct iovec message[OSPF6_MESSAGE_IOVEC_SIZE];
  int msg_len;

  /* ospf6 interface lookup */
  o6i = ospf6_interface_lookup_by_index (ifindex);
  assert (o6i);

  msg_len = OSPF6_MESSAGE_LENGTH (msg);

  /* I/F MTU check */
#if 0
  if (msg_len + sizeof (struct ospf6_header) >= o6i->interface->mtu)
#else
  if (msg_len + sizeof (struct ospf6_header) >= o6i->ifmtu)
#endif
    {
      /* If Interface MTU is 0, save the case
         since zebra had been failed to get MTU from Kernel */
      if (o6i->interface->mtu != 0)
        {
          zlog_warn ("Message: Send failed on %s: exceeds I/F MTU",
                     o6i->interface->name);
          zlog_warn ("Message:   while sending %s: Len:%d MTU:%d",
                     ospf6_message_type_string[type],
                     msg_len + sizeof (struct ospf6_header),
                     o6i->ifmtu);
          return;
        }
      else
        {
          zlog_warn ("Message: I/F MTU check ignored on %s",
                     o6i->interface->name);
        }
    }

  /* Initialize */
  OSPF6_MESSAGE_CLEAR (message);

  /* set OSPF header */
  memset (&ospf6_header, 0, sizeof (ospf6_header));
  ospf6_header.version = OSPF6_VERSION;
  ospf6_header.type = type;
  ospf6_header.len = htons (msg_len + sizeof (struct ospf6_header));
  ospf6_header.router_id = ospf6->router_id;
  ospf6_header.area_id = o6i->area->area_id;
  /* checksum is calculated by kernel */
  ospf6_header.instance_id = o6i->instance_id;
  ospf6_header.reserved = 0;
  OSPF6_MESSAGE_ATTACH (message, &ospf6_header, sizeof (struct ospf6_header));

  /* Attach rest to message */
  OSPF6_MESSAGE_JOIN (message, msg);

  /* statistics */
  if (type >= OSPF6_MESSAGE_TYPE_MAX)
    type = OSPF6_MESSAGE_TYPE_UNKNOWN;
  o6i->message_stat[type].send++;
  o6i->message_stat[type].send_octet += ntohs (ospf6_header.len);

  /* log */
  if (IS_OSPF6_DUMP_MESSAGE (type))
    {
      inet_ntop (AF_INET6, dst, dst_name, sizeof (dst_name));
      if (o6i->lladdr)
        inet_ntop (AF_INET6, o6i->lladdr, src_name, sizeof (src_name));
      else
        memcpy (src_name, "Unknown", sizeof (src_name));
      zlog_info ("Send %s on %s",
                 ospf6_message_type_string[type], o6i->interface->name);
      zlog_info ("    %s -> %s", src_name, dst_name);
      ospf6_message_log (message);
    }

  /* send message */
  ospf6_sendmsg (o6i->lladdr, dst, &ifindex, message);
}


int
ospf6_send_hello (struct thread *thread)
{
  listnode n;
  struct ospf6_interface *o6i;
  struct ospf6_neighbor *o6n;
  struct in6_addr dst;
  struct iovec message[OSPF6_MESSAGE_IOVEC_SIZE];
  struct ospf6_hello hello;
  char router_buffer[1024]; /* xxx */
  u_int router_size;

  /* which ospf6 interface to send */
  o6i = (struct ospf6_interface *) THREAD_ARG (thread);
  o6i->thread_send_hello = (struct thread *) NULL;

  /* assure interface is up */
  if (o6i->state <= IFS_DOWN)
    {
      if (IS_OSPF6_DUMP_HELLO)
        zlog_warn ("Send HELLO Failed: Interface not enabled: %s",
                   o6i->interface->name);
      return 0;
    }

  /* clear message buffer */
  OSPF6_MESSAGE_CLEAR (message);

  /* set Hello fields */
  hello.interface_id = htonl (o6i->if_id);
  hello.rtr_pri = o6i->priority;
  memcpy (hello.options, o6i->area->options, sizeof (hello.options));
  hello.hello_interval = htons (o6i->hello_interval);
  hello.router_dead_interval = htons (o6i->dead_interval);
  hello.dr = o6i->dr;
  hello.bdr = o6i->bdr;
  OSPF6_MESSAGE_ATTACH (message, &hello, sizeof (struct ospf6_hello));

  /* set neighbor router id */
  router_size = 0;
  for (n = listhead (o6i->neighbor_list); n; nextnode (n))
    {
      o6n = (struct ospf6_neighbor *) getdata (n);

      if (o6n->state < NBS_INIT)
        continue;

      if (router_size + sizeof (o6n->router_id) > sizeof (router_buffer))
        {
          zlog_warn ("Send HELLO: Buffer shortage on %s",
                     o6i->interface->name);
          break;
        }

      /* Copy Router-ID to Buffer */
      memcpy (router_buffer + router_size, &o6n->router_id,
              sizeof (o6n->router_id));
      router_size += sizeof (o6n->router_id);
    }
  OSPF6_MESSAGE_ATTACH (message, router_buffer, router_size);

  /* set destionation */
  inet_pton (AF_INET6, ALLSPFROUTERS6, &dst);

  /* send hello */
  ospf6_message_send (OSPF6_MESSAGE_TYPE_HELLO, message, &dst,
                      o6i->interface->ifindex);

  /* set next timer thread */
  o6i->thread_send_hello = thread_add_timer (master, ospf6_send_hello,
                                             o6i, o6i->hello_interval);

  return 0;
}

void
ospf6_dbdesc_seqnum_init (struct ospf6_neighbor *o6n)
{
  struct timeval tv;

  if (gettimeofday (&tv, (struct timezone *) NULL) < 0)
    tv.tv_sec = 1;

  o6n->dbdesc_seqnum = tv.tv_sec;

  if (IS_OSPF6_DUMP_DBDESC)
    zlog_info ("set dbdesc seqnum %d for %s", o6n->dbdesc_seqnum, o6n->str);
}

int
ospf6_send_dbdesc_rxmt (struct thread *thread)
{
  struct ospf6_lsdb_node node;
  struct ospf6_neighbor *o6n;
  struct iovec message[OSPF6_MESSAGE_IOVEC_SIZE];
  struct ospf6_lsa *lsa;
  struct ospf6_lsa_header *lsa_header;
  struct ospf6_dbdesc dbdesc;

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

  /* clear thread */
  o6n->thread_rxmt_dbdesc = (struct thread *) NULL;

  /* if state less than ExStart, do nothing */
  if (o6n->state < NBS_EXSTART)
    return 0;

  OSPF6_MESSAGE_CLEAR (message);

  /* set dbdesc */
  memcpy (dbdesc.options, o6n->ospf6_interface->area->options,
          sizeof (dbdesc.options));
  dbdesc.ifmtu = htons (o6n->ospf6_interface->interface->mtu);
  dbdesc.bits = o6n->dbdesc_bits;
  dbdesc.seqnum = htonl (o6n->dbdesc_seqnum);
  OSPF6_MESSAGE_ATTACH (message, &dbdesc, sizeof (struct ospf6_dbdesc));

  /* if this is not initial, set LSA summary to dbdesc */
  if (! DD_IS_IBIT_SET (o6n->dbdesc_bits))
    {
      for (ospf6_lsdb_head (&node, o6n->dbdesc_list);
           ! ospf6_lsdb_is_end (&node); ospf6_lsdb_next (&node))
        {
          lsa = node.lsa;

          /* xxx, no MTU check: no support for Dynamic MTU change */

          /* set age and add InfTransDelay */
          ospf6_lsa_age_update_to_send (lsa, o6n->ospf6_interface->transdelay);

          /* set LSA summary to send buffer */
          lsa_header = (struct ospf6_lsa_header *) lsa->lsa_hdr;
          OSPF6_MESSAGE_ATTACH (message, lsa_header,
                                sizeof (struct ospf6_lsa_header));
        }
    }

  /* send dbdesc */
  ospf6_message_send (OSPF6_MESSAGE_TYPE_DBDESC, message, &o6n->hisaddr,
                      o6n->ospf6_interface->interface->ifindex);

  /* if master, set futher retransmission */
  if (DD_IS_MSBIT_SET (o6n->dbdesc_bits))
    o6n->thread_rxmt_dbdesc =
      thread_add_timer (master, ospf6_send_dbdesc_rxmt,
                        o6n, o6n->ospf6_interface->rxmt_interval);

  /* statistics */
  o6n->ospf6_stat_retrans_dbdesc++;

  return 0;
}

int
ospf6_send_dbdesc (struct thread *thread)
{
  struct ospf6_neighbor *o6n;
  struct ospf6_lsa *lsa;
  struct iovec message[OSPF6_MESSAGE_IOVEC_SIZE];
  struct ospf6_dbdesc dbdesc;
  struct ospf6_lsdb_node node;

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

  /* clear thread */
  o6n->thread_send_dbdesc = (struct thread *) NULL;
  if (o6n->thread_rxmt_dbdesc)
    thread_cancel (o6n->thread_rxmt_dbdesc);
  o6n->thread_rxmt_dbdesc = (struct thread *) NULL;

  /* if state less than ExStart, do nothing */
  if (o6n->state < NBS_EXSTART)
    return 0;

  OSPF6_MESSAGE_CLEAR (message);
  OSPF6_MESSAGE_ATTACH (message, &dbdesc, sizeof (struct ospf6_dbdesc));

  /* clear previous LSA summary sent */
  ospf6_lsdb_remove_all (o6n->dbdesc_list);
  assert (o6n->dbdesc_list->count == 0);

  /* if this is not initial, set LSA summary to dbdesc */
  if (! DD_IS_IBIT_SET (o6n->dbdesc_bits))
    {
      for (ospf6_lsdb_head (&node, o6n->summary_list);
           ! ospf6_lsdb_is_end (&node);
           ospf6_lsdb_next (&node))
        {
          lsa = node.lsa;

          /* MTU check */
          if (OSPF6_MESSAGE_LENGTH (message)
              + sizeof (struct ospf6_lsa_header)
              + sizeof (struct ospf6_header)
              > o6n->ospf6_interface->ifmtu)
            break;

          /* debug */
          if (IS_OSPF6_DUMP_DBDESC)
            zlog_info ("Include DbDesc: %s", lsa->str);

          /* attach to dbdesclist */
          ospf6_neighbor_dbdesc_add (lsa, o6n);
          /* detach from summarylist */
          ospf6_neighbor_summary_remove (lsa, o6n);

          /* set age and add InfTransDelay */
          ospf6_lsa_age_update_to_send (lsa, o6n->ospf6_interface->transdelay);

          /* set LSA summary to send buffer */
          OSPF6_MESSAGE_ATTACH (message, lsa->header,
                                sizeof (struct ospf6_lsa_header));
        }

      if (o6n->summary_list->count == 0)
        {
          /* Clear more bit */
          DD_MBIT_CLEAR (o6n->dbdesc_bits);

          /* slave must schedule ExchangeDone on sending, here */
          if (! DD_IS_MSBIT_SET (o6n->dbdesc_bits))
            {
              if (! DD_IS_MBIT_SET (o6n->dbdesc_bits) &&
                  ! DD_IS_MBIT_SET (o6n->last_dd.bits))
                thread_add_event (master, exchange_done, o6n, 0);
            }
        }
    }

  /* if this is initial, set seqnum */
  if (DDBIT_IS_INITIAL (o6n->dbdesc_bits))
    ospf6_dbdesc_seqnum_init (o6n);

  /* set dbdesc */
  memcpy (dbdesc.options, o6n->ospf6_interface->area->options,
          sizeof (dbdesc.options));
  dbdesc.ifmtu = htons (o6n->ospf6_interface->interface->mtu);
  dbdesc.bits = o6n->dbdesc_bits;
  dbdesc.seqnum = htonl (o6n->dbdesc_seqnum);

  /* send dbdesc */
  ospf6_message_send (OSPF6_MESSAGE_TYPE_DBDESC, message, &o6n->hisaddr,
                      o6n->ospf6_interface->interface->ifindex);

  /* if master, set retransmission */
  if (DD_IS_MSBIT_SET (o6n->dbdesc_bits))
    o6n->thread_rxmt_dbdesc =
      thread_add_timer (master, ospf6_send_dbdesc_rxmt,
                          o6n, o6n->ospf6_interface->rxmt_interval);

  /* statistics */
  o6n->lsa_send[OSPF6_MESSAGE_TYPE_DBDESC] += o6n->dbdesc_list->count;

  return 0;
}

int
ospf6_send_lsreq_rxmt (struct thread *thread)
{
  struct ospf6_neighbor *o6n;

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

  o6n->thread_rxmt_lsreq = (struct thread *) NULL;
  o6n->thread_send_lsreq = thread_add_event (master, ospf6_send_lsreq, o6n, 0);
  return 0;
}

int
ospf6_send_lsreq (struct thread *thread)
{
  struct ospf6_neighbor *o6n;
  struct iovec message[OSPF6_MESSAGE_IOVEC_SIZE];
  struct ospf6_lsreq lsreq[OSPF6_MESSAGE_IOVEC_SIZE];
  struct ospf6_lsa *lsa;
  struct ospf6_lsdb_node node;
  int i;

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

  /* LSReq will be send only in ExStart or Loading */
  if (o6n->state != NBS_EXCHANGE && o6n->state != NBS_LOADING)
    return 0;

  /* clear thread */
  o6n->thread_send_lsreq = (struct thread *) NULL;
  if (o6n->thread_rxmt_lsreq)
    thread_cancel (o6n->thread_rxmt_lsreq);
  o6n->thread_rxmt_lsreq = (struct thread *) NULL;

  /* schedule loading_done if request list is empty */
  if (o6n->request_list->count == 0)
    {
      thread_add_event (master, loading_done, o6n, 0);
      return 0;
    }

  /* clear message buffer */
  OSPF6_MESSAGE_CLEAR (message);

  i = 0;
  for (ospf6_lsdb_head (&node, o6n->request_list);
       ! ospf6_lsdb_is_end (&node); ospf6_lsdb_next (&node))
    {
      lsa = node.lsa;

      /* Buffer Overflow */
      if (i >= OSPF6_MESSAGE_IOVEC_SIZE)
        break;

      /* I/F MTU check */
      if (OSPF6_MESSAGE_LENGTH (message)
          + sizeof (struct ospf6_lsreq)
          + sizeof (struct ospf6_header)
          > o6n->ospf6_interface->ifmtu)
        break;

      lsreq[i].mbz = 0;
      lsreq[i].type = lsa->header->type;
      lsreq[i].id = lsa->header->id;
      lsreq[i].adv_router = lsa->header->adv_router;

      OSPF6_MESSAGE_ATTACH (message, &lsreq[i], sizeof (struct ospf6_lsreq));
      i++;
    }

  ospf6_message_send (OSPF6_MESSAGE_TYPE_LSREQ, message, &o6n->hisaddr,
                      o6n->ospf6_interface->interface->ifindex);

  /* set retransmit thread */
  o6n->thread_rxmt_lsreq =
    thread_add_timer (master, ospf6_send_lsreq_rxmt,
                      o6n, o6n->ospf6_interface->rxmt_interval);

  /* statistics */
  o6n->lsa_send[OSPF6_MESSAGE_TYPE_LSREQ] += i;

  return 0;
}

/* Send LSUpdate directly to the neighbor, from his retransmission list */
int
ospf6_send_lsupdate_rxmt (struct thread *thread)
{
  struct ospf6_neighbor *o6n;
  struct iovec message[OSPF6_MESSAGE_IOVEC_SIZE];
  struct ospf6_lsupdate lsupdate;
  struct ospf6_lsa *lsa;
  struct ospf6_lsdb_node node;

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

  o6n->send_update = (struct thread *) NULL;

  if (o6n->ospf6_interface->state <= IFS_WAITING)
    return -1;

  /* clear message buffer */
  OSPF6_MESSAGE_CLEAR (message);

  /* set lsupdate header */
  lsupdate.lsupdate_num = 0; /* set gradually */
  OSPF6_MESSAGE_ATTACH (message, &lsupdate, sizeof (struct ospf6_lsupdate));

  /* for each LSA listed on retransmission-list */
  for (ospf6_lsdb_head (&node, o6n->retrans_list);
       ! ospf6_lsdb_is_end (&node);
       ospf6_lsdb_next (&node))
    {
      lsa = node.lsa;

      /* I/F MTU check */
      if (OSPF6_MESSAGE_LENGTH (message)
          + sizeof (struct ospf6_lsupdate)
          + sizeof (struct ospf6_header)
          + ntohs (lsa->header->length)
          > o6n->ospf6_interface->ifmtu)
        break;

      ospf6_lsa_age_update_to_send (lsa, o6n->ospf6_interface->transdelay);
      OSPF6_MESSAGE_ATTACH (message, lsa->header, ntohs (lsa->header->length));
      lsupdate.lsupdate_num++;
    }

  /* check and correct lsupdate */
  if (lsupdate.lsupdate_num == 0)
    return 0;
  lsupdate.lsupdate_num = htonl (lsupdate.lsupdate_num);

  if (IS_OSPF6_DUMP_LSUPDATE)
    zlog_info ("MESSAGE: retrsnsmit LSUpdate to %s", o6n->str);

  /* statistics */
  o6n->ospf6_stat_retrans_lsupdate++;

  ospf6_message_send (OSPF6_MESSAGE_TYPE_LSUPDATE, message,
                      &o6n->hisaddr, o6n->ospf6_interface->if_id);

  o6n->send_update = thread_add_timer (master, ospf6_send_lsupdate_rxmt, o6n,
                                       o6n->ospf6_interface->rxmt_interval);
  return 0;
}

/* Send LSUpdate containing one LSA directly to the neighbor.
   This is "implied acknowledgement" */
void
ospf6_send_lsupdate_direct (struct ospf6_lsa *lsa, struct ospf6_neighbor *o6n)
{
  struct iovec message[OSPF6_MESSAGE_IOVEC_SIZE];
  struct ospf6_lsupdate lsupdate;
  int lsa_len;

  /* clear message buffer */
  OSPF6_MESSAGE_CLEAR (message);

  /* set lsupdate header */
  lsupdate.lsupdate_num = ntohl (1);
  OSPF6_MESSAGE_ATTACH (message, &lsupdate, sizeof (struct ospf6_lsupdate));

  /* set one LSA */
  lsa_len = ntohs (lsa->lsa_hdr->lsh_len);
  ospf6_lsa_age_update_to_send (lsa, o6n->ospf6_interface->transdelay);
  OSPF6_MESSAGE_ATTACH (message, lsa->lsa_hdr, lsa_len);

  ospf6_message_send (OSPF6_MESSAGE_TYPE_LSUPDATE, message, &o6n->hisaddr,
                      o6n->ospf6_interface->if_id);
}

/* Send LSUpdate containing one LSA by multicast.
   On non-broadcast link, send it to each neighbor by unicast.
   This is ordinary flooding */
void
ospf6_send_lsupdate_flood (struct ospf6_lsa *lsa, struct ospf6_interface *o6i)
{
  struct iovec message[OSPF6_MESSAGE_IOVEC_SIZE];
  struct ospf6_lsupdate lsupdate;
  struct in6_addr dst;
  int lsa_len;

  /* clear message buffer */
  OSPF6_MESSAGE_CLEAR (message);

  /* set lsupdate header */
  lsupdate.lsupdate_num = ntohl (1);
  OSPF6_MESSAGE_ATTACH (message, &lsupdate, sizeof (struct ospf6_lsupdate));

  /* set one LSA */
  lsa_len = ntohs (lsa->lsa_hdr->lsh_len);
  ospf6_lsa_age_update_to_send (lsa, o6i->transdelay);
  OSPF6_MESSAGE_ATTACH (message, lsa->lsa_hdr, lsa_len);

  if (if_is_broadcast (o6i->interface))
    {
      /* set destination */
      if (o6i->state == IFS_DR || o6i->state == IFS_BDR)
        inet_pton (AF_INET6, ALLSPFROUTERS6, &dst);
      else
        inet_pton (AF_INET6, ALLDROUTERS6, &dst);
    }
  else
    {
      /* IPv6 relies on link local multicast */
      inet_pton (AF_INET6, ALLSPFROUTERS6, &dst);
    }

  ospf6_message_send (OSPF6_MESSAGE_TYPE_LSUPDATE, message, &dst,
                      o6i->if_id);
}

int
ospf6_send_lsack_delayed (struct thread *thread)
{
  struct ospf6_interface *o6i;
  struct iovec message[MAXIOVLIST];
  struct ospf6_lsa *lsa;
  struct ospf6_lsdb_node node;

  o6i = THREAD_ARG (thread);
  assert (o6i);

  if (IS_OSPF6_DUMP_LSACK)
    zlog_info ("LSACK: Delayed LSAck for %s\n", o6i->interface->name);

  o6i->thread_send_lsack_delayed = (struct thread *) NULL;

  if (o6i->state <= IFS_WAITING)
    return 0;

  if (o6i->ack_list->count == 0)
    return 0;

  iov_clear (message, MAXIOVLIST);

  for (ospf6_lsdb_head (&node, o6i->ack_list);
       ! ospf6_lsdb_is_end (&node);
       ospf6_lsdb_next (&node))
    {
      lsa = node.lsa;
      if (IS_OVER_MTU (message, o6i->ifmtu, sizeof (struct ospf6_lsa_hdr)))
        break;

      OSPF6_MESSAGE_ATTACH (message, lsa->header,
                            sizeof (struct ospf6_lsa_header));
      ospf6_interface_delayed_ack_remove (lsa, o6i);
    }

  /* statistics */
  o6i->ospf6_stat_delayed_lsack++;

  switch (o6i->state)
    {
    case IFS_DR:
    case IFS_BDR:
      ospf6_message_send (OSPF6_MESSAGE_TYPE_LSACK, message,
                          &allspfrouters6.sin6_addr, o6i->if_id);
      break;
    default:
      ospf6_message_send (OSPF6_MESSAGE_TYPE_LSACK, message,
                          &alldrouters6.sin6_addr, o6i->if_id);
      break;
    }

  iov_clear (message, MAXIOVLIST);
  return 0;
}

