blob: 2a738cb6dea544e4e6d929e059baf9d6c7b4d2ec [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 "linklist.h"
27#include "thread.h"
28#include "vty.h"
29#include "command.h"
30#include "if.h"
31#include "prefix.h"
32#include "table.h"
33
hasso508e53e2004-05-18 18:57:06 +000034#include "ospf6_proto.h"
35#include "ospf6_lsa.h"
36#include "ospf6_lsdb.h"
37#include "ospf6_route.h"
38#include "ospf6_spf.h"
39#include "ospf6_top.h"
40#include "ospf6_area.h"
41#include "ospf6_interface.h"
42#include "ospf6_intra.h"
hasso049207c2004-08-04 20:02:13 +000043#include "ospf6_abr.h"
44#include "ospf6d.h"
paul718e3742002-12-13 20:15:29 +000045
hasso508e53e2004-05-18 18:57:06 +000046int
47ospf6_area_cmp (void *va, void *vb)
paul718e3742002-12-13 20:15:29 +000048{
hasso508e53e2004-05-18 18:57:06 +000049 struct ospf6_area *oa = (struct ospf6_area *) va;
50 struct ospf6_area *ob = (struct ospf6_area *) vb;
hasso6452df02004-08-15 05:52:07 +000051 return (ntohl (oa->area_id) < ntohl (ob->area_id) ? -1 : 1);
paul718e3742002-12-13 20:15:29 +000052}
53
hasso508e53e2004-05-18 18:57:06 +000054/* schedule routing table recalculation */
paul718e3742002-12-13 20:15:29 +000055void
hasso508e53e2004-05-18 18:57:06 +000056ospf6_area_lsdb_hook_add (struct ospf6_lsa *lsa)
paul718e3742002-12-13 20:15:29 +000057{
hasso508e53e2004-05-18 18:57:06 +000058 switch (ntohs (lsa->header->type))
paul718e3742002-12-13 20:15:29 +000059 {
hasso508e53e2004-05-18 18:57:06 +000060 case OSPF6_LSTYPE_ROUTER:
61 case OSPF6_LSTYPE_NETWORK:
hasso1e058382004-09-01 21:36:14 +000062 if (IS_OSPF6_DEBUG_EXAMIN_TYPE (lsa->header->type))
63 {
hassoc6487d62004-12-24 06:00:11 +000064 zlog_debug ("Examin %s", lsa->name);
65 zlog_debug ("Schedule SPF Calculation for %s",
66 OSPF6_AREA (lsa->lsdb->data)->name);
hasso1e058382004-09-01 21:36:14 +000067 }
hasso6452df02004-08-15 05:52:07 +000068 ospf6_spf_schedule (OSPF6_AREA (lsa->lsdb->data));
hasso508e53e2004-05-18 18:57:06 +000069 break;
paul718e3742002-12-13 20:15:29 +000070
hasso508e53e2004-05-18 18:57:06 +000071 case OSPF6_LSTYPE_INTRA_PREFIX:
72 ospf6_intra_prefix_lsa_add (lsa);
73 break;
74
75 case OSPF6_LSTYPE_INTER_PREFIX:
76 case OSPF6_LSTYPE_INTER_ROUTER:
hassoccb59b12004-08-25 09:10:37 +000077 ospf6_abr_examin_summary (lsa, (struct ospf6_area *) lsa->lsdb->data);
hasso508e53e2004-05-18 18:57:06 +000078 break;
79
80 default:
hasso508e53e2004-05-18 18:57:06 +000081 break;
82 }
paul718e3742002-12-13 20:15:29 +000083}
84
85void
hasso508e53e2004-05-18 18:57:06 +000086ospf6_area_lsdb_hook_remove (struct ospf6_lsa *lsa)
paul718e3742002-12-13 20:15:29 +000087{
hasso508e53e2004-05-18 18:57:06 +000088 switch (ntohs (lsa->header->type))
paul718e3742002-12-13 20:15:29 +000089 {
hasso508e53e2004-05-18 18:57:06 +000090 case OSPF6_LSTYPE_ROUTER:
91 case OSPF6_LSTYPE_NETWORK:
hasso1e058382004-09-01 21:36:14 +000092 if (IS_OSPF6_DEBUG_EXAMIN_TYPE (lsa->header->type))
93 {
hassoc6487d62004-12-24 06:00:11 +000094 zlog_debug ("LSA disappearing: %s", lsa->name);
95 zlog_debug ("Schedule SPF Calculation for %s",
hasso1e058382004-09-01 21:36:14 +000096 OSPF6_AREA (lsa->lsdb->data)->name);
97 }
hasso6452df02004-08-15 05:52:07 +000098 ospf6_spf_schedule (OSPF6_AREA (lsa->lsdb->data));
hasso508e53e2004-05-18 18:57:06 +000099 break;
paul718e3742002-12-13 20:15:29 +0000100
hasso508e53e2004-05-18 18:57:06 +0000101 case OSPF6_LSTYPE_INTRA_PREFIX:
102 ospf6_intra_prefix_lsa_remove (lsa);
103 break;
104
105 case OSPF6_LSTYPE_INTER_PREFIX:
106 case OSPF6_LSTYPE_INTER_ROUTER:
hassoccb59b12004-08-25 09:10:37 +0000107 ospf6_abr_examin_summary (lsa, (struct ospf6_area *) lsa->lsdb->data);
hasso508e53e2004-05-18 18:57:06 +0000108 break;
109
110 default:
hasso508e53e2004-05-18 18:57:06 +0000111 break;
112 }
113}
114
115void
116ospf6_area_route_hook_add (struct ospf6_route *route)
117{
118 struct ospf6_route *copy = ospf6_route_copy (route);
119 ospf6_route_add (copy, ospf6->route_table);
120}
121
122void
123ospf6_area_route_hook_remove (struct ospf6_route *route)
124{
125 struct ospf6_route *copy;
126
127 copy = ospf6_route_lookup_identical (route, ospf6->route_table);
128 if (copy)
129 ospf6_route_remove (copy, ospf6->route_table);
paul718e3742002-12-13 20:15:29 +0000130}
131
132/* Make new area structure */
133struct ospf6_area *
hasso508e53e2004-05-18 18:57:06 +0000134ospf6_area_create (u_int32_t area_id, struct ospf6 *o)
paul718e3742002-12-13 20:15:29 +0000135{
hasso508e53e2004-05-18 18:57:06 +0000136 struct ospf6_area *oa;
hasso049207c2004-08-04 20:02:13 +0000137 struct ospf6_route *route;
paul718e3742002-12-13 20:15:29 +0000138
hasso508e53e2004-05-18 18:57:06 +0000139 oa = XCALLOC (MTYPE_OSPF6_AREA, sizeof (struct ospf6_area));
paul718e3742002-12-13 20:15:29 +0000140
hasso508e53e2004-05-18 18:57:06 +0000141 inet_ntop (AF_INET, &area_id, oa->name, sizeof (oa->name));
142 oa->area_id = area_id;
143 oa->if_list = list_new ();
paul718e3742002-12-13 20:15:29 +0000144
hasso6452df02004-08-15 05:52:07 +0000145 oa->lsdb = ospf6_lsdb_create (oa);
hasso508e53e2004-05-18 18:57:06 +0000146 oa->lsdb->hook_add = ospf6_area_lsdb_hook_add;
147 oa->lsdb->hook_remove = ospf6_area_lsdb_hook_remove;
hasso6452df02004-08-15 05:52:07 +0000148 oa->lsdb_self = ospf6_lsdb_create (oa);
paul718e3742002-12-13 20:15:29 +0000149
hasso508e53e2004-05-18 18:57:06 +0000150 oa->spf_table = ospf6_route_table_create ();
151 oa->route_table = ospf6_route_table_create ();
152 oa->route_table->hook_add = ospf6_area_route_hook_add;
153 oa->route_table->hook_remove = ospf6_area_route_hook_remove;
paul718e3742002-12-13 20:15:29 +0000154
hasso6452df02004-08-15 05:52:07 +0000155 oa->range_table = ospf6_route_table_create ();
156 oa->summary_prefix = ospf6_route_table_create ();
157 oa->summary_router = ospf6_route_table_create ();
158
hasso508e53e2004-05-18 18:57:06 +0000159 /* set default options */
160 OSPF6_OPT_SET (oa->options, OSPF6_OPT_V6);
161 OSPF6_OPT_SET (oa->options, OSPF6_OPT_E);
162 OSPF6_OPT_SET (oa->options, OSPF6_OPT_R);
paul718e3742002-12-13 20:15:29 +0000163
hasso508e53e2004-05-18 18:57:06 +0000164 oa->ospf6 = o;
165 listnode_add_sort (o->area_list, oa);
paul718e3742002-12-13 20:15:29 +0000166
hasso049207c2004-08-04 20:02:13 +0000167 /* import athoer area's routes as inter-area routes */
168 for (route = ospf6_route_head (o->route_table); route;
169 route = ospf6_route_next (route))
hasso6452df02004-08-15 05:52:07 +0000170 ospf6_abr_originate_summary_to_area (route, oa);
hasso049207c2004-08-04 20:02:13 +0000171
hasso508e53e2004-05-18 18:57:06 +0000172 return oa;
paul718e3742002-12-13 20:15:29 +0000173}
174
175void
hasso508e53e2004-05-18 18:57:06 +0000176ospf6_area_delete (struct ospf6_area *oa)
paul718e3742002-12-13 20:15:29 +0000177{
hasso52dc7ee2004-09-23 19:18:23 +0000178 struct listnode *n;
hasso508e53e2004-05-18 18:57:06 +0000179 struct ospf6_interface *oi;
paul718e3742002-12-13 20:15:29 +0000180
hasso6452df02004-08-15 05:52:07 +0000181 ospf6_route_table_delete (oa->range_table);
182 ospf6_route_table_delete (oa->summary_prefix);
183 ospf6_route_table_delete (oa->summary_router);
hasso049207c2004-08-04 20:02:13 +0000184
paul718e3742002-12-13 20:15:29 +0000185 /* ospf6 interface list */
hasso508e53e2004-05-18 18:57:06 +0000186 for (n = listhead (oa->if_list); n; nextnode (n))
paul718e3742002-12-13 20:15:29 +0000187 {
hasso508e53e2004-05-18 18:57:06 +0000188 oi = (struct ospf6_interface *) getdata (n);
189 ospf6_interface_delete (oi);
paul718e3742002-12-13 20:15:29 +0000190 }
hasso508e53e2004-05-18 18:57:06 +0000191 list_delete (oa->if_list);
paul718e3742002-12-13 20:15:29 +0000192
hasso508e53e2004-05-18 18:57:06 +0000193 ospf6_lsdb_delete (oa->lsdb);
hasso6452df02004-08-15 05:52:07 +0000194 ospf6_lsdb_delete (oa->lsdb_self);
195
hasso508e53e2004-05-18 18:57:06 +0000196 ospf6_route_table_delete (oa->spf_table);
197 ospf6_route_table_delete (oa->route_table);
paul718e3742002-12-13 20:15:29 +0000198
hasso508e53e2004-05-18 18:57:06 +0000199#if 0
200 ospf6_spftree_delete (oa->spf_tree);
201 ospf6_route_table_delete (oa->topology_table);
202#endif /*0*/
paul718e3742002-12-13 20:15:29 +0000203
hasso508e53e2004-05-18 18:57:06 +0000204 THREAD_OFF (oa->thread_spf_calculation);
205 THREAD_OFF (oa->thread_route_calculation);
paul718e3742002-12-13 20:15:29 +0000206
hasso508e53e2004-05-18 18:57:06 +0000207 listnode_delete (oa->ospf6->area_list, oa);
208 oa->ospf6 = NULL;
paul718e3742002-12-13 20:15:29 +0000209
210 /* free area */
hasso508e53e2004-05-18 18:57:06 +0000211 XFREE (MTYPE_OSPF6_AREA, oa);
paul718e3742002-12-13 20:15:29 +0000212}
213
214struct ospf6_area *
hasso508e53e2004-05-18 18:57:06 +0000215ospf6_area_lookup (u_int32_t area_id, struct ospf6 *ospf6)
paul718e3742002-12-13 20:15:29 +0000216{
hasso508e53e2004-05-18 18:57:06 +0000217 struct ospf6_area *oa;
hasso52dc7ee2004-09-23 19:18:23 +0000218 struct listnode *n;
paul718e3742002-12-13 20:15:29 +0000219
hasso508e53e2004-05-18 18:57:06 +0000220 for (n = listhead (ospf6->area_list); n; nextnode (n))
paul718e3742002-12-13 20:15:29 +0000221 {
hasso508e53e2004-05-18 18:57:06 +0000222 oa = (struct ospf6_area *) getdata (n);
223 if (oa->area_id == area_id)
224 return oa;
paul718e3742002-12-13 20:15:29 +0000225 }
226
227 return (struct ospf6_area *) NULL;
228}
229
hasso6452df02004-08-15 05:52:07 +0000230struct ospf6_area *
231ospf6_area_get (u_int32_t area_id, struct ospf6 *o)
232{
233 struct ospf6_area *oa;
234 oa = ospf6_area_lookup (area_id, o);
235 if (oa == NULL)
236 oa = ospf6_area_create (area_id, o);
237 return oa;
238}
239
paul718e3742002-12-13 20:15:29 +0000240void
hasso508e53e2004-05-18 18:57:06 +0000241ospf6_area_enable (struct ospf6_area *oa)
paul718e3742002-12-13 20:15:29 +0000242{
hasso52dc7ee2004-09-23 19:18:23 +0000243 struct listnode *i;
hasso508e53e2004-05-18 18:57:06 +0000244 struct ospf6_interface *oi;
paul718e3742002-12-13 20:15:29 +0000245
hasso6452df02004-08-15 05:52:07 +0000246 SET_FLAG (oa->flag, OSPF6_AREA_ENABLE);
paul718e3742002-12-13 20:15:29 +0000247
hasso508e53e2004-05-18 18:57:06 +0000248 for (i = listhead (oa->if_list); i; nextnode (i))
paul718e3742002-12-13 20:15:29 +0000249 {
hasso508e53e2004-05-18 18:57:06 +0000250 oi = (struct ospf6_interface *) getdata (i);
251 ospf6_interface_enable (oi);
paul718e3742002-12-13 20:15:29 +0000252 }
253}
254
255void
hasso508e53e2004-05-18 18:57:06 +0000256ospf6_area_disable (struct ospf6_area *oa)
paul718e3742002-12-13 20:15:29 +0000257{
hasso52dc7ee2004-09-23 19:18:23 +0000258 struct listnode *i;
hasso508e53e2004-05-18 18:57:06 +0000259 struct ospf6_interface *oi;
paul718e3742002-12-13 20:15:29 +0000260
hasso6452df02004-08-15 05:52:07 +0000261 UNSET_FLAG (oa->flag, OSPF6_AREA_ENABLE);
hasso508e53e2004-05-18 18:57:06 +0000262
263 for (i = listhead (oa->if_list); i; nextnode (i))
264 {
265 oi = (struct ospf6_interface *) getdata (i);
266 ospf6_interface_disable (oi);
267 }
paul718e3742002-12-13 20:15:29 +0000268}
269
hasso508e53e2004-05-18 18:57:06 +0000270
271void
272ospf6_area_show (struct vty *vty, struct ospf6_area *oa)
273{
hasso52dc7ee2004-09-23 19:18:23 +0000274 struct listnode *i;
hasso508e53e2004-05-18 18:57:06 +0000275 struct ospf6_interface *oi;
276
hasso049207c2004-08-04 20:02:13 +0000277 vty_out (vty, " Area %s%s", oa->name, VNL);
hasso508e53e2004-05-18 18:57:06 +0000278 vty_out (vty, " Number of Area scoped LSAs is %u%s",
hasso049207c2004-08-04 20:02:13 +0000279 oa->lsdb->count, VNL);
hasso508e53e2004-05-18 18:57:06 +0000280
281 vty_out (vty, " Interface attached to this area:");
282 for (i = listhead (oa->if_list); i; nextnode (i))
283 {
284 oi = (struct ospf6_interface *) getdata (i);
285 vty_out (vty, " %s", oi->interface->name);
286 }
hasso049207c2004-08-04 20:02:13 +0000287 vty_out (vty, "%s", VNL);
hasso508e53e2004-05-18 18:57:06 +0000288}
289
290
hasso049207c2004-08-04 20:02:13 +0000291#define OSPF6_CMD_AREA_LOOKUP(str, oa) \
292{ \
293 u_int32_t area_id = 0; \
294 if (inet_pton (AF_INET, str, &area_id) != 1) \
295 { \
296 vty_out (vty, "Malformed Area-ID: %s%s", str, VNL); \
297 return CMD_SUCCESS; \
298 } \
299 oa = ospf6_area_lookup (area_id, ospf6); \
300 if (oa == NULL) \
301 { \
302 vty_out (vty, "No such Area: %s%s", str, VNL); \
303 return CMD_SUCCESS; \
304 } \
hasso508e53e2004-05-18 18:57:06 +0000305}
306
hasso6452df02004-08-15 05:52:07 +0000307#define OSPF6_CMD_AREA_GET(str, oa) \
308{ \
309 u_int32_t area_id = 0; \
310 if (inet_pton (AF_INET, str, &area_id) != 1) \
311 { \
312 vty_out (vty, "Malformed Area-ID: %s%s", str, VNL); \
313 return CMD_SUCCESS; \
314 } \
315 oa = ospf6_area_get (area_id, ospf6); \
316}
317
318DEFUN (area_range,
319 area_range_cmd,
320 "area A.B.C.D range X:X::X:X/M",
321 "OSPF area parameters\n"
322 OSPF6_AREA_ID_STR
323 "Configured address range\n"
324 "Specify IPv6 prefix\n"
325 )
326{
327 int ret;
328 struct ospf6_area *oa;
329 struct prefix prefix;
330 struct ospf6_route *range;
331
332 OSPF6_CMD_AREA_GET (argv[0], oa);
333 argc--;
334 argv++;
335
336 ret = str2prefix (argv[0], &prefix);
337 if (ret != 1 || prefix.family != AF_INET6)
338 {
339 vty_out (vty, "Malformed argument: %s%s", argv[0], VNL);
340 return CMD_SUCCESS;
341 }
342 argc--;
343 argv++;
344
345 range = ospf6_route_lookup (&prefix, oa->range_table);
346 if (range == NULL)
347 {
348 range = ospf6_route_create ();
349 range->type = OSPF6_DEST_TYPE_RANGE;
350 range->prefix = prefix;
351 }
352
353 if (argc)
354 {
355 if (! strcmp (argv[0], "not-advertise"))
356 SET_FLAG (range->flag, OSPF6_ROUTE_DO_NOT_ADVERTISE);
357 else if (! strcmp (argv[0], "advertise"))
358 UNSET_FLAG (range->flag, OSPF6_ROUTE_DO_NOT_ADVERTISE);
359 }
360
361 ospf6_route_add (range, oa->range_table);
362 return CMD_SUCCESS;
363}
364
365ALIAS (area_range,
366 area_range_advertise_cmd,
367 "area A.B.C.D range X:X::X:X/M (advertise|not-advertise)",
368 "OSPF area parameters\n"
369 OSPF6_AREA_ID_STR
370 "Configured address range\n"
371 "Specify IPv6 prefix\n"
372 );
373
374DEFUN (no_area_range,
375 no_area_range_cmd,
376 "no area A.B.C.D range X:X::X:X/M",
377 "OSPF area parameters\n"
378 OSPF6_AREA_ID_STR
379 "Configured address range\n"
380 "Specify IPv6 prefix\n"
381 )
382{
383 int ret;
384 struct ospf6_area *oa;
385 struct prefix prefix;
386 struct ospf6_route *range;
387
388 OSPF6_CMD_AREA_GET (argv[0], oa);
389 argc--;
390 argv++;
391
392 ret = str2prefix (argv[0], &prefix);
393 if (ret != 1 || prefix.family != AF_INET6)
394 {
395 vty_out (vty, "Malformed argument: %s%s", argv[0], VNL);
396 return CMD_SUCCESS;
397 }
398
399 range = ospf6_route_lookup (&prefix, oa->range_table);
400 if (range == NULL)
401 {
402 vty_out (vty, "Range %s does not exists.%s", argv[0], VNL);
403 return CMD_SUCCESS;
404 }
405
406 ospf6_route_remove (range, oa->range_table);
407 return CMD_SUCCESS;
408}
409
410void
411ospf6_area_config_write (struct vty *vty)
412{
hasso52dc7ee2004-09-23 19:18:23 +0000413 struct listnode *node;
hasso6452df02004-08-15 05:52:07 +0000414 struct ospf6_area *oa;
415 struct ospf6_route *range;
416 char buf[128];
417
418 for (node = listhead (ospf6->area_list); node; nextnode (node))
419 {
420 oa = OSPF6_AREA (getdata (node));
421
422 for (range = ospf6_route_head (oa->range_table); range;
423 range = ospf6_route_next (range))
424 {
425 prefix2str (&range->prefix, buf, sizeof (buf));
426 vty_out (vty, " area %s range %s%s", oa->name, buf, VNL);
427 }
428 }
429}
430
hasso508e53e2004-05-18 18:57:06 +0000431DEFUN (show_ipv6_ospf6_spf_tree,
432 show_ipv6_ospf6_spf_tree_cmd,
433 "show ipv6 ospf6 spf tree",
434 SHOW_STR
435 IP6_STR
436 OSPF6_STR
437 "Shortest Path First caculation\n"
438 "Show SPF tree\n")
439{
hasso52dc7ee2004-09-23 19:18:23 +0000440 struct listnode *node;
hasso508e53e2004-05-18 18:57:06 +0000441 struct ospf6_area *oa;
442 struct ospf6_vertex *root;
443 struct ospf6_route *route;
444 struct prefix prefix;
445
446 ospf6_linkstate_prefix (ospf6->router_id, htonl (0), &prefix);
447 for (node = listhead (ospf6->area_list); node; nextnode (node))
448 {
449 oa = (struct ospf6_area *) getdata (node);
450 route = ospf6_route_lookup (&prefix, oa->spf_table);
451 if (route == NULL)
452 {
453 vty_out (vty, "LS entry for root not found in area %s%s",
hasso049207c2004-08-04 20:02:13 +0000454 oa->name, VNL);
hasso508e53e2004-05-18 18:57:06 +0000455 continue;
456 }
457 root = (struct ospf6_vertex *) route->route_option;
458 ospf6_spf_display_subtree (vty, "", 0, root);
459 }
460
461 return CMD_SUCCESS;
462}
463
464DEFUN (show_ipv6_ospf6_area_spf_tree,
465 show_ipv6_ospf6_area_spf_tree_cmd,
466 "show ipv6 ospf6 area A.B.C.D spf tree",
467 SHOW_STR
468 IP6_STR
469 OSPF6_STR
470 OSPF6_AREA_STR
471 OSPF6_AREA_ID_STR
472 "Shortest Path First caculation\n"
473 "Show SPF tree\n")
474{
475 u_int32_t area_id;
476 struct ospf6_area *oa;
477 struct ospf6_vertex *root;
478 struct ospf6_route *route;
479 struct prefix prefix;
480
481 ospf6_linkstate_prefix (ospf6->router_id, htonl (0), &prefix);
482
483 if (inet_pton (AF_INET, argv[0], &area_id) != 1)
484 {
hasso049207c2004-08-04 20:02:13 +0000485 vty_out (vty, "Malformed Area-ID: %s%s", argv[0], VNL);
hasso508e53e2004-05-18 18:57:06 +0000486 return CMD_SUCCESS;
487 }
488 oa = ospf6_area_lookup (area_id, ospf6);
489 if (oa == NULL)
490 {
hasso049207c2004-08-04 20:02:13 +0000491 vty_out (vty, "No such Area: %s%s", argv[0], VNL);
hasso508e53e2004-05-18 18:57:06 +0000492 return CMD_SUCCESS;
493 }
494
495 route = ospf6_route_lookup (&prefix, oa->spf_table);
496 if (route == NULL)
497 {
498 vty_out (vty, "LS entry for root not found in area %s%s",
hasso049207c2004-08-04 20:02:13 +0000499 oa->name, VNL);
hasso508e53e2004-05-18 18:57:06 +0000500 return CMD_SUCCESS;
501 }
502 root = (struct ospf6_vertex *) route->route_option;
503 ospf6_spf_display_subtree (vty, "", 0, root);
504
505 return CMD_SUCCESS;
506}
507
hasso508e53e2004-05-18 18:57:06 +0000508DEFUN (show_ipv6_ospf6_simulate_spf_tree_root,
509 show_ipv6_ospf6_simulate_spf_tree_root_cmd,
510 "show ipv6 ospf6 simulate spf-tree A.B.C.D area A.B.C.D",
511 SHOW_STR
512 IP6_STR
513 OSPF6_STR
514 "Shortest Path First caculation\n"
515 "Show SPF tree\n"
516 "Specify root's router-id to calculate another router's SPF tree\n")
517{
518 u_int32_t area_id;
519 struct ospf6_area *oa;
520 struct ospf6_vertex *root;
521 struct ospf6_route *route;
522 struct prefix prefix;
523 u_int32_t router_id;
524 struct ospf6_route_table *spf_table;
525 unsigned char tmp_debug_ospf6_spf = 0;
526
527 inet_pton (AF_INET, argv[0], &router_id);
528 ospf6_linkstate_prefix (router_id, htonl (0), &prefix);
529
530 if (inet_pton (AF_INET, argv[1], &area_id) != 1)
531 {
hasso049207c2004-08-04 20:02:13 +0000532 vty_out (vty, "Malformed Area-ID: %s%s", argv[1], VNL);
hasso508e53e2004-05-18 18:57:06 +0000533 return CMD_SUCCESS;
534 }
535 oa = ospf6_area_lookup (area_id, ospf6);
536 if (oa == NULL)
537 {
hasso049207c2004-08-04 20:02:13 +0000538 vty_out (vty, "No such Area: %s%s", argv[1], VNL);
hasso508e53e2004-05-18 18:57:06 +0000539 return CMD_SUCCESS;
540 }
541
542 tmp_debug_ospf6_spf = conf_debug_ospf6_spf;
543 conf_debug_ospf6_spf = 0;
544
545 spf_table = ospf6_route_table_create ();
546 ospf6_spf_calculation (router_id, spf_table, oa);
547
548 conf_debug_ospf6_spf = tmp_debug_ospf6_spf;
549
550 route = ospf6_route_lookup (&prefix, spf_table);
551 if (route == NULL)
552 {
553 ospf6_spf_table_finish (spf_table);
554 ospf6_route_table_delete (spf_table);
555 return CMD_SUCCESS;
556 }
557 root = (struct ospf6_vertex *) route->route_option;
558 ospf6_spf_display_subtree (vty, "", 0, root);
559
560 ospf6_spf_table_finish (spf_table);
561 ospf6_route_table_delete (spf_table);
562
563 return CMD_SUCCESS;
564}
paul718e3742002-12-13 20:15:29 +0000565
566void
567ospf6_area_init ()
568{
hasso508e53e2004-05-18 18:57:06 +0000569 install_element (VIEW_NODE, &show_ipv6_ospf6_spf_tree_cmd);
hasso508e53e2004-05-18 18:57:06 +0000570 install_element (VIEW_NODE, &show_ipv6_ospf6_area_spf_tree_cmd);
hasso508e53e2004-05-18 18:57:06 +0000571 install_element (VIEW_NODE, &show_ipv6_ospf6_simulate_spf_tree_root_cmd);
572
573 install_element (ENABLE_NODE, &show_ipv6_ospf6_spf_tree_cmd);
hasso508e53e2004-05-18 18:57:06 +0000574 install_element (ENABLE_NODE, &show_ipv6_ospf6_area_spf_tree_cmd);
hasso508e53e2004-05-18 18:57:06 +0000575 install_element (ENABLE_NODE, &show_ipv6_ospf6_simulate_spf_tree_root_cmd);
hasso6452df02004-08-15 05:52:07 +0000576
577 install_element (OSPF6_NODE, &area_range_cmd);
578 install_element (OSPF6_NODE, &area_range_advertise_cmd);
579 install_element (OSPF6_NODE, &no_area_range_cmd);
paul718e3742002-12-13 20:15:29 +0000580}
hasso049207c2004-08-04 20:02:13 +0000581
hasso6452df02004-08-15 05:52:07 +0000582