]> git.proxmox.com Git - mirror_frr.git/blob - ospf6d/ospf6_area.c
ospf6d: ospfv3-abr-ecmp-support.patch
[mirror_frr.git] / ospf6d / ospf6_area.c
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_PROCESS(OSPF6_AREA (lsa->lsdb->data)->ospf6),
71 ospf6_lsadd_to_spf_reason(lsa));
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 }
101 ospf6_spf_schedule (OSPF6_PROCESS(OSPF6_AREA (lsa->lsdb->data)->ospf6),
102 ospf6_lsremove_to_spf_reason(lsa));
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 bf_init(oa->range_table->idspace, 32);
164 oa->summary_prefix = OSPF6_ROUTE_TABLE_CREATE (AREA, SUMMARY_PREFIXES);
165 oa->summary_prefix->scope = oa;
166 oa->summary_router = OSPF6_ROUTE_TABLE_CREATE (AREA, SUMMARY_ROUTERS);
167 oa->summary_router->scope = oa;
168
169 /* set default options */
170 if (CHECK_FLAG (o->flag, OSPF6_STUB_ROUTER))
171 {
172 OSPF6_OPT_CLEAR (oa->options, OSPF6_OPT_V6);
173 OSPF6_OPT_CLEAR (oa->options, OSPF6_OPT_R);
174 }
175 else
176 {
177 OSPF6_OPT_SET (oa->options, OSPF6_OPT_V6);
178 OSPF6_OPT_SET (oa->options, OSPF6_OPT_R);
179 }
180
181 OSPF6_OPT_SET (oa->options, OSPF6_OPT_E);
182
183 oa->ospf6 = o;
184 listnode_add_sort (o->area_list, oa);
185
186 if (area_id == OSPF_AREA_BACKBONE)
187 {
188 o->backbone = oa;
189 }
190
191 /* import athoer area's routes as inter-area routes */
192 for (route = ospf6_route_head (o->route_table); route;
193 route = ospf6_route_next (route))
194 ospf6_abr_originate_summary_to_area (route, oa);
195
196 return oa;
197 }
198
199 void
200 ospf6_area_delete (struct ospf6_area *oa)
201 {
202 struct listnode *n;
203 struct ospf6_interface *oi;
204
205 /* The ospf6_interface structs store configuration
206 * information which should not be lost/reset when
207 * deleting an area.
208 * So just detach the interface from the area and
209 * keep it around. */
210 for (ALL_LIST_ELEMENTS_RO (oa->if_list, n, oi))
211 oi->area = NULL;
212
213 list_delete (oa->if_list);
214
215 ospf6_lsdb_delete (oa->lsdb);
216 ospf6_lsdb_delete (oa->lsdb_self);
217
218 ospf6_spf_table_finish (oa->spf_table);
219 ospf6_route_table_delete (oa->spf_table);
220 ospf6_route_table_delete (oa->route_table);
221
222 ospf6_route_table_delete (oa->range_table);
223 ospf6_route_table_delete (oa->summary_prefix);
224 ospf6_route_table_delete (oa->summary_router);
225
226 listnode_delete (oa->ospf6->area_list, oa);
227 oa->ospf6 = NULL;
228
229 /* free area */
230 XFREE (MTYPE_OSPF6_AREA, oa);
231 }
232
233 struct ospf6_area *
234 ospf6_area_lookup (u_int32_t area_id, struct ospf6 *ospf6)
235 {
236 struct ospf6_area *oa;
237 struct listnode *n;
238
239 for (ALL_LIST_ELEMENTS_RO (ospf6->area_list, n, oa))
240 if (oa->area_id == area_id)
241 return oa;
242
243 return (struct ospf6_area *) NULL;
244 }
245
246 static struct ospf6_area *
247 ospf6_area_get (u_int32_t area_id, struct ospf6 *o)
248 {
249 struct ospf6_area *oa;
250 oa = ospf6_area_lookup (area_id, o);
251 if (oa == NULL)
252 oa = ospf6_area_create (area_id, o);
253 return oa;
254 }
255
256 void
257 ospf6_area_enable (struct ospf6_area *oa)
258 {
259 struct listnode *node, *nnode;
260 struct ospf6_interface *oi;
261
262 SET_FLAG (oa->flag, OSPF6_AREA_ENABLE);
263
264 for (ALL_LIST_ELEMENTS (oa->if_list, node, nnode, oi))
265 ospf6_interface_enable (oi);
266 ospf6_abr_enable_area (oa);
267 }
268
269 void
270 ospf6_area_disable (struct ospf6_area *oa)
271 {
272 struct listnode *node, *nnode;
273 struct ospf6_interface *oi;
274
275 UNSET_FLAG (oa->flag, OSPF6_AREA_ENABLE);
276
277 for (ALL_LIST_ELEMENTS (oa->if_list, node, nnode, oi))
278 ospf6_interface_disable (oi);
279
280 ospf6_abr_disable_area (oa);
281 ospf6_lsdb_remove_all (oa->lsdb);
282 ospf6_lsdb_remove_all (oa->lsdb_self);
283
284 ospf6_spf_table_finish(oa->spf_table);
285 ospf6_route_remove_all(oa->route_table);
286
287 THREAD_OFF (oa->thread_router_lsa);
288 THREAD_OFF (oa->thread_intra_prefix_lsa);
289 }
290
291
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, *route;
350 u_int32_t cost = OSPF_AREA_RANGE_COST_UNSPEC;
351
352 OSPF6_CMD_AREA_GET (argv[0], oa);
353
354 ret = str2prefix (argv[1], &prefix);
355 if (ret != 1 || prefix.family != AF_INET6)
356 {
357 vty_out (vty, "Malformed argument: %s%s", argv[1], VNL);
358 return CMD_SUCCESS;
359 }
360
361 range = ospf6_route_lookup (&prefix, oa->range_table);
362 if (range == NULL)
363 {
364 range = ospf6_route_create ();
365 range->type = OSPF6_DEST_TYPE_RANGE;
366 range->prefix = prefix;
367 range->path.area_id = oa->area_id;
368 range->path.cost = OSPF_AREA_RANGE_COST_UNSPEC;
369 range->linkstate_id =
370 (u_int32_t) htonl(ospf6_new_range_ls_id (oa->range_table));
371 }
372
373 if (argc > 2)
374 {
375 if (strcmp (argv[2], "not-advertise") == 0)
376 {
377 SET_FLAG (range->flag, OSPF6_ROUTE_DO_NOT_ADVERTISE);
378 }
379 else if (strcmp (argv[2], "advertise") == 0)
380 {
381 UNSET_FLAG (range->flag, OSPF6_ROUTE_DO_NOT_ADVERTISE);
382 }
383 else
384 {
385 VTY_GET_INTEGER_RANGE ("cost", cost, argv[2], 0, OSPF_LS_INFINITY);
386 UNSET_FLAG (range->flag, OSPF6_ROUTE_DO_NOT_ADVERTISE);
387 }
388 }
389
390 range->path.u.cost_config = cost;
391
392 zlog_debug ("%s: for prefix %s, flag = %x\n", __func__, argv[1], range->flag);
393 if (range->rnode == NULL)
394 {
395 ospf6_route_add (range, oa->range_table);
396 }
397
398 if (ospf6_is_router_abr (ospf6))
399 {
400 /* Redo summaries if required */
401 for (route = ospf6_route_head (ospf6->route_table); route;
402 route = ospf6_route_next (route))
403 ospf6_abr_originate_summary(route);
404 }
405
406 return CMD_SUCCESS;
407 }
408
409 ALIAS (area_range,
410 area_range_advertise_cmd,
411 "area A.B.C.D range X:X::X:X/M (advertise|not-advertise)",
412 "OSPF area parameters\n"
413 OSPF6_AREA_ID_STR
414 "Configured address range\n"
415 "Specify IPv6 prefix\n"
416 )
417
418 ALIAS (area_range,
419 area_range_cost_cmd,
420 "area (A.B.C.D|<0-4294967295>) range X:X::X:X/M cost <0-16777215>",
421 "OSPF area parameters\n"
422 OSPF6_AREA_ID_STR
423 "Summarize routes matching address/mask (border routers only)\n"
424 "Area range prefix\n"
425 "User specified metric for this range\n"
426 "Advertised metric for this range\n")
427
428 ALIAS (area_range,
429 area_range_advertise_cost_cmd,
430 "area (A.B.C.D|<0-4294967295>) range X:X::X:X/M advertise cost <0-16777215>",
431 "OSPF area parameters\n"
432 OSPF6_AREA_ID_STR
433 "Summarize routes matching address/mask (border routers only)\n"
434 "Area range prefix\n"
435 "User specified metric for this range\n"
436 "Advertised metric for this range\n")
437
438 DEFUN (no_area_range,
439 no_area_range_cmd,
440 "no area A.B.C.D range X:X::X:X/M",
441 "OSPF area parameters\n"
442 OSPF6_AREA_ID_STR
443 "Configured address range\n"
444 "Specify IPv6 prefix\n"
445 )
446 {
447 int ret;
448 struct ospf6_area *oa;
449 struct prefix prefix;
450 struct ospf6_route *range, *route;
451
452 OSPF6_CMD_AREA_GET (argv[0], oa);
453 argc--;
454 argv++;
455
456 ret = str2prefix (argv[0], &prefix);
457 if (ret != 1 || prefix.family != AF_INET6)
458 {
459 vty_out (vty, "Malformed argument: %s%s", argv[0], VNL);
460 return CMD_SUCCESS;
461 }
462
463 range = ospf6_route_lookup (&prefix, oa->range_table);
464 if (range == NULL)
465 {
466 vty_out (vty, "Range %s does not exists.%s", argv[0], VNL);
467 return CMD_SUCCESS;
468 }
469
470 if (ospf6_is_router_abr(oa->ospf6))
471 {
472 /* Blow away the aggregated LSA and route */
473 SET_FLAG (range->flag, OSPF6_ROUTE_REMOVE);
474
475 /* Redo summaries if required */
476 for (route = ospf6_route_head (ospf6->route_table); route;
477 route = ospf6_route_next (route))
478 ospf6_abr_originate_summary(route);
479
480 /* purge the old aggregated summary LSA */
481 ospf6_abr_originate_summary(range);
482 }
483 ospf6_release_range_ls_id(oa->range_table,
484 (u_int32_t) ntohl(range->linkstate_id));
485 ospf6_route_remove (range, oa->range_table);
486
487 return CMD_SUCCESS;
488 }
489
490 void
491 ospf6_area_config_write (struct vty *vty)
492 {
493 struct listnode *node;
494 struct ospf6_area *oa;
495 struct ospf6_route *range;
496 char buf[128];
497
498 for (ALL_LIST_ELEMENTS_RO (ospf6->area_list, node, oa))
499 {
500 for (range = ospf6_route_head (oa->range_table); range;
501 range = ospf6_route_next (range))
502 {
503 prefix2str (&range->prefix, buf, sizeof (buf));
504 vty_out (vty, " area %s range %s%s", oa->name, buf, VNL);
505 }
506 if (PREFIX_NAME_IN (oa))
507 vty_out (vty, " area %s filter-list prefix %s in%s",
508 oa->name, PREFIX_NAME_IN (oa), VNL);
509 if (PREFIX_NAME_OUT (oa))
510 vty_out (vty, " area %s filter-list prefix %s out%s",
511 oa->name, PREFIX_NAME_OUT (oa), VNL);
512 if (IMPORT_NAME (oa))
513 vty_out (vty, " area %s import-list %s%s",
514 oa->name, IMPORT_NAME (oa), VNL);
515 if (EXPORT_NAME (oa))
516 vty_out (vty, " area %s export-list %s%s",
517 oa->name, EXPORT_NAME (oa), VNL);
518 }
519 }
520
521 DEFUN (area_filter_list,
522 area_filter_list_cmd,
523 "area A.B.C.D filter-list prefix WORD (in|out)",
524 "OSPFv6 area parameters\n"
525 "OSPFv6 area ID in IP address format\n"
526 "Filter networks between OSPFv6 areas\n"
527 "Filter prefixes between OSPFv6 areas\n"
528 "Name of an IPv6 prefix-list\n"
529 "Filter networks sent to this area\n"
530 "Filter networks sent from this area\n")
531 {
532 struct ospf6_area *area;
533 struct prefix_list *plist;
534
535 OSPF6_CMD_AREA_GET (argv[0], area);
536 argc--;
537 argv++;
538
539 plist = prefix_list_lookup (AFI_IP6, argv[0]);
540 if (strncmp (argv[1], "in", 2) == 0)
541 {
542 PREFIX_LIST_IN (area) = plist;
543 if (PREFIX_NAME_IN (area))
544 free (PREFIX_NAME_IN (area));
545
546 PREFIX_NAME_IN (area) = strdup (argv[0]);
547 ospf6_abr_reimport (area);
548 }
549 else
550 {
551 PREFIX_LIST_OUT (area) = plist;
552 if (PREFIX_NAME_OUT (area))
553 free (PREFIX_NAME_OUT (area));
554
555 PREFIX_NAME_OUT (area) = strdup (argv[0]);
556 ospf6_abr_enable_area (area);
557 }
558
559 return CMD_SUCCESS;
560 }
561
562 DEFUN (no_area_filter_list,
563 no_area_filter_list_cmd,
564 "no area A.B.C.D filter-list prefix WORD (in|out)",
565 NO_STR
566 "OSPFv6 area parameters\n"
567 "OSPFv6 area ID in IP address format\n"
568 "Filter networks between OSPFv6 areas\n"
569 "Filter prefixes between OSPFv6 areas\n"
570 "Name of an IPv6 prefix-list\n"
571 "Filter networks sent to this area\n"
572 "Filter networks sent from this area\n")
573 {
574 struct ospf6_area *area;
575 struct prefix_list *plist;
576
577 OSPF6_CMD_AREA_GET (argv[0], area);
578 argc--;
579 argv++;
580
581 plist = prefix_list_lookup (AFI_IP6, argv[0]);
582 if (strncmp (argv[1], "in", 2) == 0)
583 {
584 if (PREFIX_NAME_IN (area))
585 if (strcmp (PREFIX_NAME_IN (area), argv[0]) != 0)
586 return CMD_SUCCESS;
587
588 PREFIX_LIST_IN (area) = NULL;
589 if (PREFIX_NAME_IN (area))
590 free (PREFIX_NAME_IN (area));
591
592 PREFIX_NAME_IN (area) = NULL;
593 ospf6_abr_reimport (area);
594 }
595 else
596 {
597 if (PREFIX_NAME_OUT (area))
598 if (strcmp (PREFIX_NAME_OUT (area), argv[0]) != 0)
599 return CMD_SUCCESS;
600
601 PREFIX_LIST_OUT (area) = NULL;
602 if (PREFIX_NAME_OUT (area))
603 free (PREFIX_NAME_OUT (area));
604
605 PREFIX_NAME_OUT (area) = NULL;
606 ospf6_abr_enable_area (area);
607 }
608
609 return CMD_SUCCESS;
610 }
611
612 DEFUN (area_import_list,
613 area_import_list_cmd,
614 "area A.B.C.D import-list NAME",
615 "OSPFv6 area parameters\n"
616 "OSPFv6 area ID in IP address format\n"
617 "Set the filter for networks from other areas announced to the specified one\n"
618 "Name of the acess-list\n")
619 {
620 struct ospf6_area *area;
621 struct access_list *list;
622
623 OSPF6_CMD_AREA_GET(argv[0], area);
624
625 list = access_list_lookup (AFI_IP6, argv[1]);
626
627 IMPORT_LIST (area) = list;
628
629 if (IMPORT_NAME (area))
630 free (IMPORT_NAME (area));
631
632 IMPORT_NAME (area) = strdup (argv[1]);
633 ospf6_abr_reimport (area);
634
635 return CMD_SUCCESS;
636 }
637
638 DEFUN (no_area_import_list,
639 no_area_import_list_cmd,
640 "no area A.B.C.D import-list NAME",
641 "OSPFv6 area parameters\n"
642 "OSPFv6 area ID in IP address format\n"
643 "Unset the filter for networks announced to other areas\n"
644 "NAme of the access-list\n")
645 {
646 struct ospf6_area *area;
647
648 OSPF6_CMD_AREA_GET(argv[0], area);
649
650 IMPORT_LIST (area) = 0;
651
652 if (IMPORT_NAME (area))
653 free (IMPORT_NAME (area));
654
655 IMPORT_NAME (area) = NULL;
656 ospf6_abr_reimport (area);
657
658 return CMD_SUCCESS;
659 }
660
661 DEFUN (area_export_list,
662 area_export_list_cmd,
663 "area A.B.C.D export-list NAME",
664 "OSPFv6 area parameters\n"
665 "OSPFv6 area ID in IP address format\n"
666 "Set the filter for networks announced to other areas\n"
667 "Name of the acess-list\n")
668 {
669 struct ospf6_area *area;
670 struct access_list *list;
671
672 OSPF6_CMD_AREA_GET(argv[0], area);
673
674 list = access_list_lookup (AFI_IP6, argv[1]);
675
676 EXPORT_LIST (area) = list;
677
678 if (EXPORT_NAME (area))
679 free (EXPORT_NAME (area));
680
681 EXPORT_NAME (area) = strdup (argv[1]);
682 ospf6_abr_enable_area (area);
683
684 return CMD_SUCCESS;
685 }
686
687 DEFUN (no_area_export_list,
688 no_area_export_list_cmd,
689 "no area A.B.C.D export-list NAME",
690 "OSPFv6 area parameters\n"
691 "OSPFv6 area ID in IP address format\n"
692 "Unset the filter for networks announced to other areas\n"
693 "Name of the access-list\n")
694 {
695 struct ospf6_area *area;
696
697 OSPF6_CMD_AREA_GET(argv[0], area);
698
699 EXPORT_LIST (area) = 0;
700
701 if (EXPORT_NAME (area))
702 free (EXPORT_NAME (area));
703
704 EXPORT_NAME (area) = NULL;
705 ospf6_abr_enable_area (area);
706
707 return CMD_SUCCESS;
708 }
709
710 DEFUN (show_ipv6_ospf6_spf_tree,
711 show_ipv6_ospf6_spf_tree_cmd,
712 "show ipv6 ospf6 spf tree",
713 SHOW_STR
714 IP6_STR
715 OSPF6_STR
716 "Shortest Path First caculation\n"
717 "Show SPF tree\n")
718 {
719 struct listnode *node;
720 struct ospf6_area *oa;
721 struct ospf6_vertex *root;
722 struct ospf6_route *route;
723 struct prefix prefix;
724
725 ospf6_linkstate_prefix (ospf6->router_id, htonl (0), &prefix);
726
727 for (ALL_LIST_ELEMENTS_RO (ospf6->area_list, node, oa))
728 {
729 route = ospf6_route_lookup (&prefix, oa->spf_table);
730 if (route == NULL)
731 {
732 vty_out (vty, "LS entry for root not found in area %s%s",
733 oa->name, VNL);
734 continue;
735 }
736 root = (struct ospf6_vertex *) route->route_option;
737 ospf6_spf_display_subtree (vty, "", 0, root);
738 }
739
740 return CMD_SUCCESS;
741 }
742
743 DEFUN (show_ipv6_ospf6_area_spf_tree,
744 show_ipv6_ospf6_area_spf_tree_cmd,
745 "show ipv6 ospf6 area A.B.C.D spf tree",
746 SHOW_STR
747 IP6_STR
748 OSPF6_STR
749 OSPF6_AREA_STR
750 OSPF6_AREA_ID_STR
751 "Shortest Path First caculation\n"
752 "Show SPF tree\n")
753 {
754 u_int32_t area_id;
755 struct ospf6_area *oa;
756 struct ospf6_vertex *root;
757 struct ospf6_route *route;
758 struct prefix prefix;
759
760 ospf6_linkstate_prefix (ospf6->router_id, htonl (0), &prefix);
761
762 if (inet_pton (AF_INET, argv[0], &area_id) != 1)
763 {
764 vty_out (vty, "Malformed Area-ID: %s%s", argv[0], VNL);
765 return CMD_SUCCESS;
766 }
767 oa = ospf6_area_lookup (area_id, ospf6);
768 if (oa == NULL)
769 {
770 vty_out (vty, "No such Area: %s%s", argv[0], VNL);
771 return CMD_SUCCESS;
772 }
773
774 route = ospf6_route_lookup (&prefix, oa->spf_table);
775 if (route == NULL)
776 {
777 vty_out (vty, "LS entry for root not found in area %s%s",
778 oa->name, VNL);
779 return CMD_SUCCESS;
780 }
781 root = (struct ospf6_vertex *) route->route_option;
782 ospf6_spf_display_subtree (vty, "", 0, root);
783
784 return CMD_SUCCESS;
785 }
786
787 DEFUN (show_ipv6_ospf6_simulate_spf_tree_root,
788 show_ipv6_ospf6_simulate_spf_tree_root_cmd,
789 "show ipv6 ospf6 simulate spf-tree A.B.C.D area A.B.C.D",
790 SHOW_STR
791 IP6_STR
792 OSPF6_STR
793 "Shortest Path First caculation\n"
794 "Show SPF tree\n"
795 "Specify root's router-id to calculate another router's SPF tree\n")
796 {
797 u_int32_t area_id;
798 struct ospf6_area *oa;
799 struct ospf6_vertex *root;
800 struct ospf6_route *route;
801 struct prefix prefix;
802 u_int32_t router_id;
803 struct ospf6_route_table *spf_table;
804 unsigned char tmp_debug_ospf6_spf = 0;
805
806 inet_pton (AF_INET, argv[0], &router_id);
807 ospf6_linkstate_prefix (router_id, htonl (0), &prefix);
808
809 if (inet_pton (AF_INET, argv[1], &area_id) != 1)
810 {
811 vty_out (vty, "Malformed Area-ID: %s%s", argv[1], VNL);
812 return CMD_SUCCESS;
813 }
814 oa = ospf6_area_lookup (area_id, ospf6);
815 if (oa == NULL)
816 {
817 vty_out (vty, "No such Area: %s%s", argv[1], VNL);
818 return CMD_SUCCESS;
819 }
820
821 tmp_debug_ospf6_spf = conf_debug_ospf6_spf;
822 conf_debug_ospf6_spf = 0;
823
824 spf_table = OSPF6_ROUTE_TABLE_CREATE (NONE, SPF_RESULTS);
825 ospf6_spf_calculation (router_id, spf_table, oa);
826
827 conf_debug_ospf6_spf = tmp_debug_ospf6_spf;
828
829 route = ospf6_route_lookup (&prefix, spf_table);
830 if (route == NULL)
831 {
832 ospf6_spf_table_finish (spf_table);
833 ospf6_route_table_delete (spf_table);
834 return CMD_SUCCESS;
835 }
836 root = (struct ospf6_vertex *) route->route_option;
837 ospf6_spf_display_subtree (vty, "", 0, root);
838
839 ospf6_spf_table_finish (spf_table);
840 ospf6_route_table_delete (spf_table);
841
842 return CMD_SUCCESS;
843 }
844
845 void
846 ospf6_area_init (void)
847 {
848 install_element (VIEW_NODE, &show_ipv6_ospf6_spf_tree_cmd);
849 install_element (VIEW_NODE, &show_ipv6_ospf6_area_spf_tree_cmd);
850 install_element (VIEW_NODE, &show_ipv6_ospf6_simulate_spf_tree_root_cmd);
851
852 install_element (ENABLE_NODE, &show_ipv6_ospf6_spf_tree_cmd);
853 install_element (ENABLE_NODE, &show_ipv6_ospf6_area_spf_tree_cmd);
854 install_element (ENABLE_NODE, &show_ipv6_ospf6_simulate_spf_tree_root_cmd);
855
856 install_element (OSPF6_NODE, &area_range_cmd);
857 install_element (OSPF6_NODE, &area_range_advertise_cmd);
858 install_element (OSPF6_NODE, &area_range_cost_cmd);
859 install_element (OSPF6_NODE, &area_range_advertise_cost_cmd);
860 install_element (OSPF6_NODE, &no_area_range_cmd);
861
862 install_element (OSPF6_NODE, &area_import_list_cmd);
863 install_element (OSPF6_NODE, &no_area_import_list_cmd);
864 install_element (OSPF6_NODE, &area_export_list_cmd);
865 install_element (OSPF6_NODE, &no_area_export_list_cmd);
866
867 install_element (OSPF6_NODE, &area_filter_list_cmd);
868 install_element (OSPF6_NODE, &no_area_filter_list_cmd);
869
870 }
871
872