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
);
225 oa
->spf_table
= OSPF6_ROUTE_TABLE_CREATE(AREA
, SPF_RESULTS
);
226 oa
->spf_table
->scope
= oa
;
227 oa
->route_table
= OSPF6_ROUTE_TABLE_CREATE(AREA
, ROUTES
);
228 oa
->route_table
->scope
= oa
;
229 oa
->route_table
->hook_add
= ospf6_area_route_hook_add
;
230 oa
->route_table
->hook_remove
= ospf6_area_route_hook_remove
;
232 oa
->range_table
= OSPF6_ROUTE_TABLE_CREATE(AREA
, PREFIX_RANGES
);
233 oa
->range_table
->scope
= oa
;
234 bf_init(oa
->range_table
->idspace
, 32);
235 oa
->summary_prefix
= OSPF6_ROUTE_TABLE_CREATE(AREA
, SUMMARY_PREFIXES
);
236 oa
->summary_prefix
->scope
= oa
;
237 oa
->summary_router
= OSPF6_ROUTE_TABLE_CREATE(AREA
, SUMMARY_ROUTERS
);
238 oa
->summary_router
->scope
= oa
;
239 oa
->router_lsa_size_limit
= 1024 + 256;
241 /* set default options */
242 if (CHECK_FLAG(o
->flag
, OSPF6_STUB_ROUTER
)) {
243 OSPF6_OPT_CLEAR(oa
->options
, OSPF6_OPT_V6
);
244 OSPF6_OPT_CLEAR(oa
->options
, OSPF6_OPT_R
);
246 OSPF6_OPT_SET(oa
->options
, OSPF6_OPT_V6
);
247 OSPF6_OPT_SET(oa
->options
, OSPF6_OPT_R
);
250 OSPF6_OPT_SET(oa
->options
, OSPF6_OPT_E
);
252 SET_FLAG(oa
->flag
, OSPF6_AREA_ACTIVE
);
253 SET_FLAG(oa
->flag
, OSPF6_AREA_ENABLE
);
256 listnode_add_sort(o
->area_list
, oa
);
258 if (area_id
== OSPF_AREA_BACKBONE
) {
265 void ospf6_area_delete(struct ospf6_area
*oa
)
268 struct ospf6_interface
*oi
;
270 /* The ospf6_interface structs store configuration
271 * information which should not be lost/reset when
273 * So just detach the interface from the area and
275 for (ALL_LIST_ELEMENTS_RO(oa
->if_list
, n
, oi
))
278 list_delete_and_null(&oa
->if_list
);
280 ospf6_lsdb_delete(oa
->lsdb
);
281 ospf6_lsdb_delete(oa
->lsdb_self
);
283 ospf6_spf_table_finish(oa
->spf_table
);
284 ospf6_route_table_delete(oa
->spf_table
);
285 ospf6_route_table_delete(oa
->route_table
);
287 ospf6_route_table_delete(oa
->range_table
);
288 ospf6_route_table_delete(oa
->summary_prefix
);
289 ospf6_route_table_delete(oa
->summary_router
);
291 listnode_delete(oa
->ospf6
->area_list
, oa
);
295 XFREE(MTYPE_OSPF6_AREA
, oa
);
298 struct ospf6_area
*ospf6_area_lookup(u_int32_t area_id
, struct ospf6
*ospf6
)
300 struct ospf6_area
*oa
;
303 for (ALL_LIST_ELEMENTS_RO(ospf6
->area_list
, n
, oa
))
304 if (oa
->area_id
== area_id
)
307 return (struct ospf6_area
*)NULL
;
310 void ospf6_area_enable(struct ospf6_area
*oa
)
312 struct listnode
*node
, *nnode
;
313 struct ospf6_interface
*oi
;
315 SET_FLAG(oa
->flag
, OSPF6_AREA_ENABLE
);
317 for (ALL_LIST_ELEMENTS(oa
->if_list
, node
, nnode
, oi
))
318 ospf6_interface_enable(oi
);
319 ospf6_abr_enable_area(oa
);
322 void ospf6_area_disable(struct ospf6_area
*oa
)
324 struct listnode
*node
, *nnode
;
325 struct ospf6_interface
*oi
;
327 UNSET_FLAG(oa
->flag
, OSPF6_AREA_ENABLE
);
329 for (ALL_LIST_ELEMENTS(oa
->if_list
, node
, nnode
, oi
))
330 ospf6_interface_disable(oi
);
332 ospf6_abr_disable_area(oa
);
333 ospf6_lsdb_remove_all(oa
->lsdb
);
334 ospf6_lsdb_remove_all(oa
->lsdb_self
);
336 ospf6_spf_table_finish(oa
->spf_table
);
337 ospf6_route_remove_all(oa
->route_table
);
339 THREAD_OFF(oa
->thread_router_lsa
);
340 THREAD_OFF(oa
->thread_intra_prefix_lsa
);
344 void ospf6_area_show(struct vty
*vty
, struct ospf6_area
*oa
)
347 struct ospf6_interface
*oi
;
348 unsigned long result
;
350 if (!IS_AREA_STUB(oa
))
351 vty_out(vty
, " Area %s\n", oa
->name
);
353 if (oa
->no_summary
) {
354 vty_out(vty
, " Area %s[Stub, No Summary]\n", oa
->name
);
356 vty_out(vty
, " Area %s[Stub]\n", oa
->name
);
359 vty_out(vty
, " Number of Area scoped LSAs is %u\n",
362 vty_out(vty
, " Interface attached to this area:");
363 for (ALL_LIST_ELEMENTS_RO(oa
->if_list
, i
, oi
))
364 vty_out(vty
, " %s", oi
->interface
->name
);
367 if (oa
->ts_spf
.tv_sec
|| oa
->ts_spf
.tv_usec
) {
368 result
= monotime_since(&oa
->ts_spf
, NULL
);
369 if (result
/ TIMER_SECOND_MICRO
> 0) {
370 vty_out(vty
, "SPF last executed %ld.%lds ago\n",
371 result
/ TIMER_SECOND_MICRO
,
372 result
% TIMER_SECOND_MICRO
);
374 vty_out(vty
, "SPF last executed %ldus ago\n", result
);
377 vty_out(vty
, "SPF has not been run\n");
381 #define OSPF6_CMD_AREA_GET(str, oa) \
384 u_int32_t area_id = htonl(strtoul(str, &ep, 10)); \
385 if (*ep && inet_pton(AF_INET, str, &area_id) != 1) { \
386 vty_out(vty, "Malformed Area-ID: %s\n", str); \
387 return CMD_SUCCESS; \
389 int format = !*ep ? OSPF6_AREA_FMT_DECIMAL \
390 : OSPF6_AREA_FMT_DOTTEDQUAD; \
391 oa = ospf6_area_lookup(area_id, ospf6); \
393 oa = ospf6_area_create(area_id, ospf6, format); \
398 "area <A.B.C.D|(0-4294967295)> range X:X::X:X/M [<advertise|not-advertise|cost (0-16777215)>]",
399 "OSPF6 area parameters\n"
400 "OSPF6 area ID in IP address format\n"
401 "OSPF6 area ID as a decimal value\n"
402 "Configured address range\n"
403 "Specify IPv6 prefix\n"
406 "User specified metric for this range\n"
407 "Advertised metric for this range\n")
410 int idx_ipv6_prefixlen
= 3;
413 struct ospf6_area
*oa
;
414 struct prefix prefix
;
415 struct ospf6_route
*range
;
416 u_int32_t cost
= OSPF_AREA_RANGE_COST_UNSPEC
;
418 OSPF6_CMD_AREA_GET(argv
[idx_ipv4
]->arg
, oa
);
420 ret
= str2prefix(argv
[idx_ipv6_prefixlen
]->arg
, &prefix
);
421 if (ret
!= 1 || prefix
.family
!= AF_INET6
) {
422 vty_out(vty
, "Malformed argument: %s\n",
423 argv
[idx_ipv6_prefixlen
]->arg
);
427 range
= ospf6_route_lookup(&prefix
, oa
->range_table
);
429 range
= ospf6_route_create();
430 range
->type
= OSPF6_DEST_TYPE_RANGE
;
431 range
->prefix
= prefix
;
432 range
->path
.area_id
= oa
->area_id
;
433 range
->path
.cost
= OSPF_AREA_RANGE_COST_UNSPEC
;
436 if (argc
> idx_type
) {
437 if (strmatch(argv
[idx_type
]->text
, "not-advertise")) {
438 SET_FLAG(range
->flag
, OSPF6_ROUTE_DO_NOT_ADVERTISE
);
439 } else if (strmatch(argv
[idx_type
]->text
, "advertise")) {
440 UNSET_FLAG(range
->flag
, OSPF6_ROUTE_DO_NOT_ADVERTISE
);
442 cost
= strtoul(argv
[5]->arg
, NULL
, 10);
443 UNSET_FLAG(range
->flag
, OSPF6_ROUTE_DO_NOT_ADVERTISE
);
447 range
->path
.u
.cost_config
= cost
;
449 zlog_debug("%s: for prefix %s, flag = %x\n", __func__
,
450 argv
[idx_ipv6_prefixlen
]->arg
, range
->flag
);
451 if (range
->rnode
== NULL
) {
452 ospf6_route_add(range
, oa
->range_table
);
455 if (ospf6_is_router_abr(ospf6
)) {
456 /* Redo summaries if required */
457 ospf6_abr_prefix_resummarize(ospf6
);
463 DEFUN (no_area_range
,
465 "no area <A.B.C.D|(0-4294967295)> range X:X::X:X/M [<advertise|not-advertise|cost (0-16777215)>]",
467 "OSPF6 area parameters\n"
468 "OSPF6 area ID in IP address format\n"
469 "OSPF6 area ID as a decimal value\n"
470 "Configured address range\n"
471 "Specify IPv6 prefix\n"
474 "User specified metric for this range\n"
475 "Advertised metric for this range\n")
480 struct ospf6_area
*oa
;
481 struct prefix prefix
;
482 struct ospf6_route
*range
, *route
;
484 OSPF6_CMD_AREA_GET(argv
[idx_ipv4
]->arg
, oa
);
486 ret
= str2prefix(argv
[idx_ipv6
]->arg
, &prefix
);
487 if (ret
!= 1 || prefix
.family
!= AF_INET6
) {
488 vty_out(vty
, "Malformed argument: %s\n", argv
[idx_ipv6
]->arg
);
492 range
= ospf6_route_lookup(&prefix
, oa
->range_table
);
494 vty_out(vty
, "Range %s does not exists.\n",
495 argv
[idx_ipv6
]->arg
);
499 if (ospf6_is_router_abr(oa
->ospf6
)) {
500 /* Blow away the aggregated LSA and route */
501 SET_FLAG(range
->flag
, OSPF6_ROUTE_REMOVE
);
503 /* Redo summaries if required */
504 for (route
= ospf6_route_head(ospf6
->route_table
); route
;
505 route
= ospf6_route_next(route
))
506 ospf6_abr_originate_summary(route
);
508 /* purge the old aggregated summary LSA */
509 ospf6_abr_originate_summary(range
);
511 ospf6_route_remove(range
, oa
->range_table
);
516 void ospf6_area_config_write(struct vty
*vty
)
518 struct listnode
*node
;
519 struct ospf6_area
*oa
;
520 struct ospf6_route
*range
;
521 char buf
[PREFIX2STR_BUFFER
];
523 for (ALL_LIST_ELEMENTS_RO(ospf6
->area_list
, node
, oa
)) {
524 for (range
= ospf6_route_head(oa
->range_table
); range
;
525 range
= ospf6_route_next(range
)) {
526 prefix2str(&range
->prefix
, buf
, sizeof(buf
));
527 vty_out(vty
, " area %s range %s", oa
->name
, buf
);
529 if (CHECK_FLAG(range
->flag
,
530 OSPF6_ROUTE_DO_NOT_ADVERTISE
)) {
531 vty_out(vty
, " not-advertise");
533 // "advertise" is the default so we do not
535 if (range
->path
.u
.cost_config
536 != OSPF_AREA_RANGE_COST_UNSPEC
)
537 vty_out(vty
, " cost %d",
538 range
->path
.u
.cost_config
);
542 if (IS_AREA_STUB(oa
)) {
544 vty_out(vty
, " area %s stub no-summary\n",
547 vty_out(vty
, " area %s stub\n", oa
->name
);
549 if (PREFIX_NAME_IN(oa
))
550 vty_out(vty
, " area %s filter-list prefix %s in\n",
551 oa
->name
, PREFIX_NAME_IN(oa
));
552 if (PREFIX_NAME_OUT(oa
))
553 vty_out(vty
, " area %s filter-list prefix %s out\n",
554 oa
->name
, PREFIX_NAME_OUT(oa
));
556 vty_out(vty
, " area %s import-list %s\n", oa
->name
,
559 vty_out(vty
, " area %s export-list %s\n", oa
->name
,
564 DEFUN (area_filter_list
,
565 area_filter_list_cmd
,
566 "area A.B.C.D filter-list prefix WORD <in|out>",
567 "OSPF6 area parameters\n"
568 "OSPF6 area ID in IP address format\n"
569 "Filter networks between OSPF6 areas\n"
570 "Filter prefixes between OSPF6 areas\n"
571 "Name of an IPv6 prefix-list\n"
572 "Filter networks sent to this area\n"
573 "Filter networks sent from this area\n")
575 char *inout
= argv
[argc
- 1]->text
;
576 char *areaid
= argv
[1]->arg
;
577 char *plistname
= argv
[4]->arg
;
579 struct ospf6_area
*area
;
580 struct prefix_list
*plist
;
582 OSPF6_CMD_AREA_GET(areaid
, area
);
584 plist
= prefix_list_lookup(AFI_IP6
, plistname
);
585 if (strmatch(inout
, "in")) {
586 PREFIX_LIST_IN(area
) = plist
;
587 XFREE(MTYPE_OSPF6_PLISTNAME
, PREFIX_NAME_IN(area
));
588 PREFIX_NAME_IN(area
) = XSTRDUP(MTYPE_OSPF6_PLISTNAME
,
590 ospf6_abr_reimport(area
);
592 PREFIX_LIST_OUT(area
) = plist
;
593 XFREE(MTYPE_OSPF6_PLISTNAME
, PREFIX_NAME_OUT(area
));
594 PREFIX_NAME_OUT(area
) = XSTRDUP(MTYPE_OSPF6_PLISTNAME
,
596 ospf6_abr_enable_area(area
);
602 DEFUN (no_area_filter_list
,
603 no_area_filter_list_cmd
,
604 "no area A.B.C.D filter-list prefix WORD <in|out>",
606 "OSPF6 area parameters\n"
607 "OSPF6 area ID in IP address format\n"
608 "Filter networks between OSPF6 areas\n"
609 "Filter prefixes between OSPF6 areas\n"
610 "Name of an IPv6 prefix-list\n"
611 "Filter networks sent to this area\n"
612 "Filter networks sent from this area\n")
614 char *inout
= argv
[argc
- 1]->text
;
615 char *areaid
= argv
[2]->arg
;
616 char *plistname
= argv
[5]->arg
;
618 struct ospf6_area
*area
;
620 OSPF6_CMD_AREA_GET(areaid
, area
);
622 if (strmatch(inout
, "in")) {
623 if (PREFIX_NAME_IN(area
))
624 if (!strmatch(PREFIX_NAME_IN(area
), plistname
))
627 PREFIX_LIST_IN(area
) = NULL
;
628 XFREE(MTYPE_OSPF6_PLISTNAME
, PREFIX_NAME_IN(area
));
629 ospf6_abr_reimport(area
);
631 if (PREFIX_NAME_OUT(area
))
632 if (!strmatch(PREFIX_NAME_OUT(area
), plistname
))
635 XFREE(MTYPE_OSPF6_PLISTNAME
, PREFIX_NAME_OUT(area
));
636 ospf6_abr_enable_area(area
);
642 void ospf6_area_plist_update(struct prefix_list
*plist
, int add
)
644 struct ospf6_area
*oa
;
646 const char *name
= prefix_list_name(plist
);
651 for (ALL_LIST_ELEMENTS_RO(ospf6
->area_list
, n
, oa
)) {
652 if (PREFIX_NAME_IN(oa
) && !strcmp(PREFIX_NAME_IN(oa
), name
))
653 PREFIX_LIST_IN(oa
) = add
? plist
: NULL
;
654 if (PREFIX_NAME_OUT(oa
) && !strcmp(PREFIX_NAME_OUT(oa
), name
))
655 PREFIX_LIST_OUT(oa
) = add
? plist
: NULL
;
659 DEFUN (area_import_list
,
660 area_import_list_cmd
,
661 "area A.B.C.D import-list NAME",
662 "OSPF6 area parameters\n"
663 "OSPF6 area ID in IP address format\n"
664 "Set the filter for networks from other areas announced to the specified one\n"
665 "Name of the acess-list\n")
669 struct ospf6_area
*area
;
670 struct access_list
*list
;
672 OSPF6_CMD_AREA_GET(argv
[idx_ipv4
]->arg
, area
);
674 list
= access_list_lookup(AFI_IP6
, argv
[idx_name
]->arg
);
676 IMPORT_LIST(area
) = list
;
678 if (IMPORT_NAME(area
))
679 free(IMPORT_NAME(area
));
681 IMPORT_NAME(area
) = strdup(argv
[idx_name
]->arg
);
682 ospf6_abr_reimport(area
);
687 DEFUN (no_area_import_list
,
688 no_area_import_list_cmd
,
689 "no area A.B.C.D import-list NAME",
691 "OSPF6 area parameters\n"
692 "OSPF6 area ID in IP address format\n"
693 "Unset the filter for networks announced to other areas\n"
694 "Name of the access-list\n")
697 struct ospf6_area
*area
;
699 OSPF6_CMD_AREA_GET(argv
[idx_ipv4
]->arg
, area
);
701 IMPORT_LIST(area
) = 0;
703 if (IMPORT_NAME(area
))
704 free(IMPORT_NAME(area
));
706 IMPORT_NAME(area
) = NULL
;
707 ospf6_abr_reimport(area
);
712 DEFUN (area_export_list
,
713 area_export_list_cmd
,
714 "area A.B.C.D export-list NAME",
715 "OSPF6 area parameters\n"
716 "OSPF6 area ID in IP address format\n"
717 "Set the filter for networks announced to other areas\n"
718 "Name of the acess-list\n")
722 struct ospf6_area
*area
;
723 struct access_list
*list
;
725 OSPF6_CMD_AREA_GET(argv
[idx_ipv4
]->arg
, area
);
727 list
= access_list_lookup(AFI_IP6
, argv
[idx_name
]->arg
);
729 EXPORT_LIST(area
) = list
;
731 if (EXPORT_NAME(area
))
732 free(EXPORT_NAME(area
));
734 EXPORT_NAME(area
) = strdup(argv
[idx_name
]->arg
);
735 ospf6_abr_enable_area(area
);
740 DEFUN (no_area_export_list
,
741 no_area_export_list_cmd
,
742 "no area A.B.C.D export-list NAME",
744 "OSPF6 area parameters\n"
745 "OSPF6 area ID in IP address format\n"
746 "Unset the filter for networks announced to other areas\n"
747 "Name of the access-list\n")
750 struct ospf6_area
*area
;
752 OSPF6_CMD_AREA_GET(argv
[idx_ipv4
]->arg
, area
);
754 EXPORT_LIST(area
) = 0;
756 if (EXPORT_NAME(area
))
757 free(EXPORT_NAME(area
));
759 EXPORT_NAME(area
) = NULL
;
760 ospf6_abr_enable_area(area
);
765 DEFUN (show_ipv6_ospf6_spf_tree
,
766 show_ipv6_ospf6_spf_tree_cmd
,
767 "show ipv6 ospf6 spf tree",
771 "Shortest Path First caculation\n"
774 struct listnode
*node
;
775 struct ospf6_area
*oa
;
776 struct ospf6_vertex
*root
;
777 struct ospf6_route
*route
;
778 struct prefix prefix
;
780 OSPF6_CMD_CHECK_RUNNING();
782 ospf6_linkstate_prefix(ospf6
->router_id
, htonl(0), &prefix
);
784 for (ALL_LIST_ELEMENTS_RO(ospf6
->area_list
, node
, oa
)) {
785 route
= ospf6_route_lookup(&prefix
, oa
->spf_table
);
787 vty_out(vty
, "LS entry for root not found in area %s\n",
791 root
= (struct ospf6_vertex
*)route
->route_option
;
792 ospf6_spf_display_subtree(vty
, "", 0, root
);
798 DEFUN (show_ipv6_ospf6_area_spf_tree
,
799 show_ipv6_ospf6_area_spf_tree_cmd
,
800 "show ipv6 ospf6 area A.B.C.D spf tree",
806 "Shortest Path First caculation\n"
811 struct ospf6_area
*oa
;
812 struct ospf6_vertex
*root
;
813 struct ospf6_route
*route
;
814 struct prefix prefix
;
816 OSPF6_CMD_CHECK_RUNNING();
818 ospf6_linkstate_prefix(ospf6
->router_id
, htonl(0), &prefix
);
820 if (inet_pton(AF_INET
, argv
[idx_ipv4
]->arg
, &area_id
) != 1) {
821 vty_out(vty
, "Malformed Area-ID: %s\n", argv
[idx_ipv4
]->arg
);
824 oa
= ospf6_area_lookup(area_id
, ospf6
);
826 vty_out(vty
, "No such Area: %s\n", argv
[idx_ipv4
]->arg
);
830 route
= ospf6_route_lookup(&prefix
, oa
->spf_table
);
832 vty_out(vty
, "LS entry for root not found in area %s\n",
836 root
= (struct ospf6_vertex
*)route
->route_option
;
837 ospf6_spf_display_subtree(vty
, "", 0, root
);
842 DEFUN (show_ipv6_ospf6_simulate_spf_tree_root
,
843 show_ipv6_ospf6_simulate_spf_tree_root_cmd
,
844 "show ipv6 ospf6 simulate spf-tree A.B.C.D area A.B.C.D",
848 "Shortest Path First calculation\n"
850 "Specify root's router-id to calculate another router's SPF tree\n"
851 "OSPF6 area parameters\n"
857 struct ospf6_area
*oa
;
858 struct ospf6_vertex
*root
;
859 struct ospf6_route
*route
;
860 struct prefix prefix
;
862 struct ospf6_route_table
*spf_table
;
863 unsigned char tmp_debug_ospf6_spf
= 0;
865 OSPF6_CMD_CHECK_RUNNING();
867 inet_pton(AF_INET
, argv
[idx_ipv4
]->arg
, &router_id
);
868 ospf6_linkstate_prefix(router_id
, htonl(0), &prefix
);
870 if (inet_pton(AF_INET
, argv
[idx_ipv4_2
]->arg
, &area_id
) != 1) {
871 vty_out(vty
, "Malformed Area-ID: %s\n", argv
[idx_ipv4_2
]->arg
);
874 oa
= ospf6_area_lookup(area_id
, ospf6
);
876 vty_out(vty
, "No such Area: %s\n", argv
[idx_ipv4_2
]->arg
);
880 tmp_debug_ospf6_spf
= conf_debug_ospf6_spf
;
881 conf_debug_ospf6_spf
= 0;
883 spf_table
= OSPF6_ROUTE_TABLE_CREATE(NONE
, SPF_RESULTS
);
884 ospf6_spf_calculation(router_id
, spf_table
, oa
);
886 conf_debug_ospf6_spf
= tmp_debug_ospf6_spf
;
888 route
= ospf6_route_lookup(&prefix
, spf_table
);
890 ospf6_spf_table_finish(spf_table
);
891 ospf6_route_table_delete(spf_table
);
894 root
= (struct ospf6_vertex
*)route
->route_option
;
895 ospf6_spf_display_subtree(vty
, "", 0, root
);
897 ospf6_spf_table_finish(spf_table
);
898 ospf6_route_table_delete(spf_table
);
903 DEFUN (ospf6_area_stub
,
905 "area <A.B.C.D|(0-4294967295)> stub",
906 "OSPF6 area parameters\n"
907 "OSPF6 area ID in IP address format\n"
908 "OSPF6 area ID as a decimal value\n"
909 "Configure OSPF6 area as stub\n")
911 int idx_ipv4_number
= 1;
912 struct ospf6_area
*area
;
914 OSPF6_CMD_AREA_GET(argv
[idx_ipv4_number
]->arg
, area
);
916 if (!ospf6_area_stub_set(ospf6
, area
)) {
918 "First deconfigure all virtual link through this area\n");
919 return CMD_WARNING_CONFIG_FAILED
;
922 ospf6_area_no_summary_unset(ospf6
, area
);
927 DEFUN (ospf6_area_stub_no_summary
,
928 ospf6_area_stub_no_summary_cmd
,
929 "area <A.B.C.D|(0-4294967295)> stub no-summary",
930 "OSPF6 stub parameters\n"
931 "OSPF6 area ID in IP address format\n"
932 "OSPF6 area ID as a decimal value\n"
933 "Configure OSPF6 area as stub\n"
934 "Do not inject inter-area routes into stub\n")
936 int idx_ipv4_number
= 1;
937 struct ospf6_area
*area
;
939 OSPF6_CMD_AREA_GET(argv
[idx_ipv4_number
]->arg
, area
);
941 if (!ospf6_area_stub_set(ospf6
, area
)) {
943 "First deconfigure all virtual link through this area\n");
944 return CMD_WARNING_CONFIG_FAILED
;
947 ospf6_area_no_summary_set(ospf6
, area
);
952 DEFUN (no_ospf6_area_stub
,
953 no_ospf6_area_stub_cmd
,
954 "no area <A.B.C.D|(0-4294967295)> stub",
956 "OSPF6 area parameters\n"
957 "OSPF6 area ID in IP address format\n"
958 "OSPF6 area ID as a decimal value\n"
959 "Configure OSPF6 area as stub\n")
961 int idx_ipv4_number
= 2;
962 struct ospf6_area
*area
;
964 OSPF6_CMD_AREA_GET(argv
[idx_ipv4_number
]->arg
, area
);
966 ospf6_area_stub_unset(ospf6
, area
);
967 ospf6_area_no_summary_unset(ospf6
, area
);
972 DEFUN (no_ospf6_area_stub_no_summary
,
973 no_ospf6_area_stub_no_summary_cmd
,
974 "no area <A.B.C.D|(0-4294967295)> stub no-summary",
976 "OSPF6 area parameters\n"
977 "OSPF6 area ID in IP address format\n"
978 "OSPF6 area ID as a decimal value\n"
979 "Configure OSPF6 area as stub\n"
980 "Do not inject inter-area routes into area\n")
982 int idx_ipv4_number
= 2;
983 struct ospf6_area
*area
;
985 OSPF6_CMD_AREA_GET(argv
[idx_ipv4_number
]->arg
, area
);
987 ospf6_area_stub_unset(ospf6
, area
);
988 ospf6_area_no_summary_unset(ospf6
, area
);
993 void ospf6_area_init(void)
995 install_element(VIEW_NODE
, &show_ipv6_ospf6_spf_tree_cmd
);
996 install_element(VIEW_NODE
, &show_ipv6_ospf6_area_spf_tree_cmd
);
997 install_element(VIEW_NODE
, &show_ipv6_ospf6_simulate_spf_tree_root_cmd
);
999 install_element(OSPF6_NODE
, &area_range_cmd
);
1000 install_element(OSPF6_NODE
, &no_area_range_cmd
);
1001 install_element(OSPF6_NODE
, &ospf6_area_stub_no_summary_cmd
);
1002 install_element(OSPF6_NODE
, &ospf6_area_stub_cmd
);
1003 install_element(OSPF6_NODE
, &no_ospf6_area_stub_no_summary_cmd
);
1004 install_element(OSPF6_NODE
, &no_ospf6_area_stub_cmd
);
1007 install_element(OSPF6_NODE
, &area_import_list_cmd
);
1008 install_element(OSPF6_NODE
, &no_area_import_list_cmd
);
1009 install_element(OSPF6_NODE
, &area_export_list_cmd
);
1010 install_element(OSPF6_NODE
, &no_area_export_list_cmd
);
1012 install_element(OSPF6_NODE
, &area_filter_list_cmd
);
1013 install_element(OSPF6_NODE
, &no_area_filter_list_cmd
);