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

#include "ospf6d.h"

#include "ospf6_damp.h"

/* global ospf6d variable */
int  ospf6_sock;
list iflist;
list nexthoplist = NULL;
struct sockaddr_in6 allspfrouters6;
struct sockaddr_in6 alldrouters6;
char *recent_reason; /* set by ospf6_lsa_check_recent () */
int proctitle_mode = 0;

char ospf6_daemon_version[] = OSPF6_DAEMON_VERSION;


#define TIMER_SEC_MICRO 1000000

void
ospf6_timeval_sub (const struct timeval *t1, const struct timeval *t2,
                   struct timeval *result)
{
  long usec, movedown = 0;

  if (t1->tv_sec < t2->tv_sec ||
      (t1->tv_sec == t2->tv_sec && t1->tv_usec < t2->tv_usec))
    {
      result->tv_sec = 0;
      result->tv_usec = 0;
      return;
    }

  if (t1->tv_usec < t2->tv_usec)
    {
      usec = t1->tv_usec + TIMER_SEC_MICRO;
      movedown++;
    }
  else
    usec = t1->tv_usec;
  result->tv_usec = usec - t2->tv_usec;

  result->tv_sec = t1->tv_sec - t2->tv_sec - movedown;
}

void
ospf6_timeval_div (const struct timeval *t1, u_int by,
                   struct timeval *result)
{
  long movedown;

  if (by == 0)
    {
      result->tv_sec = 0;
      result->tv_usec = 0;
      return;
    }

  movedown = t1->tv_sec % by;
  result->tv_sec = t1->tv_sec / by;
  result->tv_usec = (t1->tv_usec + movedown * TIMER_SEC_MICRO) / by;
}

void
ospf6_timeval_decode (const struct timeval *t, long *dayp, long *hourp,
                      long *minp, long *secp, long *msecp, long *usecp)
{
  long day, hour, min, sec, msec, usec, left;

  left = t->tv_sec;
  day = left / 86400; left -= day * 86400;
  hour = left / 3600; left -= hour * 3600;
  min = left / 60; left -= min * 60;
  sec = left;
  left = t->tv_usec;
  msec = left / 1000; left -= msec * 1000;
  usec = left;

  if (dayp) *dayp = day;
  if (hourp) *hourp = hour;
  if (minp) *minp = min;
  if (secp) *secp = sec;
  if (msecp) *msecp = msec;
  if (usecp) *usecp = usec;
}

void
ospf6_timeval_string (struct timeval *tv, char *buf, int size)
{
  char days[16], hours[16], mins[16], secs[16], msecs[16], usecs[16];
  long day, hour, min, sec, msec, usec;

  ospf6_timeval_decode (tv, &day, &hour, &min, &sec, &msec, &usec);
  snprintf (days, sizeof (days), "%ld days ", day);
  snprintf (hours, sizeof (hours), "%ld hours ", hour);
  snprintf (mins, sizeof (mins), "%ld mins ", min);
  snprintf (secs, sizeof (secs), "%ld secs ", sec);
  snprintf (msecs, sizeof (msecs), "%ld msecs ", msec);
  snprintf (usecs, sizeof (usecs), "%ld usecs ", usec);

  snprintf (buf, size, "%s%s%s%s%s%s",
            (day ? days : ""), (hour ? hours : ""),
            (min ? mins : ""), (sec ? secs : ""),
            (msec ? msecs : ""), (usec ? usecs : ""));
}

void
ospf6_timeval_string_summary (struct timeval *tv, char *buf, int size)
{
  char days[16], hours[16], mins[16], secs[16], msecs[16], usecs[16];
  long day, hour, min, sec, msec, usec;

  ospf6_timeval_decode (tv, &day, &hour, &min, &sec, &msec, &usec);
  snprintf (days, sizeof (days), "%02ldd", day);
  snprintf (hours, sizeof (hours), "%ldh", hour);
  snprintf (mins, sizeof (mins), "%ldm", min);
  snprintf (secs, sizeof (secs), "%lds", sec);
  snprintf (msecs, sizeof (msecs), "%ldms", msec);
  snprintf (usecs, sizeof (usecs), "%ldus", usec);

  snprintf (buf, size, "%s%02ld:%02ld:%02ld",
            (day ? days : ""), hour, min, sec);
}

