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
33 #include "ospf6_proto.h"
34 #include "ospf6_message.h"
35 #include "ospf6_lsa.h"
36 #include "ospf6_lsdb.h"
37 #include "ospf6_route.h"
38 #include "ospf6_zebra.h"
40 #include "ospf6_top.h"
41 #include "ospf6_area.h"
42 #include "ospf6_interface.h"
43 #include "ospf6_neighbor.h"
45 #include "ospf6_flood.h"
46 #include "ospf6_asbr.h"
47 #include "ospf6_abr.h"
48 #include "ospf6_intra.h"
49 #include "ospf6_spf.h"
52 DEFINE_QOBJ_TYPE(ospf6
)
54 /* global ospf6d variable */
56 static struct ospf6_master ospf6_master
;
57 struct ospf6_master
*om6
;
59 static void ospf6_disable(struct ospf6
*o
);
61 static void ospf6_top_lsdb_hook_add(struct ospf6_lsa
*lsa
)
63 switch (ntohs(lsa
->header
->type
)) {
64 case OSPF6_LSTYPE_AS_EXTERNAL
:
65 ospf6_asbr_lsa_add(lsa
);
73 static void ospf6_top_lsdb_hook_remove(struct ospf6_lsa
*lsa
)
75 switch (ntohs(lsa
->header
->type
)) {
76 case OSPF6_LSTYPE_AS_EXTERNAL
:
77 ospf6_asbr_lsa_remove(lsa
, NULL
);
85 static void ospf6_top_route_hook_add(struct ospf6_route
*route
)
87 ospf6_abr_originate_summary(route
);
88 ospf6_zebra_route_update_add(route
);
91 static void ospf6_top_route_hook_remove(struct ospf6_route
*route
)
93 route
->flag
|= OSPF6_ROUTE_REMOVE
;
94 ospf6_abr_originate_summary(route
);
95 ospf6_zebra_route_update_remove(route
);
98 static void ospf6_top_brouter_hook_add(struct ospf6_route
*route
)
100 if (IS_OSPF6_DEBUG_EXAMIN(AS_EXTERNAL
) ||
101 IS_OSPF6_DEBUG_BROUTER
) {
103 char brouter_name
[16];
105 brouter_id
= ADV_ROUTER_IN_PREFIX(&route
->prefix
);
106 inet_ntop(AF_INET
, &brouter_id
, brouter_name
,
107 sizeof(brouter_name
));
108 zlog_debug("%s: brouter %s add with adv router %x nh count %u",
109 __PRETTY_FUNCTION__
, brouter_name
,
110 route
->path
.origin
.adv_router
,
111 listcount(route
->nh_list
));
113 ospf6_abr_examin_brouter(ADV_ROUTER_IN_PREFIX(&route
->prefix
));
114 ospf6_asbr_lsentry_add(route
);
115 ospf6_abr_originate_summary(route
);
118 static void ospf6_top_brouter_hook_remove(struct ospf6_route
*route
)
120 if (IS_OSPF6_DEBUG_EXAMIN(AS_EXTERNAL
) ||
121 IS_OSPF6_DEBUG_BROUTER
) {
123 char brouter_name
[16];
125 brouter_id
= ADV_ROUTER_IN_PREFIX(&route
->prefix
);
126 inet_ntop(AF_INET
, &brouter_id
, brouter_name
,
127 sizeof(brouter_name
));
128 zlog_debug("%s: brouter %p %s del with adv router %x nh %u",
129 __PRETTY_FUNCTION__
, (void *)route
, brouter_name
,
130 route
->path
.origin
.adv_router
,
131 listcount(route
->nh_list
));
133 route
->flag
|= OSPF6_ROUTE_REMOVE
;
134 ospf6_abr_examin_brouter(ADV_ROUTER_IN_PREFIX(&route
->prefix
));
135 ospf6_asbr_lsentry_remove(route
);
136 ospf6_abr_originate_summary(route
);
139 static struct ospf6
*ospf6_create(void)
143 o
= XCALLOC(MTYPE_OSPF6_TOP
, sizeof(struct ospf6
));
146 monotime(&o
->starttime
);
147 o
->area_list
= list_new();
148 o
->area_list
->cmp
= ospf6_area_cmp
;
149 o
->lsdb
= ospf6_lsdb_create(o
);
150 o
->lsdb_self
= ospf6_lsdb_create(o
);
151 o
->lsdb
->hook_add
= ospf6_top_lsdb_hook_add
;
152 o
->lsdb
->hook_remove
= ospf6_top_lsdb_hook_remove
;
154 o
->spf_delay
= OSPF_SPF_DELAY_DEFAULT
;
155 o
->spf_holdtime
= OSPF_SPF_HOLDTIME_DEFAULT
;
156 o
->spf_max_holdtime
= OSPF_SPF_MAX_HOLDTIME_DEFAULT
;
157 o
->spf_hold_multiplier
= 1;
159 /* LSA timers value init */
160 o
->lsa_minarrival
= OSPF_MIN_LS_ARRIVAL
;
162 o
->route_table
= OSPF6_ROUTE_TABLE_CREATE(GLOBAL
, ROUTES
);
163 o
->route_table
->scope
= o
;
164 o
->route_table
->hook_add
= ospf6_top_route_hook_add
;
165 o
->route_table
->hook_remove
= ospf6_top_route_hook_remove
;
167 o
->brouter_table
= OSPF6_ROUTE_TABLE_CREATE(GLOBAL
, BORDER_ROUTERS
);
168 o
->brouter_table
->scope
= o
;
169 o
->brouter_table
->hook_add
= ospf6_top_brouter_hook_add
;
170 o
->brouter_table
->hook_remove
= ospf6_top_brouter_hook_remove
;
172 o
->external_table
= OSPF6_ROUTE_TABLE_CREATE(GLOBAL
, EXTERNAL_ROUTES
);
173 o
->external_table
->scope
= o
;
175 o
->external_id_table
= route_table_init();
177 o
->ref_bandwidth
= OSPF6_REFERENCE_BANDWIDTH
;
179 o
->distance_table
= route_table_init();
181 /* Enable "log-adjacency-changes" */
182 #if DFLT_OSPF6_LOG_ADJACENCY_CHANGES
183 SET_FLAG(o
->config_flags
, OSPF6_LOG_ADJACENCY_CHANGES
);
191 void ospf6_delete(struct ospf6
*o
)
193 struct listnode
*node
, *nnode
;
194 struct ospf6_area
*oa
;
198 ospf6_flush_self_originated_lsas_now();
199 ospf6_disable(ospf6
);
201 for (ALL_LIST_ELEMENTS(o
->area_list
, node
, nnode
, oa
))
202 ospf6_area_delete(oa
);
205 list_delete_and_null(&o
->area_list
);
207 ospf6_lsdb_delete(o
->lsdb
);
208 ospf6_lsdb_delete(o
->lsdb_self
);
210 ospf6_route_table_delete(o
->route_table
);
211 ospf6_route_table_delete(o
->brouter_table
);
213 ospf6_route_table_delete(o
->external_table
);
214 route_table_finish(o
->external_id_table
);
216 ospf6_distance_reset(o
);
217 route_table_finish(o
->distance_table
);
219 XFREE(MTYPE_OSPF6_TOP
, o
);
222 static void ospf6_disable(struct ospf6
*o
)
224 struct listnode
*node
, *nnode
;
225 struct ospf6_area
*oa
;
227 if (!CHECK_FLAG(o
->flag
, OSPF6_DISABLED
)) {
228 SET_FLAG(o
->flag
, OSPF6_DISABLED
);
230 for (ALL_LIST_ELEMENTS(o
->area_list
, node
, nnode
, oa
))
231 ospf6_area_disable(oa
);
233 /* XXX: This also changes persistent settings */
234 ospf6_asbr_redistribute_reset();
236 ospf6_lsdb_remove_all(o
->lsdb
);
237 ospf6_route_remove_all(o
->route_table
);
238 ospf6_route_remove_all(o
->brouter_table
);
240 THREAD_OFF(o
->maxage_remover
);
241 THREAD_OFF(o
->t_spf_calc
);
242 THREAD_OFF(o
->t_ase_calc
);
243 THREAD_OFF(o
->t_distribute_update
);
247 void ospf6_master_init(void)
249 memset(&ospf6_master
, 0, sizeof(struct ospf6_master
));
254 static int ospf6_maxage_remover(struct thread
*thread
)
256 struct ospf6
*o
= (struct ospf6
*)THREAD_ARG(thread
);
257 struct ospf6_area
*oa
;
258 struct ospf6_interface
*oi
;
259 struct ospf6_neighbor
*on
;
260 struct listnode
*i
, *j
, *k
;
263 o
->maxage_remover
= (struct thread
*)NULL
;
265 for (ALL_LIST_ELEMENTS_RO(o
->area_list
, i
, oa
)) {
266 for (ALL_LIST_ELEMENTS_RO(oa
->if_list
, j
, oi
)) {
267 for (ALL_LIST_ELEMENTS_RO(oi
->neighbor_list
, k
, on
)) {
268 if (on
->state
!= OSPF6_NEIGHBOR_EXCHANGE
269 && on
->state
!= OSPF6_NEIGHBOR_LOADING
)
272 ospf6_maxage_remove(o
);
278 for (ALL_LIST_ELEMENTS_RO(o
->area_list
, i
, oa
)) {
279 for (ALL_LIST_ELEMENTS_RO(oa
->if_list
, j
, oi
)) {
280 if (ospf6_lsdb_maxage_remover(oi
->lsdb
)) {
285 if (ospf6_lsdb_maxage_remover(oa
->lsdb
)) {
290 if (ospf6_lsdb_maxage_remover(o
->lsdb
)) {
295 ospf6_maxage_remove(o
);
301 void ospf6_maxage_remove(struct ospf6
*o
)
304 thread_add_timer(master
, ospf6_maxage_remover
, o
,
305 OSPF_LSA_MAXAGE_REMOVE_DELAY_DEFAULT
,
309 void ospf6_router_id_update(void)
314 if (ospf6
->router_id_static
!= 0)
315 ospf6
->router_id
= ospf6
->router_id_static
;
317 ospf6
->router_id
= om6
->zebra_router_id
;
321 DEFUN_NOSH (router_ospf6
,
328 ospf6
= ospf6_create();
329 if (ospf6
->router_id
== 0)
330 ospf6_router_id_update();
332 /* set current ospf point. */
333 VTY_PUSH_CONTEXT(OSPF6_NODE
, ospf6
);
339 DEFUN (no_router_ospf6
,
347 vty_out(vty
, "OSPFv3 is not configured\n");
353 /* return to config node . */
354 VTY_PUSH_CONTEXT_NULL(CONFIG_NODE
);
359 /* change Router_ID commands. */
360 DEFUN(ospf6_router_id
,
362 "ospf6 router-id A.B.C.D",
364 "Configure OSPF6 Router-ID\n"
367 VTY_DECLVAR_CONTEXT(ospf6
, o
);
370 const char *router_id_str
;
372 struct ospf6_area
*oa
;
373 struct listnode
*node
;
375 argv_find(argv
, argc
, "A.B.C.D", &idx
);
376 router_id_str
= argv
[idx
]->arg
;
378 ret
= inet_pton(AF_INET
, router_id_str
, &router_id
);
380 vty_out(vty
, "malformed OSPF Router-ID: %s\n", router_id_str
);
384 o
->router_id_static
= router_id
;
386 for (ALL_LIST_ELEMENTS_RO(o
->area_list
, node
, oa
)) {
389 "For this router-id change to take effect,"
390 " save config and restart ospf6d\n");
395 o
->router_id
= router_id
;
400 DEFUN(no_ospf6_router_id
,
401 no_ospf6_router_id_cmd
,
402 "no ospf6 router-id [A.B.C.D]",
404 "Configure OSPF6 Router-ID\n"
407 VTY_DECLVAR_CONTEXT(ospf6
, o
);
408 struct ospf6_area
*oa
;
409 struct listnode
*node
;
411 o
->router_id_static
= 0;
413 for (ALL_LIST_ELEMENTS_RO(o
->area_list
, node
, oa
)) {
416 "For this router-id change to take effect,"
417 " save config and restart ospf6d\n");
422 if (o
->router_id_zebra
.s_addr
)
423 o
->router_id
= (uint32_t)o
->router_id_zebra
.s_addr
;
428 #if defined(VERSION_TYPE_DEV) && CONFDATE > 20180828
429 CPP_NOTICE("ospf6: `router-id A.B.C.D` deprecated 2017/08/28")
431 ALIAS_HIDDEN(ospf6_router_id
, ospf6_router_id_hdn_cmd
, "router-id A.B.C.D",
432 "Configure OSPF6 Router-ID\n" V4NOTATION_STR
)
434 #if defined(VERSION_TYPE_DEV) && CONFDATE > 20180828
435 CPP_NOTICE("ospf6: `no router-id A.B.C.D` deprecated 2017/08/28")
437 ALIAS_HIDDEN(no_ospf6_router_id
, no_ospf6_router_id_hdn_cmd
,
438 "no router-id [A.B.C.D]",
439 NO_STR
"Configure OSPF6 Router-ID\n" V4NOTATION_STR
)
441 DEFUN (ospf6_log_adjacency_changes
,
442 ospf6_log_adjacency_changes_cmd
,
443 "log-adjacency-changes",
444 "Log changes in adjacency state\n")
446 VTY_DECLVAR_CONTEXT(ospf6
, ospf6
);
448 SET_FLAG(ospf6
->config_flags
, OSPF6_LOG_ADJACENCY_CHANGES
);
449 UNSET_FLAG(ospf6
->config_flags
, OSPF6_LOG_ADJACENCY_DETAIL
);
453 DEFUN (ospf6_log_adjacency_changes_detail
,
454 ospf6_log_adjacency_changes_detail_cmd
,
455 "log-adjacency-changes detail",
456 "Log changes in adjacency state\n"
457 "Log all state changes\n")
459 VTY_DECLVAR_CONTEXT(ospf6
, ospf6
);
461 SET_FLAG(ospf6
->config_flags
, OSPF6_LOG_ADJACENCY_CHANGES
);
462 SET_FLAG(ospf6
->config_flags
, OSPF6_LOG_ADJACENCY_DETAIL
);
466 DEFUN (no_ospf6_log_adjacency_changes
,
467 no_ospf6_log_adjacency_changes_cmd
,
468 "no log-adjacency-changes",
470 "Log changes in adjacency state\n")
472 VTY_DECLVAR_CONTEXT(ospf6
, ospf6
);
474 UNSET_FLAG(ospf6
->config_flags
, OSPF6_LOG_ADJACENCY_DETAIL
);
475 UNSET_FLAG(ospf6
->config_flags
, OSPF6_LOG_ADJACENCY_CHANGES
);
479 DEFUN (no_ospf6_log_adjacency_changes_detail
,
480 no_ospf6_log_adjacency_changes_detail_cmd
,
481 "no log-adjacency-changes detail",
483 "Log changes in adjacency state\n"
484 "Log all state changes\n")
486 VTY_DECLVAR_CONTEXT(ospf6
, ospf6
);
488 UNSET_FLAG(ospf6
->config_flags
, OSPF6_LOG_ADJACENCY_DETAIL
);
492 DEFUN (ospf6_timers_lsa
,
493 ospf6_timers_lsa_cmd
,
494 "timers lsa min-arrival (0-600000)",
495 "Adjust routing timers\n"
497 "Minimum delay in receiving new version of a LSA\n"
498 "Delay in milliseconds\n")
500 VTY_DECLVAR_CONTEXT(ospf6
, ospf
);
502 unsigned int minarrival
;
504 minarrival
= strtoul(argv
[idx_number
]->arg
, NULL
, 10);
505 ospf
->lsa_minarrival
= minarrival
;
510 DEFUN (no_ospf6_timers_lsa
,
511 no_ospf6_timers_lsa_cmd
,
512 "no timers lsa min-arrival [(0-600000)]",
514 "Adjust routing timers\n"
516 "Minimum delay in receiving new version of a LSA\n"
517 "Delay in milliseconds\n")
519 VTY_DECLVAR_CONTEXT(ospf6
, ospf
);
521 unsigned int minarrival
;
524 minarrival
= strtoul(argv
[idx_number
]->arg
, NULL
, 10);
526 if (ospf
->lsa_minarrival
!= minarrival
527 || minarrival
== OSPF_MIN_LS_ARRIVAL
)
531 ospf
->lsa_minarrival
= OSPF_MIN_LS_ARRIVAL
;
537 DEFUN (ospf6_distance
,
540 "Administrative distance\n"
541 "OSPF6 Administrative distance\n")
543 VTY_DECLVAR_CONTEXT(ospf6
, o
);
545 o
->distance_all
= atoi(argv
[1]->arg
);
550 DEFUN (no_ospf6_distance
,
551 no_ospf6_distance_cmd
,
552 "no distance (1-255)",
554 "Administrative distance\n"
555 "OSPF6 Administrative distance\n")
557 VTY_DECLVAR_CONTEXT(ospf6
, o
);
564 DEFUN (ospf6_distance_ospf6
,
565 ospf6_distance_ospf6_cmd
,
566 "distance ospf6 {intra-area (1-255)|inter-area (1-255)|external (1-255)}",
567 "Administrative distance\n"
568 "OSPF6 administrative distance\n"
569 "Intra-area routes\n"
570 "Distance for intra-area routes\n"
571 "Inter-area routes\n"
572 "Distance for inter-area routes\n"
574 "Distance for external routes\n")
576 VTY_DECLVAR_CONTEXT(ospf6
, o
);
579 o
->distance_intra
= 0;
580 o
->distance_inter
= 0;
581 o
->distance_external
= 0;
583 if (argv_find(argv
, argc
, "intra-area", &idx
))
584 o
->distance_intra
= atoi(argv
[idx
+ 1]->arg
);
586 if (argv_find(argv
, argc
, "inter-area", &idx
))
587 o
->distance_inter
= atoi(argv
[idx
+ 1]->arg
);
589 if (argv_find(argv
, argc
, "external", &idx
))
590 o
->distance_external
= atoi(argv
[idx
+ 1]->arg
);
595 DEFUN (no_ospf6_distance_ospf6
,
596 no_ospf6_distance_ospf6_cmd
,
597 "no distance ospf6 [{intra-area [(1-255)]|inter-area [(1-255)]|external [(1-255)]}]",
599 "Administrative distance\n"
601 "Intra-area routes\n"
602 "Distance for intra-area routes\n"
603 "Inter-area routes\n"
604 "Distance for inter-area routes\n"
606 "Distance for external routes\n")
608 VTY_DECLVAR_CONTEXT(ospf6
, o
);
611 if (argv_find(argv
, argc
, "intra-area", &idx
) || argc
== 3)
612 idx
= o
->distance_intra
= 0;
613 if (argv_find(argv
, argc
, "inter-area", &idx
) || argc
== 3)
614 idx
= o
->distance_inter
= 0;
615 if (argv_find(argv
, argc
, "external", &idx
) || argc
== 3)
616 o
->distance_external
= 0;
622 DEFUN (ospf6_distance_source
,
623 ospf6_distance_source_cmd
,
624 "distance (1-255) X:X::X:X/M [WORD]",
625 "Administrative distance\n"
628 "Access list name\n")
630 VTY_DECLVAR_CONTEXT(ospf6
, o
);
631 char *alname
= (argc
== 4) ? argv
[3]->arg
: NULL
;
632 ospf6_distance_set (vty
, o
, argv
[1]->arg
, argv
[2]->arg
, alname
);
637 DEFUN (no_ospf6_distance_source
,
638 no_ospf6_distance_source_cmd
,
639 "no distance (1-255) X:X::X:X/M [WORD]",
641 "Administrative distance\n"
644 "Access list name\n")
646 VTY_DECLVAR_CONTEXT(ospf6
, o
);
647 char *alname
= (argc
== 5) ? argv
[4]->arg
: NULL
;
648 ospf6_distance_unset (vty
, o
, argv
[2]->arg
, argv
[3]->arg
, alname
);
654 DEFUN (ospf6_interface_area
,
655 ospf6_interface_area_cmd
,
656 "interface IFNAME area A.B.C.D",
657 "Enable routing on an IPv6 interface\n"
659 "Specify the OSPF6 area ID\n"
660 "OSPF6 area ID in IPv4 address notation\n"
663 VTY_DECLVAR_CONTEXT(ospf6
, o
);
666 struct ospf6_area
*oa
;
667 struct ospf6_interface
*oi
;
668 struct interface
*ifp
;
671 /* find/create ospf6 interface */
672 ifp
= if_get_by_name(argv
[idx_ifname
]->arg
, VRF_DEFAULT
, 0);
673 oi
= (struct ospf6_interface
*)ifp
->info
;
675 oi
= ospf6_interface_create(ifp
);
677 vty_out(vty
, "%s already attached to Area %s\n",
678 oi
->interface
->name
, oi
->area
->name
);
683 if (inet_pton(AF_INET
, argv
[idx_ipv4
]->arg
, &area_id
) != 1) {
684 vty_out(vty
, "Invalid Area-ID: %s\n", argv
[idx_ipv4
]->arg
);
688 /* find/create ospf6 area */
689 oa
= ospf6_area_lookup(area_id
, o
);
691 oa
= ospf6_area_create(area_id
, o
, OSPF6_AREA_FMT_DOTTEDQUAD
);
693 /* attach interface to area */
694 listnode_add(oa
->if_list
, oi
); /* sort ?? */
697 SET_FLAG(oa
->flag
, OSPF6_AREA_ENABLE
);
699 /* ospf6 process is currently disabled, not much more to do */
700 if (CHECK_FLAG(o
->flag
, OSPF6_DISABLED
))
704 ospf6_interface_enable(oi
);
706 /* If the router is ABR, originate summary routes */
707 if (ospf6_is_router_abr(o
))
708 ospf6_abr_enable_area(oa
);
713 DEFUN (no_ospf6_interface_area
,
714 no_ospf6_interface_area_cmd
,
715 "no interface IFNAME area A.B.C.D",
717 "Disable routing on an IPv6 interface\n"
719 "Specify the OSPF6 area ID\n"
720 "OSPF6 area ID in IPv4 address notation\n"
725 struct ospf6_interface
*oi
;
726 struct ospf6_area
*oa
;
727 struct interface
*ifp
;
730 ifp
= if_lookup_by_name(argv
[idx_ifname
]->arg
, VRF_DEFAULT
);
732 vty_out(vty
, "No such interface %s\n", argv
[idx_ifname
]->arg
);
736 oi
= (struct ospf6_interface
*)ifp
->info
;
738 vty_out(vty
, "Interface %s not enabled\n", ifp
->name
);
743 if (inet_pton(AF_INET
, argv
[idx_ipv4
]->arg
, &area_id
) != 1) {
744 vty_out(vty
, "Invalid Area-ID: %s\n", argv
[idx_ipv4
]->arg
);
749 if (oi
->area
== NULL
) {
750 vty_out(vty
, "No such Area-ID: %s\n", argv
[idx_ipv4
]->arg
);
754 if (oi
->area
->area_id
!= area_id
) {
755 vty_out(vty
, "Wrong Area-ID: %s is attached to area %s\n",
756 oi
->interface
->name
, oi
->area
->name
);
760 thread_execute(master
, interface_down
, oi
, 0);
763 listnode_delete(oi
->area
->if_list
, oi
);
764 oi
->area
= (struct ospf6_area
*)NULL
;
766 /* Withdraw inter-area routes from this area, if necessary */
767 if (oa
->if_list
->count
== 0) {
768 UNSET_FLAG(oa
->flag
, OSPF6_AREA_ENABLE
);
769 ospf6_abr_disable_area(oa
);
775 DEFUN (ospf6_stub_router_admin
,
776 ospf6_stub_router_admin_cmd
,
777 "stub-router administrative",
778 "Make router a stub router\n"
779 "Administratively applied, for an indefinite period\n")
781 struct listnode
*node
;
782 struct ospf6_area
*oa
;
784 if (!CHECK_FLAG(ospf6
->flag
, OSPF6_STUB_ROUTER
)) {
785 for (ALL_LIST_ELEMENTS_RO(ospf6
->area_list
, node
, oa
)) {
786 OSPF6_OPT_CLEAR(oa
->options
, OSPF6_OPT_V6
);
787 OSPF6_OPT_CLEAR(oa
->options
, OSPF6_OPT_R
);
788 OSPF6_ROUTER_LSA_SCHEDULE(oa
);
790 SET_FLAG(ospf6
->flag
, OSPF6_STUB_ROUTER
);
796 DEFUN (no_ospf6_stub_router_admin
,
797 no_ospf6_stub_router_admin_cmd
,
798 "no stub-router administrative",
800 "Make router a stub router\n"
801 "Administratively applied, for an indefinite period\n")
803 struct listnode
*node
;
804 struct ospf6_area
*oa
;
806 if (CHECK_FLAG(ospf6
->flag
, OSPF6_STUB_ROUTER
)) {
807 for (ALL_LIST_ELEMENTS_RO(ospf6
->area_list
, node
, oa
)) {
808 OSPF6_OPT_SET(oa
->options
, OSPF6_OPT_V6
);
809 OSPF6_OPT_SET(oa
->options
, OSPF6_OPT_R
);
810 OSPF6_ROUTER_LSA_SCHEDULE(oa
);
812 UNSET_FLAG(ospf6
->flag
, OSPF6_STUB_ROUTER
);
819 DEFUN (ospf6_stub_router_startup
,
820 ospf6_stub_router_startup_cmd
,
821 "stub-router on-startup (5-86400)",
822 "Make router a stub router\n"
823 "Advertise inability to be a transit router\n"
824 "Automatically advertise as stub-router on startup of OSPF6\n"
825 "Time (seconds) to advertise self as stub-router\n")
830 DEFUN (no_ospf6_stub_router_startup
,
831 no_ospf6_stub_router_startup_cmd
,
832 "no stub-router on-startup",
834 "Make router a stub router\n"
835 "Advertise inability to be a transit router\n"
836 "Automatically advertise as stub-router on startup of OSPF6\n"
837 "Time (seconds) to advertise self as stub-router\n")
842 DEFUN (ospf6_stub_router_shutdown
,
843 ospf6_stub_router_shutdown_cmd
,
844 "stub-router on-shutdown (5-86400)",
845 "Make router a stub router\n"
846 "Advertise inability to be a transit router\n"
847 "Automatically advertise as stub-router before shutdown\n"
848 "Time (seconds) to advertise self as stub-router\n")
853 DEFUN (no_ospf6_stub_router_shutdown
,
854 no_ospf6_stub_router_shutdown_cmd
,
855 "no stub-router on-shutdown",
857 "Make router a stub router\n"
858 "Advertise inability to be a transit router\n"
859 "Automatically advertise as stub-router before shutdown\n"
860 "Time (seconds) to advertise self as stub-router\n")
866 static void ospf6_show(struct vty
*vty
, struct ospf6
*o
)
869 struct ospf6_area
*oa
;
870 char router_id
[16], duration
[32];
871 struct timeval now
, running
, result
;
872 char buf
[32], rbuf
[32];
874 /* process id, router id */
875 inet_ntop(AF_INET
, &o
->router_id
, router_id
, sizeof(router_id
));
876 vty_out(vty
, " OSPFv3 Routing Process (0) with Router-ID %s\n",
881 timersub(&now
, &o
->starttime
, &running
);
882 timerstring(&running
, duration
, sizeof(duration
));
883 vty_out(vty
, " Running %s\n", duration
);
885 /* Redistribute configuration */
888 vty_out(vty
, " LSA minimum arrival %d msecs\n", o
->lsa_minarrival
);
890 /* Show SPF parameters */
892 " Initial SPF scheduling delay %d millisec(s)\n"
893 " Minimum hold time between consecutive SPFs %d millsecond(s)\n"
894 " Maximum hold time between consecutive SPFs %d millsecond(s)\n"
895 " Hold time multiplier is currently %d\n",
896 o
->spf_delay
, o
->spf_holdtime
, o
->spf_max_holdtime
,
897 o
->spf_hold_multiplier
);
899 vty_out(vty
, " SPF algorithm ");
900 if (o
->ts_spf
.tv_sec
|| o
->ts_spf
.tv_usec
) {
901 timersub(&now
, &o
->ts_spf
, &result
);
902 timerstring(&result
, buf
, sizeof(buf
));
903 ospf6_spf_reason_string(o
->last_spf_reason
, rbuf
, sizeof(rbuf
));
904 vty_out(vty
, "last executed %s ago, reason %s\n", buf
, rbuf
);
905 vty_out(vty
, " Last SPF duration %lld sec %lld usec\n",
906 (long long)o
->ts_spf_duration
.tv_sec
,
907 (long long)o
->ts_spf_duration
.tv_usec
);
909 vty_out(vty
, "has not been run\n");
910 threadtimer_string(now
, o
->t_spf_calc
, buf
, sizeof(buf
));
911 vty_out(vty
, " SPF timer %s%s\n", (o
->t_spf_calc
? "due in " : "is "),
914 if (CHECK_FLAG(o
->flag
, OSPF6_STUB_ROUTER
))
915 vty_out(vty
, " Router Is Stub Router\n");
918 vty_out(vty
, " Number of AS scoped LSAs is %u\n", o
->lsdb
->count
);
921 vty_out(vty
, " Number of areas in this router is %u\n",
922 listcount(o
->area_list
));
924 if (CHECK_FLAG(o
->config_flags
, OSPF6_LOG_ADJACENCY_CHANGES
)) {
925 if (CHECK_FLAG(o
->config_flags
, OSPF6_LOG_ADJACENCY_DETAIL
))
926 vty_out(vty
, " All adjacency changes are logged\n");
928 vty_out(vty
, " Adjacency changes are logged\n");
933 for (ALL_LIST_ELEMENTS_RO(o
->area_list
, n
, oa
))
934 ospf6_area_show(vty
, oa
);
937 /* show top level structures */
938 DEFUN (show_ipv6_ospf6
,
945 OSPF6_CMD_CHECK_RUNNING();
947 ospf6_show(vty
, ospf6
);
951 DEFUN (show_ipv6_ospf6_route
,
952 show_ipv6_ospf6_route_cmd
,
953 "show ipv6 ospf6 route [<intra-area|inter-area|external-1|external-2|X:X::X:X|X:X::X:X/M|detail|summary>]",
958 "Display Intra-Area routes\n"
959 "Display Inter-Area routes\n"
960 "Display Type-1 External routes\n"
961 "Display Type-2 External routes\n"
962 "Specify IPv6 address\n"
963 "Specify IPv6 prefix\n"
964 "Detailed information\n"
965 "Summary of route table\n")
967 OSPF6_CMD_CHECK_RUNNING();
969 ospf6_route_table_show(vty
, 4, argc
, argv
, ospf6
->route_table
);
973 DEFUN (show_ipv6_ospf6_route_match
,
974 show_ipv6_ospf6_route_match_cmd
,
975 "show ipv6 ospf6 route X:X::X:X/M <match|longer>",
980 "Specify IPv6 prefix\n"
981 "Display routes which match the specified route\n"
982 "Display routes longer than the specified route\n")
984 OSPF6_CMD_CHECK_RUNNING();
986 ospf6_route_table_show(vty
, 4, argc
, argv
, ospf6
->route_table
);
990 DEFUN (show_ipv6_ospf6_route_match_detail
,
991 show_ipv6_ospf6_route_match_detail_cmd
,
992 "show ipv6 ospf6 route X:X::X:X/M match detail",
997 "Specify IPv6 prefix\n"
998 "Display routes which match the specified route\n"
999 "Detailed information\n"
1002 OSPF6_CMD_CHECK_RUNNING();
1004 ospf6_route_table_show(vty
, 4, argc
, argv
, ospf6
->route_table
);
1009 DEFUN (show_ipv6_ospf6_route_type_detail
,
1010 show_ipv6_ospf6_route_type_detail_cmd
,
1011 "show ipv6 ospf6 route <intra-area|inter-area|external-1|external-2> detail",
1016 "Display Intra-Area routes\n"
1017 "Display Inter-Area routes\n"
1018 "Display Type-1 External routes\n"
1019 "Display Type-2 External routes\n"
1020 "Detailed information\n"
1023 OSPF6_CMD_CHECK_RUNNING();
1025 ospf6_route_table_show(vty
, 4, argc
, argv
, ospf6
->route_table
);
1029 static void ospf6_stub_router_config_write(struct vty
*vty
)
1031 if (CHECK_FLAG(ospf6
->flag
, OSPF6_STUB_ROUTER
)) {
1032 vty_out(vty
, " stub-router administrative\n");
1037 static int ospf6_distance_config_write(struct vty
*vty
)
1039 struct route_node
*rn
;
1040 struct ospf6_distance
*odistance
;
1042 if (ospf6
->distance_all
)
1043 vty_out(vty
, " distance %u\n", ospf6
->distance_all
);
1045 if (ospf6
->distance_intra
|| ospf6
->distance_inter
1046 || ospf6
->distance_external
) {
1047 vty_out(vty
, " distance ospf6");
1049 if (ospf6
->distance_intra
)
1050 vty_out(vty
, " intra-area %u", ospf6
->distance_intra
);
1051 if (ospf6
->distance_inter
)
1052 vty_out(vty
, " inter-area %u", ospf6
->distance_inter
);
1053 if (ospf6
->distance_external
)
1054 vty_out(vty
, " external %u", ospf6
->distance_external
);
1059 for (rn
= route_top(ospf6
->distance_table
); rn
; rn
= route_next(rn
))
1060 if ((odistance
= rn
->info
) != NULL
) {
1061 char buf
[PREFIX_STRLEN
];
1063 vty_out(vty
, " distance %u %s %s\n",
1064 odistance
->distance
,
1065 prefix2str(&rn
->p
, buf
, sizeof(buf
)),
1066 odistance
->access_list
? odistance
->access_list
1072 /* OSPF configuration write function. */
1073 static int config_write_ospf6(struct vty
*vty
)
1076 struct listnode
*j
, *k
;
1077 struct ospf6_area
*oa
;
1078 struct ospf6_interface
*oi
;
1080 /* OSPFv3 configuration. */
1084 inet_ntop(AF_INET
, &ospf6
->router_id_static
, router_id
,
1086 vty_out(vty
, "router ospf6\n");
1087 if (ospf6
->router_id_static
!= 0)
1088 vty_out(vty
, " ospf6 router-id %s\n", router_id
);
1090 /* log-adjacency-changes flag print. */
1091 if (CHECK_FLAG(ospf6
->config_flags
, OSPF6_LOG_ADJACENCY_CHANGES
)) {
1092 if (CHECK_FLAG(ospf6
->config_flags
, OSPF6_LOG_ADJACENCY_DETAIL
))
1093 vty_out(vty
, " log-adjacency-changes detail\n");
1094 else if (!DFLT_OSPF6_LOG_ADJACENCY_CHANGES
)
1095 vty_out(vty
, " log-adjacency-changes\n");
1096 } else if (DFLT_OSPF6_LOG_ADJACENCY_CHANGES
) {
1097 vty_out(vty
, " no log-adjacency-changes\n");
1100 if (ospf6
->ref_bandwidth
!= OSPF6_REFERENCE_BANDWIDTH
)
1101 vty_out(vty
, " auto-cost reference-bandwidth %d\n",
1102 ospf6
->ref_bandwidth
);
1104 /* LSA timers print. */
1105 if (ospf6
->lsa_minarrival
!= OSPF_MIN_LS_ARRIVAL
)
1106 vty_out(vty
, " timers lsa min-arrival %d\n",
1107 ospf6
->lsa_minarrival
);
1109 ospf6_stub_router_config_write(vty
);
1110 ospf6_redistribute_config_write(vty
);
1111 ospf6_area_config_write(vty
);
1112 ospf6_spf_config_write(vty
);
1113 ospf6_distance_config_write(vty
);
1115 for (ALL_LIST_ELEMENTS_RO(ospf6
->area_list
, j
, oa
)) {
1116 for (ALL_LIST_ELEMENTS_RO(oa
->if_list
, k
, oi
))
1117 vty_out(vty
, " interface %s area %s\n",
1118 oi
->interface
->name
, oa
->name
);
1120 vty_out(vty
, "!\n");
1124 /* OSPF6 node structure. */
1125 static struct cmd_node ospf6_node
= {
1126 OSPF6_NODE
, "%s(config-ospf6)# ", 1 /* VTYSH */
1129 /* Install ospf related commands. */
1130 void ospf6_top_init(void)
1132 /* Install ospf6 top node. */
1133 install_node(&ospf6_node
, config_write_ospf6
);
1135 install_element(VIEW_NODE
, &show_ipv6_ospf6_cmd
);
1136 install_element(CONFIG_NODE
, &router_ospf6_cmd
);
1137 install_element(CONFIG_NODE
, &no_router_ospf6_cmd
);
1139 install_element(VIEW_NODE
, &show_ipv6_ospf6_route_cmd
);
1140 install_element(VIEW_NODE
, &show_ipv6_ospf6_route_match_cmd
);
1141 install_element(VIEW_NODE
, &show_ipv6_ospf6_route_match_detail_cmd
);
1142 install_element(VIEW_NODE
, &show_ipv6_ospf6_route_type_detail_cmd
);
1144 install_default(OSPF6_NODE
);
1145 install_element(OSPF6_NODE
, &ospf6_router_id_cmd
);
1146 install_element(OSPF6_NODE
, &no_ospf6_router_id_cmd
);
1147 install_element(OSPF6_NODE
, &ospf6_router_id_hdn_cmd
);
1148 install_element(OSPF6_NODE
, &no_ospf6_router_id_hdn_cmd
);
1149 install_element(OSPF6_NODE
, &ospf6_log_adjacency_changes_cmd
);
1150 install_element(OSPF6_NODE
, &ospf6_log_adjacency_changes_detail_cmd
);
1151 install_element(OSPF6_NODE
, &no_ospf6_log_adjacency_changes_cmd
);
1152 install_element(OSPF6_NODE
, &no_ospf6_log_adjacency_changes_detail_cmd
);
1154 /* LSA timers commands */
1155 install_element(OSPF6_NODE
, &ospf6_timers_lsa_cmd
);
1156 install_element(OSPF6_NODE
, &no_ospf6_timers_lsa_cmd
);
1158 install_element(OSPF6_NODE
, &ospf6_interface_area_cmd
);
1159 install_element(OSPF6_NODE
, &no_ospf6_interface_area_cmd
);
1160 install_element(OSPF6_NODE
, &ospf6_stub_router_admin_cmd
);
1161 install_element(OSPF6_NODE
, &no_ospf6_stub_router_admin_cmd
);
1162 /* For a later time */
1164 install_element (OSPF6_NODE
, &ospf6_stub_router_startup_cmd
);
1165 install_element (OSPF6_NODE
, &no_ospf6_stub_router_startup_cmd
);
1166 install_element (OSPF6_NODE
, &ospf6_stub_router_shutdown_cmd
);
1167 install_element (OSPF6_NODE
, &no_ospf6_stub_router_shutdown_cmd
);
1170 install_element(OSPF6_NODE
, &ospf6_distance_cmd
);
1171 install_element(OSPF6_NODE
, &no_ospf6_distance_cmd
);
1172 install_element(OSPF6_NODE
, &ospf6_distance_ospf6_cmd
);
1173 install_element(OSPF6_NODE
, &no_ospf6_distance_ospf6_cmd
);
1175 install_element (OSPF6_NODE
, &ospf6_distance_source_cmd
);
1176 install_element (OSPF6_NODE
, &no_ospf6_distance_source_cmd
);