]> git.proxmox.com Git - mirror_frr.git/blame - ospf6d/ospf6_area.c
Merge remote-tracking branch 'origin/master' into pim_lib_work2
[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
436DEFUN (area_range,
437 area_range_cmd,
6de69f83 438 "area <A.B.C.D|(0-4294967295)> range X:X::X:X/M [<advertise|not-advertise|cost (0-16777215)>]",
6fbde29d
RW
439 "OSPF6 area parameters\n"
440 "OSPF6 area ID in IP address format\n"
441 "OSPF6 area ID as a decimal value\n"
6452df09 442 "Configured address range\n"
443 "Specify IPv6 prefix\n"
093d7a3a
DW
444 "Advertise\n"
445 "Do not advertise\n"
446 "User specified metric for this range\n"
447 "Advertised metric for this range\n")
6452df09 448{
51c26414
DW
449 int idx_ipv4 = 1;
450 int idx_ipv6_prefixlen = 3;
093d7a3a 451 int idx_type = 4;
6452df09 452 int ret;
453 struct ospf6_area *oa;
454 struct prefix prefix;
ca1f4309 455 struct ospf6_route *range;
c3c0ac83 456 u_int32_t cost = OSPF_AREA_RANGE_COST_UNSPEC;
6452df09 457
51c26414 458 OSPF6_CMD_AREA_GET (argv[idx_ipv4]->arg, oa);
6452df09 459
51c26414 460 ret = str2prefix (argv[idx_ipv6_prefixlen]->arg, &prefix);
6452df09 461 if (ret != 1 || prefix.family != AF_INET6)
462 {
51c26414 463 vty_out (vty, "Malformed argument: %s%s", argv[idx_ipv6_prefixlen]->arg, VNL);
6452df09 464 return CMD_SUCCESS;
465 }
6452df09 466
467 range = ospf6_route_lookup (&prefix, oa->range_table);
468 if (range == NULL)
469 {
470 range = ospf6_route_create ();
471 range->type = OSPF6_DEST_TYPE_RANGE;
472 range->prefix = prefix;
c3c0ac83
DS
473 range->path.area_id = oa->area_id;
474 range->path.cost = OSPF_AREA_RANGE_COST_UNSPEC;
6452df09 475 }
476
093d7a3a 477 if (argc > idx_type)
6452df09 478 {
093d7a3a 479 if (strmatch (argv[idx_type]->text, "not-advertise"))
c3c0ac83
DS
480 {
481 SET_FLAG (range->flag, OSPF6_ROUTE_DO_NOT_ADVERTISE);
482 }
093d7a3a 483 else if (strmatch (argv[idx_type]->text, "advertise"))
c3c0ac83
DS
484 {
485 UNSET_FLAG (range->flag, OSPF6_ROUTE_DO_NOT_ADVERTISE);
486 }
487 else
488 {
cc9de1ba 489 VTY_GET_INTEGER_RANGE ("cost", cost, argv[5]->arg, 0, OSPF_LS_INFINITY);
c3c0ac83
DS
490 UNSET_FLAG (range->flag, OSPF6_ROUTE_DO_NOT_ADVERTISE);
491 }
6452df09 492 }
493
c3c0ac83
DS
494 range->path.u.cost_config = cost;
495
51c26414 496 zlog_debug ("%s: for prefix %s, flag = %x\n", __func__, argv[idx_ipv6_prefixlen]->arg, range->flag);
c3c0ac83 497 if (range->rnode == NULL)
86f9e5a7 498 {
c3c0ac83
DS
499 ospf6_route_add (range, oa->range_table);
500 }
501
502 if (ospf6_is_router_abr (ospf6))
503 {
504 /* Redo summaries if required */
ca1f4309 505 ospf6_abr_prefix_resummarize (ospf6);
86f9e5a7
J
506 }
507
6452df09 508 return CMD_SUCCESS;
509}
510
6452df09 511DEFUN (no_area_range,
512 no_area_range_cmd,
3a2d747c 513 "no area <A.B.C.D|(0-4294967295)> range X:X::X:X/M [<advertise|not-advertise|cost (0-16777215)>]",
813d4307 514 NO_STR
6fbde29d 515 "OSPF6 area parameters\n"
3a2d747c
QY
516 "OSPF6 area ID in IP address format\n"
517 "OSPF6 area ID as a decimal value\n"
6452df09 518 "Configured address range\n"
3a2d747c
QY
519 "Specify IPv6 prefix\n"
520 "Advertise\n"
521 "Do not advertise\n"
522 "User specified metric for this range\n"
523 "Advertised metric for this range\n")
6452df09 524{
51c26414 525 int idx_ipv4 = 2;
6452df09 526 int ret;
527 struct ospf6_area *oa;
528 struct prefix prefix;
c3c0ac83 529 struct ospf6_route *range, *route;
6452df09 530
51c26414 531 OSPF6_CMD_AREA_GET (argv[idx_ipv4]->arg, oa);
6452df09 532
51c26414 533 ret = str2prefix (argv[idx_ipv4]->arg, &prefix);
6452df09 534 if (ret != 1 || prefix.family != AF_INET6)
535 {
51c26414 536 vty_out (vty, "Malformed argument: %s%s", argv[idx_ipv4]->arg, VNL);
6452df09 537 return CMD_SUCCESS;
538 }
539
540 range = ospf6_route_lookup (&prefix, oa->range_table);
541 if (range == NULL)
542 {
51c26414 543 vty_out (vty, "Range %s does not exists.%s", argv[idx_ipv4]->arg, VNL);
6452df09 544 return CMD_SUCCESS;
545 }
546
c3c0ac83
DS
547 if (ospf6_is_router_abr(oa->ospf6))
548 {
549 /* Blow away the aggregated LSA and route */
550 SET_FLAG (range->flag, OSPF6_ROUTE_REMOVE);
551
552 /* Redo summaries if required */
553 for (route = ospf6_route_head (ospf6->route_table); route;
554 route = ospf6_route_next (route))
555 ospf6_abr_originate_summary(route);
556
557 /* purge the old aggregated summary LSA */
558 ospf6_abr_originate_summary(range);
559 }
6452df09 560 ospf6_route_remove (range, oa->range_table);
8551e6da 561
6452df09 562 return CMD_SUCCESS;
563}
564
813d4307 565
f412b39a 566
813d4307 567
6452df09 568void
569ospf6_area_config_write (struct vty *vty)
570{
52dc7ee6 571 struct listnode *node;
6452df09 572 struct ospf6_area *oa;
573 struct ospf6_route *range;
4690c7d7 574 char buf[PREFIX2STR_BUFFER];
6452df09 575
1eb8ef25 576 for (ALL_LIST_ELEMENTS_RO (ospf6->area_list, node, oa))
6452df09 577 {
6452df09 578 for (range = ospf6_route_head (oa->range_table); range;
579 range = ospf6_route_next (range))
580 {
581 prefix2str (&range->prefix, buf, sizeof (buf));
813d4307
DW
582 vty_out (vty, " area %s range %s", oa->name, buf);
583
584 if (CHECK_FLAG (range->flag, OSPF6_ROUTE_DO_NOT_ADVERTISE))
585 {
586 vty_out (vty, " not-advertise");
587 }
588 else
589 {
590 // "advertise" is the default so we do not display it
591 if (range->path.u.cost_config != OSPF_AREA_RANGE_COST_UNSPEC)
592 vty_out (vty, " cost %d", range->path.u.cost_config);
593 }
594 vty_out (vty, "%s", VNL);
595
6452df09 596 }
ca1f4309
DS
597 if (IS_AREA_STUB (oa))
598 {
599 if (oa->no_summary)
600 vty_out (vty, " area %s stub no-summary%s", oa->name, VNL);
601 else
602 vty_out (vty, " area %s stub%s", oa->name, VNL);
603 }
5fdaa04e
JA
604 if (PREFIX_NAME_IN (oa))
605 vty_out (vty, " area %s filter-list prefix %s in%s",
606 oa->name, PREFIX_NAME_IN (oa), VNL);
607 if (PREFIX_NAME_OUT (oa))
608 vty_out (vty, " area %s filter-list prefix %s out%s",
609 oa->name, PREFIX_NAME_OUT (oa), VNL);
610 if (IMPORT_NAME (oa))
611 vty_out (vty, " area %s import-list %s%s",
612 oa->name, IMPORT_NAME (oa), VNL);
613 if (EXPORT_NAME (oa))
614 vty_out (vty, " area %s export-list %s%s",
615 oa->name, EXPORT_NAME (oa), VNL);
6452df09 616 }
617}
618
34956b31 619DEFUN (area_filter_list,
620 area_filter_list_cmd,
6147e2c6 621 "area A.B.C.D filter-list prefix WORD <in|out>",
b2d4d039
RW
622 "OSPF6 area parameters\n"
623 "OSPF6 area ID in IP address format\n"
624 "Filter networks between OSPF6 areas\n"
625 "Filter prefixes between OSPF6 areas\n"
34956b31 626 "Name of an IPv6 prefix-list\n"
627 "Filter networks sent to this area\n"
628 "Filter networks sent from this area\n")
629{
51c26414
DW
630 int idx_ipv4 = 1;
631 int idx_word = 4;
34956b31 632 struct ospf6_area *area;
633 struct prefix_list *plist;
634
51c26414 635 OSPF6_CMD_AREA_GET (argv[idx_ipv4]->arg, area);
34956b31 636
51c26414
DW
637 plist = prefix_list_lookup (AFI_IP6, argv[idx_ipv4]->arg);
638 if (strncmp (argv[idx_word]->arg, "in", 2) == 0)
34956b31 639 {
640 PREFIX_LIST_IN (area) = plist;
641 if (PREFIX_NAME_IN (area))
642 free (PREFIX_NAME_IN (area));
643
51c26414 644 PREFIX_NAME_IN (area) = strdup (argv[idx_ipv4]->arg);
34956b31 645 ospf6_abr_reimport (area);
646 }
647 else
648 {
649 PREFIX_LIST_OUT (area) = plist;
650 if (PREFIX_NAME_OUT (area))
651 free (PREFIX_NAME_OUT (area));
652
51c26414 653 PREFIX_NAME_OUT (area) = strdup (argv[idx_ipv4]->arg);
34956b31 654 ospf6_abr_enable_area (area);
655 }
656
657 return CMD_SUCCESS;
658}
659
660DEFUN (no_area_filter_list,
661 no_area_filter_list_cmd,
6147e2c6 662 "no area A.B.C.D filter-list prefix WORD <in|out>",
34956b31 663 NO_STR
b2d4d039
RW
664 "OSPF6 area parameters\n"
665 "OSPF6 area ID in IP address format\n"
666 "Filter networks between OSPF6 areas\n"
667 "Filter prefixes between OSPF6 areas\n"
34956b31 668 "Name of an IPv6 prefix-list\n"
669 "Filter networks sent to this area\n"
670 "Filter networks sent from this area\n")
671{
51c26414
DW
672 int idx_ipv4 = 2;
673 int idx_word = 5;
34956b31 674 struct ospf6_area *area;
34956b31 675
51c26414 676 OSPF6_CMD_AREA_GET (argv[idx_ipv4]->arg, area);
34956b31 677
51c26414 678 if (strncmp (argv[idx_word]->arg, "in", 2) == 0)
34956b31 679 {
680 if (PREFIX_NAME_IN (area))
51c26414 681 if (strcmp (PREFIX_NAME_IN (area), argv[idx_ipv4]->arg) != 0)
34956b31 682 return CMD_SUCCESS;
683
684 PREFIX_LIST_IN (area) = NULL;
685 if (PREFIX_NAME_IN (area))
686 free (PREFIX_NAME_IN (area));
687
688 PREFIX_NAME_IN (area) = NULL;
689 ospf6_abr_reimport (area);
690 }
691 else
692 {
693 if (PREFIX_NAME_OUT (area))
51c26414 694 if (strcmp (PREFIX_NAME_OUT (area), argv[idx_ipv4]->arg) != 0)
34956b31 695 return CMD_SUCCESS;
696
697 PREFIX_LIST_OUT (area) = NULL;
698 if (PREFIX_NAME_OUT (area))
699 free (PREFIX_NAME_OUT (area));
700
701 PREFIX_NAME_OUT (area) = NULL;
702 ospf6_abr_enable_area (area);
703 }
704
705 return CMD_SUCCESS;
706}
707
708DEFUN (area_import_list,
709 area_import_list_cmd,
710 "area A.B.C.D import-list NAME",
b2d4d039
RW
711 "OSPF6 area parameters\n"
712 "OSPF6 area ID in IP address format\n"
34956b31 713 "Set the filter for networks from other areas announced to the specified one\n"
714 "Name of the acess-list\n")
715{
51c26414
DW
716 int idx_ipv4 = 1;
717 int idx_name = 3;
34956b31 718 struct ospf6_area *area;
719 struct access_list *list;
720
51c26414 721 OSPF6_CMD_AREA_GET(argv[idx_ipv4]->arg, area);
34956b31 722
51c26414 723 list = access_list_lookup (AFI_IP6, argv[idx_name]->arg);
34956b31 724
725 IMPORT_LIST (area) = list;
726
727 if (IMPORT_NAME (area))
728 free (IMPORT_NAME (area));
729
51c26414 730 IMPORT_NAME (area) = strdup (argv[idx_name]->arg);
34956b31 731 ospf6_abr_reimport (area);
732
733 return CMD_SUCCESS;
734}
735
736DEFUN (no_area_import_list,
737 no_area_import_list_cmd,
738 "no area A.B.C.D import-list NAME",
6fbde29d 739 NO_STR
b2d4d039
RW
740 "OSPF6 area parameters\n"
741 "OSPF6 area ID in IP address format\n"
34956b31 742 "Unset the filter for networks announced to other areas\n"
6fbde29d 743 "Name of the access-list\n")
34956b31 744{
51c26414 745 int idx_ipv4 = 2;
34956b31 746 struct ospf6_area *area;
747
51c26414 748 OSPF6_CMD_AREA_GET(argv[idx_ipv4]->arg, area);
34956b31 749
750 IMPORT_LIST (area) = 0;
751
752 if (IMPORT_NAME (area))
753 free (IMPORT_NAME (area));
754
755 IMPORT_NAME (area) = NULL;
756 ospf6_abr_reimport (area);
757
758 return CMD_SUCCESS;
759}
760
761DEFUN (area_export_list,
762 area_export_list_cmd,
763 "area A.B.C.D export-list NAME",
b2d4d039
RW
764 "OSPF6 area parameters\n"
765 "OSPF6 area ID in IP address format\n"
34956b31 766 "Set the filter for networks announced to other areas\n"
767 "Name of the acess-list\n")
768{
51c26414
DW
769 int idx_ipv4 = 1;
770 int idx_name = 3;
34956b31 771 struct ospf6_area *area;
772 struct access_list *list;
773
51c26414 774 OSPF6_CMD_AREA_GET(argv[idx_ipv4]->arg, area);
34956b31 775
51c26414 776 list = access_list_lookup (AFI_IP6, argv[idx_name]->arg);
34956b31 777
778 EXPORT_LIST (area) = list;
779
780 if (EXPORT_NAME (area))
781 free (EXPORT_NAME (area));
782
51c26414 783 EXPORT_NAME (area) = strdup (argv[idx_name]->arg);
34956b31 784 ospf6_abr_enable_area (area);
785
786 return CMD_SUCCESS;
787}
788
789DEFUN (no_area_export_list,
790 no_area_export_list_cmd,
791 "no area A.B.C.D export-list NAME",
6fbde29d 792 NO_STR
b2d4d039
RW
793 "OSPF6 area parameters\n"
794 "OSPF6 area ID in IP address format\n"
34956b31 795 "Unset the filter for networks announced to other areas\n"
796 "Name of the access-list\n")
797{
51c26414 798 int idx_ipv4 = 2;
34956b31 799 struct ospf6_area *area;
800
51c26414 801 OSPF6_CMD_AREA_GET(argv[idx_ipv4]->arg, area);
34956b31 802
803 EXPORT_LIST (area) = 0;
804
805 if (EXPORT_NAME (area))
806 free (EXPORT_NAME (area));
807
808 EXPORT_NAME (area) = NULL;
809 ospf6_abr_enable_area (area);
810
811 return CMD_SUCCESS;
812}
813
508e53e2 814DEFUN (show_ipv6_ospf6_spf_tree,
815 show_ipv6_ospf6_spf_tree_cmd,
816 "show ipv6 ospf6 spf tree",
817 SHOW_STR
818 IP6_STR
819 OSPF6_STR
820 "Shortest Path First caculation\n"
821 "Show SPF tree\n")
718e3744 822{
52dc7ee6 823 struct listnode *node;
508e53e2 824 struct ospf6_area *oa;
825 struct ospf6_vertex *root;
826 struct ospf6_route *route;
827 struct prefix prefix;
718e3744 828
b52a8a52
DS
829 OSPF6_CMD_CHECK_RUNNING ();
830
508e53e2 831 ospf6_linkstate_prefix (ospf6->router_id, htonl (0), &prefix);
1eb8ef25 832
833 for (ALL_LIST_ELEMENTS_RO (ospf6->area_list, node, oa))
508e53e2 834 {
508e53e2 835 route = ospf6_route_lookup (&prefix, oa->spf_table);
836 if (route == NULL)
837 {
838 vty_out (vty, "LS entry for root not found in area %s%s",
049207c3 839 oa->name, VNL);
508e53e2 840 continue;
841 }
842 root = (struct ospf6_vertex *) route->route_option;
843 ospf6_spf_display_subtree (vty, "", 0, root);
844 }
845
846 return CMD_SUCCESS;
847}
848
849DEFUN (show_ipv6_ospf6_area_spf_tree,
850 show_ipv6_ospf6_area_spf_tree_cmd,
851 "show ipv6 ospf6 area A.B.C.D spf tree",
852 SHOW_STR
853 IP6_STR
854 OSPF6_STR
855 OSPF6_AREA_STR
856 OSPF6_AREA_ID_STR
857 "Shortest Path First caculation\n"
858 "Show SPF tree\n")
859{
51c26414 860 int idx_ipv4 = 4;
508e53e2 861 u_int32_t area_id;
862 struct ospf6_area *oa;
863 struct ospf6_vertex *root;
864 struct ospf6_route *route;
865 struct prefix prefix;
718e3744 866
b52a8a52
DS
867 OSPF6_CMD_CHECK_RUNNING ();
868
508e53e2 869 ospf6_linkstate_prefix (ospf6->router_id, htonl (0), &prefix);
718e3744 870
51c26414 871 if (inet_pton (AF_INET, argv[idx_ipv4]->arg, &area_id) != 1)
718e3744 872 {
51c26414 873 vty_out (vty, "Malformed Area-ID: %s%s", argv[idx_ipv4]->arg, VNL);
508e53e2 874 return CMD_SUCCESS;
875 }
876 oa = ospf6_area_lookup (area_id, ospf6);
877 if (oa == NULL)
878 {
51c26414 879 vty_out (vty, "No such Area: %s%s", argv[idx_ipv4]->arg, VNL);
508e53e2 880 return CMD_SUCCESS;
718e3744 881 }
718e3744 882
508e53e2 883 route = ospf6_route_lookup (&prefix, oa->spf_table);
884 if (route == NULL)
718e3744 885 {
508e53e2 886 vty_out (vty, "LS entry for root not found in area %s%s",
049207c3 887 oa->name, VNL);
508e53e2 888 return CMD_SUCCESS;
718e3744 889 }
508e53e2 890 root = (struct ospf6_vertex *) route->route_option;
891 ospf6_spf_display_subtree (vty, "", 0, root);
892
893 return CMD_SUCCESS;
718e3744 894}
895
508e53e2 896DEFUN (show_ipv6_ospf6_simulate_spf_tree_root,
897 show_ipv6_ospf6_simulate_spf_tree_root_cmd,
898 "show ipv6 ospf6 simulate spf-tree A.B.C.D area A.B.C.D",
899 SHOW_STR
900 IP6_STR
901 OSPF6_STR
d7fa34c1 902 "Shortest Path First calculation\n"
508e53e2 903 "Show SPF tree\n"
d7fa34c1
QY
904 "Specify root's router-id to calculate another router's SPF tree\n"
905 "OSPF6 area parameters\n"
906 OSPF6_AREA_ID_STR)
508e53e2 907{
51c26414
DW
908 int idx_ipv4 = 5;
909 int idx_ipv4_2 = 7;
508e53e2 910 u_int32_t area_id;
911 struct ospf6_area *oa;
912 struct ospf6_vertex *root;
913 struct ospf6_route *route;
914 struct prefix prefix;
915 u_int32_t router_id;
916 struct ospf6_route_table *spf_table;
917 unsigned char tmp_debug_ospf6_spf = 0;
918
b52a8a52
DS
919 OSPF6_CMD_CHECK_RUNNING ();
920
51c26414 921 inet_pton (AF_INET, argv[idx_ipv4]->arg, &router_id);
508e53e2 922 ospf6_linkstate_prefix (router_id, htonl (0), &prefix);
923
51c26414 924 if (inet_pton (AF_INET, argv[idx_ipv4_2]->arg, &area_id) != 1)
508e53e2 925 {
51c26414 926 vty_out (vty, "Malformed Area-ID: %s%s", argv[idx_ipv4_2]->arg, VNL);
508e53e2 927 return CMD_SUCCESS;
928 }
929 oa = ospf6_area_lookup (area_id, ospf6);
930 if (oa == NULL)
931 {
51c26414 932 vty_out (vty, "No such Area: %s%s", argv[idx_ipv4_2]->arg, VNL);
508e53e2 933 return CMD_SUCCESS;
934 }
935
936 tmp_debug_ospf6_spf = conf_debug_ospf6_spf;
937 conf_debug_ospf6_spf = 0;
938
cf1ce250 939 spf_table = OSPF6_ROUTE_TABLE_CREATE (NONE, SPF_RESULTS);
508e53e2 940 ospf6_spf_calculation (router_id, spf_table, oa);
941
942 conf_debug_ospf6_spf = tmp_debug_ospf6_spf;
943
944 route = ospf6_route_lookup (&prefix, spf_table);
945 if (route == NULL)
946 {
947 ospf6_spf_table_finish (spf_table);
948 ospf6_route_table_delete (spf_table);
949 return CMD_SUCCESS;
950 }
951 root = (struct ospf6_vertex *) route->route_option;
952 ospf6_spf_display_subtree (vty, "", 0, root);
718e3744 953
508e53e2 954 ospf6_spf_table_finish (spf_table);
955 ospf6_route_table_delete (spf_table);
956
957 return CMD_SUCCESS;
958}
959
ca1f4309
DS
960DEFUN (ospf6_area_stub,
961 ospf6_area_stub_cmd,
6147e2c6 962 "area <A.B.C.D|(0-4294967295)> stub",
ca1f4309
DS
963 "OSPF6 area parameters\n"
964 "OSPF6 area ID in IP address format\n"
965 "OSPF6 area ID as a decimal value\n"
966 "Configure OSPF6 area as stub\n")
967{
51c26414 968 int idx_ipv4_number = 1;
ca1f4309
DS
969 struct ospf6_area *area;
970
51c26414 971 OSPF6_CMD_AREA_GET(argv[idx_ipv4_number]->arg, area);
ca1f4309
DS
972
973 if (!ospf6_area_stub_set (ospf6, area))
974 {
975 vty_out (vty, "First deconfigure all virtual link through this area%s",
976 VTY_NEWLINE);
977 return CMD_WARNING;
978 }
979
980 ospf6_area_no_summary_unset (ospf6, area);
981
982 return CMD_SUCCESS;
983}
984
985DEFUN (ospf6_area_stub_no_summary,
986 ospf6_area_stub_no_summary_cmd,
6147e2c6 987 "area <A.B.C.D|(0-4294967295)> stub no-summary",
ca1f4309
DS
988 "OSPF6 stub parameters\n"
989 "OSPF6 area ID in IP address format\n"
990 "OSPF6 area ID as a decimal value\n"
991 "Configure OSPF6 area as stub\n"
992 "Do not inject inter-area routes into stub\n")
993{
51c26414 994 int idx_ipv4_number = 1;
ca1f4309
DS
995 struct ospf6_area *area;
996
51c26414 997 OSPF6_CMD_AREA_GET(argv[idx_ipv4_number]->arg, area);
ca1f4309
DS
998
999 if (!ospf6_area_stub_set (ospf6, area))
1000 {
1001 vty_out (vty, "First deconfigure all virtual link through this area%s",
1002 VTY_NEWLINE);
1003 return CMD_WARNING;
1004 }
1005
1006 ospf6_area_no_summary_set (ospf6, area);
1007
1008 return CMD_SUCCESS;
1009}
1010
1011DEFUN (no_ospf6_area_stub,
1012 no_ospf6_area_stub_cmd,
6147e2c6 1013 "no area <A.B.C.D|(0-4294967295)> stub",
ca1f4309
DS
1014 NO_STR
1015 "OSPF6 area parameters\n"
1016 "OSPF6 area ID in IP address format\n"
1017 "OSPF6 area ID as a decimal value\n"
1018 "Configure OSPF6 area as stub\n")
1019{
51c26414 1020 int idx_ipv4_number = 2;
ca1f4309
DS
1021 struct ospf6_area *area;
1022
51c26414 1023 OSPF6_CMD_AREA_GET(argv[idx_ipv4_number]->arg, area);
ca1f4309
DS
1024
1025 ospf6_area_stub_unset (ospf6, area);
1026 ospf6_area_no_summary_unset (ospf6, area);
1027
1028 return CMD_SUCCESS;
1029}
1030
1031DEFUN (no_ospf6_area_stub_no_summary,
1032 no_ospf6_area_stub_no_summary_cmd,
6147e2c6 1033 "no area <A.B.C.D|(0-4294967295)> stub no-summary",
ca1f4309
DS
1034 NO_STR
1035 "OSPF6 area parameters\n"
1036 "OSPF6 area ID in IP address format\n"
1037 "OSPF6 area ID as a decimal value\n"
1038 "Configure OSPF6 area as stub\n"
1039 "Do not inject inter-area routes into area\n")
1040{
51c26414 1041 int idx_ipv4_number = 2;
ca1f4309
DS
1042 struct ospf6_area *area;
1043
51c26414 1044 OSPF6_CMD_AREA_GET(argv[idx_ipv4_number]->arg, area);
ca1f4309
DS
1045
1046 ospf6_area_stub_unset (ospf6, area);
1047 ospf6_area_no_summary_unset (ospf6, area);
1048
1049 return CMD_SUCCESS;
1050}
1051
508e53e2 1052void
6ac29a51 1053ospf6_area_init (void)
508e53e2 1054{
1055 install_element (VIEW_NODE, &show_ipv6_ospf6_spf_tree_cmd);
508e53e2 1056 install_element (VIEW_NODE, &show_ipv6_ospf6_area_spf_tree_cmd);
508e53e2 1057 install_element (VIEW_NODE, &show_ipv6_ospf6_simulate_spf_tree_root_cmd);
1058
6452df09 1059 install_element (OSPF6_NODE, &area_range_cmd);
6452df09 1060 install_element (OSPF6_NODE, &no_area_range_cmd);
ca1f4309
DS
1061 install_element (OSPF6_NODE, &ospf6_area_stub_no_summary_cmd);
1062 install_element (OSPF6_NODE, &ospf6_area_stub_cmd);
1063 install_element (OSPF6_NODE, &no_ospf6_area_stub_no_summary_cmd);
1064 install_element (OSPF6_NODE, &no_ospf6_area_stub_cmd);
1065
34956b31 1066
1067 install_element (OSPF6_NODE, &area_import_list_cmd);
1068 install_element (OSPF6_NODE, &no_area_import_list_cmd);
1069 install_element (OSPF6_NODE, &area_export_list_cmd);
1070 install_element (OSPF6_NODE, &no_area_export_list_cmd);
1071
1072 install_element (OSPF6_NODE, &area_filter_list_cmd);
1073 install_element (OSPF6_NODE, &no_area_filter_list_cmd);
1074
508e53e2 1075}
049207c3 1076
6452df09 1077