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