]> git.proxmox.com Git - mirror_frr.git/blame - ospf6d/ospf6_area.c
tools: argv_translator convert <1-255> to (1-255), ()s to <>s, etc
[mirror_frr.git] / ospf6d / ospf6_area.c
CommitLineData
718e3744 1/*
508e53e2 2 * Copyright (C) 2003 Yasuhiro Ohara
718e3744 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
508e53e2 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"
34956b31 33#include "plist.h"
34#include "filter.h"
508e53e2 35
508e53e2 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"
049207c3 45#include "ospf6_abr.h"
ca1f4309 46#include "ospf6_asbr.h"
049207c3 47#include "ospf6d.h"
718e3744 48
508e53e2 49int
50ospf6_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;
6452df09 54 return (ntohl (oa->area_id) < ntohl (ob->area_id) ? -1 : 1);
508e53e2 55}
718e3744 56
508e53e2 57/* schedule routing table recalculation */
6ac29a51 58static void
508e53e2 59ospf6_area_lsdb_hook_add (struct ospf6_lsa *lsa)
60{
508e53e2 61 switch (ntohs (lsa->header->type))
718e3744 62 {
508e53e2 63 case OSPF6_LSTYPE_ROUTER:
64 case OSPF6_LSTYPE_NETWORK:
1e05838a 65 if (IS_OSPF6_DEBUG_EXAMIN_TYPE (lsa->header->type))
66 {
c6487d61 67 zlog_debug ("Examin %s", lsa->name);
68 zlog_debug ("Schedule SPF Calculation for %s",
69 OSPF6_AREA (lsa->lsdb->data)->name);
1e05838a 70 }
a0edf674
DD
71 ospf6_spf_schedule (OSPF6_PROCESS(OSPF6_AREA (lsa->lsdb->data)->ospf6),
72 ospf6_lsadd_to_spf_reason(lsa));
508e53e2 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:
ccb59b11 81 ospf6_abr_examin_summary (lsa, (struct ospf6_area *) lsa->lsdb->data);
508e53e2 82 break;
83
84 default:
508e53e2 85 break;
718e3744 86 }
87}
88
6ac29a51 89static void
508e53e2 90ospf6_area_lsdb_hook_remove (struct ospf6_lsa *lsa)
718e3744 91{
508e53e2 92 switch (ntohs (lsa->header->type))
718e3744 93 {
508e53e2 94 case OSPF6_LSTYPE_ROUTER:
95 case OSPF6_LSTYPE_NETWORK:
1e05838a 96 if (IS_OSPF6_DEBUG_EXAMIN_TYPE (lsa->header->type))
97 {
c6487d61 98 zlog_debug ("LSA disappearing: %s", lsa->name);
99 zlog_debug ("Schedule SPF Calculation for %s",
1e05838a 100 OSPF6_AREA (lsa->lsdb->data)->name);
101 }
a0edf674
DD
102 ospf6_spf_schedule (OSPF6_PROCESS(OSPF6_AREA (lsa->lsdb->data)->ospf6),
103 ospf6_lsremove_to_spf_reason(lsa));
508e53e2 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:
ccb59b11 112 ospf6_abr_examin_summary (lsa, (struct ospf6_area *) lsa->lsdb->data);
508e53e2 113 break;
114
115 default:
508e53e2 116 break;
718e3744 117 }
118}
119
6ac29a51 120static void
508e53e2 121ospf6_area_route_hook_add (struct ospf6_route *route)
718e3744 122{
508e53e2 123 struct ospf6_route *copy = ospf6_route_copy (route);
124 ospf6_route_add (copy, ospf6->route_table);
718e3744 125}
126
6ac29a51 127static void
508e53e2 128ospf6_area_route_hook_remove (struct ospf6_route *route)
718e3744 129{
508e53e2 130 struct ospf6_route *copy;
718e3744 131
508e53e2 132 copy = ospf6_route_lookup_identical (route, ospf6->route_table);
133 if (copy)
134 ospf6_route_remove (copy, ospf6->route_table);
718e3744 135}
136
ca1f4309
DS
137static void
138ospf6_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
158static int
159ospf6_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
170static void
171ospf6_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
180static void
181ospf6_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
194static void
195ospf6_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
508e53e2 208/* Make new area structure */
209struct ospf6_area *
210ospf6_area_create (u_int32_t area_id, struct ospf6 *o)
718e3744 211{
508e53e2 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
6452df09 220 oa->lsdb = ospf6_lsdb_create (oa);
508e53e2 221 oa->lsdb->hook_add = ospf6_area_lsdb_hook_add;
222 oa->lsdb->hook_remove = ospf6_area_lsdb_hook_remove;
6452df09 223 oa->lsdb_self = ospf6_lsdb_create (oa);
508e53e2 224
cf1ce250
PJ
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;
508e53e2 229 oa->route_table->hook_add = ospf6_area_route_hook_add;
230 oa->route_table->hook_remove = ospf6_area_route_hook_remove;
231
cf1ce250
PJ
232 oa->range_table = OSPF6_ROUTE_TABLE_CREATE (AREA, PREFIX_RANGES);
233 oa->range_table->scope = oa;
c3c0ac83 234 bf_init(oa->range_table->idspace, 32);
cf1ce250
PJ
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;
6452df09 239
508e53e2 240 /* set default options */
f41b4a02
DD
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
508e53e2 252 OSPF6_OPT_SET (oa->options, OSPF6_OPT_E);
508e53e2 253
ca1f4309
DS
254 SET_FLAG (oa->flag, OSPF6_AREA_ACTIVE);
255 SET_FLAG (oa->flag, OSPF6_AREA_ENABLE);
256
508e53e2 257 oa->ospf6 = o;
258 listnode_add_sort (o->area_list, oa);
259
c3c0ac83
DS
260 if (area_id == OSPF_AREA_BACKBONE)
261 {
262 o->backbone = oa;
263 }
264
508e53e2 265 return oa;
718e3744 266}
267
508e53e2 268void
269ospf6_area_delete (struct ospf6_area *oa)
718e3744 270{
d9628728 271 struct listnode *n;
508e53e2 272 struct ospf6_interface *oi;
718e3744 273
d9628728
CF
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
508e53e2 282 list_delete (oa->if_list);
718e3744 283
508e53e2 284 ospf6_lsdb_delete (oa->lsdb);
6452df09 285 ospf6_lsdb_delete (oa->lsdb_self);
286
1d19234e 287 ospf6_spf_table_finish (oa->spf_table);
508e53e2 288 ospf6_route_table_delete (oa->spf_table);
289 ospf6_route_table_delete (oa->route_table);
290
c3c0ac83
DS
291 ospf6_route_table_delete (oa->range_table);
292 ospf6_route_table_delete (oa->summary_prefix);
293 ospf6_route_table_delete (oa->summary_router);
508e53e2 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
302struct ospf6_area *
303ospf6_area_lookup (u_int32_t area_id, struct ospf6 *ospf6)
718e3744 304{
508e53e2 305 struct ospf6_area *oa;
52dc7ee6 306 struct listnode *n;
718e3744 307
1eb8ef25 308 for (ALL_LIST_ELEMENTS_RO (ospf6->area_list, n, oa))
309 if (oa->area_id == area_id)
310 return oa;
718e3744 311
508e53e2 312 return (struct ospf6_area *) NULL;
718e3744 313}
314
6ac29a51 315static struct ospf6_area *
6452df09 316ospf6_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
718e3744 325void
508e53e2 326ospf6_area_enable (struct ospf6_area *oa)
718e3744 327{
1eb8ef25 328 struct listnode *node, *nnode;
508e53e2 329 struct ospf6_interface *oi;
718e3744 330
6452df09 331 SET_FLAG (oa->flag, OSPF6_AREA_ENABLE);
508e53e2 332
1eb8ef25 333 for (ALL_LIST_ELEMENTS (oa->if_list, node, nnode, oi))
334 ospf6_interface_enable (oi);
d9628728 335 ospf6_abr_enable_area (oa);
718e3744 336}
337
508e53e2 338void
339ospf6_area_disable (struct ospf6_area *oa)
718e3744 340{
1eb8ef25 341 struct listnode *node, *nnode;
508e53e2 342 struct ospf6_interface *oi;
718e3744 343
6452df09 344 UNSET_FLAG (oa->flag, OSPF6_AREA_ENABLE);
718e3744 345
1eb8ef25 346 for (ALL_LIST_ELEMENTS (oa->if_list, node, nnode, oi))
347 ospf6_interface_disable (oi);
d9628728
CF
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
d9628728
CF
356 THREAD_OFF (oa->thread_router_lsa);
357 THREAD_OFF (oa->thread_intra_prefix_lsa);
508e53e2 358}
718e3744 359
6b0655a2 360
508e53e2 361void
362ospf6_area_show (struct vty *vty, struct ospf6_area *oa)
363{
52dc7ee6 364 struct listnode *i;
508e53e2 365 struct ospf6_interface *oi;
ca1f4309 366 unsigned long result;
718e3744 367
ca1f4309
DS
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 }
508e53e2 381 vty_out (vty, " Number of Area scoped LSAs is %u%s",
049207c3 382 oa->lsdb->count, VNL);
718e3744 383
508e53e2 384 vty_out (vty, " Interface attached to this area:");
1eb8ef25 385 for (ALL_LIST_ELEMENTS_RO (oa->if_list, i, oi))
386 vty_out (vty, " %s", oi->interface->name);
049207c3 387 vty_out (vty, "%s", VNL);
ca1f4309
DS
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);
508e53e2 406}
718e3744 407
718e3744 408
049207c3 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 } \
508e53e2 423}
718e3744 424
6452df09 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
f412b39a
DW
436/*
437 * CHECK ME - The following ALIASes need to be implemented in this DEFUN
438 * "area (A.B.C.D|<0-4294967295>) range X:X::X:X/M advertise cost <0-16777215>",
439 * "OSPF area parameters\n"
440 * OSPF6_AREA_ID_STR
441 * "Summarize routes matching address/mask (border routers only)\n"
442 * "Area range prefix\n"
443 * "User specified metric for this range\n"
444 * "Advertised metric for this range\n"
445 *
446 * "area A.B.C.D range X:X::X:X/M (advertise|not-advertise)",
447 * "OSPF area parameters\n"
448 * OSPF6_AREA_ID_STR
449 * "Configured address range\n"
450 * "Specify IPv6 prefix\n"
451 *
452 *
453 * "area (A.B.C.D|<0-4294967295>) range X:X::X:X/M cost <0-16777215>",
454 * "OSPF area parameters\n"
455 * OSPF6_AREA_ID_STR
456 * "Summarize routes matching address/mask (border routers only)\n"
457 * "Area range prefix\n"
458 * "User specified metric for this range\n"
459 * "Advertised metric for this range\n"
460 *
461 */
6452df09 462DEFUN (area_range,
463 area_range_cmd,
464 "area A.B.C.D range X:X::X:X/M",
465 "OSPF area parameters\n"
466 OSPF6_AREA_ID_STR
467 "Configured address range\n"
468 "Specify IPv6 prefix\n"
469 )
470{
471 int ret;
472 struct ospf6_area *oa;
473 struct prefix prefix;
ca1f4309 474 struct ospf6_route *range;
c3c0ac83 475 u_int32_t cost = OSPF_AREA_RANGE_COST_UNSPEC;
6452df09 476
cc9de1ba 477 OSPF6_CMD_AREA_GET (argv[1]->arg, oa);
6452df09 478
cc9de1ba 479 ret = str2prefix (argv[3]->arg, &prefix);
6452df09 480 if (ret != 1 || prefix.family != AF_INET6)
481 {
cc9de1ba 482 vty_out (vty, "Malformed argument: %s%s", argv[3]->arg, VNL);
6452df09 483 return CMD_SUCCESS;
484 }
6452df09 485
486 range = ospf6_route_lookup (&prefix, oa->range_table);
487 if (range == NULL)
488 {
489 range = ospf6_route_create ();
490 range->type = OSPF6_DEST_TYPE_RANGE;
491 range->prefix = prefix;
c3c0ac83
DS
492 range->path.area_id = oa->area_id;
493 range->path.cost = OSPF_AREA_RANGE_COST_UNSPEC;
494 range->linkstate_id =
495 (u_int32_t) htonl(ospf6_new_range_ls_id (oa->range_table));
6452df09 496 }
497
c3c0ac83 498 if (argc > 2)
6452df09 499 {
cc9de1ba 500 if (strcmp (argv[4]->arg, "not-advertise") == 0)
c3c0ac83
DS
501 {
502 SET_FLAG (range->flag, OSPF6_ROUTE_DO_NOT_ADVERTISE);
503 }
cc9de1ba 504 else if (strcmp (argv[4]->arg, "advertise") == 0)
c3c0ac83
DS
505 {
506 UNSET_FLAG (range->flag, OSPF6_ROUTE_DO_NOT_ADVERTISE);
507 }
508 else
509 {
cc9de1ba 510 VTY_GET_INTEGER_RANGE ("cost", cost, argv[5]->arg, 0, OSPF_LS_INFINITY);
c3c0ac83
DS
511 UNSET_FLAG (range->flag, OSPF6_ROUTE_DO_NOT_ADVERTISE);
512 }
6452df09 513 }
514
c3c0ac83
DS
515 range->path.u.cost_config = cost;
516
cc9de1ba 517 zlog_debug ("%s: for prefix %s, flag = %x\n", __func__, argv[3]->arg, range->flag);
c3c0ac83 518 if (range->rnode == NULL)
86f9e5a7 519 {
c3c0ac83
DS
520 ospf6_route_add (range, oa->range_table);
521 }
522
523 if (ospf6_is_router_abr (ospf6))
524 {
525 /* Redo summaries if required */
ca1f4309 526 ospf6_abr_prefix_resummarize (ospf6);
86f9e5a7
J
527 }
528
6452df09 529 return CMD_SUCCESS;
530}
531
6452df09 532
c3c0ac83 533
f412b39a
DW
534
535/*
536 * CHECK ME - The following ALIASes need to be implemented in this DEFUN
537 * "no area (A.B.C.D|<0-4294967295>) range X:X::X:X/M advertise cost <0-16777215>",
538 * NO_STR
539 * "OSPF area parameters\n"
540 * OSPF6_AREA_ID_STR
541 * "Summarize routes matching address/mask (border routers only)\n"
542 * "Area range prefix\n"
543 * "User specified metric for this range\n"
544 * "Advertised metric for this range\n"
545 *
546 * "no area A.B.C.D range X:X::X:X/M (advertise|not-advertise)",
547 * NO_STR
548 * "OSPF area parameters\n"
549 * OSPF6_AREA_ID_STR
550 * "Configured address range\n"
551 * "Specify IPv6 prefix\n"
552 *
553 * "no area (A.B.C.D|<0-4294967295>) range X:X::X:X/M cost <0-16777215>",
554 * NO_STR
555 * "OSPF area parameters\n"
556 * OSPF6_AREA_ID_STR
557 * "Summarize routes matching address/mask (border routers only)\n"
558 * "Area range prefix\n"
559 * "User specified metric for this range\n"
560 * "Advertised metric for this range\n"
561 *
562 */
6452df09 563DEFUN (no_area_range,
564 no_area_range_cmd,
565 "no area A.B.C.D range X:X::X:X/M",
813d4307 566 NO_STR
6452df09 567 "OSPF area parameters\n"
568 OSPF6_AREA_ID_STR
569 "Configured address range\n"
813d4307 570 "Specify IPv6 prefix\n")
6452df09 571{
572 int ret;
573 struct ospf6_area *oa;
574 struct prefix prefix;
c3c0ac83 575 struct ospf6_route *range, *route;
6452df09 576
cc9de1ba 577 OSPF6_CMD_AREA_GET (argv[2]->arg, oa);
6452df09 578 argc--;
579 argv++;
580
cc9de1ba 581 ret = str2prefix (argv[2]->arg, &prefix);
6452df09 582 if (ret != 1 || prefix.family != AF_INET6)
583 {
cc9de1ba 584 vty_out (vty, "Malformed argument: %s%s", argv[2]->arg, VNL);
6452df09 585 return CMD_SUCCESS;
586 }
587
588 range = ospf6_route_lookup (&prefix, oa->range_table);
589 if (range == NULL)
590 {
cc9de1ba 591 vty_out (vty, "Range %s does not exists.%s", argv[2]->arg, VNL);
6452df09 592 return CMD_SUCCESS;
593 }
594
c3c0ac83
DS
595 if (ospf6_is_router_abr(oa->ospf6))
596 {
597 /* Blow away the aggregated LSA and route */
598 SET_FLAG (range->flag, OSPF6_ROUTE_REMOVE);
599
600 /* Redo summaries if required */
601 for (route = ospf6_route_head (ospf6->route_table); route;
602 route = ospf6_route_next (route))
603 ospf6_abr_originate_summary(route);
604
605 /* purge the old aggregated summary LSA */
606 ospf6_abr_originate_summary(range);
607 }
608 ospf6_release_range_ls_id(oa->range_table,
609 (u_int32_t) ntohl(range->linkstate_id));
6452df09 610 ospf6_route_remove (range, oa->range_table);
8551e6da 611
6452df09 612 return CMD_SUCCESS;
613}
614
813d4307 615
f412b39a 616
813d4307 617
6452df09 618void
619ospf6_area_config_write (struct vty *vty)
620{
52dc7ee6 621 struct listnode *node;
6452df09 622 struct ospf6_area *oa;
623 struct ospf6_route *range;
4690c7d7 624 char buf[PREFIX2STR_BUFFER];
6452df09 625
1eb8ef25 626 for (ALL_LIST_ELEMENTS_RO (ospf6->area_list, node, oa))
6452df09 627 {
6452df09 628 for (range = ospf6_route_head (oa->range_table); range;
629 range = ospf6_route_next (range))
630 {
631 prefix2str (&range->prefix, buf, sizeof (buf));
813d4307
DW
632 vty_out (vty, " area %s range %s", oa->name, buf);
633
634 if (CHECK_FLAG (range->flag, OSPF6_ROUTE_DO_NOT_ADVERTISE))
635 {
636 vty_out (vty, " not-advertise");
637 }
638 else
639 {
640 // "advertise" is the default so we do not display it
641 if (range->path.u.cost_config != OSPF_AREA_RANGE_COST_UNSPEC)
642 vty_out (vty, " cost %d", range->path.u.cost_config);
643 }
644 vty_out (vty, "%s", VNL);
645
6452df09 646 }
ca1f4309
DS
647 if (IS_AREA_STUB (oa))
648 {
649 if (oa->no_summary)
650 vty_out (vty, " area %s stub no-summary%s", oa->name, VNL);
651 else
652 vty_out (vty, " area %s stub%s", oa->name, VNL);
653 }
5fdaa04e
JA
654 if (PREFIX_NAME_IN (oa))
655 vty_out (vty, " area %s filter-list prefix %s in%s",
656 oa->name, PREFIX_NAME_IN (oa), VNL);
657 if (PREFIX_NAME_OUT (oa))
658 vty_out (vty, " area %s filter-list prefix %s out%s",
659 oa->name, PREFIX_NAME_OUT (oa), VNL);
660 if (IMPORT_NAME (oa))
661 vty_out (vty, " area %s import-list %s%s",
662 oa->name, IMPORT_NAME (oa), VNL);
663 if (EXPORT_NAME (oa))
664 vty_out (vty, " area %s export-list %s%s",
665 oa->name, EXPORT_NAME (oa), VNL);
6452df09 666 }
667}
668
34956b31 669DEFUN (area_filter_list,
670 area_filter_list_cmd,
671 "area A.B.C.D filter-list prefix WORD (in|out)",
672 "OSPFv6 area parameters\n"
673 "OSPFv6 area ID in IP address format\n"
674 "Filter networks between OSPFv6 areas\n"
675 "Filter prefixes between OSPFv6 areas\n"
676 "Name of an IPv6 prefix-list\n"
677 "Filter networks sent to this area\n"
678 "Filter networks sent from this area\n")
679{
680 struct ospf6_area *area;
681 struct prefix_list *plist;
682
cc9de1ba 683 OSPF6_CMD_AREA_GET (argv[1]->arg, area);
34956b31 684 argc--;
685 argv++;
686
cc9de1ba
DW
687 plist = prefix_list_lookup (AFI_IP6, argv[1]->arg);
688 if (strncmp (argv[4]->arg, "in", 2) == 0)
34956b31 689 {
690 PREFIX_LIST_IN (area) = plist;
691 if (PREFIX_NAME_IN (area))
692 free (PREFIX_NAME_IN (area));
693
cc9de1ba 694 PREFIX_NAME_IN (area) = strdup (argv[1]->arg);
34956b31 695 ospf6_abr_reimport (area);
696 }
697 else
698 {
699 PREFIX_LIST_OUT (area) = plist;
700 if (PREFIX_NAME_OUT (area))
701 free (PREFIX_NAME_OUT (area));
702
cc9de1ba 703 PREFIX_NAME_OUT (area) = strdup (argv[1]->arg);
34956b31 704 ospf6_abr_enable_area (area);
705 }
706
707 return CMD_SUCCESS;
708}
709
710DEFUN (no_area_filter_list,
711 no_area_filter_list_cmd,
712 "no area A.B.C.D filter-list prefix WORD (in|out)",
713 NO_STR
714 "OSPFv6 area parameters\n"
715 "OSPFv6 area ID in IP address format\n"
716 "Filter networks between OSPFv6 areas\n"
717 "Filter prefixes between OSPFv6 areas\n"
718 "Name of an IPv6 prefix-list\n"
719 "Filter networks sent to this area\n"
720 "Filter networks sent from this area\n")
721{
722 struct ospf6_area *area;
34956b31 723
cc9de1ba 724 OSPF6_CMD_AREA_GET (argv[2]->arg, area);
34956b31 725 argc--;
726 argv++;
727
cc9de1ba 728 if (strncmp (argv[5]->arg, "in", 2) == 0)
34956b31 729 {
730 if (PREFIX_NAME_IN (area))
cc9de1ba 731 if (strcmp (PREFIX_NAME_IN (area), argv[2]->arg) != 0)
34956b31 732 return CMD_SUCCESS;
733
734 PREFIX_LIST_IN (area) = NULL;
735 if (PREFIX_NAME_IN (area))
736 free (PREFIX_NAME_IN (area));
737
738 PREFIX_NAME_IN (area) = NULL;
739 ospf6_abr_reimport (area);
740 }
741 else
742 {
743 if (PREFIX_NAME_OUT (area))
cc9de1ba 744 if (strcmp (PREFIX_NAME_OUT (area), argv[2]->arg) != 0)
34956b31 745 return CMD_SUCCESS;
746
747 PREFIX_LIST_OUT (area) = NULL;
748 if (PREFIX_NAME_OUT (area))
749 free (PREFIX_NAME_OUT (area));
750
751 PREFIX_NAME_OUT (area) = NULL;
752 ospf6_abr_enable_area (area);
753 }
754
755 return CMD_SUCCESS;
756}
757
758DEFUN (area_import_list,
759 area_import_list_cmd,
760 "area A.B.C.D import-list NAME",
761 "OSPFv6 area parameters\n"
762 "OSPFv6 area ID in IP address format\n"
763 "Set the filter for networks from other areas announced to the specified one\n"
764 "Name of the acess-list\n")
765{
766 struct ospf6_area *area;
767 struct access_list *list;
768
cc9de1ba 769 OSPF6_CMD_AREA_GET(argv[1]->arg, area);
34956b31 770
cc9de1ba 771 list = access_list_lookup (AFI_IP6, argv[3]->arg);
34956b31 772
773 IMPORT_LIST (area) = list;
774
775 if (IMPORT_NAME (area))
776 free (IMPORT_NAME (area));
777
cc9de1ba 778 IMPORT_NAME (area) = strdup (argv[3]->arg);
34956b31 779 ospf6_abr_reimport (area);
780
781 return CMD_SUCCESS;
782}
783
784DEFUN (no_area_import_list,
785 no_area_import_list_cmd,
786 "no area A.B.C.D import-list NAME",
787 "OSPFv6 area parameters\n"
788 "OSPFv6 area ID in IP address format\n"
789 "Unset the filter for networks announced to other areas\n"
790 "NAme of the access-list\n")
791{
792 struct ospf6_area *area;
793
cc9de1ba 794 OSPF6_CMD_AREA_GET(argv[2]->arg, area);
34956b31 795
796 IMPORT_LIST (area) = 0;
797
798 if (IMPORT_NAME (area))
799 free (IMPORT_NAME (area));
800
801 IMPORT_NAME (area) = NULL;
802 ospf6_abr_reimport (area);
803
804 return CMD_SUCCESS;
805}
806
807DEFUN (area_export_list,
808 area_export_list_cmd,
809 "area A.B.C.D export-list NAME",
810 "OSPFv6 area parameters\n"
811 "OSPFv6 area ID in IP address format\n"
812 "Set the filter for networks announced to other areas\n"
813 "Name of the acess-list\n")
814{
815 struct ospf6_area *area;
816 struct access_list *list;
817
cc9de1ba 818 OSPF6_CMD_AREA_GET(argv[1]->arg, area);
34956b31 819
cc9de1ba 820 list = access_list_lookup (AFI_IP6, argv[3]->arg);
34956b31 821
822 EXPORT_LIST (area) = list;
823
824 if (EXPORT_NAME (area))
825 free (EXPORT_NAME (area));
826
cc9de1ba 827 EXPORT_NAME (area) = strdup (argv[3]->arg);
34956b31 828 ospf6_abr_enable_area (area);
829
830 return CMD_SUCCESS;
831}
832
833DEFUN (no_area_export_list,
834 no_area_export_list_cmd,
835 "no area A.B.C.D export-list NAME",
836 "OSPFv6 area parameters\n"
837 "OSPFv6 area ID in IP address format\n"
838 "Unset the filter for networks announced to other areas\n"
839 "Name of the access-list\n")
840{
841 struct ospf6_area *area;
842
cc9de1ba 843 OSPF6_CMD_AREA_GET(argv[2]->arg, area);
34956b31 844
845 EXPORT_LIST (area) = 0;
846
847 if (EXPORT_NAME (area))
848 free (EXPORT_NAME (area));
849
850 EXPORT_NAME (area) = NULL;
851 ospf6_abr_enable_area (area);
852
853 return CMD_SUCCESS;
854}
855
508e53e2 856DEFUN (show_ipv6_ospf6_spf_tree,
857 show_ipv6_ospf6_spf_tree_cmd,
858 "show ipv6 ospf6 spf tree",
859 SHOW_STR
860 IP6_STR
861 OSPF6_STR
862 "Shortest Path First caculation\n"
863 "Show SPF tree\n")
718e3744 864{
52dc7ee6 865 struct listnode *node;
508e53e2 866 struct ospf6_area *oa;
867 struct ospf6_vertex *root;
868 struct ospf6_route *route;
869 struct prefix prefix;
718e3744 870
b52a8a52
DS
871 OSPF6_CMD_CHECK_RUNNING ();
872
508e53e2 873 ospf6_linkstate_prefix (ospf6->router_id, htonl (0), &prefix);
1eb8ef25 874
875 for (ALL_LIST_ELEMENTS_RO (ospf6->area_list, node, oa))
508e53e2 876 {
508e53e2 877 route = ospf6_route_lookup (&prefix, oa->spf_table);
878 if (route == NULL)
879 {
880 vty_out (vty, "LS entry for root not found in area %s%s",
049207c3 881 oa->name, VNL);
508e53e2 882 continue;
883 }
884 root = (struct ospf6_vertex *) route->route_option;
885 ospf6_spf_display_subtree (vty, "", 0, root);
886 }
887
888 return CMD_SUCCESS;
889}
890
891DEFUN (show_ipv6_ospf6_area_spf_tree,
892 show_ipv6_ospf6_area_spf_tree_cmd,
893 "show ipv6 ospf6 area A.B.C.D spf tree",
894 SHOW_STR
895 IP6_STR
896 OSPF6_STR
897 OSPF6_AREA_STR
898 OSPF6_AREA_ID_STR
899 "Shortest Path First caculation\n"
900 "Show SPF tree\n")
901{
902 u_int32_t area_id;
903 struct ospf6_area *oa;
904 struct ospf6_vertex *root;
905 struct ospf6_route *route;
906 struct prefix prefix;
718e3744 907
b52a8a52
DS
908 OSPF6_CMD_CHECK_RUNNING ();
909
508e53e2 910 ospf6_linkstate_prefix (ospf6->router_id, htonl (0), &prefix);
718e3744 911
cc9de1ba 912 if (inet_pton (AF_INET, argv[4]->arg, &area_id) != 1)
718e3744 913 {
cc9de1ba 914 vty_out (vty, "Malformed Area-ID: %s%s", argv[4]->arg, VNL);
508e53e2 915 return CMD_SUCCESS;
916 }
917 oa = ospf6_area_lookup (area_id, ospf6);
918 if (oa == NULL)
919 {
cc9de1ba 920 vty_out (vty, "No such Area: %s%s", argv[4]->arg, VNL);
508e53e2 921 return CMD_SUCCESS;
718e3744 922 }
718e3744 923
508e53e2 924 route = ospf6_route_lookup (&prefix, oa->spf_table);
925 if (route == NULL)
718e3744 926 {
508e53e2 927 vty_out (vty, "LS entry for root not found in area %s%s",
049207c3 928 oa->name, VNL);
508e53e2 929 return CMD_SUCCESS;
718e3744 930 }
508e53e2 931 root = (struct ospf6_vertex *) route->route_option;
932 ospf6_spf_display_subtree (vty, "", 0, root);
933
934 return CMD_SUCCESS;
718e3744 935}
936
508e53e2 937DEFUN (show_ipv6_ospf6_simulate_spf_tree_root,
938 show_ipv6_ospf6_simulate_spf_tree_root_cmd,
939 "show ipv6 ospf6 simulate spf-tree A.B.C.D area A.B.C.D",
940 SHOW_STR
941 IP6_STR
942 OSPF6_STR
943 "Shortest Path First caculation\n"
944 "Show SPF tree\n"
945 "Specify root's router-id to calculate another router's SPF tree\n")
946{
947 u_int32_t area_id;
948 struct ospf6_area *oa;
949 struct ospf6_vertex *root;
950 struct ospf6_route *route;
951 struct prefix prefix;
952 u_int32_t router_id;
953 struct ospf6_route_table *spf_table;
954 unsigned char tmp_debug_ospf6_spf = 0;
955
b52a8a52
DS
956 OSPF6_CMD_CHECK_RUNNING ();
957
cc9de1ba 958 inet_pton (AF_INET, argv[5]->arg, &router_id);
508e53e2 959 ospf6_linkstate_prefix (router_id, htonl (0), &prefix);
960
cc9de1ba 961 if (inet_pton (AF_INET, argv[7]->arg, &area_id) != 1)
508e53e2 962 {
cc9de1ba 963 vty_out (vty, "Malformed Area-ID: %s%s", argv[7]->arg, VNL);
508e53e2 964 return CMD_SUCCESS;
965 }
966 oa = ospf6_area_lookup (area_id, ospf6);
967 if (oa == NULL)
968 {
cc9de1ba 969 vty_out (vty, "No such Area: %s%s", argv[7]->arg, VNL);
508e53e2 970 return CMD_SUCCESS;
971 }
972
973 tmp_debug_ospf6_spf = conf_debug_ospf6_spf;
974 conf_debug_ospf6_spf = 0;
975
cf1ce250 976 spf_table = OSPF6_ROUTE_TABLE_CREATE (NONE, SPF_RESULTS);
508e53e2 977 ospf6_spf_calculation (router_id, spf_table, oa);
978
979 conf_debug_ospf6_spf = tmp_debug_ospf6_spf;
980
981 route = ospf6_route_lookup (&prefix, spf_table);
982 if (route == NULL)
983 {
984 ospf6_spf_table_finish (spf_table);
985 ospf6_route_table_delete (spf_table);
986 return CMD_SUCCESS;
987 }
988 root = (struct ospf6_vertex *) route->route_option;
989 ospf6_spf_display_subtree (vty, "", 0, root);
718e3744 990
508e53e2 991 ospf6_spf_table_finish (spf_table);
992 ospf6_route_table_delete (spf_table);
993
994 return CMD_SUCCESS;
995}
996
ca1f4309
DS
997DEFUN (ospf6_area_stub,
998 ospf6_area_stub_cmd,
999 "area (A.B.C.D|<0-4294967295>) stub",
1000 "OSPF6 area parameters\n"
1001 "OSPF6 area ID in IP address format\n"
1002 "OSPF6 area ID as a decimal value\n"
1003 "Configure OSPF6 area as stub\n")
1004{
1005 struct ospf6_area *area;
1006
cc9de1ba 1007 OSPF6_CMD_AREA_GET(argv[1]->arg, area);
ca1f4309
DS
1008
1009 if (!ospf6_area_stub_set (ospf6, area))
1010 {
1011 vty_out (vty, "First deconfigure all virtual link through this area%s",
1012 VTY_NEWLINE);
1013 return CMD_WARNING;
1014 }
1015
1016 ospf6_area_no_summary_unset (ospf6, area);
1017
1018 return CMD_SUCCESS;
1019}
1020
1021DEFUN (ospf6_area_stub_no_summary,
1022 ospf6_area_stub_no_summary_cmd,
1023 "area (A.B.C.D|<0-4294967295>) stub no-summary",
1024 "OSPF6 stub parameters\n"
1025 "OSPF6 area ID in IP address format\n"
1026 "OSPF6 area ID as a decimal value\n"
1027 "Configure OSPF6 area as stub\n"
1028 "Do not inject inter-area routes into stub\n")
1029{
1030 struct ospf6_area *area;
1031
cc9de1ba 1032 OSPF6_CMD_AREA_GET(argv[1]->arg, area);
ca1f4309
DS
1033
1034 if (!ospf6_area_stub_set (ospf6, area))
1035 {
1036 vty_out (vty, "First deconfigure all virtual link through this area%s",
1037 VTY_NEWLINE);
1038 return CMD_WARNING;
1039 }
1040
1041 ospf6_area_no_summary_set (ospf6, area);
1042
1043 return CMD_SUCCESS;
1044}
1045
1046DEFUN (no_ospf6_area_stub,
1047 no_ospf6_area_stub_cmd,
1048 "no area (A.B.C.D|<0-4294967295>) stub",
1049 NO_STR
1050 "OSPF6 area parameters\n"
1051 "OSPF6 area ID in IP address format\n"
1052 "OSPF6 area ID as a decimal value\n"
1053 "Configure OSPF6 area as stub\n")
1054{
1055 struct ospf6_area *area;
1056
cc9de1ba 1057 OSPF6_CMD_AREA_GET(argv[2]->arg, area);
ca1f4309
DS
1058
1059 ospf6_area_stub_unset (ospf6, area);
1060 ospf6_area_no_summary_unset (ospf6, area);
1061
1062 return CMD_SUCCESS;
1063}
1064
1065DEFUN (no_ospf6_area_stub_no_summary,
1066 no_ospf6_area_stub_no_summary_cmd,
1067 "no area (A.B.C.D|<0-4294967295>) stub no-summary",
1068 NO_STR
1069 "OSPF6 area parameters\n"
1070 "OSPF6 area ID in IP address format\n"
1071 "OSPF6 area ID as a decimal value\n"
1072 "Configure OSPF6 area as stub\n"
1073 "Do not inject inter-area routes into area\n")
1074{
1075 struct ospf6_area *area;
1076
cc9de1ba 1077 OSPF6_CMD_AREA_GET(argv[2]->arg, area);
ca1f4309
DS
1078
1079 ospf6_area_stub_unset (ospf6, area);
1080 ospf6_area_no_summary_unset (ospf6, area);
1081
1082 return CMD_SUCCESS;
1083}
1084
508e53e2 1085void
6ac29a51 1086ospf6_area_init (void)
508e53e2 1087{
1088 install_element (VIEW_NODE, &show_ipv6_ospf6_spf_tree_cmd);
508e53e2 1089 install_element (VIEW_NODE, &show_ipv6_ospf6_area_spf_tree_cmd);
508e53e2 1090 install_element (VIEW_NODE, &show_ipv6_ospf6_simulate_spf_tree_root_cmd);
1091
1092 install_element (ENABLE_NODE, &show_ipv6_ospf6_spf_tree_cmd);
508e53e2 1093 install_element (ENABLE_NODE, &show_ipv6_ospf6_area_spf_tree_cmd);
508e53e2 1094 install_element (ENABLE_NODE, &show_ipv6_ospf6_simulate_spf_tree_root_cmd);
6452df09 1095
1096 install_element (OSPF6_NODE, &area_range_cmd);
6452df09 1097 install_element (OSPF6_NODE, &no_area_range_cmd);
ca1f4309
DS
1098 install_element (OSPF6_NODE, &ospf6_area_stub_no_summary_cmd);
1099 install_element (OSPF6_NODE, &ospf6_area_stub_cmd);
1100 install_element (OSPF6_NODE, &no_ospf6_area_stub_no_summary_cmd);
1101 install_element (OSPF6_NODE, &no_ospf6_area_stub_cmd);
1102
34956b31 1103
1104 install_element (OSPF6_NODE, &area_import_list_cmd);
1105 install_element (OSPF6_NODE, &no_area_import_list_cmd);
1106 install_element (OSPF6_NODE, &area_export_list_cmd);
1107 install_element (OSPF6_NODE, &no_area_export_list_cmd);
1108
1109 install_element (OSPF6_NODE, &area_filter_list_cmd);
1110 install_element (OSPF6_NODE, &no_area_filter_list_cmd);
1111
508e53e2 1112}
049207c3 1113
6452df09 1114