2 * Copyright (C) 2003 Yasuhiro Ohara
4 * This file is part of GNU Zebra.
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
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.
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
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_message.h"
43 #include "ospf6_neighbor.h"
44 #include "ospf6_interface.h"
45 #include "ospf6_intra.h"
46 #include "ospf6_abr.h"
47 #include "ospf6_asbr.h"
48 #include "ospf6_zebra.h"
51 #include "ospf6_nssa.h"
52 #ifndef VTYSH_EXTRACT_PL
53 #include "ospf6d/ospf6_area_clippy.c"
56 DEFINE_MTYPE_STATIC(OSPF6D
, OSPF6_AREA
, "OSPF6 area");
57 DEFINE_MTYPE_STATIC(OSPF6D
, OSPF6_PLISTNAME
, "Prefix list name");
59 int str2area_id(const char *str
, uint32_t *area_id
, int *area_id_fmt
)
63 *area_id
= htonl(strtoul(str
, &ep
, 10));
64 if (*ep
&& inet_pton(AF_INET
, str
, area_id
) != 1)
68 !*ep
? OSPF6_AREA_FMT_DECIMAL
: OSPF6_AREA_FMT_DOTTEDQUAD
;
73 void area_id2str(char *buf
, int len
, uint32_t area_id
, int area_id_fmt
)
75 if (area_id_fmt
== OSPF6_AREA_FMT_DECIMAL
)
76 snprintf(buf
, len
, "%u", ntohl(area_id
));
78 inet_ntop(AF_INET
, &area_id
, buf
, len
);
81 int ospf6_area_cmp(void *va
, void *vb
)
83 struct ospf6_area
*oa
= (struct ospf6_area
*)va
;
84 struct ospf6_area
*ob
= (struct ospf6_area
*)vb
;
85 return (ntohl(oa
->area_id
) < ntohl(ob
->area_id
) ? -1 : 1);
88 /* schedule routing table recalculation */
89 static void ospf6_area_lsdb_hook_add(struct ospf6_lsa
*lsa
)
91 switch (ntohs(lsa
->header
->type
)) {
93 case OSPF6_LSTYPE_ROUTER
:
94 case OSPF6_LSTYPE_NETWORK
:
95 if (IS_OSPF6_DEBUG_EXAMIN_TYPE(lsa
->header
->type
)) {
96 zlog_debug("%s Examin LSA %s", __func__
, lsa
->name
);
97 zlog_debug(" Schedule SPF Calculation for %s",
98 OSPF6_AREA(lsa
->lsdb
->data
)->name
);
101 OSPF6_PROCESS(OSPF6_AREA(lsa
->lsdb
->data
)->ospf6
),
102 ospf6_lsadd_to_spf_reason(lsa
));
105 case OSPF6_LSTYPE_INTRA_PREFIX
:
106 ospf6_intra_prefix_lsa_add(lsa
);
109 case OSPF6_LSTYPE_INTER_PREFIX
:
110 case OSPF6_LSTYPE_INTER_ROUTER
:
111 ospf6_abr_examin_summary(lsa
,
112 (struct ospf6_area
*)lsa
->lsdb
->data
);
115 case OSPF6_LSTYPE_TYPE_7
:
116 ospf6_asbr_lsa_add(lsa
);
124 static void ospf6_area_lsdb_hook_remove(struct ospf6_lsa
*lsa
)
126 switch (ntohs(lsa
->header
->type
)) {
127 case OSPF6_LSTYPE_ROUTER
:
128 case OSPF6_LSTYPE_NETWORK
:
129 if (IS_OSPF6_DEBUG_EXAMIN_TYPE(lsa
->header
->type
)) {
130 zlog_debug("LSA disappearing: %s", lsa
->name
);
131 zlog_debug("Schedule SPF Calculation for %s",
132 OSPF6_AREA(lsa
->lsdb
->data
)->name
);
135 OSPF6_PROCESS(OSPF6_AREA(lsa
->lsdb
->data
)->ospf6
),
136 ospf6_lsremove_to_spf_reason(lsa
));
139 case OSPF6_LSTYPE_INTRA_PREFIX
:
140 ospf6_intra_prefix_lsa_remove(lsa
);
143 case OSPF6_LSTYPE_INTER_PREFIX
:
144 case OSPF6_LSTYPE_INTER_ROUTER
:
145 ospf6_abr_examin_summary(lsa
,
146 (struct ospf6_area
*)lsa
->lsdb
->data
);
148 case OSPF6_LSTYPE_TYPE_7
:
149 ospf6_asbr_lsa_remove(lsa
, NULL
);
156 static void ospf6_area_route_hook_add(struct ospf6_route
*route
)
158 struct ospf6_area
*oa
= route
->table
->scope
;
159 struct ospf6
*ospf6
= oa
->ospf6
;
160 struct ospf6_route
*copy
;
162 copy
= ospf6_route_copy(route
);
163 ospf6_route_add(copy
, ospf6
->route_table
);
166 static void ospf6_area_route_hook_remove(struct ospf6_route
*route
)
168 struct ospf6_area
*oa
= route
->table
->scope
;
169 struct ospf6
*ospf6
= oa
->ospf6
;
170 struct ospf6_route
*copy
;
172 copy
= ospf6_route_lookup_identical(route
, ospf6
->route_table
);
174 ospf6_route_remove(copy
, ospf6
->route_table
);
177 static void ospf6_area_stub_update(struct ospf6_area
*area
)
180 if (IS_AREA_STUB(area
)) {
181 if (IS_OSPF6_DEBUG_ORIGINATE(ROUTER
))
182 zlog_debug("Stubbing out area for area %s", area
->name
);
183 OSPF6_OPT_CLEAR(area
->options
, OSPF6_OPT_E
);
184 ospf6_asbr_remove_externals_from_area(area
);
185 } else if (IS_AREA_ENABLED(area
)) {
186 if (IS_OSPF6_DEBUG_ORIGINATE(ROUTER
))
187 zlog_debug("Normal area for area %s", area
->name
);
188 OSPF6_OPT_SET(area
->options
, OSPF6_OPT_E
);
189 ospf6_asbr_send_externals_to_area(area
);
192 OSPF6_ROUTER_LSA_SCHEDULE(area
);
195 static int ospf6_area_stub_set(struct ospf6
*ospf6
, struct ospf6_area
*area
)
197 if (!IS_AREA_STUB(area
)) {
198 /* Disable NSSA first. */
199 ospf6_area_nssa_unset(ospf6
, area
);
201 SET_FLAG(area
->flag
, OSPF6_AREA_STUB
);
202 ospf6_area_stub_update(area
);
208 void ospf6_area_stub_unset(struct ospf6
*ospf6
, struct ospf6_area
*area
)
210 if (IS_AREA_STUB(area
)) {
211 UNSET_FLAG(area
->flag
, OSPF6_AREA_STUB
);
212 ospf6_area_stub_update(area
);
216 static void ospf6_area_no_summary_set(struct ospf6
*ospf6
,
217 struct ospf6_area
*area
)
220 if (!area
->no_summary
) {
221 area
->no_summary
= 1;
222 ospf6_abr_range_reset_cost(ospf6
);
223 ospf6_abr_prefix_resummarize(ospf6
);
228 static void ospf6_area_no_summary_unset(struct ospf6
*ospf6
,
229 struct ospf6_area
*area
)
232 if (area
->no_summary
) {
233 area
->no_summary
= 0;
234 ospf6_abr_range_reset_cost(ospf6
);
235 ospf6_abr_prefix_resummarize(ospf6
);
240 static void ospf6_nssa_default_originate_set(struct ospf6
*ospf6
,
241 struct ospf6_area
*area
,
242 int metric
, int metric_type
)
244 if (!area
->nssa_default_originate
.enabled
) {
245 area
->nssa_default_originate
.enabled
= true;
246 if (++ospf6
->nssa_default_import_check
.refcnt
== 1) {
247 ospf6
->nssa_default_import_check
.status
= false;
248 ospf6_zebra_import_default_route(ospf6
, false);
252 area
->nssa_default_originate
.metric_value
= metric
;
253 area
->nssa_default_originate
.metric_type
= metric_type
;
256 static void ospf6_nssa_default_originate_unset(struct ospf6
*ospf6
,
257 struct ospf6_area
*area
)
259 if (area
->nssa_default_originate
.enabled
) {
260 area
->nssa_default_originate
.enabled
= false;
261 if (--ospf6
->nssa_default_import_check
.refcnt
== 0) {
262 ospf6
->nssa_default_import_check
.status
= false;
263 ospf6_zebra_import_default_route(ospf6
, true);
265 area
->nssa_default_originate
.metric_value
= -1;
266 area
->nssa_default_originate
.metric_type
= -1;
271 * Make new area structure.
273 * @param area_id - ospf6 area ID
274 * @param o - ospf6 instance
275 * @param df - display format for area ID
277 struct ospf6_area
*ospf6_area_create(uint32_t area_id
, struct ospf6
*o
, int df
)
279 struct ospf6_area
*oa
;
281 oa
= XCALLOC(MTYPE_OSPF6_AREA
, sizeof(struct ospf6_area
));
284 case OSPF6_AREA_FMT_DECIMAL
:
285 snprintf(oa
->name
, sizeof(oa
->name
), "%u", ntohl(area_id
));
288 case OSPF6_AREA_FMT_DOTTEDQUAD
:
289 inet_ntop(AF_INET
, &area_id
, oa
->name
, sizeof(oa
->name
));
293 oa
->area_id
= area_id
;
294 oa
->if_list
= list_new();
296 oa
->lsdb
= ospf6_lsdb_create(oa
);
297 oa
->lsdb
->hook_add
= ospf6_area_lsdb_hook_add
;
298 oa
->lsdb
->hook_remove
= ospf6_area_lsdb_hook_remove
;
299 oa
->lsdb_self
= ospf6_lsdb_create(oa
);
300 oa
->temp_router_lsa_lsdb
= ospf6_lsdb_create(oa
);
302 oa
->spf_table
= OSPF6_ROUTE_TABLE_CREATE(AREA
, SPF_RESULTS
);
303 oa
->spf_table
->scope
= oa
;
304 oa
->route_table
= OSPF6_ROUTE_TABLE_CREATE(AREA
, ROUTES
);
305 oa
->route_table
->scope
= oa
;
306 oa
->route_table
->hook_add
= ospf6_area_route_hook_add
;
307 oa
->route_table
->hook_remove
= ospf6_area_route_hook_remove
;
309 oa
->range_table
= OSPF6_ROUTE_TABLE_CREATE(AREA
, PREFIX_RANGES
);
310 oa
->range_table
->scope
= oa
;
311 oa
->nssa_range_table
= OSPF6_ROUTE_TABLE_CREATE(AREA
, PREFIX_RANGES
);
312 oa
->nssa_range_table
->scope
= oa
;
313 oa
->summary_prefix
= OSPF6_ROUTE_TABLE_CREATE(AREA
, SUMMARY_PREFIXES
);
314 oa
->summary_prefix
->scope
= oa
;
315 oa
->summary_router
= OSPF6_ROUTE_TABLE_CREATE(AREA
, SUMMARY_ROUTERS
);
316 oa
->summary_router
->scope
= oa
;
317 oa
->router_lsa_size_limit
= 1024 + 256;
319 /* set default options */
320 if (CHECK_FLAG(o
->flag
, OSPF6_STUB_ROUTER
)) {
321 OSPF6_OPT_CLEAR(oa
->options
, OSPF6_OPT_V6
);
322 OSPF6_OPT_CLEAR(oa
->options
, OSPF6_OPT_R
);
324 OSPF6_OPT_SET(oa
->options
, OSPF6_OPT_V6
);
325 OSPF6_OPT_SET(oa
->options
, OSPF6_OPT_R
);
328 OSPF6_OPT_SET(oa
->options
, OSPF6_OPT_E
);
330 SET_FLAG(oa
->flag
, OSPF6_AREA_ACTIVE
);
331 SET_FLAG(oa
->flag
, OSPF6_AREA_ENABLE
);
334 listnode_add_sort(o
->area_list
, oa
);
336 if (area_id
== OSPF_AREA_BACKBONE
) {
343 void ospf6_area_delete(struct ospf6_area
*oa
)
346 struct ospf6_interface
*oi
;
348 /* The ospf6_interface structs store configuration
349 * information which should not be lost/reset when
351 * So just detach the interface from the area and
353 for (ALL_LIST_ELEMENTS_RO(oa
->if_list
, n
, oi
)) {
356 struct listnode
*node
;
357 struct listnode
*nnode
;
358 struct ospf6_neighbor
*on
;
360 for (ALL_LIST_ELEMENTS(oi
->neighbor_list
, node
, nnode
, on
))
361 ospf6_neighbor_delete(on
);
364 list_delete(&oa
->if_list
);
366 ospf6_lsdb_delete(oa
->lsdb
);
367 ospf6_lsdb_delete(oa
->lsdb_self
);
368 ospf6_lsdb_delete(oa
->temp_router_lsa_lsdb
);
370 ospf6_spf_table_finish(oa
->spf_table
);
371 ospf6_route_table_delete(oa
->spf_table
);
372 ospf6_route_table_delete(oa
->route_table
);
374 ospf6_route_table_delete(oa
->range_table
);
375 ospf6_route_table_delete(oa
->nssa_range_table
);
376 ospf6_route_table_delete(oa
->summary_prefix
);
377 ospf6_route_table_delete(oa
->summary_router
);
379 listnode_delete(oa
->ospf6
->area_list
, oa
);
383 XFREE(MTYPE_OSPF6_AREA
, oa
);
386 struct ospf6_area
*ospf6_area_lookup_by_area_id(uint32_t area_id
)
388 struct ospf6_area
*oa
;
389 struct listnode
*n
, *node
, *nnode
;
392 for (ALL_LIST_ELEMENTS(om6
->ospf6
, node
, nnode
, ospf6
)) {
393 for (ALL_LIST_ELEMENTS_RO(ospf6
->area_list
, n
, oa
))
394 if (oa
->area_id
== area_id
)
397 return (struct ospf6_area
*)NULL
;
400 struct ospf6_area
*ospf6_area_lookup(uint32_t area_id
, struct ospf6
*ospf6
)
402 struct ospf6_area
*oa
;
405 for (ALL_LIST_ELEMENTS_RO(ospf6
->area_list
, n
, oa
))
406 if (oa
->area_id
== area_id
)
409 return (struct ospf6_area
*)NULL
;
412 void ospf6_area_enable(struct ospf6_area
*oa
)
414 struct listnode
*node
, *nnode
;
415 struct ospf6_interface
*oi
;
417 SET_FLAG(oa
->flag
, OSPF6_AREA_ENABLE
);
419 for (ALL_LIST_ELEMENTS(oa
->if_list
, node
, nnode
, oi
))
420 ospf6_interface_enable(oi
);
421 ospf6_abr_enable_area(oa
);
424 void ospf6_area_disable(struct ospf6_area
*oa
)
426 struct listnode
*node
, *nnode
;
427 struct ospf6_interface
*oi
;
429 UNSET_FLAG(oa
->flag
, OSPF6_AREA_ENABLE
);
431 for (ALL_LIST_ELEMENTS(oa
->if_list
, node
, nnode
, oi
))
432 ospf6_interface_disable(oi
);
434 ospf6_abr_disable_area(oa
);
435 ospf6_lsdb_remove_all(oa
->lsdb
);
436 ospf6_lsdb_remove_all(oa
->lsdb_self
);
438 ospf6_spf_table_finish(oa
->spf_table
);
439 ospf6_route_remove_all(oa
->route_table
);
441 THREAD_OFF(oa
->thread_router_lsa
);
442 THREAD_OFF(oa
->thread_intra_prefix_lsa
);
446 void ospf6_area_show(struct vty
*vty
, struct ospf6_area
*oa
,
447 json_object
*json_areas
, bool use_json
)
450 struct ospf6_interface
*oi
;
451 unsigned long result
;
452 json_object
*json_area
;
453 json_object
*array_interfaces
;
456 json_area
= json_object_new_object();
457 json_object_boolean_add(json_area
, "areaIsStub",
459 json_object_boolean_add(json_area
, "areaIsNSSA",
461 if (IS_AREA_STUB(oa
) || IS_AREA_NSSA(oa
)) {
462 json_object_boolean_add(json_area
, "areaNoSummary",
466 json_object_int_add(json_area
, "numberOfAreaScopedLsa",
468 json_object_object_add(
469 json_area
, "lsaStatistics",
470 JSON_OBJECT_NEW_ARRAY(json_object_new_int
,
474 /* Interfaces Attached */
475 array_interfaces
= json_object_new_array();
476 for (ALL_LIST_ELEMENTS_RO(oa
->if_list
, i
, oi
))
477 json_object_array_add(
479 json_object_new_string(oi
->interface
->name
));
481 json_object_object_add(json_area
, "interfacesAttachedToArea",
484 if (oa
->ts_spf
.tv_sec
|| oa
->ts_spf
.tv_usec
) {
485 json_object_boolean_true_add(json_area
, "spfHasRun");
486 result
= monotime_since(&oa
->ts_spf
, NULL
);
487 if (result
/ TIMER_SECOND_MICRO
> 0) {
489 json_area
, "spfLastExecutedSecs",
490 result
/ TIMER_SECOND_MICRO
);
493 json_area
, "spfLastExecutedMicroSecs",
494 result
% TIMER_SECOND_MICRO
);
496 json_object_int_add(json_area
,
497 "spfLastExecutedSecs", 0);
498 json_object_int_add(json_area
,
499 "spfLastExecutedMicroSecs",
503 json_object_boolean_false_add(json_area
, "spfHasRun");
506 json_object_object_add(json_areas
, oa
->name
, json_area
);
510 if (!IS_AREA_STUB(oa
) && !IS_AREA_NSSA(oa
))
511 vty_out(vty
, " Area %s\n", oa
->name
);
513 if (oa
->no_summary
) {
514 vty_out(vty
, " Area %s[%s, No Summary]\n",
516 IS_AREA_STUB(oa
) ? "Stub" : "NSSA");
518 vty_out(vty
, " Area %s[%s]\n", oa
->name
,
519 IS_AREA_STUB(oa
) ? "Stub" : "NSSA");
522 vty_out(vty
, " Number of Area scoped LSAs is %u\n",
525 vty_out(vty
, " Interface attached to this area:");
526 for (ALL_LIST_ELEMENTS_RO(oa
->if_list
, i
, oi
))
527 vty_out(vty
, " %s", oi
->interface
->name
);
530 if (oa
->ts_spf
.tv_sec
|| oa
->ts_spf
.tv_usec
) {
531 result
= monotime_since(&oa
->ts_spf
, NULL
);
532 if (result
/ TIMER_SECOND_MICRO
> 0) {
534 " SPF last executed %ld.%lds ago\n",
535 result
/ TIMER_SECOND_MICRO
,
536 result
% TIMER_SECOND_MICRO
);
539 " SPF last executed %ldus ago\n",
543 vty_out(vty
, "SPF has not been run\n");
549 "area <A.B.C.D|(0-4294967295)> range X:X::X:X/M [<advertise|not-advertise|cost (0-16777215)>]",
550 "OSPF6 area parameters\n"
551 "OSPF6 area ID in IP address format\n"
552 "OSPF6 area ID as a decimal value\n"
553 "Configured address range\n"
554 "Specify IPv6 prefix\n"
557 "User specified metric for this range\n"
558 "Advertised metric for this range\n")
561 int idx_ipv6_prefixlen
= 3;
564 struct ospf6_area
*oa
;
565 struct prefix prefix
;
566 struct ospf6_route
*range
;
569 VTY_DECLVAR_CONTEXT(ospf6
, ospf6
);
571 OSPF6_CMD_AREA_GET(argv
[idx_ipv4
]->arg
, oa
, ospf6
);
573 ret
= str2prefix(argv
[idx_ipv6_prefixlen
]->arg
, &prefix
);
574 if (ret
!= 1 || prefix
.family
!= AF_INET6
) {
575 vty_out(vty
, "Malformed argument: %s\n",
576 argv
[idx_ipv6_prefixlen
]->arg
);
580 range
= ospf6_route_lookup(&prefix
, oa
->range_table
);
582 range
= ospf6_route_create(ospf6
);
583 range
->type
= OSPF6_DEST_TYPE_RANGE
;
584 range
->prefix
= prefix
;
585 range
->path
.area_id
= oa
->area_id
;
586 range
->path
.cost
= OSPF_AREA_RANGE_COST_UNSPEC
;
589 /* default settings */
590 cost
= OSPF_AREA_RANGE_COST_UNSPEC
;
591 UNSET_FLAG(range
->flag
, OSPF6_ROUTE_DO_NOT_ADVERTISE
);
593 if (argc
> idx_type
) {
594 if (strmatch(argv
[idx_type
]->text
, "not-advertise"))
595 SET_FLAG(range
->flag
, OSPF6_ROUTE_DO_NOT_ADVERTISE
);
596 else if (strmatch(argv
[idx_type
]->text
, "cost"))
597 cost
= strtoul(argv
[5]->arg
, NULL
, 10);
600 range
->path
.u
.cost_config
= cost
;
602 if (range
->rnode
== NULL
) {
603 ospf6_route_add(range
, oa
->range_table
);
606 if (ospf6_check_and_set_router_abr(ospf6
)) {
607 /* Redo summaries if required */
608 ospf6_abr_prefix_resummarize(ospf6
);
614 DEFUN (no_area_range
,
616 "no area <A.B.C.D|(0-4294967295)> range X:X::X:X/M [<advertise|not-advertise|cost (0-16777215)>]",
618 "OSPF6 area parameters\n"
619 "OSPF6 area ID in IP address format\n"
620 "OSPF6 area ID as a decimal value\n"
621 "Configured address range\n"
622 "Specify IPv6 prefix\n"
625 "User specified metric for this range\n"
626 "Advertised metric for this range\n")
631 struct ospf6_area
*oa
;
632 struct prefix prefix
;
633 struct ospf6_route
*range
, *route
;
635 VTY_DECLVAR_CONTEXT(ospf6
, ospf6
);
637 OSPF6_CMD_AREA_GET(argv
[idx_ipv4
]->arg
, oa
, ospf6
);
639 ret
= str2prefix(argv
[idx_ipv6
]->arg
, &prefix
);
640 if (ret
!= 1 || prefix
.family
!= AF_INET6
) {
641 vty_out(vty
, "Malformed argument: %s\n", argv
[idx_ipv6
]->arg
);
645 range
= ospf6_route_lookup(&prefix
, oa
->range_table
);
647 vty_out(vty
, "Range %s does not exists.\n",
648 argv
[idx_ipv6
]->arg
);
652 if (ospf6_check_and_set_router_abr(oa
->ospf6
)) {
653 /* Blow away the aggregated LSA and route */
654 SET_FLAG(range
->flag
, OSPF6_ROUTE_REMOVE
);
656 /* Redo summaries if required */
657 for (route
= ospf6_route_head(oa
->ospf6
->route_table
); route
;
658 route
= ospf6_route_next(route
))
659 ospf6_abr_originate_summary(route
, oa
->ospf6
);
661 /* purge the old aggregated summary LSA */
662 ospf6_abr_originate_summary(range
, oa
->ospf6
);
664 ospf6_route_remove(range
, oa
->range_table
);
669 void ospf6_area_config_write(struct vty
*vty
, struct ospf6
*ospf6
)
671 struct listnode
*node
;
672 struct ospf6_area
*oa
;
673 struct ospf6_route
*range
;
675 for (ALL_LIST_ELEMENTS_RO(ospf6
->area_list
, node
, oa
)) {
676 for (range
= ospf6_route_head(oa
->range_table
); range
;
677 range
= ospf6_route_next(range
)) {
678 vty_out(vty
, " area %s range %pFX", oa
->name
,
681 if (CHECK_FLAG(range
->flag
,
682 OSPF6_ROUTE_DO_NOT_ADVERTISE
)) {
683 vty_out(vty
, " not-advertise");
685 // "advertise" is the default so we do not
687 if (range
->path
.u
.cost_config
688 != OSPF_AREA_RANGE_COST_UNSPEC
)
689 vty_out(vty
, " cost %d",
690 range
->path
.u
.cost_config
);
694 if (IS_AREA_STUB(oa
)) {
696 vty_out(vty
, " area %s stub no-summary\n",
699 vty_out(vty
, " area %s stub\n", oa
->name
);
701 if (IS_AREA_NSSA(oa
)) {
702 vty_out(vty
, " area %s nssa", oa
->name
);
703 if (oa
->nssa_default_originate
.enabled
) {
704 vty_out(vty
, " default-information-originate");
705 if (oa
->nssa_default_originate
.metric_value
707 vty_out(vty
, " metric %d",
708 oa
->nssa_default_originate
710 if (oa
->nssa_default_originate
.metric_type
711 != DEFAULT_METRIC_TYPE
)
712 vty_out(vty
, " metric-type 1");
715 vty_out(vty
, " no-summary");
718 for (range
= ospf6_route_head(oa
->nssa_range_table
); range
;
719 range
= ospf6_route_next(range
)) {
720 vty_out(vty
, " area %s nssa range %pFX", oa
->name
,
723 if (CHECK_FLAG(range
->flag
,
724 OSPF6_ROUTE_DO_NOT_ADVERTISE
)) {
725 vty_out(vty
, " not-advertise");
727 if (range
->path
.u
.cost_config
728 != OSPF_AREA_RANGE_COST_UNSPEC
)
729 vty_out(vty
, " cost %u",
730 range
->path
.u
.cost_config
);
734 if (PREFIX_NAME_IN(oa
))
735 vty_out(vty
, " area %s filter-list prefix %s in\n",
736 oa
->name
, PREFIX_NAME_IN(oa
));
737 if (PREFIX_NAME_OUT(oa
))
738 vty_out(vty
, " area %s filter-list prefix %s out\n",
739 oa
->name
, PREFIX_NAME_OUT(oa
));
741 vty_out(vty
, " area %s import-list %s\n", oa
->name
,
744 vty_out(vty
, " area %s export-list %s\n", oa
->name
,
749 DEFUN (area_filter_list
,
750 area_filter_list_cmd
,
751 "area <A.B.C.D|(0-4294967295)> filter-list prefix PREFIXLIST_NAME <in|out>",
752 "OSPF6 area parameters\n"
753 "OSPF6 area ID in IP address format\n"
754 "OSPF6 area ID as a decimal value\n"
755 "Filter networks between OSPF6 areas\n"
756 "Filter prefixes between OSPF6 areas\n"
757 "Name of an IPv6 prefix-list\n"
758 "Filter networks sent to this area\n"
759 "Filter networks sent from this area\n")
761 char *inout
= argv
[argc
- 1]->text
;
762 char *areaid
= argv
[1]->arg
;
763 char *plistname
= argv
[4]->arg
;
765 struct ospf6_area
*area
;
766 struct prefix_list
*plist
;
768 VTY_DECLVAR_CONTEXT(ospf6
, ospf6
);
770 OSPF6_CMD_AREA_GET(areaid
, area
, ospf6
);
772 plist
= prefix_list_lookup(AFI_IP6
, plistname
);
773 if (strmatch(inout
, "in")) {
774 PREFIX_LIST_IN(area
) = plist
;
775 XFREE(MTYPE_OSPF6_PLISTNAME
, PREFIX_NAME_IN(area
));
776 PREFIX_NAME_IN(area
) =
777 XSTRDUP(MTYPE_OSPF6_PLISTNAME
, plistname
);
779 PREFIX_LIST_OUT(area
) = plist
;
780 XFREE(MTYPE_OSPF6_PLISTNAME
, PREFIX_NAME_OUT(area
));
781 PREFIX_NAME_OUT(area
) =
782 XSTRDUP(MTYPE_OSPF6_PLISTNAME
, plistname
);
785 /* Redo summaries if required */
786 if (ospf6_check_and_set_router_abr(area
->ospf6
))
787 ospf6_schedule_abr_task(ospf6
);
792 DEFUN (no_area_filter_list
,
793 no_area_filter_list_cmd
,
794 "no area <A.B.C.D|(0-4294967295)> filter-list prefix PREFIXLIST_NAME <in|out>",
796 "OSPF6 area parameters\n"
797 "OSPF6 area ID in IP address format\n"
798 "OSPF6 area ID as a decimal value\n"
799 "Filter networks between OSPF6 areas\n"
800 "Filter prefixes between OSPF6 areas\n"
801 "Name of an IPv6 prefix-list\n"
802 "Filter networks sent to this area\n"
803 "Filter networks sent from this area\n")
805 char *inout
= argv
[argc
- 1]->text
;
806 char *areaid
= argv
[2]->arg
;
807 char *plistname
= argv
[5]->arg
;
809 struct ospf6_area
*area
;
811 VTY_DECLVAR_CONTEXT(ospf6
, ospf6
);
812 OSPF6_CMD_AREA_GET(areaid
, area
, ospf6
);
814 if (strmatch(inout
, "in")) {
815 if (PREFIX_NAME_IN(area
))
816 if (!strmatch(PREFIX_NAME_IN(area
), plistname
))
819 PREFIX_LIST_IN(area
) = NULL
;
820 XFREE(MTYPE_OSPF6_PLISTNAME
, PREFIX_NAME_IN(area
));
822 if (PREFIX_NAME_OUT(area
))
823 if (!strmatch(PREFIX_NAME_OUT(area
), plistname
))
826 XFREE(MTYPE_OSPF6_PLISTNAME
, PREFIX_NAME_OUT(area
));
827 PREFIX_LIST_OUT(area
) = NULL
;
830 /* Redo summaries if required */
831 if (ospf6_check_and_set_router_abr(area
->ospf6
))
832 ospf6_schedule_abr_task(ospf6
);
837 void ospf6_filter_update(struct access_list
*access
)
839 struct ospf6_area
*oa
;
840 struct listnode
*n
, *node
, *nnode
;
843 for (ALL_LIST_ELEMENTS(om6
->ospf6
, node
, nnode
, ospf6
)) {
846 for (ALL_LIST_ELEMENTS_RO(ospf6
->area_list
, n
, oa
)) {
848 && strcmp(IMPORT_NAME(oa
), access
->name
) == 0) {
849 IMPORT_LIST(oa
) = access_list_lookup(
850 AFI_IP6
, IMPORT_NAME(oa
));
855 && strcmp(EXPORT_NAME(oa
), access
->name
) == 0) {
856 EXPORT_LIST(oa
) = access_list_lookup(
857 AFI_IP6
, EXPORT_NAME(oa
));
862 if (update
&& ospf6_check_and_set_router_abr(ospf6
))
863 ospf6_schedule_abr_task(ospf6
);
867 void ospf6_plist_update(struct prefix_list
*plist
)
869 struct listnode
*node
, *nnode
;
870 struct ospf6_area
*oa
;
872 const char *name
= prefix_list_name(plist
);
873 struct ospf6
*ospf6
= NULL
;
875 if (prefix_list_afi(plist
) != AFI_IP6
)
878 for (ALL_LIST_ELEMENTS(om6
->ospf6
, node
, nnode
, ospf6
)) {
881 for (ALL_LIST_ELEMENTS_RO(ospf6
->area_list
, n
, oa
)) {
882 if (PREFIX_NAME_IN(oa
)
883 && !strcmp(PREFIX_NAME_IN(oa
), name
)) {
884 PREFIX_LIST_IN(oa
) = prefix_list_lookup(
885 AFI_IP6
, PREFIX_NAME_IN(oa
));
888 if (PREFIX_NAME_OUT(oa
)
889 && !strcmp(PREFIX_NAME_OUT(oa
), name
)) {
890 PREFIX_LIST_OUT(oa
) = prefix_list_lookup(
891 AFI_IP6
, PREFIX_NAME_OUT(oa
));
896 if (update
&& ospf6_check_and_set_router_abr(ospf6
))
897 ospf6_schedule_abr_task(ospf6
);
901 DEFUN (area_import_list
,
902 area_import_list_cmd
,
903 "area <A.B.C.D|(0-4294967295)> import-list ACCESSLIST6_NAME",
904 "OSPF6 area parameters\n"
905 "OSPF6 area ID in IP address format\n"
906 "OSPF6 area ID as a decimal value\n"
907 "Set the filter for networks from other areas announced to the specified one\n"
908 "Name of the access-list\n")
912 struct ospf6_area
*area
;
913 struct access_list
*list
;
915 VTY_DECLVAR_CONTEXT(ospf6
, ospf6
);
917 OSPF6_CMD_AREA_GET(argv
[idx_ipv4
]->arg
, area
, ospf6
);
919 list
= access_list_lookup(AFI_IP6
, argv
[idx_name
]->arg
);
921 IMPORT_LIST(area
) = list
;
923 if (IMPORT_NAME(area
))
924 free(IMPORT_NAME(area
));
926 IMPORT_NAME(area
) = strdup(argv
[idx_name
]->arg
);
927 if (ospf6_check_and_set_router_abr(area
->ospf6
))
928 ospf6_schedule_abr_task(ospf6
);
933 DEFUN (no_area_import_list
,
934 no_area_import_list_cmd
,
935 "no area <A.B.C.D|(0-4294967295)> import-list ACCESSLIST6_NAME",
937 "OSPF6 area parameters\n"
938 "OSPF6 area ID in IP address format\n"
939 "OSPF6 area ID as a decimal value\n"
940 "Unset the filter for networks announced to other areas\n"
941 "Name of the access-list\n")
944 struct ospf6_area
*area
;
946 VTY_DECLVAR_CONTEXT(ospf6
, ospf6
);
948 OSPF6_CMD_AREA_GET(argv
[idx_ipv4
]->arg
, area
, ospf6
);
950 IMPORT_LIST(area
) = NULL
;
952 if (IMPORT_NAME(area
))
953 free(IMPORT_NAME(area
));
955 IMPORT_NAME(area
) = NULL
;
956 if (ospf6_check_and_set_router_abr(area
->ospf6
))
957 ospf6_schedule_abr_task(ospf6
);
962 DEFUN (area_export_list
,
963 area_export_list_cmd
,
964 "area <A.B.C.D|(0-4294967295)> export-list ACCESSLIST6_NAME",
965 "OSPF6 area parameters\n"
966 "OSPF6 area ID in IP address format\n"
967 "OSPF6 area ID as a decimal value\n"
968 "Set the filter for networks announced to other areas\n"
969 "Name of the access-list\n")
973 struct ospf6_area
*area
;
974 struct access_list
*list
;
976 VTY_DECLVAR_CONTEXT(ospf6
, ospf6
);
978 OSPF6_CMD_AREA_GET(argv
[idx_ipv4
]->arg
, area
, ospf6
);
980 list
= access_list_lookup(AFI_IP6
, argv
[idx_name
]->arg
);
982 EXPORT_LIST(area
) = list
;
984 if (EXPORT_NAME(area
))
985 free(EXPORT_NAME(area
));
987 EXPORT_NAME(area
) = strdup(argv
[idx_name
]->arg
);
989 /* Redo summaries if required */
990 if (ospf6_check_and_set_router_abr(area
->ospf6
))
991 ospf6_schedule_abr_task(ospf6
);
996 DEFUN (no_area_export_list
,
997 no_area_export_list_cmd
,
998 "no area <A.B.C.D|(0-4294967295)> export-list ACCESSLIST6_NAME",
1000 "OSPF6 area parameters\n"
1001 "OSPF6 area ID in IP address format\n"
1002 "OSPF6 area ID as a decimal value\n"
1003 "Unset the filter for networks announced to other areas\n"
1004 "Name of the access-list\n")
1007 struct ospf6_area
*area
;
1009 VTY_DECLVAR_CONTEXT(ospf6
, ospf6
);
1011 OSPF6_CMD_AREA_GET(argv
[idx_ipv4
]->arg
, area
, ospf6
);
1013 EXPORT_LIST(area
) = NULL
;
1015 if (EXPORT_NAME(area
))
1016 free(EXPORT_NAME(area
));
1018 EXPORT_NAME(area
) = NULL
;
1019 if (ospf6_check_and_set_router_abr(area
->ospf6
))
1020 ospf6_schedule_abr_task(ospf6
);
1025 static int ipv6_ospf6_spf_tree_common(struct vty
*vty
, struct ospf6
*ospf6
,
1028 struct listnode
*node
;
1029 struct ospf6_area
*oa
;
1030 struct prefix prefix
;
1031 struct ospf6_vertex
*root
;
1032 struct ospf6_route
*route
;
1033 json_object
*json
= NULL
;
1034 json_object
*json_area
= NULL
;
1035 json_object
*json_head
= NULL
;
1038 json
= json_object_new_object();
1039 ospf6_linkstate_prefix(ospf6
->router_id
, htonl(0), &prefix
);
1040 for (ALL_LIST_ELEMENTS_RO(ospf6
->area_list
, node
, oa
)) {
1042 json_area
= json_object_new_object();
1043 json_head
= json_object_new_object();
1045 route
= ospf6_route_lookup(&prefix
, oa
->spf_table
);
1046 if (route
== NULL
) {
1048 json_object_string_add(
1050 "LS entry for not not found");
1051 json_object_free(json_head
);
1052 json_object_free(json_area
);
1055 "LS entry for root not found in area %s\n",
1059 root
= (struct ospf6_vertex
*)route
->route_option
;
1060 ospf6_spf_display_subtree(vty
, "", 0, root
, json_head
, uj
);
1063 json_object_object_add(json_area
, root
->name
,
1065 json_object_object_add(json
, oa
->name
, json_area
);
1070 vty_json(vty
, json
);
1075 DEFUN(show_ipv6_ospf6_spf_tree
, show_ipv6_ospf6_spf_tree_cmd
,
1076 "show ipv6 ospf6 [vrf <NAME|all>] spf tree [json]",
1077 SHOW_STR IP6_STR OSPF6_STR VRF_CMD_HELP_STR
1079 "Shortest Path First calculation\n"
1080 "Show SPF tree\n" JSON_STR
)
1082 struct listnode
*node
;
1083 struct ospf6
*ospf6
;
1084 const char *vrf_name
= NULL
;
1085 bool all_vrf
= false;
1087 bool uj
= use_json(argc
, argv
);
1089 OSPF6_FIND_VRF_ARGS(argv
, argc
, idx_vrf
, vrf_name
, all_vrf
);
1091 for (ALL_LIST_ELEMENTS_RO(om6
->ospf6
, node
, ospf6
)) {
1092 if (all_vrf
|| strcmp(ospf6
->name
, vrf_name
) == 0) {
1093 ipv6_ospf6_spf_tree_common(vty
, ospf6
, uj
);
1099 OSPF6_CMD_CHECK_VRF(uj
, all_vrf
, ospf6
);
1104 static int show_ospf6_area_spf_tree_common(struct vty
*vty
,
1105 struct cmd_token
**argv
,
1106 struct ospf6
*ospf6
,
1107 uint32_t area_id
, int idx_ipv4
)
1110 struct ospf6_area
*oa
;
1111 struct prefix prefix
;
1112 struct ospf6_vertex
*root
;
1113 struct ospf6_route
*route
;
1115 ospf6_linkstate_prefix(ospf6
->router_id
, htonl(0), &prefix
);
1117 oa
= ospf6_area_lookup(area_id
, ospf6
);
1119 vty_out(vty
, "No such Area: %s\n", argv
[idx_ipv4
]->arg
);
1123 route
= ospf6_route_lookup(&prefix
, oa
->spf_table
);
1124 if (route
== NULL
) {
1125 vty_out(vty
, "LS entry for root not found in area %s\n",
1129 root
= (struct ospf6_vertex
*)route
->route_option
;
1130 ospf6_spf_display_subtree(vty
, "", 0, root
, NULL
, false);
1135 DEFUN(show_ipv6_ospf6_area_spf_tree
, show_ipv6_ospf6_area_spf_tree_cmd
,
1136 "show ipv6 ospf6 [vrf <NAME|all>] area A.B.C.D spf tree",
1137 SHOW_STR IP6_STR OSPF6_STR VRF_CMD_HELP_STR
1138 "All VRFs\n" OSPF6_AREA_STR OSPF6_AREA_ID_STR
1139 "Shortest Path First calculation\n"
1144 struct ospf6
*ospf6
;
1145 struct listnode
*node
;
1146 const char *vrf_name
= NULL
;
1147 bool all_vrf
= false;
1150 OSPF6_FIND_VRF_ARGS(argv
, argc
, idx_vrf
, vrf_name
, all_vrf
);
1154 if (inet_pton(AF_INET
, argv
[idx_ipv4
]->arg
, &area_id
) != 1) {
1155 vty_out(vty
, "Malformed Area-ID: %s\n", argv
[idx_ipv4
]->arg
);
1159 for (ALL_LIST_ELEMENTS_RO(om6
->ospf6
, node
, ospf6
)) {
1160 if (all_vrf
|| strcmp(ospf6
->name
, vrf_name
) == 0) {
1161 show_ospf6_area_spf_tree_common(vty
, argv
, ospf6
,
1168 OSPF6_CMD_CHECK_VRF(false, all_vrf
, ospf6
);
1174 show_ospf6_simulate_spf_tree_commen(struct vty
*vty
, struct cmd_token
**argv
,
1175 struct ospf6
*ospf6
, uint32_t router_id
,
1176 uint32_t area_id
, struct prefix prefix
,
1177 int idx_ipv4
, int idx_ipv4_2
)
1179 struct ospf6_area
*oa
;
1180 struct ospf6_vertex
*root
;
1181 struct ospf6_route
*route
;
1182 struct ospf6_route_table
*spf_table
;
1183 unsigned char tmp_debug_ospf6_spf
= 0;
1185 oa
= ospf6_area_lookup(area_id
, ospf6
);
1187 vty_out(vty
, "No such Area: %s\n", argv
[idx_ipv4_2
]->arg
);
1191 tmp_debug_ospf6_spf
= conf_debug_ospf6_spf
;
1192 conf_debug_ospf6_spf
= 0;
1194 spf_table
= OSPF6_ROUTE_TABLE_CREATE(NONE
, SPF_RESULTS
);
1195 ospf6_spf_calculation(router_id
, spf_table
, oa
);
1197 conf_debug_ospf6_spf
= tmp_debug_ospf6_spf
;
1199 route
= ospf6_route_lookup(&prefix
, spf_table
);
1200 if (route
== NULL
) {
1201 ospf6_spf_table_finish(spf_table
);
1202 ospf6_route_table_delete(spf_table
);
1205 root
= (struct ospf6_vertex
*)route
->route_option
;
1206 ospf6_spf_display_subtree(vty
, "", 0, root
, NULL
, false);
1208 ospf6_spf_table_finish(spf_table
);
1209 ospf6_route_table_delete(spf_table
);
1214 DEFUN(show_ipv6_ospf6_simulate_spf_tree_root
,
1215 show_ipv6_ospf6_simulate_spf_tree_root_cmd
,
1216 "show ipv6 ospf6 [vrf <NAME|all>] simulate spf-tree A.B.C.D area A.B.C.D",
1217 SHOW_STR IP6_STR OSPF6_STR VRF_CMD_HELP_STR
1219 "Shortest Path First calculation\n"
1221 "Specify root's router-id to calculate another router's SPF tree\n"
1222 "OSPF6 area parameters\n" OSPF6_AREA_ID_STR
)
1227 struct prefix prefix
;
1229 struct ospf6
*ospf6
;
1230 struct listnode
*node
;
1231 const char *vrf_name
= NULL
;
1232 bool all_vrf
= false;
1235 OSPF6_FIND_VRF_ARGS(argv
, argc
, idx_vrf
, vrf_name
, all_vrf
);
1240 inet_pton(AF_INET
, argv
[idx_ipv4
]->arg
, &router_id
);
1241 ospf6_linkstate_prefix(router_id
, htonl(0), &prefix
);
1243 if (inet_pton(AF_INET
, argv
[idx_ipv4_2
]->arg
, &area_id
) != 1) {
1244 vty_out(vty
, "Malformed Area-ID: %s\n", argv
[idx_ipv4_2
]->arg
);
1248 for (ALL_LIST_ELEMENTS_RO(om6
->ospf6
, node
, ospf6
)) {
1249 if (all_vrf
|| strcmp(ospf6
->name
, vrf_name
) == 0) {
1250 show_ospf6_simulate_spf_tree_commen(
1251 vty
, argv
, ospf6
, router_id
, area_id
, prefix
,
1252 idx_ipv4
, idx_ipv4_2
);
1258 OSPF6_CMD_CHECK_VRF(false, all_vrf
, ospf6
);
1263 DEFUN (ospf6_area_stub
,
1264 ospf6_area_stub_cmd
,
1265 "area <A.B.C.D|(0-4294967295)> stub",
1266 "OSPF6 area parameters\n"
1267 "OSPF6 area ID in IP address format\n"
1268 "OSPF6 area ID as a decimal value\n"
1269 "Configure OSPF6 area as stub\n")
1271 int idx_ipv4_number
= 1;
1272 struct ospf6_area
*area
;
1274 VTY_DECLVAR_CONTEXT(ospf6
, ospf6
);
1276 OSPF6_CMD_AREA_GET(argv
[idx_ipv4_number
]->arg
, area
, ospf6
);
1278 if (!ospf6_area_stub_set(ospf6
, area
)) {
1280 "First deconfigure all virtual link through this area\n");
1281 return CMD_WARNING_CONFIG_FAILED
;
1284 ospf6_area_no_summary_unset(ospf6
, area
);
1289 DEFUN (ospf6_area_stub_no_summary
,
1290 ospf6_area_stub_no_summary_cmd
,
1291 "area <A.B.C.D|(0-4294967295)> stub no-summary",
1292 "OSPF6 stub parameters\n"
1293 "OSPF6 area ID in IP address format\n"
1294 "OSPF6 area ID as a decimal value\n"
1295 "Configure OSPF6 area as stub\n"
1296 "Do not inject inter-area routes into stub\n")
1298 int idx_ipv4_number
= 1;
1299 struct ospf6_area
*area
;
1301 VTY_DECLVAR_CONTEXT(ospf6
, ospf6
);
1303 OSPF6_CMD_AREA_GET(argv
[idx_ipv4_number
]->arg
, area
, ospf6
);
1305 if (!ospf6_area_stub_set(ospf6
, area
)) {
1307 "First deconfigure all virtual link through this area\n");
1308 return CMD_WARNING_CONFIG_FAILED
;
1311 ospf6_area_no_summary_set(ospf6
, area
);
1316 DEFUN (no_ospf6_area_stub
,
1317 no_ospf6_area_stub_cmd
,
1318 "no area <A.B.C.D|(0-4294967295)> stub",
1320 "OSPF6 area parameters\n"
1321 "OSPF6 area ID in IP address format\n"
1322 "OSPF6 area ID as a decimal value\n"
1323 "Configure OSPF6 area as stub\n")
1325 int idx_ipv4_number
= 2;
1326 struct ospf6_area
*area
;
1328 VTY_DECLVAR_CONTEXT(ospf6
, ospf6
);
1330 OSPF6_CMD_AREA_GET(argv
[idx_ipv4_number
]->arg
, area
, ospf6
);
1332 ospf6_area_stub_unset(ospf6
, area
);
1333 ospf6_area_no_summary_unset(ospf6
, area
);
1338 DEFUN (no_ospf6_area_stub_no_summary
,
1339 no_ospf6_area_stub_no_summary_cmd
,
1340 "no area <A.B.C.D|(0-4294967295)> stub no-summary",
1342 "OSPF6 area parameters\n"
1343 "OSPF6 area ID in IP address format\n"
1344 "OSPF6 area ID as a decimal value\n"
1345 "Configure OSPF6 area as stub\n"
1346 "Do not inject inter-area routes into area\n")
1348 int idx_ipv4_number
= 2;
1349 struct ospf6_area
*area
;
1351 VTY_DECLVAR_CONTEXT(ospf6
, ospf6
);
1353 OSPF6_CMD_AREA_GET(argv
[idx_ipv4_number
]->arg
, area
, ospf6
);
1355 ospf6_area_stub_unset(ospf6
, area
);
1356 ospf6_area_no_summary_unset(ospf6
, area
);
1361 DEFPY(ospf6_area_nssa
, ospf6_area_nssa_cmd
,
1362 "area <A.B.C.D|(0-4294967295)>$area_str nssa\
1364 default-information-originate$dflt_originate [{metric (0-16777214)$mval|metric-type (1-2)$mtype}]\
1365 |no-summary$no_summary\
1367 "OSPF6 area parameters\n"
1368 "OSPF6 area ID in IP address format\n"
1369 "OSPF6 area ID as a decimal value\n"
1370 "Configure OSPF6 area as nssa\n"
1371 "Originate Type 7 default into NSSA area\n"
1372 "OSPFv3 default metric\n"
1374 "OSPFv3 metric type for default routes\n"
1375 "Set OSPFv3 External Type 1/2 metrics\n"
1376 "Do not inject inter-area routes into area\n")
1378 struct ospf6_area
*area
;
1380 VTY_DECLVAR_CONTEXT(ospf6
, ospf6
);
1381 OSPF6_CMD_AREA_GET(area_str
, area
, ospf6
);
1383 if (!ospf6_area_nssa_set(ospf6
, area
)) {
1385 "First deconfigure all virtual link through this area\n");
1386 return CMD_WARNING_CONFIG_FAILED
;
1389 if (dflt_originate
) {
1390 if (mval_str
== NULL
)
1392 if (mtype_str
== NULL
)
1393 mtype
= DEFAULT_METRIC_TYPE
;
1394 ospf6_nssa_default_originate_set(ospf6
, area
, mval
, mtype
);
1396 ospf6_nssa_default_originate_unset(ospf6
, area
);
1399 ospf6_area_no_summary_set(ospf6
, area
);
1401 ospf6_area_no_summary_unset(ospf6
, area
);
1403 if (ospf6_check_and_set_router_abr(ospf6
)) {
1404 ospf6_abr_defaults_to_stub(ospf6
);
1405 ospf6_abr_nssa_type_7_defaults(ospf6
);
1411 DEFPY(no_ospf6_area_nssa
, no_ospf6_area_nssa_cmd
,
1412 "no area <A.B.C.D|(0-4294967295)>$area_str nssa\
1414 default-information-originate [{metric (0-16777214)|metric-type (1-2)}]\
1418 "OSPF6 area parameters\n"
1419 "OSPF6 area ID in IP address format\n"
1420 "OSPF6 area ID as a decimal value\n"
1421 "Configure OSPF6 area as nssa\n"
1422 "Originate Type 7 default into NSSA area\n"
1423 "OSPFv3 default metric\n"
1425 "OSPFv3 metric type for default routes\n"
1426 "Set OSPFv3 External Type 1/2 metrics\n"
1427 "Do not inject inter-area routes into area\n")
1429 struct ospf6_area
*area
;
1431 VTY_DECLVAR_CONTEXT(ospf6
, ospf6
);
1432 OSPF6_CMD_AREA_GET(area_str
, area
, ospf6
);
1434 ospf6_area_nssa_unset(ospf6
, area
);
1435 ospf6_area_no_summary_unset(ospf6
, area
);
1436 ospf6_nssa_default_originate_unset(ospf6
, area
);
1442 void ospf6_area_init(void)
1444 install_element(VIEW_NODE
, &show_ipv6_ospf6_spf_tree_cmd
);
1445 install_element(VIEW_NODE
, &show_ipv6_ospf6_area_spf_tree_cmd
);
1446 install_element(VIEW_NODE
, &show_ipv6_ospf6_simulate_spf_tree_root_cmd
);
1448 install_element(OSPF6_NODE
, &area_range_cmd
);
1449 install_element(OSPF6_NODE
, &no_area_range_cmd
);
1450 install_element(OSPF6_NODE
, &ospf6_area_stub_no_summary_cmd
);
1451 install_element(OSPF6_NODE
, &ospf6_area_stub_cmd
);
1452 install_element(OSPF6_NODE
, &no_ospf6_area_stub_no_summary_cmd
);
1453 install_element(OSPF6_NODE
, &no_ospf6_area_stub_cmd
);
1456 install_element(OSPF6_NODE
, &area_import_list_cmd
);
1457 install_element(OSPF6_NODE
, &no_area_import_list_cmd
);
1458 install_element(OSPF6_NODE
, &area_export_list_cmd
);
1459 install_element(OSPF6_NODE
, &no_area_export_list_cmd
);
1461 install_element(OSPF6_NODE
, &area_filter_list_cmd
);
1462 install_element(OSPF6_NODE
, &no_area_filter_list_cmd
);
1464 /* "area nssa" commands. */
1465 install_element(OSPF6_NODE
, &ospf6_area_nssa_cmd
);
1466 install_element(OSPF6_NODE
, &no_ospf6_area_nssa_cmd
);
1469 void ospf6_area_interface_delete(struct ospf6_interface
*oi
)
1471 struct ospf6_area
*oa
;
1472 struct listnode
*node
, *nnode
;
1473 struct ospf6
*ospf6
;
1475 for (ALL_LIST_ELEMENTS(om6
->ospf6
, node
, nnode
, ospf6
)) {
1476 for (ALL_LIST_ELEMENTS(ospf6
->area_list
, node
, nnode
, oa
))
1477 if (listnode_lookup(oa
->if_list
, oi
))
1478 listnode_delete(oa
->if_list
, oi
);