1/*
2 * Copyright (C) 2002 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 <zebra.h>
23
24#include "memory.h"
25#include "log.h"
26#include "command.h"
27#include "if.h"
28
29#include "ospf6_dump.h"
30#include "ospf6_lsdb.h"
31
32#include "ospf6_interface.h"
33#include "ospf6_area.h"
34#include "ospf6_top.h"
35
36#define OSPF6_LSDB_MATCH_TYPE        0x01
37#define OSPF6_LSDB_MATCH_ID          0x02
38#define OSPF6_LSDB_MATCH_ADV_ROUTER  0x04
39#define OSPF6_LSDB_SHOW_DUMP         0x08
40#define OSPF6_LSDB_SHOW_DETAIL       0x10
41
42struct ospf6_lsdb_hook_t hooks[0x2000];
43struct ospf6_lsdb_hook_t *ospf6_lsdb_hook = hooks;
44
45struct ospf6_lsdb *
46ospf6_lsdb_create ()
47{
48  struct ospf6_lsdb *lsdb;
49
50  lsdb = XCALLOC (MTYPE_OSPF6_LSDB, sizeof (struct ospf6_lsdb));
51  if (lsdb == NULL)
52    {
53      zlog_warn ("Can't malloc lsdb");
54      return NULL;
55    }
56  memset (lsdb, 0, sizeof (struct ospf6_lsdb));
57
58  lsdb->table = route_table_init ();
59  return lsdb;
60}
61
62void
63ospf6_lsdb_delete (struct ospf6_lsdb *lsdb)
64{
65  ospf6_lsdb_remove_all (lsdb);
66  route_table_finish (lsdb->table);
67  XFREE (MTYPE_OSPF6_LSDB, lsdb);
68}
69
70static void
71ospf6_lsdb_set_key (struct prefix_ipv6 *key, int flag,
72                    u_int16_t type, u_int32_t id, u_int32_t adv_router)
73{
74  int len = 0;
75  memset (key, 0, sizeof (struct prefix_ipv6));
76
77  if (CHECK_FLAG (flag, OSPF6_LSDB_MATCH_TYPE))
78    {
79      len += 2;
80      if (CHECK_FLAG (flag, OSPF6_LSDB_MATCH_ADV_ROUTER))
81        {
82          len += 4;
83          if (CHECK_FLAG (flag, OSPF6_LSDB_MATCH_ID))
84            len += 4;
85        }
86    }
87
88  if (len > 0)
89    memcpy ((char *)&key->prefix, &type, 2);
90  if (len > 2)
91    memcpy ((char *)&key->prefix + 2, &adv_router, 4);
92  if (len > 6)
93    memcpy ((char *)&key->prefix + 6, &id, 4);
94
95  key->family = AF_INET6;
96  key->prefixlen = len * 8;
97}
98
99void
100ospf6_lsdb_add (struct ospf6_lsa *lsa, struct ospf6_lsdb *lsdb)
101{
102  int flag;
103  struct prefix_ipv6 key;
104  struct route_node *rn;
105  struct ospf6_lsa *old = NULL;
106
107  flag = OSPF6_LSDB_MATCH_TYPE | OSPF6_LSDB_MATCH_ID |
108         OSPF6_LSDB_MATCH_ADV_ROUTER;
109  ospf6_lsdb_set_key (&key, flag, lsa->header->type, lsa->header->id,
110                      lsa->header->adv_router);
111
112  rn = route_node_get (lsdb->table, (struct prefix *) &key);
113  if (rn->info)
114    old = rn->info;
115  rn->info = lsa;
116  ospf6_lsa_lock (lsa);
117
118  if (old)
119    ospf6_lsa_unlock (old);
120  else
121    lsdb->count++;
122}
123
124void
125ospf6_lsdb_remove (struct ospf6_lsa *lsa, struct ospf6_lsdb *lsdb)
126{
127  int flag;
128  struct prefix_ipv6 key;
129  struct route_node *rn;
130  struct ospf6_lsa *old;
131
132  flag = OSPF6_LSDB_MATCH_TYPE | OSPF6_LSDB_MATCH_ID |
133         OSPF6_LSDB_MATCH_ADV_ROUTER;
134  ospf6_lsdb_set_key (&key, flag, lsa->header->type, lsa->header->id,
135                      lsa->header->adv_router);
136
137  rn = route_node_lookup (lsdb->table, (struct prefix *) &key);
138  if (! rn || ! rn->info)
139    {
140      zlog_warn ("LSDB: Can't remove: no such LSA: %s", lsa->str);
141      return;
142    }
143
144  old = rn->info;
145  if (old != lsa)
146    {
147      zlog_warn ("LSDB: Can't remove: different instance: %s (%p <-> %p) %s",
148                 lsa->str, lsa, old, old->str);
149      return;
150    }
151
152  rn->info = NULL;
153  ospf6_lsa_unlock (old);
154  lsdb->count--;
155}
156
157static void
158ospf6_lsdb_lookup_node (struct ospf6_lsdb_node *node,
159                        u_int16_t type, u_int32_t id, u_int32_t adv_router,
160                        struct ospf6_lsdb *lsdb)
161{
162  int flag;
163  struct route_node *rn;
164
165  memset (node, 0, sizeof (struct ospf6_lsdb_node));
166
167  flag = OSPF6_LSDB_MATCH_TYPE | OSPF6_LSDB_MATCH_ID |
168         OSPF6_LSDB_MATCH_ADV_ROUTER;
169  ospf6_lsdb_set_key (&node->key, flag, type, id, adv_router);
170
171  rn = route_node_lookup (lsdb->table, (struct prefix *) &node->key);
172  if (! rn || ! rn->info)
173    return;
174
175  node->node = rn;
176  node->next = route_next (rn);
177  node->lsa = rn->info;
178  if (node->next != NULL)
179    route_unlock_node (node->next);
180}
181
182struct ospf6_lsa *
183ospf6_lsdb_lookup_lsdb (u_int16_t type, u_int32_t id, u_int32_t adv_router,
184                        struct ospf6_lsdb *lsdb)
185{
186  struct ospf6_lsdb_node node;
187  ospf6_lsdb_lookup_node (&node, type, id, adv_router, lsdb);
188  return node.lsa;
189}
190
191/* Iteration function */
192void
193ospf6_lsdb_head (struct ospf6_lsdb_node *node, struct ospf6_lsdb *lsdb)
194{
195  struct route_node *rn;
196
197  memset (node, 0, sizeof (struct ospf6_lsdb_node));
198
199  rn = route_top (lsdb->table);
200  if (rn == NULL)
201    return;
202
203  while (rn && rn->info == NULL)
204    rn = route_next (rn);
205
206  if (rn && rn->info)
207    {
208      node->node = rn;
209      node->next = route_next (rn);
210      node->lsa = rn->info;
211      if (node->next != NULL)
212        route_unlock_node (node->next);
213    }
214}
215
216void
217ospf6_lsdb_type (struct ospf6_lsdb_node *node, u_int16_t type,
218                 struct ospf6_lsdb *lsdb)
219{
220  int flag;
221  struct route_node *rn;
222
223  memset (node, 0, sizeof (struct ospf6_lsdb_node));
224
225  flag = OSPF6_LSDB_MATCH_TYPE;
226  ospf6_lsdb_set_key (&node->key, flag, type, 0, 0);
227
228  /* get the closest radix node */
229  rn = route_node_get (lsdb->table, (struct prefix *) &node->key);
230
231  /* skip to the real existing lsdb entry */
232  while (rn && rn->info == NULL && rn->p.prefixlen >= node->key.prefixlen &&
233         prefix_match ((struct prefix *) &node->key, &rn->p))
234    rn = route_next (rn);
235
236  if (rn && rn->info)
237    {
238      node->node = rn;
239      node->next = route_next (rn);
240      node->lsa = rn->info;
241      if (node->next != NULL)
242        route_unlock_node (node->next);
243    }
244}
245
246void
247ospf6_lsdb_type_router (struct ospf6_lsdb_node *node,
248                        u_int16_t type, u_int32_t adv_router,
249                        struct ospf6_lsdb *lsdb)
250{
251  int flag;
252  struct route_node *rn;
253
254  memset (node, 0, sizeof (struct ospf6_lsdb_node));
255
256  flag = OSPF6_LSDB_MATCH_TYPE | OSPF6_LSDB_MATCH_ADV_ROUTER;
257  ospf6_lsdb_set_key (&node->key, flag, type, 0, adv_router);
258
259  /* get the closest radix node */
260  rn = route_node_get (lsdb->table, (struct prefix *) &node->key);
261
262  /* skip to the real existing lsdb entry */
263  while (rn && rn->info == NULL && rn->p.prefixlen >= node->key.prefixlen &&
264         prefix_match ((struct prefix *) &node->key, &rn->p))
265    rn = route_next (rn);
266
267  if (rn && rn->info)
268    {
269      node->node = rn;
270      node->next = route_next (rn);
271      node->lsa = rn->info;
272      if (node->next != NULL)
273        route_unlock_node (node->next);
274    }
275}
276
277void
278ospf6_lsdb_next (struct ospf6_lsdb_node *node)
279{
280  struct route_node *rn;
281
282  route_lock_node (node->node);
283  rn = route_next (node->node);
284
285  /* skip to the real existing lsdb entry */
286  while (rn && rn->info == NULL && rn->p.prefixlen >= node->key.prefixlen &&
287         prefix_match ((struct prefix *) &node->key, &rn->p))
288    rn = route_next (rn);
289
290  if (rn && rn->info && rn->p.prefixlen >= node->key.prefixlen &&
291      prefix_match ((struct prefix *) &node->key, &rn->p))
292    {
293      node->node = rn;
294      node->next = route_next (rn);
295      node->lsa = rn->info;
296      if (node->next != NULL)
297        route_unlock_node (node->next);
298    }
299  else
300    {
301      node->node = NULL;
302      node->next = NULL;
303      node->lsa = NULL;
304    }
305}
306
307struct ospf6_lsa *
308ospf6_lsdb_lookup (u_int16_t type, u_int32_t id, u_int32_t adv_router,
309                   void *scope)
310{
311  struct ospf6_interface *o6i;
312  struct ospf6_area *o6a;
313  listnode i, j;
314
315  if (scope == (void *) ospf6)
316    return ospf6_lsdb_lookup_lsdb (type, id, adv_router, ospf6->lsdb);
317
318  for (i = listhead (ospf6->area_list); i; nextnode (i))
319    {
320      o6a = getdata (i);
321
322      if (scope == (void *) o6a)
323        return ospf6_lsdb_lookup_lsdb (type, id, adv_router, o6a->lsdb);
324
325      for (j = listhead (o6a->if_list); j; nextnode (j))
326        {
327          o6i = getdata (j);
328
329          if (scope == (void *) o6i)
330            return ospf6_lsdb_lookup_lsdb (type, id, adv_router, o6i->lsdb);
331        }
332    }
333
334  zlog_warn ("LSDB: Can't lookup: unknown scope, type %#hx", ntohs (type));
335  return NULL;
336}
337
338void
339ospf6_lsdb_install (struct ospf6_lsa *new)
340{
341  struct ospf6_lsdb *lsdb;
342  struct ospf6_lsa *old;
343  int need_hook = 0;
344  void (*hook) (struct ospf6_lsa *, struct ospf6_lsa *);
345
346  struct ospf6 *as = NULL;
347  struct ospf6_area *area = NULL;
348  struct ospf6_interface *linklocal = NULL;
349  hook = NULL;
350
351  switch (ntohs (new->header->type) & OSPF6_LSTYPE_SCOPE_MASK)
352    {
353      case OSPF6_LSA_SCOPE_LINKLOCAL:
354        linklocal = (struct ospf6_interface *) new->scope;
355        lsdb = linklocal->lsdb;
356        break;
357      case OSPF6_LSA_SCOPE_AREA:
358        area = (struct ospf6_area *) new->scope;
359        lsdb = area->lsdb;
360        break;
361      case OSPF6_LSA_SCOPE_AS:
362        as = (struct ospf6 *) new->scope;
363        lsdb = as->lsdb;
364        break;
365      default:
366        zlog_warn ("LSDB: Can't install: scope unknown: %s", new->str);
367        return;
368    }
369
370  /* whether schedule calculation or not */
371  old = ospf6_lsdb_lookup_lsdb (new->header->type, new->header->id,
372                                new->header->adv_router, lsdb);
373
374  if (! old || ospf6_lsa_differ (old, new))
375    need_hook++;
376
377  /* log */
378  if (IS_OSPF6_DUMP_LSDB)
379    zlog_info ("LSDB: Install: %s %s", new->str,
380               ((IS_LSA_MAXAGE (new)) ? "(MaxAge)" : ""));
381
382  if (old)
383    ospf6_lsa_lock (old);
384
385  ospf6_lsdb_add (new, lsdb);
386  gettimeofday (&new->installed, NULL);
387
388  hook = ospf6_lsdb_hook[ntohs (new->header->type) &
389                         OSPF6_LSTYPE_CODE_MASK].hook;
390  if (need_hook && hook)
391    (*hook) (old, new);
392
393  /* old LSA should be freed here */
394  if (old)
395    ospf6_lsa_unlock (old);
396}
397
398void
399ospf6_lsdb_remove_all (struct ospf6_lsdb *lsdb)
400{
401  struct ospf6_lsdb_node node;
402  for (ospf6_lsdb_head (&node, lsdb); ! ospf6_lsdb_is_end (&node);
403       ospf6_lsdb_next (&node))
404    ospf6_lsdb_remove (node.lsa, lsdb);
405}
406
407void
408ospf6_lsdb_remove_maxage (struct ospf6_lsdb *lsdb)
409{
410  struct ospf6_lsdb_node node;
411  struct ospf6_lsa *lsa;
412
413  for (ospf6_lsdb_head (&node, lsdb); ! ospf6_lsdb_is_end (&node);
414       ospf6_lsdb_next (&node))
415    {
416      lsa = node.lsa;
417
418      /* contiue if it's not MaxAge */
419      if (! IS_LSA_MAXAGE (lsa))
420        continue;
421
422      /* continue if it's referenced by some retrans-lists */
423      if (lsa->lock != 1)
424        continue;
425
426      if (IS_OSPF6_DUMP_LSDB)
427        zlog_info ("Remove MaxAge LSA: %s", lsa->str);
428
429      ospf6_lsdb_remove (lsa, lsdb);
430    }
431}
432
433
434
435/* vty functions */
436
437static int
438ospf6_lsdb_match (int flag, u_int16_t type, u_int32_t id,
439                  u_int32_t adv_router, struct ospf6_lsa *lsa)
440{
441  if (CHECK_FLAG (flag, OSPF6_LSDB_MATCH_TYPE) &&
442      lsa->header->type != type)
443    return 0;
444
445  if (CHECK_FLAG (flag, OSPF6_LSDB_MATCH_ID) &&
446      lsa->header->id != id)
447    return 0;
448
449  if (CHECK_FLAG (flag, OSPF6_LSDB_MATCH_ADV_ROUTER) &&
450      lsa->header->adv_router != adv_router)
451    return 0;
452
453  return 1;
454}
455
456int
457show_ipv6_ospf6_lsdb (struct vty *vty, int argc, char **argv,
458                      struct ospf6_lsdb *lsdb)
459{
460  u_int flag;
461  u_int16_t type = 0;
462  u_int32_t id, adv_router;
463  int ret;
464  struct ospf6_lsdb_node node;
465  char invalid[32], *invalidp;
466  int l_argc = argc;
467  char **l_argv = argv;
468
469  flag = 0;
470  memset (invalid, 0, sizeof (invalid));
471  invalidp = invalid;
472
473  /* chop tail if the words is 'dump' or 'summary' */
474  if (l_argc > 0 && ! strcmp (l_argv[l_argc - 1], "dump"))
475    {
476      SET_FLAG (flag, OSPF6_LSDB_SHOW_DUMP);
477      l_argc --;
478    }
479  else if (l_argc > 0 && ! strcmp (l_argv[l_argc - 1], "detail"))
480    {
481      SET_FLAG (flag, OSPF6_LSDB_SHOW_DETAIL);
482      l_argc --;
483    }
484
485  if (l_argc > 0)
486    {
487      SET_FLAG (flag, OSPF6_LSDB_MATCH_TYPE);
488      if (! strncmp (l_argv[0], "r", 1))
489        type = htons (OSPF6_LSA_TYPE_ROUTER);
490      if (! strncmp (l_argv[0], "n", 1))
491        type = htons (OSPF6_LSA_TYPE_NETWORK);
492      if (! strncmp (l_argv[0], "a", 1))
493        type = htons (OSPF6_LSA_TYPE_AS_EXTERNAL);
494      if (! strcmp (l_argv[0], "intra-prefix"))
495        type = htons (OSPF6_LSA_TYPE_INTRA_PREFIX);
496      if (! strcmp (l_argv[0], "inter-router"))
497        type = htons (OSPF6_LSA_TYPE_INTER_ROUTER);
498      if (! strcmp (l_argv[0], "inter-prefix"))
499        type = htons (OSPF6_LSA_TYPE_INTER_PREFIX);
500      if (! strncmp (l_argv[0], "l", 1))
501        type = htons (OSPF6_LSA_TYPE_LINK);
502      if (! strncmp (l_argv[0], "0x", 2) && strlen (l_argv[0]) == 6)
503        type = htons ((short) strtol (l_argv[0], (char **)NULL, 16));
504      if (! strncmp (l_argv[0], "*", 1))
505        UNSET_FLAG (flag, OSPF6_LSDB_MATCH_TYPE);
506    }
507
508  if (l_argc > 1)
509    {
510      SET_FLAG (flag, OSPF6_LSDB_MATCH_ID);
511      if (! strncmp (l_argv[1], "*", 1))
512        UNSET_FLAG (flag, OSPF6_LSDB_MATCH_ID);
513      else
514        {
515          ret = inet_pton (AF_INET, l_argv[1], &id);
516          if (ret != 1)
517            {
518              id = htonl (strtoul (l_argv[1], &invalidp, 10));
519              if (invalid[0] != '\0')
520                {
521                  vty_out (vty, "Link State ID is not parsable: %s%s",
522                           l_argv[1], VTY_NEWLINE);
523                  return CMD_SUCCESS;
524                }
525            }
526        }
527    }
528
529  if (l_argc > 2)
530    {
531      SET_FLAG (flag, OSPF6_LSDB_MATCH_ADV_ROUTER);
532      if (! strncmp (l_argv[2], "*", 1))
533        UNSET_FLAG (flag, OSPF6_LSDB_MATCH_ADV_ROUTER);
534      else
535        {
536          ret = inet_pton (AF_INET, l_argv[2], &adv_router);
537          if (ret != 1)
538            {
539              adv_router = htonl (strtoul (l_argv[2], &invalidp, 10));
540              if (invalid[0] != '\0')
541                {
542                  vty_out (vty, "Advertising Router is not parsable: %s%s",
543                           l_argv[2], VTY_NEWLINE);
544                  return CMD_SUCCESS;
545                }
546            }
547        }
548    }
549
550  if (! CHECK_FLAG (flag, OSPF6_LSDB_SHOW_DETAIL))
551    ospf6_lsa_show_summary_header (vty);
552
553  for (ospf6_lsdb_head (&node, lsdb); ! ospf6_lsdb_is_end (&node);
554       ospf6_lsdb_next (&node))
555    {
556      if (! ospf6_lsdb_match (flag, type, id, adv_router, node.lsa))
557        continue;
558
559      if (CHECK_FLAG (flag, OSPF6_LSDB_SHOW_DUMP))
560        ospf6_lsa_show_dump (vty, node.lsa);
561      else if (CHECK_FLAG (flag, OSPF6_LSDB_SHOW_DETAIL))
562        ospf6_lsa_show (vty, node.lsa);
563      else
564        ospf6_lsa_show_summary (vty, node.lsa);
565    }
566
567  return CMD_SUCCESS;
568}
569
570DEFUN (show_ipv6_ospf6_database,
571       show_ipv6_ospf6_database_cmd,
572       "show ipv6 ospf6 database",
573       SHOW_STR
574       IP6_STR
575       OSPF6_STR
576       "LSA Database\n"
577       )
578{
579  struct ospf6_area *o6a;
580  struct ospf6_interface *o6i;
581  listnode i, j;
582
583  /* call show function for each of LSAs in the LSDBs */
584
585  for (i = listhead (ospf6->area_list); i; nextnode (i))
586    {
587      o6a = (struct ospf6_area *) getdata (i);
588
589      /* LinkLocal LSDBs */
590      for (j = listhead (o6a->if_list); j; nextnode (j))
591        {
592          o6i = (struct ospf6_interface *) getdata (j);
593
594          vty_out (vty, "%s", VTY_NEWLINE);
595          vty_out (vty, "                Interface %s (Area: %s):%s",
596                   o6i->interface->name, o6a->str, VTY_NEWLINE);
597          vty_out (vty, "%s", VTY_NEWLINE);
598          show_ipv6_ospf6_lsdb (vty, argc, argv, o6i->lsdb);
599        }
600
601      /* Area LSDBs */
602      vty_out (vty, "%s", VTY_NEWLINE);
603      vty_out (vty, "                Area %s:%s", o6a->str, VTY_NEWLINE);
604      vty_out (vty, "%s", VTY_NEWLINE);
605      show_ipv6_ospf6_lsdb (vty, argc, argv, o6a->lsdb);
606    }
607
608  /* AS LSDBs */
609  vty_out (vty, "%s", VTY_NEWLINE);
610  vty_out (vty, "                AS:%s", VTY_NEWLINE);
611  vty_out (vty, "%s", VTY_NEWLINE);
612  show_ipv6_ospf6_lsdb (vty, argc, argv, ospf6->lsdb);
613
614  return CMD_SUCCESS;
615}
616
617ALIAS (show_ipv6_ospf6_database,
618       show_ipv6_ospf6_database_type_cmd,
619       "show ipv6 ospf6 database (router|network|as-external|intra-prefix|inter-prefix|inter-router|link|*|HEX|dump|detail)",
620       SHOW_STR
621       IP6_STR
622       OSPF6_STR
623       "LSA Database\n"
624       "Router-LSA\n"
625       "Network-LSA\n"
626       "AS-External-LSA\n"
627       "Intra-Area-Prefix-LSA\n"
628       "Inter-Area-Router-LSA\n"
629       "Inter-Area-Prefix-LSA\n"
630       "Link-LSA\n"
631       "All LS Type\n"
632       "Specify LS Type by Hex\n"
633       "Dump raw LSA data in Hex\n"
634       "show detail of LSAs\n"
635       )
636
637ALIAS (show_ipv6_ospf6_database,
638       show_ipv6_ospf6_database_type_id_cmd,
639       "show ipv6 ospf6 database (router|network|as-external|intra-prefix|inter-prefix|inter-router|link|*|HEX) (A.B.C.D|*|dump|detail)",
640       SHOW_STR
641       IP6_STR
642       OSPF6_STR
643       "LSA Database\n"
644       "Router-LSA\n"
645       "Network-LSA\n"
646       "AS-External-LSA\n"
647       "Intra-Area-Prefix-LSA\n"
648       "Inter-Area-Router-LSA\n"
649       "Inter-Area-Prefix-LSA\n"
650       "Link-LSA\n"
651       "All LS Type\n"
652       "Specify LS Type by Hex\n"
653       "Link State ID\n"
654       "All Link State ID\n"
655       "Dump raw LSA data in Hex\n"
656       "show detail of LSAs\n"
657       )
658
659ALIAS (show_ipv6_ospf6_database,
660       show_ipv6_ospf6_database_type_id_adv_router_cmd,
661       "show ipv6 ospf6 database (router|network|as-external|intra-prefix|inter-prefix|inter-router|link|*|HEX) (A.B.C.D|*) (A.B.C.D|*|dump|detail)",
662       SHOW_STR
663       IP6_STR
664       OSPF6_STR
665       "LSA Database\n"
666       "Router-LSA\n"
667       "Network-LSA\n"
668       "AS-External-LSA\n"
669       "Intra-Area-Prefix-LSA\n"
670       "Inter-Area-Router-LSA\n"
671       "Inter-Area-Prefix-LSA\n"
672       "Link-LSA\n"
673       "All LS Type\n"
674       "Specify LS Type by Hex\n"
675       "Link State ID\n"
676       "All Link State ID\n"
677       "Advertising Router\n"
678       "All Advertising Router\n"
679       "Dump raw LSA data in Hex\n"
680       "show detail of LSAs\n"
681       )
682
683ALIAS (show_ipv6_ospf6_database,
684       show_ipv6_ospf6_database_type_id_adv_router_dump_cmd,
685       "show ipv6 ospf6 database (router|network|as-external|intra-prefix|inter-prefix|inter-router|link|*|HEX) (A.B.C.D|*) (A.B.C.D|*) (dump|detail|)",
686       SHOW_STR
687       IP6_STR
688       OSPF6_STR
689       "LSA Database\n"
690       "Router-LSA\n"
691       "Network-LSA\n"
692       "AS-External-LSA\n"
693       "Intra-Area-Prefix-LSA\n"
694       "Inter-Area-Router-LSA\n"
695       "Inter-Area-Prefix-LSA\n"
696       "Link-LSA\n"
697       "All LS Type\n"
698       "Specify LS Type by Hex\n"
699       "Link State ID\n"
700       "All Link State ID\n"
701       "Advertising Router\n"
702       "All Advertising Router\n"
703       "Dump raw LSA data in Hex\n"
704       "show detail of LSAs\n"
705       )
706
707void
708ospf6_lsdb_init ()
709{
710  install_element (VIEW_NODE, &show_ipv6_ospf6_database_cmd);
711  install_element (VIEW_NODE, &show_ipv6_ospf6_database_type_cmd);
712  install_element (VIEW_NODE, &show_ipv6_ospf6_database_type_id_cmd);
713  install_element (VIEW_NODE, &show_ipv6_ospf6_database_type_id_adv_router_cmd);
714  install_element (VIEW_NODE, &show_ipv6_ospf6_database_type_id_adv_router_dump_cmd);
715
716  install_element (ENABLE_NODE, &show_ipv6_ospf6_database_cmd);
717  install_element (ENABLE_NODE, &show_ipv6_ospf6_database_type_cmd);
718  install_element (ENABLE_NODE, &show_ipv6_ospf6_database_type_id_cmd);
719  install_element (ENABLE_NODE, &show_ipv6_ospf6_database_type_id_adv_router_cmd);
720  install_element (ENABLE_NODE, &show_ipv6_ospf6_database_type_id_adv_router_dump_cmd);
721}
722
723
724