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", 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", 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", __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|(0-4294967295)> filter-list prefix WORD <in|out>",
571 "OSPF6 area parameters\n"
572 "OSPF6 area ID in IP address format\n"
573 "OSPF6 area ID as a decimal value\n"
574 "Filter networks between OSPF6 areas\n"
575 "Filter prefixes between OSPF6 areas\n"
576 "Name of an IPv6 prefix-list\n"
577 "Filter networks sent to this area\n"
578 "Filter networks sent from this area\n")
580 char *inout
= argv
[argc
- 1]->text
;
581 char *areaid
= argv
[1]->arg
;
582 char *plistname
= argv
[4]->arg
;
584 struct ospf6_area
*area
;
585 struct prefix_list
*plist
;
587 OSPF6_CMD_AREA_GET(areaid
, area
);
589 plist
= prefix_list_lookup(AFI_IP6
, plistname
);
590 if (strmatch(inout
, "in")) {
591 PREFIX_LIST_IN(area
) = plist
;
592 XFREE(MTYPE_OSPF6_PLISTNAME
, PREFIX_NAME_IN(area
));
593 PREFIX_NAME_IN(area
) =
594 XSTRDUP(MTYPE_OSPF6_PLISTNAME
, plistname
);
595 ospf6_abr_reimport(area
);
597 PREFIX_LIST_OUT(area
) = plist
;
598 XFREE(MTYPE_OSPF6_PLISTNAME
, PREFIX_NAME_OUT(area
));
599 PREFIX_NAME_OUT(area
) =
600 XSTRDUP(MTYPE_OSPF6_PLISTNAME
, plistname
);
601 ospf6_abr_enable_area(area
);
607 DEFUN (no_area_filter_list
,
608 no_area_filter_list_cmd
,
609 "no area <A.B.C.D|(0-4294967295)> filter-list prefix WORD <in|out>",
611 "OSPF6 area parameters\n"
612 "OSPF6 area ID in IP address format\n"
613 "OSPF6 area ID as a decimal value\n"
614 "Filter networks between OSPF6 areas\n"
615 "Filter prefixes between OSPF6 areas\n"
616 "Name of an IPv6 prefix-list\n"
617 "Filter networks sent to this area\n"
618 "Filter networks sent from this area\n")
620 char *inout
= argv
[argc
- 1]->text
;
621 char *areaid
= argv
[2]->arg
;
622 char *plistname
= argv
[5]->arg
;
624 struct ospf6_area
*area
;
626 OSPF6_CMD_AREA_GET(areaid
, area
);
628 if (strmatch(inout
, "in")) {
629 if (PREFIX_NAME_IN(area
))
630 if (!strmatch(PREFIX_NAME_IN(area
), plistname
))
633 PREFIX_LIST_IN(area
) = NULL
;
634 XFREE(MTYPE_OSPF6_PLISTNAME
, PREFIX_NAME_IN(area
));
635 ospf6_abr_reimport(area
);
637 if (PREFIX_NAME_OUT(area
))
638 if (!strmatch(PREFIX_NAME_OUT(area
), plistname
))
641 XFREE(MTYPE_OSPF6_PLISTNAME
, PREFIX_NAME_OUT(area
));
642 ospf6_abr_enable_area(area
);
648 void ospf6_area_plist_update(struct prefix_list
*plist
, int add
)
650 struct ospf6_area
*oa
;
652 const char *name
= prefix_list_name(plist
);
657 for (ALL_LIST_ELEMENTS_RO(ospf6
->area_list
, n
, oa
)) {
658 if (PREFIX_NAME_IN(oa
) && !strcmp(PREFIX_NAME_IN(oa
), name
))
659 PREFIX_LIST_IN(oa
) = add
? plist
: NULL
;
660 if (PREFIX_NAME_OUT(oa
) && !strcmp(PREFIX_NAME_OUT(oa
), name
))
661 PREFIX_LIST_OUT(oa
) = add
? plist
: NULL
;
665 DEFUN (area_import_list
,
666 area_import_list_cmd
,
667 "area <A.B.C.D|(0-4294967295)> import-list NAME",
668 "OSPF6 area parameters\n"
669 "OSPF6 area ID in IP address format\n"
670 "OSPF6 area ID as a decimal value\n"
671 "Set the filter for networks from other areas announced to the specified one\n"
672 "Name of the acess-list\n")
676 struct ospf6_area
*area
;
677 struct access_list
*list
;
679 OSPF6_CMD_AREA_GET(argv
[idx_ipv4
]->arg
, area
);
681 list
= access_list_lookup(AFI_IP6
, argv
[idx_name
]->arg
);
683 IMPORT_LIST(area
) = list
;
685 if (IMPORT_NAME(area
))
686 free(IMPORT_NAME(area
));
688 IMPORT_NAME(area
) = strdup(argv
[idx_name
]->arg
);
689 ospf6_abr_reimport(area
);
694 DEFUN (no_area_import_list
,
695 no_area_import_list_cmd
,
696 "no area <A.B.C.D|(0-4294967295)> import-list NAME",
698 "OSPF6 area parameters\n"
699 "OSPF6 area ID in IP address format\n"
700 "OSPF6 area ID as a decimal value\n"
701 "Unset the filter for networks announced to other areas\n"
702 "Name of the access-list\n")
705 struct ospf6_area
*area
;
707 OSPF6_CMD_AREA_GET(argv
[idx_ipv4
]->arg
, area
);
709 IMPORT_LIST(area
) = 0;
711 if (IMPORT_NAME(area
))
712 free(IMPORT_NAME(area
));
714 IMPORT_NAME(area
) = NULL
;
715 ospf6_abr_reimport(area
);
720 DEFUN (area_export_list
,
721 area_export_list_cmd
,
722 "area <A.B.C.D|(0-4294967295)> export-list NAME",
723 "OSPF6 area parameters\n"
724 "OSPF6 area ID in IP address format\n"
725 "OSPF6 area ID as a decimal value\n"
726 "Set the filter for networks announced to other areas\n"
727 "Name of the acess-list\n")
731 struct ospf6_area
*area
;
732 struct access_list
*list
;
734 OSPF6_CMD_AREA_GET(argv
[idx_ipv4
]->arg
, area
);
736 list
= access_list_lookup(AFI_IP6
, argv
[idx_name
]->arg
);
738 EXPORT_LIST(area
) = list
;
740 if (EXPORT_NAME(area
))
741 free(EXPORT_NAME(area
));
743 EXPORT_NAME(area
) = strdup(argv
[idx_name
]->arg
);
744 ospf6_abr_enable_area(area
);
749 DEFUN (no_area_export_list
,
750 no_area_export_list_cmd
,
751 "no area <A.B.C.D|(0-4294967295)> export-list NAME",
753 "OSPF6 area parameters\n"
754 "OSPF6 area ID in IP address format\n"
755 "OSPF6 area ID as a decimal value\n"
756 "Unset the filter for networks announced to other areas\n"
757 "Name of the access-list\n")
760 struct ospf6_area
*area
;
762 OSPF6_CMD_AREA_GET(argv
[idx_ipv4
]->arg
, area
);
764 EXPORT_LIST(area
) = 0;
766 if (EXPORT_NAME(area
))
767 free(EXPORT_NAME(area
));
769 EXPORT_NAME(area
) = NULL
;
770 ospf6_abr_enable_area(area
);
775 DEFUN (show_ipv6_ospf6_spf_tree
,
776 show_ipv6_ospf6_spf_tree_cmd
,
777 "show ipv6 ospf6 spf tree",
781 "Shortest Path First calculation\n"
784 struct listnode
*node
;
785 struct ospf6_area
*oa
;
786 struct ospf6_vertex
*root
;
787 struct ospf6_route
*route
;
788 struct prefix prefix
;
790 OSPF6_CMD_CHECK_RUNNING();
792 ospf6_linkstate_prefix(ospf6
->router_id
, htonl(0), &prefix
);
794 for (ALL_LIST_ELEMENTS_RO(ospf6
->area_list
, node
, oa
)) {
795 route
= ospf6_route_lookup(&prefix
, oa
->spf_table
);
797 vty_out(vty
, "LS entry for root not found in area %s\n",
801 root
= (struct ospf6_vertex
*)route
->route_option
;
802 ospf6_spf_display_subtree(vty
, "", 0, root
);
808 DEFUN (show_ipv6_ospf6_area_spf_tree
,
809 show_ipv6_ospf6_area_spf_tree_cmd
,
810 "show ipv6 ospf6 area A.B.C.D spf tree",
816 "Shortest Path First calculation\n"
821 struct ospf6_area
*oa
;
822 struct ospf6_vertex
*root
;
823 struct ospf6_route
*route
;
824 struct prefix prefix
;
826 OSPF6_CMD_CHECK_RUNNING();
828 ospf6_linkstate_prefix(ospf6
->router_id
, htonl(0), &prefix
);
830 if (inet_pton(AF_INET
, argv
[idx_ipv4
]->arg
, &area_id
) != 1) {
831 vty_out(vty
, "Malformed Area-ID: %s\n", argv
[idx_ipv4
]->arg
);
834 oa
= ospf6_area_lookup(area_id
, ospf6
);
836 vty_out(vty
, "No such Area: %s\n", argv
[idx_ipv4
]->arg
);
840 route
= ospf6_route_lookup(&prefix
, oa
->spf_table
);
842 vty_out(vty
, "LS entry for root not found in area %s\n",
846 root
= (struct ospf6_vertex
*)route
->route_option
;
847 ospf6_spf_display_subtree(vty
, "", 0, root
);
852 DEFUN (show_ipv6_ospf6_simulate_spf_tree_root
,
853 show_ipv6_ospf6_simulate_spf_tree_root_cmd
,
854 "show ipv6 ospf6 simulate spf-tree A.B.C.D area A.B.C.D",
858 "Shortest Path First calculation\n"
860 "Specify root's router-id to calculate another router's SPF tree\n"
861 "OSPF6 area parameters\n"
867 struct ospf6_area
*oa
;
868 struct ospf6_vertex
*root
;
869 struct ospf6_route
*route
;
870 struct prefix prefix
;
872 struct ospf6_route_table
*spf_table
;
873 unsigned char tmp_debug_ospf6_spf
= 0;
875 OSPF6_CMD_CHECK_RUNNING();
877 inet_pton(AF_INET
, argv
[idx_ipv4
]->arg
, &router_id
);
878 ospf6_linkstate_prefix(router_id
, htonl(0), &prefix
);
880 if (inet_pton(AF_INET
, argv
[idx_ipv4_2
]->arg
, &area_id
) != 1) {
881 vty_out(vty
, "Malformed Area-ID: %s\n", argv
[idx_ipv4_2
]->arg
);
884 oa
= ospf6_area_lookup(area_id
, ospf6
);
886 vty_out(vty
, "No such Area: %s\n", argv
[idx_ipv4_2
]->arg
);
890 tmp_debug_ospf6_spf
= conf_debug_ospf6_spf
;
891 conf_debug_ospf6_spf
= 0;
893 spf_table
= OSPF6_ROUTE_TABLE_CREATE(NONE
, SPF_RESULTS
);
894 ospf6_spf_calculation(router_id
, spf_table
, oa
);
896 conf_debug_ospf6_spf
= tmp_debug_ospf6_spf
;
898 route
= ospf6_route_lookup(&prefix
, spf_table
);
900 ospf6_spf_table_finish(spf_table
);
901 ospf6_route_table_delete(spf_table
);
904 root
= (struct ospf6_vertex
*)route
->route_option
;
905 ospf6_spf_display_subtree(vty
, "", 0, root
);
907 ospf6_spf_table_finish(spf_table
);
908 ospf6_route_table_delete(spf_table
);
913 DEFUN (ospf6_area_stub
,
915 "area <A.B.C.D|(0-4294967295)> stub",
916 "OSPF6 area parameters\n"
917 "OSPF6 area ID in IP address format\n"
918 "OSPF6 area ID as a decimal value\n"
919 "Configure OSPF6 area as stub\n")
921 int idx_ipv4_number
= 1;
922 struct ospf6_area
*area
;
924 OSPF6_CMD_AREA_GET(argv
[idx_ipv4_number
]->arg
, area
);
926 if (!ospf6_area_stub_set(ospf6
, area
)) {
928 "First deconfigure all virtual link through this area\n");
929 return CMD_WARNING_CONFIG_FAILED
;
932 ospf6_area_no_summary_unset(ospf6
, area
);
937 DEFUN (ospf6_area_stub_no_summary
,
938 ospf6_area_stub_no_summary_cmd
,
939 "area <A.B.C.D|(0-4294967295)> stub no-summary",
940 "OSPF6 stub parameters\n"
941 "OSPF6 area ID in IP address format\n"
942 "OSPF6 area ID as a decimal value\n"
943 "Configure OSPF6 area as stub\n"
944 "Do not inject inter-area routes into stub\n")
946 int idx_ipv4_number
= 1;
947 struct ospf6_area
*area
;
949 OSPF6_CMD_AREA_GET(argv
[idx_ipv4_number
]->arg
, area
);
951 if (!ospf6_area_stub_set(ospf6
, area
)) {
953 "First deconfigure all virtual link through this area\n");
954 return CMD_WARNING_CONFIG_FAILED
;
957 ospf6_area_no_summary_set(ospf6
, area
);
962 DEFUN (no_ospf6_area_stub
,
963 no_ospf6_area_stub_cmd
,
964 "no area <A.B.C.D|(0-4294967295)> stub",
966 "OSPF6 area parameters\n"
967 "OSPF6 area ID in IP address format\n"
968 "OSPF6 area ID as a decimal value\n"
969 "Configure OSPF6 area as stub\n")
971 int idx_ipv4_number
= 2;
972 struct ospf6_area
*area
;
974 OSPF6_CMD_AREA_GET(argv
[idx_ipv4_number
]->arg
, area
);
976 ospf6_area_stub_unset(ospf6
, area
);
977 ospf6_area_no_summary_unset(ospf6
, area
);
982 DEFUN (no_ospf6_area_stub_no_summary
,
983 no_ospf6_area_stub_no_summary_cmd
,
984 "no area <A.B.C.D|(0-4294967295)> stub no-summary",
986 "OSPF6 area parameters\n"
987 "OSPF6 area ID in IP address format\n"
988 "OSPF6 area ID as a decimal value\n"
989 "Configure OSPF6 area as stub\n"
990 "Do not inject inter-area routes into area\n")
992 int idx_ipv4_number
= 2;
993 struct ospf6_area
*area
;
995 OSPF6_CMD_AREA_GET(argv
[idx_ipv4_number
]->arg
, area
);
997 ospf6_area_stub_unset(ospf6
, area
);
998 ospf6_area_no_summary_unset(ospf6
, area
);
1003 void ospf6_area_init(void)
1005 install_element(VIEW_NODE
, &show_ipv6_ospf6_spf_tree_cmd
);
1006 install_element(VIEW_NODE
, &show_ipv6_ospf6_area_spf_tree_cmd
);
1007 install_element(VIEW_NODE
, &show_ipv6_ospf6_simulate_spf_tree_root_cmd
);
1009 install_element(OSPF6_NODE
, &area_range_cmd
);
1010 install_element(OSPF6_NODE
, &no_area_range_cmd
);
1011 install_element(OSPF6_NODE
, &ospf6_area_stub_no_summary_cmd
);
1012 install_element(OSPF6_NODE
, &ospf6_area_stub_cmd
);
1013 install_element(OSPF6_NODE
, &no_ospf6_area_stub_no_summary_cmd
);
1014 install_element(OSPF6_NODE
, &no_ospf6_area_stub_cmd
);
1017 install_element(OSPF6_NODE
, &area_import_list_cmd
);
1018 install_element(OSPF6_NODE
, &no_area_import_list_cmd
);
1019 install_element(OSPF6_NODE
, &area_export_list_cmd
);
1020 install_element(OSPF6_NODE
, &no_area_export_list_cmd
);
1022 install_element(OSPF6_NODE
, &area_filter_list_cmd
);
1023 install_element(OSPF6_NODE
, &no_area_filter_list_cmd
);
1026 void ospf6_area_interface_delete(struct ospf6_interface
*oi
)
1028 struct ospf6_area
*oa
;
1029 struct listnode
*node
, *nnode
;
1033 for (ALL_LIST_ELEMENTS(ospf6
->area_list
, node
, nnode
, oa
))
1034 if(listnode_lookup(oa
->if_list
, oi
))
1035 listnode_delete(oa
->if_list
, oi
);