/*
 * 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)
          && ((size_t)((char *)lsdesc - buffer)
                 + sizeof (struct ospf6_router_lsdesc)
               > 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);
}


