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

#include <zebra.h>

#include "log.h"
#include "memory.h"
#include "linklist.h"
#include "thread.h"
#include "vty.h"
#include "command.h"
#include "if.h"
#include "prefix.h"
#include "table.h"
#include "plist.h"
#include "filter.h"

#include "ospf6_proto.h"
#include "ospf6_lsa.h"
#include "ospf6_lsdb.h"
#include "ospf6_route.h"
#include "ospf6_spf.h"
#include "ospf6_top.h"
#include "ospf6_area.h"
#include "ospf6_interface.h"
#include "ospf6_intra.h"
#include "ospf6_abr.h"
#include "ospf6d.h"

int
ospf6_area_cmp (void *va, void *vb)
{
  struct ospf6_area *oa = (struct ospf6_area *) va;
  struct ospf6_area *ob = (struct ospf6_area *) vb;
  return (ntohl (oa->area_id) < ntohl (ob->area_id) ? -1 : 1);
}

/* schedule routing table recalculation */
static void
ospf6_area_lsdb_hook_add (struct ospf6_lsa *lsa)
{
  switch (ntohs (lsa->header->type))
    {
    case OSPF6_LSTYPE_ROUTER:
    case OSPF6_LSTYPE_NETWORK:
      if (IS_OSPF6_DEBUG_EXAMIN_TYPE (lsa->header->type))
        {
          zlog_debug ("Examin %s", lsa->name);
          zlog_debug ("Schedule SPF Calculation for %s",
		      OSPF6_AREA (lsa->lsdb->data)->name);
        }
      ospf6_spf_schedule (OSPF6_PROCESS(OSPF6_AREA (lsa->lsdb->data)->ospf6),
			  ospf6_lsadd_to_spf_reason(lsa));
      break;

    case OSPF6_LSTYPE_INTRA_PREFIX:
      ospf6_intra_prefix_lsa_add (lsa);
      break;

    case OSPF6_LSTYPE_INTER_PREFIX:
    case OSPF6_LSTYPE_INTER_ROUTER:
      ospf6_abr_examin_summary (lsa, (struct ospf6_area *) lsa->lsdb->data);
      break;

    default:
      break;
    }
}

static void
ospf6_area_lsdb_hook_remove (struct ospf6_lsa *lsa)
{
  switch (ntohs (lsa->header->type))
    {
    case OSPF6_LSTYPE_ROUTER:
    case OSPF6_LSTYPE_NETWORK:
      if (IS_OSPF6_DEBUG_EXAMIN_TYPE (lsa->header->type))
        {
          zlog_debug ("LSA disappearing: %s", lsa->name);
          zlog_debug ("Schedule SPF Calculation for %s",
                     OSPF6_AREA (lsa->lsdb->data)->name);
        }
      ospf6_spf_schedule (OSPF6_PROCESS(OSPF6_AREA (lsa->lsdb->data)->ospf6),
			  ospf6_lsremove_to_spf_reason(lsa));
      break;

    case OSPF6_LSTYPE_INTRA_PREFIX:
      ospf6_intra_prefix_lsa_remove (lsa);
      break;

    case OSPF6_LSTYPE_INTER_PREFIX:
    case OSPF6_LSTYPE_INTER_ROUTER:
      ospf6_abr_examin_summary (lsa, (struct ospf6_area *) lsa->lsdb->data);
      break;

    default:
      break;
    }
}

static void
ospf6_area_route_hook_add (struct ospf6_route *route)
{
  struct ospf6_route *copy = ospf6_route_copy (route);
  ospf6_route_add (copy, ospf6->route_table);
}

static void
ospf6_area_route_hook_remove (struct ospf6_route *route)
{
  struct ospf6_route *copy;

  copy = ospf6_route_lookup_identical (route, ospf6->route_table);
  if (copy)
    ospf6_route_remove (copy, ospf6->route_table);
}

