]>
Commit | Line | Data |
---|---|---|
718e3744 | 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 | ||
42 | struct ospf6_lsdb_hook_t hooks[0x2000]; | |
43 | struct ospf6_lsdb_hook_t *ospf6_lsdb_hook = hooks; | |
44 | ||
45 | struct ospf6_lsdb * | |
46 | ospf6_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 | ||
62 | void | |
63 | ospf6_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 | ||
70 | static void | |
71 | ospf6_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 | ||
99 | void | |
100 | ospf6_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 | ||
124 | void | |
125 | ospf6_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 | ||
157 | static void | |
158 | ospf6_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 | ||
182 | struct ospf6_lsa * | |
183 | ospf6_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 */ | |
192 | void | |
193 | ospf6_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 | ||
216 | void | |
217 | ospf6_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 | ||
246 | void | |
247 | ospf6_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 | ||
277 | void | |
278 | ospf6_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 | ||
307 | struct ospf6_lsa * | |
308 | ospf6_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 | ||
338 | void | |
339 | ospf6_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 | ||
398 | void | |
399 | ospf6_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 | ||
407 | void | |
408 | ospf6_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 | \f | |
434 | ||
435 | /* vty functions */ | |
436 | ||
437 | static int | |
438 | ospf6_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 | ||
456 | int | |
457 | show_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 | ||
570 | DEFUN (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 | ||
617 | ALIAS (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 | ||
637 | ALIAS (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 | ||
659 | ALIAS (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 | ||
683 | ALIAS (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 | ||
707 | void | |
708 | ospf6_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 |