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("%s Examin LSA %s", __PRETTY_FUNCTION__
, 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
;
122 copy
= ospf6_route_copy(route
);
123 ospf6_route_add(copy
, ospf6
->route_table
);
126 static void ospf6_area_route_hook_remove(struct ospf6_route
*route
)
128 struct ospf6_route
*copy
;
130 copy
= ospf6_route_lookup_identical(route
, ospf6
->route_table
);
132 ospf6_route_remove(copy
, ospf6
->route_table
);
135 static void ospf6_area_stub_update(struct ospf6_area
*area
)
138 if (IS_AREA_STUB(area
)) {
139 if (IS_OSPF6_DEBUG_ORIGINATE(ROUTER
))
140 zlog_debug("Stubbing out area for if %s\n", area
->name
);
141 OSPF6_OPT_CLEAR(area
->options
, OSPF6_OPT_E
);
142 } else if (IS_AREA_ENABLED(area
)) {
143 if (IS_OSPF6_DEBUG_ORIGINATE(ROUTER
))
144 zlog_debug("Normal area for if %s\n", area
->name
);
145 OSPF6_OPT_SET(area
->options
, OSPF6_OPT_E
);
146 ospf6_asbr_send_externals_to_area(area
);
149 OSPF6_ROUTER_LSA_SCHEDULE(area
);
152 static int ospf6_area_stub_set(struct ospf6
*ospf6
, struct ospf6_area
*area
)
154 if (!IS_AREA_STUB(area
)) {
155 SET_FLAG(area
->flag
, OSPF6_AREA_STUB
);
156 ospf6_area_stub_update(area
);
162 static void ospf6_area_stub_unset(struct ospf6
*ospf6
, struct ospf6_area
*area
)
164 if (IS_AREA_STUB(area
)) {
165 UNSET_FLAG(area
->flag
, OSPF6_AREA_STUB
);
166 ospf6_area_stub_update(area
);
170 static void ospf6_area_no_summary_set(struct ospf6
*ospf6
,
171 struct ospf6_area
*area
)
174 if (!area
->no_summary
) {
175 area
->no_summary
= 1;
176 ospf6_abr_range_reset_cost(ospf6
);
177 ospf6_abr_prefix_resummarize(ospf6
);
182 static void ospf6_area_no_summary_unset(struct ospf6
*ospf6
,
183 struct ospf6_area
*area
)
186 if (area
->no_summary
) {
187 area
->no_summary
= 0;
188 ospf6_abr_range_reset_cost(ospf6
);
189 ospf6_abr_prefix_resummarize(ospf6
);
195 * Make new area structure.
197 * @param area_id - ospf6 area ID
198 * @param o - ospf6 instance
199 * @param df - display format for area ID
201 struct ospf6_area
*ospf6_area_create(u_int32_t area_id
, struct ospf6
*o
, int df
)
203 struct ospf6_area
*oa
;
205 oa
= XCALLOC(MTYPE_OSPF6_AREA
, sizeof(struct ospf6_area
));
208 case OSPF6_AREA_FMT_DECIMAL
:
209 snprintf(oa
->name
, sizeof(oa
->name
), "%u", ntohl(area_id
));
212 case OSPF6_AREA_FMT_DOTTEDQUAD
:
213 inet_ntop(AF_INET
, &area_id
, oa
->name
, sizeof(oa
->name
));
217 oa
->area_id
= area_id
;
218 oa
->if_list
= list_new();
220 oa
->lsdb
= ospf6_lsdb_create(oa
);
221 oa
->lsdb
->hook_add
= ospf6_area_lsdb_hook_add
;
222 oa
->lsdb
->hook_remove
= ospf6_area_lsdb_hook_remove
;
223 oa
->lsdb_self
= ospf6_lsdb_create(oa
);
224 oa
->temp_router_lsa_lsdb
= ospf6_lsdb_create(oa
);
226 oa
->spf_table
= OSPF6_ROUTE_TABLE_CREATE(AREA
, SPF_RESULTS
);
227 oa
->spf_table
->scope
= oa
;
228 oa
->route_table
= OSPF6_ROUTE_TABLE_CREATE(AREA
, ROUTES
);
229 oa
->route_table
->scope
= oa
;
230 oa
->route_table
->hook_add
= ospf6_area_route_hook_add
;
231 oa
->route_table
->hook_remove
= ospf6_area_route_hook_remove
;
233 oa
->range_table
= OSPF6_ROUTE_TABLE_CREATE(AREA
, PREFIX_RANGES
);
234 oa
->range_table
->scope
= oa
;
235 bf_init(oa
->range_table
->idspace
, 32);
236 oa
->summary_prefix
= OSPF6_ROUTE_TABLE_CREATE(AREA
, SUMMARY_PREFIXES
);
237 oa
->summary_prefix
->scope
= oa
;
238 oa
->summary_router
= OSPF6_ROUTE_TABLE_CREATE(AREA
, SUMMARY_ROUTERS
);
239 oa
->summary_router
->scope
= oa
;
240 oa
->router_lsa_size_limit
= 1024 + 256;
242 /* set default options */
243 if (CHECK_FLAG(o
->flag
, OSPF6_STUB_ROUTER
)) {
244 OSPF6_OPT_CLEAR(oa
->options
, OSPF6_OPT_V6
);
245 OSPF6_OPT_CLEAR(oa
->options
, OSPF6_OPT_R
);
247 OSPF6_OPT_SET(oa
->options
, OSPF6_OPT_V6
);
248 OSPF6_OPT_SET(oa
->options
, OSPF6_OPT_R
);
251 OSPF6_OPT_SET(oa
->options
, OSPF6_OPT_E
);
253 SET_FLAG(oa
->flag
, OSPF6_AREA_ACTIVE
);
254 SET_FLAG(oa
->flag
, OSPF6_AREA_ENABLE
);
257 listnode_add_sort(o
->area_list
, oa
);
259 if (area_id
== OSPF_AREA_BACKBONE
) {
266 void ospf6_area_delete(struct ospf6_area
*oa
)
269 struct ospf6_interface
*oi
;
271 /* The ospf6_interface structs store configuration
272 * information which should not be lost/reset when
274 * So just detach the interface from the area and
276 for (ALL_LIST_ELEMENTS_RO(oa
->if_list
, n
, oi
))
279 list_delete_and_null(&oa
->if_list
);
281 ospf6_lsdb_delete(oa
->lsdb
);
282 ospf6_lsdb_delete(oa
->lsdb_self
);
283 ospf6_lsdb_delete(oa
->temp_router_lsa_lsdb
);
285 ospf6_spf_table_finish(oa
->spf_table
);
286 ospf6_route_table_delete(oa
->spf_table
);
287 ospf6_route_table_delete(oa
->route_table
);
289 ospf6_route_table_delete(oa
->range_table
);
290 ospf6_route_table_delete(oa
->summary_prefix
);
291 ospf6_route_table_delete(oa
->summary_router
);
293 listnode_delete(oa
->ospf6
->area_list
, oa
);
297 XFREE(MTYPE_OSPF6_AREA
, oa
);
300 struct ospf6_area
*ospf6_area_lookup(u_int32_t area_id
, struct ospf6
*ospf6
)
302 struct ospf6_area
*oa
;
305 for (ALL_LIST_ELEMENTS_RO(ospf6
->area_list
, n
, oa
))
306 if (oa
->area_id
== area_id
)
309 return (struct ospf6_area
*)NULL
;
312 void ospf6_area_enable(struct ospf6_area
*oa
)
314 struct listnode
*node
, *nnode
;
315 struct ospf6_interface
*oi
;
317 SET_FLAG(oa
->flag
, OSPF6_AREA_ENABLE
);
319 for (ALL_LIST_ELEMENTS(oa
->if_list
, node
, nnode
, oi
))
320 ospf6_interface_enable(oi
);
321 ospf6_abr_enable_area(oa
);
324 void ospf6_area_disable(struct ospf6_area
*oa
)
326 struct listnode
*node
, *nnode
;
327 struct ospf6_interface
*oi
;
329 UNSET_FLAG(oa
->flag
, OSPF6_AREA_ENABLE
);
331 for (ALL_LIST_ELEMENTS(oa
->if_list
, node
, nnode
, oi
))
332 ospf6_interface_disable(oi
);
334 ospf6_abr_disable_area(oa
);
335 ospf6_lsdb_remove_all(oa
->lsdb
);
336 ospf6_lsdb_remove_all(oa
->lsdb_self
);
338 ospf6_spf_table_finish(oa
->spf_table
);
339 ospf6_route_remove_all(oa
->route_table
);
341 THREAD_OFF(oa
->thread_router_lsa
);
342 THREAD_OFF(oa
->thread_intra_prefix_lsa
);
346 void ospf6_area_show(struct vty
*vty
, struct ospf6_area
*oa
)
349 struct ospf6_interface
*oi
;
350 unsigned long result
;
352 if (!IS_AREA_STUB(oa
))
353 vty_out(vty
, " Area %s\n", oa
->name
);
355 if (oa
->no_summary
) {
356 vty_out(vty
, " Area %s[Stub, No Summary]\n", oa
->name
);
358 vty_out(vty
, " Area %s[Stub]\n", oa
->name
);
361 vty_out(vty
, " Number of Area scoped LSAs is %u\n",
364 vty_out(vty
, " Interface attached to this area:");
365 for (ALL_LIST_ELEMENTS_RO(oa
->if_list
, i
, oi
))
366 vty_out(vty
, " %s", oi
->interface
->name
);
369 if (oa
->ts_spf
.tv_sec
|| oa
->ts_spf
.tv_usec
) {
370 result
= monotime_since(&oa
->ts_spf
, NULL
);
371 if (result
/ TIMER_SECOND_MICRO
> 0) {
372 vty_out(vty
, "SPF last executed %ld.%lds ago\n",
373 result
/ TIMER_SECOND_MICRO
,
374 result
% TIMER_SECOND_MICRO
);
376 vty_out(vty
, "SPF last executed %ldus ago\n", result
);
379 vty_out(vty
, "SPF has not been run\n");
383 #define OSPF6_CMD_AREA_GET(str, oa) \
386 u_int32_t area_id = htonl(strtoul(str, &ep, 10)); \
387 if (*ep && inet_pton(AF_INET, str, &area_id) != 1) { \
388 vty_out(vty, "Malformed Area-ID: %s\n", str); \
389 return CMD_SUCCESS; \
391 int format = !*ep ? OSPF6_AREA_FMT_DECIMAL \
392 : OSPF6_AREA_FMT_DOTTEDQUAD; \
393 oa = ospf6_area_lookup(area_id, ospf6); \
395 oa = ospf6_area_create(area_id, ospf6, format); \
400 "area <A.B.C.D|(0-4294967295)> range X:X::X:X/M [<advertise|not-advertise|cost (0-16777215)>]",
401 "OSPF6 area parameters\n"
402 "OSPF6 area ID in IP address format\n"
403 "OSPF6 area ID as a decimal value\n"
404 "Configured address range\n"
405 "Specify IPv6 prefix\n"
408 "User specified metric for this range\n"
409 "Advertised metric for this range\n")
412 int idx_ipv6_prefixlen
= 3;
415 struct ospf6_area
*oa
;
416 struct prefix prefix
;
417 struct ospf6_route
*range
;
418 u_int32_t cost
= OSPF_AREA_RANGE_COST_UNSPEC
;
420 OSPF6_CMD_AREA_GET(argv
[idx_ipv4
]->arg
, oa
);
422 ret
= str2prefix(argv
[idx_ipv6_prefixlen
]->arg
, &prefix
);
423 if (ret
!= 1 || prefix
.family
!= AF_INET6
) {
424 vty_out(vty
, "Malformed argument: %s\n",
425 argv
[idx_ipv6_prefixlen
]->arg
);
429 range
= ospf6_route_lookup(&prefix
, oa
->range_table
);
431 range
= ospf6_route_create();
432 range
->type
= OSPF6_DEST_TYPE_RANGE
;
433 range
->prefix
= prefix
;
434 range
->path
.area_id
= oa
->area_id
;
435 range
->path
.cost
= OSPF_AREA_RANGE_COST_UNSPEC
;
438 if (argc
> idx_type
) {
439 if (strmatch(argv
[idx_type
]->text
, "not-advertise")) {
440 SET_FLAG(range
->flag
, OSPF6_ROUTE_DO_NOT_ADVERTISE
);
441 } else if (strmatch(argv
[idx_type
]->text
, "advertise")) {
442 UNSET_FLAG(range
->flag
, OSPF6_ROUTE_DO_NOT_ADVERTISE
);
444 cost
= strtoul(argv
[5]->arg
, NULL
, 10);
445 UNSET_FLAG(range
->flag
, OSPF6_ROUTE_DO_NOT_ADVERTISE
);
449 range
->path
.u
.cost_config
= cost
;
451 zlog_debug("%s: for prefix %s, flag = %x\n", __func__
,
452 argv
[idx_ipv6_prefixlen
]->arg
, range
->flag
);
453 if (range
->rnode
== NULL
) {
454 ospf6_route_add(range
, oa
->range_table
);
457 if (ospf6_is_router_abr(ospf6
)) {
458 /* Redo summaries if required */
459 ospf6_abr_prefix_resummarize(ospf6
);
465 DEFUN (no_area_range
,
467 "no area <A.B.C.D|(0-4294967295)> range X:X::X:X/M [<advertise|not-advertise|cost (0-16777215)>]",
469 "OSPF6 area parameters\n"
470 "OSPF6 area ID in IP address format\n"
471 "OSPF6 area ID as a decimal value\n"
472 "Configured address range\n"
473 "Specify IPv6 prefix\n"
476 "User specified metric for this range\n"
477 "Advertised metric for this range\n")
482 struct ospf6_area
*oa
;
483 struct prefix prefix
;
484 struct ospf6_route
*range
, *route
;
486 OSPF6_CMD_AREA_GET(argv
[idx_ipv4
]->arg
, oa
);
488 ret
= str2prefix(argv
[idx_ipv6
]->arg
, &prefix
);
489 if (ret
!= 1 || prefix
.family
!= AF_INET6
) {
490 vty_out(vty
, "Malformed argument: %s\n", argv
[idx_ipv6
]->arg
);
494 range
= ospf6_route_lookup(&prefix
, oa
->range_table
);
496 vty_out(vty
, "Range %s does not exists.\n",
497 argv
[idx_ipv6
]->arg
);
501 if (ospf6_is_router_abr(oa
->ospf6
)) {
502 /* Blow away the aggregated LSA and route */
503 SET_FLAG(range
->flag
, OSPF6_ROUTE_REMOVE
);
505 /* Redo summaries if required */
506 for (route
= ospf6_route_head(ospf6
->route_table
); route
;
507 route
= ospf6_route_next(route
))
508 ospf6_abr_originate_summary(route
);
510 /* purge the old aggregated summary LSA */
511 ospf6_abr_originate_summary(range
);
513 ospf6_route_remove(range
, oa
->range_table
);
518 void ospf6_area_config_write(struct vty
*vty
)
520 struct listnode
*node
;
521 struct ospf6_area
*oa
;
522 struct ospf6_route
*range
;
523 char buf
[PREFIX2STR_BUFFER
];
525 for (ALL_LIST_ELEMENTS_RO(ospf6
->area_list
, node
, oa
)) {
526 for (range
= ospf6_route_head(oa
->range_table
); range
;
527 range
= ospf6_route_next(range
)) {
528 prefix2str(&range
->prefix
, buf
, sizeof(buf
));
529 vty_out(vty
, " area %s range %s", oa
->name
, buf
);
531 if (CHECK_FLAG(range
->flag
,
532 OSPF6_ROUTE_DO_NOT_ADVERTISE
)) {
533 vty_out(vty
, " not-advertise");
535 // "advertise" is the default so we do not
537 if (range
->path
.u
.cost_config
538 != OSPF_AREA_RANGE_COST_UNSPEC
)
539 vty_out(vty
, " cost %d",
540 range
->path
.u
.cost_config
);
544 if (IS_AREA_STUB(oa
)) {
546 vty_out(vty
, " area %s stub no-summary\n",
549 vty_out(vty
, " area %s stub\n", oa
->name
);
551 if (PREFIX_NAME_IN(oa
))
552 vty_out(vty
, " area %s filter-list prefix %s in\n",
553 oa
->name
, PREFIX_NAME_IN(oa
));
554 if (PREFIX_NAME_OUT(oa
))
555 vty_out(vty
, " area %s filter-list prefix %s out\n",
556 oa
->name
, PREFIX_NAME_OUT(oa
));
558 vty_out(vty
, " area %s import-list %s\n", oa
->name
,
561 vty_out(vty
, " area %s export-list %s\n", oa
->name
,
566 DEFUN (area_filter_list
,
567 area_filter_list_cmd
,
568 "area A.B.C.D filter-list prefix WORD <in|out>",
569 "OSPF6 area parameters\n"
570 "OSPF6 area ID in IP address format\n"
571 "Filter networks between OSPF6 areas\n"
572 "Filter prefixes between OSPF6 areas\n"
573 "Name of an IPv6 prefix-list\n"
574 "Filter networks sent to this area\n"
575 "Filter networks sent from this area\n")
577 char *inout
= argv
[argc
- 1]->text
;
578 char *areaid
= argv
[1]->arg
;
579 char *plistname
= argv
[4]->arg
;
581 struct ospf6_area
*area
;
582 struct prefix_list
*plist
;
584 OSPF6_CMD_AREA_GET(areaid
, area
);
586 plist
= prefix_list_lookup(AFI_IP6
, plistname
);
587 if (strmatch(inout
, "in")) {
588 PREFIX_LIST_IN(area
) = plist
;
589 XFREE(MTYPE_OSPF6_PLISTNAME
, PREFIX_NAME_IN(area
));
590 PREFIX_NAME_IN(area
) = XSTRDUP(MTYPE_OSPF6_PLISTNAME
,
592 ospf6_abr_reimport(area
);
594 PREFIX_LIST_OUT(area
) = plist
;
595 XFREE(MTYPE_OSPF6_PLISTNAME
, PREFIX_NAME_OUT(area
));
596 PREFIX_NAME_OUT(area
) = XSTRDUP(MTYPE_OSPF6_PLISTNAME
,
598 ospf6_abr_enable_area(area
);
604 DEFUN (no_area_filter_list
,
605 no_area_filter_list_cmd
,
606 "no area A.B.C.D filter-list prefix WORD <in|out>",
608 "OSPF6 area parameters\n"
609 "OSPF6 area ID in IP address format\n"
610 "Filter networks between OSPF6 areas\n"
611 "Filter prefixes between OSPF6 areas\n"
612 "Name of an IPv6 prefix-list\n"
613 "Filter networks sent to this area\n"
614 "Filter networks sent from this area\n")
616 char *inout
= argv
[argc
- 1]->text
;
617 char *areaid
= argv
[2]->arg
;
618 char *plistname
= argv
[5]->arg
;
620 struct ospf6_area
*area
;
622 OSPF6_CMD_AREA_GET(areaid
, area
);
624 if (strmatch(inout
, "in")) {
625 if (PREFIX_NAME_IN(area
))
626 if (!strmatch(PREFIX_NAME_IN(area
), plistname
))
629 PREFIX_LIST_IN(area
) = NULL
;
630 XFREE(MTYPE_OSPF6_PLISTNAME
, PREFIX_NAME_IN(area
));
631 ospf6_abr_reimport(area
);
633 if (PREFIX_NAME_OUT(area
))
634 if (!strmatch(PREFIX_NAME_OUT(area
), plistname
))
637 XFREE(MTYPE_OSPF6_PLISTNAME
, PREFIX_NAME_OUT(area
));
638 ospf6_abr_enable_area(area
);
644 void ospf6_area_plist_update(struct prefix_list
*plist
, int add
)
646 struct ospf6_area
*oa
;
648 const char *name
= prefix_list_name(plist
);
653 for (ALL_LIST_ELEMENTS_RO(ospf6
->area_list
, n
, oa
)) {
654 if (PREFIX_NAME_IN(oa
) && !strcmp(PREFIX_NAME_IN(oa
), name
))
655 PREFIX_LIST_IN(oa
) = add
? plist
: NULL
;
656 if (PREFIX_NAME_OUT(oa
) && !strcmp(PREFIX_NAME_OUT(oa
), name
))
657 PREFIX_LIST_OUT(oa
) = add
? plist
: NULL
;
661 DEFUN (area_import_list
,
662 area_import_list_cmd
,
663 "area A.B.C.D import-list NAME",
664 "OSPF6 area parameters\n"
665 "OSPF6 area ID in IP address format\n"
666 "Set the filter for networks from other areas announced to the specified one\n"
667 "Name of the acess-list\n")
671 struct ospf6_area
*area
;
672 struct access_list
*list
;
674 OSPF6_CMD_AREA_GET(argv
[idx_ipv4
]->arg
, area
);
676 list
= access_list_lookup(AFI_IP6
, argv
[idx_name
]->arg
);
678 IMPORT_LIST(area
) = list
;
680 if (IMPORT_NAME(area
))
681 free(IMPORT_NAME(area
));
683 IMPORT_NAME(area
) = strdup(argv
[idx_name
]->arg
);
684 ospf6_abr_reimport(area
);
689 DEFUN (no_area_import_list
,
690 no_area_import_list_cmd
,
691 "no area A.B.C.D import-list NAME",
693 "OSPF6 area parameters\n"
694 "OSPF6 area ID in IP address format\n"
695 "Unset the filter for networks announced to other areas\n"
696 "Name of the access-list\n")
699 struct ospf6_area
*area
;
701 OSPF6_CMD_AREA_GET(argv
[idx_ipv4
]->arg
, area
);
703 IMPORT_LIST(area
) = 0;
705 if (IMPORT_NAME(area
))
706 free(IMPORT_NAME(area
));
708 IMPORT_NAME(area
) = NULL
;
709 ospf6_abr_reimport(area
);
714 DEFUN (area_export_list
,
715 area_export_list_cmd
,
716 "area A.B.C.D export-list NAME",
717 "OSPF6 area parameters\n"
718 "OSPF6 area ID in IP address format\n"
719 "Set the filter for networks announced to other areas\n"
720 "Name of the acess-list\n")
724 struct ospf6_area
*area
;
725 struct access_list
*list
;
727 OSPF6_CMD_AREA_GET(argv
[idx_ipv4
]->arg
, area
);
729 list
= access_list_lookup(AFI_IP6
, argv
[idx_name
]->arg
);
731 EXPORT_LIST(area
) = list
;
733 if (EXPORT_NAME(area
))
734 free(EXPORT_NAME(area
));
736 EXPORT_NAME(area
) = strdup(argv
[idx_name
]->arg
);
737 ospf6_abr_enable_area(area
);
742 DEFUN (no_area_export_list
,
743 no_area_export_list_cmd
,
744 "no area A.B.C.D export-list NAME",
746 "OSPF6 area parameters\n"
747 "OSPF6 area ID in IP address format\n"
748 "Unset the filter for networks announced to other areas\n"
749 "Name of the access-list\n")
752 struct ospf6_area
*area
;
754 OSPF6_CMD_AREA_GET(argv
[idx_ipv4
]->arg
, area
);
756 EXPORT_LIST(area
) = 0;
758 if (EXPORT_NAME(area
))
759 free(EXPORT_NAME(area
));
761 EXPORT_NAME(area
) = NULL
;
762 ospf6_abr_enable_area(area
);
767 DEFUN (show_ipv6_ospf6_spf_tree
,
768 show_ipv6_ospf6_spf_tree_cmd
,
769 "show ipv6 ospf6 spf tree",
773 "Shortest Path First caculation\n"
776 struct listnode
*node
;
777 struct ospf6_area
*oa
;
778 struct ospf6_vertex
*root
;
779 struct ospf6_route
*route
;
780 struct prefix prefix
;
782 OSPF6_CMD_CHECK_RUNNING();
784 ospf6_linkstate_prefix(ospf6
->router_id
, htonl(0), &prefix
);
786 for (ALL_LIST_ELEMENTS_RO(ospf6
->area_list
, node
, oa
)) {
787 route
= ospf6_route_lookup(&prefix
, oa
->spf_table
);
789 vty_out(vty
, "LS entry for root not found in area %s\n",
793 root
= (struct ospf6_vertex
*)route
->route_option
;
794 ospf6_spf_display_subtree(vty
, "", 0, root
);
800 DEFUN (show_ipv6_ospf6_area_spf_tree
,
801 show_ipv6_ospf6_area_spf_tree_cmd
,
802 "show ipv6 ospf6 area A.B.C.D spf tree",
808 "Shortest Path First caculation\n"
813 struct ospf6_area
*oa
;
814 struct ospf6_vertex
*root
;
815 struct ospf6_route
*route
;
816 struct prefix prefix
;
818 OSPF6_CMD_CHECK_RUNNING();
820 ospf6_linkstate_prefix(ospf6
->router_id
, htonl(0), &prefix
);
822 if (inet_pton(AF_INET
, argv
[idx_ipv4
]->arg
, &area_id
) != 1) {
823 vty_out(vty
, "Malformed Area-ID: %s\n", argv
[idx_ipv4
]->arg
);
826 oa
= ospf6_area_lookup(area_id
, ospf6
);
828 vty_out(vty
, "No such Area: %s\n", argv
[idx_ipv4
]->arg
);
832 route
= ospf6_route_lookup(&prefix
, oa
->spf_table
);
834 vty_out(vty
, "LS entry for root not found in area %s\n",
838 root
= (struct ospf6_vertex
*)route
->route_option
;
839 ospf6_spf_display_subtree(vty
, "", 0, root
);
844 DEFUN (show_ipv6_ospf6_simulate_spf_tree_root
,
845 show_ipv6_ospf6_simulate_spf_tree_root_cmd
,
846 "show ipv6 ospf6 simulate spf-tree A.B.C.D area A.B.C.D",
850 "Shortest Path First calculation\n"
852 "Specify root's router-id to calculate another router's SPF tree\n"
853 "OSPF6 area parameters\n"
859 struct ospf6_area
*oa
;
860 struct ospf6_vertex
*root
;
861 struct ospf6_route
*route
;
862 struct prefix prefix
;
864 struct ospf6_route_table
*spf_table
;
865 unsigned char tmp_debug_ospf6_spf
= 0;
867 OSPF6_CMD_CHECK_RUNNING();
869 inet_pton(AF_INET
, argv
[idx_ipv4
]->arg
, &router_id
);
870 ospf6_linkstate_prefix(router_id
, htonl(0), &prefix
);
872 if (inet_pton(AF_INET
, argv
[idx_ipv4_2
]->arg
, &area_id
) != 1) {
873 vty_out(vty
, "Malformed Area-ID: %s\n", argv
[idx_ipv4_2
]->arg
);
876 oa
= ospf6_area_lookup(area_id
, ospf6
);
878 vty_out(vty
, "No such Area: %s\n", argv
[idx_ipv4_2
]->arg
);
882 tmp_debug_ospf6_spf
= conf_debug_ospf6_spf
;
883 conf_debug_ospf6_spf
= 0;
885 spf_table
= OSPF6_ROUTE_TABLE_CREATE(NONE
, SPF_RESULTS
);
886 ospf6_spf_calculation(router_id
, spf_table
, oa
);
888 conf_debug_ospf6_spf
= tmp_debug_ospf6_spf
;
890 route
= ospf6_route_lookup(&prefix
, spf_table
);
892 ospf6_spf_table_finish(spf_table
);
893 ospf6_route_table_delete(spf_table
);
896 root
= (struct ospf6_vertex
*)route
->route_option
;
897 ospf6_spf_display_subtree(vty
, "", 0, root
);
899 ospf6_spf_table_finish(spf_table
);
900 ospf6_route_table_delete(spf_table
);
905 DEFUN (ospf6_area_stub
,
907 "area <A.B.C.D|(0-4294967295)> stub",
908 "OSPF6 area parameters\n"
909 "OSPF6 area ID in IP address format\n"
910 "OSPF6 area ID as a decimal value\n"
911 "Configure OSPF6 area as stub\n")
913 int idx_ipv4_number
= 1;
914 struct ospf6_area
*area
;
916 OSPF6_CMD_AREA_GET(argv
[idx_ipv4_number
]->arg
, area
);
918 if (!ospf6_area_stub_set(ospf6
, area
)) {
920 "First deconfigure all virtual link through this area\n");
921 return CMD_WARNING_CONFIG_FAILED
;
924 ospf6_area_no_summary_unset(ospf6
, area
);
929 DEFUN (ospf6_area_stub_no_summary
,
930 ospf6_area_stub_no_summary_cmd
,
931 "area <A.B.C.D|(0-4294967295)> stub no-summary",
932 "OSPF6 stub parameters\n"
933 "OSPF6 area ID in IP address format\n"
934 "OSPF6 area ID as a decimal value\n"
935 "Configure OSPF6 area as stub\n"
936 "Do not inject inter-area routes into stub\n")
938 int idx_ipv4_number
= 1;
939 struct ospf6_area
*area
;
941 OSPF6_CMD_AREA_GET(argv
[idx_ipv4_number
]->arg
, area
);
943 if (!ospf6_area_stub_set(ospf6
, area
)) {
945 "First deconfigure all virtual link through this area\n");
946 return CMD_WARNING_CONFIG_FAILED
;
949 ospf6_area_no_summary_set(ospf6
, area
);
954 DEFUN (no_ospf6_area_stub
,
955 no_ospf6_area_stub_cmd
,
956 "no area <A.B.C.D|(0-4294967295)> stub",
958 "OSPF6 area parameters\n"
959 "OSPF6 area ID in IP address format\n"
960 "OSPF6 area ID as a decimal value\n"
961 "Configure OSPF6 area as stub\n")
963 int idx_ipv4_number
= 2;
964 struct ospf6_area
*area
;
966 OSPF6_CMD_AREA_GET(argv
[idx_ipv4_number
]->arg
, area
);
968 ospf6_area_stub_unset(ospf6
, area
);
969 ospf6_area_no_summary_unset(ospf6
, area
);
974 DEFUN (no_ospf6_area_stub_no_summary
,
975 no_ospf6_area_stub_no_summary_cmd
,
976 "no area <A.B.C.D|(0-4294967295)> stub no-summary",
978 "OSPF6 area parameters\n"
979 "OSPF6 area ID in IP address format\n"
980 "OSPF6 area ID as a decimal value\n"
981 "Configure OSPF6 area as stub\n"
982 "Do not inject inter-area routes into area\n")
984 int idx_ipv4_number
= 2;
985 struct ospf6_area
*area
;
987 OSPF6_CMD_AREA_GET(argv
[idx_ipv4_number
]->arg
, area
);
989 ospf6_area_stub_unset(ospf6
, area
);
990 ospf6_area_no_summary_unset(ospf6
, area
);
995 void ospf6_area_init(void)
997 install_element(VIEW_NODE
, &show_ipv6_ospf6_spf_tree_cmd
);
998 install_element(VIEW_NODE
, &show_ipv6_ospf6_area_spf_tree_cmd
);
999 install_element(VIEW_NODE
, &show_ipv6_ospf6_simulate_spf_tree_root_cmd
);
1001 install_element(OSPF6_NODE
, &area_range_cmd
);
1002 install_element(OSPF6_NODE
, &no_area_range_cmd
);
1003 install_element(OSPF6_NODE
, &ospf6_area_stub_no_summary_cmd
);
1004 install_element(OSPF6_NODE
, &ospf6_area_stub_cmd
);
1005 install_element(OSPF6_NODE
, &no_ospf6_area_stub_no_summary_cmd
);
1006 install_element(OSPF6_NODE
, &no_ospf6_area_stub_cmd
);
1009 install_element(OSPF6_NODE
, &area_import_list_cmd
);
1010 install_element(OSPF6_NODE
, &no_area_import_list_cmd
);
1011 install_element(OSPF6_NODE
, &area_export_list_cmd
);
1012 install_element(OSPF6_NODE
, &no_area_export_list_cmd
);
1014 install_element(OSPF6_NODE
, &area_filter_list_cmd
);
1015 install_element(OSPF6_NODE
, &no_area_filter_list_cmd
);