/* Make new area structure */
struct ospf6_area *
ospf6_area_create (u_int32_t area_id, struct ospf6 *o)
{
  struct ospf6_area *oa;
  struct ospf6_route *route;

  oa = XCALLOC (MTYPE_OSPF6_AREA, sizeof (struct ospf6_area));

  inet_ntop (AF_INET, &area_id, oa->name, sizeof (oa->name));
  oa->area_id = area_id;
  oa->if_list = list_new ();

  oa->lsdb = ospf6_lsdb_create (oa);
  oa->lsdb->hook_add = ospf6_area_lsdb_hook_add;
  oa->lsdb->hook_remove = ospf6_area_lsdb_hook_remove;
  oa->lsdb_self = ospf6_lsdb_create (oa);

  oa->spf_table = OSPF6_ROUTE_TABLE_CREATE (AREA, SPF_RESULTS);
  oa->spf_table->scope = oa;
  oa->route_table = OSPF6_ROUTE_TABLE_CREATE (AREA, ROUTES);
  oa->route_table->scope = oa;
  oa->route_table->hook_add = ospf6_area_route_hook_add;
  oa->route_table->hook_remove = ospf6_area_route_hook_remove;

  oa->range_table = OSPF6_ROUTE_TABLE_CREATE (AREA, PREFIX_RANGES);
  oa->range_table->scope = oa;
  oa->summary_prefix = OSPF6_ROUTE_TABLE_CREATE (AREA, SUMMARY_PREFIXES);
  oa->summary_prefix->scope = oa;
  oa->summary_router = OSPF6_ROUTE_TABLE_CREATE (AREA, SUMMARY_ROUTERS);
  oa->summary_router->scope = oa;

  /* set default options */
  if (CHECK_FLAG (o->flag, OSPF6_STUB_ROUTER))
    {
      OSPF6_OPT_CLEAR (oa->options, OSPF6_OPT_V6);
      OSPF6_OPT_CLEAR (oa->options, OSPF6_OPT_R);
    }
  else
    {
      OSPF6_OPT_SET (oa->options, OSPF6_OPT_V6);
      OSPF6_OPT_SET (oa->options, OSPF6_OPT_R);
    }

  OSPF6_OPT_SET (oa->options, OSPF6_OPT_E);

  oa->ospf6 = o;
  listnode_add_sort (o->area_list, oa);

  /* import athoer area's routes as inter-area routes */
  for (route = ospf6_route_head (o->route_table); route;
       route = ospf6_route_next (route))
    ospf6_abr_originate_summary_to_area (route, oa);

  return oa;
}

void
ospf6_area_delete (struct ospf6_area *oa)
{
  struct listnode *n;
  struct ospf6_interface *oi;

  ospf6_route_table_delete (oa->range_table);
  ospf6_route_table_delete (oa->summary_prefix);
  ospf6_route_table_delete (oa->summary_router);

  /* The ospf6_interface structs store configuration
   * information which should not be lost/reset when
   * deleting an area.
   * So just detach the interface from the area and
   * keep it around. */
  for (ALL_LIST_ELEMENTS_RO (oa->if_list, n, oi))
    oi->area = NULL;

  list_delete (oa->if_list);

  ospf6_lsdb_delete (oa->lsdb);
  ospf6_lsdb_delete (oa->lsdb_self);

  ospf6_spf_table_finish (oa->spf_table);
  ospf6_route_table_delete (oa->spf_table);
  ospf6_route_table_delete (oa->route_table);

  THREAD_OFF (oa->thread_spf_calculation);
  THREAD_OFF (oa->thread_route_calculation);

  listnode_delete (oa->ospf6->area_list, oa);
  oa->ospf6 = NULL;

  /* free area */
  XFREE (MTYPE_OSPF6_AREA, oa);
}

