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_and_null(&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
);
445 cost
= strtoul(argv
[5]->arg
, NULL
, 10);
446 UNSET_FLAG(range
->flag
, OSPF6_ROUTE_DO_NOT_ADVERTISE
);
450 range
->path
.u
.cost_config
= cost
;
452 zlog_debug("%s: for prefix %s, flag = %x\n", __func__
,
453 argv
[idx_ipv6_prefixlen
]->arg
, range
->flag
);
454 if (range
->rnode
== NULL
) {
455 ospf6_route_add(range
, oa
->range_table
);
458 if (ospf6_is_router_abr(ospf6
)) {
459 /* Redo summaries if required */
460 ospf6_abr_prefix_resummarize(ospf6
);
466 DEFUN (no_area_range
,
468 "no area <A.B.C.D|(0-4294967295)> range X:X::X:X/M [<advertise|not-advertise|cost (0-16777215)>]",
470 "OSPF6 area parameters\n"
471 "OSPF6 area ID in IP address format\n"
472 "OSPF6 area ID as a decimal value\n"
473 "Configured address range\n"
474 "Specify IPv6 prefix\n"
477 "User specified metric for this range\n"
478 "Advertised metric for this range\n")
483 struct ospf6_area
*oa
;
484 struct prefix prefix
;
485 struct ospf6_route
*range
, *route
;
487 OSPF6_CMD_AREA_GET(argv
[idx_ipv4
]->arg
, oa
);
489 ret
= str2prefix(argv
[idx_ipv6
]->arg
, &prefix
);
490 if (ret
!= 1 || prefix
.family
!= AF_INET6
) {
491 vty_out(vty
, "Malformed argument: %s\n", argv
[idx_ipv6
]->arg
);
495 range
= ospf6_route_lookup(&prefix
, oa
->range_table
);
497 vty_out(vty
, "Range %s does not exists.\n",
498 argv
[idx_ipv6
]->arg
);
502 if (ospf6_is_router_abr(oa
->ospf6
)) {
503 /* Blow away the aggregated LSA and route */
504 SET_FLAG(range
->flag
, OSPF6_ROUTE_REMOVE
);
506 /* Redo summaries if required */
507 for (route
= ospf6_route_head(ospf6
->route_table
); route
;
508 route
= ospf6_route_next(route
))
509 ospf6_abr_originate_summary(route
);
511 /* purge the old aggregated summary LSA */
512 ospf6_abr_originate_summary(range
);
514 ospf6_route_remove(range
, oa
->range_table
);
519 void ospf6_area_config_write(struct vty
*vty
)
521 struct listnode
*node
;
522 struct ospf6_area
*oa
;
523 struct ospf6_route
*range
;
524 char buf
[PREFIX2STR_BUFFER
];
526 for (ALL_LIST_ELEMENTS_RO(ospf6
->area_list
, node
, oa
)) {
527 for (range
= ospf6_route_head(oa
->range_table
); range
;
528 range
= ospf6_route_next(range
)) {
529 prefix2str(&range
->prefix
, buf
, sizeof(buf
));
530 vty_out(vty
, " area %s range %s", oa
->name
, buf
);
532 if (CHECK_FLAG(range
->flag
,
533 OSPF6_ROUTE_DO_NOT_ADVERTISE
)) {
534 vty_out(vty
, " not-advertise");
536 // "advertise" is the default so we do not
538 if (range
->path
.u
.cost_config
539 != OSPF_AREA_RANGE_COST_UNSPEC
)
540 vty_out(vty
, " cost %d",
541 range
->path
.u
.cost_config
);
545 if (IS_AREA_STUB(oa
)) {
547 vty_out(vty
, " area %s stub no-summary\n",
550 vty_out(vty
, " area %s stub\n", oa
->name
);
552 if (PREFIX_NAME_IN(oa
))
553 vty_out(vty
, " area %s filter-list prefix %s in\n",
554 oa
->name
, PREFIX_NAME_IN(oa
));
555 if (PREFIX_NAME_OUT(oa
))
556 vty_out(vty
, " area %s filter-list prefix %s out\n",
557 oa
->name
, PREFIX_NAME_OUT(oa
));
559 vty_out(vty
, " area %s import-list %s\n", oa
->name
,
562 vty_out(vty
, " area %s export-list %s\n", oa
->name
,
567 DEFUN (area_filter_list
,
568 area_filter_list_cmd
,
569 "area A.B.C.D filter-list prefix WORD <in|out>",
570 "OSPF6 area parameters\n"
571 "OSPF6 area ID in IP address format\n"
572 "Filter networks between OSPF6 areas\n"
573 "Filter prefixes between OSPF6 areas\n"
574 "Name of an IPv6 prefix-list\n"
575 "Filter networks sent to this area\n"
576 "Filter networks sent from this area\n")
578 char *inout
= argv
[argc
- 1]->text
;
579 char *areaid
= argv
[1]->arg
;
580 char *plistname
= argv
[4]->arg
;
582 struct ospf6_area
*area
;
583 struct prefix_list
*plist
;
585 OSPF6_CMD_AREA_GET(areaid
, area
);
587 plist
= prefix_list_lookup(AFI_IP6
, plistname
);
588 if (strmatch(inout
, "in")) {
589 PREFIX_LIST_IN(area
) = plist
;
590 XFREE(MTYPE_OSPF6_PLISTNAME
, PREFIX_NAME_IN(area
));
591 PREFIX_NAME_IN(area
) =
592 XSTRDUP(MTYPE_OSPF6_PLISTNAME
, plistname
);
593 ospf6_abr_reimport(area
);
595 PREFIX_LIST_OUT(area
) = plist
;
596 XFREE(MTYPE_OSPF6_PLISTNAME
, PREFIX_NAME_OUT(area
));
597 PREFIX_NAME_OUT(area
) =
598 XSTRDUP(MTYPE_OSPF6_PLISTNAME
, plistname
);
599 ospf6_abr_enable_area(area
);
605 DEFUN (no_area_filter_list
,
606 no_area_filter_list_cmd
,
607 "no area A.B.C.D filter-list prefix WORD <in|out>",
609 "OSPF6 area parameters\n"
610 "OSPF6 area ID in IP address format\n"
611 "Filter networks between OSPF6 areas\n"
612 "Filter prefixes between OSPF6 areas\n"
613 "Name of an IPv6 prefix-list\n"
614 "Filter networks sent to this area\n"
615 "Filter networks sent from this area\n")
617 char *inout
= argv
[argc
- 1]->text
;
618 char *areaid
= argv
[2]->arg
;
619 char *plistname
= argv
[5]->arg
;
621 struct ospf6_area
*area
;
623 OSPF6_CMD_AREA_GET(areaid
, area
);
625 if (strmatch(inout
, "in")) {
626 if (PREFIX_NAME_IN(area
))
627 if (!strmatch(PREFIX_NAME_IN(area
), plistname
))
630 PREFIX_LIST_IN(area
) = NULL
;
631 XFREE(MTYPE_OSPF6_PLISTNAME
, PREFIX_NAME_IN(area
));
632 ospf6_abr_reimport(area
);
634 if (PREFIX_NAME_OUT(area
))
635 if (!strmatch(PREFIX_NAME_OUT(area
), plistname
))
638 XFREE(MTYPE_OSPF6_PLISTNAME
, PREFIX_NAME_OUT(area
));
639 ospf6_abr_enable_area(area
);
645 void ospf6_area_plist_update(struct prefix_list
*plist
, int add
)
647 struct ospf6_area
*oa
;
649 const char *name
= prefix_list_name(plist
);
654 for (ALL_LIST_ELEMENTS_RO(ospf6
->area_list
, n
, oa
)) {
655 if (PREFIX_NAME_IN(oa
) && !strcmp(PREFIX_NAME_IN(oa
), name
))
656 PREFIX_LIST_IN(oa
) = add
? plist
: NULL
;
657 if (PREFIX_NAME_OUT(oa
) && !strcmp(PREFIX_NAME_OUT(oa
), name
))
658 PREFIX_LIST_OUT(oa
) = add
? plist
: NULL
;
662 DEFUN (area_import_list
,
663 area_import_list_cmd
,
664 "area A.B.C.D import-list NAME",
665 "OSPF6 area parameters\n"
666 "OSPF6 area ID in IP address format\n"
667 "Set the filter for networks from other areas announced to the specified one\n"
668 "Name of the acess-list\n")
672 struct ospf6_area
*area
;
673 struct access_list
*list
;
675 OSPF6_CMD_AREA_GET(argv
[idx_ipv4
]->arg
, area
);
677 list
= access_list_lookup(AFI_IP6
, argv
[idx_name
]->arg
);
679 IMPORT_LIST(area
) = list
;
681 if (IMPORT_NAME(area
))
682 free(IMPORT_NAME(area
));
684 IMPORT_NAME(area
) = strdup(argv
[idx_name
]->arg
);
685 ospf6_abr_reimport(area
);
690 DEFUN (no_area_import_list
,
691 no_area_import_list_cmd
,
692 "no area A.B.C.D import-list NAME",
694 "OSPF6 area parameters\n"
695 "OSPF6 area ID in IP address format\n"
696 "Unset the filter for networks announced to other areas\n"
697 "Name of the access-list\n")
700 struct ospf6_area
*area
;
702 OSPF6_CMD_AREA_GET(argv
[idx_ipv4
]->arg
, area
);
704 IMPORT_LIST(area
) = 0;
706 if (IMPORT_NAME(area
))
707 free(IMPORT_NAME(area
));
709 IMPORT_NAME(area
) = NULL
;
710 ospf6_abr_reimport(area
);
715 DEFUN (area_export_list
,
716 area_export_list_cmd
,
717 "area A.B.C.D export-list NAME",
718 "OSPF6 area parameters\n"
719 "OSPF6 area ID in IP address format\n"
720 "Set the filter for networks announced to other areas\n"
721 "Name of the acess-list\n")
725 struct ospf6_area
*area
;
726 struct access_list
*list
;
728 OSPF6_CMD_AREA_GET(argv
[idx_ipv4
]->arg
, area
);
730 list
= access_list_lookup(AFI_IP6
, argv
[idx_name
]->arg
);
732 EXPORT_LIST(area
) = list
;
734 if (EXPORT_NAME(area
))
735 free(EXPORT_NAME(area
));
737 EXPORT_NAME(area
) = strdup(argv
[idx_name
]->arg
);
738 ospf6_abr_enable_area(area
);
743 DEFUN (no_area_export_list
,
744 no_area_export_list_cmd
,
745 "no area A.B.C.D export-list NAME",
747 "OSPF6 area parameters\n"
748 "OSPF6 area ID in IP address format\n"
749 "Unset the filter for networks announced to other areas\n"
750 "Name of the access-list\n")
753 struct ospf6_area
*area
;
755 OSPF6_CMD_AREA_GET(argv
[idx_ipv4
]->arg
, area
);
757 EXPORT_LIST(area
) = 0;
759 if (EXPORT_NAME(area
))
760 free(EXPORT_NAME(area
));
762 EXPORT_NAME(area
) = NULL
;
763 ospf6_abr_enable_area(area
);
768 DEFUN (show_ipv6_ospf6_spf_tree
,
769 show_ipv6_ospf6_spf_tree_cmd
,
770 "show ipv6 ospf6 spf tree",
774 "Shortest Path First caculation\n"
777 struct listnode
*node
;
778 struct ospf6_area
*oa
;
779 struct ospf6_vertex
*root
;
780 struct ospf6_route
*route
;
781 struct prefix prefix
;
783 OSPF6_CMD_CHECK_RUNNING();
785 ospf6_linkstate_prefix(ospf6
->router_id
, htonl(0), &prefix
);
787 for (ALL_LIST_ELEMENTS_RO(ospf6
->area_list
, node
, oa
)) {
788 route
= ospf6_route_lookup(&prefix
, oa
->spf_table
);
790 vty_out(vty
, "LS entry for root not found in area %s\n",
794 root
= (struct ospf6_vertex
*)route
->route_option
;
795 ospf6_spf_display_subtree(vty
, "", 0, root
);
801 DEFUN (show_ipv6_ospf6_area_spf_tree
,
802 show_ipv6_ospf6_area_spf_tree_cmd
,
803 "show ipv6 ospf6 area A.B.C.D spf tree",
809 "Shortest Path First caculation\n"
814 struct ospf6_area
*oa
;
815 struct ospf6_vertex
*root
;
816 struct ospf6_route
*route
;
817 struct prefix prefix
;
819 OSPF6_CMD_CHECK_RUNNING();
821 ospf6_linkstate_prefix(ospf6
->router_id
, htonl(0), &prefix
);
823 if (inet_pton(AF_INET
, argv
[idx_ipv4
]->arg
, &area_id
) != 1) {
824 vty_out(vty
, "Malformed Area-ID: %s\n", argv
[idx_ipv4
]->arg
);
827 oa
= ospf6_area_lookup(area_id
, ospf6
);
829 vty_out(vty
, "No such Area: %s\n", argv
[idx_ipv4
]->arg
);
833 route
= ospf6_route_lookup(&prefix
, oa
->spf_table
);
835 vty_out(vty
, "LS entry for root not found in area %s\n",
839 root
= (struct ospf6_vertex
*)route
->route_option
;
840 ospf6_spf_display_subtree(vty
, "", 0, root
);
845 DEFUN (show_ipv6_ospf6_simulate_spf_tree_root
,
846 show_ipv6_ospf6_simulate_spf_tree_root_cmd
,
847 "show ipv6 ospf6 simulate spf-tree A.B.C.D area A.B.C.D",
851 "Shortest Path First calculation\n"
853 "Specify root's router-id to calculate another router's SPF tree\n"
854 "OSPF6 area parameters\n"
860 struct ospf6_area
*oa
;
861 struct ospf6_vertex
*root
;
862 struct ospf6_route
*route
;
863 struct prefix prefix
;
865 struct ospf6_route_table
*spf_table
;
866 unsigned char tmp_debug_ospf6_spf
= 0;
868 OSPF6_CMD_CHECK_RUNNING();
870 inet_pton(AF_INET
, argv
[idx_ipv4
]->arg
, &router_id
);
871 ospf6_linkstate_prefix(router_id
, htonl(0), &prefix
);
873 if (inet_pton(AF_INET
, argv
[idx_ipv4_2
]->arg
, &area_id
) != 1) {
874 vty_out(vty
, "Malformed Area-ID: %s\n", argv
[idx_ipv4_2
]->arg
);
877 oa
= ospf6_area_lookup(area_id
, ospf6
);
879 vty_out(vty
, "No such Area: %s\n", argv
[idx_ipv4_2
]->arg
);
883 tmp_debug_ospf6_spf
= conf_debug_ospf6_spf
;
884 conf_debug_ospf6_spf
= 0;
886 spf_table
= OSPF6_ROUTE_TABLE_CREATE(NONE
, SPF_RESULTS
);
887 ospf6_spf_calculation(router_id
, spf_table
, oa
);
889 conf_debug_ospf6_spf
= tmp_debug_ospf6_spf
;
891 route
= ospf6_route_lookup(&prefix
, spf_table
);
893 ospf6_spf_table_finish(spf_table
);
894 ospf6_route_table_delete(spf_table
);
897 root
= (struct ospf6_vertex
*)route
->route_option
;
898 ospf6_spf_display_subtree(vty
, "", 0, root
);
900 ospf6_spf_table_finish(spf_table
);
901 ospf6_route_table_delete(spf_table
);
906 DEFUN (ospf6_area_stub
,
908 "area <A.B.C.D|(0-4294967295)> stub",
909 "OSPF6 area parameters\n"
910 "OSPF6 area ID in IP address format\n"
911 "OSPF6 area ID as a decimal value\n"
912 "Configure OSPF6 area as stub\n")
914 int idx_ipv4_number
= 1;
915 struct ospf6_area
*area
;
917 OSPF6_CMD_AREA_GET(argv
[idx_ipv4_number
]->arg
, area
);
919 if (!ospf6_area_stub_set(ospf6
, area
)) {
921 "First deconfigure all virtual link through this area\n");
922 return CMD_WARNING_CONFIG_FAILED
;
925 ospf6_area_no_summary_unset(ospf6
, area
);
930 DEFUN (ospf6_area_stub_no_summary
,
931 ospf6_area_stub_no_summary_cmd
,
932 "area <A.B.C.D|(0-4294967295)> stub no-summary",
933 "OSPF6 stub parameters\n"
934 "OSPF6 area ID in IP address format\n"
935 "OSPF6 area ID as a decimal value\n"
936 "Configure OSPF6 area as stub\n"
937 "Do not inject inter-area routes into stub\n")
939 int idx_ipv4_number
= 1;
940 struct ospf6_area
*area
;
942 OSPF6_CMD_AREA_GET(argv
[idx_ipv4_number
]->arg
, area
);
944 if (!ospf6_area_stub_set(ospf6
, area
)) {
946 "First deconfigure all virtual link through this area\n");
947 return CMD_WARNING_CONFIG_FAILED
;
950 ospf6_area_no_summary_set(ospf6
, area
);
955 DEFUN (no_ospf6_area_stub
,
956 no_ospf6_area_stub_cmd
,
957 "no area <A.B.C.D|(0-4294967295)> stub",
959 "OSPF6 area parameters\n"
960 "OSPF6 area ID in IP address format\n"
961 "OSPF6 area ID as a decimal value\n"
962 "Configure OSPF6 area as stub\n")
964 int idx_ipv4_number
= 2;
965 struct ospf6_area
*area
;
967 OSPF6_CMD_AREA_GET(argv
[idx_ipv4_number
]->arg
, area
);
969 ospf6_area_stub_unset(ospf6
, area
);
970 ospf6_area_no_summary_unset(ospf6
, area
);
975 DEFUN (no_ospf6_area_stub_no_summary
,
976 no_ospf6_area_stub_no_summary_cmd
,
977 "no area <A.B.C.D|(0-4294967295)> stub no-summary",
979 "OSPF6 area parameters\n"
980 "OSPF6 area ID in IP address format\n"
981 "OSPF6 area ID as a decimal value\n"
982 "Configure OSPF6 area as stub\n"
983 "Do not inject inter-area routes into area\n")
985 int idx_ipv4_number
= 2;
986 struct ospf6_area
*area
;
988 OSPF6_CMD_AREA_GET(argv
[idx_ipv4_number
]->arg
, area
);
990 ospf6_area_stub_unset(ospf6
, area
);
991 ospf6_area_no_summary_unset(ospf6
, area
);
996 void ospf6_area_init(void)
998 install_element(VIEW_NODE
, &show_ipv6_ospf6_spf_tree_cmd
);
999 install_element(VIEW_NODE
, &show_ipv6_ospf6_area_spf_tree_cmd
);
1000 install_element(VIEW_NODE
, &show_ipv6_ospf6_simulate_spf_tree_root_cmd
);
1002 install_element(OSPF6_NODE
, &area_range_cmd
);
1003 install_element(OSPF6_NODE
, &no_area_range_cmd
);
1004 install_element(OSPF6_NODE
, &ospf6_area_stub_no_summary_cmd
);
1005 install_element(OSPF6_NODE
, &ospf6_area_stub_cmd
);
1006 install_element(OSPF6_NODE
, &no_ospf6_area_stub_no_summary_cmd
);
1007 install_element(OSPF6_NODE
, &no_ospf6_area_stub_cmd
);
1010 install_element(OSPF6_NODE
, &area_import_list_cmd
);
1011 install_element(OSPF6_NODE
, &no_area_import_list_cmd
);
1012 install_element(OSPF6_NODE
, &area_export_list_cmd
);
1013 install_element(OSPF6_NODE
, &no_area_export_list_cmd
);
1015 install_element(OSPF6_NODE
, &area_filter_list_cmd
);
1016 install_element(OSPF6_NODE
, &no_area_filter_list_cmd
);