blob: b054c7b4d02d9f6c4744d53fe4f6d4128fda7741 [file] [log] [blame]
paul718e3742002-12-13 20:15:29 +00001/*
hasso508e53e2004-05-18 18:57:06 +00002 * Copyright (C) 2003 Yasuhiro Ohara
paul718e3742002-12-13 20:15:29 +00003 *
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
hasso508e53e2004-05-18 18:57:06 +000022#include <zebra.h>
23
24#include "log.h"
25#include "memory.h"
26#include "prefix.h"
27#include "table.h"
28#include "vty.h"
29#include "command.h"
30
hasso508e53e2004-05-18 18:57:06 +000031#include "ospf6_proto.h"
32#include "ospf6_lsa.h"
hasso049207c2004-08-04 20:02:13 +000033#include "ospf6_lsdb.h"
hasso508e53e2004-05-18 18:57:06 +000034#include "ospf6_route.h"
hasso049207c2004-08-04 20:02:13 +000035#include "ospf6d.h"
paul718e3742002-12-13 20:15:29 +000036
hasso508e53e2004-05-18 18:57:06 +000037unsigned char conf_debug_ospf6_route = 0;
38
39void
40ospf6_linkstate_prefix (u_int32_t adv_router, u_int32_t id,
41 struct prefix *prefix)
paul718e3742002-12-13 20:15:29 +000042{
hasso508e53e2004-05-18 18:57:06 +000043 memset (prefix, 0, sizeof (struct prefix));
44 prefix->family = AF_INET6;
45 prefix->prefixlen = 64;
46 memcpy (&prefix->u.prefix6.s6_addr[0], &adv_router, 4);
47 memcpy (&prefix->u.prefix6.s6_addr[4], &id, 4);
paul718e3742002-12-13 20:15:29 +000048}
49
hasso508e53e2004-05-18 18:57:06 +000050void
51ospf6_linkstate_prefix2str (struct prefix *prefix, char *buf, int size)
paul718e3742002-12-13 20:15:29 +000052{
hasso508e53e2004-05-18 18:57:06 +000053 u_int32_t adv_router, id;
hasso4846ef62004-09-03 06:04:00 +000054 char adv_router_str[16], id_str[16];
hasso508e53e2004-05-18 18:57:06 +000055 memcpy (&adv_router, &prefix->u.prefix6.s6_addr[0], 4);
56 memcpy (&id, &prefix->u.prefix6.s6_addr[4], 4);
57 inet_ntop (AF_INET, &adv_router, adv_router_str, sizeof (adv_router_str));
hasso4846ef62004-09-03 06:04:00 +000058 inet_ntop (AF_INET, &id, id_str, sizeof (id_str));
59 if (ntohl (id))
60 snprintf (buf, size, "%s Net-ID: %s", adv_router_str, id_str);
61 else
62 snprintf (buf, size, "%s", adv_router_str);
paul718e3742002-12-13 20:15:29 +000063}
64
hasso508e53e2004-05-18 18:57:06 +000065/* Global strings for logging */
66char *ospf6_dest_type_str[OSPF6_DEST_TYPE_MAX] =
hasso4846ef62004-09-03 06:04:00 +000067{ "Unknown", "Router", "Network", "Discard", "Linkstate", "AddressRange", };
hasso508e53e2004-05-18 18:57:06 +000068
69char *ospf6_dest_type_substr[OSPF6_DEST_TYPE_MAX] =
hasso4846ef62004-09-03 06:04:00 +000070{ "?", "R", "N", "D", "L", "A", };
hasso508e53e2004-05-18 18:57:06 +000071
72char *ospf6_path_type_str[OSPF6_PATH_TYPE_MAX] =
73{ "Unknown", "Intra-Area", "Inter-Area", "External-1", "External-2", };
74
75char *ospf6_path_type_substr[OSPF6_PATH_TYPE_MAX] =
hasso4846ef62004-09-03 06:04:00 +000076{ "??", "IA", "IE", "E1", "E2", };
hasso508e53e2004-05-18 18:57:06 +000077
78
79struct ospf6_route *
80ospf6_route_create ()
paul718e3742002-12-13 20:15:29 +000081{
hasso508e53e2004-05-18 18:57:06 +000082 struct ospf6_route *route;
83 route = XCALLOC (MTYPE_OSPF6_ROUTE, sizeof (struct ospf6_route));
84 return route;
paul718e3742002-12-13 20:15:29 +000085}
86
hasso508e53e2004-05-18 18:57:06 +000087void
88ospf6_route_delete (struct ospf6_route *route)
paul718e3742002-12-13 20:15:29 +000089{
hasso508e53e2004-05-18 18:57:06 +000090 XFREE (MTYPE_OSPF6_ROUTE, route);
paul718e3742002-12-13 20:15:29 +000091}
92
hasso508e53e2004-05-18 18:57:06 +000093struct ospf6_route *
94ospf6_route_copy (struct ospf6_route *route)
95{
96 struct ospf6_route *new;
97
98 new = ospf6_route_create ();
99 memcpy (new, route, sizeof (struct ospf6_route));
100 new->rnode = NULL;
101 new->prev = NULL;
102 new->next = NULL;
103 new->lock = 0;
104 return new;
105}
106
107void
108ospf6_route_lock (struct ospf6_route *route)
109{
110 route->lock++;
111}
112
113void
114ospf6_route_unlock (struct ospf6_route *route)
115{
116 assert (route->lock > 0);
117 route->lock--;
118 if (route->lock == 0)
119 ospf6_route_delete (route);
120}
121
122/* Route compare function. If ra is more preferred, it returns
123 less than 0. If rb is more preferred returns greater than 0.
124 Otherwise (neither one is preferred), returns 0 */
125static int
126ospf6_route_cmp (struct ospf6_route *ra, struct ospf6_route *rb)
127{
128 assert (ospf6_route_is_same (ra, rb));
129 assert (OSPF6_PATH_TYPE_NONE < ra->path.type &&
130 ra->path.type < OSPF6_PATH_TYPE_MAX);
131 assert (OSPF6_PATH_TYPE_NONE < rb->path.type &&
132 rb->path.type < OSPF6_PATH_TYPE_MAX);
133
134 if (ra->type != rb->type)
135 return (ra->type - rb->type);
136
137 if (ra->path.area_id != rb->path.area_id)
138 return (ntohl (ra->path.area_id) - ntohl (rb->path.area_id));
139
140 if (ra->path.type != rb->path.type)
141 return (ra->path.type - rb->path.type);
142
143 if (ra->path.type == OSPF6_PATH_TYPE_EXTERNAL2)
144 {
145 if (ra->path.cost_e2 != rb->path.cost_e2)
146 return (ra->path.cost_e2 - rb->path.cost_e2);
147 }
148 else
149 {
150 if (ra->path.cost != rb->path.cost)
151 return (ra->path.cost - rb->path.cost);
152 }
153
154 return 0;
155}
156
157struct ospf6_route *
158ospf6_route_lookup (struct prefix *prefix,
paul718e3742002-12-13 20:15:29 +0000159 struct ospf6_route_table *table)
160{
161 struct route_node *node;
hasso508e53e2004-05-18 18:57:06 +0000162 struct ospf6_route *route;
paul718e3742002-12-13 20:15:29 +0000163
164 node = route_node_lookup (table->table, prefix);
hasso508e53e2004-05-18 18:57:06 +0000165 if (node == NULL)
166 return NULL;
paul718e3742002-12-13 20:15:29 +0000167
hasso508e53e2004-05-18 18:57:06 +0000168 route = (struct ospf6_route *) node->info;
169 return route;
paul718e3742002-12-13 20:15:29 +0000170}
171
hasso508e53e2004-05-18 18:57:06 +0000172struct ospf6_route *
173ospf6_route_lookup_identical (struct ospf6_route *route,
174 struct ospf6_route_table *table)
175{
176 struct ospf6_route *target;
177
178 for (target = ospf6_route_lookup (&route->prefix, table);
179 target; target = target->next)
180 {
181 if (ospf6_route_is_identical (target, route))
182 return target;
183 }
184 return NULL;
185}
186
187struct ospf6_route *
188ospf6_route_lookup_bestmatch (struct prefix *prefix,
189 struct ospf6_route_table *table)
paul718e3742002-12-13 20:15:29 +0000190{
191 struct route_node *node;
hasso508e53e2004-05-18 18:57:06 +0000192 struct ospf6_route *route;
paul718e3742002-12-13 20:15:29 +0000193
hasso508e53e2004-05-18 18:57:06 +0000194 node = route_node_match (table->table, prefix);
195 if (node == NULL)
196 return NULL;
197 route_unlock_node (node);
paul718e3742002-12-13 20:15:29 +0000198
hasso508e53e2004-05-18 18:57:06 +0000199 route = (struct ospf6_route *) node->info;
200 return route;
paul718e3742002-12-13 20:15:29 +0000201}
202
hasso508e53e2004-05-18 18:57:06 +0000203#ifndef NDEBUG
204static void
205_route_count_assert (struct ospf6_route_table *table)
paul718e3742002-12-13 20:15:29 +0000206{
hasso508e53e2004-05-18 18:57:06 +0000207 struct ospf6_route *debug;
hassoccb59b12004-08-25 09:10:37 +0000208 char buf[64];
hasso508e53e2004-05-18 18:57:06 +0000209 int num = 0;
210 for (debug = ospf6_route_head (table); debug;
211 debug = ospf6_route_next (debug))
212 num++;
hassoccb59b12004-08-25 09:10:37 +0000213
214 if (num == table->count)
215 return;
216
217 zlog_info ("PANIC !! table[%p]->count = %d, real = %d",
218 table, table->count, num);
219 for (debug = ospf6_route_head (table); debug;
220 debug = ospf6_route_next (debug))
221 {
222 prefix2str (&debug->prefix, buf, sizeof (buf));
223 zlog_info ("%p %p %s", debug->prev, debug->next, buf);
224 }
225 zlog_info ("DUMP END");
226
hasso508e53e2004-05-18 18:57:06 +0000227 assert (num == table->count);
paul718e3742002-12-13 20:15:29 +0000228}
hasso508e53e2004-05-18 18:57:06 +0000229#define ospf6_route_count_assert(t) (_route_count_assert (t))
230#else
231#define ospf6_route_count_assert(t) ((void) 0)
232#endif /*NDEBUG*/
paul718e3742002-12-13 20:15:29 +0000233
hasso508e53e2004-05-18 18:57:06 +0000234struct ospf6_route *
235ospf6_route_add (struct ospf6_route *route,
paul718e3742002-12-13 20:15:29 +0000236 struct ospf6_route_table *table)
237{
hasso508e53e2004-05-18 18:57:06 +0000238 struct route_node *node, *nextnode, *prevnode;
239 struct ospf6_route *current = NULL;
240 struct ospf6_route *prev = NULL, *old = NULL, *next = NULL;
241 char buf[64];
242 struct timeval now;
paul718e3742002-12-13 20:15:29 +0000243
hasso508e53e2004-05-18 18:57:06 +0000244 assert (route->rnode == NULL);
245 assert (route->lock == 0);
246 assert (route->next == NULL);
247 assert (route->prev == NULL);
paul718e3742002-12-13 20:15:29 +0000248
hasso508e53e2004-05-18 18:57:06 +0000249 if (route->type == OSPF6_DEST_TYPE_LINKSTATE)
250 ospf6_linkstate_prefix2str (&route->prefix, buf, sizeof (buf));
251 else
252 prefix2str (&route->prefix, buf, sizeof (buf));
paul718e3742002-12-13 20:15:29 +0000253
hasso508e53e2004-05-18 18:57:06 +0000254 if (IS_OSPF6_DEBUG_ROUTE (TABLE))
255 zlog_info ("route add %s", buf);
paul718e3742002-12-13 20:15:29 +0000256
hasso508e53e2004-05-18 18:57:06 +0000257 gettimeofday (&now, NULL);
258
259 node = route_node_get (table->table, &route->prefix);
260 route->rnode = node;
261
262 /* find place to insert */
263 for (current = node->info; current; current = current->next)
paul718e3742002-12-13 20:15:29 +0000264 {
hasso508e53e2004-05-18 18:57:06 +0000265 if (! ospf6_route_is_same (current, route))
266 next = current;
267 else if (current->type != route->type)
268 prev = current;
269 else if (ospf6_route_is_same_origin (current, route))
270 old = current;
271 else if (ospf6_route_cmp (current, route) > 0)
272 next = current;
273 else
274 prev = current;
275
276 if (old || next)
277 break;
paul718e3742002-12-13 20:15:29 +0000278 }
hasso508e53e2004-05-18 18:57:06 +0000279
280 if (old)
281 {
282 /* if route does not actually change, return unchanged */
283 if (ospf6_route_is_identical (old, route))
284 {
285 if (IS_OSPF6_DEBUG_ROUTE (TABLE))
286 zlog_info (" identical route found, ignore");
287
288 ospf6_route_delete (route);
289 SET_FLAG (old->flag, OSPF6_ROUTE_ADD);
290 ospf6_route_count_assert (table);
291 return old;
292 }
293
294 if (IS_OSPF6_DEBUG_ROUTE (TABLE))
295 zlog_info (" old route found, replace");
296
297 /* replace old one if exists */
298 if (node->info == old)
299 {
300 node->info = route;
301 SET_FLAG (route->flag, OSPF6_ROUTE_BEST);
302 }
303
304 if (old->prev)
305 old->prev->next = route;
306 route->prev = old->prev;
307 if (old->next)
308 old->next->prev = route;
309 route->next = old->next;
310
311 route->installed = old->installed;
312 route->changed = now;
313
314 ospf6_route_unlock (old); /* will be deleted later */
315 ospf6_route_lock (route);
316
317 SET_FLAG (route->flag, OSPF6_ROUTE_CHANGE);
318 if (table->hook_add)
319 (*table->hook_add) (route);
320
321 ospf6_route_count_assert (table);
322 return route;
323 }
324
325 /* insert if previous or next node found */
326 if (prev || next)
327 {
328 if (IS_OSPF6_DEBUG_ROUTE (TABLE))
329 zlog_info (" another path found, insert");
330
331 if (prev == NULL)
332 prev = next->prev;
333 if (next == NULL)
334 next = prev->next;
335
336 if (prev)
337 prev->next = route;
338 route->prev = prev;
339 if (next)
340 next->prev = route;
341 route->next = next;
342
343 if (node->info == next)
344 {
345 assert (next->rnode == node);
346 node->info = route;
347 UNSET_FLAG (next->flag, OSPF6_ROUTE_BEST);
348 SET_FLAG (route->flag, OSPF6_ROUTE_BEST);
349 }
350
351 route->installed = now;
352 route->changed = now;
353
354 ospf6_route_lock (route);
355 table->count++;
356
357 SET_FLAG (route->flag, OSPF6_ROUTE_ADD);
358 if (table->hook_add)
359 (*table->hook_add) (route);
360
361 ospf6_route_count_assert (table);
362 return route;
363 }
364
365 /* Else, this is the brand new route regarding to the prefix */
366 if (IS_OSPF6_DEBUG_ROUTE (TABLE))
367 zlog_info (" brand new route, add");
368
369 assert (node->info == NULL);
370 node->info = route;
371 SET_FLAG (route->flag, OSPF6_ROUTE_BEST);
372 ospf6_route_lock (route);
373 route->installed = now;
374 route->changed = now;
375
376 /* lookup real existing next route */
377 nextnode = node;
378 route_lock_node (nextnode);
379 do {
380 nextnode = route_next (nextnode);
381 } while (nextnode && nextnode->info == NULL);
382
383 /* set next link */
384 if (nextnode == NULL)
385 route->next = NULL;
paul718e3742002-12-13 20:15:29 +0000386 else
387 {
hasso508e53e2004-05-18 18:57:06 +0000388 route_unlock_node (nextnode);
389
390 next = nextnode->info;
391 route->next = next;
392 next->prev = route;
paul718e3742002-12-13 20:15:29 +0000393 }
394
hasso508e53e2004-05-18 18:57:06 +0000395 /* lookup real existing prev route */
396 prevnode = node;
397 route_lock_node (prevnode);
398 do {
399 prevnode = route_prev (prevnode);
400 } while (prevnode && prevnode->info == NULL);
paul718e3742002-12-13 20:15:29 +0000401
hasso508e53e2004-05-18 18:57:06 +0000402 /* set prev link */
403 if (prevnode == NULL)
404 route->prev = NULL;
paul718e3742002-12-13 20:15:29 +0000405 else
406 {
hasso508e53e2004-05-18 18:57:06 +0000407 route_unlock_node (prevnode);
408
409 prev = prevnode->info;
410 while (prev->next && ospf6_route_is_same (prev, prev->next))
411 prev = prev->next;
412 route->prev = prev;
413 prev->next = route;
paul718e3742002-12-13 20:15:29 +0000414 }
415
hasso508e53e2004-05-18 18:57:06 +0000416 table->count++;
paul718e3742002-12-13 20:15:29 +0000417
hasso508e53e2004-05-18 18:57:06 +0000418 SET_FLAG (route->flag, OSPF6_ROUTE_ADD);
419 if (table->hook_add)
420 (*table->hook_add) (route);
paul718e3742002-12-13 20:15:29 +0000421
hasso508e53e2004-05-18 18:57:06 +0000422 ospf6_route_count_assert (table);
423 return route;
paul718e3742002-12-13 20:15:29 +0000424}
425
426void
hasso508e53e2004-05-18 18:57:06 +0000427ospf6_route_remove (struct ospf6_route *route,
paul718e3742002-12-13 20:15:29 +0000428 struct ospf6_route_table *table)
429{
hasso508e53e2004-05-18 18:57:06 +0000430 struct route_node *node;
431 struct ospf6_route *current;
432 char buf[64];
paul718e3742002-12-13 20:15:29 +0000433
hasso508e53e2004-05-18 18:57:06 +0000434 if (route->type == OSPF6_DEST_TYPE_LINKSTATE)
435 ospf6_linkstate_prefix2str (&route->prefix, buf, sizeof (buf));
436 else
437 prefix2str (&route->prefix, buf, sizeof (buf));
paul718e3742002-12-13 20:15:29 +0000438
hasso508e53e2004-05-18 18:57:06 +0000439 if (IS_OSPF6_DEBUG_ROUTE (TABLE))
440 zlog_info ("route remove: %s", buf);
441
442 node = route_node_lookup (table->table, &route->prefix);
443 assert (node);
444
445 /* find the route to remove, making sure that the route pointer
446 is from the route table. */
447 current = node->info;
448 while (current && ospf6_route_is_same (current, route))
paul718e3742002-12-13 20:15:29 +0000449 {
hasso508e53e2004-05-18 18:57:06 +0000450 if (current == route)
451 break;
452 current = current->next;
453 }
454 assert (current == route);
455
456 /* adjust doubly linked list */
457 if (route->prev)
458 route->prev->next = route->next;
459 if (route->next)
460 route->next->prev = route->prev;
461
462 if (node->info == route)
463 {
464 if (route->next && ospf6_route_is_same (route->next, route))
paul718e3742002-12-13 20:15:29 +0000465 {
hasso508e53e2004-05-18 18:57:06 +0000466 node->info = route->next;
467 SET_FLAG (route->next->flag, OSPF6_ROUTE_BEST);
paul718e3742002-12-13 20:15:29 +0000468 }
hasso508e53e2004-05-18 18:57:06 +0000469 else
470 node->info = NULL; /* should unlock route_node here ? */
paul718e3742002-12-13 20:15:29 +0000471 }
472
paul718e3742002-12-13 20:15:29 +0000473 if (table->hook_remove)
hasso508e53e2004-05-18 18:57:06 +0000474 (*table->hook_remove) (route);
paul718e3742002-12-13 20:15:29 +0000475
hasso508e53e2004-05-18 18:57:06 +0000476 ospf6_route_unlock (route);
477 table->count--;
paul718e3742002-12-13 20:15:29 +0000478
hasso508e53e2004-05-18 18:57:06 +0000479 ospf6_route_count_assert (table);
480}
paul718e3742002-12-13 20:15:29 +0000481
hasso508e53e2004-05-18 18:57:06 +0000482struct ospf6_route *
483ospf6_route_head (struct ospf6_route_table *table)
484{
485 struct route_node *node;
486 struct ospf6_route *route;
paul718e3742002-12-13 20:15:29 +0000487
hasso508e53e2004-05-18 18:57:06 +0000488 node = route_top (table->table);
489 if (node == NULL)
490 return NULL;
491
492 /* skip to the real existing entry */
493 while (node && node->info == NULL)
494 node = route_next (node);
495 if (node == NULL)
496 return NULL;
497
498 route_unlock_node (node);
499 assert (node->info);
500
501 route = (struct ospf6_route *) node->info;
502 assert (route->prev == NULL);
503 ospf6_route_lock (route);
504 return route;
505}
506
507struct ospf6_route *
508ospf6_route_next (struct ospf6_route *route)
509{
510 struct ospf6_route *next = route->next;
511
512 ospf6_route_unlock (route);
513 if (next)
514 ospf6_route_lock (next);
515
516 return next;
517}
518
519struct ospf6_route *
520ospf6_route_best_next (struct ospf6_route *route)
521{
522 struct route_node *rnode;
523 struct ospf6_route *next;
524
525 rnode = route->rnode;
526 route_lock_node (rnode);
527 rnode = route_next (rnode);
528 while (rnode && rnode->info == NULL)
529 rnode = route_next (rnode);
530 if (rnode == NULL)
531 return NULL;
532 route_unlock_node (rnode);
533
534 assert (rnode->info);
535 next = (struct ospf6_route *) rnode->info;
536 ospf6_route_unlock (route);
537 ospf6_route_lock (next);
538 return next;
539}
540
541/* Macro version of check_bit (). */
542#define CHECK_BIT(X,P) ((((u_char *)(X))[(P) / 8]) >> (7 - ((P) % 8)) & 1)
543
544struct ospf6_route *
545ospf6_route_match_head (struct prefix *prefix,
546 struct ospf6_route_table *table)
547{
548 struct route_node *node;
549 struct ospf6_route *route;
550
551 /* Walk down tree. */
552 node = table->table->top;
553 while (node && node->p.prefixlen < prefix->prefixlen &&
554 prefix_match (&node->p, prefix))
555 node = node->link[CHECK_BIT(&prefix->u.prefix, node->p.prefixlen)];
556
557 if (node)
558 route_lock_node (node);
559 while (node && node->info == NULL)
560 node = route_next (node);
561 if (node == NULL)
562 return NULL;
563 route_unlock_node (node);
564
565 if (! prefix_match (prefix, &node->p))
566 return NULL;
567
568 route = node->info;
569 ospf6_route_lock (route);
570 return route;
571}
572
573struct ospf6_route *
574ospf6_route_match_next (struct prefix *prefix,
575 struct ospf6_route *route)
576{
577 struct ospf6_route *next;
578
579 next = ospf6_route_next (route);
580 if (next && ! prefix_match (prefix, &next->prefix))
581 {
582 ospf6_route_unlock (next);
583 next = NULL;
584 }
585
586 return next;
paul718e3742002-12-13 20:15:29 +0000587}
588
589void
590ospf6_route_remove_all (struct ospf6_route_table *table)
591{
hasso508e53e2004-05-18 18:57:06 +0000592 struct ospf6_route *route;
593 for (route = ospf6_route_head (table); route;
594 route = ospf6_route_next (route))
595 ospf6_route_remove (route, table);
paul718e3742002-12-13 20:15:29 +0000596}
597
paul718e3742002-12-13 20:15:29 +0000598struct ospf6_route_table *
hasso508e53e2004-05-18 18:57:06 +0000599ospf6_route_table_create ()
paul718e3742002-12-13 20:15:29 +0000600{
paul718e3742002-12-13 20:15:29 +0000601 struct ospf6_route_table *new;
paul718e3742002-12-13 20:15:29 +0000602 new = XCALLOC (MTYPE_OSPF6_ROUTE, sizeof (struct ospf6_route_table));
paul718e3742002-12-13 20:15:29 +0000603 new->table = route_table_init ();
paul718e3742002-12-13 20:15:29 +0000604 return new;
605}
606
607void
608ospf6_route_table_delete (struct ospf6_route_table *table)
609{
paul718e3742002-12-13 20:15:29 +0000610 ospf6_route_remove_all (table);
611 route_table_finish (table->table);
paul718e3742002-12-13 20:15:29 +0000612 XFREE (MTYPE_OSPF6_ROUTE, table);
613}
614
paul718e3742002-12-13 20:15:29 +0000615
616
617/* VTY commands */
hasso508e53e2004-05-18 18:57:06 +0000618void
619ospf6_route_show (struct vty *vty, struct ospf6_route *route)
620{
621 int i;
622 char destination[64], nexthop[64];
623 char duration[16], ifname[IFNAMSIZ];
624 struct timeval now, res;
625
626 gettimeofday (&now, (struct timezone *) NULL);
627 timersub (&now, &route->changed, &res);
628 timerstring (&res, duration, sizeof (duration));
629
630 /* destination */
631 if (route->type == OSPF6_DEST_TYPE_LINKSTATE)
632 ospf6_linkstate_prefix2str (&route->prefix, destination,
633 sizeof (destination));
634 else if (route->type == OSPF6_DEST_TYPE_ROUTER)
635 inet_ntop (route->prefix.family, &route->prefix.u.prefix,
636 destination, sizeof (destination));
637 else
638 prefix2str (&route->prefix, destination, sizeof (destination));
639
640 /* nexthop */
641 inet_ntop (AF_INET6, &route->nexthop[0].address, nexthop,
642 sizeof (nexthop));
643 if (! if_indextoname (route->nexthop[0].ifindex, ifname))
644 snprintf (ifname, sizeof (ifname), "%d", route->nexthop[0].ifindex);
645
646 vty_out (vty, "%c%1s %2s %-30s %-25s %6s %s%s",
647 (ospf6_route_is_best (route) ? '*' : ' '),
648 OSPF6_DEST_TYPE_SUBSTR (route->type),
649 OSPF6_PATH_TYPE_SUBSTR (route->path.type),
hasso049207c2004-08-04 20:02:13 +0000650 destination, nexthop, ifname, duration, VNL);
hasso508e53e2004-05-18 18:57:06 +0000651
652 for (i = 1; ospf6_nexthop_is_set (&route->nexthop[i]) &&
653 i < OSPF6_MULTI_PATH_LIMIT; i++)
654 {
655 /* nexthop */
656 inet_ntop (AF_INET6, &route->nexthop[i].address, nexthop,
657 sizeof (nexthop));
658 if (! if_indextoname (route->nexthop[i].ifindex, ifname))
659 snprintf (ifname, sizeof (ifname), "%d", route->nexthop[i].ifindex);
660
661 vty_out (vty, "%c%1s %2s %-30s %-25s %6s %s%s",
hasso049207c2004-08-04 20:02:13 +0000662 ' ', "", "", "", nexthop, ifname, "", VNL);
hasso508e53e2004-05-18 18:57:06 +0000663 }
664}
paul718e3742002-12-13 20:15:29 +0000665
666void
hasso508e53e2004-05-18 18:57:06 +0000667ospf6_route_show_detail (struct vty *vty, struct ospf6_route *route)
paul718e3742002-12-13 20:15:29 +0000668{
hasso508e53e2004-05-18 18:57:06 +0000669 char destination[64], nexthop[64], ifname[IFNAMSIZ];
670 char area_id[16], id[16], adv_router[16], capa[16], options[16];
paul718e3742002-12-13 20:15:29 +0000671 struct timeval now, res;
672 char duration[16];
hasso508e53e2004-05-18 18:57:06 +0000673 int i;
paul718e3742002-12-13 20:15:29 +0000674
675 gettimeofday (&now, (struct timezone *) NULL);
676
677 /* destination */
hasso508e53e2004-05-18 18:57:06 +0000678 if (route->type == OSPF6_DEST_TYPE_LINKSTATE)
679 ospf6_linkstate_prefix2str (&route->prefix, destination,
680 sizeof (destination));
681 else if (route->type == OSPF6_DEST_TYPE_ROUTER)
682 inet_ntop (route->prefix.family, &route->prefix.u.prefix,
683 destination, sizeof (destination));
paul718e3742002-12-13 20:15:29 +0000684 else
hasso508e53e2004-05-18 18:57:06 +0000685 prefix2str (&route->prefix, destination, sizeof (destination));
hasso049207c2004-08-04 20:02:13 +0000686 vty_out (vty, "Destination: %s%s", destination, VNL);
paul718e3742002-12-13 20:15:29 +0000687
hasso508e53e2004-05-18 18:57:06 +0000688 /* destination type */
689 vty_out (vty, "Destination type: %s%s",
690 OSPF6_DEST_TYPE_NAME (route->type),
hasso049207c2004-08-04 20:02:13 +0000691 VNL);
hasso508e53e2004-05-18 18:57:06 +0000692
693 /* Time */
694 timersub (&now, &route->installed, &res);
695 timerstring (&res, duration, sizeof (duration));
hasso049207c2004-08-04 20:02:13 +0000696 vty_out (vty, "Installed Time: %s ago%s", duration, VNL);
hasso508e53e2004-05-18 18:57:06 +0000697
698 timersub (&now, &route->changed, &res);
699 timerstring (&res, duration, sizeof (duration));
hasso049207c2004-08-04 20:02:13 +0000700 vty_out (vty, " Changed Time: %s ago%s", duration, VNL);
hasso508e53e2004-05-18 18:57:06 +0000701
702 /* Debugging info */
703 vty_out (vty, "Lock: %d Flags: %s%s%s%s%s", route->lock,
704 (CHECK_FLAG (route->flag, OSPF6_ROUTE_BEST) ? "B" : "-"),
705 (CHECK_FLAG (route->flag, OSPF6_ROUTE_ADD) ? "A" : "-"),
706 (CHECK_FLAG (route->flag, OSPF6_ROUTE_REMOVE) ? "R" : "-"),
707 (CHECK_FLAG (route->flag, OSPF6_ROUTE_CHANGE) ? "C" : "-"),
hasso049207c2004-08-04 20:02:13 +0000708 VNL);
hasso508e53e2004-05-18 18:57:06 +0000709 vty_out (vty, "Memory: prev: %p this: %p next: %p%s",
hasso049207c2004-08-04 20:02:13 +0000710 route->prev, route, route->next, VNL);
hasso508e53e2004-05-18 18:57:06 +0000711
712 /* Path section */
713
714 /* Area-ID */
715 inet_ntop (AF_INET, &route->path.area_id, area_id, sizeof (area_id));
hasso049207c2004-08-04 20:02:13 +0000716 vty_out (vty, "Associated Area: %s%s", area_id, VNL);
hasso508e53e2004-05-18 18:57:06 +0000717
718 /* Path type */
719 vty_out (vty, "Path Type: %s%s",
hasso049207c2004-08-04 20:02:13 +0000720 OSPF6_PATH_TYPE_NAME (route->path.type), VNL);
hasso508e53e2004-05-18 18:57:06 +0000721
722 /* LS Origin */
723 inet_ntop (AF_INET, &route->path.origin.id, id, sizeof (id));
724 inet_ntop (AF_INET, &route->path.origin.adv_router, adv_router,
725 sizeof (adv_router));
726 vty_out (vty, "LS Origin: %s Id: %s Adv: %s%s",
hasso1e058382004-09-01 21:36:14 +0000727 ospf6_lstype_name (route->path.origin.type),
hasso049207c2004-08-04 20:02:13 +0000728 id, adv_router, VNL);
hasso508e53e2004-05-18 18:57:06 +0000729
730 /* Options */
731 ospf6_options_printbuf (route->path.options, options, sizeof (options));
hasso049207c2004-08-04 20:02:13 +0000732 vty_out (vty, "Options: %s%s", options, VNL);
hasso508e53e2004-05-18 18:57:06 +0000733
734 /* Router Bits */
735 ospf6_capability_printbuf (route->path.router_bits, capa, sizeof (capa));
hasso049207c2004-08-04 20:02:13 +0000736 vty_out (vty, "Router Bits: %s%s", capa, VNL);
hasso508e53e2004-05-18 18:57:06 +0000737
738 /* Prefix Options */
hasso049207c2004-08-04 20:02:13 +0000739 vty_out (vty, "Prefix Options: xxx%s", VNL);
hasso508e53e2004-05-18 18:57:06 +0000740
741 /* Metrics */
742 vty_out (vty, "Metric Type: %d%s", route->path.metric_type,
hasso049207c2004-08-04 20:02:13 +0000743 VNL);
hasso508e53e2004-05-18 18:57:06 +0000744 vty_out (vty, "Metric: %d (%d)%s",
hasso049207c2004-08-04 20:02:13 +0000745 route->path.cost, route->path.cost_e2, VNL);
hasso508e53e2004-05-18 18:57:06 +0000746
747 /* Nexthops */
hasso049207c2004-08-04 20:02:13 +0000748 vty_out (vty, "Nexthop:%s", VNL);
hasso508e53e2004-05-18 18:57:06 +0000749 for (i = 0; ospf6_nexthop_is_set (&route->nexthop[i]) &&
750 i < OSPF6_MULTI_PATH_LIMIT; i++)
paul718e3742002-12-13 20:15:29 +0000751 {
hasso508e53e2004-05-18 18:57:06 +0000752 /* nexthop */
753 inet_ntop (AF_INET6, &route->nexthop[i].address, nexthop,
754 sizeof (nexthop));
755 if (! if_indextoname (route->nexthop[i].ifindex, ifname))
756 snprintf (ifname, sizeof (ifname), "%d", route->nexthop[i].ifindex);
hasso049207c2004-08-04 20:02:13 +0000757 vty_out (vty, " %s %s%s", nexthop, ifname, VNL);
paul718e3742002-12-13 20:15:29 +0000758 }
hasso049207c2004-08-04 20:02:13 +0000759 vty_out (vty, "%s", VNL);
paul718e3742002-12-13 20:15:29 +0000760}
761
762void
hasso508e53e2004-05-18 18:57:06 +0000763ospf6_route_show_table_summary (struct vty *vty,
764 struct ospf6_route_table *table)
paul718e3742002-12-13 20:15:29 +0000765{
hasso508e53e2004-05-18 18:57:06 +0000766 struct ospf6_route *route, *prev = NULL;
767 int i, pathtype[OSPF6_PATH_TYPE_MAX];
768 int number = 0;
769 int nhinval = 0, ecmp = 0;
hasso4846ef62004-09-03 06:04:00 +0000770 int alternative = 0, destination = 0;
paul718e3742002-12-13 20:15:29 +0000771
hasso508e53e2004-05-18 18:57:06 +0000772 for (i = 0; i < OSPF6_PATH_TYPE_MAX; i++)
773 pathtype[i] = 0;
paul718e3742002-12-13 20:15:29 +0000774
hasso508e53e2004-05-18 18:57:06 +0000775 for (route = ospf6_route_head (table); route;
776 route = ospf6_route_next (route))
paul718e3742002-12-13 20:15:29 +0000777 {
hasso508e53e2004-05-18 18:57:06 +0000778 if (prev == NULL || ! ospf6_route_is_same (prev, route))
779 destination++;
780 else
hasso4846ef62004-09-03 06:04:00 +0000781 alternative++;
hasso508e53e2004-05-18 18:57:06 +0000782 if (! ospf6_nexthop_is_set (&route->nexthop[0]))
783 nhinval++;
784 else if (ospf6_nexthop_is_set (&route->nexthop[1]))
785 ecmp++;
hasso4846ef62004-09-03 06:04:00 +0000786 pathtype[route->path.type]++;
hasso508e53e2004-05-18 18:57:06 +0000787 number++;
hasso4846ef62004-09-03 06:04:00 +0000788
hasso508e53e2004-05-18 18:57:06 +0000789 prev = route;
paul718e3742002-12-13 20:15:29 +0000790 }
hasso508e53e2004-05-18 18:57:06 +0000791
792 assert (number == table->count);
hasso508e53e2004-05-18 18:57:06 +0000793
hasso4846ef62004-09-03 06:04:00 +0000794 vty_out (vty, "Number of OSPFv3 routes: %d%s", number, VNL);
795 vty_out (vty, "Number of Destination: %d%s", destination, VNL);
796 vty_out (vty, "Number of Alternative routes: %d%s", alternative, VNL);
797 vty_out (vty, "Number of Equal Cost Multi Path: %d%s", ecmp, VNL);
798 for (i = OSPF6_PATH_TYPE_INTRA; i <= OSPF6_PATH_TYPE_EXTERNAL2; i++)
hasso508e53e2004-05-18 18:57:06 +0000799 {
hasso4846ef62004-09-03 06:04:00 +0000800 vty_out (vty, "Number of %s routes: %d%s",
801 OSPF6_PATH_TYPE_NAME (i), pathtype[i], VNL);
802 }
803}
804
805void
806ospf6_route_show_table_prefix (struct vty *vty,
807 struct prefix *prefix,
808 struct ospf6_route_table *table)
809{
810 struct ospf6_route *route;
811
812 route = ospf6_route_lookup (prefix, table);
813 if (route == NULL)
814 return;
815
816 ospf6_route_lock (route);
817 while (route && ospf6_route_is_prefix (prefix, route))
818 {
819 /* Specifying a prefix will always display details */
820 ospf6_route_show_detail (vty, route);
821 route = ospf6_route_next (route);
822 }
823 if (route)
824 ospf6_route_unlock (route);
825}
826
827void
828ospf6_route_show_table_address (struct vty *vty,
829 struct prefix *prefix,
830 struct ospf6_route_table *table)
831{
832 struct ospf6_route *route;
833
834 route = ospf6_route_lookup_bestmatch (prefix, table);
835 if (route == NULL)
836 return;
837
838 prefix = &route->prefix;
839 ospf6_route_lock (route);
840 while (route && ospf6_route_is_prefix (prefix, route))
841 {
842 /* Specifying a prefix will always display details */
843 ospf6_route_show_detail (vty, route);
844 route = ospf6_route_next (route);
845 }
846 if (route)
847 ospf6_route_unlock (route);
848}
849
850void
851ospf6_route_show_table_match (struct vty *vty, int detail,
852 struct prefix *prefix,
853 struct ospf6_route_table *table)
854{
855 struct ospf6_route *route;
856 assert (prefix->family);
857
858 route = ospf6_route_match_head (prefix, table);
859 while (route)
860 {
861 if (detail)
862 ospf6_route_show_detail (vty, route);
863 else
864 ospf6_route_show (vty, route);
865 route = ospf6_route_match_next (prefix, route);
866 }
867}
868
869void
870ospf6_route_show_table_type (struct vty *vty, int detail, u_char type,
871 struct ospf6_route_table *table)
872{
873 struct ospf6_route *route;
874
875 route = ospf6_route_head (table);
876 while (route)
877 {
878 if (route->path.type == type)
879 {
880 if (detail)
881 ospf6_route_show_detail (vty, route);
882 else
883 ospf6_route_show (vty, route);
884 }
885 route = ospf6_route_next (route);
886 }
887}
888
889void
890ospf6_route_show_table (struct vty *vty, int detail,
891 struct ospf6_route_table *table)
892{
893 struct ospf6_route *route;
894
895 route = ospf6_route_head (table);
896 while (route)
897 {
898 if (detail)
899 ospf6_route_show_detail (vty, route);
900 else
901 ospf6_route_show (vty, route);
902 route = ospf6_route_next (route);
hasso508e53e2004-05-18 18:57:06 +0000903 }
paul718e3742002-12-13 20:15:29 +0000904}
905
906int
907ospf6_route_table_show (struct vty *vty, int argc, char **argv,
908 struct ospf6_route_table *table)
909{
hasso4846ef62004-09-03 06:04:00 +0000910 int summary = 0;
911 int match = 0;
912 int detail = 0;
913 int slash = 0;
914 int isprefix = 0;
paul718e3742002-12-13 20:15:29 +0000915 int i, ret;
hasso4846ef62004-09-03 06:04:00 +0000916 struct prefix prefix;
917 u_char type = 0;
paul718e3742002-12-13 20:15:29 +0000918
919 memset (&prefix, 0, sizeof (struct prefix));
920
921 for (i = 0; i < argc; i++)
922 {
hasso508e53e2004-05-18 18:57:06 +0000923 if (! strcmp (argv[i], "summary"))
924 {
hasso4846ef62004-09-03 06:04:00 +0000925 summary++;
hasso508e53e2004-05-18 18:57:06 +0000926 continue;
927 }
928
hasso4846ef62004-09-03 06:04:00 +0000929 if (! strcmp (argv[i], "intra-area"))
930 {
931 type = OSPF6_PATH_TYPE_INTRA;
932 continue;
933 }
934
935 if (! strcmp (argv[i], "inter-area"))
936 {
937 type = OSPF6_PATH_TYPE_INTER;
938 continue;
939 }
940
941 if (! strcmp (argv[i], "external-1"))
942 {
943 type = OSPF6_PATH_TYPE_EXTERNAL1;
944 continue;
945 }
946
947 if (! strcmp (argv[i], "external-2"))
948 {
949 type = OSPF6_PATH_TYPE_EXTERNAL2;
950 continue;
951 }
952
paul718e3742002-12-13 20:15:29 +0000953 if (! strcmp (argv[i], "detail"))
954 {
hasso4846ef62004-09-03 06:04:00 +0000955 detail++;
hasso508e53e2004-05-18 18:57:06 +0000956 continue;
paul718e3742002-12-13 20:15:29 +0000957 }
958
hasso508e53e2004-05-18 18:57:06 +0000959 if (! strcmp (argv[i], "match"))
paul718e3742002-12-13 20:15:29 +0000960 {
hasso4846ef62004-09-03 06:04:00 +0000961 match++;
hasso508e53e2004-05-18 18:57:06 +0000962 continue;
paul718e3742002-12-13 20:15:29 +0000963 }
964
hasso508e53e2004-05-18 18:57:06 +0000965 ret = str2prefix (argv[i], &prefix);
hasso4846ef62004-09-03 06:04:00 +0000966 if (ret == 1 && prefix.family == AF_INET6)
hasso508e53e2004-05-18 18:57:06 +0000967 {
hasso4846ef62004-09-03 06:04:00 +0000968 isprefix++;
969 if (strchr (argv[i], '/'))
970 slash++;
971 continue;
hasso508e53e2004-05-18 18:57:06 +0000972 }
973
hasso4846ef62004-09-03 06:04:00 +0000974 vty_out (vty, "Malformed argument: %s%s", argv[i], VNL);
975 return CMD_SUCCESS;
paul718e3742002-12-13 20:15:29 +0000976 }
977
hasso508e53e2004-05-18 18:57:06 +0000978 /* Give summary of this route table */
hasso4846ef62004-09-03 06:04:00 +0000979 if (summary)
paul718e3742002-12-13 20:15:29 +0000980 {
hasso508e53e2004-05-18 18:57:06 +0000981 ospf6_route_show_table_summary (vty, table);
paul718e3742002-12-13 20:15:29 +0000982 return CMD_SUCCESS;
983 }
984
hasso508e53e2004-05-18 18:57:06 +0000985 /* Give exact prefix-match route */
hasso4846ef62004-09-03 06:04:00 +0000986 if (isprefix && ! match)
paul718e3742002-12-13 20:15:29 +0000987 {
hasso508e53e2004-05-18 18:57:06 +0000988 /* If exact address, give best matching route */
hasso4846ef62004-09-03 06:04:00 +0000989 if (! slash)
990 ospf6_route_show_table_address (vty, &prefix, table);
hasso508e53e2004-05-18 18:57:06 +0000991 else
hasso4846ef62004-09-03 06:04:00 +0000992 ospf6_route_show_table_prefix (vty, &prefix, table);
hasso508e53e2004-05-18 18:57:06 +0000993
994 return CMD_SUCCESS;
paul718e3742002-12-13 20:15:29 +0000995 }
996
hasso4846ef62004-09-03 06:04:00 +0000997 if (match)
998 ospf6_route_show_table_match (vty, detail, &prefix, table);
999 else if (type)
1000 ospf6_route_show_table_type (vty, detail, type, table);
hasso508e53e2004-05-18 18:57:06 +00001001 else
hasso4846ef62004-09-03 06:04:00 +00001002 ospf6_route_show_table (vty, detail, table);
paul718e3742002-12-13 20:15:29 +00001003
paul718e3742002-12-13 20:15:29 +00001004 return CMD_SUCCESS;
1005}
1006
hasso4846ef62004-09-03 06:04:00 +00001007void
1008ospf6_linkstate_show_header (struct vty *vty)
hasso508e53e2004-05-18 18:57:06 +00001009{
hasso4846ef62004-09-03 06:04:00 +00001010 vty_out (vty, "%-7s %-15s %-15s %-8s %-14s %s%s",
1011 "Type", "Router-ID", "Net-ID", "Rtr-Bits", "Options", "Cost", VNL);
1012}
1013
1014void
1015ospf6_linkstate_show (struct vty *vty, struct ospf6_route *route)
1016{
1017 u_int32_t router, id;
1018 char routername[16], idname[16], rbits[16], options[16];
1019
1020 router = ospf6_linkstate_prefix_adv_router (&route->prefix);
1021 inet_ntop (AF_INET, &router, routername, sizeof (routername));
1022 id = ospf6_linkstate_prefix_id (&route->prefix);
1023 inet_ntop (AF_INET, &id, idname, sizeof (idname));
1024
1025 ospf6_capability_printbuf (route->path.router_bits, rbits, sizeof (rbits));
1026 ospf6_options_printbuf (route->path.options, options, sizeof (options));
1027
1028 if (ntohl (id))
1029 vty_out (vty, "%-7s %-15s %-15s %-8s %-14s %lu%s",
1030 "Network", routername, idname, rbits, options,
1031 (unsigned long) route->path.cost, VNL);
1032 else
1033 vty_out (vty, "%-7s %-15s %-15s %-8s %-14s %lu%s",
1034 "Router", routername, idname, rbits, options,
1035 (unsigned long) route->path.cost, VNL);
1036}
1037
1038
1039void
1040ospf6_linkstate_show_table_exact (struct vty *vty,
1041 struct prefix *prefix,
1042 struct ospf6_route_table *table)
1043{
hasso508e53e2004-05-18 18:57:06 +00001044 struct ospf6_route *route;
1045
hasso4846ef62004-09-03 06:04:00 +00001046 route = ospf6_route_lookup (prefix, table);
1047 if (route == NULL)
1048 return;
1049
1050 ospf6_route_lock (route);
1051 while (route && ospf6_route_is_prefix (prefix, route))
1052 {
1053 /* Specifying a prefix will always display details */
1054 ospf6_route_show_detail (vty, route);
1055 route = ospf6_route_next (route);
1056 }
1057 if (route)
1058 ospf6_route_unlock (route);
1059}
1060
1061void
1062ospf6_linkstate_show_table (struct vty *vty, int detail,
1063 struct ospf6_route_table *table)
1064{
1065 struct ospf6_route *route;
1066
1067 if (! detail)
1068 ospf6_linkstate_show_header (vty);
1069
1070 route = ospf6_route_head (table);
1071 while (route)
1072 {
1073 if (detail)
1074 ospf6_route_show_detail (vty, route);
1075 else
1076 ospf6_linkstate_show (vty, route);
1077 route = ospf6_route_next (route);
1078 }
1079}
1080
1081int
1082ospf6_linkstate_table_show (struct vty *vty, int argc, char **argv,
1083 struct ospf6_route_table *table)
1084{
1085 int detail = 0;
1086 int is_id = 0;
1087 int is_router = 0;
1088 int i, ret;
1089 struct prefix router, id, prefix;
1090
1091 memset (&router, 0, sizeof (struct prefix));
hasso508e53e2004-05-18 18:57:06 +00001092 memset (&id, 0, sizeof (struct prefix));
hasso4846ef62004-09-03 06:04:00 +00001093 memset (&prefix, 0, sizeof (struct prefix));
hasso508e53e2004-05-18 18:57:06 +00001094
1095 for (i = 0; i < argc; i++)
1096 {
hasso508e53e2004-05-18 18:57:06 +00001097 if (! strcmp (argv[i], "detail"))
1098 {
hasso4846ef62004-09-03 06:04:00 +00001099 detail++;
hasso508e53e2004-05-18 18:57:06 +00001100 continue;
1101 }
1102
hasso4846ef62004-09-03 06:04:00 +00001103 if (! is_router)
hasso508e53e2004-05-18 18:57:06 +00001104 {
hasso4846ef62004-09-03 06:04:00 +00001105 ret = str2prefix (argv[i], &router);
1106 if (ret == 1 && router.family == AF_INET)
1107 {
1108 is_router++;
1109 continue;
1110 }
1111 vty_out (vty, "Malformed argument: %s%s", argv[i], VNL);
hasso508e53e2004-05-18 18:57:06 +00001112 return CMD_SUCCESS;
1113 }
1114
hasso4846ef62004-09-03 06:04:00 +00001115 if (! is_id)
hasso508e53e2004-05-18 18:57:06 +00001116 {
hasso508e53e2004-05-18 18:57:06 +00001117 ret = str2prefix (argv[i], &id);
hasso4846ef62004-09-03 06:04:00 +00001118 if (ret == 1 && id.family == AF_INET)
hasso508e53e2004-05-18 18:57:06 +00001119 {
hasso4846ef62004-09-03 06:04:00 +00001120 is_id++;
1121 continue;
hasso508e53e2004-05-18 18:57:06 +00001122 }
hasso4846ef62004-09-03 06:04:00 +00001123 vty_out (vty, "Malformed argument: %s%s", argv[i], VNL);
hasso508e53e2004-05-18 18:57:06 +00001124 return CMD_SUCCESS;
1125 }
1126
hasso4846ef62004-09-03 06:04:00 +00001127 vty_out (vty, "Malformed argument: %s%s", argv[i], VNL);
hasso508e53e2004-05-18 18:57:06 +00001128 return CMD_SUCCESS;
1129 }
1130
hasso4846ef62004-09-03 06:04:00 +00001131 if (is_router)
1132 ospf6_linkstate_prefix (router.u.prefix4.s_addr,
1133 id.u.prefix4.s_addr, &prefix);
1134
1135 if (prefix.family)
1136 ospf6_linkstate_show_table_exact (vty, &prefix, table);
hasso508e53e2004-05-18 18:57:06 +00001137 else
hasso4846ef62004-09-03 06:04:00 +00001138 ospf6_linkstate_show_table (vty, detail, table);
hasso508e53e2004-05-18 18:57:06 +00001139
1140 return CMD_SUCCESS;
1141}
1142
hasso4846ef62004-09-03 06:04:00 +00001143
hasso6452df02004-08-15 05:52:07 +00001144void
1145ospf6_brouter_show_header (struct vty *vty)
1146{
1147 vty_out (vty, "%-15s %-8s %-14s %-10s %-15s%s",
1148 "Router-ID", "Rtr-Bits", "Options", "Path-Type", "Area", VNL);
1149}
1150
1151void
1152ospf6_brouter_show (struct vty *vty, struct ospf6_route *route)
1153{
1154 u_int32_t adv_router;
1155 char adv[16], rbits[16], options[16], area[16];
1156
1157 adv_router = ospf6_linkstate_prefix_adv_router (&route->prefix);
1158 inet_ntop (AF_INET, &adv_router, adv, sizeof (adv));
1159 ospf6_capability_printbuf (route->path.router_bits, rbits, sizeof (rbits));
1160 ospf6_options_printbuf (route->path.options, options, sizeof (options));
1161 inet_ntop (AF_INET, &route->path.area_id, area, sizeof (area));
1162
1163 /* vty_out (vty, "%-15s %-8s %-14s %-10s %-15s%s",
1164 "Router-ID", "Rtr-Bits", "Options", "Path-Type", "Area", VNL); */
1165 vty_out (vty, "%-15s %-8s %-14s %-10s %-15s%s",
1166 adv, rbits, options, OSPF6_PATH_TYPE_NAME (route->path.type),
1167 area, VNL);
1168}
1169
hasso508e53e2004-05-18 18:57:06 +00001170DEFUN (debug_ospf6_route,
1171 debug_ospf6_route_cmd,
1172 "debug ospf6 route (table|intra-area|inter-area)",
1173 DEBUG_STR
1174 OSPF6_STR
1175 "Debug route table calculation\n"
1176 "Debug detail\n"
1177 "Debug intra-area route calculation\n"
1178 "Debug inter-area route calculation\n"
1179 )
1180{
1181 unsigned char level = 0;
1182
1183 if (! strncmp (argv[0], "table", 5))
1184 level = OSPF6_DEBUG_ROUTE_TABLE;
1185 else if (! strncmp (argv[0], "intra", 5))
1186 level = OSPF6_DEBUG_ROUTE_INTRA;
1187 else if (! strncmp (argv[0], "inter", 5))
1188 level = OSPF6_DEBUG_ROUTE_INTER;
1189 OSPF6_DEBUG_ROUTE_ON (level);
1190 return CMD_SUCCESS;
1191}
1192
1193DEFUN (no_debug_ospf6_route,
1194 no_debug_ospf6_route_cmd,
1195 "no debug ospf6 route (table|intra-area|inter-area)",
1196 NO_STR
1197 DEBUG_STR
1198 OSPF6_STR
1199 "Debug route table calculation\n"
1200 "Debug intra-area route calculation\n")
1201{
1202 unsigned char level = 0;
1203
1204 if (! strncmp (argv[0], "table", 5))
1205 level = OSPF6_DEBUG_ROUTE_TABLE;
1206 else if (! strncmp (argv[0], "intra", 5))
1207 level = OSPF6_DEBUG_ROUTE_INTRA;
1208 else if (! strncmp (argv[0], "inter", 5))
1209 level = OSPF6_DEBUG_ROUTE_INTER;
1210 OSPF6_DEBUG_ROUTE_OFF (level);
1211 return CMD_SUCCESS;
1212}
1213
1214int
1215config_write_ospf6_debug_route (struct vty *vty)
1216{
1217 if (IS_OSPF6_DEBUG_ROUTE (TABLE))
hasso049207c2004-08-04 20:02:13 +00001218 vty_out (vty, "debug ospf6 route table%s", VNL);
hasso508e53e2004-05-18 18:57:06 +00001219 if (IS_OSPF6_DEBUG_ROUTE (INTRA))
hasso049207c2004-08-04 20:02:13 +00001220 vty_out (vty, "debug ospf6 route intra-area%s", VNL);
hasso508e53e2004-05-18 18:57:06 +00001221 if (IS_OSPF6_DEBUG_ROUTE (INTER))
hasso049207c2004-08-04 20:02:13 +00001222 vty_out (vty, "debug ospf6 route inter-area%s", VNL);
hasso508e53e2004-05-18 18:57:06 +00001223 return 0;
1224}
1225
1226void
1227install_element_ospf6_debug_route ()
1228{
1229 install_element (ENABLE_NODE, &debug_ospf6_route_cmd);
1230 install_element (ENABLE_NODE, &no_debug_ospf6_route_cmd);
1231 install_element (CONFIG_NODE, &debug_ospf6_route_cmd);
1232 install_element (CONFIG_NODE, &no_debug_ospf6_route_cmd);
1233}
1234
1235
1236