struct ospf6_area *
ospf6_area_lookup (u_int32_t area_id, struct ospf6 *ospf6)
{
  struct ospf6_area *oa;
  struct listnode *n;

  for (ALL_LIST_ELEMENTS_RO (ospf6->area_list, n, oa))
    if (oa->area_id == area_id)
      return oa;

  return (struct ospf6_area *) NULL;
}

static struct ospf6_area *
ospf6_area_get (u_int32_t area_id, struct ospf6 *o)
{
  struct ospf6_area *oa;
  oa = ospf6_area_lookup (area_id, o);
  if (oa == NULL)
    oa = ospf6_area_create (area_id, o);
  return oa;
}

void
ospf6_area_enable (struct ospf6_area *oa)
{
  struct listnode *node, *nnode;
  struct ospf6_interface *oi;

  SET_FLAG (oa->flag, OSPF6_AREA_ENABLE);

  for (ALL_LIST_ELEMENTS (oa->if_list, node, nnode, oi))
    ospf6_interface_enable (oi);
  ospf6_abr_enable_area (oa);
}

void
ospf6_area_disable (struct ospf6_area *oa)
{
  struct listnode *node, *nnode;
  struct ospf6_interface *oi;

  UNSET_FLAG (oa->flag, OSPF6_AREA_ENABLE);

  for (ALL_LIST_ELEMENTS (oa->if_list, node, nnode, oi))
    ospf6_interface_disable (oi);

  ospf6_abr_disable_area (oa);
  ospf6_lsdb_remove_all (oa->lsdb);
  ospf6_lsdb_remove_all (oa->lsdb_self);

  ospf6_spf_table_finish(oa->spf_table);
  ospf6_route_remove_all(oa->route_table);

  THREAD_OFF (oa->thread_spf_calculation);
  THREAD_OFF (oa->thread_route_calculation);

  THREAD_OFF (oa->thread_router_lsa);
  THREAD_OFF (oa->thread_intra_prefix_lsa);
}


void
ospf6_area_show (struct vty *vty, struct ospf6_area *oa)
{
  struct listnode *i;
  struct ospf6_interface *oi;

  vty_out (vty, " Area %s%s", oa->name, VNL);
  vty_out (vty, "     Number of Area scoped LSAs is %u%s",
           oa->lsdb->count, VNL);

  vty_out (vty, "     Interface attached to this area:");
  for (ALL_LIST_ELEMENTS_RO (oa->if_list, i, oi))
    vty_out (vty, " %s", oi->interface->name);
  
  vty_out (vty, "%s", VNL);
}


#define OSPF6_CMD_AREA_LOOKUP(str, oa)                     \
{                                                          \
  u_int32_t area_id = 0;                                   \
  if (inet_pton (AF_INET, str, &area_id) != 1)             \
    {                                                      \
      vty_out (vty, "Malformed Area-ID: %s%s", str, VNL);  \
      return CMD_SUCCESS;                                  \
    }                                                      \
  oa = ospf6_area_lookup (area_id, ospf6);                 \
  if (oa == NULL)                                          \
    {                                                      \
      vty_out (vty, "No such Area: %s%s", str, VNL);       \
      return CMD_SUCCESS;                                  \
    }                                                      \
}

#define OSPF6_CMD_AREA_GET(str, oa)                        \
{                                                          \
  u_int32_t area_id = 0;                                   \
  if (inet_pton (AF_INET, str, &area_id) != 1)             \
    {                                                      \
      vty_out (vty, "Malformed Area-ID: %s%s", str, VNL);  \
      return CMD_SUCCESS;                                  \
    }                                                      \
  oa = ospf6_area_get (area_id, ospf6);                    \
}

