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 thread_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 thread_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);
458 if (ospf6
->vrf_id
!= VRF_UNKNOWN
) {
459 vrf
= vrf_lookup_by_id(ospf6
->vrf_id
);
460 FOR_ALL_INTERFACES (vrf
, ifp
) {
462 ospf6_interface_start(ifp
->info
);
469 * Read from non-volatile memory whether this instance is performing a
470 * graceful restart or not.
472 ospf6_gr_nvm_read(ospf6
);
474 thread_add_read(master
, ospf6_receive
, ospf6
, ospf6
->fd
,
475 &ospf6
->t_ospf6_receive
);
480 void ospf6_delete(struct ospf6
*o
)
482 struct listnode
*node
, *nnode
;
483 struct route_node
*rn
= NULL
;
484 struct ospf6_area
*oa
;
486 struct ospf6_external_aggr_rt
*aggr
;
490 ospf6_gr_helper_deinit(o
);
491 if (!o
->gr_info
.prepare_in_progress
)
492 ospf6_flush_self_originated_lsas_now(o
);
496 ospf6_zebra_vrf_deregister(o
);
498 ospf6_serv_close(&o
->fd
);
500 for (ALL_LIST_ELEMENTS(o
->area_list
, node
, nnode
, oa
))
501 ospf6_area_delete(oa
);
504 list_delete(&o
->area_list
);
506 ospf6_lsdb_delete(o
->lsdb
);
507 ospf6_lsdb_delete(o
->lsdb_self
);
509 ospf6_route_table_delete(o
->route_table
);
510 ospf6_route_table_delete(o
->brouter_table
);
512 ospf6_route_table_delete(o
->external_table
);
514 ospf6_distance_reset(o
);
515 route_table_finish(o
->distance_table
);
516 list_delete(&o
->oi_write_q
);
518 if (o
->vrf_id
!= VRF_UNKNOWN
) {
519 vrf
= vrf_lookup_by_id(o
->vrf_id
);
521 ospf6_vrf_unlink(o
, vrf
);
524 for (rn
= route_top(o
->rt_aggr_tbl
); rn
; rn
= route_next(rn
))
527 ospf6_asbr_summary_config_delete(o
, rn
);
528 ospf6_external_aggregator_free(aggr
);
530 route_table_finish(o
->rt_aggr_tbl
);
532 XFREE(MTYPE_OSPF6_TOP
, o
->name
);
533 XFREE(MTYPE_OSPF6_TOP
, o
);
536 static void ospf6_disable(struct ospf6
*o
)
538 struct listnode
*node
, *nnode
;
539 struct ospf6_area
*oa
;
541 if (!CHECK_FLAG(o
->flag
, OSPF6_DISABLED
)) {
542 SET_FLAG(o
->flag
, OSPF6_DISABLED
);
544 for (ALL_LIST_ELEMENTS(o
->area_list
, node
, nnode
, oa
))
545 ospf6_area_disable(oa
);
547 /* XXX: This also changes persistent settings */
548 /* Unregister redistribution */
549 ospf6_asbr_redistribute_disable(o
);
551 ospf6_lsdb_remove_all(o
->lsdb
);
552 ospf6_route_remove_all(o
->route_table
);
553 ospf6_route_remove_all(o
->brouter_table
);
555 THREAD_OFF(o
->maxage_remover
);
556 THREAD_OFF(o
->t_spf_calc
);
557 THREAD_OFF(o
->t_ase_calc
);
558 THREAD_OFF(o
->t_distribute_update
);
559 THREAD_OFF(o
->t_ospf6_receive
);
560 THREAD_OFF(o
->t_external_aggr
);
561 THREAD_OFF(o
->gr_info
.t_grace_period
);
562 THREAD_OFF(o
->t_write
);
563 THREAD_OFF(o
->t_abr_task
);
567 void ospf6_master_init(struct thread_master
*master
)
569 memset(&ospf6_master
, 0, sizeof(ospf6_master
));
572 om6
->ospf6
= list_new();
573 om6
->master
= master
;
576 static void ospf6_maxage_remover(struct thread
*thread
)
578 struct ospf6
*o
= (struct ospf6
*)THREAD_ARG(thread
);
579 struct ospf6_area
*oa
;
580 struct ospf6_interface
*oi
;
581 struct ospf6_neighbor
*on
;
582 struct listnode
*i
, *j
, *k
;
585 for (ALL_LIST_ELEMENTS_RO(o
->area_list
, i
, oa
)) {
586 for (ALL_LIST_ELEMENTS_RO(oa
->if_list
, j
, oi
)) {
587 for (ALL_LIST_ELEMENTS_RO(oi
->neighbor_list
, k
, on
)) {
588 if (on
->state
!= OSPF6_NEIGHBOR_EXCHANGE
589 && on
->state
!= OSPF6_NEIGHBOR_LOADING
)
592 ospf6_maxage_remove(o
);
598 for (ALL_LIST_ELEMENTS_RO(o
->area_list
, i
, oa
)) {
599 for (ALL_LIST_ELEMENTS_RO(oa
->if_list
, j
, oi
)) {
600 if (ospf6_lsdb_maxage_remover(oi
->lsdb
)) {
605 if (ospf6_lsdb_maxage_remover(oa
->lsdb
)) {
610 if (ospf6_lsdb_maxage_remover(o
->lsdb
)) {
615 ospf6_maxage_remove(o
);
619 void ospf6_maxage_remove(struct ospf6
*o
)
622 thread_add_timer(master
, ospf6_maxage_remover
, o
,
623 OSPF_LSA_MAXAGE_REMOVE_DELAY_DEFAULT
,
627 bool ospf6_router_id_update(struct ospf6
*ospf6
, bool init
)
629 in_addr_t new_router_id
;
630 struct listnode
*node
;
631 struct ospf6_area
*oa
;
636 if (ospf6
->router_id_static
!= 0)
637 new_router_id
= ospf6
->router_id_static
;
639 new_router_id
= ospf6
->router_id_zebra
;
641 if (ospf6
->router_id
== new_router_id
)
645 for (ALL_LIST_ELEMENTS_RO(ospf6
->area_list
, node
, oa
)) {
648 "%s: cannot update router-id. Run the \"clear ipv6 ospf6 process\" command",
654 ospf6
->router_id
= new_router_id
;
659 DEFUN_NOSH(router_ospf6
, router_ospf6_cmd
, "router ospf6 [vrf NAME]",
660 ROUTER_STR OSPF6_STR VRF_CMD_HELP_STR
)
663 const char *vrf_name
= VRF_DEFAULT_NAME
;
666 if (argv_find(argv
, argc
, "vrf", &idx_vrf
)) {
667 vrf_name
= argv
[idx_vrf
+ 1]->arg
;
670 ospf6
= ospf6_lookup_by_vrf_name(vrf_name
);
672 ospf6
= ospf6_instance_create(vrf_name
);
674 /* set current ospf point. */
675 VTY_PUSH_CONTEXT(OSPF6_NODE
, ospf6
);
681 DEFUN(no_router_ospf6
, no_router_ospf6_cmd
, "no router ospf6 [vrf NAME]",
682 NO_STR ROUTER_STR OSPF6_STR VRF_CMD_HELP_STR
)
685 const char *vrf_name
= VRF_DEFAULT_NAME
;
688 if (argv_find(argv
, argc
, "vrf", &idx_vrf
)) {
689 vrf_name
= argv
[idx_vrf
+ 1]->arg
;
692 ospf6
= ospf6_lookup_by_vrf_name(vrf_name
);
694 vty_out(vty
, "OSPFv3 is not configured\n");
700 /* return to config node . */
701 VTY_PUSH_CONTEXT_NULL(CONFIG_NODE
);
706 static void ospf6_db_clear(struct ospf6
*ospf6
)
708 struct ospf6_interface
*oi
;
709 struct interface
*ifp
;
710 struct vrf
*vrf
= vrf_lookup_by_id(ospf6
->vrf_id
);
711 struct listnode
*node
, *nnode
;
712 struct ospf6_area
*oa
;
714 FOR_ALL_INTERFACES (vrf
, ifp
) {
715 if (if_is_operative(ifp
) && ifp
->info
!= NULL
) {
716 oi
= (struct ospf6_interface
*)ifp
->info
;
717 ospf6_lsdb_remove_all(oi
->lsdb
);
718 ospf6_lsdb_remove_all(oi
->lsdb_self
);
719 ospf6_lsdb_remove_all(oi
->lsupdate_list
);
720 ospf6_lsdb_remove_all(oi
->lsack_list
);
724 for (ALL_LIST_ELEMENTS(ospf6
->area_list
, node
, nnode
, oa
)) {
725 ospf6_lsdb_remove_all(oa
->lsdb
);
726 ospf6_lsdb_remove_all(oa
->lsdb_self
);
728 ospf6_spf_table_finish(oa
->spf_table
);
729 ospf6_route_remove_all(oa
->route_table
);
732 ospf6_lsdb_remove_all(ospf6
->lsdb
);
733 ospf6_lsdb_remove_all(ospf6
->lsdb_self
);
734 ospf6_route_remove_all(ospf6
->route_table
);
735 ospf6_route_remove_all(ospf6
->brouter_table
);
738 static void ospf6_process_reset(struct ospf6
*ospf6
)
740 struct interface
*ifp
;
741 struct vrf
*vrf
= vrf_lookup_by_id(ospf6
->vrf_id
);
743 ospf6_unset_all_aggr_flag(ospf6
);
744 ospf6_flush_self_originated_lsas_now(ospf6
);
745 ospf6
->inst_shutdown
= 0;
746 ospf6_db_clear(ospf6
);
748 ospf6_asbr_redistribute_reset(ospf6
);
749 FOR_ALL_INTERFACES (vrf
, ifp
)
750 ospf6_interface_clear(ifp
);
753 DEFPY (clear_router_ospf6
,
754 clear_router_ospf6_cmd
,
755 "clear ipv6 ospf6 process [vrf NAME$name]",
759 "Reset OSPF Process\n"
763 const char *vrf_name
= VRF_DEFAULT_NAME
;
768 ospf6
= ospf6_lookup_by_vrf_name(vrf_name
);
770 vty_out(vty
, "OSPFv3 is not configured\n");
772 ospf6_router_id_update(ospf6
, true);
773 ospf6_process_reset(ospf6
);
779 /* change Router_ID commands. */
780 DEFUN(ospf6_router_id
,
782 "ospf6 router-id A.B.C.D",
784 "Configure OSPF6 Router-ID\n"
787 VTY_DECLVAR_CONTEXT(ospf6
, o
);
790 const char *router_id_str
;
793 argv_find(argv
, argc
, "A.B.C.D", &idx
);
794 router_id_str
= argv
[idx
]->arg
;
796 ret
= inet_pton(AF_INET
, router_id_str
, &router_id
);
798 vty_out(vty
, "malformed OSPF Router-ID: %s\n", router_id_str
);
802 o
->router_id_static
= router_id
;
804 if (ospf6_router_id_update(o
, false))
805 ospf6_process_reset(o
);
808 "For this router-id change to take effect run the \"clear ipv6 ospf6 process\" command\n");
813 DEFUN(no_ospf6_router_id
,
814 no_ospf6_router_id_cmd
,
815 "no ospf6 router-id [A.B.C.D]",
817 "Configure OSPF6 Router-ID\n"
820 VTY_DECLVAR_CONTEXT(ospf6
, o
);
822 o
->router_id_static
= 0;
825 if (ospf6_router_id_update(o
, false))
826 ospf6_process_reset(o
);
829 "For this router-id change to take effect run the \"clear ipv6 ospf6 process\" command\n");
834 DEFUN (ospf6_log_adjacency_changes
,
835 ospf6_log_adjacency_changes_cmd
,
836 "log-adjacency-changes",
837 "Log changes in adjacency state\n")
839 VTY_DECLVAR_CONTEXT(ospf6
, ospf6
);
841 SET_FLAG(ospf6
->config_flags
, OSPF6_LOG_ADJACENCY_CHANGES
);
842 UNSET_FLAG(ospf6
->config_flags
, OSPF6_LOG_ADJACENCY_DETAIL
);
846 DEFUN (ospf6_log_adjacency_changes_detail
,
847 ospf6_log_adjacency_changes_detail_cmd
,
848 "log-adjacency-changes detail",
849 "Log changes in adjacency state\n"
850 "Log all state changes\n")
852 VTY_DECLVAR_CONTEXT(ospf6
, ospf6
);
854 SET_FLAG(ospf6
->config_flags
, OSPF6_LOG_ADJACENCY_CHANGES
);
855 SET_FLAG(ospf6
->config_flags
, OSPF6_LOG_ADJACENCY_DETAIL
);
859 DEFUN (no_ospf6_log_adjacency_changes
,
860 no_ospf6_log_adjacency_changes_cmd
,
861 "no log-adjacency-changes",
863 "Log changes in adjacency state\n")
865 VTY_DECLVAR_CONTEXT(ospf6
, ospf6
);
867 UNSET_FLAG(ospf6
->config_flags
, OSPF6_LOG_ADJACENCY_DETAIL
);
868 UNSET_FLAG(ospf6
->config_flags
, OSPF6_LOG_ADJACENCY_CHANGES
);
872 DEFUN (no_ospf6_log_adjacency_changes_detail
,
873 no_ospf6_log_adjacency_changes_detail_cmd
,
874 "no log-adjacency-changes detail",
876 "Log changes in adjacency state\n"
877 "Log all state changes\n")
879 VTY_DECLVAR_CONTEXT(ospf6
, ospf6
);
881 UNSET_FLAG(ospf6
->config_flags
, OSPF6_LOG_ADJACENCY_DETAIL
);
885 static void ospf6_reinstall_routes(struct ospf6
*ospf6
)
887 struct ospf6_route
*route
;
889 for (route
= ospf6_route_head(ospf6
->route_table
); route
;
890 route
= ospf6_route_next(route
))
891 ospf6_zebra_route_update_add(route
, ospf6
);
894 DEFPY (ospf6_send_extra_data
,
895 ospf6_send_extra_data_cmd
,
896 "[no] ospf6 send-extra-data zebra",
899 "Extra data to Zebra for display/use\n"
902 VTY_DECLVAR_CONTEXT(ospf6
, ospf6
);
905 && CHECK_FLAG(ospf6
->config_flags
,
906 OSPF6_SEND_EXTRA_DATA_TO_ZEBRA
)) {
907 UNSET_FLAG(ospf6
->config_flags
, OSPF6_SEND_EXTRA_DATA_TO_ZEBRA
);
908 ospf6_reinstall_routes(ospf6
);
909 } else if (!CHECK_FLAG(ospf6
->config_flags
,
910 OSPF6_SEND_EXTRA_DATA_TO_ZEBRA
)) {
911 SET_FLAG(ospf6
->config_flags
, OSPF6_SEND_EXTRA_DATA_TO_ZEBRA
);
912 ospf6_reinstall_routes(ospf6
);
918 DEFUN (ospf6_timers_lsa
,
919 ospf6_timers_lsa_cmd
,
920 "timers lsa min-arrival (0-600000)",
921 "Adjust routing timers\n"
923 "Minimum delay in receiving new version of a LSA\n"
924 "Delay in milliseconds\n")
926 VTY_DECLVAR_CONTEXT(ospf6
, ospf
);
928 unsigned int minarrival
;
930 minarrival
= strtoul(argv
[idx_number
]->arg
, NULL
, 10);
931 ospf
->lsa_minarrival
= minarrival
;
936 DEFUN (no_ospf6_timers_lsa
,
937 no_ospf6_timers_lsa_cmd
,
938 "no timers lsa min-arrival [(0-600000)]",
940 "Adjust routing timers\n"
942 "Minimum delay in receiving new version of a LSA\n"
943 "Delay in milliseconds\n")
945 VTY_DECLVAR_CONTEXT(ospf6
, ospf
);
947 unsigned int minarrival
;
950 minarrival
= strtoul(argv
[idx_number
]->arg
, NULL
, 10);
952 if (ospf
->lsa_minarrival
!= minarrival
953 || minarrival
== OSPF_MIN_LS_ARRIVAL
)
957 ospf
->lsa_minarrival
= OSPF_MIN_LS_ARRIVAL
;
963 DEFUN (ospf6_distance
,
966 "Administrative distance\n"
967 "OSPF6 Administrative distance\n")
969 VTY_DECLVAR_CONTEXT(ospf6
, o
);
972 distance
= atoi(argv
[1]->arg
);
973 if (o
->distance_all
!= distance
) {
974 o
->distance_all
= distance
;
975 ospf6_restart_spf(o
);
981 DEFUN (no_ospf6_distance
,
982 no_ospf6_distance_cmd
,
983 "no distance (1-255)",
985 "Administrative distance\n"
986 "OSPF6 Administrative distance\n")
988 VTY_DECLVAR_CONTEXT(ospf6
, o
);
990 if (o
->distance_all
) {
992 ospf6_restart_spf(o
);
997 DEFUN (ospf6_distance_ospf6
,
998 ospf6_distance_ospf6_cmd
,
999 "distance ospf6 {intra-area (1-255)|inter-area (1-255)|external (1-255)}",
1000 "Administrative distance\n"
1001 "OSPF6 administrative distance\n"
1002 "Intra-area routes\n"
1003 "Distance for intra-area routes\n"
1004 "Inter-area routes\n"
1005 "Distance for inter-area routes\n"
1007 "Distance for external routes\n")
1009 VTY_DECLVAR_CONTEXT(ospf6
, o
);
1012 o
->distance_intra
= 0;
1013 o
->distance_inter
= 0;
1014 o
->distance_external
= 0;
1016 if (argv_find(argv
, argc
, "intra-area", &idx
))
1017 o
->distance_intra
= atoi(argv
[idx
+ 1]->arg
);
1019 if (argv_find(argv
, argc
, "inter-area", &idx
))
1020 o
->distance_inter
= atoi(argv
[idx
+ 1]->arg
);
1022 if (argv_find(argv
, argc
, "external", &idx
))
1023 o
->distance_external
= atoi(argv
[idx
+ 1]->arg
);
1028 DEFUN (no_ospf6_distance_ospf6
,
1029 no_ospf6_distance_ospf6_cmd
,
1030 "no distance ospf6 [{intra-area [(1-255)]|inter-area [(1-255)]|external [(1-255)]}]",
1032 "Administrative distance\n"
1034 "Intra-area routes\n"
1035 "Distance for intra-area routes\n"
1036 "Inter-area routes\n"
1037 "Distance for inter-area routes\n"
1039 "Distance for external routes\n")
1041 VTY_DECLVAR_CONTEXT(ospf6
, o
);
1044 if (argv_find(argv
, argc
, "intra-area", &idx
) || argc
== 3)
1045 idx
= o
->distance_intra
= 0;
1046 if (argv_find(argv
, argc
, "inter-area", &idx
) || argc
== 3)
1047 idx
= o
->distance_inter
= 0;
1048 if (argv_find(argv
, argc
, "external", &idx
) || argc
== 3)
1049 o
->distance_external
= 0;
1054 DEFUN_HIDDEN (ospf6_interface_area
,
1055 ospf6_interface_area_cmd
,
1056 "interface IFNAME area <A.B.C.D|(0-4294967295)>",
1057 "Enable routing on an IPv6 interface\n"
1059 "Specify the OSPF6 area ID\n"
1060 "OSPF6 area ID in IPv4 address notation\n"
1061 "OSPF6 area ID in decimal notation\n"
1064 VTY_DECLVAR_CONTEXT(ospf6
, ospf6
);
1067 struct ospf6_area
*oa
;
1068 struct ospf6_interface
*oi
;
1069 struct interface
*ifp
;
1074 "This command is deprecated, because it is not VRF-aware.\n");
1076 "Please, use \"ipv6 ospf6 area\" on an interface instead.\n");
1078 /* find/create ospf6 interface */
1079 ifp
= if_get_by_name(argv
[idx_ifname
]->arg
, ospf6
->vrf_id
, ospf6
->name
);
1080 oi
= (struct ospf6_interface
*)ifp
->info
;
1082 oi
= ospf6_interface_create(ifp
);
1084 vty_out(vty
, "%s already attached to Area %s\n",
1085 oi
->interface
->name
, oi
->area
->name
);
1089 if (str2area_id(argv
[idx_ipv4
]->arg
, &area_id
, &format
)) {
1090 vty_out(vty
, "Malformed Area-ID: %s\n", argv
[idx_ipv4
]->arg
);
1091 return CMD_WARNING_CONFIG_FAILED
;
1094 oi
->area_id
= area_id
;
1095 oi
->area_id_format
= format
;
1097 oa
= ospf6_area_lookup(area_id
, ospf6
);
1099 oa
= ospf6_area_create(area_id
, ospf6
, format
);
1101 /* attach interface to area */
1102 listnode_add(oa
->if_list
, oi
); /* sort ?? */
1105 SET_FLAG(oa
->flag
, OSPF6_AREA_ENABLE
);
1107 /* ospf6 process is currently disabled, not much more to do */
1108 if (CHECK_FLAG(ospf6
->flag
, OSPF6_DISABLED
))
1112 ospf6_interface_enable(oi
);
1114 /* If the router is ABR, originate summary routes */
1115 if (ospf6_check_and_set_router_abr(ospf6
)) {
1116 ospf6_abr_enable_area(oa
);
1117 ospf6_schedule_abr_task(oa
->ospf6
);
1123 DEFUN_HIDDEN (no_ospf6_interface_area
,
1124 no_ospf6_interface_area_cmd
,
1125 "no interface IFNAME area <A.B.C.D|(0-4294967295)>",
1127 "Disable routing on an IPv6 interface\n"
1129 "Specify the OSPF6 area ID\n"
1130 "OSPF6 area ID in IPv4 address notation\n"
1131 "OSPF6 area ID in decimal notation\n"
1134 VTY_DECLVAR_CONTEXT(ospf6
, ospf6
);
1137 struct ospf6_interface
*oi
;
1138 struct ospf6_area
*oa
;
1139 struct interface
*ifp
;
1143 "This command is deprecated, because it is not VRF-aware.\n");
1145 "Please, use \"no ipv6 ospf6 area\" on an interface instead.\n");
1147 /* find/create ospf6 interface */
1148 ifp
= if_get_by_name(argv
[idx_ifname
]->arg
, ospf6
->vrf_id
, ospf6
->name
);
1151 vty_out(vty
, "No such interface %s\n", argv
[idx_ifname
]->arg
);
1155 oi
= (struct ospf6_interface
*)ifp
->info
;
1157 vty_out(vty
, "Interface %s not enabled\n", ifp
->name
);
1162 if (inet_pton(AF_INET
, argv
[idx_ipv4
]->arg
, &area_id
) != 1)
1163 area_id
= htonl(strtoul(argv
[idx_ipv4
]->arg
, NULL
, 10));
1166 if (oi
->area
== NULL
) {
1167 vty_out(vty
, "%s not attached to area %s\n",
1168 oi
->interface
->name
, argv
[idx_ipv4
]->arg
);
1172 if (oi
->area
->area_id
!= area_id
) {
1173 vty_out(vty
, "Wrong Area-ID: %s is attached to area %s\n",
1174 oi
->interface
->name
, oi
->area
->name
);
1178 ospf6_interface_disable(oi
);
1181 listnode_delete(oi
->area
->if_list
, oi
);
1182 oi
->area
= (struct ospf6_area
*)NULL
;
1184 /* Withdraw inter-area routes from this area, if necessary */
1185 if (oa
->if_list
->count
== 0) {
1186 UNSET_FLAG(oa
->flag
, OSPF6_AREA_ENABLE
);
1187 ospf6_abr_disable_area(oa
);
1191 oi
->area_id_format
= OSPF6_AREA_FMT_UNSET
;
1196 DEFUN (ospf6_stub_router_admin
,
1197 ospf6_stub_router_admin_cmd
,
1198 "stub-router administrative",
1199 "Make router a stub router\n"
1200 "Administratively applied, for an indefinite period\n")
1202 struct listnode
*node
;
1203 struct ospf6_area
*oa
;
1205 VTY_DECLVAR_CONTEXT(ospf6
, ospf6
);
1207 if (!CHECK_FLAG(ospf6
->flag
, OSPF6_STUB_ROUTER
)) {
1208 for (ALL_LIST_ELEMENTS_RO(ospf6
->area_list
, node
, oa
)) {
1209 OSPF6_OPT_CLEAR(oa
->options
, OSPF6_OPT_V6
);
1210 OSPF6_OPT_CLEAR(oa
->options
, OSPF6_OPT_R
);
1211 OSPF6_ROUTER_LSA_SCHEDULE(oa
);
1213 SET_FLAG(ospf6
->flag
, OSPF6_STUB_ROUTER
);
1219 DEFUN (no_ospf6_stub_router_admin
,
1220 no_ospf6_stub_router_admin_cmd
,
1221 "no stub-router administrative",
1223 "Make router a stub router\n"
1224 "Administratively applied, for an indefinite period\n")
1226 struct listnode
*node
;
1227 struct ospf6_area
*oa
;
1229 VTY_DECLVAR_CONTEXT(ospf6
, ospf6
);
1230 if (CHECK_FLAG(ospf6
->flag
, OSPF6_STUB_ROUTER
)) {
1231 for (ALL_LIST_ELEMENTS_RO(ospf6
->area_list
, node
, oa
)) {
1232 OSPF6_OPT_SET(oa
->options
, OSPF6_OPT_V6
);
1233 OSPF6_OPT_SET(oa
->options
, OSPF6_OPT_R
);
1234 OSPF6_ROUTER_LSA_SCHEDULE(oa
);
1236 UNSET_FLAG(ospf6
->flag
, OSPF6_STUB_ROUTER
);
1242 /* Restart OSPF SPF algorithm*/
1243 void ospf6_restart_spf(struct ospf6
*ospf6
)
1245 ospf6_route_remove_all(ospf6
->route_table
);
1246 ospf6_route_remove_all(ospf6
->brouter_table
);
1249 ospf6_spf_schedule(ospf6
, OSPF6_SPF_FLAGS_CONFIG_CHANGE
);
1252 /* Set the max paths */
1253 static void ospf6_maxpath_set(struct ospf6
*ospf6
, uint16_t paths
)
1255 if (ospf6
->max_multipath
== paths
)
1258 ospf6
->max_multipath
= paths
;
1260 /* Send deletion to zebra to delete all
1261 * ospf specific routes and reinitiate
1262 * SPF to reflect the new max multipath.
1264 ospf6_restart_spf(ospf6
);
1267 /* Ospf Maximum-paths config support */
1268 DEFUN(ospf6_max_multipath
,
1269 ospf6_max_multipath_cmd
,
1270 "maximum-paths " CMD_RANGE_STR(1, MULTIPATH_NUM
),
1271 "Max no of multiple paths for ECMP support\n"
1272 "Number of paths\n")
1274 VTY_DECLVAR_CONTEXT(ospf6
, ospf6
);
1276 int maximum_paths
= strtol(argv
[idx_number
]->arg
, NULL
, 10);
1278 ospf6_maxpath_set(ospf6
, maximum_paths
);
1283 DEFUN(no_ospf6_max_multipath
,
1284 no_ospf6_max_multipath_cmd
,
1285 "no maximum-paths [" CMD_RANGE_STR(1, MULTIPATH_NUM
)"]",
1287 "Max no of multiple paths for ECMP support\n"
1288 "Number of paths\n")
1290 VTY_DECLVAR_CONTEXT(ospf6
, ospf6
);
1292 ospf6_maxpath_set(ospf6
, MULTIPATH_NUM
);
1297 static void ospf6_show(struct vty
*vty
, struct ospf6
*o
, json_object
*json
,
1301 struct ospf6_area
*oa
;
1302 char router_id
[16], duration
[32];
1303 struct timeval now
, running
, result
;
1304 char buf
[32], rbuf
[32];
1305 json_object
*json_areas
= NULL
;
1306 const char *adjacency
;
1309 json_areas
= json_object_new_object();
1311 /* process id, router id */
1312 inet_ntop(AF_INET
, &o
->router_id
, router_id
, sizeof(router_id
));
1313 json_object_string_add(json
, "routerId", router_id
);
1317 timersub(&now
, &o
->starttime
, &running
);
1318 timerstring(&running
, duration
, sizeof(duration
));
1319 json_object_string_add(json
, "running", duration
);
1321 /* Redistribute configuration */
1323 json_object_int_add(json
, "lsaMinimumArrivalMsecs",
1326 /* Show SPF parameters */
1327 json_object_int_add(json
, "spfScheduleDelayMsecs",
1329 json_object_int_add(json
, "holdTimeMinMsecs", o
->spf_holdtime
);
1330 json_object_int_add(json
, "holdTimeMaxMsecs",
1331 o
->spf_max_holdtime
);
1332 json_object_int_add(json
, "holdTimeMultiplier",
1333 o
->spf_hold_multiplier
);
1335 json_object_int_add(json
, "maximumPaths", o
->max_multipath
);
1336 json_object_int_add(json
, "preference",
1339 : ZEBRA_OSPF6_DISTANCE_DEFAULT
);
1341 if (o
->ts_spf
.tv_sec
|| o
->ts_spf
.tv_usec
) {
1342 timersub(&now
, &o
->ts_spf
, &result
);
1343 timerstring(&result
, buf
, sizeof(buf
));
1344 ospf6_spf_reason_string(o
->last_spf_reason
, rbuf
,
1346 json_object_boolean_true_add(json
, "spfHasRun");
1347 json_object_string_add(json
, "spfLastExecutedMsecs",
1349 json_object_string_add(json
, "spfLastExecutedReason",
1352 json_object_int_add(
1353 json
, "spfLastDurationSecs",
1354 (long long)o
->ts_spf_duration
.tv_sec
);
1356 json_object_int_add(
1357 json
, "spfLastDurationMsecs",
1358 (long long)o
->ts_spf_duration
.tv_usec
);
1360 json_object_boolean_false_add(json
, "spfHasRun");
1362 if (thread_is_scheduled(o
->t_spf_calc
)) {
1365 json_object_boolean_true_add(json
, "spfTimerActive");
1367 monotime_until(&o
->t_spf_calc
->u
.sands
, NULL
)
1369 json_object_int_add(json
, "spfTimerDueInMsecs",
1372 json_object_boolean_false_add(json
, "spfTimerActive");
1374 json_object_boolean_add(json
, "routerIsStubRouter",
1375 CHECK_FLAG(o
->flag
, OSPF6_STUB_ROUTER
));
1378 json_object_int_add(json
, "numberOfAsScopedLsa",
1381 json_object_int_add(json
, "numberOfAreaInRouter",
1382 listcount(o
->area_list
));
1384 json_object_int_add(json
, "AuthTrailerHigherSeqNo",
1386 json_object_int_add(json
, "AuthTrailerLowerSeqNo", o
->seqnum_l
);
1388 if (CHECK_FLAG(o
->config_flags
, OSPF6_LOG_ADJACENCY_CHANGES
)) {
1389 if (CHECK_FLAG(o
->config_flags
,
1390 OSPF6_LOG_ADJACENCY_DETAIL
))
1391 adjacency
= "LoggedAll";
1393 adjacency
= "Logged";
1395 adjacency
= "NotLogged";
1396 json_object_string_add(json
, "adjacencyChanges", adjacency
);
1398 for (ALL_LIST_ELEMENTS_RO(o
->area_list
, n
, oa
))
1399 ospf6_area_show(vty
, oa
, json_areas
, use_json
);
1401 json_object_object_add(json
, "areas", json_areas
);
1403 vty_out(vty
, "%s\n",
1404 json_object_to_json_string_ext(
1405 json
, JSON_C_TO_STRING_PRETTY
));
1408 /* process id, router id */
1409 inet_ntop(AF_INET
, &o
->router_id
, router_id
, sizeof(router_id
));
1410 vty_out(vty
, " OSPFv3 Routing Process (0) with Router-ID %s\n",
1415 timersub(&now
, &o
->starttime
, &running
);
1416 timerstring(&running
, duration
, sizeof(duration
));
1417 vty_out(vty
, " Running %s\n", duration
);
1419 /* Redistribute configuration */
1421 vty_out(vty
, " LSA minimum arrival %d msecs\n",
1424 vty_out(vty
, " Maximum-paths %u\n", o
->max_multipath
);
1425 vty_out(vty
, " Administrative distance %u\n",
1426 o
->distance_all
? o
->distance_all
1427 : ZEBRA_OSPF6_DISTANCE_DEFAULT
);
1429 /* Show SPF parameters */
1431 " Initial SPF scheduling delay %d millisec(s)\n"
1432 " Minimum hold time between consecutive SPFs %d millsecond(s)\n"
1433 " Maximum hold time between consecutive SPFs %d millsecond(s)\n"
1434 " Hold time multiplier is currently %d\n",
1435 o
->spf_delay
, o
->spf_holdtime
, o
->spf_max_holdtime
,
1436 o
->spf_hold_multiplier
);
1439 vty_out(vty
, " SPF algorithm ");
1440 if (o
->ts_spf
.tv_sec
|| o
->ts_spf
.tv_usec
) {
1441 timersub(&now
, &o
->ts_spf
, &result
);
1442 timerstring(&result
, buf
, sizeof(buf
));
1443 ospf6_spf_reason_string(o
->last_spf_reason
, rbuf
,
1445 vty_out(vty
, "last executed %s ago, reason %s\n", buf
,
1447 vty_out(vty
, " Last SPF duration %lld sec %lld usec\n",
1448 (long long)o
->ts_spf_duration
.tv_sec
,
1449 (long long)o
->ts_spf_duration
.tv_usec
);
1451 vty_out(vty
, "has not been run\n");
1453 threadtimer_string(now
, o
->t_spf_calc
, buf
, sizeof(buf
));
1454 vty_out(vty
, " SPF timer %s%s\n",
1455 (thread_is_scheduled(o
->t_spf_calc
) ? "due in "
1459 if (CHECK_FLAG(o
->flag
, OSPF6_STUB_ROUTER
))
1460 vty_out(vty
, " Router Is Stub Router\n");
1463 vty_out(vty
, " Number of AS scoped LSAs is %u\n",
1467 vty_out(vty
, " Number of areas in this router is %u\n",
1468 listcount(o
->area_list
));
1470 vty_out(vty
, " Authentication Sequence number info\n");
1471 vty_out(vty
, " Higher sequence no %u, Lower sequence no %u\n",
1472 o
->seqnum_h
, o
->seqnum_l
);
1474 if (CHECK_FLAG(o
->config_flags
, OSPF6_LOG_ADJACENCY_CHANGES
)) {
1475 if (CHECK_FLAG(o
->config_flags
,
1476 OSPF6_LOG_ADJACENCY_DETAIL
))
1478 " All adjacency changes are logged\n");
1480 vty_out(vty
, " Adjacency changes are logged\n");
1486 for (ALL_LIST_ELEMENTS_RO(o
->area_list
, n
, oa
))
1487 ospf6_area_show(vty
, oa
, json_areas
, use_json
);
1491 DEFUN(show_ipv6_ospf6_vrfs
, show_ipv6_ospf6_vrfs_cmd
,
1492 "show ipv6 ospf6 vrfs [json]",
1493 SHOW_STR IP6_STR OSPF6_STR
"Show OSPF6 VRFs \n" JSON_STR
)
1495 bool uj
= use_json(argc
, argv
);
1496 json_object
*json
= NULL
;
1497 json_object
*json_vrfs
= NULL
;
1498 struct ospf6
*ospf6
= NULL
;
1499 struct listnode
*node
= NULL
;
1501 char buf
[PREFIX_STRLEN
];
1502 static const char header
[] =
1503 "Name Id RouterId ";
1506 json
= json_object_new_object();
1507 json_vrfs
= json_object_new_object();
1510 for (ALL_LIST_ELEMENTS_RO(om6
->ospf6
, node
, ospf6
)) {
1511 json_object
*json_vrf
= NULL
;
1512 const char *name
= NULL
;
1513 int64_t vrf_id_ui
= 0;
1514 struct in_addr router_id
;
1516 router_id
.s_addr
= ospf6
->router_id
;
1519 if (!uj
&& count
== 1)
1520 vty_out(vty
, "%s\n", header
);
1522 json_vrf
= json_object_new_object();
1524 if (ospf6
->vrf_id
== VRF_DEFAULT
)
1525 name
= VRF_DEFAULT_NAME
;
1529 vrf_id_ui
= (ospf6
->vrf_id
== VRF_UNKNOWN
)
1531 : (int64_t)ospf6
->vrf_id
;
1534 json_object_int_add(json_vrf
, "vrfId", vrf_id_ui
);
1535 json_object_string_addf(json_vrf
, "routerId", "%pI4",
1537 json_object_object_add(json_vrfs
, name
, json_vrf
);
1540 vty_out(vty
, "%-25s %-5d %-16s \n", name
,
1542 inet_ntop(AF_INET
, &router_id
, buf
,
1548 json_object_object_add(json
, "vrfs", json_vrfs
);
1549 json_object_int_add(json
, "totalVrfs", count
);
1551 vty_json(vty
, json
);
1554 vty_out(vty
, "\nTotal number of OSPF VRFs: %d\n",
1561 /* show top level structures */
1562 DEFUN(show_ipv6_ospf6
, show_ipv6_ospf6_cmd
,
1563 "show ipv6 ospf6 [vrf <NAME|all>] [json]",
1564 SHOW_STR IP6_STR OSPF6_STR VRF_CMD_HELP_STR
"All VRFs\n" JSON_STR
)
1566 struct ospf6
*ospf6
;
1567 struct listnode
*node
;
1568 const char *vrf_name
= NULL
;
1569 bool all_vrf
= false;
1572 bool uj
= use_json(argc
, argv
);
1573 json_object
*json
= NULL
;
1575 OSPF6_FIND_VRF_ARGS(argv
, argc
, idx_vrf
, vrf_name
, all_vrf
);
1577 for (ALL_LIST_ELEMENTS_RO(om6
->ospf6
, node
, ospf6
)) {
1578 if (all_vrf
|| strcmp(ospf6
->name
, vrf_name
) == 0) {
1580 json
= json_object_new_object();
1581 ospf6_show(vty
, ospf6
, json
, uj
);
1589 json_object_free(json
);
1591 OSPF6_CMD_CHECK_VRF(uj
, all_vrf
, ospf6
);
1596 DEFUN(show_ipv6_ospf6_route
, show_ipv6_ospf6_route_cmd
,
1597 "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]",
1598 SHOW_STR IP6_STR OSPF6_STR VRF_CMD_HELP_STR
1599 "All VRFs\n" ROUTE_STR
1600 "Display Intra-Area routes\n"
1601 "Display Inter-Area routes\n"
1602 "Display Type-1 External routes\n"
1603 "Display Type-2 External routes\n"
1604 "Specify IPv6 address\n"
1605 "Specify IPv6 prefix\n"
1606 "Detailed information\n"
1607 "Summary of route table\n" JSON_STR
)
1609 struct ospf6
*ospf6
;
1610 struct listnode
*node
;
1611 const char *vrf_name
= NULL
;
1612 bool all_vrf
= false;
1614 int idx_arg_start
= 4;
1615 bool uj
= use_json(argc
, argv
);
1617 OSPF6_FIND_VRF_ARGS(argv
, argc
, idx_vrf
, vrf_name
, all_vrf
);
1621 for (ALL_LIST_ELEMENTS_RO(om6
->ospf6
, node
, ospf6
)) {
1622 if (all_vrf
|| strcmp(ospf6
->name
, vrf_name
) == 0) {
1623 ospf6_route_table_show(vty
, idx_arg_start
, argc
, argv
,
1624 ospf6
->route_table
, uj
);
1631 OSPF6_CMD_CHECK_VRF(uj
, all_vrf
, ospf6
);
1636 DEFUN(show_ipv6_ospf6_route_match
, show_ipv6_ospf6_route_match_cmd
,
1637 "show ipv6 ospf6 [vrf <NAME|all>] route X:X::X:X/M <match|longer> [json]",
1638 SHOW_STR IP6_STR OSPF6_STR VRF_CMD_HELP_STR
1639 "All VRFs\n" ROUTE_STR
1640 "Specify IPv6 prefix\n"
1641 "Display routes which match the specified route\n"
1642 "Display routes longer than the specified route\n" JSON_STR
)
1644 struct ospf6
*ospf6
;
1645 struct listnode
*node
;
1646 const char *vrf_name
= NULL
;
1647 bool all_vrf
= false;
1649 int idx_start_arg
= 4;
1650 bool uj
= use_json(argc
, argv
);
1652 OSPF6_FIND_VRF_ARGS(argv
, argc
, idx_vrf
, vrf_name
, all_vrf
);
1656 for (ALL_LIST_ELEMENTS_RO(om6
->ospf6
, node
, ospf6
)) {
1657 if (all_vrf
|| strcmp(ospf6
->name
, vrf_name
) == 0) {
1658 ospf6_route_table_show(vty
, idx_start_arg
, argc
, argv
,
1659 ospf6
->route_table
, uj
);
1666 OSPF6_CMD_CHECK_VRF(uj
, all_vrf
, ospf6
);
1671 DEFUN(show_ipv6_ospf6_route_match_detail
,
1672 show_ipv6_ospf6_route_match_detail_cmd
,
1673 "show ipv6 ospf6 [vrf <NAME|all>] route X:X::X:X/M match detail [json]",
1674 SHOW_STR IP6_STR OSPF6_STR VRF_CMD_HELP_STR
1675 "All VRFs\n" ROUTE_STR
1676 "Specify IPv6 prefix\n"
1677 "Display routes which match the specified route\n"
1678 "Detailed information\n" JSON_STR
)
1680 struct ospf6
*ospf6
;
1681 struct listnode
*node
;
1682 const char *vrf_name
= NULL
;
1683 bool all_vrf
= false;
1685 int idx_start_arg
= 4;
1686 bool uj
= use_json(argc
, argv
);
1688 OSPF6_FIND_VRF_ARGS(argv
, argc
, idx_vrf
, vrf_name
, all_vrf
);
1692 for (ALL_LIST_ELEMENTS_RO(om6
->ospf6
, node
, ospf6
)) {
1693 if (all_vrf
|| strcmp(ospf6
->name
, vrf_name
) == 0) {
1694 ospf6_route_table_show(vty
, idx_start_arg
, argc
, argv
,
1695 ospf6
->route_table
, uj
);
1702 OSPF6_CMD_CHECK_VRF(uj
, all_vrf
, ospf6
);
1707 DEFUN(show_ipv6_ospf6_route_type_detail
, show_ipv6_ospf6_route_type_detail_cmd
,
1708 "show ipv6 ospf6 [vrf <NAME|all>] route <intra-area|inter-area|external-1|external-2> detail [json]",
1709 SHOW_STR IP6_STR OSPF6_STR VRF_CMD_HELP_STR
1710 "All VRFs\n" ROUTE_STR
1711 "Display Intra-Area routes\n"
1712 "Display Inter-Area routes\n"
1713 "Display Type-1 External routes\n"
1714 "Display Type-2 External routes\n"
1715 "Detailed information\n" JSON_STR
)
1717 struct ospf6
*ospf6
;
1718 struct listnode
*node
;
1719 const char *vrf_name
= NULL
;
1720 bool all_vrf
= false;
1722 int idx_start_arg
= 4;
1723 bool uj
= use_json(argc
, argv
);
1725 OSPF6_FIND_VRF_ARGS(argv
, argc
, idx_vrf
, vrf_name
, all_vrf
);
1729 for (ALL_LIST_ELEMENTS_RO(om6
->ospf6
, node
, ospf6
)) {
1730 if (all_vrf
|| strcmp(ospf6
->name
, vrf_name
) == 0) {
1731 ospf6_route_table_show(vty
, idx_start_arg
, argc
, argv
,
1732 ospf6
->route_table
, uj
);
1739 OSPF6_CMD_CHECK_VRF(uj
, all_vrf
, ospf6
);
1744 bool ospf6_is_valid_summary_addr(struct vty
*vty
, struct prefix
*p
)
1746 /* Default prefix validation*/
1747 if (is_default_prefix(p
)) {
1749 "Default address should not be configured as summary address.\n");
1753 /* Host route should not be configured as summary address */
1754 if (p
->prefixlen
== IPV6_MAX_BITLEN
) {
1755 vty_out(vty
, "Host route should not be configured as summary address.\n");
1762 /* External Route Aggregation */
1763 DEFPY (ospf6_external_route_aggregation
,
1764 ospf6_external_route_aggregation_cmd
,
1765 "summary-address X:X::X:X/M$prefix [tag (1-4294967295)] [{metric (0-16777215) | metric-type (1-2)$mtype}]",
1766 "External summary address\n"
1767 "Specify IPv6 prefix\n"
1769 "Router tag value\n"
1771 "Advertised metric for this route\n"
1772 "OSPFv3 exterior metric type for summarised routes\n"
1773 "Set OSPFv3 External Type 1/2 metrics\n")
1775 VTY_DECLVAR_CONTEXT(ospf6
, ospf6
);
1778 int ret
= CMD_SUCCESS
;
1780 p
.family
= AF_INET6
;
1781 ret
= str2prefix(prefix_str
, &p
);
1783 vty_out(vty
, "Malformed prefix\n");
1784 return CMD_WARNING_CONFIG_FAILED
;
1787 /* Apply mask for given prefix. */
1790 if (!ospf6_is_valid_summary_addr(vty
, &p
))
1791 return CMD_WARNING_CONFIG_FAILED
;
1800 mtype
= DEFAULT_METRIC_TYPE
;
1802 ret
= ospf6_external_aggr_config_set(ospf6
, &p
, tag
, metric
, mtype
);
1803 if (ret
== OSPF6_FAILURE
) {
1804 vty_out(vty
, "Invalid configuration!!\n");
1805 return CMD_WARNING_CONFIG_FAILED
;
1811 DEFPY(no_ospf6_external_route_aggregation
,
1812 no_ospf6_external_route_aggregation_cmd
,
1813 "no summary-address X:X::X:X/M$prefix [tag (1-4294967295)] [{metric (0-16777215) | metric-type (1-2)}]",
1815 "External summary address\n"
1816 "Specify IPv6 prefix\n"
1818 "Router tag value\n"
1820 "Advertised metric for this route\n"
1821 "OSPFv3 exterior metric type for summarised routes\n"
1822 "Set OSPFv3 External Type 1/2 metrics\n")
1824 VTY_DECLVAR_CONTEXT(ospf6
, ospf6
);
1827 int ret
= CMD_SUCCESS
;
1829 ret
= str2prefix(prefix_str
, &p
);
1831 vty_out(vty
, "Malformed prefix\n");
1832 return CMD_WARNING_CONFIG_FAILED
;
1835 /* Apply mask for given prefix. */
1838 if (!ospf6_is_valid_summary_addr(vty
, &p
))
1839 return CMD_WARNING_CONFIG_FAILED
;
1841 ret
= ospf6_external_aggr_config_unset(ospf6
, &p
);
1842 if (ret
== OSPF6_INVALID
)
1843 vty_out(vty
, "Invalid configuration!!\n");
1848 DEFPY (ospf6_external_route_aggregation_no_advertise
,
1849 ospf6_external_route_aggregation_no_advertise_cmd
,
1850 "summary-address X:X::X:X/M$prefix no-advertise",
1851 "External summary address\n"
1852 "Specify IPv6 prefix\n"
1853 "Don't advertise summary route \n")
1855 VTY_DECLVAR_CONTEXT(ospf6
, ospf6
);
1858 int ret
= CMD_SUCCESS
;
1860 ret
= str2prefix(prefix_str
, &p
);
1862 vty_out(vty
, "Malformed prefix\n");
1863 return CMD_WARNING_CONFIG_FAILED
;
1866 /* Apply mask for given prefix. */
1869 if (!ospf6_is_valid_summary_addr(vty
, &p
))
1870 return CMD_WARNING_CONFIG_FAILED
;
1872 ret
= ospf6_asbr_external_rt_no_advertise(ospf6
, &p
);
1873 if (ret
== OSPF6_INVALID
)
1874 vty_out(vty
, "!!Invalid configuration\n");
1879 DEFPY (no_ospf6_external_route_aggregation_no_advertise
,
1880 no_ospf6_external_route_aggregation_no_advertise_cmd
,
1881 "no summary-address X:X::X:X/M$prefix no-advertise",
1883 "External summary address\n"
1884 "Specify IPv6 prefix\n"
1885 "Adverise summary route to the AS \n")
1887 VTY_DECLVAR_CONTEXT(ospf6
, ospf6
);
1890 int ret
= CMD_SUCCESS
;
1892 ret
= str2prefix(prefix_str
, &p
);
1894 vty_out(vty
, "Malformed prefix\n");
1895 return CMD_WARNING_CONFIG_FAILED
;
1898 /* Apply mask for given prefix. */
1901 if (!ospf6_is_valid_summary_addr(vty
, &p
))
1902 return CMD_WARNING_CONFIG_FAILED
;
1904 ret
= ospf6_asbr_external_rt_advertise(ospf6
, &p
);
1905 if (ret
== OSPF6_INVALID
)
1906 vty_out(vty
, "!!Invalid configuration\n");
1911 DEFPY (ospf6_route_aggregation_timer
,
1912 ospf6_route_aggregation_timer_cmd
,
1913 "aggregation timer (5-1800)",
1914 "External route aggregation\n"
1915 "Delay timer (in seconds)\n"
1916 "Timer interval(in seconds)\n")
1918 VTY_DECLVAR_CONTEXT(ospf6
, ospf6
);
1920 ospf6_external_aggr_delay_timer_set(ospf6
, timer
);
1925 DEFPY (no_ospf6_route_aggregation_timer
,
1926 no_ospf6_route_aggregation_timer_cmd
,
1927 "no aggregation timer [5-1800]",
1929 "External route aggregation\n"
1931 "Timer interval(in seconds)\n")
1933 VTY_DECLVAR_CONTEXT(ospf6
, ospf6
);
1935 ospf6_external_aggr_delay_timer_set(ospf6
,
1936 OSPF6_EXTL_AGGR_DEFAULT_DELAY
);
1941 ospf6_print_vty_external_routes_walkcb(struct hash_bucket
*bucket
, void *arg
)
1943 struct ospf6_route
*rt
= bucket
->data
;
1944 struct vty
*vty
= (struct vty
*)arg
;
1945 static unsigned int count
;
1947 vty_out(vty
, "%pFX ", &rt
->prefix
);
1954 if (OSPF6_EXTERNAL_RT_COUNT(rt
->aggr_route
) == count
)
1957 return HASHWALK_CONTINUE
;
1961 ospf6_print_json_external_routes_walkcb(struct hash_bucket
*bucket
, void *arg
)
1963 struct ospf6_route
*rt
= bucket
->data
;
1964 struct json_object
*json
= (struct json_object
*)arg
;
1965 char buf
[PREFIX2STR_BUFFER
];
1967 static unsigned int count
;
1969 prefix2str(&rt
->prefix
, buf
, sizeof(buf
));
1971 snprintf(exnalbuf
, sizeof(exnalbuf
), "Exnl Addr-%d", count
);
1973 json_object_string_add(json
, exnalbuf
, buf
);
1977 if (OSPF6_EXTERNAL_RT_COUNT(rt
->aggr_route
) == count
)
1980 return HASHWALK_CONTINUE
;
1984 ospf6_show_vrf_name(struct vty
*vty
, struct ospf6
*ospf6
,
1988 if (ospf6
->vrf_id
== VRF_DEFAULT
)
1989 json_object_string_add(json
, "vrfName",
1992 json_object_string_add(json
, "vrfName",
1994 json_object_int_add(json
, "vrfId", ospf6
->vrf_id
);
1996 if (ospf6
->vrf_id
== VRF_DEFAULT
)
1997 vty_out(vty
, "VRF Name: %s\n", "default");
1998 else if (ospf6
->name
)
1999 vty_out(vty
, "VRF Name: %s\n", ospf6
->name
);
2004 ospf6_show_summary_address(struct vty
*vty
, struct ospf6
*ospf6
,
2006 bool uj
, const char *detail
)
2008 struct route_node
*rn
;
2009 static const char header
[] = "Summary-address Metric-type Metric Tag External_Rt_count\n";
2010 json_object
*json_vrf
= NULL
;
2013 ospf6_show_vrf_name(vty
, ospf6
, json_vrf
);
2014 vty_out(vty
, "aggregation delay interval :%u(in seconds)\n\n",
2015 ospf6
->aggr_delay_interval
);
2016 vty_out(vty
, "%s\n", header
);
2018 json_vrf
= json_object_new_object();
2020 ospf6_show_vrf_name(vty
, ospf6
, json_vrf
);
2022 json_object_int_add(json_vrf
, "aggregationDelayInterval",
2023 ospf6
->aggr_delay_interval
);
2027 for (rn
= route_top(ospf6
->rt_aggr_tbl
); rn
; rn
= route_next(rn
)) {
2031 struct ospf6_external_aggr_rt
*aggr
= rn
->info
;
2032 json_object
*json_aggr
= NULL
;
2033 char buf
[PREFIX2STR_BUFFER
];
2035 prefix2str(&aggr
->p
, buf
, sizeof(buf
));
2039 json_aggr
= json_object_new_object();
2041 json_object_object_add(json_vrf
,
2045 json_object_string_add(json_aggr
, "summaryAddress",
2048 json_object_string_add(
2049 json_aggr
, "metricType",
2050 (aggr
->mtype
== DEFAULT_METRIC_TYPE
) ? "E2"
2053 json_object_int_add(json_aggr
, "Metric",
2054 (aggr
->metric
!= -1)
2056 : DEFAULT_DEFAULT_METRIC
);
2058 json_object_int_add(json_aggr
, "Tag",
2061 json_object_int_add(json_aggr
, "externalRouteCount",
2062 OSPF6_EXTERNAL_RT_COUNT(aggr
));
2064 if (OSPF6_EXTERNAL_RT_COUNT(aggr
) && detail
) {
2065 json_object_int_add(json_aggr
, "ID",
2067 json_object_int_add(json_aggr
, "Flags",
2069 hash_walk(aggr
->match_extnl_hash
,
2070 ospf6_print_json_external_routes_walkcb
,
2075 vty_out(vty
, "%-22s", buf
);
2077 (aggr
->mtype
== DEFAULT_METRIC_TYPE
)
2078 ? vty_out(vty
, "%-16s", "E2")
2079 : vty_out(vty
, "%-16s", "E1");
2080 vty_out(vty
, "%-11d", (aggr
->metric
!= -1)
2082 : DEFAULT_DEFAULT_METRIC
);
2084 vty_out(vty
, "%-12u", aggr
->tag
);
2086 vty_out(vty
, "%-5ld\n",
2087 OSPF6_EXTERNAL_RT_COUNT(aggr
));
2089 if (OSPF6_EXTERNAL_RT_COUNT(aggr
) && detail
) {
2091 "Matched External routes:\n");
2092 hash_walk(aggr
->match_extnl_hash
,
2093 ospf6_print_vty_external_routes_walkcb
,
2103 json_object_object_add(json
, ospf6
->name
,
2109 DEFPY (show_ipv6_ospf6_external_aggregator
,
2110 show_ipv6_ospf6_external_aggregator_cmd
,
2111 "show ipv6 ospf6 [vrf <NAME|all>] summary-address [detail$detail] [json]",
2117 "Show external summary addresses\n"
2118 "detailed information\n"
2121 bool uj
= use_json(argc
, argv
);
2122 struct ospf6
*ospf6
= NULL
;
2123 json_object
*json
= NULL
;
2124 const char *vrf_name
= NULL
;
2125 struct listnode
*node
;
2126 bool all_vrf
= false;
2130 json
= json_object_new_object();
2132 OSPF6_FIND_VRF_ARGS(argv
, argc
, idx_vrf
, vrf_name
, all_vrf
);
2134 for (ALL_LIST_ELEMENTS_RO(om6
->ospf6
, node
, ospf6
)) {
2135 if (all_vrf
|| strcmp(ospf6
->name
, vrf_name
) == 0) {
2137 ospf6_show_summary_address(vty
, ospf6
, json
, uj
,
2146 vty_json(vty
, json
);
2149 OSPF6_CMD_CHECK_VRF(uj
, all_vrf
, ospf6
);
2154 static void ospf6_stub_router_config_write(struct vty
*vty
, struct ospf6
*ospf6
)
2156 if (CHECK_FLAG(ospf6
->flag
, OSPF6_STUB_ROUTER
))
2157 vty_out(vty
, " stub-router administrative\n");
2161 static int ospf6_distance_config_write(struct vty
*vty
, struct ospf6
*ospf6
)
2163 struct route_node
*rn
;
2164 struct ospf6_distance
*odistance
;
2166 if (ospf6
->distance_all
)
2167 vty_out(vty
, " distance %u\n", ospf6
->distance_all
);
2169 if (ospf6
->distance_intra
|| ospf6
->distance_inter
2170 || ospf6
->distance_external
) {
2171 vty_out(vty
, " distance ospf6");
2173 if (ospf6
->distance_intra
)
2174 vty_out(vty
, " intra-area %u", ospf6
->distance_intra
);
2175 if (ospf6
->distance_inter
)
2176 vty_out(vty
, " inter-area %u", ospf6
->distance_inter
);
2177 if (ospf6
->distance_external
)
2178 vty_out(vty
, " external %u", ospf6
->distance_external
);
2183 for (rn
= route_top(ospf6
->distance_table
); rn
; rn
= route_next(rn
))
2184 if ((odistance
= rn
->info
) != NULL
)
2185 vty_out(vty
, " distance %u %pFX %s\n",
2186 odistance
->distance
, &rn
->p
,
2187 odistance
->access_list
? odistance
->access_list
2192 static int ospf6_asbr_summary_config_write(struct vty
*vty
, struct ospf6
*ospf6
)
2194 struct route_node
*rn
;
2195 struct ospf6_external_aggr_rt
*aggr
;
2196 char buf
[PREFIX2STR_BUFFER
];
2198 if (ospf6
->aggr_delay_interval
!= OSPF6_EXTL_AGGR_DEFAULT_DELAY
)
2199 vty_out(vty
, " aggregation timer %u\n",
2200 ospf6
->aggr_delay_interval
);
2202 /* print 'summary-address A:B::C:D/M' */
2203 for (rn
= route_top(ospf6
->rt_aggr_tbl
); rn
; rn
= route_next(rn
)) {
2209 prefix2str(&aggr
->p
, buf
, sizeof(buf
));
2210 vty_out(vty
, " summary-address %s", buf
);
2212 vty_out(vty
, " tag %u", aggr
->tag
);
2214 if (aggr
->metric
!= -1)
2215 vty_out(vty
, " metric %d", aggr
->metric
);
2217 if (aggr
->mtype
!= DEFAULT_METRIC_TYPE
)
2218 vty_out(vty
, " metric-type %d", aggr
->mtype
);
2220 if (CHECK_FLAG(aggr
->aggrflags
,
2221 OSPF6_EXTERNAL_AGGRT_NO_ADVERTISE
))
2222 vty_out(vty
, " no-advertise");
2230 /* OSPF configuration write function. */
2231 static int config_write_ospf6(struct vty
*vty
)
2233 struct ospf6
*ospf6
;
2234 struct listnode
*node
, *nnode
;
2236 /* OSPFv3 configuration. */
2240 for (ALL_LIST_ELEMENTS(om6
->ospf6
, node
, nnode
, ospf6
)) {
2241 if (ospf6
->name
&& strcmp(ospf6
->name
, VRF_DEFAULT_NAME
))
2242 vty_out(vty
, "router ospf6 vrf %s\n", ospf6
->name
);
2244 vty_out(vty
, "router ospf6\n");
2246 if (ospf6
->router_id_static
!= 0)
2247 vty_out(vty
, " ospf6 router-id %pI4\n",
2248 &ospf6
->router_id_static
);
2250 if (CHECK_FLAG(ospf6
->config_flags
,
2251 OSPF6_SEND_EXTRA_DATA_TO_ZEBRA
))
2252 vty_out(vty
, " ospf6 send-extra-data zebra\n");
2254 /* log-adjacency-changes flag print. */
2255 if (CHECK_FLAG(ospf6
->config_flags
,
2256 OSPF6_LOG_ADJACENCY_CHANGES
)) {
2257 if (CHECK_FLAG(ospf6
->config_flags
,
2258 OSPF6_LOG_ADJACENCY_DETAIL
))
2259 vty_out(vty
, " log-adjacency-changes detail\n");
2260 else if (!SAVE_OSPF6_LOG_ADJACENCY_CHANGES
)
2261 vty_out(vty
, " log-adjacency-changes\n");
2262 } else if (SAVE_OSPF6_LOG_ADJACENCY_CHANGES
) {
2263 vty_out(vty
, " no log-adjacency-changes\n");
2266 if (ospf6
->ref_bandwidth
!= OSPF6_REFERENCE_BANDWIDTH
)
2267 vty_out(vty
, " auto-cost reference-bandwidth %d\n",
2268 ospf6
->ref_bandwidth
);
2270 if (ospf6
->write_oi_count
2271 != OSPF6_WRITE_INTERFACE_COUNT_DEFAULT
)
2272 vty_out(vty
, " write-multiplier %d\n",
2273 ospf6
->write_oi_count
);
2275 /* LSA timers print. */
2276 if (ospf6
->lsa_minarrival
!= OSPF_MIN_LS_ARRIVAL
)
2277 vty_out(vty
, " timers lsa min-arrival %d\n",
2278 ospf6
->lsa_minarrival
);
2280 /* ECMP max path config */
2281 if (ospf6
->max_multipath
!= MULTIPATH_NUM
)
2282 vty_out(vty
, " maximum-paths %d\n",
2283 ospf6
->max_multipath
);
2285 ospf6_stub_router_config_write(vty
, ospf6
);
2286 ospf6_redistribute_config_write(vty
, ospf6
);
2287 ospf6_area_config_write(vty
, ospf6
);
2288 ospf6_spf_config_write(vty
, ospf6
);
2289 ospf6_distance_config_write(vty
, ospf6
);
2290 ospf6_distribute_config_write(vty
, ospf6
);
2291 ospf6_asbr_summary_config_write(vty
, ospf6
);
2292 config_write_ospf6_gr(vty
, ospf6
);
2293 config_write_ospf6_gr_helper(vty
, ospf6
);
2295 vty_out(vty
, "exit\n");
2296 vty_out(vty
, "!\n");
2301 static int config_write_ospf6(struct vty
*vty
);
2302 /* OSPF6 node structure. */
2303 static struct cmd_node ospf6_node
= {
2306 .parent_node
= CONFIG_NODE
,
2307 .prompt
= "%s(config-ospf6)# ",
2308 .config_write
= config_write_ospf6
,
2311 void install_element_ospf6_clear_process(void)
2313 install_element(ENABLE_NODE
, &clear_router_ospf6_cmd
);
2316 /* Install ospf related commands. */
2317 void ospf6_top_init(void)
2319 /* Install ospf6 top node. */
2320 install_node(&ospf6_node
);
2322 install_element(VIEW_NODE
, &show_ipv6_ospf6_cmd
);
2323 install_element(VIEW_NODE
, &show_ipv6_ospf6_vrfs_cmd
);
2324 install_element(CONFIG_NODE
, &router_ospf6_cmd
);
2325 install_element(CONFIG_NODE
, &no_router_ospf6_cmd
);
2327 install_element(VIEW_NODE
, &show_ipv6_ospf6_route_cmd
);
2328 install_element(VIEW_NODE
, &show_ipv6_ospf6_route_match_cmd
);
2329 install_element(VIEW_NODE
, &show_ipv6_ospf6_route_match_detail_cmd
);
2330 install_element(VIEW_NODE
, &show_ipv6_ospf6_route_type_detail_cmd
);
2332 install_default(OSPF6_NODE
);
2333 install_element(OSPF6_NODE
, &ospf6_router_id_cmd
);
2334 install_element(OSPF6_NODE
, &no_ospf6_router_id_cmd
);
2335 install_element(OSPF6_NODE
, &ospf6_log_adjacency_changes_cmd
);
2336 install_element(OSPF6_NODE
, &ospf6_log_adjacency_changes_detail_cmd
);
2337 install_element(OSPF6_NODE
, &no_ospf6_log_adjacency_changes_cmd
);
2338 install_element(OSPF6_NODE
, &no_ospf6_log_adjacency_changes_detail_cmd
);
2339 install_element(OSPF6_NODE
, &ospf6_send_extra_data_cmd
);
2341 /* LSA timers commands */
2342 install_element(OSPF6_NODE
, &ospf6_timers_lsa_cmd
);
2343 install_element(OSPF6_NODE
, &no_ospf6_timers_lsa_cmd
);
2345 install_element(OSPF6_NODE
, &ospf6_interface_area_cmd
);
2346 install_element(OSPF6_NODE
, &no_ospf6_interface_area_cmd
);
2347 install_element(OSPF6_NODE
, &ospf6_stub_router_admin_cmd
);
2348 install_element(OSPF6_NODE
, &no_ospf6_stub_router_admin_cmd
);
2350 /* maximum-paths command */
2351 install_element(OSPF6_NODE
, &ospf6_max_multipath_cmd
);
2352 install_element(OSPF6_NODE
, &no_ospf6_max_multipath_cmd
);
2354 /* ASBR Summarisation */
2355 install_element(OSPF6_NODE
, &ospf6_external_route_aggregation_cmd
);
2356 install_element(OSPF6_NODE
, &no_ospf6_external_route_aggregation_cmd
);
2357 install_element(OSPF6_NODE
,
2358 &ospf6_external_route_aggregation_no_advertise_cmd
);
2359 install_element(OSPF6_NODE
,
2360 &no_ospf6_external_route_aggregation_no_advertise_cmd
);
2361 install_element(OSPF6_NODE
, &ospf6_route_aggregation_timer_cmd
);
2362 install_element(OSPF6_NODE
, &no_ospf6_route_aggregation_timer_cmd
);
2363 install_element(VIEW_NODE
, &show_ipv6_ospf6_external_aggregator_cmd
);
2365 install_element(OSPF6_NODE
, &ospf6_distance_cmd
);
2366 install_element(OSPF6_NODE
, &no_ospf6_distance_cmd
);
2367 install_element(OSPF6_NODE
, &ospf6_distance_ospf6_cmd
);
2368 install_element(OSPF6_NODE
, &no_ospf6_distance_ospf6_cmd
);