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_interface.h"
43 #include "ospf6_intra.h"
44 #include "ospf6_abr.h"
45 #include "ospf6_asbr.h"
46 #include "ospf6_zebra.h"
49 #include "ospf6_nssa.h"
50 #ifndef VTYSH_EXTRACT_PL
51 #include "ospf6d/ospf6_area_clippy.c"
54 DEFINE_MTYPE_STATIC(OSPF6D
, OSPF6_AREA
, "OSPF6 area");
55 DEFINE_MTYPE_STATIC(OSPF6D
, OSPF6_PLISTNAME
, "Prefix list name");
57 int str2area_id(const char *str
, uint32_t *area_id
, int *area_id_fmt
)
61 *area_id
= htonl(strtoul(str
, &ep
, 10));
62 if (*ep
&& inet_pton(AF_INET
, str
, area_id
) != 1)
66 !*ep
? OSPF6_AREA_FMT_DECIMAL
: OSPF6_AREA_FMT_DOTTEDQUAD
;
71 void area_id2str(char *buf
, int len
, uint32_t area_id
, int area_id_fmt
)
73 if (area_id_fmt
== OSPF6_AREA_FMT_DECIMAL
)
74 snprintf(buf
, len
, "%u", ntohl(area_id
));
76 inet_ntop(AF_INET
, &area_id
, buf
, len
);
79 int ospf6_area_cmp(void *va
, void *vb
)
81 struct ospf6_area
*oa
= (struct ospf6_area
*)va
;
82 struct ospf6_area
*ob
= (struct ospf6_area
*)vb
;
83 return (ntohl(oa
->area_id
) < ntohl(ob
->area_id
) ? -1 : 1);
86 /* schedule routing table recalculation */
87 static void ospf6_area_lsdb_hook_add(struct ospf6_lsa
*lsa
)
89 switch (ntohs(lsa
->header
->type
)) {
91 case OSPF6_LSTYPE_ROUTER
:
92 case OSPF6_LSTYPE_NETWORK
:
93 if (IS_OSPF6_DEBUG_EXAMIN_TYPE(lsa
->header
->type
)) {
94 zlog_debug("%s Examin LSA %s", __func__
, lsa
->name
);
95 zlog_debug(" Schedule SPF Calculation for %s",
96 OSPF6_AREA(lsa
->lsdb
->data
)->name
);
99 OSPF6_PROCESS(OSPF6_AREA(lsa
->lsdb
->data
)->ospf6
),
100 ospf6_lsadd_to_spf_reason(lsa
));
103 case OSPF6_LSTYPE_INTRA_PREFIX
:
104 ospf6_intra_prefix_lsa_add(lsa
);
107 case OSPF6_LSTYPE_INTER_PREFIX
:
108 case OSPF6_LSTYPE_INTER_ROUTER
:
109 ospf6_abr_examin_summary(lsa
,
110 (struct ospf6_area
*)lsa
->lsdb
->data
);
113 case OSPF6_LSTYPE_TYPE_7
:
114 ospf6_asbr_lsa_add(lsa
);
122 static void ospf6_area_lsdb_hook_remove(struct ospf6_lsa
*lsa
)
124 switch (ntohs(lsa
->header
->type
)) {
125 case OSPF6_LSTYPE_ROUTER
:
126 case OSPF6_LSTYPE_NETWORK
:
127 if (IS_OSPF6_DEBUG_EXAMIN_TYPE(lsa
->header
->type
)) {
128 zlog_debug("LSA disappearing: %s", lsa
->name
);
129 zlog_debug("Schedule SPF Calculation for %s",
130 OSPF6_AREA(lsa
->lsdb
->data
)->name
);
133 OSPF6_PROCESS(OSPF6_AREA(lsa
->lsdb
->data
)->ospf6
),
134 ospf6_lsremove_to_spf_reason(lsa
));
137 case OSPF6_LSTYPE_INTRA_PREFIX
:
138 ospf6_intra_prefix_lsa_remove(lsa
);
141 case OSPF6_LSTYPE_INTER_PREFIX
:
142 case OSPF6_LSTYPE_INTER_ROUTER
:
143 ospf6_abr_examin_summary(lsa
,
144 (struct ospf6_area
*)lsa
->lsdb
->data
);
146 case OSPF6_LSTYPE_TYPE_7
:
147 ospf6_asbr_lsa_remove(lsa
, NULL
);
154 static void ospf6_area_route_hook_add(struct ospf6_route
*route
)
156 struct ospf6_area
*oa
= route
->table
->scope
;
157 struct ospf6
*ospf6
= oa
->ospf6
;
158 struct ospf6_route
*copy
;
160 copy
= ospf6_route_copy(route
);
161 ospf6_route_add(copy
, ospf6
->route_table
);
164 static void ospf6_area_route_hook_remove(struct ospf6_route
*route
)
166 struct ospf6_area
*oa
= route
->table
->scope
;
167 struct ospf6
*ospf6
= oa
->ospf6
;
168 struct ospf6_route
*copy
;
170 copy
= ospf6_route_lookup_identical(route
, ospf6
->route_table
);
172 ospf6_route_remove(copy
, ospf6
->route_table
);
175 static void ospf6_area_stub_update(struct ospf6_area
*area
)
178 if (IS_AREA_STUB(area
)) {
179 if (IS_OSPF6_DEBUG_ORIGINATE(ROUTER
))
180 zlog_debug("Stubbing out area for area %s", area
->name
);
181 OSPF6_OPT_CLEAR(area
->options
, OSPF6_OPT_E
);
182 ospf6_asbr_remove_externals_from_area(area
);
183 } else if (IS_AREA_ENABLED(area
)) {
184 if (IS_OSPF6_DEBUG_ORIGINATE(ROUTER
))
185 zlog_debug("Normal area for area %s", area
->name
);
186 OSPF6_OPT_SET(area
->options
, OSPF6_OPT_E
);
187 ospf6_asbr_send_externals_to_area(area
);
190 OSPF6_ROUTER_LSA_SCHEDULE(area
);
193 static int ospf6_area_stub_set(struct ospf6
*ospf6
, struct ospf6_area
*area
)
195 if (!IS_AREA_STUB(area
)) {
196 /* Disable NSSA first. */
197 ospf6_area_nssa_unset(ospf6
, area
);
199 SET_FLAG(area
->flag
, OSPF6_AREA_STUB
);
200 ospf6_area_stub_update(area
);
206 void ospf6_area_stub_unset(struct ospf6
*ospf6
, struct ospf6_area
*area
)
208 if (IS_AREA_STUB(area
)) {
209 UNSET_FLAG(area
->flag
, OSPF6_AREA_STUB
);
210 ospf6_area_stub_update(area
);
214 static void ospf6_area_no_summary_set(struct ospf6
*ospf6
,
215 struct ospf6_area
*area
)
218 if (!area
->no_summary
) {
219 area
->no_summary
= 1;
220 ospf6_abr_range_reset_cost(ospf6
);
221 ospf6_abr_prefix_resummarize(ospf6
);
226 static void ospf6_area_no_summary_unset(struct ospf6
*ospf6
,
227 struct ospf6_area
*area
)
230 if (area
->no_summary
) {
231 area
->no_summary
= 0;
232 ospf6_abr_range_reset_cost(ospf6
);
233 ospf6_abr_prefix_resummarize(ospf6
);
238 static void ospf6_nssa_default_originate_set(struct ospf6
*ospf6
,
239 struct ospf6_area
*area
,
240 int metric
, int metric_type
)
242 if (!area
->nssa_default_originate
.enabled
) {
243 area
->nssa_default_originate
.enabled
= true;
244 if (++ospf6
->nssa_default_import_check
.refcnt
== 1) {
245 ospf6
->nssa_default_import_check
.status
= false;
246 ospf6_zebra_import_default_route(ospf6
, false);
250 area
->nssa_default_originate
.metric_value
= metric
;
251 area
->nssa_default_originate
.metric_type
= metric_type
;
254 static void ospf6_nssa_default_originate_unset(struct ospf6
*ospf6
,
255 struct ospf6_area
*area
)
257 if (area
->nssa_default_originate
.enabled
) {
258 area
->nssa_default_originate
.enabled
= false;
259 if (--ospf6
->nssa_default_import_check
.refcnt
== 0) {
260 ospf6
->nssa_default_import_check
.status
= false;
261 ospf6_zebra_import_default_route(ospf6
, true);
263 area
->nssa_default_originate
.metric_value
= -1;
264 area
->nssa_default_originate
.metric_type
= -1;
269 * Make new area structure.
271 * @param area_id - ospf6 area ID
272 * @param o - ospf6 instance
273 * @param df - display format for area ID
275 struct ospf6_area
*ospf6_area_create(uint32_t area_id
, struct ospf6
*o
, int df
)
277 struct ospf6_area
*oa
;
279 oa
= XCALLOC(MTYPE_OSPF6_AREA
, sizeof(struct ospf6_area
));
282 case OSPF6_AREA_FMT_DECIMAL
:
283 snprintf(oa
->name
, sizeof(oa
->name
), "%u", ntohl(area_id
));
286 case OSPF6_AREA_FMT_DOTTEDQUAD
:
287 inet_ntop(AF_INET
, &area_id
, oa
->name
, sizeof(oa
->name
));
291 oa
->area_id
= area_id
;
292 oa
->if_list
= list_new();
294 oa
->lsdb
= ospf6_lsdb_create(oa
);
295 oa
->lsdb
->hook_add
= ospf6_area_lsdb_hook_add
;
296 oa
->lsdb
->hook_remove
= ospf6_area_lsdb_hook_remove
;
297 oa
->lsdb_self
= ospf6_lsdb_create(oa
);
298 oa
->temp_router_lsa_lsdb
= ospf6_lsdb_create(oa
);
300 oa
->spf_table
= OSPF6_ROUTE_TABLE_CREATE(AREA
, SPF_RESULTS
);
301 oa
->spf_table
->scope
= oa
;
302 oa
->route_table
= OSPF6_ROUTE_TABLE_CREATE(AREA
, ROUTES
);
303 oa
->route_table
->scope
= oa
;
304 oa
->route_table
->hook_add
= ospf6_area_route_hook_add
;
305 oa
->route_table
->hook_remove
= ospf6_area_route_hook_remove
;
307 oa
->range_table
= OSPF6_ROUTE_TABLE_CREATE(AREA
, PREFIX_RANGES
);
308 oa
->range_table
->scope
= oa
;
309 oa
->nssa_range_table
= OSPF6_ROUTE_TABLE_CREATE(AREA
, PREFIX_RANGES
);
310 oa
->nssa_range_table
->scope
= oa
;
311 oa
->summary_prefix
= OSPF6_ROUTE_TABLE_CREATE(AREA
, SUMMARY_PREFIXES
);
312 oa
->summary_prefix
->scope
= oa
;
313 oa
->summary_router
= OSPF6_ROUTE_TABLE_CREATE(AREA
, SUMMARY_ROUTERS
);
314 oa
->summary_router
->scope
= oa
;
315 oa
->router_lsa_size_limit
= 1024 + 256;
317 /* set default options */
318 if (CHECK_FLAG(o
->flag
, OSPF6_STUB_ROUTER
)) {
319 OSPF6_OPT_CLEAR(oa
->options
, OSPF6_OPT_V6
);
320 OSPF6_OPT_CLEAR(oa
->options
, OSPF6_OPT_R
);
322 OSPF6_OPT_SET(oa
->options
, OSPF6_OPT_V6
);
323 OSPF6_OPT_SET(oa
->options
, OSPF6_OPT_R
);
326 OSPF6_OPT_SET(oa
->options
, OSPF6_OPT_E
);
328 SET_FLAG(oa
->flag
, OSPF6_AREA_ACTIVE
);
329 SET_FLAG(oa
->flag
, OSPF6_AREA_ENABLE
);
332 listnode_add_sort(o
->area_list
, oa
);
334 if (area_id
== OSPF_AREA_BACKBONE
) {
341 void ospf6_area_delete(struct ospf6_area
*oa
)
344 struct ospf6_interface
*oi
;
346 /* The ospf6_interface structs store configuration
347 * information which should not be lost/reset when
349 * So just detach the interface from the area and
351 for (ALL_LIST_ELEMENTS_RO(oa
->if_list
, n
, oi
))
354 list_delete(&oa
->if_list
);
356 ospf6_lsdb_delete(oa
->lsdb
);
357 ospf6_lsdb_delete(oa
->lsdb_self
);
358 ospf6_lsdb_delete(oa
->temp_router_lsa_lsdb
);
360 ospf6_spf_table_finish(oa
->spf_table
);
361 ospf6_route_table_delete(oa
->spf_table
);
362 ospf6_route_table_delete(oa
->route_table
);
364 ospf6_route_table_delete(oa
->range_table
);
365 ospf6_route_table_delete(oa
->nssa_range_table
);
366 ospf6_route_table_delete(oa
->summary_prefix
);
367 ospf6_route_table_delete(oa
->summary_router
);
369 listnode_delete(oa
->ospf6
->area_list
, oa
);
373 XFREE(MTYPE_OSPF6_AREA
, oa
);
376 struct ospf6_area
*ospf6_area_lookup_by_area_id(uint32_t area_id
)
378 struct ospf6_area
*oa
;
379 struct listnode
*n
, *node
, *nnode
;
382 for (ALL_LIST_ELEMENTS(om6
->ospf6
, node
, nnode
, ospf6
)) {
383 for (ALL_LIST_ELEMENTS_RO(ospf6
->area_list
, n
, oa
))
384 if (oa
->area_id
== area_id
)
387 return (struct ospf6_area
*)NULL
;
390 struct ospf6_area
*ospf6_area_lookup(uint32_t area_id
, struct ospf6
*ospf6
)
392 struct ospf6_area
*oa
;
395 for (ALL_LIST_ELEMENTS_RO(ospf6
->area_list
, n
, oa
))
396 if (oa
->area_id
== area_id
)
399 return (struct ospf6_area
*)NULL
;
402 void ospf6_area_enable(struct ospf6_area
*oa
)
404 struct listnode
*node
, *nnode
;
405 struct ospf6_interface
*oi
;
407 SET_FLAG(oa
->flag
, OSPF6_AREA_ENABLE
);
409 for (ALL_LIST_ELEMENTS(oa
->if_list
, node
, nnode
, oi
))
410 ospf6_interface_enable(oi
);
411 ospf6_abr_enable_area(oa
);
414 void ospf6_area_disable(struct ospf6_area
*oa
)
416 struct listnode
*node
, *nnode
;
417 struct ospf6_interface
*oi
;
419 UNSET_FLAG(oa
->flag
, OSPF6_AREA_ENABLE
);
421 for (ALL_LIST_ELEMENTS(oa
->if_list
, node
, nnode
, oi
))
422 ospf6_interface_disable(oi
);
424 ospf6_abr_disable_area(oa
);
425 ospf6_lsdb_remove_all(oa
->lsdb
);
426 ospf6_lsdb_remove_all(oa
->lsdb_self
);
428 ospf6_spf_table_finish(oa
->spf_table
);
429 ospf6_route_remove_all(oa
->route_table
);
431 THREAD_OFF(oa
->thread_router_lsa
);
432 THREAD_OFF(oa
->thread_intra_prefix_lsa
);
436 void ospf6_area_show(struct vty
*vty
, struct ospf6_area
*oa
,
437 json_object
*json_areas
, bool use_json
)
440 struct ospf6_interface
*oi
;
441 unsigned long result
;
442 json_object
*json_area
;
443 json_object
*array_interfaces
;
446 json_area
= json_object_new_object();
447 json_object_boolean_add(json_area
, "areaIsStub",
449 json_object_boolean_add(json_area
, "areaIsNSSA",
451 if (IS_AREA_STUB(oa
) || IS_AREA_NSSA(oa
)) {
452 json_object_boolean_add(json_area
, "areaNoSummary",
456 json_object_int_add(json_area
, "numberOfAreaScopedLsa",
458 json_object_object_add(
459 json_area
, "lsaStatistics",
460 JSON_OBJECT_NEW_ARRAY(json_object_new_int
,
464 /* Interfaces Attached */
465 array_interfaces
= json_object_new_array();
466 for (ALL_LIST_ELEMENTS_RO(oa
->if_list
, i
, oi
))
467 json_object_array_add(
469 json_object_new_string(oi
->interface
->name
));
471 json_object_object_add(json_area
, "interfacesAttachedToArea",
474 if (oa
->ts_spf
.tv_sec
|| oa
->ts_spf
.tv_usec
) {
475 json_object_boolean_true_add(json_area
, "spfHasRun");
476 result
= monotime_since(&oa
->ts_spf
, NULL
);
477 if (result
/ TIMER_SECOND_MICRO
> 0) {
479 json_area
, "spfLastExecutedSecs",
480 result
/ TIMER_SECOND_MICRO
);
483 json_area
, "spfLastExecutedMicroSecs",
484 result
% TIMER_SECOND_MICRO
);
486 json_object_int_add(json_area
,
487 "spfLastExecutedSecs", 0);
488 json_object_int_add(json_area
,
489 "spfLastExecutedMicroSecs",
493 json_object_boolean_false_add(json_area
, "spfHasRun");
496 json_object_object_add(json_areas
, oa
->name
, json_area
);
500 if (!IS_AREA_STUB(oa
) && !IS_AREA_NSSA(oa
))
501 vty_out(vty
, " Area %s\n", oa
->name
);
503 if (oa
->no_summary
) {
504 vty_out(vty
, " Area %s[%s, No Summary]\n",
506 IS_AREA_STUB(oa
) ? "Stub" : "NSSA");
508 vty_out(vty
, " Area %s[%s]\n", oa
->name
,
509 IS_AREA_STUB(oa
) ? "Stub" : "NSSA");
512 vty_out(vty
, " Number of Area scoped LSAs is %u\n",
515 vty_out(vty
, " Interface attached to this area:");
516 for (ALL_LIST_ELEMENTS_RO(oa
->if_list
, i
, oi
))
517 vty_out(vty
, " %s", oi
->interface
->name
);
520 if (oa
->ts_spf
.tv_sec
|| oa
->ts_spf
.tv_usec
) {
521 result
= monotime_since(&oa
->ts_spf
, NULL
);
522 if (result
/ TIMER_SECOND_MICRO
> 0) {
524 " SPF last executed %ld.%lds ago\n",
525 result
/ TIMER_SECOND_MICRO
,
526 result
% TIMER_SECOND_MICRO
);
529 " SPF last executed %ldus ago\n",
533 vty_out(vty
, "SPF has not been run\n");
539 "area <A.B.C.D|(0-4294967295)> range X:X::X:X/M [<advertise|not-advertise|cost (0-16777215)>]",
540 "OSPF6 area parameters\n"
541 "OSPF6 area ID in IP address format\n"
542 "OSPF6 area ID as a decimal value\n"
543 "Configured address range\n"
544 "Specify IPv6 prefix\n"
547 "User specified metric for this range\n"
548 "Advertised metric for this range\n")
551 int idx_ipv6_prefixlen
= 3;
554 struct ospf6_area
*oa
;
555 struct prefix prefix
;
556 struct ospf6_route
*range
;
559 VTY_DECLVAR_CONTEXT(ospf6
, ospf6
);
561 OSPF6_CMD_AREA_GET(argv
[idx_ipv4
]->arg
, oa
, ospf6
);
563 ret
= str2prefix(argv
[idx_ipv6_prefixlen
]->arg
, &prefix
);
564 if (ret
!= 1 || prefix
.family
!= AF_INET6
) {
565 vty_out(vty
, "Malformed argument: %s\n",
566 argv
[idx_ipv6_prefixlen
]->arg
);
570 range
= ospf6_route_lookup(&prefix
, oa
->range_table
);
572 range
= ospf6_route_create(ospf6
);
573 range
->type
= OSPF6_DEST_TYPE_RANGE
;
574 range
->prefix
= prefix
;
575 range
->path
.area_id
= oa
->area_id
;
576 range
->path
.cost
= OSPF_AREA_RANGE_COST_UNSPEC
;
579 /* default settings */
580 cost
= OSPF_AREA_RANGE_COST_UNSPEC
;
581 UNSET_FLAG(range
->flag
, OSPF6_ROUTE_DO_NOT_ADVERTISE
);
583 if (argc
> idx_type
) {
584 if (strmatch(argv
[idx_type
]->text
, "not-advertise"))
585 SET_FLAG(range
->flag
, OSPF6_ROUTE_DO_NOT_ADVERTISE
);
586 else if (strmatch(argv
[idx_type
]->text
, "cost"))
587 cost
= strtoul(argv
[5]->arg
, NULL
, 10);
590 range
->path
.u
.cost_config
= cost
;
592 if (range
->rnode
== NULL
) {
593 ospf6_route_add(range
, oa
->range_table
);
596 if (ospf6_check_and_set_router_abr(ospf6
)) {
597 /* Redo summaries if required */
598 ospf6_abr_prefix_resummarize(ospf6
);
604 DEFUN (no_area_range
,
606 "no area <A.B.C.D|(0-4294967295)> range X:X::X:X/M [<advertise|not-advertise|cost (0-16777215)>]",
608 "OSPF6 area parameters\n"
609 "OSPF6 area ID in IP address format\n"
610 "OSPF6 area ID as a decimal value\n"
611 "Configured address range\n"
612 "Specify IPv6 prefix\n"
615 "User specified metric for this range\n"
616 "Advertised metric for this range\n")
621 struct ospf6_area
*oa
;
622 struct prefix prefix
;
623 struct ospf6_route
*range
, *route
;
625 VTY_DECLVAR_CONTEXT(ospf6
, ospf6
);
627 OSPF6_CMD_AREA_GET(argv
[idx_ipv4
]->arg
, oa
, ospf6
);
629 ret
= str2prefix(argv
[idx_ipv6
]->arg
, &prefix
);
630 if (ret
!= 1 || prefix
.family
!= AF_INET6
) {
631 vty_out(vty
, "Malformed argument: %s\n", argv
[idx_ipv6
]->arg
);
635 range
= ospf6_route_lookup(&prefix
, oa
->range_table
);
637 vty_out(vty
, "Range %s does not exists.\n",
638 argv
[idx_ipv6
]->arg
);
642 if (ospf6_check_and_set_router_abr(oa
->ospf6
)) {
643 /* Blow away the aggregated LSA and route */
644 SET_FLAG(range
->flag
, OSPF6_ROUTE_REMOVE
);
646 /* Redo summaries if required */
647 for (route
= ospf6_route_head(oa
->ospf6
->route_table
); route
;
648 route
= ospf6_route_next(route
))
649 ospf6_abr_originate_summary(route
, oa
->ospf6
);
651 /* purge the old aggregated summary LSA */
652 ospf6_abr_originate_summary(range
, oa
->ospf6
);
654 ospf6_route_remove(range
, oa
->range_table
);
659 void ospf6_area_config_write(struct vty
*vty
, struct ospf6
*ospf6
)
661 struct listnode
*node
;
662 struct ospf6_area
*oa
;
663 struct ospf6_route
*range
;
665 for (ALL_LIST_ELEMENTS_RO(ospf6
->area_list
, node
, oa
)) {
666 for (range
= ospf6_route_head(oa
->range_table
); range
;
667 range
= ospf6_route_next(range
)) {
668 vty_out(vty
, " area %s range %pFX", oa
->name
,
671 if (CHECK_FLAG(range
->flag
,
672 OSPF6_ROUTE_DO_NOT_ADVERTISE
)) {
673 vty_out(vty
, " not-advertise");
675 // "advertise" is the default so we do not
677 if (range
->path
.u
.cost_config
678 != OSPF_AREA_RANGE_COST_UNSPEC
)
679 vty_out(vty
, " cost %d",
680 range
->path
.u
.cost_config
);
684 if (IS_AREA_STUB(oa
)) {
686 vty_out(vty
, " area %s stub no-summary\n",
689 vty_out(vty
, " area %s stub\n", oa
->name
);
691 if (IS_AREA_NSSA(oa
)) {
692 vty_out(vty
, " area %s nssa", oa
->name
);
693 if (oa
->nssa_default_originate
.enabled
) {
694 vty_out(vty
, " default-information-originate");
695 if (oa
->nssa_default_originate
.metric_value
697 vty_out(vty
, " metric %d",
698 oa
->nssa_default_originate
700 if (oa
->nssa_default_originate
.metric_type
701 != DEFAULT_METRIC_TYPE
)
702 vty_out(vty
, " metric-type 1");
705 vty_out(vty
, " no-summary");
708 for (range
= ospf6_route_head(oa
->nssa_range_table
); range
;
709 range
= ospf6_route_next(range
)) {
710 vty_out(vty
, " area %s nssa range %pFX", oa
->name
,
713 if (CHECK_FLAG(range
->flag
,
714 OSPF6_ROUTE_DO_NOT_ADVERTISE
)) {
715 vty_out(vty
, " not-advertise");
717 if (range
->path
.u
.cost_config
718 != OSPF_AREA_RANGE_COST_UNSPEC
)
719 vty_out(vty
, " cost %u",
720 range
->path
.u
.cost_config
);
724 if (PREFIX_NAME_IN(oa
))
725 vty_out(vty
, " area %s filter-list prefix %s in\n",
726 oa
->name
, PREFIX_NAME_IN(oa
));
727 if (PREFIX_NAME_OUT(oa
))
728 vty_out(vty
, " area %s filter-list prefix %s out\n",
729 oa
->name
, PREFIX_NAME_OUT(oa
));
731 vty_out(vty
, " area %s import-list %s\n", oa
->name
,
734 vty_out(vty
, " area %s export-list %s\n", oa
->name
,
739 DEFUN (area_filter_list
,
740 area_filter_list_cmd
,
741 "area <A.B.C.D|(0-4294967295)> filter-list prefix PREFIXLIST_NAME <in|out>",
742 "OSPF6 area parameters\n"
743 "OSPF6 area ID in IP address format\n"
744 "OSPF6 area ID as a decimal value\n"
745 "Filter networks between OSPF6 areas\n"
746 "Filter prefixes between OSPF6 areas\n"
747 "Name of an IPv6 prefix-list\n"
748 "Filter networks sent to this area\n"
749 "Filter networks sent from this area\n")
751 char *inout
= argv
[argc
- 1]->text
;
752 char *areaid
= argv
[1]->arg
;
753 char *plistname
= argv
[4]->arg
;
755 struct ospf6_area
*area
;
756 struct prefix_list
*plist
;
758 VTY_DECLVAR_CONTEXT(ospf6
, ospf6
);
760 OSPF6_CMD_AREA_GET(areaid
, area
, ospf6
);
762 plist
= prefix_list_lookup(AFI_IP6
, plistname
);
763 if (strmatch(inout
, "in")) {
764 PREFIX_LIST_IN(area
) = plist
;
765 XFREE(MTYPE_OSPF6_PLISTNAME
, PREFIX_NAME_IN(area
));
766 PREFIX_NAME_IN(area
) =
767 XSTRDUP(MTYPE_OSPF6_PLISTNAME
, plistname
);
769 PREFIX_LIST_OUT(area
) = plist
;
770 XFREE(MTYPE_OSPF6_PLISTNAME
, PREFIX_NAME_OUT(area
));
771 PREFIX_NAME_OUT(area
) =
772 XSTRDUP(MTYPE_OSPF6_PLISTNAME
, plistname
);
775 /* Redo summaries if required */
776 if (ospf6_check_and_set_router_abr(area
->ospf6
))
777 ospf6_schedule_abr_task(ospf6
);
782 DEFUN (no_area_filter_list
,
783 no_area_filter_list_cmd
,
784 "no area <A.B.C.D|(0-4294967295)> filter-list prefix PREFIXLIST_NAME <in|out>",
786 "OSPF6 area parameters\n"
787 "OSPF6 area ID in IP address format\n"
788 "OSPF6 area ID as a decimal value\n"
789 "Filter networks between OSPF6 areas\n"
790 "Filter prefixes between OSPF6 areas\n"
791 "Name of an IPv6 prefix-list\n"
792 "Filter networks sent to this area\n"
793 "Filter networks sent from this area\n")
795 char *inout
= argv
[argc
- 1]->text
;
796 char *areaid
= argv
[2]->arg
;
797 char *plistname
= argv
[5]->arg
;
799 struct ospf6_area
*area
;
801 VTY_DECLVAR_CONTEXT(ospf6
, ospf6
);
802 OSPF6_CMD_AREA_GET(areaid
, area
, ospf6
);
804 if (strmatch(inout
, "in")) {
805 if (PREFIX_NAME_IN(area
))
806 if (!strmatch(PREFIX_NAME_IN(area
), plistname
))
809 PREFIX_LIST_IN(area
) = NULL
;
810 XFREE(MTYPE_OSPF6_PLISTNAME
, PREFIX_NAME_IN(area
));
812 if (PREFIX_NAME_OUT(area
))
813 if (!strmatch(PREFIX_NAME_OUT(area
), plistname
))
816 XFREE(MTYPE_OSPF6_PLISTNAME
, PREFIX_NAME_OUT(area
));
817 PREFIX_LIST_OUT(area
) = NULL
;
820 /* Redo summaries if required */
821 if (ospf6_check_and_set_router_abr(area
->ospf6
))
822 ospf6_schedule_abr_task(ospf6
);
827 void ospf6_filter_update(struct access_list
*access
)
829 struct ospf6_area
*oa
;
830 struct listnode
*n
, *node
, *nnode
;
833 for (ALL_LIST_ELEMENTS(om6
->ospf6
, node
, nnode
, ospf6
)) {
836 for (ALL_LIST_ELEMENTS_RO(ospf6
->area_list
, n
, oa
)) {
838 && strcmp(IMPORT_NAME(oa
), access
->name
) == 0) {
839 IMPORT_LIST(oa
) = access_list_lookup(
840 AFI_IP6
, IMPORT_NAME(oa
));
845 && strcmp(EXPORT_NAME(oa
), access
->name
) == 0) {
846 EXPORT_LIST(oa
) = access_list_lookup(
847 AFI_IP6
, EXPORT_NAME(oa
));
852 if (update
&& ospf6_check_and_set_router_abr(ospf6
))
853 ospf6_schedule_abr_task(ospf6
);
857 void ospf6_plist_update(struct prefix_list
*plist
)
859 struct listnode
*node
, *nnode
;
860 struct ospf6_area
*oa
;
862 const char *name
= prefix_list_name(plist
);
863 struct ospf6
*ospf6
= NULL
;
865 if (prefix_list_afi(plist
) != AFI_IP6
)
868 for (ALL_LIST_ELEMENTS(om6
->ospf6
, node
, nnode
, ospf6
)) {
871 for (ALL_LIST_ELEMENTS_RO(ospf6
->area_list
, n
, oa
)) {
872 if (PREFIX_NAME_IN(oa
)
873 && !strcmp(PREFIX_NAME_IN(oa
), name
)) {
874 PREFIX_LIST_IN(oa
) = prefix_list_lookup(
875 AFI_IP6
, PREFIX_NAME_IN(oa
));
878 if (PREFIX_NAME_OUT(oa
)
879 && !strcmp(PREFIX_NAME_OUT(oa
), name
)) {
880 PREFIX_LIST_OUT(oa
) = prefix_list_lookup(
881 AFI_IP6
, PREFIX_NAME_OUT(oa
));
886 if (update
&& ospf6_check_and_set_router_abr(ospf6
))
887 ospf6_schedule_abr_task(ospf6
);
891 DEFUN (area_import_list
,
892 area_import_list_cmd
,
893 "area <A.B.C.D|(0-4294967295)> import-list ACCESSLIST6_NAME",
894 "OSPF6 area parameters\n"
895 "OSPF6 area ID in IP address format\n"
896 "OSPF6 area ID as a decimal value\n"
897 "Set the filter for networks from other areas announced to the specified one\n"
898 "Name of the access-list\n")
902 struct ospf6_area
*area
;
903 struct access_list
*list
;
905 VTY_DECLVAR_CONTEXT(ospf6
, ospf6
);
907 OSPF6_CMD_AREA_GET(argv
[idx_ipv4
]->arg
, area
, ospf6
);
909 list
= access_list_lookup(AFI_IP6
, argv
[idx_name
]->arg
);
911 IMPORT_LIST(area
) = list
;
913 if (IMPORT_NAME(area
))
914 free(IMPORT_NAME(area
));
916 IMPORT_NAME(area
) = strdup(argv
[idx_name
]->arg
);
917 if (ospf6_check_and_set_router_abr(area
->ospf6
))
918 ospf6_schedule_abr_task(ospf6
);
923 DEFUN (no_area_import_list
,
924 no_area_import_list_cmd
,
925 "no area <A.B.C.D|(0-4294967295)> import-list ACCESSLIST6_NAME",
927 "OSPF6 area parameters\n"
928 "OSPF6 area ID in IP address format\n"
929 "OSPF6 area ID as a decimal value\n"
930 "Unset the filter for networks announced to other areas\n"
931 "Name of the access-list\n")
934 struct ospf6_area
*area
;
936 VTY_DECLVAR_CONTEXT(ospf6
, ospf6
);
938 OSPF6_CMD_AREA_GET(argv
[idx_ipv4
]->arg
, area
, ospf6
);
940 IMPORT_LIST(area
) = NULL
;
942 if (IMPORT_NAME(area
))
943 free(IMPORT_NAME(area
));
945 IMPORT_NAME(area
) = NULL
;
946 if (ospf6_check_and_set_router_abr(area
->ospf6
))
947 ospf6_schedule_abr_task(ospf6
);
952 DEFUN (area_export_list
,
953 area_export_list_cmd
,
954 "area <A.B.C.D|(0-4294967295)> export-list ACCESSLIST6_NAME",
955 "OSPF6 area parameters\n"
956 "OSPF6 area ID in IP address format\n"
957 "OSPF6 area ID as a decimal value\n"
958 "Set the filter for networks announced to other areas\n"
959 "Name of the access-list\n")
963 struct ospf6_area
*area
;
964 struct access_list
*list
;
966 VTY_DECLVAR_CONTEXT(ospf6
, ospf6
);
968 OSPF6_CMD_AREA_GET(argv
[idx_ipv4
]->arg
, area
, ospf6
);
970 list
= access_list_lookup(AFI_IP6
, argv
[idx_name
]->arg
);
972 EXPORT_LIST(area
) = list
;
974 if (EXPORT_NAME(area
))
975 free(EXPORT_NAME(area
));
977 EXPORT_NAME(area
) = strdup(argv
[idx_name
]->arg
);
979 /* Redo summaries if required */
980 if (ospf6_check_and_set_router_abr(area
->ospf6
))
981 ospf6_schedule_abr_task(ospf6
);
986 DEFUN (no_area_export_list
,
987 no_area_export_list_cmd
,
988 "no area <A.B.C.D|(0-4294967295)> export-list ACCESSLIST6_NAME",
990 "OSPF6 area parameters\n"
991 "OSPF6 area ID in IP address format\n"
992 "OSPF6 area ID as a decimal value\n"
993 "Unset the filter for networks announced to other areas\n"
994 "Name of the access-list\n")
997 struct ospf6_area
*area
;
999 VTY_DECLVAR_CONTEXT(ospf6
, ospf6
);
1001 OSPF6_CMD_AREA_GET(argv
[idx_ipv4
]->arg
, area
, ospf6
);
1003 EXPORT_LIST(area
) = NULL
;
1005 if (EXPORT_NAME(area
))
1006 free(EXPORT_NAME(area
));
1008 EXPORT_NAME(area
) = NULL
;
1009 if (ospf6_check_and_set_router_abr(area
->ospf6
))
1010 ospf6_schedule_abr_task(ospf6
);
1015 static int ipv6_ospf6_spf_tree_common(struct vty
*vty
, struct ospf6
*ospf6
,
1018 struct listnode
*node
;
1019 struct ospf6_area
*oa
;
1020 struct prefix prefix
;
1021 struct ospf6_vertex
*root
;
1022 struct ospf6_route
*route
;
1023 json_object
*json
= NULL
;
1024 json_object
*json_area
= NULL
;
1025 json_object
*json_head
= NULL
;
1028 json
= json_object_new_object();
1029 ospf6_linkstate_prefix(ospf6
->router_id
, htonl(0), &prefix
);
1030 for (ALL_LIST_ELEMENTS_RO(ospf6
->area_list
, node
, oa
)) {
1032 json_area
= json_object_new_object();
1033 json_head
= json_object_new_object();
1035 route
= ospf6_route_lookup(&prefix
, oa
->spf_table
);
1036 if (route
== NULL
) {
1038 json_object_string_add(
1040 "LS entry for not not found");
1041 json_object_free(json_head
);
1042 json_object_free(json_area
);
1045 "LS entry for root not found in area %s\n",
1049 root
= (struct ospf6_vertex
*)route
->route_option
;
1050 ospf6_spf_display_subtree(vty
, "", 0, root
, json_head
, uj
);
1053 json_object_object_add(json_area
, root
->name
,
1055 json_object_object_add(json
, oa
->name
, json_area
);
1060 vty_json(vty
, json
);
1065 DEFUN(show_ipv6_ospf6_spf_tree
, show_ipv6_ospf6_spf_tree_cmd
,
1066 "show ipv6 ospf6 [vrf <NAME|all>] spf tree [json]",
1067 SHOW_STR IP6_STR OSPF6_STR VRF_CMD_HELP_STR
1069 "Shortest Path First calculation\n"
1070 "Show SPF tree\n" JSON_STR
)
1072 struct listnode
*node
;
1073 struct ospf6
*ospf6
;
1074 const char *vrf_name
= NULL
;
1075 bool all_vrf
= false;
1077 bool uj
= use_json(argc
, argv
);
1079 OSPF6_FIND_VRF_ARGS(argv
, argc
, idx_vrf
, vrf_name
, all_vrf
);
1081 for (ALL_LIST_ELEMENTS_RO(om6
->ospf6
, node
, ospf6
)) {
1082 if (all_vrf
|| strcmp(ospf6
->name
, vrf_name
) == 0) {
1083 ipv6_ospf6_spf_tree_common(vty
, ospf6
, uj
);
1089 OSPF6_CMD_CHECK_VRF(uj
, all_vrf
, ospf6
);
1094 static int show_ospf6_area_spf_tree_common(struct vty
*vty
,
1095 struct cmd_token
**argv
,
1096 struct ospf6
*ospf6
,
1097 uint32_t area_id
, int idx_ipv4
)
1100 struct ospf6_area
*oa
;
1101 struct prefix prefix
;
1102 struct ospf6_vertex
*root
;
1103 struct ospf6_route
*route
;
1105 ospf6_linkstate_prefix(ospf6
->router_id
, htonl(0), &prefix
);
1107 oa
= ospf6_area_lookup(area_id
, ospf6
);
1109 vty_out(vty
, "No such Area: %s\n", argv
[idx_ipv4
]->arg
);
1113 route
= ospf6_route_lookup(&prefix
, oa
->spf_table
);
1114 if (route
== NULL
) {
1115 vty_out(vty
, "LS entry for root not found in area %s\n",
1119 root
= (struct ospf6_vertex
*)route
->route_option
;
1120 ospf6_spf_display_subtree(vty
, "", 0, root
, NULL
, false);
1125 DEFUN(show_ipv6_ospf6_area_spf_tree
, show_ipv6_ospf6_area_spf_tree_cmd
,
1126 "show ipv6 ospf6 [vrf <NAME|all>] area A.B.C.D spf tree",
1127 SHOW_STR IP6_STR OSPF6_STR VRF_CMD_HELP_STR
1128 "All VRFs\n" OSPF6_AREA_STR OSPF6_AREA_ID_STR
1129 "Shortest Path First calculation\n"
1134 struct ospf6
*ospf6
;
1135 struct listnode
*node
;
1136 const char *vrf_name
= NULL
;
1137 bool all_vrf
= false;
1140 OSPF6_FIND_VRF_ARGS(argv
, argc
, idx_vrf
, vrf_name
, all_vrf
);
1144 if (inet_pton(AF_INET
, argv
[idx_ipv4
]->arg
, &area_id
) != 1) {
1145 vty_out(vty
, "Malformed Area-ID: %s\n", argv
[idx_ipv4
]->arg
);
1149 for (ALL_LIST_ELEMENTS_RO(om6
->ospf6
, node
, ospf6
)) {
1150 if (all_vrf
|| strcmp(ospf6
->name
, vrf_name
) == 0) {
1151 show_ospf6_area_spf_tree_common(vty
, argv
, ospf6
,
1158 OSPF6_CMD_CHECK_VRF(false, all_vrf
, ospf6
);
1164 show_ospf6_simulate_spf_tree_commen(struct vty
*vty
, struct cmd_token
**argv
,
1165 struct ospf6
*ospf6
, uint32_t router_id
,
1166 uint32_t area_id
, struct prefix prefix
,
1167 int idx_ipv4
, int idx_ipv4_2
)
1169 struct ospf6_area
*oa
;
1170 struct ospf6_vertex
*root
;
1171 struct ospf6_route
*route
;
1172 struct ospf6_route_table
*spf_table
;
1173 unsigned char tmp_debug_ospf6_spf
= 0;
1175 oa
= ospf6_area_lookup(area_id
, ospf6
);
1177 vty_out(vty
, "No such Area: %s\n", argv
[idx_ipv4_2
]->arg
);
1181 tmp_debug_ospf6_spf
= conf_debug_ospf6_spf
;
1182 conf_debug_ospf6_spf
= 0;
1184 spf_table
= OSPF6_ROUTE_TABLE_CREATE(NONE
, SPF_RESULTS
);
1185 ospf6_spf_calculation(router_id
, spf_table
, oa
);
1187 conf_debug_ospf6_spf
= tmp_debug_ospf6_spf
;
1189 route
= ospf6_route_lookup(&prefix
, spf_table
);
1190 if (route
== NULL
) {
1191 ospf6_spf_table_finish(spf_table
);
1192 ospf6_route_table_delete(spf_table
);
1195 root
= (struct ospf6_vertex
*)route
->route_option
;
1196 ospf6_spf_display_subtree(vty
, "", 0, root
, NULL
, false);
1198 ospf6_spf_table_finish(spf_table
);
1199 ospf6_route_table_delete(spf_table
);
1204 DEFUN(show_ipv6_ospf6_simulate_spf_tree_root
,
1205 show_ipv6_ospf6_simulate_spf_tree_root_cmd
,
1206 "show ipv6 ospf6 [vrf <NAME|all>] simulate spf-tree A.B.C.D area A.B.C.D",
1207 SHOW_STR IP6_STR OSPF6_STR VRF_CMD_HELP_STR
1209 "Shortest Path First calculation\n"
1211 "Specify root's router-id to calculate another router's SPF tree\n"
1212 "OSPF6 area parameters\n" OSPF6_AREA_ID_STR
)
1217 struct prefix prefix
;
1219 struct ospf6
*ospf6
;
1220 struct listnode
*node
;
1221 const char *vrf_name
= NULL
;
1222 bool all_vrf
= false;
1225 OSPF6_FIND_VRF_ARGS(argv
, argc
, idx_vrf
, vrf_name
, all_vrf
);
1230 inet_pton(AF_INET
, argv
[idx_ipv4
]->arg
, &router_id
);
1231 ospf6_linkstate_prefix(router_id
, htonl(0), &prefix
);
1233 if (inet_pton(AF_INET
, argv
[idx_ipv4_2
]->arg
, &area_id
) != 1) {
1234 vty_out(vty
, "Malformed Area-ID: %s\n", argv
[idx_ipv4_2
]->arg
);
1238 for (ALL_LIST_ELEMENTS_RO(om6
->ospf6
, node
, ospf6
)) {
1239 if (all_vrf
|| strcmp(ospf6
->name
, vrf_name
) == 0) {
1240 show_ospf6_simulate_spf_tree_commen(
1241 vty
, argv
, ospf6
, router_id
, area_id
, prefix
,
1242 idx_ipv4
, idx_ipv4_2
);
1248 OSPF6_CMD_CHECK_VRF(false, all_vrf
, ospf6
);
1253 DEFUN (ospf6_area_stub
,
1254 ospf6_area_stub_cmd
,
1255 "area <A.B.C.D|(0-4294967295)> stub",
1256 "OSPF6 area parameters\n"
1257 "OSPF6 area ID in IP address format\n"
1258 "OSPF6 area ID as a decimal value\n"
1259 "Configure OSPF6 area as stub\n")
1261 int idx_ipv4_number
= 1;
1262 struct ospf6_area
*area
;
1264 VTY_DECLVAR_CONTEXT(ospf6
, ospf6
);
1266 OSPF6_CMD_AREA_GET(argv
[idx_ipv4_number
]->arg
, area
, ospf6
);
1268 if (!ospf6_area_stub_set(ospf6
, area
)) {
1270 "First deconfigure all virtual link through this area\n");
1271 return CMD_WARNING_CONFIG_FAILED
;
1274 ospf6_area_no_summary_unset(ospf6
, area
);
1279 DEFUN (ospf6_area_stub_no_summary
,
1280 ospf6_area_stub_no_summary_cmd
,
1281 "area <A.B.C.D|(0-4294967295)> stub no-summary",
1282 "OSPF6 stub parameters\n"
1283 "OSPF6 area ID in IP address format\n"
1284 "OSPF6 area ID as a decimal value\n"
1285 "Configure OSPF6 area as stub\n"
1286 "Do not inject inter-area routes into stub\n")
1288 int idx_ipv4_number
= 1;
1289 struct ospf6_area
*area
;
1291 VTY_DECLVAR_CONTEXT(ospf6
, ospf6
);
1293 OSPF6_CMD_AREA_GET(argv
[idx_ipv4_number
]->arg
, area
, ospf6
);
1295 if (!ospf6_area_stub_set(ospf6
, area
)) {
1297 "First deconfigure all virtual link through this area\n");
1298 return CMD_WARNING_CONFIG_FAILED
;
1301 ospf6_area_no_summary_set(ospf6
, area
);
1306 DEFUN (no_ospf6_area_stub
,
1307 no_ospf6_area_stub_cmd
,
1308 "no area <A.B.C.D|(0-4294967295)> stub",
1310 "OSPF6 area parameters\n"
1311 "OSPF6 area ID in IP address format\n"
1312 "OSPF6 area ID as a decimal value\n"
1313 "Configure OSPF6 area as stub\n")
1315 int idx_ipv4_number
= 2;
1316 struct ospf6_area
*area
;
1318 VTY_DECLVAR_CONTEXT(ospf6
, ospf6
);
1320 OSPF6_CMD_AREA_GET(argv
[idx_ipv4_number
]->arg
, area
, ospf6
);
1322 ospf6_area_stub_unset(ospf6
, area
);
1323 ospf6_area_no_summary_unset(ospf6
, area
);
1328 DEFUN (no_ospf6_area_stub_no_summary
,
1329 no_ospf6_area_stub_no_summary_cmd
,
1330 "no area <A.B.C.D|(0-4294967295)> stub no-summary",
1332 "OSPF6 area parameters\n"
1333 "OSPF6 area ID in IP address format\n"
1334 "OSPF6 area ID as a decimal value\n"
1335 "Configure OSPF6 area as stub\n"
1336 "Do not inject inter-area routes into area\n")
1338 int idx_ipv4_number
= 2;
1339 struct ospf6_area
*area
;
1341 VTY_DECLVAR_CONTEXT(ospf6
, ospf6
);
1343 OSPF6_CMD_AREA_GET(argv
[idx_ipv4_number
]->arg
, area
, ospf6
);
1345 ospf6_area_stub_unset(ospf6
, area
);
1346 ospf6_area_no_summary_unset(ospf6
, area
);
1351 DEFPY(ospf6_area_nssa
, ospf6_area_nssa_cmd
,
1352 "area <A.B.C.D|(0-4294967295)>$area_str nssa\
1354 default-information-originate$dflt_originate [{metric (0-16777214)$mval|metric-type (1-2)$mtype}]\
1355 |no-summary$no_summary\
1357 "OSPF6 area parameters\n"
1358 "OSPF6 area ID in IP address format\n"
1359 "OSPF6 area ID as a decimal value\n"
1360 "Configure OSPF6 area as nssa\n"
1361 "Originate Type 7 default into NSSA area\n"
1362 "OSPFv3 default metric\n"
1364 "OSPFv3 metric type for default routes\n"
1365 "Set OSPFv3 External Type 1/2 metrics\n"
1366 "Do not inject inter-area routes into area\n")
1368 struct ospf6_area
*area
;
1370 VTY_DECLVAR_CONTEXT(ospf6
, ospf6
);
1371 OSPF6_CMD_AREA_GET(area_str
, area
, ospf6
);
1373 if (!ospf6_area_nssa_set(ospf6
, area
)) {
1375 "First deconfigure all virtual link through this area\n");
1376 return CMD_WARNING_CONFIG_FAILED
;
1379 if (dflt_originate
) {
1380 if (mval_str
== NULL
)
1382 if (mtype_str
== NULL
)
1383 mtype
= DEFAULT_METRIC_TYPE
;
1384 ospf6_nssa_default_originate_set(ospf6
, area
, mval
, mtype
);
1386 ospf6_nssa_default_originate_unset(ospf6
, area
);
1389 ospf6_area_no_summary_set(ospf6
, area
);
1391 ospf6_area_no_summary_unset(ospf6
, area
);
1393 if (ospf6_check_and_set_router_abr(ospf6
)) {
1394 ospf6_abr_defaults_to_stub(ospf6
);
1395 ospf6_abr_nssa_type_7_defaults(ospf6
);
1401 DEFPY(no_ospf6_area_nssa
, no_ospf6_area_nssa_cmd
,
1402 "no area <A.B.C.D|(0-4294967295)>$area_str nssa\
1404 default-information-originate [{metric (0-16777214)|metric-type (1-2)}]\
1408 "OSPF6 area parameters\n"
1409 "OSPF6 area ID in IP address format\n"
1410 "OSPF6 area ID as a decimal value\n"
1411 "Configure OSPF6 area as nssa\n"
1412 "Originate Type 7 default into NSSA area\n"
1413 "OSPFv3 default metric\n"
1415 "OSPFv3 metric type for default routes\n"
1416 "Set OSPFv3 External Type 1/2 metrics\n"
1417 "Do not inject inter-area routes into area\n")
1419 struct ospf6_area
*area
;
1421 VTY_DECLVAR_CONTEXT(ospf6
, ospf6
);
1422 OSPF6_CMD_AREA_GET(area_str
, area
, ospf6
);
1424 ospf6_area_nssa_unset(ospf6
, area
);
1425 ospf6_area_no_summary_unset(ospf6
, area
);
1426 ospf6_nssa_default_originate_unset(ospf6
, area
);
1432 void ospf6_area_init(void)
1434 install_element(VIEW_NODE
, &show_ipv6_ospf6_spf_tree_cmd
);
1435 install_element(VIEW_NODE
, &show_ipv6_ospf6_area_spf_tree_cmd
);
1436 install_element(VIEW_NODE
, &show_ipv6_ospf6_simulate_spf_tree_root_cmd
);
1438 install_element(OSPF6_NODE
, &area_range_cmd
);
1439 install_element(OSPF6_NODE
, &no_area_range_cmd
);
1440 install_element(OSPF6_NODE
, &ospf6_area_stub_no_summary_cmd
);
1441 install_element(OSPF6_NODE
, &ospf6_area_stub_cmd
);
1442 install_element(OSPF6_NODE
, &no_ospf6_area_stub_no_summary_cmd
);
1443 install_element(OSPF6_NODE
, &no_ospf6_area_stub_cmd
);
1446 install_element(OSPF6_NODE
, &area_import_list_cmd
);
1447 install_element(OSPF6_NODE
, &no_area_import_list_cmd
);
1448 install_element(OSPF6_NODE
, &area_export_list_cmd
);
1449 install_element(OSPF6_NODE
, &no_area_export_list_cmd
);
1451 install_element(OSPF6_NODE
, &area_filter_list_cmd
);
1452 install_element(OSPF6_NODE
, &no_area_filter_list_cmd
);
1454 /* "area nssa" commands. */
1455 install_element(OSPF6_NODE
, &ospf6_area_nssa_cmd
);
1456 install_element(OSPF6_NODE
, &no_ospf6_area_nssa_cmd
);
1459 void ospf6_area_interface_delete(struct ospf6_interface
*oi
)
1461 struct ospf6_area
*oa
;
1462 struct listnode
*node
, *nnode
;
1463 struct ospf6
*ospf6
;
1465 for (ALL_LIST_ELEMENTS(om6
->ospf6
, node
, nnode
, ospf6
)) {
1466 for (ALL_LIST_ELEMENTS(ospf6
->area_list
, node
, nnode
, oa
))
1467 if (listnode_lookup(oa
->if_list
, oi
))
1468 listnode_delete(oa
->if_list
, oi
);