/* foreach function */
void
ospf6_count_state (void *arg, int val, void *obj)
{
  int *count = (int *) arg;
  u_char state = val;
  struct ospf6_neighbor *nei = (struct ospf6_neighbor *) obj;

  if (nei->state == state)
    (*count)++;
}

/* VTY commands.  */
DEFUN (reload,
       reload_cmd,
       "reload",
       "Reloads\n")
{
  extern void _reload ();
  _reload ();
  return CMD_SUCCESS;
}

DEFUN (garbage_collection,
       garbage_collection_cmd,
       "ipv6 ospf6 garbage collect",
       IPV6_STR
       OSPF6_STR
       "garbage collection by hand\n"
       "Remove Maxages if possible and recalculate routes\n")
{
  ospf6_maxage_remover ();
#if 0
  ospf6_route_calculation_schedule ();
#endif
  return CMD_SUCCESS;
}

/* Show version. */
DEFUN (show_version_ospf6,
       show_version_ospf6_cmd,
       "show version ospf6",
       SHOW_STR
       "Displays ospf6d version\n")
{
  vty_out (vty, "Zebra OSPF6d Version: %s%s",
           ospf6_daemon_version, VTY_NEWLINE);

  return CMD_SUCCESS;
}

/* start ospf6 */
DEFUN (router_ospf6,
       router_ospf6_cmd,
       "router ospf6",
       OSPF6_ROUTER_STR
       OSPF6_STR)
{
  if (ospf6 == NULL)
    ospf6_start ();

  /* set current ospf point. */
  vty->node = OSPF6_NODE;
  vty->index = ospf6;

  return CMD_SUCCESS;
}

/* stop ospf6 */
DEFUN (no_router_ospf6,
       no_router_ospf6_cmd,
       "no router ospf6",
       NO_STR
       OSPF6_ROUTER_STR)
{
  if (!ospf6)
    vty_out (vty, "OSPFv3 is not running%s", VTY_NEWLINE);
  else
    ospf6_stop ();

  /* return to config node . */
  vty->node = CONFIG_NODE;
  vty->index = NULL;

  return CMD_SUCCESS;
}

/* show top level structures */
DEFUN (show_ipv6_ospf6,
       show_ipv6_ospf6_cmd,
       "show ipv6 ospf6",
       SHOW_STR
       IP6_STR
       OSPF6_STR)
{
  OSPF6_CMD_CHECK_RUNNING ();

  ospf6_show (vty);
  return CMD_SUCCESS;
}

DEFUN (show_ipv6_ospf6_nexthoplist,
       show_ipv6_ospf6_nexthoplist_cmd,
       "show ipv6 ospf6 nexthop-list",
       SHOW_STR
       IP6_STR
       OSPF6_STR
       "List of nexthop\n")
{
#if 0
  listnode i;
  struct ospf6_nexthop *nh;
  char buf[128];
  for (i = listhead (nexthoplist); i; nextnode (i))
    {
      nh = (struct ospf6_nexthop *) getdata (i);
      nexthop_str (nh, buf, sizeof (buf));
      vty_out (vty, "%s%s", buf,
	       VTY_NEWLINE);
    }
#endif
  return CMD_SUCCESS;
}

DEFUN (show_ipv6_ospf6_statistics,
       show_ipv6_ospf6_statistics_cmd,
       "show ipv6 ospf6 statistics",
       SHOW_STR
       IP6_STR
       OSPF6_STR
       "Statistics\n")
{
  OSPF6_CMD_CHECK_RUNNING ();

  ospf6_statistics_show (vty, ospf6);
  return CMD_SUCCESS;
}

/* change Router_ID commands. */
DEFUN (router_id,
       router_id_cmd,
       "router-id ROUTER_ID",
       "Configure ospf Router-ID.\n"
       V4NOTATION_STR)
{
  int ret;
  u_int32_t router_id;

  ret = inet_pton (AF_INET, argv[0], &router_id);
  if (!ret)
    {
      vty_out (vty, "malformed ospf router identifier%s", VTY_NEWLINE);
      vty_out (vty, "%s", VTY_NEWLINE);
      return CMD_WARNING;
    }

  if (IS_OSPF6_DUMP_CONFIG)
    zlog_info ("CONFIG: router-id %s", argv[0]);
  ospf6->router_id = router_id;

  return CMD_SUCCESS;
}

