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