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

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

#include "ospf6_top.h"
#include "ospf6_area.h"
#include "ospf6_interface.h"
#include "ospf6_neighbor.h"
#include "ospf6_intra.h"
#include "ospf6_asbr.h"
#include "ospf6_abr.h"
#include "ospf6_flood.h"
#include "ospf6d.h"
#include "ospf6_spf.h"

unsigned char conf_debug_ospf6_brouter = 0;
u_int32_t conf_debug_ospf6_brouter_specific_router_id;
u_int32_t conf_debug_ospf6_brouter_specific_area_id;

/******************************/
/* RFC2740 3.4.3.1 Router-LSA */
/******************************/

static char *
ospf6_router_lsa_get_nbr_id (struct ospf6_lsa *lsa, char *buf, int buflen,
			     int pos)
{
  struct ospf6_router_lsa *router_lsa;
  struct ospf6_router_lsdesc *lsdesc;
  char *start, *end;
  char buf1[INET_ADDRSTRLEN], buf2[INET_ADDRSTRLEN];

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

      lsdesc = (struct ospf6_router_lsdesc *)
	(start + pos*(sizeof (struct ospf6_router_lsdesc)));
      if ((char *)lsdesc < end)
	{
	  if (buf && (buflen > INET_ADDRSTRLEN*2))
	    {
	      inet_ntop (AF_INET, &lsdesc->neighbor_interface_id,
			 buf1, sizeof(buf1));
	      inet_ntop (AF_INET, &lsdesc->neighbor_router_id,
			 buf2, sizeof(buf2));
	      sprintf (buf, "%s/%s", buf2, buf1);
	    }
	}
      else
	return NULL;
    }

  return buf;
}

static int
ospf6_router_lsa_show (struct vty *vty, struct ospf6_lsa *lsa)
{
  char *start, *end, *current;
  char buf[32], name[32], bits[16], options[32];
  struct ospf6_router_lsa *router_lsa;
  struct ospf6_router_lsdesc *lsdesc;

  router_lsa = (struct ospf6_router_lsa *)
    ((char *) lsa->header + sizeof (struct ospf6_lsa_header));

  ospf6_capability_printbuf (router_lsa->bits, bits, sizeof (bits));
  ospf6_options_printbuf (router_lsa->options, options, sizeof (options));
  vty_out (vty, "    Bits: %s Options: %s%s", bits, options, VNL);

  start = (char *) router_lsa + sizeof (struct ospf6_router_lsa);
  end = (char *) lsa->header + ntohs (lsa->header->length);
  for (current = start; current + sizeof (struct ospf6_router_lsdesc) <= end;
       current += sizeof (struct ospf6_router_lsdesc))
    {
      lsdesc = (struct ospf6_router_lsdesc *) current;

      if (lsdesc->type == OSPF6_ROUTER_LSDESC_POINTTOPOINT)
        snprintf (name, sizeof (name), "Point-To-Point");
      else if (lsdesc->type == OSPF6_ROUTER_LSDESC_TRANSIT_NETWORK)
        snprintf (name, sizeof (name), "Transit-Network");
      else if (lsdesc->type == OSPF6_ROUTER_LSDESC_STUB_NETWORK)
        snprintf (name, sizeof (name), "Stub-Network");
      else if (lsdesc->type == OSPF6_ROUTER_LSDESC_VIRTUAL_LINK)
        snprintf (name, sizeof (name), "Virtual-Link");
      else
        snprintf (name, sizeof (name), "Unknown (%#x)", lsdesc->type);

      vty_out (vty, "    Type: %s Metric: %d%s",
               name, ntohs (lsdesc->metric), VNL);
      vty_out (vty, "    Interface ID: %s%s",
               inet_ntop (AF_INET, &lsdesc->interface_id,
                          buf, sizeof (buf)), VNL);
      vty_out (vty, "    Neighbor Interface ID: %s%s",
               inet_ntop (AF_INET, &lsdesc->neighbor_interface_id,
                          buf, sizeof (buf)), VNL);
      vty_out (vty, "    Neighbor Router ID: %s%s",
               inet_ntop (AF_INET, &lsdesc->neighbor_router_id,
                          buf, sizeof (buf)), VNL);
    }
  return 0;
}

int
ospf6_router_is_stub_router (struct ospf6_lsa *lsa)
{
  struct ospf6_router_lsa *rtr_lsa;

  if (lsa != NULL && OSPF6_LSA_IS_TYPE (ROUTER, lsa))
    {
      rtr_lsa = (struct ospf6_router_lsa *)
	((caddr_t) lsa->header + sizeof (struct ospf6_lsa_header));

      if (!OSPF6_OPT_ISSET (rtr_lsa->options, OSPF6_OPT_R))
	{
	  return (OSPF6_IS_STUB_ROUTER);
	}
      else if (!OSPF6_OPT_ISSET (rtr_lsa->options, OSPF6_OPT_V6))
	{
	  return (OSPF6_IS_STUB_ROUTER_V6);
	}
    }

  return (OSPF6_NOT_STUB_ROUTER);
}

