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"
56 #include "ospf6_nssa.h"
57 #include "ospf6_auth_trailer.h"
59 DEFINE_MTYPE_STATIC(OSPF6D
, OSPF6_TOP
, "OSPF6 top");
61 DEFINE_QOBJ_TYPE(ospf6
);
63 FRR_CFG_DEFAULT_BOOL(OSPF6_LOG_ADJACENCY_CHANGES
,
64 { .val_bool
= true, .match_profile
= "datacenter", },
65 { .val_bool
= false },
68 #ifndef VTYSH_EXTRACT_PL
69 #include "ospf6d/ospf6_top_clippy.c"
72 /* global ospf6d variable */
73 static struct ospf6_master ospf6_master
;
74 struct ospf6_master
*om6
;
76 static void ospf6_disable(struct ospf6
*o
);
78 static void ospf6_add(struct ospf6
*ospf6
)
80 listnode_add(om6
->ospf6
, ospf6
);
83 static void ospf6_del(struct ospf6
*ospf6
)
85 listnode_delete(om6
->ospf6
, ospf6
);
88 const char *ospf6_vrf_id_to_name(vrf_id_t vrf_id
)
90 struct vrf
*vrf
= vrf_lookup_by_id(vrf_id
);
92 return vrf
? vrf
->name
: "NIL";
95 /* Link OSPF instance to VRF. */
96 void ospf6_vrf_link(struct ospf6
*ospf6
, struct vrf
*vrf
)
98 ospf6
->vrf_id
= vrf
->vrf_id
;
99 if (vrf
->info
!= (void *)ospf6
)
100 vrf
->info
= (void *)ospf6
;
103 /* Unlink OSPF instance from VRF. */
104 void ospf6_vrf_unlink(struct ospf6
*ospf6
, struct vrf
*vrf
)
106 if (vrf
->info
== (void *)ospf6
)
108 ospf6
->vrf_id
= VRF_UNKNOWN
;
111 struct ospf6
*ospf6_lookup_by_vrf_id(vrf_id_t vrf_id
)
113 struct vrf
*vrf
= NULL
;
115 vrf
= vrf_lookup_by_id(vrf_id
);
118 return (vrf
->info
) ? (struct ospf6
*)vrf
->info
: NULL
;
121 struct ospf6
*ospf6_lookup_by_vrf_name(const char *name
)
123 struct ospf6
*o
= NULL
;
124 struct listnode
*node
, *nnode
;
126 for (ALL_LIST_ELEMENTS(om6
->ospf6
, node
, nnode
, o
)) {
127 if (((o
->name
== NULL
&& name
== NULL
)
128 || (o
->name
&& name
&& strcmp(o
->name
, name
) == 0)))
134 /* This is hook function for vrf create called as part of vrf_init */
135 static int ospf6_vrf_new(struct vrf
*vrf
)
140 /* This is hook function for vrf delete call as part of vrf_init */
141 static int ospf6_vrf_delete(struct vrf
*vrf
)
146 static void ospf6_set_redist_vrf_bitmaps(struct ospf6
*ospf6
, bool set
)
149 struct list
*red_list
;
151 for (type
= 0; type
< ZEBRA_ROUTE_MAX
; type
++) {
152 red_list
= ospf6
->redist
[type
];
155 if (IS_OSPF6_DEBUG_ZEBRA(RECV
))
157 "%s: setting redist vrf %d bitmap for type %d",
158 __func__
, ospf6
->vrf_id
, type
);
160 vrf_bitmap_set(zclient
->redist
[AFI_IP6
][type
],
163 vrf_bitmap_unset(zclient
->redist
[AFI_IP6
][type
],
167 red_list
= ospf6
->redist
[DEFAULT_ROUTE
];
170 vrf_bitmap_set(zclient
->default_information
[AFI_IP6
],
173 vrf_bitmap_unset(zclient
->default_information
[AFI_IP6
],
178 /* Disable OSPF6 VRF instance */
179 static int ospf6_vrf_disable(struct vrf
*vrf
)
181 struct ospf6
*ospf6
= NULL
;
183 if (vrf
->vrf_id
== VRF_DEFAULT
)
186 ospf6
= ospf6_lookup_by_vrf_name(vrf
->name
);
188 ospf6_zebra_vrf_deregister(ospf6
);
190 ospf6_set_redist_vrf_bitmaps(ospf6
, false);
192 /* We have instance configured, unlink
193 * from VRF and make it "down".
195 ospf6_vrf_unlink(ospf6
, vrf
);
196 thread_cancel(&ospf6
->t_ospf6_receive
);
201 /* Note: This is a callback, the VRF will be deleted by the caller. */
205 /* Enable OSPF6 VRF instance */
206 static int ospf6_vrf_enable(struct vrf
*vrf
)
208 struct ospf6
*ospf6
= NULL
;
212 ospf6
= ospf6_lookup_by_vrf_name(vrf
->name
);
214 old_vrf_id
= ospf6
->vrf_id
;
215 /* We have instance configured, link to VRF and make it "up". */
216 ospf6_vrf_link(ospf6
, vrf
);
218 if (old_vrf_id
!= ospf6
->vrf_id
) {
219 ospf6_set_redist_vrf_bitmaps(ospf6
, true);
221 /* start zebra redist to us for new vrf */
222 ospf6_zebra_vrf_register(ospf6
);
224 ret
= ospf6_serv_sock(ospf6
);
225 if (ret
< 0 || ospf6
->fd
<= 0)
227 thread_add_read(master
, ospf6_receive
, ospf6
, ospf6
->fd
,
228 &ospf6
->t_ospf6_receive
);
230 ospf6_router_id_update(ospf6
, true);
237 void ospf6_vrf_init(void)
239 vrf_init(ospf6_vrf_new
, ospf6_vrf_enable
, ospf6_vrf_disable
,
245 static void ospf6_top_lsdb_hook_add(struct ospf6_lsa
*lsa
)
247 switch (ntohs(lsa
->header
->type
)) {
248 case OSPF6_LSTYPE_AS_EXTERNAL
:
249 ospf6_asbr_lsa_add(lsa
);
257 static void ospf6_top_lsdb_hook_remove(struct ospf6_lsa
*lsa
)
259 switch (ntohs(lsa
->header
->type
)) {
260 case OSPF6_LSTYPE_AS_EXTERNAL
:
261 ospf6_asbr_lsa_remove(lsa
, NULL
);
269 static void ospf6_top_route_hook_add(struct ospf6_route
*route
)
271 struct ospf6
*ospf6
= NULL
;
272 struct ospf6_area
*oa
= NULL
;
274 if (route
->table
->scope_type
== OSPF6_SCOPE_TYPE_GLOBAL
)
275 ospf6
= route
->table
->scope
;
276 else if (route
->table
->scope_type
== OSPF6_SCOPE_TYPE_AREA
) {
277 oa
= (struct ospf6_area
*)route
->table
->scope
;
280 if (IS_OSPF6_DEBUG_EXAMIN(AS_EXTERNAL
)
281 || IS_OSPF6_DEBUG_BROUTER
)
283 "%s: Route is not GLOBAL or scope is not of TYPE_AREA: %pFX",
284 __func__
, &route
->prefix
);
288 ospf6_abr_originate_summary(route
, ospf6
);
289 ospf6_zebra_route_update_add(route
, ospf6
);
292 static void ospf6_top_route_hook_remove(struct ospf6_route
*route
)
294 struct ospf6
*ospf6
= NULL
;
295 struct ospf6_area
*oa
= NULL
;
297 if (route
->table
->scope_type
== OSPF6_SCOPE_TYPE_GLOBAL
)
298 ospf6
= route
->table
->scope
;
299 else if (route
->table
->scope_type
== OSPF6_SCOPE_TYPE_AREA
) {
300 oa
= (struct ospf6_area
*)route
->table
->scope
;
303 if (IS_OSPF6_DEBUG_EXAMIN(AS_EXTERNAL
)
304 || IS_OSPF6_DEBUG_BROUTER
)
306 "%s: Route is not GLOBAL or scope is not of TYPE_AREA: %pFX",
307 __func__
, &route
->prefix
);
311 route
->flag
|= OSPF6_ROUTE_REMOVE
;
312 ospf6_abr_originate_summary(route
, ospf6
);
313 ospf6_zebra_route_update_remove(route
, ospf6
);
316 static void ospf6_top_brouter_hook_add(struct ospf6_route
*route
)
318 struct ospf6
*ospf6
= route
->table
->scope
;
320 if (IS_OSPF6_DEBUG_EXAMIN(AS_EXTERNAL
) ||
321 IS_OSPF6_DEBUG_BROUTER
) {
323 char brouter_name
[16];
325 brouter_id
= ADV_ROUTER_IN_PREFIX(&route
->prefix
);
326 inet_ntop(AF_INET
, &brouter_id
, brouter_name
,
327 sizeof(brouter_name
));
328 zlog_debug("%s: brouter %s add with adv router %x nh count %u",
329 __func__
, brouter_name
,
330 route
->path
.origin
.adv_router
,
331 listcount(route
->nh_list
));
333 ospf6_abr_examin_brouter(ADV_ROUTER_IN_PREFIX(&route
->prefix
), route
,
335 ospf6_asbr_lsentry_add(route
, ospf6
);
336 ospf6_abr_originate_summary(route
, ospf6
);
339 static void ospf6_top_brouter_hook_remove(struct ospf6_route
*route
)
341 struct ospf6
*ospf6
= route
->table
->scope
;
343 if (IS_OSPF6_DEBUG_EXAMIN(AS_EXTERNAL
) ||
344 IS_OSPF6_DEBUG_BROUTER
) {
346 char brouter_name
[16];
348 brouter_id
= ADV_ROUTER_IN_PREFIX(&route
->prefix
);
349 inet_ntop(AF_INET
, &brouter_id
, brouter_name
,
350 sizeof(brouter_name
));
351 zlog_debug("%s: brouter %p %s del with adv router %x nh %u",
352 __func__
, (void *)route
, brouter_name
,
353 route
->path
.origin
.adv_router
,
354 listcount(route
->nh_list
));
356 route
->flag
|= OSPF6_ROUTE_REMOVE
;
357 ospf6_abr_examin_brouter(ADV_ROUTER_IN_PREFIX(&route
->prefix
), route
,
359 ospf6_asbr_lsentry_remove(route
, ospf6
);
360 ospf6_abr_originate_summary(route
, ospf6
);
363 static struct ospf6
*ospf6_create(const char *name
)
366 struct vrf
*vrf
= NULL
;
368 o
= XCALLOC(MTYPE_OSPF6_TOP
, sizeof(struct ospf6
));
370 vrf
= vrf_lookup_by_name(name
);
372 o
->vrf_id
= vrf
->vrf_id
;
374 o
->vrf_id
= VRF_UNKNOWN
;
376 /* Freed in ospf6_delete */
377 o
->name
= XSTRDUP(MTYPE_OSPF6_TOP
, name
);
379 ospf6_vrf_link(o
, vrf
);
381 ospf6_zebra_vrf_register(o
);
384 monotime(&o
->starttime
);
385 o
->area_list
= list_new();
386 o
->area_list
->cmp
= ospf6_area_cmp
;
387 o
->lsdb
= ospf6_lsdb_create(o
);
388 o
->lsdb_self
= ospf6_lsdb_create(o
);
389 o
->lsdb
->hook_add
= ospf6_top_lsdb_hook_add
;
390 o
->lsdb
->hook_remove
= ospf6_top_lsdb_hook_remove
;
392 o
->spf_delay
= OSPF_SPF_DELAY_DEFAULT
;
393 o
->spf_holdtime
= OSPF_SPF_HOLDTIME_DEFAULT
;
394 o
->spf_max_holdtime
= OSPF_SPF_MAX_HOLDTIME_DEFAULT
;
395 o
->spf_hold_multiplier
= 1;
397 o
->default_originate
= DEFAULT_ORIGINATE_NONE
;
399 /* LSA timers value init */
400 o
->lsa_minarrival
= OSPF_MIN_LS_ARRIVAL
;
402 o
->route_table
= OSPF6_ROUTE_TABLE_CREATE(GLOBAL
, ROUTES
);
403 o
->route_table
->scope
= o
;
404 o
->route_table
->hook_add
= ospf6_top_route_hook_add
;
405 o
->route_table
->hook_remove
= ospf6_top_route_hook_remove
;
407 o
->brouter_table
= OSPF6_ROUTE_TABLE_CREATE(GLOBAL
, BORDER_ROUTERS
);
408 o
->brouter_table
->scope
= o
;
409 o
->brouter_table
->hook_add
= ospf6_top_brouter_hook_add
;
410 o
->brouter_table
->hook_remove
= ospf6_top_brouter_hook_remove
;
412 o
->external_table
= OSPF6_ROUTE_TABLE_CREATE(GLOBAL
, EXTERNAL_ROUTES
);
413 o
->external_table
->scope
= o
;
414 /* Setting this to 1, so that the LS ID 0 can be considered as invalid
415 * for self originated external LSAs. This helps in differentiating if
416 * an LSA is originated for any route or not in the route data.
417 * rt->route_option->id is by default 0
418 * Consider a route having id as 0 and prefix as 1::1, an external LSA
419 * is originated with ID 0.0.0.0. Now consider another route 2::2
420 * and for this LSA was not originated because of some configuration
421 * but the ID field rt->route_option->id is still 0.Consider now this
422 * 2::2 is being deleted, it will search LSA with LS ID as 0 and it
423 * will find the LSA and hence delete it but the LSA belonged to prefix
424 * 1::1, this happened because of LS ID 0.
426 o
->external_id
= OSPF6_EXT_INIT_LS_ID
;
428 o
->write_oi_count
= OSPF6_WRITE_INTERFACE_COUNT_DEFAULT
;
429 o
->ref_bandwidth
= OSPF6_REFERENCE_BANDWIDTH
;
431 o
->distance_table
= route_table_init();
433 o
->rt_aggr_tbl
= route_table_init();
434 o
->aggr_delay_interval
= OSPF6_EXTL_AGGR_DEFAULT_DELAY
;
435 o
->aggr_action
= OSPF6_ROUTE_AGGR_NONE
;
439 o
->max_multipath
= MULTIPATH_NUM
;
441 o
->oi_write_q
= list_new();
443 ospf6_gr_helper_init(o
);
446 /* Make ospf protocol socket. */
449 /* If sequence number is stored in persistent storage, read it.
451 if (ospf6_auth_nvm_file_exist() == OSPF6_AUTH_FILE_EXIST
) {
452 ospf6_auth_seqno_nvm_read(o
);
453 o
->seqnum_h
= o
->seqnum_h
+ 1;
454 ospf6_auth_seqno_nvm_update(o
);
456 o
->seqnum_l
= o
->seqnum_h
= 0;
457 ospf6_auth_seqno_nvm_update(o
);
463 struct ospf6
*ospf6_instance_create(const char *name
)
467 struct interface
*ifp
;
469 ospf6
= ospf6_create(name
);
470 if (DFLT_OSPF6_LOG_ADJACENCY_CHANGES
)
471 SET_FLAG(ospf6
->config_flags
, OSPF6_LOG_ADJACENCY_CHANGES
);
472 if (ospf6
->router_id
== 0)
473 ospf6_router_id_update(ospf6
, true);
475 if (ospf6
->vrf_id
!= VRF_UNKNOWN
) {
476 vrf
= vrf_lookup_by_id(ospf6
->vrf_id
);
477 FOR_ALL_INTERFACES (vrf
, ifp
) {
479 ospf6_interface_start(ifp
->info
);
486 * Read from non-volatile memory whether this instance is performing a
487 * graceful restart or not.
489 ospf6_gr_nvm_read(ospf6
);
491 thread_add_read(master
, ospf6_receive
, ospf6
, ospf6
->fd
,
492 &ospf6
->t_ospf6_receive
);
497 void ospf6_delete(struct ospf6
*o
)
499 struct listnode
*node
, *nnode
;
500 struct route_node
*rn
= NULL
;
501 struct ospf6_area
*oa
;
506 ospf6_gr_helper_deinit(o
);
507 if (!o
->gr_info
.prepare_in_progress
)
508 ospf6_flush_self_originated_lsas_now(o
);
512 ospf6_zebra_vrf_deregister(o
);
514 ospf6_serv_close(&o
->fd
);
516 for (ALL_LIST_ELEMENTS(o
->area_list
, node
, nnode
, oa
))
517 ospf6_area_delete(oa
);
520 list_delete(&o
->area_list
);
522 ospf6_lsdb_delete(o
->lsdb
);
523 ospf6_lsdb_delete(o
->lsdb_self
);
525 ospf6_route_table_delete(o
->route_table
);
526 ospf6_route_table_delete(o
->brouter_table
);
528 ospf6_route_table_delete(o
->external_table
);
530 ospf6_distance_reset(o
);
531 route_table_finish(o
->distance_table
);
532 list_delete(&o
->oi_write_q
);
534 if (o
->vrf_id
!= VRF_UNKNOWN
) {
535 vrf
= vrf_lookup_by_id(o
->vrf_id
);
537 ospf6_vrf_unlink(o
, vrf
);
540 for (rn
= route_top(o
->rt_aggr_tbl
); rn
; rn
= route_next(rn
))
542 ospf6_external_aggregator_free(rn
->info
);
543 route_table_finish(o
->rt_aggr_tbl
);
545 XFREE(MTYPE_OSPF6_TOP
, o
->name
);
546 XFREE(MTYPE_OSPF6_TOP
, o
);
549 static void ospf6_disable(struct ospf6
*o
)
551 struct listnode
*node
, *nnode
;
552 struct ospf6_area
*oa
;
554 if (!CHECK_FLAG(o
->flag
, OSPF6_DISABLED
)) {
555 SET_FLAG(o
->flag
, OSPF6_DISABLED
);
557 for (ALL_LIST_ELEMENTS(o
->area_list
, node
, nnode
, oa
))
558 ospf6_area_disable(oa
);
560 /* XXX: This also changes persistent settings */
561 /* Unregister redistribution */
562 ospf6_asbr_redistribute_disable(o
);
564 ospf6_lsdb_remove_all(o
->lsdb
);
565 ospf6_route_remove_all(o
->route_table
);
566 ospf6_route_remove_all(o
->brouter_table
);
568 THREAD_OFF(o
->maxage_remover
);
569 THREAD_OFF(o
->t_spf_calc
);
570 THREAD_OFF(o
->t_ase_calc
);
571 THREAD_OFF(o
->t_distribute_update
);
572 THREAD_OFF(o
->t_ospf6_receive
);
573 THREAD_OFF(o
->t_external_aggr
);
574 THREAD_OFF(o
->gr_info
.t_grace_period
);
575 THREAD_OFF(o
->t_write
);
576 THREAD_OFF(o
->t_abr_task
);
580 void ospf6_master_init(struct thread_master
*master
)
582 memset(&ospf6_master
, 0, sizeof(struct ospf6_master
));
585 om6
->ospf6
= list_new();
586 om6
->master
= master
;
589 static void ospf6_maxage_remover(struct thread
*thread
)
591 struct ospf6
*o
= (struct ospf6
*)THREAD_ARG(thread
);
592 struct ospf6_area
*oa
;
593 struct ospf6_interface
*oi
;
594 struct ospf6_neighbor
*on
;
595 struct listnode
*i
, *j
, *k
;
598 for (ALL_LIST_ELEMENTS_RO(o
->area_list
, i
, oa
)) {
599 for (ALL_LIST_ELEMENTS_RO(oa
->if_list
, j
, oi
)) {
600 for (ALL_LIST_ELEMENTS_RO(oi
->neighbor_list
, k
, on
)) {
601 if (on
->state
!= OSPF6_NEIGHBOR_EXCHANGE
602 && on
->state
!= OSPF6_NEIGHBOR_LOADING
)
605 ospf6_maxage_remove(o
);
611 for (ALL_LIST_ELEMENTS_RO(o
->area_list
, i
, oa
)) {
612 for (ALL_LIST_ELEMENTS_RO(oa
->if_list
, j
, oi
)) {
613 if (ospf6_lsdb_maxage_remover(oi
->lsdb
)) {
618 if (ospf6_lsdb_maxage_remover(oa
->lsdb
)) {
623 if (ospf6_lsdb_maxage_remover(o
->lsdb
)) {
628 ospf6_maxage_remove(o
);
632 void ospf6_maxage_remove(struct ospf6
*o
)
635 thread_add_timer(master
, ospf6_maxage_remover
, o
,
636 OSPF_LSA_MAXAGE_REMOVE_DELAY_DEFAULT
,
640 bool ospf6_router_id_update(struct ospf6
*ospf6
, bool init
)
642 in_addr_t new_router_id
;
643 struct listnode
*node
;
644 struct ospf6_area
*oa
;
649 if (ospf6
->router_id_static
!= 0)
650 new_router_id
= ospf6
->router_id_static
;
652 new_router_id
= ospf6
->router_id_zebra
;
654 if (ospf6
->router_id
== new_router_id
)
658 for (ALL_LIST_ELEMENTS_RO(ospf6
->area_list
, node
, oa
)) {
661 "%s: cannot update router-id. Run the \"clear ipv6 ospf6 process\" command",
667 ospf6
->router_id
= new_router_id
;
672 DEFUN_NOSH(router_ospf6
, router_ospf6_cmd
, "router ospf6 [vrf NAME]",
673 ROUTER_STR OSPF6_STR VRF_CMD_HELP_STR
)
676 const char *vrf_name
= VRF_DEFAULT_NAME
;
679 if (argv_find(argv
, argc
, "vrf", &idx_vrf
)) {
680 vrf_name
= argv
[idx_vrf
+ 1]->arg
;
683 ospf6
= ospf6_lookup_by_vrf_name(vrf_name
);
685 ospf6
= ospf6_instance_create(vrf_name
);
687 /* set current ospf point. */
688 VTY_PUSH_CONTEXT(OSPF6_NODE
, ospf6
);
694 DEFUN(no_router_ospf6
, no_router_ospf6_cmd
, "no router ospf6 [vrf NAME]",
695 NO_STR ROUTER_STR OSPF6_STR VRF_CMD_HELP_STR
)
698 const char *vrf_name
= VRF_DEFAULT_NAME
;
701 if (argv_find(argv
, argc
, "vrf", &idx_vrf
)) {
702 vrf_name
= argv
[idx_vrf
+ 1]->arg
;
705 ospf6
= ospf6_lookup_by_vrf_name(vrf_name
);
707 vty_out(vty
, "OSPFv3 is not configured\n");
713 /* return to config node . */
714 VTY_PUSH_CONTEXT_NULL(CONFIG_NODE
);
719 static void ospf6_db_clear(struct ospf6
*ospf6
)
721 struct ospf6_interface
*oi
;
722 struct interface
*ifp
;
723 struct vrf
*vrf
= vrf_lookup_by_id(ospf6
->vrf_id
);
724 struct listnode
*node
, *nnode
;
725 struct ospf6_area
*oa
;
727 FOR_ALL_INTERFACES (vrf
, ifp
) {
728 if (if_is_operative(ifp
) && ifp
->info
!= NULL
) {
729 oi
= (struct ospf6_interface
*)ifp
->info
;
730 ospf6_lsdb_remove_all(oi
->lsdb
);
731 ospf6_lsdb_remove_all(oi
->lsdb_self
);
732 ospf6_lsdb_remove_all(oi
->lsupdate_list
);
733 ospf6_lsdb_remove_all(oi
->lsack_list
);
737 for (ALL_LIST_ELEMENTS(ospf6
->area_list
, node
, nnode
, oa
)) {
738 ospf6_lsdb_remove_all(oa
->lsdb
);
739 ospf6_lsdb_remove_all(oa
->lsdb_self
);
741 ospf6_spf_table_finish(oa
->spf_table
);
742 ospf6_route_remove_all(oa
->route_table
);
745 ospf6_lsdb_remove_all(ospf6
->lsdb
);
746 ospf6_lsdb_remove_all(ospf6
->lsdb_self
);
747 ospf6_route_remove_all(ospf6
->route_table
);
748 ospf6_route_remove_all(ospf6
->brouter_table
);
751 static void ospf6_process_reset(struct ospf6
*ospf6
)
753 struct interface
*ifp
;
754 struct vrf
*vrf
= vrf_lookup_by_id(ospf6
->vrf_id
);
756 ospf6_unset_all_aggr_flag(ospf6
);
757 ospf6_flush_self_originated_lsas_now(ospf6
);
758 ospf6
->inst_shutdown
= 0;
759 ospf6_db_clear(ospf6
);
761 ospf6_asbr_redistribute_reset(ospf6
);
762 FOR_ALL_INTERFACES (vrf
, ifp
)
763 ospf6_interface_clear(ifp
);
766 DEFPY (clear_router_ospf6
,
767 clear_router_ospf6_cmd
,
768 "clear ipv6 ospf6 process [vrf NAME$name]",
772 "Reset OSPF Process\n"
776 const char *vrf_name
= VRF_DEFAULT_NAME
;
781 ospf6
= ospf6_lookup_by_vrf_name(vrf_name
);
783 vty_out(vty
, "OSPFv3 is not configured\n");
785 ospf6_router_id_update(ospf6
, true);
786 ospf6_process_reset(ospf6
);
792 /* change Router_ID commands. */
793 DEFUN(ospf6_router_id
,
795 "ospf6 router-id A.B.C.D",
797 "Configure OSPF6 Router-ID\n"
800 VTY_DECLVAR_CONTEXT(ospf6
, o
);
803 const char *router_id_str
;
806 argv_find(argv
, argc
, "A.B.C.D", &idx
);
807 router_id_str
= argv
[idx
]->arg
;
809 ret
= inet_pton(AF_INET
, router_id_str
, &router_id
);
811 vty_out(vty
, "malformed OSPF Router-ID: %s\n", router_id_str
);
815 o
->router_id_static
= router_id
;
817 if (ospf6_router_id_update(o
, false))
818 ospf6_process_reset(o
);
821 "For this router-id change to take effect run the \"clear ipv6 ospf6 process\" command\n");
826 DEFUN(no_ospf6_router_id
,
827 no_ospf6_router_id_cmd
,
828 "no ospf6 router-id [A.B.C.D]",
830 "Configure OSPF6 Router-ID\n"
833 VTY_DECLVAR_CONTEXT(ospf6
, o
);
835 o
->router_id_static
= 0;
838 if (ospf6_router_id_update(o
, false))
839 ospf6_process_reset(o
);
842 "For this router-id change to take effect run the \"clear ipv6 ospf6 process\" command\n");
847 DEFUN (ospf6_log_adjacency_changes
,
848 ospf6_log_adjacency_changes_cmd
,
849 "log-adjacency-changes",
850 "Log changes in adjacency state\n")
852 VTY_DECLVAR_CONTEXT(ospf6
, ospf6
);
854 SET_FLAG(ospf6
->config_flags
, OSPF6_LOG_ADJACENCY_CHANGES
);
855 UNSET_FLAG(ospf6
->config_flags
, OSPF6_LOG_ADJACENCY_DETAIL
);
859 DEFUN (ospf6_log_adjacency_changes_detail
,
860 ospf6_log_adjacency_changes_detail_cmd
,
861 "log-adjacency-changes detail",
862 "Log changes in adjacency state\n"
863 "Log all state changes\n")
865 VTY_DECLVAR_CONTEXT(ospf6
, ospf6
);
867 SET_FLAG(ospf6
->config_flags
, OSPF6_LOG_ADJACENCY_CHANGES
);
868 SET_FLAG(ospf6
->config_flags
, OSPF6_LOG_ADJACENCY_DETAIL
);
872 DEFUN (no_ospf6_log_adjacency_changes
,
873 no_ospf6_log_adjacency_changes_cmd
,
874 "no log-adjacency-changes",
876 "Log changes in adjacency state\n")
878 VTY_DECLVAR_CONTEXT(ospf6
, ospf6
);
880 UNSET_FLAG(ospf6
->config_flags
, OSPF6_LOG_ADJACENCY_DETAIL
);
881 UNSET_FLAG(ospf6
->config_flags
, OSPF6_LOG_ADJACENCY_CHANGES
);
885 DEFUN (no_ospf6_log_adjacency_changes_detail
,
886 no_ospf6_log_adjacency_changes_detail_cmd
,
887 "no log-adjacency-changes detail",
889 "Log changes in adjacency state\n"
890 "Log all state changes\n")
892 VTY_DECLVAR_CONTEXT(ospf6
, ospf6
);
894 UNSET_FLAG(ospf6
->config_flags
, OSPF6_LOG_ADJACENCY_DETAIL
);
898 static void ospf6_reinstall_routes(struct ospf6
*ospf6
)
900 struct ospf6_route
*route
;
902 for (route
= ospf6_route_head(ospf6
->route_table
); route
;
903 route
= ospf6_route_next(route
))
904 ospf6_zebra_route_update_add(route
, ospf6
);
907 DEFPY (ospf6_send_extra_data
,
908 ospf6_send_extra_data_cmd
,
909 "[no] ospf6 send-extra-data zebra",
912 "Extra data to Zebra for display/use\n"
915 VTY_DECLVAR_CONTEXT(ospf6
, ospf6
);
918 && CHECK_FLAG(ospf6
->config_flags
,
919 OSPF6_SEND_EXTRA_DATA_TO_ZEBRA
)) {
920 UNSET_FLAG(ospf6
->config_flags
, OSPF6_SEND_EXTRA_DATA_TO_ZEBRA
);
921 ospf6_reinstall_routes(ospf6
);
922 } else if (!CHECK_FLAG(ospf6
->config_flags
,
923 OSPF6_SEND_EXTRA_DATA_TO_ZEBRA
)) {
924 SET_FLAG(ospf6
->config_flags
, OSPF6_SEND_EXTRA_DATA_TO_ZEBRA
);
925 ospf6_reinstall_routes(ospf6
);
931 DEFUN (ospf6_timers_lsa
,
932 ospf6_timers_lsa_cmd
,
933 "timers lsa min-arrival (0-600000)",
934 "Adjust routing timers\n"
936 "Minimum delay in receiving new version of a LSA\n"
937 "Delay in milliseconds\n")
939 VTY_DECLVAR_CONTEXT(ospf6
, ospf
);
941 unsigned int minarrival
;
943 minarrival
= strtoul(argv
[idx_number
]->arg
, NULL
, 10);
944 ospf
->lsa_minarrival
= minarrival
;
949 DEFUN (no_ospf6_timers_lsa
,
950 no_ospf6_timers_lsa_cmd
,
951 "no timers lsa min-arrival [(0-600000)]",
953 "Adjust routing timers\n"
955 "Minimum delay in receiving new version of a LSA\n"
956 "Delay in milliseconds\n")
958 VTY_DECLVAR_CONTEXT(ospf6
, ospf
);
960 unsigned int minarrival
;
963 minarrival
= strtoul(argv
[idx_number
]->arg
, NULL
, 10);
965 if (ospf
->lsa_minarrival
!= minarrival
966 || minarrival
== OSPF_MIN_LS_ARRIVAL
)
970 ospf
->lsa_minarrival
= OSPF_MIN_LS_ARRIVAL
;
976 DEFUN (ospf6_distance
,
979 "Administrative distance\n"
980 "OSPF6 Administrative distance\n")
982 VTY_DECLVAR_CONTEXT(ospf6
, o
);
985 distance
= atoi(argv
[1]->arg
);
986 if (o
->distance_all
!= distance
) {
987 o
->distance_all
= distance
;
988 ospf6_restart_spf(o
);
994 DEFUN (no_ospf6_distance
,
995 no_ospf6_distance_cmd
,
996 "no distance (1-255)",
998 "Administrative distance\n"
999 "OSPF6 Administrative distance\n")
1001 VTY_DECLVAR_CONTEXT(ospf6
, o
);
1003 if (o
->distance_all
) {
1004 o
->distance_all
= 0;
1005 ospf6_restart_spf(o
);
1010 DEFUN (ospf6_distance_ospf6
,
1011 ospf6_distance_ospf6_cmd
,
1012 "distance ospf6 {intra-area (1-255)|inter-area (1-255)|external (1-255)}",
1013 "Administrative distance\n"
1014 "OSPF6 administrative distance\n"
1015 "Intra-area routes\n"
1016 "Distance for intra-area routes\n"
1017 "Inter-area routes\n"
1018 "Distance for inter-area routes\n"
1020 "Distance for external routes\n")
1022 VTY_DECLVAR_CONTEXT(ospf6
, o
);
1025 o
->distance_intra
= 0;
1026 o
->distance_inter
= 0;
1027 o
->distance_external
= 0;
1029 if (argv_find(argv
, argc
, "intra-area", &idx
))
1030 o
->distance_intra
= atoi(argv
[idx
+ 1]->arg
);
1032 if (argv_find(argv
, argc
, "inter-area", &idx
))
1033 o
->distance_inter
= atoi(argv
[idx
+ 1]->arg
);
1035 if (argv_find(argv
, argc
, "external", &idx
))
1036 o
->distance_external
= atoi(argv
[idx
+ 1]->arg
);
1041 DEFUN (no_ospf6_distance_ospf6
,
1042 no_ospf6_distance_ospf6_cmd
,
1043 "no distance ospf6 [{intra-area [(1-255)]|inter-area [(1-255)]|external [(1-255)]}]",
1045 "Administrative distance\n"
1047 "Intra-area routes\n"
1048 "Distance for intra-area routes\n"
1049 "Inter-area routes\n"
1050 "Distance for inter-area routes\n"
1052 "Distance for external routes\n")
1054 VTY_DECLVAR_CONTEXT(ospf6
, o
);
1057 if (argv_find(argv
, argc
, "intra-area", &idx
) || argc
== 3)
1058 idx
= o
->distance_intra
= 0;
1059 if (argv_find(argv
, argc
, "inter-area", &idx
) || argc
== 3)
1060 idx
= o
->distance_inter
= 0;
1061 if (argv_find(argv
, argc
, "external", &idx
) || argc
== 3)
1062 o
->distance_external
= 0;
1067 DEFUN_HIDDEN (ospf6_interface_area
,
1068 ospf6_interface_area_cmd
,
1069 "interface IFNAME area <A.B.C.D|(0-4294967295)>",
1070 "Enable 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_area
*oa
;
1081 struct ospf6_interface
*oi
;
1082 struct interface
*ifp
;
1087 "This command is deprecated, because it is not VRF-aware.\n");
1089 "Please, use \"ipv6 ospf6 area\" on an interface instead.\n");
1091 /* find/create ospf6 interface */
1092 ifp
= if_get_by_name(argv
[idx_ifname
]->arg
, ospf6
->vrf_id
, ospf6
->name
);
1093 oi
= (struct ospf6_interface
*)ifp
->info
;
1095 oi
= ospf6_interface_create(ifp
);
1097 vty_out(vty
, "%s already attached to Area %s\n",
1098 oi
->interface
->name
, oi
->area
->name
);
1102 if (str2area_id(argv
[idx_ipv4
]->arg
, &area_id
, &format
)) {
1103 vty_out(vty
, "Malformed Area-ID: %s\n", argv
[idx_ipv4
]->arg
);
1104 return CMD_WARNING_CONFIG_FAILED
;
1107 oi
->area_id
= area_id
;
1108 oi
->area_id_format
= format
;
1110 oa
= ospf6_area_lookup(area_id
, ospf6
);
1112 oa
= ospf6_area_create(area_id
, ospf6
, format
);
1114 /* attach interface to area */
1115 listnode_add(oa
->if_list
, oi
); /* sort ?? */
1118 SET_FLAG(oa
->flag
, OSPF6_AREA_ENABLE
);
1120 /* ospf6 process is currently disabled, not much more to do */
1121 if (CHECK_FLAG(ospf6
->flag
, OSPF6_DISABLED
))
1125 ospf6_interface_enable(oi
);
1127 /* If the router is ABR, originate summary routes */
1128 if (ospf6_check_and_set_router_abr(ospf6
)) {
1129 ospf6_abr_enable_area(oa
);
1130 ospf6_schedule_abr_task(oa
->ospf6
);
1136 DEFUN_HIDDEN (no_ospf6_interface_area
,
1137 no_ospf6_interface_area_cmd
,
1138 "no interface IFNAME area <A.B.C.D|(0-4294967295)>",
1140 "Disable routing on an IPv6 interface\n"
1142 "Specify the OSPF6 area ID\n"
1143 "OSPF6 area ID in IPv4 address notation\n"
1144 "OSPF6 area ID in decimal notation\n"
1147 VTY_DECLVAR_CONTEXT(ospf6
, ospf6
);
1150 struct ospf6_interface
*oi
;
1151 struct ospf6_area
*oa
;
1152 struct interface
*ifp
;
1156 "This command is deprecated, because it is not VRF-aware.\n");
1158 "Please, use \"no ipv6 ospf6 area\" on an interface instead.\n");
1160 /* find/create ospf6 interface */
1161 ifp
= if_get_by_name(argv
[idx_ifname
]->arg
, ospf6
->vrf_id
, ospf6
->name
);
1164 vty_out(vty
, "No such interface %s\n", argv
[idx_ifname
]->arg
);
1168 oi
= (struct ospf6_interface
*)ifp
->info
;
1170 vty_out(vty
, "Interface %s not enabled\n", ifp
->name
);
1175 if (inet_pton(AF_INET
, argv
[idx_ipv4
]->arg
, &area_id
) != 1)
1176 area_id
= htonl(strtoul(argv
[idx_ipv4
]->arg
, NULL
, 10));
1179 if (oi
->area
== NULL
) {
1180 vty_out(vty
, "%s not attached to area %s\n",
1181 oi
->interface
->name
, argv
[idx_ipv4
]->arg
);
1185 if (oi
->area
->area_id
!= area_id
) {
1186 vty_out(vty
, "Wrong Area-ID: %s is attached to area %s\n",
1187 oi
->interface
->name
, oi
->area
->name
);
1191 ospf6_interface_disable(oi
);
1194 listnode_delete(oi
->area
->if_list
, oi
);
1195 oi
->area
= (struct ospf6_area
*)NULL
;
1197 /* Withdraw inter-area routes from this area, if necessary */
1198 if (oa
->if_list
->count
== 0) {
1199 UNSET_FLAG(oa
->flag
, OSPF6_AREA_ENABLE
);
1200 ospf6_abr_disable_area(oa
);
1204 oi
->area_id_format
= OSPF6_AREA_FMT_UNSET
;
1209 DEFUN (ospf6_stub_router_admin
,
1210 ospf6_stub_router_admin_cmd
,
1211 "stub-router administrative",
1212 "Make router a stub router\n"
1213 "Administratively applied, for an indefinite period\n")
1215 struct listnode
*node
;
1216 struct ospf6_area
*oa
;
1218 VTY_DECLVAR_CONTEXT(ospf6
, ospf6
);
1220 if (!CHECK_FLAG(ospf6
->flag
, OSPF6_STUB_ROUTER
)) {
1221 for (ALL_LIST_ELEMENTS_RO(ospf6
->area_list
, node
, oa
)) {
1222 OSPF6_OPT_CLEAR(oa
->options
, OSPF6_OPT_V6
);
1223 OSPF6_OPT_CLEAR(oa
->options
, OSPF6_OPT_R
);
1224 OSPF6_ROUTER_LSA_SCHEDULE(oa
);
1226 SET_FLAG(ospf6
->flag
, OSPF6_STUB_ROUTER
);
1232 DEFUN (no_ospf6_stub_router_admin
,
1233 no_ospf6_stub_router_admin_cmd
,
1234 "no stub-router administrative",
1236 "Make router a stub router\n"
1237 "Administratively applied, for an indefinite period\n")
1239 struct listnode
*node
;
1240 struct ospf6_area
*oa
;
1242 VTY_DECLVAR_CONTEXT(ospf6
, ospf6
);
1243 if (CHECK_FLAG(ospf6
->flag
, OSPF6_STUB_ROUTER
)) {
1244 for (ALL_LIST_ELEMENTS_RO(ospf6
->area_list
, node
, oa
)) {
1245 OSPF6_OPT_SET(oa
->options
, OSPF6_OPT_V6
);
1246 OSPF6_OPT_SET(oa
->options
, OSPF6_OPT_R
);
1247 OSPF6_ROUTER_LSA_SCHEDULE(oa
);
1249 UNSET_FLAG(ospf6
->flag
, OSPF6_STUB_ROUTER
);
1255 /* Restart OSPF SPF algorithm*/
1256 void ospf6_restart_spf(struct ospf6
*ospf6
)
1258 ospf6_route_remove_all(ospf6
->route_table
);
1259 ospf6_route_remove_all(ospf6
->brouter_table
);
1262 ospf6_spf_schedule(ospf6
, OSPF6_SPF_FLAGS_CONFIG_CHANGE
);
1265 /* Set the max paths */
1266 static void ospf6_maxpath_set(struct ospf6
*ospf6
, uint16_t paths
)
1268 if (ospf6
->max_multipath
== paths
)
1271 ospf6
->max_multipath
= paths
;
1273 /* Send deletion to zebra to delete all
1274 * ospf specific routes and reinitiate
1275 * SPF to reflect the new max multipath.
1277 ospf6_restart_spf(ospf6
);
1280 /* Ospf Maximum-paths config support */
1281 DEFUN(ospf6_max_multipath
,
1282 ospf6_max_multipath_cmd
,
1283 "maximum-paths " CMD_RANGE_STR(1, MULTIPATH_NUM
),
1284 "Max no of multiple paths for ECMP support\n"
1285 "Number of paths\n")
1287 VTY_DECLVAR_CONTEXT(ospf6
, ospf6
);
1289 int maximum_paths
= strtol(argv
[idx_number
]->arg
, NULL
, 10);
1291 ospf6_maxpath_set(ospf6
, maximum_paths
);
1296 DEFUN(no_ospf6_max_multipath
,
1297 no_ospf6_max_multipath_cmd
,
1298 "no maximum-paths [" CMD_RANGE_STR(1, MULTIPATH_NUM
)"]",
1300 "Max no of multiple paths for ECMP support\n"
1301 "Number of paths\n")
1303 VTY_DECLVAR_CONTEXT(ospf6
, ospf6
);
1305 ospf6_maxpath_set(ospf6
, MULTIPATH_NUM
);
1310 static void ospf6_show(struct vty
*vty
, struct ospf6
*o
, json_object
*json
,
1314 struct ospf6_area
*oa
;
1315 char router_id
[16], duration
[32];
1316 struct timeval now
, running
, result
;
1317 char buf
[32], rbuf
[32];
1318 json_object
*json_areas
= NULL
;
1319 const char *adjacency
;
1322 json_areas
= json_object_new_object();
1324 /* process id, router id */
1325 inet_ntop(AF_INET
, &o
->router_id
, router_id
, sizeof(router_id
));
1326 json_object_string_add(json
, "routerId", router_id
);
1330 timersub(&now
, &o
->starttime
, &running
);
1331 timerstring(&running
, duration
, sizeof(duration
));
1332 json_object_string_add(json
, "running", duration
);
1334 /* Redistribute configuration */
1336 json_object_int_add(json
, "lsaMinimumArrivalMsecs",
1339 /* Show SPF parameters */
1340 json_object_int_add(json
, "spfScheduleDelayMsecs",
1342 json_object_int_add(json
, "holdTimeMinMsecs", o
->spf_holdtime
);
1343 json_object_int_add(json
, "holdTimeMaxMsecs",
1344 o
->spf_max_holdtime
);
1345 json_object_int_add(json
, "holdTimeMultiplier",
1346 o
->spf_hold_multiplier
);
1348 json_object_int_add(json
, "maximumPaths", o
->max_multipath
);
1349 json_object_int_add(json
, "preference",
1352 : ZEBRA_OSPF6_DISTANCE_DEFAULT
);
1354 if (o
->ts_spf
.tv_sec
|| o
->ts_spf
.tv_usec
) {
1355 timersub(&now
, &o
->ts_spf
, &result
);
1356 timerstring(&result
, buf
, sizeof(buf
));
1357 ospf6_spf_reason_string(o
->last_spf_reason
, rbuf
,
1359 json_object_boolean_true_add(json
, "spfHasRun");
1360 json_object_string_add(json
, "spfLastExecutedMsecs",
1362 json_object_string_add(json
, "spfLastExecutedReason",
1365 json_object_int_add(
1366 json
, "spfLastDurationSecs",
1367 (long long)o
->ts_spf_duration
.tv_sec
);
1369 json_object_int_add(
1370 json
, "spfLastDurationMsecs",
1371 (long long)o
->ts_spf_duration
.tv_usec
);
1373 json_object_boolean_false_add(json
, "spfHasRun");
1376 threadtimer_string(now
, o
->t_spf_calc
, buf
, sizeof(buf
));
1377 if (o
->t_spf_calc
) {
1380 json_object_boolean_true_add(json
, "spfTimerActive");
1382 monotime_until(&o
->t_spf_calc
->u
.sands
, NULL
)
1384 json_object_int_add(json
, "spfTimerDueInMsecs",
1387 json_object_boolean_false_add(json
, "spfTimerActive");
1389 json_object_boolean_add(json
, "routerIsStubRouter",
1390 CHECK_FLAG(o
->flag
, OSPF6_STUB_ROUTER
));
1393 json_object_int_add(json
, "numberOfAsScopedLsa",
1396 json_object_int_add(json
, "numberOfAreaInRouter",
1397 listcount(o
->area_list
));
1399 json_object_int_add(json
, "AuthTrailerHigherSeqNo",
1401 json_object_int_add(json
, "AuthTrailerLowerSeqNo", o
->seqnum_l
);
1403 if (CHECK_FLAG(o
->config_flags
, OSPF6_LOG_ADJACENCY_CHANGES
)) {
1404 if (CHECK_FLAG(o
->config_flags
,
1405 OSPF6_LOG_ADJACENCY_DETAIL
))
1406 adjacency
= "LoggedAll";
1408 adjacency
= "Logged";
1410 adjacency
= "NotLogged";
1411 json_object_string_add(json
, "adjacencyChanges", adjacency
);
1413 for (ALL_LIST_ELEMENTS_RO(o
->area_list
, n
, oa
))
1414 ospf6_area_show(vty
, oa
, json_areas
, use_json
);
1416 json_object_object_add(json
, "areas", json_areas
);
1418 vty_out(vty
, "%s\n",
1419 json_object_to_json_string_ext(
1420 json
, JSON_C_TO_STRING_PRETTY
));
1423 /* process id, router id */
1424 inet_ntop(AF_INET
, &o
->router_id
, router_id
, sizeof(router_id
));
1425 vty_out(vty
, " OSPFv3 Routing Process (0) with Router-ID %s\n",
1430 timersub(&now
, &o
->starttime
, &running
);
1431 timerstring(&running
, duration
, sizeof(duration
));
1432 vty_out(vty
, " Running %s\n", duration
);
1434 /* Redistribute configuration */
1436 vty_out(vty
, " LSA minimum arrival %d msecs\n",
1439 vty_out(vty
, " Maximum-paths %u\n", o
->max_multipath
);
1440 vty_out(vty
, " Administrative distance %u\n",
1441 o
->distance_all
? o
->distance_all
1442 : ZEBRA_OSPF6_DISTANCE_DEFAULT
);
1444 /* Show SPF parameters */
1446 " Initial SPF scheduling delay %d millisec(s)\n"
1447 " Minimum hold time between consecutive SPFs %d millsecond(s)\n"
1448 " Maximum hold time between consecutive SPFs %d millsecond(s)\n"
1449 " Hold time multiplier is currently %d\n",
1450 o
->spf_delay
, o
->spf_holdtime
, o
->spf_max_holdtime
,
1451 o
->spf_hold_multiplier
);
1454 vty_out(vty
, " SPF algorithm ");
1455 if (o
->ts_spf
.tv_sec
|| o
->ts_spf
.tv_usec
) {
1456 timersub(&now
, &o
->ts_spf
, &result
);
1457 timerstring(&result
, buf
, sizeof(buf
));
1458 ospf6_spf_reason_string(o
->last_spf_reason
, rbuf
,
1460 vty_out(vty
, "last executed %s ago, reason %s\n", buf
,
1462 vty_out(vty
, " Last SPF duration %lld sec %lld usec\n",
1463 (long long)o
->ts_spf_duration
.tv_sec
,
1464 (long long)o
->ts_spf_duration
.tv_usec
);
1466 vty_out(vty
, "has not been run\n");
1468 threadtimer_string(now
, o
->t_spf_calc
, buf
, sizeof(buf
));
1469 vty_out(vty
, " SPF timer %s%s\n",
1470 (o
->t_spf_calc
? "due in " : "is "), buf
);
1472 if (CHECK_FLAG(o
->flag
, OSPF6_STUB_ROUTER
))
1473 vty_out(vty
, " Router Is Stub Router\n");
1476 vty_out(vty
, " Number of AS scoped LSAs is %u\n",
1480 vty_out(vty
, " Number of areas in this router is %u\n",
1481 listcount(o
->area_list
));
1483 vty_out(vty
, " Authentication Sequence number info\n");
1484 vty_out(vty
, " Higher sequence no %u, Lower sequence no %u\n",
1485 o
->seqnum_h
, o
->seqnum_l
);
1487 if (CHECK_FLAG(o
->config_flags
, OSPF6_LOG_ADJACENCY_CHANGES
)) {
1488 if (CHECK_FLAG(o
->config_flags
,
1489 OSPF6_LOG_ADJACENCY_DETAIL
))
1491 " All adjacency changes are logged\n");
1493 vty_out(vty
, " Adjacency changes are logged\n");
1499 for (ALL_LIST_ELEMENTS_RO(o
->area_list
, n
, oa
))
1500 ospf6_area_show(vty
, oa
, json_areas
, use_json
);
1504 DEFUN(show_ipv6_ospf6_vrfs
, show_ipv6_ospf6_vrfs_cmd
,
1505 "show ipv6 ospf6 vrfs [json]",
1506 SHOW_STR IP6_STR OSPF6_STR
"Show OSPF6 VRFs \n" JSON_STR
)
1508 bool uj
= use_json(argc
, argv
);
1509 json_object
*json
= NULL
;
1510 json_object
*json_vrfs
= NULL
;
1511 struct ospf6
*ospf6
= NULL
;
1512 struct listnode
*node
= NULL
;
1514 char buf
[PREFIX_STRLEN
];
1515 static const char header
[] =
1516 "Name Id RouterId ";
1519 json
= json_object_new_object();
1520 json_vrfs
= json_object_new_object();
1523 for (ALL_LIST_ELEMENTS_RO(om6
->ospf6
, node
, ospf6
)) {
1524 json_object
*json_vrf
= NULL
;
1525 const char *name
= NULL
;
1526 int64_t vrf_id_ui
= 0;
1527 struct in_addr router_id
;
1529 router_id
.s_addr
= ospf6
->router_id
;
1532 if (!uj
&& count
== 1)
1533 vty_out(vty
, "%s\n", header
);
1535 json_vrf
= json_object_new_object();
1537 if (ospf6
->vrf_id
== VRF_DEFAULT
)
1538 name
= VRF_DEFAULT_NAME
;
1542 vrf_id_ui
= (ospf6
->vrf_id
== VRF_UNKNOWN
)
1544 : (int64_t)ospf6
->vrf_id
;
1547 json_object_int_add(json_vrf
, "vrfId", vrf_id_ui
);
1548 json_object_string_addf(json_vrf
, "routerId", "%pI4",
1550 json_object_object_add(json_vrfs
, name
, json_vrf
);
1553 vty_out(vty
, "%-25s %-5d %-16s \n", name
,
1555 inet_ntop(AF_INET
, &router_id
, buf
,
1561 json_object_object_add(json
, "vrfs", json_vrfs
);
1562 json_object_int_add(json
, "totalVrfs", count
);
1564 vty_json(vty
, json
);
1567 vty_out(vty
, "\nTotal number of OSPF VRFs: %d\n",
1574 /* show top level structures */
1575 DEFUN(show_ipv6_ospf6
, show_ipv6_ospf6_cmd
,
1576 "show ipv6 ospf6 [vrf <NAME|all>] [json]",
1577 SHOW_STR IP6_STR OSPF6_STR VRF_CMD_HELP_STR
"All VRFs\n" JSON_STR
)
1579 struct ospf6
*ospf6
;
1580 struct listnode
*node
;
1581 const char *vrf_name
= NULL
;
1582 bool all_vrf
= false;
1585 bool uj
= use_json(argc
, argv
);
1586 json_object
*json
= NULL
;
1588 OSPF6_FIND_VRF_ARGS(argv
, argc
, idx_vrf
, vrf_name
, all_vrf
);
1590 for (ALL_LIST_ELEMENTS_RO(om6
->ospf6
, node
, ospf6
)) {
1591 if (all_vrf
|| strcmp(ospf6
->name
, vrf_name
) == 0) {
1593 json
= json_object_new_object();
1594 ospf6_show(vty
, ospf6
, json
, uj
);
1602 json_object_free(json
);
1604 OSPF6_CMD_CHECK_VRF(uj
, all_vrf
, ospf6
);
1609 DEFUN(show_ipv6_ospf6_route
, show_ipv6_ospf6_route_cmd
,
1610 "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]",
1611 SHOW_STR IP6_STR OSPF6_STR VRF_CMD_HELP_STR
1612 "All VRFs\n" ROUTE_STR
1613 "Display Intra-Area routes\n"
1614 "Display Inter-Area routes\n"
1615 "Display Type-1 External routes\n"
1616 "Display Type-2 External routes\n"
1617 "Specify IPv6 address\n"
1618 "Specify IPv6 prefix\n"
1619 "Detailed information\n"
1620 "Summary of route table\n" JSON_STR
)
1622 struct ospf6
*ospf6
;
1623 struct listnode
*node
;
1624 const char *vrf_name
= NULL
;
1625 bool all_vrf
= false;
1627 int idx_arg_start
= 4;
1628 bool uj
= use_json(argc
, argv
);
1630 OSPF6_FIND_VRF_ARGS(argv
, argc
, idx_vrf
, vrf_name
, all_vrf
);
1634 for (ALL_LIST_ELEMENTS_RO(om6
->ospf6
, node
, ospf6
)) {
1635 if (all_vrf
|| strcmp(ospf6
->name
, vrf_name
) == 0) {
1636 ospf6_route_table_show(vty
, idx_arg_start
, argc
, argv
,
1637 ospf6
->route_table
, uj
);
1644 OSPF6_CMD_CHECK_VRF(uj
, all_vrf
, ospf6
);
1649 DEFUN(show_ipv6_ospf6_route_match
, show_ipv6_ospf6_route_match_cmd
,
1650 "show ipv6 ospf6 [vrf <NAME|all>] route X:X::X:X/M <match|longer> [json]",
1651 SHOW_STR IP6_STR OSPF6_STR VRF_CMD_HELP_STR
1652 "All VRFs\n" ROUTE_STR
1653 "Specify IPv6 prefix\n"
1654 "Display routes which match the specified route\n"
1655 "Display routes longer than the specified route\n" JSON_STR
)
1657 struct ospf6
*ospf6
;
1658 struct listnode
*node
;
1659 const char *vrf_name
= NULL
;
1660 bool all_vrf
= false;
1662 int idx_start_arg
= 4;
1663 bool uj
= use_json(argc
, argv
);
1665 OSPF6_FIND_VRF_ARGS(argv
, argc
, idx_vrf
, vrf_name
, all_vrf
);
1669 for (ALL_LIST_ELEMENTS_RO(om6
->ospf6
, node
, ospf6
)) {
1670 if (all_vrf
|| strcmp(ospf6
->name
, vrf_name
) == 0) {
1671 ospf6_route_table_show(vty
, idx_start_arg
, argc
, argv
,
1672 ospf6
->route_table
, uj
);
1679 OSPF6_CMD_CHECK_VRF(uj
, all_vrf
, ospf6
);
1684 DEFUN(show_ipv6_ospf6_route_match_detail
,
1685 show_ipv6_ospf6_route_match_detail_cmd
,
1686 "show ipv6 ospf6 [vrf <NAME|all>] route X:X::X:X/M match detail [json]",
1687 SHOW_STR IP6_STR OSPF6_STR VRF_CMD_HELP_STR
1688 "All VRFs\n" ROUTE_STR
1689 "Specify IPv6 prefix\n"
1690 "Display routes which match the specified route\n"
1691 "Detailed information\n" JSON_STR
)
1693 struct ospf6
*ospf6
;
1694 struct listnode
*node
;
1695 const char *vrf_name
= NULL
;
1696 bool all_vrf
= false;
1698 int idx_start_arg
= 4;
1699 bool uj
= use_json(argc
, argv
);
1701 OSPF6_FIND_VRF_ARGS(argv
, argc
, idx_vrf
, vrf_name
, all_vrf
);
1705 for (ALL_LIST_ELEMENTS_RO(om6
->ospf6
, node
, ospf6
)) {
1706 if (all_vrf
|| strcmp(ospf6
->name
, vrf_name
) == 0) {
1707 ospf6_route_table_show(vty
, idx_start_arg
, argc
, argv
,
1708 ospf6
->route_table
, uj
);
1715 OSPF6_CMD_CHECK_VRF(uj
, all_vrf
, ospf6
);
1720 DEFUN(show_ipv6_ospf6_route_type_detail
, show_ipv6_ospf6_route_type_detail_cmd
,
1721 "show ipv6 ospf6 [vrf <NAME|all>] route <intra-area|inter-area|external-1|external-2> detail [json]",
1722 SHOW_STR IP6_STR OSPF6_STR VRF_CMD_HELP_STR
1723 "All VRFs\n" ROUTE_STR
1724 "Display Intra-Area routes\n"
1725 "Display Inter-Area routes\n"
1726 "Display Type-1 External routes\n"
1727 "Display Type-2 External routes\n"
1728 "Detailed information\n" JSON_STR
)
1730 struct ospf6
*ospf6
;
1731 struct listnode
*node
;
1732 const char *vrf_name
= NULL
;
1733 bool all_vrf
= false;
1735 int idx_start_arg
= 4;
1736 bool uj
= use_json(argc
, argv
);
1738 OSPF6_FIND_VRF_ARGS(argv
, argc
, idx_vrf
, vrf_name
, all_vrf
);
1742 for (ALL_LIST_ELEMENTS_RO(om6
->ospf6
, node
, ospf6
)) {
1743 if (all_vrf
|| strcmp(ospf6
->name
, vrf_name
) == 0) {
1744 ospf6_route_table_show(vty
, idx_start_arg
, argc
, argv
,
1745 ospf6
->route_table
, uj
);
1752 OSPF6_CMD_CHECK_VRF(uj
, all_vrf
, ospf6
);
1757 bool ospf6_is_valid_summary_addr(struct vty
*vty
, struct prefix
*p
)
1759 struct in6_addr addr_zero
;
1761 memset(&addr_zero
, 0, sizeof(struct in6_addr
));
1763 /* Default prefix validation*/
1764 if ((is_default_prefix((struct prefix
*)p
))
1765 || (!memcmp(&p
->u
.prefix6
, &addr_zero
, sizeof(struct in6_addr
)))) {
1766 vty_out(vty
, "Default address should not be configured as summary address.\n");
1770 /* Host route should not be configured as summary address */
1771 if (p
->prefixlen
== IPV6_MAX_BITLEN
) {
1772 vty_out(vty
, "Host route should not be configured as summary address.\n");
1779 /* External Route Aggregation */
1780 DEFPY (ospf6_external_route_aggregation
,
1781 ospf6_external_route_aggregation_cmd
,
1782 "summary-address X:X::X:X/M$prefix [tag (1-4294967295)] [{metric (0-16777215) | metric-type (1-2)$mtype}]",
1783 "External summary address\n"
1784 "Specify IPv6 prefix\n"
1786 "Router tag value\n"
1788 "Advertised metric for this route\n"
1789 "OSPFv3 exterior metric type for summarised routes\n"
1790 "Set OSPFv3 External Type 1/2 metrics\n")
1792 VTY_DECLVAR_CONTEXT(ospf6
, ospf6
);
1795 int ret
= CMD_SUCCESS
;
1797 p
.family
= AF_INET6
;
1798 ret
= str2prefix(prefix_str
, &p
);
1800 vty_out(vty
, "Malformed prefix\n");
1801 return CMD_WARNING_CONFIG_FAILED
;
1804 /* Apply mask for given prefix. */
1805 apply_mask((struct prefix
*)&p
);
1807 if (!ospf6_is_valid_summary_addr(vty
, &p
))
1808 return CMD_WARNING_CONFIG_FAILED
;
1817 mtype
= DEFAULT_METRIC_TYPE
;
1819 ret
= ospf6_external_aggr_config_set(ospf6
, &p
, tag
, metric
, mtype
);
1820 if (ret
== OSPF6_FAILURE
) {
1821 vty_out(vty
, "Invalid configuration!!\n");
1822 return CMD_WARNING_CONFIG_FAILED
;
1828 DEFPY(no_ospf6_external_route_aggregation
,
1829 no_ospf6_external_route_aggregation_cmd
,
1830 "no summary-address X:X::X:X/M$prefix [tag (1-4294967295)] [{metric (0-16777215) | metric-type (1-2)}]",
1832 "External summary address\n"
1833 "Specify IPv6 prefix\n"
1835 "Router tag value\n"
1837 "Advertised metric for this route\n"
1838 "OSPFv3 exterior metric type for summarised routes\n"
1839 "Set OSPFv3 External Type 1/2 metrics\n")
1841 VTY_DECLVAR_CONTEXT(ospf6
, ospf6
);
1844 int ret
= CMD_SUCCESS
;
1846 ret
= str2prefix(prefix_str
, &p
);
1848 vty_out(vty
, "Malformed prefix\n");
1849 return CMD_WARNING_CONFIG_FAILED
;
1852 /* Apply mask for given prefix. */
1853 apply_mask((struct prefix
*)&p
);
1855 if (!ospf6_is_valid_summary_addr(vty
, &p
))
1856 return CMD_WARNING_CONFIG_FAILED
;
1858 ret
= ospf6_external_aggr_config_unset(ospf6
, &p
);
1859 if (ret
== OSPF6_INVALID
)
1860 vty_out(vty
, "Invalid configuration!!\n");
1865 DEFPY (ospf6_external_route_aggregation_no_advertise
,
1866 ospf6_external_route_aggregation_no_advertise_cmd
,
1867 "summary-address X:X::X:X/M$prefix no-advertise",
1868 "External summary address\n"
1869 "Specify IPv6 prefix\n"
1870 "Don't advertise summary route \n")
1872 VTY_DECLVAR_CONTEXT(ospf6
, ospf6
);
1875 int ret
= CMD_SUCCESS
;
1877 ret
= str2prefix(prefix_str
, &p
);
1879 vty_out(vty
, "Malformed prefix\n");
1880 return CMD_WARNING_CONFIG_FAILED
;
1883 /* Apply mask for given prefix. */
1884 apply_mask((struct prefix
*)&p
);
1886 if (!ospf6_is_valid_summary_addr(vty
, &p
))
1887 return CMD_WARNING_CONFIG_FAILED
;
1889 ret
= ospf6_asbr_external_rt_no_advertise(ospf6
, &p
);
1890 if (ret
== OSPF6_INVALID
)
1891 vty_out(vty
, "!!Invalid configuration\n");
1896 DEFPY (no_ospf6_external_route_aggregation_no_advertise
,
1897 no_ospf6_external_route_aggregation_no_advertise_cmd
,
1898 "no summary-address X:X::X:X/M$prefix no-advertise",
1900 "External summary address\n"
1901 "Specify IPv6 prefix\n"
1902 "Adverise summary route to the AS \n")
1904 VTY_DECLVAR_CONTEXT(ospf6
, ospf6
);
1907 int ret
= CMD_SUCCESS
;
1909 ret
= str2prefix(prefix_str
, &p
);
1911 vty_out(vty
, "Malformed prefix\n");
1912 return CMD_WARNING_CONFIG_FAILED
;
1915 /* Apply mask for given prefix. */
1916 apply_mask((struct prefix
*)&p
);
1918 if (!ospf6_is_valid_summary_addr(vty
, &p
))
1919 return CMD_WARNING_CONFIG_FAILED
;
1921 ret
= ospf6_asbr_external_rt_advertise(ospf6
, &p
);
1922 if (ret
== OSPF6_INVALID
)
1923 vty_out(vty
, "!!Invalid configuration\n");
1928 DEFPY (ospf6_route_aggregation_timer
,
1929 ospf6_route_aggregation_timer_cmd
,
1930 "aggregation timer (5-1800)",
1931 "External route aggregation\n"
1932 "Delay timer (in seconds)\n"
1933 "Timer interval(in seconds)\n")
1935 VTY_DECLVAR_CONTEXT(ospf6
, ospf6
);
1937 ospf6_external_aggr_delay_timer_set(ospf6
, timer
);
1942 DEFPY (no_ospf6_route_aggregation_timer
,
1943 no_ospf6_route_aggregation_timer_cmd
,
1944 "no aggregation timer [5-1800]",
1946 "External route aggregation\n"
1948 "Timer interval(in seconds)\n")
1950 VTY_DECLVAR_CONTEXT(ospf6
, ospf6
);
1952 ospf6_external_aggr_delay_timer_set(ospf6
,
1953 OSPF6_EXTL_AGGR_DEFAULT_DELAY
);
1958 ospf6_print_vty_external_routes_walkcb(struct hash_bucket
*bucket
, void *arg
)
1960 struct ospf6_route
*rt
= bucket
->data
;
1961 struct vty
*vty
= (struct vty
*)arg
;
1962 static unsigned int count
;
1964 vty_out(vty
, "%pFX ", &rt
->prefix
);
1971 if (OSPF6_EXTERNAL_RT_COUNT(rt
->aggr_route
) == count
)
1974 return HASHWALK_CONTINUE
;
1978 ospf6_print_json_external_routes_walkcb(struct hash_bucket
*bucket
, void *arg
)
1980 struct ospf6_route
*rt
= bucket
->data
;
1981 struct json_object
*json
= (struct json_object
*)arg
;
1982 char buf
[PREFIX2STR_BUFFER
];
1984 static unsigned int count
;
1986 prefix2str(&rt
->prefix
, buf
, sizeof(buf
));
1988 snprintf(exnalbuf
, sizeof(exnalbuf
), "Exnl Addr-%d", count
);
1990 json_object_string_add(json
, exnalbuf
, buf
);
1994 if (OSPF6_EXTERNAL_RT_COUNT(rt
->aggr_route
) == count
)
1997 return HASHWALK_CONTINUE
;
2001 ospf6_show_vrf_name(struct vty
*vty
, struct ospf6
*ospf6
,
2005 if (ospf6
->vrf_id
== VRF_DEFAULT
)
2006 json_object_string_add(json
, "vrfName",
2009 json_object_string_add(json
, "vrfName",
2011 json_object_int_add(json
, "vrfId", ospf6
->vrf_id
);
2013 if (ospf6
->vrf_id
== VRF_DEFAULT
)
2014 vty_out(vty
, "VRF Name: %s\n", "default");
2015 else if (ospf6
->name
)
2016 vty_out(vty
, "VRF Name: %s\n", ospf6
->name
);
2021 ospf6_show_summary_address(struct vty
*vty
, struct ospf6
*ospf6
,
2023 bool uj
, const char *detail
)
2025 struct route_node
*rn
;
2026 static const char header
[] = "Summary-address Metric-type Metric Tag External_Rt_count\n";
2027 json_object
*json_vrf
= NULL
;
2030 ospf6_show_vrf_name(vty
, ospf6
, json_vrf
);
2031 vty_out(vty
, "aggregation delay interval :%u(in seconds)\n\n",
2032 ospf6
->aggr_delay_interval
);
2033 vty_out(vty
, "%s\n", header
);
2035 json_vrf
= json_object_new_object();
2037 ospf6_show_vrf_name(vty
, ospf6
, json_vrf
);
2039 json_object_int_add(json_vrf
, "aggregation delay interval",
2040 ospf6
->aggr_delay_interval
);
2044 for (rn
= route_top(ospf6
->rt_aggr_tbl
); rn
; rn
= route_next(rn
)) {
2048 struct ospf6_external_aggr_rt
*aggr
= rn
->info
;
2049 json_object
*json_aggr
= NULL
;
2050 char buf
[PREFIX2STR_BUFFER
];
2052 prefix2str(&aggr
->p
, buf
, sizeof(buf
));
2056 json_aggr
= json_object_new_object();
2058 json_object_object_add(json_vrf
,
2062 json_object_string_add(json_aggr
,
2066 json_object_string_add(
2067 json_aggr
, "Metric-type",
2068 (aggr
->mtype
== DEFAULT_METRIC_TYPE
)
2072 json_object_int_add(json_aggr
, "Metric",
2073 (aggr
->metric
!= -1)
2075 : DEFAULT_DEFAULT_METRIC
);
2077 json_object_int_add(json_aggr
, "Tag",
2080 json_object_int_add(json_aggr
,
2081 "External route count",
2082 OSPF6_EXTERNAL_RT_COUNT(aggr
));
2084 if (OSPF6_EXTERNAL_RT_COUNT(aggr
) && detail
) {
2085 json_object_int_add(json_aggr
, "ID",
2087 json_object_int_add(json_aggr
, "Flags",
2089 hash_walk(aggr
->match_extnl_hash
,
2090 ospf6_print_json_external_routes_walkcb
,
2095 vty_out(vty
, "%-22s", buf
);
2097 (aggr
->mtype
== DEFAULT_METRIC_TYPE
)
2098 ? vty_out(vty
, "%-16s", "E2")
2099 : vty_out(vty
, "%-16s", "E1");
2100 vty_out(vty
, "%-11d", (aggr
->metric
!= -1)
2102 : DEFAULT_DEFAULT_METRIC
);
2104 vty_out(vty
, "%-12u", aggr
->tag
);
2106 vty_out(vty
, "%-5ld\n",
2107 OSPF6_EXTERNAL_RT_COUNT(aggr
));
2109 if (OSPF6_EXTERNAL_RT_COUNT(aggr
) && detail
) {
2111 "Matched External routes:\n");
2112 hash_walk(aggr
->match_extnl_hash
,
2113 ospf6_print_vty_external_routes_walkcb
,
2123 json_object_object_add(json
, ospf6
->name
,
2129 DEFPY (show_ipv6_ospf6_external_aggregator
,
2130 show_ipv6_ospf6_external_aggregator_cmd
,
2131 "show ipv6 ospf6 [vrf <NAME|all>] summary-address [detail$detail] [json]",
2137 "Show external summary addresses\n"
2138 "detailed information\n"
2141 bool uj
= use_json(argc
, argv
);
2142 struct ospf6
*ospf6
= NULL
;
2143 json_object
*json
= NULL
;
2144 const char *vrf_name
= NULL
;
2145 struct listnode
*node
;
2146 bool all_vrf
= false;
2150 json
= json_object_new_object();
2152 OSPF6_FIND_VRF_ARGS(argv
, argc
, idx_vrf
, vrf_name
, all_vrf
);
2154 for (ALL_LIST_ELEMENTS_RO(om6
->ospf6
, node
, ospf6
)) {
2155 if (all_vrf
|| strcmp(ospf6
->name
, vrf_name
) == 0) {
2157 ospf6_show_summary_address(vty
, ospf6
, json
, uj
,
2166 vty_json(vty
, json
);
2169 OSPF6_CMD_CHECK_VRF(uj
, all_vrf
, ospf6
);
2174 static void ospf6_stub_router_config_write(struct vty
*vty
, struct ospf6
*ospf6
)
2176 if (CHECK_FLAG(ospf6
->flag
, OSPF6_STUB_ROUTER
))
2177 vty_out(vty
, " stub-router administrative\n");
2181 static int ospf6_distance_config_write(struct vty
*vty
, struct ospf6
*ospf6
)
2183 struct route_node
*rn
;
2184 struct ospf6_distance
*odistance
;
2186 if (ospf6
->distance_all
)
2187 vty_out(vty
, " distance %u\n", ospf6
->distance_all
);
2189 if (ospf6
->distance_intra
|| ospf6
->distance_inter
2190 || ospf6
->distance_external
) {
2191 vty_out(vty
, " distance ospf6");
2193 if (ospf6
->distance_intra
)
2194 vty_out(vty
, " intra-area %u", ospf6
->distance_intra
);
2195 if (ospf6
->distance_inter
)
2196 vty_out(vty
, " inter-area %u", ospf6
->distance_inter
);
2197 if (ospf6
->distance_external
)
2198 vty_out(vty
, " external %u", ospf6
->distance_external
);
2203 for (rn
= route_top(ospf6
->distance_table
); rn
; rn
= route_next(rn
))
2204 if ((odistance
= rn
->info
) != NULL
)
2205 vty_out(vty
, " distance %u %pFX %s\n",
2206 odistance
->distance
, &rn
->p
,
2207 odistance
->access_list
? odistance
->access_list
2212 static int ospf6_asbr_summary_config_write(struct vty
*vty
, struct ospf6
*ospf6
)
2214 struct route_node
*rn
;
2215 struct ospf6_external_aggr_rt
*aggr
;
2216 char buf
[PREFIX2STR_BUFFER
];
2218 if (ospf6
->aggr_delay_interval
!= OSPF6_EXTL_AGGR_DEFAULT_DELAY
)
2219 vty_out(vty
, " aggregation timer %u\n",
2220 ospf6
->aggr_delay_interval
);
2222 /* print 'summary-address A:B::C:D/M' */
2223 for (rn
= route_top(ospf6
->rt_aggr_tbl
); rn
; rn
= route_next(rn
)) {
2229 prefix2str(&aggr
->p
, buf
, sizeof(buf
));
2230 vty_out(vty
, " summary-address %s", buf
);
2232 vty_out(vty
, " tag %u", aggr
->tag
);
2234 if (aggr
->metric
!= -1)
2235 vty_out(vty
, " metric %d", aggr
->metric
);
2237 if (aggr
->mtype
!= DEFAULT_METRIC_TYPE
)
2238 vty_out(vty
, " metric-type %d", aggr
->mtype
);
2240 if (CHECK_FLAG(aggr
->aggrflags
,
2241 OSPF6_EXTERNAL_AGGRT_NO_ADVERTISE
))
2242 vty_out(vty
, " no-advertise");
2250 /* OSPF configuration write function. */
2251 static int config_write_ospf6(struct vty
*vty
)
2253 struct ospf6
*ospf6
;
2254 struct listnode
*node
, *nnode
;
2256 /* OSPFv3 configuration. */
2260 for (ALL_LIST_ELEMENTS(om6
->ospf6
, node
, nnode
, ospf6
)) {
2261 if (ospf6
->name
&& strcmp(ospf6
->name
, VRF_DEFAULT_NAME
))
2262 vty_out(vty
, "router ospf6 vrf %s\n", ospf6
->name
);
2264 vty_out(vty
, "router ospf6\n");
2266 if (ospf6
->router_id_static
!= 0)
2267 vty_out(vty
, " ospf6 router-id %pI4\n",
2268 &ospf6
->router_id_static
);
2270 if (CHECK_FLAG(ospf6
->config_flags
,
2271 OSPF6_SEND_EXTRA_DATA_TO_ZEBRA
))
2272 vty_out(vty
, " ospf6 send-extra-data zebra\n");
2274 /* log-adjacency-changes flag print. */
2275 if (CHECK_FLAG(ospf6
->config_flags
,
2276 OSPF6_LOG_ADJACENCY_CHANGES
)) {
2277 if (CHECK_FLAG(ospf6
->config_flags
,
2278 OSPF6_LOG_ADJACENCY_DETAIL
))
2279 vty_out(vty
, " log-adjacency-changes detail\n");
2280 else if (!SAVE_OSPF6_LOG_ADJACENCY_CHANGES
)
2281 vty_out(vty
, " log-adjacency-changes\n");
2282 } else if (SAVE_OSPF6_LOG_ADJACENCY_CHANGES
) {
2283 vty_out(vty
, " no log-adjacency-changes\n");
2286 if (ospf6
->ref_bandwidth
!= OSPF6_REFERENCE_BANDWIDTH
)
2287 vty_out(vty
, " auto-cost reference-bandwidth %d\n",
2288 ospf6
->ref_bandwidth
);
2290 if (ospf6
->write_oi_count
2291 != OSPF6_WRITE_INTERFACE_COUNT_DEFAULT
)
2292 vty_out(vty
, " write-multiplier %d\n",
2293 ospf6
->write_oi_count
);
2295 /* LSA timers print. */
2296 if (ospf6
->lsa_minarrival
!= OSPF_MIN_LS_ARRIVAL
)
2297 vty_out(vty
, " timers lsa min-arrival %d\n",
2298 ospf6
->lsa_minarrival
);
2300 /* ECMP max path config */
2301 if (ospf6
->max_multipath
!= MULTIPATH_NUM
)
2302 vty_out(vty
, " maximum-paths %d\n",
2303 ospf6
->max_multipath
);
2305 ospf6_stub_router_config_write(vty
, ospf6
);
2306 ospf6_redistribute_config_write(vty
, ospf6
);
2307 ospf6_area_config_write(vty
, ospf6
);
2308 ospf6_spf_config_write(vty
, ospf6
);
2309 ospf6_distance_config_write(vty
, ospf6
);
2310 ospf6_distribute_config_write(vty
, ospf6
);
2311 ospf6_asbr_summary_config_write(vty
, ospf6
);
2312 config_write_ospf6_gr(vty
, ospf6
);
2313 config_write_ospf6_gr_helper(vty
, ospf6
);
2315 vty_out(vty
, "exit\n");
2316 vty_out(vty
, "!\n");
2321 static int config_write_ospf6(struct vty
*vty
);
2322 /* OSPF6 node structure. */
2323 static struct cmd_node ospf6_node
= {
2326 .parent_node
= CONFIG_NODE
,
2327 .prompt
= "%s(config-ospf6)# ",
2328 .config_write
= config_write_ospf6
,
2331 void install_element_ospf6_clear_process(void)
2333 install_element(ENABLE_NODE
, &clear_router_ospf6_cmd
);
2336 /* Install ospf related commands. */
2337 void ospf6_top_init(void)
2339 /* Install ospf6 top node. */
2340 install_node(&ospf6_node
);
2342 install_element(VIEW_NODE
, &show_ipv6_ospf6_cmd
);
2343 install_element(VIEW_NODE
, &show_ipv6_ospf6_vrfs_cmd
);
2344 install_element(CONFIG_NODE
, &router_ospf6_cmd
);
2345 install_element(CONFIG_NODE
, &no_router_ospf6_cmd
);
2347 install_element(VIEW_NODE
, &show_ipv6_ospf6_route_cmd
);
2348 install_element(VIEW_NODE
, &show_ipv6_ospf6_route_match_cmd
);
2349 install_element(VIEW_NODE
, &show_ipv6_ospf6_route_match_detail_cmd
);
2350 install_element(VIEW_NODE
, &show_ipv6_ospf6_route_type_detail_cmd
);
2352 install_default(OSPF6_NODE
);
2353 install_element(OSPF6_NODE
, &ospf6_router_id_cmd
);
2354 install_element(OSPF6_NODE
, &no_ospf6_router_id_cmd
);
2355 install_element(OSPF6_NODE
, &ospf6_log_adjacency_changes_cmd
);
2356 install_element(OSPF6_NODE
, &ospf6_log_adjacency_changes_detail_cmd
);
2357 install_element(OSPF6_NODE
, &no_ospf6_log_adjacency_changes_cmd
);
2358 install_element(OSPF6_NODE
, &no_ospf6_log_adjacency_changes_detail_cmd
);
2359 install_element(OSPF6_NODE
, &ospf6_send_extra_data_cmd
);
2361 /* LSA timers commands */
2362 install_element(OSPF6_NODE
, &ospf6_timers_lsa_cmd
);
2363 install_element(OSPF6_NODE
, &no_ospf6_timers_lsa_cmd
);
2365 install_element(OSPF6_NODE
, &ospf6_interface_area_cmd
);
2366 install_element(OSPF6_NODE
, &no_ospf6_interface_area_cmd
);
2367 install_element(OSPF6_NODE
, &ospf6_stub_router_admin_cmd
);
2368 install_element(OSPF6_NODE
, &no_ospf6_stub_router_admin_cmd
);
2370 /* maximum-paths command */
2371 install_element(OSPF6_NODE
, &ospf6_max_multipath_cmd
);
2372 install_element(OSPF6_NODE
, &no_ospf6_max_multipath_cmd
);
2374 /* ASBR Summarisation */
2375 install_element(OSPF6_NODE
, &ospf6_external_route_aggregation_cmd
);
2376 install_element(OSPF6_NODE
, &no_ospf6_external_route_aggregation_cmd
);
2377 install_element(OSPF6_NODE
,
2378 &ospf6_external_route_aggregation_no_advertise_cmd
);
2379 install_element(OSPF6_NODE
,
2380 &no_ospf6_external_route_aggregation_no_advertise_cmd
);
2381 install_element(OSPF6_NODE
, &ospf6_route_aggregation_timer_cmd
);
2382 install_element(OSPF6_NODE
, &no_ospf6_route_aggregation_timer_cmd
);
2383 install_element(VIEW_NODE
, &show_ipv6_ospf6_external_aggregator_cmd
);
2385 install_element(OSPF6_NODE
, &ospf6_distance_cmd
);
2386 install_element(OSPF6_NODE
, &no_ospf6_distance_cmd
);
2387 install_element(OSPF6_NODE
, &ospf6_distance_ospf6_cmd
);
2388 install_element(OSPF6_NODE
, &no_ospf6_distance_ospf6_cmd
);