]> git.proxmox.com Git - mirror_frr.git/blame - ospf6d/ospf6_top.c
Merge pull request #13177 from mjstapp/fix_ospf_supoort_typo
[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"
24a58196 14#include "frrevent.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
e16d030c
DS
555 EVENT_OFF(o->maxage_remover);
556 EVENT_OFF(o->t_spf_calc);
557 EVENT_OFF(o->t_ase_calc);
558 EVENT_OFF(o->t_distribute_update);
559 EVENT_OFF(o->t_ospf6_receive);
560 EVENT_OFF(o->t_external_aggr);
561 EVENT_OFF(o->gr_info.t_grace_period);
562 EVENT_OFF(o->t_write);
563 EVENT_OFF(o->t_abr_task);
d62a17ae 564 }
508e53e2 565}
718e3744 566
cd9d0537 567void ospf6_master_init(struct event_loop *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{
e16d030c 578 struct ospf6 *o = (struct ospf6 *)EVENT_ARG(thread);
d62a17ae 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
5f6eaa9b 1362 if (event_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",
5f6eaa9b 1455 (event_is_scheduled(o->t_spf_calc) ? "due in " : "is "),
c905f04c 1456 buf);
35a45dea 1457
1458 if (CHECK_FLAG(o->flag, OSPF6_STUB_ROUTER))
1459 vty_out(vty, " Router Is Stub Router\n");
1460
1461 /* LSAs */
1462 vty_out(vty, " Number of AS scoped LSAs is %u\n",
1463 o->lsdb->count);
1464
1465 /* Areas */
1466 vty_out(vty, " Number of areas in this router is %u\n",
1467 listcount(o->area_list));
1468
6cb85350
AR
1469 vty_out(vty, " Authentication Sequence number info\n");
1470 vty_out(vty, " Higher sequence no %u, Lower sequence no %u\n",
1471 o->seqnum_h, o->seqnum_l);
1472
35a45dea 1473 if (CHECK_FLAG(o->config_flags, OSPF6_LOG_ADJACENCY_CHANGES)) {
1474 if (CHECK_FLAG(o->config_flags,
1475 OSPF6_LOG_ADJACENCY_DETAIL))
1476 vty_out(vty,
1477 " All adjacency changes are logged\n");
1478 else
1479 vty_out(vty, " Adjacency changes are logged\n");
1480 }
d62a17ae 1481
d62a17ae 1482
35a45dea 1483 vty_out(vty, "\n");
d62a17ae 1484
35a45dea 1485 for (ALL_LIST_ELEMENTS_RO(o->area_list, n, oa))
1486 ospf6_area_show(vty, oa, json_areas, use_json);
1487 }
718e3744 1488}
1489
dd7fb1db
PG
1490DEFUN(show_ipv6_ospf6_vrfs, show_ipv6_ospf6_vrfs_cmd,
1491 "show ipv6 ospf6 vrfs [json]",
1492 SHOW_STR IP6_STR OSPF6_STR "Show OSPF6 VRFs \n" JSON_STR)
1493{
1494 bool uj = use_json(argc, argv);
1495 json_object *json = NULL;
1496 json_object *json_vrfs = NULL;
1497 struct ospf6 *ospf6 = NULL;
1498 struct listnode *node = NULL;
1499 int count = 0;
1500 char buf[PREFIX_STRLEN];
1501 static const char header[] =
1502 "Name Id RouterId ";
1503
1504 if (uj) {
1505 json = json_object_new_object();
1506 json_vrfs = json_object_new_object();
1507 }
1508
1509 for (ALL_LIST_ELEMENTS_RO(om6->ospf6, node, ospf6)) {
1510 json_object *json_vrf = NULL;
1511 const char *name = NULL;
1512 int64_t vrf_id_ui = 0;
1513 struct in_addr router_id;
1514
1515 router_id.s_addr = ospf6->router_id;
1516 count++;
1517
1518 if (!uj && count == 1)
1519 vty_out(vty, "%s\n", header);
1520 if (uj)
1521 json_vrf = json_object_new_object();
1522
1523 if (ospf6->vrf_id == VRF_DEFAULT)
1524 name = VRF_DEFAULT_NAME;
1525 else
1526 name = ospf6->name;
1527
1528 vrf_id_ui = (ospf6->vrf_id == VRF_UNKNOWN)
1529 ? -1
1530 : (int64_t)ospf6->vrf_id;
1531
1532 if (uj) {
1533 json_object_int_add(json_vrf, "vrfId", vrf_id_ui);
ce4b236f
DA
1534 json_object_string_addf(json_vrf, "routerId", "%pI4",
1535 &router_id);
dd7fb1db
PG
1536 json_object_object_add(json_vrfs, name, json_vrf);
1537
1538 } else {
1539 vty_out(vty, "%-25s %-5d %-16s \n", name,
1540 ospf6->vrf_id,
1541 inet_ntop(AF_INET, &router_id, buf,
1542 sizeof(buf)));
1543 }
1544 }
1545
1546 if (uj) {
1547 json_object_object_add(json, "vrfs", json_vrfs);
1548 json_object_int_add(json, "totalVrfs", count);
1549
5a6c232b 1550 vty_json(vty, json);
dd7fb1db
PG
1551 } else {
1552 if (count)
1553 vty_out(vty, "\nTotal number of OSPF VRFs: %d\n",
1554 count);
1555 }
1556
1557 return CMD_SUCCESS;
1558}
1559
508e53e2 1560/* show top level structures */
d48ef099 1561DEFUN(show_ipv6_ospf6, show_ipv6_ospf6_cmd,
1562 "show ipv6 ospf6 [vrf <NAME|all>] [json]",
1563 SHOW_STR IP6_STR OSPF6_STR VRF_CMD_HELP_STR "All VRFs\n" JSON_STR)
718e3744 1564{
beadc736 1565 struct ospf6 *ospf6;
d48ef099 1566 struct listnode *node;
1567 const char *vrf_name = NULL;
1568 bool all_vrf = false;
1569 int idx_vrf = 0;
1570
35a45dea 1571 bool uj = use_json(argc, argv);
1572 json_object *json = NULL;
508e53e2 1573
d48ef099 1574 OSPF6_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
35a45dea 1575
d48ef099 1576 for (ALL_LIST_ELEMENTS_RO(om6->ospf6, node, ospf6)) {
1577 if (all_vrf || strcmp(ospf6->name, vrf_name) == 0) {
1578 if (uj)
1579 json = json_object_new_object();
1580 ospf6_show(vty, ospf6, json, uj);
35a45dea 1581
d48ef099 1582 if (!all_vrf)
1583 break;
1584 }
1585 }
35a45dea 1586
1587 if (uj)
1588 json_object_free(json);
d48ef099 1589
d6b901ac 1590 OSPF6_CMD_CHECK_VRF(uj, all_vrf, ospf6);
1591
d62a17ae 1592 return CMD_SUCCESS;
718e3744 1593}
1594
d48ef099 1595DEFUN(show_ipv6_ospf6_route, show_ipv6_ospf6_route_cmd,
1596 "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]",
1597 SHOW_STR IP6_STR OSPF6_STR VRF_CMD_HELP_STR
1598 "All VRFs\n" ROUTE_STR
1599 "Display Intra-Area routes\n"
1600 "Display Inter-Area routes\n"
1601 "Display Type-1 External routes\n"
1602 "Display Type-2 External routes\n"
1603 "Specify IPv6 address\n"
1604 "Specify IPv6 prefix\n"
1605 "Detailed information\n"
1606 "Summary of route table\n" JSON_STR)
718e3744 1607{
beadc736 1608 struct ospf6 *ospf6;
d48ef099 1609 struct listnode *node;
1610 const char *vrf_name = NULL;
1611 bool all_vrf = false;
1612 int idx_vrf = 0;
1613 int idx_arg_start = 4;
eacd0828 1614 bool uj = use_json(argc, argv);
beadc736 1615
d48ef099 1616 OSPF6_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
1617 if (idx_vrf > 0)
1618 idx_arg_start += 2;
1619
1620 for (ALL_LIST_ELEMENTS_RO(om6->ospf6, node, ospf6)) {
1621 if (all_vrf || strcmp(ospf6->name, vrf_name) == 0) {
1622 ospf6_route_table_show(vty, idx_arg_start, argc, argv,
1623 ospf6->route_table, uj);
1624
1625 if (!all_vrf)
1626 break;
1627 }
1628 }
b52a8a52 1629
d6b901ac 1630 OSPF6_CMD_CHECK_VRF(uj, all_vrf, ospf6);
1631
d62a17ae 1632 return CMD_SUCCESS;
718e3744 1633}
1634
d48ef099 1635DEFUN(show_ipv6_ospf6_route_match, show_ipv6_ospf6_route_match_cmd,
1636 "show ipv6 ospf6 [vrf <NAME|all>] route X:X::X:X/M <match|longer> [json]",
1637 SHOW_STR IP6_STR OSPF6_STR VRF_CMD_HELP_STR
1638 "All VRFs\n" ROUTE_STR
1639 "Specify IPv6 prefix\n"
1640 "Display routes which match the specified route\n"
1641 "Display routes longer than the specified route\n" JSON_STR)
718e3744 1642{
beadc736 1643 struct ospf6 *ospf6;
d48ef099 1644 struct listnode *node;
1645 const char *vrf_name = NULL;
1646 bool all_vrf = false;
1647 int idx_vrf = 0;
1648 int idx_start_arg = 4;
eacd0828 1649 bool uj = use_json(argc, argv);
beadc736 1650
d48ef099 1651 OSPF6_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
1652 if (idx_vrf > 0)
1653 idx_start_arg += 2;
1654
1655 for (ALL_LIST_ELEMENTS_RO(om6->ospf6, node, ospf6)) {
1656 if (all_vrf || strcmp(ospf6->name, vrf_name) == 0) {
1657 ospf6_route_table_show(vty, idx_start_arg, argc, argv,
1658 ospf6->route_table, uj);
1659
1660 if (!all_vrf)
1661 break;
1662 }
1663 }
b52a8a52 1664
d6b901ac 1665 OSPF6_CMD_CHECK_VRF(uj, all_vrf, ospf6);
1666
d62a17ae 1667 return CMD_SUCCESS;
718e3744 1668}
1669
d48ef099 1670DEFUN(show_ipv6_ospf6_route_match_detail,
1671 show_ipv6_ospf6_route_match_detail_cmd,
1672 "show ipv6 ospf6 [vrf <NAME|all>] route X:X::X:X/M match detail [json]",
1673 SHOW_STR IP6_STR OSPF6_STR VRF_CMD_HELP_STR
1674 "All VRFs\n" ROUTE_STR
1675 "Specify IPv6 prefix\n"
1676 "Display routes which match the specified route\n"
1677 "Detailed information\n" JSON_STR)
508e53e2 1678{
beadc736 1679 struct ospf6 *ospf6;
d48ef099 1680 struct listnode *node;
1681 const char *vrf_name = NULL;
1682 bool all_vrf = false;
1683 int idx_vrf = 0;
1684 int idx_start_arg = 4;
eacd0828 1685 bool uj = use_json(argc, argv);
beadc736 1686
d48ef099 1687 OSPF6_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
1688 if (idx_vrf > 0)
1689 idx_start_arg += 2;
1690
1691 for (ALL_LIST_ELEMENTS_RO(om6->ospf6, node, ospf6)) {
1692 if (all_vrf || strcmp(ospf6->name, vrf_name) == 0) {
1693 ospf6_route_table_show(vty, idx_start_arg, argc, argv,
1694 ospf6->route_table, uj);
1695
1696 if (!all_vrf)
1697 break;
1698 }
1699 }
b52a8a52 1700
d6b901ac 1701 OSPF6_CMD_CHECK_VRF(uj, all_vrf, ospf6);
1702
d62a17ae 1703 return CMD_SUCCESS;
508e53e2 1704}
718e3744 1705
d48ef099 1706DEFUN(show_ipv6_ospf6_route_type_detail, show_ipv6_ospf6_route_type_detail_cmd,
1707 "show ipv6 ospf6 [vrf <NAME|all>] route <intra-area|inter-area|external-1|external-2> detail [json]",
1708 SHOW_STR IP6_STR OSPF6_STR VRF_CMD_HELP_STR
1709 "All VRFs\n" ROUTE_STR
1710 "Display Intra-Area routes\n"
1711 "Display Inter-Area routes\n"
1712 "Display Type-1 External routes\n"
1713 "Display Type-2 External routes\n"
1714 "Detailed information\n" JSON_STR)
4846ef64 1715{
beadc736 1716 struct ospf6 *ospf6;
d48ef099 1717 struct listnode *node;
1718 const char *vrf_name = NULL;
1719 bool all_vrf = false;
1720 int idx_vrf = 0;
1721 int idx_start_arg = 4;
eacd0828 1722 bool uj = use_json(argc, argv);
beadc736 1723
d48ef099 1724 OSPF6_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
1725 if (idx_vrf > 0)
1726 idx_start_arg += 2;
1727
1728 for (ALL_LIST_ELEMENTS_RO(om6->ospf6, node, ospf6)) {
1729 if (all_vrf || strcmp(ospf6->name, vrf_name) == 0) {
1730 ospf6_route_table_show(vty, idx_start_arg, argc, argv,
1731 ospf6->route_table, uj);
1732
1733 if (!all_vrf)
1734 break;
1735 }
1736 }
b52a8a52 1737
d6b901ac 1738 OSPF6_CMD_CHECK_VRF(uj, all_vrf, ospf6);
1739
d62a17ae 1740 return CMD_SUCCESS;
4846ef64 1741}
718e3744 1742
4dc43886
MR
1743bool ospf6_is_valid_summary_addr(struct vty *vty, struct prefix *p)
1744{
23b11ab1
DS
1745 /* Default prefix validation*/
1746 if (is_default_prefix(p)) {
1747 vty_out(vty,
1748 "Default address should not be configured as summary address.\n");
4dc43886
MR
1749 return false;
1750 }
1751
c3a70f65
MR
1752 /* Host route should not be configured as summary address */
1753 if (p->prefixlen == IPV6_MAX_BITLEN) {
4dc43886 1754 vty_out(vty, "Host route should not be configured as summary address.\n");
c3a70f65 1755 return false;
4dc43886
MR
1756 }
1757
c3a70f65 1758 return true;
4dc43886
MR
1759}
1760
1761/* External Route Aggregation */
1762DEFPY (ospf6_external_route_aggregation,
1763 ospf6_external_route_aggregation_cmd,
1764 "summary-address X:X::X:X/M$prefix [tag (1-4294967295)] [{metric (0-16777215) | metric-type (1-2)$mtype}]",
1765 "External summary address\n"
1766 "Specify IPv6 prefix\n"
1767 "Router tag \n"
1768 "Router tag value\n"
1769 "Metric \n"
1770 "Advertised metric for this route\n"
1771 "OSPFv3 exterior metric type for summarised routes\n"
1772 "Set OSPFv3 External Type 1/2 metrics\n")
1773{
1774 VTY_DECLVAR_CONTEXT(ospf6, ospf6);
1775
1776 struct prefix p;
1777 int ret = CMD_SUCCESS;
c3a70f65 1778
4dc43886
MR
1779 p.family = AF_INET6;
1780 ret = str2prefix(prefix_str, &p);
1781 if (ret == 0) {
1782 vty_out(vty, "Malformed prefix\n");
1783 return CMD_WARNING_CONFIG_FAILED;
1784 }
1785
1786 /* Apply mask for given prefix. */
8998807f 1787 apply_mask(&p);
4dc43886
MR
1788
1789 if (!ospf6_is_valid_summary_addr(vty, &p))
1790 return CMD_WARNING_CONFIG_FAILED;
1791
1792 if (!tag_str)
1793 tag = 0;
1794
1795 if (!metric_str)
1796 metric = -1;
1797
1798 if (!mtype_str)
1799 mtype = DEFAULT_METRIC_TYPE;
1800
1801 ret = ospf6_external_aggr_config_set(ospf6, &p, tag, metric, mtype);
1802 if (ret == OSPF6_FAILURE) {
1803 vty_out(vty, "Invalid configuration!!\n");
1804 return CMD_WARNING_CONFIG_FAILED;
1805 }
1806
1807 return CMD_SUCCESS;
1808}
1809
1810DEFPY(no_ospf6_external_route_aggregation,
1811 no_ospf6_external_route_aggregation_cmd,
1812 "no summary-address X:X::X:X/M$prefix [tag (1-4294967295)] [{metric (0-16777215) | metric-type (1-2)}]",
1813 NO_STR
1814 "External summary address\n"
1815 "Specify IPv6 prefix\n"
1816 "Router tag\n"
1817 "Router tag value\n"
1818 "Metric \n"
1819 "Advertised metric for this route\n"
1820 "OSPFv3 exterior metric type for summarised routes\n"
1821 "Set OSPFv3 External Type 1/2 metrics\n")
1822{
1823 VTY_DECLVAR_CONTEXT(ospf6, ospf6);
1824
1825 struct prefix p;
1826 int ret = CMD_SUCCESS;
1827
1828 ret = str2prefix(prefix_str, &p);
1829 if (ret == 0) {
1830 vty_out(vty, "Malformed prefix\n");
1831 return CMD_WARNING_CONFIG_FAILED;
1832 }
1833
1834 /* Apply mask for given prefix. */
8998807f 1835 apply_mask(&p);
4dc43886
MR
1836
1837 if (!ospf6_is_valid_summary_addr(vty, &p))
1838 return CMD_WARNING_CONFIG_FAILED;
1839
1840 ret = ospf6_external_aggr_config_unset(ospf6, &p);
1841 if (ret == OSPF6_INVALID)
1842 vty_out(vty, "Invalid configuration!!\n");
1843
1844 return CMD_SUCCESS;
1845}
1846
1847DEFPY (ospf6_external_route_aggregation_no_advertise,
1848 ospf6_external_route_aggregation_no_advertise_cmd,
1849 "summary-address X:X::X:X/M$prefix no-advertise",
1850 "External summary address\n"
1851 "Specify IPv6 prefix\n"
1852 "Don't advertise summary route \n")
1853{
1854 VTY_DECLVAR_CONTEXT(ospf6, ospf6);
1855
1856 struct prefix p;
1857 int ret = CMD_SUCCESS;
1858
1859 ret = str2prefix(prefix_str, &p);
1860 if (ret == 0) {
1861 vty_out(vty, "Malformed prefix\n");
1862 return CMD_WARNING_CONFIG_FAILED;
1863 }
1864
1865 /* Apply mask for given prefix. */
8998807f 1866 apply_mask(&p);
4dc43886
MR
1867
1868 if (!ospf6_is_valid_summary_addr(vty, &p))
1869 return CMD_WARNING_CONFIG_FAILED;
1870
1871 ret = ospf6_asbr_external_rt_no_advertise(ospf6, &p);
1872 if (ret == OSPF6_INVALID)
1873 vty_out(vty, "!!Invalid configuration\n");
1874
c3a70f65 1875 return CMD_SUCCESS;
4dc43886
MR
1876}
1877
1878DEFPY (no_ospf6_external_route_aggregation_no_advertise,
1879 no_ospf6_external_route_aggregation_no_advertise_cmd,
1880 "no summary-address X:X::X:X/M$prefix no-advertise",
1881 NO_STR
1882 "External summary address\n"
1883 "Specify IPv6 prefix\n"
1884 "Adverise summary route to the AS \n")
1885{
1886 VTY_DECLVAR_CONTEXT(ospf6, ospf6);
1887
1888 struct prefix p;
1889 int ret = CMD_SUCCESS;
1890
1891 ret = str2prefix(prefix_str, &p);
1892 if (ret == 0) {
1893 vty_out(vty, "Malformed prefix\n");
1894 return CMD_WARNING_CONFIG_FAILED;
1895 }
1896
1897 /* Apply mask for given prefix. */
8998807f 1898 apply_mask(&p);
4dc43886
MR
1899
1900 if (!ospf6_is_valid_summary_addr(vty, &p))
1901 return CMD_WARNING_CONFIG_FAILED;
1902
1903 ret = ospf6_asbr_external_rt_advertise(ospf6, &p);
1904 if (ret == OSPF6_INVALID)
1905 vty_out(vty, "!!Invalid configuration\n");
1906
1907 return CMD_SUCCESS;
1908}
1909
1910DEFPY (ospf6_route_aggregation_timer,
1911 ospf6_route_aggregation_timer_cmd,
1912 "aggregation timer (5-1800)",
1913 "External route aggregation\n"
1914 "Delay timer (in seconds)\n"
1915 "Timer interval(in seconds)\n")
1916{
1917 VTY_DECLVAR_CONTEXT(ospf6, ospf6);
1918
1919 ospf6_external_aggr_delay_timer_set(ospf6, timer);
1920
1921 return CMD_SUCCESS;
1922}
1923
1924DEFPY (no_ospf6_route_aggregation_timer,
1925 no_ospf6_route_aggregation_timer_cmd,
1926 "no aggregation timer [5-1800]",
1927 NO_STR
1928 "External route aggregation\n"
1929 "Delay timer\n"
1930 "Timer interval(in seconds)\n")
1931{
1932 VTY_DECLVAR_CONTEXT(ospf6, ospf6);
1933
1934 ospf6_external_aggr_delay_timer_set(ospf6,
1935 OSPF6_EXTL_AGGR_DEFAULT_DELAY);
1936 return CMD_SUCCESS;
1937}
1938
1939static int
1940ospf6_print_vty_external_routes_walkcb(struct hash_bucket *bucket, void *arg)
1941{
1942 struct ospf6_route *rt = bucket->data;
1943 struct vty *vty = (struct vty *)arg;
1944 static unsigned int count;
1945
1946 vty_out(vty, "%pFX ", &rt->prefix);
1947
1948 count++;
1949
1950 if (count%5 == 0)
1951 vty_out(vty, "\n");
1952
1953 if (OSPF6_EXTERNAL_RT_COUNT(rt->aggr_route) == count)
1954 count = 0;
1955
1956 return HASHWALK_CONTINUE;
1957}
1958
1959static int
1960ospf6_print_json_external_routes_walkcb(struct hash_bucket *bucket, void *arg)
1961{
1962 struct ospf6_route *rt = bucket->data;
1963 struct json_object *json = (struct json_object *)arg;
1964 char buf[PREFIX2STR_BUFFER];
1965 char exnalbuf[20];
1966 static unsigned int count;
1967
1968 prefix2str(&rt->prefix, buf, sizeof(buf));
1969
78982818 1970 snprintf(exnalbuf, sizeof(exnalbuf), "Exnl Addr-%d", count);
4dc43886
MR
1971
1972 json_object_string_add(json, exnalbuf, buf);
1973
1974 count++;
1975
1976 if (OSPF6_EXTERNAL_RT_COUNT(rt->aggr_route) == count)
1977 count = 0;
1978
1979 return HASHWALK_CONTINUE;
1980}
1981
ad21f6c2
MR
1982static void
1983ospf6_show_vrf_name(struct vty *vty, struct ospf6 *ospf6,
1984 json_object *json)
1985{
1986 if (json) {
1987 if (ospf6->vrf_id == VRF_DEFAULT)
1988 json_object_string_add(json, "vrfName",
1989 "default");
1990 else
1991 json_object_string_add(json, "vrfName",
1992 ospf6->name);
1993 json_object_int_add(json, "vrfId", ospf6->vrf_id);
1994 } else {
1995 if (ospf6->vrf_id == VRF_DEFAULT)
1996 vty_out(vty, "VRF Name: %s\n", "default");
1997 else if (ospf6->name)
1998 vty_out(vty, "VRF Name: %s\n", ospf6->name);
1999 }
2000}
2001
4dc43886
MR
2002static int
2003ospf6_show_summary_address(struct vty *vty, struct ospf6 *ospf6,
2004 json_object *json,
2005 bool uj, const char *detail)
2006{
2007 struct route_node *rn;
c3a70f65 2008 static const char header[] = "Summary-address Metric-type Metric Tag External_Rt_count\n";
ad21f6c2 2009 json_object *json_vrf = NULL;
4dc43886
MR
2010
2011 if (!uj) {
ad21f6c2 2012 ospf6_show_vrf_name(vty, ospf6, json_vrf);
74e8311e 2013 vty_out(vty, "aggregation delay interval :%u(in seconds)\n\n",
2014 ospf6->aggr_delay_interval);
4dc43886 2015 vty_out(vty, "%s\n", header);
c3a70f65 2016 } else {
ad21f6c2
MR
2017 json_vrf = json_object_new_object();
2018
2019 ospf6_show_vrf_name(vty, ospf6, json_vrf);
2020
08d79bce
DA
2021 json_object_int_add(json_vrf, "aggregationDelayInterval",
2022 ospf6->aggr_delay_interval);
c3a70f65 2023 }
4dc43886 2024
ad21f6c2 2025
78982818
MR
2026 for (rn = route_top(ospf6->rt_aggr_tbl); rn; rn = route_next(rn)) {
2027 if (!rn->info)
2028 continue;
4dc43886 2029
78982818
MR
2030 struct ospf6_external_aggr_rt *aggr = rn->info;
2031 json_object *json_aggr = NULL;
2032 char buf[PREFIX2STR_BUFFER];
4dc43886 2033
78982818 2034 prefix2str(&aggr->p, buf, sizeof(buf));
4dc43886 2035
78982818 2036 if (uj) {
4dc43886 2037
78982818 2038 json_aggr = json_object_new_object();
4dc43886 2039
ad21f6c2 2040 json_object_object_add(json_vrf,
78982818
MR
2041 buf,
2042 json_aggr);
4dc43886 2043
08d79bce
DA
2044 json_object_string_add(json_aggr, "summaryAddress",
2045 buf);
4dc43886 2046
08d79bce
DA
2047 json_object_string_add(
2048 json_aggr, "metricType",
2049 (aggr->mtype == DEFAULT_METRIC_TYPE) ? "E2"
2050 : "E1");
78982818
MR
2051
2052 json_object_int_add(json_aggr, "Metric",
2053 (aggr->metric != -1)
2054 ? aggr->metric
2055 : DEFAULT_DEFAULT_METRIC);
4dc43886 2056
78982818
MR
2057 json_object_int_add(json_aggr, "Tag",
2058 aggr->tag);
4dc43886 2059
08d79bce
DA
2060 json_object_int_add(json_aggr, "externalRouteCount",
2061 OSPF6_EXTERNAL_RT_COUNT(aggr));
4dc43886 2062
78982818
MR
2063 if (OSPF6_EXTERNAL_RT_COUNT(aggr) && detail) {
2064 json_object_int_add(json_aggr, "ID",
2065 aggr->id);
2066 json_object_int_add(json_aggr, "Flags",
2067 aggr->aggrflags);
2068 hash_walk(aggr->match_extnl_hash,
2069 ospf6_print_json_external_routes_walkcb,
2070 json_aggr);
2071 }
2072
2073 } else {
2074 vty_out(vty, "%-22s", buf);
2075
2076 (aggr->mtype == DEFAULT_METRIC_TYPE)
2077 ? vty_out(vty, "%-16s", "E2")
2078 : vty_out(vty, "%-16s", "E1");
2079 vty_out(vty, "%-11d", (aggr->metric != -1)
2080 ? aggr->metric
2081 : DEFAULT_DEFAULT_METRIC);
2082
2083 vty_out(vty, "%-12u", aggr->tag);
4dc43886 2084
78982818
MR
2085 vty_out(vty, "%-5ld\n",
2086 OSPF6_EXTERNAL_RT_COUNT(aggr));
2087
2088 if (OSPF6_EXTERNAL_RT_COUNT(aggr) && detail) {
2089 vty_out(vty,
2090 "Matched External routes:\n");
2091 hash_walk(aggr->match_extnl_hash,
2092 ospf6_print_vty_external_routes_walkcb,
2093 vty);
4dc43886
MR
2094 vty_out(vty, "\n");
2095 }
78982818
MR
2096
2097 vty_out(vty, "\n");
4dc43886 2098 }
78982818 2099 }
4dc43886 2100
ad21f6c2
MR
2101 if (uj)
2102 json_object_object_add(json, ospf6->name,
2103 json_vrf);
2104
4dc43886
MR
2105 return CMD_SUCCESS;
2106}
2107
2108DEFPY (show_ipv6_ospf6_external_aggregator,
2109 show_ipv6_ospf6_external_aggregator_cmd,
ad21f6c2 2110 "show ipv6 ospf6 [vrf <NAME|all>] summary-address [detail$detail] [json]",
4dc43886
MR
2111 SHOW_STR
2112 IP6_STR
2113 OSPF6_STR
ad21f6c2
MR
2114 VRF_CMD_HELP_STR
2115 "All VRFs\n"
4dc43886 2116 "Show external summary addresses\n"
bbf5104c 2117 "detailed information\n"
4dc43886
MR
2118 JSON_STR)
2119{
2120 bool uj = use_json(argc, argv);
2121 struct ospf6 *ospf6 = NULL;
c3a70f65 2122 json_object *json = NULL;
ad21f6c2
MR
2123 const char *vrf_name = NULL;
2124 struct listnode *node;
2125 bool all_vrf = false;
2126 int idx_vrf = 0;
4dc43886
MR
2127
2128 if (uj)
2129 json = json_object_new_object();
2130
ad21f6c2 2131 OSPF6_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
4dc43886 2132
ad21f6c2
MR
2133 for (ALL_LIST_ELEMENTS_RO(om6->ospf6, node, ospf6)) {
2134 if (all_vrf || strcmp(ospf6->name, vrf_name) == 0) {
4dc43886 2135
ad21f6c2
MR
2136 ospf6_show_summary_address(vty, ospf6, json, uj,
2137 detail);
2138
2139 if (!all_vrf)
2140 break;
2141 }
2142 }
4dc43886
MR
2143
2144 if (uj) {
5a6c232b 2145 vty_json(vty, json);
4dc43886
MR
2146 }
2147
d6b901ac 2148 OSPF6_CMD_CHECK_VRF(uj, all_vrf, ospf6);
2149
4dc43886
MR
2150 return CMD_SUCCESS;
2151}
2152
beadc736 2153static void ospf6_stub_router_config_write(struct vty *vty, struct ospf6 *ospf6)
f41b4a02 2154{
c48349e3 2155 if (CHECK_FLAG(ospf6->flag, OSPF6_STUB_ROUTER))
d62a17ae 2156 vty_out(vty, " stub-router administrative\n");
d62a17ae 2157 return;
f41b4a02
DD
2158}
2159
beadc736 2160static int ospf6_distance_config_write(struct vty *vty, struct ospf6 *ospf6)
baff583e 2161{
d62a17ae 2162 struct route_node *rn;
2163 struct ospf6_distance *odistance;
2164
2165 if (ospf6->distance_all)
2166 vty_out(vty, " distance %u\n", ospf6->distance_all);
2167
2168 if (ospf6->distance_intra || ospf6->distance_inter
2169 || ospf6->distance_external) {
2170 vty_out(vty, " distance ospf6");
2171
2172 if (ospf6->distance_intra)
2173 vty_out(vty, " intra-area %u", ospf6->distance_intra);
2174 if (ospf6->distance_inter)
2175 vty_out(vty, " inter-area %u", ospf6->distance_inter);
2176 if (ospf6->distance_external)
2177 vty_out(vty, " external %u", ospf6->distance_external);
2178
2179 vty_out(vty, "\n");
2180 }
2181
2182 for (rn = route_top(ospf6->distance_table); rn; rn = route_next(rn))
2dbe669b
DA
2183 if ((odistance = rn->info) != NULL)
2184 vty_out(vty, " distance %u %pFX %s\n",
2185 odistance->distance, &rn->p,
d62a17ae 2186 odistance->access_list ? odistance->access_list
2187 : "");
d62a17ae 2188 return 0;
baff583e
MZ
2189}
2190
4dc43886
MR
2191static int ospf6_asbr_summary_config_write(struct vty *vty, struct ospf6 *ospf6)
2192{
2193 struct route_node *rn;
2194 struct ospf6_external_aggr_rt *aggr;
2195 char buf[PREFIX2STR_BUFFER];
2196
2197 if (ospf6->aggr_delay_interval != OSPF6_EXTL_AGGR_DEFAULT_DELAY)
2198 vty_out(vty, " aggregation timer %u\n",
2199 ospf6->aggr_delay_interval);
2200
2201 /* print 'summary-address A:B::C:D/M' */
78982818
MR
2202 for (rn = route_top(ospf6->rt_aggr_tbl); rn; rn = route_next(rn)) {
2203 if (!rn->info)
2204 continue;
4dc43886 2205
78982818 2206 aggr = rn->info;
4dc43886 2207
78982818
MR
2208 prefix2str(&aggr->p, buf, sizeof(buf));
2209 vty_out(vty, " summary-address %s", buf);
2210 if (aggr->tag)
2211 vty_out(vty, " tag %u", aggr->tag);
4dc43886 2212
78982818
MR
2213 if (aggr->metric != -1)
2214 vty_out(vty, " metric %d", aggr->metric);
4dc43886 2215
78982818
MR
2216 if (aggr->mtype != DEFAULT_METRIC_TYPE)
2217 vty_out(vty, " metric-type %d", aggr->mtype);
2218
2219 if (CHECK_FLAG(aggr->aggrflags,
2220 OSPF6_EXTERNAL_AGGRT_NO_ADVERTISE))
2221 vty_out(vty, " no-advertise");
2222
2223 vty_out(vty, "\n");
2224 }
4dc43886
MR
2225
2226 return 0;
2227}
2228
508e53e2 2229/* OSPF configuration write function. */
d62a17ae 2230static int config_write_ospf6(struct vty *vty)
508e53e2 2231{
beadc736 2232 struct ospf6 *ospf6;
2233 struct listnode *node, *nnode;
d62a17ae 2234
2235 /* OSPFv3 configuration. */
beadc736 2236 if (om6 == NULL)
d62a17ae 2237 return CMD_SUCCESS;
2238
beadc736 2239 for (ALL_LIST_ELEMENTS(om6->ospf6, node, nnode, ospf6)) {
d48ef099 2240 if (ospf6->name && strcmp(ospf6->name, VRF_DEFAULT_NAME))
2241 vty_out(vty, "router ospf6 vrf %s\n", ospf6->name);
2242 else
2243 vty_out(vty, "router ospf6\n");
2244
beadc736 2245 if (ospf6->router_id_static != 0)
2246 vty_out(vty, " ospf6 router-id %pI4\n",
2247 &ospf6->router_id_static);
2248
870791a3
IR
2249 if (CHECK_FLAG(ospf6->config_flags,
2250 OSPF6_SEND_EXTRA_DATA_TO_ZEBRA))
2251 vty_out(vty, " ospf6 send-extra-data zebra\n");
5b5d66c4 2252
beadc736 2253 /* log-adjacency-changes flag print. */
2254 if (CHECK_FLAG(ospf6->config_flags,
2255 OSPF6_LOG_ADJACENCY_CHANGES)) {
2256 if (CHECK_FLAG(ospf6->config_flags,
2257 OSPF6_LOG_ADJACENCY_DETAIL))
2258 vty_out(vty, " log-adjacency-changes detail\n");
2259 else if (!SAVE_OSPF6_LOG_ADJACENCY_CHANGES)
2260 vty_out(vty, " log-adjacency-changes\n");
2261 } else if (SAVE_OSPF6_LOG_ADJACENCY_CHANGES) {
2262 vty_out(vty, " no log-adjacency-changes\n");
2263 }
d62a17ae 2264
beadc736 2265 if (ospf6->ref_bandwidth != OSPF6_REFERENCE_BANDWIDTH)
2266 vty_out(vty, " auto-cost reference-bandwidth %d\n",
2267 ospf6->ref_bandwidth);
2268
78156066
PR
2269 if (ospf6->write_oi_count
2270 != OSPF6_WRITE_INTERFACE_COUNT_DEFAULT)
2271 vty_out(vty, " write-multiplier %d\n",
2272 ospf6->write_oi_count);
2273
beadc736 2274 /* LSA timers print. */
2275 if (ospf6->lsa_minarrival != OSPF_MIN_LS_ARRIVAL)
2276 vty_out(vty, " timers lsa min-arrival %d\n",
2277 ospf6->lsa_minarrival);
2278
1958143e
MR
2279 /* ECMP max path config */
2280 if (ospf6->max_multipath != MULTIPATH_NUM)
2281 vty_out(vty, " maximum-paths %d\n",
2282 ospf6->max_multipath);
2283
beadc736 2284 ospf6_stub_router_config_write(vty, ospf6);
2285 ospf6_redistribute_config_write(vty, ospf6);
2286 ospf6_area_config_write(vty, ospf6);
2287 ospf6_spf_config_write(vty, ospf6);
2288 ospf6_distance_config_write(vty, ospf6);
b19502d3 2289 ospf6_distribute_config_write(vty, ospf6);
4dc43886 2290 ospf6_asbr_summary_config_write(vty, ospf6);
71165098 2291 config_write_ospf6_gr(vty, ospf6);
0fc3e113 2292 config_write_ospf6_gr_helper(vty, ospf6);
07679ad9
IR
2293
2294 vty_out(vty, "exit\n");
beadc736 2295 vty_out(vty, "!\n");
d62a17ae 2296 }
d62a17ae 2297 return 0;
508e53e2 2298}
2299
612c2c15 2300static int config_write_ospf6(struct vty *vty);
508e53e2 2301/* OSPF6 node structure. */
d62a17ae 2302static struct cmd_node ospf6_node = {
f4b8291f 2303 .name = "ospf6",
62b346ee 2304 .node = OSPF6_NODE,
24389580 2305 .parent_node = CONFIG_NODE,
62b346ee 2306 .prompt = "%s(config-ospf6)# ",
612c2c15 2307 .config_write = config_write_ospf6,
508e53e2 2308};
2309
f71ed6df
YR
2310void install_element_ospf6_clear_process(void)
2311{
2312 install_element(ENABLE_NODE, &clear_router_ospf6_cmd);
2313}
2314
508e53e2 2315/* Install ospf related commands. */
d62a17ae 2316void ospf6_top_init(void)
718e3744 2317{
d62a17ae 2318 /* Install ospf6 top node. */
612c2c15 2319 install_node(&ospf6_node);
d62a17ae 2320
2321 install_element(VIEW_NODE, &show_ipv6_ospf6_cmd);
dd7fb1db 2322 install_element(VIEW_NODE, &show_ipv6_ospf6_vrfs_cmd);
d62a17ae 2323 install_element(CONFIG_NODE, &router_ospf6_cmd);
2324 install_element(CONFIG_NODE, &no_router_ospf6_cmd);
2325
2326 install_element(VIEW_NODE, &show_ipv6_ospf6_route_cmd);
2327 install_element(VIEW_NODE, &show_ipv6_ospf6_route_match_cmd);
2328 install_element(VIEW_NODE, &show_ipv6_ospf6_route_match_detail_cmd);
2329 install_element(VIEW_NODE, &show_ipv6_ospf6_route_type_detail_cmd);
2330
2331 install_default(OSPF6_NODE);
2332 install_element(OSPF6_NODE, &ospf6_router_id_cmd);
5d1a2ee8 2333 install_element(OSPF6_NODE, &no_ospf6_router_id_cmd);
d62a17ae 2334 install_element(OSPF6_NODE, &ospf6_log_adjacency_changes_cmd);
2335 install_element(OSPF6_NODE, &ospf6_log_adjacency_changes_detail_cmd);
2336 install_element(OSPF6_NODE, &no_ospf6_log_adjacency_changes_cmd);
2337 install_element(OSPF6_NODE, &no_ospf6_log_adjacency_changes_detail_cmd);
5b5d66c4 2338 install_element(OSPF6_NODE, &ospf6_send_extra_data_cmd);
d62a17ae 2339
2340 /* LSA timers commands */
2341 install_element(OSPF6_NODE, &ospf6_timers_lsa_cmd);
2342 install_element(OSPF6_NODE, &no_ospf6_timers_lsa_cmd);
2343
2344 install_element(OSPF6_NODE, &ospf6_interface_area_cmd);
2345 install_element(OSPF6_NODE, &no_ospf6_interface_area_cmd);
2346 install_element(OSPF6_NODE, &ospf6_stub_router_admin_cmd);
2347 install_element(OSPF6_NODE, &no_ospf6_stub_router_admin_cmd);
508e53e2 2348
1958143e
MR
2349 /* maximum-paths command */
2350 install_element(OSPF6_NODE, &ospf6_max_multipath_cmd);
2351 install_element(OSPF6_NODE, &no_ospf6_max_multipath_cmd);
2352
4dc43886
MR
2353 /* ASBR Summarisation */
2354 install_element(OSPF6_NODE, &ospf6_external_route_aggregation_cmd);
2355 install_element(OSPF6_NODE, &no_ospf6_external_route_aggregation_cmd);
2356 install_element(OSPF6_NODE,
2357 &ospf6_external_route_aggregation_no_advertise_cmd);
2358 install_element(OSPF6_NODE,
2359 &no_ospf6_external_route_aggregation_no_advertise_cmd);
2360 install_element(OSPF6_NODE, &ospf6_route_aggregation_timer_cmd);
2361 install_element(OSPF6_NODE, &no_ospf6_route_aggregation_timer_cmd);
2362 install_element(VIEW_NODE, &show_ipv6_ospf6_external_aggregator_cmd);
2363
d62a17ae 2364 install_element(OSPF6_NODE, &ospf6_distance_cmd);
2365 install_element(OSPF6_NODE, &no_ospf6_distance_cmd);
2366 install_element(OSPF6_NODE, &ospf6_distance_ospf6_cmd);
2367 install_element(OSPF6_NODE, &no_ospf6_distance_ospf6_cmd);
718e3744 2368}