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 "lib_errors.h"
35 #include "ospf6_proto.h"
36 #include "ospf6_message.h"
37 #include "ospf6_lsa.h"
38 #include "ospf6_lsdb.h"
39 #include "ospf6_route.h"
40 #include "ospf6_zebra.h"
42 #include "ospf6_top.h"
43 #include "ospf6_area.h"
44 #include "ospf6_interface.h"
45 #include "ospf6_neighbor.h"
46 #include "ospf6_network.h"
48 #include "ospf6_flood.h"
49 #include "ospf6_asbr.h"
50 #include "ospf6_abr.h"
51 #include "ospf6_intra.h"
52 #include "ospf6_spf.h"
55 #include "ospf6_nssa.h"
57 DEFINE_MTYPE_STATIC(OSPF6D
, OSPF6_TOP
, "OSPF6 top");
59 DEFINE_QOBJ_TYPE(ospf6
);
61 FRR_CFG_DEFAULT_BOOL(OSPF6_LOG_ADJACENCY_CHANGES
,
62 { .val_bool
= true, .match_profile
= "datacenter", },
63 { .val_bool
= false },
66 #ifndef VTYSH_EXTRACT_PL
67 #include "ospf6d/ospf6_top_clippy.c"
70 /* global ospf6d variable */
71 static struct ospf6_master ospf6_master
;
72 struct ospf6_master
*om6
;
74 static void ospf6_disable(struct ospf6
*o
);
76 static void ospf6_add(struct ospf6
*ospf6
)
78 listnode_add(om6
->ospf6
, ospf6
);
81 static void ospf6_del(struct ospf6
*ospf6
)
83 listnode_delete(om6
->ospf6
, ospf6
);
86 const char *ospf6_vrf_id_to_name(vrf_id_t vrf_id
)
88 struct vrf
*vrf
= vrf_lookup_by_id(vrf_id
);
90 return vrf
? vrf
->name
: "NIL";
93 /* Link OSPF instance to VRF. */
94 void ospf6_vrf_link(struct ospf6
*ospf6
, struct vrf
*vrf
)
96 ospf6
->vrf_id
= vrf
->vrf_id
;
97 if (vrf
->info
!= (void *)ospf6
)
98 vrf
->info
= (void *)ospf6
;
101 /* Unlink OSPF instance from VRF. */
102 void ospf6_vrf_unlink(struct ospf6
*ospf6
, struct vrf
*vrf
)
104 if (vrf
->info
== (void *)ospf6
)
106 ospf6
->vrf_id
= VRF_UNKNOWN
;
109 struct ospf6
*ospf6_lookup_by_vrf_id(vrf_id_t vrf_id
)
111 struct vrf
*vrf
= NULL
;
113 vrf
= vrf_lookup_by_id(vrf_id
);
116 return (vrf
->info
) ? (struct ospf6
*)vrf
->info
: NULL
;
119 struct ospf6
*ospf6_lookup_by_vrf_name(const char *name
)
121 struct ospf6
*o
= NULL
;
122 struct listnode
*node
, *nnode
;
124 for (ALL_LIST_ELEMENTS(om6
->ospf6
, node
, nnode
, o
)) {
125 if (((o
->name
== NULL
&& name
== NULL
)
126 || (o
->name
&& name
&& strcmp(o
->name
, name
) == 0)))
132 /* This is hook function for vrf create called as part of vrf_init */
133 static int ospf6_vrf_new(struct vrf
*vrf
)
138 /* This is hook function for vrf delete call as part of vrf_init */
139 static int ospf6_vrf_delete(struct vrf
*vrf
)
144 static void ospf6_set_redist_vrf_bitmaps(struct ospf6
*ospf6
, bool set
)
147 struct list
*red_list
;
149 for (type
= 0; type
< ZEBRA_ROUTE_MAX
; type
++) {
150 red_list
= ospf6
->redist
[type
];
153 if (IS_OSPF6_DEBUG_ZEBRA(RECV
))
155 "%s: setting redist vrf %d bitmap for type %d",
156 __func__
, ospf6
->vrf_id
, type
);
158 vrf_bitmap_set(zclient
->redist
[AFI_IP6
][type
],
161 vrf_bitmap_unset(zclient
->redist
[AFI_IP6
][type
],
165 red_list
= ospf6
->redist
[DEFAULT_ROUTE
];
168 vrf_bitmap_set(zclient
->default_information
[AFI_IP6
],
171 vrf_bitmap_unset(zclient
->default_information
[AFI_IP6
],
176 /* Disable OSPF6 VRF instance */
177 static int ospf6_vrf_disable(struct vrf
*vrf
)
179 struct ospf6
*ospf6
= NULL
;
181 if (vrf
->vrf_id
== VRF_DEFAULT
)
184 ospf6
= ospf6_lookup_by_vrf_name(vrf
->name
);
186 ospf6_zebra_vrf_deregister(ospf6
);
188 ospf6_set_redist_vrf_bitmaps(ospf6
, false);
190 /* We have instance configured, unlink
191 * from VRF and make it "down".
193 ospf6_vrf_unlink(ospf6
, vrf
);
194 thread_cancel(&ospf6
->t_ospf6_receive
);
199 /* Note: This is a callback, the VRF will be deleted by the caller. */
203 /* Enable OSPF6 VRF instance */
204 static int ospf6_vrf_enable(struct vrf
*vrf
)
206 struct ospf6
*ospf6
= NULL
;
210 ospf6
= ospf6_lookup_by_vrf_name(vrf
->name
);
212 old_vrf_id
= ospf6
->vrf_id
;
213 /* We have instance configured, link to VRF and make it "up". */
214 ospf6_vrf_link(ospf6
, vrf
);
216 if (old_vrf_id
!= ospf6
->vrf_id
) {
217 ospf6_set_redist_vrf_bitmaps(ospf6
, true);
219 /* start zebra redist to us for new vrf */
220 ospf6_zebra_vrf_register(ospf6
);
222 ret
= ospf6_serv_sock(ospf6
);
223 if (ret
< 0 || ospf6
->fd
<= 0)
225 thread_add_read(master
, ospf6_receive
, ospf6
, ospf6
->fd
,
226 &ospf6
->t_ospf6_receive
);
228 ospf6_router_id_update(ospf6
);
235 void ospf6_vrf_init(void)
237 vrf_init(ospf6_vrf_new
, ospf6_vrf_enable
, ospf6_vrf_disable
,
238 ospf6_vrf_delete
, ospf6_vrf_enable
);
240 vrf_cmd_init(NULL
, &ospf6d_privs
);
243 static void ospf6_top_lsdb_hook_add(struct ospf6_lsa
*lsa
)
245 switch (ntohs(lsa
->header
->type
)) {
246 case OSPF6_LSTYPE_AS_EXTERNAL
:
247 ospf6_asbr_lsa_add(lsa
);
255 static void ospf6_top_lsdb_hook_remove(struct ospf6_lsa
*lsa
)
257 switch (ntohs(lsa
->header
->type
)) {
258 case OSPF6_LSTYPE_AS_EXTERNAL
:
259 ospf6_asbr_lsa_remove(lsa
, NULL
);
267 static void ospf6_top_route_hook_add(struct ospf6_route
*route
)
269 struct ospf6
*ospf6
= NULL
;
270 struct ospf6_area
*oa
= NULL
;
272 if (route
->table
->scope_type
== OSPF6_SCOPE_TYPE_GLOBAL
)
273 ospf6
= route
->table
->scope
;
274 else if (route
->table
->scope_type
== OSPF6_SCOPE_TYPE_AREA
) {
275 oa
= (struct ospf6_area
*)route
->table
->scope
;
278 if (IS_OSPF6_DEBUG_EXAMIN(AS_EXTERNAL
)
279 || IS_OSPF6_DEBUG_BROUTER
)
281 "%s: Route is not GLOBAL or scope is not of TYPE_AREA: %pFX",
282 __func__
, &route
->prefix
);
286 ospf6_abr_originate_summary(route
, ospf6
);
287 ospf6_zebra_route_update_add(route
, ospf6
);
290 static void ospf6_top_route_hook_remove(struct ospf6_route
*route
)
292 struct ospf6
*ospf6
= NULL
;
293 struct ospf6_area
*oa
= NULL
;
295 if (route
->table
->scope_type
== OSPF6_SCOPE_TYPE_GLOBAL
)
296 ospf6
= route
->table
->scope
;
297 else if (route
->table
->scope_type
== OSPF6_SCOPE_TYPE_AREA
) {
298 oa
= (struct ospf6_area
*)route
->table
->scope
;
301 if (IS_OSPF6_DEBUG_EXAMIN(AS_EXTERNAL
)
302 || IS_OSPF6_DEBUG_BROUTER
)
304 "%s: Route is not GLOBAL or scope is not of TYPE_AREA: %pFX",
305 __func__
, &route
->prefix
);
309 route
->flag
|= OSPF6_ROUTE_REMOVE
;
310 ospf6_abr_originate_summary(route
, ospf6
);
311 ospf6_zebra_route_update_remove(route
, ospf6
);
314 static void ospf6_top_brouter_hook_add(struct ospf6_route
*route
)
316 struct ospf6
*ospf6
= route
->table
->scope
;
318 if (IS_OSPF6_DEBUG_EXAMIN(AS_EXTERNAL
) ||
319 IS_OSPF6_DEBUG_BROUTER
) {
321 char brouter_name
[16];
323 brouter_id
= ADV_ROUTER_IN_PREFIX(&route
->prefix
);
324 inet_ntop(AF_INET
, &brouter_id
, brouter_name
,
325 sizeof(brouter_name
));
326 zlog_debug("%s: brouter %s add with adv router %x nh count %u",
327 __func__
, brouter_name
,
328 route
->path
.origin
.adv_router
,
329 listcount(route
->nh_list
));
331 ospf6_abr_examin_brouter(ADV_ROUTER_IN_PREFIX(&route
->prefix
), route
,
333 ospf6_asbr_lsentry_add(route
, ospf6
);
334 ospf6_abr_originate_summary(route
, ospf6
);
337 static void ospf6_top_brouter_hook_remove(struct ospf6_route
*route
)
339 struct ospf6
*ospf6
= route
->table
->scope
;
341 if (IS_OSPF6_DEBUG_EXAMIN(AS_EXTERNAL
) ||
342 IS_OSPF6_DEBUG_BROUTER
) {
344 char brouter_name
[16];
346 brouter_id
= ADV_ROUTER_IN_PREFIX(&route
->prefix
);
347 inet_ntop(AF_INET
, &brouter_id
, brouter_name
,
348 sizeof(brouter_name
));
349 zlog_debug("%s: brouter %p %s del with adv router %x nh %u",
350 __func__
, (void *)route
, brouter_name
,
351 route
->path
.origin
.adv_router
,
352 listcount(route
->nh_list
));
354 route
->flag
|= OSPF6_ROUTE_REMOVE
;
355 ospf6_abr_examin_brouter(ADV_ROUTER_IN_PREFIX(&route
->prefix
), route
,
357 ospf6_asbr_lsentry_remove(route
, ospf6
);
358 ospf6_abr_originate_summary(route
, ospf6
);
361 static struct ospf6
*ospf6_create(const char *name
)
364 struct vrf
*vrf
= NULL
;
366 o
= XCALLOC(MTYPE_OSPF6_TOP
, sizeof(struct ospf6
));
368 vrf
= vrf_lookup_by_name(name
);
370 o
->vrf_id
= vrf
->vrf_id
;
372 o
->vrf_id
= VRF_UNKNOWN
;
374 /* Freed in ospf6_delete */
375 o
->name
= XSTRDUP(MTYPE_OSPF6_TOP
, name
);
377 ospf6_vrf_link(o
, vrf
);
379 ospf6_zebra_vrf_register(o
);
382 monotime(&o
->starttime
);
383 o
->area_list
= list_new();
384 o
->area_list
->cmp
= ospf6_area_cmp
;
385 o
->lsdb
= ospf6_lsdb_create(o
);
386 o
->lsdb_self
= ospf6_lsdb_create(o
);
387 o
->lsdb
->hook_add
= ospf6_top_lsdb_hook_add
;
388 o
->lsdb
->hook_remove
= ospf6_top_lsdb_hook_remove
;
390 o
->spf_delay
= OSPF_SPF_DELAY_DEFAULT
;
391 o
->spf_holdtime
= OSPF_SPF_HOLDTIME_DEFAULT
;
392 o
->spf_max_holdtime
= OSPF_SPF_MAX_HOLDTIME_DEFAULT
;
393 o
->spf_hold_multiplier
= 1;
395 o
->default_originate
= DEFAULT_ORIGINATE_NONE
;
397 /* LSA timers value init */
398 o
->lsa_minarrival
= OSPF_MIN_LS_ARRIVAL
;
400 o
->route_table
= OSPF6_ROUTE_TABLE_CREATE(GLOBAL
, ROUTES
);
401 o
->route_table
->scope
= o
;
402 o
->route_table
->hook_add
= ospf6_top_route_hook_add
;
403 o
->route_table
->hook_remove
= ospf6_top_route_hook_remove
;
405 o
->brouter_table
= OSPF6_ROUTE_TABLE_CREATE(GLOBAL
, BORDER_ROUTERS
);
406 o
->brouter_table
->scope
= o
;
407 o
->brouter_table
->hook_add
= ospf6_top_brouter_hook_add
;
408 o
->brouter_table
->hook_remove
= ospf6_top_brouter_hook_remove
;
410 o
->external_table
= OSPF6_ROUTE_TABLE_CREATE(GLOBAL
, EXTERNAL_ROUTES
);
411 o
->external_table
->scope
= o
;
413 o
->external_id_table
= route_table_init();
415 o
->write_oi_count
= OSPF6_WRITE_INTERFACE_COUNT_DEFAULT
;
416 o
->ref_bandwidth
= OSPF6_REFERENCE_BANDWIDTH
;
418 o
->distance_table
= route_table_init();
421 o
->max_multipath
= MULTIPATH_NUM
;
423 o
->oi_write_q
= list_new();
427 /* Make ospf protocol socket. */
433 struct ospf6
*ospf6_instance_create(const char *name
)
437 struct interface
*ifp
;
439 ospf6
= ospf6_create(name
);
440 if (DFLT_OSPF6_LOG_ADJACENCY_CHANGES
)
441 SET_FLAG(ospf6
->config_flags
, OSPF6_LOG_ADJACENCY_CHANGES
);
442 if (ospf6
->router_id
== 0)
443 ospf6_router_id_update(ospf6
);
445 if (ospf6
->vrf_id
!= VRF_UNKNOWN
) {
446 vrf
= vrf_lookup_by_id(ospf6
->vrf_id
);
447 FOR_ALL_INTERFACES (vrf
, ifp
) {
449 ospf6_interface_start(ifp
->info
);
455 thread_add_read(master
, ospf6_receive
, ospf6
, ospf6
->fd
,
456 &ospf6
->t_ospf6_receive
);
461 void ospf6_delete(struct ospf6
*o
)
463 struct listnode
*node
, *nnode
;
464 struct ospf6_area
*oa
;
469 ospf6_flush_self_originated_lsas_now(o
);
473 ospf6_zebra_vrf_deregister(o
);
475 ospf6_serv_close(&o
->fd
);
477 for (ALL_LIST_ELEMENTS(o
->area_list
, node
, nnode
, oa
))
478 ospf6_area_delete(oa
);
481 list_delete(&o
->area_list
);
483 ospf6_lsdb_delete(o
->lsdb
);
484 ospf6_lsdb_delete(o
->lsdb_self
);
486 ospf6_route_table_delete(o
->route_table
);
487 ospf6_route_table_delete(o
->brouter_table
);
489 ospf6_route_table_delete(o
->external_table
);
490 route_table_finish(o
->external_id_table
);
492 ospf6_distance_reset(o
);
493 route_table_finish(o
->distance_table
);
494 list_delete(&o
->oi_write_q
);
496 if (o
->vrf_id
!= VRF_UNKNOWN
) {
497 vrf
= vrf_lookup_by_id(o
->vrf_id
);
499 ospf6_vrf_unlink(o
, vrf
);
502 XFREE(MTYPE_OSPF6_TOP
, o
->name
);
503 XFREE(MTYPE_OSPF6_TOP
, o
);
506 static void ospf6_disable(struct ospf6
*o
)
508 struct listnode
*node
, *nnode
;
509 struct ospf6_area
*oa
;
511 if (!CHECK_FLAG(o
->flag
, OSPF6_DISABLED
)) {
512 SET_FLAG(o
->flag
, OSPF6_DISABLED
);
514 for (ALL_LIST_ELEMENTS(o
->area_list
, node
, nnode
, oa
))
515 ospf6_area_disable(oa
);
517 /* XXX: This also changes persistent settings */
518 /* Unregister redistribution */
519 ospf6_asbr_redistribute_disable(o
);
521 ospf6_lsdb_remove_all(o
->lsdb
);
522 ospf6_route_remove_all(o
->route_table
);
523 ospf6_route_remove_all(o
->brouter_table
);
525 THREAD_OFF(o
->maxage_remover
);
526 THREAD_OFF(o
->t_spf_calc
);
527 THREAD_OFF(o
->t_ase_calc
);
528 THREAD_OFF(o
->t_distribute_update
);
529 THREAD_OFF(o
->t_ospf6_receive
);
533 void ospf6_master_init(struct thread_master
*master
)
535 memset(&ospf6_master
, 0, sizeof(struct ospf6_master
));
538 om6
->ospf6
= list_new();
539 om6
->master
= master
;
542 static int ospf6_maxage_remover(struct thread
*thread
)
544 struct ospf6
*o
= (struct ospf6
*)THREAD_ARG(thread
);
545 struct ospf6_area
*oa
;
546 struct ospf6_interface
*oi
;
547 struct ospf6_neighbor
*on
;
548 struct listnode
*i
, *j
, *k
;
551 o
->maxage_remover
= (struct thread
*)NULL
;
553 for (ALL_LIST_ELEMENTS_RO(o
->area_list
, i
, oa
)) {
554 for (ALL_LIST_ELEMENTS_RO(oa
->if_list
, j
, oi
)) {
555 for (ALL_LIST_ELEMENTS_RO(oi
->neighbor_list
, k
, on
)) {
556 if (on
->state
!= OSPF6_NEIGHBOR_EXCHANGE
557 && on
->state
!= OSPF6_NEIGHBOR_LOADING
)
560 ospf6_maxage_remove(o
);
566 for (ALL_LIST_ELEMENTS_RO(o
->area_list
, i
, oa
)) {
567 for (ALL_LIST_ELEMENTS_RO(oa
->if_list
, j
, oi
)) {
568 if (ospf6_lsdb_maxage_remover(oi
->lsdb
)) {
573 if (ospf6_lsdb_maxage_remover(oa
->lsdb
)) {
578 if (ospf6_lsdb_maxage_remover(o
->lsdb
)) {
583 ospf6_maxage_remove(o
);
589 void ospf6_maxage_remove(struct ospf6
*o
)
592 thread_add_timer(master
, ospf6_maxage_remover
, o
,
593 OSPF_LSA_MAXAGE_REMOVE_DELAY_DEFAULT
,
597 void ospf6_router_id_update(struct ospf6
*ospf6
)
602 if (ospf6
->router_id_static
!= 0)
603 ospf6
->router_id
= ospf6
->router_id_static
;
605 ospf6
->router_id
= ospf6
->router_id_zebra
;
609 DEFUN_NOSH(router_ospf6
, router_ospf6_cmd
, "router ospf6 [vrf NAME]",
610 ROUTER_STR OSPF6_STR VRF_CMD_HELP_STR
)
613 const char *vrf_name
= VRF_DEFAULT_NAME
;
616 if (argv_find(argv
, argc
, "vrf", &idx_vrf
)) {
617 vrf_name
= argv
[idx_vrf
+ 1]->arg
;
620 ospf6
= ospf6_lookup_by_vrf_name(vrf_name
);
622 ospf6
= ospf6_instance_create(vrf_name
);
624 /* set current ospf point. */
625 VTY_PUSH_CONTEXT(OSPF6_NODE
, ospf6
);
631 DEFUN(no_router_ospf6
, no_router_ospf6_cmd
, "no router ospf6 [vrf NAME]",
632 NO_STR ROUTER_STR OSPF6_STR VRF_CMD_HELP_STR
)
635 const char *vrf_name
= VRF_DEFAULT_NAME
;
638 if (argv_find(argv
, argc
, "vrf", &idx_vrf
)) {
639 vrf_name
= argv
[idx_vrf
+ 1]->arg
;
642 ospf6
= ospf6_lookup_by_vrf_name(vrf_name
);
644 vty_out(vty
, "OSPFv3 is not configured\n");
650 /* return to config node . */
651 VTY_PUSH_CONTEXT_NULL(CONFIG_NODE
);
656 static void ospf6_db_clear(struct ospf6
*ospf6
)
658 struct ospf6_interface
*oi
;
659 struct interface
*ifp
;
660 struct vrf
*vrf
= vrf_lookup_by_id(ospf6
->vrf_id
);
661 struct listnode
*node
, *nnode
;
662 struct ospf6_area
*oa
;
664 FOR_ALL_INTERFACES (vrf
, ifp
) {
665 if (if_is_operative(ifp
) && ifp
->info
!= NULL
) {
666 oi
= (struct ospf6_interface
*)ifp
->info
;
667 ospf6_lsdb_remove_all(oi
->lsdb
);
668 ospf6_lsdb_remove_all(oi
->lsdb_self
);
669 ospf6_lsdb_remove_all(oi
->lsupdate_list
);
670 ospf6_lsdb_remove_all(oi
->lsack_list
);
674 for (ALL_LIST_ELEMENTS(ospf6
->area_list
, node
, nnode
, oa
)) {
675 ospf6_lsdb_remove_all(oa
->lsdb
);
676 ospf6_lsdb_remove_all(oa
->lsdb_self
);
678 ospf6_spf_table_finish(oa
->spf_table
);
679 ospf6_route_remove_all(oa
->route_table
);
682 ospf6_lsdb_remove_all(ospf6
->lsdb
);
683 ospf6_lsdb_remove_all(ospf6
->lsdb_self
);
684 ospf6_route_remove_all(ospf6
->route_table
);
685 ospf6_route_remove_all(ospf6
->brouter_table
);
688 static void ospf6_process_reset(struct ospf6
*ospf6
)
690 struct interface
*ifp
;
691 struct vrf
*vrf
= vrf_lookup_by_id(ospf6
->vrf_id
);
693 ospf6_flush_self_originated_lsas_now(ospf6
);
694 ospf6
->inst_shutdown
= 0;
695 ospf6_db_clear(ospf6
);
697 ospf6_router_id_update(ospf6
);
699 ospf6_asbr_redistribute_reset(ospf6
);
700 FOR_ALL_INTERFACES (vrf
, ifp
)
701 ospf6_interface_clear(ifp
);
704 DEFPY (clear_router_ospf6
,
705 clear_router_ospf6_cmd
,
706 "clear ipv6 ospf6 process [vrf NAME$name]",
710 "Reset OSPF Process\n"
714 const char *vrf_name
= VRF_DEFAULT_NAME
;
719 ospf6
= ospf6_lookup_by_vrf_name(vrf_name
);
721 vty_out(vty
, "OSPFv3 is not configured\n");
723 ospf6_process_reset(ospf6
);
728 /* change Router_ID commands. */
729 DEFUN(ospf6_router_id
,
731 "ospf6 router-id A.B.C.D",
733 "Configure OSPF6 Router-ID\n"
736 VTY_DECLVAR_CONTEXT(ospf6
, o
);
739 const char *router_id_str
;
741 struct ospf6_area
*oa
;
742 struct listnode
*node
;
744 argv_find(argv
, argc
, "A.B.C.D", &idx
);
745 router_id_str
= argv
[idx
]->arg
;
747 ret
= inet_pton(AF_INET
, router_id_str
, &router_id
);
749 vty_out(vty
, "malformed OSPF Router-ID: %s\n", router_id_str
);
753 o
->router_id_static
= router_id
;
755 for (ALL_LIST_ELEMENTS_RO(o
->area_list
, node
, oa
)) {
758 "For this router-id change to take effect, run the \"clear ipv6 ospf6 process\" command\n");
763 o
->router_id
= router_id
;
768 DEFUN(no_ospf6_router_id
,
769 no_ospf6_router_id_cmd
,
770 "no ospf6 router-id [A.B.C.D]",
772 "Configure OSPF6 Router-ID\n"
775 VTY_DECLVAR_CONTEXT(ospf6
, o
);
776 struct ospf6_area
*oa
;
777 struct listnode
*node
;
779 o
->router_id_static
= 0;
781 for (ALL_LIST_ELEMENTS_RO(o
->area_list
, node
, oa
)) {
784 "For this router-id change to take effect, run the \"clear ipv6 ospf6 process\" command\n");
789 if (o
->router_id_zebra
)
790 o
->router_id
= o
->router_id_zebra
;
795 DEFUN (ospf6_log_adjacency_changes
,
796 ospf6_log_adjacency_changes_cmd
,
797 "log-adjacency-changes",
798 "Log changes in adjacency state\n")
800 VTY_DECLVAR_CONTEXT(ospf6
, ospf6
);
802 SET_FLAG(ospf6
->config_flags
, OSPF6_LOG_ADJACENCY_CHANGES
);
803 UNSET_FLAG(ospf6
->config_flags
, OSPF6_LOG_ADJACENCY_DETAIL
);
807 DEFUN (ospf6_log_adjacency_changes_detail
,
808 ospf6_log_adjacency_changes_detail_cmd
,
809 "log-adjacency-changes detail",
810 "Log changes in adjacency state\n"
811 "Log all state changes\n")
813 VTY_DECLVAR_CONTEXT(ospf6
, ospf6
);
815 SET_FLAG(ospf6
->config_flags
, OSPF6_LOG_ADJACENCY_CHANGES
);
816 SET_FLAG(ospf6
->config_flags
, OSPF6_LOG_ADJACENCY_DETAIL
);
820 DEFUN (no_ospf6_log_adjacency_changes
,
821 no_ospf6_log_adjacency_changes_cmd
,
822 "no log-adjacency-changes",
824 "Log changes in adjacency state\n")
826 VTY_DECLVAR_CONTEXT(ospf6
, ospf6
);
828 UNSET_FLAG(ospf6
->config_flags
, OSPF6_LOG_ADJACENCY_DETAIL
);
829 UNSET_FLAG(ospf6
->config_flags
, OSPF6_LOG_ADJACENCY_CHANGES
);
833 DEFUN (no_ospf6_log_adjacency_changes_detail
,
834 no_ospf6_log_adjacency_changes_detail_cmd
,
835 "no log-adjacency-changes detail",
837 "Log changes in adjacency state\n"
838 "Log all state changes\n")
840 VTY_DECLVAR_CONTEXT(ospf6
, ospf6
);
842 UNSET_FLAG(ospf6
->config_flags
, OSPF6_LOG_ADJACENCY_DETAIL
);
846 DEFUN (ospf6_timers_lsa
,
847 ospf6_timers_lsa_cmd
,
848 "timers lsa min-arrival (0-600000)",
849 "Adjust routing timers\n"
851 "Minimum delay in receiving new version of a LSA\n"
852 "Delay in milliseconds\n")
854 VTY_DECLVAR_CONTEXT(ospf6
, ospf
);
856 unsigned int minarrival
;
858 minarrival
= strtoul(argv
[idx_number
]->arg
, NULL
, 10);
859 ospf
->lsa_minarrival
= minarrival
;
864 DEFUN (no_ospf6_timers_lsa
,
865 no_ospf6_timers_lsa_cmd
,
866 "no timers lsa min-arrival [(0-600000)]",
868 "Adjust routing timers\n"
870 "Minimum delay in receiving new version of a LSA\n"
871 "Delay in milliseconds\n")
873 VTY_DECLVAR_CONTEXT(ospf6
, ospf
);
875 unsigned int minarrival
;
878 minarrival
= strtoul(argv
[idx_number
]->arg
, NULL
, 10);
880 if (ospf
->lsa_minarrival
!= minarrival
881 || minarrival
== OSPF_MIN_LS_ARRIVAL
)
885 ospf
->lsa_minarrival
= OSPF_MIN_LS_ARRIVAL
;
891 DEFUN (ospf6_distance
,
894 "Administrative distance\n"
895 "OSPF6 Administrative distance\n")
897 VTY_DECLVAR_CONTEXT(ospf6
, o
);
899 o
->distance_all
= atoi(argv
[1]->arg
);
904 DEFUN (no_ospf6_distance
,
905 no_ospf6_distance_cmd
,
906 "no distance (1-255)",
908 "Administrative distance\n"
909 "OSPF6 Administrative distance\n")
911 VTY_DECLVAR_CONTEXT(ospf6
, o
);
918 DEFUN (ospf6_distance_ospf6
,
919 ospf6_distance_ospf6_cmd
,
920 "distance ospf6 {intra-area (1-255)|inter-area (1-255)|external (1-255)}",
921 "Administrative distance\n"
922 "OSPF6 administrative distance\n"
923 "Intra-area routes\n"
924 "Distance for intra-area routes\n"
925 "Inter-area routes\n"
926 "Distance for inter-area routes\n"
928 "Distance for external routes\n")
930 VTY_DECLVAR_CONTEXT(ospf6
, o
);
933 o
->distance_intra
= 0;
934 o
->distance_inter
= 0;
935 o
->distance_external
= 0;
937 if (argv_find(argv
, argc
, "intra-area", &idx
))
938 o
->distance_intra
= atoi(argv
[idx
+ 1]->arg
);
940 if (argv_find(argv
, argc
, "inter-area", &idx
))
941 o
->distance_inter
= atoi(argv
[idx
+ 1]->arg
);
943 if (argv_find(argv
, argc
, "external", &idx
))
944 o
->distance_external
= atoi(argv
[idx
+ 1]->arg
);
949 DEFUN (no_ospf6_distance_ospf6
,
950 no_ospf6_distance_ospf6_cmd
,
951 "no distance ospf6 [{intra-area [(1-255)]|inter-area [(1-255)]|external [(1-255)]}]",
953 "Administrative distance\n"
955 "Intra-area routes\n"
956 "Distance for intra-area routes\n"
957 "Inter-area routes\n"
958 "Distance for inter-area routes\n"
960 "Distance for external routes\n")
962 VTY_DECLVAR_CONTEXT(ospf6
, o
);
965 if (argv_find(argv
, argc
, "intra-area", &idx
) || argc
== 3)
966 idx
= o
->distance_intra
= 0;
967 if (argv_find(argv
, argc
, "inter-area", &idx
) || argc
== 3)
968 idx
= o
->distance_inter
= 0;
969 if (argv_find(argv
, argc
, "external", &idx
) || argc
== 3)
970 o
->distance_external
= 0;
975 DEFUN_HIDDEN (ospf6_interface_area
,
976 ospf6_interface_area_cmd
,
977 "interface IFNAME area <A.B.C.D|(0-4294967295)>",
978 "Enable routing on an IPv6 interface\n"
980 "Specify the OSPF6 area ID\n"
981 "OSPF6 area ID in IPv4 address notation\n"
982 "OSPF6 area ID in decimal notation\n"
985 VTY_DECLVAR_CONTEXT(ospf6
, ospf6
);
988 struct ospf6_area
*oa
;
989 struct ospf6_interface
*oi
;
990 struct interface
*ifp
;
991 vrf_id_t vrf_id
= VRF_DEFAULT
;
997 "This command is deprecated, because it is not VRF-aware.\n");
999 "Please, use \"ipv6 ospf6 area\" on an interface instead.\n");
1001 if (ospf6
->vrf_id
!= VRF_UNKNOWN
)
1002 vrf_id
= ospf6
->vrf_id
;
1004 /* find/create ospf6 interface */
1005 ifp
= if_get_by_name(argv
[idx_ifname
]->arg
, vrf_id
);
1006 oi
= (struct ospf6_interface
*)ifp
->info
;
1008 oi
= ospf6_interface_create(ifp
);
1010 vty_out(vty
, "%s already attached to Area %s\n",
1011 oi
->interface
->name
, oi
->area
->name
);
1015 /* if more than OSPF6_MAX_IF_ADDRS are configured on this interface
1016 * then don't allow ospfv3 to be configured
1018 ipv6_count
= connected_count_by_family(ifp
, AF_INET6
);
1019 if (oi
->ifmtu
== OSPF6_DEFAULT_MTU
&& ipv6_count
> OSPF6_MAX_IF_ADDRS
) {
1021 "can not configure OSPFv3 on if %s, must have less than %d interface addresses but has %d addresses\n",
1022 ifp
->name
, OSPF6_MAX_IF_ADDRS
, ipv6_count
);
1023 return CMD_WARNING_CONFIG_FAILED
;
1024 } else if (oi
->ifmtu
>= OSPF6_JUMBO_MTU
1025 && ipv6_count
> OSPF6_MAX_IF_ADDRS_JUMBO
) {
1027 "can not configure OSPFv3 on if %s, must have less than %d interface addresses but has %d addresses\n",
1028 ifp
->name
, OSPF6_MAX_IF_ADDRS_JUMBO
, ipv6_count
);
1029 return CMD_WARNING_CONFIG_FAILED
;
1032 if (str2area_id(argv
[idx_ipv4
]->arg
, &area_id
, &format
)) {
1033 vty_out(vty
, "Malformed Area-ID: %s\n", argv
[idx_ipv4
]->arg
);
1034 return CMD_WARNING_CONFIG_FAILED
;
1037 oi
->area_id
= area_id
;
1038 oi
->area_id_format
= format
;
1040 oa
= ospf6_area_lookup(area_id
, ospf6
);
1042 oa
= ospf6_area_create(area_id
, ospf6
, format
);
1044 /* attach interface to area */
1045 listnode_add(oa
->if_list
, oi
); /* sort ?? */
1048 SET_FLAG(oa
->flag
, OSPF6_AREA_ENABLE
);
1050 /* ospf6 process is currently disabled, not much more to do */
1051 if (CHECK_FLAG(ospf6
->flag
, OSPF6_DISABLED
))
1055 ospf6_interface_enable(oi
);
1057 /* If the router is ABR, originate summary routes */
1058 if (ospf6_check_and_set_router_abr(ospf6
)) {
1059 ospf6_abr_enable_area(oa
);
1060 ospf6_schedule_abr_task(oa
->ospf6
);
1066 DEFUN_HIDDEN (no_ospf6_interface_area
,
1067 no_ospf6_interface_area_cmd
,
1068 "no interface IFNAME area <A.B.C.D|(0-4294967295)>",
1070 "Disable routing on an IPv6 interface\n"
1072 "Specify the OSPF6 area ID\n"
1073 "OSPF6 area ID in IPv4 address notation\n"
1074 "OSPF6 area ID in decimal notation\n"
1077 VTY_DECLVAR_CONTEXT(ospf6
, ospf6
);
1080 struct ospf6_interface
*oi
;
1081 struct ospf6_area
*oa
;
1082 struct interface
*ifp
;
1084 vrf_id_t vrf_id
= VRF_DEFAULT
;
1087 "This command is deprecated, because it is not VRF-aware.\n");
1089 "Please, use \"no ipv6 ospf6 area\" on an interface instead.\n");
1091 if (ospf6
->vrf_id
!= VRF_UNKNOWN
)
1092 vrf_id
= ospf6
->vrf_id
;
1094 /* find/create ospf6 interface */
1095 ifp
= if_get_by_name(argv
[idx_ifname
]->arg
, vrf_id
);
1098 vty_out(vty
, "No such interface %s\n", argv
[idx_ifname
]->arg
);
1102 oi
= (struct ospf6_interface
*)ifp
->info
;
1104 vty_out(vty
, "Interface %s not enabled\n", ifp
->name
);
1109 if (inet_pton(AF_INET
, argv
[idx_ipv4
]->arg
, &area_id
) != 1)
1110 area_id
= htonl(strtoul(argv
[idx_ipv4
]->arg
, NULL
, 10));
1113 if (oi
->area
== NULL
) {
1114 vty_out(vty
, "%s not attached to area %s\n",
1115 oi
->interface
->name
, argv
[idx_ipv4
]->arg
);
1119 if (oi
->area
->area_id
!= area_id
) {
1120 vty_out(vty
, "Wrong Area-ID: %s is attached to area %s\n",
1121 oi
->interface
->name
, oi
->area
->name
);
1125 ospf6_interface_disable(oi
);
1128 listnode_delete(oi
->area
->if_list
, oi
);
1129 oi
->area
= (struct ospf6_area
*)NULL
;
1131 /* Withdraw inter-area routes from this area, if necessary */
1132 if (oa
->if_list
->count
== 0) {
1133 UNSET_FLAG(oa
->flag
, OSPF6_AREA_ENABLE
);
1134 ospf6_abr_disable_area(oa
);
1138 oi
->area_id_format
= OSPF6_AREA_FMT_UNSET
;
1143 DEFUN (ospf6_stub_router_admin
,
1144 ospf6_stub_router_admin_cmd
,
1145 "stub-router administrative",
1146 "Make router a stub router\n"
1147 "Administratively applied, for an indefinite period\n")
1149 struct listnode
*node
;
1150 struct ospf6_area
*oa
;
1152 VTY_DECLVAR_CONTEXT(ospf6
, ospf6
);
1154 if (!CHECK_FLAG(ospf6
->flag
, OSPF6_STUB_ROUTER
)) {
1155 for (ALL_LIST_ELEMENTS_RO(ospf6
->area_list
, node
, oa
)) {
1156 OSPF6_OPT_CLEAR(oa
->options
, OSPF6_OPT_V6
);
1157 OSPF6_OPT_CLEAR(oa
->options
, OSPF6_OPT_R
);
1158 OSPF6_ROUTER_LSA_SCHEDULE(oa
);
1160 SET_FLAG(ospf6
->flag
, OSPF6_STUB_ROUTER
);
1166 DEFUN (no_ospf6_stub_router_admin
,
1167 no_ospf6_stub_router_admin_cmd
,
1168 "no stub-router administrative",
1170 "Make router a stub router\n"
1171 "Administratively applied, for an indefinite period\n")
1173 struct listnode
*node
;
1174 struct ospf6_area
*oa
;
1176 VTY_DECLVAR_CONTEXT(ospf6
, ospf6
);
1177 if (CHECK_FLAG(ospf6
->flag
, OSPF6_STUB_ROUTER
)) {
1178 for (ALL_LIST_ELEMENTS_RO(ospf6
->area_list
, node
, oa
)) {
1179 OSPF6_OPT_SET(oa
->options
, OSPF6_OPT_V6
);
1180 OSPF6_OPT_SET(oa
->options
, OSPF6_OPT_R
);
1181 OSPF6_ROUTER_LSA_SCHEDULE(oa
);
1183 UNSET_FLAG(ospf6
->flag
, OSPF6_STUB_ROUTER
);
1189 /* Restart OSPF SPF algorithm*/
1190 static void ospf6_restart_spf(struct ospf6
*ospf6
)
1192 ospf6_route_remove_all(ospf6
->route_table
);
1193 ospf6_route_remove_all(ospf6
->brouter_table
);
1196 ospf6_spf_schedule(ospf6
, OSPF6_SPF_FLAGS_CONFIG_CHANGE
);
1199 /* Set the max paths */
1200 static void ospf6_maxpath_set(struct ospf6
*ospf6
, uint16_t paths
)
1202 if (ospf6
->max_multipath
== paths
)
1205 ospf6
->max_multipath
= paths
;
1207 /* Send deletion to zebra to delete all
1208 * ospf specific routes and reinitiate
1209 * SPF to reflect the new max multipath.
1211 ospf6_restart_spf(ospf6
);
1214 /* Ospf Maximum-paths config support */
1215 DEFUN(ospf6_max_multipath
,
1216 ospf6_max_multipath_cmd
,
1217 "maximum-paths " CMD_RANGE_STR(1, MULTIPATH_NUM
),
1218 "Max no of multiple paths for ECMP support\n"
1219 "Number of paths\n")
1221 VTY_DECLVAR_CONTEXT(ospf6
, ospf6
);
1223 int maximum_paths
= strtol(argv
[idx_number
]->arg
, NULL
, 10);
1225 ospf6_maxpath_set(ospf6
, maximum_paths
);
1230 DEFUN(no_ospf6_max_multipath
,
1231 no_ospf6_max_multipath_cmd
,
1232 "no maximum-paths [" CMD_RANGE_STR(1, MULTIPATH_NUM
)"]",
1234 "Max no of multiple paths for ECMP support\n"
1235 "Number of paths\n")
1237 VTY_DECLVAR_CONTEXT(ospf6
, ospf6
);
1239 ospf6_maxpath_set(ospf6
, MULTIPATH_NUM
);
1244 static void ospf6_show(struct vty
*vty
, struct ospf6
*o
, json_object
*json
,
1248 struct ospf6_area
*oa
;
1249 char router_id
[16], duration
[32];
1250 struct timeval now
, running
, result
;
1251 char buf
[32], rbuf
[32];
1252 json_object
*json_areas
= NULL
;
1253 const char *adjacency
;
1256 json_areas
= json_object_new_object();
1258 /* process id, router id */
1259 inet_ntop(AF_INET
, &o
->router_id
, router_id
, sizeof(router_id
));
1260 json_object_string_add(json
, "routerId", router_id
);
1264 timersub(&now
, &o
->starttime
, &running
);
1265 timerstring(&running
, duration
, sizeof(duration
));
1266 json_object_string_add(json
, "running", duration
);
1268 /* Redistribute configuration */
1270 json_object_int_add(json
, "lsaMinimumArrivalMsecs",
1273 /* Show SPF parameters */
1274 json_object_int_add(json
, "spfScheduleDelayMsecs",
1276 json_object_int_add(json
, "holdTimeMinMsecs", o
->spf_holdtime
);
1277 json_object_int_add(json
, "holdTimeMaxMsecs",
1278 o
->spf_max_holdtime
);
1279 json_object_int_add(json
, "holdTimeMultiplier",
1280 o
->spf_hold_multiplier
);
1282 json_object_int_add(json
, "maximumPaths", o
->max_multipath
);
1284 if (o
->ts_spf
.tv_sec
|| o
->ts_spf
.tv_usec
) {
1285 timersub(&now
, &o
->ts_spf
, &result
);
1286 timerstring(&result
, buf
, sizeof(buf
));
1287 ospf6_spf_reason_string(o
->last_spf_reason
, rbuf
,
1289 json_object_boolean_true_add(json
, "spfHasRun");
1290 json_object_string_add(json
, "spfLastExecutedMsecs",
1292 json_object_string_add(json
, "spfLastExecutedReason",
1295 json_object_int_add(
1296 json
, "spfLastDurationSecs",
1297 (long long)o
->ts_spf_duration
.tv_sec
);
1299 json_object_int_add(
1300 json
, "spfLastDurationMsecs",
1301 (long long)o
->ts_spf_duration
.tv_usec
);
1303 json_object_boolean_false_add(json
, "spfHasRun");
1306 threadtimer_string(now
, o
->t_spf_calc
, buf
, sizeof(buf
));
1307 if (o
->t_spf_calc
) {
1310 json_object_boolean_true_add(json
, "spfTimerActive");
1312 monotime_until(&o
->t_spf_calc
->u
.sands
, NULL
)
1314 json_object_int_add(json
, "spfTimerDueInMsecs",
1317 json_object_boolean_false_add(json
, "spfTimerActive");
1319 json_object_boolean_add(json
, "routerIsStubRouter",
1320 CHECK_FLAG(o
->flag
, OSPF6_STUB_ROUTER
));
1323 json_object_int_add(json
, "numberOfAsScopedLsa",
1326 json_object_int_add(json
, "numberOfAreaInRouter",
1327 listcount(o
->area_list
));
1329 if (CHECK_FLAG(o
->config_flags
, OSPF6_LOG_ADJACENCY_CHANGES
)) {
1330 if (CHECK_FLAG(o
->config_flags
,
1331 OSPF6_LOG_ADJACENCY_DETAIL
))
1332 adjacency
= "LoggedAll";
1334 adjacency
= "Logged";
1336 adjacency
= "NotLogged";
1337 json_object_string_add(json
, "adjacencyChanges", adjacency
);
1339 for (ALL_LIST_ELEMENTS_RO(o
->area_list
, n
, oa
))
1340 ospf6_area_show(vty
, oa
, json_areas
, use_json
);
1342 json_object_object_add(json
, "areas", json_areas
);
1344 vty_out(vty
, "%s\n",
1345 json_object_to_json_string_ext(
1346 json
, JSON_C_TO_STRING_PRETTY
));
1349 /* process id, router id */
1350 inet_ntop(AF_INET
, &o
->router_id
, router_id
, sizeof(router_id
));
1351 vty_out(vty
, " OSPFv3 Routing Process (0) with Router-ID %s\n",
1356 timersub(&now
, &o
->starttime
, &running
);
1357 timerstring(&running
, duration
, sizeof(duration
));
1358 vty_out(vty
, " Running %s\n", duration
);
1360 /* Redistribute configuration */
1362 vty_out(vty
, " LSA minimum arrival %d msecs\n",
1365 vty_out(vty
, " Maximum-paths %u\n", o
->max_multipath
);
1367 /* Show SPF parameters */
1369 " Initial SPF scheduling delay %d millisec(s)\n"
1370 " Minimum hold time between consecutive SPFs %d millsecond(s)\n"
1371 " Maximum hold time between consecutive SPFs %d millsecond(s)\n"
1372 " Hold time multiplier is currently %d\n",
1373 o
->spf_delay
, o
->spf_holdtime
, o
->spf_max_holdtime
,
1374 o
->spf_hold_multiplier
);
1377 vty_out(vty
, " SPF algorithm ");
1378 if (o
->ts_spf
.tv_sec
|| o
->ts_spf
.tv_usec
) {
1379 timersub(&now
, &o
->ts_spf
, &result
);
1380 timerstring(&result
, buf
, sizeof(buf
));
1381 ospf6_spf_reason_string(o
->last_spf_reason
, rbuf
,
1383 vty_out(vty
, "last executed %s ago, reason %s\n", buf
,
1385 vty_out(vty
, " Last SPF duration %lld sec %lld usec\n",
1386 (long long)o
->ts_spf_duration
.tv_sec
,
1387 (long long)o
->ts_spf_duration
.tv_usec
);
1389 vty_out(vty
, "has not been run\n");
1391 threadtimer_string(now
, o
->t_spf_calc
, buf
, sizeof(buf
));
1392 vty_out(vty
, " SPF timer %s%s\n",
1393 (o
->t_spf_calc
? "due in " : "is "), buf
);
1395 if (CHECK_FLAG(o
->flag
, OSPF6_STUB_ROUTER
))
1396 vty_out(vty
, " Router Is Stub Router\n");
1399 vty_out(vty
, " Number of AS scoped LSAs is %u\n",
1403 vty_out(vty
, " Number of areas in this router is %u\n",
1404 listcount(o
->area_list
));
1406 if (CHECK_FLAG(o
->config_flags
, OSPF6_LOG_ADJACENCY_CHANGES
)) {
1407 if (CHECK_FLAG(o
->config_flags
,
1408 OSPF6_LOG_ADJACENCY_DETAIL
))
1410 " All adjacency changes are logged\n");
1412 vty_out(vty
, " Adjacency changes are logged\n");
1418 for (ALL_LIST_ELEMENTS_RO(o
->area_list
, n
, oa
))
1419 ospf6_area_show(vty
, oa
, json_areas
, use_json
);
1423 DEFUN(show_ipv6_ospf6_vrfs
, show_ipv6_ospf6_vrfs_cmd
,
1424 "show ipv6 ospf6 vrfs [json]",
1425 SHOW_STR IP6_STR OSPF6_STR
"Show OSPF6 VRFs \n" JSON_STR
)
1427 bool uj
= use_json(argc
, argv
);
1428 json_object
*json
= NULL
;
1429 json_object
*json_vrfs
= NULL
;
1430 struct ospf6
*ospf6
= NULL
;
1431 struct listnode
*node
= NULL
;
1433 char buf
[PREFIX_STRLEN
];
1434 static const char header
[] =
1435 "Name Id RouterId ";
1438 json
= json_object_new_object();
1439 json_vrfs
= json_object_new_object();
1442 for (ALL_LIST_ELEMENTS_RO(om6
->ospf6
, node
, ospf6
)) {
1443 json_object
*json_vrf
= NULL
;
1444 const char *name
= NULL
;
1445 int64_t vrf_id_ui
= 0;
1446 struct in_addr router_id
;
1448 router_id
.s_addr
= ospf6
->router_id
;
1451 if (!uj
&& count
== 1)
1452 vty_out(vty
, "%s\n", header
);
1454 json_vrf
= json_object_new_object();
1456 if (ospf6
->vrf_id
== VRF_DEFAULT
)
1457 name
= VRF_DEFAULT_NAME
;
1461 vrf_id_ui
= (ospf6
->vrf_id
== VRF_UNKNOWN
)
1463 : (int64_t)ospf6
->vrf_id
;
1466 json_object_int_add(json_vrf
, "vrfId", vrf_id_ui
);
1467 json_object_string_add(json_vrf
, "routerId",
1468 inet_ntop(AF_INET
, &router_id
,
1470 json_object_object_add(json_vrfs
, name
, json_vrf
);
1473 vty_out(vty
, "%-25s %-5d %-16s \n", name
,
1475 inet_ntop(AF_INET
, &router_id
, buf
,
1481 json_object_object_add(json
, "vrfs", json_vrfs
);
1482 json_object_int_add(json
, "totalVrfs", count
);
1484 vty_out(vty
, "%s\n",
1485 json_object_to_json_string_ext(
1486 json
, JSON_C_TO_STRING_PRETTY
));
1487 json_object_free(json
);
1490 vty_out(vty
, "\nTotal number of OSPF VRFs: %d\n",
1497 /* show top level structures */
1498 DEFUN(show_ipv6_ospf6
, show_ipv6_ospf6_cmd
,
1499 "show ipv6 ospf6 [vrf <NAME|all>] [json]",
1500 SHOW_STR IP6_STR OSPF6_STR VRF_CMD_HELP_STR
"All VRFs\n" JSON_STR
)
1502 struct ospf6
*ospf6
;
1503 struct listnode
*node
;
1504 const char *vrf_name
= NULL
;
1505 bool all_vrf
= false;
1508 bool uj
= use_json(argc
, argv
);
1509 json_object
*json
= NULL
;
1511 OSPF6_CMD_CHECK_RUNNING();
1512 OSPF6_FIND_VRF_ARGS(argv
, argc
, idx_vrf
, vrf_name
, all_vrf
);
1514 for (ALL_LIST_ELEMENTS_RO(om6
->ospf6
, node
, ospf6
)) {
1515 if (all_vrf
|| strcmp(ospf6
->name
, vrf_name
) == 0) {
1517 json
= json_object_new_object();
1518 ospf6_show(vty
, ospf6
, json
, uj
);
1526 json_object_free(json
);
1531 DEFUN(show_ipv6_ospf6_route
, show_ipv6_ospf6_route_cmd
,
1532 "show ipv6 ospf6 [vrf <NAME|all>] route [<intra-area|inter-area|external-1|external-2|X:X::X:X|X:X::X:X/M|detail|summary>] [json]",
1533 SHOW_STR IP6_STR OSPF6_STR VRF_CMD_HELP_STR
1534 "All VRFs\n" ROUTE_STR
1535 "Display Intra-Area routes\n"
1536 "Display Inter-Area routes\n"
1537 "Display Type-1 External routes\n"
1538 "Display Type-2 External routes\n"
1539 "Specify IPv6 address\n"
1540 "Specify IPv6 prefix\n"
1541 "Detailed information\n"
1542 "Summary of route table\n" JSON_STR
)
1544 struct ospf6
*ospf6
;
1545 struct listnode
*node
;
1546 const char *vrf_name
= NULL
;
1547 bool all_vrf
= false;
1549 int idx_arg_start
= 4;
1550 bool uj
= use_json(argc
, argv
);
1552 OSPF6_CMD_CHECK_RUNNING();
1553 OSPF6_FIND_VRF_ARGS(argv
, argc
, idx_vrf
, vrf_name
, all_vrf
);
1557 for (ALL_LIST_ELEMENTS_RO(om6
->ospf6
, node
, ospf6
)) {
1558 if (all_vrf
|| strcmp(ospf6
->name
, vrf_name
) == 0) {
1559 ospf6_route_table_show(vty
, idx_arg_start
, argc
, argv
,
1560 ospf6
->route_table
, uj
);
1570 DEFUN(show_ipv6_ospf6_route_match
, show_ipv6_ospf6_route_match_cmd
,
1571 "show ipv6 ospf6 [vrf <NAME|all>] route X:X::X:X/M <match|longer> [json]",
1572 SHOW_STR IP6_STR OSPF6_STR VRF_CMD_HELP_STR
1573 "All VRFs\n" ROUTE_STR
1574 "Specify IPv6 prefix\n"
1575 "Display routes which match the specified route\n"
1576 "Display routes longer than the specified route\n" JSON_STR
)
1578 struct ospf6
*ospf6
;
1579 struct listnode
*node
;
1580 const char *vrf_name
= NULL
;
1581 bool all_vrf
= false;
1583 int idx_start_arg
= 4;
1584 bool uj
= use_json(argc
, argv
);
1586 OSPF6_CMD_CHECK_RUNNING();
1587 OSPF6_FIND_VRF_ARGS(argv
, argc
, idx_vrf
, vrf_name
, all_vrf
);
1591 for (ALL_LIST_ELEMENTS_RO(om6
->ospf6
, node
, ospf6
)) {
1592 if (all_vrf
|| strcmp(ospf6
->name
, vrf_name
) == 0) {
1593 ospf6_route_table_show(vty
, idx_start_arg
, argc
, argv
,
1594 ospf6
->route_table
, uj
);
1604 DEFUN(show_ipv6_ospf6_route_match_detail
,
1605 show_ipv6_ospf6_route_match_detail_cmd
,
1606 "show ipv6 ospf6 [vrf <NAME|all>] route X:X::X:X/M match detail [json]",
1607 SHOW_STR IP6_STR OSPF6_STR VRF_CMD_HELP_STR
1608 "All VRFs\n" ROUTE_STR
1609 "Specify IPv6 prefix\n"
1610 "Display routes which match the specified route\n"
1611 "Detailed information\n" JSON_STR
)
1613 struct ospf6
*ospf6
;
1614 struct listnode
*node
;
1615 const char *vrf_name
= NULL
;
1616 bool all_vrf
= false;
1618 int idx_start_arg
= 4;
1619 bool uj
= use_json(argc
, argv
);
1621 OSPF6_CMD_CHECK_RUNNING();
1622 OSPF6_FIND_VRF_ARGS(argv
, argc
, idx_vrf
, vrf_name
, all_vrf
);
1626 for (ALL_LIST_ELEMENTS_RO(om6
->ospf6
, node
, ospf6
)) {
1627 if (all_vrf
|| strcmp(ospf6
->name
, vrf_name
) == 0) {
1628 ospf6_route_table_show(vty
, idx_start_arg
, argc
, argv
,
1629 ospf6
->route_table
, uj
);
1639 DEFUN(show_ipv6_ospf6_route_type_detail
, show_ipv6_ospf6_route_type_detail_cmd
,
1640 "show ipv6 ospf6 [vrf <NAME|all>] route <intra-area|inter-area|external-1|external-2> detail [json]",
1641 SHOW_STR IP6_STR OSPF6_STR VRF_CMD_HELP_STR
1642 "All VRFs\n" ROUTE_STR
1643 "Display Intra-Area routes\n"
1644 "Display Inter-Area routes\n"
1645 "Display Type-1 External routes\n"
1646 "Display Type-2 External routes\n"
1647 "Detailed information\n" JSON_STR
)
1649 struct ospf6
*ospf6
;
1650 struct listnode
*node
;
1651 const char *vrf_name
= NULL
;
1652 bool all_vrf
= false;
1654 int idx_start_arg
= 4;
1655 bool uj
= use_json(argc
, argv
);
1657 OSPF6_CMD_CHECK_RUNNING();
1658 OSPF6_FIND_VRF_ARGS(argv
, argc
, idx_vrf
, vrf_name
, all_vrf
);
1662 for (ALL_LIST_ELEMENTS_RO(om6
->ospf6
, node
, ospf6
)) {
1663 if (all_vrf
|| strcmp(ospf6
->name
, vrf_name
) == 0) {
1664 ospf6_route_table_show(vty
, idx_start_arg
, argc
, argv
,
1665 ospf6
->route_table
, uj
);
1675 static void ospf6_stub_router_config_write(struct vty
*vty
, struct ospf6
*ospf6
)
1677 if (CHECK_FLAG(ospf6
->flag
, OSPF6_STUB_ROUTER
)) {
1678 vty_out(vty
, " stub-router administrative\n");
1683 static int ospf6_distance_config_write(struct vty
*vty
, struct ospf6
*ospf6
)
1685 struct route_node
*rn
;
1686 struct ospf6_distance
*odistance
;
1688 if (ospf6
->distance_all
)
1689 vty_out(vty
, " distance %u\n", ospf6
->distance_all
);
1691 if (ospf6
->distance_intra
|| ospf6
->distance_inter
1692 || ospf6
->distance_external
) {
1693 vty_out(vty
, " distance ospf6");
1695 if (ospf6
->distance_intra
)
1696 vty_out(vty
, " intra-area %u", ospf6
->distance_intra
);
1697 if (ospf6
->distance_inter
)
1698 vty_out(vty
, " inter-area %u", ospf6
->distance_inter
);
1699 if (ospf6
->distance_external
)
1700 vty_out(vty
, " external %u", ospf6
->distance_external
);
1705 for (rn
= route_top(ospf6
->distance_table
); rn
; rn
= route_next(rn
))
1706 if ((odistance
= rn
->info
) != NULL
)
1707 vty_out(vty
, " distance %u %pFX %s\n",
1708 odistance
->distance
, &rn
->p
,
1709 odistance
->access_list
? odistance
->access_list
1714 /* OSPF configuration write function. */
1715 static int config_write_ospf6(struct vty
*vty
)
1717 struct ospf6
*ospf6
;
1718 struct listnode
*node
, *nnode
;
1720 /* OSPFv3 configuration. */
1724 for (ALL_LIST_ELEMENTS(om6
->ospf6
, node
, nnode
, ospf6
)) {
1725 if (ospf6
->name
&& strcmp(ospf6
->name
, VRF_DEFAULT_NAME
))
1726 vty_out(vty
, "router ospf6 vrf %s\n", ospf6
->name
);
1728 vty_out(vty
, "router ospf6\n");
1730 if (ospf6
->router_id_static
!= 0)
1731 vty_out(vty
, " ospf6 router-id %pI4\n",
1732 &ospf6
->router_id_static
);
1734 /* log-adjacency-changes flag print. */
1735 if (CHECK_FLAG(ospf6
->config_flags
,
1736 OSPF6_LOG_ADJACENCY_CHANGES
)) {
1737 if (CHECK_FLAG(ospf6
->config_flags
,
1738 OSPF6_LOG_ADJACENCY_DETAIL
))
1739 vty_out(vty
, " log-adjacency-changes detail\n");
1740 else if (!SAVE_OSPF6_LOG_ADJACENCY_CHANGES
)
1741 vty_out(vty
, " log-adjacency-changes\n");
1742 } else if (SAVE_OSPF6_LOG_ADJACENCY_CHANGES
) {
1743 vty_out(vty
, " no log-adjacency-changes\n");
1746 if (ospf6
->ref_bandwidth
!= OSPF6_REFERENCE_BANDWIDTH
)
1747 vty_out(vty
, " auto-cost reference-bandwidth %d\n",
1748 ospf6
->ref_bandwidth
);
1750 if (ospf6
->write_oi_count
1751 != OSPF6_WRITE_INTERFACE_COUNT_DEFAULT
)
1752 vty_out(vty
, " write-multiplier %d\n",
1753 ospf6
->write_oi_count
);
1755 /* LSA timers print. */
1756 if (ospf6
->lsa_minarrival
!= OSPF_MIN_LS_ARRIVAL
)
1757 vty_out(vty
, " timers lsa min-arrival %d\n",
1758 ospf6
->lsa_minarrival
);
1760 /* ECMP max path config */
1761 if (ospf6
->max_multipath
!= MULTIPATH_NUM
)
1762 vty_out(vty
, " maximum-paths %d\n",
1763 ospf6
->max_multipath
);
1765 ospf6_stub_router_config_write(vty
, ospf6
);
1766 ospf6_redistribute_config_write(vty
, ospf6
);
1767 ospf6_area_config_write(vty
, ospf6
);
1768 ospf6_spf_config_write(vty
, ospf6
);
1769 ospf6_distance_config_write(vty
, ospf6
);
1770 ospf6_distribute_config_write(vty
, ospf6
);
1772 vty_out(vty
, "!\n");
1777 static int config_write_ospf6(struct vty
*vty
);
1778 /* OSPF6 node structure. */
1779 static struct cmd_node ospf6_node
= {
1782 .parent_node
= CONFIG_NODE
,
1783 .prompt
= "%s(config-ospf6)# ",
1784 .config_write
= config_write_ospf6
,
1787 void install_element_ospf6_clear_process(void)
1789 install_element(ENABLE_NODE
, &clear_router_ospf6_cmd
);
1792 /* Install ospf related commands. */
1793 void ospf6_top_init(void)
1795 /* Install ospf6 top node. */
1796 install_node(&ospf6_node
);
1798 install_element(VIEW_NODE
, &show_ipv6_ospf6_cmd
);
1799 install_element(VIEW_NODE
, &show_ipv6_ospf6_vrfs_cmd
);
1800 install_element(CONFIG_NODE
, &router_ospf6_cmd
);
1801 install_element(CONFIG_NODE
, &no_router_ospf6_cmd
);
1803 install_element(VIEW_NODE
, &show_ipv6_ospf6_route_cmd
);
1804 install_element(VIEW_NODE
, &show_ipv6_ospf6_route_match_cmd
);
1805 install_element(VIEW_NODE
, &show_ipv6_ospf6_route_match_detail_cmd
);
1806 install_element(VIEW_NODE
, &show_ipv6_ospf6_route_type_detail_cmd
);
1808 install_default(OSPF6_NODE
);
1809 install_element(OSPF6_NODE
, &ospf6_router_id_cmd
);
1810 install_element(OSPF6_NODE
, &no_ospf6_router_id_cmd
);
1811 install_element(OSPF6_NODE
, &ospf6_log_adjacency_changes_cmd
);
1812 install_element(OSPF6_NODE
, &ospf6_log_adjacency_changes_detail_cmd
);
1813 install_element(OSPF6_NODE
, &no_ospf6_log_adjacency_changes_cmd
);
1814 install_element(OSPF6_NODE
, &no_ospf6_log_adjacency_changes_detail_cmd
);
1816 /* LSA timers commands */
1817 install_element(OSPF6_NODE
, &ospf6_timers_lsa_cmd
);
1818 install_element(OSPF6_NODE
, &no_ospf6_timers_lsa_cmd
);
1820 install_element(OSPF6_NODE
, &ospf6_interface_area_cmd
);
1821 install_element(OSPF6_NODE
, &no_ospf6_interface_area_cmd
);
1822 install_element(OSPF6_NODE
, &ospf6_stub_router_admin_cmd
);
1823 install_element(OSPF6_NODE
, &no_ospf6_stub_router_admin_cmd
);
1825 /* maximum-paths command */
1826 install_element(OSPF6_NODE
, &ospf6_max_multipath_cmd
);
1827 install_element(OSPF6_NODE
, &no_ospf6_max_multipath_cmd
);
1829 install_element(OSPF6_NODE
, &ospf6_distance_cmd
);
1830 install_element(OSPF6_NODE
, &no_ospf6_distance_cmd
);
1831 install_element(OSPF6_NODE
, &ospf6_distance_ospf6_cmd
);
1832 install_element(OSPF6_NODE
, &no_ospf6_distance_ospf6_cmd
);