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
17 * along with GNU Zebra; see the file COPYING. If not, write to the
18 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 * Boston, MA 02111-1307, USA.
34 #include "ospf6_proto.h"
35 #include "ospf6_message.h"
36 #include "ospf6_lsa.h"
37 #include "ospf6_lsdb.h"
38 #include "ospf6_route.h"
39 #include "ospf6_zebra.h"
41 #include "ospf6_top.h"
42 #include "ospf6_area.h"
43 #include "ospf6_interface.h"
44 #include "ospf6_neighbor.h"
46 #include "ospf6_flood.h"
47 #include "ospf6_asbr.h"
48 #include "ospf6_abr.h"
49 #include "ospf6_intra.h"
50 #include "ospf6_spf.h"
53 DEFINE_QOBJ_TYPE(ospf6
)
55 /* global ospf6d variable */
58 static void ospf6_disable(struct ospf6
*o
);
60 static void ospf6_top_lsdb_hook_add(struct ospf6_lsa
*lsa
)
62 switch (ntohs(lsa
->header
->type
)) {
63 case OSPF6_LSTYPE_AS_EXTERNAL
:
64 ospf6_asbr_lsa_add(lsa
);
72 static void ospf6_top_lsdb_hook_remove(struct ospf6_lsa
*lsa
)
74 switch (ntohs(lsa
->header
->type
)) {
75 case OSPF6_LSTYPE_AS_EXTERNAL
:
76 ospf6_asbr_lsa_remove(lsa
);
84 static void ospf6_top_route_hook_add(struct ospf6_route
*route
)
86 ospf6_abr_originate_summary(route
);
87 ospf6_zebra_route_update_add(route
);
90 static void ospf6_top_route_hook_remove(struct ospf6_route
*route
)
92 route
->flag
|= OSPF6_ROUTE_REMOVE
;
93 ospf6_abr_originate_summary(route
);
94 ospf6_zebra_route_update_remove(route
);
97 static void ospf6_top_brouter_hook_add(struct ospf6_route
*route
)
99 ospf6_abr_examin_brouter(ADV_ROUTER_IN_PREFIX(&route
->prefix
));
100 ospf6_asbr_lsentry_add(route
);
101 ospf6_abr_originate_summary(route
);
104 static void ospf6_top_brouter_hook_remove(struct ospf6_route
*route
)
106 route
->flag
|= OSPF6_ROUTE_REMOVE
;
107 ospf6_abr_examin_brouter(ADV_ROUTER_IN_PREFIX(&route
->prefix
));
108 ospf6_asbr_lsentry_remove(route
);
109 ospf6_abr_originate_summary(route
);
112 static struct ospf6
*ospf6_create(void)
116 o
= XCALLOC(MTYPE_OSPF6_TOP
, sizeof(struct ospf6
));
119 monotime(&o
->starttime
);
120 o
->area_list
= list_new();
121 o
->area_list
->cmp
= ospf6_area_cmp
;
122 o
->lsdb
= ospf6_lsdb_create(o
);
123 o
->lsdb_self
= ospf6_lsdb_create(o
);
124 o
->lsdb
->hook_add
= ospf6_top_lsdb_hook_add
;
125 o
->lsdb
->hook_remove
= ospf6_top_lsdb_hook_remove
;
127 o
->spf_delay
= OSPF_SPF_DELAY_DEFAULT
;
128 o
->spf_holdtime
= OSPF_SPF_HOLDTIME_DEFAULT
;
129 o
->spf_max_holdtime
= OSPF_SPF_MAX_HOLDTIME_DEFAULT
;
130 o
->spf_hold_multiplier
= 1;
132 /* LSA timers value init */
133 o
->lsa_minarrival
= OSPF_MIN_LS_ARRIVAL
;
135 o
->route_table
= OSPF6_ROUTE_TABLE_CREATE(GLOBAL
, ROUTES
);
136 o
->route_table
->scope
= o
;
137 o
->route_table
->hook_add
= ospf6_top_route_hook_add
;
138 o
->route_table
->hook_remove
= ospf6_top_route_hook_remove
;
140 o
->brouter_table
= OSPF6_ROUTE_TABLE_CREATE(GLOBAL
, BORDER_ROUTERS
);
141 o
->brouter_table
->scope
= o
;
142 o
->brouter_table
->hook_add
= ospf6_top_brouter_hook_add
;
143 o
->brouter_table
->hook_remove
= ospf6_top_brouter_hook_remove
;
145 o
->external_table
= OSPF6_ROUTE_TABLE_CREATE(GLOBAL
, EXTERNAL_ROUTES
);
146 o
->external_table
->scope
= o
;
148 o
->external_id_table
= route_table_init();
150 o
->ref_bandwidth
= OSPF6_REFERENCE_BANDWIDTH
;
152 o
->distance_table
= route_table_init();
154 /* Enable "log-adjacency-changes" */
155 #if DFLT_OSPF6_LOG_ADJACENCY_CHANGES
156 SET_FLAG(o
->config_flags
, OSPF6_LOG_ADJACENCY_CHANGES
);
164 void ospf6_delete(struct ospf6
*o
)
166 struct listnode
*node
, *nnode
;
167 struct ospf6_area
*oa
;
170 ospf6_disable(ospf6
);
172 for (ALL_LIST_ELEMENTS(o
->area_list
, node
, nnode
, oa
))
173 ospf6_area_delete(oa
);
176 list_delete(o
->area_list
);
178 ospf6_lsdb_delete(o
->lsdb
);
179 ospf6_lsdb_delete(o
->lsdb_self
);
181 ospf6_route_table_delete(o
->route_table
);
182 ospf6_route_table_delete(o
->brouter_table
);
184 ospf6_route_table_delete(o
->external_table
);
185 route_table_finish(o
->external_id_table
);
187 ospf6_distance_reset(o
);
188 route_table_finish(o
->distance_table
);
190 XFREE(MTYPE_OSPF6_TOP
, o
);
193 static void ospf6_disable(struct ospf6
*o
)
195 struct listnode
*node
, *nnode
;
196 struct ospf6_area
*oa
;
198 if (!CHECK_FLAG(o
->flag
, OSPF6_DISABLED
)) {
199 SET_FLAG(o
->flag
, OSPF6_DISABLED
);
201 for (ALL_LIST_ELEMENTS(o
->area_list
, node
, nnode
, oa
))
202 ospf6_area_disable(oa
);
204 /* XXX: This also changes persistent settings */
205 ospf6_asbr_redistribute_reset();
207 ospf6_lsdb_remove_all(o
->lsdb
);
208 ospf6_route_remove_all(o
->route_table
);
209 ospf6_route_remove_all(o
->brouter_table
);
211 THREAD_OFF(o
->maxage_remover
);
212 THREAD_OFF(o
->t_spf_calc
);
213 THREAD_OFF(o
->t_ase_calc
);
217 static int ospf6_maxage_remover(struct thread
*thread
)
219 struct ospf6
*o
= (struct ospf6
*)THREAD_ARG(thread
);
220 struct ospf6_area
*oa
;
221 struct ospf6_interface
*oi
;
222 struct ospf6_neighbor
*on
;
223 struct listnode
*i
, *j
, *k
;
226 o
->maxage_remover
= (struct thread
*)NULL
;
228 for (ALL_LIST_ELEMENTS_RO(o
->area_list
, i
, oa
)) {
229 for (ALL_LIST_ELEMENTS_RO(oa
->if_list
, j
, oi
)) {
230 for (ALL_LIST_ELEMENTS_RO(oi
->neighbor_list
, k
, on
)) {
231 if (on
->state
!= OSPF6_NEIGHBOR_EXCHANGE
232 && on
->state
!= OSPF6_NEIGHBOR_LOADING
)
235 ospf6_maxage_remove(o
);
241 for (ALL_LIST_ELEMENTS_RO(o
->area_list
, i
, oa
)) {
242 for (ALL_LIST_ELEMENTS_RO(oa
->if_list
, j
, oi
)) {
243 if (ospf6_lsdb_maxage_remover(oi
->lsdb
)) {
248 if (ospf6_lsdb_maxage_remover(oa
->lsdb
)) {
253 if (ospf6_lsdb_maxage_remover(o
->lsdb
)) {
258 ospf6_maxage_remove(o
);
264 void ospf6_maxage_remove(struct ospf6
*o
)
266 if (o
&& !o
->maxage_remover
)
268 thread_add_timer(master
, ospf6_maxage_remover
, o
,
269 OSPF_LSA_MAXAGE_REMOVE_DELAY_DEFAULT
);
273 DEFUN_NOSH (router_ospf6
,
280 ospf6
= ospf6_create();
282 /* set current ospf point. */
283 VTY_PUSH_CONTEXT(OSPF6_NODE
, ospf6
);
289 DEFUN (no_router_ospf6
,
297 vty_out(vty
, "OSPFv3 is not configured%s", VNL
);
303 /* return to config node . */
304 VTY_PUSH_CONTEXT_NULL(CONFIG_NODE
);
309 /* change Router_ID commands. */
310 DEFUN (ospf6_router_id
,
313 "Configure OSPF Router-ID\n"
316 VTY_DECLVAR_CONTEXT(ospf6
, o
);
321 ret
= inet_pton(AF_INET
, argv
[idx_ipv4
]->arg
, &router_id
);
323 vty_out(vty
, "malformed OSPF Router-ID: %s%s",
324 argv
[idx_ipv4
]->arg
, VNL
);
328 o
->router_id_static
= router_id
;
329 if (o
->router_id
== 0)
330 o
->router_id
= router_id
;
335 DEFUN (ospf6_log_adjacency_changes
,
336 ospf6_log_adjacency_changes_cmd
,
337 "log-adjacency-changes",
338 "Log changes in adjacency state\n")
340 VTY_DECLVAR_CONTEXT(ospf6
, ospf6
);
342 SET_FLAG(ospf6
->config_flags
, OSPF6_LOG_ADJACENCY_CHANGES
);
343 UNSET_FLAG(ospf6
->config_flags
, OSPF6_LOG_ADJACENCY_DETAIL
);
347 DEFUN (ospf6_log_adjacency_changes_detail
,
348 ospf6_log_adjacency_changes_detail_cmd
,
349 "log-adjacency-changes detail",
350 "Log changes in adjacency state\n"
351 "Log all state changes\n")
353 VTY_DECLVAR_CONTEXT(ospf6
, ospf6
);
355 SET_FLAG(ospf6
->config_flags
, OSPF6_LOG_ADJACENCY_CHANGES
);
356 SET_FLAG(ospf6
->config_flags
, OSPF6_LOG_ADJACENCY_DETAIL
);
360 DEFUN (no_ospf6_log_adjacency_changes
,
361 no_ospf6_log_adjacency_changes_cmd
,
362 "no log-adjacency-changes",
364 "Log changes in adjacency state\n")
366 VTY_DECLVAR_CONTEXT(ospf6
, ospf6
);
368 UNSET_FLAG(ospf6
->config_flags
, OSPF6_LOG_ADJACENCY_DETAIL
);
369 UNSET_FLAG(ospf6
->config_flags
, OSPF6_LOG_ADJACENCY_CHANGES
);
373 DEFUN (no_ospf6_log_adjacency_changes_detail
,
374 no_ospf6_log_adjacency_changes_detail_cmd
,
375 "no log-adjacency-changes detail",
377 "Log changes in adjacency state\n"
378 "Log all state changes\n")
380 VTY_DECLVAR_CONTEXT(ospf6
, ospf6
);
382 UNSET_FLAG(ospf6
->config_flags
, OSPF6_LOG_ADJACENCY_DETAIL
);
386 DEFUN (ospf6_timers_lsa
,
387 ospf6_timers_lsa_cmd
,
388 "timers lsa min-arrival (0-600000)",
389 "Adjust routing timers\n"
391 "Minimum delay in receiving new version of a LSA\n"
392 "Delay in milliseconds\n")
394 VTY_DECLVAR_CONTEXT(ospf6
, ospf
);
396 unsigned int minarrival
;
398 VTY_GET_INTEGER("LSA min-arrival", minarrival
, argv
[idx_number
]->arg
);
399 ospf
->lsa_minarrival
= minarrival
;
404 DEFUN (no_ospf6_timers_lsa
,
405 no_ospf6_timers_lsa_cmd
,
406 "no timers lsa min-arrival [(0-600000)]",
408 "Adjust routing timers\n"
410 "Minimum delay in receiving new version of a LSA\n"
411 "Delay in milliseconds\n")
413 VTY_DECLVAR_CONTEXT(ospf6
, ospf
);
415 unsigned int minarrival
;
418 VTY_GET_INTEGER("LSA min-arrival", minarrival
,
419 argv
[idx_number
]->arg
);
421 if (ospf
->lsa_minarrival
!= minarrival
422 || minarrival
== OSPF_MIN_LS_ARRIVAL
)
426 ospf
->lsa_minarrival
= OSPF_MIN_LS_ARRIVAL
;
432 DEFUN (ospf6_distance
,
435 "Administrative distance\n"
436 "OSPF6 Administrative distance\n")
438 VTY_DECLVAR_CONTEXT(ospf6
, o
);
440 o
->distance_all
= atoi(argv
[1]->arg
);
445 DEFUN (no_ospf6_distance
,
446 no_ospf6_distance_cmd
,
447 "no distance (1-255)",
449 "Administrative distance\n"
450 "OSPF6 Administrative distance\n")
452 VTY_DECLVAR_CONTEXT(ospf6
, o
);
459 DEFUN (ospf6_distance_ospf6
,
460 ospf6_distance_ospf6_cmd
,
461 "distance ospf6 {intra-area (1-255)|inter-area (1-255)|external (1-255)}",
462 "Administrative distance\n"
463 "OSPF6 administrative distance\n"
464 "Intra-area routes\n"
465 "Distance for intra-area routes\n"
466 "Inter-area routes\n"
467 "Distance for inter-area routes\n"
469 "Distance for external routes\n")
471 VTY_DECLVAR_CONTEXT(ospf6
, o
);
474 if (argv_find(argv
, argc
, "intra-area", &idx
))
475 o
->distance_intra
= atoi(argv
[idx
+ 1]->arg
);
477 if (argv_find(argv
, argc
, "inter-area", &idx
))
478 o
->distance_inter
= atoi(argv
[idx
+ 1]->arg
);
480 if (argv_find(argv
, argc
, "external", &idx
))
481 o
->distance_external
= atoi(argv
[idx
+ 1]->arg
);
486 DEFUN (no_ospf6_distance_ospf6
,
487 no_ospf6_distance_ospf6_cmd
,
488 "no distance ospf6 [{intra-area [(1-255)]|inter-area [(1-255)]|external [(1-255)]}]",
490 "Administrative distance\n"
492 "Intra-area routes\n"
493 "Distance for intra-area routes\n"
494 "Inter-area routes\n"
495 "Distance for inter-area routes\n"
497 "Distance for external routes\n")
499 VTY_DECLVAR_CONTEXT(ospf6
, o
);
502 if (argv_find(argv
, argc
, "intra-area", &idx
) || argc
== 3)
503 idx
= o
->distance_intra
= 0;
504 if (argv_find(argv
, argc
, "inter-area", &idx
) || argc
== 3)
505 idx
= o
->distance_inter
= 0;
506 if (argv_find(argv
, argc
, "external", &idx
) || argc
== 3)
507 o
->distance_external
= 0;
513 DEFUN (ospf6_distance_source
,
514 ospf6_distance_source_cmd
,
515 "distance (1-255) X:X::X:X/M [WORD]",
516 "Administrative distance\n"
519 "Access list name\n")
521 VTY_DECLVAR_CONTEXT(ospf6
, o
);
522 char *alname
= (argc
== 4) ? argv
[3]->arg
: NULL
;
523 ospf6_distance_set (vty
, o
, argv
[1]->arg
, argv
[2]->arg
, alname
);
528 DEFUN (no_ospf6_distance_source
,
529 no_ospf6_distance_source_cmd
,
530 "no distance (1-255) X:X::X:X/M [WORD]",
532 "Administrative distance\n"
535 "Access list name\n")
537 VTY_DECLVAR_CONTEXT(ospf6
, o
);
538 char *alname
= (argc
== 5) ? argv
[4]->arg
: NULL
;
539 ospf6_distance_unset (vty
, o
, argv
[2]->arg
, argv
[3]->arg
, alname
);
545 DEFUN (ospf6_interface_area
,
546 ospf6_interface_area_cmd
,
547 "interface IFNAME area A.B.C.D",
548 "Enable routing on an IPv6 interface\n"
550 "Specify the OSPF6 area ID\n"
551 "OSPF6 area ID in IPv4 address notation\n"
554 VTY_DECLVAR_CONTEXT(ospf6
, o
);
557 struct ospf6_area
*oa
;
558 struct ospf6_interface
*oi
;
559 struct interface
*ifp
;
562 /* find/create ospf6 interface */
563 ifp
= if_get_by_name(argv
[idx_ifname
]->arg
, VRF_DEFAULT
);
564 oi
= (struct ospf6_interface
*)ifp
->info
;
566 oi
= ospf6_interface_create(ifp
);
568 vty_out(vty
, "%s already attached to Area %s%s",
569 oi
->interface
->name
, oi
->area
->name
, VNL
);
574 if (inet_pton(AF_INET
, argv
[idx_ipv4
]->arg
, &area_id
) != 1) {
575 vty_out(vty
, "Invalid Area-ID: %s%s", argv
[idx_ipv4
]->arg
, VNL
);
579 /* find/create ospf6 area */
580 oa
= ospf6_area_lookup(area_id
, o
);
582 oa
= ospf6_area_create(area_id
, o
);
584 /* attach interface to area */
585 listnode_add(oa
->if_list
, oi
); /* sort ?? */
588 SET_FLAG(oa
->flag
, OSPF6_AREA_ENABLE
);
590 /* ospf6 process is currently disabled, not much more to do */
591 if (CHECK_FLAG(o
->flag
, OSPF6_DISABLED
))
595 ospf6_interface_enable(oi
);
597 /* If the router is ABR, originate summary routes */
598 if (ospf6_is_router_abr(o
))
599 ospf6_abr_enable_area(oa
);
604 DEFUN (no_ospf6_interface_area
,
605 no_ospf6_interface_area_cmd
,
606 "no interface IFNAME area A.B.C.D",
608 "Disable routing on an IPv6 interface\n"
610 "Specify the OSPF6 area ID\n"
611 "OSPF6 area ID in IPv4 address notation\n"
616 struct ospf6_interface
*oi
;
617 struct ospf6_area
*oa
;
618 struct interface
*ifp
;
621 ifp
= if_lookup_by_name(argv
[idx_ifname
]->arg
, VRF_DEFAULT
);
623 vty_out(vty
, "No such interface %s%s", argv
[idx_ifname
]->arg
,
628 oi
= (struct ospf6_interface
*)ifp
->info
;
630 vty_out(vty
, "Interface %s not enabled%s", ifp
->name
, VNL
);
635 if (inet_pton(AF_INET
, argv
[idx_ipv4
]->arg
, &area_id
) != 1) {
636 vty_out(vty
, "Invalid Area-ID: %s%s", argv
[idx_ipv4
]->arg
, VNL
);
641 if (oi
->area
== NULL
) {
642 vty_out(vty
, "No such Area-ID: %s%s", argv
[idx_ipv4
]->arg
, VNL
);
646 if (oi
->area
->area_id
!= area_id
) {
647 vty_out(vty
, "Wrong Area-ID: %s is attached to area %s%s",
648 oi
->interface
->name
, oi
->area
->name
, VNL
);
652 thread_execute(master
, interface_down
, oi
, 0);
655 listnode_delete(oi
->area
->if_list
, oi
);
656 oi
->area
= (struct ospf6_area
*)NULL
;
658 /* Withdraw inter-area routes from this area, if necessary */
659 if (oa
->if_list
->count
== 0) {
660 UNSET_FLAG(oa
->flag
, OSPF6_AREA_ENABLE
);
661 ospf6_abr_disable_area(oa
);
667 DEFUN (ospf6_stub_router_admin
,
668 ospf6_stub_router_admin_cmd
,
669 "stub-router administrative",
670 "Make router a stub router\n"
671 "Advertise inability to be a transit router\n"
672 "Administratively applied, for an indefinite period\n")
674 struct listnode
*node
;
675 struct ospf6_area
*oa
;
677 if (!CHECK_FLAG(ospf6
->flag
, OSPF6_STUB_ROUTER
)) {
678 for (ALL_LIST_ELEMENTS_RO(ospf6
->area_list
, node
, oa
)) {
679 OSPF6_OPT_CLEAR(oa
->options
, OSPF6_OPT_V6
);
680 OSPF6_OPT_CLEAR(oa
->options
, OSPF6_OPT_R
);
681 OSPF6_ROUTER_LSA_SCHEDULE(oa
);
683 SET_FLAG(ospf6
->flag
, OSPF6_STUB_ROUTER
);
689 DEFUN (no_ospf6_stub_router_admin
,
690 no_ospf6_stub_router_admin_cmd
,
691 "no stub-router administrative",
693 "Make router a stub router\n"
694 "Advertise ability to be a transit router\n"
695 "Administratively applied, for an indefinite period\n")
697 struct listnode
*node
;
698 struct ospf6_area
*oa
;
700 if (CHECK_FLAG(ospf6
->flag
, OSPF6_STUB_ROUTER
)) {
701 for (ALL_LIST_ELEMENTS_RO(ospf6
->area_list
, node
, oa
)) {
702 OSPF6_OPT_SET(oa
->options
, OSPF6_OPT_V6
);
703 OSPF6_OPT_SET(oa
->options
, OSPF6_OPT_R
);
704 OSPF6_ROUTER_LSA_SCHEDULE(oa
);
706 UNSET_FLAG(ospf6
->flag
, OSPF6_STUB_ROUTER
);
713 DEFUN (ospf6_stub_router_startup
,
714 ospf6_stub_router_startup_cmd
,
715 "stub-router on-startup (5-86400)",
716 "Make router a stub router\n"
717 "Advertise inability to be a transit router\n"
718 "Automatically advertise as stub-router on startup of OSPF6\n"
719 "Time (seconds) to advertise self as stub-router\n")
724 DEFUN (no_ospf6_stub_router_startup
,
725 no_ospf6_stub_router_startup_cmd
,
726 "no stub-router on-startup",
728 "Make router a stub router\n"
729 "Advertise inability to be a transit router\n"
730 "Automatically advertise as stub-router on startup of OSPF6\n"
731 "Time (seconds) to advertise self as stub-router\n")
736 DEFUN (ospf6_stub_router_shutdown
,
737 ospf6_stub_router_shutdown_cmd
,
738 "stub-router on-shutdown (5-86400)",
739 "Make router a stub router\n"
740 "Advertise inability to be a transit router\n"
741 "Automatically advertise as stub-router before shutdown\n"
742 "Time (seconds) to advertise self as stub-router\n")
747 DEFUN (no_ospf6_stub_router_shutdown
,
748 no_ospf6_stub_router_shutdown_cmd
,
749 "no stub-router on-shutdown",
751 "Make router a stub router\n"
752 "Advertise inability to be a transit router\n"
753 "Automatically advertise as stub-router before shutdown\n"
754 "Time (seconds) to advertise self as stub-router\n")
760 static void ospf6_show(struct vty
*vty
, struct ospf6
*o
)
763 struct ospf6_area
*oa
;
764 char router_id
[16], duration
[32];
765 struct timeval now
, running
, result
;
766 char buf
[32], rbuf
[32];
768 /* process id, router id */
769 inet_ntop(AF_INET
, &o
->router_id
, router_id
, sizeof(router_id
));
770 vty_out(vty
, " OSPFv3 Routing Process (0) with Router-ID %s%s",
775 timersub(&now
, &o
->starttime
, &running
);
776 timerstring(&running
, duration
, sizeof(duration
));
777 vty_out(vty
, " Running %s%s", duration
, VNL
);
779 /* Redistribute configuration */
782 vty_out(vty
, " LSA minimum arrival %d msecs%s", o
->lsa_minarrival
,
785 /* Show SPF parameters */
787 " Initial SPF scheduling delay %d millisec(s)%s"
788 " Minimum hold time between consecutive SPFs %d millsecond(s)%s"
789 " Maximum hold time between consecutive SPFs %d millsecond(s)%s"
790 " Hold time multiplier is currently %d%s",
791 o
->spf_delay
, VNL
, o
->spf_holdtime
, VNL
, o
->spf_max_holdtime
,
792 VNL
, o
->spf_hold_multiplier
, VNL
);
794 vty_out(vty
, " SPF algorithm ");
795 if (o
->ts_spf
.tv_sec
|| o
->ts_spf
.tv_usec
) {
796 timersub(&now
, &o
->ts_spf
, &result
);
797 timerstring(&result
, buf
, sizeof(buf
));
798 ospf6_spf_reason_string(o
->last_spf_reason
, rbuf
, sizeof(rbuf
));
799 vty_out(vty
, "last executed %s ago, reason %s%s", buf
, rbuf
,
801 vty_out(vty
, " Last SPF duration %lld sec %lld usec%s",
802 (long long)o
->ts_spf_duration
.tv_sec
,
803 (long long)o
->ts_spf_duration
.tv_usec
, VNL
);
805 vty_out(vty
, "has not been run$%s", VNL
);
806 threadtimer_string(now
, o
->t_spf_calc
, buf
, sizeof(buf
));
807 vty_out(vty
, " SPF timer %s%s%s", (o
->t_spf_calc
? "due in " : "is "),
810 if (CHECK_FLAG(o
->flag
, OSPF6_STUB_ROUTER
))
811 vty_out(vty
, " Router Is Stub Router%s", VNL
);
814 vty_out(vty
, " Number of AS scoped LSAs is %u%s", o
->lsdb
->count
, VNL
);
817 vty_out(vty
, " Number of areas in this router is %u%s",
818 listcount(o
->area_list
), VNL
);
820 if (CHECK_FLAG(o
->config_flags
, OSPF6_LOG_ADJACENCY_CHANGES
)) {
821 if (CHECK_FLAG(o
->config_flags
, OSPF6_LOG_ADJACENCY_DETAIL
))
822 vty_out(vty
, " All adjacency changes are logged%s",
825 vty_out(vty
, " Adjacency changes are logged%s",
829 vty_out(vty
, "%s", VTY_NEWLINE
);
831 for (ALL_LIST_ELEMENTS_RO(o
->area_list
, n
, oa
))
832 ospf6_area_show(vty
, oa
);
835 /* show top level structures */
836 DEFUN (show_ipv6_ospf6
,
843 OSPF6_CMD_CHECK_RUNNING();
845 ospf6_show(vty
, ospf6
);
849 DEFUN (show_ipv6_ospf6_route
,
850 show_ipv6_ospf6_route_cmd
,
851 "show ipv6 ospf6 route [<intra-area|inter-area|external-1|external-2|X:X::X:X|X:X::X:X/M|detail|summary>]",
856 "Display Intra-Area routes\n"
857 "Display Inter-Area routes\n"
858 "Display Type-1 External routes\n"
859 "Display Type-2 External routes\n"
860 "Specify IPv6 address\n"
861 "Specify IPv6 prefix\n"
862 "Detailed information\n"
863 "Summary of route table\n")
865 OSPF6_CMD_CHECK_RUNNING();
867 ospf6_route_table_show(vty
, 4, argc
, argv
, ospf6
->route_table
);
871 DEFUN (show_ipv6_ospf6_route_match
,
872 show_ipv6_ospf6_route_match_cmd
,
873 "show ipv6 ospf6 route X:X::X:X/M <match|longer>",
878 "Specify IPv6 prefix\n"
879 "Display routes which match the specified route\n"
880 "Display routes longer than the specified route\n")
882 OSPF6_CMD_CHECK_RUNNING();
884 ospf6_route_table_show(vty
, 4, argc
, argv
, ospf6
->route_table
);
888 DEFUN (show_ipv6_ospf6_route_match_detail
,
889 show_ipv6_ospf6_route_match_detail_cmd
,
890 "show ipv6 ospf6 route X:X::X:X/M match detail",
895 "Specify IPv6 prefix\n"
896 "Display routes which match the specified route\n"
897 "Detailed information\n"
900 OSPF6_CMD_CHECK_RUNNING();
902 ospf6_route_table_show(vty
, 4, argc
, argv
, ospf6
->route_table
);
907 DEFUN (show_ipv6_ospf6_route_type_detail
,
908 show_ipv6_ospf6_route_type_detail_cmd
,
909 "show ipv6 ospf6 route <intra-area|inter-area|external-1|external-2> detail",
914 "Display Intra-Area routes\n"
915 "Display Inter-Area routes\n"
916 "Display Type-1 External routes\n"
917 "Display Type-2 External routes\n"
918 "Detailed information\n"
921 OSPF6_CMD_CHECK_RUNNING();
923 ospf6_route_table_show(vty
, 4, argc
, argv
, ospf6
->route_table
);
927 static void ospf6_stub_router_config_write(struct vty
*vty
)
929 if (CHECK_FLAG(ospf6
->flag
, OSPF6_STUB_ROUTER
)) {
930 vty_out(vty
, " stub-router administrative%s", VNL
);
935 static int ospf6_distance_config_write(struct vty
*vty
)
937 struct route_node
*rn
;
938 struct ospf6_distance
*odistance
;
940 if (ospf6
->distance_all
)
941 vty_out(vty
, " distance %u%s", ospf6
->distance_all
,
944 if (ospf6
->distance_intra
|| ospf6
->distance_inter
945 || ospf6
->distance_external
) {
946 vty_out(vty
, " distance ospf6");
948 if (ospf6
->distance_intra
)
949 vty_out(vty
, " intra-area %u", ospf6
->distance_intra
);
950 if (ospf6
->distance_inter
)
951 vty_out(vty
, " inter-area %u", ospf6
->distance_inter
);
952 if (ospf6
->distance_external
)
953 vty_out(vty
, " external %u", ospf6
->distance_external
);
955 vty_out(vty
, "%s", VTY_NEWLINE
);
958 for (rn
= route_top(ospf6
->distance_table
); rn
; rn
= route_next(rn
))
959 if ((odistance
= rn
->info
) != NULL
) {
960 char buf
[PREFIX_STRLEN
];
962 vty_out(vty
, " distance %u %s %s%s",
964 prefix2str(&rn
->p
, buf
, sizeof(buf
)),
965 odistance
->access_list
? odistance
->access_list
972 /* OSPF configuration write function. */
973 static int config_write_ospf6(struct vty
*vty
)
976 struct listnode
*j
, *k
;
977 struct ospf6_area
*oa
;
978 struct ospf6_interface
*oi
;
980 /* OSPFv3 configuration. */
984 inet_ntop(AF_INET
, &ospf6
->router_id_static
, router_id
,
986 vty_out(vty
, "router ospf6%s", VNL
);
987 if (ospf6
->router_id_static
!= 0)
988 vty_out(vty
, " router-id %s%s", router_id
, VNL
);
990 /* log-adjacency-changes flag print. */
991 if (CHECK_FLAG(ospf6
->config_flags
, OSPF6_LOG_ADJACENCY_CHANGES
)) {
992 if (CHECK_FLAG(ospf6
->config_flags
, OSPF6_LOG_ADJACENCY_DETAIL
))
993 vty_out(vty
, " log-adjacency-changes detail%s",
995 else if (!DFLT_OSPF6_LOG_ADJACENCY_CHANGES
)
996 vty_out(vty
, " log-adjacency-changes%s", VTY_NEWLINE
);
997 } else if (DFLT_OSPF6_LOG_ADJACENCY_CHANGES
) {
998 vty_out(vty
, " no log-adjacency-changes%s", VTY_NEWLINE
);
1001 if (ospf6
->ref_bandwidth
!= OSPF6_REFERENCE_BANDWIDTH
)
1002 vty_out(vty
, " auto-cost reference-bandwidth %d%s",
1003 ospf6
->ref_bandwidth
, VNL
);
1005 /* LSA timers print. */
1006 if (ospf6
->lsa_minarrival
!= OSPF_MIN_LS_ARRIVAL
)
1007 vty_out(vty
, " timers lsa min-arrival %d%s",
1008 ospf6
->lsa_minarrival
, VTY_NEWLINE
);
1010 ospf6_stub_router_config_write(vty
);
1011 ospf6_redistribute_config_write(vty
);
1012 ospf6_area_config_write(vty
);
1013 ospf6_spf_config_write(vty
);
1014 ospf6_distance_config_write(vty
);
1016 for (ALL_LIST_ELEMENTS_RO(ospf6
->area_list
, j
, oa
)) {
1017 for (ALL_LIST_ELEMENTS_RO(oa
->if_list
, k
, oi
))
1018 vty_out(vty
, " interface %s area %s%s",
1019 oi
->interface
->name
, oa
->name
, VNL
);
1021 vty_out(vty
, "!%s", VNL
);
1025 /* OSPF6 node structure. */
1026 static struct cmd_node ospf6_node
= {
1027 OSPF6_NODE
, "%s(config-ospf6)# ", 1 /* VTYSH */
1030 /* Install ospf related commands. */
1031 void ospf6_top_init(void)
1033 /* Install ospf6 top node. */
1034 install_node(&ospf6_node
, config_write_ospf6
);
1036 install_element(VIEW_NODE
, &show_ipv6_ospf6_cmd
);
1037 install_element(CONFIG_NODE
, &router_ospf6_cmd
);
1038 install_element(CONFIG_NODE
, &no_router_ospf6_cmd
);
1040 install_element(VIEW_NODE
, &show_ipv6_ospf6_route_cmd
);
1041 install_element(VIEW_NODE
, &show_ipv6_ospf6_route_match_cmd
);
1042 install_element(VIEW_NODE
, &show_ipv6_ospf6_route_match_detail_cmd
);
1043 install_element(VIEW_NODE
, &show_ipv6_ospf6_route_type_detail_cmd
);
1045 install_default(OSPF6_NODE
);
1046 install_element(OSPF6_NODE
, &ospf6_router_id_cmd
);
1047 install_element(OSPF6_NODE
, &ospf6_log_adjacency_changes_cmd
);
1048 install_element(OSPF6_NODE
, &ospf6_log_adjacency_changes_detail_cmd
);
1049 install_element(OSPF6_NODE
, &no_ospf6_log_adjacency_changes_cmd
);
1050 install_element(OSPF6_NODE
, &no_ospf6_log_adjacency_changes_detail_cmd
);
1052 /* LSA timers commands */
1053 install_element(OSPF6_NODE
, &ospf6_timers_lsa_cmd
);
1054 install_element(OSPF6_NODE
, &no_ospf6_timers_lsa_cmd
);
1056 install_element(OSPF6_NODE
, &ospf6_interface_area_cmd
);
1057 install_element(OSPF6_NODE
, &no_ospf6_interface_area_cmd
);
1058 install_element(OSPF6_NODE
, &ospf6_stub_router_admin_cmd
);
1059 install_element(OSPF6_NODE
, &no_ospf6_stub_router_admin_cmd
);
1060 /* For a later time */
1062 install_element (OSPF6_NODE
, &ospf6_stub_router_startup_cmd
);
1063 install_element (OSPF6_NODE
, &no_ospf6_stub_router_startup_cmd
);
1064 install_element (OSPF6_NODE
, &ospf6_stub_router_shutdown_cmd
);
1065 install_element (OSPF6_NODE
, &no_ospf6_stub_router_shutdown_cmd
);
1068 install_element(OSPF6_NODE
, &ospf6_distance_cmd
);
1069 install_element(OSPF6_NODE
, &no_ospf6_distance_cmd
);
1070 install_element(OSPF6_NODE
, &ospf6_distance_ospf6_cmd
);
1071 install_element(OSPF6_NODE
, &no_ospf6_distance_ospf6_cmd
);
1073 install_element (OSPF6_NODE
, &ospf6_distance_source_cmd
);
1074 install_element (OSPF6_NODE
, &no_ospf6_distance_source_cmd
);