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__
,
66 zlog_debug(" Schedule SPF Calculation for %s",
67 OSPF6_AREA(lsa
->lsdb
->data
)->name
);
70 OSPF6_PROCESS(OSPF6_AREA(lsa
->lsdb
->data
)->ospf6
),
71 ospf6_lsadd_to_spf_reason(lsa
));
74 case OSPF6_LSTYPE_INTRA_PREFIX
:
75 ospf6_intra_prefix_lsa_add(lsa
);
78 case OSPF6_LSTYPE_INTER_PREFIX
:
79 case OSPF6_LSTYPE_INTER_ROUTER
:
80 ospf6_abr_examin_summary(lsa
,
81 (struct ospf6_area
*)lsa
->lsdb
->data
);
89 static void ospf6_area_lsdb_hook_remove(struct ospf6_lsa
*lsa
)
91 switch (ntohs(lsa
->header
->type
)) {
92 case OSPF6_LSTYPE_ROUTER
:
93 case OSPF6_LSTYPE_NETWORK
:
94 if (IS_OSPF6_DEBUG_EXAMIN_TYPE(lsa
->header
->type
)) {
95 zlog_debug("LSA disappearing: %s", lsa
->name
);
96 zlog_debug("Schedule SPF Calculation for %s",
97 OSPF6_AREA(lsa
->lsdb
->data
)->name
);
100 OSPF6_PROCESS(OSPF6_AREA(lsa
->lsdb
->data
)->ospf6
),
101 ospf6_lsremove_to_spf_reason(lsa
));
104 case OSPF6_LSTYPE_INTRA_PREFIX
:
105 ospf6_intra_prefix_lsa_remove(lsa
);
108 case OSPF6_LSTYPE_INTER_PREFIX
:
109 case OSPF6_LSTYPE_INTER_ROUTER
:
110 ospf6_abr_examin_summary(lsa
,
111 (struct ospf6_area
*)lsa
->lsdb
->data
);
119 static void ospf6_area_route_hook_add(struct ospf6_route
*route
)
121 struct ospf6_route
*copy
;
123 copy
= ospf6_route_copy(route
);
124 ospf6_route_add(copy
, ospf6
->route_table
);
127 static void ospf6_area_route_hook_remove(struct ospf6_route
*route
)
129 struct ospf6_route
*copy
;
131 copy
= ospf6_route_lookup_identical(route
, ospf6
->route_table
);
133 ospf6_route_remove(copy
, ospf6
->route_table
);
136 static void ospf6_area_stub_update(struct ospf6_area
*area
)
139 if (IS_AREA_STUB(area
)) {
140 if (IS_OSPF6_DEBUG_ORIGINATE(ROUTER
))
141 zlog_debug("Stubbing out area for if %s\n", area
->name
);
142 OSPF6_OPT_CLEAR(area
->options
, OSPF6_OPT_E
);
143 } else if (IS_AREA_ENABLED(area
)) {
144 if (IS_OSPF6_DEBUG_ORIGINATE(ROUTER
))
145 zlog_debug("Normal area for if %s\n", area
->name
);
146 OSPF6_OPT_SET(area
->options
, OSPF6_OPT_E
);
147 ospf6_asbr_send_externals_to_area(area
);
150 OSPF6_ROUTER_LSA_SCHEDULE(area
);
153 static int ospf6_area_stub_set(struct ospf6
*ospf6
, struct ospf6_area
*area
)
155 if (!IS_AREA_STUB(area
)) {
156 SET_FLAG(area
->flag
, OSPF6_AREA_STUB
);
157 ospf6_area_stub_update(area
);
163 static void ospf6_area_stub_unset(struct ospf6
*ospf6
, struct ospf6_area
*area
)
165 if (IS_AREA_STUB(area
)) {
166 UNSET_FLAG(area
->flag
, OSPF6_AREA_STUB
);
167 ospf6_area_stub_update(area
);
171 static void ospf6_area_no_summary_set(struct ospf6
*ospf6
,
172 struct ospf6_area
*area
)
175 if (!area
->no_summary
) {
176 area
->no_summary
= 1;
177 ospf6_abr_range_reset_cost(ospf6
);
178 ospf6_abr_prefix_resummarize(ospf6
);
183 static void ospf6_area_no_summary_unset(struct ospf6
*ospf6
,
184 struct ospf6_area
*area
)
187 if (area
->no_summary
) {
188 area
->no_summary
= 0;
189 ospf6_abr_range_reset_cost(ospf6
);
190 ospf6_abr_prefix_resummarize(ospf6
);
196 * Make new area structure.
198 * @param area_id - ospf6 area ID
199 * @param o - ospf6 instance
200 * @param df - display format for area ID
202 struct ospf6_area
*ospf6_area_create(uint32_t area_id
, struct ospf6
*o
, int df
)
204 struct ospf6_area
*oa
;
206 oa
= XCALLOC(MTYPE_OSPF6_AREA
, sizeof(struct ospf6_area
));
209 case OSPF6_AREA_FMT_DECIMAL
:
210 snprintf(oa
->name
, sizeof(oa
->name
), "%u", ntohl(area_id
));
213 case OSPF6_AREA_FMT_DOTTEDQUAD
:
214 inet_ntop(AF_INET
, &area_id
, oa
->name
, sizeof(oa
->name
));
218 oa
->area_id
= area_id
;
219 oa
->if_list
= list_new();
221 oa
->lsdb
= ospf6_lsdb_create(oa
);
222 oa
->lsdb
->hook_add
= ospf6_area_lsdb_hook_add
;
223 oa
->lsdb
->hook_remove
= ospf6_area_lsdb_hook_remove
;
224 oa
->lsdb_self
= ospf6_lsdb_create(oa
);
225 oa
->temp_router_lsa_lsdb
= ospf6_lsdb_create(oa
);
227 oa
->spf_table
= OSPF6_ROUTE_TABLE_CREATE(AREA
, SPF_RESULTS
);
228 oa
->spf_table
->scope
= oa
;
229 oa
->route_table
= OSPF6_ROUTE_TABLE_CREATE(AREA
, ROUTES
);
230 oa
->route_table
->scope
= oa
;
231 oa
->route_table
->hook_add
= ospf6_area_route_hook_add
;
232 oa
->route_table
->hook_remove
= ospf6_area_route_hook_remove
;
234 oa
->range_table
= OSPF6_ROUTE_TABLE_CREATE(AREA
, PREFIX_RANGES
);
235 oa
->range_table
->scope
= oa
;
236 bf_init(oa
->range_table
->idspace
, 32);
237 oa
->summary_prefix
= OSPF6_ROUTE_TABLE_CREATE(AREA
, SUMMARY_PREFIXES
);
238 oa
->summary_prefix
->scope
= oa
;
239 oa
->summary_router
= OSPF6_ROUTE_TABLE_CREATE(AREA
, SUMMARY_ROUTERS
);
240 oa
->summary_router
->scope
= oa
;
241 oa
->router_lsa_size_limit
= 1024 + 256;
243 /* set default options */
244 if (CHECK_FLAG(o
->flag
, OSPF6_STUB_ROUTER
)) {
245 OSPF6_OPT_CLEAR(oa
->options
, OSPF6_OPT_V6
);
246 OSPF6_OPT_CLEAR(oa
->options
, OSPF6_OPT_R
);
248 OSPF6_OPT_SET(oa
->options
, OSPF6_OPT_V6
);
249 OSPF6_OPT_SET(oa
->options
, OSPF6_OPT_R
);
252 OSPF6_OPT_SET(oa
->options
, OSPF6_OPT_E
);
254 SET_FLAG(oa
->flag
, OSPF6_AREA_ACTIVE
);
255 SET_FLAG(oa
->flag
, OSPF6_AREA_ENABLE
);
258 listnode_add_sort(o
->area_list
, oa
);
260 if (area_id
== OSPF_AREA_BACKBONE
) {
267 void ospf6_area_delete(struct ospf6_area
*oa
)
270 struct ospf6_interface
*oi
;
272 /* The ospf6_interface structs store configuration
273 * information which should not be lost/reset when
275 * So just detach the interface from the area and
277 for (ALL_LIST_ELEMENTS_RO(oa
->if_list
, n
, oi
))
280 list_delete(&oa
->if_list
);
282 ospf6_lsdb_delete(oa
->lsdb
);
283 ospf6_lsdb_delete(oa
->lsdb_self
);
284 ospf6_lsdb_delete(oa
->temp_router_lsa_lsdb
);
286 ospf6_spf_table_finish(oa
->spf_table
);
287 ospf6_route_table_delete(oa
->spf_table
);
288 ospf6_route_table_delete(oa
->route_table
);
290 ospf6_route_table_delete(oa
->range_table
);
291 ospf6_route_table_delete(oa
->summary_prefix
);
292 ospf6_route_table_delete(oa
->summary_router
);
294 listnode_delete(oa
->ospf6
->area_list
, oa
);
298 XFREE(MTYPE_OSPF6_AREA
, oa
);
301 struct ospf6_area
*ospf6_area_lookup(uint32_t area_id
, struct ospf6
*ospf6
)
303 struct ospf6_area
*oa
;
306 for (ALL_LIST_ELEMENTS_RO(ospf6
->area_list
, n
, oa
))
307 if (oa
->area_id
== area_id
)
310 return (struct ospf6_area
*)NULL
;
313 void ospf6_area_enable(struct ospf6_area
*oa
)
315 struct listnode
*node
, *nnode
;
316 struct ospf6_interface
*oi
;
318 SET_FLAG(oa
->flag
, OSPF6_AREA_ENABLE
);
320 for (ALL_LIST_ELEMENTS(oa
->if_list
, node
, nnode
, oi
))
321 ospf6_interface_enable(oi
);
322 ospf6_abr_enable_area(oa
);
325 void ospf6_area_disable(struct ospf6_area
*oa
)
327 struct listnode
*node
, *nnode
;
328 struct ospf6_interface
*oi
;
330 UNSET_FLAG(oa
->flag
, OSPF6_AREA_ENABLE
);
332 for (ALL_LIST_ELEMENTS(oa
->if_list
, node
, nnode
, oi
))
333 ospf6_interface_disable(oi
);
335 ospf6_abr_disable_area(oa
);
336 ospf6_lsdb_remove_all(oa
->lsdb
);
337 ospf6_lsdb_remove_all(oa
->lsdb_self
);
339 ospf6_spf_table_finish(oa
->spf_table
);
340 ospf6_route_remove_all(oa
->route_table
);
342 THREAD_OFF(oa
->thread_router_lsa
);
343 THREAD_OFF(oa
->thread_intra_prefix_lsa
);
347 void ospf6_area_show(struct vty
*vty
, struct ospf6_area
*oa
)
350 struct ospf6_interface
*oi
;
351 unsigned long result
;
353 if (!IS_AREA_STUB(oa
))
354 vty_out(vty
, " Area %s\n", oa
->name
);
356 if (oa
->no_summary
) {
357 vty_out(vty
, " Area %s[Stub, No Summary]\n", oa
->name
);
359 vty_out(vty
, " Area %s[Stub]\n", oa
->name
);
362 vty_out(vty
, " Number of Area scoped LSAs is %u\n",
365 vty_out(vty
, " Interface attached to this area:");
366 for (ALL_LIST_ELEMENTS_RO(oa
->if_list
, i
, oi
))
367 vty_out(vty
, " %s", oi
->interface
->name
);
370 if (oa
->ts_spf
.tv_sec
|| oa
->ts_spf
.tv_usec
) {
371 result
= monotime_since(&oa
->ts_spf
, NULL
);
372 if (result
/ TIMER_SECOND_MICRO
> 0) {
373 vty_out(vty
, "SPF last executed %ld.%lds ago\n",
374 result
/ TIMER_SECOND_MICRO
,
375 result
% TIMER_SECOND_MICRO
);
377 vty_out(vty
, "SPF last executed %ldus ago\n", result
);
380 vty_out(vty
, "SPF has not been run\n");
384 #define OSPF6_CMD_AREA_GET(str, oa) \
387 uint32_t area_id = htonl(strtoul(str, &ep, 10)); \
388 if (*ep && inet_pton(AF_INET, str, &area_id) != 1) { \
389 vty_out(vty, "Malformed Area-ID: %s\n", str); \
390 return CMD_SUCCESS; \
392 int format = !*ep ? OSPF6_AREA_FMT_DECIMAL \
393 : OSPF6_AREA_FMT_DOTTEDQUAD; \
394 oa = ospf6_area_lookup(area_id, ospf6); \
396 oa = ospf6_area_create(area_id, ospf6, format); \
401 "area <A.B.C.D|(0-4294967295)> range X:X::X:X/M [<advertise|not-advertise|cost (0-16777215)>]",
402 "OSPF6 area parameters\n"
403 "OSPF6 area ID in IP address format\n"
404 "OSPF6 area ID as a decimal value\n"
405 "Configured address range\n"
406 "Specify IPv6 prefix\n"
409 "User specified metric for this range\n"
410 "Advertised metric for this range\n")
413 int idx_ipv6_prefixlen
= 3;
416 struct ospf6_area
*oa
;
417 struct prefix prefix
;
418 struct ospf6_route
*range
;
419 uint32_t cost
= OSPF_AREA_RANGE_COST_UNSPEC
;
421 OSPF6_CMD_AREA_GET(argv
[idx_ipv4
]->arg
, oa
);
423 ret
= str2prefix(argv
[idx_ipv6_prefixlen
]->arg
, &prefix
);
424 if (ret
!= 1 || prefix
.family
!= AF_INET6
) {
425 vty_out(vty
, "Malformed argument: %s\n",
426 argv
[idx_ipv6_prefixlen
]->arg
);
430 range
= ospf6_route_lookup(&prefix
, oa
->range_table
);
432 range
= ospf6_route_create();
433 range
->type
= OSPF6_DEST_TYPE_RANGE
;
434 range
->prefix
= prefix
;
435 range
->path
.area_id
= oa
->area_id
;
436 range
->path
.cost
= OSPF_AREA_RANGE_COST_UNSPEC
;
439 if (argc
> idx_type
) {
440 if (strmatch(argv
[idx_type
]->text
, "not-advertise")) {
441 SET_FLAG(range
->flag
, OSPF6_ROUTE_DO_NOT_ADVERTISE
);
442 } else if (strmatch(argv
[idx_type
]->text
, "advertise")) {
443 UNSET_FLAG(range
->flag
, OSPF6_ROUTE_DO_NOT_ADVERTISE
);
444 cost
= range
->path
.u
.cost_config
;
446 cost
= strtoul(argv
[5]->arg
, NULL
, 10);
447 UNSET_FLAG(range
->flag
, OSPF6_ROUTE_DO_NOT_ADVERTISE
);
451 range
->path
.u
.cost_config
= cost
;
453 zlog_debug("%s: for prefix %s, flag = %x\n", __func__
,
454 argv
[idx_ipv6_prefixlen
]->arg
, range
->flag
);
455 if (range
->rnode
== NULL
) {
456 ospf6_route_add(range
, oa
->range_table
);
459 if (ospf6_is_router_abr(ospf6
)) {
460 /* Redo summaries if required */
461 ospf6_abr_prefix_resummarize(ospf6
);
467 DEFUN (no_area_range
,
469 "no area <A.B.C.D|(0-4294967295)> range X:X::X:X/M [<advertise|not-advertise|cost (0-16777215)>]",
471 "OSPF6 area parameters\n"
472 "OSPF6 area ID in IP address format\n"
473 "OSPF6 area ID as a decimal value\n"
474 "Configured address range\n"
475 "Specify IPv6 prefix\n"
478 "User specified metric for this range\n"
479 "Advertised metric for this range\n")
484 struct ospf6_area
*oa
;
485 struct prefix prefix
;
486 struct ospf6_route
*range
, *route
;
488 OSPF6_CMD_AREA_GET(argv
[idx_ipv4
]->arg
, oa
);
490 ret
= str2prefix(argv
[idx_ipv6
]->arg
, &prefix
);
491 if (ret
!= 1 || prefix
.family
!= AF_INET6
) {
492 vty_out(vty
, "Malformed argument: %s\n", argv
[idx_ipv6
]->arg
);
496 range
= ospf6_route_lookup(&prefix
, oa
->range_table
);
498 vty_out(vty
, "Range %s does not exists.\n",
499 argv
[idx_ipv6
]->arg
);
503 if (ospf6_is_router_abr(oa
->ospf6
)) {
504 /* Blow away the aggregated LSA and route */
505 SET_FLAG(range
->flag
, OSPF6_ROUTE_REMOVE
);
507 /* Redo summaries if required */
508 for (route
= ospf6_route_head(ospf6
->route_table
); route
;
509 route
= ospf6_route_next(route
))
510 ospf6_abr_originate_summary(route
);
512 /* purge the old aggregated summary LSA */
513 ospf6_abr_originate_summary(range
);
515 ospf6_route_remove(range
, oa
->range_table
);
520 void ospf6_area_config_write(struct vty
*vty
)
522 struct listnode
*node
;
523 struct ospf6_area
*oa
;
524 struct ospf6_route
*range
;
525 char buf
[PREFIX2STR_BUFFER
];
527 for (ALL_LIST_ELEMENTS_RO(ospf6
->area_list
, node
, oa
)) {
528 for (range
= ospf6_route_head(oa
->range_table
); range
;
529 range
= ospf6_route_next(range
)) {
530 prefix2str(&range
->prefix
, buf
, sizeof(buf
));
531 vty_out(vty
, " area %s range %s", oa
->name
, buf
);
533 if (CHECK_FLAG(range
->flag
,
534 OSPF6_ROUTE_DO_NOT_ADVERTISE
)) {
535 vty_out(vty
, " not-advertise");
537 // "advertise" is the default so we do not
539 if (range
->path
.u
.cost_config
540 != OSPF_AREA_RANGE_COST_UNSPEC
)
541 vty_out(vty
, " cost %d",
542 range
->path
.u
.cost_config
);
546 if (IS_AREA_STUB(oa
)) {
548 vty_out(vty
, " area %s stub no-summary\n",
551 vty_out(vty
, " area %s stub\n", oa
->name
);
553 if (PREFIX_NAME_IN(oa
))
554 vty_out(vty
, " area %s filter-list prefix %s in\n",
555 oa
->name
, PREFIX_NAME_IN(oa
));
556 if (PREFIX_NAME_OUT(oa
))
557 vty_out(vty
, " area %s filter-list prefix %s out\n",
558 oa
->name
, PREFIX_NAME_OUT(oa
));
560 vty_out(vty
, " area %s import-list %s\n", oa
->name
,
563 vty_out(vty
, " area %s export-list %s\n", oa
->name
,
568 DEFUN (area_filter_list
,
569 area_filter_list_cmd
,
570 "area A.B.C.D filter-list prefix WORD <in|out>",
571 "OSPF6 area parameters\n"
572 "OSPF6 area ID in IP address format\n"
573 "Filter networks between OSPF6 areas\n"
574 "Filter prefixes between OSPF6 areas\n"
575 "Name of an IPv6 prefix-list\n"
576 "Filter networks sent to this area\n"
577 "Filter networks sent from this area\n")
579 char *inout
= argv
[argc
- 1]->text
;
580 char *areaid
= argv
[1]->arg
;
581 char *plistname
= argv
[4]->arg
;
583 struct ospf6_area
*area
;
584 struct prefix_list
*plist
;
586 OSPF6_CMD_AREA_GET(areaid
, area
);
588 plist
= prefix_list_lookup(AFI_IP6
, plistname
);
589 if (strmatch(inout
, "in")) {
590 PREFIX_LIST_IN(area
) = plist
;
591 XFREE(MTYPE_OSPF6_PLISTNAME
, PREFIX_NAME_IN(area
));
592 PREFIX_NAME_IN(area
) =
593 XSTRDUP(MTYPE_OSPF6_PLISTNAME
, plistname
);
594 ospf6_abr_reimport(area
);
596 PREFIX_LIST_OUT(area
) = plist
;
597 XFREE(MTYPE_OSPF6_PLISTNAME
, PREFIX_NAME_OUT(area
));
598 PREFIX_NAME_OUT(area
) =
599 XSTRDUP(MTYPE_OSPF6_PLISTNAME
, plistname
);
600 ospf6_abr_enable_area(area
);
606 DEFUN (no_area_filter_list
,
607 no_area_filter_list_cmd
,
608 "no area A.B.C.D filter-list prefix WORD <in|out>",
610 "OSPF6 area parameters\n"
611 "OSPF6 area ID in IP address format\n"
612 "Filter networks between OSPF6 areas\n"
613 "Filter prefixes between OSPF6 areas\n"
614 "Name of an IPv6 prefix-list\n"
615 "Filter networks sent to this area\n"
616 "Filter networks sent from this area\n")
618 char *inout
= argv
[argc
- 1]->text
;
619 char *areaid
= argv
[2]->arg
;
620 char *plistname
= argv
[5]->arg
;
622 struct ospf6_area
*area
;
624 OSPF6_CMD_AREA_GET(areaid
, area
);
626 if (strmatch(inout
, "in")) {
627 if (PREFIX_NAME_IN(area
))
628 if (!strmatch(PREFIX_NAME_IN(area
), plistname
))
631 PREFIX_LIST_IN(area
) = NULL
;
632 XFREE(MTYPE_OSPF6_PLISTNAME
, PREFIX_NAME_IN(area
));
633 ospf6_abr_reimport(area
);
635 if (PREFIX_NAME_OUT(area
))
636 if (!strmatch(PREFIX_NAME_OUT(area
), plistname
))
639 XFREE(MTYPE_OSPF6_PLISTNAME
, PREFIX_NAME_OUT(area
));
640 ospf6_abr_enable_area(area
);
646 void ospf6_area_plist_update(struct prefix_list
*plist
, int add
)
648 struct ospf6_area
*oa
;
650 const char *name
= prefix_list_name(plist
);
655 for (ALL_LIST_ELEMENTS_RO(ospf6
->area_list
, n
, oa
)) {
656 if (PREFIX_NAME_IN(oa
) && !strcmp(PREFIX_NAME_IN(oa
), name
))
657 PREFIX_LIST_IN(oa
) = add
? plist
: NULL
;
658 if (PREFIX_NAME_OUT(oa
) && !strcmp(PREFIX_NAME_OUT(oa
), name
))
659 PREFIX_LIST_OUT(oa
) = add
? plist
: NULL
;
663 DEFUN (area_import_list
,
664 area_import_list_cmd
,
665 "area A.B.C.D import-list NAME",
666 "OSPF6 area parameters\n"
667 "OSPF6 area ID in IP address format\n"
668 "Set the filter for networks from other areas announced to the specified one\n"
669 "Name of the acess-list\n")
673 struct ospf6_area
*area
;
674 struct access_list
*list
;
676 OSPF6_CMD_AREA_GET(argv
[idx_ipv4
]->arg
, area
);
678 list
= access_list_lookup(AFI_IP6
, argv
[idx_name
]->arg
);
680 IMPORT_LIST(area
) = list
;
682 if (IMPORT_NAME(area
))
683 free(IMPORT_NAME(area
));
685 IMPORT_NAME(area
) = strdup(argv
[idx_name
]->arg
);
686 ospf6_abr_reimport(area
);
691 DEFUN (no_area_import_list
,
692 no_area_import_list_cmd
,
693 "no area A.B.C.D import-list NAME",
695 "OSPF6 area parameters\n"
696 "OSPF6 area ID in IP address format\n"
697 "Unset the filter for networks announced to other areas\n"
698 "Name of the access-list\n")
701 struct ospf6_area
*area
;
703 OSPF6_CMD_AREA_GET(argv
[idx_ipv4
]->arg
, area
);
705 IMPORT_LIST(area
) = 0;
707 if (IMPORT_NAME(area
))
708 free(IMPORT_NAME(area
));
710 IMPORT_NAME(area
) = NULL
;
711 ospf6_abr_reimport(area
);
716 DEFUN (area_export_list
,
717 area_export_list_cmd
,
718 "area A.B.C.D export-list NAME",
719 "OSPF6 area parameters\n"
720 "OSPF6 area ID in IP address format\n"
721 "Set the filter for networks announced to other areas\n"
722 "Name of the acess-list\n")
726 struct ospf6_area
*area
;
727 struct access_list
*list
;
729 OSPF6_CMD_AREA_GET(argv
[idx_ipv4
]->arg
, area
);
731 list
= access_list_lookup(AFI_IP6
, argv
[idx_name
]->arg
);
733 EXPORT_LIST(area
) = list
;
735 if (EXPORT_NAME(area
))
736 free(EXPORT_NAME(area
));
738 EXPORT_NAME(area
) = strdup(argv
[idx_name
]->arg
);
739 ospf6_abr_enable_area(area
);
744 DEFUN (no_area_export_list
,
745 no_area_export_list_cmd
,
746 "no area A.B.C.D export-list NAME",
748 "OSPF6 area parameters\n"
749 "OSPF6 area ID in IP address format\n"
750 "Unset the filter for networks announced to other areas\n"
751 "Name of the access-list\n")
754 struct ospf6_area
*area
;
756 OSPF6_CMD_AREA_GET(argv
[idx_ipv4
]->arg
, area
);
758 EXPORT_LIST(area
) = 0;
760 if (EXPORT_NAME(area
))
761 free(EXPORT_NAME(area
));
763 EXPORT_NAME(area
) = NULL
;
764 ospf6_abr_enable_area(area
);
769 DEFUN (show_ipv6_ospf6_spf_tree
,
770 show_ipv6_ospf6_spf_tree_cmd
,
771 "show ipv6 ospf6 spf tree",
775 "Shortest Path First calculation\n"
778 struct listnode
*node
;
779 struct ospf6_area
*oa
;
780 struct ospf6_vertex
*root
;
781 struct ospf6_route
*route
;
782 struct prefix prefix
;
784 OSPF6_CMD_CHECK_RUNNING();
786 ospf6_linkstate_prefix(ospf6
->router_id
, htonl(0), &prefix
);
788 for (ALL_LIST_ELEMENTS_RO(ospf6
->area_list
, node
, oa
)) {
789 route
= ospf6_route_lookup(&prefix
, oa
->spf_table
);
791 vty_out(vty
, "LS entry for root not found in area %s\n",
795 root
= (struct ospf6_vertex
*)route
->route_option
;
796 ospf6_spf_display_subtree(vty
, "", 0, root
);
802 DEFUN (show_ipv6_ospf6_area_spf_tree
,
803 show_ipv6_ospf6_area_spf_tree_cmd
,
804 "show ipv6 ospf6 area A.B.C.D spf tree",
810 "Shortest Path First calculation\n"
815 struct ospf6_area
*oa
;
816 struct ospf6_vertex
*root
;
817 struct ospf6_route
*route
;
818 struct prefix prefix
;
820 OSPF6_CMD_CHECK_RUNNING();
822 ospf6_linkstate_prefix(ospf6
->router_id
, htonl(0), &prefix
);
824 if (inet_pton(AF_INET
, argv
[idx_ipv4
]->arg
, &area_id
) != 1) {
825 vty_out(vty
, "Malformed Area-ID: %s\n", argv
[idx_ipv4
]->arg
);
828 oa
= ospf6_area_lookup(area_id
, ospf6
);
830 vty_out(vty
, "No such Area: %s\n", argv
[idx_ipv4
]->arg
);
834 route
= ospf6_route_lookup(&prefix
, oa
->spf_table
);
836 vty_out(vty
, "LS entry for root not found in area %s\n",
840 root
= (struct ospf6_vertex
*)route
->route_option
;
841 ospf6_spf_display_subtree(vty
, "", 0, root
);
846 DEFUN (show_ipv6_ospf6_simulate_spf_tree_root
,
847 show_ipv6_ospf6_simulate_spf_tree_root_cmd
,
848 "show ipv6 ospf6 simulate spf-tree A.B.C.D area A.B.C.D",
852 "Shortest Path First calculation\n"
854 "Specify root's router-id to calculate another router's SPF tree\n"
855 "OSPF6 area parameters\n"
861 struct ospf6_area
*oa
;
862 struct ospf6_vertex
*root
;
863 struct ospf6_route
*route
;
864 struct prefix prefix
;
866 struct ospf6_route_table
*spf_table
;
867 unsigned char tmp_debug_ospf6_spf
= 0;
869 OSPF6_CMD_CHECK_RUNNING();
871 inet_pton(AF_INET
, argv
[idx_ipv4
]->arg
, &router_id
);
872 ospf6_linkstate_prefix(router_id
, htonl(0), &prefix
);
874 if (inet_pton(AF_INET
, argv
[idx_ipv4_2
]->arg
, &area_id
) != 1) {
875 vty_out(vty
, "Malformed Area-ID: %s\n", argv
[idx_ipv4_2
]->arg
);
878 oa
= ospf6_area_lookup(area_id
, ospf6
);
880 vty_out(vty
, "No such Area: %s\n", argv
[idx_ipv4_2
]->arg
);
884 tmp_debug_ospf6_spf
= conf_debug_ospf6_spf
;
885 conf_debug_ospf6_spf
= 0;
887 spf_table
= OSPF6_ROUTE_TABLE_CREATE(NONE
, SPF_RESULTS
);
888 ospf6_spf_calculation(router_id
, spf_table
, oa
);
890 conf_debug_ospf6_spf
= tmp_debug_ospf6_spf
;
892 route
= ospf6_route_lookup(&prefix
, spf_table
);
894 ospf6_spf_table_finish(spf_table
);
895 ospf6_route_table_delete(spf_table
);
898 root
= (struct ospf6_vertex
*)route
->route_option
;
899 ospf6_spf_display_subtree(vty
, "", 0, root
);
901 ospf6_spf_table_finish(spf_table
);
902 ospf6_route_table_delete(spf_table
);
907 DEFUN (ospf6_area_stub
,
909 "area <A.B.C.D|(0-4294967295)> stub",
910 "OSPF6 area parameters\n"
911 "OSPF6 area ID in IP address format\n"
912 "OSPF6 area ID as a decimal value\n"
913 "Configure OSPF6 area as stub\n")
915 int idx_ipv4_number
= 1;
916 struct ospf6_area
*area
;
918 OSPF6_CMD_AREA_GET(argv
[idx_ipv4_number
]->arg
, area
);
920 if (!ospf6_area_stub_set(ospf6
, area
)) {
922 "First deconfigure all virtual link through this area\n");
923 return CMD_WARNING_CONFIG_FAILED
;
926 ospf6_area_no_summary_unset(ospf6
, area
);
931 DEFUN (ospf6_area_stub_no_summary
,
932 ospf6_area_stub_no_summary_cmd
,
933 "area <A.B.C.D|(0-4294967295)> stub no-summary",
934 "OSPF6 stub parameters\n"
935 "OSPF6 area ID in IP address format\n"
936 "OSPF6 area ID as a decimal value\n"
937 "Configure OSPF6 area as stub\n"
938 "Do not inject inter-area routes into stub\n")
940 int idx_ipv4_number
= 1;
941 struct ospf6_area
*area
;
943 OSPF6_CMD_AREA_GET(argv
[idx_ipv4_number
]->arg
, area
);
945 if (!ospf6_area_stub_set(ospf6
, area
)) {
947 "First deconfigure all virtual link through this area\n");
948 return CMD_WARNING_CONFIG_FAILED
;
951 ospf6_area_no_summary_set(ospf6
, area
);
956 DEFUN (no_ospf6_area_stub
,
957 no_ospf6_area_stub_cmd
,
958 "no area <A.B.C.D|(0-4294967295)> stub",
960 "OSPF6 area parameters\n"
961 "OSPF6 area ID in IP address format\n"
962 "OSPF6 area ID as a decimal value\n"
963 "Configure OSPF6 area as stub\n")
965 int idx_ipv4_number
= 2;
966 struct ospf6_area
*area
;
968 OSPF6_CMD_AREA_GET(argv
[idx_ipv4_number
]->arg
, area
);
970 ospf6_area_stub_unset(ospf6
, area
);
971 ospf6_area_no_summary_unset(ospf6
, area
);
976 DEFUN (no_ospf6_area_stub_no_summary
,
977 no_ospf6_area_stub_no_summary_cmd
,
978 "no area <A.B.C.D|(0-4294967295)> stub no-summary",
980 "OSPF6 area parameters\n"
981 "OSPF6 area ID in IP address format\n"
982 "OSPF6 area ID as a decimal value\n"
983 "Configure OSPF6 area as stub\n"
984 "Do not inject inter-area routes into area\n")
986 int idx_ipv4_number
= 2;
987 struct ospf6_area
*area
;
989 OSPF6_CMD_AREA_GET(argv
[idx_ipv4_number
]->arg
, area
);
991 ospf6_area_stub_unset(ospf6
, area
);
992 ospf6_area_no_summary_unset(ospf6
, area
);
997 void ospf6_area_init(void)
999 install_element(VIEW_NODE
, &show_ipv6_ospf6_spf_tree_cmd
);
1000 install_element(VIEW_NODE
, &show_ipv6_ospf6_area_spf_tree_cmd
);
1001 install_element(VIEW_NODE
, &show_ipv6_ospf6_simulate_spf_tree_root_cmd
);
1003 install_element(OSPF6_NODE
, &area_range_cmd
);
1004 install_element(OSPF6_NODE
, &no_area_range_cmd
);
1005 install_element(OSPF6_NODE
, &ospf6_area_stub_no_summary_cmd
);
1006 install_element(OSPF6_NODE
, &ospf6_area_stub_cmd
);
1007 install_element(OSPF6_NODE
, &no_ospf6_area_stub_no_summary_cmd
);
1008 install_element(OSPF6_NODE
, &no_ospf6_area_stub_cmd
);
1011 install_element(OSPF6_NODE
, &area_import_list_cmd
);
1012 install_element(OSPF6_NODE
, &no_area_import_list_cmd
);
1013 install_element(OSPF6_NODE
, &area_export_list_cmd
);
1014 install_element(OSPF6_NODE
, &no_area_export_list_cmd
);
1016 install_element(OSPF6_NODE
, &area_filter_list_cmd
);
1017 install_element(OSPF6_NODE
, &no_area_filter_list_cmd
);