1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Copyright (C) 2003 Yasuhiro Ohara
18 #include "lib_errors.h"
20 #include "ospf6_proto.h"
21 #include "ospf6_message.h"
22 #include "ospf6_lsa.h"
23 #include "ospf6_lsdb.h"
24 #include "ospf6_route.h"
25 #include "ospf6_zebra.h"
27 #include "ospf6_top.h"
28 #include "ospf6_area.h"
29 #include "ospf6_interface.h"
30 #include "ospf6_neighbor.h"
31 #include "ospf6_network.h"
33 #include "ospf6_flood.h"
34 #include "ospf6_asbr.h"
35 #include "ospf6_abr.h"
36 #include "ospf6_intra.h"
37 #include "ospf6_spf.h"
41 #include "ospf6_nssa.h"
42 #include "ospf6_auth_trailer.h"
44 DEFINE_MTYPE_STATIC(OSPF6D
, OSPF6_TOP
, "OSPF6 top");
46 DEFINE_QOBJ_TYPE(ospf6
);
48 FRR_CFG_DEFAULT_BOOL(OSPF6_LOG_ADJACENCY_CHANGES
,
49 { .val_bool
= true, .match_profile
= "datacenter", },
50 { .val_bool
= false },
53 #include "ospf6d/ospf6_top_clippy.c"
55 /* global ospf6d variable */
56 static struct ospf6_master ospf6_master
;
57 struct ospf6_master
*om6
;
59 static void ospf6_disable(struct ospf6
*o
);
61 static void ospf6_add(struct ospf6
*ospf6
)
63 listnode_add(om6
->ospf6
, ospf6
);
66 static void ospf6_del(struct ospf6
*ospf6
)
68 listnode_delete(om6
->ospf6
, ospf6
);
71 const char *ospf6_vrf_id_to_name(vrf_id_t vrf_id
)
73 struct vrf
*vrf
= vrf_lookup_by_id(vrf_id
);
75 return vrf
? vrf
->name
: "NIL";
78 /* Link OSPF instance to VRF. */
79 void ospf6_vrf_link(struct ospf6
*ospf6
, struct vrf
*vrf
)
81 ospf6
->vrf_id
= vrf
->vrf_id
;
82 if (vrf
->info
!= (void *)ospf6
)
83 vrf
->info
= (void *)ospf6
;
86 /* Unlink OSPF instance from VRF. */
87 void ospf6_vrf_unlink(struct ospf6
*ospf6
, struct vrf
*vrf
)
89 if (vrf
->info
== (void *)ospf6
)
91 ospf6
->vrf_id
= VRF_UNKNOWN
;
94 struct ospf6
*ospf6_lookup_by_vrf_id(vrf_id_t vrf_id
)
96 struct vrf
*vrf
= NULL
;
98 vrf
= vrf_lookup_by_id(vrf_id
);
101 return (vrf
->info
) ? (struct ospf6
*)vrf
->info
: NULL
;
104 struct ospf6
*ospf6_lookup_by_vrf_name(const char *name
)
106 struct ospf6
*o
= NULL
;
107 struct listnode
*node
, *nnode
;
109 for (ALL_LIST_ELEMENTS(om6
->ospf6
, node
, nnode
, o
)) {
110 if (((o
->name
== NULL
&& name
== NULL
)
111 || (o
->name
&& name
&& strcmp(o
->name
, name
) == 0)))
117 /* This is hook function for vrf create called as part of vrf_init */
118 static int ospf6_vrf_new(struct vrf
*vrf
)
123 /* This is hook function for vrf delete call as part of vrf_init */
124 static int ospf6_vrf_delete(struct vrf
*vrf
)
129 static void ospf6_set_redist_vrf_bitmaps(struct ospf6
*ospf6
, bool set
)
132 struct list
*red_list
;
134 for (type
= 0; type
< ZEBRA_ROUTE_MAX
; type
++) {
135 red_list
= ospf6
->redist
[type
];
138 if (IS_OSPF6_DEBUG_ZEBRA(RECV
))
140 "%s: setting redist vrf %d bitmap for type %d",
141 __func__
, ospf6
->vrf_id
, type
);
143 vrf_bitmap_set(zclient
->redist
[AFI_IP6
][type
],
146 vrf_bitmap_unset(zclient
->redist
[AFI_IP6
][type
],
150 red_list
= ospf6
->redist
[DEFAULT_ROUTE
];
153 vrf_bitmap_set(zclient
->default_information
[AFI_IP6
],
156 vrf_bitmap_unset(zclient
->default_information
[AFI_IP6
],
161 /* Disable OSPF6 VRF instance */
162 static int ospf6_vrf_disable(struct vrf
*vrf
)
164 struct ospf6
*ospf6
= NULL
;
166 if (vrf
->vrf_id
== VRF_DEFAULT
)
169 ospf6
= ospf6_lookup_by_vrf_name(vrf
->name
);
171 ospf6_zebra_vrf_deregister(ospf6
);
173 ospf6_set_redist_vrf_bitmaps(ospf6
, false);
175 /* We have instance configured, unlink
176 * from VRF and make it "down".
178 ospf6_vrf_unlink(ospf6
, vrf
);
179 event_cancel(&ospf6
->t_ospf6_receive
);
184 /* Note: This is a callback, the VRF will be deleted by the caller. */
188 /* Enable OSPF6 VRF instance */
189 static int ospf6_vrf_enable(struct vrf
*vrf
)
191 struct ospf6
*ospf6
= NULL
;
195 ospf6
= ospf6_lookup_by_vrf_name(vrf
->name
);
197 old_vrf_id
= ospf6
->vrf_id
;
198 /* We have instance configured, link to VRF and make it "up". */
199 ospf6_vrf_link(ospf6
, vrf
);
201 if (old_vrf_id
!= ospf6
->vrf_id
) {
202 ospf6_set_redist_vrf_bitmaps(ospf6
, true);
204 /* start zebra redist to us for new vrf */
205 ospf6_zebra_vrf_register(ospf6
);
207 ret
= ospf6_serv_sock(ospf6
);
208 if (ret
< 0 || ospf6
->fd
<= 0)
210 event_add_read(master
, ospf6_receive
, ospf6
, ospf6
->fd
,
211 &ospf6
->t_ospf6_receive
);
213 ospf6_router_id_update(ospf6
, true);
220 void ospf6_vrf_init(void)
222 vrf_init(ospf6_vrf_new
, ospf6_vrf_enable
, ospf6_vrf_disable
,
228 static void ospf6_top_lsdb_hook_add(struct ospf6_lsa
*lsa
)
230 switch (ntohs(lsa
->header
->type
)) {
231 case OSPF6_LSTYPE_AS_EXTERNAL
:
232 ospf6_asbr_lsa_add(lsa
);
240 static void ospf6_top_lsdb_hook_remove(struct ospf6_lsa
*lsa
)
242 switch (ntohs(lsa
->header
->type
)) {
243 case OSPF6_LSTYPE_AS_EXTERNAL
:
244 ospf6_asbr_lsa_remove(lsa
, NULL
);
252 static void ospf6_top_route_hook_add(struct ospf6_route
*route
)
254 struct ospf6
*ospf6
= NULL
;
255 struct ospf6_area
*oa
= NULL
;
257 if (route
->table
->scope_type
== OSPF6_SCOPE_TYPE_GLOBAL
)
258 ospf6
= route
->table
->scope
;
259 else if (route
->table
->scope_type
== OSPF6_SCOPE_TYPE_AREA
) {
260 oa
= (struct ospf6_area
*)route
->table
->scope
;
263 if (IS_OSPF6_DEBUG_EXAMIN(AS_EXTERNAL
)
264 || IS_OSPF6_DEBUG_BROUTER
)
266 "%s: Route is not GLOBAL or scope is not of TYPE_AREA: %pFX",
267 __func__
, &route
->prefix
);
271 ospf6_abr_originate_summary(route
, ospf6
);
272 ospf6_zebra_route_update_add(route
, ospf6
);
275 static void ospf6_top_route_hook_remove(struct ospf6_route
*route
)
277 struct ospf6
*ospf6
= NULL
;
278 struct ospf6_area
*oa
= NULL
;
280 if (route
->table
->scope_type
== OSPF6_SCOPE_TYPE_GLOBAL
)
281 ospf6
= route
->table
->scope
;
282 else if (route
->table
->scope_type
== OSPF6_SCOPE_TYPE_AREA
) {
283 oa
= (struct ospf6_area
*)route
->table
->scope
;
286 if (IS_OSPF6_DEBUG_EXAMIN(AS_EXTERNAL
)
287 || IS_OSPF6_DEBUG_BROUTER
)
289 "%s: Route is not GLOBAL or scope is not of TYPE_AREA: %pFX",
290 __func__
, &route
->prefix
);
294 route
->flag
|= OSPF6_ROUTE_REMOVE
;
295 ospf6_abr_originate_summary(route
, ospf6
);
296 ospf6_zebra_route_update_remove(route
, ospf6
);
299 static void ospf6_top_brouter_hook_add(struct ospf6_route
*route
)
301 struct ospf6
*ospf6
= route
->table
->scope
;
303 if (IS_OSPF6_DEBUG_EXAMIN(AS_EXTERNAL
) ||
304 IS_OSPF6_DEBUG_BROUTER
) {
306 char brouter_name
[16];
308 brouter_id
= ADV_ROUTER_IN_PREFIX(&route
->prefix
);
309 inet_ntop(AF_INET
, &brouter_id
, brouter_name
,
310 sizeof(brouter_name
));
311 zlog_debug("%s: brouter %s add with adv router %x nh count %u",
312 __func__
, brouter_name
,
313 route
->path
.origin
.adv_router
,
314 listcount(route
->nh_list
));
316 ospf6_abr_examin_brouter(ADV_ROUTER_IN_PREFIX(&route
->prefix
), route
,
318 ospf6_asbr_lsentry_add(route
, ospf6
);
319 ospf6_abr_originate_summary(route
, ospf6
);
322 static void ospf6_top_brouter_hook_remove(struct ospf6_route
*route
)
324 struct ospf6
*ospf6
= route
->table
->scope
;
326 if (IS_OSPF6_DEBUG_EXAMIN(AS_EXTERNAL
) ||
327 IS_OSPF6_DEBUG_BROUTER
) {
329 char brouter_name
[16];
331 brouter_id
= ADV_ROUTER_IN_PREFIX(&route
->prefix
);
332 inet_ntop(AF_INET
, &brouter_id
, brouter_name
,
333 sizeof(brouter_name
));
334 zlog_debug("%s: brouter %p %s del with adv router %x nh %u",
335 __func__
, (void *)route
, brouter_name
,
336 route
->path
.origin
.adv_router
,
337 listcount(route
->nh_list
));
339 route
->flag
|= OSPF6_ROUTE_REMOVE
;
340 ospf6_abr_examin_brouter(ADV_ROUTER_IN_PREFIX(&route
->prefix
), route
,
342 ospf6_asbr_lsentry_remove(route
, ospf6
);
343 ospf6_abr_originate_summary(route
, ospf6
);
346 static struct ospf6
*ospf6_create(const char *name
)
349 struct vrf
*vrf
= NULL
;
351 o
= XCALLOC(MTYPE_OSPF6_TOP
, sizeof(struct ospf6
));
353 vrf
= vrf_lookup_by_name(name
);
355 o
->vrf_id
= vrf
->vrf_id
;
357 o
->vrf_id
= VRF_UNKNOWN
;
359 /* Freed in ospf6_delete */
360 o
->name
= XSTRDUP(MTYPE_OSPF6_TOP
, name
);
362 ospf6_vrf_link(o
, vrf
);
364 ospf6_zebra_vrf_register(o
);
367 monotime(&o
->starttime
);
368 o
->area_list
= list_new();
369 o
->area_list
->cmp
= ospf6_area_cmp
;
370 o
->lsdb
= ospf6_lsdb_create(o
);
371 o
->lsdb_self
= ospf6_lsdb_create(o
);
372 o
->lsdb
->hook_add
= ospf6_top_lsdb_hook_add
;
373 o
->lsdb
->hook_remove
= ospf6_top_lsdb_hook_remove
;
375 o
->spf_delay
= OSPF_SPF_DELAY_DEFAULT
;
376 o
->spf_holdtime
= OSPF_SPF_HOLDTIME_DEFAULT
;
377 o
->spf_max_holdtime
= OSPF_SPF_MAX_HOLDTIME_DEFAULT
;
378 o
->spf_hold_multiplier
= 1;
380 o
->default_originate
= DEFAULT_ORIGINATE_NONE
;
382 /* LSA timers value init */
383 o
->lsa_minarrival
= OSPF_MIN_LS_ARRIVAL
;
385 o
->route_table
= OSPF6_ROUTE_TABLE_CREATE(GLOBAL
, ROUTES
);
386 o
->route_table
->scope
= o
;
387 o
->route_table
->hook_add
= ospf6_top_route_hook_add
;
388 o
->route_table
->hook_remove
= ospf6_top_route_hook_remove
;
390 o
->brouter_table
= OSPF6_ROUTE_TABLE_CREATE(GLOBAL
, BORDER_ROUTERS
);
391 o
->brouter_table
->scope
= o
;
392 o
->brouter_table
->hook_add
= ospf6_top_brouter_hook_add
;
393 o
->brouter_table
->hook_remove
= ospf6_top_brouter_hook_remove
;
395 o
->external_table
= OSPF6_ROUTE_TABLE_CREATE(GLOBAL
, EXTERNAL_ROUTES
);
396 o
->external_table
->scope
= o
;
397 /* Setting this to 1, so that the LS ID 0 can be considered as invalid
398 * for self originated external LSAs. This helps in differentiating if
399 * an LSA is originated for any route or not in the route data.
400 * rt->route_option->id is by default 0
401 * Consider a route having id as 0 and prefix as 1::1, an external LSA
402 * is originated with ID 0.0.0.0. Now consider another route 2::2
403 * and for this LSA was not originated because of some configuration
404 * but the ID field rt->route_option->id is still 0.Consider now this
405 * 2::2 is being deleted, it will search LSA with LS ID as 0 and it
406 * will find the LSA and hence delete it but the LSA belonged to prefix
407 * 1::1, this happened because of LS ID 0.
409 o
->external_id
= OSPF6_EXT_INIT_LS_ID
;
411 o
->write_oi_count
= OSPF6_WRITE_INTERFACE_COUNT_DEFAULT
;
412 o
->ref_bandwidth
= OSPF6_REFERENCE_BANDWIDTH
;
414 o
->distance_table
= route_table_init();
416 o
->rt_aggr_tbl
= route_table_init();
417 o
->aggr_delay_interval
= OSPF6_EXTL_AGGR_DEFAULT_DELAY
;
418 o
->aggr_action
= OSPF6_ROUTE_AGGR_NONE
;
422 o
->max_multipath
= MULTIPATH_NUM
;
424 o
->oi_write_q
= list_new();
426 ospf6_gr_helper_init(o
);
429 /* Make ospf protocol socket. */
432 /* If sequence number is stored in persistent storage, read it.
434 if (ospf6_auth_nvm_file_exist() == OSPF6_AUTH_FILE_EXIST
) {
435 ospf6_auth_seqno_nvm_read(o
);
436 o
->seqnum_h
= o
->seqnum_h
+ 1;
437 ospf6_auth_seqno_nvm_update(o
);
439 o
->seqnum_l
= o
->seqnum_h
= 0;
440 ospf6_auth_seqno_nvm_update(o
);
446 struct ospf6
*ospf6_instance_create(const char *name
)
450 struct interface
*ifp
;
452 ospf6
= ospf6_create(name
);
453 if (DFLT_OSPF6_LOG_ADJACENCY_CHANGES
)
454 SET_FLAG(ospf6
->config_flags
, OSPF6_LOG_ADJACENCY_CHANGES
);
455 if (ospf6
->router_id
== 0)
456 ospf6_router_id_update(ospf6
, true);
460 * Read from non-volatile memory whether this instance is performing a
461 * graceful restart or not.
463 ospf6_gr_nvm_read(ospf6
);
465 if (ospf6
->vrf_id
!= VRF_UNKNOWN
) {
466 vrf
= vrf_lookup_by_id(ospf6
->vrf_id
);
467 FOR_ALL_INTERFACES (vrf
, ifp
) {
469 ospf6_interface_start(ifp
->info
);
475 event_add_read(master
, ospf6_receive
, ospf6
, ospf6
->fd
,
476 &ospf6
->t_ospf6_receive
);
481 void ospf6_delete(struct ospf6
*o
)
483 struct listnode
*node
, *nnode
;
484 struct route_node
*rn
= NULL
;
485 struct ospf6_area
*oa
;
487 struct ospf6_external_aggr_rt
*aggr
;
491 ospf6_gr_helper_deinit(o
);
492 if (!o
->gr_info
.prepare_in_progress
)
493 ospf6_flush_self_originated_lsas_now(o
);
494 XFREE(MTYPE_TMP
, o
->gr_info
.exit_reason
);
498 ospf6_zebra_vrf_deregister(o
);
500 ospf6_serv_close(&o
->fd
);
502 for (ALL_LIST_ELEMENTS(o
->area_list
, node
, nnode
, oa
))
503 ospf6_area_delete(oa
);
506 list_delete(&o
->area_list
);
508 ospf6_lsdb_delete(o
->lsdb
);
509 ospf6_lsdb_delete(o
->lsdb_self
);
511 ospf6_route_table_delete(o
->route_table
);
512 ospf6_route_table_delete(o
->brouter_table
);
514 ospf6_route_table_delete(o
->external_table
);
516 ospf6_distance_reset(o
);
517 route_table_finish(o
->distance_table
);
518 list_delete(&o
->oi_write_q
);
520 if (o
->vrf_id
!= VRF_UNKNOWN
) {
521 vrf
= vrf_lookup_by_id(o
->vrf_id
);
523 ospf6_vrf_unlink(o
, vrf
);
526 for (rn
= route_top(o
->rt_aggr_tbl
); rn
; rn
= route_next(rn
))
529 ospf6_asbr_summary_config_delete(o
, rn
);
530 ospf6_external_aggregator_free(aggr
);
532 route_table_finish(o
->rt_aggr_tbl
);
534 XFREE(MTYPE_OSPF6_TOP
, o
->name
);
535 XFREE(MTYPE_OSPF6_TOP
, o
);
538 static void ospf6_disable(struct ospf6
*o
)
540 struct listnode
*node
, *nnode
;
541 struct ospf6_area
*oa
;
543 if (!CHECK_FLAG(o
->flag
, OSPF6_DISABLED
)) {
544 SET_FLAG(o
->flag
, OSPF6_DISABLED
);
546 for (ALL_LIST_ELEMENTS(o
->area_list
, node
, nnode
, oa
))
547 ospf6_area_disable(oa
);
549 /* XXX: This also changes persistent settings */
550 /* Unregister redistribution */
551 ospf6_asbr_redistribute_disable(o
);
553 ospf6_lsdb_remove_all(o
->lsdb
);
554 ospf6_route_remove_all(o
->route_table
);
555 ospf6_route_remove_all(o
->brouter_table
);
557 EVENT_OFF(o
->maxage_remover
);
558 EVENT_OFF(o
->t_spf_calc
);
559 EVENT_OFF(o
->t_ase_calc
);
560 EVENT_OFF(o
->t_distribute_update
);
561 EVENT_OFF(o
->t_ospf6_receive
);
562 EVENT_OFF(o
->t_external_aggr
);
563 EVENT_OFF(o
->gr_info
.t_grace_period
);
564 EVENT_OFF(o
->t_write
);
565 EVENT_OFF(o
->t_abr_task
);
569 void ospf6_master_init(struct event_loop
*master
)
571 memset(&ospf6_master
, 0, sizeof(ospf6_master
));
574 om6
->ospf6
= list_new();
575 om6
->master
= master
;
578 static void ospf6_maxage_remover(struct event
*thread
)
580 struct ospf6
*o
= (struct ospf6
*)EVENT_ARG(thread
);
581 struct ospf6_area
*oa
;
582 struct ospf6_interface
*oi
;
583 struct ospf6_neighbor
*on
;
584 struct listnode
*i
, *j
, *k
;
587 for (ALL_LIST_ELEMENTS_RO(o
->area_list
, i
, oa
)) {
588 for (ALL_LIST_ELEMENTS_RO(oa
->if_list
, j
, oi
)) {
589 for (ALL_LIST_ELEMENTS_RO(oi
->neighbor_list
, k
, on
)) {
590 if (on
->state
!= OSPF6_NEIGHBOR_EXCHANGE
591 && on
->state
!= OSPF6_NEIGHBOR_LOADING
)
594 ospf6_maxage_remove(o
);
600 for (ALL_LIST_ELEMENTS_RO(o
->area_list
, i
, oa
)) {
601 for (ALL_LIST_ELEMENTS_RO(oa
->if_list
, j
, oi
)) {
602 if (ospf6_lsdb_maxage_remover(oi
->lsdb
)) {
607 if (ospf6_lsdb_maxage_remover(oa
->lsdb
)) {
612 if (ospf6_lsdb_maxage_remover(o
->lsdb
)) {
617 ospf6_maxage_remove(o
);
621 void ospf6_maxage_remove(struct ospf6
*o
)
624 event_add_timer(master
, ospf6_maxage_remover
, o
,
625 OSPF_LSA_MAXAGE_REMOVE_DELAY_DEFAULT
,
629 bool ospf6_router_id_update(struct ospf6
*ospf6
, bool init
)
631 in_addr_t new_router_id
;
632 struct listnode
*node
;
633 struct ospf6_area
*oa
;
638 if (ospf6
->router_id_static
!= 0)
639 new_router_id
= ospf6
->router_id_static
;
641 new_router_id
= ospf6
->router_id_zebra
;
643 if (ospf6
->router_id
== new_router_id
)
647 for (ALL_LIST_ELEMENTS_RO(ospf6
->area_list
, node
, oa
)) {
650 "%s: cannot update router-id. Run the \"clear ipv6 ospf6 process\" command",
656 ospf6
->router_id
= new_router_id
;
661 DEFUN_NOSH(router_ospf6
, router_ospf6_cmd
, "router ospf6 [vrf NAME]",
662 ROUTER_STR OSPF6_STR VRF_CMD_HELP_STR
)
665 const char *vrf_name
= VRF_DEFAULT_NAME
;
668 if (argv_find(argv
, argc
, "vrf", &idx_vrf
)) {
669 vrf_name
= argv
[idx_vrf
+ 1]->arg
;
672 ospf6
= ospf6_lookup_by_vrf_name(vrf_name
);
674 ospf6
= ospf6_instance_create(vrf_name
);
676 /* set current ospf point. */
677 VTY_PUSH_CONTEXT(OSPF6_NODE
, ospf6
);
683 DEFUN(no_router_ospf6
, no_router_ospf6_cmd
, "no router ospf6 [vrf NAME]",
684 NO_STR ROUTER_STR OSPF6_STR VRF_CMD_HELP_STR
)
687 const char *vrf_name
= VRF_DEFAULT_NAME
;
690 if (argv_find(argv
, argc
, "vrf", &idx_vrf
)) {
691 vrf_name
= argv
[idx_vrf
+ 1]->arg
;
694 ospf6
= ospf6_lookup_by_vrf_name(vrf_name
);
696 vty_out(vty
, "OSPFv3 is not configured\n");
698 if (ospf6
->gr_info
.restart_support
)
699 ospf6_gr_nvm_delete(ospf6
);
705 /* return to config node . */
706 VTY_PUSH_CONTEXT_NULL(CONFIG_NODE
);
711 static void ospf6_db_clear(struct ospf6
*ospf6
)
713 struct ospf6_interface
*oi
;
714 struct interface
*ifp
;
715 struct vrf
*vrf
= vrf_lookup_by_id(ospf6
->vrf_id
);
716 struct listnode
*node
, *nnode
;
717 struct ospf6_area
*oa
;
719 FOR_ALL_INTERFACES (vrf
, ifp
) {
720 if (if_is_operative(ifp
) && ifp
->info
!= NULL
) {
721 oi
= (struct ospf6_interface
*)ifp
->info
;
722 ospf6_lsdb_remove_all(oi
->lsdb
);
723 ospf6_lsdb_remove_all(oi
->lsdb_self
);
724 ospf6_lsdb_remove_all(oi
->lsupdate_list
);
725 ospf6_lsdb_remove_all(oi
->lsack_list
);
729 for (ALL_LIST_ELEMENTS(ospf6
->area_list
, node
, nnode
, oa
)) {
730 ospf6_lsdb_remove_all(oa
->lsdb
);
731 ospf6_lsdb_remove_all(oa
->lsdb_self
);
733 ospf6_spf_table_finish(oa
->spf_table
);
734 ospf6_route_remove_all(oa
->route_table
);
737 ospf6_lsdb_remove_all(ospf6
->lsdb
);
738 ospf6_lsdb_remove_all(ospf6
->lsdb_self
);
739 ospf6_route_remove_all(ospf6
->route_table
);
740 ospf6_route_remove_all(ospf6
->brouter_table
);
743 static void ospf6_process_reset(struct ospf6
*ospf6
)
745 struct interface
*ifp
;
746 struct vrf
*vrf
= vrf_lookup_by_id(ospf6
->vrf_id
);
748 ospf6_unset_all_aggr_flag(ospf6
);
749 ospf6_flush_self_originated_lsas_now(ospf6
);
750 ospf6
->inst_shutdown
= 0;
751 ospf6_db_clear(ospf6
);
753 ospf6_asbr_redistribute_reset(ospf6
);
754 FOR_ALL_INTERFACES (vrf
, ifp
)
755 ospf6_interface_clear(ifp
);
758 DEFPY (clear_router_ospf6
,
759 clear_router_ospf6_cmd
,
760 "clear ipv6 ospf6 process [vrf NAME$name]",
764 "Reset OSPF Process\n"
768 const char *vrf_name
= VRF_DEFAULT_NAME
;
773 ospf6
= ospf6_lookup_by_vrf_name(vrf_name
);
775 vty_out(vty
, "OSPFv3 is not configured\n");
777 ospf6_router_id_update(ospf6
, true);
778 ospf6_process_reset(ospf6
);
784 /* change Router_ID commands. */
785 DEFUN(ospf6_router_id
,
787 "ospf6 router-id A.B.C.D",
789 "Configure OSPF6 Router-ID\n"
792 VTY_DECLVAR_CONTEXT(ospf6
, o
);
795 const char *router_id_str
;
798 argv_find(argv
, argc
, "A.B.C.D", &idx
);
799 router_id_str
= argv
[idx
]->arg
;
801 ret
= inet_pton(AF_INET
, router_id_str
, &router_id
);
803 vty_out(vty
, "malformed OSPF Router-ID: %s\n", router_id_str
);
807 o
->router_id_static
= router_id
;
809 if (ospf6_router_id_update(o
, false))
810 ospf6_process_reset(o
);
813 "For this router-id change to take effect run the \"clear ipv6 ospf6 process\" command\n");
818 DEFUN(no_ospf6_router_id
,
819 no_ospf6_router_id_cmd
,
820 "no ospf6 router-id [A.B.C.D]",
822 "Configure OSPF6 Router-ID\n"
825 VTY_DECLVAR_CONTEXT(ospf6
, o
);
827 o
->router_id_static
= 0;
830 if (ospf6_router_id_update(o
, false))
831 ospf6_process_reset(o
);
834 "For this router-id change to take effect run the \"clear ipv6 ospf6 process\" command\n");
839 DEFUN (ospf6_log_adjacency_changes
,
840 ospf6_log_adjacency_changes_cmd
,
841 "log-adjacency-changes",
842 "Log changes in adjacency state\n")
844 VTY_DECLVAR_CONTEXT(ospf6
, ospf6
);
846 SET_FLAG(ospf6
->config_flags
, OSPF6_LOG_ADJACENCY_CHANGES
);
847 UNSET_FLAG(ospf6
->config_flags
, OSPF6_LOG_ADJACENCY_DETAIL
);
851 DEFUN (ospf6_log_adjacency_changes_detail
,
852 ospf6_log_adjacency_changes_detail_cmd
,
853 "log-adjacency-changes detail",
854 "Log changes in adjacency state\n"
855 "Log all state changes\n")
857 VTY_DECLVAR_CONTEXT(ospf6
, ospf6
);
859 SET_FLAG(ospf6
->config_flags
, OSPF6_LOG_ADJACENCY_CHANGES
);
860 SET_FLAG(ospf6
->config_flags
, OSPF6_LOG_ADJACENCY_DETAIL
);
864 DEFUN (no_ospf6_log_adjacency_changes
,
865 no_ospf6_log_adjacency_changes_cmd
,
866 "no log-adjacency-changes",
868 "Log changes in adjacency state\n")
870 VTY_DECLVAR_CONTEXT(ospf6
, ospf6
);
872 UNSET_FLAG(ospf6
->config_flags
, OSPF6_LOG_ADJACENCY_DETAIL
);
873 UNSET_FLAG(ospf6
->config_flags
, OSPF6_LOG_ADJACENCY_CHANGES
);
877 DEFUN (no_ospf6_log_adjacency_changes_detail
,
878 no_ospf6_log_adjacency_changes_detail_cmd
,
879 "no log-adjacency-changes detail",
881 "Log changes in adjacency state\n"
882 "Log all state changes\n")
884 VTY_DECLVAR_CONTEXT(ospf6
, ospf6
);
886 UNSET_FLAG(ospf6
->config_flags
, OSPF6_LOG_ADJACENCY_DETAIL
);
890 static void ospf6_reinstall_routes(struct ospf6
*ospf6
)
892 struct ospf6_route
*route
;
894 for (route
= ospf6_route_head(ospf6
->route_table
); route
;
895 route
= ospf6_route_next(route
))
896 ospf6_zebra_route_update_add(route
, ospf6
);
899 DEFPY (ospf6_send_extra_data
,
900 ospf6_send_extra_data_cmd
,
901 "[no] ospf6 send-extra-data zebra",
904 "Extra data to Zebra for display/use\n"
907 VTY_DECLVAR_CONTEXT(ospf6
, ospf6
);
910 && CHECK_FLAG(ospf6
->config_flags
,
911 OSPF6_SEND_EXTRA_DATA_TO_ZEBRA
)) {
912 UNSET_FLAG(ospf6
->config_flags
, OSPF6_SEND_EXTRA_DATA_TO_ZEBRA
);
913 ospf6_reinstall_routes(ospf6
);
914 } else if (!CHECK_FLAG(ospf6
->config_flags
,
915 OSPF6_SEND_EXTRA_DATA_TO_ZEBRA
)) {
916 SET_FLAG(ospf6
->config_flags
, OSPF6_SEND_EXTRA_DATA_TO_ZEBRA
);
917 ospf6_reinstall_routes(ospf6
);
923 DEFUN (ospf6_timers_lsa
,
924 ospf6_timers_lsa_cmd
,
925 "timers lsa min-arrival (0-600000)",
926 "Adjust routing timers\n"
928 "Minimum delay in receiving new version of a LSA\n"
929 "Delay in milliseconds\n")
931 VTY_DECLVAR_CONTEXT(ospf6
, ospf
);
933 unsigned int minarrival
;
935 minarrival
= strtoul(argv
[idx_number
]->arg
, NULL
, 10);
936 ospf
->lsa_minarrival
= minarrival
;
941 DEFUN (no_ospf6_timers_lsa
,
942 no_ospf6_timers_lsa_cmd
,
943 "no timers lsa min-arrival [(0-600000)]",
945 "Adjust routing timers\n"
947 "Minimum delay in receiving new version of a LSA\n"
948 "Delay in milliseconds\n")
950 VTY_DECLVAR_CONTEXT(ospf6
, ospf
);
952 unsigned int minarrival
;
955 minarrival
= strtoul(argv
[idx_number
]->arg
, NULL
, 10);
957 if (ospf
->lsa_minarrival
!= minarrival
958 || minarrival
== OSPF_MIN_LS_ARRIVAL
)
962 ospf
->lsa_minarrival
= OSPF_MIN_LS_ARRIVAL
;
968 DEFUN (ospf6_distance
,
971 "Administrative distance\n"
972 "OSPF6 Administrative distance\n")
974 VTY_DECLVAR_CONTEXT(ospf6
, o
);
977 distance
= atoi(argv
[1]->arg
);
978 if (o
->distance_all
!= distance
) {
979 o
->distance_all
= distance
;
980 ospf6_restart_spf(o
);
986 DEFUN (no_ospf6_distance
,
987 no_ospf6_distance_cmd
,
988 "no distance (1-255)",
990 "Administrative distance\n"
991 "OSPF6 Administrative distance\n")
993 VTY_DECLVAR_CONTEXT(ospf6
, o
);
995 if (o
->distance_all
) {
997 ospf6_restart_spf(o
);
1002 DEFUN (ospf6_distance_ospf6
,
1003 ospf6_distance_ospf6_cmd
,
1004 "distance ospf6 {intra-area (1-255)|inter-area (1-255)|external (1-255)}",
1005 "Administrative distance\n"
1006 "OSPF6 administrative distance\n"
1007 "Intra-area routes\n"
1008 "Distance for intra-area routes\n"
1009 "Inter-area routes\n"
1010 "Distance for inter-area routes\n"
1012 "Distance for external routes\n")
1014 VTY_DECLVAR_CONTEXT(ospf6
, o
);
1017 o
->distance_intra
= 0;
1018 o
->distance_inter
= 0;
1019 o
->distance_external
= 0;
1021 if (argv_find(argv
, argc
, "intra-area", &idx
))
1022 o
->distance_intra
= atoi(argv
[idx
+ 1]->arg
);
1024 if (argv_find(argv
, argc
, "inter-area", &idx
))
1025 o
->distance_inter
= atoi(argv
[idx
+ 1]->arg
);
1027 if (argv_find(argv
, argc
, "external", &idx
))
1028 o
->distance_external
= atoi(argv
[idx
+ 1]->arg
);
1033 DEFUN (no_ospf6_distance_ospf6
,
1034 no_ospf6_distance_ospf6_cmd
,
1035 "no distance ospf6 [{intra-area [(1-255)]|inter-area [(1-255)]|external [(1-255)]}]",
1037 "Administrative distance\n"
1039 "Intra-area routes\n"
1040 "Distance for intra-area routes\n"
1041 "Inter-area routes\n"
1042 "Distance for inter-area routes\n"
1044 "Distance for external routes\n")
1046 VTY_DECLVAR_CONTEXT(ospf6
, o
);
1049 if (argv_find(argv
, argc
, "intra-area", &idx
) || argc
== 3)
1050 idx
= o
->distance_intra
= 0;
1051 if (argv_find(argv
, argc
, "inter-area", &idx
) || argc
== 3)
1052 idx
= o
->distance_inter
= 0;
1053 if (argv_find(argv
, argc
, "external", &idx
) || argc
== 3)
1054 o
->distance_external
= 0;
1059 DEFUN_HIDDEN (ospf6_interface_area
,
1060 ospf6_interface_area_cmd
,
1061 "interface IFNAME area <A.B.C.D|(0-4294967295)>",
1062 "Enable routing on an IPv6 interface\n"
1064 "Specify the OSPF6 area ID\n"
1065 "OSPF6 area ID in IPv4 address notation\n"
1066 "OSPF6 area ID in decimal notation\n"
1069 VTY_DECLVAR_CONTEXT(ospf6
, ospf6
);
1072 struct ospf6_area
*oa
;
1073 struct ospf6_interface
*oi
;
1074 struct interface
*ifp
;
1079 "This command is deprecated, because it is not VRF-aware.\n");
1081 "Please, use \"ipv6 ospf6 area\" on an interface instead.\n");
1083 /* find/create ospf6 interface */
1084 ifp
= if_get_by_name(argv
[idx_ifname
]->arg
, ospf6
->vrf_id
, ospf6
->name
);
1085 oi
= (struct ospf6_interface
*)ifp
->info
;
1087 oi
= ospf6_interface_create(ifp
);
1089 vty_out(vty
, "%s already attached to Area %s\n",
1090 oi
->interface
->name
, oi
->area
->name
);
1094 if (str2area_id(argv
[idx_ipv4
]->arg
, &area_id
, &format
)) {
1095 vty_out(vty
, "Malformed Area-ID: %s\n", argv
[idx_ipv4
]->arg
);
1096 return CMD_WARNING_CONFIG_FAILED
;
1099 oi
->area_id
= area_id
;
1100 oi
->area_id_format
= format
;
1102 oa
= ospf6_area_lookup(area_id
, ospf6
);
1104 oa
= ospf6_area_create(area_id
, ospf6
, format
);
1106 /* attach interface to area */
1107 listnode_add(oa
->if_list
, oi
); /* sort ?? */
1110 SET_FLAG(oa
->flag
, OSPF6_AREA_ENABLE
);
1112 /* ospf6 process is currently disabled, not much more to do */
1113 if (CHECK_FLAG(ospf6
->flag
, OSPF6_DISABLED
))
1117 ospf6_interface_enable(oi
);
1119 /* If the router is ABR, originate summary routes */
1120 if (ospf6_check_and_set_router_abr(ospf6
)) {
1121 ospf6_abr_enable_area(oa
);
1122 ospf6_schedule_abr_task(oa
->ospf6
);
1128 DEFUN_HIDDEN (no_ospf6_interface_area
,
1129 no_ospf6_interface_area_cmd
,
1130 "no interface IFNAME area <A.B.C.D|(0-4294967295)>",
1132 "Disable routing on an IPv6 interface\n"
1134 "Specify the OSPF6 area ID\n"
1135 "OSPF6 area ID in IPv4 address notation\n"
1136 "OSPF6 area ID in decimal notation\n"
1139 VTY_DECLVAR_CONTEXT(ospf6
, ospf6
);
1142 struct ospf6_interface
*oi
;
1143 struct ospf6_area
*oa
;
1144 struct interface
*ifp
;
1148 "This command is deprecated, because it is not VRF-aware.\n");
1150 "Please, use \"no ipv6 ospf6 area\" on an interface instead.\n");
1152 /* find/create ospf6 interface */
1153 ifp
= if_get_by_name(argv
[idx_ifname
]->arg
, ospf6
->vrf_id
, ospf6
->name
);
1156 vty_out(vty
, "No such interface %s\n", argv
[idx_ifname
]->arg
);
1160 oi
= (struct ospf6_interface
*)ifp
->info
;
1162 vty_out(vty
, "Interface %s not enabled\n", ifp
->name
);
1167 if (inet_pton(AF_INET
, argv
[idx_ipv4
]->arg
, &area_id
) != 1)
1168 area_id
= htonl(strtoul(argv
[idx_ipv4
]->arg
, NULL
, 10));
1171 if (oi
->area
== NULL
) {
1172 vty_out(vty
, "%s not attached to area %s\n",
1173 oi
->interface
->name
, argv
[idx_ipv4
]->arg
);
1177 if (oi
->area
->area_id
!= area_id
) {
1178 vty_out(vty
, "Wrong Area-ID: %s is attached to area %s\n",
1179 oi
->interface
->name
, oi
->area
->name
);
1183 ospf6_interface_disable(oi
);
1186 listnode_delete(oi
->area
->if_list
, oi
);
1187 oi
->area
= (struct ospf6_area
*)NULL
;
1189 /* Withdraw inter-area routes from this area, if necessary */
1190 if (oa
->if_list
->count
== 0) {
1191 UNSET_FLAG(oa
->flag
, OSPF6_AREA_ENABLE
);
1192 ospf6_abr_disable_area(oa
);
1196 oi
->area_id_format
= OSPF6_AREA_FMT_UNSET
;
1201 DEFUN (ospf6_stub_router_admin
,
1202 ospf6_stub_router_admin_cmd
,
1203 "stub-router administrative",
1204 "Make router a stub router\n"
1205 "Administratively applied, for an indefinite period\n")
1207 struct listnode
*node
;
1208 struct ospf6_area
*oa
;
1210 VTY_DECLVAR_CONTEXT(ospf6
, ospf6
);
1212 if (!CHECK_FLAG(ospf6
->flag
, OSPF6_STUB_ROUTER
)) {
1213 for (ALL_LIST_ELEMENTS_RO(ospf6
->area_list
, node
, oa
)) {
1214 OSPF6_OPT_CLEAR(oa
->options
, OSPF6_OPT_V6
);
1215 OSPF6_OPT_CLEAR(oa
->options
, OSPF6_OPT_R
);
1216 OSPF6_ROUTER_LSA_SCHEDULE(oa
);
1218 SET_FLAG(ospf6
->flag
, OSPF6_STUB_ROUTER
);
1224 DEFUN (no_ospf6_stub_router_admin
,
1225 no_ospf6_stub_router_admin_cmd
,
1226 "no stub-router administrative",
1228 "Make router a stub router\n"
1229 "Administratively applied, for an indefinite period\n")
1231 struct listnode
*node
;
1232 struct ospf6_area
*oa
;
1234 VTY_DECLVAR_CONTEXT(ospf6
, ospf6
);
1235 if (CHECK_FLAG(ospf6
->flag
, OSPF6_STUB_ROUTER
)) {
1236 for (ALL_LIST_ELEMENTS_RO(ospf6
->area_list
, node
, oa
)) {
1237 OSPF6_OPT_SET(oa
->options
, OSPF6_OPT_V6
);
1238 OSPF6_OPT_SET(oa
->options
, OSPF6_OPT_R
);
1239 OSPF6_ROUTER_LSA_SCHEDULE(oa
);
1241 UNSET_FLAG(ospf6
->flag
, OSPF6_STUB_ROUTER
);
1247 /* Restart OSPF SPF algorithm*/
1248 void ospf6_restart_spf(struct ospf6
*ospf6
)
1250 ospf6_route_remove_all(ospf6
->route_table
);
1251 ospf6_route_remove_all(ospf6
->brouter_table
);
1254 ospf6_spf_schedule(ospf6
, OSPF6_SPF_FLAGS_CONFIG_CHANGE
);
1257 /* Set the max paths */
1258 static void ospf6_maxpath_set(struct ospf6
*ospf6
, uint16_t paths
)
1260 if (ospf6
->max_multipath
== paths
)
1263 ospf6
->max_multipath
= paths
;
1265 /* Send deletion to zebra to delete all
1266 * ospf specific routes and reinitiate
1267 * SPF to reflect the new max multipath.
1269 ospf6_restart_spf(ospf6
);
1272 /* Ospf Maximum-paths config support */
1273 DEFUN(ospf6_max_multipath
,
1274 ospf6_max_multipath_cmd
,
1275 "maximum-paths " CMD_RANGE_STR(1, MULTIPATH_NUM
),
1276 "Max no of multiple paths for ECMP support\n"
1277 "Number of paths\n")
1279 VTY_DECLVAR_CONTEXT(ospf6
, ospf6
);
1281 int maximum_paths
= strtol(argv
[idx_number
]->arg
, NULL
, 10);
1283 ospf6_maxpath_set(ospf6
, maximum_paths
);
1288 DEFUN(no_ospf6_max_multipath
,
1289 no_ospf6_max_multipath_cmd
,
1290 "no maximum-paths [" CMD_RANGE_STR(1, MULTIPATH_NUM
)"]",
1292 "Max no of multiple paths for ECMP support\n"
1293 "Number of paths\n")
1295 VTY_DECLVAR_CONTEXT(ospf6
, ospf6
);
1297 ospf6_maxpath_set(ospf6
, MULTIPATH_NUM
);
1302 static void ospf6_show(struct vty
*vty
, struct ospf6
*o
, json_object
*json
,
1306 struct ospf6_area
*oa
;
1307 char router_id
[16], duration
[32];
1308 struct timeval now
, running
, result
;
1309 char buf
[32], rbuf
[32];
1310 json_object
*json_areas
= NULL
;
1311 const char *adjacency
;
1314 json_areas
= json_object_new_object();
1316 /* process id, router id */
1317 inet_ntop(AF_INET
, &o
->router_id
, router_id
, sizeof(router_id
));
1318 json_object_string_add(json
, "routerId", router_id
);
1322 timersub(&now
, &o
->starttime
, &running
);
1323 timerstring(&running
, duration
, sizeof(duration
));
1324 json_object_string_add(json
, "running", duration
);
1326 /* Redistribute configuration */
1328 json_object_int_add(json
, "lsaMinimumArrivalMsecs",
1331 /* Show SPF parameters */
1332 json_object_int_add(json
, "spfScheduleDelayMsecs",
1334 json_object_int_add(json
, "holdTimeMinMsecs", o
->spf_holdtime
);
1335 json_object_int_add(json
, "holdTimeMaxMsecs",
1336 o
->spf_max_holdtime
);
1337 json_object_int_add(json
, "holdTimeMultiplier",
1338 o
->spf_hold_multiplier
);
1340 json_object_int_add(json
, "maximumPaths", o
->max_multipath
);
1341 json_object_int_add(json
, "preference",
1344 : ZEBRA_OSPF6_DISTANCE_DEFAULT
);
1346 if (o
->ts_spf
.tv_sec
|| o
->ts_spf
.tv_usec
) {
1347 timersub(&now
, &o
->ts_spf
, &result
);
1348 timerstring(&result
, buf
, sizeof(buf
));
1349 ospf6_spf_reason_string(o
->last_spf_reason
, rbuf
,
1351 json_object_boolean_true_add(json
, "spfHasRun");
1352 json_object_string_add(json
, "spfLastExecutedMsecs",
1354 json_object_string_add(json
, "spfLastExecutedReason",
1357 json_object_int_add(
1358 json
, "spfLastDurationSecs",
1359 (long long)o
->ts_spf_duration
.tv_sec
);
1361 json_object_int_add(
1362 json
, "spfLastDurationMsecs",
1363 (long long)o
->ts_spf_duration
.tv_usec
);
1365 json_object_boolean_false_add(json
, "spfHasRun");
1367 if (event_is_scheduled(o
->t_spf_calc
)) {
1370 json_object_boolean_true_add(json
, "spfTimerActive");
1372 monotime_until(&o
->t_spf_calc
->u
.sands
, NULL
)
1374 json_object_int_add(json
, "spfTimerDueInMsecs",
1377 json_object_boolean_false_add(json
, "spfTimerActive");
1379 json_object_boolean_add(json
, "routerIsStubRouter",
1380 CHECK_FLAG(o
->flag
, OSPF6_STUB_ROUTER
));
1383 json_object_int_add(json
, "numberOfAsScopedLsa",
1386 json_object_int_add(json
, "numberOfAreaInRouter",
1387 listcount(o
->area_list
));
1389 json_object_int_add(json
, "AuthTrailerHigherSeqNo",
1391 json_object_int_add(json
, "AuthTrailerLowerSeqNo", o
->seqnum_l
);
1393 if (CHECK_FLAG(o
->config_flags
, OSPF6_LOG_ADJACENCY_CHANGES
)) {
1394 if (CHECK_FLAG(o
->config_flags
,
1395 OSPF6_LOG_ADJACENCY_DETAIL
))
1396 adjacency
= "LoggedAll";
1398 adjacency
= "Logged";
1400 adjacency
= "NotLogged";
1401 json_object_string_add(json
, "adjacencyChanges", adjacency
);
1403 for (ALL_LIST_ELEMENTS_RO(o
->area_list
, n
, oa
))
1404 ospf6_area_show(vty
, oa
, json_areas
, use_json
);
1406 json_object_object_add(json
, "areas", json_areas
);
1408 vty_out(vty
, "%s\n",
1409 json_object_to_json_string_ext(
1410 json
, JSON_C_TO_STRING_PRETTY
));
1413 /* process id, router id */
1414 inet_ntop(AF_INET
, &o
->router_id
, router_id
, sizeof(router_id
));
1415 vty_out(vty
, " OSPFv3 Routing Process (0) with Router-ID %s\n",
1420 timersub(&now
, &o
->starttime
, &running
);
1421 timerstring(&running
, duration
, sizeof(duration
));
1422 vty_out(vty
, " Running %s\n", duration
);
1424 /* Redistribute configuration */
1426 vty_out(vty
, " LSA minimum arrival %d msecs\n",
1429 vty_out(vty
, " Maximum-paths %u\n", o
->max_multipath
);
1430 vty_out(vty
, " Administrative distance %u\n",
1431 o
->distance_all
? o
->distance_all
1432 : ZEBRA_OSPF6_DISTANCE_DEFAULT
);
1434 /* Show SPF parameters */
1436 " Initial SPF scheduling delay %d millisec(s)\n"
1437 " Minimum hold time between consecutive SPFs %d millsecond(s)\n"
1438 " Maximum hold time between consecutive SPFs %d millsecond(s)\n"
1439 " Hold time multiplier is currently %d\n",
1440 o
->spf_delay
, o
->spf_holdtime
, o
->spf_max_holdtime
,
1441 o
->spf_hold_multiplier
);
1444 vty_out(vty
, " SPF algorithm ");
1445 if (o
->ts_spf
.tv_sec
|| o
->ts_spf
.tv_usec
) {
1446 timersub(&now
, &o
->ts_spf
, &result
);
1447 timerstring(&result
, buf
, sizeof(buf
));
1448 ospf6_spf_reason_string(o
->last_spf_reason
, rbuf
,
1450 vty_out(vty
, "last executed %s ago, reason %s\n", buf
,
1452 vty_out(vty
, " Last SPF duration %lld sec %lld usec\n",
1453 (long long)o
->ts_spf_duration
.tv_sec
,
1454 (long long)o
->ts_spf_duration
.tv_usec
);
1456 vty_out(vty
, "has not been run\n");
1458 threadtimer_string(now
, o
->t_spf_calc
, buf
, sizeof(buf
));
1459 vty_out(vty
, " SPF timer %s%s\n",
1460 (event_is_scheduled(o
->t_spf_calc
) ? "due in " : "is "),
1463 if (CHECK_FLAG(o
->flag
, OSPF6_STUB_ROUTER
))
1464 vty_out(vty
, " Router Is Stub Router\n");
1467 vty_out(vty
, " Number of AS scoped LSAs is %u\n",
1471 vty_out(vty
, " Number of areas in this router is %u\n",
1472 listcount(o
->area_list
));
1474 vty_out(vty
, " Authentication Sequence number info\n");
1475 vty_out(vty
, " Higher sequence no %u, Lower sequence no %u\n",
1476 o
->seqnum_h
, o
->seqnum_l
);
1478 if (CHECK_FLAG(o
->config_flags
, OSPF6_LOG_ADJACENCY_CHANGES
)) {
1479 if (CHECK_FLAG(o
->config_flags
,
1480 OSPF6_LOG_ADJACENCY_DETAIL
))
1482 " All adjacency changes are logged\n");
1484 vty_out(vty
, " Adjacency changes are logged\n");
1490 for (ALL_LIST_ELEMENTS_RO(o
->area_list
, n
, oa
))
1491 ospf6_area_show(vty
, oa
, json_areas
, use_json
);
1495 DEFUN(show_ipv6_ospf6_vrfs
, show_ipv6_ospf6_vrfs_cmd
,
1496 "show ipv6 ospf6 vrfs [json]",
1497 SHOW_STR IP6_STR OSPF6_STR
"Show OSPF6 VRFs \n" JSON_STR
)
1499 bool uj
= use_json(argc
, argv
);
1500 json_object
*json
= NULL
;
1501 json_object
*json_vrfs
= NULL
;
1502 struct ospf6
*ospf6
= NULL
;
1503 struct listnode
*node
= NULL
;
1505 char buf
[PREFIX_STRLEN
];
1506 static const char header
[] =
1507 "Name Id RouterId ";
1510 json
= json_object_new_object();
1511 json_vrfs
= json_object_new_object();
1514 for (ALL_LIST_ELEMENTS_RO(om6
->ospf6
, node
, ospf6
)) {
1515 json_object
*json_vrf
= NULL
;
1516 const char *name
= NULL
;
1517 int64_t vrf_id_ui
= 0;
1518 struct in_addr router_id
;
1520 router_id
.s_addr
= ospf6
->router_id
;
1523 if (!uj
&& count
== 1)
1524 vty_out(vty
, "%s\n", header
);
1526 json_vrf
= json_object_new_object();
1528 if (ospf6
->vrf_id
== VRF_DEFAULT
)
1529 name
= VRF_DEFAULT_NAME
;
1533 vrf_id_ui
= (ospf6
->vrf_id
== VRF_UNKNOWN
)
1535 : (int64_t)ospf6
->vrf_id
;
1538 json_object_int_add(json_vrf
, "vrfId", vrf_id_ui
);
1539 json_object_string_addf(json_vrf
, "routerId", "%pI4",
1541 json_object_object_add(json_vrfs
, name
, json_vrf
);
1544 vty_out(vty
, "%-25s %-5d %-16s \n", name
,
1546 inet_ntop(AF_INET
, &router_id
, buf
,
1552 json_object_object_add(json
, "vrfs", json_vrfs
);
1553 json_object_int_add(json
, "totalVrfs", count
);
1555 vty_json(vty
, json
);
1558 vty_out(vty
, "\nTotal number of OSPF VRFs: %d\n",
1565 /* show top level structures */
1566 DEFUN(show_ipv6_ospf6
, show_ipv6_ospf6_cmd
,
1567 "show ipv6 ospf6 [vrf <NAME|all>] [json]",
1568 SHOW_STR IP6_STR OSPF6_STR VRF_CMD_HELP_STR
"All VRFs\n" JSON_STR
)
1570 struct ospf6
*ospf6
;
1571 struct listnode
*node
;
1572 const char *vrf_name
= NULL
;
1573 bool all_vrf
= false;
1576 bool uj
= use_json(argc
, argv
);
1577 json_object
*json
= NULL
;
1579 OSPF6_FIND_VRF_ARGS(argv
, argc
, idx_vrf
, vrf_name
, all_vrf
);
1581 for (ALL_LIST_ELEMENTS_RO(om6
->ospf6
, node
, ospf6
)) {
1582 if (all_vrf
|| strcmp(ospf6
->name
, vrf_name
) == 0) {
1584 json
= json_object_new_object();
1585 ospf6_show(vty
, ospf6
, json
, uj
);
1593 json_object_free(json
);
1595 OSPF6_CMD_CHECK_VRF(uj
, all_vrf
, ospf6
);
1600 DEFUN(show_ipv6_ospf6_route
, show_ipv6_ospf6_route_cmd
,
1601 "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]",
1602 SHOW_STR IP6_STR OSPF6_STR VRF_CMD_HELP_STR
1603 "All VRFs\n" ROUTE_STR
1604 "Display Intra-Area routes\n"
1605 "Display Inter-Area routes\n"
1606 "Display Type-1 External routes\n"
1607 "Display Type-2 External routes\n"
1608 "Specify IPv6 address\n"
1609 "Specify IPv6 prefix\n"
1610 "Detailed information\n"
1611 "Summary of route table\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_arg_start
= 4;
1619 bool uj
= use_json(argc
, argv
);
1621 OSPF6_FIND_VRF_ARGS(argv
, argc
, idx_vrf
, vrf_name
, all_vrf
);
1625 for (ALL_LIST_ELEMENTS_RO(om6
->ospf6
, node
, ospf6
)) {
1626 if (all_vrf
|| strcmp(ospf6
->name
, vrf_name
) == 0) {
1627 ospf6_route_table_show(vty
, idx_arg_start
, argc
, argv
,
1628 ospf6
->route_table
, uj
);
1635 OSPF6_CMD_CHECK_VRF(uj
, all_vrf
, ospf6
);
1640 DEFUN(show_ipv6_ospf6_route_match
, show_ipv6_ospf6_route_match_cmd
,
1641 "show ipv6 ospf6 [vrf <NAME|all>] route X:X::X:X/M <match|longer> [json]",
1642 SHOW_STR IP6_STR OSPF6_STR VRF_CMD_HELP_STR
1643 "All VRFs\n" ROUTE_STR
1644 "Specify IPv6 prefix\n"
1645 "Display routes which match the specified route\n"
1646 "Display routes longer than the specified route\n" JSON_STR
)
1648 struct ospf6
*ospf6
;
1649 struct listnode
*node
;
1650 const char *vrf_name
= NULL
;
1651 bool all_vrf
= false;
1653 int idx_start_arg
= 4;
1654 bool uj
= use_json(argc
, argv
);
1656 OSPF6_FIND_VRF_ARGS(argv
, argc
, idx_vrf
, vrf_name
, all_vrf
);
1660 for (ALL_LIST_ELEMENTS_RO(om6
->ospf6
, node
, ospf6
)) {
1661 if (all_vrf
|| strcmp(ospf6
->name
, vrf_name
) == 0) {
1662 ospf6_route_table_show(vty
, idx_start_arg
, argc
, argv
,
1663 ospf6
->route_table
, uj
);
1670 OSPF6_CMD_CHECK_VRF(uj
, all_vrf
, ospf6
);
1675 DEFUN(show_ipv6_ospf6_route_match_detail
,
1676 show_ipv6_ospf6_route_match_detail_cmd
,
1677 "show ipv6 ospf6 [vrf <NAME|all>] route X:X::X:X/M match detail [json]",
1678 SHOW_STR IP6_STR OSPF6_STR VRF_CMD_HELP_STR
1679 "All VRFs\n" ROUTE_STR
1680 "Specify IPv6 prefix\n"
1681 "Display routes which match the specified route\n"
1682 "Detailed information\n" JSON_STR
)
1684 struct ospf6
*ospf6
;
1685 struct listnode
*node
;
1686 const char *vrf_name
= NULL
;
1687 bool all_vrf
= false;
1689 int idx_start_arg
= 4;
1690 bool uj
= use_json(argc
, argv
);
1692 OSPF6_FIND_VRF_ARGS(argv
, argc
, idx_vrf
, vrf_name
, all_vrf
);
1696 for (ALL_LIST_ELEMENTS_RO(om6
->ospf6
, node
, ospf6
)) {
1697 if (all_vrf
|| strcmp(ospf6
->name
, vrf_name
) == 0) {
1698 ospf6_route_table_show(vty
, idx_start_arg
, argc
, argv
,
1699 ospf6
->route_table
, uj
);
1706 OSPF6_CMD_CHECK_VRF(uj
, all_vrf
, ospf6
);
1711 DEFUN(show_ipv6_ospf6_route_type_detail
, show_ipv6_ospf6_route_type_detail_cmd
,
1712 "show ipv6 ospf6 [vrf <NAME|all>] route <intra-area|inter-area|external-1|external-2> detail [json]",
1713 SHOW_STR IP6_STR OSPF6_STR VRF_CMD_HELP_STR
1714 "All VRFs\n" ROUTE_STR
1715 "Display Intra-Area routes\n"
1716 "Display Inter-Area routes\n"
1717 "Display Type-1 External routes\n"
1718 "Display Type-2 External routes\n"
1719 "Detailed information\n" JSON_STR
)
1721 struct ospf6
*ospf6
;
1722 struct listnode
*node
;
1723 const char *vrf_name
= NULL
;
1724 bool all_vrf
= false;
1726 int idx_start_arg
= 4;
1727 bool uj
= use_json(argc
, argv
);
1729 OSPF6_FIND_VRF_ARGS(argv
, argc
, idx_vrf
, vrf_name
, all_vrf
);
1733 for (ALL_LIST_ELEMENTS_RO(om6
->ospf6
, node
, ospf6
)) {
1734 if (all_vrf
|| strcmp(ospf6
->name
, vrf_name
) == 0) {
1735 ospf6_route_table_show(vty
, idx_start_arg
, argc
, argv
,
1736 ospf6
->route_table
, uj
);
1743 OSPF6_CMD_CHECK_VRF(uj
, all_vrf
, ospf6
);
1748 bool ospf6_is_valid_summary_addr(struct vty
*vty
, struct prefix
*p
)
1750 /* Default prefix validation*/
1751 if (is_default_prefix(p
)) {
1753 "Default address should not be configured as summary address.\n");
1757 /* Host route should not be configured as summary address */
1758 if (p
->prefixlen
== IPV6_MAX_BITLEN
) {
1759 vty_out(vty
, "Host route should not be configured as summary address.\n");
1766 /* External Route Aggregation */
1767 DEFPY (ospf6_external_route_aggregation
,
1768 ospf6_external_route_aggregation_cmd
,
1769 "summary-address X:X::X:X/M$prefix [tag (1-4294967295)] [{metric (0-16777215) | metric-type (1-2)$mtype}]",
1770 "External summary address\n"
1771 "Specify IPv6 prefix\n"
1773 "Router tag value\n"
1775 "Advertised metric for this route\n"
1776 "OSPFv3 exterior metric type for summarised routes\n"
1777 "Set OSPFv3 External Type 1/2 metrics\n")
1779 VTY_DECLVAR_CONTEXT(ospf6
, ospf6
);
1782 int ret
= CMD_SUCCESS
;
1784 p
.family
= AF_INET6
;
1785 ret
= str2prefix(prefix_str
, &p
);
1787 vty_out(vty
, "Malformed prefix\n");
1788 return CMD_WARNING_CONFIG_FAILED
;
1791 /* Apply mask for given prefix. */
1794 if (!ospf6_is_valid_summary_addr(vty
, &p
))
1795 return CMD_WARNING_CONFIG_FAILED
;
1804 mtype
= DEFAULT_METRIC_TYPE
;
1806 ret
= ospf6_external_aggr_config_set(ospf6
, &p
, tag
, metric
, mtype
);
1807 if (ret
== OSPF6_FAILURE
) {
1808 vty_out(vty
, "Invalid configuration!!\n");
1809 return CMD_WARNING_CONFIG_FAILED
;
1815 DEFPY(no_ospf6_external_route_aggregation
,
1816 no_ospf6_external_route_aggregation_cmd
,
1817 "no summary-address X:X::X:X/M$prefix [tag (1-4294967295)] [{metric (0-16777215) | metric-type (1-2)}]",
1819 "External summary address\n"
1820 "Specify IPv6 prefix\n"
1822 "Router tag value\n"
1824 "Advertised metric for this route\n"
1825 "OSPFv3 exterior metric type for summarised routes\n"
1826 "Set OSPFv3 External Type 1/2 metrics\n")
1828 VTY_DECLVAR_CONTEXT(ospf6
, ospf6
);
1831 int ret
= CMD_SUCCESS
;
1833 ret
= str2prefix(prefix_str
, &p
);
1835 vty_out(vty
, "Malformed prefix\n");
1836 return CMD_WARNING_CONFIG_FAILED
;
1839 /* Apply mask for given prefix. */
1842 if (!ospf6_is_valid_summary_addr(vty
, &p
))
1843 return CMD_WARNING_CONFIG_FAILED
;
1845 ret
= ospf6_external_aggr_config_unset(ospf6
, &p
);
1846 if (ret
== OSPF6_INVALID
)
1847 vty_out(vty
, "Invalid configuration!!\n");
1852 DEFPY (ospf6_external_route_aggregation_no_advertise
,
1853 ospf6_external_route_aggregation_no_advertise_cmd
,
1854 "summary-address X:X::X:X/M$prefix no-advertise",
1855 "External summary address\n"
1856 "Specify IPv6 prefix\n"
1857 "Don't advertise summary route \n")
1859 VTY_DECLVAR_CONTEXT(ospf6
, ospf6
);
1862 int ret
= CMD_SUCCESS
;
1864 ret
= str2prefix(prefix_str
, &p
);
1866 vty_out(vty
, "Malformed prefix\n");
1867 return CMD_WARNING_CONFIG_FAILED
;
1870 /* Apply mask for given prefix. */
1873 if (!ospf6_is_valid_summary_addr(vty
, &p
))
1874 return CMD_WARNING_CONFIG_FAILED
;
1876 ret
= ospf6_asbr_external_rt_no_advertise(ospf6
, &p
);
1877 if (ret
== OSPF6_INVALID
)
1878 vty_out(vty
, "!!Invalid configuration\n");
1883 DEFPY (no_ospf6_external_route_aggregation_no_advertise
,
1884 no_ospf6_external_route_aggregation_no_advertise_cmd
,
1885 "no summary-address X:X::X:X/M$prefix no-advertise",
1887 "External summary address\n"
1888 "Specify IPv6 prefix\n"
1889 "Adverise summary route to the AS \n")
1891 VTY_DECLVAR_CONTEXT(ospf6
, ospf6
);
1894 int ret
= CMD_SUCCESS
;
1896 ret
= str2prefix(prefix_str
, &p
);
1898 vty_out(vty
, "Malformed prefix\n");
1899 return CMD_WARNING_CONFIG_FAILED
;
1902 /* Apply mask for given prefix. */
1905 if (!ospf6_is_valid_summary_addr(vty
, &p
))
1906 return CMD_WARNING_CONFIG_FAILED
;
1908 ret
= ospf6_asbr_external_rt_advertise(ospf6
, &p
);
1909 if (ret
== OSPF6_INVALID
)
1910 vty_out(vty
, "!!Invalid configuration\n");
1915 DEFPY (ospf6_route_aggregation_timer
,
1916 ospf6_route_aggregation_timer_cmd
,
1917 "aggregation timer (5-1800)",
1918 "External route aggregation\n"
1919 "Delay timer (in seconds)\n"
1920 "Timer interval(in seconds)\n")
1922 VTY_DECLVAR_CONTEXT(ospf6
, ospf6
);
1924 ospf6_external_aggr_delay_timer_set(ospf6
, timer
);
1929 DEFPY (no_ospf6_route_aggregation_timer
,
1930 no_ospf6_route_aggregation_timer_cmd
,
1931 "no aggregation timer [5-1800]",
1933 "External route aggregation\n"
1935 "Timer interval(in seconds)\n")
1937 VTY_DECLVAR_CONTEXT(ospf6
, ospf6
);
1939 ospf6_external_aggr_delay_timer_set(ospf6
,
1940 OSPF6_EXTL_AGGR_DEFAULT_DELAY
);
1945 ospf6_print_vty_external_routes_walkcb(struct hash_bucket
*bucket
, void *arg
)
1947 struct ospf6_route
*rt
= bucket
->data
;
1948 struct vty
*vty
= (struct vty
*)arg
;
1949 static unsigned int count
;
1951 vty_out(vty
, "%pFX ", &rt
->prefix
);
1958 if (OSPF6_EXTERNAL_RT_COUNT(rt
->aggr_route
) == count
)
1961 return HASHWALK_CONTINUE
;
1965 ospf6_print_json_external_routes_walkcb(struct hash_bucket
*bucket
, void *arg
)
1967 struct ospf6_route
*rt
= bucket
->data
;
1968 struct json_object
*json
= (struct json_object
*)arg
;
1969 char buf
[PREFIX2STR_BUFFER
];
1971 static unsigned int count
;
1973 prefix2str(&rt
->prefix
, buf
, sizeof(buf
));
1975 snprintf(exnalbuf
, sizeof(exnalbuf
), "Exnl Addr-%d", count
);
1977 json_object_string_add(json
, exnalbuf
, buf
);
1981 if (OSPF6_EXTERNAL_RT_COUNT(rt
->aggr_route
) == count
)
1984 return HASHWALK_CONTINUE
;
1988 ospf6_show_vrf_name(struct vty
*vty
, struct ospf6
*ospf6
,
1992 if (ospf6
->vrf_id
== VRF_DEFAULT
)
1993 json_object_string_add(json
, "vrfName",
1996 json_object_string_add(json
, "vrfName",
1998 json_object_int_add(json
, "vrfId", ospf6
->vrf_id
);
2000 if (ospf6
->vrf_id
== VRF_DEFAULT
)
2001 vty_out(vty
, "VRF Name: %s\n", "default");
2002 else if (ospf6
->name
)
2003 vty_out(vty
, "VRF Name: %s\n", ospf6
->name
);
2008 ospf6_show_summary_address(struct vty
*vty
, struct ospf6
*ospf6
,
2010 bool uj
, const char *detail
)
2012 struct route_node
*rn
;
2013 static const char header
[] = "Summary-address Metric-type Metric Tag External_Rt_count\n";
2014 json_object
*json_vrf
= NULL
;
2017 ospf6_show_vrf_name(vty
, ospf6
, json_vrf
);
2018 vty_out(vty
, "aggregation delay interval :%u(in seconds)\n\n",
2019 ospf6
->aggr_delay_interval
);
2020 vty_out(vty
, "%s\n", header
);
2022 json_vrf
= json_object_new_object();
2024 ospf6_show_vrf_name(vty
, ospf6
, json_vrf
);
2026 json_object_int_add(json_vrf
, "aggregationDelayInterval",
2027 ospf6
->aggr_delay_interval
);
2031 for (rn
= route_top(ospf6
->rt_aggr_tbl
); rn
; rn
= route_next(rn
)) {
2035 struct ospf6_external_aggr_rt
*aggr
= rn
->info
;
2036 json_object
*json_aggr
= NULL
;
2037 char buf
[PREFIX2STR_BUFFER
];
2039 prefix2str(&aggr
->p
, buf
, sizeof(buf
));
2043 json_aggr
= json_object_new_object();
2045 json_object_object_add(json_vrf
,
2049 json_object_string_add(json_aggr
, "summaryAddress",
2052 json_object_string_add(
2053 json_aggr
, "metricType",
2054 (aggr
->mtype
== DEFAULT_METRIC_TYPE
) ? "E2"
2057 json_object_int_add(json_aggr
, "Metric",
2058 (aggr
->metric
!= -1)
2060 : DEFAULT_DEFAULT_METRIC
);
2062 json_object_int_add(json_aggr
, "Tag",
2065 json_object_int_add(json_aggr
, "externalRouteCount",
2066 OSPF6_EXTERNAL_RT_COUNT(aggr
));
2068 if (OSPF6_EXTERNAL_RT_COUNT(aggr
) && detail
) {
2069 json_object_int_add(json_aggr
, "ID",
2071 json_object_int_add(json_aggr
, "Flags",
2073 hash_walk(aggr
->match_extnl_hash
,
2074 ospf6_print_json_external_routes_walkcb
,
2079 vty_out(vty
, "%-22s", buf
);
2081 (aggr
->mtype
== DEFAULT_METRIC_TYPE
)
2082 ? vty_out(vty
, "%-16s", "E2")
2083 : vty_out(vty
, "%-16s", "E1");
2084 vty_out(vty
, "%-11d", (aggr
->metric
!= -1)
2086 : DEFAULT_DEFAULT_METRIC
);
2088 vty_out(vty
, "%-12u", aggr
->tag
);
2090 vty_out(vty
, "%-5ld\n",
2091 OSPF6_EXTERNAL_RT_COUNT(aggr
));
2093 if (OSPF6_EXTERNAL_RT_COUNT(aggr
) && detail
) {
2095 "Matched External routes:\n");
2096 hash_walk(aggr
->match_extnl_hash
,
2097 ospf6_print_vty_external_routes_walkcb
,
2107 json_object_object_add(json
, ospf6
->name
,
2113 DEFPY (show_ipv6_ospf6_external_aggregator
,
2114 show_ipv6_ospf6_external_aggregator_cmd
,
2115 "show ipv6 ospf6 [vrf <NAME|all>] summary-address [detail$detail] [json]",
2121 "Show external summary addresses\n"
2122 "detailed information\n"
2125 bool uj
= use_json(argc
, argv
);
2126 struct ospf6
*ospf6
= NULL
;
2127 json_object
*json
= NULL
;
2128 const char *vrf_name
= NULL
;
2129 struct listnode
*node
;
2130 bool all_vrf
= false;
2134 json
= json_object_new_object();
2136 OSPF6_FIND_VRF_ARGS(argv
, argc
, idx_vrf
, vrf_name
, all_vrf
);
2138 for (ALL_LIST_ELEMENTS_RO(om6
->ospf6
, node
, ospf6
)) {
2139 if (all_vrf
|| strcmp(ospf6
->name
, vrf_name
) == 0) {
2141 ospf6_show_summary_address(vty
, ospf6
, json
, uj
,
2150 vty_json(vty
, json
);
2153 OSPF6_CMD_CHECK_VRF(uj
, all_vrf
, ospf6
);
2158 static void ospf6_stub_router_config_write(struct vty
*vty
, struct ospf6
*ospf6
)
2160 if (CHECK_FLAG(ospf6
->flag
, OSPF6_STUB_ROUTER
))
2161 vty_out(vty
, " stub-router administrative\n");
2165 static int ospf6_distance_config_write(struct vty
*vty
, struct ospf6
*ospf6
)
2167 struct route_node
*rn
;
2168 struct ospf6_distance
*odistance
;
2170 if (ospf6
->distance_all
)
2171 vty_out(vty
, " distance %u\n", ospf6
->distance_all
);
2173 if (ospf6
->distance_intra
|| ospf6
->distance_inter
2174 || ospf6
->distance_external
) {
2175 vty_out(vty
, " distance ospf6");
2177 if (ospf6
->distance_intra
)
2178 vty_out(vty
, " intra-area %u", ospf6
->distance_intra
);
2179 if (ospf6
->distance_inter
)
2180 vty_out(vty
, " inter-area %u", ospf6
->distance_inter
);
2181 if (ospf6
->distance_external
)
2182 vty_out(vty
, " external %u", ospf6
->distance_external
);
2187 for (rn
= route_top(ospf6
->distance_table
); rn
; rn
= route_next(rn
))
2188 if ((odistance
= rn
->info
) != NULL
)
2189 vty_out(vty
, " distance %u %pFX %s\n",
2190 odistance
->distance
, &rn
->p
,
2191 odistance
->access_list
? odistance
->access_list
2196 static int ospf6_asbr_summary_config_write(struct vty
*vty
, struct ospf6
*ospf6
)
2198 struct route_node
*rn
;
2199 struct ospf6_external_aggr_rt
*aggr
;
2200 char buf
[PREFIX2STR_BUFFER
];
2202 if (ospf6
->aggr_delay_interval
!= OSPF6_EXTL_AGGR_DEFAULT_DELAY
)
2203 vty_out(vty
, " aggregation timer %u\n",
2204 ospf6
->aggr_delay_interval
);
2206 /* print 'summary-address A:B::C:D/M' */
2207 for (rn
= route_top(ospf6
->rt_aggr_tbl
); rn
; rn
= route_next(rn
)) {
2213 prefix2str(&aggr
->p
, buf
, sizeof(buf
));
2214 vty_out(vty
, " summary-address %s", buf
);
2216 vty_out(vty
, " tag %u", aggr
->tag
);
2218 if (aggr
->metric
!= -1)
2219 vty_out(vty
, " metric %d", aggr
->metric
);
2221 if (aggr
->mtype
!= DEFAULT_METRIC_TYPE
)
2222 vty_out(vty
, " metric-type %d", aggr
->mtype
);
2224 if (CHECK_FLAG(aggr
->aggrflags
,
2225 OSPF6_EXTERNAL_AGGRT_NO_ADVERTISE
))
2226 vty_out(vty
, " no-advertise");
2234 /* OSPF configuration write function. */
2235 static int config_write_ospf6(struct vty
*vty
)
2237 struct ospf6
*ospf6
;
2238 struct listnode
*node
, *nnode
;
2240 /* OSPFv3 configuration. */
2244 for (ALL_LIST_ELEMENTS(om6
->ospf6
, node
, nnode
, ospf6
)) {
2245 if (ospf6
->name
&& strcmp(ospf6
->name
, VRF_DEFAULT_NAME
))
2246 vty_out(vty
, "router ospf6 vrf %s\n", ospf6
->name
);
2248 vty_out(vty
, "router ospf6\n");
2250 if (ospf6
->router_id_static
!= 0)
2251 vty_out(vty
, " ospf6 router-id %pI4\n",
2252 &ospf6
->router_id_static
);
2254 if (CHECK_FLAG(ospf6
->config_flags
,
2255 OSPF6_SEND_EXTRA_DATA_TO_ZEBRA
))
2256 vty_out(vty
, " ospf6 send-extra-data zebra\n");
2258 /* log-adjacency-changes flag print. */
2259 if (CHECK_FLAG(ospf6
->config_flags
,
2260 OSPF6_LOG_ADJACENCY_CHANGES
)) {
2261 if (CHECK_FLAG(ospf6
->config_flags
,
2262 OSPF6_LOG_ADJACENCY_DETAIL
))
2263 vty_out(vty
, " log-adjacency-changes detail\n");
2264 else if (!SAVE_OSPF6_LOG_ADJACENCY_CHANGES
)
2265 vty_out(vty
, " log-adjacency-changes\n");
2266 } else if (SAVE_OSPF6_LOG_ADJACENCY_CHANGES
) {
2267 vty_out(vty
, " no log-adjacency-changes\n");
2270 if (ospf6
->ref_bandwidth
!= OSPF6_REFERENCE_BANDWIDTH
)
2271 vty_out(vty
, " auto-cost reference-bandwidth %d\n",
2272 ospf6
->ref_bandwidth
);
2274 if (ospf6
->write_oi_count
2275 != OSPF6_WRITE_INTERFACE_COUNT_DEFAULT
)
2276 vty_out(vty
, " write-multiplier %d\n",
2277 ospf6
->write_oi_count
);
2279 /* LSA timers print. */
2280 if (ospf6
->lsa_minarrival
!= OSPF_MIN_LS_ARRIVAL
)
2281 vty_out(vty
, " timers lsa min-arrival %d\n",
2282 ospf6
->lsa_minarrival
);
2284 /* ECMP max path config */
2285 if (ospf6
->max_multipath
!= MULTIPATH_NUM
)
2286 vty_out(vty
, " maximum-paths %d\n",
2287 ospf6
->max_multipath
);
2289 ospf6_stub_router_config_write(vty
, ospf6
);
2290 ospf6_redistribute_config_write(vty
, ospf6
);
2291 ospf6_area_config_write(vty
, ospf6
);
2292 ospf6_spf_config_write(vty
, ospf6
);
2293 ospf6_distance_config_write(vty
, ospf6
);
2294 ospf6_distribute_config_write(vty
, ospf6
);
2295 ospf6_asbr_summary_config_write(vty
, ospf6
);
2296 config_write_ospf6_gr(vty
, ospf6
);
2297 config_write_ospf6_gr_helper(vty
, ospf6
);
2299 vty_out(vty
, "exit\n");
2300 vty_out(vty
, "!\n");
2305 static int config_write_ospf6(struct vty
*vty
);
2306 /* OSPF6 node structure. */
2307 static struct cmd_node ospf6_node
= {
2310 .parent_node
= CONFIG_NODE
,
2311 .prompt
= "%s(config-ospf6)# ",
2312 .config_write
= config_write_ospf6
,
2315 void install_element_ospf6_clear_process(void)
2317 install_element(ENABLE_NODE
, &clear_router_ospf6_cmd
);
2320 /* Install ospf related commands. */
2321 void ospf6_top_init(void)
2323 /* Install ospf6 top node. */
2324 install_node(&ospf6_node
);
2326 install_element(VIEW_NODE
, &show_ipv6_ospf6_cmd
);
2327 install_element(VIEW_NODE
, &show_ipv6_ospf6_vrfs_cmd
);
2328 install_element(CONFIG_NODE
, &router_ospf6_cmd
);
2329 install_element(CONFIG_NODE
, &no_router_ospf6_cmd
);
2331 install_element(VIEW_NODE
, &show_ipv6_ospf6_route_cmd
);
2332 install_element(VIEW_NODE
, &show_ipv6_ospf6_route_match_cmd
);
2333 install_element(VIEW_NODE
, &show_ipv6_ospf6_route_match_detail_cmd
);
2334 install_element(VIEW_NODE
, &show_ipv6_ospf6_route_type_detail_cmd
);
2336 install_default(OSPF6_NODE
);
2337 install_element(OSPF6_NODE
, &ospf6_router_id_cmd
);
2338 install_element(OSPF6_NODE
, &no_ospf6_router_id_cmd
);
2339 install_element(OSPF6_NODE
, &ospf6_log_adjacency_changes_cmd
);
2340 install_element(OSPF6_NODE
, &ospf6_log_adjacency_changes_detail_cmd
);
2341 install_element(OSPF6_NODE
, &no_ospf6_log_adjacency_changes_cmd
);
2342 install_element(OSPF6_NODE
, &no_ospf6_log_adjacency_changes_detail_cmd
);
2343 install_element(OSPF6_NODE
, &ospf6_send_extra_data_cmd
);
2345 /* LSA timers commands */
2346 install_element(OSPF6_NODE
, &ospf6_timers_lsa_cmd
);
2347 install_element(OSPF6_NODE
, &no_ospf6_timers_lsa_cmd
);
2349 install_element(OSPF6_NODE
, &ospf6_interface_area_cmd
);
2350 install_element(OSPF6_NODE
, &no_ospf6_interface_area_cmd
);
2351 install_element(OSPF6_NODE
, &ospf6_stub_router_admin_cmd
);
2352 install_element(OSPF6_NODE
, &no_ospf6_stub_router_admin_cmd
);
2354 /* maximum-paths command */
2355 install_element(OSPF6_NODE
, &ospf6_max_multipath_cmd
);
2356 install_element(OSPF6_NODE
, &no_ospf6_max_multipath_cmd
);
2358 /* ASBR Summarisation */
2359 install_element(OSPF6_NODE
, &ospf6_external_route_aggregation_cmd
);
2360 install_element(OSPF6_NODE
, &no_ospf6_external_route_aggregation_cmd
);
2361 install_element(OSPF6_NODE
,
2362 &ospf6_external_route_aggregation_no_advertise_cmd
);
2363 install_element(OSPF6_NODE
,
2364 &no_ospf6_external_route_aggregation_no_advertise_cmd
);
2365 install_element(OSPF6_NODE
, &ospf6_route_aggregation_timer_cmd
);
2366 install_element(OSPF6_NODE
, &no_ospf6_route_aggregation_timer_cmd
);
2367 install_element(VIEW_NODE
, &show_ipv6_ospf6_external_aggregator_cmd
);
2369 install_element(OSPF6_NODE
, &ospf6_distance_cmd
);
2370 install_element(OSPF6_NODE
, &no_ospf6_distance_cmd
);
2371 install_element(OSPF6_NODE
, &ospf6_distance_ospf6_cmd
);
2372 install_element(OSPF6_NODE
, &no_ospf6_distance_ospf6_cmd
);