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