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"
48 int ospf6_area_cmp(void *va
, void *vb
)
50 struct ospf6_area
*oa
= (struct ospf6_area
*)va
;
51 struct ospf6_area
*ob
= (struct ospf6_area
*)vb
;
52 return (ntohl(oa
->area_id
) < ntohl(ob
->area_id
) ? -1 : 1);
55 /* schedule routing table recalculation */
56 static void ospf6_area_lsdb_hook_add(struct ospf6_lsa
*lsa
)
58 switch (ntohs(lsa
->header
->type
)) {
59 case OSPF6_LSTYPE_ROUTER
:
60 case OSPF6_LSTYPE_NETWORK
:
61 if (IS_OSPF6_DEBUG_EXAMIN_TYPE(lsa
->header
->type
)) {
62 zlog_debug("Examin %s", lsa
->name
);
63 zlog_debug("Schedule SPF Calculation for %s",
64 OSPF6_AREA(lsa
->lsdb
->data
)->name
);
67 OSPF6_PROCESS(OSPF6_AREA(lsa
->lsdb
->data
)->ospf6
),
68 ospf6_lsadd_to_spf_reason(lsa
));
71 case OSPF6_LSTYPE_INTRA_PREFIX
:
72 ospf6_intra_prefix_lsa_add(lsa
);
75 case OSPF6_LSTYPE_INTER_PREFIX
:
76 case OSPF6_LSTYPE_INTER_ROUTER
:
77 ospf6_abr_examin_summary(lsa
,
78 (struct ospf6_area
*)lsa
->lsdb
->data
);
86 static void ospf6_area_lsdb_hook_remove(struct ospf6_lsa
*lsa
)
88 switch (ntohs(lsa
->header
->type
)) {
89 case OSPF6_LSTYPE_ROUTER
:
90 case OSPF6_LSTYPE_NETWORK
:
91 if (IS_OSPF6_DEBUG_EXAMIN_TYPE(lsa
->header
->type
)) {
92 zlog_debug("LSA disappearing: %s", lsa
->name
);
93 zlog_debug("Schedule SPF Calculation for %s",
94 OSPF6_AREA(lsa
->lsdb
->data
)->name
);
97 OSPF6_PROCESS(OSPF6_AREA(lsa
->lsdb
->data
)->ospf6
),
98 ospf6_lsremove_to_spf_reason(lsa
));
101 case OSPF6_LSTYPE_INTRA_PREFIX
:
102 ospf6_intra_prefix_lsa_remove(lsa
);
105 case OSPF6_LSTYPE_INTER_PREFIX
:
106 case OSPF6_LSTYPE_INTER_ROUTER
:
107 ospf6_abr_examin_summary(lsa
,
108 (struct ospf6_area
*)lsa
->lsdb
->data
);
116 static void ospf6_area_route_hook_add(struct ospf6_route
*route
)
118 struct ospf6_route
*copy
= ospf6_route_copy(route
);
119 ospf6_route_add(copy
, ospf6
->route_table
);
122 static void ospf6_area_route_hook_remove(struct ospf6_route
*route
)
124 struct ospf6_route
*copy
;
126 copy
= ospf6_route_lookup_identical(route
, ospf6
->route_table
);
128 ospf6_route_remove(copy
, ospf6
->route_table
);
131 static void ospf6_area_stub_update(struct ospf6_area
*area
)
134 if (IS_AREA_STUB(area
)) {
135 if (IS_OSPF6_DEBUG_ORIGINATE(ROUTER
))
136 zlog_debug("Stubbing out area for if %s\n", area
->name
);
137 OSPF6_OPT_CLEAR(area
->options
, OSPF6_OPT_E
);
138 } else if (IS_AREA_ENABLED(area
)) {
139 if (IS_OSPF6_DEBUG_ORIGINATE(ROUTER
))
140 zlog_debug("Normal area for if %s\n", area
->name
);
141 OSPF6_OPT_SET(area
->options
, OSPF6_OPT_E
);
142 ospf6_asbr_send_externals_to_area(area
);
145 OSPF6_ROUTER_LSA_SCHEDULE(area
);
148 static int ospf6_area_stub_set(struct ospf6
*ospf6
, struct ospf6_area
*area
)
150 if (!IS_AREA_STUB(area
)) {
151 SET_FLAG(area
->flag
, OSPF6_AREA_STUB
);
152 ospf6_area_stub_update(area
);
158 static void ospf6_area_stub_unset(struct ospf6
*ospf6
, struct ospf6_area
*area
)
160 if (IS_AREA_STUB(area
)) {
161 UNSET_FLAG(area
->flag
, OSPF6_AREA_STUB
);
162 ospf6_area_stub_update(area
);
166 static void ospf6_area_no_summary_set(struct ospf6
*ospf6
,
167 struct ospf6_area
*area
)
170 if (!area
->no_summary
) {
171 area
->no_summary
= 1;
172 ospf6_abr_range_reset_cost(ospf6
);
173 ospf6_abr_prefix_resummarize(ospf6
);
178 static void ospf6_area_no_summary_unset(struct ospf6
*ospf6
,
179 struct ospf6_area
*area
)
182 if (area
->no_summary
) {
183 area
->no_summary
= 0;
184 ospf6_abr_range_reset_cost(ospf6
);
185 ospf6_abr_prefix_resummarize(ospf6
);
191 * Make new area structure.
193 * @param area_id - ospf6 area ID
194 * @param o - ospf6 instance
195 * @param df - display format for area ID
197 struct ospf6_area
*ospf6_area_create(u_int32_t area_id
, struct ospf6
*o
, int df
)
199 struct ospf6_area
*oa
;
201 oa
= XCALLOC(MTYPE_OSPF6_AREA
, sizeof(struct ospf6_area
));
204 case OSPF6_AREA_FMT_DECIMAL
:
205 snprintf(oa
->name
, sizeof(oa
->name
), "%u", ntohl(area_id
));
208 case OSPF6_AREA_FMT_DOTTEDQUAD
:
209 inet_ntop(AF_INET
, &area_id
, oa
->name
, sizeof(oa
->name
));
213 oa
->area_id
= area_id
;
214 oa
->if_list
= list_new();
216 oa
->lsdb
= ospf6_lsdb_create(oa
);
217 oa
->lsdb
->hook_add
= ospf6_area_lsdb_hook_add
;
218 oa
->lsdb
->hook_remove
= ospf6_area_lsdb_hook_remove
;
219 oa
->lsdb_self
= ospf6_lsdb_create(oa
);
221 oa
->spf_table
= OSPF6_ROUTE_TABLE_CREATE(AREA
, SPF_RESULTS
);
222 oa
->spf_table
->scope
= oa
;
223 oa
->route_table
= OSPF6_ROUTE_TABLE_CREATE(AREA
, ROUTES
);
224 oa
->route_table
->scope
= oa
;
225 oa
->route_table
->hook_add
= ospf6_area_route_hook_add
;
226 oa
->route_table
->hook_remove
= ospf6_area_route_hook_remove
;
228 oa
->range_table
= OSPF6_ROUTE_TABLE_CREATE(AREA
, PREFIX_RANGES
);
229 oa
->range_table
->scope
= oa
;
230 bf_init(oa
->range_table
->idspace
, 32);
231 oa
->summary_prefix
= OSPF6_ROUTE_TABLE_CREATE(AREA
, SUMMARY_PREFIXES
);
232 oa
->summary_prefix
->scope
= oa
;
233 oa
->summary_router
= OSPF6_ROUTE_TABLE_CREATE(AREA
, SUMMARY_ROUTERS
);
234 oa
->summary_router
->scope
= oa
;
236 /* set default options */
237 if (CHECK_FLAG(o
->flag
, OSPF6_STUB_ROUTER
)) {
238 OSPF6_OPT_CLEAR(oa
->options
, OSPF6_OPT_V6
);
239 OSPF6_OPT_CLEAR(oa
->options
, OSPF6_OPT_R
);
241 OSPF6_OPT_SET(oa
->options
, OSPF6_OPT_V6
);
242 OSPF6_OPT_SET(oa
->options
, OSPF6_OPT_R
);
245 OSPF6_OPT_SET(oa
->options
, OSPF6_OPT_E
);
247 SET_FLAG(oa
->flag
, OSPF6_AREA_ACTIVE
);
248 SET_FLAG(oa
->flag
, OSPF6_AREA_ENABLE
);
251 listnode_add_sort(o
->area_list
, oa
);
253 if (area_id
== OSPF_AREA_BACKBONE
) {
260 void ospf6_area_delete(struct ospf6_area
*oa
)
263 struct ospf6_interface
*oi
;
265 /* The ospf6_interface structs store configuration
266 * information which should not be lost/reset when
268 * So just detach the interface from the area and
270 for (ALL_LIST_ELEMENTS_RO(oa
->if_list
, n
, oi
))
273 list_delete(oa
->if_list
);
275 ospf6_lsdb_delete(oa
->lsdb
);
276 ospf6_lsdb_delete(oa
->lsdb_self
);
278 ospf6_spf_table_finish(oa
->spf_table
);
279 ospf6_route_table_delete(oa
->spf_table
);
280 ospf6_route_table_delete(oa
->route_table
);
282 ospf6_route_table_delete(oa
->range_table
);
283 ospf6_route_table_delete(oa
->summary_prefix
);
284 ospf6_route_table_delete(oa
->summary_router
);
286 listnode_delete(oa
->ospf6
->area_list
, oa
);
290 XFREE(MTYPE_OSPF6_AREA
, oa
);
293 struct ospf6_area
*ospf6_area_lookup(u_int32_t area_id
, struct ospf6
*ospf6
)
295 struct ospf6_area
*oa
;
298 for (ALL_LIST_ELEMENTS_RO(ospf6
->area_list
, n
, oa
))
299 if (oa
->area_id
== area_id
)
302 return (struct ospf6_area
*)NULL
;
305 void ospf6_area_enable(struct ospf6_area
*oa
)
307 struct listnode
*node
, *nnode
;
308 struct ospf6_interface
*oi
;
310 SET_FLAG(oa
->flag
, OSPF6_AREA_ENABLE
);
312 for (ALL_LIST_ELEMENTS(oa
->if_list
, node
, nnode
, oi
))
313 ospf6_interface_enable(oi
);
314 ospf6_abr_enable_area(oa
);
317 void ospf6_area_disable(struct ospf6_area
*oa
)
319 struct listnode
*node
, *nnode
;
320 struct ospf6_interface
*oi
;
322 UNSET_FLAG(oa
->flag
, OSPF6_AREA_ENABLE
);
324 for (ALL_LIST_ELEMENTS(oa
->if_list
, node
, nnode
, oi
))
325 ospf6_interface_disable(oi
);
327 ospf6_abr_disable_area(oa
);
328 ospf6_lsdb_remove_all(oa
->lsdb
);
329 ospf6_lsdb_remove_all(oa
->lsdb_self
);
331 ospf6_spf_table_finish(oa
->spf_table
);
332 ospf6_route_remove_all(oa
->route_table
);
334 THREAD_OFF(oa
->thread_router_lsa
);
335 THREAD_OFF(oa
->thread_intra_prefix_lsa
);
339 void ospf6_area_show(struct vty
*vty
, struct ospf6_area
*oa
)
342 struct ospf6_interface
*oi
;
343 unsigned long result
;
345 if (!IS_AREA_STUB(oa
))
346 vty_out(vty
, " Area %s\n", oa
->name
);
348 if (oa
->no_summary
) {
349 vty_out(vty
, " Area %s[Stub, No Summary]\n", oa
->name
);
351 vty_out(vty
, " Area %s[Stub]\n", oa
->name
);
354 vty_out(vty
, " Number of Area scoped LSAs is %u\n",
357 vty_out(vty
, " Interface attached to this area:");
358 for (ALL_LIST_ELEMENTS_RO(oa
->if_list
, i
, oi
))
359 vty_out(vty
, " %s", oi
->interface
->name
);
362 if (oa
->ts_spf
.tv_sec
|| oa
->ts_spf
.tv_usec
) {
363 result
= monotime_since(&oa
->ts_spf
, NULL
);
364 if (result
/ TIMER_SECOND_MICRO
> 0) {
365 vty_out(vty
, "SPF last executed %ld.%lds ago\n",
366 result
/ TIMER_SECOND_MICRO
,
367 result
% TIMER_SECOND_MICRO
);
369 vty_out(vty
, "SPF last executed %ldus ago\n", result
);
372 vty_out(vty
, "SPF has not been run\n");
376 #define OSPF6_CMD_AREA_GET(str, oa) \
379 u_int32_t area_id = htonl(strtoul(str, &ep, 10)); \
380 if (*ep && inet_pton(AF_INET, str, &area_id) != 1) { \
381 vty_out(vty, "Malformed Area-ID: %s\n", str); \
382 return CMD_SUCCESS; \
384 int format = !*ep ? OSPF6_AREA_FMT_DECIMAL \
385 : OSPF6_AREA_FMT_DOTTEDQUAD; \
386 oa = ospf6_area_lookup(area_id, ospf6); \
388 oa = ospf6_area_create(area_id, ospf6, format); \
393 "area <A.B.C.D|(0-4294967295)> range X:X::X:X/M [<advertise|not-advertise|cost (0-16777215)>]",
394 "OSPF6 area parameters\n"
395 "OSPF6 area ID in IP address format\n"
396 "OSPF6 area ID as a decimal value\n"
397 "Configured address range\n"
398 "Specify IPv6 prefix\n"
401 "User specified metric for this range\n"
402 "Advertised metric for this range\n")
405 int idx_ipv6_prefixlen
= 3;
408 struct ospf6_area
*oa
;
409 struct prefix prefix
;
410 struct ospf6_route
*range
;
411 u_int32_t cost
= OSPF_AREA_RANGE_COST_UNSPEC
;
413 OSPF6_CMD_AREA_GET(argv
[idx_ipv4
]->arg
, oa
);
415 ret
= str2prefix(argv
[idx_ipv6_prefixlen
]->arg
, &prefix
);
416 if (ret
!= 1 || prefix
.family
!= AF_INET6
) {
417 vty_out(vty
, "Malformed argument: %s\n",
418 argv
[idx_ipv6_prefixlen
]->arg
);
422 range
= ospf6_route_lookup(&prefix
, oa
->range_table
);
424 range
= ospf6_route_create();
425 range
->type
= OSPF6_DEST_TYPE_RANGE
;
426 range
->prefix
= prefix
;
427 range
->path
.area_id
= oa
->area_id
;
428 range
->path
.cost
= OSPF_AREA_RANGE_COST_UNSPEC
;
431 if (argc
> idx_type
) {
432 if (strmatch(argv
[idx_type
]->text
, "not-advertise")) {
433 SET_FLAG(range
->flag
, OSPF6_ROUTE_DO_NOT_ADVERTISE
);
434 } else if (strmatch(argv
[idx_type
]->text
, "advertise")) {
435 UNSET_FLAG(range
->flag
, OSPF6_ROUTE_DO_NOT_ADVERTISE
);
437 cost
= strtoul(argv
[5]->arg
, NULL
, 10);
438 UNSET_FLAG(range
->flag
, OSPF6_ROUTE_DO_NOT_ADVERTISE
);
442 range
->path
.u
.cost_config
= cost
;
444 zlog_debug("%s: for prefix %s, flag = %x\n", __func__
,
445 argv
[idx_ipv6_prefixlen
]->arg
, range
->flag
);
446 if (range
->rnode
== NULL
) {
447 ospf6_route_add(range
, oa
->range_table
);
450 if (ospf6_is_router_abr(ospf6
)) {
451 /* Redo summaries if required */
452 ospf6_abr_prefix_resummarize(ospf6
);
458 DEFUN (no_area_range
,
460 "no area <A.B.C.D|(0-4294967295)> range X:X::X:X/M [<advertise|not-advertise|cost (0-16777215)>]",
462 "OSPF6 area parameters\n"
463 "OSPF6 area ID in IP address format\n"
464 "OSPF6 area ID as a decimal value\n"
465 "Configured address range\n"
466 "Specify IPv6 prefix\n"
469 "User specified metric for this range\n"
470 "Advertised metric for this range\n")
475 struct ospf6_area
*oa
;
476 struct prefix prefix
;
477 struct ospf6_route
*range
, *route
;
479 OSPF6_CMD_AREA_GET(argv
[idx_ipv4
]->arg
, oa
);
481 ret
= str2prefix(argv
[idx_ipv6
]->arg
, &prefix
);
482 if (ret
!= 1 || prefix
.family
!= AF_INET6
) {
483 vty_out(vty
, "Malformed argument: %s\n", argv
[idx_ipv6
]->arg
);
487 range
= ospf6_route_lookup(&prefix
, oa
->range_table
);
489 vty_out(vty
, "Range %s does not exists.\n",
490 argv
[idx_ipv6
]->arg
);
494 if (ospf6_is_router_abr(oa
->ospf6
)) {
495 /* Blow away the aggregated LSA and route */
496 SET_FLAG(range
->flag
, OSPF6_ROUTE_REMOVE
);
498 /* Redo summaries if required */
499 for (route
= ospf6_route_head(ospf6
->route_table
); route
;
500 route
= ospf6_route_next(route
))
501 ospf6_abr_originate_summary(route
);
503 /* purge the old aggregated summary LSA */
504 ospf6_abr_originate_summary(range
);
506 ospf6_route_remove(range
, oa
->range_table
);
511 void ospf6_area_config_write(struct vty
*vty
)
513 struct listnode
*node
;
514 struct ospf6_area
*oa
;
515 struct ospf6_route
*range
;
516 char buf
[PREFIX2STR_BUFFER
];
518 for (ALL_LIST_ELEMENTS_RO(ospf6
->area_list
, node
, oa
)) {
519 for (range
= ospf6_route_head(oa
->range_table
); range
;
520 range
= ospf6_route_next(range
)) {
521 prefix2str(&range
->prefix
, buf
, sizeof(buf
));
522 vty_out(vty
, " area %s range %s", oa
->name
, buf
);
524 if (CHECK_FLAG(range
->flag
,
525 OSPF6_ROUTE_DO_NOT_ADVERTISE
)) {
526 vty_out(vty
, " not-advertise");
528 // "advertise" is the default so we do not
530 if (range
->path
.u
.cost_config
531 != OSPF_AREA_RANGE_COST_UNSPEC
)
532 vty_out(vty
, " cost %d",
533 range
->path
.u
.cost_config
);
537 if (IS_AREA_STUB(oa
)) {
539 vty_out(vty
, " area %s stub no-summary\n",
542 vty_out(vty
, " area %s stub\n", oa
->name
);
544 if (PREFIX_NAME_IN(oa
))
545 vty_out(vty
, " area %s filter-list prefix %s in\n",
546 oa
->name
, PREFIX_NAME_IN(oa
));
547 if (PREFIX_NAME_OUT(oa
))
548 vty_out(vty
, " area %s filter-list prefix %s out\n",
549 oa
->name
, PREFIX_NAME_OUT(oa
));
551 vty_out(vty
, " area %s import-list %s\n", oa
->name
,
554 vty_out(vty
, " area %s export-list %s\n", oa
->name
,
559 DEFUN (area_filter_list
,
560 area_filter_list_cmd
,
561 "area A.B.C.D filter-list prefix WORD <in|out>",
562 "OSPF6 area parameters\n"
563 "OSPF6 area ID in IP address format\n"
564 "Filter networks between OSPF6 areas\n"
565 "Filter prefixes between OSPF6 areas\n"
566 "Name of an IPv6 prefix-list\n"
567 "Filter networks sent to this area\n"
568 "Filter networks sent from this area\n")
570 char *inout
= argv
[argc
- 1]->text
;
571 char *areaid
= argv
[1]->arg
;
572 char *plistname
= argv
[4]->arg
;
574 struct ospf6_area
*area
;
575 struct prefix_list
*plist
;
577 OSPF6_CMD_AREA_GET(areaid
, area
);
579 plist
= prefix_list_lookup(AFI_IP6
, plistname
);
580 if (strmatch(inout
, "in")) {
581 PREFIX_LIST_IN(area
) = plist
;
582 if (PREFIX_NAME_IN(area
))
583 free(PREFIX_NAME_IN(area
));
585 PREFIX_NAME_IN(area
) = strdup(plistname
);
586 ospf6_abr_reimport(area
);
588 PREFIX_LIST_OUT(area
) = plist
;
589 if (PREFIX_NAME_OUT(area
))
590 free(PREFIX_NAME_OUT(area
));
592 PREFIX_NAME_OUT(area
) = strdup(plistname
);
593 ospf6_abr_enable_area(area
);
599 DEFUN (no_area_filter_list
,
600 no_area_filter_list_cmd
,
601 "no area A.B.C.D filter-list prefix WORD <in|out>",
603 "OSPF6 area parameters\n"
604 "OSPF6 area ID in IP address format\n"
605 "Filter networks between OSPF6 areas\n"
606 "Filter prefixes between OSPF6 areas\n"
607 "Name of an IPv6 prefix-list\n"
608 "Filter networks sent to this area\n"
609 "Filter networks sent from this area\n")
611 char *inout
= argv
[argc
- 1]->text
;
612 char *areaid
= argv
[2]->arg
;
613 char *plistname
= argv
[5]->arg
;
615 struct ospf6_area
*area
;
617 OSPF6_CMD_AREA_GET(areaid
, area
);
619 if (strmatch(inout
, "in")) {
620 if (PREFIX_NAME_IN(area
))
621 if (!strmatch(PREFIX_NAME_IN(area
), plistname
))
624 PREFIX_LIST_IN(area
) = NULL
;
625 if (PREFIX_NAME_IN(area
))
626 free(PREFIX_NAME_IN(area
));
628 PREFIX_NAME_IN(area
) = NULL
;
629 ospf6_abr_reimport(area
);
631 if (PREFIX_NAME_OUT(area
))
632 if (!strmatch(PREFIX_NAME_OUT(area
), plistname
))
635 PREFIX_LIST_OUT(area
) = NULL
;
636 if (PREFIX_NAME_OUT(area
))
637 free(PREFIX_NAME_OUT(area
));
639 PREFIX_NAME_OUT(area
) = NULL
;
640 ospf6_abr_enable_area(area
);
646 DEFUN (area_import_list
,
647 area_import_list_cmd
,
648 "area A.B.C.D import-list NAME",
649 "OSPF6 area parameters\n"
650 "OSPF6 area ID in IP address format\n"
651 "Set the filter for networks from other areas announced to the specified one\n"
652 "Name of the acess-list\n")
656 struct ospf6_area
*area
;
657 struct access_list
*list
;
659 OSPF6_CMD_AREA_GET(argv
[idx_ipv4
]->arg
, area
);
661 list
= access_list_lookup(AFI_IP6
, argv
[idx_name
]->arg
);
663 IMPORT_LIST(area
) = list
;
665 if (IMPORT_NAME(area
))
666 free(IMPORT_NAME(area
));
668 IMPORT_NAME(area
) = strdup(argv
[idx_name
]->arg
);
669 ospf6_abr_reimport(area
);
674 DEFUN (no_area_import_list
,
675 no_area_import_list_cmd
,
676 "no area A.B.C.D import-list NAME",
678 "OSPF6 area parameters\n"
679 "OSPF6 area ID in IP address format\n"
680 "Unset the filter for networks announced to other areas\n"
681 "Name of the access-list\n")
684 struct ospf6_area
*area
;
686 OSPF6_CMD_AREA_GET(argv
[idx_ipv4
]->arg
, area
);
688 IMPORT_LIST(area
) = 0;
690 if (IMPORT_NAME(area
))
691 free(IMPORT_NAME(area
));
693 IMPORT_NAME(area
) = NULL
;
694 ospf6_abr_reimport(area
);
699 DEFUN (area_export_list
,
700 area_export_list_cmd
,
701 "area A.B.C.D export-list NAME",
702 "OSPF6 area parameters\n"
703 "OSPF6 area ID in IP address format\n"
704 "Set the filter for networks announced to other areas\n"
705 "Name of the acess-list\n")
709 struct ospf6_area
*area
;
710 struct access_list
*list
;
712 OSPF6_CMD_AREA_GET(argv
[idx_ipv4
]->arg
, area
);
714 list
= access_list_lookup(AFI_IP6
, argv
[idx_name
]->arg
);
716 EXPORT_LIST(area
) = list
;
718 if (EXPORT_NAME(area
))
719 free(EXPORT_NAME(area
));
721 EXPORT_NAME(area
) = strdup(argv
[idx_name
]->arg
);
722 ospf6_abr_enable_area(area
);
727 DEFUN (no_area_export_list
,
728 no_area_export_list_cmd
,
729 "no area A.B.C.D export-list NAME",
731 "OSPF6 area parameters\n"
732 "OSPF6 area ID in IP address format\n"
733 "Unset the filter for networks announced to other areas\n"
734 "Name of the access-list\n")
737 struct ospf6_area
*area
;
739 OSPF6_CMD_AREA_GET(argv
[idx_ipv4
]->arg
, area
);
741 EXPORT_LIST(area
) = 0;
743 if (EXPORT_NAME(area
))
744 free(EXPORT_NAME(area
));
746 EXPORT_NAME(area
) = NULL
;
747 ospf6_abr_enable_area(area
);
752 DEFUN (show_ipv6_ospf6_spf_tree
,
753 show_ipv6_ospf6_spf_tree_cmd
,
754 "show ipv6 ospf6 spf tree",
758 "Shortest Path First caculation\n"
761 struct listnode
*node
;
762 struct ospf6_area
*oa
;
763 struct ospf6_vertex
*root
;
764 struct ospf6_route
*route
;
765 struct prefix prefix
;
767 OSPF6_CMD_CHECK_RUNNING();
769 ospf6_linkstate_prefix(ospf6
->router_id
, htonl(0), &prefix
);
771 for (ALL_LIST_ELEMENTS_RO(ospf6
->area_list
, node
, oa
)) {
772 route
= ospf6_route_lookup(&prefix
, oa
->spf_table
);
774 vty_out(vty
, "LS entry for root not found in area %s\n",
778 root
= (struct ospf6_vertex
*)route
->route_option
;
779 ospf6_spf_display_subtree(vty
, "", 0, root
);
785 DEFUN (show_ipv6_ospf6_area_spf_tree
,
786 show_ipv6_ospf6_area_spf_tree_cmd
,
787 "show ipv6 ospf6 area A.B.C.D spf tree",
793 "Shortest Path First caculation\n"
798 struct ospf6_area
*oa
;
799 struct ospf6_vertex
*root
;
800 struct ospf6_route
*route
;
801 struct prefix prefix
;
803 OSPF6_CMD_CHECK_RUNNING();
805 ospf6_linkstate_prefix(ospf6
->router_id
, htonl(0), &prefix
);
807 if (inet_pton(AF_INET
, argv
[idx_ipv4
]->arg
, &area_id
) != 1) {
808 vty_out(vty
, "Malformed Area-ID: %s\n", argv
[idx_ipv4
]->arg
);
811 oa
= ospf6_area_lookup(area_id
, ospf6
);
813 vty_out(vty
, "No such Area: %s\n", argv
[idx_ipv4
]->arg
);
817 route
= ospf6_route_lookup(&prefix
, oa
->spf_table
);
819 vty_out(vty
, "LS entry for root not found in area %s\n",
823 root
= (struct ospf6_vertex
*)route
->route_option
;
824 ospf6_spf_display_subtree(vty
, "", 0, root
);
829 DEFUN (show_ipv6_ospf6_simulate_spf_tree_root
,
830 show_ipv6_ospf6_simulate_spf_tree_root_cmd
,
831 "show ipv6 ospf6 simulate spf-tree A.B.C.D area A.B.C.D",
835 "Shortest Path First calculation\n"
837 "Specify root's router-id to calculate another router's SPF tree\n"
838 "OSPF6 area parameters\n"
844 struct ospf6_area
*oa
;
845 struct ospf6_vertex
*root
;
846 struct ospf6_route
*route
;
847 struct prefix prefix
;
849 struct ospf6_route_table
*spf_table
;
850 unsigned char tmp_debug_ospf6_spf
= 0;
852 OSPF6_CMD_CHECK_RUNNING();
854 inet_pton(AF_INET
, argv
[idx_ipv4
]->arg
, &router_id
);
855 ospf6_linkstate_prefix(router_id
, htonl(0), &prefix
);
857 if (inet_pton(AF_INET
, argv
[idx_ipv4_2
]->arg
, &area_id
) != 1) {
858 vty_out(vty
, "Malformed Area-ID: %s\n", argv
[idx_ipv4_2
]->arg
);
861 oa
= ospf6_area_lookup(area_id
, ospf6
);
863 vty_out(vty
, "No such Area: %s\n", argv
[idx_ipv4_2
]->arg
);
867 tmp_debug_ospf6_spf
= conf_debug_ospf6_spf
;
868 conf_debug_ospf6_spf
= 0;
870 spf_table
= OSPF6_ROUTE_TABLE_CREATE(NONE
, SPF_RESULTS
);
871 ospf6_spf_calculation(router_id
, spf_table
, oa
);
873 conf_debug_ospf6_spf
= tmp_debug_ospf6_spf
;
875 route
= ospf6_route_lookup(&prefix
, spf_table
);
877 ospf6_spf_table_finish(spf_table
);
878 ospf6_route_table_delete(spf_table
);
881 root
= (struct ospf6_vertex
*)route
->route_option
;
882 ospf6_spf_display_subtree(vty
, "", 0, root
);
884 ospf6_spf_table_finish(spf_table
);
885 ospf6_route_table_delete(spf_table
);
890 DEFUN (ospf6_area_stub
,
892 "area <A.B.C.D|(0-4294967295)> stub",
893 "OSPF6 area parameters\n"
894 "OSPF6 area ID in IP address format\n"
895 "OSPF6 area ID as a decimal value\n"
896 "Configure OSPF6 area as stub\n")
898 int idx_ipv4_number
= 1;
899 struct ospf6_area
*area
;
901 OSPF6_CMD_AREA_GET(argv
[idx_ipv4_number
]->arg
, area
);
903 if (!ospf6_area_stub_set(ospf6
, area
)) {
905 "First deconfigure all virtual link through this area\n");
906 return CMD_WARNING_CONFIG_FAILED
;
909 ospf6_area_no_summary_unset(ospf6
, area
);
914 DEFUN (ospf6_area_stub_no_summary
,
915 ospf6_area_stub_no_summary_cmd
,
916 "area <A.B.C.D|(0-4294967295)> stub no-summary",
917 "OSPF6 stub parameters\n"
918 "OSPF6 area ID in IP address format\n"
919 "OSPF6 area ID as a decimal value\n"
920 "Configure OSPF6 area as stub\n"
921 "Do not inject inter-area routes into stub\n")
923 int idx_ipv4_number
= 1;
924 struct ospf6_area
*area
;
926 OSPF6_CMD_AREA_GET(argv
[idx_ipv4_number
]->arg
, area
);
928 if (!ospf6_area_stub_set(ospf6
, area
)) {
930 "First deconfigure all virtual link through this area\n");
931 return CMD_WARNING_CONFIG_FAILED
;
934 ospf6_area_no_summary_set(ospf6
, area
);
939 DEFUN (no_ospf6_area_stub
,
940 no_ospf6_area_stub_cmd
,
941 "no area <A.B.C.D|(0-4294967295)> stub",
943 "OSPF6 area parameters\n"
944 "OSPF6 area ID in IP address format\n"
945 "OSPF6 area ID as a decimal value\n"
946 "Configure OSPF6 area as stub\n")
948 int idx_ipv4_number
= 2;
949 struct ospf6_area
*area
;
951 OSPF6_CMD_AREA_GET(argv
[idx_ipv4_number
]->arg
, area
);
953 ospf6_area_stub_unset(ospf6
, area
);
954 ospf6_area_no_summary_unset(ospf6
, area
);
959 DEFUN (no_ospf6_area_stub_no_summary
,
960 no_ospf6_area_stub_no_summary_cmd
,
961 "no area <A.B.C.D|(0-4294967295)> stub no-summary",
963 "OSPF6 area parameters\n"
964 "OSPF6 area ID in IP address format\n"
965 "OSPF6 area ID as a decimal value\n"
966 "Configure OSPF6 area as stub\n"
967 "Do not inject inter-area routes into area\n")
969 int idx_ipv4_number
= 2;
970 struct ospf6_area
*area
;
972 OSPF6_CMD_AREA_GET(argv
[idx_ipv4_number
]->arg
, area
);
974 ospf6_area_stub_unset(ospf6
, area
);
975 ospf6_area_no_summary_unset(ospf6
, area
);
980 void ospf6_area_init(void)
982 install_element(VIEW_NODE
, &show_ipv6_ospf6_spf_tree_cmd
);
983 install_element(VIEW_NODE
, &show_ipv6_ospf6_area_spf_tree_cmd
);
984 install_element(VIEW_NODE
, &show_ipv6_ospf6_simulate_spf_tree_root_cmd
);
986 install_element(OSPF6_NODE
, &area_range_cmd
);
987 install_element(OSPF6_NODE
, &no_area_range_cmd
);
988 install_element(OSPF6_NODE
, &ospf6_area_stub_no_summary_cmd
);
989 install_element(OSPF6_NODE
, &ospf6_area_stub_cmd
);
990 install_element(OSPF6_NODE
, &no_ospf6_area_stub_no_summary_cmd
);
991 install_element(OSPF6_NODE
, &no_ospf6_area_stub_cmd
);
994 install_element(OSPF6_NODE
, &area_import_list_cmd
);
995 install_element(OSPF6_NODE
, &no_area_import_list_cmd
);
996 install_element(OSPF6_NODE
, &area_export_list_cmd
);
997 install_element(OSPF6_NODE
, &no_area_export_list_cmd
);
999 install_element(OSPF6_NODE
, &area_filter_list_cmd
);
1000 install_element(OSPF6_NODE
, &no_area_filter_list_cmd
);