]> git.proxmox.com Git - mirror_frr.git/blame - ospf6d/ospf6_top.c
Merge pull request #13646 from donaldsharp/logically_illogical
[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);
88b3d5e5
RW
458
459 /*
460 * Read from non-volatile memory whether this instance is performing a
461 * graceful restart or not.
462 */
463 ospf6_gr_nvm_read(ospf6);
464
42cabc55
IR
465 if (ospf6->vrf_id != VRF_UNKNOWN) {
466 vrf = vrf_lookup_by_id(ospf6->vrf_id);
467 FOR_ALL_INTERFACES (vrf, ifp) {
468 if (ifp->info)
469 ospf6_interface_start(ifp->info);
470 }
471 }
4e8ccd92 472 if (ospf6->fd < 0)
473 return ospf6;
474
907a2395
DS
475 event_add_read(master, ospf6_receive, ospf6, ospf6->fd,
476 &ospf6->t_ospf6_receive);
beadc736 477
478 return ospf6;
7df1f362
K
479}
480
d62a17ae 481void ospf6_delete(struct ospf6 *o)
718e3744 482{
d62a17ae 483 struct listnode *node, *nnode;
4dc43886 484 struct route_node *rn = NULL;
d62a17ae 485 struct ospf6_area *oa;
92699b9b 486 struct vrf *vrf;
a28474d3 487 struct ospf6_external_aggr_rt *aggr;
718e3744 488
d62a17ae 489 QOBJ_UNREG(o);
76249532 490
59790f52 491 ospf6_gr_helper_deinit(o);
71165098
RW
492 if (!o->gr_info.prepare_in_progress)
493 ospf6_flush_self_originated_lsas_now(o);
88b3d5e5 494 XFREE(MTYPE_TMP, o->gr_info.exit_reason);
beadc736 495 ospf6_disable(o);
496 ospf6_del(o);
ae2254aa 497
4e8ccd92 498 ospf6_zebra_vrf_deregister(o);
499
d3136990
IR
500 ospf6_serv_close(&o->fd);
501
d62a17ae 502 for (ALL_LIST_ELEMENTS(o->area_list, node, nnode, oa))
503 ospf6_area_delete(oa);
d9628728
CF
504
505
6a154c88 506 list_delete(&o->area_list);
718e3744 507
d62a17ae 508 ospf6_lsdb_delete(o->lsdb);
509 ospf6_lsdb_delete(o->lsdb_self);
718e3744 510
e285b70d
IR
511 ospf6_route_table_delete(o->route_table);
512 ospf6_route_table_delete(o->brouter_table);
718e3744 513
e285b70d 514 ospf6_route_table_delete(o->external_table);
718e3744 515
d62a17ae 516 ospf6_distance_reset(o);
517 route_table_finish(o->distance_table);
4f7bf1ab 518 list_delete(&o->oi_write_q);
baff583e 519
92699b9b
IR
520 if (o->vrf_id != VRF_UNKNOWN) {
521 vrf = vrf_lookup_by_id(o->vrf_id);
522 if (vrf)
523 ospf6_vrf_unlink(o, vrf);
524 }
525
4dc43886 526 for (rn = route_top(o->rt_aggr_tbl); rn; rn = route_next(rn))
a28474d3
MN
527 if (rn->info) {
528 aggr = rn->info;
529 ospf6_asbr_summary_config_delete(o, rn);
530 ospf6_external_aggregator_free(aggr);
531 }
4dc43886
MR
532 route_table_finish(o->rt_aggr_tbl);
533
7df1f362 534 XFREE(MTYPE_OSPF6_TOP, o->name);
d62a17ae 535 XFREE(MTYPE_OSPF6_TOP, o);
508e53e2 536}
718e3744 537
d62a17ae 538static void ospf6_disable(struct ospf6 *o)
718e3744 539{
d62a17ae 540 struct listnode *node, *nnode;
541 struct ospf6_area *oa;
542
543 if (!CHECK_FLAG(o->flag, OSPF6_DISABLED)) {
544 SET_FLAG(o->flag, OSPF6_DISABLED);
545
546 for (ALL_LIST_ELEMENTS(o->area_list, node, nnode, oa))
547 ospf6_area_disable(oa);
548
549 /* XXX: This also changes persistent settings */
a069482f 550 /* Unregister redistribution */
f71ed6df 551 ospf6_asbr_redistribute_disable(o);
d62a17ae 552
553 ospf6_lsdb_remove_all(o->lsdb);
e285b70d
IR
554 ospf6_route_remove_all(o->route_table);
555 ospf6_route_remove_all(o->brouter_table);
d62a17ae 556
e16d030c
DS
557 EVENT_OFF(o->maxage_remover);
558 EVENT_OFF(o->t_spf_calc);
559 EVENT_OFF(o->t_ase_calc);
560 EVENT_OFF(o->t_distribute_update);
561 EVENT_OFF(o->t_ospf6_receive);
562 EVENT_OFF(o->t_external_aggr);
563 EVENT_OFF(o->gr_info.t_grace_period);
564 EVENT_OFF(o->t_write);
565 EVENT_OFF(o->t_abr_task);
d62a17ae 566 }
508e53e2 567}
718e3744 568
cd9d0537 569void ospf6_master_init(struct event_loop *master)
78c6ba61 570{
6006b807 571 memset(&ospf6_master, 0, sizeof(ospf6_master));
78c6ba61
CS
572
573 om6 = &ospf6_master;
beadc736 574 om6->ospf6 = list_new();
575 om6->master = master;
78c6ba61
CS
576}
577
e6685141 578static void ospf6_maxage_remover(struct event *thread)
508e53e2 579{
e16d030c 580 struct ospf6 *o = (struct ospf6 *)EVENT_ARG(thread);
d62a17ae 581 struct ospf6_area *oa;
582 struct ospf6_interface *oi;
583 struct ospf6_neighbor *on;
584 struct listnode *i, *j, *k;
585 int reschedule = 0;
586
d62a17ae 587 for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa)) {
588 for (ALL_LIST_ELEMENTS_RO(oa->if_list, j, oi)) {
589 for (ALL_LIST_ELEMENTS_RO(oi->neighbor_list, k, on)) {
590 if (on->state != OSPF6_NEIGHBOR_EXCHANGE
591 && on->state != OSPF6_NEIGHBOR_LOADING)
592 continue;
593
594 ospf6_maxage_remove(o);
cc9f21da 595 return;
d62a17ae 596 }
597 }
2449fcd6 598 }
d62a17ae 599
600 for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa)) {
601 for (ALL_LIST_ELEMENTS_RO(oa->if_list, j, oi)) {
602 if (ospf6_lsdb_maxage_remover(oi->lsdb)) {
603 reschedule = 1;
604 }
605 }
606
607 if (ospf6_lsdb_maxage_remover(oa->lsdb)) {
608 reschedule = 1;
609 }
2449fcd6 610 }
2449fcd6 611
d62a17ae 612 if (ospf6_lsdb_maxage_remover(o->lsdb)) {
613 reschedule = 1;
614 }
2449fcd6 615
d62a17ae 616 if (reschedule) {
617 ospf6_maxage_remove(o);
618 }
718e3744 619}
620
d62a17ae 621void ospf6_maxage_remove(struct ospf6 *o)
718e3744 622{
d62a17ae 623 if (o)
907a2395
DS
624 event_add_timer(master, ospf6_maxage_remover, o,
625 OSPF_LSA_MAXAGE_REMOVE_DELAY_DEFAULT,
626 &o->maxage_remover);
718e3744 627}
628
a3049476 629bool ospf6_router_id_update(struct ospf6 *ospf6, bool init)
78c6ba61 630{
436a55a1
LS
631 in_addr_t new_router_id;
632 struct listnode *node;
633 struct ospf6_area *oa;
634
78c6ba61 635 if (!ospf6)
a3049476 636 return true;
78c6ba61
CS
637
638 if (ospf6->router_id_static != 0)
436a55a1 639 new_router_id = ospf6->router_id_static;
78c6ba61 640 else
436a55a1
LS
641 new_router_id = ospf6->router_id_zebra;
642
643 if (ospf6->router_id == new_router_id)
a3049476 644 return true;
436a55a1
LS
645
646 if (!init)
647 for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, node, oa)) {
648 if (oa->full_nbrs) {
649 zlog_err(
e2874251 650 "%s: cannot update router-id. Run the \"clear ipv6 ospf6 process\" command",
436a55a1 651 __func__);
a3049476 652 return false;
436a55a1
LS
653 }
654 }
655
656 ospf6->router_id = new_router_id;
a3049476 657 return true;
78c6ba61
CS
658}
659
508e53e2 660/* start ospf6 */
d48ef099 661DEFUN_NOSH(router_ospf6, router_ospf6_cmd, "router ospf6 [vrf NAME]",
662 ROUTER_STR OSPF6_STR VRF_CMD_HELP_STR)
718e3744 663{
beadc736 664 struct ospf6 *ospf6;
d48ef099 665 const char *vrf_name = VRF_DEFAULT_NAME;
666 int idx_vrf = 0;
beadc736 667
d48ef099 668 if (argv_find(argv, argc, "vrf", &idx_vrf)) {
669 vrf_name = argv[idx_vrf + 1]->arg;
670 }
671
672 ospf6 = ospf6_lookup_by_vrf_name(vrf_name);
7df1f362 673 if (ospf6 == NULL)
d48ef099 674 ospf6 = ospf6_instance_create(vrf_name);
7df1f362 675
d62a17ae 676 /* set current ospf point. */
677 VTY_PUSH_CONTEXT(OSPF6_NODE, ospf6);
508e53e2 678
d62a17ae 679 return CMD_SUCCESS;
718e3744 680}
681
508e53e2 682/* stop ospf6 */
d48ef099 683DEFUN(no_router_ospf6, no_router_ospf6_cmd, "no router ospf6 [vrf NAME]",
684 NO_STR ROUTER_STR OSPF6_STR VRF_CMD_HELP_STR)
718e3744 685{
beadc736 686 struct ospf6 *ospf6;
d48ef099 687 const char *vrf_name = VRF_DEFAULT_NAME;
688 int idx_vrf = 0;
beadc736 689
d48ef099 690 if (argv_find(argv, argc, "vrf", &idx_vrf)) {
691 vrf_name = argv[idx_vrf + 1]->arg;
692 }
693
694 ospf6 = ospf6_lookup_by_vrf_name(vrf_name);
d62a17ae 695 if (ospf6 == NULL)
696 vty_out(vty, "OSPFv3 is not configured\n");
697 else {
88b3d5e5
RW
698 if (ospf6->gr_info.restart_support)
699 ospf6_gr_nvm_delete(ospf6);
700
d62a17ae 701 ospf6_delete(ospf6);
702 ospf6 = NULL;
703 }
34288970 704
d62a17ae 705 /* return to config node . */
706 VTY_PUSH_CONTEXT_NULL(CONFIG_NODE);
508e53e2 707
d62a17ae 708 return CMD_SUCCESS;
718e3744 709}
710
f71ed6df
YR
711static void ospf6_db_clear(struct ospf6 *ospf6)
712{
713 struct ospf6_interface *oi;
714 struct interface *ifp;
715 struct vrf *vrf = vrf_lookup_by_id(ospf6->vrf_id);
716 struct listnode *node, *nnode;
717 struct ospf6_area *oa;
718
719 FOR_ALL_INTERFACES (vrf, ifp) {
720 if (if_is_operative(ifp) && ifp->info != NULL) {
721 oi = (struct ospf6_interface *)ifp->info;
722 ospf6_lsdb_remove_all(oi->lsdb);
723 ospf6_lsdb_remove_all(oi->lsdb_self);
724 ospf6_lsdb_remove_all(oi->lsupdate_list);
725 ospf6_lsdb_remove_all(oi->lsack_list);
726 }
727 }
728
729 for (ALL_LIST_ELEMENTS(ospf6->area_list, node, nnode, oa)) {
730 ospf6_lsdb_remove_all(oa->lsdb);
731 ospf6_lsdb_remove_all(oa->lsdb_self);
732
733 ospf6_spf_table_finish(oa->spf_table);
734 ospf6_route_remove_all(oa->route_table);
735 }
736
737 ospf6_lsdb_remove_all(ospf6->lsdb);
738 ospf6_lsdb_remove_all(ospf6->lsdb_self);
739 ospf6_route_remove_all(ospf6->route_table);
740 ospf6_route_remove_all(ospf6->brouter_table);
741}
742
743static void ospf6_process_reset(struct ospf6 *ospf6)
744{
745 struct interface *ifp;
746 struct vrf *vrf = vrf_lookup_by_id(ospf6->vrf_id);
747
c3a70f65 748 ospf6_unset_all_aggr_flag(ospf6);
f71ed6df
YR
749 ospf6_flush_self_originated_lsas_now(ospf6);
750 ospf6->inst_shutdown = 0;
751 ospf6_db_clear(ospf6);
752
f71ed6df
YR
753 ospf6_asbr_redistribute_reset(ospf6);
754 FOR_ALL_INTERFACES (vrf, ifp)
755 ospf6_interface_clear(ifp);
756}
757
758DEFPY (clear_router_ospf6,
759 clear_router_ospf6_cmd,
760 "clear ipv6 ospf6 process [vrf NAME$name]",
761 CLEAR_STR
762 IP6_STR
763 OSPF6_STR
764 "Reset OSPF Process\n"
765 VRF_CMD_HELP_STR)
766{
767 struct ospf6 *ospf6;
768 const char *vrf_name = VRF_DEFAULT_NAME;
769
770 if (name != NULL)
771 vrf_name = name;
772
773 ospf6 = ospf6_lookup_by_vrf_name(vrf_name);
078f6092 774 if (ospf6 == NULL) {
f71ed6df 775 vty_out(vty, "OSPFv3 is not configured\n");
078f6092
LS
776 } else {
777 ospf6_router_id_update(ospf6, true);
f71ed6df 778 ospf6_process_reset(ospf6);
078f6092 779 }
f71ed6df
YR
780
781 return CMD_SUCCESS;
782}
783
508e53e2 784/* change Router_ID commands. */
60466a63
QY
785DEFUN(ospf6_router_id,
786 ospf6_router_id_cmd,
787 "ospf6 router-id A.B.C.D",
788 OSPF6_STR
789 "Configure OSPF6 Router-ID\n"
790 V4NOTATION_STR)
718e3744 791{
d62a17ae 792 VTY_DECLVAR_CONTEXT(ospf6, o);
5d1a2ee8 793 int idx = 0;
d62a17ae 794 int ret;
5d1a2ee8 795 const char *router_id_str;
d7c0a89a 796 uint32_t router_id;
d62a17ae 797
5d1a2ee8
QY
798 argv_find(argv, argc, "A.B.C.D", &idx);
799 router_id_str = argv[idx]->arg;
800
801 ret = inet_pton(AF_INET, router_id_str, &router_id);
d62a17ae 802 if (ret == 0) {
60466a63 803 vty_out(vty, "malformed OSPF Router-ID: %s\n", router_id_str);
d62a17ae 804 return CMD_SUCCESS;
805 }
508e53e2 806
d62a17ae 807 o->router_id_static = router_id;
d6927cf3 808
078f6092
LS
809 if (ospf6_router_id_update(o, false))
810 ospf6_process_reset(o);
811 else
a3049476
LS
812 vty_out(vty,
813 "For this router-id change to take effect run the \"clear ipv6 ospf6 process\" command\n");
c8a440ec 814
d62a17ae 815 return CMD_SUCCESS;
718e3744 816}
817
60466a63
QY
818DEFUN(no_ospf6_router_id,
819 no_ospf6_router_id_cmd,
820 "no ospf6 router-id [A.B.C.D]",
821 NO_STR OSPF6_STR
822 "Configure OSPF6 Router-ID\n"
823 V4NOTATION_STR)
5d1a2ee8
QY
824{
825 VTY_DECLVAR_CONTEXT(ospf6, o);
d6927cf3 826
5d1a2ee8 827 o->router_id_static = 0;
d6927cf3 828
078f6092
LS
829
830 if (ospf6_router_id_update(o, false))
831 ospf6_process_reset(o);
832 else
a3049476
LS
833 vty_out(vty,
834 "For this router-id change to take effect run the \"clear ipv6 ospf6 process\" command\n");
5d1a2ee8
QY
835
836 return CMD_SUCCESS;
837}
838
3d35ca48
DD
839DEFUN (ospf6_log_adjacency_changes,
840 ospf6_log_adjacency_changes_cmd,
841 "log-adjacency-changes",
842 "Log changes in adjacency state\n")
843{
d62a17ae 844 VTY_DECLVAR_CONTEXT(ospf6, ospf6);
3d35ca48 845
d62a17ae 846 SET_FLAG(ospf6->config_flags, OSPF6_LOG_ADJACENCY_CHANGES);
847 UNSET_FLAG(ospf6->config_flags, OSPF6_LOG_ADJACENCY_DETAIL);
848 return CMD_SUCCESS;
3d35ca48
DD
849}
850
851DEFUN (ospf6_log_adjacency_changes_detail,
852 ospf6_log_adjacency_changes_detail_cmd,
853 "log-adjacency-changes detail",
692c7954 854 "Log changes in adjacency state\n"
3d35ca48
DD
855 "Log all state changes\n")
856{
d62a17ae 857 VTY_DECLVAR_CONTEXT(ospf6, ospf6);
3d35ca48 858
d62a17ae 859 SET_FLAG(ospf6->config_flags, OSPF6_LOG_ADJACENCY_CHANGES);
860 SET_FLAG(ospf6->config_flags, OSPF6_LOG_ADJACENCY_DETAIL);
861 return CMD_SUCCESS;
3d35ca48
DD
862}
863
864DEFUN (no_ospf6_log_adjacency_changes,
865 no_ospf6_log_adjacency_changes_cmd,
866 "no log-adjacency-changes",
692c7954 867 NO_STR
3d35ca48
DD
868 "Log changes in adjacency state\n")
869{
d62a17ae 870 VTY_DECLVAR_CONTEXT(ospf6, ospf6);
3d35ca48 871
d62a17ae 872 UNSET_FLAG(ospf6->config_flags, OSPF6_LOG_ADJACENCY_DETAIL);
873 UNSET_FLAG(ospf6->config_flags, OSPF6_LOG_ADJACENCY_CHANGES);
874 return CMD_SUCCESS;
3d35ca48
DD
875}
876
877DEFUN (no_ospf6_log_adjacency_changes_detail,
878 no_ospf6_log_adjacency_changes_detail_cmd,
879 "no log-adjacency-changes detail",
692c7954
DW
880 NO_STR
881 "Log changes in adjacency state\n"
3d35ca48
DD
882 "Log all state changes\n")
883{
d62a17ae 884 VTY_DECLVAR_CONTEXT(ospf6, ospf6);
3d35ca48 885
d62a17ae 886 UNSET_FLAG(ospf6->config_flags, OSPF6_LOG_ADJACENCY_DETAIL);
887 return CMD_SUCCESS;
3d35ca48
DD
888}
889
5b5d66c4
RW
890static void ospf6_reinstall_routes(struct ospf6 *ospf6)
891{
892 struct ospf6_route *route;
893
894 for (route = ospf6_route_head(ospf6->route_table); route;
895 route = ospf6_route_next(route))
896 ospf6_zebra_route_update_add(route, ospf6);
897}
898
899DEFPY (ospf6_send_extra_data,
900 ospf6_send_extra_data_cmd,
901 "[no] ospf6 send-extra-data zebra",
902 NO_STR
903 OSPF6_STR
904 "Extra data to Zebra for display/use\n"
905 "To zebra\n")
906{
907 VTY_DECLVAR_CONTEXT(ospf6, ospf6);
908
909 if (no
910 && CHECK_FLAG(ospf6->config_flags,
911 OSPF6_SEND_EXTRA_DATA_TO_ZEBRA)) {
912 UNSET_FLAG(ospf6->config_flags, OSPF6_SEND_EXTRA_DATA_TO_ZEBRA);
913 ospf6_reinstall_routes(ospf6);
914 } else if (!CHECK_FLAG(ospf6->config_flags,
915 OSPF6_SEND_EXTRA_DATA_TO_ZEBRA)) {
916 SET_FLAG(ospf6->config_flags, OSPF6_SEND_EXTRA_DATA_TO_ZEBRA);
917 ospf6_reinstall_routes(ospf6);
918 }
919
920 return CMD_SUCCESS;
921}
922
b6927875
DS
923DEFUN (ospf6_timers_lsa,
924 ospf6_timers_lsa_cmd,
6147e2c6 925 "timers lsa min-arrival (0-600000)",
b6927875
DS
926 "Adjust routing timers\n"
927 "OSPF6 LSA timers\n"
928 "Minimum delay in receiving new version of a LSA\n"
929 "Delay in milliseconds\n")
930{
d62a17ae 931 VTY_DECLVAR_CONTEXT(ospf6, ospf);
932 int idx_number = 3;
933 unsigned int minarrival;
b6927875 934
d62a17ae 935 minarrival = strtoul(argv[idx_number]->arg, NULL, 10);
936 ospf->lsa_minarrival = minarrival;
b6927875 937
d62a17ae 938 return CMD_SUCCESS;
b6927875
DS
939}
940
941DEFUN (no_ospf6_timers_lsa,
942 no_ospf6_timers_lsa_cmd,
1d68dbfe 943 "no timers lsa min-arrival [(0-600000)]",
b6927875
DS
944 NO_STR
945 "Adjust routing timers\n"
946 "OSPF6 LSA timers\n"
3a2d747c
QY
947 "Minimum delay in receiving new version of a LSA\n"
948 "Delay in milliseconds\n")
b6927875 949{
d62a17ae 950 VTY_DECLVAR_CONTEXT(ospf6, ospf);
951 int idx_number = 4;
952 unsigned int minarrival;
b6927875 953
d62a17ae 954 if (argc == 5) {
955 minarrival = strtoul(argv[idx_number]->arg, NULL, 10);
b6927875 956
d62a17ae 957 if (ospf->lsa_minarrival != minarrival
958 || minarrival == OSPF_MIN_LS_ARRIVAL)
959 return CMD_SUCCESS;
960 }
b6927875 961
d62a17ae 962 ospf->lsa_minarrival = OSPF_MIN_LS_ARRIVAL;
b6927875 963
d62a17ae 964 return CMD_SUCCESS;
b6927875
DS
965}
966
b6927875 967
baff583e
MZ
968DEFUN (ospf6_distance,
969 ospf6_distance_cmd,
39e92c06 970 "distance (1-255)",
baff583e
MZ
971 "Administrative distance\n"
972 "OSPF6 Administrative distance\n")
973{
d62a17ae 974 VTY_DECLVAR_CONTEXT(ospf6, o);
fcd45026 975 uint8_t distance;
baff583e 976
fcd45026 977 distance = atoi(argv[1]->arg);
978 if (o->distance_all != distance) {
979 o->distance_all = distance;
980 ospf6_restart_spf(o);
981 }
baff583e 982
d62a17ae 983 return CMD_SUCCESS;
baff583e
MZ
984}
985
986DEFUN (no_ospf6_distance,
987 no_ospf6_distance_cmd,
39e92c06 988 "no distance (1-255)",
baff583e
MZ
989 NO_STR
990 "Administrative distance\n"
991 "OSPF6 Administrative distance\n")
992{
d62a17ae 993 VTY_DECLVAR_CONTEXT(ospf6, o);
baff583e 994
fcd45026 995 if (o->distance_all) {
996 o->distance_all = 0;
997 ospf6_restart_spf(o);
998 }
d62a17ae 999 return CMD_SUCCESS;
baff583e
MZ
1000}
1001
1002DEFUN (ospf6_distance_ospf6,
1003 ospf6_distance_ospf6_cmd,
eaa1ae0d 1004 "distance ospf6 {intra-area (1-255)|inter-area (1-255)|external (1-255)}",
baff583e 1005 "Administrative distance\n"
eaa1ae0d 1006 "OSPF6 administrative distance\n"
39e92c06
QY
1007 "Intra-area routes\n"
1008 "Distance for intra-area routes\n"
1009 "Inter-area routes\n"
1010 "Distance for inter-area routes\n"
1011 "External routes\n"
baff583e
MZ
1012 "Distance for external routes\n")
1013{
d62a17ae 1014 VTY_DECLVAR_CONTEXT(ospf6, o);
1015 int idx = 0;
1016
f89a449b
CS
1017 o->distance_intra = 0;
1018 o->distance_inter = 0;
1019 o->distance_external = 0;
1020
d62a17ae 1021 if (argv_find(argv, argc, "intra-area", &idx))
1022 o->distance_intra = atoi(argv[idx + 1]->arg);
1023 idx = 0;
1024 if (argv_find(argv, argc, "inter-area", &idx))
1025 o->distance_inter = atoi(argv[idx + 1]->arg);
1026 idx = 0;
1027 if (argv_find(argv, argc, "external", &idx))
1028 o->distance_external = atoi(argv[idx + 1]->arg);
39e92c06 1029
d62a17ae 1030 return CMD_SUCCESS;
baff583e
MZ
1031}
1032
1033DEFUN (no_ospf6_distance_ospf6,
1034 no_ospf6_distance_ospf6_cmd,
eaa1ae0d 1035 "no distance ospf6 [{intra-area [(1-255)]|inter-area [(1-255)]|external [(1-255)]}]",
baff583e
MZ
1036 NO_STR
1037 "Administrative distance\n"
1038 "OSPF6 distance\n"
1039 "Intra-area routes\n"
1040 "Distance for intra-area routes\n"
1041 "Inter-area routes\n"
1042 "Distance for inter-area routes\n"
1043 "External routes\n"
1044 "Distance for external routes\n")
1045{
d62a17ae 1046 VTY_DECLVAR_CONTEXT(ospf6, o);
1047 int idx = 0;
baff583e 1048
d62a17ae 1049 if (argv_find(argv, argc, "intra-area", &idx) || argc == 3)
1050 idx = o->distance_intra = 0;
1051 if (argv_find(argv, argc, "inter-area", &idx) || argc == 3)
1052 idx = o->distance_inter = 0;
1053 if (argv_find(argv, argc, "external", &idx) || argc == 3)
1054 o->distance_external = 0;
baff583e 1055
d62a17ae 1056 return CMD_SUCCESS;
baff583e
MZ
1057}
1058
42cabc55 1059DEFUN_HIDDEN (ospf6_interface_area,
508e53e2 1060 ospf6_interface_area_cmd,
de842255 1061 "interface IFNAME area <A.B.C.D|(0-4294967295)>",
508e53e2 1062 "Enable routing on an IPv6 interface\n"
1063 IFNAME_STR
1064 "Specify the OSPF6 area ID\n"
1065 "OSPF6 area ID in IPv4 address notation\n"
de842255 1066 "OSPF6 area ID in decimal notation\n"
508e53e2 1067 )
718e3744 1068{
d48ef099 1069 VTY_DECLVAR_CONTEXT(ospf6, ospf6);
d62a17ae 1070 int idx_ifname = 1;
1071 int idx_ipv4 = 3;
1072 struct ospf6_area *oa;
1073 struct ospf6_interface *oi;
1074 struct interface *ifp;
42cabc55
IR
1075 uint32_t area_id;
1076 int format;
1077
1078 vty_out(vty,
1079 "This command is deprecated, because it is not VRF-aware.\n");
1080 vty_out(vty,
1081 "Please, use \"ipv6 ospf6 area\" on an interface instead.\n");
d62a17ae 1082
1083 /* find/create ospf6 interface */
f60a1188 1084 ifp = if_get_by_name(argv[idx_ifname]->arg, ospf6->vrf_id, ospf6->name);
d62a17ae 1085 oi = (struct ospf6_interface *)ifp->info;
1086 if (oi == NULL)
1087 oi = ospf6_interface_create(ifp);
1088 if (oi->area) {
1089 vty_out(vty, "%s already attached to Area %s\n",
1090 oi->interface->name, oi->area->name);
1091 return CMD_SUCCESS;
1092 }
6452df09 1093
42cabc55
IR
1094 if (str2area_id(argv[idx_ipv4]->arg, &area_id, &format)) {
1095 vty_out(vty, "Malformed Area-ID: %s\n", argv[idx_ipv4]->arg);
1096 return CMD_WARNING_CONFIG_FAILED;
1097 }
1098
1099 oi->area_id = area_id;
1100 oi->area_id_format = format;
1101
1102 oa = ospf6_area_lookup(area_id, ospf6);
1103 if (oa == NULL)
1104 oa = ospf6_area_create(area_id, ospf6, format);
d62a17ae 1105
1106 /* attach interface to area */
1107 listnode_add(oa->if_list, oi); /* sort ?? */
1108 oi->area = oa;
1109
1110 SET_FLAG(oa->flag, OSPF6_AREA_ENABLE);
1111
1112 /* ospf6 process is currently disabled, not much more to do */
beadc736 1113 if (CHECK_FLAG(ospf6->flag, OSPF6_DISABLED))
d62a17ae 1114 return CMD_SUCCESS;
1115
1116 /* start up */
1117 ospf6_interface_enable(oi);
1118
1119 /* If the router is ABR, originate summary routes */
95b3f03d 1120 if (ospf6_check_and_set_router_abr(ospf6)) {
d62a17ae 1121 ospf6_abr_enable_area(oa);
ad500b22
K
1122 ospf6_schedule_abr_task(oa->ospf6);
1123 }
d62a17ae 1124
1125 return CMD_SUCCESS;
718e3744 1126}
1127
42cabc55 1128DEFUN_HIDDEN (no_ospf6_interface_area,
508e53e2 1129 no_ospf6_interface_area_cmd,
de842255 1130 "no interface IFNAME area <A.B.C.D|(0-4294967295)>",
508e53e2 1131 NO_STR
1132 "Disable routing on an IPv6 interface\n"
1133 IFNAME_STR
1134 "Specify the OSPF6 area ID\n"
1135 "OSPF6 area ID in IPv4 address notation\n"
de842255 1136 "OSPF6 area ID in decimal notation\n"
508e53e2 1137 )
718e3744 1138{
d48ef099 1139 VTY_DECLVAR_CONTEXT(ospf6, ospf6);
d62a17ae 1140 int idx_ifname = 2;
1141 int idx_ipv4 = 4;
1142 struct ospf6_interface *oi;
1143 struct ospf6_area *oa;
1144 struct interface *ifp;
d7c0a89a 1145 uint32_t area_id;
d48ef099 1146
42cabc55
IR
1147 vty_out(vty,
1148 "This command is deprecated, because it is not VRF-aware.\n");
1149 vty_out(vty,
1150 "Please, use \"no ipv6 ospf6 area\" on an interface instead.\n");
1151
d48ef099 1152 /* find/create ospf6 interface */
f60a1188 1153 ifp = if_get_by_name(argv[idx_ifname]->arg, ospf6->vrf_id, ospf6->name);
d62a17ae 1154
d62a17ae 1155 if (ifp == NULL) {
1156 vty_out(vty, "No such interface %s\n", argv[idx_ifname]->arg);
1157 return CMD_SUCCESS;
1158 }
6452df09 1159
d62a17ae 1160 oi = (struct ospf6_interface *)ifp->info;
1161 if (oi == NULL) {
1162 vty_out(vty, "Interface %s not enabled\n", ifp->name);
1163 return CMD_SUCCESS;
1164 }
1165
1166 /* parse Area-ID */
de842255
PR
1167 if (inet_pton(AF_INET, argv[idx_ipv4]->arg, &area_id) != 1)
1168 area_id = htonl(strtoul(argv[idx_ipv4]->arg, NULL, 10));
d62a17ae 1169
1170 /* Verify Area */
1171 if (oi->area == NULL) {
800cc918 1172 vty_out(vty, "%s not attached to area %s\n",
f85a4112 1173 oi->interface->name, argv[idx_ipv4]->arg);
d62a17ae 1174 return CMD_SUCCESS;
1175 }
1176
1177 if (oi->area->area_id != area_id) {
1178 vty_out(vty, "Wrong Area-ID: %s is attached to area %s\n",
1179 oi->interface->name, oi->area->name);
1180 return CMD_SUCCESS;
1181 }
1182
4a30f056 1183 ospf6_interface_disable(oi);
d62a17ae 1184
1185 oa = oi->area;
1186 listnode_delete(oi->area->if_list, oi);
1187 oi->area = (struct ospf6_area *)NULL;
1188
1189 /* Withdraw inter-area routes from this area, if necessary */
1190 if (oa->if_list->count == 0) {
1191 UNSET_FLAG(oa->flag, OSPF6_AREA_ENABLE);
1192 ospf6_abr_disable_area(oa);
1193 }
1194
42cabc55
IR
1195 oi->area_id = 0;
1196 oi->area_id_format = OSPF6_AREA_FMT_UNSET;
1197
d62a17ae 1198 return CMD_SUCCESS;
718e3744 1199}
1200
f41b4a02
DD
1201DEFUN (ospf6_stub_router_admin,
1202 ospf6_stub_router_admin_cmd,
1203 "stub-router administrative",
1204 "Make router a stub router\n"
f41b4a02
DD
1205 "Administratively applied, for an indefinite period\n")
1206{
d62a17ae 1207 struct listnode *node;
1208 struct ospf6_area *oa;
1209
beadc736 1210 VTY_DECLVAR_CONTEXT(ospf6, ospf6);
1211
d62a17ae 1212 if (!CHECK_FLAG(ospf6->flag, OSPF6_STUB_ROUTER)) {
1213 for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, node, oa)) {
1214 OSPF6_OPT_CLEAR(oa->options, OSPF6_OPT_V6);
1215 OSPF6_OPT_CLEAR(oa->options, OSPF6_OPT_R);
1216 OSPF6_ROUTER_LSA_SCHEDULE(oa);
1217 }
1218 SET_FLAG(ospf6->flag, OSPF6_STUB_ROUTER);
f41b4a02 1219 }
f41b4a02 1220
d62a17ae 1221 return CMD_SUCCESS;
f41b4a02
DD
1222}
1223
1224DEFUN (no_ospf6_stub_router_admin,
1225 no_ospf6_stub_router_admin_cmd,
1226 "no stub-router administrative",
1227 NO_STR
1228 "Make router a stub router\n"
f41b4a02
DD
1229 "Administratively applied, for an indefinite period\n")
1230{
d62a17ae 1231 struct listnode *node;
1232 struct ospf6_area *oa;
1233
beadc736 1234 VTY_DECLVAR_CONTEXT(ospf6, ospf6);
d62a17ae 1235 if (CHECK_FLAG(ospf6->flag, OSPF6_STUB_ROUTER)) {
1236 for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, node, oa)) {
1237 OSPF6_OPT_SET(oa->options, OSPF6_OPT_V6);
1238 OSPF6_OPT_SET(oa->options, OSPF6_OPT_R);
1239 OSPF6_ROUTER_LSA_SCHEDULE(oa);
1240 }
1241 UNSET_FLAG(ospf6->flag, OSPF6_STUB_ROUTER);
f41b4a02 1242 }
f41b4a02 1243
d62a17ae 1244 return CMD_SUCCESS;
f41b4a02
DD
1245}
1246
1958143e 1247/* Restart OSPF SPF algorithm*/
fcd45026 1248void ospf6_restart_spf(struct ospf6 *ospf6)
1958143e
MR
1249{
1250 ospf6_route_remove_all(ospf6->route_table);
1251 ospf6_route_remove_all(ospf6->brouter_table);
1958143e
MR
1252
1253 /* Trigger SPF */
1254 ospf6_spf_schedule(ospf6, OSPF6_SPF_FLAGS_CONFIG_CHANGE);
1255}
1256
1257/* Set the max paths */
1258static void ospf6_maxpath_set(struct ospf6 *ospf6, uint16_t paths)
1259{
1260 if (ospf6->max_multipath == paths)
1261 return;
1262
1263 ospf6->max_multipath = paths;
1264
1265 /* Send deletion to zebra to delete all
1266 * ospf specific routes and reinitiate
1267 * SPF to reflect the new max multipath.
1268 */
1269 ospf6_restart_spf(ospf6);
1270}
1271
1272/* Ospf Maximum-paths config support */
1273DEFUN(ospf6_max_multipath,
1274 ospf6_max_multipath_cmd,
1275 "maximum-paths " CMD_RANGE_STR(1, MULTIPATH_NUM),
1276 "Max no of multiple paths for ECMP support\n"
1277 "Number of paths\n")
1278{
1279 VTY_DECLVAR_CONTEXT(ospf6, ospf6);
1280 int idx_number = 1;
1281 int maximum_paths = strtol(argv[idx_number]->arg, NULL, 10);
1282
1283 ospf6_maxpath_set(ospf6, maximum_paths);
1284
1285 return CMD_SUCCESS;
1286}
1287
1288DEFUN(no_ospf6_max_multipath,
1289 no_ospf6_max_multipath_cmd,
1290 "no maximum-paths [" CMD_RANGE_STR(1, MULTIPATH_NUM)"]",
1291 NO_STR
1292 "Max no of multiple paths for ECMP support\n"
1293 "Number of paths\n")
1294{
1295 VTY_DECLVAR_CONTEXT(ospf6, ospf6);
1296
1297 ospf6_maxpath_set(ospf6, MULTIPATH_NUM);
1298
1299 return CMD_SUCCESS;
1300}
1301
35a45dea 1302static void ospf6_show(struct vty *vty, struct ospf6 *o, json_object *json,
1303 bool use_json)
718e3744 1304{
d62a17ae 1305 struct listnode *n;
1306 struct ospf6_area *oa;
1307 char router_id[16], duration[32];
1308 struct timeval now, running, result;
1309 char buf[32], rbuf[32];
35a45dea 1310 json_object *json_areas = NULL;
1311 const char *adjacency;
1312
1313 if (use_json) {
1314 json_areas = json_object_new_object();
1315
1316 /* process id, router id */
1317 inet_ntop(AF_INET, &o->router_id, router_id, sizeof(router_id));
1318 json_object_string_add(json, "routerId", router_id);
1319
1320 /* running time */
1321 monotime(&now);
1322 timersub(&now, &o->starttime, &running);
1323 timerstring(&running, duration, sizeof(duration));
1324 json_object_string_add(json, "running", duration);
1325
1326 /* Redistribute configuration */
1327 /* XXX */
1328 json_object_int_add(json, "lsaMinimumArrivalMsecs",
1329 o->lsa_minarrival);
1330
1331 /* Show SPF parameters */
1332 json_object_int_add(json, "spfScheduleDelayMsecs",
1333 o->spf_delay);
1334 json_object_int_add(json, "holdTimeMinMsecs", o->spf_holdtime);
1335 json_object_int_add(json, "holdTimeMaxMsecs",
1336 o->spf_max_holdtime);
1337 json_object_int_add(json, "holdTimeMultiplier",
1338 o->spf_hold_multiplier);
1339
1958143e 1340 json_object_int_add(json, "maximumPaths", o->max_multipath);
94c78d3b 1341 json_object_int_add(json, "preference",
1342 o->distance_all
1343 ? o->distance_all
1344 : ZEBRA_OSPF6_DISTANCE_DEFAULT);
35a45dea 1345
1346 if (o->ts_spf.tv_sec || o->ts_spf.tv_usec) {
1347 timersub(&now, &o->ts_spf, &result);
1348 timerstring(&result, buf, sizeof(buf));
1349 ospf6_spf_reason_string(o->last_spf_reason, rbuf,
1350 sizeof(rbuf));
1351 json_object_boolean_true_add(json, "spfHasRun");
1352 json_object_string_add(json, "spfLastExecutedMsecs",
1353 buf);
1354 json_object_string_add(json, "spfLastExecutedReason",
1355 rbuf);
1356
1357 json_object_int_add(
1358 json, "spfLastDurationSecs",
1359 (long long)o->ts_spf_duration.tv_sec);
1360
1361 json_object_int_add(
1362 json, "spfLastDurationMsecs",
1363 (long long)o->ts_spf_duration.tv_usec);
1364 } else
1365 json_object_boolean_false_add(json, "spfHasRun");
1366
5f6eaa9b 1367 if (event_is_scheduled(o->t_spf_calc)) {
35a45dea 1368 long time_store;
1369
1370 json_object_boolean_true_add(json, "spfTimerActive");
1371 time_store =
1372 monotime_until(&o->t_spf_calc->u.sands, NULL)
1373 / 1000LL;
1374 json_object_int_add(json, "spfTimerDueInMsecs",
1375 time_store);
1376 } else
1377 json_object_boolean_false_add(json, "spfTimerActive");
1378
1379 json_object_boolean_add(json, "routerIsStubRouter",
1380 CHECK_FLAG(o->flag, OSPF6_STUB_ROUTER));
1381
1382 /* LSAs */
1383 json_object_int_add(json, "numberOfAsScopedLsa",
1384 o->lsdb->count);
1385 /* Areas */
1386 json_object_int_add(json, "numberOfAreaInRouter",
1387 listcount(o->area_list));
1388
6cb85350
AR
1389 json_object_int_add(json, "AuthTrailerHigherSeqNo",
1390 o->seqnum_h);
1391 json_object_int_add(json, "AuthTrailerLowerSeqNo", o->seqnum_l);
1392
35a45dea 1393 if (CHECK_FLAG(o->config_flags, OSPF6_LOG_ADJACENCY_CHANGES)) {
1394 if (CHECK_FLAG(o->config_flags,
1395 OSPF6_LOG_ADJACENCY_DETAIL))
1396 adjacency = "LoggedAll";
1397 else
1398 adjacency = "Logged";
1399 } else
1400 adjacency = "NotLogged";
1401 json_object_string_add(json, "adjacencyChanges", adjacency);
1402
1403 for (ALL_LIST_ELEMENTS_RO(o->area_list, n, oa))
1404 ospf6_area_show(vty, oa, json_areas, use_json);
1405
1406 json_object_object_add(json, "areas", json_areas);
1407
1408 vty_out(vty, "%s\n",
1409 json_object_to_json_string_ext(
1410 json, JSON_C_TO_STRING_PRETTY));
1411
1412 } else {
1413 /* process id, router id */
1414 inet_ntop(AF_INET, &o->router_id, router_id, sizeof(router_id));
1415 vty_out(vty, " OSPFv3 Routing Process (0) with Router-ID %s\n",
1416 router_id);
1417
1418 /* running time */
1419 monotime(&now);
1420 timersub(&now, &o->starttime, &running);
1421 timerstring(&running, duration, sizeof(duration));
1422 vty_out(vty, " Running %s\n", duration);
1423
1424 /* Redistribute configuration */
1425 /* XXX */
1426 vty_out(vty, " LSA minimum arrival %d msecs\n",
1427 o->lsa_minarrival);
1428
1958143e 1429 vty_out(vty, " Maximum-paths %u\n", o->max_multipath);
94c78d3b 1430 vty_out(vty, " Administrative distance %u\n",
1431 o->distance_all ? o->distance_all
1432 : ZEBRA_OSPF6_DISTANCE_DEFAULT);
35a45dea 1433
1434 /* Show SPF parameters */
1435 vty_out(vty,
1436 " Initial SPF scheduling delay %d millisec(s)\n"
1437 " Minimum hold time between consecutive SPFs %d millsecond(s)\n"
1438 " Maximum hold time between consecutive SPFs %d millsecond(s)\n"
1439 " Hold time multiplier is currently %d\n",
1440 o->spf_delay, o->spf_holdtime, o->spf_max_holdtime,
1441 o->spf_hold_multiplier);
1442
1443
1444 vty_out(vty, " SPF algorithm ");
1445 if (o->ts_spf.tv_sec || o->ts_spf.tv_usec) {
1446 timersub(&now, &o->ts_spf, &result);
1447 timerstring(&result, buf, sizeof(buf));
1448 ospf6_spf_reason_string(o->last_spf_reason, rbuf,
1449 sizeof(rbuf));
1450 vty_out(vty, "last executed %s ago, reason %s\n", buf,
1451 rbuf);
1452 vty_out(vty, " Last SPF duration %lld sec %lld usec\n",
1453 (long long)o->ts_spf_duration.tv_sec,
1454 (long long)o->ts_spf_duration.tv_usec);
1455 } else
1456 vty_out(vty, "has not been run\n");
1457
1458 threadtimer_string(now, o->t_spf_calc, buf, sizeof(buf));
1459 vty_out(vty, " SPF timer %s%s\n",
5f6eaa9b 1460 (event_is_scheduled(o->t_spf_calc) ? "due in " : "is "),
c905f04c 1461 buf);
35a45dea 1462
1463 if (CHECK_FLAG(o->flag, OSPF6_STUB_ROUTER))
1464 vty_out(vty, " Router Is Stub Router\n");
1465
1466 /* LSAs */
1467 vty_out(vty, " Number of AS scoped LSAs is %u\n",
1468 o->lsdb->count);
1469
1470 /* Areas */
1471 vty_out(vty, " Number of areas in this router is %u\n",
1472 listcount(o->area_list));
1473
6cb85350
AR
1474 vty_out(vty, " Authentication Sequence number info\n");
1475 vty_out(vty, " Higher sequence no %u, Lower sequence no %u\n",
1476 o->seqnum_h, o->seqnum_l);
1477
35a45dea 1478 if (CHECK_FLAG(o->config_flags, OSPF6_LOG_ADJACENCY_CHANGES)) {
1479 if (CHECK_FLAG(o->config_flags,
1480 OSPF6_LOG_ADJACENCY_DETAIL))
1481 vty_out(vty,
1482 " All adjacency changes are logged\n");
1483 else
1484 vty_out(vty, " Adjacency changes are logged\n");
1485 }
d62a17ae 1486
d62a17ae 1487
35a45dea 1488 vty_out(vty, "\n");
d62a17ae 1489
35a45dea 1490 for (ALL_LIST_ELEMENTS_RO(o->area_list, n, oa))
1491 ospf6_area_show(vty, oa, json_areas, use_json);
1492 }
718e3744 1493}
1494
dd7fb1db
PG
1495DEFUN(show_ipv6_ospf6_vrfs, show_ipv6_ospf6_vrfs_cmd,
1496 "show ipv6 ospf6 vrfs [json]",
1497 SHOW_STR IP6_STR OSPF6_STR "Show OSPF6 VRFs \n" JSON_STR)
1498{
1499 bool uj = use_json(argc, argv);
1500 json_object *json = NULL;
1501 json_object *json_vrfs = NULL;
1502 struct ospf6 *ospf6 = NULL;
1503 struct listnode *node = NULL;
1504 int count = 0;
1505 char buf[PREFIX_STRLEN];
1506 static const char header[] =
1507 "Name Id RouterId ";
1508
1509 if (uj) {
1510 json = json_object_new_object();
1511 json_vrfs = json_object_new_object();
1512 }
1513
1514 for (ALL_LIST_ELEMENTS_RO(om6->ospf6, node, ospf6)) {
1515 json_object *json_vrf = NULL;
1516 const char *name = NULL;
1517 int64_t vrf_id_ui = 0;
1518 struct in_addr router_id;
1519
1520 router_id.s_addr = ospf6->router_id;
1521 count++;
1522
1523 if (!uj && count == 1)
1524 vty_out(vty, "%s\n", header);
1525 if (uj)
1526 json_vrf = json_object_new_object();
1527
1528 if (ospf6->vrf_id == VRF_DEFAULT)
1529 name = VRF_DEFAULT_NAME;
1530 else
1531 name = ospf6->name;
1532
1533 vrf_id_ui = (ospf6->vrf_id == VRF_UNKNOWN)
1534 ? -1
1535 : (int64_t)ospf6->vrf_id;
1536
1537 if (uj) {
1538 json_object_int_add(json_vrf, "vrfId", vrf_id_ui);
ce4b236f
DA
1539 json_object_string_addf(json_vrf, "routerId", "%pI4",
1540 &router_id);
dd7fb1db
PG
1541 json_object_object_add(json_vrfs, name, json_vrf);
1542
1543 } else {
1544 vty_out(vty, "%-25s %-5d %-16s \n", name,
1545 ospf6->vrf_id,
1546 inet_ntop(AF_INET, &router_id, buf,
1547 sizeof(buf)));
1548 }
1549 }
1550
1551 if (uj) {
1552 json_object_object_add(json, "vrfs", json_vrfs);
1553 json_object_int_add(json, "totalVrfs", count);
1554
5a6c232b 1555 vty_json(vty, json);
dd7fb1db
PG
1556 } else {
1557 if (count)
1558 vty_out(vty, "\nTotal number of OSPF VRFs: %d\n",
1559 count);
1560 }
1561
1562 return CMD_SUCCESS;
1563}
1564
508e53e2 1565/* show top level structures */
d48ef099 1566DEFUN(show_ipv6_ospf6, show_ipv6_ospf6_cmd,
1567 "show ipv6 ospf6 [vrf <NAME|all>] [json]",
1568 SHOW_STR IP6_STR OSPF6_STR VRF_CMD_HELP_STR "All VRFs\n" JSON_STR)
718e3744 1569{
beadc736 1570 struct ospf6 *ospf6;
d48ef099 1571 struct listnode *node;
1572 const char *vrf_name = NULL;
1573 bool all_vrf = false;
1574 int idx_vrf = 0;
1575
35a45dea 1576 bool uj = use_json(argc, argv);
1577 json_object *json = NULL;
508e53e2 1578
d48ef099 1579 OSPF6_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
35a45dea 1580
d48ef099 1581 for (ALL_LIST_ELEMENTS_RO(om6->ospf6, node, ospf6)) {
1582 if (all_vrf || strcmp(ospf6->name, vrf_name) == 0) {
1583 if (uj)
1584 json = json_object_new_object();
1585 ospf6_show(vty, ospf6, json, uj);
35a45dea 1586
d48ef099 1587 if (!all_vrf)
1588 break;
1589 }
1590 }
35a45dea 1591
1592 if (uj)
1593 json_object_free(json);
d48ef099 1594
d6b901ac 1595 OSPF6_CMD_CHECK_VRF(uj, all_vrf, ospf6);
1596
d62a17ae 1597 return CMD_SUCCESS;
718e3744 1598}
1599
d48ef099 1600DEFUN(show_ipv6_ospf6_route, show_ipv6_ospf6_route_cmd,
1601 "show ipv6 ospf6 [vrf <NAME|all>] route [<intra-area|inter-area|external-1|external-2|X:X::X:X|X:X::X:X/M|detail|summary>] [json]",
1602 SHOW_STR IP6_STR OSPF6_STR VRF_CMD_HELP_STR
1603 "All VRFs\n" ROUTE_STR
1604 "Display Intra-Area routes\n"
1605 "Display Inter-Area routes\n"
1606 "Display Type-1 External routes\n"
1607 "Display Type-2 External routes\n"
1608 "Specify IPv6 address\n"
1609 "Specify IPv6 prefix\n"
1610 "Detailed information\n"
1611 "Summary of route table\n" JSON_STR)
718e3744 1612{
beadc736 1613 struct ospf6 *ospf6;
d48ef099 1614 struct listnode *node;
1615 const char *vrf_name = NULL;
1616 bool all_vrf = false;
1617 int idx_vrf = 0;
1618 int idx_arg_start = 4;
eacd0828 1619 bool uj = use_json(argc, argv);
beadc736 1620
d48ef099 1621 OSPF6_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
1622 if (idx_vrf > 0)
1623 idx_arg_start += 2;
1624
1625 for (ALL_LIST_ELEMENTS_RO(om6->ospf6, node, ospf6)) {
1626 if (all_vrf || strcmp(ospf6->name, vrf_name) == 0) {
1627 ospf6_route_table_show(vty, idx_arg_start, argc, argv,
1628 ospf6->route_table, uj);
1629
1630 if (!all_vrf)
1631 break;
1632 }
1633 }
b52a8a52 1634
d6b901ac 1635 OSPF6_CMD_CHECK_VRF(uj, all_vrf, ospf6);
1636
d62a17ae 1637 return CMD_SUCCESS;
718e3744 1638}
1639
d48ef099 1640DEFUN(show_ipv6_ospf6_route_match, show_ipv6_ospf6_route_match_cmd,
1641 "show ipv6 ospf6 [vrf <NAME|all>] route X:X::X:X/M <match|longer> [json]",
1642 SHOW_STR IP6_STR OSPF6_STR VRF_CMD_HELP_STR
1643 "All VRFs\n" ROUTE_STR
1644 "Specify IPv6 prefix\n"
1645 "Display routes which match the specified route\n"
1646 "Display routes longer than the specified route\n" JSON_STR)
718e3744 1647{
beadc736 1648 struct ospf6 *ospf6;
d48ef099 1649 struct listnode *node;
1650 const char *vrf_name = NULL;
1651 bool all_vrf = false;
1652 int idx_vrf = 0;
1653 int idx_start_arg = 4;
eacd0828 1654 bool uj = use_json(argc, argv);
beadc736 1655
d48ef099 1656 OSPF6_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
1657 if (idx_vrf > 0)
1658 idx_start_arg += 2;
1659
1660 for (ALL_LIST_ELEMENTS_RO(om6->ospf6, node, ospf6)) {
1661 if (all_vrf || strcmp(ospf6->name, vrf_name) == 0) {
1662 ospf6_route_table_show(vty, idx_start_arg, argc, argv,
1663 ospf6->route_table, uj);
1664
1665 if (!all_vrf)
1666 break;
1667 }
1668 }
b52a8a52 1669
d6b901ac 1670 OSPF6_CMD_CHECK_VRF(uj, all_vrf, ospf6);
1671
d62a17ae 1672 return CMD_SUCCESS;
718e3744 1673}
1674
d48ef099 1675DEFUN(show_ipv6_ospf6_route_match_detail,
1676 show_ipv6_ospf6_route_match_detail_cmd,
1677 "show ipv6 ospf6 [vrf <NAME|all>] route X:X::X:X/M match detail [json]",
1678 SHOW_STR IP6_STR OSPF6_STR VRF_CMD_HELP_STR
1679 "All VRFs\n" ROUTE_STR
1680 "Specify IPv6 prefix\n"
1681 "Display routes which match the specified route\n"
1682 "Detailed information\n" JSON_STR)
508e53e2 1683{
beadc736 1684 struct ospf6 *ospf6;
d48ef099 1685 struct listnode *node;
1686 const char *vrf_name = NULL;
1687 bool all_vrf = false;
1688 int idx_vrf = 0;
1689 int idx_start_arg = 4;
eacd0828 1690 bool uj = use_json(argc, argv);
beadc736 1691
d48ef099 1692 OSPF6_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
1693 if (idx_vrf > 0)
1694 idx_start_arg += 2;
1695
1696 for (ALL_LIST_ELEMENTS_RO(om6->ospf6, node, ospf6)) {
1697 if (all_vrf || strcmp(ospf6->name, vrf_name) == 0) {
1698 ospf6_route_table_show(vty, idx_start_arg, argc, argv,
1699 ospf6->route_table, uj);
1700
1701 if (!all_vrf)
1702 break;
1703 }
1704 }
b52a8a52 1705
d6b901ac 1706 OSPF6_CMD_CHECK_VRF(uj, all_vrf, ospf6);
1707
d62a17ae 1708 return CMD_SUCCESS;
508e53e2 1709}
718e3744 1710
d48ef099 1711DEFUN(show_ipv6_ospf6_route_type_detail, show_ipv6_ospf6_route_type_detail_cmd,
1712 "show ipv6 ospf6 [vrf <NAME|all>] route <intra-area|inter-area|external-1|external-2> detail [json]",
1713 SHOW_STR IP6_STR OSPF6_STR VRF_CMD_HELP_STR
1714 "All VRFs\n" ROUTE_STR
1715 "Display Intra-Area routes\n"
1716 "Display Inter-Area routes\n"
1717 "Display Type-1 External routes\n"
1718 "Display Type-2 External routes\n"
1719 "Detailed information\n" JSON_STR)
4846ef64 1720{
beadc736 1721 struct ospf6 *ospf6;
d48ef099 1722 struct listnode *node;
1723 const char *vrf_name = NULL;
1724 bool all_vrf = false;
1725 int idx_vrf = 0;
1726 int idx_start_arg = 4;
eacd0828 1727 bool uj = use_json(argc, argv);
beadc736 1728
d48ef099 1729 OSPF6_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
1730 if (idx_vrf > 0)
1731 idx_start_arg += 2;
1732
1733 for (ALL_LIST_ELEMENTS_RO(om6->ospf6, node, ospf6)) {
1734 if (all_vrf || strcmp(ospf6->name, vrf_name) == 0) {
1735 ospf6_route_table_show(vty, idx_start_arg, argc, argv,
1736 ospf6->route_table, uj);
1737
1738 if (!all_vrf)
1739 break;
1740 }
1741 }
b52a8a52 1742
d6b901ac 1743 OSPF6_CMD_CHECK_VRF(uj, all_vrf, ospf6);
1744
d62a17ae 1745 return CMD_SUCCESS;
4846ef64 1746}
718e3744 1747
4dc43886
MR
1748bool ospf6_is_valid_summary_addr(struct vty *vty, struct prefix *p)
1749{
23b11ab1
DS
1750 /* Default prefix validation*/
1751 if (is_default_prefix(p)) {
1752 vty_out(vty,
1753 "Default address should not be configured as summary address.\n");
4dc43886
MR
1754 return false;
1755 }
1756
c3a70f65
MR
1757 /* Host route should not be configured as summary address */
1758 if (p->prefixlen == IPV6_MAX_BITLEN) {
4dc43886 1759 vty_out(vty, "Host route should not be configured as summary address.\n");
c3a70f65 1760 return false;
4dc43886
MR
1761 }
1762
c3a70f65 1763 return true;
4dc43886
MR
1764}
1765
1766/* External Route Aggregation */
1767DEFPY (ospf6_external_route_aggregation,
1768 ospf6_external_route_aggregation_cmd,
1769 "summary-address X:X::X:X/M$prefix [tag (1-4294967295)] [{metric (0-16777215) | metric-type (1-2)$mtype}]",
1770 "External summary address\n"
1771 "Specify IPv6 prefix\n"
1772 "Router tag \n"
1773 "Router tag value\n"
1774 "Metric \n"
1775 "Advertised metric for this route\n"
1776 "OSPFv3 exterior metric type for summarised routes\n"
1777 "Set OSPFv3 External Type 1/2 metrics\n")
1778{
1779 VTY_DECLVAR_CONTEXT(ospf6, ospf6);
1780
1781 struct prefix p;
1782 int ret = CMD_SUCCESS;
c3a70f65 1783
4dc43886
MR
1784 p.family = AF_INET6;
1785 ret = str2prefix(prefix_str, &p);
1786 if (ret == 0) {
1787 vty_out(vty, "Malformed prefix\n");
1788 return CMD_WARNING_CONFIG_FAILED;
1789 }
1790
1791 /* Apply mask for given prefix. */
8998807f 1792 apply_mask(&p);
4dc43886
MR
1793
1794 if (!ospf6_is_valid_summary_addr(vty, &p))
1795 return CMD_WARNING_CONFIG_FAILED;
1796
1797 if (!tag_str)
1798 tag = 0;
1799
1800 if (!metric_str)
1801 metric = -1;
1802
1803 if (!mtype_str)
1804 mtype = DEFAULT_METRIC_TYPE;
1805
1806 ret = ospf6_external_aggr_config_set(ospf6, &p, tag, metric, mtype);
1807 if (ret == OSPF6_FAILURE) {
1808 vty_out(vty, "Invalid configuration!!\n");
1809 return CMD_WARNING_CONFIG_FAILED;
1810 }
1811
1812 return CMD_SUCCESS;
1813}
1814
1815DEFPY(no_ospf6_external_route_aggregation,
1816 no_ospf6_external_route_aggregation_cmd,
1817 "no summary-address X:X::X:X/M$prefix [tag (1-4294967295)] [{metric (0-16777215) | metric-type (1-2)}]",
1818 NO_STR
1819 "External summary address\n"
1820 "Specify IPv6 prefix\n"
1821 "Router tag\n"
1822 "Router tag value\n"
1823 "Metric \n"
1824 "Advertised metric for this route\n"
1825 "OSPFv3 exterior metric type for summarised routes\n"
1826 "Set OSPFv3 External Type 1/2 metrics\n")
1827{
1828 VTY_DECLVAR_CONTEXT(ospf6, ospf6);
1829
1830 struct prefix p;
1831 int ret = CMD_SUCCESS;
1832
1833 ret = str2prefix(prefix_str, &p);
1834 if (ret == 0) {
1835 vty_out(vty, "Malformed prefix\n");
1836 return CMD_WARNING_CONFIG_FAILED;
1837 }
1838
1839 /* Apply mask for given prefix. */
8998807f 1840 apply_mask(&p);
4dc43886
MR
1841
1842 if (!ospf6_is_valid_summary_addr(vty, &p))
1843 return CMD_WARNING_CONFIG_FAILED;
1844
1845 ret = ospf6_external_aggr_config_unset(ospf6, &p);
1846 if (ret == OSPF6_INVALID)
1847 vty_out(vty, "Invalid configuration!!\n");
1848
1849 return CMD_SUCCESS;
1850}
1851
1852DEFPY (ospf6_external_route_aggregation_no_advertise,
1853 ospf6_external_route_aggregation_no_advertise_cmd,
1854 "summary-address X:X::X:X/M$prefix no-advertise",
1855 "External summary address\n"
1856 "Specify IPv6 prefix\n"
1857 "Don't advertise summary route \n")
1858{
1859 VTY_DECLVAR_CONTEXT(ospf6, ospf6);
1860
1861 struct prefix p;
1862 int ret = CMD_SUCCESS;
1863
1864 ret = str2prefix(prefix_str, &p);
1865 if (ret == 0) {
1866 vty_out(vty, "Malformed prefix\n");
1867 return CMD_WARNING_CONFIG_FAILED;
1868 }
1869
1870 /* Apply mask for given prefix. */
8998807f 1871 apply_mask(&p);
4dc43886
MR
1872
1873 if (!ospf6_is_valid_summary_addr(vty, &p))
1874 return CMD_WARNING_CONFIG_FAILED;
1875
1876 ret = ospf6_asbr_external_rt_no_advertise(ospf6, &p);
1877 if (ret == OSPF6_INVALID)
1878 vty_out(vty, "!!Invalid configuration\n");
1879
c3a70f65 1880 return CMD_SUCCESS;
4dc43886
MR
1881}
1882
1883DEFPY (no_ospf6_external_route_aggregation_no_advertise,
1884 no_ospf6_external_route_aggregation_no_advertise_cmd,
1885 "no summary-address X:X::X:X/M$prefix no-advertise",
1886 NO_STR
1887 "External summary address\n"
1888 "Specify IPv6 prefix\n"
1889 "Adverise summary route to the AS \n")
1890{
1891 VTY_DECLVAR_CONTEXT(ospf6, ospf6);
1892
1893 struct prefix p;
1894 int ret = CMD_SUCCESS;
1895
1896 ret = str2prefix(prefix_str, &p);
1897 if (ret == 0) {
1898 vty_out(vty, "Malformed prefix\n");
1899 return CMD_WARNING_CONFIG_FAILED;
1900 }
1901
1902 /* Apply mask for given prefix. */
8998807f 1903 apply_mask(&p);
4dc43886
MR
1904
1905 if (!ospf6_is_valid_summary_addr(vty, &p))
1906 return CMD_WARNING_CONFIG_FAILED;
1907
1908 ret = ospf6_asbr_external_rt_advertise(ospf6, &p);
1909 if (ret == OSPF6_INVALID)
1910 vty_out(vty, "!!Invalid configuration\n");
1911
1912 return CMD_SUCCESS;
1913}
1914
1915DEFPY (ospf6_route_aggregation_timer,
1916 ospf6_route_aggregation_timer_cmd,
1917 "aggregation timer (5-1800)",
1918 "External route aggregation\n"
1919 "Delay timer (in seconds)\n"
1920 "Timer interval(in seconds)\n")
1921{
1922 VTY_DECLVAR_CONTEXT(ospf6, ospf6);
1923
1924 ospf6_external_aggr_delay_timer_set(ospf6, timer);
1925
1926 return CMD_SUCCESS;
1927}
1928
1929DEFPY (no_ospf6_route_aggregation_timer,
1930 no_ospf6_route_aggregation_timer_cmd,
1931 "no aggregation timer [5-1800]",
1932 NO_STR
1933 "External route aggregation\n"
1934 "Delay timer\n"
1935 "Timer interval(in seconds)\n")
1936{
1937 VTY_DECLVAR_CONTEXT(ospf6, ospf6);
1938
1939 ospf6_external_aggr_delay_timer_set(ospf6,
1940 OSPF6_EXTL_AGGR_DEFAULT_DELAY);
1941 return CMD_SUCCESS;
1942}
1943
1944static int
1945ospf6_print_vty_external_routes_walkcb(struct hash_bucket *bucket, void *arg)
1946{
1947 struct ospf6_route *rt = bucket->data;
1948 struct vty *vty = (struct vty *)arg;
1949 static unsigned int count;
1950
1951 vty_out(vty, "%pFX ", &rt->prefix);
1952
1953 count++;
1954
1955 if (count%5 == 0)
1956 vty_out(vty, "\n");
1957
1958 if (OSPF6_EXTERNAL_RT_COUNT(rt->aggr_route) == count)
1959 count = 0;
1960
1961 return HASHWALK_CONTINUE;
1962}
1963
1964static int
1965ospf6_print_json_external_routes_walkcb(struct hash_bucket *bucket, void *arg)
1966{
1967 struct ospf6_route *rt = bucket->data;
1968 struct json_object *json = (struct json_object *)arg;
1969 char buf[PREFIX2STR_BUFFER];
1970 char exnalbuf[20];
1971 static unsigned int count;
1972
1973 prefix2str(&rt->prefix, buf, sizeof(buf));
1974
78982818 1975 snprintf(exnalbuf, sizeof(exnalbuf), "Exnl Addr-%d", count);
4dc43886
MR
1976
1977 json_object_string_add(json, exnalbuf, buf);
1978
1979 count++;
1980
1981 if (OSPF6_EXTERNAL_RT_COUNT(rt->aggr_route) == count)
1982 count = 0;
1983
1984 return HASHWALK_CONTINUE;
1985}
1986
ad21f6c2
MR
1987static void
1988ospf6_show_vrf_name(struct vty *vty, struct ospf6 *ospf6,
1989 json_object *json)
1990{
1991 if (json) {
1992 if (ospf6->vrf_id == VRF_DEFAULT)
1993 json_object_string_add(json, "vrfName",
1994 "default");
1995 else
1996 json_object_string_add(json, "vrfName",
1997 ospf6->name);
1998 json_object_int_add(json, "vrfId", ospf6->vrf_id);
1999 } else {
2000 if (ospf6->vrf_id == VRF_DEFAULT)
2001 vty_out(vty, "VRF Name: %s\n", "default");
2002 else if (ospf6->name)
2003 vty_out(vty, "VRF Name: %s\n", ospf6->name);
2004 }
2005}
2006
4dc43886
MR
2007static int
2008ospf6_show_summary_address(struct vty *vty, struct ospf6 *ospf6,
2009 json_object *json,
2010 bool uj, const char *detail)
2011{
2012 struct route_node *rn;
c3a70f65 2013 static const char header[] = "Summary-address Metric-type Metric Tag External_Rt_count\n";
ad21f6c2 2014 json_object *json_vrf = NULL;
4dc43886
MR
2015
2016 if (!uj) {
ad21f6c2 2017 ospf6_show_vrf_name(vty, ospf6, json_vrf);
74e8311e 2018 vty_out(vty, "aggregation delay interval :%u(in seconds)\n\n",
2019 ospf6->aggr_delay_interval);
4dc43886 2020 vty_out(vty, "%s\n", header);
c3a70f65 2021 } else {
ad21f6c2
MR
2022 json_vrf = json_object_new_object();
2023
2024 ospf6_show_vrf_name(vty, ospf6, json_vrf);
2025
08d79bce
DA
2026 json_object_int_add(json_vrf, "aggregationDelayInterval",
2027 ospf6->aggr_delay_interval);
c3a70f65 2028 }
4dc43886 2029
ad21f6c2 2030
78982818
MR
2031 for (rn = route_top(ospf6->rt_aggr_tbl); rn; rn = route_next(rn)) {
2032 if (!rn->info)
2033 continue;
4dc43886 2034
78982818
MR
2035 struct ospf6_external_aggr_rt *aggr = rn->info;
2036 json_object *json_aggr = NULL;
2037 char buf[PREFIX2STR_BUFFER];
4dc43886 2038
78982818 2039 prefix2str(&aggr->p, buf, sizeof(buf));
4dc43886 2040
78982818 2041 if (uj) {
4dc43886 2042
78982818 2043 json_aggr = json_object_new_object();
4dc43886 2044
ad21f6c2 2045 json_object_object_add(json_vrf,
78982818
MR
2046 buf,
2047 json_aggr);
4dc43886 2048
08d79bce
DA
2049 json_object_string_add(json_aggr, "summaryAddress",
2050 buf);
4dc43886 2051
08d79bce
DA
2052 json_object_string_add(
2053 json_aggr, "metricType",
2054 (aggr->mtype == DEFAULT_METRIC_TYPE) ? "E2"
2055 : "E1");
78982818
MR
2056
2057 json_object_int_add(json_aggr, "Metric",
2058 (aggr->metric != -1)
2059 ? aggr->metric
2060 : DEFAULT_DEFAULT_METRIC);
4dc43886 2061
78982818
MR
2062 json_object_int_add(json_aggr, "Tag",
2063 aggr->tag);
4dc43886 2064
08d79bce
DA
2065 json_object_int_add(json_aggr, "externalRouteCount",
2066 OSPF6_EXTERNAL_RT_COUNT(aggr));
4dc43886 2067
78982818
MR
2068 if (OSPF6_EXTERNAL_RT_COUNT(aggr) && detail) {
2069 json_object_int_add(json_aggr, "ID",
2070 aggr->id);
2071 json_object_int_add(json_aggr, "Flags",
2072 aggr->aggrflags);
2073 hash_walk(aggr->match_extnl_hash,
2074 ospf6_print_json_external_routes_walkcb,
2075 json_aggr);
2076 }
2077
2078 } else {
2079 vty_out(vty, "%-22s", buf);
2080
2081 (aggr->mtype == DEFAULT_METRIC_TYPE)
2082 ? vty_out(vty, "%-16s", "E2")
2083 : vty_out(vty, "%-16s", "E1");
2084 vty_out(vty, "%-11d", (aggr->metric != -1)
2085 ? aggr->metric
2086 : DEFAULT_DEFAULT_METRIC);
2087
2088 vty_out(vty, "%-12u", aggr->tag);
4dc43886 2089
78982818
MR
2090 vty_out(vty, "%-5ld\n",
2091 OSPF6_EXTERNAL_RT_COUNT(aggr));
2092
2093 if (OSPF6_EXTERNAL_RT_COUNT(aggr) && detail) {
2094 vty_out(vty,
2095 "Matched External routes:\n");
2096 hash_walk(aggr->match_extnl_hash,
2097 ospf6_print_vty_external_routes_walkcb,
2098 vty);
4dc43886
MR
2099 vty_out(vty, "\n");
2100 }
78982818
MR
2101
2102 vty_out(vty, "\n");
4dc43886 2103 }
78982818 2104 }
4dc43886 2105
ad21f6c2
MR
2106 if (uj)
2107 json_object_object_add(json, ospf6->name,
2108 json_vrf);
2109
4dc43886
MR
2110 return CMD_SUCCESS;
2111}
2112
2113DEFPY (show_ipv6_ospf6_external_aggregator,
2114 show_ipv6_ospf6_external_aggregator_cmd,
ad21f6c2 2115 "show ipv6 ospf6 [vrf <NAME|all>] summary-address [detail$detail] [json]",
4dc43886
MR
2116 SHOW_STR
2117 IP6_STR
2118 OSPF6_STR
ad21f6c2
MR
2119 VRF_CMD_HELP_STR
2120 "All VRFs\n"
4dc43886 2121 "Show external summary addresses\n"
bbf5104c 2122 "detailed information\n"
4dc43886
MR
2123 JSON_STR)
2124{
2125 bool uj = use_json(argc, argv);
2126 struct ospf6 *ospf6 = NULL;
c3a70f65 2127 json_object *json = NULL;
ad21f6c2
MR
2128 const char *vrf_name = NULL;
2129 struct listnode *node;
2130 bool all_vrf = false;
2131 int idx_vrf = 0;
4dc43886
MR
2132
2133 if (uj)
2134 json = json_object_new_object();
2135
ad21f6c2 2136 OSPF6_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
4dc43886 2137
ad21f6c2
MR
2138 for (ALL_LIST_ELEMENTS_RO(om6->ospf6, node, ospf6)) {
2139 if (all_vrf || strcmp(ospf6->name, vrf_name) == 0) {
4dc43886 2140
ad21f6c2
MR
2141 ospf6_show_summary_address(vty, ospf6, json, uj,
2142 detail);
2143
2144 if (!all_vrf)
2145 break;
2146 }
2147 }
4dc43886
MR
2148
2149 if (uj) {
5a6c232b 2150 vty_json(vty, json);
4dc43886
MR
2151 }
2152
d6b901ac 2153 OSPF6_CMD_CHECK_VRF(uj, all_vrf, ospf6);
2154
4dc43886
MR
2155 return CMD_SUCCESS;
2156}
2157
beadc736 2158static void ospf6_stub_router_config_write(struct vty *vty, struct ospf6 *ospf6)
f41b4a02 2159{
c48349e3 2160 if (CHECK_FLAG(ospf6->flag, OSPF6_STUB_ROUTER))
d62a17ae 2161 vty_out(vty, " stub-router administrative\n");
d62a17ae 2162 return;
f41b4a02
DD
2163}
2164
beadc736 2165static int ospf6_distance_config_write(struct vty *vty, struct ospf6 *ospf6)
baff583e 2166{
d62a17ae 2167 struct route_node *rn;
2168 struct ospf6_distance *odistance;
2169
2170 if (ospf6->distance_all)
2171 vty_out(vty, " distance %u\n", ospf6->distance_all);
2172
2173 if (ospf6->distance_intra || ospf6->distance_inter
2174 || ospf6->distance_external) {
2175 vty_out(vty, " distance ospf6");
2176
2177 if (ospf6->distance_intra)
2178 vty_out(vty, " intra-area %u", ospf6->distance_intra);
2179 if (ospf6->distance_inter)
2180 vty_out(vty, " inter-area %u", ospf6->distance_inter);
2181 if (ospf6->distance_external)
2182 vty_out(vty, " external %u", ospf6->distance_external);
2183
2184 vty_out(vty, "\n");
2185 }
2186
2187 for (rn = route_top(ospf6->distance_table); rn; rn = route_next(rn))
2dbe669b
DA
2188 if ((odistance = rn->info) != NULL)
2189 vty_out(vty, " distance %u %pFX %s\n",
2190 odistance->distance, &rn->p,
d62a17ae 2191 odistance->access_list ? odistance->access_list
2192 : "");
d62a17ae 2193 return 0;
baff583e
MZ
2194}
2195
4dc43886
MR
2196static int ospf6_asbr_summary_config_write(struct vty *vty, struct ospf6 *ospf6)
2197{
2198 struct route_node *rn;
2199 struct ospf6_external_aggr_rt *aggr;
2200 char buf[PREFIX2STR_BUFFER];
2201
2202 if (ospf6->aggr_delay_interval != OSPF6_EXTL_AGGR_DEFAULT_DELAY)
2203 vty_out(vty, " aggregation timer %u\n",
2204 ospf6->aggr_delay_interval);
2205
2206 /* print 'summary-address A:B::C:D/M' */
78982818
MR
2207 for (rn = route_top(ospf6->rt_aggr_tbl); rn; rn = route_next(rn)) {
2208 if (!rn->info)
2209 continue;
4dc43886 2210
78982818 2211 aggr = rn->info;
4dc43886 2212
78982818
MR
2213 prefix2str(&aggr->p, buf, sizeof(buf));
2214 vty_out(vty, " summary-address %s", buf);
2215 if (aggr->tag)
2216 vty_out(vty, " tag %u", aggr->tag);
4dc43886 2217
78982818
MR
2218 if (aggr->metric != -1)
2219 vty_out(vty, " metric %d", aggr->metric);
4dc43886 2220
78982818
MR
2221 if (aggr->mtype != DEFAULT_METRIC_TYPE)
2222 vty_out(vty, " metric-type %d", aggr->mtype);
2223
2224 if (CHECK_FLAG(aggr->aggrflags,
2225 OSPF6_EXTERNAL_AGGRT_NO_ADVERTISE))
2226 vty_out(vty, " no-advertise");
2227
2228 vty_out(vty, "\n");
2229 }
4dc43886
MR
2230
2231 return 0;
2232}
2233
508e53e2 2234/* OSPF configuration write function. */
d62a17ae 2235static int config_write_ospf6(struct vty *vty)
508e53e2 2236{
beadc736 2237 struct ospf6 *ospf6;
2238 struct listnode *node, *nnode;
d62a17ae 2239
2240 /* OSPFv3 configuration. */
beadc736 2241 if (om6 == NULL)
d62a17ae 2242 return CMD_SUCCESS;
2243
beadc736 2244 for (ALL_LIST_ELEMENTS(om6->ospf6, node, nnode, ospf6)) {
d48ef099 2245 if (ospf6->name && strcmp(ospf6->name, VRF_DEFAULT_NAME))
2246 vty_out(vty, "router ospf6 vrf %s\n", ospf6->name);
2247 else
2248 vty_out(vty, "router ospf6\n");
2249
beadc736 2250 if (ospf6->router_id_static != 0)
2251 vty_out(vty, " ospf6 router-id %pI4\n",
2252 &ospf6->router_id_static);
2253
870791a3
IR
2254 if (CHECK_FLAG(ospf6->config_flags,
2255 OSPF6_SEND_EXTRA_DATA_TO_ZEBRA))
2256 vty_out(vty, " ospf6 send-extra-data zebra\n");
5b5d66c4 2257
beadc736 2258 /* log-adjacency-changes flag print. */
2259 if (CHECK_FLAG(ospf6->config_flags,
2260 OSPF6_LOG_ADJACENCY_CHANGES)) {
2261 if (CHECK_FLAG(ospf6->config_flags,
2262 OSPF6_LOG_ADJACENCY_DETAIL))
2263 vty_out(vty, " log-adjacency-changes detail\n");
2264 else if (!SAVE_OSPF6_LOG_ADJACENCY_CHANGES)
2265 vty_out(vty, " log-adjacency-changes\n");
2266 } else if (SAVE_OSPF6_LOG_ADJACENCY_CHANGES) {
2267 vty_out(vty, " no log-adjacency-changes\n");
2268 }
d62a17ae 2269
beadc736 2270 if (ospf6->ref_bandwidth != OSPF6_REFERENCE_BANDWIDTH)
2271 vty_out(vty, " auto-cost reference-bandwidth %d\n",
2272 ospf6->ref_bandwidth);
2273
78156066
PR
2274 if (ospf6->write_oi_count
2275 != OSPF6_WRITE_INTERFACE_COUNT_DEFAULT)
2276 vty_out(vty, " write-multiplier %d\n",
2277 ospf6->write_oi_count);
2278
beadc736 2279 /* LSA timers print. */
2280 if (ospf6->lsa_minarrival != OSPF_MIN_LS_ARRIVAL)
2281 vty_out(vty, " timers lsa min-arrival %d\n",
2282 ospf6->lsa_minarrival);
2283
1958143e
MR
2284 /* ECMP max path config */
2285 if (ospf6->max_multipath != MULTIPATH_NUM)
2286 vty_out(vty, " maximum-paths %d\n",
2287 ospf6->max_multipath);
2288
beadc736 2289 ospf6_stub_router_config_write(vty, ospf6);
2290 ospf6_redistribute_config_write(vty, ospf6);
2291 ospf6_area_config_write(vty, ospf6);
2292 ospf6_spf_config_write(vty, ospf6);
2293 ospf6_distance_config_write(vty, ospf6);
b19502d3 2294 ospf6_distribute_config_write(vty, ospf6);
4dc43886 2295 ospf6_asbr_summary_config_write(vty, ospf6);
71165098 2296 config_write_ospf6_gr(vty, ospf6);
0fc3e113 2297 config_write_ospf6_gr_helper(vty, ospf6);
07679ad9
IR
2298
2299 vty_out(vty, "exit\n");
beadc736 2300 vty_out(vty, "!\n");
d62a17ae 2301 }
d62a17ae 2302 return 0;
508e53e2 2303}
2304
612c2c15 2305static int config_write_ospf6(struct vty *vty);
508e53e2 2306/* OSPF6 node structure. */
d62a17ae 2307static struct cmd_node ospf6_node = {
f4b8291f 2308 .name = "ospf6",
62b346ee 2309 .node = OSPF6_NODE,
24389580 2310 .parent_node = CONFIG_NODE,
62b346ee 2311 .prompt = "%s(config-ospf6)# ",
612c2c15 2312 .config_write = config_write_ospf6,
508e53e2 2313};
2314
f71ed6df
YR
2315void install_element_ospf6_clear_process(void)
2316{
2317 install_element(ENABLE_NODE, &clear_router_ospf6_cmd);
2318}
2319
508e53e2 2320/* Install ospf related commands. */
d62a17ae 2321void ospf6_top_init(void)
718e3744 2322{
d62a17ae 2323 /* Install ospf6 top node. */
612c2c15 2324 install_node(&ospf6_node);
d62a17ae 2325
2326 install_element(VIEW_NODE, &show_ipv6_ospf6_cmd);
dd7fb1db 2327 install_element(VIEW_NODE, &show_ipv6_ospf6_vrfs_cmd);
d62a17ae 2328 install_element(CONFIG_NODE, &router_ospf6_cmd);
2329 install_element(CONFIG_NODE, &no_router_ospf6_cmd);
2330
2331 install_element(VIEW_NODE, &show_ipv6_ospf6_route_cmd);
2332 install_element(VIEW_NODE, &show_ipv6_ospf6_route_match_cmd);
2333 install_element(VIEW_NODE, &show_ipv6_ospf6_route_match_detail_cmd);
2334 install_element(VIEW_NODE, &show_ipv6_ospf6_route_type_detail_cmd);
2335
2336 install_default(OSPF6_NODE);
2337 install_element(OSPF6_NODE, &ospf6_router_id_cmd);
5d1a2ee8 2338 install_element(OSPF6_NODE, &no_ospf6_router_id_cmd);
d62a17ae 2339 install_element(OSPF6_NODE, &ospf6_log_adjacency_changes_cmd);
2340 install_element(OSPF6_NODE, &ospf6_log_adjacency_changes_detail_cmd);
2341 install_element(OSPF6_NODE, &no_ospf6_log_adjacency_changes_cmd);
2342 install_element(OSPF6_NODE, &no_ospf6_log_adjacency_changes_detail_cmd);
5b5d66c4 2343 install_element(OSPF6_NODE, &ospf6_send_extra_data_cmd);
d62a17ae 2344
2345 /* LSA timers commands */
2346 install_element(OSPF6_NODE, &ospf6_timers_lsa_cmd);
2347 install_element(OSPF6_NODE, &no_ospf6_timers_lsa_cmd);
2348
2349 install_element(OSPF6_NODE, &ospf6_interface_area_cmd);
2350 install_element(OSPF6_NODE, &no_ospf6_interface_area_cmd);
2351 install_element(OSPF6_NODE, &ospf6_stub_router_admin_cmd);
2352 install_element(OSPF6_NODE, &no_ospf6_stub_router_admin_cmd);
508e53e2 2353
1958143e
MR
2354 /* maximum-paths command */
2355 install_element(OSPF6_NODE, &ospf6_max_multipath_cmd);
2356 install_element(OSPF6_NODE, &no_ospf6_max_multipath_cmd);
2357
4dc43886
MR
2358 /* ASBR Summarisation */
2359 install_element(OSPF6_NODE, &ospf6_external_route_aggregation_cmd);
2360 install_element(OSPF6_NODE, &no_ospf6_external_route_aggregation_cmd);
2361 install_element(OSPF6_NODE,
2362 &ospf6_external_route_aggregation_no_advertise_cmd);
2363 install_element(OSPF6_NODE,
2364 &no_ospf6_external_route_aggregation_no_advertise_cmd);
2365 install_element(OSPF6_NODE, &ospf6_route_aggregation_timer_cmd);
2366 install_element(OSPF6_NODE, &no_ospf6_route_aggregation_timer_cmd);
2367 install_element(VIEW_NODE, &show_ipv6_ospf6_external_aggregator_cmd);
2368
d62a17ae 2369 install_element(OSPF6_NODE, &ospf6_distance_cmd);
2370 install_element(OSPF6_NODE, &no_ospf6_distance_cmd);
2371 install_element(OSPF6_NODE, &ospf6_distance_ospf6_cmd);
2372 install_element(OSPF6_NODE, &no_ospf6_distance_ospf6_cmd);
718e3744 2373}