Annotation of embedaddon/quagga/ospf6d/ospf6_area.c, revision 1.1.1.1
1.1 misho 1: /*
2: * Copyright (C) 2003 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 "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: #include "plist.h"
34: #include "filter.h"
35:
36: #include "ospf6_proto.h"
37: #include "ospf6_lsa.h"
38: #include "ospf6_lsdb.h"
39: #include "ospf6_route.h"
40: #include "ospf6_spf.h"
41: #include "ospf6_top.h"
42: #include "ospf6_area.h"
43: #include "ospf6_interface.h"
44: #include "ospf6_intra.h"
45: #include "ospf6_abr.h"
46: #include "ospf6d.h"
47:
48: int
49: ospf6_area_cmp (void *va, void *vb)
50: {
51: struct ospf6_area *oa = (struct ospf6_area *) va;
52: struct ospf6_area *ob = (struct ospf6_area *) vb;
53: return (ntohl (oa->area_id) < ntohl (ob->area_id) ? -1 : 1);
54: }
55:
56: /* schedule routing table recalculation */
57: static void
58: ospf6_area_lsdb_hook_add (struct ospf6_lsa *lsa)
59: {
60: switch (ntohs (lsa->header->type))
61: {
62: case OSPF6_LSTYPE_ROUTER:
63: case OSPF6_LSTYPE_NETWORK:
64: if (IS_OSPF6_DEBUG_EXAMIN_TYPE (lsa->header->type))
65: {
66: zlog_debug ("Examin %s", lsa->name);
67: zlog_debug ("Schedule SPF Calculation for %s",
68: OSPF6_AREA (lsa->lsdb->data)->name);
69: }
70: ospf6_spf_schedule (OSPF6_AREA (lsa->lsdb->data));
71: break;
72:
73: case OSPF6_LSTYPE_INTRA_PREFIX:
74: ospf6_intra_prefix_lsa_add (lsa);
75: break;
76:
77: case OSPF6_LSTYPE_INTER_PREFIX:
78: case OSPF6_LSTYPE_INTER_ROUTER:
79: ospf6_abr_examin_summary (lsa, (struct ospf6_area *) lsa->lsdb->data);
80: break;
81:
82: default:
83: break;
84: }
85: }
86:
87: static void
88: ospf6_area_lsdb_hook_remove (struct ospf6_lsa *lsa)
89: {
90: switch (ntohs (lsa->header->type))
91: {
92: case OSPF6_LSTYPE_ROUTER:
93: case OSPF6_LSTYPE_NETWORK:
94: if (IS_OSPF6_DEBUG_EXAMIN_TYPE (lsa->header->type))
95: {
96: zlog_debug ("LSA disappearing: %s", lsa->name);
97: zlog_debug ("Schedule SPF Calculation for %s",
98: OSPF6_AREA (lsa->lsdb->data)->name);
99: }
100: ospf6_spf_schedule (OSPF6_AREA (lsa->lsdb->data));
101: break;
102:
103: case OSPF6_LSTYPE_INTRA_PREFIX:
104: ospf6_intra_prefix_lsa_remove (lsa);
105: break;
106:
107: case OSPF6_LSTYPE_INTER_PREFIX:
108: case OSPF6_LSTYPE_INTER_ROUTER:
109: ospf6_abr_examin_summary (lsa, (struct ospf6_area *) lsa->lsdb->data);
110: break;
111:
112: default:
113: break;
114: }
115: }
116:
117: static void
118: ospf6_area_route_hook_add (struct ospf6_route *route)
119: {
120: struct ospf6_route *copy = ospf6_route_copy (route);
121: ospf6_route_add (copy, ospf6->route_table);
122: }
123:
124: static void
125: ospf6_area_route_hook_remove (struct ospf6_route *route)
126: {
127: struct ospf6_route *copy;
128:
129: copy = ospf6_route_lookup_identical (route, ospf6->route_table);
130: if (copy)
131: ospf6_route_remove (copy, ospf6->route_table);
132: }
133:
134: /* Make new area structure */
135: struct ospf6_area *
136: ospf6_area_create (u_int32_t area_id, struct ospf6 *o)
137: {
138: struct ospf6_area *oa;
139: struct ospf6_route *route;
140:
141: oa = XCALLOC (MTYPE_OSPF6_AREA, sizeof (struct ospf6_area));
142:
143: inet_ntop (AF_INET, &area_id, oa->name, sizeof (oa->name));
144: oa->area_id = area_id;
145: oa->if_list = list_new ();
146:
147: oa->lsdb = ospf6_lsdb_create (oa);
148: oa->lsdb->hook_add = ospf6_area_lsdb_hook_add;
149: oa->lsdb->hook_remove = ospf6_area_lsdb_hook_remove;
150: oa->lsdb_self = ospf6_lsdb_create (oa);
151:
152: oa->spf_table = OSPF6_ROUTE_TABLE_CREATE (AREA, SPF_RESULTS);
153: oa->spf_table->scope = oa;
154: oa->route_table = OSPF6_ROUTE_TABLE_CREATE (AREA, ROUTES);
155: oa->route_table->scope = oa;
156: oa->route_table->hook_add = ospf6_area_route_hook_add;
157: oa->route_table->hook_remove = ospf6_area_route_hook_remove;
158:
159: oa->range_table = OSPF6_ROUTE_TABLE_CREATE (AREA, PREFIX_RANGES);
160: oa->range_table->scope = oa;
161: oa->summary_prefix = OSPF6_ROUTE_TABLE_CREATE (AREA, SUMMARY_PREFIXES);
162: oa->summary_prefix->scope = oa;
163: oa->summary_router = OSPF6_ROUTE_TABLE_CREATE (AREA, SUMMARY_ROUTERS);
164: oa->summary_router->scope = oa;
165:
166: /* set default options */
167: OSPF6_OPT_SET (oa->options, OSPF6_OPT_V6);
168: OSPF6_OPT_SET (oa->options, OSPF6_OPT_E);
169: OSPF6_OPT_SET (oa->options, OSPF6_OPT_R);
170:
171: oa->ospf6 = o;
172: listnode_add_sort (o->area_list, oa);
173:
174: /* import athoer area's routes as inter-area routes */
175: for (route = ospf6_route_head (o->route_table); route;
176: route = ospf6_route_next (route))
177: ospf6_abr_originate_summary_to_area (route, oa);
178:
179: return oa;
180: }
181:
182: void
183: ospf6_area_delete (struct ospf6_area *oa)
184: {
185: struct listnode *n, *nnode;
186: struct ospf6_interface *oi;
187:
188: ospf6_route_table_delete (oa->range_table);
189: ospf6_route_table_delete (oa->summary_prefix);
190: ospf6_route_table_delete (oa->summary_router);
191:
192: /* ospf6 interface list */
193: for (ALL_LIST_ELEMENTS (oa->if_list, n, nnode, oi))
194: {
195: ospf6_interface_delete (oi);
196: }
197: list_delete (oa->if_list);
198:
199: ospf6_lsdb_delete (oa->lsdb);
200: ospf6_lsdb_delete (oa->lsdb_self);
201:
202: ospf6_spf_table_finish (oa->spf_table);
203: ospf6_route_table_delete (oa->spf_table);
204: ospf6_route_table_delete (oa->route_table);
205:
206: THREAD_OFF (oa->thread_spf_calculation);
207: THREAD_OFF (oa->thread_route_calculation);
208:
209: listnode_delete (oa->ospf6->area_list, oa);
210: oa->ospf6 = NULL;
211:
212: /* free area */
213: XFREE (MTYPE_OSPF6_AREA, oa);
214: }
215:
216: struct ospf6_area *
217: ospf6_area_lookup (u_int32_t area_id, struct ospf6 *ospf6)
218: {
219: struct ospf6_area *oa;
220: struct listnode *n;
221:
222: for (ALL_LIST_ELEMENTS_RO (ospf6->area_list, n, oa))
223: if (oa->area_id == area_id)
224: return oa;
225:
226: return (struct ospf6_area *) NULL;
227: }
228:
229: static struct ospf6_area *
230: ospf6_area_get (u_int32_t area_id, struct ospf6 *o)
231: {
232: struct ospf6_area *oa;
233: oa = ospf6_area_lookup (area_id, o);
234: if (oa == NULL)
235: oa = ospf6_area_create (area_id, o);
236: return oa;
237: }
238:
239: void
240: ospf6_area_enable (struct ospf6_area *oa)
241: {
242: struct listnode *node, *nnode;
243: struct ospf6_interface *oi;
244:
245: SET_FLAG (oa->flag, OSPF6_AREA_ENABLE);
246:
247: for (ALL_LIST_ELEMENTS (oa->if_list, node, nnode, oi))
248: ospf6_interface_enable (oi);
249: }
250:
251: void
252: ospf6_area_disable (struct ospf6_area *oa)
253: {
254: struct listnode *node, *nnode;
255: struct ospf6_interface *oi;
256:
257: UNSET_FLAG (oa->flag, OSPF6_AREA_ENABLE);
258:
259: for (ALL_LIST_ELEMENTS (oa->if_list, node, nnode, oi))
260: ospf6_interface_disable (oi);
261: }
262:
263:
264: void
265: ospf6_area_show (struct vty *vty, struct ospf6_area *oa)
266: {
267: struct listnode *i;
268: struct ospf6_interface *oi;
269:
270: vty_out (vty, " Area %s%s", oa->name, VNL);
271: vty_out (vty, " Number of Area scoped LSAs is %u%s",
272: oa->lsdb->count, VNL);
273:
274: vty_out (vty, " Interface attached to this area:");
275: for (ALL_LIST_ELEMENTS_RO (oa->if_list, i, oi))
276: vty_out (vty, " %s", oi->interface->name);
277:
278: vty_out (vty, "%s", VNL);
279: }
280:
281:
282: #define OSPF6_CMD_AREA_LOOKUP(str, oa) \
283: { \
284: u_int32_t area_id = 0; \
285: if (inet_pton (AF_INET, str, &area_id) != 1) \
286: { \
287: vty_out (vty, "Malformed Area-ID: %s%s", str, VNL); \
288: return CMD_SUCCESS; \
289: } \
290: oa = ospf6_area_lookup (area_id, ospf6); \
291: if (oa == NULL) \
292: { \
293: vty_out (vty, "No such Area: %s%s", str, VNL); \
294: return CMD_SUCCESS; \
295: } \
296: }
297:
298: #define OSPF6_CMD_AREA_GET(str, oa) \
299: { \
300: u_int32_t area_id = 0; \
301: if (inet_pton (AF_INET, str, &area_id) != 1) \
302: { \
303: vty_out (vty, "Malformed Area-ID: %s%s", str, VNL); \
304: return CMD_SUCCESS; \
305: } \
306: oa = ospf6_area_get (area_id, ospf6); \
307: }
308:
309: DEFUN (area_range,
310: area_range_cmd,
311: "area A.B.C.D range X:X::X:X/M",
312: "OSPF area parameters\n"
313: OSPF6_AREA_ID_STR
314: "Configured address range\n"
315: "Specify IPv6 prefix\n"
316: )
317: {
318: int ret;
319: struct ospf6_area *oa;
320: struct prefix prefix;
321: struct ospf6_route *range;
322:
323: OSPF6_CMD_AREA_GET (argv[0], oa);
324: argc--;
325: argv++;
326:
327: ret = str2prefix (argv[0], &prefix);
328: if (ret != 1 || prefix.family != AF_INET6)
329: {
330: vty_out (vty, "Malformed argument: %s%s", argv[0], VNL);
331: return CMD_SUCCESS;
332: }
333: argc--;
334: argv++;
335:
336: range = ospf6_route_lookup (&prefix, oa->range_table);
337: if (range == NULL)
338: {
339: range = ospf6_route_create ();
340: range->type = OSPF6_DEST_TYPE_RANGE;
341: range->prefix = prefix;
342: }
343:
344: if (argc)
345: {
346: if (! strcmp (argv[0], "not-advertise"))
347: SET_FLAG (range->flag, OSPF6_ROUTE_DO_NOT_ADVERTISE);
348: else if (! strcmp (argv[0], "advertise"))
349: UNSET_FLAG (range->flag, OSPF6_ROUTE_DO_NOT_ADVERTISE);
350: }
351:
352: if (range->rnode)
353: {
354: vty_out (vty, "Range already defined: %s%s", argv[-1], VNL);
355: return CMD_WARNING;
356: }
357:
358: ospf6_route_add (range, oa->range_table);
359: return CMD_SUCCESS;
360: }
361:
362: ALIAS (area_range,
363: area_range_advertise_cmd,
364: "area A.B.C.D range X:X::X:X/M (advertise|not-advertise)",
365: "OSPF area parameters\n"
366: OSPF6_AREA_ID_STR
367: "Configured address range\n"
368: "Specify IPv6 prefix\n"
369: )
370:
371: DEFUN (no_area_range,
372: no_area_range_cmd,
373: "no area A.B.C.D range X:X::X:X/M",
374: "OSPF area parameters\n"
375: OSPF6_AREA_ID_STR
376: "Configured address range\n"
377: "Specify IPv6 prefix\n"
378: )
379: {
380: int ret;
381: struct ospf6_area *oa;
382: struct prefix prefix;
383: struct ospf6_route *range;
384:
385: OSPF6_CMD_AREA_GET (argv[0], oa);
386: argc--;
387: argv++;
388:
389: ret = str2prefix (argv[0], &prefix);
390: if (ret != 1 || prefix.family != AF_INET6)
391: {
392: vty_out (vty, "Malformed argument: %s%s", argv[0], VNL);
393: return CMD_SUCCESS;
394: }
395:
396: range = ospf6_route_lookup (&prefix, oa->range_table);
397: if (range == NULL)
398: {
399: vty_out (vty, "Range %s does not exists.%s", argv[0], VNL);
400: return CMD_SUCCESS;
401: }
402:
403: ospf6_route_remove (range, oa->range_table);
404: return CMD_SUCCESS;
405: }
406:
407: void
408: ospf6_area_config_write (struct vty *vty)
409: {
410: struct listnode *node;
411: struct ospf6_area *oa;
412: struct ospf6_route *range;
413: char buf[128];
414:
415: for (ALL_LIST_ELEMENTS_RO (ospf6->area_list, node, oa))
416: {
417: for (range = ospf6_route_head (oa->range_table); range;
418: range = ospf6_route_next (range))
419: {
420: prefix2str (&range->prefix, buf, sizeof (buf));
421: vty_out (vty, " area %s range %s%s", oa->name, buf, VNL);
422: }
423: if (PREFIX_NAME_IN (oa))
424: vty_out (vty, " area %s filter-list prefix %s in%s",
425: oa->name, PREFIX_NAME_IN (oa), VNL);
426: if (PREFIX_NAME_OUT (oa))
427: vty_out (vty, " area %s filter-list prefix %s out%s",
428: oa->name, PREFIX_NAME_OUT (oa), VNL);
429: if (IMPORT_NAME (oa))
430: vty_out (vty, " area %s import-list %s%s",
431: oa->name, IMPORT_NAME (oa), VNL);
432: if (EXPORT_NAME (oa))
433: vty_out (vty, " area %s export-list %s%s",
434: oa->name, EXPORT_NAME (oa), VNL);
435: }
436: }
437:
438: DEFUN (area_filter_list,
439: area_filter_list_cmd,
440: "area A.B.C.D filter-list prefix WORD (in|out)",
441: "OSPFv6 area parameters\n"
442: "OSPFv6 area ID in IP address format\n"
443: "Filter networks between OSPFv6 areas\n"
444: "Filter prefixes between OSPFv6 areas\n"
445: "Name of an IPv6 prefix-list\n"
446: "Filter networks sent to this area\n"
447: "Filter networks sent from this area\n")
448: {
449: struct ospf6_area *area;
450: struct prefix_list *plist;
451:
452: OSPF6_CMD_AREA_GET (argv[0], area);
453: argc--;
454: argv++;
455:
456: plist = prefix_list_lookup (AFI_IP6, argv[0]);
457: if (strncmp (argv[1], "in", 2) == 0)
458: {
459: PREFIX_LIST_IN (area) = plist;
460: if (PREFIX_NAME_IN (area))
461: free (PREFIX_NAME_IN (area));
462:
463: PREFIX_NAME_IN (area) = strdup (argv[0]);
464: ospf6_abr_reimport (area);
465: }
466: else
467: {
468: PREFIX_LIST_OUT (area) = plist;
469: if (PREFIX_NAME_OUT (area))
470: free (PREFIX_NAME_OUT (area));
471:
472: PREFIX_NAME_OUT (area) = strdup (argv[0]);
473: ospf6_abr_enable_area (area);
474: }
475:
476: return CMD_SUCCESS;
477: }
478:
479: DEFUN (no_area_filter_list,
480: no_area_filter_list_cmd,
481: "no area A.B.C.D filter-list prefix WORD (in|out)",
482: NO_STR
483: "OSPFv6 area parameters\n"
484: "OSPFv6 area ID in IP address format\n"
485: "Filter networks between OSPFv6 areas\n"
486: "Filter prefixes between OSPFv6 areas\n"
487: "Name of an IPv6 prefix-list\n"
488: "Filter networks sent to this area\n"
489: "Filter networks sent from this area\n")
490: {
491: struct ospf6_area *area;
492: struct prefix_list *plist;
493:
494: OSPF6_CMD_AREA_GET (argv[0], area);
495: argc--;
496: argv++;
497:
498: plist = prefix_list_lookup (AFI_IP6, argv[0]);
499: if (strncmp (argv[1], "in", 2) == 0)
500: {
501: if (PREFIX_NAME_IN (area))
502: if (strcmp (PREFIX_NAME_IN (area), argv[0]) != 0)
503: return CMD_SUCCESS;
504:
505: PREFIX_LIST_IN (area) = NULL;
506: if (PREFIX_NAME_IN (area))
507: free (PREFIX_NAME_IN (area));
508:
509: PREFIX_NAME_IN (area) = NULL;
510: ospf6_abr_reimport (area);
511: }
512: else
513: {
514: if (PREFIX_NAME_OUT (area))
515: if (strcmp (PREFIX_NAME_OUT (area), argv[0]) != 0)
516: return CMD_SUCCESS;
517:
518: PREFIX_LIST_OUT (area) = NULL;
519: if (PREFIX_NAME_OUT (area))
520: free (PREFIX_NAME_OUT (area));
521:
522: PREFIX_NAME_OUT (area) = NULL;
523: ospf6_abr_enable_area (area);
524: }
525:
526: return CMD_SUCCESS;
527: }
528:
529: DEFUN (area_import_list,
530: area_import_list_cmd,
531: "area A.B.C.D import-list NAME",
532: "OSPFv6 area parameters\n"
533: "OSPFv6 area ID in IP address format\n"
534: "Set the filter for networks from other areas announced to the specified one\n"
535: "Name of the acess-list\n")
536: {
537: struct ospf6_area *area;
538: struct access_list *list;
539:
540: OSPF6_CMD_AREA_GET(argv[0], area);
541:
542: list = access_list_lookup (AFI_IP6, argv[1]);
543:
544: IMPORT_LIST (area) = list;
545:
546: if (IMPORT_NAME (area))
547: free (IMPORT_NAME (area));
548:
549: IMPORT_NAME (area) = strdup (argv[1]);
550: ospf6_abr_reimport (area);
551:
552: return CMD_SUCCESS;
553: }
554:
555: DEFUN (no_area_import_list,
556: no_area_import_list_cmd,
557: "no area A.B.C.D import-list NAME",
558: "OSPFv6 area parameters\n"
559: "OSPFv6 area ID in IP address format\n"
560: "Unset the filter for networks announced to other areas\n"
561: "NAme of the access-list\n")
562: {
563: struct ospf6_area *area;
564:
565: OSPF6_CMD_AREA_GET(argv[0], area);
566:
567: IMPORT_LIST (area) = 0;
568:
569: if (IMPORT_NAME (area))
570: free (IMPORT_NAME (area));
571:
572: IMPORT_NAME (area) = NULL;
573: ospf6_abr_reimport (area);
574:
575: return CMD_SUCCESS;
576: }
577:
578: DEFUN (area_export_list,
579: area_export_list_cmd,
580: "area A.B.C.D export-list NAME",
581: "OSPFv6 area parameters\n"
582: "OSPFv6 area ID in IP address format\n"
583: "Set the filter for networks announced to other areas\n"
584: "Name of the acess-list\n")
585: {
586: struct ospf6_area *area;
587: struct access_list *list;
588:
589: OSPF6_CMD_AREA_GET(argv[0], area);
590:
591: list = access_list_lookup (AFI_IP6, argv[1]);
592:
593: EXPORT_LIST (area) = list;
594:
595: if (EXPORT_NAME (area))
596: free (EXPORT_NAME (area));
597:
598: EXPORT_NAME (area) = strdup (argv[1]);
599: ospf6_abr_enable_area (area);
600:
601: return CMD_SUCCESS;
602: }
603:
604: DEFUN (no_area_export_list,
605: no_area_export_list_cmd,
606: "no area A.B.C.D export-list NAME",
607: "OSPFv6 area parameters\n"
608: "OSPFv6 area ID in IP address format\n"
609: "Unset the filter for networks announced to other areas\n"
610: "Name of the access-list\n")
611: {
612: struct ospf6_area *area;
613:
614: OSPF6_CMD_AREA_GET(argv[0], area);
615:
616: EXPORT_LIST (area) = 0;
617:
618: if (EXPORT_NAME (area))
619: free (EXPORT_NAME (area));
620:
621: EXPORT_NAME (area) = NULL;
622: ospf6_abr_enable_area (area);
623:
624: return CMD_SUCCESS;
625: }
626:
627: DEFUN (show_ipv6_ospf6_spf_tree,
628: show_ipv6_ospf6_spf_tree_cmd,
629: "show ipv6 ospf6 spf tree",
630: SHOW_STR
631: IP6_STR
632: OSPF6_STR
633: "Shortest Path First caculation\n"
634: "Show SPF tree\n")
635: {
636: struct listnode *node;
637: struct ospf6_area *oa;
638: struct ospf6_vertex *root;
639: struct ospf6_route *route;
640: struct prefix prefix;
641:
642: ospf6_linkstate_prefix (ospf6->router_id, htonl (0), &prefix);
643:
644: for (ALL_LIST_ELEMENTS_RO (ospf6->area_list, node, oa))
645: {
646: route = ospf6_route_lookup (&prefix, oa->spf_table);
647: if (route == NULL)
648: {
649: vty_out (vty, "LS entry for root not found in area %s%s",
650: oa->name, VNL);
651: continue;
652: }
653: root = (struct ospf6_vertex *) route->route_option;
654: ospf6_spf_display_subtree (vty, "", 0, root);
655: }
656:
657: return CMD_SUCCESS;
658: }
659:
660: DEFUN (show_ipv6_ospf6_area_spf_tree,
661: show_ipv6_ospf6_area_spf_tree_cmd,
662: "show ipv6 ospf6 area A.B.C.D spf tree",
663: SHOW_STR
664: IP6_STR
665: OSPF6_STR
666: OSPF6_AREA_STR
667: OSPF6_AREA_ID_STR
668: "Shortest Path First caculation\n"
669: "Show SPF tree\n")
670: {
671: u_int32_t area_id;
672: struct ospf6_area *oa;
673: struct ospf6_vertex *root;
674: struct ospf6_route *route;
675: struct prefix prefix;
676:
677: ospf6_linkstate_prefix (ospf6->router_id, htonl (0), &prefix);
678:
679: if (inet_pton (AF_INET, argv[0], &area_id) != 1)
680: {
681: vty_out (vty, "Malformed Area-ID: %s%s", argv[0], VNL);
682: return CMD_SUCCESS;
683: }
684: oa = ospf6_area_lookup (area_id, ospf6);
685: if (oa == NULL)
686: {
687: vty_out (vty, "No such Area: %s%s", argv[0], VNL);
688: return CMD_SUCCESS;
689: }
690:
691: route = ospf6_route_lookup (&prefix, oa->spf_table);
692: if (route == NULL)
693: {
694: vty_out (vty, "LS entry for root not found in area %s%s",
695: oa->name, VNL);
696: return CMD_SUCCESS;
697: }
698: root = (struct ospf6_vertex *) route->route_option;
699: ospf6_spf_display_subtree (vty, "", 0, root);
700:
701: return CMD_SUCCESS;
702: }
703:
704: DEFUN (show_ipv6_ospf6_simulate_spf_tree_root,
705: show_ipv6_ospf6_simulate_spf_tree_root_cmd,
706: "show ipv6 ospf6 simulate spf-tree A.B.C.D area A.B.C.D",
707: SHOW_STR
708: IP6_STR
709: OSPF6_STR
710: "Shortest Path First caculation\n"
711: "Show SPF tree\n"
712: "Specify root's router-id to calculate another router's SPF tree\n")
713: {
714: u_int32_t area_id;
715: struct ospf6_area *oa;
716: struct ospf6_vertex *root;
717: struct ospf6_route *route;
718: struct prefix prefix;
719: u_int32_t router_id;
720: struct ospf6_route_table *spf_table;
721: unsigned char tmp_debug_ospf6_spf = 0;
722:
723: inet_pton (AF_INET, argv[0], &router_id);
724: ospf6_linkstate_prefix (router_id, htonl (0), &prefix);
725:
726: if (inet_pton (AF_INET, argv[1], &area_id) != 1)
727: {
728: vty_out (vty, "Malformed Area-ID: %s%s", argv[1], VNL);
729: return CMD_SUCCESS;
730: }
731: oa = ospf6_area_lookup (area_id, ospf6);
732: if (oa == NULL)
733: {
734: vty_out (vty, "No such Area: %s%s", argv[1], VNL);
735: return CMD_SUCCESS;
736: }
737:
738: tmp_debug_ospf6_spf = conf_debug_ospf6_spf;
739: conf_debug_ospf6_spf = 0;
740:
741: spf_table = OSPF6_ROUTE_TABLE_CREATE (NONE, SPF_RESULTS);
742: ospf6_spf_calculation (router_id, spf_table, oa);
743:
744: conf_debug_ospf6_spf = tmp_debug_ospf6_spf;
745:
746: route = ospf6_route_lookup (&prefix, spf_table);
747: if (route == NULL)
748: {
749: ospf6_spf_table_finish (spf_table);
750: ospf6_route_table_delete (spf_table);
751: return CMD_SUCCESS;
752: }
753: root = (struct ospf6_vertex *) route->route_option;
754: ospf6_spf_display_subtree (vty, "", 0, root);
755:
756: ospf6_spf_table_finish (spf_table);
757: ospf6_route_table_delete (spf_table);
758:
759: return CMD_SUCCESS;
760: }
761:
762: void
763: ospf6_area_init (void)
764: {
765: install_element (VIEW_NODE, &show_ipv6_ospf6_spf_tree_cmd);
766: install_element (VIEW_NODE, &show_ipv6_ospf6_area_spf_tree_cmd);
767: install_element (VIEW_NODE, &show_ipv6_ospf6_simulate_spf_tree_root_cmd);
768:
769: install_element (ENABLE_NODE, &show_ipv6_ospf6_spf_tree_cmd);
770: install_element (ENABLE_NODE, &show_ipv6_ospf6_area_spf_tree_cmd);
771: install_element (ENABLE_NODE, &show_ipv6_ospf6_simulate_spf_tree_root_cmd);
772:
773: install_element (OSPF6_NODE, &area_range_cmd);
774: install_element (OSPF6_NODE, &area_range_advertise_cmd);
775: install_element (OSPF6_NODE, &no_area_range_cmd);
776:
777: install_element (OSPF6_NODE, &area_import_list_cmd);
778: install_element (OSPF6_NODE, &no_area_import_list_cmd);
779: install_element (OSPF6_NODE, &area_export_list_cmd);
780: install_element (OSPF6_NODE, &no_area_export_list_cmd);
781:
782: install_element (OSPF6_NODE, &area_filter_list_cmd);
783: install_element (OSPF6_NODE, &no_area_filter_list_cmd);
784:
785: }
786:
787:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>