int
ospf6_router_lsa_originate (struct thread *thread)
{
  struct ospf6_area *oa;

  char buffer [OSPF6_MAX_LSASIZE];
  struct ospf6_lsa_header *lsa_header;
  struct ospf6_lsa *lsa;

  u_int32_t link_state_id = 0;
  struct listnode *node, *nnode;
  struct listnode *j;
  struct ospf6_interface *oi;
  struct ospf6_neighbor *on, *drouter = NULL;
  struct ospf6_router_lsa *router_lsa;
  struct ospf6_router_lsdesc *lsdesc;
  u_int16_t type;
  u_int32_t router;
  int count;

  oa = (struct ospf6_area *) THREAD_ARG (thread);
  oa->thread_router_lsa = NULL;

  if (IS_OSPF6_DEBUG_ORIGINATE (ROUTER))
    zlog_debug ("Originate Router-LSA for Area %s", oa->name);

  memset (buffer, 0, sizeof (buffer));
  lsa_header = (struct ospf6_lsa_header *) buffer;
  router_lsa = (struct ospf6_router_lsa *)
    ((caddr_t) lsa_header + sizeof (struct ospf6_lsa_header));

  OSPF6_OPT_SET (router_lsa->options, OSPF6_OPT_V6);
  OSPF6_OPT_SET (router_lsa->options, OSPF6_OPT_E);
  OSPF6_OPT_CLEAR (router_lsa->options, OSPF6_OPT_MC);
  OSPF6_OPT_CLEAR (router_lsa->options, OSPF6_OPT_N);
  OSPF6_OPT_SET (router_lsa->options, OSPF6_OPT_R);
  OSPF6_OPT_CLEAR (router_lsa->options, OSPF6_OPT_DC);

  if (ospf6_is_router_abr (ospf6))
    SET_FLAG (router_lsa->bits, OSPF6_ROUTER_BIT_B);
  else
    UNSET_FLAG (router_lsa->bits, OSPF6_ROUTER_BIT_B);
  if (ospf6_asbr_is_asbr (ospf6))
    SET_FLAG (router_lsa->bits, OSPF6_ROUTER_BIT_E);
  else
    UNSET_FLAG (router_lsa->bits, OSPF6_ROUTER_BIT_E);
  UNSET_FLAG (router_lsa->bits, OSPF6_ROUTER_BIT_V);
  UNSET_FLAG (router_lsa->bits, OSPF6_ROUTER_BIT_W);

  /* describe links for each interfaces */
  lsdesc = (struct ospf6_router_lsdesc *)
    ((caddr_t) router_lsa + sizeof (struct ospf6_router_lsa));

  for (ALL_LIST_ELEMENTS (oa->if_list, node, nnode, oi))
    {
      /* Interfaces in state Down or Loopback are not described */
      if (oi->state == OSPF6_INTERFACE_DOWN ||
          oi->state == OSPF6_INTERFACE_LOOPBACK)
        continue;

      /* Nor are interfaces without any full adjacencies described */
      count = 0;
      for (ALL_LIST_ELEMENTS_RO (oi->neighbor_list, j, on))
        if (on->state == OSPF6_NEIGHBOR_FULL)
          count++;
      
      if (count == 0)
        continue;

      /* Multiple Router-LSA instance according to size limit setting */
      if ( (oa->router_lsa_size_limit != 0)
          && ((caddr_t) lsdesc + sizeof (struct ospf6_router_lsdesc) -
	      /* XXX warning: comparison between signed and unsigned */
              (caddr_t) buffer > oa->router_lsa_size_limit))
        {
          if ((caddr_t) lsdesc == (caddr_t) router_lsa +
                                  sizeof (struct ospf6_router_lsa))
            {
              if (IS_OSPF6_DEBUG_ORIGINATE (ROUTER))
                zlog_debug ("Size limit setting for Router-LSA too short");
              return 0;
            }

          /* Fill LSA Header */
          lsa_header->age = 0;
          lsa_header->type = htons (OSPF6_LSTYPE_ROUTER);
          lsa_header->id = htonl (link_state_id);
          lsa_header->adv_router = oa->ospf6->router_id;
          lsa_header->seqnum =
            ospf6_new_ls_seqnum (lsa_header->type, lsa_header->id,
                                 lsa_header->adv_router, oa->lsdb);
          lsa_header->length = htons ((caddr_t) lsdesc - (caddr_t) buffer);

          /* LSA checksum */
          ospf6_lsa_checksum (lsa_header);

          /* create LSA */
          lsa = ospf6_lsa_create (lsa_header);

          /* Originate */
          ospf6_lsa_originate_area (lsa, oa);

          /* Reset setting for consecutive origination */
          memset ((caddr_t) router_lsa + sizeof (struct ospf6_router_lsa),
                  0, (caddr_t) lsdesc - (caddr_t) router_lsa);
          lsdesc = (struct ospf6_router_lsdesc *)
            ((caddr_t) router_lsa + sizeof (struct ospf6_router_lsa));
          link_state_id ++;
        }

      /* Point-to-Point interfaces */
      if (oi->type == OSPF_IFTYPE_POINTOPOINT)
        {
          for (ALL_LIST_ELEMENTS_RO (oi->neighbor_list, j, on))
            {
              if (on->state != OSPF6_NEIGHBOR_FULL)
                continue;

              lsdesc->type = OSPF6_ROUTER_LSDESC_POINTTOPOINT;
              lsdesc->metric = htons (oi->cost);
              lsdesc->interface_id = htonl (oi->interface->ifindex);
              lsdesc->neighbor_interface_id = htonl (on->ifindex);
              lsdesc->neighbor_router_id = on->router_id;

              lsdesc++;
            }
        }

      /* Broadcast and NBMA interfaces */
      else if (oi->type == OSPF_IFTYPE_BROADCAST)
        {
          /* If this router is not DR,
             and If this router not fully adjacent with DR,
             this interface is not transit yet: ignore. */
          if (oi->state != OSPF6_INTERFACE_DR)
            {
              drouter = ospf6_neighbor_lookup (oi->drouter, oi);
              if (drouter == NULL || drouter->state != OSPF6_NEIGHBOR_FULL)
                continue;
            }

          lsdesc->type = OSPF6_ROUTER_LSDESC_TRANSIT_NETWORK;
          lsdesc->metric = htons (oi->cost);
          lsdesc->interface_id = htonl (oi->interface->ifindex);
          if (oi->state != OSPF6_INTERFACE_DR)
            {
              lsdesc->neighbor_interface_id = htonl (drouter->ifindex);
              lsdesc->neighbor_router_id = drouter->router_id;
            }
          else
            {
              lsdesc->neighbor_interface_id = htonl (oi->interface->ifindex);
              lsdesc->neighbor_router_id = oi->area->ospf6->router_id;
            }

          lsdesc++;
        }
      else
	{
	  assert (0);		/* Unknown interface type */
	}

      /* Virtual links */
        /* xxx */
      /* Point-to-Multipoint interfaces */
        /* xxx */
    }

  /* Fill LSA Header */
  lsa_header->age = 0;
  lsa_header->type = htons (OSPF6_LSTYPE_ROUTER);
  lsa_header->id = htonl (link_state_id);
  lsa_header->adv_router = oa->ospf6->router_id;
  lsa_header->seqnum =
    ospf6_new_ls_seqnum (lsa_header->type, lsa_header->id,
                         lsa_header->adv_router, oa->lsdb);
  lsa_header->length = htons ((caddr_t) lsdesc - (caddr_t) buffer);

  /* LSA checksum */
  ospf6_lsa_checksum (lsa_header);

  /* create LSA */
  lsa = ospf6_lsa_create (lsa_header);

  /* Originate */
  ospf6_lsa_originate_area (lsa, oa);

  link_state_id ++;

  /* Do premature-aging of rest, undesired Router-LSAs */
  type = ntohs (OSPF6_LSTYPE_ROUTER);
  router = oa->ospf6->router_id;
  for (lsa = ospf6_lsdb_type_router_head (type, router, oa->lsdb); lsa;
       lsa = ospf6_lsdb_type_router_next (type, router, lsa))
    {
      if (ntohl (lsa->header->id) < link_state_id)
        continue;
      ospf6_lsa_purge (lsa);
    }

  return 0;
}

/*******************************/
/* RFC2740 3.4.3.2 Network-LSA */
/*******************************/

static char *
ospf6_network_lsa_get_ar_id (struct ospf6_lsa *lsa, char *buf, int buflen,
			     int pos)
{
  char *start, *end, *current;
  struct ospf6_network_lsa *network_lsa;
  struct ospf6_network_lsdesc *lsdesc;

  if (lsa)
    {
      network_lsa = (struct ospf6_network_lsa *)
	((caddr_t) lsa->header + sizeof (struct ospf6_lsa_header));

      start = (char *) network_lsa + sizeof (struct ospf6_network_lsa);
      end = (char *) lsa->header + ntohs (lsa->header->length);
      current = start + pos*(sizeof (struct ospf6_network_lsdesc));

      if ((current + sizeof(struct ospf6_network_lsdesc)) <= end)
	{
	  lsdesc = (struct ospf6_network_lsdesc *)current;
	  if (buf)
	    inet_ntop (AF_INET, &lsdesc->router_id, buf, buflen);
	}
      else
	return NULL;
    }

  return (buf);
}

static int
ospf6_network_lsa_show (struct vty *vty, struct ospf6_lsa *lsa)
{
  char *start, *end, *current;
  struct ospf6_network_lsa *network_lsa;
  struct ospf6_network_lsdesc *lsdesc;
  char buf[128], options[32];

  network_lsa = (struct ospf6_network_lsa *)
    ((caddr_t) lsa->header + sizeof (struct ospf6_lsa_header));

  ospf6_options_printbuf (network_lsa->options, options, sizeof (options));
  vty_out (vty, "     Options: %s%s", options, VNL);

  start = (char *) network_lsa + sizeof (struct ospf6_network_lsa);
  end = (char *) lsa->header + ntohs (lsa->header->length);
  for (current = start; current + sizeof (struct ospf6_network_lsdesc) <= end;
       current += sizeof (struct ospf6_network_lsdesc))
    {
      lsdesc = (struct ospf6_network_lsdesc *) current;
      inet_ntop (AF_INET, &lsdesc->router_id, buf, sizeof (buf));
      vty_out (vty, "     Attached Router: %s%s", buf, VNL);
    }
  return 0;
}