DEFUN (area_range,
       area_range_cmd,
       "area A.B.C.D range X:X::X:X/M",
       "OSPF area parameters\n"
       OSPF6_AREA_ID_STR
       "Configured address range\n"
       "Specify IPv6 prefix\n"
       )
{
  int ret;
  struct ospf6_area *oa;
  struct prefix prefix;
  struct ospf6_route *range;

  OSPF6_CMD_AREA_GET (argv[0], oa);
  argc--;
  argv++;

  ret = str2prefix (argv[0], &prefix);
  if (ret != 1 || prefix.family != AF_INET6)
    {
      vty_out (vty, "Malformed argument: %s%s", argv[0], VNL);
      return CMD_SUCCESS;
    }
  argc--;
  argv++;

  range = ospf6_route_lookup (&prefix, oa->range_table);
  if (range == NULL)
    {
      range = ospf6_route_create ();
      range->type = OSPF6_DEST_TYPE_RANGE;
      range->prefix = prefix;
    }

  if (argc)
    {
      if (! strcmp (argv[0], "not-advertise"))
        SET_FLAG (range->flag, OSPF6_ROUTE_DO_NOT_ADVERTISE);
      else if (! strcmp (argv[0], "advertise"))
        UNSET_FLAG (range->flag, OSPF6_ROUTE_DO_NOT_ADVERTISE);
    }

  if (range->rnode)
    {
      vty_out (vty, "Range already defined: %s%s", argv[-1], VNL);
      return CMD_WARNING;
    }

  ospf6_route_add (range, oa->range_table);
  return CMD_SUCCESS;
}

ALIAS (area_range,
       area_range_advertise_cmd,
       "area A.B.C.D range X:X::X:X/M (advertise|not-advertise)",
       "OSPF area parameters\n"
       OSPF6_AREA_ID_STR
       "Configured address range\n"
       "Specify IPv6 prefix\n"
       )

DEFUN (no_area_range,
       no_area_range_cmd,
       "no area A.B.C.D range X:X::X:X/M",
       "OSPF area parameters\n"
       OSPF6_AREA_ID_STR
       "Configured address range\n"
       "Specify IPv6 prefix\n"
       )
{
  int ret;
  struct ospf6_area *oa;
  struct prefix prefix;
  struct ospf6_route *range;

  OSPF6_CMD_AREA_GET (argv[0], oa);
  argc--;
  argv++;

  ret = str2prefix (argv[0], &prefix);
  if (ret != 1 || prefix.family != AF_INET6)
    {
      vty_out (vty, "Malformed argument: %s%s", argv[0], VNL);
      return CMD_SUCCESS;
    }

  range = ospf6_route_lookup (&prefix, oa->range_table);
  if (range == NULL)
    {
      vty_out (vty, "Range %s does not exists.%s", argv[0], VNL);
      return CMD_SUCCESS;
    }

  ospf6_route_remove (range, oa->range_table);

  return CMD_SUCCESS;
}

void
ospf6_area_config_write (struct vty *vty)
{
  struct listnode *node;
  struct ospf6_area *oa;
  struct ospf6_route *range;
  char buf[128];

  for (ALL_LIST_ELEMENTS_RO (ospf6->area_list, node, oa))
    {
      for (range = ospf6_route_head (oa->range_table); range;
           range = ospf6_route_next (range))
        {
          prefix2str (&range->prefix, buf, sizeof (buf));
          vty_out (vty, " area %s range %s%s", oa->name, buf, VNL);
        }
      if (PREFIX_NAME_IN (oa))
        vty_out (vty, " area %s filter-list prefix %s in%s",
                 oa->name, PREFIX_NAME_IN (oa), VNL);
      if (PREFIX_NAME_OUT (oa))
        vty_out (vty, " area %s filter-list prefix %s out%s",
                 oa->name, PREFIX_NAME_OUT (oa), VNL);
      if (IMPORT_NAME (oa))
        vty_out (vty, " area %s import-list %s%s",
                 oa->name, IMPORT_NAME (oa), VNL);
      if (EXPORT_NAME (oa))
        vty_out (vty, " area %s export-list %s%s",
                 oa->name, EXPORT_NAME (oa), VNL);
    }
}

