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