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 DEFINE_MTYPE_STATIC(OSPF6D
, OSPF6_PLISTNAME
, "Prefix list name")
50 int ospf6_area_cmp(void *va
, void *vb
)
52 struct ospf6_area
*oa
= (struct ospf6_area
*)va
;
53 struct ospf6_area
*ob
= (struct ospf6_area
*)vb
;
54 return (ntohl(oa
->area_id
) < ntohl(ob
->area_id
) ? -1 : 1);
57 /* schedule routing table recalculation */
58 static void ospf6_area_lsdb_hook_add(struct ospf6_lsa
*lsa
)
60 switch (ntohs(lsa
->header
->type
)) {
61 case OSPF6_LSTYPE_ROUTER
:
62 case OSPF6_LSTYPE_NETWORK
:
63 if (IS_OSPF6_DEBUG_EXAMIN_TYPE(lsa
->header
->type
)) {
64 zlog_debug("Examin %s", lsa
->name
);
65 zlog_debug("Schedule SPF Calculation for %s",
66 OSPF6_AREA(lsa
->lsdb
->data
)->name
);
69 OSPF6_PROCESS(OSPF6_AREA(lsa
->lsdb
->data
)->ospf6
),
70 ospf6_lsadd_to_spf_reason(lsa
));
73 case OSPF6_LSTYPE_INTRA_PREFIX
:
74 ospf6_intra_prefix_lsa_add(lsa
);
77 case OSPF6_LSTYPE_INTER_PREFIX
:
78 case OSPF6_LSTYPE_INTER_ROUTER
:
79 ospf6_abr_examin_summary(lsa
,
80 (struct ospf6_area
*)lsa
->lsdb
->data
);
88 static void ospf6_area_lsdb_hook_remove(struct ospf6_lsa
*lsa
)
90 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("LSA disappearing: %s", 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_lsremove_to_spf_reason(lsa
));
103 case OSPF6_LSTYPE_INTRA_PREFIX
:
104 ospf6_intra_prefix_lsa_remove(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
);
118 static void ospf6_area_route_hook_add(struct ospf6_route
*route
)
120 struct ospf6_route
*copy
= ospf6_route_copy(route
);
121 ospf6_route_add(copy
, ospf6
->route_table
);
124 static void ospf6_area_route_hook_remove(struct ospf6_route
*route
)
126 struct ospf6_route
*copy
;
128 copy
= ospf6_route_lookup_identical(route
, ospf6
->route_table
);
130 ospf6_route_remove(copy
, ospf6
->route_table
);
133 static void ospf6_area_stub_update(struct ospf6_area
*area
)
136 if (IS_AREA_STUB(area
)) {
137 if (IS_OSPF6_DEBUG_ORIGINATE(ROUTER
))
138 zlog_debug("Stubbing out area for if %s\n", area
->name
);
139 OSPF6_OPT_CLEAR(area
->options
, OSPF6_OPT_E
);
140 } else if (IS_AREA_ENABLED(area
)) {
141 if (IS_OSPF6_DEBUG_ORIGINATE(ROUTER
))
142 zlog_debug("Normal area for if %s\n", area
->name
);
143 OSPF6_OPT_SET(area
->options
, OSPF6_OPT_E
);
144 ospf6_asbr_send_externals_to_area(area
);
147 OSPF6_ROUTER_LSA_SCHEDULE(area
);
150 static int ospf6_area_stub_set(struct ospf6
*ospf6
, struct ospf6_area
*area
)
152 if (!IS_AREA_STUB(area
)) {
153 SET_FLAG(area
->flag
, OSPF6_AREA_STUB
);
154 ospf6_area_stub_update(area
);
160 static void ospf6_area_stub_unset(struct ospf6
*ospf6
, struct ospf6_area
*area
)
162 if (IS_AREA_STUB(area
)) {
163 UNSET_FLAG(area
->flag
, OSPF6_AREA_STUB
);
164 ospf6_area_stub_update(area
);
168 static void ospf6_area_no_summary_set(struct ospf6
*ospf6
,
169 struct ospf6_area
*area
)
172 if (!area
->no_summary
) {
173 area
->no_summary
= 1;
174 ospf6_abr_range_reset_cost(ospf6
);
175 ospf6_abr_prefix_resummarize(ospf6
);
180 static void ospf6_area_no_summary_unset(struct ospf6
*ospf6
,
181 struct ospf6_area
*area
)
184 if (area
->no_summary
) {
185 area
->no_summary
= 0;
186 ospf6_abr_range_reset_cost(ospf6
);
187 ospf6_abr_prefix_resummarize(ospf6
);
193 * Make new area structure.
195 * @param area_id - ospf6 area ID
196 * @param o - ospf6 instance
197 * @param df - display format for area ID
199 struct ospf6_area
*ospf6_area_create(u_int32_t area_id
, struct ospf6
*o
, int df
)
201 struct ospf6_area
*oa
;
203 oa
= XCALLOC(MTYPE_OSPF6_AREA
, sizeof(struct ospf6_area
));
206 case OSPF6_AREA_FMT_DECIMAL
:
207 snprintf(oa
->name
, sizeof(oa
->name
), "%u", ntohl(area_id
));
210 case OSPF6_AREA_FMT_DOTTEDQUAD
:
211 inet_ntop(AF_INET
, &area_id
, oa
->name
, sizeof(oa
->name
));
215 oa
->area_id
= area_id
;
216 oa
->if_list
= list_new();
218 oa
->lsdb
= ospf6_lsdb_create(oa
);
219 oa
->lsdb
->hook_add
= ospf6_area_lsdb_hook_add
;
220 oa
->lsdb
->hook_remove
= ospf6_area_lsdb_hook_remove
;
221 oa
->lsdb_self
= ospf6_lsdb_create(oa
);
223 oa
->spf_table
= OSPF6_ROUTE_TABLE_CREATE(AREA
, SPF_RESULTS
);
224 oa
->spf_table
->scope
= oa
;
225 oa
->route_table
= OSPF6_ROUTE_TABLE_CREATE(AREA
, ROUTES
);
226 oa
->route_table
->scope
= oa
;
227 oa
->route_table
->hook_add
= ospf6_area_route_hook_add
;
228 oa
->route_table
->hook_remove
= ospf6_area_route_hook_remove
;
230 oa
->range_table
= OSPF6_ROUTE_TABLE_CREATE(AREA
, PREFIX_RANGES
);
231 oa
->range_table
->scope
= oa
;
232 bf_init(oa
->range_table
->idspace
, 32);
233 oa
->summary_prefix
= OSPF6_ROUTE_TABLE_CREATE(AREA
, SUMMARY_PREFIXES
);
234 oa
->summary_prefix
->scope
= oa
;
235 oa
->summary_router
= OSPF6_ROUTE_TABLE_CREATE(AREA
, SUMMARY_ROUTERS
);
236 oa
->summary_router
->scope
= oa
;
238 /* set default options */
239 if (CHECK_FLAG(o
->flag
, OSPF6_STUB_ROUTER
)) {
240 OSPF6_OPT_CLEAR(oa
->options
, OSPF6_OPT_V6
);
241 OSPF6_OPT_CLEAR(oa
->options
, OSPF6_OPT_R
);
243 OSPF6_OPT_SET(oa
->options
, OSPF6_OPT_V6
);
244 OSPF6_OPT_SET(oa
->options
, OSPF6_OPT_R
);
247 OSPF6_OPT_SET(oa
->options
, OSPF6_OPT_E
);
249 SET_FLAG(oa
->flag
, OSPF6_AREA_ACTIVE
);
250 SET_FLAG(oa
->flag
, OSPF6_AREA_ENABLE
);
253 listnode_add_sort(o
->area_list
, oa
);
255 if (area_id
== OSPF_AREA_BACKBONE
) {
262 void ospf6_area_delete(struct ospf6_area
*oa
)
265 struct ospf6_interface
*oi
;
267 /* The ospf6_interface structs store configuration
268 * information which should not be lost/reset when
270 * So just detach the interface from the area and
272 for (ALL_LIST_ELEMENTS_RO(oa
->if_list
, n
, oi
))
275 list_delete_and_null(&oa
->if_list
);
277 ospf6_lsdb_delete(oa
->lsdb
);
278 ospf6_lsdb_delete(oa
->lsdb_self
);
280 ospf6_spf_table_finish(oa
->spf_table
);
281 ospf6_route_table_delete(oa
->spf_table
);
282 ospf6_route_table_delete(oa
->route_table
);
284 ospf6_route_table_delete(oa
->range_table
);
285 ospf6_route_table_delete(oa
->summary_prefix
);
286 ospf6_route_table_delete(oa
->summary_router
);
288 listnode_delete(oa
->ospf6
->area_list
, oa
);
292 XFREE(MTYPE_OSPF6_AREA
, oa
);
295 struct ospf6_area
*ospf6_area_lookup(u_int32_t area_id
, struct ospf6
*ospf6
)
297 struct ospf6_area
*oa
;
300 for (ALL_LIST_ELEMENTS_RO(ospf6
->area_list
, n
, oa
))
301 if (oa
->area_id
== area_id
)
304 return (struct ospf6_area
*)NULL
;
307 void ospf6_area_enable(struct ospf6_area
*oa
)
309 struct listnode
*node
, *nnode
;
310 struct ospf6_interface
*oi
;
312 SET_FLAG(oa
->flag
, OSPF6_AREA_ENABLE
);
314 for (ALL_LIST_ELEMENTS(oa
->if_list
, node
, nnode
, oi
))
315 ospf6_interface_enable(oi
);
316 ospf6_abr_enable_area(oa
);
319 void ospf6_area_disable(struct ospf6_area
*oa
)
321 struct listnode
*node
, *nnode
;
322 struct ospf6_interface
*oi
;
324 UNSET_FLAG(oa
->flag
, OSPF6_AREA_ENABLE
);
326 for (ALL_LIST_ELEMENTS(oa
->if_list
, node
, nnode
, oi
))
327 ospf6_interface_disable(oi
);
329 ospf6_abr_disable_area(oa
);
330 ospf6_lsdb_remove_all(oa
->lsdb
);
331 ospf6_lsdb_remove_all(oa
->lsdb_self
);
333 ospf6_spf_table_finish(oa
->spf_table
);
334 ospf6_route_remove_all(oa
->route_table
);
336 THREAD_OFF(oa
->thread_router_lsa
);
337 THREAD_OFF(oa
->thread_intra_prefix_lsa
);
341 void ospf6_area_show(struct vty
*vty
, struct ospf6_area
*oa
)
344 struct ospf6_interface
*oi
;
345 unsigned long result
;
347 if (!IS_AREA_STUB(oa
))
348 vty_out(vty
, " Area %s\n", oa
->name
);
350 if (oa
->no_summary
) {
351 vty_out(vty
, " Area %s[Stub, No Summary]\n", oa
->name
);
353 vty_out(vty
, " Area %s[Stub]\n", oa
->name
);
356 vty_out(vty
, " Number of Area scoped LSAs is %u\n",
359 vty_out(vty
, " Interface attached to this area:");
360 for (ALL_LIST_ELEMENTS_RO(oa
->if_list
, i
, oi
))
361 vty_out(vty
, " %s", oi
->interface
->name
);
364 if (oa
->ts_spf
.tv_sec
|| oa
->ts_spf
.tv_usec
) {
365 result
= monotime_since(&oa
->ts_spf
, NULL
);
366 if (result
/ TIMER_SECOND_MICRO
> 0) {
367 vty_out(vty
, "SPF last executed %ld.%lds ago\n",
368 result
/ TIMER_SECOND_MICRO
,
369 result
% TIMER_SECOND_MICRO
);
371 vty_out(vty
, "SPF last executed %ldus ago\n", result
);
374 vty_out(vty
, "SPF has not been run\n");
378 #define OSPF6_CMD_AREA_GET(str, oa) \
381 u_int32_t area_id = htonl(strtoul(str, &ep, 10)); \
382 if (*ep && inet_pton(AF_INET, str, &area_id) != 1) { \
383 vty_out(vty, "Malformed Area-ID: %s\n", str); \
384 return CMD_SUCCESS; \
386 int format = !*ep ? OSPF6_AREA_FMT_DECIMAL \
387 : OSPF6_AREA_FMT_DOTTEDQUAD; \
388 oa = ospf6_area_lookup(area_id, ospf6); \
390 oa = ospf6_area_create(area_id, ospf6, format); \
395 "area <A.B.C.D|(0-4294967295)> range X:X::X:X/M [<advertise|not-advertise|cost (0-16777215)>]",
396 "OSPF6 area parameters\n"
397 "OSPF6 area ID in IP address format\n"
398 "OSPF6 area ID as a decimal value\n"
399 "Configured address range\n"
400 "Specify IPv6 prefix\n"
403 "User specified metric for this range\n"
404 "Advertised metric for this range\n")
407 int idx_ipv6_prefixlen
= 3;
410 struct ospf6_area
*oa
;
411 struct prefix prefix
;
412 struct ospf6_route
*range
;
413 u_int32_t cost
= OSPF_AREA_RANGE_COST_UNSPEC
;
415 OSPF6_CMD_AREA_GET(argv
[idx_ipv4
]->arg
, oa
);
417 ret
= str2prefix(argv
[idx_ipv6_prefixlen
]->arg
, &prefix
);
418 if (ret
!= 1 || prefix
.family
!= AF_INET6
) {
419 vty_out(vty
, "Malformed argument: %s\n",
420 argv
[idx_ipv6_prefixlen
]->arg
);
424 range
= ospf6_route_lookup(&prefix
, oa
->range_table
);
426 range
= ospf6_route_create();
427 range
->type
= OSPF6_DEST_TYPE_RANGE
;
428 range
->prefix
= prefix
;
429 range
->path
.area_id
= oa
->area_id
;
430 range
->path
.cost
= OSPF_AREA_RANGE_COST_UNSPEC
;
433 if (argc
> idx_type
) {
434 if (strmatch(argv
[idx_type
]->text
, "not-advertise")) {
435 SET_FLAG(range
->flag
, OSPF6_ROUTE_DO_NOT_ADVERTISE
);
436 } else if (strmatch(argv
[idx_type
]->text
, "advertise")) {
437 UNSET_FLAG(range
->flag
, OSPF6_ROUTE_DO_NOT_ADVERTISE
);
439 cost
= strtoul(argv
[5]->arg
, NULL
, 10);
440 UNSET_FLAG(range
->flag
, OSPF6_ROUTE_DO_NOT_ADVERTISE
);
444 range
->path
.u
.cost_config
= cost
;
446 zlog_debug("%s: for prefix %s, flag = %x\n", __func__
,
447 argv
[idx_ipv6_prefixlen
]->arg
, range
->flag
);
448 if (range
->rnode
== NULL
) {
449 ospf6_route_add(range
, oa
->range_table
);
452 if (ospf6_is_router_abr(ospf6
)) {
453 /* Redo summaries if required */
454 ospf6_abr_prefix_resummarize(ospf6
);
460 DEFUN (no_area_range
,
462 "no area <A.B.C.D|(0-4294967295)> range X:X::X:X/M [<advertise|not-advertise|cost (0-16777215)>]",
464 "OSPF6 area parameters\n"
465 "OSPF6 area ID in IP address format\n"
466 "OSPF6 area ID as a decimal value\n"
467 "Configured address range\n"
468 "Specify IPv6 prefix\n"
471 "User specified metric for this range\n"
472 "Advertised metric for this range\n")
477 struct ospf6_area
*oa
;
478 struct prefix prefix
;
479 struct ospf6_route
*range
, *route
;
481 OSPF6_CMD_AREA_GET(argv
[idx_ipv4
]->arg
, oa
);
483 ret
= str2prefix(argv
[idx_ipv6
]->arg
, &prefix
);
484 if (ret
!= 1 || prefix
.family
!= AF_INET6
) {
485 vty_out(vty
, "Malformed argument: %s\n", argv
[idx_ipv6
]->arg
);
489 range
= ospf6_route_lookup(&prefix
, oa
->range_table
);
491 vty_out(vty
, "Range %s does not exists.\n",
492 argv
[idx_ipv6
]->arg
);
496 if (ospf6_is_router_abr(oa
->ospf6
)) {
497 /* Blow away the aggregated LSA and route */
498 SET_FLAG(range
->flag
, OSPF6_ROUTE_REMOVE
);
500 /* Redo summaries if required */
501 for (route
= ospf6_route_head(ospf6
->route_table
); route
;
502 route
= ospf6_route_next(route
))
503 ospf6_abr_originate_summary(route
);
505 /* purge the old aggregated summary LSA */
506 ospf6_abr_originate_summary(range
);
508 ospf6_route_remove(range
, oa
->range_table
);
513 void ospf6_area_config_write(struct vty
*vty
)
515 struct listnode
*node
;
516 struct ospf6_area
*oa
;
517 struct ospf6_route
*range
;
518 char buf
[PREFIX2STR_BUFFER
];
520 for (ALL_LIST_ELEMENTS_RO(ospf6
->area_list
, node
, oa
)) {
521 for (range
= ospf6_route_head(oa
->range_table
); range
;
522 range
= ospf6_route_next(range
)) {
523 prefix2str(&range
->prefix
, buf
, sizeof(buf
));
524 vty_out(vty
, " area %s range %s", oa
->name
, buf
);
526 if (CHECK_FLAG(range
->flag
,
527 OSPF6_ROUTE_DO_NOT_ADVERTISE
)) {
528 vty_out(vty
, " not-advertise");
530 // "advertise" is the default so we do not
532 if (range
->path
.u
.cost_config
533 != OSPF_AREA_RANGE_COST_UNSPEC
)
534 vty_out(vty
, " cost %d",
535 range
->path
.u
.cost_config
);
539 if (IS_AREA_STUB(oa
)) {
541 vty_out(vty
, " area %s stub no-summary\n",
544 vty_out(vty
, " area %s stub\n", oa
->name
);
546 if (PREFIX_NAME_IN(oa
))
547 vty_out(vty
, " area %s filter-list prefix %s in\n",
548 oa
->name
, PREFIX_NAME_IN(oa
));
549 if (PREFIX_NAME_OUT(oa
))
550 vty_out(vty
, " area %s filter-list prefix %s out\n",
551 oa
->name
, PREFIX_NAME_OUT(oa
));
553 vty_out(vty
, " area %s import-list %s\n", oa
->name
,
556 vty_out(vty
, " area %s export-list %s\n", oa
->name
,
561 DEFUN (area_filter_list
,
562 area_filter_list_cmd
,
563 "area A.B.C.D filter-list prefix WORD <in|out>",
564 "OSPF6 area parameters\n"
565 "OSPF6 area ID in IP address format\n"
566 "Filter networks between OSPF6 areas\n"
567 "Filter prefixes between OSPF6 areas\n"
568 "Name of an IPv6 prefix-list\n"
569 "Filter networks sent to this area\n"
570 "Filter networks sent from this area\n")
572 char *inout
= argv
[argc
- 1]->text
;
573 char *areaid
= argv
[1]->arg
;
574 char *plistname
= argv
[4]->arg
;
576 struct ospf6_area
*area
;
577 struct prefix_list
*plist
;
579 OSPF6_CMD_AREA_GET(areaid
, area
);
581 plist
= prefix_list_lookup(AFI_IP6
, plistname
);
582 if (strmatch(inout
, "in")) {
583 PREFIX_LIST_IN(area
) = plist
;
584 XFREE(MTYPE_OSPF6_PLISTNAME
, PREFIX_NAME_IN(area
));
585 PREFIX_NAME_IN(area
) = XSTRDUP(MTYPE_OSPF6_PLISTNAME
,
587 ospf6_abr_reimport(area
);
589 PREFIX_LIST_OUT(area
) = plist
;
590 XFREE(MTYPE_OSPF6_PLISTNAME
, PREFIX_NAME_OUT(area
));
591 PREFIX_NAME_OUT(area
) = XSTRDUP(MTYPE_OSPF6_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 XFREE(MTYPE_OSPF6_PLISTNAME
, PREFIX_NAME_IN(area
));
626 ospf6_abr_reimport(area
);
628 if (PREFIX_NAME_OUT(area
))
629 if (!strmatch(PREFIX_NAME_OUT(area
), plistname
))
632 XFREE(MTYPE_OSPF6_PLISTNAME
, PREFIX_NAME_OUT(area
));
633 ospf6_abr_enable_area(area
);
639 void ospf6_area_plist_update(struct prefix_list
*plist
, int add
)
641 struct ospf6_area
*oa
;
643 const char *name
= prefix_list_name(plist
);
648 for (ALL_LIST_ELEMENTS_RO(ospf6
->area_list
, n
, oa
)) {
649 if (PREFIX_NAME_IN(oa
) && !strcmp(PREFIX_NAME_IN(oa
), name
))
650 PREFIX_LIST_IN(oa
) = add
? plist
: NULL
;
651 if (PREFIX_NAME_OUT(oa
) && !strcmp(PREFIX_NAME_OUT(oa
), name
))
652 PREFIX_LIST_OUT(oa
) = add
? plist
: NULL
;
656 DEFUN (area_import_list
,
657 area_import_list_cmd
,
658 "area A.B.C.D import-list NAME",
659 "OSPF6 area parameters\n"
660 "OSPF6 area ID in IP address format\n"
661 "Set the filter for networks from other areas announced to the specified one\n"
662 "Name of the acess-list\n")
666 struct ospf6_area
*area
;
667 struct access_list
*list
;
669 OSPF6_CMD_AREA_GET(argv
[idx_ipv4
]->arg
, area
);
671 list
= access_list_lookup(AFI_IP6
, argv
[idx_name
]->arg
);
673 IMPORT_LIST(area
) = list
;
675 if (IMPORT_NAME(area
))
676 free(IMPORT_NAME(area
));
678 IMPORT_NAME(area
) = strdup(argv
[idx_name
]->arg
);
679 ospf6_abr_reimport(area
);
684 DEFUN (no_area_import_list
,
685 no_area_import_list_cmd
,
686 "no area A.B.C.D import-list NAME",
688 "OSPF6 area parameters\n"
689 "OSPF6 area ID in IP address format\n"
690 "Unset the filter for networks announced to other areas\n"
691 "Name of the access-list\n")
694 struct ospf6_area
*area
;
696 OSPF6_CMD_AREA_GET(argv
[idx_ipv4
]->arg
, area
);
698 IMPORT_LIST(area
) = 0;
700 if (IMPORT_NAME(area
))
701 free(IMPORT_NAME(area
));
703 IMPORT_NAME(area
) = NULL
;
704 ospf6_abr_reimport(area
);
709 DEFUN (area_export_list
,
710 area_export_list_cmd
,
711 "area A.B.C.D export-list NAME",
712 "OSPF6 area parameters\n"
713 "OSPF6 area ID in IP address format\n"
714 "Set the filter for networks announced to other areas\n"
715 "Name of the acess-list\n")
719 struct ospf6_area
*area
;
720 struct access_list
*list
;
722 OSPF6_CMD_AREA_GET(argv
[idx_ipv4
]->arg
, area
);
724 list
= access_list_lookup(AFI_IP6
, argv
[idx_name
]->arg
);
726 EXPORT_LIST(area
) = list
;
728 if (EXPORT_NAME(area
))
729 free(EXPORT_NAME(area
));
731 EXPORT_NAME(area
) = strdup(argv
[idx_name
]->arg
);
732 ospf6_abr_enable_area(area
);
737 DEFUN (no_area_export_list
,
738 no_area_export_list_cmd
,
739 "no area A.B.C.D export-list NAME",
741 "OSPF6 area parameters\n"
742 "OSPF6 area ID in IP address format\n"
743 "Unset the filter for networks announced to other areas\n"
744 "Name of the access-list\n")
747 struct ospf6_area
*area
;
749 OSPF6_CMD_AREA_GET(argv
[idx_ipv4
]->arg
, area
);
751 EXPORT_LIST(area
) = 0;
753 if (EXPORT_NAME(area
))
754 free(EXPORT_NAME(area
));
756 EXPORT_NAME(area
) = NULL
;
757 ospf6_abr_enable_area(area
);
762 DEFUN (show_ipv6_ospf6_spf_tree
,
763 show_ipv6_ospf6_spf_tree_cmd
,
764 "show ipv6 ospf6 spf tree",
768 "Shortest Path First caculation\n"
771 struct listnode
*node
;
772 struct ospf6_area
*oa
;
773 struct ospf6_vertex
*root
;
774 struct ospf6_route
*route
;
775 struct prefix prefix
;
777 OSPF6_CMD_CHECK_RUNNING();
779 ospf6_linkstate_prefix(ospf6
->router_id
, htonl(0), &prefix
);
781 for (ALL_LIST_ELEMENTS_RO(ospf6
->area_list
, node
, oa
)) {
782 route
= ospf6_route_lookup(&prefix
, oa
->spf_table
);
784 vty_out(vty
, "LS entry for root not found in area %s\n",
788 root
= (struct ospf6_vertex
*)route
->route_option
;
789 ospf6_spf_display_subtree(vty
, "", 0, root
);
795 DEFUN (show_ipv6_ospf6_area_spf_tree
,
796 show_ipv6_ospf6_area_spf_tree_cmd
,
797 "show ipv6 ospf6 area A.B.C.D spf tree",
803 "Shortest Path First caculation\n"
808 struct ospf6_area
*oa
;
809 struct ospf6_vertex
*root
;
810 struct ospf6_route
*route
;
811 struct prefix prefix
;
813 OSPF6_CMD_CHECK_RUNNING();
815 ospf6_linkstate_prefix(ospf6
->router_id
, htonl(0), &prefix
);
817 if (inet_pton(AF_INET
, argv
[idx_ipv4
]->arg
, &area_id
) != 1) {
818 vty_out(vty
, "Malformed Area-ID: %s\n", argv
[idx_ipv4
]->arg
);
821 oa
= ospf6_area_lookup(area_id
, ospf6
);
823 vty_out(vty
, "No such Area: %s\n", argv
[idx_ipv4
]->arg
);
827 route
= ospf6_route_lookup(&prefix
, oa
->spf_table
);
829 vty_out(vty
, "LS entry for root not found in area %s\n",
833 root
= (struct ospf6_vertex
*)route
->route_option
;
834 ospf6_spf_display_subtree(vty
, "", 0, root
);
839 DEFUN (show_ipv6_ospf6_simulate_spf_tree_root
,
840 show_ipv6_ospf6_simulate_spf_tree_root_cmd
,
841 "show ipv6 ospf6 simulate spf-tree A.B.C.D area A.B.C.D",
845 "Shortest Path First calculation\n"
847 "Specify root's router-id to calculate another router's SPF tree\n"
848 "OSPF6 area parameters\n"
854 struct ospf6_area
*oa
;
855 struct ospf6_vertex
*root
;
856 struct ospf6_route
*route
;
857 struct prefix prefix
;
859 struct ospf6_route_table
*spf_table
;
860 unsigned char tmp_debug_ospf6_spf
= 0;
862 OSPF6_CMD_CHECK_RUNNING();
864 inet_pton(AF_INET
, argv
[idx_ipv4
]->arg
, &router_id
);
865 ospf6_linkstate_prefix(router_id
, htonl(0), &prefix
);
867 if (inet_pton(AF_INET
, argv
[idx_ipv4_2
]->arg
, &area_id
) != 1) {
868 vty_out(vty
, "Malformed Area-ID: %s\n", argv
[idx_ipv4_2
]->arg
);
871 oa
= ospf6_area_lookup(area_id
, ospf6
);
873 vty_out(vty
, "No such Area: %s\n", argv
[idx_ipv4_2
]->arg
);
877 tmp_debug_ospf6_spf
= conf_debug_ospf6_spf
;
878 conf_debug_ospf6_spf
= 0;
880 spf_table
= OSPF6_ROUTE_TABLE_CREATE(NONE
, SPF_RESULTS
);
881 ospf6_spf_calculation(router_id
, spf_table
, oa
);
883 conf_debug_ospf6_spf
= tmp_debug_ospf6_spf
;
885 route
= ospf6_route_lookup(&prefix
, spf_table
);
887 ospf6_spf_table_finish(spf_table
);
888 ospf6_route_table_delete(spf_table
);
891 root
= (struct ospf6_vertex
*)route
->route_option
;
892 ospf6_spf_display_subtree(vty
, "", 0, root
);
894 ospf6_spf_table_finish(spf_table
);
895 ospf6_route_table_delete(spf_table
);
900 DEFUN (ospf6_area_stub
,
902 "area <A.B.C.D|(0-4294967295)> stub",
903 "OSPF6 area parameters\n"
904 "OSPF6 area ID in IP address format\n"
905 "OSPF6 area ID as a decimal value\n"
906 "Configure OSPF6 area as stub\n")
908 int idx_ipv4_number
= 1;
909 struct ospf6_area
*area
;
911 OSPF6_CMD_AREA_GET(argv
[idx_ipv4_number
]->arg
, area
);
913 if (!ospf6_area_stub_set(ospf6
, area
)) {
915 "First deconfigure all virtual link through this area\n");
916 return CMD_WARNING_CONFIG_FAILED
;
919 ospf6_area_no_summary_unset(ospf6
, area
);
924 DEFUN (ospf6_area_stub_no_summary
,
925 ospf6_area_stub_no_summary_cmd
,
926 "area <A.B.C.D|(0-4294967295)> stub no-summary",
927 "OSPF6 stub parameters\n"
928 "OSPF6 area ID in IP address format\n"
929 "OSPF6 area ID as a decimal value\n"
930 "Configure OSPF6 area as stub\n"
931 "Do not inject inter-area routes into stub\n")
933 int idx_ipv4_number
= 1;
934 struct ospf6_area
*area
;
936 OSPF6_CMD_AREA_GET(argv
[idx_ipv4_number
]->arg
, area
);
938 if (!ospf6_area_stub_set(ospf6
, area
)) {
940 "First deconfigure all virtual link through this area\n");
941 return CMD_WARNING_CONFIG_FAILED
;
944 ospf6_area_no_summary_set(ospf6
, area
);
949 DEFUN (no_ospf6_area_stub
,
950 no_ospf6_area_stub_cmd
,
951 "no area <A.B.C.D|(0-4294967295)> stub",
953 "OSPF6 area parameters\n"
954 "OSPF6 area ID in IP address format\n"
955 "OSPF6 area ID as a decimal value\n"
956 "Configure OSPF6 area as stub\n")
958 int idx_ipv4_number
= 2;
959 struct ospf6_area
*area
;
961 OSPF6_CMD_AREA_GET(argv
[idx_ipv4_number
]->arg
, area
);
963 ospf6_area_stub_unset(ospf6
, area
);
964 ospf6_area_no_summary_unset(ospf6
, area
);
969 DEFUN (no_ospf6_area_stub_no_summary
,
970 no_ospf6_area_stub_no_summary_cmd
,
971 "no area <A.B.C.D|(0-4294967295)> stub no-summary",
973 "OSPF6 area parameters\n"
974 "OSPF6 area ID in IP address format\n"
975 "OSPF6 area ID as a decimal value\n"
976 "Configure OSPF6 area as stub\n"
977 "Do not inject inter-area routes into area\n")
979 int idx_ipv4_number
= 2;
980 struct ospf6_area
*area
;
982 OSPF6_CMD_AREA_GET(argv
[idx_ipv4_number
]->arg
, area
);
984 ospf6_area_stub_unset(ospf6
, area
);
985 ospf6_area_no_summary_unset(ospf6
, area
);
990 void ospf6_area_init(void)
992 install_element(VIEW_NODE
, &show_ipv6_ospf6_spf_tree_cmd
);
993 install_element(VIEW_NODE
, &show_ipv6_ospf6_area_spf_tree_cmd
);
994 install_element(VIEW_NODE
, &show_ipv6_ospf6_simulate_spf_tree_root_cmd
);
996 install_element(OSPF6_NODE
, &area_range_cmd
);
997 install_element(OSPF6_NODE
, &no_area_range_cmd
);
998 install_element(OSPF6_NODE
, &ospf6_area_stub_no_summary_cmd
);
999 install_element(OSPF6_NODE
, &ospf6_area_stub_cmd
);
1000 install_element(OSPF6_NODE
, &no_ospf6_area_stub_no_summary_cmd
);
1001 install_element(OSPF6_NODE
, &no_ospf6_area_stub_cmd
);
1004 install_element(OSPF6_NODE
, &area_import_list_cmd
);
1005 install_element(OSPF6_NODE
, &no_area_import_list_cmd
);
1006 install_element(OSPF6_NODE
, &area_export_list_cmd
);
1007 install_element(OSPF6_NODE
, &no_area_export_list_cmd
);
1009 install_element(OSPF6_NODE
, &area_filter_list_cmd
);
1010 install_element(OSPF6_NODE
, &no_area_filter_list_cmd
);