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