int
ospf6_interface_bind_area (struct vty *vty,
                           char *if_name, char *area_name,
                           char *plist_name, int passive)
{
  struct interface *ifp;
  struct ospf6_interface *o6i;
  struct ospf6_area *o6a;
  u_int32_t area_id;

  /* find/create ospf6 interface */
  ifp = if_get_by_name (if_name);
  o6i = (struct ospf6_interface *) ifp->info;
  if (! o6i)
    o6i = ospf6_interface_create (ifp);

  /* parse Area-ID */
  if (inet_pton (AF_INET, area_name, &area_id) != 1)
    {
      vty_out (vty, "Invalid Area-ID: %s%s", area_name, VTY_NEWLINE);
      return CMD_ERR_AMBIGUOUS;
    }

  /* find/create ospf6 area */
  o6a = ospf6_area_lookup (area_id, ospf6);
  if (!o6a)
    {
      o6a = ospf6_area_create (area_id);
      o6a->ospf6 = ospf6;
      listnode_add (ospf6->area_list, o6a);
    }

  if (o6i->area)
    {
      if (o6i->area != o6a)
        {
          vty_out (vty, "Aready attached to area %s%s",
                   o6i->area->str, VTY_NEWLINE);
          return CMD_ERR_NOTHING_TODO;
        }
    }
  else
    {
      listnode_add (o6a->if_list, o6i);
      o6i->area = o6a;
    }

  /* prefix-list name */
  if (plist_name)
    {
      if (o6i->plist_name)
        XFREE (MTYPE_PREFIX_LIST_STR, o6i->plist_name);
      o6i->plist_name = XSTRDUP (MTYPE_PREFIX_LIST_STR, plist_name);
    }
  else
    {
      if (o6i->plist_name)
        XFREE (MTYPE_PREFIX_LIST_STR, o6i->plist_name);
      o6i->plist_name = NULL;
    }

  if (passive)
    {
      listnode node;
      struct ospf6_neighbor *o6n;

      SET_FLAG (o6i->flag, OSPF6_INTERFACE_FLAG_PASSIVE);
      if (o6i->thread_send_hello)
        {
          thread_cancel (o6i->thread_send_hello);
          o6i->thread_send_hello = (struct thread *) NULL;
        }

      for (node = listhead (o6i->neighbor_list); node; nextnode (node))
        {
          o6n = getdata (node);
          if (o6n->inactivity_timer)
            thread_cancel (o6n->inactivity_timer);
          thread_execute (master, inactivity_timer, o6n, 0);
        }
    }
  else
    {
      UNSET_FLAG (o6i->flag, OSPF6_INTERFACE_FLAG_PASSIVE);
      if (o6i->thread_send_hello == NULL)
        thread_add_event (master, ospf6_send_hello, o6i, 0);
    }

  /* enable I/F if it's not enabled still */
  if (! ospf6_interface_is_enabled (o6i->interface->ifindex))
    thread_add_event (master, interface_up, o6i, 0);
  else
    CALL_FOREACH_LSA_HOOK (hook_interface, hook_change, o6i);

  CALL_CHANGE_HOOK (&interface_hook, o6i);
  return CMD_SUCCESS;
}

DEFUN (interface_area_plist,
       interface_area_plist_cmd,
       "interface IFNAME area A.B.C.D prefix-list WORD",
       "Enable routing on an IPv6 interface\n"
       IFNAME_STR
       "Set the OSPF6 area ID\n"
       "OSPF6 area ID in IPv4 address notation\n"
       OSPF6_PREFIX_LIST_STR
       "IPv6 prefix-list name\n"
      )
{
  if (IS_OSPF6_DUMP_CONFIG)
    zlog_info ("CONFIG: interface %s area %s prefix-list %s",
               argv[0], argv[1], argv[2]);

  return ospf6_interface_bind_area (vty, argv[0], argv[1], argv[2], 0);
}

DEFUN (interface_area_plist_passive,
       interface_area_plist_passive_cmd,
       "interface IFNAME area A.B.C.D prefix-list WORD passive",
       "Enable routing on an IPv6 interface\n"
       IFNAME_STR
       "Set the OSPF6 area ID\n"
       "OSPF6 area ID in IPv4 address notation\n"
       OSPF6_PREFIX_LIST_STR
       "IPv6 prefix-list name\n"
       "IPv6 prefix-list name\n"
       OSPF6_PASSIVE_STR
      )
{
  if (IS_OSPF6_DUMP_CONFIG)
    zlog_info ("CONFIG: interface %s area %s prefix-list %s passive",
               argv[0], argv[1], argv[2]);

  return ospf6_interface_bind_area (vty, argv[0], argv[1], argv[2], 1);
}

