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