]> git.proxmox.com Git - mirror_frr.git/blob - ospf6d/ospf6_area.c
*: rename all instances of OSPFv6 to OSPF6 or OSPFv3
[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 "ospf6_asbr.h"
47 #include "ospf6d.h"
48
49 int
50 ospf6_area_cmp (void *va, void *vb)
51 {
52 struct ospf6_area *oa = (struct ospf6_area *) va;
53 struct ospf6_area *ob = (struct ospf6_area *) vb;
54 return (ntohl (oa->area_id) < ntohl (ob->area_id) ? -1 : 1);
55 }
56
57 /* schedule routing table recalculation */
58 static void
59 ospf6_area_lsdb_hook_add (struct ospf6_lsa *lsa)
60 {
61 switch (ntohs (lsa->header->type))
62 {
63 case OSPF6_LSTYPE_ROUTER:
64 case OSPF6_LSTYPE_NETWORK:
65 if (IS_OSPF6_DEBUG_EXAMIN_TYPE (lsa->header->type))
66 {
67 zlog_debug ("Examin %s", lsa->name);
68 zlog_debug ("Schedule SPF Calculation for %s",
69 OSPF6_AREA (lsa->lsdb->data)->name);
70 }
71 ospf6_spf_schedule (OSPF6_PROCESS(OSPF6_AREA (lsa->lsdb->data)->ospf6),
72 ospf6_lsadd_to_spf_reason(lsa));
73 break;
74
75 case OSPF6_LSTYPE_INTRA_PREFIX:
76 ospf6_intra_prefix_lsa_add (lsa);
77 break;
78
79 case OSPF6_LSTYPE_INTER_PREFIX:
80 case OSPF6_LSTYPE_INTER_ROUTER:
81 ospf6_abr_examin_summary (lsa, (struct ospf6_area *) lsa->lsdb->data);
82 break;
83
84 default:
85 break;
86 }
87 }
88
89 static void
90 ospf6_area_lsdb_hook_remove (struct ospf6_lsa *lsa)
91 {
92 switch (ntohs (lsa->header->type))
93 {
94 case OSPF6_LSTYPE_ROUTER:
95 case OSPF6_LSTYPE_NETWORK:
96 if (IS_OSPF6_DEBUG_EXAMIN_TYPE (lsa->header->type))
97 {
98 zlog_debug ("LSA disappearing: %s", lsa->name);
99 zlog_debug ("Schedule SPF Calculation for %s",
100 OSPF6_AREA (lsa->lsdb->data)->name);
101 }
102 ospf6_spf_schedule (OSPF6_PROCESS(OSPF6_AREA (lsa->lsdb->data)->ospf6),
103 ospf6_lsremove_to_spf_reason(lsa));
104 break;
105
106 case OSPF6_LSTYPE_INTRA_PREFIX:
107 ospf6_intra_prefix_lsa_remove (lsa);
108 break;
109
110 case OSPF6_LSTYPE_INTER_PREFIX:
111 case OSPF6_LSTYPE_INTER_ROUTER:
112 ospf6_abr_examin_summary (lsa, (struct ospf6_area *) lsa->lsdb->data);
113 break;
114
115 default:
116 break;
117 }
118 }
119
120 static void
121 ospf6_area_route_hook_add (struct ospf6_route *route)
122 {
123 struct ospf6_route *copy = ospf6_route_copy (route);
124 ospf6_route_add (copy, ospf6->route_table);
125 }
126
127 static void
128 ospf6_area_route_hook_remove (struct ospf6_route *route)
129 {
130 struct ospf6_route *copy;
131
132 copy = ospf6_route_lookup_identical (route, ospf6->route_table);
133 if (copy)
134 ospf6_route_remove (copy, ospf6->route_table);
135 }
136
137 static void
138 ospf6_area_stub_update (struct ospf6_area *area)
139 {
140
141 if (IS_AREA_STUB (area))
142 {
143 if (IS_OSPF6_DEBUG_ORIGINATE (ROUTER))
144 zlog_debug ("Stubbing out area for if %s\n", area->name);
145 OSPF6_OPT_CLEAR (area->options, OSPF6_OPT_E);
146 }
147 else if (IS_AREA_ENABLED (area))
148 {
149 if (IS_OSPF6_DEBUG_ORIGINATE (ROUTER))
150 zlog_debug ("Normal area for if %s\n", area->name);
151 OSPF6_OPT_SET (area->options, OSPF6_OPT_E);
152 ospf6_asbr_send_externals_to_area (area);
153 }
154
155 OSPF6_ROUTER_LSA_SCHEDULE(area);
156 }
157
158 static int
159 ospf6_area_stub_set (struct ospf6 *ospf6, struct ospf6_area *area)
160 {
161 if (!IS_AREA_STUB(area))
162 {
163 SET_FLAG (area->flag, OSPF6_AREA_STUB);
164 ospf6_area_stub_update (area);
165 }
166
167 return (1);
168 }
169
170 static void
171 ospf6_area_stub_unset (struct ospf6 *ospf6, struct ospf6_area *area)
172 {
173 if (IS_AREA_STUB (area))
174 {
175 UNSET_FLAG (area->flag, OSPF6_AREA_STUB);
176 ospf6_area_stub_update (area);
177 }
178 }
179
180 static void
181 ospf6_area_no_summary_set (struct ospf6 *ospf6, struct ospf6_area *area)
182 {
183 if (area)
184 {
185 if (!area->no_summary)
186 {
187 area->no_summary = 1;
188 ospf6_abr_range_reset_cost (ospf6);
189 ospf6_abr_prefix_resummarize (ospf6);
190 }
191 }
192 }
193
194 static void
195 ospf6_area_no_summary_unset (struct ospf6 *ospf6, struct ospf6_area *area)
196 {
197 if (area)
198 {
199 if (area->no_summary)
200 {
201 area->no_summary = 0;
202 ospf6_abr_range_reset_cost (ospf6);
203 ospf6_abr_prefix_resummarize (ospf6);
204 }
205 }
206 }
207
208 /* Make new area structure */
209 struct ospf6_area *
210 ospf6_area_create (u_int32_t area_id, struct ospf6 *o)
211 {
212 struct ospf6_area *oa;
213
214 oa = XCALLOC (MTYPE_OSPF6_AREA, sizeof (struct ospf6_area));
215
216 inet_ntop (AF_INET, &area_id, oa->name, sizeof (oa->name));
217 oa->area_id = area_id;
218 oa->if_list = list_new ();
219
220 oa->lsdb = ospf6_lsdb_create (oa);
221 oa->lsdb->hook_add = ospf6_area_lsdb_hook_add;
222 oa->lsdb->hook_remove = ospf6_area_lsdb_hook_remove;
223 oa->lsdb_self = ospf6_lsdb_create (oa);
224
225 oa->spf_table = OSPF6_ROUTE_TABLE_CREATE (AREA, SPF_RESULTS);
226 oa->spf_table->scope = oa;
227 oa->route_table = OSPF6_ROUTE_TABLE_CREATE (AREA, ROUTES);
228 oa->route_table->scope = oa;
229 oa->route_table->hook_add = ospf6_area_route_hook_add;
230 oa->route_table->hook_remove = ospf6_area_route_hook_remove;
231
232 oa->range_table = OSPF6_ROUTE_TABLE_CREATE (AREA, PREFIX_RANGES);
233 oa->range_table->scope = oa;
234 bf_init(oa->range_table->idspace, 32);
235 oa->summary_prefix = OSPF6_ROUTE_TABLE_CREATE (AREA, SUMMARY_PREFIXES);
236 oa->summary_prefix->scope = oa;
237 oa->summary_router = OSPF6_ROUTE_TABLE_CREATE (AREA, SUMMARY_ROUTERS);
238 oa->summary_router->scope = oa;
239
240 /* set default options */
241 if (CHECK_FLAG (o->flag, OSPF6_STUB_ROUTER))
242 {
243 OSPF6_OPT_CLEAR (oa->options, OSPF6_OPT_V6);
244 OSPF6_OPT_CLEAR (oa->options, OSPF6_OPT_R);
245 }
246 else
247 {
248 OSPF6_OPT_SET (oa->options, OSPF6_OPT_V6);
249 OSPF6_OPT_SET (oa->options, OSPF6_OPT_R);
250 }
251
252 OSPF6_OPT_SET (oa->options, OSPF6_OPT_E);
253
254 SET_FLAG (oa->flag, OSPF6_AREA_ACTIVE);
255 SET_FLAG (oa->flag, OSPF6_AREA_ENABLE);
256
257 oa->ospf6 = o;
258 listnode_add_sort (o->area_list, oa);
259
260 if (area_id == OSPF_AREA_BACKBONE)
261 {
262 o->backbone = oa;
263 }
264
265 return oa;
266 }
267
268 void
269 ospf6_area_delete (struct ospf6_area *oa)
270 {
271 struct listnode *n;
272 struct ospf6_interface *oi;
273
274 /* The ospf6_interface structs store configuration
275 * information which should not be lost/reset when
276 * deleting an area.
277 * So just detach the interface from the area and
278 * keep it around. */
279 for (ALL_LIST_ELEMENTS_RO (oa->if_list, n, oi))
280 oi->area = NULL;
281
282 list_delete (oa->if_list);
283
284 ospf6_lsdb_delete (oa->lsdb);
285 ospf6_lsdb_delete (oa->lsdb_self);
286
287 ospf6_spf_table_finish (oa->spf_table);
288 ospf6_route_table_delete (oa->spf_table);
289 ospf6_route_table_delete (oa->route_table);
290
291 ospf6_route_table_delete (oa->range_table);
292 ospf6_route_table_delete (oa->summary_prefix);
293 ospf6_route_table_delete (oa->summary_router);
294
295 listnode_delete (oa->ospf6->area_list, oa);
296 oa->ospf6 = NULL;
297
298 /* free area */
299 XFREE (MTYPE_OSPF6_AREA, oa);
300 }
301
302 struct ospf6_area *
303 ospf6_area_lookup (u_int32_t area_id, struct ospf6 *ospf6)
304 {
305 struct ospf6_area *oa;
306 struct listnode *n;
307
308 for (ALL_LIST_ELEMENTS_RO (ospf6->area_list, n, oa))
309 if (oa->area_id == area_id)
310 return oa;
311
312 return (struct ospf6_area *) NULL;
313 }
314
315 static struct ospf6_area *
316 ospf6_area_get (u_int32_t area_id, struct ospf6 *o)
317 {
318 struct ospf6_area *oa;
319 oa = ospf6_area_lookup (area_id, o);
320 if (oa == NULL)
321 oa = ospf6_area_create (area_id, o);
322 return oa;
323 }
324
325 void
326 ospf6_area_enable (struct ospf6_area *oa)
327 {
328 struct listnode *node, *nnode;
329 struct ospf6_interface *oi;
330
331 SET_FLAG (oa->flag, OSPF6_AREA_ENABLE);
332
333 for (ALL_LIST_ELEMENTS (oa->if_list, node, nnode, oi))
334 ospf6_interface_enable (oi);
335 ospf6_abr_enable_area (oa);
336 }
337
338 void
339 ospf6_area_disable (struct ospf6_area *oa)
340 {
341 struct listnode *node, *nnode;
342 struct ospf6_interface *oi;
343
344 UNSET_FLAG (oa->flag, OSPF6_AREA_ENABLE);
345
346 for (ALL_LIST_ELEMENTS (oa->if_list, node, nnode, oi))
347 ospf6_interface_disable (oi);
348
349 ospf6_abr_disable_area (oa);
350 ospf6_lsdb_remove_all (oa->lsdb);
351 ospf6_lsdb_remove_all (oa->lsdb_self);
352
353 ospf6_spf_table_finish(oa->spf_table);
354 ospf6_route_remove_all(oa->route_table);
355
356 THREAD_OFF (oa->thread_router_lsa);
357 THREAD_OFF (oa->thread_intra_prefix_lsa);
358 }
359
360
361 void
362 ospf6_area_show (struct vty *vty, struct ospf6_area *oa)
363 {
364 struct listnode *i;
365 struct ospf6_interface *oi;
366 unsigned long result;
367
368 if (!IS_AREA_STUB (oa))
369 vty_out (vty, " Area %s%s", oa->name, VNL);
370 else
371 {
372 if (oa->no_summary)
373 {
374 vty_out (vty, " Area %s[Stub, No Summary]%s", oa->name, VNL);
375 }
376 else
377 {
378 vty_out (vty, " Area %s[Stub]%s", oa->name, VNL);
379 }
380 }
381 vty_out (vty, " Number of Area scoped LSAs is %u%s",
382 oa->lsdb->count, VNL);
383
384 vty_out (vty, " Interface attached to this area:");
385 for (ALL_LIST_ELEMENTS_RO (oa->if_list, i, oi))
386 vty_out (vty, " %s", oi->interface->name);
387 vty_out (vty, "%s", VNL);
388
389 if (oa->ts_spf.tv_sec || oa->ts_spf.tv_usec)
390 {
391 result = timeval_elapsed (recent_relative_time (), oa->ts_spf);
392 if (result/TIMER_SECOND_MICRO > 0)
393 {
394 vty_out (vty, "SPF last executed %ld.%lds ago%s",
395 result/TIMER_SECOND_MICRO,
396 result%TIMER_SECOND_MICRO, VTY_NEWLINE);
397 }
398 else
399 {
400 vty_out (vty, "SPF last executed %ldus ago%s",
401 result, VTY_NEWLINE);
402 }
403 }
404 else
405 vty_out (vty, "SPF has not been run%s", VTY_NEWLINE);
406 }
407
408
409 #define OSPF6_CMD_AREA_LOOKUP(str, oa) \
410 { \
411 u_int32_t area_id = 0; \
412 if (inet_pton (AF_INET, str, &area_id) != 1) \
413 { \
414 vty_out (vty, "Malformed Area-ID: %s%s", str, VNL); \
415 return CMD_SUCCESS; \
416 } \
417 oa = ospf6_area_lookup (area_id, ospf6); \
418 if (oa == NULL) \
419 { \
420 vty_out (vty, "No such Area: %s%s", str, VNL); \
421 return CMD_SUCCESS; \
422 } \
423 }
424
425 #define OSPF6_CMD_AREA_GET(str, oa) \
426 { \
427 u_int32_t area_id = 0; \
428 if (inet_pton (AF_INET, str, &area_id) != 1) \
429 { \
430 vty_out (vty, "Malformed Area-ID: %s%s", str, VNL); \
431 return CMD_SUCCESS; \
432 } \
433 oa = ospf6_area_get (area_id, ospf6); \
434 }
435
436 DEFUN (area_range,
437 area_range_cmd,
438 "area <A.B.C.D|(0-4294967295)> range X:X::X:X/M [<advertise|not-advertise|cost (0-16777215)>]",
439 "OSPF area parameters\n"
440 OSPF6_AREA_ID_STR
441 "Configured address range\n"
442 "Specify IPv6 prefix\n"
443 "Advertise\n"
444 "Do not advertise\n"
445 "User specified metric for this range\n"
446 "Advertised metric for this range\n")
447 {
448 int idx_ipv4 = 1;
449 int idx_ipv6_prefixlen = 3;
450 int idx_type = 4;
451 int ret;
452 struct ospf6_area *oa;
453 struct prefix prefix;
454 struct ospf6_route *range;
455 u_int32_t cost = OSPF_AREA_RANGE_COST_UNSPEC;
456
457 OSPF6_CMD_AREA_GET (argv[idx_ipv4]->arg, oa);
458
459 ret = str2prefix (argv[idx_ipv6_prefixlen]->arg, &prefix);
460 if (ret != 1 || prefix.family != AF_INET6)
461 {
462 vty_out (vty, "Malformed argument: %s%s", argv[idx_ipv6_prefixlen]->arg, VNL);
463 return CMD_SUCCESS;
464 }
465
466 range = ospf6_route_lookup (&prefix, oa->range_table);
467 if (range == NULL)
468 {
469 range = ospf6_route_create ();
470 range->type = OSPF6_DEST_TYPE_RANGE;
471 range->prefix = prefix;
472 range->path.area_id = oa->area_id;
473 range->path.cost = OSPF_AREA_RANGE_COST_UNSPEC;
474 range->linkstate_id =
475 (u_int32_t) htonl(ospf6_new_range_ls_id (oa->range_table));
476 }
477
478 if (argc > idx_type)
479 {
480 if (strmatch (argv[idx_type]->text, "not-advertise"))
481 {
482 SET_FLAG (range->flag, OSPF6_ROUTE_DO_NOT_ADVERTISE);
483 }
484 else if (strmatch (argv[idx_type]->text, "advertise"))
485 {
486 UNSET_FLAG (range->flag, OSPF6_ROUTE_DO_NOT_ADVERTISE);
487 }
488 else
489 {
490 VTY_GET_INTEGER_RANGE ("cost", cost, argv[5]->arg, 0, OSPF_LS_INFINITY);
491 UNSET_FLAG (range->flag, OSPF6_ROUTE_DO_NOT_ADVERTISE);
492 }
493 }
494
495 range->path.u.cost_config = cost;
496
497 zlog_debug ("%s: for prefix %s, flag = %x\n", __func__, argv[idx_ipv6_prefixlen]->arg, range->flag);
498 if (range->rnode == NULL)
499 {
500 ospf6_route_add (range, oa->range_table);
501 }
502
503 if (ospf6_is_router_abr (ospf6))
504 {
505 /* Redo summaries if required */
506 ospf6_abr_prefix_resummarize (ospf6);
507 }
508
509 return CMD_SUCCESS;
510 }
511
512 DEFUN (no_area_range,
513 no_area_range_cmd,
514 "no area A.B.C.D range X:X::X:X/M [<advertise|not-advertise>] [cost (0-16777215)]",
515 NO_STR
516 "OSPF area parameters\n"
517 OSPF6_AREA_ID_STR
518 "Configured address range\n"
519 "Specify IPv6 prefix\n")
520 {
521 int idx_ipv4 = 2;
522 int ret;
523 struct ospf6_area *oa;
524 struct prefix prefix;
525 struct ospf6_route *range, *route;
526
527 OSPF6_CMD_AREA_GET (argv[idx_ipv4]->arg, oa);
528
529 ret = str2prefix (argv[idx_ipv4]->arg, &prefix);
530 if (ret != 1 || prefix.family != AF_INET6)
531 {
532 vty_out (vty, "Malformed argument: %s%s", argv[idx_ipv4]->arg, VNL);
533 return CMD_SUCCESS;
534 }
535
536 range = ospf6_route_lookup (&prefix, oa->range_table);
537 if (range == NULL)
538 {
539 vty_out (vty, "Range %s does not exists.%s", argv[idx_ipv4]->arg, VNL);
540 return CMD_SUCCESS;
541 }
542
543 if (ospf6_is_router_abr(oa->ospf6))
544 {
545 /* Blow away the aggregated LSA and route */
546 SET_FLAG (range->flag, OSPF6_ROUTE_REMOVE);
547
548 /* Redo summaries if required */
549 for (route = ospf6_route_head (ospf6->route_table); route;
550 route = ospf6_route_next (route))
551 ospf6_abr_originate_summary(route);
552
553 /* purge the old aggregated summary LSA */
554 ospf6_abr_originate_summary(range);
555 }
556 ospf6_release_range_ls_id(oa->range_table,
557 (u_int32_t) ntohl(range->linkstate_id));
558 ospf6_route_remove (range, oa->range_table);
559
560 return CMD_SUCCESS;
561 }
562
563
564
565
566 void
567 ospf6_area_config_write (struct vty *vty)
568 {
569 struct listnode *node;
570 struct ospf6_area *oa;
571 struct ospf6_route *range;
572 char buf[PREFIX2STR_BUFFER];
573
574 for (ALL_LIST_ELEMENTS_RO (ospf6->area_list, node, oa))
575 {
576 for (range = ospf6_route_head (oa->range_table); range;
577 range = ospf6_route_next (range))
578 {
579 prefix2str (&range->prefix, buf, sizeof (buf));
580 vty_out (vty, " area %s range %s", oa->name, buf);
581
582 if (CHECK_FLAG (range->flag, OSPF6_ROUTE_DO_NOT_ADVERTISE))
583 {
584 vty_out (vty, " not-advertise");
585 }
586 else
587 {
588 // "advertise" is the default so we do not display it
589 if (range->path.u.cost_config != OSPF_AREA_RANGE_COST_UNSPEC)
590 vty_out (vty, " cost %d", range->path.u.cost_config);
591 }
592 vty_out (vty, "%s", VNL);
593
594 }
595 if (IS_AREA_STUB (oa))
596 {
597 if (oa->no_summary)
598 vty_out (vty, " area %s stub no-summary%s", oa->name, VNL);
599 else
600 vty_out (vty, " area %s stub%s", oa->name, VNL);
601 }
602 if (PREFIX_NAME_IN (oa))
603 vty_out (vty, " area %s filter-list prefix %s in%s",
604 oa->name, PREFIX_NAME_IN (oa), VNL);
605 if (PREFIX_NAME_OUT (oa))
606 vty_out (vty, " area %s filter-list prefix %s out%s",
607 oa->name, PREFIX_NAME_OUT (oa), VNL);
608 if (IMPORT_NAME (oa))
609 vty_out (vty, " area %s import-list %s%s",
610 oa->name, IMPORT_NAME (oa), VNL);
611 if (EXPORT_NAME (oa))
612 vty_out (vty, " area %s export-list %s%s",
613 oa->name, EXPORT_NAME (oa), VNL);
614 }
615 }
616
617 DEFUN (area_filter_list,
618 area_filter_list_cmd,
619 "area A.B.C.D filter-list prefix WORD <in|out>",
620 "OSPF6 area parameters\n"
621 "OSPF6 area ID in IP address format\n"
622 "Filter networks between OSPF6 areas\n"
623 "Filter prefixes between OSPF6 areas\n"
624 "Name of an IPv6 prefix-list\n"
625 "Filter networks sent to this area\n"
626 "Filter networks sent from this area\n")
627 {
628 int idx_ipv4 = 1;
629 int idx_word = 4;
630 struct ospf6_area *area;
631 struct prefix_list *plist;
632
633 OSPF6_CMD_AREA_GET (argv[idx_ipv4]->arg, area);
634
635 plist = prefix_list_lookup (AFI_IP6, argv[idx_ipv4]->arg);
636 if (strncmp (argv[idx_word]->arg, "in", 2) == 0)
637 {
638 PREFIX_LIST_IN (area) = plist;
639 if (PREFIX_NAME_IN (area))
640 free (PREFIX_NAME_IN (area));
641
642 PREFIX_NAME_IN (area) = strdup (argv[idx_ipv4]->arg);
643 ospf6_abr_reimport (area);
644 }
645 else
646 {
647 PREFIX_LIST_OUT (area) = plist;
648 if (PREFIX_NAME_OUT (area))
649 free (PREFIX_NAME_OUT (area));
650
651 PREFIX_NAME_OUT (area) = strdup (argv[idx_ipv4]->arg);
652 ospf6_abr_enable_area (area);
653 }
654
655 return CMD_SUCCESS;
656 }
657
658 DEFUN (no_area_filter_list,
659 no_area_filter_list_cmd,
660 "no area A.B.C.D filter-list prefix WORD <in|out>",
661 NO_STR
662 "OSPF6 area parameters\n"
663 "OSPF6 area ID in IP address format\n"
664 "Filter networks between OSPF6 areas\n"
665 "Filter prefixes between OSPF6 areas\n"
666 "Name of an IPv6 prefix-list\n"
667 "Filter networks sent to this area\n"
668 "Filter networks sent from this area\n")
669 {
670 int idx_ipv4 = 2;
671 int idx_word = 5;
672 struct ospf6_area *area;
673
674 OSPF6_CMD_AREA_GET (argv[idx_ipv4]->arg, area);
675
676 if (strncmp (argv[idx_word]->arg, "in", 2) == 0)
677 {
678 if (PREFIX_NAME_IN (area))
679 if (strcmp (PREFIX_NAME_IN (area), argv[idx_ipv4]->arg) != 0)
680 return CMD_SUCCESS;
681
682 PREFIX_LIST_IN (area) = NULL;
683 if (PREFIX_NAME_IN (area))
684 free (PREFIX_NAME_IN (area));
685
686 PREFIX_NAME_IN (area) = NULL;
687 ospf6_abr_reimport (area);
688 }
689 else
690 {
691 if (PREFIX_NAME_OUT (area))
692 if (strcmp (PREFIX_NAME_OUT (area), argv[idx_ipv4]->arg) != 0)
693 return CMD_SUCCESS;
694
695 PREFIX_LIST_OUT (area) = NULL;
696 if (PREFIX_NAME_OUT (area))
697 free (PREFIX_NAME_OUT (area));
698
699 PREFIX_NAME_OUT (area) = NULL;
700 ospf6_abr_enable_area (area);
701 }
702
703 return CMD_SUCCESS;
704 }
705
706 DEFUN (area_import_list,
707 area_import_list_cmd,
708 "area A.B.C.D import-list NAME",
709 "OSPF6 area parameters\n"
710 "OSPF6 area ID in IP address format\n"
711 "Set the filter for networks from other areas announced to the specified one\n"
712 "Name of the acess-list\n")
713 {
714 int idx_ipv4 = 1;
715 int idx_name = 3;
716 struct ospf6_area *area;
717 struct access_list *list;
718
719 OSPF6_CMD_AREA_GET(argv[idx_ipv4]->arg, area);
720
721 list = access_list_lookup (AFI_IP6, argv[idx_name]->arg);
722
723 IMPORT_LIST (area) = list;
724
725 if (IMPORT_NAME (area))
726 free (IMPORT_NAME (area));
727
728 IMPORT_NAME (area) = strdup (argv[idx_name]->arg);
729 ospf6_abr_reimport (area);
730
731 return CMD_SUCCESS;
732 }
733
734 DEFUN (no_area_import_list,
735 no_area_import_list_cmd,
736 "no area A.B.C.D import-list NAME",
737 "OSPF6 area parameters\n"
738 "OSPF6 area ID in IP address format\n"
739 "Unset the filter for networks announced to other areas\n"
740 "NAme of the access-list\n")
741 {
742 int idx_ipv4 = 2;
743 struct ospf6_area *area;
744
745 OSPF6_CMD_AREA_GET(argv[idx_ipv4]->arg, area);
746
747 IMPORT_LIST (area) = 0;
748
749 if (IMPORT_NAME (area))
750 free (IMPORT_NAME (area));
751
752 IMPORT_NAME (area) = NULL;
753 ospf6_abr_reimport (area);
754
755 return CMD_SUCCESS;
756 }
757
758 DEFUN (area_export_list,
759 area_export_list_cmd,
760 "area A.B.C.D export-list NAME",
761 "OSPF6 area parameters\n"
762 "OSPF6 area ID in IP address format\n"
763 "Set the filter for networks announced to other areas\n"
764 "Name of the acess-list\n")
765 {
766 int idx_ipv4 = 1;
767 int idx_name = 3;
768 struct ospf6_area *area;
769 struct access_list *list;
770
771 OSPF6_CMD_AREA_GET(argv[idx_ipv4]->arg, area);
772
773 list = access_list_lookup (AFI_IP6, argv[idx_name]->arg);
774
775 EXPORT_LIST (area) = list;
776
777 if (EXPORT_NAME (area))
778 free (EXPORT_NAME (area));
779
780 EXPORT_NAME (area) = strdup (argv[idx_name]->arg);
781 ospf6_abr_enable_area (area);
782
783 return CMD_SUCCESS;
784 }
785
786 DEFUN (no_area_export_list,
787 no_area_export_list_cmd,
788 "no area A.B.C.D export-list NAME",
789 "OSPF6 area parameters\n"
790 "OSPF6 area ID in IP address format\n"
791 "Unset the filter for networks announced to other areas\n"
792 "Name of the access-list\n")
793 {
794 int idx_ipv4 = 2;
795 struct ospf6_area *area;
796
797 OSPF6_CMD_AREA_GET(argv[idx_ipv4]->arg, area);
798
799 EXPORT_LIST (area) = 0;
800
801 if (EXPORT_NAME (area))
802 free (EXPORT_NAME (area));
803
804 EXPORT_NAME (area) = NULL;
805 ospf6_abr_enable_area (area);
806
807 return CMD_SUCCESS;
808 }
809
810 DEFUN (show_ipv6_ospf6_spf_tree,
811 show_ipv6_ospf6_spf_tree_cmd,
812 "show ipv6 ospf6 spf tree",
813 SHOW_STR
814 IP6_STR
815 OSPF6_STR
816 "Shortest Path First caculation\n"
817 "Show SPF tree\n")
818 {
819 struct listnode *node;
820 struct ospf6_area *oa;
821 struct ospf6_vertex *root;
822 struct ospf6_route *route;
823 struct prefix prefix;
824
825 OSPF6_CMD_CHECK_RUNNING ();
826
827 ospf6_linkstate_prefix (ospf6->router_id, htonl (0), &prefix);
828
829 for (ALL_LIST_ELEMENTS_RO (ospf6->area_list, node, oa))
830 {
831 route = ospf6_route_lookup (&prefix, oa->spf_table);
832 if (route == NULL)
833 {
834 vty_out (vty, "LS entry for root not found in area %s%s",
835 oa->name, VNL);
836 continue;
837 }
838 root = (struct ospf6_vertex *) route->route_option;
839 ospf6_spf_display_subtree (vty, "", 0, root);
840 }
841
842 return CMD_SUCCESS;
843 }
844
845 DEFUN (show_ipv6_ospf6_area_spf_tree,
846 show_ipv6_ospf6_area_spf_tree_cmd,
847 "show ipv6 ospf6 area A.B.C.D spf tree",
848 SHOW_STR
849 IP6_STR
850 OSPF6_STR
851 OSPF6_AREA_STR
852 OSPF6_AREA_ID_STR
853 "Shortest Path First caculation\n"
854 "Show SPF tree\n")
855 {
856 int idx_ipv4 = 4;
857 u_int32_t area_id;
858 struct ospf6_area *oa;
859 struct ospf6_vertex *root;
860 struct ospf6_route *route;
861 struct prefix prefix;
862
863 OSPF6_CMD_CHECK_RUNNING ();
864
865 ospf6_linkstate_prefix (ospf6->router_id, htonl (0), &prefix);
866
867 if (inet_pton (AF_INET, argv[idx_ipv4]->arg, &area_id) != 1)
868 {
869 vty_out (vty, "Malformed Area-ID: %s%s", argv[idx_ipv4]->arg, VNL);
870 return CMD_SUCCESS;
871 }
872 oa = ospf6_area_lookup (area_id, ospf6);
873 if (oa == NULL)
874 {
875 vty_out (vty, "No such Area: %s%s", argv[idx_ipv4]->arg, VNL);
876 return CMD_SUCCESS;
877 }
878
879 route = ospf6_route_lookup (&prefix, oa->spf_table);
880 if (route == NULL)
881 {
882 vty_out (vty, "LS entry for root not found in area %s%s",
883 oa->name, VNL);
884 return CMD_SUCCESS;
885 }
886 root = (struct ospf6_vertex *) route->route_option;
887 ospf6_spf_display_subtree (vty, "", 0, root);
888
889 return CMD_SUCCESS;
890 }
891
892 DEFUN (show_ipv6_ospf6_simulate_spf_tree_root,
893 show_ipv6_ospf6_simulate_spf_tree_root_cmd,
894 "show ipv6 ospf6 simulate spf-tree A.B.C.D area A.B.C.D",
895 SHOW_STR
896 IP6_STR
897 OSPF6_STR
898 "Shortest Path First caculation\n"
899 "Show SPF tree\n"
900 "Specify root's router-id to calculate another router's SPF tree\n")
901 {
902 int idx_ipv4 = 5;
903 int idx_ipv4_2 = 7;
904 u_int32_t area_id;
905 struct ospf6_area *oa;
906 struct ospf6_vertex *root;
907 struct ospf6_route *route;
908 struct prefix prefix;
909 u_int32_t router_id;
910 struct ospf6_route_table *spf_table;
911 unsigned char tmp_debug_ospf6_spf = 0;
912
913 OSPF6_CMD_CHECK_RUNNING ();
914
915 inet_pton (AF_INET, argv[idx_ipv4]->arg, &router_id);
916 ospf6_linkstate_prefix (router_id, htonl (0), &prefix);
917
918 if (inet_pton (AF_INET, argv[idx_ipv4_2]->arg, &area_id) != 1)
919 {
920 vty_out (vty, "Malformed Area-ID: %s%s", argv[idx_ipv4_2]->arg, VNL);
921 return CMD_SUCCESS;
922 }
923 oa = ospf6_area_lookup (area_id, ospf6);
924 if (oa == NULL)
925 {
926 vty_out (vty, "No such Area: %s%s", argv[idx_ipv4_2]->arg, VNL);
927 return CMD_SUCCESS;
928 }
929
930 tmp_debug_ospf6_spf = conf_debug_ospf6_spf;
931 conf_debug_ospf6_spf = 0;
932
933 spf_table = OSPF6_ROUTE_TABLE_CREATE (NONE, SPF_RESULTS);
934 ospf6_spf_calculation (router_id, spf_table, oa);
935
936 conf_debug_ospf6_spf = tmp_debug_ospf6_spf;
937
938 route = ospf6_route_lookup (&prefix, spf_table);
939 if (route == NULL)
940 {
941 ospf6_spf_table_finish (spf_table);
942 ospf6_route_table_delete (spf_table);
943 return CMD_SUCCESS;
944 }
945 root = (struct ospf6_vertex *) route->route_option;
946 ospf6_spf_display_subtree (vty, "", 0, root);
947
948 ospf6_spf_table_finish (spf_table);
949 ospf6_route_table_delete (spf_table);
950
951 return CMD_SUCCESS;
952 }
953
954 DEFUN (ospf6_area_stub,
955 ospf6_area_stub_cmd,
956 "area <A.B.C.D|(0-4294967295)> stub",
957 "OSPF6 area parameters\n"
958 "OSPF6 area ID in IP address format\n"
959 "OSPF6 area ID as a decimal value\n"
960 "Configure OSPF6 area as stub\n")
961 {
962 int idx_ipv4_number = 1;
963 struct ospf6_area *area;
964
965 OSPF6_CMD_AREA_GET(argv[idx_ipv4_number]->arg, area);
966
967 if (!ospf6_area_stub_set (ospf6, area))
968 {
969 vty_out (vty, "First deconfigure all virtual link through this area%s",
970 VTY_NEWLINE);
971 return CMD_WARNING;
972 }
973
974 ospf6_area_no_summary_unset (ospf6, area);
975
976 return CMD_SUCCESS;
977 }
978
979 DEFUN (ospf6_area_stub_no_summary,
980 ospf6_area_stub_no_summary_cmd,
981 "area <A.B.C.D|(0-4294967295)> stub no-summary",
982 "OSPF6 stub parameters\n"
983 "OSPF6 area ID in IP address format\n"
984 "OSPF6 area ID as a decimal value\n"
985 "Configure OSPF6 area as stub\n"
986 "Do not inject inter-area routes into stub\n")
987 {
988 int idx_ipv4_number = 1;
989 struct ospf6_area *area;
990
991 OSPF6_CMD_AREA_GET(argv[idx_ipv4_number]->arg, area);
992
993 if (!ospf6_area_stub_set (ospf6, area))
994 {
995 vty_out (vty, "First deconfigure all virtual link through this area%s",
996 VTY_NEWLINE);
997 return CMD_WARNING;
998 }
999
1000 ospf6_area_no_summary_set (ospf6, area);
1001
1002 return CMD_SUCCESS;
1003 }
1004
1005 DEFUN (no_ospf6_area_stub,
1006 no_ospf6_area_stub_cmd,
1007 "no area <A.B.C.D|(0-4294967295)> stub",
1008 NO_STR
1009 "OSPF6 area parameters\n"
1010 "OSPF6 area ID in IP address format\n"
1011 "OSPF6 area ID as a decimal value\n"
1012 "Configure OSPF6 area as stub\n")
1013 {
1014 int idx_ipv4_number = 2;
1015 struct ospf6_area *area;
1016
1017 OSPF6_CMD_AREA_GET(argv[idx_ipv4_number]->arg, area);
1018
1019 ospf6_area_stub_unset (ospf6, area);
1020 ospf6_area_no_summary_unset (ospf6, area);
1021
1022 return CMD_SUCCESS;
1023 }
1024
1025 DEFUN (no_ospf6_area_stub_no_summary,
1026 no_ospf6_area_stub_no_summary_cmd,
1027 "no area <A.B.C.D|(0-4294967295)> stub no-summary",
1028 NO_STR
1029 "OSPF6 area parameters\n"
1030 "OSPF6 area ID in IP address format\n"
1031 "OSPF6 area ID as a decimal value\n"
1032 "Configure OSPF6 area as stub\n"
1033 "Do not inject inter-area routes into area\n")
1034 {
1035 int idx_ipv4_number = 2;
1036 struct ospf6_area *area;
1037
1038 OSPF6_CMD_AREA_GET(argv[idx_ipv4_number]->arg, area);
1039
1040 ospf6_area_stub_unset (ospf6, area);
1041 ospf6_area_no_summary_unset (ospf6, area);
1042
1043 return CMD_SUCCESS;
1044 }
1045
1046 void
1047 ospf6_area_init (void)
1048 {
1049 install_element (VIEW_NODE, &show_ipv6_ospf6_spf_tree_cmd);
1050 install_element (VIEW_NODE, &show_ipv6_ospf6_area_spf_tree_cmd);
1051 install_element (VIEW_NODE, &show_ipv6_ospf6_simulate_spf_tree_root_cmd);
1052
1053 install_element (ENABLE_NODE, &show_ipv6_ospf6_spf_tree_cmd);
1054 install_element (ENABLE_NODE, &show_ipv6_ospf6_area_spf_tree_cmd);
1055 install_element (ENABLE_NODE, &show_ipv6_ospf6_simulate_spf_tree_root_cmd);
1056
1057 install_element (OSPF6_NODE, &area_range_cmd);
1058 install_element (OSPF6_NODE, &no_area_range_cmd);
1059 install_element (OSPF6_NODE, &ospf6_area_stub_no_summary_cmd);
1060 install_element (OSPF6_NODE, &ospf6_area_stub_cmd);
1061 install_element (OSPF6_NODE, &no_ospf6_area_stub_no_summary_cmd);
1062 install_element (OSPF6_NODE, &no_ospf6_area_stub_cmd);
1063
1064
1065 install_element (OSPF6_NODE, &area_import_list_cmd);
1066 install_element (OSPF6_NODE, &no_area_import_list_cmd);
1067 install_element (OSPF6_NODE, &area_export_list_cmd);
1068 install_element (OSPF6_NODE, &no_area_export_list_cmd);
1069
1070 install_element (OSPF6_NODE, &area_filter_list_cmd);
1071 install_element (OSPF6_NODE, &no_area_filter_list_cmd);
1072
1073 }
1074
1075