int
ospf6_network_lsa_originate (struct thread *thread)
{
  struct ospf6_interface *oi;

  char buffer [OSPF6_MAX_LSASIZE];
  struct ospf6_lsa_header *lsa_header;

  int count;
  struct ospf6_lsa *old, *lsa;
  struct ospf6_network_lsa *network_lsa;
  struct ospf6_network_lsdesc *lsdesc;
  struct ospf6_neighbor *on;
  struct ospf6_link_lsa *link_lsa;
  struct listnode *i;
  u_int16_t type;

  oi = (struct ospf6_interface *) THREAD_ARG (thread);
  oi->thread_network_lsa = NULL;

  /* The interface must be enabled until here. A Network-LSA of a
     disabled interface (but was once enabled) should be flushed
     by ospf6_lsa_refresh (), and does not come here. */
  assert (oi->area);

  old = ospf6_lsdb_lookup (htons (OSPF6_LSTYPE_NETWORK),
                           htonl (oi->interface->ifindex),
                           oi->area->ospf6->router_id, oi->area->lsdb);

  /* Do not originate Network-LSA if not DR */
  if (oi->state != OSPF6_INTERFACE_DR)
    {
      if (old)
        ospf6_lsa_purge (old);
      return 0;
    }

  if (IS_OSPF6_DEBUG_ORIGINATE (NETWORK))
    zlog_debug ("Originate Network-LSA for Interface %s", oi->interface->name);

  /* If none of neighbor is adjacent to us */
  count = 0;
  
  for (ALL_LIST_ELEMENTS_RO (oi->neighbor_list, i, on))
    if (on->state == OSPF6_NEIGHBOR_FULL)
      count++;
  
  if (count == 0)
    {
      if (IS_OSPF6_DEBUG_ORIGINATE (NETWORK))
        zlog_debug ("Interface stub, ignore");
      if (old)
        ospf6_lsa_purge (old);
      return 0;
    }

  /* prepare buffer */
  memset (buffer, 0, sizeof (buffer));
  lsa_header = (struct ospf6_lsa_header *) buffer;
  network_lsa = (struct ospf6_network_lsa *)
    ((caddr_t) lsa_header + sizeof (struct ospf6_lsa_header));

  /* Collect the interface's Link-LSAs to describe
     network's optional capabilities */
  type = htons (OSPF6_LSTYPE_LINK);
  for (lsa = ospf6_lsdb_type_head (type, oi->lsdb); lsa;
       lsa = ospf6_lsdb_type_next (type, lsa))
    {
      link_lsa = (struct ospf6_link_lsa *)
        ((caddr_t) lsa->header + sizeof (struct ospf6_lsa_header));
      network_lsa->options[0] |= link_lsa->options[0];
      network_lsa->options[1] |= link_lsa->options[1];
      network_lsa->options[2] |= link_lsa->options[2];
    }

  lsdesc = (struct ospf6_network_lsdesc *)
    ((caddr_t) network_lsa + sizeof (struct ospf6_network_lsa));

  /* set Link Description to the router itself */
  lsdesc->router_id = oi->area->ospf6->router_id;
  lsdesc++;

  /* Walk through the neighbors */
  for (ALL_LIST_ELEMENTS_RO (oi->neighbor_list, i, on))
    {
      if (on->state != OSPF6_NEIGHBOR_FULL)
        continue;

      /* set this neighbor's Router-ID to LSA */
      lsdesc->router_id = on->router_id;
      lsdesc++;
    }

  /* Fill LSA Header */
  lsa_header->age = 0;
  lsa_header->type = htons (OSPF6_LSTYPE_NETWORK);
  lsa_header->id = htonl (oi->interface->ifindex);
  lsa_header->adv_router = oi->area->ospf6->router_id;
  lsa_header->seqnum =
    ospf6_new_ls_seqnum (lsa_header->type, lsa_header->id,
                         lsa_header->adv_router, oi->area->lsdb);
  lsa_header->length = htons ((caddr_t) lsdesc - (caddr_t) buffer);

  /* LSA checksum */
  ospf6_lsa_checksum (lsa_header);

  /* create LSA */
  lsa = ospf6_lsa_create (lsa_header);

  /* Originate */
  ospf6_lsa_originate_area (lsa, oi->area);

  return 0;
}


/****************************/
/* RFC2740 3.4.3.6 Link-LSA */
/****************************/

static char *
ospf6_link_lsa_get_prefix_str (struct ospf6_lsa *lsa, char *buf, int buflen,
			       int pos)
{
  char *start, *end, *current;
  struct ospf6_link_lsa *link_lsa;
  struct in6_addr in6;
  struct ospf6_prefix *prefix;
  int cnt = 0, prefixnum;

  if (lsa)
    {
      link_lsa = (struct ospf6_link_lsa *)
	((caddr_t) lsa->header + sizeof (struct ospf6_lsa_header));

      if (pos == 0) {
	inet_ntop (AF_INET6, &link_lsa->linklocal_addr, buf, buflen);
	return (buf);
      }

      prefixnum = ntohl (link_lsa->prefix_num);
      if (pos > prefixnum)
	return (NULL);

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

      do
	{
	  prefix = (struct ospf6_prefix *) current;
	  if (prefix->prefix_length == 0 ||
	      current + OSPF6_PREFIX_SIZE (prefix) > end)
	    {
	      return (NULL);
	    }

	  if (cnt < pos)
	    {
	      current = start + pos*OSPF6_PREFIX_SIZE(prefix);
	      cnt++;
	    }
	  else
	    {
	      memset (&in6, 0, sizeof (in6));
	      memcpy (&in6, OSPF6_PREFIX_BODY (prefix),
		      OSPF6_PREFIX_SPACE (prefix->prefix_length));
	      inet_ntop (AF_INET6, &in6, buf, buflen);
	      return (buf);
	    }
	} while (current <= end);
    }
  return (NULL);
}

static int
ospf6_link_lsa_show (struct vty *vty, struct ospf6_lsa *lsa)
{
  char *start, *end, *current;
  struct ospf6_link_lsa *link_lsa;
  int prefixnum;
  char buf[128], options[32];
  struct ospf6_prefix *prefix;
  const char *p, *mc, *la, *nu;
  struct in6_addr in6;

  link_lsa = (struct ospf6_link_lsa *)
    ((caddr_t) lsa->header + sizeof (struct ospf6_lsa_header));

  ospf6_options_printbuf (link_lsa->options, options, sizeof (options));
  inet_ntop (AF_INET6, &link_lsa->linklocal_addr, buf, sizeof (buf));
  prefixnum = ntohl (link_lsa->prefix_num);

  vty_out (vty, "     Priority: %d Options: %s%s",
           link_lsa->priority, options, VNL);
  vty_out (vty, "     LinkLocal Address: %s%s", buf, VNL);
  vty_out (vty, "     Number of Prefix: %d%s", prefixnum, VNL);

  start = (char *) link_lsa + sizeof (struct ospf6_link_lsa);
  end = (char *) lsa->header + ntohs (lsa->header->length); 
  for (current = start; current < end; current += OSPF6_PREFIX_SIZE (prefix))
    {
      prefix = (struct ospf6_prefix *) current;
      if (prefix->prefix_length == 0 ||
          current + OSPF6_PREFIX_SIZE (prefix) > end)
        break;

      p = (CHECK_FLAG (prefix->prefix_options, OSPF6_PREFIX_OPTION_P) ?
           "P" : "--");
      mc = (CHECK_FLAG (prefix->prefix_options, OSPF6_PREFIX_OPTION_MC) ?
           "MC" : "--");
      la = (CHECK_FLAG (prefix->prefix_options, OSPF6_PREFIX_OPTION_LA) ?
           "LA" : "--");
      nu = (CHECK_FLAG (prefix->prefix_options, OSPF6_PREFIX_OPTION_NU) ?
           "NU" : "--");
      vty_out (vty, "     Prefix Options: %s|%s|%s|%s%s",
               p, mc, la, nu, VNL);

      memset (&in6, 0, sizeof (in6));
      memcpy (&in6, OSPF6_PREFIX_BODY (prefix),
              OSPF6_PREFIX_SPACE (prefix->prefix_length));
      inet_ntop (AF_INET6, &in6, buf, sizeof (buf));
      vty_out (vty, "     Prefix: %s/%d%s",
               buf, prefix->prefix_length, VNL);
    }

  return 0;
}