DEFUN (area_filter_list,
       area_filter_list_cmd,
       "area A.B.C.D filter-list prefix WORD (in|out)",
       "OSPFv6 area parameters\n"
       "OSPFv6 area ID in IP address format\n"
       "Filter networks between OSPFv6 areas\n"
       "Filter prefixes between OSPFv6 areas\n"
       "Name of an IPv6 prefix-list\n"
       "Filter networks sent to this area\n"
       "Filter networks sent from this area\n")
{
  struct ospf6_area *area;
  struct prefix_list *plist;

  OSPF6_CMD_AREA_GET (argv[0], area);
  argc--;
  argv++;

  plist = prefix_list_lookup (AFI_IP6, argv[0]);
  if (strncmp (argv[1], "in", 2) == 0)
    {
      PREFIX_LIST_IN (area) = plist;
      if (PREFIX_NAME_IN (area))
	free (PREFIX_NAME_IN (area));

      PREFIX_NAME_IN (area) = strdup (argv[0]);
      ospf6_abr_reimport (area);
    }
  else
    {
      PREFIX_LIST_OUT (area) = plist;
      if (PREFIX_NAME_OUT (area))
	free (PREFIX_NAME_OUT (area));

      PREFIX_NAME_OUT (area) = strdup (argv[0]);
      ospf6_abr_enable_area (area);
    }

  return CMD_SUCCESS;
}
     
DEFUN (no_area_filter_list,
       no_area_filter_list_cmd,
       "no area A.B.C.D filter-list prefix WORD (in|out)",
       NO_STR
       "OSPFv6 area parameters\n"
       "OSPFv6 area ID in IP address format\n"
       "Filter networks between OSPFv6 areas\n"
       "Filter prefixes between OSPFv6 areas\n"
       "Name of an IPv6 prefix-list\n"
       "Filter networks sent to this area\n"
       "Filter networks sent from this area\n")
{
  struct ospf6_area *area;

  OSPF6_CMD_AREA_GET (argv[0], area);
  argc--;
  argv++;

  if (strncmp (argv[1], "in", 2) == 0)
    {
      if (PREFIX_NAME_IN (area))
	if (strcmp (PREFIX_NAME_IN (area), argv[0]) != 0)
	  return CMD_SUCCESS;

      PREFIX_LIST_IN (area) = NULL;
      if (PREFIX_NAME_IN (area))
	free (PREFIX_NAME_IN (area));

      PREFIX_NAME_IN (area) = NULL;
      ospf6_abr_reimport (area);
    }
  else
    {
      if (PREFIX_NAME_OUT (area))
	if (strcmp (PREFIX_NAME_OUT (area), argv[0]) != 0)
	  return CMD_SUCCESS;

      PREFIX_LIST_OUT (area) = NULL;
      if (PREFIX_NAME_OUT (area))
	free (PREFIX_NAME_OUT (area));

      PREFIX_NAME_OUT (area) = NULL;
      ospf6_abr_enable_area (area);
    }

  return CMD_SUCCESS;
}

DEFUN (area_import_list,
       area_import_list_cmd,
       "area A.B.C.D import-list NAME",
       "OSPFv6 area parameters\n"
       "OSPFv6 area ID in IP address format\n"
       "Set the filter for networks from other areas announced to the specified one\n"
       "Name of the acess-list\n")
{
  struct ospf6_area *area;
  struct access_list *list;

  OSPF6_CMD_AREA_GET(argv[0], area);

  list = access_list_lookup (AFI_IP6, argv[1]);

  IMPORT_LIST (area) = list;

  if (IMPORT_NAME (area))
    free (IMPORT_NAME (area));

  IMPORT_NAME (area) = strdup (argv[1]);
  ospf6_abr_reimport (area);

  return CMD_SUCCESS; 
}

