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
32 #include "lib_errors.h"
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"
45 #include "ospf6_network.h"
47 #include "ospf6_flood.h"
48 #include "ospf6_asbr.h"
49 #include "ospf6_abr.h"
50 #include "ospf6_intra.h"
51 #include "ospf6_spf.h"
54 DEFINE_QOBJ_TYPE(ospf6
)
56 FRR_CFG_DEFAULT_BOOL(OSPF6_LOG_ADJACENCY_CHANGES
,
57 { .val_bool
= true, .match_profile
= "datacenter", },
58 { .val_bool
= false },
61 /* global ospf6d variable */
62 static struct ospf6_master ospf6_master
;
63 struct ospf6_master
*om6
;
65 static void ospf6_disable(struct ospf6
*o
);
67 static void ospf6_add(struct ospf6
*ospf6
)
69 listnode_add(om6
->ospf6
, ospf6
);
72 static void ospf6_del(struct ospf6
*ospf6
)
74 listnode_delete(om6
->ospf6
, ospf6
);
77 const char *ospf6_vrf_id_to_name(vrf_id_t vrf_id
)
79 struct vrf
*vrf
= vrf_lookup_by_id(vrf_id
);
81 return vrf
? vrf
->name
: "NIL";
84 /* Link OSPF instance to VRF. */
85 void ospf6_vrf_link(struct ospf6
*ospf6
, struct vrf
*vrf
)
87 ospf6
->vrf_id
= vrf
->vrf_id
;
88 if (vrf
->info
!= (void *)ospf6
)
89 vrf
->info
= (void *)ospf6
;
92 /* Unlink OSPF instance from VRF. */
93 void ospf6_vrf_unlink(struct ospf6
*ospf6
, struct vrf
*vrf
)
95 if (vrf
->info
== (void *)ospf6
)
97 ospf6
->vrf_id
= VRF_UNKNOWN
;
100 struct ospf6
*ospf6_lookup_by_vrf_id(vrf_id_t vrf_id
)
102 struct vrf
*vrf
= NULL
;
104 vrf
= vrf_lookup_by_id(vrf_id
);
107 return (vrf
->info
) ? (struct ospf6
*)vrf
->info
: NULL
;
110 struct ospf6
*ospf6_lookup_by_vrf_name(const char *name
)
112 struct ospf6
*o
= NULL
;
113 struct listnode
*node
, *nnode
;
115 for (ALL_LIST_ELEMENTS(om6
->ospf6
, node
, nnode
, o
)) {
116 if (((o
->name
== NULL
&& name
== NULL
)
117 || (o
->name
&& name
&& strcmp(o
->name
, name
) == 0)))
124 static void ospf6_top_lsdb_hook_add(struct ospf6_lsa
*lsa
)
126 struct ospf6
*ospf6
= NULL
;
128 switch (ntohs(lsa
->header
->type
)) {
129 case OSPF6_LSTYPE_AS_EXTERNAL
:
130 ospf6
= ospf6_get_by_lsdb(lsa
);
131 ospf6_asbr_lsa_add(lsa
, ospf6
);
139 static void ospf6_top_lsdb_hook_remove(struct ospf6_lsa
*lsa
)
141 switch (ntohs(lsa
->header
->type
)) {
142 case OSPF6_LSTYPE_AS_EXTERNAL
:
143 ospf6_asbr_lsa_remove(lsa
, NULL
);
151 static void ospf6_top_route_hook_add(struct ospf6_route
*route
,
154 ospf6_abr_originate_summary(route
, ospf6
);
155 ospf6_zebra_route_update_add(route
, ospf6
);
158 static void ospf6_top_route_hook_remove(struct ospf6_route
*route
,
161 route
->flag
|= OSPF6_ROUTE_REMOVE
;
162 ospf6_abr_originate_summary(route
, ospf6
);
163 ospf6_zebra_route_update_remove(route
, ospf6
);
166 static void ospf6_top_brouter_hook_add(struct ospf6_route
*route
,
169 if (IS_OSPF6_DEBUG_EXAMIN(AS_EXTERNAL
) ||
170 IS_OSPF6_DEBUG_BROUTER
) {
172 char brouter_name
[16];
174 brouter_id
= ADV_ROUTER_IN_PREFIX(&route
->prefix
);
175 inet_ntop(AF_INET
, &brouter_id
, brouter_name
,
176 sizeof(brouter_name
));
177 zlog_debug("%s: brouter %s add with adv router %x nh count %u",
178 __func__
, brouter_name
,
179 route
->path
.origin
.adv_router
,
180 listcount(route
->nh_list
));
182 ospf6_abr_examin_brouter(ADV_ROUTER_IN_PREFIX(&route
->prefix
), route
,
184 ospf6_asbr_lsentry_add(route
, ospf6
);
185 ospf6_abr_originate_summary(route
, ospf6
);
188 static void ospf6_top_brouter_hook_remove(struct ospf6_route
*route
,
191 if (IS_OSPF6_DEBUG_EXAMIN(AS_EXTERNAL
) ||
192 IS_OSPF6_DEBUG_BROUTER
) {
194 char brouter_name
[16];
196 brouter_id
= ADV_ROUTER_IN_PREFIX(&route
->prefix
);
197 inet_ntop(AF_INET
, &brouter_id
, brouter_name
,
198 sizeof(brouter_name
));
199 zlog_debug("%s: brouter %p %s del with adv router %x nh %u",
200 __func__
, (void *)route
, brouter_name
,
201 route
->path
.origin
.adv_router
,
202 listcount(route
->nh_list
));
204 route
->flag
|= OSPF6_ROUTE_REMOVE
;
205 ospf6_abr_examin_brouter(ADV_ROUTER_IN_PREFIX(&route
->prefix
), route
,
207 ospf6_asbr_lsentry_remove(route
, ospf6
);
208 ospf6_abr_originate_summary(route
, ospf6
);
211 static struct ospf6
*ospf6_create(const char *name
)
214 struct vrf
*vrf
= NULL
;
216 o
= XCALLOC(MTYPE_OSPF6_TOP
, sizeof(struct ospf6
));
218 vrf
= vrf_lookup_by_name(name
);
220 o
->vrf_id
= vrf
->vrf_id
;
222 o
->vrf_id
= VRF_UNKNOWN
;
224 /* Freed in ospf6_delete */
225 o
->name
= XSTRDUP(MTYPE_OSPF6_TOP
, name
);
227 ospf6_vrf_link(o
, vrf
);
229 ospf6_zebra_vrf_register(o
);
232 monotime(&o
->starttime
);
233 o
->area_list
= list_new();
234 o
->area_list
->cmp
= ospf6_area_cmp
;
235 o
->lsdb
= ospf6_lsdb_create(o
);
236 o
->lsdb_self
= ospf6_lsdb_create(o
);
237 o
->lsdb
->hook_add
= ospf6_top_lsdb_hook_add
;
238 o
->lsdb
->hook_remove
= ospf6_top_lsdb_hook_remove
;
240 o
->spf_delay
= OSPF_SPF_DELAY_DEFAULT
;
241 o
->spf_holdtime
= OSPF_SPF_HOLDTIME_DEFAULT
;
242 o
->spf_max_holdtime
= OSPF_SPF_MAX_HOLDTIME_DEFAULT
;
243 o
->spf_hold_multiplier
= 1;
245 /* LSA timers value init */
246 o
->lsa_minarrival
= OSPF_MIN_LS_ARRIVAL
;
248 o
->route_table
= OSPF6_ROUTE_TABLE_CREATE(GLOBAL
, ROUTES
);
249 o
->route_table
->scope
= o
;
250 o
->route_table
->hook_add
= ospf6_top_route_hook_add
;
251 o
->route_table
->hook_remove
= ospf6_top_route_hook_remove
;
253 o
->brouter_table
= OSPF6_ROUTE_TABLE_CREATE(GLOBAL
, BORDER_ROUTERS
);
254 o
->brouter_table
->scope
= o
;
255 o
->brouter_table
->hook_add
= ospf6_top_brouter_hook_add
;
256 o
->brouter_table
->hook_remove
= ospf6_top_brouter_hook_remove
;
258 o
->external_table
= OSPF6_ROUTE_TABLE_CREATE(GLOBAL
, EXTERNAL_ROUTES
);
259 o
->external_table
->scope
= o
;
261 o
->external_id_table
= route_table_init();
263 o
->ref_bandwidth
= OSPF6_REFERENCE_BANDWIDTH
;
265 o
->distance_table
= route_table_init();
270 /* Make ospf protocol socket. */
276 struct ospf6
*ospf6_instance_create(const char *name
)
280 ospf6
= ospf6_create(name
);
281 if (DFLT_OSPF6_LOG_ADJACENCY_CHANGES
)
282 SET_FLAG(ospf6
->config_flags
, OSPF6_LOG_ADJACENCY_CHANGES
);
283 if (ospf6
->router_id
== 0)
284 ospf6_router_id_update(ospf6
);
286 thread_add_read(master
, ospf6_receive
, ospf6
, ospf6
->fd
,
287 &ospf6
->t_ospf6_receive
);
292 void ospf6_delete(struct ospf6
*o
)
294 struct listnode
*node
, *nnode
;
295 struct ospf6_area
*oa
;
299 ospf6_flush_self_originated_lsas_now(o
);
303 for (ALL_LIST_ELEMENTS(o
->area_list
, node
, nnode
, oa
))
304 ospf6_area_delete(oa
);
307 list_delete(&o
->area_list
);
309 ospf6_lsdb_delete(o
->lsdb
);
310 ospf6_lsdb_delete(o
->lsdb_self
);
312 ospf6_route_table_delete(o
->route_table
, o
);
313 ospf6_route_table_delete(o
->brouter_table
, o
);
315 ospf6_route_table_delete(o
->external_table
, o
);
316 route_table_finish(o
->external_id_table
);
318 ospf6_distance_reset(o
);
319 route_table_finish(o
->distance_table
);
321 XFREE(MTYPE_OSPF6_TOP
, o
->name
);
322 XFREE(MTYPE_OSPF6_TOP
, o
);
325 static void ospf6_disable(struct ospf6
*o
)
327 struct listnode
*node
, *nnode
;
328 struct ospf6_area
*oa
;
330 if (!CHECK_FLAG(o
->flag
, OSPF6_DISABLED
)) {
331 SET_FLAG(o
->flag
, OSPF6_DISABLED
);
333 for (ALL_LIST_ELEMENTS(o
->area_list
, node
, nnode
, oa
))
334 ospf6_area_disable(oa
);
336 /* XXX: This also changes persistent settings */
337 ospf6_asbr_redistribute_reset(o
->vrf_id
);
339 ospf6_lsdb_remove_all(o
->lsdb
);
340 ospf6_route_remove_all(o
->route_table
, o
);
341 ospf6_route_remove_all(o
->brouter_table
, o
);
343 THREAD_OFF(o
->maxage_remover
);
344 THREAD_OFF(o
->t_spf_calc
);
345 THREAD_OFF(o
->t_ase_calc
);
346 THREAD_OFF(o
->t_distribute_update
);
347 THREAD_OFF(o
->t_ospf6_receive
);
351 void ospf6_master_init(struct thread_master
*master
)
353 memset(&ospf6_master
, 0, sizeof(struct ospf6_master
));
356 om6
->ospf6
= list_new();
357 om6
->master
= master
;
360 static int ospf6_maxage_remover(struct thread
*thread
)
362 struct ospf6
*o
= (struct ospf6
*)THREAD_ARG(thread
);
363 struct ospf6_area
*oa
;
364 struct ospf6_interface
*oi
;
365 struct ospf6_neighbor
*on
;
366 struct listnode
*i
, *j
, *k
;
369 o
->maxage_remover
= (struct thread
*)NULL
;
371 for (ALL_LIST_ELEMENTS_RO(o
->area_list
, i
, oa
)) {
372 for (ALL_LIST_ELEMENTS_RO(oa
->if_list
, j
, oi
)) {
373 for (ALL_LIST_ELEMENTS_RO(oi
->neighbor_list
, k
, on
)) {
374 if (on
->state
!= OSPF6_NEIGHBOR_EXCHANGE
375 && on
->state
!= OSPF6_NEIGHBOR_LOADING
)
378 ospf6_maxage_remove(o
);
384 for (ALL_LIST_ELEMENTS_RO(o
->area_list
, i
, oa
)) {
385 for (ALL_LIST_ELEMENTS_RO(oa
->if_list
, j
, oi
)) {
386 if (ospf6_lsdb_maxage_remover(oi
->lsdb
)) {
391 if (ospf6_lsdb_maxage_remover(oa
->lsdb
)) {
396 if (ospf6_lsdb_maxage_remover(o
->lsdb
)) {
401 ospf6_maxage_remove(o
);
407 void ospf6_maxage_remove(struct ospf6
*o
)
410 thread_add_timer(master
, ospf6_maxage_remover
, o
,
411 OSPF_LSA_MAXAGE_REMOVE_DELAY_DEFAULT
,
415 void ospf6_router_id_update(struct ospf6
*ospf6
)
420 if (ospf6
->router_id_static
!= 0)
421 ospf6
->router_id
= ospf6
->router_id_static
;
423 ospf6
->router_id
= om6
->zebra_router_id
;
427 DEFUN_NOSH (router_ospf6
,
435 ospf6
= ospf6_lookup_by_vrf_name(VRF_DEFAULT_NAME
);
437 ospf6
= ospf6_instance_create(VRF_DEFAULT_NAME
);
439 /* set current ospf point. */
440 VTY_PUSH_CONTEXT(OSPF6_NODE
, ospf6
);
446 DEFUN (no_router_ospf6
,
455 ospf6
= ospf6_lookup_by_vrf_name(VRF_DEFAULT_NAME
);
457 vty_out(vty
, "OSPFv3 is not configured\n");
459 ospf6_serv_close(&ospf6
->fd
);
464 /* return to config node . */
465 VTY_PUSH_CONTEXT_NULL(CONFIG_NODE
);
470 /* change Router_ID commands. */
471 DEFUN(ospf6_router_id
,
473 "ospf6 router-id A.B.C.D",
475 "Configure OSPF6 Router-ID\n"
478 VTY_DECLVAR_CONTEXT(ospf6
, o
);
481 const char *router_id_str
;
483 struct ospf6_area
*oa
;
484 struct listnode
*node
;
486 argv_find(argv
, argc
, "A.B.C.D", &idx
);
487 router_id_str
= argv
[idx
]->arg
;
489 ret
= inet_pton(AF_INET
, router_id_str
, &router_id
);
491 vty_out(vty
, "malformed OSPF Router-ID: %s\n", router_id_str
);
495 o
->router_id_static
= router_id
;
497 for (ALL_LIST_ELEMENTS_RO(o
->area_list
, node
, oa
)) {
500 "For this router-id change to take effect, save config and restart ospf6d\n");
505 o
->router_id
= router_id
;
510 DEFUN(no_ospf6_router_id
,
511 no_ospf6_router_id_cmd
,
512 "no ospf6 router-id [A.B.C.D]",
514 "Configure OSPF6 Router-ID\n"
517 VTY_DECLVAR_CONTEXT(ospf6
, o
);
518 struct ospf6_area
*oa
;
519 struct listnode
*node
;
521 o
->router_id_static
= 0;
523 for (ALL_LIST_ELEMENTS_RO(o
->area_list
, node
, oa
)) {
526 "For this router-id change to take effect, save config and restart ospf6d\n");
531 if (o
->router_id_zebra
.s_addr
)
532 o
->router_id
= (uint32_t)o
->router_id_zebra
.s_addr
;
537 DEFUN (ospf6_log_adjacency_changes
,
538 ospf6_log_adjacency_changes_cmd
,
539 "log-adjacency-changes",
540 "Log changes in adjacency state\n")
542 VTY_DECLVAR_CONTEXT(ospf6
, ospf6
);
544 SET_FLAG(ospf6
->config_flags
, OSPF6_LOG_ADJACENCY_CHANGES
);
545 UNSET_FLAG(ospf6
->config_flags
, OSPF6_LOG_ADJACENCY_DETAIL
);
549 DEFUN (ospf6_log_adjacency_changes_detail
,
550 ospf6_log_adjacency_changes_detail_cmd
,
551 "log-adjacency-changes detail",
552 "Log changes in adjacency state\n"
553 "Log all state changes\n")
555 VTY_DECLVAR_CONTEXT(ospf6
, ospf6
);
557 SET_FLAG(ospf6
->config_flags
, OSPF6_LOG_ADJACENCY_CHANGES
);
558 SET_FLAG(ospf6
->config_flags
, OSPF6_LOG_ADJACENCY_DETAIL
);
562 DEFUN (no_ospf6_log_adjacency_changes
,
563 no_ospf6_log_adjacency_changes_cmd
,
564 "no log-adjacency-changes",
566 "Log changes in adjacency state\n")
568 VTY_DECLVAR_CONTEXT(ospf6
, ospf6
);
570 UNSET_FLAG(ospf6
->config_flags
, OSPF6_LOG_ADJACENCY_DETAIL
);
571 UNSET_FLAG(ospf6
->config_flags
, OSPF6_LOG_ADJACENCY_CHANGES
);
575 DEFUN (no_ospf6_log_adjacency_changes_detail
,
576 no_ospf6_log_adjacency_changes_detail_cmd
,
577 "no log-adjacency-changes detail",
579 "Log changes in adjacency state\n"
580 "Log all state changes\n")
582 VTY_DECLVAR_CONTEXT(ospf6
, ospf6
);
584 UNSET_FLAG(ospf6
->config_flags
, OSPF6_LOG_ADJACENCY_DETAIL
);
588 DEFUN (ospf6_timers_lsa
,
589 ospf6_timers_lsa_cmd
,
590 "timers lsa min-arrival (0-600000)",
591 "Adjust routing timers\n"
593 "Minimum delay in receiving new version of a LSA\n"
594 "Delay in milliseconds\n")
596 VTY_DECLVAR_CONTEXT(ospf6
, ospf
);
598 unsigned int minarrival
;
600 minarrival
= strtoul(argv
[idx_number
]->arg
, NULL
, 10);
601 ospf
->lsa_minarrival
= minarrival
;
606 DEFUN (no_ospf6_timers_lsa
,
607 no_ospf6_timers_lsa_cmd
,
608 "no timers lsa min-arrival [(0-600000)]",
610 "Adjust routing timers\n"
612 "Minimum delay in receiving new version of a LSA\n"
613 "Delay in milliseconds\n")
615 VTY_DECLVAR_CONTEXT(ospf6
, ospf
);
617 unsigned int minarrival
;
620 minarrival
= strtoul(argv
[idx_number
]->arg
, NULL
, 10);
622 if (ospf
->lsa_minarrival
!= minarrival
623 || minarrival
== OSPF_MIN_LS_ARRIVAL
)
627 ospf
->lsa_minarrival
= OSPF_MIN_LS_ARRIVAL
;
633 DEFUN (ospf6_distance
,
636 "Administrative distance\n"
637 "OSPF6 Administrative distance\n")
639 VTY_DECLVAR_CONTEXT(ospf6
, o
);
641 o
->distance_all
= atoi(argv
[1]->arg
);
646 DEFUN (no_ospf6_distance
,
647 no_ospf6_distance_cmd
,
648 "no distance (1-255)",
650 "Administrative distance\n"
651 "OSPF6 Administrative distance\n")
653 VTY_DECLVAR_CONTEXT(ospf6
, o
);
660 DEFUN (ospf6_distance_ospf6
,
661 ospf6_distance_ospf6_cmd
,
662 "distance ospf6 {intra-area (1-255)|inter-area (1-255)|external (1-255)}",
663 "Administrative distance\n"
664 "OSPF6 administrative distance\n"
665 "Intra-area routes\n"
666 "Distance for intra-area routes\n"
667 "Inter-area routes\n"
668 "Distance for inter-area routes\n"
670 "Distance for external routes\n")
672 VTY_DECLVAR_CONTEXT(ospf6
, o
);
675 o
->distance_intra
= 0;
676 o
->distance_inter
= 0;
677 o
->distance_external
= 0;
679 if (argv_find(argv
, argc
, "intra-area", &idx
))
680 o
->distance_intra
= atoi(argv
[idx
+ 1]->arg
);
682 if (argv_find(argv
, argc
, "inter-area", &idx
))
683 o
->distance_inter
= atoi(argv
[idx
+ 1]->arg
);
685 if (argv_find(argv
, argc
, "external", &idx
))
686 o
->distance_external
= atoi(argv
[idx
+ 1]->arg
);
691 DEFUN (no_ospf6_distance_ospf6
,
692 no_ospf6_distance_ospf6_cmd
,
693 "no distance ospf6 [{intra-area [(1-255)]|inter-area [(1-255)]|external [(1-255)]}]",
695 "Administrative distance\n"
697 "Intra-area routes\n"
698 "Distance for intra-area routes\n"
699 "Inter-area routes\n"
700 "Distance for inter-area routes\n"
702 "Distance for external routes\n")
704 VTY_DECLVAR_CONTEXT(ospf6
, o
);
707 if (argv_find(argv
, argc
, "intra-area", &idx
) || argc
== 3)
708 idx
= o
->distance_intra
= 0;
709 if (argv_find(argv
, argc
, "inter-area", &idx
) || argc
== 3)
710 idx
= o
->distance_inter
= 0;
711 if (argv_find(argv
, argc
, "external", &idx
) || argc
== 3)
712 o
->distance_external
= 0;
718 DEFUN (ospf6_distance_source
,
719 ospf6_distance_source_cmd
,
720 "distance (1-255) X:X::X:X/M [WORD]",
721 "Administrative distance\n"
724 "Access list name\n")
726 VTY_DECLVAR_CONTEXT(ospf6
, o
);
727 char *alname
= (argc
== 4) ? argv
[3]->arg
: NULL
;
728 ospf6_distance_set (vty
, o
, argv
[1]->arg
, argv
[2]->arg
, alname
);
733 DEFUN (no_ospf6_distance_source
,
734 no_ospf6_distance_source_cmd
,
735 "no distance (1-255) X:X::X:X/M [WORD]",
737 "Administrative distance\n"
740 "Access list name\n")
742 VTY_DECLVAR_CONTEXT(ospf6
, o
);
743 char *alname
= (argc
== 5) ? argv
[4]->arg
: NULL
;
744 ospf6_distance_unset (vty
, o
, argv
[2]->arg
, argv
[3]->arg
, alname
);
750 DEFUN (ospf6_interface_area
,
751 ospf6_interface_area_cmd
,
752 "interface IFNAME area <A.B.C.D|(0-4294967295)>",
753 "Enable routing on an IPv6 interface\n"
755 "Specify the OSPF6 area ID\n"
756 "OSPF6 area ID in IPv4 address notation\n"
757 "OSPF6 area ID in decimal notation\n"
762 struct ospf6_area
*oa
;
763 struct ospf6_interface
*oi
;
764 struct interface
*ifp
;
766 VTY_DECLVAR_CONTEXT(ospf6
, ospf6
);
768 /* find/create ospf6 interface */
769 ifp
= if_get_by_name(argv
[idx_ifname
]->arg
, VRF_DEFAULT
);
770 oi
= (struct ospf6_interface
*)ifp
->info
;
772 oi
= ospf6_interface_create(ifp
);
774 vty_out(vty
, "%s already attached to Area %s\n",
775 oi
->interface
->name
, oi
->area
->name
);
780 OSPF6_CMD_AREA_GET(argv
[idx_ipv4
]->arg
, oa
, ospf6
);
782 /* attach interface to area */
783 listnode_add(oa
->if_list
, oi
); /* sort ?? */
786 SET_FLAG(oa
->flag
, OSPF6_AREA_ENABLE
);
788 /* ospf6 process is currently disabled, not much more to do */
789 if (CHECK_FLAG(ospf6
->flag
, OSPF6_DISABLED
))
793 ospf6_interface_enable(oi
);
795 /* If the router is ABR, originate summary routes */
796 if (ospf6_is_router_abr(ospf6
))
797 ospf6_abr_enable_area(oa
);
802 DEFUN (no_ospf6_interface_area
,
803 no_ospf6_interface_area_cmd
,
804 "no interface IFNAME area <A.B.C.D|(0-4294967295)>",
806 "Disable routing on an IPv6 interface\n"
808 "Specify the OSPF6 area ID\n"
809 "OSPF6 area ID in IPv4 address notation\n"
810 "OSPF6 area ID in decimal notation\n"
815 struct ospf6_interface
*oi
;
816 struct ospf6_area
*oa
;
817 struct interface
*ifp
;
820 ifp
= if_lookup_by_name(argv
[idx_ifname
]->arg
, VRF_DEFAULT
);
822 vty_out(vty
, "No such interface %s\n", argv
[idx_ifname
]->arg
);
826 oi
= (struct ospf6_interface
*)ifp
->info
;
828 vty_out(vty
, "Interface %s not enabled\n", ifp
->name
);
833 if (inet_pton(AF_INET
, argv
[idx_ipv4
]->arg
, &area_id
) != 1)
834 area_id
= htonl(strtoul(argv
[idx_ipv4
]->arg
, NULL
, 10));
837 if (oi
->area
== NULL
) {
838 vty_out(vty
, "No such Area-ID: %s\n", argv
[idx_ipv4
]->arg
);
842 if (oi
->area
->area_id
!= area_id
) {
843 vty_out(vty
, "Wrong Area-ID: %s is attached to area %s\n",
844 oi
->interface
->name
, oi
->area
->name
);
848 thread_execute(master
, interface_down
, oi
, 0);
851 listnode_delete(oi
->area
->if_list
, oi
);
852 oi
->area
= (struct ospf6_area
*)NULL
;
854 /* Withdraw inter-area routes from this area, if necessary */
855 if (oa
->if_list
->count
== 0) {
856 UNSET_FLAG(oa
->flag
, OSPF6_AREA_ENABLE
);
857 ospf6_abr_disable_area(oa
);
863 DEFUN (ospf6_stub_router_admin
,
864 ospf6_stub_router_admin_cmd
,
865 "stub-router administrative",
866 "Make router a stub router\n"
867 "Administratively applied, for an indefinite period\n")
869 struct listnode
*node
;
870 struct ospf6_area
*oa
;
872 VTY_DECLVAR_CONTEXT(ospf6
, ospf6
);
874 if (!CHECK_FLAG(ospf6
->flag
, OSPF6_STUB_ROUTER
)) {
875 for (ALL_LIST_ELEMENTS_RO(ospf6
->area_list
, node
, oa
)) {
876 OSPF6_OPT_CLEAR(oa
->options
, OSPF6_OPT_V6
);
877 OSPF6_OPT_CLEAR(oa
->options
, OSPF6_OPT_R
);
878 OSPF6_ROUTER_LSA_SCHEDULE(oa
);
880 SET_FLAG(ospf6
->flag
, OSPF6_STUB_ROUTER
);
886 DEFUN (no_ospf6_stub_router_admin
,
887 no_ospf6_stub_router_admin_cmd
,
888 "no stub-router administrative",
890 "Make router a stub router\n"
891 "Administratively applied, for an indefinite period\n")
893 struct listnode
*node
;
894 struct ospf6_area
*oa
;
896 VTY_DECLVAR_CONTEXT(ospf6
, ospf6
);
897 if (CHECK_FLAG(ospf6
->flag
, OSPF6_STUB_ROUTER
)) {
898 for (ALL_LIST_ELEMENTS_RO(ospf6
->area_list
, node
, oa
)) {
899 OSPF6_OPT_SET(oa
->options
, OSPF6_OPT_V6
);
900 OSPF6_OPT_SET(oa
->options
, OSPF6_OPT_R
);
901 OSPF6_ROUTER_LSA_SCHEDULE(oa
);
903 UNSET_FLAG(ospf6
->flag
, OSPF6_STUB_ROUTER
);
910 DEFUN (ospf6_stub_router_startup
,
911 ospf6_stub_router_startup_cmd
,
912 "stub-router on-startup (5-86400)",
913 "Make router a stub router\n"
914 "Advertise inability to be a transit router\n"
915 "Automatically advertise as stub-router on startup of OSPF6\n"
916 "Time (seconds) to advertise self as stub-router\n")
921 DEFUN (no_ospf6_stub_router_startup
,
922 no_ospf6_stub_router_startup_cmd
,
923 "no stub-router on-startup",
925 "Make router a stub router\n"
926 "Advertise inability to be a transit router\n"
927 "Automatically advertise as stub-router on startup of OSPF6\n"
928 "Time (seconds) to advertise self as stub-router\n")
933 DEFUN (ospf6_stub_router_shutdown
,
934 ospf6_stub_router_shutdown_cmd
,
935 "stub-router on-shutdown (5-86400)",
936 "Make router a stub router\n"
937 "Advertise inability to be a transit router\n"
938 "Automatically advertise as stub-router before shutdown\n"
939 "Time (seconds) to advertise self as stub-router\n")
944 DEFUN (no_ospf6_stub_router_shutdown
,
945 no_ospf6_stub_router_shutdown_cmd
,
946 "no stub-router on-shutdown",
948 "Make router a stub router\n"
949 "Advertise inability to be a transit router\n"
950 "Automatically advertise as stub-router before shutdown\n"
951 "Time (seconds) to advertise self as stub-router\n")
957 static void ospf6_show(struct vty
*vty
, struct ospf6
*o
)
960 struct ospf6_area
*oa
;
961 char router_id
[16], duration
[32];
962 struct timeval now
, running
, result
;
963 char buf
[32], rbuf
[32];
965 /* process id, router id */
966 inet_ntop(AF_INET
, &o
->router_id
, router_id
, sizeof(router_id
));
967 vty_out(vty
, " OSPFv3 Routing Process (0) with Router-ID %s\n",
972 timersub(&now
, &o
->starttime
, &running
);
973 timerstring(&running
, duration
, sizeof(duration
));
974 vty_out(vty
, " Running %s\n", duration
);
976 /* Redistribute configuration */
979 vty_out(vty
, " LSA minimum arrival %d msecs\n", o
->lsa_minarrival
);
981 /* Show SPF parameters */
983 " Initial SPF scheduling delay %d millisec(s)\n"
984 " Minimum hold time between consecutive SPFs %d millsecond(s)\n"
985 " Maximum hold time between consecutive SPFs %d millsecond(s)\n"
986 " Hold time multiplier is currently %d\n",
987 o
->spf_delay
, o
->spf_holdtime
, o
->spf_max_holdtime
,
988 o
->spf_hold_multiplier
);
990 vty_out(vty
, " SPF algorithm ");
991 if (o
->ts_spf
.tv_sec
|| o
->ts_spf
.tv_usec
) {
992 timersub(&now
, &o
->ts_spf
, &result
);
993 timerstring(&result
, buf
, sizeof(buf
));
994 ospf6_spf_reason_string(o
->last_spf_reason
, rbuf
, sizeof(rbuf
));
995 vty_out(vty
, "last executed %s ago, reason %s\n", buf
, rbuf
);
996 vty_out(vty
, " Last SPF duration %lld sec %lld usec\n",
997 (long long)o
->ts_spf_duration
.tv_sec
,
998 (long long)o
->ts_spf_duration
.tv_usec
);
1000 vty_out(vty
, "has not been run\n");
1001 threadtimer_string(now
, o
->t_spf_calc
, buf
, sizeof(buf
));
1002 vty_out(vty
, " SPF timer %s%s\n", (o
->t_spf_calc
? "due in " : "is "),
1005 if (CHECK_FLAG(o
->flag
, OSPF6_STUB_ROUTER
))
1006 vty_out(vty
, " Router Is Stub Router\n");
1009 vty_out(vty
, " Number of AS scoped LSAs is %u\n", o
->lsdb
->count
);
1012 vty_out(vty
, " Number of areas in this router is %u\n",
1013 listcount(o
->area_list
));
1015 if (CHECK_FLAG(o
->config_flags
, OSPF6_LOG_ADJACENCY_CHANGES
)) {
1016 if (CHECK_FLAG(o
->config_flags
, OSPF6_LOG_ADJACENCY_DETAIL
))
1017 vty_out(vty
, " All adjacency changes are logged\n");
1019 vty_out(vty
, " Adjacency changes are logged\n");
1024 for (ALL_LIST_ELEMENTS_RO(o
->area_list
, n
, oa
))
1025 ospf6_area_show(vty
, oa
);
1028 /* show top level structures */
1029 DEFUN (show_ipv6_ospf6
,
1030 show_ipv6_ospf6_cmd
,
1036 struct ospf6
*ospf6
;
1038 ospf6
= ospf6_lookup_by_vrf_name(VRF_DEFAULT_NAME
);
1039 OSPF6_CMD_CHECK_RUNNING(ospf6
);
1040 ospf6_show(vty
, ospf6
);
1044 DEFUN (show_ipv6_ospf6_route
,
1045 show_ipv6_ospf6_route_cmd
,
1046 "show ipv6 ospf6 route [<intra-area|inter-area|external-1|external-2|X:X::X:X|X:X::X:X/M|detail|summary>]",
1051 "Display Intra-Area routes\n"
1052 "Display Inter-Area routes\n"
1053 "Display Type-1 External routes\n"
1054 "Display Type-2 External routes\n"
1055 "Specify IPv6 address\n"
1056 "Specify IPv6 prefix\n"
1057 "Detailed information\n"
1058 "Summary of route table\n")
1060 struct ospf6
*ospf6
;
1062 ospf6
= ospf6_lookup_by_vrf_name(VRF_DEFAULT_NAME
);
1063 OSPF6_CMD_CHECK_RUNNING(ospf6
);
1065 ospf6_route_table_show(vty
, 4, argc
, argv
, ospf6
->route_table
);
1069 DEFUN (show_ipv6_ospf6_route_match
,
1070 show_ipv6_ospf6_route_match_cmd
,
1071 "show ipv6 ospf6 route X:X::X:X/M <match|longer>",
1076 "Specify IPv6 prefix\n"
1077 "Display routes which match the specified route\n"
1078 "Display routes longer than the specified route\n")
1080 struct ospf6
*ospf6
;
1082 ospf6
= ospf6_lookup_by_vrf_name(VRF_DEFAULT_NAME
);
1083 OSPF6_CMD_CHECK_RUNNING(ospf6
);
1085 ospf6_route_table_show(vty
, 4, argc
, argv
, ospf6
->route_table
);
1090 DEFUN (show_ipv6_ospf6_route_match_detail
,
1091 show_ipv6_ospf6_route_match_detail_cmd
,
1092 "show ipv6 ospf6 route X:X::X:X/M match detail",
1097 "Specify IPv6 prefix\n"
1098 "Display routes which match the specified route\n"
1099 "Detailed information\n"
1102 struct ospf6
*ospf6
;
1104 ospf6
= ospf6_lookup_by_vrf_name(VRF_DEFAULT_NAME
);
1105 OSPF6_CMD_CHECK_RUNNING(ospf6
);
1107 ospf6_route_table_show(vty
, 4, argc
, argv
, ospf6
->route_table
);
1112 DEFUN (show_ipv6_ospf6_route_type_detail
,
1113 show_ipv6_ospf6_route_type_detail_cmd
,
1114 "show ipv6 ospf6 route <intra-area|inter-area|external-1|external-2> detail",
1119 "Display Intra-Area routes\n"
1120 "Display Inter-Area routes\n"
1121 "Display Type-1 External routes\n"
1122 "Display Type-2 External routes\n"
1123 "Detailed information\n"
1126 struct ospf6
*ospf6
;
1128 ospf6
= ospf6_lookup_by_vrf_name(VRF_DEFAULT_NAME
);
1129 OSPF6_CMD_CHECK_RUNNING(ospf6
);
1131 ospf6_route_table_show(vty
, 4, argc
, argv
, ospf6
->route_table
);
1135 static void ospf6_stub_router_config_write(struct vty
*vty
, struct ospf6
*ospf6
)
1137 if (CHECK_FLAG(ospf6
->flag
, OSPF6_STUB_ROUTER
)) {
1138 vty_out(vty
, " stub-router administrative\n");
1143 static int ospf6_distance_config_write(struct vty
*vty
, struct ospf6
*ospf6
)
1145 struct route_node
*rn
;
1146 struct ospf6_distance
*odistance
;
1148 if (ospf6
->distance_all
)
1149 vty_out(vty
, " distance %u\n", ospf6
->distance_all
);
1151 if (ospf6
->distance_intra
|| ospf6
->distance_inter
1152 || ospf6
->distance_external
) {
1153 vty_out(vty
, " distance ospf6");
1155 if (ospf6
->distance_intra
)
1156 vty_out(vty
, " intra-area %u", ospf6
->distance_intra
);
1157 if (ospf6
->distance_inter
)
1158 vty_out(vty
, " inter-area %u", ospf6
->distance_inter
);
1159 if (ospf6
->distance_external
)
1160 vty_out(vty
, " external %u", ospf6
->distance_external
);
1165 for (rn
= route_top(ospf6
->distance_table
); rn
; rn
= route_next(rn
))
1166 if ((odistance
= rn
->info
) != NULL
)
1167 vty_out(vty
, " distance %u %pFX %s\n",
1168 odistance
->distance
, &rn
->p
,
1169 odistance
->access_list
? odistance
->access_list
1174 /* OSPF configuration write function. */
1175 static int config_write_ospf6(struct vty
*vty
)
1177 struct listnode
*j
, *k
;
1178 struct ospf6_area
*oa
;
1179 struct ospf6_interface
*oi
;
1180 struct ospf6
*ospf6
;
1181 struct listnode
*node
, *nnode
;
1183 /* OSPFv3 configuration. */
1187 for (ALL_LIST_ELEMENTS(om6
->ospf6
, node
, nnode
, ospf6
)) {
1188 vty_out(vty
, "router ospf6\n");
1189 if (ospf6
->router_id_static
!= 0)
1190 vty_out(vty
, " ospf6 router-id %pI4\n",
1191 &ospf6
->router_id_static
);
1193 /* log-adjacency-changes flag print. */
1194 if (CHECK_FLAG(ospf6
->config_flags
,
1195 OSPF6_LOG_ADJACENCY_CHANGES
)) {
1196 if (CHECK_FLAG(ospf6
->config_flags
,
1197 OSPF6_LOG_ADJACENCY_DETAIL
))
1198 vty_out(vty
, " log-adjacency-changes detail\n");
1199 else if (!SAVE_OSPF6_LOG_ADJACENCY_CHANGES
)
1200 vty_out(vty
, " log-adjacency-changes\n");
1201 } else if (SAVE_OSPF6_LOG_ADJACENCY_CHANGES
) {
1202 vty_out(vty
, " no log-adjacency-changes\n");
1205 if (ospf6
->ref_bandwidth
!= OSPF6_REFERENCE_BANDWIDTH
)
1206 vty_out(vty
, " auto-cost reference-bandwidth %d\n",
1207 ospf6
->ref_bandwidth
);
1209 /* LSA timers print. */
1210 if (ospf6
->lsa_minarrival
!= OSPF_MIN_LS_ARRIVAL
)
1211 vty_out(vty
, " timers lsa min-arrival %d\n",
1212 ospf6
->lsa_minarrival
);
1214 ospf6_stub_router_config_write(vty
, ospf6
);
1215 ospf6_redistribute_config_write(vty
, ospf6
);
1216 ospf6_area_config_write(vty
, ospf6
);
1217 ospf6_spf_config_write(vty
, ospf6
);
1218 ospf6_distance_config_write(vty
, ospf6
);
1220 for (ALL_LIST_ELEMENTS_RO(ospf6
->area_list
, j
, oa
)) {
1221 for (ALL_LIST_ELEMENTS_RO(oa
->if_list
, k
, oi
))
1222 vty_out(vty
, " interface %s area %s\n",
1223 oi
->interface
->name
, oa
->name
);
1225 vty_out(vty
, "!\n");
1230 static int config_write_ospf6(struct vty
*vty
);
1231 /* OSPF6 node structure. */
1232 static struct cmd_node ospf6_node
= {
1235 .parent_node
= CONFIG_NODE
,
1236 .prompt
= "%s(config-ospf6)# ",
1237 .config_write
= config_write_ospf6
,
1240 /* Install ospf related commands. */
1241 void ospf6_top_init(void)
1243 /* Install ospf6 top node. */
1244 install_node(&ospf6_node
);
1246 install_element(VIEW_NODE
, &show_ipv6_ospf6_cmd
);
1247 install_element(CONFIG_NODE
, &router_ospf6_cmd
);
1248 install_element(CONFIG_NODE
, &no_router_ospf6_cmd
);
1250 install_element(VIEW_NODE
, &show_ipv6_ospf6_route_cmd
);
1251 install_element(VIEW_NODE
, &show_ipv6_ospf6_route_match_cmd
);
1252 install_element(VIEW_NODE
, &show_ipv6_ospf6_route_match_detail_cmd
);
1253 install_element(VIEW_NODE
, &show_ipv6_ospf6_route_type_detail_cmd
);
1255 install_default(OSPF6_NODE
);
1256 install_element(OSPF6_NODE
, &ospf6_router_id_cmd
);
1257 install_element(OSPF6_NODE
, &no_ospf6_router_id_cmd
);
1258 install_element(OSPF6_NODE
, &ospf6_log_adjacency_changes_cmd
);
1259 install_element(OSPF6_NODE
, &ospf6_log_adjacency_changes_detail_cmd
);
1260 install_element(OSPF6_NODE
, &no_ospf6_log_adjacency_changes_cmd
);
1261 install_element(OSPF6_NODE
, &no_ospf6_log_adjacency_changes_detail_cmd
);
1263 /* LSA timers commands */
1264 install_element(OSPF6_NODE
, &ospf6_timers_lsa_cmd
);
1265 install_element(OSPF6_NODE
, &no_ospf6_timers_lsa_cmd
);
1267 install_element(OSPF6_NODE
, &ospf6_interface_area_cmd
);
1268 install_element(OSPF6_NODE
, &no_ospf6_interface_area_cmd
);
1269 install_element(OSPF6_NODE
, &ospf6_stub_router_admin_cmd
);
1270 install_element(OSPF6_NODE
, &no_ospf6_stub_router_admin_cmd
);
1271 /* For a later time */
1273 install_element (OSPF6_NODE
, &ospf6_stub_router_startup_cmd
);
1274 install_element (OSPF6_NODE
, &no_ospf6_stub_router_startup_cmd
);
1275 install_element (OSPF6_NODE
, &ospf6_stub_router_shutdown_cmd
);
1276 install_element (OSPF6_NODE
, &no_ospf6_stub_router_shutdown_cmd
);
1279 install_element(OSPF6_NODE
, &ospf6_distance_cmd
);
1280 install_element(OSPF6_NODE
, &no_ospf6_distance_cmd
);
1281 install_element(OSPF6_NODE
, &ospf6_distance_ospf6_cmd
);
1282 install_element(OSPF6_NODE
, &no_ospf6_distance_ospf6_cmd
);
1284 install_element (OSPF6_NODE
, &ospf6_distance_source_cmd
);
1285 install_element (OSPF6_NODE
, &no_ospf6_distance_source_cmd
);