int
ospf6_link_lsa_originate (struct thread *thread)
{
  struct ospf6_interface *oi;

  char buffer[OSPF6_MAX_LSASIZE];
  struct ospf6_lsa_header *lsa_header;
  struct ospf6_lsa *old, *lsa;

  struct ospf6_link_lsa *link_lsa;
  struct ospf6_route *route;
  struct ospf6_prefix *op;

  oi = (struct ospf6_interface *) THREAD_ARG (thread);
  oi->thread_link_lsa = NULL;

  assert (oi->area);

  /* find previous LSA */
  old = ospf6_lsdb_lookup (htons (OSPF6_LSTYPE_LINK),
                           htonl (oi->interface->ifindex),
                           oi->area->ospf6->router_id, oi->lsdb);

  if (CHECK_FLAG (oi->flag, OSPF6_INTERFACE_DISABLE))
    {
      if (old)
        ospf6_lsa_purge (old);
      return 0;
    }

  if (IS_OSPF6_DEBUG_ORIGINATE (LINK))
    zlog_debug ("Originate Link-LSA for Interface %s", oi->interface->name);

  /* can't make Link-LSA if linklocal address not set */
  if (oi->linklocal_addr == NULL)
    {
      if (IS_OSPF6_DEBUG_ORIGINATE (LINK))
        zlog_debug ("No Linklocal address on %s, defer originating",
                   oi->interface->name);
      if (old)
        ospf6_lsa_purge (old);
      return 0;
    }

  /* prepare buffer */
  memset (buffer, 0, sizeof (buffer));
  lsa_header = (struct ospf6_lsa_header *) buffer;
  link_lsa = (struct ospf6_link_lsa *)
    ((caddr_t) lsa_header + sizeof (struct ospf6_lsa_header));

  /* Fill Link-LSA */
  link_lsa->priority = oi->priority;
  memcpy (link_lsa->options, oi->area->options, 3);
  memcpy (&link_lsa->linklocal_addr, oi->linklocal_addr,
          sizeof (struct in6_addr));
  link_lsa->prefix_num = htonl (oi->route_connected->count);

  op = (struct ospf6_prefix *)
    ((caddr_t) link_lsa + sizeof (struct ospf6_link_lsa));

  /* connected prefix to advertise */
  for (route = ospf6_route_head (oi->route_connected); route;
       route = ospf6_route_next (route))
    {
      op->prefix_length = route->prefix.prefixlen;
      op->prefix_options = route->path.prefix_options;
      op->prefix_metric = htons (0);
      memcpy (OSPF6_PREFIX_BODY (op), &route->prefix.u.prefix6,
              OSPF6_PREFIX_SPACE (op->prefix_length));
      op = OSPF6_PREFIX_NEXT (op);
    }

  /* Fill LSA Header */
  lsa_header->age = 0;
  lsa_header->type = htons (OSPF6_LSTYPE_LINK);
  lsa_header->id = htonl (oi->interface->ifindex);
  lsa_header->adv_router = oi->area->ospf6->router_id;
  lsa_header->seqnum =
    ospf6_new_ls_seqnum (lsa_header->type, lsa_header->id,
                         lsa_header->adv_router, oi->lsdb);
  lsa_header->length = htons ((caddr_t) op - (caddr_t) buffer);

  /* LSA checksum */
  ospf6_lsa_checksum (lsa_header);

  /* create LSA */
  lsa = ospf6_lsa_create (lsa_header);

  /* Originate */
  ospf6_lsa_originate_interface (lsa, oi);

  return 0;
}


/*****************************************/
/* RFC2740 3.4.3.7 Intra-Area-Prefix-LSA */
/*****************************************/
static char *
ospf6_intra_prefix_lsa_get_prefix_str (struct ospf6_lsa *lsa, char *buf,
				       int buflen, int pos)
{
  char *start, *end, *current;
  struct ospf6_intra_prefix_lsa *intra_prefix_lsa;
  struct in6_addr in6;
  int prefixnum, cnt = 0;
  struct ospf6_prefix *prefix;

  if (lsa)
    {
      intra_prefix_lsa = (struct ospf6_intra_prefix_lsa *)
	((caddr_t) lsa->header + sizeof (struct ospf6_lsa_header));

      prefixnum = ntohs (intra_prefix_lsa->prefix_num);
      if (pos > prefixnum)
	return (NULL);

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

      do
	{
	  prefix = (struct ospf6_prefix *) current;
	  if (prefix->prefix_length == 0 ||
	      current + OSPF6_PREFIX_SIZE (prefix) > end)
	    {
	      return NULL;
	    }

	  if (cnt < pos)
	    {
	      current = start + pos*OSPF6_PREFIX_SIZE(prefix);
	      cnt++;
	    }
	  else
	    {
	      memset (&in6, 0, sizeof (in6));
	      memcpy (&in6, OSPF6_PREFIX_BODY (prefix),
		      OSPF6_PREFIX_SPACE (prefix->prefix_length));
	      inet_ntop (AF_INET6, &in6, buf, buflen);
	      sprintf(&buf[strlen(buf)], "/%d", prefix->prefix_length);
	      return (buf);
	    }
	} while (current <= end);
    }
  return (buf);
}

static int
ospf6_intra_prefix_lsa_show (struct vty *vty, struct ospf6_lsa *lsa)
{
  char *start, *end, *current;
  struct ospf6_intra_prefix_lsa *intra_prefix_lsa;
  int prefixnum;
  char buf[128];
  struct ospf6_prefix *prefix;
  char id[16], adv_router[16];
  const char *p, *mc, *la, *nu;
  struct in6_addr in6;

  intra_prefix_lsa = (struct ospf6_intra_prefix_lsa *)
    ((caddr_t) lsa->header + sizeof (struct ospf6_lsa_header));

  prefixnum = ntohs (intra_prefix_lsa->prefix_num);

  vty_out (vty, "     Number of Prefix: %d%s", prefixnum, VNL);

  inet_ntop (AF_INET, &intra_prefix_lsa->ref_id, id, sizeof (id));
  inet_ntop (AF_INET, &intra_prefix_lsa->ref_adv_router,
             adv_router, sizeof (adv_router));
  vty_out (vty, "     Reference: %s Id: %s Adv: %s%s",
           ospf6_lstype_name (intra_prefix_lsa->ref_type), id, adv_router,
           VNL);

  start = (char *) intra_prefix_lsa + sizeof (struct ospf6_intra_prefix_lsa);
  end = (char *) lsa->header + ntohs (lsa->header->length); 
  for (current = start; current < end; current += OSPF6_PREFIX_SIZE (prefix))
    {
      prefix = (struct ospf6_prefix *) current;
      if (prefix->prefix_length == 0 ||
          current + OSPF6_PREFIX_SIZE (prefix) > end)
        break;

      p = (CHECK_FLAG (prefix->prefix_options, OSPF6_PREFIX_OPTION_P) ?
           "P" : "--");
      mc = (CHECK_FLAG (prefix->prefix_options, OSPF6_PREFIX_OPTION_MC) ?
           "MC" : "--");
      la = (CHECK_FLAG (prefix->prefix_options, OSPF6_PREFIX_OPTION_LA) ?
           "LA" : "--");
      nu = (CHECK_FLAG (prefix->prefix_options, OSPF6_PREFIX_OPTION_NU) ?
           "NU" : "--");
      vty_out (vty, "     Prefix Options: %s|%s|%s|%s%s",
               p, mc, la, nu, VNL);

      memset (&in6, 0, sizeof (in6));
      memcpy (&in6, OSPF6_PREFIX_BODY (prefix),
              OSPF6_PREFIX_SPACE (prefix->prefix_length));
      inet_ntop (AF_INET6, &in6, buf, sizeof (buf));
      vty_out (vty, "     Prefix: %s/%d%s",
               buf, prefix->prefix_length, VNL);
    }

  return 0;
}

