Initial revision
diff --git a/ospf6d/ospf6d.c b/ospf6d/ospf6d.c
new file mode 100644
index 0000000..dbe7a88
--- /dev/null
+++ b/ospf6d/ospf6d.c
@@ -0,0 +1,826 @@
+/*
+ * 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;
+}
+