DEFUN (interface_area,
       interface_area_cmd,
       "interface IFNAME area A.B.C.D",
       "Enable routing on an IPv6 interface\n"
       IFNAME_STR
       "Set the OSPF6 area ID\n"
       "OSPF6 area ID in IPv4 address notation\n"
      )
{
  struct interface *ifp;
  struct ospf6_interface *o6i;
  int passive;
  char *plist_name;

  if (IS_OSPF6_DUMP_CONFIG)
    zlog_info ("CONFIG: interface %s area %s",
               argv[0], argv[1]);

  ifp = if_get_by_name (argv[0]);
  o6i = (struct ospf6_interface *) ifp->info;
  if (o6i)
    {
      passive = CHECK_FLAG (o6i->flag, OSPF6_INTERFACE_FLAG_PASSIVE);
      plist_name = o6i->plist_name;
    }
  else
    {
      passive = 0;
      plist_name = NULL;
    }

  return ospf6_interface_bind_area (vty, argv[0], argv[1],
                                    plist_name, passive);
}

DEFUN (interface_area_passive,
       interface_area_passive_cmd,
       "interface IFNAME area A.B.C.D passive",
       "Enable routing on an IPv6 interface\n"
       IFNAME_STR
       "Set the OSPF6 area ID\n"
       "OSPF6 area ID in IPv4 address notation\n"
       OSPF6_PASSIVE_STR
      )
{
  if (IS_OSPF6_DUMP_CONFIG)
    zlog_info ("CONFIG: interface %s area %s passive",
               argv[0], argv[1]);

  return ospf6_interface_bind_area (vty, argv[0], argv[1], NULL, 1);
}

DEFUN (no_interface_area,
       no_interface_area_cmd,
       "no interface IFNAME area A.B.C.D",
       NO_STR
       "Disable routing on an IPv6 interface\n"
       IFNAME_STR)
{
  struct interface *ifp;
  struct ospf6_interface *o6i;
  struct ospf6 *o6;
  u_int32_t area_id;

  o6 = (struct ospf6 *) vty->index;

  ifp = if_lookup_by_name (argv[0]);
  if (!ifp)
    return CMD_ERR_NO_MATCH;

  o6i = (struct ospf6_interface *) ifp->info;
  if (!o6i)
    return CMD_SUCCESS;

  /* parse Area-ID */
  if (inet_pton (AF_INET, argv[1], &area_id) != 1)
    {
      vty_out (vty, "Invalid Area-ID: %s%s", argv[1], VTY_NEWLINE);
      return CMD_ERR_AMBIGUOUS;
    }

  if (o6i->area->area_id != area_id)
    {
      vty_out (vty, "Wrong Area-ID: %s aready attached to area %s%s",
               o6i->interface->name, o6i->area->str, VTY_NEWLINE);
      return CMD_ERR_NOTHING_TODO;
    }

  if (o6i->area)
    thread_execute (master, interface_down, o6i, 0);

  listnode_delete (o6i->area->if_list, o6i);
  o6i->area = (struct ospf6_area *) NULL;

  return CMD_SUCCESS;
}

DEFUN (area_range,
       area_range_cmd,
       "area A.B.C.D range X:X::X:X/M",
       "OSPFv3 area parameters\n"
       "OSPFv3 area ID in IPv4 address format\n"
       "Summarize routes matching address/mask (border routers only)\n"
       "IPv6 address range\n")
{
  struct ospf6 *o6;
  struct ospf6_area *o6a;
  u_int32_t area_id;
  int ret;

  o6 = (struct ospf6 *) vty->index;
  inet_pton (AF_INET, argv[0], &area_id);
  o6a = ospf6_area_lookup (area_id, o6);
  if (! o6a)
    {
      vty_out (vty, "No such area%s", VTY_NEWLINE);
      return CMD_ERR_NO_MATCH;
    }

  ret = str2prefix_ipv6 (argv[1], &o6a->area_range);
  if (ret <= 0)
    {
      vty_out (vty, "Malformed IPv6 address%s", VTY_NEWLINE);
      return CMD_WARNING;
    }

  return CMD_SUCCESS;
}