int
ospf6_intra_prefix_lsa_originate_stub (struct thread *thread)
{
  struct ospf6_area *oa;

  char buffer[OSPF6_MAX_LSASIZE];
  struct ospf6_lsa_header *lsa_header;
  struct ospf6_lsa *old, *lsa;

  struct ospf6_intra_prefix_lsa *intra_prefix_lsa;
  struct ospf6_interface *oi;
  struct ospf6_neighbor *on;
  struct ospf6_route *route;
  struct ospf6_prefix *op;
  struct listnode *i, *j;
  int full_count = 0;
  unsigned short prefix_num = 0;
  char buf[BUFSIZ];
  struct ospf6_route_table *route_advertise;

  oa = (struct ospf6_area *) THREAD_ARG (thread);
  oa->thread_intra_prefix_lsa = NULL;

  /* find previous LSA */
  old = ospf6_lsdb_lookup (htons (OSPF6_LSTYPE_INTRA_PREFIX),
                           htonl (0), oa->ospf6->router_id, oa->lsdb);

  if (! IS_AREA_ENABLED (oa))
    {
      if (old)
        ospf6_lsa_purge (old);
      return 0;
    }

  if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
    zlog_debug ("Originate Intra-Area-Prefix-LSA for area %s's stub prefix",
               oa->name);

  /* prepare buffer */
  memset (buffer, 0, sizeof (buffer));
  lsa_header = (struct ospf6_lsa_header *) buffer;
  intra_prefix_lsa = (struct ospf6_intra_prefix_lsa *)
    ((caddr_t) lsa_header + sizeof (struct ospf6_lsa_header));

  /* Fill Intra-Area-Prefix-LSA */
  intra_prefix_lsa->ref_type = htons (OSPF6_LSTYPE_ROUTER);
  intra_prefix_lsa->ref_id = htonl (0);
  intra_prefix_lsa->ref_adv_router = oa->ospf6->router_id;

  route_advertise = ospf6_route_table_create (0, 0);

  for (ALL_LIST_ELEMENTS_RO (oa->if_list, i, oi))
    {
      if (oi->state == OSPF6_INTERFACE_DOWN)
        {
          if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
            zlog_debug ("  Interface %s is down, ignore", oi->interface->name);
          continue;
        }

      full_count = 0;

      for (ALL_LIST_ELEMENTS_RO (oi->neighbor_list, j, on))
        if (on->state == OSPF6_NEIGHBOR_FULL)
          full_count++;

      if (oi->state != OSPF6_INTERFACE_LOOPBACK &&
          oi->state != OSPF6_INTERFACE_POINTTOPOINT &&
          full_count != 0)
        {
          if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
            zlog_debug ("  Interface %s is not stub, ignore",
                       oi->interface->name);
          continue;
        }

      if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
        zlog_debug ("  Interface %s:", oi->interface->name);

      /* connected prefix to advertise */
      for (route = ospf6_route_head (oi->route_connected); route;
           route = ospf6_route_best_next (route))
        {
          if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
            {
              prefix2str (&route->prefix, buf, sizeof (buf));
              zlog_debug ("    include %s", buf);
            }
          ospf6_route_add (ospf6_route_copy (route), route_advertise);
        }
    }

  if (route_advertise->count == 0)
    {
      if (old)
        ospf6_lsa_purge (old);
      ospf6_route_table_delete (route_advertise);
      return 0;
    }

  /* put prefixes to advertise */
  prefix_num = 0;
  op = (struct ospf6_prefix *)
    ((caddr_t) intra_prefix_lsa + sizeof (struct ospf6_intra_prefix_lsa));
  for (route = ospf6_route_head (route_advertise); route;
       route = ospf6_route_best_next (route))
    {
      op->prefix_length = route->prefix.prefixlen;
      op->prefix_options = route->path.prefix_options;
      op->prefix_metric = htons (route->path.cost);
      memcpy (OSPF6_PREFIX_BODY (op), &route->prefix.u.prefix6,
              OSPF6_PREFIX_SPACE (op->prefix_length));
      op = OSPF6_PREFIX_NEXT (op);
      prefix_num++;
    }

  ospf6_route_table_delete (route_advertise);

  if (prefix_num == 0)
    {
      if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
        zlog_debug ("Quit to Advertise Intra-Prefix: no route to advertise");
      return 0;
    }

  intra_prefix_lsa->prefix_num = htons (prefix_num);

  /* Fill LSA Header */
  lsa_header->age = 0;
  lsa_header->type = htons (OSPF6_LSTYPE_INTRA_PREFIX);
  lsa_header->id = htonl (0);
  lsa_header->adv_router = oa->ospf6->router_id;
  lsa_header->seqnum =
    ospf6_new_ls_seqnum (lsa_header->type, lsa_header->id,
                         lsa_header->adv_router, oa->lsdb);
  lsa_header->length = htons ((caddr_t) op - (caddr_t) lsa_header);

  /* LSA checksum */
  ospf6_lsa_checksum (lsa_header);

  /* create LSA */
  lsa = ospf6_lsa_create (lsa_header);

  /* Originate */
  ospf6_lsa_originate_area (lsa, oa);

  return 0;
}


