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