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 #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 struct listnode
*node
;
355 struct listnode
*nnode
;
356 struct ospf6_neighbor
*on
;
358 for (ALL_LIST_ELEMENTS(oi
->neighbor_list
, node
, nnode
, on
))
359 ospf6_neighbor_delete(on
);
362 list_delete(&oa
->if_list
);
364 ospf6_lsdb_delete(oa
->lsdb
);
365 ospf6_lsdb_delete(oa
->lsdb_self
);
366 ospf6_lsdb_delete(oa
->temp_router_lsa_lsdb
);
368 ospf6_spf_table_finish(oa
->spf_table
);
369 ospf6_route_table_delete(oa
->spf_table
);
370 ospf6_route_table_delete(oa
->route_table
);
372 ospf6_route_table_delete(oa
->range_table
);
373 ospf6_route_table_delete(oa
->nssa_range_table
);
374 ospf6_route_table_delete(oa
->summary_prefix
);
375 ospf6_route_table_delete(oa
->summary_router
);
377 listnode_delete(oa
->ospf6
->area_list
, oa
);
381 XFREE(MTYPE_OSPF6_AREA
, oa
);
384 struct ospf6_area
*ospf6_area_lookup_by_area_id(uint32_t area_id
)
386 struct ospf6_area
*oa
;
387 struct listnode
*n
, *node
, *nnode
;
390 for (ALL_LIST_ELEMENTS(om6
->ospf6
, node
, nnode
, ospf6
)) {
391 for (ALL_LIST_ELEMENTS_RO(ospf6
->area_list
, n
, oa
))
392 if (oa
->area_id
== area_id
)
395 return (struct ospf6_area
*)NULL
;
398 struct ospf6_area
*ospf6_area_lookup(uint32_t area_id
, struct ospf6
*ospf6
)
400 struct ospf6_area
*oa
;
403 for (ALL_LIST_ELEMENTS_RO(ospf6
->area_list
, n
, oa
))
404 if (oa
->area_id
== area_id
)
407 return (struct ospf6_area
*)NULL
;
410 void ospf6_area_enable(struct ospf6_area
*oa
)
412 struct listnode
*node
, *nnode
;
413 struct ospf6_interface
*oi
;
415 SET_FLAG(oa
->flag
, OSPF6_AREA_ENABLE
);
417 for (ALL_LIST_ELEMENTS(oa
->if_list
, node
, nnode
, oi
))
418 ospf6_interface_enable(oi
);
419 ospf6_abr_enable_area(oa
);
422 void ospf6_area_disable(struct ospf6_area
*oa
)
424 struct listnode
*node
, *nnode
;
425 struct ospf6_interface
*oi
;
427 UNSET_FLAG(oa
->flag
, OSPF6_AREA_ENABLE
);
429 for (ALL_LIST_ELEMENTS(oa
->if_list
, node
, nnode
, oi
))
430 ospf6_interface_disable(oi
);
432 ospf6_abr_disable_area(oa
);
433 ospf6_lsdb_remove_all(oa
->lsdb
);
434 ospf6_lsdb_remove_all(oa
->lsdb_self
);
436 ospf6_spf_table_finish(oa
->spf_table
);
437 ospf6_route_remove_all(oa
->route_table
);
439 THREAD_OFF(oa
->thread_router_lsa
);
440 THREAD_OFF(oa
->thread_intra_prefix_lsa
);
444 void ospf6_area_show(struct vty
*vty
, struct ospf6_area
*oa
,
445 json_object
*json_areas
, bool use_json
)
448 struct ospf6_interface
*oi
;
449 unsigned long result
;
450 json_object
*json_area
;
451 json_object
*array_interfaces
;
454 json_area
= json_object_new_object();
455 json_object_boolean_add(json_area
, "areaIsStub",
457 json_object_boolean_add(json_area
, "areaIsNSSA",
459 if (IS_AREA_STUB(oa
) || IS_AREA_NSSA(oa
)) {
460 json_object_boolean_add(json_area
, "areaNoSummary",
464 json_object_int_add(json_area
, "numberOfAreaScopedLsa",
466 json_object_object_add(
467 json_area
, "lsaStatistics",
468 JSON_OBJECT_NEW_ARRAY(json_object_new_int
,
472 /* Interfaces Attached */
473 array_interfaces
= json_object_new_array();
474 for (ALL_LIST_ELEMENTS_RO(oa
->if_list
, i
, oi
))
475 json_object_array_add(
477 json_object_new_string(oi
->interface
->name
));
479 json_object_object_add(json_area
, "interfacesAttachedToArea",
482 if (oa
->ts_spf
.tv_sec
|| oa
->ts_spf
.tv_usec
) {
483 json_object_boolean_true_add(json_area
, "spfHasRun");
484 result
= monotime_since(&oa
->ts_spf
, NULL
);
485 if (result
/ TIMER_SECOND_MICRO
> 0) {
487 json_area
, "spfLastExecutedSecs",
488 result
/ TIMER_SECOND_MICRO
);
491 json_area
, "spfLastExecutedMicroSecs",
492 result
% TIMER_SECOND_MICRO
);
494 json_object_int_add(json_area
,
495 "spfLastExecutedSecs", 0);
496 json_object_int_add(json_area
,
497 "spfLastExecutedMicroSecs",
501 json_object_boolean_false_add(json_area
, "spfHasRun");
504 json_object_object_add(json_areas
, oa
->name
, json_area
);
508 if (!IS_AREA_STUB(oa
) && !IS_AREA_NSSA(oa
))
509 vty_out(vty
, " Area %s\n", oa
->name
);
511 if (oa
->no_summary
) {
512 vty_out(vty
, " Area %s[%s, No Summary]\n",
514 IS_AREA_STUB(oa
) ? "Stub" : "NSSA");
516 vty_out(vty
, " Area %s[%s]\n", oa
->name
,
517 IS_AREA_STUB(oa
) ? "Stub" : "NSSA");
520 vty_out(vty
, " Number of Area scoped LSAs is %u\n",
523 vty_out(vty
, " Interface attached to this area:");
524 for (ALL_LIST_ELEMENTS_RO(oa
->if_list
, i
, oi
))
525 vty_out(vty
, " %s", oi
->interface
->name
);
528 if (oa
->ts_spf
.tv_sec
|| oa
->ts_spf
.tv_usec
) {
529 result
= monotime_since(&oa
->ts_spf
, NULL
);
530 if (result
/ TIMER_SECOND_MICRO
> 0) {
532 " SPF last executed %ld.%lds ago\n",
533 result
/ TIMER_SECOND_MICRO
,
534 result
% TIMER_SECOND_MICRO
);
537 " SPF last executed %ldus ago\n",
541 vty_out(vty
, "SPF has not been run\n");
547 "area <A.B.C.D|(0-4294967295)> range X:X::X:X/M [<advertise|not-advertise|cost (0-16777215)>]",
548 "OSPF6 area parameters\n"
549 "OSPF6 area ID in IP address format\n"
550 "OSPF6 area ID as a decimal value\n"
551 "Configured address range\n"
552 "Specify IPv6 prefix\n"
555 "User specified metric for this range\n"
556 "Advertised metric for this range\n")
559 int idx_ipv6_prefixlen
= 3;
562 struct ospf6_area
*oa
;
563 struct prefix prefix
;
564 struct ospf6_route
*range
;
567 VTY_DECLVAR_CONTEXT(ospf6
, ospf6
);
569 OSPF6_CMD_AREA_GET(argv
[idx_ipv4
]->arg
, oa
, ospf6
);
571 ret
= str2prefix(argv
[idx_ipv6_prefixlen
]->arg
, &prefix
);
572 if (ret
!= 1 || prefix
.family
!= AF_INET6
) {
573 vty_out(vty
, "Malformed argument: %s\n",
574 argv
[idx_ipv6_prefixlen
]->arg
);
578 range
= ospf6_route_lookup(&prefix
, oa
->range_table
);
580 range
= ospf6_route_create(ospf6
);
581 range
->type
= OSPF6_DEST_TYPE_RANGE
;
582 range
->prefix
= prefix
;
583 range
->path
.area_id
= oa
->area_id
;
584 range
->path
.cost
= OSPF_AREA_RANGE_COST_UNSPEC
;
587 /* default settings */
588 cost
= OSPF_AREA_RANGE_COST_UNSPEC
;
589 UNSET_FLAG(range
->flag
, OSPF6_ROUTE_DO_NOT_ADVERTISE
);
591 if (argc
> idx_type
) {
592 if (strmatch(argv
[idx_type
]->text
, "not-advertise"))
593 SET_FLAG(range
->flag
, OSPF6_ROUTE_DO_NOT_ADVERTISE
);
594 else if (strmatch(argv
[idx_type
]->text
, "cost"))
595 cost
= strtoul(argv
[5]->arg
, NULL
, 10);
598 range
->path
.u
.cost_config
= cost
;
600 if (range
->rnode
== NULL
) {
601 ospf6_route_add(range
, oa
->range_table
);
604 if (ospf6_check_and_set_router_abr(ospf6
)) {
605 /* Redo summaries if required */
606 ospf6_abr_prefix_resummarize(ospf6
);
612 DEFUN (no_area_range
,
614 "no area <A.B.C.D|(0-4294967295)> range X:X::X:X/M [<advertise|not-advertise|cost (0-16777215)>]",
616 "OSPF6 area parameters\n"
617 "OSPF6 area ID in IP address format\n"
618 "OSPF6 area ID as a decimal value\n"
619 "Configured address range\n"
620 "Specify IPv6 prefix\n"
623 "User specified metric for this range\n"
624 "Advertised metric for this range\n")
629 struct ospf6_area
*oa
;
630 struct prefix prefix
;
631 struct ospf6_route
*range
, *route
;
633 VTY_DECLVAR_CONTEXT(ospf6
, ospf6
);
635 OSPF6_CMD_AREA_GET(argv
[idx_ipv4
]->arg
, oa
, ospf6
);
637 ret
= str2prefix(argv
[idx_ipv6
]->arg
, &prefix
);
638 if (ret
!= 1 || prefix
.family
!= AF_INET6
) {
639 vty_out(vty
, "Malformed argument: %s\n", argv
[idx_ipv6
]->arg
);
643 range
= ospf6_route_lookup(&prefix
, oa
->range_table
);
645 vty_out(vty
, "Range %s does not exists.\n",
646 argv
[idx_ipv6
]->arg
);
650 if (ospf6_check_and_set_router_abr(oa
->ospf6
)) {
651 /* Blow away the aggregated LSA and route */
652 SET_FLAG(range
->flag
, OSPF6_ROUTE_REMOVE
);
654 /* Redo summaries if required */
655 for (route
= ospf6_route_head(oa
->ospf6
->route_table
); route
;
656 route
= ospf6_route_next(route
))
657 ospf6_abr_originate_summary(route
, oa
->ospf6
);
659 /* purge the old aggregated summary LSA */
660 ospf6_abr_originate_summary(range
, oa
->ospf6
);
662 ospf6_route_remove(range
, oa
->range_table
);
667 void ospf6_area_config_write(struct vty
*vty
, struct ospf6
*ospf6
)
669 struct listnode
*node
;
670 struct ospf6_area
*oa
;
671 struct ospf6_route
*range
;
673 for (ALL_LIST_ELEMENTS_RO(ospf6
->area_list
, node
, oa
)) {
674 for (range
= ospf6_route_head(oa
->range_table
); range
;
675 range
= ospf6_route_next(range
)) {
676 vty_out(vty
, " area %s range %pFX", oa
->name
,
679 if (CHECK_FLAG(range
->flag
,
680 OSPF6_ROUTE_DO_NOT_ADVERTISE
)) {
681 vty_out(vty
, " not-advertise");
683 // "advertise" is the default so we do not
685 if (range
->path
.u
.cost_config
686 != OSPF_AREA_RANGE_COST_UNSPEC
)
687 vty_out(vty
, " cost %d",
688 range
->path
.u
.cost_config
);
692 if (IS_AREA_STUB(oa
)) {
694 vty_out(vty
, " area %s stub no-summary\n",
697 vty_out(vty
, " area %s stub\n", oa
->name
);
699 if (IS_AREA_NSSA(oa
)) {
700 vty_out(vty
, " area %s nssa", oa
->name
);
701 if (oa
->nssa_default_originate
.enabled
) {
702 vty_out(vty
, " default-information-originate");
703 if (oa
->nssa_default_originate
.metric_value
705 vty_out(vty
, " metric %d",
706 oa
->nssa_default_originate
708 if (oa
->nssa_default_originate
.metric_type
709 != DEFAULT_METRIC_TYPE
)
710 vty_out(vty
, " metric-type 1");
713 vty_out(vty
, " no-summary");
716 for (range
= ospf6_route_head(oa
->nssa_range_table
); range
;
717 range
= ospf6_route_next(range
)) {
718 vty_out(vty
, " area %s nssa range %pFX", oa
->name
,
721 if (CHECK_FLAG(range
->flag
,
722 OSPF6_ROUTE_DO_NOT_ADVERTISE
)) {
723 vty_out(vty
, " not-advertise");
725 if (range
->path
.u
.cost_config
726 != OSPF_AREA_RANGE_COST_UNSPEC
)
727 vty_out(vty
, " cost %u",
728 range
->path
.u
.cost_config
);
732 if (PREFIX_NAME_IN(oa
))
733 vty_out(vty
, " area %s filter-list prefix %s in\n",
734 oa
->name
, PREFIX_NAME_IN(oa
));
735 if (PREFIX_NAME_OUT(oa
))
736 vty_out(vty
, " area %s filter-list prefix %s out\n",
737 oa
->name
, PREFIX_NAME_OUT(oa
));
739 vty_out(vty
, " area %s import-list %s\n", oa
->name
,
742 vty_out(vty
, " area %s export-list %s\n", oa
->name
,
747 DEFUN (area_filter_list
,
748 area_filter_list_cmd
,
749 "area <A.B.C.D|(0-4294967295)> filter-list prefix PREFIXLIST_NAME <in|out>",
750 "OSPF6 area parameters\n"
751 "OSPF6 area ID in IP address format\n"
752 "OSPF6 area ID as a decimal value\n"
753 "Filter networks between OSPF6 areas\n"
754 "Filter prefixes between OSPF6 areas\n"
755 "Name of an IPv6 prefix-list\n"
756 "Filter networks sent to this area\n"
757 "Filter networks sent from this area\n")
759 char *inout
= argv
[argc
- 1]->text
;
760 char *areaid
= argv
[1]->arg
;
761 char *plistname
= argv
[4]->arg
;
763 struct ospf6_area
*area
;
764 struct prefix_list
*plist
;
766 VTY_DECLVAR_CONTEXT(ospf6
, ospf6
);
768 OSPF6_CMD_AREA_GET(areaid
, area
, ospf6
);
770 plist
= prefix_list_lookup(AFI_IP6
, plistname
);
771 if (strmatch(inout
, "in")) {
772 PREFIX_LIST_IN(area
) = plist
;
773 XFREE(MTYPE_OSPF6_PLISTNAME
, PREFIX_NAME_IN(area
));
774 PREFIX_NAME_IN(area
) =
775 XSTRDUP(MTYPE_OSPF6_PLISTNAME
, plistname
);
777 PREFIX_LIST_OUT(area
) = plist
;
778 XFREE(MTYPE_OSPF6_PLISTNAME
, PREFIX_NAME_OUT(area
));
779 PREFIX_NAME_OUT(area
) =
780 XSTRDUP(MTYPE_OSPF6_PLISTNAME
, plistname
);
783 /* Redo summaries if required */
784 if (ospf6_check_and_set_router_abr(area
->ospf6
))
785 ospf6_schedule_abr_task(ospf6
);
790 DEFUN (no_area_filter_list
,
791 no_area_filter_list_cmd
,
792 "no area <A.B.C.D|(0-4294967295)> filter-list prefix PREFIXLIST_NAME <in|out>",
794 "OSPF6 area parameters\n"
795 "OSPF6 area ID in IP address format\n"
796 "OSPF6 area ID as a decimal value\n"
797 "Filter networks between OSPF6 areas\n"
798 "Filter prefixes between OSPF6 areas\n"
799 "Name of an IPv6 prefix-list\n"
800 "Filter networks sent to this area\n"
801 "Filter networks sent from this area\n")
803 char *inout
= argv
[argc
- 1]->text
;
804 char *areaid
= argv
[2]->arg
;
805 char *plistname
= argv
[5]->arg
;
807 struct ospf6_area
*area
;
809 VTY_DECLVAR_CONTEXT(ospf6
, ospf6
);
810 OSPF6_CMD_AREA_GET(areaid
, area
, ospf6
);
812 if (strmatch(inout
, "in")) {
813 if (PREFIX_NAME_IN(area
))
814 if (!strmatch(PREFIX_NAME_IN(area
), plistname
))
817 PREFIX_LIST_IN(area
) = NULL
;
818 XFREE(MTYPE_OSPF6_PLISTNAME
, PREFIX_NAME_IN(area
));
820 if (PREFIX_NAME_OUT(area
))
821 if (!strmatch(PREFIX_NAME_OUT(area
), plistname
))
824 XFREE(MTYPE_OSPF6_PLISTNAME
, PREFIX_NAME_OUT(area
));
825 PREFIX_LIST_OUT(area
) = NULL
;
828 /* Redo summaries if required */
829 if (ospf6_check_and_set_router_abr(area
->ospf6
))
830 ospf6_schedule_abr_task(ospf6
);
835 void ospf6_filter_update(struct access_list
*access
)
837 struct ospf6_area
*oa
;
838 struct listnode
*n
, *node
, *nnode
;
841 for (ALL_LIST_ELEMENTS(om6
->ospf6
, node
, nnode
, ospf6
)) {
844 for (ALL_LIST_ELEMENTS_RO(ospf6
->area_list
, n
, oa
)) {
846 && strcmp(IMPORT_NAME(oa
), access
->name
) == 0) {
847 IMPORT_LIST(oa
) = access_list_lookup(
848 AFI_IP6
, IMPORT_NAME(oa
));
853 && strcmp(EXPORT_NAME(oa
), access
->name
) == 0) {
854 EXPORT_LIST(oa
) = access_list_lookup(
855 AFI_IP6
, EXPORT_NAME(oa
));
860 if (update
&& ospf6_check_and_set_router_abr(ospf6
))
861 ospf6_schedule_abr_task(ospf6
);
865 void ospf6_plist_update(struct prefix_list
*plist
)
867 struct listnode
*node
, *nnode
;
868 struct ospf6_area
*oa
;
870 const char *name
= prefix_list_name(plist
);
871 struct ospf6
*ospf6
= NULL
;
873 if (prefix_list_afi(plist
) != AFI_IP6
)
876 for (ALL_LIST_ELEMENTS(om6
->ospf6
, node
, nnode
, ospf6
)) {
879 for (ALL_LIST_ELEMENTS_RO(ospf6
->area_list
, n
, oa
)) {
880 if (PREFIX_NAME_IN(oa
)
881 && !strcmp(PREFIX_NAME_IN(oa
), name
)) {
882 PREFIX_LIST_IN(oa
) = prefix_list_lookup(
883 AFI_IP6
, PREFIX_NAME_IN(oa
));
886 if (PREFIX_NAME_OUT(oa
)
887 && !strcmp(PREFIX_NAME_OUT(oa
), name
)) {
888 PREFIX_LIST_OUT(oa
) = prefix_list_lookup(
889 AFI_IP6
, PREFIX_NAME_OUT(oa
));
894 if (update
&& ospf6_check_and_set_router_abr(ospf6
))
895 ospf6_schedule_abr_task(ospf6
);
899 DEFUN (area_import_list
,
900 area_import_list_cmd
,
901 "area <A.B.C.D|(0-4294967295)> import-list ACCESSLIST6_NAME",
902 "OSPF6 area parameters\n"
903 "OSPF6 area ID in IP address format\n"
904 "OSPF6 area ID as a decimal value\n"
905 "Set the filter for networks from other areas announced to the specified one\n"
906 "Name of the access-list\n")
910 struct ospf6_area
*area
;
911 struct access_list
*list
;
913 VTY_DECLVAR_CONTEXT(ospf6
, ospf6
);
915 OSPF6_CMD_AREA_GET(argv
[idx_ipv4
]->arg
, area
, ospf6
);
917 list
= access_list_lookup(AFI_IP6
, argv
[idx_name
]->arg
);
919 IMPORT_LIST(area
) = list
;
921 if (IMPORT_NAME(area
))
922 free(IMPORT_NAME(area
));
924 IMPORT_NAME(area
) = strdup(argv
[idx_name
]->arg
);
925 if (ospf6_check_and_set_router_abr(area
->ospf6
))
926 ospf6_schedule_abr_task(ospf6
);
931 DEFUN (no_area_import_list
,
932 no_area_import_list_cmd
,
933 "no area <A.B.C.D|(0-4294967295)> import-list ACCESSLIST6_NAME",
935 "OSPF6 area parameters\n"
936 "OSPF6 area ID in IP address format\n"
937 "OSPF6 area ID as a decimal value\n"
938 "Unset the filter for networks announced to other areas\n"
939 "Name of the access-list\n")
942 struct ospf6_area
*area
;
944 VTY_DECLVAR_CONTEXT(ospf6
, ospf6
);
946 OSPF6_CMD_AREA_GET(argv
[idx_ipv4
]->arg
, area
, ospf6
);
948 IMPORT_LIST(area
) = NULL
;
950 if (IMPORT_NAME(area
))
951 free(IMPORT_NAME(area
));
953 IMPORT_NAME(area
) = NULL
;
954 if (ospf6_check_and_set_router_abr(area
->ospf6
))
955 ospf6_schedule_abr_task(ospf6
);
960 DEFUN (area_export_list
,
961 area_export_list_cmd
,
962 "area <A.B.C.D|(0-4294967295)> export-list ACCESSLIST6_NAME",
963 "OSPF6 area parameters\n"
964 "OSPF6 area ID in IP address format\n"
965 "OSPF6 area ID as a decimal value\n"
966 "Set the filter for networks announced to other areas\n"
967 "Name of the access-list\n")
971 struct ospf6_area
*area
;
972 struct access_list
*list
;
974 VTY_DECLVAR_CONTEXT(ospf6
, ospf6
);
976 OSPF6_CMD_AREA_GET(argv
[idx_ipv4
]->arg
, area
, ospf6
);
978 list
= access_list_lookup(AFI_IP6
, argv
[idx_name
]->arg
);
980 EXPORT_LIST(area
) = list
;
982 if (EXPORT_NAME(area
))
983 free(EXPORT_NAME(area
));
985 EXPORT_NAME(area
) = strdup(argv
[idx_name
]->arg
);
987 /* Redo summaries if required */
988 if (ospf6_check_and_set_router_abr(area
->ospf6
))
989 ospf6_schedule_abr_task(ospf6
);
994 DEFUN (no_area_export_list
,
995 no_area_export_list_cmd
,
996 "no area <A.B.C.D|(0-4294967295)> export-list ACCESSLIST6_NAME",
998 "OSPF6 area parameters\n"
999 "OSPF6 area ID in IP address format\n"
1000 "OSPF6 area ID as a decimal value\n"
1001 "Unset the filter for networks announced to other areas\n"
1002 "Name of the access-list\n")
1005 struct ospf6_area
*area
;
1007 VTY_DECLVAR_CONTEXT(ospf6
, ospf6
);
1009 OSPF6_CMD_AREA_GET(argv
[idx_ipv4
]->arg
, area
, ospf6
);
1011 EXPORT_LIST(area
) = NULL
;
1013 if (EXPORT_NAME(area
))
1014 free(EXPORT_NAME(area
));
1016 EXPORT_NAME(area
) = NULL
;
1017 if (ospf6_check_and_set_router_abr(area
->ospf6
))
1018 ospf6_schedule_abr_task(ospf6
);
1023 static int ipv6_ospf6_spf_tree_common(struct vty
*vty
, struct ospf6
*ospf6
,
1026 struct listnode
*node
;
1027 struct ospf6_area
*oa
;
1028 struct prefix prefix
;
1029 struct ospf6_vertex
*root
;
1030 struct ospf6_route
*route
;
1031 json_object
*json
= NULL
;
1032 json_object
*json_area
= NULL
;
1033 json_object
*json_head
= NULL
;
1036 json
= json_object_new_object();
1037 ospf6_linkstate_prefix(ospf6
->router_id
, htonl(0), &prefix
);
1038 for (ALL_LIST_ELEMENTS_RO(ospf6
->area_list
, node
, oa
)) {
1040 json_area
= json_object_new_object();
1041 json_head
= json_object_new_object();
1043 route
= ospf6_route_lookup(&prefix
, oa
->spf_table
);
1044 if (route
== NULL
) {
1046 json_object_string_add(
1048 "LS entry for not not found");
1049 json_object_free(json_head
);
1050 json_object_free(json_area
);
1053 "LS entry for root not found in area %s\n",
1057 root
= (struct ospf6_vertex
*)route
->route_option
;
1058 ospf6_spf_display_subtree(vty
, "", 0, root
, json_head
, uj
);
1061 json_object_object_add(json_area
, root
->name
,
1063 json_object_object_add(json
, oa
->name
, json_area
);
1068 vty_json(vty
, json
);
1073 DEFUN(show_ipv6_ospf6_spf_tree
, show_ipv6_ospf6_spf_tree_cmd
,
1074 "show ipv6 ospf6 [vrf <NAME|all>] spf tree [json]",
1075 SHOW_STR IP6_STR OSPF6_STR VRF_CMD_HELP_STR
1077 "Shortest Path First calculation\n"
1078 "Show SPF tree\n" JSON_STR
)
1080 struct listnode
*node
;
1081 struct ospf6
*ospf6
;
1082 const char *vrf_name
= NULL
;
1083 bool all_vrf
= false;
1085 bool uj
= use_json(argc
, argv
);
1087 OSPF6_FIND_VRF_ARGS(argv
, argc
, idx_vrf
, vrf_name
, all_vrf
);
1089 for (ALL_LIST_ELEMENTS_RO(om6
->ospf6
, node
, ospf6
)) {
1090 if (all_vrf
|| strcmp(ospf6
->name
, vrf_name
) == 0) {
1091 ipv6_ospf6_spf_tree_common(vty
, ospf6
, uj
);
1097 OSPF6_CMD_CHECK_VRF(uj
, all_vrf
, ospf6
);
1102 static int show_ospf6_area_spf_tree_common(struct vty
*vty
,
1103 struct cmd_token
**argv
,
1104 struct ospf6
*ospf6
,
1105 uint32_t area_id
, int idx_ipv4
)
1108 struct ospf6_area
*oa
;
1109 struct prefix prefix
;
1110 struct ospf6_vertex
*root
;
1111 struct ospf6_route
*route
;
1113 ospf6_linkstate_prefix(ospf6
->router_id
, htonl(0), &prefix
);
1115 oa
= ospf6_area_lookup(area_id
, ospf6
);
1117 vty_out(vty
, "No such Area: %s\n", argv
[idx_ipv4
]->arg
);
1121 route
= ospf6_route_lookup(&prefix
, oa
->spf_table
);
1122 if (route
== NULL
) {
1123 vty_out(vty
, "LS entry for root not found in area %s\n",
1127 root
= (struct ospf6_vertex
*)route
->route_option
;
1128 ospf6_spf_display_subtree(vty
, "", 0, root
, NULL
, false);
1133 DEFUN(show_ipv6_ospf6_area_spf_tree
, show_ipv6_ospf6_area_spf_tree_cmd
,
1134 "show ipv6 ospf6 [vrf <NAME|all>] area A.B.C.D spf tree",
1135 SHOW_STR IP6_STR OSPF6_STR VRF_CMD_HELP_STR
1136 "All VRFs\n" OSPF6_AREA_STR OSPF6_AREA_ID_STR
1137 "Shortest Path First calculation\n"
1142 struct ospf6
*ospf6
;
1143 struct listnode
*node
;
1144 const char *vrf_name
= NULL
;
1145 bool all_vrf
= false;
1148 OSPF6_FIND_VRF_ARGS(argv
, argc
, idx_vrf
, vrf_name
, all_vrf
);
1152 if (inet_pton(AF_INET
, argv
[idx_ipv4
]->arg
, &area_id
) != 1) {
1153 vty_out(vty
, "Malformed Area-ID: %s\n", argv
[idx_ipv4
]->arg
);
1157 for (ALL_LIST_ELEMENTS_RO(om6
->ospf6
, node
, ospf6
)) {
1158 if (all_vrf
|| strcmp(ospf6
->name
, vrf_name
) == 0) {
1159 show_ospf6_area_spf_tree_common(vty
, argv
, ospf6
,
1166 OSPF6_CMD_CHECK_VRF(false, all_vrf
, ospf6
);
1172 show_ospf6_simulate_spf_tree_commen(struct vty
*vty
, struct cmd_token
**argv
,
1173 struct ospf6
*ospf6
, uint32_t router_id
,
1174 uint32_t area_id
, struct prefix prefix
,
1175 int idx_ipv4
, int idx_ipv4_2
)
1177 struct ospf6_area
*oa
;
1178 struct ospf6_vertex
*root
;
1179 struct ospf6_route
*route
;
1180 struct ospf6_route_table
*spf_table
;
1181 unsigned char tmp_debug_ospf6_spf
= 0;
1183 oa
= ospf6_area_lookup(area_id
, ospf6
);
1185 vty_out(vty
, "No such Area: %s\n", argv
[idx_ipv4_2
]->arg
);
1189 tmp_debug_ospf6_spf
= conf_debug_ospf6_spf
;
1190 conf_debug_ospf6_spf
= 0;
1192 spf_table
= OSPF6_ROUTE_TABLE_CREATE(NONE
, SPF_RESULTS
);
1193 ospf6_spf_calculation(router_id
, spf_table
, oa
);
1195 conf_debug_ospf6_spf
= tmp_debug_ospf6_spf
;
1197 route
= ospf6_route_lookup(&prefix
, spf_table
);
1198 if (route
== NULL
) {
1199 ospf6_spf_table_finish(spf_table
);
1200 ospf6_route_table_delete(spf_table
);
1203 root
= (struct ospf6_vertex
*)route
->route_option
;
1204 ospf6_spf_display_subtree(vty
, "", 0, root
, NULL
, false);
1206 ospf6_spf_table_finish(spf_table
);
1207 ospf6_route_table_delete(spf_table
);
1212 DEFUN(show_ipv6_ospf6_simulate_spf_tree_root
,
1213 show_ipv6_ospf6_simulate_spf_tree_root_cmd
,
1214 "show ipv6 ospf6 [vrf <NAME|all>] simulate spf-tree A.B.C.D area A.B.C.D",
1215 SHOW_STR IP6_STR OSPF6_STR VRF_CMD_HELP_STR
1217 "Shortest Path First calculation\n"
1219 "Specify root's router-id to calculate another router's SPF tree\n"
1220 "OSPF6 area parameters\n" OSPF6_AREA_ID_STR
)
1225 struct prefix prefix
;
1227 struct ospf6
*ospf6
;
1228 struct listnode
*node
;
1229 const char *vrf_name
= NULL
;
1230 bool all_vrf
= false;
1233 OSPF6_FIND_VRF_ARGS(argv
, argc
, idx_vrf
, vrf_name
, all_vrf
);
1238 inet_pton(AF_INET
, argv
[idx_ipv4
]->arg
, &router_id
);
1239 ospf6_linkstate_prefix(router_id
, htonl(0), &prefix
);
1241 if (inet_pton(AF_INET
, argv
[idx_ipv4_2
]->arg
, &area_id
) != 1) {
1242 vty_out(vty
, "Malformed Area-ID: %s\n", argv
[idx_ipv4_2
]->arg
);
1246 for (ALL_LIST_ELEMENTS_RO(om6
->ospf6
, node
, ospf6
)) {
1247 if (all_vrf
|| strcmp(ospf6
->name
, vrf_name
) == 0) {
1248 show_ospf6_simulate_spf_tree_commen(
1249 vty
, argv
, ospf6
, router_id
, area_id
, prefix
,
1250 idx_ipv4
, idx_ipv4_2
);
1256 OSPF6_CMD_CHECK_VRF(false, all_vrf
, ospf6
);
1261 DEFUN (ospf6_area_stub
,
1262 ospf6_area_stub_cmd
,
1263 "area <A.B.C.D|(0-4294967295)> stub",
1264 "OSPF6 area parameters\n"
1265 "OSPF6 area ID in IP address format\n"
1266 "OSPF6 area ID as a decimal value\n"
1267 "Configure OSPF6 area as stub\n")
1269 int idx_ipv4_number
= 1;
1270 struct ospf6_area
*area
;
1272 VTY_DECLVAR_CONTEXT(ospf6
, ospf6
);
1274 OSPF6_CMD_AREA_GET(argv
[idx_ipv4_number
]->arg
, area
, ospf6
);
1276 if (!ospf6_area_stub_set(ospf6
, area
)) {
1278 "First deconfigure all virtual link through this area\n");
1279 return CMD_WARNING_CONFIG_FAILED
;
1282 ospf6_area_no_summary_unset(ospf6
, area
);
1287 DEFUN (ospf6_area_stub_no_summary
,
1288 ospf6_area_stub_no_summary_cmd
,
1289 "area <A.B.C.D|(0-4294967295)> stub no-summary",
1290 "OSPF6 stub parameters\n"
1291 "OSPF6 area ID in IP address format\n"
1292 "OSPF6 area ID as a decimal value\n"
1293 "Configure OSPF6 area as stub\n"
1294 "Do not inject inter-area routes into stub\n")
1296 int idx_ipv4_number
= 1;
1297 struct ospf6_area
*area
;
1299 VTY_DECLVAR_CONTEXT(ospf6
, ospf6
);
1301 OSPF6_CMD_AREA_GET(argv
[idx_ipv4_number
]->arg
, area
, ospf6
);
1303 if (!ospf6_area_stub_set(ospf6
, area
)) {
1305 "First deconfigure all virtual link through this area\n");
1306 return CMD_WARNING_CONFIG_FAILED
;
1309 ospf6_area_no_summary_set(ospf6
, area
);
1314 DEFUN (no_ospf6_area_stub
,
1315 no_ospf6_area_stub_cmd
,
1316 "no area <A.B.C.D|(0-4294967295)> stub",
1318 "OSPF6 area parameters\n"
1319 "OSPF6 area ID in IP address format\n"
1320 "OSPF6 area ID as a decimal value\n"
1321 "Configure OSPF6 area as stub\n")
1323 int idx_ipv4_number
= 2;
1324 struct ospf6_area
*area
;
1326 VTY_DECLVAR_CONTEXT(ospf6
, ospf6
);
1328 OSPF6_CMD_AREA_GET(argv
[idx_ipv4_number
]->arg
, area
, ospf6
);
1330 ospf6_area_stub_unset(ospf6
, area
);
1331 ospf6_area_no_summary_unset(ospf6
, area
);
1336 DEFUN (no_ospf6_area_stub_no_summary
,
1337 no_ospf6_area_stub_no_summary_cmd
,
1338 "no area <A.B.C.D|(0-4294967295)> stub no-summary",
1340 "OSPF6 area parameters\n"
1341 "OSPF6 area ID in IP address format\n"
1342 "OSPF6 area ID as a decimal value\n"
1343 "Configure OSPF6 area as stub\n"
1344 "Do not inject inter-area routes into area\n")
1346 int idx_ipv4_number
= 2;
1347 struct ospf6_area
*area
;
1349 VTY_DECLVAR_CONTEXT(ospf6
, ospf6
);
1351 OSPF6_CMD_AREA_GET(argv
[idx_ipv4_number
]->arg
, area
, ospf6
);
1353 ospf6_area_stub_unset(ospf6
, area
);
1354 ospf6_area_no_summary_unset(ospf6
, area
);
1359 DEFPY(ospf6_area_nssa
, ospf6_area_nssa_cmd
,
1360 "area <A.B.C.D|(0-4294967295)>$area_str nssa\
1362 default-information-originate$dflt_originate [{metric (0-16777214)$mval|metric-type (1-2)$mtype}]\
1363 |no-summary$no_summary\
1365 "OSPF6 area parameters\n"
1366 "OSPF6 area ID in IP address format\n"
1367 "OSPF6 area ID as a decimal value\n"
1368 "Configure OSPF6 area as nssa\n"
1369 "Originate Type 7 default into NSSA area\n"
1370 "OSPFv3 default metric\n"
1372 "OSPFv3 metric type for default routes\n"
1373 "Set OSPFv3 External Type 1/2 metrics\n"
1374 "Do not inject inter-area routes into area\n")
1376 struct ospf6_area
*area
;
1378 VTY_DECLVAR_CONTEXT(ospf6
, ospf6
);
1379 OSPF6_CMD_AREA_GET(area_str
, area
, ospf6
);
1381 if (!ospf6_area_nssa_set(ospf6
, area
)) {
1383 "First deconfigure all virtual link through this area\n");
1384 return CMD_WARNING_CONFIG_FAILED
;
1387 if (dflt_originate
) {
1388 if (mval_str
== NULL
)
1390 if (mtype_str
== NULL
)
1391 mtype
= DEFAULT_METRIC_TYPE
;
1392 ospf6_nssa_default_originate_set(ospf6
, area
, mval
, mtype
);
1394 ospf6_nssa_default_originate_unset(ospf6
, area
);
1397 ospf6_area_no_summary_set(ospf6
, area
);
1399 ospf6_area_no_summary_unset(ospf6
, area
);
1401 if (ospf6_check_and_set_router_abr(ospf6
)) {
1402 ospf6_abr_defaults_to_stub(ospf6
);
1403 ospf6_abr_nssa_type_7_defaults(ospf6
);
1409 DEFPY(no_ospf6_area_nssa
, no_ospf6_area_nssa_cmd
,
1410 "no area <A.B.C.D|(0-4294967295)>$area_str nssa\
1412 default-information-originate [{metric (0-16777214)|metric-type (1-2)}]\
1416 "OSPF6 area parameters\n"
1417 "OSPF6 area ID in IP address format\n"
1418 "OSPF6 area ID as a decimal value\n"
1419 "Configure OSPF6 area as nssa\n"
1420 "Originate Type 7 default into NSSA area\n"
1421 "OSPFv3 default metric\n"
1423 "OSPFv3 metric type for default routes\n"
1424 "Set OSPFv3 External Type 1/2 metrics\n"
1425 "Do not inject inter-area routes into area\n")
1427 struct ospf6_area
*area
;
1429 VTY_DECLVAR_CONTEXT(ospf6
, ospf6
);
1430 OSPF6_CMD_AREA_GET(area_str
, area
, ospf6
);
1432 ospf6_area_nssa_unset(ospf6
, area
);
1433 ospf6_area_no_summary_unset(ospf6
, area
);
1434 ospf6_nssa_default_originate_unset(ospf6
, area
);
1440 void ospf6_area_init(void)
1442 install_element(VIEW_NODE
, &show_ipv6_ospf6_spf_tree_cmd
);
1443 install_element(VIEW_NODE
, &show_ipv6_ospf6_area_spf_tree_cmd
);
1444 install_element(VIEW_NODE
, &show_ipv6_ospf6_simulate_spf_tree_root_cmd
);
1446 install_element(OSPF6_NODE
, &area_range_cmd
);
1447 install_element(OSPF6_NODE
, &no_area_range_cmd
);
1448 install_element(OSPF6_NODE
, &ospf6_area_stub_no_summary_cmd
);
1449 install_element(OSPF6_NODE
, &ospf6_area_stub_cmd
);
1450 install_element(OSPF6_NODE
, &no_ospf6_area_stub_no_summary_cmd
);
1451 install_element(OSPF6_NODE
, &no_ospf6_area_stub_cmd
);
1454 install_element(OSPF6_NODE
, &area_import_list_cmd
);
1455 install_element(OSPF6_NODE
, &no_area_import_list_cmd
);
1456 install_element(OSPF6_NODE
, &area_export_list_cmd
);
1457 install_element(OSPF6_NODE
, &no_area_export_list_cmd
);
1459 install_element(OSPF6_NODE
, &area_filter_list_cmd
);
1460 install_element(OSPF6_NODE
, &no_area_filter_list_cmd
);
1462 /* "area nssa" commands. */
1463 install_element(OSPF6_NODE
, &ospf6_area_nssa_cmd
);
1464 install_element(OSPF6_NODE
, &no_ospf6_area_nssa_cmd
);
1467 void ospf6_area_interface_delete(struct ospf6_interface
*oi
)
1469 struct ospf6_area
*oa
;
1470 struct listnode
*node
, *nnode
;
1471 struct ospf6
*ospf6
;
1473 for (ALL_LIST_ELEMENTS(om6
->ospf6
, node
, nnode
, ospf6
)) {
1474 for (ALL_LIST_ELEMENTS(ospf6
->area_list
, node
, nnode
, oa
))
1475 if (listnode_lookup(oa
->if_list
, oi
))
1476 listnode_delete(oa
->if_list
, oi
);