int
ospf6_intra_prefix_lsa_originate_transit (struct thread *thread)
{
  struct ospf6_interface *oi;

  char buffer[OSPF6_MAX_LSASIZE];
  struct ospf6_lsa_header *lsa_header;
  struct ospf6_lsa *old, *lsa;

  struct ospf6_intra_prefix_lsa *intra_prefix_lsa;
  struct ospf6_neighbor *on;
  struct ospf6_route *route;
  struct ospf6_prefix *op;
  struct listnode *i;
  int full_count = 0;
  unsigned short prefix_num = 0;
  struct ospf6_route_table *route_advertise;
  struct ospf6_link_lsa *link_lsa;
  char *start, *end, *current;
  u_int16_t type;
  char buf[BUFSIZ];

  oi = (struct ospf6_interface *) THREAD_ARG (thread);
  oi->thread_intra_prefix_lsa = NULL;

  assert (oi->area);

  /* find previous LSA */
  old = ospf6_lsdb_lookup (htons (OSPF6_LSTYPE_INTRA_PREFIX),
                           htonl (oi->interface->ifindex),
                           oi->area->ospf6->router_id, oi->area->lsdb);

  if (CHECK_FLAG (oi->flag, OSPF6_INTERFACE_DISABLE))
    {
      if (old)
        ospf6_lsa_purge (old);
      return 0;
    }

  if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
    zlog_debug ("Originate Intra-Area-Prefix-LSA for interface %s's prefix",
               oi->interface->name);

  /* prepare buffer */
  memset (buffer, 0, sizeof (buffer));
  lsa_header = (struct ospf6_lsa_header *) buffer;
  intra_prefix_lsa = (struct ospf6_intra_prefix_lsa *)
    ((caddr_t) lsa_header + sizeof (struct ospf6_lsa_header));

  /* Fill Intra-Area-Prefix-LSA */
  intra_prefix_lsa->ref_type = htons (OSPF6_LSTYPE_NETWORK);
  intra_prefix_lsa->ref_id = htonl (oi->interface->ifindex);
  intra_prefix_lsa->ref_adv_router = oi->area->ospf6->router_id;

  if (oi->state != OSPF6_INTERFACE_DR)
    {
      if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
        zlog_debug ("  Interface is not DR");
      if (old)
        ospf6_lsa_purge (old);
      return 0;
    }

  full_count = 0;
  for (ALL_LIST_ELEMENTS_RO (oi->neighbor_list, i, on))
    if (on->state == OSPF6_NEIGHBOR_FULL)
      full_count++;
  
  if (full_count == 0)
    {
      if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
        zlog_debug ("  Interface is stub");
      if (old)
        ospf6_lsa_purge (old);
      return 0;
    }

  /* connected prefix to advertise */
  route_advertise = ospf6_route_table_create (0, 0);

  type = ntohs (OSPF6_LSTYPE_LINK);
  for (lsa = ospf6_lsdb_type_head (type, oi->lsdb); lsa;
       lsa = ospf6_lsdb_type_next (type, lsa))
    {
      if (OSPF6_LSA_IS_MAXAGE (lsa))
        continue;

      if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
        zlog_debug ("  include prefix from %s", lsa->name);

      if (lsa->header->adv_router != oi->area->ospf6->router_id)
        {
          on = ospf6_neighbor_lookup (lsa->header->adv_router, oi);
          if (on == NULL || on->state != OSPF6_NEIGHBOR_FULL)
            {
              if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
                zlog_debug ("    Neighbor not found or not Full, ignore");
              continue;
            }
        }

      link_lsa = (struct ospf6_link_lsa *)
        ((caddr_t) lsa->header + sizeof (struct ospf6_lsa_header));

      prefix_num = (unsigned short) ntohl (link_lsa->prefix_num);
      start = (char *) link_lsa + sizeof (struct ospf6_link_lsa);
      end = (char *) lsa->header + ntohs (lsa->header->length); 
      for (current = start; current < end && prefix_num;
           current += OSPF6_PREFIX_SIZE (op))
        {
          op = (struct ospf6_prefix *) current;
          if (op->prefix_length == 0 ||
              current + OSPF6_PREFIX_SIZE (op) > end)
            break;

          route = ospf6_route_create ();

          route->type = OSPF6_DEST_TYPE_NETWORK;
          route->prefix.family = AF_INET6;
          route->prefix.prefixlen = op->prefix_length;
          memset (&route->prefix.u.prefix6, 0, sizeof (struct in6_addr));
          memcpy (&route->prefix.u.prefix6, OSPF6_PREFIX_BODY (op),
                  OSPF6_PREFIX_SPACE (op->prefix_length));

          route->path.origin.type = lsa->header->type;
          route->path.origin.id = lsa->header->id;
          route->path.origin.adv_router = lsa->header->adv_router;
          route->path.options[0] = link_lsa->options[0];
          route->path.options[1] = link_lsa->options[1];
          route->path.options[2] = link_lsa->options[2];
          route->path.prefix_options = op->prefix_options;
          route->path.area_id = oi->area->area_id;
          route->path.type = OSPF6_PATH_TYPE_INTRA;

          if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
            {
              prefix2str (&route->prefix, buf, sizeof (buf));
              zlog_debug ("    include %s", buf);
            }

          ospf6_route_add (route, route_advertise);
          prefix_num--;
        }
      if (current != end && IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
        zlog_debug ("Trailing garbage in %s", lsa->name);
    }

  op = (struct ospf6_prefix *)
    ((caddr_t) intra_prefix_lsa + sizeof (struct ospf6_intra_prefix_lsa));

  prefix_num = 0;
  for (route = ospf6_route_head (route_advertise); route;
       route = ospf6_route_best_next (route))
    {
      op->prefix_length = route->prefix.prefixlen;
      op->prefix_options = route->path.prefix_options;
      op->prefix_metric = htons (0);
      memcpy (OSPF6_PREFIX_BODY (op), &route->prefix.u.prefix6,
              OSPF6_PREFIX_SPACE (op->prefix_length));
      op = OSPF6_PREFIX_NEXT (op);
      prefix_num++;
    }

  ospf6_route_table_delete (route_advertise);

  if (prefix_num == 0)
    {
      if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
        zlog_debug ("Quit to Advertise Intra-Prefix: no route to advertise");
      return 0;
    }

  intra_prefix_lsa->prefix_num = htons (prefix_num);

  /* Fill LSA Header */
  lsa_header->age = 0;
  lsa_header->type = htons (OSPF6_LSTYPE_INTRA_PREFIX);
  lsa_header->id = htonl (oi->interface->ifindex);
  lsa_header->adv_router = oi->area->ospf6->router_id;
  lsa_header->seqnum =
    ospf6_new_ls_seqnum (lsa_header->type, lsa_header->id,
                         lsa_header->adv_router, oi->area->lsdb);
  lsa_header->length = htons ((caddr_t) op - (caddr_t) lsa_header);

  /* LSA checksum */
  ospf6_lsa_checksum (lsa_header);

  /* create LSA */
  lsa = ospf6_lsa_create (lsa_header);

  /* Originate */
  ospf6_lsa_originate_area (lsa, oi->area);

  return 0;
}

void
ospf6_intra_prefix_lsa_add (struct ospf6_lsa *lsa)
{
  struct ospf6_area *oa;
  struct ospf6_intra_prefix_lsa *intra_prefix_lsa;
  struct prefix ls_prefix;
  struct ospf6_route *route, *ls_entry;
  int i, prefix_num;
  struct ospf6_prefix *op;
  char *start, *current, *end;
  char buf[64];
  struct interface *ifp;
  int direct_connect = 0;

  if (OSPF6_LSA_IS_MAXAGE (lsa))
    return;

  if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX))
    zlog_debug ("%s found", lsa->name);

  oa = OSPF6_AREA (lsa->lsdb->data);

  intra_prefix_lsa = (struct ospf6_intra_prefix_lsa *)
    OSPF6_LSA_HEADER_END (lsa->header);
  if (intra_prefix_lsa->ref_type == htons (OSPF6_LSTYPE_ROUTER))
    ospf6_linkstate_prefix (intra_prefix_lsa->ref_adv_router,
                            htonl (0), &ls_prefix);
  else if (intra_prefix_lsa->ref_type == htons (OSPF6_LSTYPE_NETWORK))
    ospf6_linkstate_prefix (intra_prefix_lsa->ref_adv_router,
                            intra_prefix_lsa->ref_id, &ls_prefix);
  else
    {
      if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX))
        zlog_debug ("Unknown reference LS-type: %#hx",
		    ntohs (intra_prefix_lsa->ref_type));
      return;
    }

  ls_entry = ospf6_route_lookup (&ls_prefix, oa->spf_table);
  if (ls_entry == NULL)
    {
      if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX))
        {
          ospf6_linkstate_prefix2str (&ls_prefix, buf, sizeof (buf));
          zlog_debug ("LS entry does not exist: %s", buf);
        }
      return;
    }

  if (intra_prefix_lsa->ref_adv_router == oa->ospf6->router_id)
    {
      /* the intra-prefix are directly connected */
      direct_connect = 1;
    }

  prefix_num = ntohs (intra_prefix_lsa->prefix_num);
  start = (caddr_t) intra_prefix_lsa +
          sizeof (struct ospf6_intra_prefix_lsa);
  end = OSPF6_LSA_END (lsa->header);
  for (current = start; current < end; current += OSPF6_PREFIX_SIZE (op))
    {
      op = (struct ospf6_prefix *) current;
      if (prefix_num == 0)
        break;
      if (end < current + OSPF6_PREFIX_SIZE (op))
        break;

      /* Appendix A.4.1.1 */
      if (CHECK_FLAG(op->prefix_options, OSPF6_PREFIX_OPTION_NU) ||
	  CHECK_FLAG(op->prefix_options, OSPF6_PREFIX_OPTION_LA))
	{
	  if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX))
	    {
	      ospf6_linkstate_prefix2str ((struct prefix *)OSPF6_PREFIX_BODY(op),
					  buf, sizeof (buf));
	      zlog_debug ("%s: Skipping Prefix %s has NU/LA option set",
			  __func__, buf);
	    }
	  continue;
	}

      route = ospf6_route_create ();

      memset (&route->prefix, 0, sizeof (struct prefix));
      route->prefix.family = AF_INET6;
      route->prefix.prefixlen = op->prefix_length;
      ospf6_prefix_in6_addr (&route->prefix.u.prefix6, op);

      route->type = OSPF6_DEST_TYPE_NETWORK;
      route->path.origin.type = lsa->header->type;
      route->path.origin.id = lsa->header->id;
      route->path.origin.adv_router = lsa->header->adv_router;
      route->path.prefix_options = op->prefix_options;
      route->path.area_id = oa->area_id;
      route->path.type = OSPF6_PATH_TYPE_INTRA;
      route->path.metric_type = 1;
      route->path.cost = ls_entry->path.cost +
                         ntohs (op->prefix_metric);

      if (direct_connect)
        {
          ifp = if_lookup_prefix(&route->prefix);
          if (ifp)
            route->nexthop[0].ifindex = ifp->ifindex;
        }
      else
        {
          for (i = 0; ospf6_nexthop_is_set (&ls_entry->nexthop[i]) &&
               i < OSPF6_MULTI_PATH_LIMIT; i++)
            ospf6_nexthop_copy (&route->nexthop[i], &ls_entry->nexthop[i]);
        }

      if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX))
        {
          prefix2str (&route->prefix, buf, sizeof (buf));
          zlog_debug ("  add %s", buf);
        }

      ospf6_route_add (route, oa->route_table);
      prefix_num--;
    }

  if (current != end && IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX))
    zlog_debug ("Trailing garbage ignored");
}

void
ospf6_intra_prefix_lsa_remove (struct ospf6_lsa *lsa)
{
  struct ospf6_area *oa;
  struct ospf6_intra_prefix_lsa *intra_prefix_lsa;
  struct prefix prefix;
  struct ospf6_route *route;
  int prefix_num;
  struct ospf6_prefix *op;
  char *start, *current, *end;
  char buf[64];

  if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX))
    zlog_debug ("%s disappearing", lsa->name);

  oa = OSPF6_AREA (lsa->lsdb->data);

  intra_prefix_lsa = (struct ospf6_intra_prefix_lsa *)
    OSPF6_LSA_HEADER_END (lsa->header);

  prefix_num = ntohs (intra_prefix_lsa->prefix_num);
  start = (caddr_t) intra_prefix_lsa +
          sizeof (struct ospf6_intra_prefix_lsa);
  end = OSPF6_LSA_END (lsa->header);
  for (current = start; current < end; current += OSPF6_PREFIX_SIZE (op))
    {
      op = (struct ospf6_prefix *) current;
      if (prefix_num == 0)
        break;
      if (end < current + OSPF6_PREFIX_SIZE (op))
        break;
      prefix_num--;

      memset (&prefix, 0, sizeof (struct prefix));
      prefix.family = AF_INET6;
      prefix.prefixlen = op->prefix_length;
      ospf6_prefix_in6_addr (&prefix.u.prefix6, op);

      route = ospf6_route_lookup (&prefix, oa->route_table);
      if (route == NULL)
        continue;

      for (ospf6_route_lock (route);
           route && ospf6_route_is_prefix (&prefix, route);
           route = ospf6_route_next (route))
        {
          if (route->type != OSPF6_DEST_TYPE_NETWORK)
            continue;
          if (route->path.area_id != oa->area_id)
            continue;
          if (route->path.type != OSPF6_PATH_TYPE_INTRA)
            continue;
          if (route->path.origin.type != lsa->header->type ||
              route->path.origin.id != lsa->header->id ||
              route->path.origin.adv_router != lsa->header->adv_router)
            continue;

          if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX))
            {
              prefix2str (&route->prefix, buf, sizeof (buf));
              zlog_debug ("remove %s", buf);
            }
          ospf6_route_remove (route, oa->route_table);
        }
      if (route)
	ospf6_route_unlock (route);
    }

  if (current != end && IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX))
    zlog_debug ("Trailing garbage ignored");
}