DEFUN (no_area_import_list,
       no_area_import_list_cmd,
       "no area A.B.C.D import-list NAME",
       "OSPFv6 area parameters\n"
       "OSPFv6 area ID in IP address format\n"
       "Unset the filter for networks announced to other areas\n"
       "NAme of the access-list\n")
{
  struct ospf6_area *area;

  OSPF6_CMD_AREA_GET(argv[0], area);

  IMPORT_LIST (area) = 0;

  if (IMPORT_NAME (area))
    free (IMPORT_NAME (area));

  IMPORT_NAME (area) = NULL;
  ospf6_abr_reimport (area);

  return CMD_SUCCESS;
}

DEFUN (area_export_list,
       area_export_list_cmd,
       "area A.B.C.D export-list NAME",
       "OSPFv6 area parameters\n"
       "OSPFv6 area ID in IP address format\n"
       "Set the filter for networks announced to other areas\n"
       "Name of the acess-list\n")
{
  struct ospf6_area *area;
  struct access_list *list;

  OSPF6_CMD_AREA_GET(argv[0], area);

  list = access_list_lookup (AFI_IP6, argv[1]);

  EXPORT_LIST (area) = list;

  if (EXPORT_NAME (area))
    free (EXPORT_NAME (area));

  EXPORT_NAME (area) = strdup (argv[1]);
  ospf6_abr_enable_area (area);

  return CMD_SUCCESS; 
}

DEFUN (no_area_export_list,
       no_area_export_list_cmd,
       "no area A.B.C.D export-list NAME",
       "OSPFv6 area parameters\n"
       "OSPFv6 area ID in IP address format\n"
       "Unset the filter for networks announced to other areas\n"
       "Name of the access-list\n")
{
  struct ospf6_area *area;

  OSPF6_CMD_AREA_GET(argv[0], area);

  EXPORT_LIST (area) = 0;

  if (EXPORT_NAME (area))
    free (EXPORT_NAME (area));

  EXPORT_NAME (area) = NULL;
  ospf6_abr_enable_area (area);

  return CMD_SUCCESS;
}

DEFUN (show_ipv6_ospf6_spf_tree,
       show_ipv6_ospf6_spf_tree_cmd,
       "show ipv6 ospf6 spf tree",
       SHOW_STR
       IP6_STR
       OSPF6_STR
       "Shortest Path First caculation\n"
       "Show SPF tree\n")
{
  struct listnode *node;
  struct ospf6_area *oa;
  struct ospf6_vertex *root;
  struct ospf6_route *route;
  struct prefix prefix;

  OSPF6_CMD_CHECK_RUNNING ();

  ospf6_linkstate_prefix (ospf6->router_id, htonl (0), &prefix);

  for (ALL_LIST_ELEMENTS_RO (ospf6->area_list, node, oa))
    {
      route = ospf6_route_lookup (&prefix, oa->spf_table);
      if (route == NULL)
        {
          vty_out (vty, "LS entry for root not found in area %s%s",
                   oa->name, VNL);
          continue;
        }
      root = (struct ospf6_vertex *) route->route_option;
      ospf6_spf_display_subtree (vty, "", 0, root);
    }

  return CMD_SUCCESS;
}

DEFUN (show_ipv6_ospf6_area_spf_tree,
       show_ipv6_ospf6_area_spf_tree_cmd,
       "show ipv6 ospf6 area A.B.C.D spf tree",
       SHOW_STR
       IP6_STR
       OSPF6_STR
       OSPF6_AREA_STR
       OSPF6_AREA_ID_STR
       "Shortest Path First caculation\n"
       "Show SPF tree\n")
{
  u_int32_t area_id;
  struct ospf6_area *oa;
  struct ospf6_vertex *root;
  struct ospf6_route *route;
  struct prefix prefix;

  OSPF6_CMD_CHECK_RUNNING ();

  ospf6_linkstate_prefix (ospf6->router_id, htonl (0), &prefix);

  if (inet_pton (AF_INET, argv[0], &area_id) != 1)
    {
      vty_out (vty, "Malformed Area-ID: %s%s", argv[0], VNL);
      return CMD_SUCCESS;
    }
  oa = ospf6_area_lookup (area_id, ospf6);
  if (oa == NULL)
    {
      vty_out (vty, "No such Area: %s%s", argv[0], VNL);
      return CMD_SUCCESS;
    }

  route = ospf6_route_lookup (&prefix, oa->spf_table);
  if (route == NULL)
    {
      vty_out (vty, "LS entry for root not found in area %s%s",
               oa->name, VNL);
      return CMD_SUCCESS;
    }
  root = (struct ospf6_vertex *) route->route_option;
  ospf6_spf_display_subtree (vty, "", 0, root);

  return CMD_SUCCESS;
}

