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