void
ospf6_intra_route_calculation (struct ospf6_area *oa)
{
  struct ospf6_route *route;
  u_int16_t type;
  struct ospf6_lsa *lsa;
  void (*hook_add) (struct ospf6_route *) = NULL;
  void (*hook_remove) (struct ospf6_route *) = NULL;

  if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX))
    zlog_debug ("Re-examin intra-routes for area %s", oa->name);

  hook_add = oa->route_table->hook_add;
  hook_remove = oa->route_table->hook_remove;
  oa->route_table->hook_add = NULL;
  oa->route_table->hook_remove = NULL;

  for (route = ospf6_route_head (oa->route_table); route;
       route = ospf6_route_next (route))
    route->flag = OSPF6_ROUTE_REMOVE;

  type = htons (OSPF6_LSTYPE_INTRA_PREFIX);
  for (lsa = ospf6_lsdb_type_head (type, oa->lsdb); lsa;
       lsa = ospf6_lsdb_type_next (type, lsa))
    ospf6_intra_prefix_lsa_add (lsa);

  oa->route_table->hook_add = hook_add;
  oa->route_table->hook_remove = hook_remove;

  for (route = ospf6_route_head (oa->route_table); route;
       route = ospf6_route_next (route))
    {
      if (CHECK_FLAG (route->flag, OSPF6_ROUTE_REMOVE) &&
          CHECK_FLAG (route->flag, OSPF6_ROUTE_ADD))
        {
          UNSET_FLAG (route->flag, OSPF6_ROUTE_REMOVE);
          UNSET_FLAG (route->flag, OSPF6_ROUTE_ADD);
        }

      if (CHECK_FLAG (route->flag, OSPF6_ROUTE_REMOVE))
        ospf6_route_remove (route, oa->route_table);
      else if (CHECK_FLAG (route->flag, OSPF6_ROUTE_ADD) ||
               CHECK_FLAG (route->flag, OSPF6_ROUTE_CHANGE))
        {
          if (hook_add)
            (*hook_add) (route);
        }

      route->flag = 0;
    }

  if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX))
    zlog_debug ("Re-examin intra-routes for area %s: Done", oa->name);
}

static void
ospf6_brouter_debug_print (struct ospf6_route *brouter)
{
  u_int32_t brouter_id;
  char brouter_name[16];
  char area_name[16];
  char destination[64];
  char installed[16], changed[16];
  struct timeval now, res;
  char id[16], adv_router[16];
  char capa[16], options[16];

  brouter_id = ADV_ROUTER_IN_PREFIX (&brouter->prefix);
  inet_ntop (AF_INET, &brouter_id, brouter_name, sizeof (brouter_name));
  inet_ntop (AF_INET, &brouter->path.area_id, area_name, sizeof (area_name));
  ospf6_linkstate_prefix2str (&brouter->prefix, destination,
                              sizeof (destination));

  quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
  timersub (&now, &brouter->installed, &res);
  timerstring (&res, installed, sizeof (installed));

  quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
  timersub (&now, &brouter->changed, &res);
  timerstring (&res, changed, sizeof (changed));

  inet_ntop (AF_INET, &brouter->path.origin.id, id, sizeof (id));
  inet_ntop (AF_INET, &brouter->path.origin.adv_router, adv_router,
             sizeof (adv_router));

  ospf6_options_printbuf (brouter->path.options, options, sizeof (options));
  ospf6_capability_printbuf (brouter->path.router_bits, capa, sizeof (capa));

  zlog_info ("Brouter: %s via area %s", brouter_name, area_name);
  zlog_info ("  memory: prev: %p this: %p next: %p parent rnode: %p",
             (void *)brouter->prev, (void *)brouter, (void *)brouter->next,
             (void *)brouter->rnode);
  zlog_info ("  type: %d prefix: %s installed: %s changed: %s",
             brouter->type, destination, installed, changed);
  zlog_info ("  lock: %d flags: %s%s%s%s", brouter->lock,
           (CHECK_FLAG (brouter->flag, OSPF6_ROUTE_BEST)   ? "B" : "-"),
           (CHECK_FLAG (brouter->flag, OSPF6_ROUTE_ADD)    ? "A" : "-"),
           (CHECK_FLAG (brouter->flag, OSPF6_ROUTE_REMOVE) ? "R" : "-"),
           (CHECK_FLAG (brouter->flag, OSPF6_ROUTE_CHANGE) ? "C" : "-"));
  zlog_info ("  path type: %s ls-origin %s id: %s adv-router %s",
             OSPF6_PATH_TYPE_NAME (brouter->path.type),
             ospf6_lstype_name (brouter->path.origin.type),
             id, adv_router);
  zlog_info ("  options: %s router-bits: %s metric-type: %d metric: %d/%d",
             options, capa, brouter->path.metric_type,
             brouter->path.cost, brouter->path.cost_e2);
}

