| /* |
| * 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 (ospf6_router_id, |
| ospf6_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 (ospf6_interface_area_plist, |
| ospf6_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 (ospf6_interface_area_plist_passive, |
| ospf6_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 (ospf6_interface_area, |
| ospf6_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 (ospf6_interface_area_passive, |
| ospf6_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_ospf6_interface_area, |
| no_ospf6_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 (ospf6_area_range, |
| ospf6_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 (ospf6_passive_interface, |
| ospf6_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_ospf6_passive_interface, |
| no_ospf6_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, QUAGGA_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)# ", |
| vtysh: 1 |
| }; |
| |
| /* 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); |
| install_element (CONFIG_NODE, &no_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, &ospf6_router_id_cmd); |
| install_element (OSPF6_NODE, &ospf6_interface_area_cmd); |
| install_element (OSPF6_NODE, &ospf6_interface_area_passive_cmd); |
| install_element (OSPF6_NODE, &ospf6_interface_area_plist_cmd); |
| install_element (OSPF6_NODE, &ospf6_interface_area_plist_passive_cmd); |
| install_element (OSPF6_NODE, &no_ospf6_interface_area_cmd); |
| install_element (OSPF6_NODE, &ospf6_passive_interface_cmd); |
| install_element (OSPF6_NODE, &no_ospf6_passive_interface_cmd); |
| install_element (OSPF6_NODE, &ospf6_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; |
| } |
| |