]> git.proxmox.com Git - mirror_frr.git/blame - ospf6d/ospf6_top.c
*: Convert thread_cancelXXX to event_cancelXXX
[mirror_frr.git] / ospf6d / ospf6_top.c
CommitLineData
acddc0ed 1// SPDX-License-Identifier: GPL-2.0-or-later
718e3744 2/*
508e53e2 3 * Copyright (C) 2003 Yasuhiro Ohara
718e3744 4 */
5
6#include <zebra.h>
7
8#include "log.h"
9#include "memory.h"
10#include "vty.h"
11#include "linklist.h"
12#include "prefix.h"
13#include "table.h"
cb37cb33 14#include "event.h"
718e3744 15#include "command.h"
8efe88ea 16#include "defaults.h"
35a45dea 17#include "lib/json.h"
7df1f362 18#include "lib_errors.h"
718e3744 19
718e3744 20#include "ospf6_proto.h"
508e53e2 21#include "ospf6_message.h"
718e3744 22#include "ospf6_lsa.h"
23#include "ospf6_lsdb.h"
718e3744 24#include "ospf6_route.h"
25#include "ospf6_zebra.h"
26
508e53e2 27#include "ospf6_top.h"
28#include "ospf6_area.h"
29#include "ospf6_interface.h"
30#include "ospf6_neighbor.h"
7df1f362 31#include "ospf6_network.h"
718e3744 32
6452df09 33#include "ospf6_flood.h"
508e53e2 34#include "ospf6_asbr.h"
049207c3 35#include "ospf6_abr.h"
6452df09 36#include "ospf6_intra.h"
3810e06e 37#include "ospf6_spf.h"
049207c3 38#include "ospf6d.h"
0d1753a7 39#include "ospf6_gr.h"
eacd0828 40#include "lib/json.h"
ad500b22 41#include "ospf6_nssa.h"
6cb85350 42#include "ospf6_auth_trailer.h"
718e3744 43
30043e4c
DL
44DEFINE_MTYPE_STATIC(OSPF6D, OSPF6_TOP, "OSPF6 top");
45
96244aca 46DEFINE_QOBJ_TYPE(ospf6);
ae19c240 47
c572fbfe 48FRR_CFG_DEFAULT_BOOL(OSPF6_LOG_ADJACENCY_CHANGES,
4c1458b5
DL
49 { .val_bool = true, .match_profile = "datacenter", },
50 { .val_bool = false },
67b0f40c 51);
c572fbfe 52
f71ed6df 53#include "ospf6d/ospf6_top_clippy.c"
f71ed6df 54
718e3744 55/* global ospf6d variable */
78c6ba61
CS
56static struct ospf6_master ospf6_master;
57struct ospf6_master *om6;
718e3744 58
d62a17ae 59static void ospf6_disable(struct ospf6 *o);
ae2254aa 60
beadc736 61static void ospf6_add(struct ospf6 *ospf6)
62{
63 listnode_add(om6->ospf6, ospf6);
64}
65
66static void ospf6_del(struct ospf6 *ospf6)
67{
68 listnode_delete(om6->ospf6, ospf6);
69}
70
71const char *ospf6_vrf_id_to_name(vrf_id_t vrf_id)
72{
73 struct vrf *vrf = vrf_lookup_by_id(vrf_id);
74
75 return vrf ? vrf->name : "NIL";
76}
77
78/* Link OSPF instance to VRF. */
79void ospf6_vrf_link(struct ospf6 *ospf6, struct vrf *vrf)
80{
81 ospf6->vrf_id = vrf->vrf_id;
82 if (vrf->info != (void *)ospf6)
83 vrf->info = (void *)ospf6;
84}
85
86/* Unlink OSPF instance from VRF. */
87void ospf6_vrf_unlink(struct ospf6 *ospf6, struct vrf *vrf)
88{
89 if (vrf->info == (void *)ospf6)
90 vrf->info = NULL;
91 ospf6->vrf_id = VRF_UNKNOWN;
92}
93
94struct ospf6 *ospf6_lookup_by_vrf_id(vrf_id_t vrf_id)
95{
96 struct vrf *vrf = NULL;
97
98 vrf = vrf_lookup_by_id(vrf_id);
99 if (!vrf)
100 return NULL;
101 return (vrf->info) ? (struct ospf6 *)vrf->info : NULL;
102}
103
104struct ospf6 *ospf6_lookup_by_vrf_name(const char *name)
105{
106 struct ospf6 *o = NULL;
107 struct listnode *node, *nnode;
108
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)))
112 return o;
113 }
114 return NULL;
115}
116
4e8ccd92 117/* This is hook function for vrf create called as part of vrf_init */
118static int ospf6_vrf_new(struct vrf *vrf)
119{
120 return 0;
121}
122
123/* This is hook function for vrf delete call as part of vrf_init */
124static int ospf6_vrf_delete(struct vrf *vrf)
125{
126 return 0;
127}
128
129static void ospf6_set_redist_vrf_bitmaps(struct ospf6 *ospf6, bool set)
130{
131 int type;
132 struct list *red_list;
133
134 for (type = 0; type < ZEBRA_ROUTE_MAX; type++) {
135 red_list = ospf6->redist[type];
136 if (!red_list)
137 continue;
138 if (IS_OSPF6_DEBUG_ZEBRA(RECV))
139 zlog_debug(
140 "%s: setting redist vrf %d bitmap for type %d",
141 __func__, ospf6->vrf_id, type);
142 if (set)
143 vrf_bitmap_set(zclient->redist[AFI_IP6][type],
144 ospf6->vrf_id);
145 else
146 vrf_bitmap_unset(zclient->redist[AFI_IP6][type],
147 ospf6->vrf_id);
148 }
82bc4b8a
IR
149
150 red_list = ospf6->redist[DEFAULT_ROUTE];
151 if (red_list) {
152 if (set)
153 vrf_bitmap_set(zclient->default_information[AFI_IP6],
154 ospf6->vrf_id);
155 else
156 vrf_bitmap_unset(zclient->default_information[AFI_IP6],
157 ospf6->vrf_id);
158 }
4e8ccd92 159}
160
161/* Disable OSPF6 VRF instance */
162static int ospf6_vrf_disable(struct vrf *vrf)
163{
164 struct ospf6 *ospf6 = NULL;
165
166 if (vrf->vrf_id == VRF_DEFAULT)
167 return 0;
168
169 ospf6 = ospf6_lookup_by_vrf_name(vrf->name);
170 if (ospf6) {
171 ospf6_zebra_vrf_deregister(ospf6);
172
173 ospf6_set_redist_vrf_bitmaps(ospf6, false);
174
175 /* We have instance configured, unlink
176 * from VRF and make it "down".
177 */
178 ospf6_vrf_unlink(ospf6, vrf);
332beb64 179 event_cancel(&ospf6->t_ospf6_receive);
4e8ccd92 180 close(ospf6->fd);
181 ospf6->fd = -1;
182 }
183
184 /* Note: This is a callback, the VRF will be deleted by the caller. */
185 return 0;
186}
187
188/* Enable OSPF6 VRF instance */
189static int ospf6_vrf_enable(struct vrf *vrf)
190{
191 struct ospf6 *ospf6 = NULL;
192 vrf_id_t old_vrf_id;
193 int ret = 0;
194
195 ospf6 = ospf6_lookup_by_vrf_name(vrf->name);
196 if (ospf6) {
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);
200
201 if (old_vrf_id != ospf6->vrf_id) {
202 ospf6_set_redist_vrf_bitmaps(ospf6, true);
203
204 /* start zebra redist to us for new vrf */
205 ospf6_zebra_vrf_register(ospf6);
206
207 ret = ospf6_serv_sock(ospf6);
208 if (ret < 0 || ospf6->fd <= 0)
209 return 0;
907a2395
DS
210 event_add_read(master, ospf6_receive, ospf6, ospf6->fd,
211 &ospf6->t_ospf6_receive);
4e8ccd92 212
436a55a1 213 ospf6_router_id_update(ospf6, true);
4e8ccd92 214 }
215 }
216
217 return 0;
218}
219
220void ospf6_vrf_init(void)
221{
222 vrf_init(ospf6_vrf_new, ospf6_vrf_enable, ospf6_vrf_disable,
ac2cb9bf 223 ospf6_vrf_delete);
f5eef2d5 224
cfc369c4 225 vrf_cmd_init(NULL);
4e8ccd92 226}
beadc736 227
d62a17ae 228static void ospf6_top_lsdb_hook_add(struct ospf6_lsa *lsa)
718e3744 229{
d62a17ae 230 switch (ntohs(lsa->header->type)) {
231 case OSPF6_LSTYPE_AS_EXTERNAL:
f5f26b8f 232 ospf6_asbr_lsa_add(lsa);
d62a17ae 233 break;
234
235 default:
236 break;
237 }
718e3744 238}
239
d62a17ae 240static void ospf6_top_lsdb_hook_remove(struct ospf6_lsa *lsa)
718e3744 241{
d62a17ae 242 switch (ntohs(lsa->header->type)) {
243 case OSPF6_LSTYPE_AS_EXTERNAL:
07b37f93 244 ospf6_asbr_lsa_remove(lsa, NULL);
d62a17ae 245 break;
246
247 default:
248 break;
249 }
718e3744 250}
251
e285b70d 252static void ospf6_top_route_hook_add(struct ospf6_route *route)
049207c3 253{
ad500b22
K
254 struct ospf6 *ospf6 = NULL;
255 struct ospf6_area *oa = NULL;
256
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;
261 ospf6 = oa->ospf6;
0d882ec7
DS
262 } else {
263 if (IS_OSPF6_DEBUG_EXAMIN(AS_EXTERNAL)
264 || IS_OSPF6_DEBUG_BROUTER)
265 zlog_debug(
266 "%s: Route is not GLOBAL or scope is not of TYPE_AREA: %pFX",
267 __func__, &route->prefix);
268 return;
ad500b22 269 }
e285b70d 270
beadc736 271 ospf6_abr_originate_summary(route, ospf6);
272 ospf6_zebra_route_update_add(route, ospf6);
049207c3 273}
274
e285b70d 275static void ospf6_top_route_hook_remove(struct ospf6_route *route)
049207c3 276{
ad500b22
K
277 struct ospf6 *ospf6 = NULL;
278 struct ospf6_area *oa = NULL;
279
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;
284 ospf6 = oa->ospf6;
0d882ec7
DS
285 } else {
286 if (IS_OSPF6_DEBUG_EXAMIN(AS_EXTERNAL)
287 || IS_OSPF6_DEBUG_BROUTER)
288 zlog_debug(
289 "%s: Route is not GLOBAL or scope is not of TYPE_AREA: %pFX",
290 __func__, &route->prefix);
291 return;
ad500b22 292 }
e285b70d 293
d62a17ae 294 route->flag |= OSPF6_ROUTE_REMOVE;
beadc736 295 ospf6_abr_originate_summary(route, ospf6);
296 ospf6_zebra_route_update_remove(route, ospf6);
049207c3 297}
298
e285b70d 299static void ospf6_top_brouter_hook_add(struct ospf6_route *route)
6452df09 300{
e285b70d
IR
301 struct ospf6 *ospf6 = route->table->scope;
302
99ab28cb
CS
303 if (IS_OSPF6_DEBUG_EXAMIN(AS_EXTERNAL) ||
304 IS_OSPF6_DEBUG_BROUTER) {
07b37f93
CS
305 uint32_t brouter_id;
306 char brouter_name[16];
307
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",
15569c58 312 __func__, brouter_name,
07b37f93
CS
313 route->path.origin.adv_router,
314 listcount(route->nh_list));
064d4355 315 }
beadc736 316 ospf6_abr_examin_brouter(ADV_ROUTER_IN_PREFIX(&route->prefix), route,
317 ospf6);
318 ospf6_asbr_lsentry_add(route, ospf6);
319 ospf6_abr_originate_summary(route, ospf6);
6452df09 320}
321
e285b70d 322static void ospf6_top_brouter_hook_remove(struct ospf6_route *route)
6452df09 323{
e285b70d
IR
324 struct ospf6 *ospf6 = route->table->scope;
325
99ab28cb
CS
326 if (IS_OSPF6_DEBUG_EXAMIN(AS_EXTERNAL) ||
327 IS_OSPF6_DEBUG_BROUTER) {
07b37f93
CS
328 uint32_t brouter_id;
329 char brouter_name[16];
064d4355 330
07b37f93
CS
331 brouter_id = ADV_ROUTER_IN_PREFIX(&route->prefix);
332 inet_ntop(AF_INET, &brouter_id, brouter_name,
333 sizeof(brouter_name));
99ab28cb 334 zlog_debug("%s: brouter %p %s del with adv router %x nh %u",
15569c58 335 __func__, (void *)route, brouter_name,
99ab28cb 336 route->path.origin.adv_router,
07b37f93 337 listcount(route->nh_list));
064d4355 338 }
d62a17ae 339 route->flag |= OSPF6_ROUTE_REMOVE;
beadc736 340 ospf6_abr_examin_brouter(ADV_ROUTER_IN_PREFIX(&route->prefix), route,
341 ospf6);
342 ospf6_asbr_lsentry_remove(route, ospf6);
343 ospf6_abr_originate_summary(route, ospf6);
6452df09 344}
345
7df1f362 346static struct ospf6 *ospf6_create(const char *name)
718e3744 347{
d62a17ae 348 struct ospf6 *o;
7df1f362 349 struct vrf *vrf = NULL;
718e3744 350
d62a17ae 351 o = XCALLOC(MTYPE_OSPF6_TOP, sizeof(struct ospf6));
718e3744 352
7df1f362
K
353 vrf = vrf_lookup_by_name(name);
354 if (vrf) {
355 o->vrf_id = vrf->vrf_id;
beadc736 356 } else
357 o->vrf_id = VRF_UNKNOWN;
358
359 /* Freed in ospf6_delete */
360 o->name = XSTRDUP(MTYPE_OSPF6_TOP, name);
361 if (vrf)
362 ospf6_vrf_link(o, vrf);
363
364 ospf6_zebra_vrf_register(o);
365
d62a17ae 366 /* initialize */
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;
718e3744 374
d62a17ae 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;
3810e06e 379
b19502d3 380 o->default_originate = DEFAULT_ORIGINATE_NONE;
b8212e03 381 o->redistribute = 0;
d62a17ae 382 /* LSA timers value init */
383 o->lsa_minarrival = OSPF_MIN_LS_ARRIVAL;
b6927875 384
d62a17ae 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;
718e3744 389
d62a17ae 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;
049207c3 394
d62a17ae 395 o->external_table = OSPF6_ROUTE_TABLE_CREATE(GLOBAL, EXTERNAL_ROUTES);
396 o->external_table->scope = o;
4dc43886
MR
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.
408 */
409 o->external_id = OSPF6_EXT_INIT_LS_ID;
718e3744 410
78156066 411 o->write_oi_count = OSPF6_WRITE_INTERFACE_COUNT_DEFAULT;
d62a17ae 412 o->ref_bandwidth = OSPF6_REFERENCE_BANDWIDTH;
fd500689 413
d62a17ae 414 o->distance_table = route_table_init();
4dc43886
MR
415
416 o->rt_aggr_tbl = route_table_init();
417 o->aggr_delay_interval = OSPF6_EXTL_AGGR_DEFAULT_DELAY;
4dc43886
MR
418 o->aggr_action = OSPF6_ROUTE_AGGR_NONE;
419
7df1f362 420 o->fd = -1;
baff583e 421
1958143e
MR
422 o->max_multipath = MULTIPATH_NUM;
423
4f7bf1ab
PR
424 o->oi_write_q = list_new();
425
59790f52 426 ospf6_gr_helper_init(o);
d62a17ae 427 QOBJ_REG(o, ospf6);
692c7954 428
7df1f362
K
429 /* Make ospf protocol socket. */
430 ospf6_serv_sock(o);
431
6cb85350
AR
432 /* If sequence number is stored in persistent storage, read it.
433 */
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);
438 } else {
439 o->seqnum_l = o->seqnum_h = 0;
440 ospf6_auth_seqno_nvm_update(o);
441 }
442
d62a17ae 443 return o;
718e3744 444}
445
beadc736 446struct ospf6 *ospf6_instance_create(const char *name)
7df1f362 447{
beadc736 448 struct ospf6 *ospf6;
42cabc55
IR
449 struct vrf *vrf;
450 struct interface *ifp;
beadc736 451
7df1f362
K
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)
436a55a1 456 ospf6_router_id_update(ospf6, true);
beadc736 457 ospf6_add(ospf6);
42cabc55
IR
458 if (ospf6->vrf_id != VRF_UNKNOWN) {
459 vrf = vrf_lookup_by_id(ospf6->vrf_id);
460 FOR_ALL_INTERFACES (vrf, ifp) {
461 if (ifp->info)
462 ospf6_interface_start(ifp->info);
463 }
464 }
4e8ccd92 465 if (ospf6->fd < 0)
466 return ospf6;
467
71165098
RW
468 /*
469 * Read from non-volatile memory whether this instance is performing a
470 * graceful restart or not.
471 */
472 ospf6_gr_nvm_read(ospf6);
473
907a2395
DS
474 event_add_read(master, ospf6_receive, ospf6, ospf6->fd,
475 &ospf6->t_ospf6_receive);
beadc736 476
477 return ospf6;
7df1f362
K
478}
479
d62a17ae 480void ospf6_delete(struct ospf6 *o)
718e3744 481{
d62a17ae 482 struct listnode *node, *nnode;
4dc43886 483 struct route_node *rn = NULL;
d62a17ae 484 struct ospf6_area *oa;
92699b9b 485 struct vrf *vrf;
a28474d3 486 struct ospf6_external_aggr_rt *aggr;
718e3744 487
d62a17ae 488 QOBJ_UNREG(o);
76249532 489
59790f52 490 ospf6_gr_helper_deinit(o);
71165098
RW
491 if (!o->gr_info.prepare_in_progress)
492 ospf6_flush_self_originated_lsas_now(o);
beadc736 493 ospf6_disable(o);
494 ospf6_del(o);
ae2254aa 495
4e8ccd92 496 ospf6_zebra_vrf_deregister(o);
497
d3136990
IR
498 ospf6_serv_close(&o->fd);
499
d62a17ae 500 for (ALL_LIST_ELEMENTS(o->area_list, node, nnode, oa))
501 ospf6_area_delete(oa);
d9628728
CF
502
503
6a154c88 504 list_delete(&o->area_list);
718e3744 505
d62a17ae 506 ospf6_lsdb_delete(o->lsdb);
507 ospf6_lsdb_delete(o->lsdb_self);
718e3744 508
e285b70d
IR
509 ospf6_route_table_delete(o->route_table);
510 ospf6_route_table_delete(o->brouter_table);
718e3744 511
e285b70d 512 ospf6_route_table_delete(o->external_table);
718e3744 513
d62a17ae 514 ospf6_distance_reset(o);
515 route_table_finish(o->distance_table);
4f7bf1ab 516 list_delete(&o->oi_write_q);
baff583e 517
92699b9b
IR
518 if (o->vrf_id != VRF_UNKNOWN) {
519 vrf = vrf_lookup_by_id(o->vrf_id);
520 if (vrf)
521 ospf6_vrf_unlink(o, vrf);
522 }
523
4dc43886 524 for (rn = route_top(o->rt_aggr_tbl); rn; rn = route_next(rn))
a28474d3
MN
525 if (rn->info) {
526 aggr = rn->info;
527 ospf6_asbr_summary_config_delete(o, rn);
528 ospf6_external_aggregator_free(aggr);
529 }
4dc43886
MR
530 route_table_finish(o->rt_aggr_tbl);
531
7df1f362 532 XFREE(MTYPE_OSPF6_TOP, o->name);
d62a17ae 533 XFREE(MTYPE_OSPF6_TOP, o);
508e53e2 534}
718e3744 535
d62a17ae 536static void ospf6_disable(struct ospf6 *o)
718e3744 537{
d62a17ae 538 struct listnode *node, *nnode;
539 struct ospf6_area *oa;
540
541 if (!CHECK_FLAG(o->flag, OSPF6_DISABLED)) {
542 SET_FLAG(o->flag, OSPF6_DISABLED);
543
544 for (ALL_LIST_ELEMENTS(o->area_list, node, nnode, oa))
545 ospf6_area_disable(oa);
546
547 /* XXX: This also changes persistent settings */
a069482f 548 /* Unregister redistribution */
f71ed6df 549 ospf6_asbr_redistribute_disable(o);
d62a17ae 550
551 ospf6_lsdb_remove_all(o->lsdb);
e285b70d
IR
552 ospf6_route_remove_all(o->route_table);
553 ospf6_route_remove_all(o->brouter_table);
d62a17ae 554
555 THREAD_OFF(o->maxage_remover);
556 THREAD_OFF(o->t_spf_calc);
557 THREAD_OFF(o->t_ase_calc);
856ae1eb 558 THREAD_OFF(o->t_distribute_update);
7df1f362 559 THREAD_OFF(o->t_ospf6_receive);
4dc43886 560 THREAD_OFF(o->t_external_aggr);
71165098 561 THREAD_OFF(o->gr_info.t_grace_period);
a8f692ed
DS
562 THREAD_OFF(o->t_write);
563 THREAD_OFF(o->t_abr_task);
d62a17ae 564 }
508e53e2 565}
718e3744 566
beadc736 567void ospf6_master_init(struct thread_master *master)
78c6ba61 568{
6006b807 569 memset(&ospf6_master, 0, sizeof(ospf6_master));
78c6ba61
CS
570
571 om6 = &ospf6_master;
beadc736 572 om6->ospf6 = list_new();
573 om6->master = master;
78c6ba61
CS
574}
575
e6685141 576static void ospf6_maxage_remover(struct event *thread)
508e53e2 577{
d62a17ae 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;
583 int reschedule = 0;
584
d62a17ae 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)
590 continue;
591
592 ospf6_maxage_remove(o);
cc9f21da 593 return;
d62a17ae 594 }
595 }
2449fcd6 596 }
d62a17ae 597
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)) {
601 reschedule = 1;
602 }
603 }
604
605 if (ospf6_lsdb_maxage_remover(oa->lsdb)) {
606 reschedule = 1;
607 }
2449fcd6 608 }
2449fcd6 609
d62a17ae 610 if (ospf6_lsdb_maxage_remover(o->lsdb)) {
611 reschedule = 1;
612 }
2449fcd6 613
d62a17ae 614 if (reschedule) {
615 ospf6_maxage_remove(o);
616 }
718e3744 617}
618
d62a17ae 619void ospf6_maxage_remove(struct ospf6 *o)
718e3744 620{
d62a17ae 621 if (o)
907a2395
DS
622 event_add_timer(master, ospf6_maxage_remover, o,
623 OSPF_LSA_MAXAGE_REMOVE_DELAY_DEFAULT,
624 &o->maxage_remover);
718e3744 625}
626
a3049476 627bool ospf6_router_id_update(struct ospf6 *ospf6, bool init)
78c6ba61 628{
436a55a1
LS
629 in_addr_t new_router_id;
630 struct listnode *node;
631 struct ospf6_area *oa;
632
78c6ba61 633 if (!ospf6)
a3049476 634 return true;
78c6ba61
CS
635
636 if (ospf6->router_id_static != 0)
436a55a1 637 new_router_id = ospf6->router_id_static;
78c6ba61 638 else
436a55a1
LS
639 new_router_id = ospf6->router_id_zebra;
640
641 if (ospf6->router_id == new_router_id)
a3049476 642 return true;
436a55a1
LS
643
644 if (!init)
645 for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, node, oa)) {
646 if (oa->full_nbrs) {
647 zlog_err(
e2874251 648 "%s: cannot update router-id. Run the \"clear ipv6 ospf6 process\" command",
436a55a1 649 __func__);
a3049476 650 return false;
436a55a1
LS
651 }
652 }
653
654 ospf6->router_id = new_router_id;
a3049476 655 return true;
78c6ba61
CS
656}
657
508e53e2 658/* start ospf6 */
d48ef099 659DEFUN_NOSH(router_ospf6, router_ospf6_cmd, "router ospf6 [vrf NAME]",
660 ROUTER_STR OSPF6_STR VRF_CMD_HELP_STR)
718e3744 661{
beadc736 662 struct ospf6 *ospf6;
d48ef099 663 const char *vrf_name = VRF_DEFAULT_NAME;
664 int idx_vrf = 0;
beadc736 665
d48ef099 666 if (argv_find(argv, argc, "vrf", &idx_vrf)) {
667 vrf_name = argv[idx_vrf + 1]->arg;
668 }
669
670 ospf6 = ospf6_lookup_by_vrf_name(vrf_name);
7df1f362 671 if (ospf6 == NULL)
d48ef099 672 ospf6 = ospf6_instance_create(vrf_name);
7df1f362 673
d62a17ae 674 /* set current ospf point. */
675 VTY_PUSH_CONTEXT(OSPF6_NODE, ospf6);
508e53e2 676
d62a17ae 677 return CMD_SUCCESS;
718e3744 678}
679
508e53e2 680/* stop ospf6 */
d48ef099 681DEFUN(no_router_ospf6, no_router_ospf6_cmd, "no router ospf6 [vrf NAME]",
682 NO_STR ROUTER_STR OSPF6_STR VRF_CMD_HELP_STR)
718e3744 683{
beadc736 684 struct ospf6 *ospf6;
d48ef099 685 const char *vrf_name = VRF_DEFAULT_NAME;
686 int idx_vrf = 0;
beadc736 687
d48ef099 688 if (argv_find(argv, argc, "vrf", &idx_vrf)) {
689 vrf_name = argv[idx_vrf + 1]->arg;
690 }
691
692 ospf6 = ospf6_lookup_by_vrf_name(vrf_name);
d62a17ae 693 if (ospf6 == NULL)
694 vty_out(vty, "OSPFv3 is not configured\n");
695 else {
696 ospf6_delete(ospf6);
697 ospf6 = NULL;
698 }
34288970 699
d62a17ae 700 /* return to config node . */
701 VTY_PUSH_CONTEXT_NULL(CONFIG_NODE);
508e53e2 702
d62a17ae 703 return CMD_SUCCESS;
718e3744 704}
705
f71ed6df
YR
706static void ospf6_db_clear(struct ospf6 *ospf6)
707{
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;
713
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);
721 }
722 }
723
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);
727
728 ospf6_spf_table_finish(oa->spf_table);
729 ospf6_route_remove_all(oa->route_table);
730 }
731
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);
736}
737
738static void ospf6_process_reset(struct ospf6 *ospf6)
739{
740 struct interface *ifp;
741 struct vrf *vrf = vrf_lookup_by_id(ospf6->vrf_id);
742
c3a70f65 743 ospf6_unset_all_aggr_flag(ospf6);
f71ed6df
YR
744 ospf6_flush_self_originated_lsas_now(ospf6);
745 ospf6->inst_shutdown = 0;
746 ospf6_db_clear(ospf6);
747
f71ed6df
YR
748 ospf6_asbr_redistribute_reset(ospf6);
749 FOR_ALL_INTERFACES (vrf, ifp)
750 ospf6_interface_clear(ifp);
751}
752
753DEFPY (clear_router_ospf6,
754 clear_router_ospf6_cmd,
755 "clear ipv6 ospf6 process [vrf NAME$name]",
756 CLEAR_STR
757 IP6_STR
758 OSPF6_STR
759 "Reset OSPF Process\n"
760 VRF_CMD_HELP_STR)
761{
762 struct ospf6 *ospf6;
763 const char *vrf_name = VRF_DEFAULT_NAME;
764
765 if (name != NULL)
766 vrf_name = name;
767
768 ospf6 = ospf6_lookup_by_vrf_name(vrf_name);
078f6092 769 if (ospf6 == NULL) {
f71ed6df 770 vty_out(vty, "OSPFv3 is not configured\n");
078f6092
LS
771 } else {
772 ospf6_router_id_update(ospf6, true);
f71ed6df 773 ospf6_process_reset(ospf6);
078f6092 774 }
f71ed6df
YR
775
776 return CMD_SUCCESS;
777}
778
508e53e2 779/* change Router_ID commands. */
60466a63
QY
780DEFUN(ospf6_router_id,
781 ospf6_router_id_cmd,
782 "ospf6 router-id A.B.C.D",
783 OSPF6_STR
784 "Configure OSPF6 Router-ID\n"
785 V4NOTATION_STR)
718e3744 786{
d62a17ae 787 VTY_DECLVAR_CONTEXT(ospf6, o);
5d1a2ee8 788 int idx = 0;
d62a17ae 789 int ret;
5d1a2ee8 790 const char *router_id_str;
d7c0a89a 791 uint32_t router_id;
d62a17ae 792
5d1a2ee8
QY
793 argv_find(argv, argc, "A.B.C.D", &idx);
794 router_id_str = argv[idx]->arg;
795
796 ret = inet_pton(AF_INET, router_id_str, &router_id);
d62a17ae 797 if (ret == 0) {
60466a63 798 vty_out(vty, "malformed OSPF Router-ID: %s\n", router_id_str);
d62a17ae 799 return CMD_SUCCESS;
800 }
508e53e2 801
d62a17ae 802 o->router_id_static = router_id;
d6927cf3 803
078f6092
LS
804 if (ospf6_router_id_update(o, false))
805 ospf6_process_reset(o);
806 else
a3049476
LS
807 vty_out(vty,
808 "For this router-id change to take effect run the \"clear ipv6 ospf6 process\" command\n");
c8a440ec 809
d62a17ae 810 return CMD_SUCCESS;
718e3744 811}
812
60466a63
QY
813DEFUN(no_ospf6_router_id,
814 no_ospf6_router_id_cmd,
815 "no ospf6 router-id [A.B.C.D]",
816 NO_STR OSPF6_STR
817 "Configure OSPF6 Router-ID\n"
818 V4NOTATION_STR)
5d1a2ee8
QY
819{
820 VTY_DECLVAR_CONTEXT(ospf6, o);
d6927cf3 821
5d1a2ee8 822 o->router_id_static = 0;
d6927cf3 823
078f6092
LS
824
825 if (ospf6_router_id_update(o, false))
826 ospf6_process_reset(o);
827 else
a3049476
LS
828 vty_out(vty,
829 "For this router-id change to take effect run the \"clear ipv6 ospf6 process\" command\n");
5d1a2ee8
QY
830
831 return CMD_SUCCESS;
832}
833
3d35ca48
DD
834DEFUN (ospf6_log_adjacency_changes,
835 ospf6_log_adjacency_changes_cmd,
836 "log-adjacency-changes",
837 "Log changes in adjacency state\n")
838{
d62a17ae 839 VTY_DECLVAR_CONTEXT(ospf6, ospf6);
3d35ca48 840
d62a17ae 841 SET_FLAG(ospf6->config_flags, OSPF6_LOG_ADJACENCY_CHANGES);
842 UNSET_FLAG(ospf6->config_flags, OSPF6_LOG_ADJACENCY_DETAIL);
843 return CMD_SUCCESS;
3d35ca48
DD
844}
845
846DEFUN (ospf6_log_adjacency_changes_detail,
847 ospf6_log_adjacency_changes_detail_cmd,
848 "log-adjacency-changes detail",
692c7954 849 "Log changes in adjacency state\n"
3d35ca48
DD
850 "Log all state changes\n")
851{
d62a17ae 852 VTY_DECLVAR_CONTEXT(ospf6, ospf6);
3d35ca48 853
d62a17ae 854 SET_FLAG(ospf6->config_flags, OSPF6_LOG_ADJACENCY_CHANGES);
855 SET_FLAG(ospf6->config_flags, OSPF6_LOG_ADJACENCY_DETAIL);
856 return CMD_SUCCESS;
3d35ca48
DD
857}
858
859DEFUN (no_ospf6_log_adjacency_changes,
860 no_ospf6_log_adjacency_changes_cmd,
861 "no log-adjacency-changes",
692c7954 862 NO_STR
3d35ca48
DD
863 "Log changes in adjacency state\n")
864{
d62a17ae 865 VTY_DECLVAR_CONTEXT(ospf6, ospf6);
3d35ca48 866
d62a17ae 867 UNSET_FLAG(ospf6->config_flags, OSPF6_LOG_ADJACENCY_DETAIL);
868 UNSET_FLAG(ospf6->config_flags, OSPF6_LOG_ADJACENCY_CHANGES);
869 return CMD_SUCCESS;
3d35ca48
DD
870}
871
872DEFUN (no_ospf6_log_adjacency_changes_detail,
873 no_ospf6_log_adjacency_changes_detail_cmd,
874 "no log-adjacency-changes detail",
692c7954
DW
875 NO_STR
876 "Log changes in adjacency state\n"
3d35ca48
DD
877 "Log all state changes\n")
878{
d62a17ae 879 VTY_DECLVAR_CONTEXT(ospf6, ospf6);
3d35ca48 880
d62a17ae 881 UNSET_FLAG(ospf6->config_flags, OSPF6_LOG_ADJACENCY_DETAIL);
882 return CMD_SUCCESS;
3d35ca48
DD
883}
884
5b5d66c4
RW
885static void ospf6_reinstall_routes(struct ospf6 *ospf6)
886{
887 struct ospf6_route *route;
888
889 for (route = ospf6_route_head(ospf6->route_table); route;
890 route = ospf6_route_next(route))
891 ospf6_zebra_route_update_add(route, ospf6);
892}
893
894DEFPY (ospf6_send_extra_data,
895 ospf6_send_extra_data_cmd,
896 "[no] ospf6 send-extra-data zebra",
897 NO_STR
898 OSPF6_STR
899 "Extra data to Zebra for display/use\n"
900 "To zebra\n")
901{
902 VTY_DECLVAR_CONTEXT(ospf6, ospf6);
903
904 if (no
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);
913 }
914
915 return CMD_SUCCESS;
916}
917
b6927875
DS
918DEFUN (ospf6_timers_lsa,
919 ospf6_timers_lsa_cmd,
6147e2c6 920 "timers lsa min-arrival (0-600000)",
b6927875
DS
921 "Adjust routing timers\n"
922 "OSPF6 LSA timers\n"
923 "Minimum delay in receiving new version of a LSA\n"
924 "Delay in milliseconds\n")
925{
d62a17ae 926 VTY_DECLVAR_CONTEXT(ospf6, ospf);
927 int idx_number = 3;
928 unsigned int minarrival;
b6927875 929
d62a17ae 930 minarrival = strtoul(argv[idx_number]->arg, NULL, 10);
931 ospf->lsa_minarrival = minarrival;
b6927875 932
d62a17ae 933 return CMD_SUCCESS;
b6927875
DS
934}
935
936DEFUN (no_ospf6_timers_lsa,
937 no_ospf6_timers_lsa_cmd,
1d68dbfe 938 "no timers lsa min-arrival [(0-600000)]",
b6927875
DS
939 NO_STR
940 "Adjust routing timers\n"
941 "OSPF6 LSA timers\n"
3a2d747c
QY
942 "Minimum delay in receiving new version of a LSA\n"
943 "Delay in milliseconds\n")
b6927875 944{
d62a17ae 945 VTY_DECLVAR_CONTEXT(ospf6, ospf);
946 int idx_number = 4;
947 unsigned int minarrival;
b6927875 948
d62a17ae 949 if (argc == 5) {
950 minarrival = strtoul(argv[idx_number]->arg, NULL, 10);
b6927875 951
d62a17ae 952 if (ospf->lsa_minarrival != minarrival
953 || minarrival == OSPF_MIN_LS_ARRIVAL)
954 return CMD_SUCCESS;
955 }
b6927875 956
d62a17ae 957 ospf->lsa_minarrival = OSPF_MIN_LS_ARRIVAL;
b6927875 958
d62a17ae 959 return CMD_SUCCESS;
b6927875
DS
960}
961
b6927875 962
baff583e
MZ
963DEFUN (ospf6_distance,
964 ospf6_distance_cmd,
39e92c06 965 "distance (1-255)",
baff583e
MZ
966 "Administrative distance\n"
967 "OSPF6 Administrative distance\n")
968{
d62a17ae 969 VTY_DECLVAR_CONTEXT(ospf6, o);
fcd45026 970 uint8_t distance;
baff583e 971
fcd45026 972 distance = atoi(argv[1]->arg);
973 if (o->distance_all != distance) {
974 o->distance_all = distance;
975 ospf6_restart_spf(o);
976 }
baff583e 977
d62a17ae 978 return CMD_SUCCESS;
baff583e
MZ
979}
980
981DEFUN (no_ospf6_distance,
982 no_ospf6_distance_cmd,
39e92c06 983 "no distance (1-255)",
baff583e
MZ
984 NO_STR
985 "Administrative distance\n"
986 "OSPF6 Administrative distance\n")
987{
d62a17ae 988 VTY_DECLVAR_CONTEXT(ospf6, o);
baff583e 989
fcd45026 990 if (o->distance_all) {
991 o->distance_all = 0;
992 ospf6_restart_spf(o);
993 }
d62a17ae 994 return CMD_SUCCESS;
baff583e
MZ
995}
996
997DEFUN (ospf6_distance_ospf6,
998 ospf6_distance_ospf6_cmd,
eaa1ae0d 999 "distance ospf6 {intra-area (1-255)|inter-area (1-255)|external (1-255)}",
baff583e 1000 "Administrative distance\n"
eaa1ae0d 1001 "OSPF6 administrative distance\n"
39e92c06
QY
1002 "Intra-area routes\n"
1003 "Distance for intra-area routes\n"
1004 "Inter-area routes\n"
1005 "Distance for inter-area routes\n"
1006 "External routes\n"
baff583e
MZ
1007 "Distance for external routes\n")
1008{
d62a17ae 1009 VTY_DECLVAR_CONTEXT(ospf6, o);
1010 int idx = 0;
1011
f89a449b
CS
1012 o->distance_intra = 0;
1013 o->distance_inter = 0;
1014 o->distance_external = 0;
1015
d62a17ae 1016 if (argv_find(argv, argc, "intra-area", &idx))
1017 o->distance_intra = atoi(argv[idx + 1]->arg);
1018 idx = 0;
1019 if (argv_find(argv, argc, "inter-area", &idx))
1020 o->distance_inter = atoi(argv[idx + 1]->arg);
1021 idx = 0;
1022 if (argv_find(argv, argc, "external", &idx))
1023 o->distance_external = atoi(argv[idx + 1]->arg);
39e92c06 1024
d62a17ae 1025 return CMD_SUCCESS;
baff583e
MZ
1026}
1027
1028DEFUN (no_ospf6_distance_ospf6,
1029 no_ospf6_distance_ospf6_cmd,
eaa1ae0d 1030 "no distance ospf6 [{intra-area [(1-255)]|inter-area [(1-255)]|external [(1-255)]}]",
baff583e
MZ
1031 NO_STR
1032 "Administrative distance\n"
1033 "OSPF6 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"
1038 "External routes\n"
1039 "Distance for external routes\n")
1040{
d62a17ae 1041 VTY_DECLVAR_CONTEXT(ospf6, o);
1042 int idx = 0;
baff583e 1043
d62a17ae 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;
baff583e 1050
d62a17ae 1051 return CMD_SUCCESS;
baff583e
MZ
1052}
1053
42cabc55 1054DEFUN_HIDDEN (ospf6_interface_area,
508e53e2 1055 ospf6_interface_area_cmd,
de842255 1056 "interface IFNAME area <A.B.C.D|(0-4294967295)>",
508e53e2 1057 "Enable routing on an IPv6 interface\n"
1058 IFNAME_STR
1059 "Specify the OSPF6 area ID\n"
1060 "OSPF6 area ID in IPv4 address notation\n"
de842255 1061 "OSPF6 area ID in decimal notation\n"
508e53e2 1062 )
718e3744 1063{
d48ef099 1064 VTY_DECLVAR_CONTEXT(ospf6, ospf6);
d62a17ae 1065 int idx_ifname = 1;
1066 int idx_ipv4 = 3;
1067 struct ospf6_area *oa;
1068 struct ospf6_interface *oi;
1069 struct interface *ifp;
42cabc55
IR
1070 uint32_t area_id;
1071 int format;
1072
1073 vty_out(vty,
1074 "This command is deprecated, because it is not VRF-aware.\n");
1075 vty_out(vty,
1076 "Please, use \"ipv6 ospf6 area\" on an interface instead.\n");
d62a17ae 1077
1078 /* find/create ospf6 interface */
f60a1188 1079 ifp = if_get_by_name(argv[idx_ifname]->arg, ospf6->vrf_id, ospf6->name);
d62a17ae 1080 oi = (struct ospf6_interface *)ifp->info;
1081 if (oi == NULL)
1082 oi = ospf6_interface_create(ifp);
1083 if (oi->area) {
1084 vty_out(vty, "%s already attached to Area %s\n",
1085 oi->interface->name, oi->area->name);
1086 return CMD_SUCCESS;
1087 }
6452df09 1088
42cabc55
IR
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;
1092 }
1093
1094 oi->area_id = area_id;
1095 oi->area_id_format = format;
1096
1097 oa = ospf6_area_lookup(area_id, ospf6);
1098 if (oa == NULL)
1099 oa = ospf6_area_create(area_id, ospf6, format);
d62a17ae 1100
1101 /* attach interface to area */
1102 listnode_add(oa->if_list, oi); /* sort ?? */
1103 oi->area = oa;
1104
1105 SET_FLAG(oa->flag, OSPF6_AREA_ENABLE);
1106
1107 /* ospf6 process is currently disabled, not much more to do */
beadc736 1108 if (CHECK_FLAG(ospf6->flag, OSPF6_DISABLED))
d62a17ae 1109 return CMD_SUCCESS;
1110
1111 /* start up */
1112 ospf6_interface_enable(oi);
1113
1114 /* If the router is ABR, originate summary routes */
95b3f03d 1115 if (ospf6_check_and_set_router_abr(ospf6)) {
d62a17ae 1116 ospf6_abr_enable_area(oa);
ad500b22
K
1117 ospf6_schedule_abr_task(oa->ospf6);
1118 }
d62a17ae 1119
1120 return CMD_SUCCESS;
718e3744 1121}
1122
42cabc55 1123DEFUN_HIDDEN (no_ospf6_interface_area,
508e53e2 1124 no_ospf6_interface_area_cmd,
de842255 1125 "no interface IFNAME area <A.B.C.D|(0-4294967295)>",
508e53e2 1126 NO_STR
1127 "Disable routing on an IPv6 interface\n"
1128 IFNAME_STR
1129 "Specify the OSPF6 area ID\n"
1130 "OSPF6 area ID in IPv4 address notation\n"
de842255 1131 "OSPF6 area ID in decimal notation\n"
508e53e2 1132 )
718e3744 1133{
d48ef099 1134 VTY_DECLVAR_CONTEXT(ospf6, ospf6);
d62a17ae 1135 int idx_ifname = 2;
1136 int idx_ipv4 = 4;
1137 struct ospf6_interface *oi;
1138 struct ospf6_area *oa;
1139 struct interface *ifp;
d7c0a89a 1140 uint32_t area_id;
d48ef099 1141
42cabc55
IR
1142 vty_out(vty,
1143 "This command is deprecated, because it is not VRF-aware.\n");
1144 vty_out(vty,
1145 "Please, use \"no ipv6 ospf6 area\" on an interface instead.\n");
1146
d48ef099 1147 /* find/create ospf6 interface */
f60a1188 1148 ifp = if_get_by_name(argv[idx_ifname]->arg, ospf6->vrf_id, ospf6->name);
d62a17ae 1149
d62a17ae 1150 if (ifp == NULL) {
1151 vty_out(vty, "No such interface %s\n", argv[idx_ifname]->arg);
1152 return CMD_SUCCESS;
1153 }
6452df09 1154
d62a17ae 1155 oi = (struct ospf6_interface *)ifp->info;
1156 if (oi == NULL) {
1157 vty_out(vty, "Interface %s not enabled\n", ifp->name);
1158 return CMD_SUCCESS;
1159 }
1160
1161 /* parse Area-ID */
de842255
PR
1162 if (inet_pton(AF_INET, argv[idx_ipv4]->arg, &area_id) != 1)
1163 area_id = htonl(strtoul(argv[idx_ipv4]->arg, NULL, 10));
d62a17ae 1164
1165 /* Verify Area */
1166 if (oi->area == NULL) {
800cc918 1167 vty_out(vty, "%s not attached to area %s\n",
f85a4112 1168 oi->interface->name, argv[idx_ipv4]->arg);
d62a17ae 1169 return CMD_SUCCESS;
1170 }
1171
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);
1175 return CMD_SUCCESS;
1176 }
1177
4a30f056 1178 ospf6_interface_disable(oi);
d62a17ae 1179
1180 oa = oi->area;
1181 listnode_delete(oi->area->if_list, oi);
1182 oi->area = (struct ospf6_area *)NULL;
1183
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);
1188 }
1189
42cabc55
IR
1190 oi->area_id = 0;
1191 oi->area_id_format = OSPF6_AREA_FMT_UNSET;
1192
d62a17ae 1193 return CMD_SUCCESS;
718e3744 1194}
1195
f41b4a02
DD
1196DEFUN (ospf6_stub_router_admin,
1197 ospf6_stub_router_admin_cmd,
1198 "stub-router administrative",
1199 "Make router a stub router\n"
f41b4a02
DD
1200 "Administratively applied, for an indefinite period\n")
1201{
d62a17ae 1202 struct listnode *node;
1203 struct ospf6_area *oa;
1204
beadc736 1205 VTY_DECLVAR_CONTEXT(ospf6, ospf6);
1206
d62a17ae 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);
1212 }
1213 SET_FLAG(ospf6->flag, OSPF6_STUB_ROUTER);
f41b4a02 1214 }
f41b4a02 1215
d62a17ae 1216 return CMD_SUCCESS;
f41b4a02
DD
1217}
1218
1219DEFUN (no_ospf6_stub_router_admin,
1220 no_ospf6_stub_router_admin_cmd,
1221 "no stub-router administrative",
1222 NO_STR
1223 "Make router a stub router\n"
f41b4a02
DD
1224 "Administratively applied, for an indefinite period\n")
1225{
d62a17ae 1226 struct listnode *node;
1227 struct ospf6_area *oa;
1228
beadc736 1229 VTY_DECLVAR_CONTEXT(ospf6, ospf6);
d62a17ae 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);
1235 }
1236 UNSET_FLAG(ospf6->flag, OSPF6_STUB_ROUTER);
f41b4a02 1237 }
f41b4a02 1238
d62a17ae 1239 return CMD_SUCCESS;
f41b4a02
DD
1240}
1241
1958143e 1242/* Restart OSPF SPF algorithm*/
fcd45026 1243void ospf6_restart_spf(struct ospf6 *ospf6)
1958143e
MR
1244{
1245 ospf6_route_remove_all(ospf6->route_table);
1246 ospf6_route_remove_all(ospf6->brouter_table);
1958143e
MR
1247
1248 /* Trigger SPF */
1249 ospf6_spf_schedule(ospf6, OSPF6_SPF_FLAGS_CONFIG_CHANGE);
1250}
1251
1252/* Set the max paths */
1253static void ospf6_maxpath_set(struct ospf6 *ospf6, uint16_t paths)
1254{
1255 if (ospf6->max_multipath == paths)
1256 return;
1257
1258 ospf6->max_multipath = paths;
1259
1260 /* Send deletion to zebra to delete all
1261 * ospf specific routes and reinitiate
1262 * SPF to reflect the new max multipath.
1263 */
1264 ospf6_restart_spf(ospf6);
1265}
1266
1267/* Ospf Maximum-paths config support */
1268DEFUN(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")
1273{
1274 VTY_DECLVAR_CONTEXT(ospf6, ospf6);
1275 int idx_number = 1;
1276 int maximum_paths = strtol(argv[idx_number]->arg, NULL, 10);
1277
1278 ospf6_maxpath_set(ospf6, maximum_paths);
1279
1280 return CMD_SUCCESS;
1281}
1282
1283DEFUN(no_ospf6_max_multipath,
1284 no_ospf6_max_multipath_cmd,
1285 "no maximum-paths [" CMD_RANGE_STR(1, MULTIPATH_NUM)"]",
1286 NO_STR
1287 "Max no of multiple paths for ECMP support\n"
1288 "Number of paths\n")
1289{
1290 VTY_DECLVAR_CONTEXT(ospf6, ospf6);
1291
1292 ospf6_maxpath_set(ospf6, MULTIPATH_NUM);
1293
1294 return CMD_SUCCESS;
1295}
1296
35a45dea 1297static void ospf6_show(struct vty *vty, struct ospf6 *o, json_object *json,
1298 bool use_json)
718e3744 1299{
d62a17ae 1300 struct listnode *n;
1301 struct ospf6_area *oa;
1302 char router_id[16], duration[32];
1303 struct timeval now, running, result;
1304 char buf[32], rbuf[32];
35a45dea 1305 json_object *json_areas = NULL;
1306 const char *adjacency;
1307
1308 if (use_json) {
1309 json_areas = json_object_new_object();
1310
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);
1314
1315 /* running time */
1316 monotime(&now);
1317 timersub(&now, &o->starttime, &running);
1318 timerstring(&running, duration, sizeof(duration));
1319 json_object_string_add(json, "running", duration);
1320
1321 /* Redistribute configuration */
1322 /* XXX */
1323 json_object_int_add(json, "lsaMinimumArrivalMsecs",
1324 o->lsa_minarrival);
1325
1326 /* Show SPF parameters */
1327 json_object_int_add(json, "spfScheduleDelayMsecs",
1328 o->spf_delay);
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);
1334
1958143e 1335 json_object_int_add(json, "maximumPaths", o->max_multipath);
94c78d3b 1336 json_object_int_add(json, "preference",
1337 o->distance_all
1338 ? o->distance_all
1339 : ZEBRA_OSPF6_DISTANCE_DEFAULT);
35a45dea 1340
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,
1345 sizeof(rbuf));
1346 json_object_boolean_true_add(json, "spfHasRun");
1347 json_object_string_add(json, "spfLastExecutedMsecs",
1348 buf);
1349 json_object_string_add(json, "spfLastExecutedReason",
1350 rbuf);
1351
1352 json_object_int_add(
1353 json, "spfLastDurationSecs",
1354 (long long)o->ts_spf_duration.tv_sec);
1355
1356 json_object_int_add(
1357 json, "spfLastDurationMsecs",
1358 (long long)o->ts_spf_duration.tv_usec);
1359 } else
1360 json_object_boolean_false_add(json, "spfHasRun");
1361
c905f04c 1362 if (thread_is_scheduled(o->t_spf_calc)) {
35a45dea 1363 long time_store;
1364
1365 json_object_boolean_true_add(json, "spfTimerActive");
1366 time_store =
1367 monotime_until(&o->t_spf_calc->u.sands, NULL)
1368 / 1000LL;
1369 json_object_int_add(json, "spfTimerDueInMsecs",
1370 time_store);
1371 } else
1372 json_object_boolean_false_add(json, "spfTimerActive");
1373
1374 json_object_boolean_add(json, "routerIsStubRouter",
1375 CHECK_FLAG(o->flag, OSPF6_STUB_ROUTER));
1376
1377 /* LSAs */
1378 json_object_int_add(json, "numberOfAsScopedLsa",
1379 o->lsdb->count);
1380 /* Areas */
1381 json_object_int_add(json, "numberOfAreaInRouter",
1382 listcount(o->area_list));
1383
6cb85350
AR
1384 json_object_int_add(json, "AuthTrailerHigherSeqNo",
1385 o->seqnum_h);
1386 json_object_int_add(json, "AuthTrailerLowerSeqNo", o->seqnum_l);
1387
35a45dea 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";
1392 else
1393 adjacency = "Logged";
1394 } else
1395 adjacency = "NotLogged";
1396 json_object_string_add(json, "adjacencyChanges", adjacency);
1397
1398 for (ALL_LIST_ELEMENTS_RO(o->area_list, n, oa))
1399 ospf6_area_show(vty, oa, json_areas, use_json);
1400
1401 json_object_object_add(json, "areas", json_areas);
1402
1403 vty_out(vty, "%s\n",
1404 json_object_to_json_string_ext(
1405 json, JSON_C_TO_STRING_PRETTY));
1406
1407 } else {
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",
1411 router_id);
1412
1413 /* running time */
1414 monotime(&now);
1415 timersub(&now, &o->starttime, &running);
1416 timerstring(&running, duration, sizeof(duration));
1417 vty_out(vty, " Running %s\n", duration);
1418
1419 /* Redistribute configuration */
1420 /* XXX */
1421 vty_out(vty, " LSA minimum arrival %d msecs\n",
1422 o->lsa_minarrival);
1423
1958143e 1424 vty_out(vty, " Maximum-paths %u\n", o->max_multipath);
94c78d3b 1425 vty_out(vty, " Administrative distance %u\n",
1426 o->distance_all ? o->distance_all
1427 : ZEBRA_OSPF6_DISTANCE_DEFAULT);
35a45dea 1428
1429 /* Show SPF parameters */
1430 vty_out(vty,
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);
1437
1438
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,
1444 sizeof(rbuf));
1445 vty_out(vty, "last executed %s ago, reason %s\n", buf,
1446 rbuf);
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);
1450 } else
1451 vty_out(vty, "has not been run\n");
1452
1453 threadtimer_string(now, o->t_spf_calc, buf, sizeof(buf));
1454 vty_out(vty, " SPF timer %s%s\n",
c905f04c
DS
1455 (thread_is_scheduled(o->t_spf_calc) ? "due in "
1456 : "is "),
1457 buf);
35a45dea 1458
1459 if (CHECK_FLAG(o->flag, OSPF6_STUB_ROUTER))
1460 vty_out(vty, " Router Is Stub Router\n");
1461
1462 /* LSAs */
1463 vty_out(vty, " Number of AS scoped LSAs is %u\n",
1464 o->lsdb->count);
1465
1466 /* Areas */
1467 vty_out(vty, " Number of areas in this router is %u\n",
1468 listcount(o->area_list));
1469
6cb85350
AR
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);
1473
35a45dea 1474 if (CHECK_FLAG(o->config_flags, OSPF6_LOG_ADJACENCY_CHANGES)) {
1475 if (CHECK_FLAG(o->config_flags,
1476 OSPF6_LOG_ADJACENCY_DETAIL))
1477 vty_out(vty,
1478 " All adjacency changes are logged\n");
1479 else
1480 vty_out(vty, " Adjacency changes are logged\n");
1481 }
d62a17ae 1482
d62a17ae 1483
35a45dea 1484 vty_out(vty, "\n");
d62a17ae 1485
35a45dea 1486 for (ALL_LIST_ELEMENTS_RO(o->area_list, n, oa))
1487 ospf6_area_show(vty, oa, json_areas, use_json);
1488 }
718e3744 1489}
1490
dd7fb1db
PG
1491DEFUN(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)
1494{
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;
1500 int count = 0;
1501 char buf[PREFIX_STRLEN];
1502 static const char header[] =
1503 "Name Id RouterId ";
1504
1505 if (uj) {
1506 json = json_object_new_object();
1507 json_vrfs = json_object_new_object();
1508 }
1509
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;
1515
1516 router_id.s_addr = ospf6->router_id;
1517 count++;
1518
1519 if (!uj && count == 1)
1520 vty_out(vty, "%s\n", header);
1521 if (uj)
1522 json_vrf = json_object_new_object();
1523
1524 if (ospf6->vrf_id == VRF_DEFAULT)
1525 name = VRF_DEFAULT_NAME;
1526 else
1527 name = ospf6->name;
1528
1529 vrf_id_ui = (ospf6->vrf_id == VRF_UNKNOWN)
1530 ? -1
1531 : (int64_t)ospf6->vrf_id;
1532
1533 if (uj) {
1534 json_object_int_add(json_vrf, "vrfId", vrf_id_ui);
ce4b236f
DA
1535 json_object_string_addf(json_vrf, "routerId", "%pI4",
1536 &router_id);
dd7fb1db
PG
1537 json_object_object_add(json_vrfs, name, json_vrf);
1538
1539 } else {
1540 vty_out(vty, "%-25s %-5d %-16s \n", name,
1541 ospf6->vrf_id,
1542 inet_ntop(AF_INET, &router_id, buf,
1543 sizeof(buf)));
1544 }
1545 }
1546
1547 if (uj) {
1548 json_object_object_add(json, "vrfs", json_vrfs);
1549 json_object_int_add(json, "totalVrfs", count);
1550
5a6c232b 1551 vty_json(vty, json);
dd7fb1db
PG
1552 } else {
1553 if (count)
1554 vty_out(vty, "\nTotal number of OSPF VRFs: %d\n",
1555 count);
1556 }
1557
1558 return CMD_SUCCESS;
1559}
1560
508e53e2 1561/* show top level structures */
d48ef099 1562DEFUN(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)
718e3744 1565{
beadc736 1566 struct ospf6 *ospf6;
d48ef099 1567 struct listnode *node;
1568 const char *vrf_name = NULL;
1569 bool all_vrf = false;
1570 int idx_vrf = 0;
1571
35a45dea 1572 bool uj = use_json(argc, argv);
1573 json_object *json = NULL;
508e53e2 1574
d48ef099 1575 OSPF6_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
35a45dea 1576
d48ef099 1577 for (ALL_LIST_ELEMENTS_RO(om6->ospf6, node, ospf6)) {
1578 if (all_vrf || strcmp(ospf6->name, vrf_name) == 0) {
1579 if (uj)
1580 json = json_object_new_object();
1581 ospf6_show(vty, ospf6, json, uj);
35a45dea 1582
d48ef099 1583 if (!all_vrf)
1584 break;
1585 }
1586 }
35a45dea 1587
1588 if (uj)
1589 json_object_free(json);
d48ef099 1590
d6b901ac 1591 OSPF6_CMD_CHECK_VRF(uj, all_vrf, ospf6);
1592
d62a17ae 1593 return CMD_SUCCESS;
718e3744 1594}
1595
d48ef099 1596DEFUN(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)
718e3744 1608{
beadc736 1609 struct ospf6 *ospf6;
d48ef099 1610 struct listnode *node;
1611 const char *vrf_name = NULL;
1612 bool all_vrf = false;
1613 int idx_vrf = 0;
1614 int idx_arg_start = 4;
eacd0828 1615 bool uj = use_json(argc, argv);
beadc736 1616
d48ef099 1617 OSPF6_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
1618 if (idx_vrf > 0)
1619 idx_arg_start += 2;
1620
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);
1625
1626 if (!all_vrf)
1627 break;
1628 }
1629 }
b52a8a52 1630
d6b901ac 1631 OSPF6_CMD_CHECK_VRF(uj, all_vrf, ospf6);
1632
d62a17ae 1633 return CMD_SUCCESS;
718e3744 1634}
1635
d48ef099 1636DEFUN(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)
718e3744 1643{
beadc736 1644 struct ospf6 *ospf6;
d48ef099 1645 struct listnode *node;
1646 const char *vrf_name = NULL;
1647 bool all_vrf = false;
1648 int idx_vrf = 0;
1649 int idx_start_arg = 4;
eacd0828 1650 bool uj = use_json(argc, argv);
beadc736 1651
d48ef099 1652 OSPF6_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
1653 if (idx_vrf > 0)
1654 idx_start_arg += 2;
1655
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);
1660
1661 if (!all_vrf)
1662 break;
1663 }
1664 }
b52a8a52 1665
d6b901ac 1666 OSPF6_CMD_CHECK_VRF(uj, all_vrf, ospf6);
1667
d62a17ae 1668 return CMD_SUCCESS;
718e3744 1669}
1670
d48ef099 1671DEFUN(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)
508e53e2 1679{
beadc736 1680 struct ospf6 *ospf6;
d48ef099 1681 struct listnode *node;
1682 const char *vrf_name = NULL;
1683 bool all_vrf = false;
1684 int idx_vrf = 0;
1685 int idx_start_arg = 4;
eacd0828 1686 bool uj = use_json(argc, argv);
beadc736 1687
d48ef099 1688 OSPF6_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
1689 if (idx_vrf > 0)
1690 idx_start_arg += 2;
1691
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);
1696
1697 if (!all_vrf)
1698 break;
1699 }
1700 }
b52a8a52 1701
d6b901ac 1702 OSPF6_CMD_CHECK_VRF(uj, all_vrf, ospf6);
1703
d62a17ae 1704 return CMD_SUCCESS;
508e53e2 1705}
718e3744 1706
d48ef099 1707DEFUN(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)
4846ef64 1716{
beadc736 1717 struct ospf6 *ospf6;
d48ef099 1718 struct listnode *node;
1719 const char *vrf_name = NULL;
1720 bool all_vrf = false;
1721 int idx_vrf = 0;
1722 int idx_start_arg = 4;
eacd0828 1723 bool uj = use_json(argc, argv);
beadc736 1724
d48ef099 1725 OSPF6_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
1726 if (idx_vrf > 0)
1727 idx_start_arg += 2;
1728
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);
1733
1734 if (!all_vrf)
1735 break;
1736 }
1737 }
b52a8a52 1738
d6b901ac 1739 OSPF6_CMD_CHECK_VRF(uj, all_vrf, ospf6);
1740
d62a17ae 1741 return CMD_SUCCESS;
4846ef64 1742}
718e3744 1743
4dc43886
MR
1744bool ospf6_is_valid_summary_addr(struct vty *vty, struct prefix *p)
1745{
23b11ab1
DS
1746 /* Default prefix validation*/
1747 if (is_default_prefix(p)) {
1748 vty_out(vty,
1749 "Default address should not be configured as summary address.\n");
4dc43886
MR
1750 return false;
1751 }
1752
c3a70f65
MR
1753 /* Host route should not be configured as summary address */
1754 if (p->prefixlen == IPV6_MAX_BITLEN) {
4dc43886 1755 vty_out(vty, "Host route should not be configured as summary address.\n");
c3a70f65 1756 return false;
4dc43886
MR
1757 }
1758
c3a70f65 1759 return true;
4dc43886
MR
1760}
1761
1762/* External Route Aggregation */
1763DEFPY (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"
1768 "Router tag \n"
1769 "Router tag value\n"
1770 "Metric \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")
1774{
1775 VTY_DECLVAR_CONTEXT(ospf6, ospf6);
1776
1777 struct prefix p;
1778 int ret = CMD_SUCCESS;
c3a70f65 1779
4dc43886
MR
1780 p.family = AF_INET6;
1781 ret = str2prefix(prefix_str, &p);
1782 if (ret == 0) {
1783 vty_out(vty, "Malformed prefix\n");
1784 return CMD_WARNING_CONFIG_FAILED;
1785 }
1786
1787 /* Apply mask for given prefix. */
8998807f 1788 apply_mask(&p);
4dc43886
MR
1789
1790 if (!ospf6_is_valid_summary_addr(vty, &p))
1791 return CMD_WARNING_CONFIG_FAILED;
1792
1793 if (!tag_str)
1794 tag = 0;
1795
1796 if (!metric_str)
1797 metric = -1;
1798
1799 if (!mtype_str)
1800 mtype = DEFAULT_METRIC_TYPE;
1801
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;
1806 }
1807
1808 return CMD_SUCCESS;
1809}
1810
1811DEFPY(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)}]",
1814 NO_STR
1815 "External summary address\n"
1816 "Specify IPv6 prefix\n"
1817 "Router tag\n"
1818 "Router tag value\n"
1819 "Metric \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")
1823{
1824 VTY_DECLVAR_CONTEXT(ospf6, ospf6);
1825
1826 struct prefix p;
1827 int ret = CMD_SUCCESS;
1828
1829 ret = str2prefix(prefix_str, &p);
1830 if (ret == 0) {
1831 vty_out(vty, "Malformed prefix\n");
1832 return CMD_WARNING_CONFIG_FAILED;
1833 }
1834
1835 /* Apply mask for given prefix. */
8998807f 1836 apply_mask(&p);
4dc43886
MR
1837
1838 if (!ospf6_is_valid_summary_addr(vty, &p))
1839 return CMD_WARNING_CONFIG_FAILED;
1840
1841 ret = ospf6_external_aggr_config_unset(ospf6, &p);
1842 if (ret == OSPF6_INVALID)
1843 vty_out(vty, "Invalid configuration!!\n");
1844
1845 return CMD_SUCCESS;
1846}
1847
1848DEFPY (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")
1854{
1855 VTY_DECLVAR_CONTEXT(ospf6, ospf6);
1856
1857 struct prefix p;
1858 int ret = CMD_SUCCESS;
1859
1860 ret = str2prefix(prefix_str, &p);
1861 if (ret == 0) {
1862 vty_out(vty, "Malformed prefix\n");
1863 return CMD_WARNING_CONFIG_FAILED;
1864 }
1865
1866 /* Apply mask for given prefix. */
8998807f 1867 apply_mask(&p);
4dc43886
MR
1868
1869 if (!ospf6_is_valid_summary_addr(vty, &p))
1870 return CMD_WARNING_CONFIG_FAILED;
1871
1872 ret = ospf6_asbr_external_rt_no_advertise(ospf6, &p);
1873 if (ret == OSPF6_INVALID)
1874 vty_out(vty, "!!Invalid configuration\n");
1875
c3a70f65 1876 return CMD_SUCCESS;
4dc43886
MR
1877}
1878
1879DEFPY (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",
1882 NO_STR
1883 "External summary address\n"
1884 "Specify IPv6 prefix\n"
1885 "Adverise summary route to the AS \n")
1886{
1887 VTY_DECLVAR_CONTEXT(ospf6, ospf6);
1888
1889 struct prefix p;
1890 int ret = CMD_SUCCESS;
1891
1892 ret = str2prefix(prefix_str, &p);
1893 if (ret == 0) {
1894 vty_out(vty, "Malformed prefix\n");
1895 return CMD_WARNING_CONFIG_FAILED;
1896 }
1897
1898 /* Apply mask for given prefix. */
8998807f 1899 apply_mask(&p);
4dc43886
MR
1900
1901 if (!ospf6_is_valid_summary_addr(vty, &p))
1902 return CMD_WARNING_CONFIG_FAILED;
1903
1904 ret = ospf6_asbr_external_rt_advertise(ospf6, &p);
1905 if (ret == OSPF6_INVALID)
1906 vty_out(vty, "!!Invalid configuration\n");
1907
1908 return CMD_SUCCESS;
1909}
1910
1911DEFPY (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")
1917{
1918 VTY_DECLVAR_CONTEXT(ospf6, ospf6);
1919
1920 ospf6_external_aggr_delay_timer_set(ospf6, timer);
1921
1922 return CMD_SUCCESS;
1923}
1924
1925DEFPY (no_ospf6_route_aggregation_timer,
1926 no_ospf6_route_aggregation_timer_cmd,
1927 "no aggregation timer [5-1800]",
1928 NO_STR
1929 "External route aggregation\n"
1930 "Delay timer\n"
1931 "Timer interval(in seconds)\n")
1932{
1933 VTY_DECLVAR_CONTEXT(ospf6, ospf6);
1934
1935 ospf6_external_aggr_delay_timer_set(ospf6,
1936 OSPF6_EXTL_AGGR_DEFAULT_DELAY);
1937 return CMD_SUCCESS;
1938}
1939
1940static int
1941ospf6_print_vty_external_routes_walkcb(struct hash_bucket *bucket, void *arg)
1942{
1943 struct ospf6_route *rt = bucket->data;
1944 struct vty *vty = (struct vty *)arg;
1945 static unsigned int count;
1946
1947 vty_out(vty, "%pFX ", &rt->prefix);
1948
1949 count++;
1950
1951 if (count%5 == 0)
1952 vty_out(vty, "\n");
1953
1954 if (OSPF6_EXTERNAL_RT_COUNT(rt->aggr_route) == count)
1955 count = 0;
1956
1957 return HASHWALK_CONTINUE;
1958}
1959
1960static int
1961ospf6_print_json_external_routes_walkcb(struct hash_bucket *bucket, void *arg)
1962{
1963 struct ospf6_route *rt = bucket->data;
1964 struct json_object *json = (struct json_object *)arg;
1965 char buf[PREFIX2STR_BUFFER];
1966 char exnalbuf[20];
1967 static unsigned int count;
1968
1969 prefix2str(&rt->prefix, buf, sizeof(buf));
1970
78982818 1971 snprintf(exnalbuf, sizeof(exnalbuf), "Exnl Addr-%d", count);
4dc43886
MR
1972
1973 json_object_string_add(json, exnalbuf, buf);
1974
1975 count++;
1976
1977 if (OSPF6_EXTERNAL_RT_COUNT(rt->aggr_route) == count)
1978 count = 0;
1979
1980 return HASHWALK_CONTINUE;
1981}
1982
ad21f6c2
MR
1983static void
1984ospf6_show_vrf_name(struct vty *vty, struct ospf6 *ospf6,
1985 json_object *json)
1986{
1987 if (json) {
1988 if (ospf6->vrf_id == VRF_DEFAULT)
1989 json_object_string_add(json, "vrfName",
1990 "default");
1991 else
1992 json_object_string_add(json, "vrfName",
1993 ospf6->name);
1994 json_object_int_add(json, "vrfId", ospf6->vrf_id);
1995 } else {
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);
2000 }
2001}
2002
4dc43886
MR
2003static int
2004ospf6_show_summary_address(struct vty *vty, struct ospf6 *ospf6,
2005 json_object *json,
2006 bool uj, const char *detail)
2007{
2008 struct route_node *rn;
c3a70f65 2009 static const char header[] = "Summary-address Metric-type Metric Tag External_Rt_count\n";
ad21f6c2 2010 json_object *json_vrf = NULL;
4dc43886
MR
2011
2012 if (!uj) {
ad21f6c2 2013 ospf6_show_vrf_name(vty, ospf6, json_vrf);
74e8311e 2014 vty_out(vty, "aggregation delay interval :%u(in seconds)\n\n",
2015 ospf6->aggr_delay_interval);
4dc43886 2016 vty_out(vty, "%s\n", header);
c3a70f65 2017 } else {
ad21f6c2
MR
2018 json_vrf = json_object_new_object();
2019
2020 ospf6_show_vrf_name(vty, ospf6, json_vrf);
2021
08d79bce
DA
2022 json_object_int_add(json_vrf, "aggregationDelayInterval",
2023 ospf6->aggr_delay_interval);
c3a70f65 2024 }
4dc43886 2025
ad21f6c2 2026
78982818
MR
2027 for (rn = route_top(ospf6->rt_aggr_tbl); rn; rn = route_next(rn)) {
2028 if (!rn->info)
2029 continue;
4dc43886 2030
78982818
MR
2031 struct ospf6_external_aggr_rt *aggr = rn->info;
2032 json_object *json_aggr = NULL;
2033 char buf[PREFIX2STR_BUFFER];
4dc43886 2034
78982818 2035 prefix2str(&aggr->p, buf, sizeof(buf));
4dc43886 2036
78982818 2037 if (uj) {
4dc43886 2038
78982818 2039 json_aggr = json_object_new_object();
4dc43886 2040
ad21f6c2 2041 json_object_object_add(json_vrf,
78982818
MR
2042 buf,
2043 json_aggr);
4dc43886 2044
08d79bce
DA
2045 json_object_string_add(json_aggr, "summaryAddress",
2046 buf);
4dc43886 2047
08d79bce
DA
2048 json_object_string_add(
2049 json_aggr, "metricType",
2050 (aggr->mtype == DEFAULT_METRIC_TYPE) ? "E2"
2051 : "E1");
78982818
MR
2052
2053 json_object_int_add(json_aggr, "Metric",
2054 (aggr->metric != -1)
2055 ? aggr->metric
2056 : DEFAULT_DEFAULT_METRIC);
4dc43886 2057
78982818
MR
2058 json_object_int_add(json_aggr, "Tag",
2059 aggr->tag);
4dc43886 2060
08d79bce
DA
2061 json_object_int_add(json_aggr, "externalRouteCount",
2062 OSPF6_EXTERNAL_RT_COUNT(aggr));
4dc43886 2063
78982818
MR
2064 if (OSPF6_EXTERNAL_RT_COUNT(aggr) && detail) {
2065 json_object_int_add(json_aggr, "ID",
2066 aggr->id);
2067 json_object_int_add(json_aggr, "Flags",
2068 aggr->aggrflags);
2069 hash_walk(aggr->match_extnl_hash,
2070 ospf6_print_json_external_routes_walkcb,
2071 json_aggr);
2072 }
2073
2074 } else {
2075 vty_out(vty, "%-22s", buf);
2076
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)
2081 ? aggr->metric
2082 : DEFAULT_DEFAULT_METRIC);
2083
2084 vty_out(vty, "%-12u", aggr->tag);
4dc43886 2085
78982818
MR
2086 vty_out(vty, "%-5ld\n",
2087 OSPF6_EXTERNAL_RT_COUNT(aggr));
2088
2089 if (OSPF6_EXTERNAL_RT_COUNT(aggr) && detail) {
2090 vty_out(vty,
2091 "Matched External routes:\n");
2092 hash_walk(aggr->match_extnl_hash,
2093 ospf6_print_vty_external_routes_walkcb,
2094 vty);
4dc43886
MR
2095 vty_out(vty, "\n");
2096 }
78982818
MR
2097
2098 vty_out(vty, "\n");
4dc43886 2099 }
78982818 2100 }
4dc43886 2101
ad21f6c2
MR
2102 if (uj)
2103 json_object_object_add(json, ospf6->name,
2104 json_vrf);
2105
4dc43886
MR
2106 return CMD_SUCCESS;
2107}
2108
2109DEFPY (show_ipv6_ospf6_external_aggregator,
2110 show_ipv6_ospf6_external_aggregator_cmd,
ad21f6c2 2111 "show ipv6 ospf6 [vrf <NAME|all>] summary-address [detail$detail] [json]",
4dc43886
MR
2112 SHOW_STR
2113 IP6_STR
2114 OSPF6_STR
ad21f6c2
MR
2115 VRF_CMD_HELP_STR
2116 "All VRFs\n"
4dc43886 2117 "Show external summary addresses\n"
bbf5104c 2118 "detailed information\n"
4dc43886
MR
2119 JSON_STR)
2120{
2121 bool uj = use_json(argc, argv);
2122 struct ospf6 *ospf6 = NULL;
c3a70f65 2123 json_object *json = NULL;
ad21f6c2
MR
2124 const char *vrf_name = NULL;
2125 struct listnode *node;
2126 bool all_vrf = false;
2127 int idx_vrf = 0;
4dc43886
MR
2128
2129 if (uj)
2130 json = json_object_new_object();
2131
ad21f6c2 2132 OSPF6_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
4dc43886 2133
ad21f6c2
MR
2134 for (ALL_LIST_ELEMENTS_RO(om6->ospf6, node, ospf6)) {
2135 if (all_vrf || strcmp(ospf6->name, vrf_name) == 0) {
4dc43886 2136
ad21f6c2
MR
2137 ospf6_show_summary_address(vty, ospf6, json, uj,
2138 detail);
2139
2140 if (!all_vrf)
2141 break;
2142 }
2143 }
4dc43886
MR
2144
2145 if (uj) {
5a6c232b 2146 vty_json(vty, json);
4dc43886
MR
2147 }
2148
d6b901ac 2149 OSPF6_CMD_CHECK_VRF(uj, all_vrf, ospf6);
2150
4dc43886
MR
2151 return CMD_SUCCESS;
2152}
2153
beadc736 2154static void ospf6_stub_router_config_write(struct vty *vty, struct ospf6 *ospf6)
f41b4a02 2155{
c48349e3 2156 if (CHECK_FLAG(ospf6->flag, OSPF6_STUB_ROUTER))
d62a17ae 2157 vty_out(vty, " stub-router administrative\n");
d62a17ae 2158 return;
f41b4a02
DD
2159}
2160
beadc736 2161static int ospf6_distance_config_write(struct vty *vty, struct ospf6 *ospf6)
baff583e 2162{
d62a17ae 2163 struct route_node *rn;
2164 struct ospf6_distance *odistance;
2165
2166 if (ospf6->distance_all)
2167 vty_out(vty, " distance %u\n", ospf6->distance_all);
2168
2169 if (ospf6->distance_intra || ospf6->distance_inter
2170 || ospf6->distance_external) {
2171 vty_out(vty, " distance ospf6");
2172
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);
2179
2180 vty_out(vty, "\n");
2181 }
2182
2183 for (rn = route_top(ospf6->distance_table); rn; rn = route_next(rn))
2dbe669b
DA
2184 if ((odistance = rn->info) != NULL)
2185 vty_out(vty, " distance %u %pFX %s\n",
2186 odistance->distance, &rn->p,
d62a17ae 2187 odistance->access_list ? odistance->access_list
2188 : "");
d62a17ae 2189 return 0;
baff583e
MZ
2190}
2191
4dc43886
MR
2192static int ospf6_asbr_summary_config_write(struct vty *vty, struct ospf6 *ospf6)
2193{
2194 struct route_node *rn;
2195 struct ospf6_external_aggr_rt *aggr;
2196 char buf[PREFIX2STR_BUFFER];
2197
2198 if (ospf6->aggr_delay_interval != OSPF6_EXTL_AGGR_DEFAULT_DELAY)
2199 vty_out(vty, " aggregation timer %u\n",
2200 ospf6->aggr_delay_interval);
2201
2202 /* print 'summary-address A:B::C:D/M' */
78982818
MR
2203 for (rn = route_top(ospf6->rt_aggr_tbl); rn; rn = route_next(rn)) {
2204 if (!rn->info)
2205 continue;
4dc43886 2206
78982818 2207 aggr = rn->info;
4dc43886 2208
78982818
MR
2209 prefix2str(&aggr->p, buf, sizeof(buf));
2210 vty_out(vty, " summary-address %s", buf);
2211 if (aggr->tag)
2212 vty_out(vty, " tag %u", aggr->tag);
4dc43886 2213
78982818
MR
2214 if (aggr->metric != -1)
2215 vty_out(vty, " metric %d", aggr->metric);
4dc43886 2216
78982818
MR
2217 if (aggr->mtype != DEFAULT_METRIC_TYPE)
2218 vty_out(vty, " metric-type %d", aggr->mtype);
2219
2220 if (CHECK_FLAG(aggr->aggrflags,
2221 OSPF6_EXTERNAL_AGGRT_NO_ADVERTISE))
2222 vty_out(vty, " no-advertise");
2223
2224 vty_out(vty, "\n");
2225 }
4dc43886
MR
2226
2227 return 0;
2228}
2229
508e53e2 2230/* OSPF configuration write function. */
d62a17ae 2231static int config_write_ospf6(struct vty *vty)
508e53e2 2232{
beadc736 2233 struct ospf6 *ospf6;
2234 struct listnode *node, *nnode;
d62a17ae 2235
2236 /* OSPFv3 configuration. */
beadc736 2237 if (om6 == NULL)
d62a17ae 2238 return CMD_SUCCESS;
2239
beadc736 2240 for (ALL_LIST_ELEMENTS(om6->ospf6, node, nnode, ospf6)) {
d48ef099 2241 if (ospf6->name && strcmp(ospf6->name, VRF_DEFAULT_NAME))
2242 vty_out(vty, "router ospf6 vrf %s\n", ospf6->name);
2243 else
2244 vty_out(vty, "router ospf6\n");
2245
beadc736 2246 if (ospf6->router_id_static != 0)
2247 vty_out(vty, " ospf6 router-id %pI4\n",
2248 &ospf6->router_id_static);
2249
870791a3
IR
2250 if (CHECK_FLAG(ospf6->config_flags,
2251 OSPF6_SEND_EXTRA_DATA_TO_ZEBRA))
2252 vty_out(vty, " ospf6 send-extra-data zebra\n");
5b5d66c4 2253
beadc736 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");
2264 }
d62a17ae 2265
beadc736 2266 if (ospf6->ref_bandwidth != OSPF6_REFERENCE_BANDWIDTH)
2267 vty_out(vty, " auto-cost reference-bandwidth %d\n",
2268 ospf6->ref_bandwidth);
2269
78156066
PR
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);
2274
beadc736 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);
2279
1958143e
MR
2280 /* ECMP max path config */
2281 if (ospf6->max_multipath != MULTIPATH_NUM)
2282 vty_out(vty, " maximum-paths %d\n",
2283 ospf6->max_multipath);
2284
beadc736 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);
b19502d3 2290 ospf6_distribute_config_write(vty, ospf6);
4dc43886 2291 ospf6_asbr_summary_config_write(vty, ospf6);
71165098 2292 config_write_ospf6_gr(vty, ospf6);
0fc3e113 2293 config_write_ospf6_gr_helper(vty, ospf6);
07679ad9
IR
2294
2295 vty_out(vty, "exit\n");
beadc736 2296 vty_out(vty, "!\n");
d62a17ae 2297 }
d62a17ae 2298 return 0;
508e53e2 2299}
2300
612c2c15 2301static int config_write_ospf6(struct vty *vty);
508e53e2 2302/* OSPF6 node structure. */
d62a17ae 2303static struct cmd_node ospf6_node = {
f4b8291f 2304 .name = "ospf6",
62b346ee 2305 .node = OSPF6_NODE,
24389580 2306 .parent_node = CONFIG_NODE,
62b346ee 2307 .prompt = "%s(config-ospf6)# ",
612c2c15 2308 .config_write = config_write_ospf6,
508e53e2 2309};
2310
f71ed6df
YR
2311void install_element_ospf6_clear_process(void)
2312{
2313 install_element(ENABLE_NODE, &clear_router_ospf6_cmd);
2314}
2315
508e53e2 2316/* Install ospf related commands. */
d62a17ae 2317void ospf6_top_init(void)
718e3744 2318{
d62a17ae 2319 /* Install ospf6 top node. */
612c2c15 2320 install_node(&ospf6_node);
d62a17ae 2321
2322 install_element(VIEW_NODE, &show_ipv6_ospf6_cmd);
dd7fb1db 2323 install_element(VIEW_NODE, &show_ipv6_ospf6_vrfs_cmd);
d62a17ae 2324 install_element(CONFIG_NODE, &router_ospf6_cmd);
2325 install_element(CONFIG_NODE, &no_router_ospf6_cmd);
2326
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);
2331
2332 install_default(OSPF6_NODE);
2333 install_element(OSPF6_NODE, &ospf6_router_id_cmd);
5d1a2ee8 2334 install_element(OSPF6_NODE, &no_ospf6_router_id_cmd);
d62a17ae 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);
5b5d66c4 2339 install_element(OSPF6_NODE, &ospf6_send_extra_data_cmd);
d62a17ae 2340
2341 /* LSA timers commands */
2342 install_element(OSPF6_NODE, &ospf6_timers_lsa_cmd);
2343 install_element(OSPF6_NODE, &no_ospf6_timers_lsa_cmd);
2344
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);
508e53e2 2349
1958143e
MR
2350 /* maximum-paths command */
2351 install_element(OSPF6_NODE, &ospf6_max_multipath_cmd);
2352 install_element(OSPF6_NODE, &no_ospf6_max_multipath_cmd);
2353
4dc43886
MR
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);
2364
d62a17ae 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);
718e3744 2369}