void
ospf6_intra_brouter_calculation (struct ospf6_area *oa)
{
  struct ospf6_route *brouter, *copy;
  void (*hook_add) (struct ospf6_route *) = NULL;
  void (*hook_remove) (struct ospf6_route *) = NULL;
  u_int32_t brouter_id;
  char brouter_name[16];
  
  if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ID (oa->area_id))
    zlog_info ("border-router calculation for area %s", oa->name);
  
  hook_add = oa->ospf6->brouter_table->hook_add;
  hook_remove = oa->ospf6->brouter_table->hook_remove;
  oa->ospf6->brouter_table->hook_add = NULL;
  oa->ospf6->brouter_table->hook_remove = NULL;

  /* withdraw the previous router entries for the area */
  for (brouter = ospf6_route_head (oa->ospf6->brouter_table); brouter;
       brouter = ospf6_route_next (brouter))
    {
      brouter_id = ADV_ROUTER_IN_PREFIX (&brouter->prefix);
      inet_ntop (AF_INET, &brouter_id, brouter_name, sizeof (brouter_name));
      if (brouter->path.area_id != oa->area_id)
        continue;
      brouter->flag = OSPF6_ROUTE_REMOVE;

      if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_ID (brouter_id) ||
          IS_OSPF6_DEBUG_ROUTE (MEMORY))
        {
          zlog_info ("%p: mark as removing: area %s brouter %s",
                     (void *)brouter, oa->name, brouter_name);
          ospf6_brouter_debug_print (brouter);
        }
    }

  for (brouter = ospf6_route_head (oa->spf_table); brouter;
       brouter = ospf6_route_next (brouter))
    {
      brouter_id = ADV_ROUTER_IN_PREFIX (&brouter->prefix);
      inet_ntop (AF_INET, &brouter_id, brouter_name, sizeof (brouter_name));

      if (brouter->type != OSPF6_DEST_TYPE_LINKSTATE)
        continue;
      if (ospf6_linkstate_prefix_id (&brouter->prefix) != htonl (0))
        continue;
      if (! CHECK_FLAG (brouter->path.router_bits, OSPF6_ROUTER_BIT_E) &&
          ! CHECK_FLAG (brouter->path.router_bits, OSPF6_ROUTER_BIT_B))
        continue;

      if (! OSPF6_OPT_ISSET (brouter->path.options, OSPF6_OPT_V6) ||
	  ! OSPF6_OPT_ISSET (brouter->path.options, OSPF6_OPT_R))
	continue;

      copy = ospf6_route_copy (brouter);
      copy->type = OSPF6_DEST_TYPE_ROUTER;
      copy->path.area_id = oa->area_id;
      ospf6_route_add (copy, oa->ospf6->brouter_table);

      if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_ID (brouter_id) ||
          IS_OSPF6_DEBUG_ROUTE (MEMORY))
        {
          zlog_info ("%p: transfer: area %s brouter %s",
                     (void *)brouter, oa->name, brouter_name);
          ospf6_brouter_debug_print (brouter);
        }
    }

  oa->ospf6->brouter_table->hook_add = hook_add;
  oa->ospf6->brouter_table->hook_remove = hook_remove;

  for (brouter = ospf6_route_head (oa->ospf6->brouter_table); brouter;
       brouter = ospf6_route_next (brouter))
    {
      brouter_id = ADV_ROUTER_IN_PREFIX (&brouter->prefix);
      inet_ntop (AF_INET, &brouter_id, brouter_name, sizeof (brouter_name));
      
      if (brouter->path.area_id != oa->area_id)
        continue;

      if (CHECK_FLAG (brouter->flag, OSPF6_ROUTE_WAS_REMOVED))
        continue;

      if (CHECK_FLAG (brouter->flag, OSPF6_ROUTE_REMOVE) &&
          CHECK_FLAG (brouter->flag, OSPF6_ROUTE_ADD))
        {
          UNSET_FLAG (brouter->flag, OSPF6_ROUTE_REMOVE);
          UNSET_FLAG (brouter->flag, OSPF6_ROUTE_ADD);
        }

      if (CHECK_FLAG (brouter->flag, OSPF6_ROUTE_REMOVE))
        {
          if (IS_OSPF6_DEBUG_BROUTER ||
              IS_OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_ID (brouter_id) ||
              IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ID (oa->area_id))
            zlog_info ("brouter %s disappears via area %s",
                       brouter_name, oa->name);
          ospf6_route_remove (brouter, oa->ospf6->brouter_table);
        }
      else if (CHECK_FLAG (brouter->flag, OSPF6_ROUTE_ADD) ||
               CHECK_FLAG (brouter->flag, OSPF6_ROUTE_CHANGE))
        {
          if (IS_OSPF6_DEBUG_BROUTER ||
              IS_OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_ID (brouter_id) ||
              IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ID (oa->area_id))
            zlog_info ("brouter %s appears via area %s",
                       brouter_name, oa->name);

          /* newly added */
          if (hook_add)
            (*hook_add) (brouter);
        }
      else
        {
          if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_ID (brouter_id) ||
              IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ID (oa->area_id))
            zlog_info ("brouter %s still exists via area %s",
                       brouter_name, oa->name);
        }

      brouter->flag = 0;
    }

  if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ID (oa->area_id))
    zlog_info ("border-router calculation for area %s: done", oa->name);
}

struct ospf6_lsa_handler router_handler =
{
  OSPF6_LSTYPE_ROUTER,
  "Router",
  "Rtr",
  ospf6_router_lsa_show,
  ospf6_router_lsa_get_nbr_id
};

struct ospf6_lsa_handler network_handler =
{
  OSPF6_LSTYPE_NETWORK,
  "Network",
  "Net",
  ospf6_network_lsa_show,
  ospf6_network_lsa_get_ar_id
};

struct ospf6_lsa_handler link_handler =
{
  OSPF6_LSTYPE_LINK,
  "Link",
  "Lnk",
  ospf6_link_lsa_show,
  ospf6_link_lsa_get_prefix_str
};

struct ospf6_lsa_handler intra_prefix_handler =
{
  OSPF6_LSTYPE_INTRA_PREFIX,
  "Intra-Prefix",
  "INP",
  ospf6_intra_prefix_lsa_show,
  ospf6_intra_prefix_lsa_get_prefix_str
};

void
ospf6_intra_init (void)
{
  ospf6_install_lsa_handler (&router_handler);
  ospf6_install_lsa_handler (&network_handler);
  ospf6_install_lsa_handler (&link_handler);
  ospf6_install_lsa_handler (&intra_prefix_handler);
}

DEFUN (debug_ospf6_brouter,
       debug_ospf6_brouter_cmd,
       "debug ospf6 border-routers",
       DEBUG_STR
       OSPF6_STR
       "Debug border router\n"
      )
{
  OSPF6_DEBUG_BROUTER_ON ();
  return CMD_SUCCESS;
}

DEFUN (no_debug_ospf6_brouter,
       no_debug_ospf6_brouter_cmd,
       "no debug ospf6 border-routers",
       NO_STR
       DEBUG_STR
       OSPF6_STR
       "Debug border router\n"
      )
{
  OSPF6_DEBUG_BROUTER_OFF ();
  return CMD_SUCCESS;
}

DEFUN (debug_ospf6_brouter_router,
       debug_ospf6_brouter_router_cmd,
       "debug ospf6 border-routers router-id A.B.C.D",
       DEBUG_STR
       OSPF6_STR
       "Debug border router\n"
       "Debug specific border router\n"
       "Specify border-router's router-id\n"
      )
{
  u_int32_t router_id;
  inet_pton (AF_INET, argv[0], &router_id);
  OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_ON (router_id);
  return CMD_SUCCESS;
}

DEFUN (no_debug_ospf6_brouter_router,
       no_debug_ospf6_brouter_router_cmd,
       "no debug ospf6 border-routers router-id",
       NO_STR
       DEBUG_STR
       OSPF6_STR
       "Debug border router\n"
       "Debug specific border router\n"
      )
{
  OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_OFF ();
  return CMD_SUCCESS;
}

DEFUN (debug_ospf6_brouter_area,
       debug_ospf6_brouter_area_cmd,
       "debug ospf6 border-routers area-id A.B.C.D",
       DEBUG_STR
       OSPF6_STR
       "Debug border router\n"
       "Debug border routers in specific Area\n"
       "Specify Area-ID\n"
      )
{
  u_int32_t area_id;
  inet_pton (AF_INET, argv[0], &area_id);
  OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ON (area_id);
  return CMD_SUCCESS;
}

DEFUN (no_debug_ospf6_brouter_area,
       no_debug_ospf6_brouter_area_cmd,
       "no debug ospf6 border-routers area-id",
       NO_STR
       DEBUG_STR
       OSPF6_STR
       "Debug border router\n"
       "Debug border routers in specific Area\n"
      )
{
  OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_OFF ();
  return CMD_SUCCESS;
}

int
config_write_ospf6_debug_brouter (struct vty *vty)
{
  char buf[16];
  if (IS_OSPF6_DEBUG_BROUTER)
    vty_out (vty, "debug ospf6 border-routers%s", VNL);
  if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER)
    {
      inet_ntop (AF_INET, &conf_debug_ospf6_brouter_specific_router_id,
                 buf, sizeof (buf));
      vty_out (vty, "debug ospf6 border-routers router-id %s%s", buf, VNL);
    }
  if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA)
    {
      inet_ntop (AF_INET, &conf_debug_ospf6_brouter_specific_area_id,
                 buf, sizeof (buf));
      vty_out (vty, "debug ospf6 border-routers area-id %s%s", buf, VNL);
    }
  return 0;
}

void
install_element_ospf6_debug_brouter (void)
{
  install_element (ENABLE_NODE, &debug_ospf6_brouter_cmd);
  install_element (ENABLE_NODE, &debug_ospf6_brouter_router_cmd);
  install_element (ENABLE_NODE, &debug_ospf6_brouter_area_cmd);
  install_element (ENABLE_NODE, &no_debug_ospf6_brouter_cmd);
  install_element (ENABLE_NODE, &no_debug_ospf6_brouter_router_cmd);
  install_element (ENABLE_NODE, &no_debug_ospf6_brouter_area_cmd);
  install_element (CONFIG_NODE, &debug_ospf6_brouter_cmd);
  install_element (CONFIG_NODE, &debug_ospf6_brouter_router_cmd);
  install_element (CONFIG_NODE, &debug_ospf6_brouter_area_cmd);
  install_element (CONFIG_NODE, &no_debug_ospf6_brouter_cmd);
  install_element (CONFIG_NODE, &no_debug_ospf6_brouter_router_cmd);
  install_element (CONFIG_NODE, &no_debug_ospf6_brouter_area_cmd);
}


