1/* 2 * Copyright (C) 1999 Yasuhiro Ohara 3 * 4 * This file is part of GNU Zebra. 5 * 6 * GNU Zebra is free software; you can redistribute it and/or modify it 7 * under the terms of the GNU General Public License as published by the 8 * Free Software Foundation; either version 2, or (at your option) any 9 * later version. 10 * 11 * GNU Zebra is distributed in the hope that it will be useful, but 12 * WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with GNU Zebra; see the file COPYING. If not, write to the 18 * Free Software Foundation, Inc., 59 Temple Place - Suite 330, 19 * Boston, MA 02111-1307, USA. 20 */ 21 22#include "ospf6d.h" 23 24/* global ospf6d variable */ 25int ospf6_sock; 26list iflist; 27list nexthoplist = NULL; 28struct sockaddr_in6 allspfrouters6; 29struct sockaddr_in6 alldrouters6; 30char *recent_reason; /* set by ospf6_lsa_check_recent () */ 31int proctitle_mode = 0; 32 33char ospf6_daemon_version[] = OSPF6_DAEMON_VERSION; 34 35 36#define TIMER_SEC_MICRO 1000000 37 38void 39ospf6_timeval_sub (const struct timeval *t1, const struct timeval *t2, 40 struct timeval *result) 41{ 42 long usec, movedown = 0; 43 44 if (t1->tv_sec < t2->tv_sec || 45 (t1->tv_sec == t2->tv_sec && t1->tv_usec < t2->tv_usec)) 46 { 47 result->tv_sec = 0; 48 result->tv_usec = 0; 49 return; 50 } 51 52 if (t1->tv_usec < t2->tv_usec) 53 { 54 usec = t1->tv_usec + TIMER_SEC_MICRO; 55 movedown++; 56 } 57 else 58 usec = t1->tv_usec; 59 result->tv_usec = usec - t2->tv_usec; 60 61 result->tv_sec = t1->tv_sec - t2->tv_sec - movedown; 62} 63 64void 65ospf6_timeval_div (const struct timeval *t1, u_int by, 66 struct timeval *result) 67{ 68 long movedown; 69 70 if (by == 0) 71 { 72 result->tv_sec = 0; 73 result->tv_usec = 0; 74 return; 75 } 76 77 movedown = t1->tv_sec % by; 78 result->tv_sec = t1->tv_sec / by; 79 result->tv_usec = (t1->tv_usec + movedown * TIMER_SEC_MICRO) / by; 80} 81 82void 83ospf6_timeval_decode (const struct timeval *t, long *dayp, long *hourp, 84 long *minp, long *secp, long *msecp, long *usecp) 85{ 86 long day, hour, min, sec, msec, usec, left; 87 88 left = t->tv_sec; 89 day = left / 86400; left -= day * 86400; 90 hour = left / 3600; left -= hour * 3600; 91 min = left / 60; left -= min * 60; 92 sec = left; 93 left = t->tv_usec; 94 msec = left / 1000; left -= msec * 1000; 95 usec = left; 96 97 if (dayp) *dayp = day; 98 if (hourp) *hourp = hour; 99 if (minp) *minp = min; 100 if (secp) *secp = sec; 101 if (msecp) *msecp = msec; 102 if (usecp) *usecp = usec; 103} 104 105void 106ospf6_timeval_string (struct timeval *tv, char *buf, int size) 107{ 108 char days[16], hours[16], mins[16], secs[16], msecs[16], usecs[16]; 109 long day, hour, min, sec, msec, usec; 110 111 ospf6_timeval_decode (tv, &day, &hour, &min, &sec, &msec, &usec); 112 snprintf (days, sizeof (days), "%ld days ", day); 113 snprintf (hours, sizeof (hours), "%ld hours ", hour); 114 snprintf (mins, sizeof (mins), "%ld mins ", min); 115 snprintf (secs, sizeof (secs), "%ld secs ", sec); 116 snprintf (msecs, sizeof (msecs), "%ld msecs ", msec); 117 snprintf (usecs, sizeof (usecs), "%ld usecs ", usec); 118 119 snprintf (buf, size, "%s%s%s%s%s%s", 120 (day ? days : ""), (hour ? hours : ""), 121 (min ? mins : ""), (sec ? secs : ""), 122 (msec ? msecs : ""), (usec ? usecs : "")); 123} 124 125void 126ospf6_timeval_string_summary (struct timeval *tv, char *buf, int size) 127{ 128 char days[16], hours[16], mins[16], secs[16], msecs[16], usecs[16]; 129 long day, hour, min, sec, msec, usec; 130 131 ospf6_timeval_decode (tv, &day, &hour, &min, &sec, &msec, &usec); 132 snprintf (days, sizeof (days), "%02ldd", day); 133 snprintf (hours, sizeof (hours), "%ldh", hour); 134 snprintf (mins, sizeof (mins), "%ldm", min); 135 snprintf (secs, sizeof (secs), "%lds", sec); 136 snprintf (msecs, sizeof (msecs), "%ldms", msec); 137 snprintf (usecs, sizeof (usecs), "%ldus", usec); 138 139 snprintf (buf, size, "%s%02ld:%02ld:%02ld", 140 (day ? days : ""), hour, min, sec); 141} 142 143/* foreach function */ 144void 145ospf6_count_state (void *arg, int val, void *obj) 146{ 147 int *count = (int *) arg; 148 u_char state = val; 149 struct ospf6_neighbor *nei = (struct ospf6_neighbor *) obj; 150 151 if (nei->state == state) 152 (*count)++; 153} 154 155/* VTY commands. */ 156DEFUN (reload, 157 reload_cmd, 158 "reload", 159 "Reloads\n") 160{ 161 extern void _reload (); 162 _reload (); 163 return CMD_SUCCESS; 164} 165 166DEFUN (garbage_collection, 167 garbage_collection_cmd, 168 "ipv6 ospf6 garbage collect", 169 IPV6_STR 170 OSPF6_STR 171 "garbage collection by hand\n" 172 "Remove Maxages if possible and recalculate routes\n") 173{ 174 ospf6_maxage_remover (); 175#if 0 176 ospf6_route_calculation_schedule (); 177#endif 178 return CMD_SUCCESS; 179} 180 181/* Show version. */ 182DEFUN (show_version_ospf6, 183 show_version_ospf6_cmd, 184 "show version ospf6", 185 SHOW_STR 186 "Displays ospf6d version\n") 187{ 188 vty_out (vty, "Zebra OSPF6d Version: %s%s", 189 ospf6_daemon_version, VTY_NEWLINE); 190 191 return CMD_SUCCESS; 192} 193 194/* start ospf6 */ 195DEFUN (router_ospf6, 196 router_ospf6_cmd, 197 "router ospf6", 198 OSPF6_ROUTER_STR 199 OSPF6_STR) 200{ 201 if (ospf6 == NULL) 202 ospf6_start (); 203 204 /* set current ospf point. */ 205 vty->node = OSPF6_NODE; 206 vty->index = ospf6; 207 208 return CMD_SUCCESS; 209} 210 211/* stop ospf6 */ 212DEFUN (no_router_ospf6, 213 no_router_ospf6_cmd, 214 "no router ospf6", 215 NO_STR 216 OSPF6_ROUTER_STR) 217{ 218 if (!ospf6) 219 vty_out (vty, "OSPFv3 is not running%s", VTY_NEWLINE); 220 else 221 ospf6_stop (); 222 223 /* return to config node . */ 224 vty->node = CONFIG_NODE; 225 vty->index = NULL; 226 227 return CMD_SUCCESS; 228} 229 230/* show top level structures */ 231DEFUN (show_ipv6_ospf6, 232 show_ipv6_ospf6_cmd, 233 "show ipv6 ospf6", 234 SHOW_STR 235 IP6_STR 236 OSPF6_STR) 237{ 238 OSPF6_CMD_CHECK_RUNNING (); 239 240 ospf6_show (vty); 241 return CMD_SUCCESS; 242} 243 244DEFUN (show_ipv6_ospf6_nexthoplist, 245 show_ipv6_ospf6_nexthoplist_cmd, 246 "show ipv6 ospf6 nexthop-list", 247 SHOW_STR 248 IP6_STR 249 OSPF6_STR 250 "List of nexthop\n") 251{ 252#if 0 253 listnode i; 254 struct ospf6_nexthop *nh; 255 char buf[128]; 256 for (i = listhead (nexthoplist); i; nextnode (i)) 257 { 258 nh = (struct ospf6_nexthop *) getdata (i); 259 nexthop_str (nh, buf, sizeof (buf)); 260 vty_out (vty, "%s%s", buf, 261 VTY_NEWLINE); 262 } 263#endif 264 return CMD_SUCCESS; 265} 266 267DEFUN (show_ipv6_ospf6_statistics, 268 show_ipv6_ospf6_statistics_cmd, 269 "show ipv6 ospf6 statistics", 270 SHOW_STR 271 IP6_STR 272 OSPF6_STR 273 "Statistics\n") 274{ 275 OSPF6_CMD_CHECK_RUNNING (); 276 277 ospf6_statistics_show (vty, ospf6); 278 return CMD_SUCCESS; 279} 280 281/* change Router_ID commands. */ 282DEFUN (router_id, 283 router_id_cmd, 284 "router-id ROUTER_ID", 285 "Configure ospf Router-ID.\n" 286 V4NOTATION_STR) 287{ 288 int ret; 289 u_int32_t router_id; 290 291 ret = inet_pton (AF_INET, argv[0], &router_id); 292 if (!ret) 293 { 294 vty_out (vty, "malformed ospf router identifier%s", VTY_NEWLINE); 295 vty_out (vty, "%s", VTY_NEWLINE); 296 return CMD_WARNING; 297 } 298 299 if (IS_OSPF6_DUMP_CONFIG) 300 zlog_info ("CONFIG: router-id %s", argv[0]); 301 ospf6->router_id = router_id; 302 303 return CMD_SUCCESS; 304} 305 306int 307ospf6_interface_bind_area (struct vty *vty, 308 char *if_name, char *area_name, 309 char *plist_name, int passive) 310{ 311 struct interface *ifp; 312 struct ospf6_interface *o6i; 313 struct ospf6_area *o6a; 314 u_int32_t area_id; 315 316 /* find/create ospf6 interface */ 317 ifp = if_get_by_name (if_name); 318 o6i = (struct ospf6_interface *) ifp->info; 319 if (! o6i) 320 o6i = ospf6_interface_create (ifp); 321 322 /* parse Area-ID */ 323 if (inet_pton (AF_INET, area_name, &area_id) != 1) 324 { 325 vty_out (vty, "Invalid Area-ID: %s%s", area_name, VTY_NEWLINE); 326 return CMD_ERR_AMBIGUOUS; 327 } 328 329 /* find/create ospf6 area */ 330 o6a = ospf6_area_lookup (area_id, ospf6); 331 if (!o6a) 332 { 333 o6a = ospf6_area_create (area_id); 334 o6a->ospf6 = ospf6; 335 listnode_add (ospf6->area_list, o6a); 336 } 337 338 if (o6i->area) 339 { 340 if (o6i->area != o6a) 341 { 342 vty_out (vty, "Aready attached to area %s%s", 343 o6i->area->str, VTY_NEWLINE); 344 return CMD_ERR_NOTHING_TODO; 345 } 346 } 347 else 348 { 349 listnode_add (o6a->if_list, o6i); 350 o6i->area = o6a; 351 } 352 353 /* prefix-list name */ 354 if (plist_name) 355 { 356 if (o6i->plist_name) 357 XFREE (MTYPE_PREFIX_LIST_STR, o6i->plist_name); 358 o6i->plist_name = XSTRDUP (MTYPE_PREFIX_LIST_STR, plist_name); 359 } 360 else 361 { 362 if (o6i->plist_name) 363 XFREE (MTYPE_PREFIX_LIST_STR, o6i->plist_name); 364 o6i->plist_name = NULL; 365 } 366 367 if (passive) 368 { 369 listnode node; 370 struct ospf6_neighbor *o6n; 371 372 SET_FLAG (o6i->flag, OSPF6_INTERFACE_FLAG_PASSIVE); 373 if (o6i->thread_send_hello) 374 { 375 thread_cancel (o6i->thread_send_hello); 376 o6i->thread_send_hello = (struct thread *) NULL; 377 } 378 379 for (node = listhead (o6i->neighbor_list); node; nextnode (node)) 380 { 381 o6n = getdata (node); 382 if (o6n->inactivity_timer) 383 thread_cancel (o6n->inactivity_timer); 384 thread_execute (master, inactivity_timer, o6n, 0); 385 } 386 } 387 else 388 { 389 UNSET_FLAG (o6i->flag, OSPF6_INTERFACE_FLAG_PASSIVE); 390 if (o6i->thread_send_hello == NULL) 391 thread_add_event (master, ospf6_send_hello, o6i, 0); 392 } 393 394 /* enable I/F if it's not enabled still */ 395 if (! ospf6_interface_is_enabled (o6i->interface->ifindex)) 396 thread_add_event (master, interface_up, o6i, 0); 397 else 398 CALL_FOREACH_LSA_HOOK (hook_interface, hook_change, o6i); 399 400 CALL_CHANGE_HOOK (&interface_hook, o6i); 401 return CMD_SUCCESS; 402} 403 404DEFUN (interface_area_plist, 405 interface_area_plist_cmd, 406 "interface IFNAME area A.B.C.D prefix-list WORD", 407 "Enable routing on an IPv6 interface\n" 408 IFNAME_STR 409 "Set the OSPF6 area ID\n" 410 "OSPF6 area ID in IPv4 address notation\n" 411 OSPF6_PREFIX_LIST_STR 412 "IPv6 prefix-list name\n" 413 ) 414{ 415 if (IS_OSPF6_DUMP_CONFIG) 416 zlog_info ("CONFIG: interface %s area %s prefix-list %s", 417 argv[0], argv[1], argv[2]); 418 419 return ospf6_interface_bind_area (vty, argv[0], argv[1], argv[2], 0); 420} 421 422DEFUN (interface_area_plist_passive, 423 interface_area_plist_passive_cmd, 424 "interface IFNAME area A.B.C.D prefix-list WORD passive", 425 "Enable routing on an IPv6 interface\n" 426 IFNAME_STR 427 "Set the OSPF6 area ID\n" 428 "OSPF6 area ID in IPv4 address notation\n" 429 OSPF6_PREFIX_LIST_STR 430 "IPv6 prefix-list name\n" 431 "IPv6 prefix-list name\n" 432 OSPF6_PASSIVE_STR 433 ) 434{ 435 if (IS_OSPF6_DUMP_CONFIG) 436 zlog_info ("CONFIG: interface %s area %s prefix-list %s passive", 437 argv[0], argv[1], argv[2]); 438 439 return ospf6_interface_bind_area (vty, argv[0], argv[1], argv[2], 1); 440} 441 442DEFUN (interface_area, 443 interface_area_cmd, 444 "interface IFNAME area A.B.C.D", 445 "Enable routing on an IPv6 interface\n" 446 IFNAME_STR 447 "Set the OSPF6 area ID\n" 448 "OSPF6 area ID in IPv4 address notation\n" 449 ) 450{ 451 struct interface *ifp; 452 struct ospf6_interface *o6i; 453 int passive; 454 char *plist_name; 455 456 if (IS_OSPF6_DUMP_CONFIG) 457 zlog_info ("CONFIG: interface %s area %s", 458 argv[0], argv[1]); 459 460 ifp = if_get_by_name (argv[0]); 461 o6i = (struct ospf6_interface *) ifp->info; 462 if (o6i) 463 { 464 passive = CHECK_FLAG (o6i->flag, OSPF6_INTERFACE_FLAG_PASSIVE); 465 plist_name = o6i->plist_name; 466 } 467 else 468 { 469 passive = 0; 470 plist_name = NULL; 471 } 472 473 return ospf6_interface_bind_area (vty, argv[0], argv[1], 474 plist_name, passive); 475} 476 477DEFUN (interface_area_passive, 478 interface_area_passive_cmd, 479 "interface IFNAME area A.B.C.D passive", 480 "Enable routing on an IPv6 interface\n" 481 IFNAME_STR 482 "Set the OSPF6 area ID\n" 483 "OSPF6 area ID in IPv4 address notation\n" 484 OSPF6_PASSIVE_STR 485 ) 486{ 487 if (IS_OSPF6_DUMP_CONFIG) 488 zlog_info ("CONFIG: interface %s area %s passive", 489 argv[0], argv[1]); 490 491 return ospf6_interface_bind_area (vty, argv[0], argv[1], NULL, 1); 492} 493 494DEFUN (no_interface_area, 495 no_interface_area_cmd, 496 "no interface IFNAME area A.B.C.D", 497 NO_STR 498 "Disable routing on an IPv6 interface\n" 499 IFNAME_STR) 500{ 501 struct interface *ifp; 502 struct ospf6_interface *o6i; 503 struct ospf6 *o6; 504 u_int32_t area_id; 505 506 o6 = (struct ospf6 *) vty->index; 507 508 ifp = if_lookup_by_name (argv[0]); 509 if (!ifp) 510 return CMD_ERR_NO_MATCH; 511 512 o6i = (struct ospf6_interface *) ifp->info; 513 if (!o6i) 514 return CMD_SUCCESS; 515 516 /* parse Area-ID */ 517 if (inet_pton (AF_INET, argv[1], &area_id) != 1) 518 { 519 vty_out (vty, "Invalid Area-ID: %s%s", argv[1], VTY_NEWLINE); 520 return CMD_ERR_AMBIGUOUS; 521 } 522 523 if (o6i->area->area_id != area_id) 524 { 525 vty_out (vty, "Wrong Area-ID: %s aready attached to area %s%s", 526 o6i->interface->name, o6i->area->str, VTY_NEWLINE); 527 return CMD_ERR_NOTHING_TODO; 528 } 529 530 if (o6i->area) 531 thread_execute (master, interface_down, o6i, 0); 532 533 listnode_delete (o6i->area->if_list, o6i); 534 o6i->area = (struct ospf6_area *) NULL; 535 536 return CMD_SUCCESS; 537} 538 539DEFUN (area_range, 540 area_range_cmd, 541 "area A.B.C.D range X:X::X:X/M", 542 "OSPFv3 area parameters\n" 543 "OSPFv3 area ID in IPv4 address format\n" 544 "Summarize routes matching address/mask (border routers only)\n" 545 "IPv6 address range\n") 546{ 547 struct ospf6 *o6; 548 struct ospf6_area *o6a; 549 u_int32_t area_id; 550 int ret; 551 552 o6 = (struct ospf6 *) vty->index; 553 inet_pton (AF_INET, argv[0], &area_id); 554 o6a = ospf6_area_lookup (area_id, o6); 555 if (! o6a) 556 { 557 vty_out (vty, "No such area%s", VTY_NEWLINE); 558 return CMD_ERR_NO_MATCH; 559 } 560 561 ret = str2prefix_ipv6 (argv[1], &o6a->area_range); 562 if (ret <= 0) 563 { 564 vty_out (vty, "Malformed IPv6 address%s", VTY_NEWLINE); 565 return CMD_WARNING; 566 } 567 568 return CMD_SUCCESS; 569} 570 571DEFUN (passive_interface, 572 passive_interface_cmd, 573 "passive-interface IFNAME", 574 OSPF6_PASSIVE_STR 575 IFNAME_STR) 576{ 577 struct interface *ifp; 578 struct ospf6_interface *o6i; 579 580 ifp = if_get_by_name (argv[0]); 581 if (ifp->info) 582 o6i = (struct ospf6_interface *) ifp->info; 583 else 584 o6i = ospf6_interface_create (ifp); 585 586 SET_FLAG (o6i->flag, OSPF6_INTERFACE_FLAG_PASSIVE); 587 588 if (o6i->thread_send_hello) 589 { 590 thread_cancel (o6i->thread_send_hello); 591 o6i->thread_send_hello = (struct thread *) NULL; 592 } 593 594 return CMD_SUCCESS; 595} 596 597DEFUN (no_passive_interface, 598 no_passive_interface_cmd, 599 "no passive-interface IFNAME", 600 NO_STR 601 OSPF6_PASSIVE_STR 602 IFNAME_STR) 603{ 604 struct interface *ifp; 605 struct ospf6_interface *o6i; 606 607 ifp = if_lookup_by_name (argv[0]); 608 if (! ifp) 609 return CMD_ERR_NO_MATCH; 610 611 o6i = (struct ospf6_interface *) ifp->info; 612 UNSET_FLAG (o6i->flag, OSPF6_INTERFACE_FLAG_PASSIVE); 613 if (o6i->thread_send_hello == NULL) 614 thread_add_event (master, ospf6_send_hello, o6i, 0); 615 616 return CMD_SUCCESS; 617} 618 619#ifdef HAVE_SETPROCTITLE 620extern int _argc; 621extern char **_argv; 622 623DEFUN (set_proctitle, 624 set_proctitle_cmd, 625 "set proctitle (version|normal|none)", 626 "Set command\n" 627 "Process title\n" 628 "Version information\n" 629 "Normal command-line options\n" 630 "Just program name\n") 631{ 632 int i; 633 char buf[64], tmp[64]; 634 635 if (strncmp (argv[0], "v", 1) == 0) 636 { 637 proctitle_mode = 1; 638 setproctitle ("%s Zebra: %s", OSPF6_DAEMON_VERSION, ZEBRA_VERSION); 639 } 640 else if (strncmp (argv[0], "nor", 3) == 0) 641 { 642 proctitle_mode = 0; 643 memset (tmp, 0, sizeof (tmp)); 644 memset (buf, 0, sizeof (buf)); 645 for (i = 0; i < _argc; i++) 646 { 647 snprintf (buf, sizeof (buf), "%s%s ", tmp, _argv[i]); 648 memcpy (&tmp, &buf, sizeof (tmp)); 649 } 650 setproctitle (buf); 651 } 652 else if (strncmp (argv[0], "non", 3) == 0) 653 { 654 proctitle_mode = -1; 655 setproctitle (NULL); 656 } 657 else 658 return CMD_ERR_NO_MATCH; 659 660 return CMD_SUCCESS; 661} 662#endif /* HAVE_SETPROCTITLE */ 663 664/* OSPF configuration write function. */ 665int 666ospf6_config_write (struct vty *vty) 667{ 668 listnode j, k; 669 char buf[64]; 670 struct ospf6_area *area; 671 struct ospf6_interface *o6i; 672 673 if (proctitle_mode == 1) 674 vty_out (vty, "set proctitle version%s", VTY_NEWLINE); 675 else if (proctitle_mode == -1) 676 vty_out (vty, "set proctitle none%s", VTY_NEWLINE); 677 678 vty_out (vty, "!%s", VTY_NEWLINE); 679 680 if (! ospf6) 681 return 0; 682 683 /* OSPFv6 configuration. */ 684 if (!ospf6) 685 return CMD_SUCCESS; 686 687 inet_ntop (AF_INET, &ospf6->router_id, buf, sizeof (buf)); 688 vty_out (vty, "router ospf6%s", VTY_NEWLINE); 689 vty_out (vty, " router-id %s%s", buf, VTY_NEWLINE); 690 691 ospf6_redistribute_config_write (vty); 692 693 for (j = listhead (ospf6->area_list); j; nextnode (j)) 694 { 695 area = (struct ospf6_area *)getdata (j); 696 for (k = listhead (area->if_list); k; nextnode (k)) 697 { 698 o6i = (struct ospf6_interface *) getdata (k); 699 vty_out (vty, " interface %s area %s%s", 700 o6i->interface->name, area->str, VTY_NEWLINE); 701 } 702 } 703 vty_out (vty, "!%s", VTY_NEWLINE); 704 return 0; 705} 706 707/* OSPF6 node structure. */ 708struct cmd_node ospf6_node = 709{ 710 OSPF6_NODE, 711 "%s(config-ospf6)# ", 712}; 713 714/* Install ospf related commands. */ 715void 716ospf6_init () 717{ 718 /* Install ospf6 top node. */ 719 install_node (&ospf6_node, ospf6_config_write); 720 721 install_element (VIEW_NODE, &show_ipv6_ospf6_cmd); 722 install_element (VIEW_NODE, &show_version_ospf6_cmd); 723 install_element (ENABLE_NODE, &show_ipv6_ospf6_cmd); 724 install_element (ENABLE_NODE, &show_version_ospf6_cmd); 725 install_element (ENABLE_NODE, &reload_cmd); 726 install_element (CONFIG_NODE, &router_ospf6_cmd); 727 install_element (CONFIG_NODE, &interface_cmd); 728#ifdef OSPF6_STATISTICS 729 install_element (VIEW_NODE, &show_ipv6_ospf6_statistics_cmd); 730 install_element (ENABLE_NODE, &show_ipv6_ospf6_statistics_cmd); 731#endif /* OSPF6_STATISTICS */ 732#ifdef OSPF6_GARBAGE_COLLECT 733 install_element (ENABLE_NODE, &garbage_collection_cmd); 734#endif /* OSPF6_GARBAGE_COLLECT */ 735#ifdef HAVE_SETPROCTITLE 736 install_element (CONFIG_NODE, &set_proctitle_cmd); 737#endif /* HAVE_SETPROCTITLE */ 738 739 install_default (OSPF6_NODE); 740 install_element (OSPF6_NODE, &router_id_cmd); 741 install_element (OSPF6_NODE, &interface_area_cmd); 742 install_element (OSPF6_NODE, &interface_area_passive_cmd); 743 install_element (OSPF6_NODE, &interface_area_plist_cmd); 744 install_element (OSPF6_NODE, &interface_area_plist_passive_cmd); 745 install_element (OSPF6_NODE, &no_interface_area_cmd); 746 install_element (OSPF6_NODE, &passive_interface_cmd); 747 install_element (OSPF6_NODE, &no_passive_interface_cmd); 748 install_element (OSPF6_NODE, &area_range_cmd); 749 750 /* Make empty list of top list. */ 751 if_init (); 752 753 /* Install access list */ 754 access_list_init (); 755 756 /* Install prefix list */ 757 prefix_list_init (); 758 759 ospf6_dump_init (); 760 761 ospf6_hook_init (); 762 ospf6_lsa_init (); 763 764 ospf6_top_init (); 765 ospf6_area_init (); 766 ospf6_interface_init (); 767 ospf6_neighbor_init (); 768 ospf6_zebra_init (); 769 770 ospf6_routemap_init (); 771 ospf6_lsdb_init (); 772 773 ospf6_spf_init (); 774 775 ospf6_intra_init (); 776 ospf6_abr_init (); 777 ospf6_asbr_init (); 778} 779 780void 781ospf6_terminate () 782{ 783 /* stop ospf6 */ 784 ospf6_stop (); 785 786 /* log */ 787 zlog (NULL, LOG_INFO, "OSPF6d terminated"); 788} 789 790void 791ospf6_maxage_remover () 792{ 793#if 0 794 if (IS_OSPF6_DUMP_LSDB) 795 zlog_info ("MaxAge Remover"); 796#endif 797 798 ospf6_top_schedule_maxage_remover (NULL, 0, ospf6); 799 (*ospf6->foreach_area) (ospf6, NULL, 0, 800 ospf6_area_schedule_maxage_remover); 801 (*ospf6->foreach_if) (ospf6, NULL, 0, 802 ospf6_interface_schedule_maxage_remover); 803} 804 805 806 807void * 808ospf6_lsa_get_scope (u_int16_t type, struct ospf6_interface *o6i) 809{ 810 if (OSPF6_LSA_IS_SCOPE_LINKLOCAL (ntohs (type))) 811 return o6i; 812 else if (OSPF6_LSA_IS_SCOPE_AREA (ntohs (type))) 813 return o6i->area; 814 else if (OSPF6_LSA_IS_SCOPE_AS (ntohs (type))) 815 return o6i->area->ospf6; 816 else 817 return NULL; 818} 819 820