DEFUN (show_ipv6_ospf6_simulate_spf_tree_root,
       show_ipv6_ospf6_simulate_spf_tree_root_cmd,
       "show ipv6 ospf6 simulate spf-tree A.B.C.D area A.B.C.D",
       SHOW_STR
       IP6_STR
       OSPF6_STR
       "Shortest Path First caculation\n"
       "Show SPF tree\n"
       "Specify root's router-id to calculate another router's SPF tree\n")
{
  u_int32_t area_id;
  struct ospf6_area *oa;
  struct ospf6_vertex *root;
  struct ospf6_route *route;
  struct prefix prefix;
  u_int32_t router_id;
  struct ospf6_route_table *spf_table;
  unsigned char tmp_debug_ospf6_spf = 0;

  OSPF6_CMD_CHECK_RUNNING ();

  inet_pton (AF_INET, argv[0], &router_id);
  ospf6_linkstate_prefix (router_id, htonl (0), &prefix);

  if (inet_pton (AF_INET, argv[1], &area_id) != 1)
    {
      vty_out (vty, "Malformed Area-ID: %s%s", argv[1], VNL);
      return CMD_SUCCESS;
    }
  oa = ospf6_area_lookup (area_id, ospf6);
  if (oa == NULL)
    {
      vty_out (vty, "No such Area: %s%s", argv[1], VNL);
      return CMD_SUCCESS;
    }

  tmp_debug_ospf6_spf = conf_debug_ospf6_spf;
  conf_debug_ospf6_spf = 0;

  spf_table = OSPF6_ROUTE_TABLE_CREATE (NONE, SPF_RESULTS);
  ospf6_spf_calculation (router_id, spf_table, oa);

  conf_debug_ospf6_spf = tmp_debug_ospf6_spf;

  route = ospf6_route_lookup (&prefix, spf_table);
  if (route == NULL)
    {
      ospf6_spf_table_finish (spf_table);
      ospf6_route_table_delete (spf_table);
      return CMD_SUCCESS;
    }
  root = (struct ospf6_vertex *) route->route_option;
  ospf6_spf_display_subtree (vty, "", 0, root);

  ospf6_spf_table_finish (spf_table);
  ospf6_route_table_delete (spf_table);

  return CMD_SUCCESS;
}

void
ospf6_area_init (void)
{
  install_element (VIEW_NODE, &show_ipv6_ospf6_spf_tree_cmd);
  install_element (VIEW_NODE, &show_ipv6_ospf6_area_spf_tree_cmd);
  install_element (VIEW_NODE, &show_ipv6_ospf6_simulate_spf_tree_root_cmd);

  install_element (OSPF6_NODE, &area_range_cmd);
  install_element (OSPF6_NODE, &area_range_advertise_cmd);
  install_element (OSPF6_NODE, &no_area_range_cmd);

  install_element (OSPF6_NODE, &area_import_list_cmd);
  install_element (OSPF6_NODE, &no_area_import_list_cmd);
  install_element (OSPF6_NODE, &area_export_list_cmd);
  install_element (OSPF6_NODE, &no_area_export_list_cmd);

  install_element (OSPF6_NODE, &area_filter_list_cmd);
  install_element (OSPF6_NODE, &no_area_filter_list_cmd);

}