DEFUN (passive_interface,
       passive_interface_cmd,
       "passive-interface IFNAME",
       OSPF6_PASSIVE_STR
       IFNAME_STR)
{
  struct interface *ifp;
  struct ospf6_interface *o6i;

  ifp = if_get_by_name (argv[0]);
  if (ifp->info)
    o6i = (struct ospf6_interface *) ifp->info;
  else
    o6i = ospf6_interface_create (ifp);

  SET_FLAG (o6i->flag, OSPF6_INTERFACE_FLAG_PASSIVE);

  if (o6i->thread_send_hello)
    {
      thread_cancel (o6i->thread_send_hello);
      o6i->thread_send_hello = (struct thread *) NULL;
    }

  return CMD_SUCCESS;
}

DEFUN (no_passive_interface,
       no_passive_interface_cmd,
       "no passive-interface IFNAME",
       NO_STR
       OSPF6_PASSIVE_STR
       IFNAME_STR)
{
  struct interface *ifp;
  struct ospf6_interface *o6i;

  ifp = if_lookup_by_name (argv[0]);
  if (! ifp)
    return CMD_ERR_NO_MATCH;

  o6i = (struct ospf6_interface *) ifp->info;
  UNSET_FLAG (o6i->flag, OSPF6_INTERFACE_FLAG_PASSIVE);
  if (o6i->thread_send_hello == NULL)
    thread_add_event (master, ospf6_send_hello, o6i, 0);

  return CMD_SUCCESS;
}

#ifdef HAVE_SETPROCTITLE
extern int _argc;
extern char **_argv;

DEFUN (set_proctitle,
       set_proctitle_cmd,
       "set proctitle (version|normal|none)",
       "Set command\n"
       "Process title\n"
       "Version information\n"
       "Normal command-line options\n"
       "Just program name\n")
{
  int i;
  char buf[64], tmp[64];

  if (strncmp (argv[0], "v", 1) == 0)
    {
      proctitle_mode = 1;
      setproctitle ("%s Zebra: %s", OSPF6_DAEMON_VERSION, ZEBRA_VERSION);
    }
  else if (strncmp (argv[0], "nor", 3) == 0)
    {
      proctitle_mode = 0;
      memset (tmp, 0, sizeof (tmp));
      memset (buf, 0, sizeof (buf));
      for (i = 0; i < _argc; i++)
        {
          snprintf (buf, sizeof (buf), "%s%s ", tmp, _argv[i]);
          memcpy (&tmp, &buf, sizeof (tmp));
        }
      setproctitle (buf);
    }
  else if (strncmp (argv[0], "non", 3) == 0)
    {
      proctitle_mode = -1;
      setproctitle (NULL);
    }
  else
    return CMD_ERR_NO_MATCH;

  return CMD_SUCCESS;
}
#endif /* HAVE_SETPROCTITLE */

/* OSPF configuration write function. */
int
ospf6_config_write (struct vty *vty)
{
  listnode j, k;
  char buf[64];
  struct ospf6_area *area;
  struct ospf6_interface *o6i;

  if (proctitle_mode == 1)
    vty_out (vty, "set proctitle version%s", VTY_NEWLINE);
  else if (proctitle_mode == -1)
    vty_out (vty, "set proctitle none%s", VTY_NEWLINE);

  vty_out (vty, "!%s", VTY_NEWLINE);

  if (! ospf6)
    return 0;

  /* OSPFv6 configuration. */
  if (!ospf6)
    return CMD_SUCCESS;

  inet_ntop (AF_INET, &ospf6->router_id, buf, sizeof (buf));
  vty_out (vty, "router ospf6%s", VTY_NEWLINE);
  vty_out (vty, " router-id %s%s", buf, VTY_NEWLINE);

  ospf6_redistribute_config_write (vty);
  ospf6_damp_config_write (vty);

  for (j = listhead (ospf6->area_list); j; nextnode (j))
    {
      area = (struct ospf6_area *)getdata (j);
      for (k = listhead (area->if_list); k; nextnode (k))
        {
          o6i = (struct ospf6_interface *) getdata (k);
          vty_out (vty, " interface %s area %s%s",
                   o6i->interface->name, area->str, VTY_NEWLINE);
        }
    }
  vty_out (vty, "!%s", VTY_NEWLINE);
  return 0;
}

/* OSPF6 node structure. */
struct cmd_node ospf6_node =
{
  OSPF6_NODE,
  "%s(config-ospf6)# ",
};

/* Install ospf related commands. */
void
ospf6_init ()
{
  /* Install ospf6 top node. */
  install_node (&ospf6_node, ospf6_config_write);

  install_element (VIEW_NODE, &show_ipv6_ospf6_cmd);
  install_element (VIEW_NODE, &show_version_ospf6_cmd);
  install_element (ENABLE_NODE, &show_ipv6_ospf6_cmd);
  install_element (ENABLE_NODE, &show_version_ospf6_cmd);
  install_element (ENABLE_NODE, &reload_cmd);
  install_element (CONFIG_NODE, &router_ospf6_cmd);
  install_element (CONFIG_NODE, &interface_cmd);
#ifdef OSPF6_STATISTICS
  install_element (VIEW_NODE, &show_ipv6_ospf6_statistics_cmd);
  install_element (ENABLE_NODE, &show_ipv6_ospf6_statistics_cmd);
#endif /* OSPF6_STATISTICS */
#ifdef OSPF6_GARBAGE_COLLECT
  install_element (ENABLE_NODE, &garbage_collection_cmd);
#endif /* OSPF6_GARBAGE_COLLECT */
#ifdef HAVE_SETPROCTITLE
  install_element (CONFIG_NODE, &set_proctitle_cmd);
#endif /* HAVE_SETPROCTITLE */

  install_default (OSPF6_NODE);
  install_element (OSPF6_NODE, &router_id_cmd);
  install_element (OSPF6_NODE, &interface_area_cmd);
  install_element (OSPF6_NODE, &interface_area_passive_cmd);
  install_element (OSPF6_NODE, &interface_area_plist_cmd);
  install_element (OSPF6_NODE, &interface_area_plist_passive_cmd);
  install_element (OSPF6_NODE, &no_interface_area_cmd);
  install_element (OSPF6_NODE, &passive_interface_cmd);
  install_element (OSPF6_NODE, &no_passive_interface_cmd);
  install_element (OSPF6_NODE, &area_range_cmd);

  /* Make empty list of top list. */
  if_init ();

  /* Install access list */
  access_list_init ();

  /* Install prefix list */
  prefix_list_init ();

  ospf6_dump_init ();

#ifdef HAVE_OSPF6_DAMP
  ospf6_damp_init ();
#endif /*HAVE_OSPF6_DAMP*/

  ospf6_hook_init ();
  ospf6_lsa_init ();

  ospf6_top_init ();
  ospf6_area_init ();
  ospf6_interface_init ();
  ospf6_neighbor_init ();
  ospf6_zebra_init ();

  ospf6_routemap_init ();
  ospf6_lsdb_init ();

  ospf6_spf_init ();

  ospf6_intra_init ();
  ospf6_abr_init ();
  ospf6_asbr_init ();
}

void
ospf6_terminate ()
{
  /* stop ospf6 */
  ospf6_stop ();

  /* log */
  zlog (NULL, LOG_INFO, "OSPF6d terminated");
}

void
ospf6_maxage_remover ()
{
#if 0
  if (IS_OSPF6_DUMP_LSDB)
    zlog_info ("MaxAge Remover");
#endif

  ospf6_top_schedule_maxage_remover (NULL, 0, ospf6);
  (*ospf6->foreach_area) (ospf6, NULL, 0,
                          ospf6_area_schedule_maxage_remover);
  (*ospf6->foreach_if) (ospf6, NULL, 0,
                        ospf6_interface_schedule_maxage_remover);
}



void *
ospf6_lsa_get_scope (u_int16_t type, struct ospf6_interface *o6i)
{
  if (OSPF6_LSA_IS_SCOPE_LINKLOCAL (ntohs (type)))
    return o6i;
  else if (OSPF6_LSA_IS_SCOPE_AREA (ntohs (type)))
    return o6i->area;
  else if (OSPF6_LSA_IS_SCOPE_AS (ntohs (type)))
    return o6i->area->ospf6;
  else
    return NULL;
}

