]> git.proxmox.com Git - mirror_frr.git/blame - ospf6d/ospf6_top.c
Merge pull request #7935 from donaldsharp/ospf6_use_after_free
[mirror_frr.git] / ospf6d / ospf6_top.c
CommitLineData
718e3744 1/*
508e53e2 2 * Copyright (C) 2003 Yasuhiro Ohara
718e3744 3 *
4 * This file is part of GNU Zebra.
5 *
6 * GNU Zebra is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2, or (at your option) any
9 * later version.
10 *
11 * GNU Zebra is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
896014f4
DL
16 * You should have received a copy of the GNU General Public License along
17 * with this program; see the file COPYING; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
718e3744 19 */
20
21#include <zebra.h>
22
23#include "log.h"
24#include "memory.h"
25#include "vty.h"
26#include "linklist.h"
27#include "prefix.h"
28#include "table.h"
29#include "thread.h"
30#include "command.h"
8efe88ea 31#include "defaults.h"
35a45dea 32#include "lib/json.h"
7df1f362 33#include "lib_errors.h"
718e3744 34
718e3744 35#include "ospf6_proto.h"
508e53e2 36#include "ospf6_message.h"
718e3744 37#include "ospf6_lsa.h"
38#include "ospf6_lsdb.h"
718e3744 39#include "ospf6_route.h"
40#include "ospf6_zebra.h"
41
508e53e2 42#include "ospf6_top.h"
43#include "ospf6_area.h"
44#include "ospf6_interface.h"
45#include "ospf6_neighbor.h"
7df1f362 46#include "ospf6_network.h"
718e3744 47
6452df09 48#include "ospf6_flood.h"
508e53e2 49#include "ospf6_asbr.h"
049207c3 50#include "ospf6_abr.h"
6452df09 51#include "ospf6_intra.h"
3810e06e 52#include "ospf6_spf.h"
049207c3 53#include "ospf6d.h"
718e3744 54
ae19c240
DL
55DEFINE_QOBJ_TYPE(ospf6)
56
c572fbfe 57FRR_CFG_DEFAULT_BOOL(OSPF6_LOG_ADJACENCY_CHANGES,
4c1458b5
DL
58 { .val_bool = true, .match_profile = "datacenter", },
59 { .val_bool = false },
c572fbfe
DL
60)
61
718e3744 62/* global ospf6d variable */
78c6ba61
CS
63static struct ospf6_master ospf6_master;
64struct ospf6_master *om6;
718e3744 65
d62a17ae 66static void ospf6_disable(struct ospf6 *o);
ae2254aa 67
beadc736 68static void ospf6_add(struct ospf6 *ospf6)
69{
70 listnode_add(om6->ospf6, ospf6);
71}
72
73static void ospf6_del(struct ospf6 *ospf6)
74{
75 listnode_delete(om6->ospf6, ospf6);
76}
77
78const char *ospf6_vrf_id_to_name(vrf_id_t vrf_id)
79{
80 struct vrf *vrf = vrf_lookup_by_id(vrf_id);
81
82 return vrf ? vrf->name : "NIL";
83}
84
85/* Link OSPF instance to VRF. */
86void ospf6_vrf_link(struct ospf6 *ospf6, struct vrf *vrf)
87{
88 ospf6->vrf_id = vrf->vrf_id;
89 if (vrf->info != (void *)ospf6)
90 vrf->info = (void *)ospf6;
91}
92
93/* Unlink OSPF instance from VRF. */
94void ospf6_vrf_unlink(struct ospf6 *ospf6, struct vrf *vrf)
95{
96 if (vrf->info == (void *)ospf6)
97 vrf->info = NULL;
98 ospf6->vrf_id = VRF_UNKNOWN;
99}
100
101struct ospf6 *ospf6_lookup_by_vrf_id(vrf_id_t vrf_id)
102{
103 struct vrf *vrf = NULL;
104
105 vrf = vrf_lookup_by_id(vrf_id);
106 if (!vrf)
107 return NULL;
108 return (vrf->info) ? (struct ospf6 *)vrf->info : NULL;
109}
110
111struct ospf6 *ospf6_lookup_by_vrf_name(const char *name)
112{
113 struct ospf6 *o = NULL;
114 struct listnode *node, *nnode;
115
116 for (ALL_LIST_ELEMENTS(om6->ospf6, node, nnode, o)) {
117 if (((o->name == NULL && name == NULL)
118 || (o->name && name && strcmp(o->name, name) == 0)))
119 return o;
120 }
121 return NULL;
122}
123
124
d62a17ae 125static void ospf6_top_lsdb_hook_add(struct ospf6_lsa *lsa)
718e3744 126{
d62a17ae 127 switch (ntohs(lsa->header->type)) {
128 case OSPF6_LSTYPE_AS_EXTERNAL:
f5f26b8f 129 ospf6_asbr_lsa_add(lsa);
d62a17ae 130 break;
131
132 default:
133 break;
134 }
718e3744 135}
136
d62a17ae 137static void ospf6_top_lsdb_hook_remove(struct ospf6_lsa *lsa)
718e3744 138{
d62a17ae 139 switch (ntohs(lsa->header->type)) {
140 case OSPF6_LSTYPE_AS_EXTERNAL:
07b37f93 141 ospf6_asbr_lsa_remove(lsa, NULL);
d62a17ae 142 break;
143
144 default:
145 break;
146 }
718e3744 147}
148
e285b70d 149static void ospf6_top_route_hook_add(struct ospf6_route *route)
049207c3 150{
e285b70d
IR
151 struct ospf6 *ospf6 = route->table->scope;
152
beadc736 153 ospf6_abr_originate_summary(route, ospf6);
154 ospf6_zebra_route_update_add(route, ospf6);
049207c3 155}
156
e285b70d 157static void ospf6_top_route_hook_remove(struct ospf6_route *route)
049207c3 158{
e285b70d
IR
159 struct ospf6 *ospf6 = route->table->scope;
160
d62a17ae 161 route->flag |= OSPF6_ROUTE_REMOVE;
beadc736 162 ospf6_abr_originate_summary(route, ospf6);
163 ospf6_zebra_route_update_remove(route, ospf6);
049207c3 164}
165
e285b70d 166static void ospf6_top_brouter_hook_add(struct ospf6_route *route)
6452df09 167{
e285b70d
IR
168 struct ospf6 *ospf6 = route->table->scope;
169
99ab28cb
CS
170 if (IS_OSPF6_DEBUG_EXAMIN(AS_EXTERNAL) ||
171 IS_OSPF6_DEBUG_BROUTER) {
07b37f93
CS
172 uint32_t brouter_id;
173 char brouter_name[16];
174
175 brouter_id = ADV_ROUTER_IN_PREFIX(&route->prefix);
176 inet_ntop(AF_INET, &brouter_id, brouter_name,
177 sizeof(brouter_name));
178 zlog_debug("%s: brouter %s add with adv router %x nh count %u",
15569c58 179 __func__, brouter_name,
07b37f93
CS
180 route->path.origin.adv_router,
181 listcount(route->nh_list));
064d4355 182 }
beadc736 183 ospf6_abr_examin_brouter(ADV_ROUTER_IN_PREFIX(&route->prefix), route,
184 ospf6);
185 ospf6_asbr_lsentry_add(route, ospf6);
186 ospf6_abr_originate_summary(route, ospf6);
6452df09 187}
188
e285b70d 189static void ospf6_top_brouter_hook_remove(struct ospf6_route *route)
6452df09 190{
e285b70d
IR
191 struct ospf6 *ospf6 = route->table->scope;
192
99ab28cb
CS
193 if (IS_OSPF6_DEBUG_EXAMIN(AS_EXTERNAL) ||
194 IS_OSPF6_DEBUG_BROUTER) {
07b37f93
CS
195 uint32_t brouter_id;
196 char brouter_name[16];
064d4355 197
07b37f93
CS
198 brouter_id = ADV_ROUTER_IN_PREFIX(&route->prefix);
199 inet_ntop(AF_INET, &brouter_id, brouter_name,
200 sizeof(brouter_name));
99ab28cb 201 zlog_debug("%s: brouter %p %s del with adv router %x nh %u",
15569c58 202 __func__, (void *)route, brouter_name,
99ab28cb 203 route->path.origin.adv_router,
07b37f93 204 listcount(route->nh_list));
064d4355 205 }
d62a17ae 206 route->flag |= OSPF6_ROUTE_REMOVE;
beadc736 207 ospf6_abr_examin_brouter(ADV_ROUTER_IN_PREFIX(&route->prefix), route,
208 ospf6);
209 ospf6_asbr_lsentry_remove(route, ospf6);
210 ospf6_abr_originate_summary(route, ospf6);
6452df09 211}
212
7df1f362 213static struct ospf6 *ospf6_create(const char *name)
718e3744 214{
d62a17ae 215 struct ospf6 *o;
7df1f362 216 struct vrf *vrf = NULL;
718e3744 217
d62a17ae 218 o = XCALLOC(MTYPE_OSPF6_TOP, sizeof(struct ospf6));
718e3744 219
7df1f362
K
220 vrf = vrf_lookup_by_name(name);
221 if (vrf) {
222 o->vrf_id = vrf->vrf_id;
beadc736 223 } else
224 o->vrf_id = VRF_UNKNOWN;
225
226 /* Freed in ospf6_delete */
227 o->name = XSTRDUP(MTYPE_OSPF6_TOP, name);
228 if (vrf)
229 ospf6_vrf_link(o, vrf);
230
231 ospf6_zebra_vrf_register(o);
232
d62a17ae 233 /* initialize */
234 monotime(&o->starttime);
235 o->area_list = list_new();
236 o->area_list->cmp = ospf6_area_cmp;
237 o->lsdb = ospf6_lsdb_create(o);
238 o->lsdb_self = ospf6_lsdb_create(o);
239 o->lsdb->hook_add = ospf6_top_lsdb_hook_add;
240 o->lsdb->hook_remove = ospf6_top_lsdb_hook_remove;
718e3744 241
d62a17ae 242 o->spf_delay = OSPF_SPF_DELAY_DEFAULT;
243 o->spf_holdtime = OSPF_SPF_HOLDTIME_DEFAULT;
244 o->spf_max_holdtime = OSPF_SPF_MAX_HOLDTIME_DEFAULT;
245 o->spf_hold_multiplier = 1;
3810e06e 246
d62a17ae 247 /* LSA timers value init */
248 o->lsa_minarrival = OSPF_MIN_LS_ARRIVAL;
b6927875 249
d62a17ae 250 o->route_table = OSPF6_ROUTE_TABLE_CREATE(GLOBAL, ROUTES);
251 o->route_table->scope = o;
252 o->route_table->hook_add = ospf6_top_route_hook_add;
253 o->route_table->hook_remove = ospf6_top_route_hook_remove;
718e3744 254
d62a17ae 255 o->brouter_table = OSPF6_ROUTE_TABLE_CREATE(GLOBAL, BORDER_ROUTERS);
256 o->brouter_table->scope = o;
257 o->brouter_table->hook_add = ospf6_top_brouter_hook_add;
258 o->brouter_table->hook_remove = ospf6_top_brouter_hook_remove;
049207c3 259
d62a17ae 260 o->external_table = OSPF6_ROUTE_TABLE_CREATE(GLOBAL, EXTERNAL_ROUTES);
261 o->external_table->scope = o;
cf1ce250 262
d62a17ae 263 o->external_id_table = route_table_init();
718e3744 264
d62a17ae 265 o->ref_bandwidth = OSPF6_REFERENCE_BANDWIDTH;
fd500689 266
d62a17ae 267 o->distance_table = route_table_init();
7df1f362 268 o->fd = -1;
baff583e 269
d62a17ae 270 QOBJ_REG(o, ospf6);
692c7954 271
7df1f362
K
272 /* Make ospf protocol socket. */
273 ospf6_serv_sock(o);
274
d62a17ae 275 return o;
718e3744 276}
277
beadc736 278struct ospf6 *ospf6_instance_create(const char *name)
7df1f362 279{
beadc736 280 struct ospf6 *ospf6;
281
7df1f362
K
282 ospf6 = ospf6_create(name);
283 if (DFLT_OSPF6_LOG_ADJACENCY_CHANGES)
284 SET_FLAG(ospf6->config_flags, OSPF6_LOG_ADJACENCY_CHANGES);
285 if (ospf6->router_id == 0)
beadc736 286 ospf6_router_id_update(ospf6);
287 ospf6_add(ospf6);
7df1f362
K
288 thread_add_read(master, ospf6_receive, ospf6, ospf6->fd,
289 &ospf6->t_ospf6_receive);
beadc736 290
291 return ospf6;
7df1f362
K
292}
293
d62a17ae 294void ospf6_delete(struct ospf6 *o)
718e3744 295{
d62a17ae 296 struct listnode *node, *nnode;
297 struct ospf6_area *oa;
718e3744 298
d62a17ae 299 QOBJ_UNREG(o);
76249532 300
beadc736 301 ospf6_flush_self_originated_lsas_now(o);
302 ospf6_disable(o);
303 ospf6_del(o);
ae2254aa 304
d3136990
IR
305 ospf6_serv_close(&o->fd);
306
d62a17ae 307 for (ALL_LIST_ELEMENTS(o->area_list, node, nnode, oa))
308 ospf6_area_delete(oa);
d9628728
CF
309
310
6a154c88 311 list_delete(&o->area_list);
718e3744 312
d62a17ae 313 ospf6_lsdb_delete(o->lsdb);
314 ospf6_lsdb_delete(o->lsdb_self);
718e3744 315
e285b70d
IR
316 ospf6_route_table_delete(o->route_table);
317 ospf6_route_table_delete(o->brouter_table);
718e3744 318
e285b70d 319 ospf6_route_table_delete(o->external_table);
d62a17ae 320 route_table_finish(o->external_id_table);
718e3744 321
d62a17ae 322 ospf6_distance_reset(o);
323 route_table_finish(o->distance_table);
baff583e 324
7df1f362 325 XFREE(MTYPE_OSPF6_TOP, o->name);
d62a17ae 326 XFREE(MTYPE_OSPF6_TOP, o);
508e53e2 327}
718e3744 328
d62a17ae 329static void ospf6_disable(struct ospf6 *o)
718e3744 330{
d62a17ae 331 struct listnode *node, *nnode;
332 struct ospf6_area *oa;
333
334 if (!CHECK_FLAG(o->flag, OSPF6_DISABLED)) {
335 SET_FLAG(o->flag, OSPF6_DISABLED);
336
337 for (ALL_LIST_ELEMENTS(o->area_list, node, nnode, oa))
338 ospf6_area_disable(oa);
339
340 /* XXX: This also changes persistent settings */
a069482f
K
341 /* Unregister redistribution */
342 ospf6_asbr_redistribute_reset(o);
d62a17ae 343
344 ospf6_lsdb_remove_all(o->lsdb);
e285b70d
IR
345 ospf6_route_remove_all(o->route_table);
346 ospf6_route_remove_all(o->brouter_table);
d62a17ae 347
348 THREAD_OFF(o->maxage_remover);
349 THREAD_OFF(o->t_spf_calc);
350 THREAD_OFF(o->t_ase_calc);
856ae1eb 351 THREAD_OFF(o->t_distribute_update);
7df1f362 352 THREAD_OFF(o->t_ospf6_receive);
d62a17ae 353 }
508e53e2 354}
718e3744 355
beadc736 356void ospf6_master_init(struct thread_master *master)
78c6ba61
CS
357{
358 memset(&ospf6_master, 0, sizeof(struct ospf6_master));
359
360 om6 = &ospf6_master;
beadc736 361 om6->ospf6 = list_new();
362 om6->master = master;
78c6ba61
CS
363}
364
d62a17ae 365static int ospf6_maxage_remover(struct thread *thread)
508e53e2 366{
d62a17ae 367 struct ospf6 *o = (struct ospf6 *)THREAD_ARG(thread);
368 struct ospf6_area *oa;
369 struct ospf6_interface *oi;
370 struct ospf6_neighbor *on;
371 struct listnode *i, *j, *k;
372 int reschedule = 0;
373
374 o->maxage_remover = (struct thread *)NULL;
375
376 for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa)) {
377 for (ALL_LIST_ELEMENTS_RO(oa->if_list, j, oi)) {
378 for (ALL_LIST_ELEMENTS_RO(oi->neighbor_list, k, on)) {
379 if (on->state != OSPF6_NEIGHBOR_EXCHANGE
380 && on->state != OSPF6_NEIGHBOR_LOADING)
381 continue;
382
383 ospf6_maxage_remove(o);
384 return 0;
385 }
386 }
2449fcd6 387 }
d62a17ae 388
389 for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa)) {
390 for (ALL_LIST_ELEMENTS_RO(oa->if_list, j, oi)) {
391 if (ospf6_lsdb_maxage_remover(oi->lsdb)) {
392 reschedule = 1;
393 }
394 }
395
396 if (ospf6_lsdb_maxage_remover(oa->lsdb)) {
397 reschedule = 1;
398 }
2449fcd6 399 }
2449fcd6 400
d62a17ae 401 if (ospf6_lsdb_maxage_remover(o->lsdb)) {
402 reschedule = 1;
403 }
2449fcd6 404
d62a17ae 405 if (reschedule) {
406 ospf6_maxage_remove(o);
407 }
508e53e2 408
d62a17ae 409 return 0;
718e3744 410}
411
d62a17ae 412void ospf6_maxage_remove(struct ospf6 *o)
718e3744 413{
d62a17ae 414 if (o)
415 thread_add_timer(master, ospf6_maxage_remover, o,
416 OSPF_LSA_MAXAGE_REMOVE_DELAY_DEFAULT,
417 &o->maxage_remover);
718e3744 418}
419
beadc736 420void ospf6_router_id_update(struct ospf6 *ospf6)
78c6ba61
CS
421{
422 if (!ospf6)
423 return;
424
425 if (ospf6->router_id_static != 0)
426 ospf6->router_id = ospf6->router_id_static;
427 else
428 ospf6->router_id = om6->zebra_router_id;
429}
430
508e53e2 431/* start ospf6 */
505e5056 432DEFUN_NOSH (router_ospf6,
508e53e2 433 router_ospf6_cmd,
434 "router ospf6",
435 ROUTER_STR
436 OSPF6_STR)
718e3744 437{
beadc736 438 struct ospf6 *ospf6;
439
440 ospf6 = ospf6_lookup_by_vrf_name(VRF_DEFAULT_NAME);
7df1f362 441 if (ospf6 == NULL)
beadc736 442 ospf6 = ospf6_instance_create(VRF_DEFAULT_NAME);
7df1f362 443
d62a17ae 444 /* set current ospf point. */
445 VTY_PUSH_CONTEXT(OSPF6_NODE, ospf6);
508e53e2 446
d62a17ae 447 return CMD_SUCCESS;
718e3744 448}
449
508e53e2 450/* stop ospf6 */
451DEFUN (no_router_ospf6,
452 no_router_ospf6_cmd,
453 "no router ospf6",
454 NO_STR
16cedbb0
QY
455 ROUTER_STR
456 OSPF6_STR)
718e3744 457{
beadc736 458 struct ospf6 *ospf6;
459
460 ospf6 = ospf6_lookup_by_vrf_name(VRF_DEFAULT_NAME);
d62a17ae 461 if (ospf6 == NULL)
462 vty_out(vty, "OSPFv3 is not configured\n");
463 else {
464 ospf6_delete(ospf6);
465 ospf6 = NULL;
466 }
34288970 467
d62a17ae 468 /* return to config node . */
469 VTY_PUSH_CONTEXT_NULL(CONFIG_NODE);
508e53e2 470
d62a17ae 471 return CMD_SUCCESS;
718e3744 472}
473
508e53e2 474/* change Router_ID commands. */
60466a63
QY
475DEFUN(ospf6_router_id,
476 ospf6_router_id_cmd,
477 "ospf6 router-id A.B.C.D",
478 OSPF6_STR
479 "Configure OSPF6 Router-ID\n"
480 V4NOTATION_STR)
718e3744 481{
d62a17ae 482 VTY_DECLVAR_CONTEXT(ospf6, o);
5d1a2ee8 483 int idx = 0;
d62a17ae 484 int ret;
5d1a2ee8 485 const char *router_id_str;
d7c0a89a 486 uint32_t router_id;
d6927cf3
CS
487 struct ospf6_area *oa;
488 struct listnode *node;
d62a17ae 489
5d1a2ee8
QY
490 argv_find(argv, argc, "A.B.C.D", &idx);
491 router_id_str = argv[idx]->arg;
492
493 ret = inet_pton(AF_INET, router_id_str, &router_id);
d62a17ae 494 if (ret == 0) {
60466a63 495 vty_out(vty, "malformed OSPF Router-ID: %s\n", router_id_str);
d62a17ae 496 return CMD_SUCCESS;
497 }
508e53e2 498
d62a17ae 499 o->router_id_static = router_id;
d6927cf3
CS
500
501 for (ALL_LIST_ELEMENTS_RO(o->area_list, node, oa)) {
502 if (oa->full_nbrs) {
503 vty_out(vty,
3efd0893 504 "For this router-id change to take effect, save config and restart ospf6d\n");
d6927cf3
CS
505 return CMD_SUCCESS;
506 }
507 }
508
509 o->router_id = router_id;
c8a440ec 510
d62a17ae 511 return CMD_SUCCESS;
718e3744 512}
513
60466a63
QY
514DEFUN(no_ospf6_router_id,
515 no_ospf6_router_id_cmd,
516 "no ospf6 router-id [A.B.C.D]",
517 NO_STR OSPF6_STR
518 "Configure OSPF6 Router-ID\n"
519 V4NOTATION_STR)
5d1a2ee8
QY
520{
521 VTY_DECLVAR_CONTEXT(ospf6, o);
d6927cf3
CS
522 struct ospf6_area *oa;
523 struct listnode *node;
524
5d1a2ee8 525 o->router_id_static = 0;
d6927cf3
CS
526
527 for (ALL_LIST_ELEMENTS_RO(o->area_list, node, oa)) {
528 if (oa->full_nbrs) {
529 vty_out(vty,
3efd0893 530 "For this router-id change to take effect, save config and restart ospf6d\n");
d6927cf3
CS
531 return CMD_SUCCESS;
532 }
533 }
5d1a2ee8 534 o->router_id = 0;
d6927cf3
CS
535 if (o->router_id_zebra.s_addr)
536 o->router_id = (uint32_t)o->router_id_zebra.s_addr;
5d1a2ee8
QY
537
538 return CMD_SUCCESS;
539}
540
3d35ca48
DD
541DEFUN (ospf6_log_adjacency_changes,
542 ospf6_log_adjacency_changes_cmd,
543 "log-adjacency-changes",
544 "Log changes in adjacency state\n")
545{
d62a17ae 546 VTY_DECLVAR_CONTEXT(ospf6, ospf6);
3d35ca48 547
d62a17ae 548 SET_FLAG(ospf6->config_flags, OSPF6_LOG_ADJACENCY_CHANGES);
549 UNSET_FLAG(ospf6->config_flags, OSPF6_LOG_ADJACENCY_DETAIL);
550 return CMD_SUCCESS;
3d35ca48
DD
551}
552
553DEFUN (ospf6_log_adjacency_changes_detail,
554 ospf6_log_adjacency_changes_detail_cmd,
555 "log-adjacency-changes detail",
692c7954 556 "Log changes in adjacency state\n"
3d35ca48
DD
557 "Log all state changes\n")
558{
d62a17ae 559 VTY_DECLVAR_CONTEXT(ospf6, ospf6);
3d35ca48 560
d62a17ae 561 SET_FLAG(ospf6->config_flags, OSPF6_LOG_ADJACENCY_CHANGES);
562 SET_FLAG(ospf6->config_flags, OSPF6_LOG_ADJACENCY_DETAIL);
563 return CMD_SUCCESS;
3d35ca48
DD
564}
565
566DEFUN (no_ospf6_log_adjacency_changes,
567 no_ospf6_log_adjacency_changes_cmd,
568 "no log-adjacency-changes",
692c7954 569 NO_STR
3d35ca48
DD
570 "Log changes in adjacency state\n")
571{
d62a17ae 572 VTY_DECLVAR_CONTEXT(ospf6, ospf6);
3d35ca48 573
d62a17ae 574 UNSET_FLAG(ospf6->config_flags, OSPF6_LOG_ADJACENCY_DETAIL);
575 UNSET_FLAG(ospf6->config_flags, OSPF6_LOG_ADJACENCY_CHANGES);
576 return CMD_SUCCESS;
3d35ca48
DD
577}
578
579DEFUN (no_ospf6_log_adjacency_changes_detail,
580 no_ospf6_log_adjacency_changes_detail_cmd,
581 "no log-adjacency-changes detail",
692c7954
DW
582 NO_STR
583 "Log changes in adjacency state\n"
3d35ca48
DD
584 "Log all state changes\n")
585{
d62a17ae 586 VTY_DECLVAR_CONTEXT(ospf6, ospf6);
3d35ca48 587
d62a17ae 588 UNSET_FLAG(ospf6->config_flags, OSPF6_LOG_ADJACENCY_DETAIL);
589 return CMD_SUCCESS;
3d35ca48
DD
590}
591
b6927875
DS
592DEFUN (ospf6_timers_lsa,
593 ospf6_timers_lsa_cmd,
6147e2c6 594 "timers lsa min-arrival (0-600000)",
b6927875
DS
595 "Adjust routing timers\n"
596 "OSPF6 LSA timers\n"
597 "Minimum delay in receiving new version of a LSA\n"
598 "Delay in milliseconds\n")
599{
d62a17ae 600 VTY_DECLVAR_CONTEXT(ospf6, ospf);
601 int idx_number = 3;
602 unsigned int minarrival;
b6927875 603
d62a17ae 604 minarrival = strtoul(argv[idx_number]->arg, NULL, 10);
605 ospf->lsa_minarrival = minarrival;
b6927875 606
d62a17ae 607 return CMD_SUCCESS;
b6927875
DS
608}
609
610DEFUN (no_ospf6_timers_lsa,
611 no_ospf6_timers_lsa_cmd,
1d68dbfe 612 "no timers lsa min-arrival [(0-600000)]",
b6927875
DS
613 NO_STR
614 "Adjust routing timers\n"
615 "OSPF6 LSA timers\n"
3a2d747c
QY
616 "Minimum delay in receiving new version of a LSA\n"
617 "Delay in milliseconds\n")
b6927875 618{
d62a17ae 619 VTY_DECLVAR_CONTEXT(ospf6, ospf);
620 int idx_number = 4;
621 unsigned int minarrival;
b6927875 622
d62a17ae 623 if (argc == 5) {
624 minarrival = strtoul(argv[idx_number]->arg, NULL, 10);
b6927875 625
d62a17ae 626 if (ospf->lsa_minarrival != minarrival
627 || minarrival == OSPF_MIN_LS_ARRIVAL)
628 return CMD_SUCCESS;
629 }
b6927875 630
d62a17ae 631 ospf->lsa_minarrival = OSPF_MIN_LS_ARRIVAL;
b6927875 632
d62a17ae 633 return CMD_SUCCESS;
b6927875
DS
634}
635
b6927875 636
baff583e
MZ
637DEFUN (ospf6_distance,
638 ospf6_distance_cmd,
39e92c06 639 "distance (1-255)",
baff583e
MZ
640 "Administrative distance\n"
641 "OSPF6 Administrative distance\n")
642{
d62a17ae 643 VTY_DECLVAR_CONTEXT(ospf6, o);
baff583e 644
d62a17ae 645 o->distance_all = atoi(argv[1]->arg);
baff583e 646
d62a17ae 647 return CMD_SUCCESS;
baff583e
MZ
648}
649
650DEFUN (no_ospf6_distance,
651 no_ospf6_distance_cmd,
39e92c06 652 "no distance (1-255)",
baff583e
MZ
653 NO_STR
654 "Administrative distance\n"
655 "OSPF6 Administrative distance\n")
656{
d62a17ae 657 VTY_DECLVAR_CONTEXT(ospf6, o);
baff583e 658
d62a17ae 659 o->distance_all = 0;
baff583e 660
d62a17ae 661 return CMD_SUCCESS;
baff583e
MZ
662}
663
664DEFUN (ospf6_distance_ospf6,
665 ospf6_distance_ospf6_cmd,
eaa1ae0d 666 "distance ospf6 {intra-area (1-255)|inter-area (1-255)|external (1-255)}",
baff583e 667 "Administrative distance\n"
eaa1ae0d 668 "OSPF6 administrative distance\n"
39e92c06
QY
669 "Intra-area routes\n"
670 "Distance for intra-area routes\n"
671 "Inter-area routes\n"
672 "Distance for inter-area routes\n"
673 "External routes\n"
baff583e
MZ
674 "Distance for external routes\n")
675{
d62a17ae 676 VTY_DECLVAR_CONTEXT(ospf6, o);
677 int idx = 0;
678
f89a449b
CS
679 o->distance_intra = 0;
680 o->distance_inter = 0;
681 o->distance_external = 0;
682
d62a17ae 683 if (argv_find(argv, argc, "intra-area", &idx))
684 o->distance_intra = atoi(argv[idx + 1]->arg);
685 idx = 0;
686 if (argv_find(argv, argc, "inter-area", &idx))
687 o->distance_inter = atoi(argv[idx + 1]->arg);
688 idx = 0;
689 if (argv_find(argv, argc, "external", &idx))
690 o->distance_external = atoi(argv[idx + 1]->arg);
39e92c06 691
d62a17ae 692 return CMD_SUCCESS;
baff583e
MZ
693}
694
695DEFUN (no_ospf6_distance_ospf6,
696 no_ospf6_distance_ospf6_cmd,
eaa1ae0d 697 "no distance ospf6 [{intra-area [(1-255)]|inter-area [(1-255)]|external [(1-255)]}]",
baff583e
MZ
698 NO_STR
699 "Administrative distance\n"
700 "OSPF6 distance\n"
701 "Intra-area routes\n"
702 "Distance for intra-area routes\n"
703 "Inter-area routes\n"
704 "Distance for inter-area routes\n"
705 "External routes\n"
706 "Distance for external routes\n")
707{
d62a17ae 708 VTY_DECLVAR_CONTEXT(ospf6, o);
709 int idx = 0;
baff583e 710
d62a17ae 711 if (argv_find(argv, argc, "intra-area", &idx) || argc == 3)
712 idx = o->distance_intra = 0;
713 if (argv_find(argv, argc, "inter-area", &idx) || argc == 3)
714 idx = o->distance_inter = 0;
715 if (argv_find(argv, argc, "external", &idx) || argc == 3)
716 o->distance_external = 0;
baff583e 717
d62a17ae 718 return CMD_SUCCESS;
baff583e
MZ
719}
720
d7d73ffc 721#if 0
baff583e
MZ
722DEFUN (ospf6_distance_source,
723 ospf6_distance_source_cmd,
39e92c06 724 "distance (1-255) X:X::X:X/M [WORD]",
baff583e
MZ
725 "Administrative distance\n"
726 "Distance value\n"
727 "IP source prefix\n"
728 "Access list name\n")
729{
cdc2d765 730 VTY_DECLVAR_CONTEXT(ospf6, o);
39e92c06
QY
731 char *alname = (argc == 4) ? argv[3]->arg : NULL;
732 ospf6_distance_set (vty, o, argv[1]->arg, argv[2]->arg, alname);
baff583e
MZ
733
734 return CMD_SUCCESS;
735}
736
737DEFUN (no_ospf6_distance_source,
738 no_ospf6_distance_source_cmd,
39e92c06 739 "no distance (1-255) X:X::X:X/M [WORD]",
baff583e
MZ
740 NO_STR
741 "Administrative distance\n"
742 "Distance value\n"
743 "IP source prefix\n"
744 "Access list name\n")
745{
cdc2d765 746 VTY_DECLVAR_CONTEXT(ospf6, o);
39e92c06
QY
747 char *alname = (argc == 5) ? argv[4]->arg : NULL;
748 ospf6_distance_unset (vty, o, argv[2]->arg, argv[3]->arg, alname);
baff583e
MZ
749
750 return CMD_SUCCESS;
751}
d7d73ffc 752#endif
baff583e 753
508e53e2 754DEFUN (ospf6_interface_area,
755 ospf6_interface_area_cmd,
de842255 756 "interface IFNAME area <A.B.C.D|(0-4294967295)>",
508e53e2 757 "Enable routing on an IPv6 interface\n"
758 IFNAME_STR
759 "Specify the OSPF6 area ID\n"
760 "OSPF6 area ID in IPv4 address notation\n"
de842255 761 "OSPF6 area ID in decimal notation\n"
508e53e2 762 )
718e3744 763{
d62a17ae 764 int idx_ifname = 1;
765 int idx_ipv4 = 3;
766 struct ospf6_area *oa;
767 struct ospf6_interface *oi;
768 struct interface *ifp;
d62a17ae 769
beadc736 770 VTY_DECLVAR_CONTEXT(ospf6, ospf6);
771
d62a17ae 772 /* find/create ospf6 interface */
a36898e7 773 ifp = if_get_by_name(argv[idx_ifname]->arg, VRF_DEFAULT);
d62a17ae 774 oi = (struct ospf6_interface *)ifp->info;
775 if (oi == NULL)
776 oi = ospf6_interface_create(ifp);
777 if (oi->area) {
778 vty_out(vty, "%s already attached to Area %s\n",
779 oi->interface->name, oi->area->name);
780 return CMD_SUCCESS;
781 }
6452df09 782
d62a17ae 783 /* parse Area-ID */
beadc736 784 OSPF6_CMD_AREA_GET(argv[idx_ipv4]->arg, oa, ospf6);
d62a17ae 785
786 /* attach interface to area */
787 listnode_add(oa->if_list, oi); /* sort ?? */
788 oi->area = oa;
789
790 SET_FLAG(oa->flag, OSPF6_AREA_ENABLE);
791
792 /* ospf6 process is currently disabled, not much more to do */
beadc736 793 if (CHECK_FLAG(ospf6->flag, OSPF6_DISABLED))
d62a17ae 794 return CMD_SUCCESS;
795
796 /* start up */
797 ospf6_interface_enable(oi);
798
799 /* If the router is ABR, originate summary routes */
beadc736 800 if (ospf6_is_router_abr(ospf6))
d62a17ae 801 ospf6_abr_enable_area(oa);
802
803 return CMD_SUCCESS;
718e3744 804}
805
508e53e2 806DEFUN (no_ospf6_interface_area,
807 no_ospf6_interface_area_cmd,
de842255 808 "no interface IFNAME area <A.B.C.D|(0-4294967295)>",
508e53e2 809 NO_STR
810 "Disable routing on an IPv6 interface\n"
811 IFNAME_STR
812 "Specify the OSPF6 area ID\n"
813 "OSPF6 area ID in IPv4 address notation\n"
de842255 814 "OSPF6 area ID in decimal notation\n"
508e53e2 815 )
718e3744 816{
d62a17ae 817 int idx_ifname = 2;
818 int idx_ipv4 = 4;
819 struct ospf6_interface *oi;
820 struct ospf6_area *oa;
821 struct interface *ifp;
d7c0a89a 822 uint32_t area_id;
d62a17ae 823
a36898e7 824 ifp = if_lookup_by_name(argv[idx_ifname]->arg, VRF_DEFAULT);
d62a17ae 825 if (ifp == NULL) {
826 vty_out(vty, "No such interface %s\n", argv[idx_ifname]->arg);
827 return CMD_SUCCESS;
828 }
6452df09 829
d62a17ae 830 oi = (struct ospf6_interface *)ifp->info;
831 if (oi == NULL) {
832 vty_out(vty, "Interface %s not enabled\n", ifp->name);
833 return CMD_SUCCESS;
834 }
835
836 /* parse Area-ID */
de842255
PR
837 if (inet_pton(AF_INET, argv[idx_ipv4]->arg, &area_id) != 1)
838 area_id = htonl(strtoul(argv[idx_ipv4]->arg, NULL, 10));
d62a17ae 839
840 /* Verify Area */
841 if (oi->area == NULL) {
842 vty_out(vty, "No such Area-ID: %s\n", argv[idx_ipv4]->arg);
843 return CMD_SUCCESS;
844 }
845
846 if (oi->area->area_id != area_id) {
847 vty_out(vty, "Wrong Area-ID: %s is attached to area %s\n",
848 oi->interface->name, oi->area->name);
849 return CMD_SUCCESS;
850 }
851
4a30f056 852 ospf6_interface_disable(oi);
d62a17ae 853
854 oa = oi->area;
855 listnode_delete(oi->area->if_list, oi);
856 oi->area = (struct ospf6_area *)NULL;
857
858 /* Withdraw inter-area routes from this area, if necessary */
859 if (oa->if_list->count == 0) {
860 UNSET_FLAG(oa->flag, OSPF6_AREA_ENABLE);
861 ospf6_abr_disable_area(oa);
862 }
4a30f056 863 ospf6_interface_delete(oi);
d62a17ae 864
865 return CMD_SUCCESS;
718e3744 866}
867
f41b4a02
DD
868DEFUN (ospf6_stub_router_admin,
869 ospf6_stub_router_admin_cmd,
870 "stub-router administrative",
871 "Make router a stub router\n"
f41b4a02
DD
872 "Administratively applied, for an indefinite period\n")
873{
d62a17ae 874 struct listnode *node;
875 struct ospf6_area *oa;
876
beadc736 877 VTY_DECLVAR_CONTEXT(ospf6, ospf6);
878
d62a17ae 879 if (!CHECK_FLAG(ospf6->flag, OSPF6_STUB_ROUTER)) {
880 for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, node, oa)) {
881 OSPF6_OPT_CLEAR(oa->options, OSPF6_OPT_V6);
882 OSPF6_OPT_CLEAR(oa->options, OSPF6_OPT_R);
883 OSPF6_ROUTER_LSA_SCHEDULE(oa);
884 }
885 SET_FLAG(ospf6->flag, OSPF6_STUB_ROUTER);
f41b4a02 886 }
f41b4a02 887
d62a17ae 888 return CMD_SUCCESS;
f41b4a02
DD
889}
890
891DEFUN (no_ospf6_stub_router_admin,
892 no_ospf6_stub_router_admin_cmd,
893 "no stub-router administrative",
894 NO_STR
895 "Make router a stub router\n"
f41b4a02
DD
896 "Administratively applied, for an indefinite period\n")
897{
d62a17ae 898 struct listnode *node;
899 struct ospf6_area *oa;
900
beadc736 901 VTY_DECLVAR_CONTEXT(ospf6, ospf6);
d62a17ae 902 if (CHECK_FLAG(ospf6->flag, OSPF6_STUB_ROUTER)) {
903 for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, node, oa)) {
904 OSPF6_OPT_SET(oa->options, OSPF6_OPT_V6);
905 OSPF6_OPT_SET(oa->options, OSPF6_OPT_R);
906 OSPF6_ROUTER_LSA_SCHEDULE(oa);
907 }
908 UNSET_FLAG(ospf6->flag, OSPF6_STUB_ROUTER);
f41b4a02 909 }
f41b4a02 910
d62a17ae 911 return CMD_SUCCESS;
f41b4a02
DD
912}
913
d7d73ffc 914#if 0
f41b4a02
DD
915DEFUN (ospf6_stub_router_startup,
916 ospf6_stub_router_startup_cmd,
6147e2c6 917 "stub-router on-startup (5-86400)",
f41b4a02
DD
918 "Make router a stub router\n"
919 "Advertise inability to be a transit router\n"
920 "Automatically advertise as stub-router on startup of OSPF6\n"
921 "Time (seconds) to advertise self as stub-router\n")
922{
923 return CMD_SUCCESS;
924}
925
926DEFUN (no_ospf6_stub_router_startup,
927 no_ospf6_stub_router_startup_cmd,
928 "no stub-router on-startup",
929 NO_STR
930 "Make router a stub router\n"
931 "Advertise inability to be a transit router\n"
932 "Automatically advertise as stub-router on startup of OSPF6\n"
933 "Time (seconds) to advertise self as stub-router\n")
934{
935 return CMD_SUCCESS;
936}
937
938DEFUN (ospf6_stub_router_shutdown,
939 ospf6_stub_router_shutdown_cmd,
6147e2c6 940 "stub-router on-shutdown (5-86400)",
f41b4a02
DD
941 "Make router a stub router\n"
942 "Advertise inability to be a transit router\n"
943 "Automatically advertise as stub-router before shutdown\n"
944 "Time (seconds) to advertise self as stub-router\n")
945{
946 return CMD_SUCCESS;
947}
948
949DEFUN (no_ospf6_stub_router_shutdown,
950 no_ospf6_stub_router_shutdown_cmd,
951 "no stub-router on-shutdown",
952 NO_STR
953 "Make router a stub router\n"
954 "Advertise inability to be a transit router\n"
955 "Automatically advertise as stub-router before shutdown\n"
956 "Time (seconds) to advertise self as stub-router\n")
957{
958 return CMD_SUCCESS;
959}
d7d73ffc 960#endif
f41b4a02 961
35a45dea 962
963static void ospf6_show(struct vty *vty, struct ospf6 *o, json_object *json,
964 bool use_json)
718e3744 965{
d62a17ae 966 struct listnode *n;
967 struct ospf6_area *oa;
968 char router_id[16], duration[32];
969 struct timeval now, running, result;
970 char buf[32], rbuf[32];
35a45dea 971 json_object *json_areas = NULL;
972 const char *adjacency;
973
974 if (use_json) {
975 json_areas = json_object_new_object();
976
977 /* process id, router id */
978 inet_ntop(AF_INET, &o->router_id, router_id, sizeof(router_id));
979 json_object_string_add(json, "routerId", router_id);
980
981 /* running time */
982 monotime(&now);
983 timersub(&now, &o->starttime, &running);
984 timerstring(&running, duration, sizeof(duration));
985 json_object_string_add(json, "running", duration);
986
987 /* Redistribute configuration */
988 /* XXX */
989 json_object_int_add(json, "lsaMinimumArrivalMsecs",
990 o->lsa_minarrival);
991
992 /* Show SPF parameters */
993 json_object_int_add(json, "spfScheduleDelayMsecs",
994 o->spf_delay);
995 json_object_int_add(json, "holdTimeMinMsecs", o->spf_holdtime);
996 json_object_int_add(json, "holdTimeMaxMsecs",
997 o->spf_max_holdtime);
998 json_object_int_add(json, "holdTimeMultiplier",
999 o->spf_hold_multiplier);
1000
1001
1002 if (o->ts_spf.tv_sec || o->ts_spf.tv_usec) {
1003 timersub(&now, &o->ts_spf, &result);
1004 timerstring(&result, buf, sizeof(buf));
1005 ospf6_spf_reason_string(o->last_spf_reason, rbuf,
1006 sizeof(rbuf));
1007 json_object_boolean_true_add(json, "spfHasRun");
1008 json_object_string_add(json, "spfLastExecutedMsecs",
1009 buf);
1010 json_object_string_add(json, "spfLastExecutedReason",
1011 rbuf);
1012
1013 json_object_int_add(
1014 json, "spfLastDurationSecs",
1015 (long long)o->ts_spf_duration.tv_sec);
1016
1017 json_object_int_add(
1018 json, "spfLastDurationMsecs",
1019 (long long)o->ts_spf_duration.tv_usec);
1020 } else
1021 json_object_boolean_false_add(json, "spfHasRun");
1022
1023
1024 threadtimer_string(now, o->t_spf_calc, buf, sizeof(buf));
1025 if (o->t_spf_calc) {
1026 long time_store;
1027
1028 json_object_boolean_true_add(json, "spfTimerActive");
1029 time_store =
1030 monotime_until(&o->t_spf_calc->u.sands, NULL)
1031 / 1000LL;
1032 json_object_int_add(json, "spfTimerDueInMsecs",
1033 time_store);
1034 } else
1035 json_object_boolean_false_add(json, "spfTimerActive");
1036
1037 json_object_boolean_add(json, "routerIsStubRouter",
1038 CHECK_FLAG(o->flag, OSPF6_STUB_ROUTER));
1039
1040 /* LSAs */
1041 json_object_int_add(json, "numberOfAsScopedLsa",
1042 o->lsdb->count);
1043 /* Areas */
1044 json_object_int_add(json, "numberOfAreaInRouter",
1045 listcount(o->area_list));
1046
1047 if (CHECK_FLAG(o->config_flags, OSPF6_LOG_ADJACENCY_CHANGES)) {
1048 if (CHECK_FLAG(o->config_flags,
1049 OSPF6_LOG_ADJACENCY_DETAIL))
1050 adjacency = "LoggedAll";
1051 else
1052 adjacency = "Logged";
1053 } else
1054 adjacency = "NotLogged";
1055 json_object_string_add(json, "adjacencyChanges", adjacency);
1056
1057 for (ALL_LIST_ELEMENTS_RO(o->area_list, n, oa))
1058 ospf6_area_show(vty, oa, json_areas, use_json);
1059
1060 json_object_object_add(json, "areas", json_areas);
1061
1062 vty_out(vty, "%s\n",
1063 json_object_to_json_string_ext(
1064 json, JSON_C_TO_STRING_PRETTY));
1065
1066 } else {
1067 /* process id, router id */
1068 inet_ntop(AF_INET, &o->router_id, router_id, sizeof(router_id));
1069 vty_out(vty, " OSPFv3 Routing Process (0) with Router-ID %s\n",
1070 router_id);
1071
1072 /* running time */
1073 monotime(&now);
1074 timersub(&now, &o->starttime, &running);
1075 timerstring(&running, duration, sizeof(duration));
1076 vty_out(vty, " Running %s\n", duration);
1077
1078 /* Redistribute configuration */
1079 /* XXX */
1080 vty_out(vty, " LSA minimum arrival %d msecs\n",
1081 o->lsa_minarrival);
1082
1083
1084 /* Show SPF parameters */
1085 vty_out(vty,
1086 " Initial SPF scheduling delay %d millisec(s)\n"
1087 " Minimum hold time between consecutive SPFs %d millsecond(s)\n"
1088 " Maximum hold time between consecutive SPFs %d millsecond(s)\n"
1089 " Hold time multiplier is currently %d\n",
1090 o->spf_delay, o->spf_holdtime, o->spf_max_holdtime,
1091 o->spf_hold_multiplier);
1092
1093
1094 vty_out(vty, " SPF algorithm ");
1095 if (o->ts_spf.tv_sec || o->ts_spf.tv_usec) {
1096 timersub(&now, &o->ts_spf, &result);
1097 timerstring(&result, buf, sizeof(buf));
1098 ospf6_spf_reason_string(o->last_spf_reason, rbuf,
1099 sizeof(rbuf));
1100 vty_out(vty, "last executed %s ago, reason %s\n", buf,
1101 rbuf);
1102 vty_out(vty, " Last SPF duration %lld sec %lld usec\n",
1103 (long long)o->ts_spf_duration.tv_sec,
1104 (long long)o->ts_spf_duration.tv_usec);
1105 } else
1106 vty_out(vty, "has not been run\n");
1107
1108 threadtimer_string(now, o->t_spf_calc, buf, sizeof(buf));
1109 vty_out(vty, " SPF timer %s%s\n",
1110 (o->t_spf_calc ? "due in " : "is "), buf);
1111
1112 if (CHECK_FLAG(o->flag, OSPF6_STUB_ROUTER))
1113 vty_out(vty, " Router Is Stub Router\n");
1114
1115 /* LSAs */
1116 vty_out(vty, " Number of AS scoped LSAs is %u\n",
1117 o->lsdb->count);
1118
1119 /* Areas */
1120 vty_out(vty, " Number of areas in this router is %u\n",
1121 listcount(o->area_list));
1122
1123 if (CHECK_FLAG(o->config_flags, OSPF6_LOG_ADJACENCY_CHANGES)) {
1124 if (CHECK_FLAG(o->config_flags,
1125 OSPF6_LOG_ADJACENCY_DETAIL))
1126 vty_out(vty,
1127 " All adjacency changes are logged\n");
1128 else
1129 vty_out(vty, " Adjacency changes are logged\n");
1130 }
d62a17ae 1131
d62a17ae 1132
35a45dea 1133 vty_out(vty, "\n");
d62a17ae 1134
35a45dea 1135 for (ALL_LIST_ELEMENTS_RO(o->area_list, n, oa))
1136 ospf6_area_show(vty, oa, json_areas, use_json);
1137 }
718e3744 1138}
1139
508e53e2 1140/* show top level structures */
35a45dea 1141DEFUN(show_ipv6_ospf6,
1142 show_ipv6_ospf6_cmd,
1143 "show ipv6 ospf6 [json]",
1144 SHOW_STR
1145 IP6_STR
1146 OSPF6_STR
1147 JSON_STR)
718e3744 1148{
beadc736 1149 struct ospf6 *ospf6;
35a45dea 1150 bool uj = use_json(argc, argv);
1151 json_object *json = NULL;
508e53e2 1152
beadc736 1153 ospf6 = ospf6_lookup_by_vrf_name(VRF_DEFAULT_NAME);
1154 OSPF6_CMD_CHECK_RUNNING(ospf6);
35a45dea 1155
1156 if (uj)
1157 json = json_object_new_object();
1158
1159 ospf6_show(vty, ospf6, json, uj);
1160
1161 if (uj)
1162 json_object_free(json);
d62a17ae 1163 return CMD_SUCCESS;
718e3744 1164}
1165
1166DEFUN (show_ipv6_ospf6_route,
1167 show_ipv6_ospf6_route_cmd,
6de69f83 1168 "show ipv6 ospf6 route [<intra-area|inter-area|external-1|external-2|X:X::X:X|X:X::X:X/M|detail|summary>]",
718e3744 1169 SHOW_STR
1170 IP6_STR
1171 OSPF6_STR
508e53e2 1172 ROUTE_STR
1d68dbfe
DW
1173 "Display Intra-Area routes\n"
1174 "Display Inter-Area routes\n"
1175 "Display Type-1 External routes\n"
1176 "Display Type-2 External routes\n"
1177 "Specify IPv6 address\n"
1178 "Specify IPv6 prefix\n"
1179 "Detailed information\n"
1180 "Summary of route table\n")
718e3744 1181{
beadc736 1182 struct ospf6 *ospf6;
1183
1184 ospf6 = ospf6_lookup_by_vrf_name(VRF_DEFAULT_NAME);
1185 OSPF6_CMD_CHECK_RUNNING(ospf6);
b52a8a52 1186
d62a17ae 1187 ospf6_route_table_show(vty, 4, argc, argv, ospf6->route_table);
1188 return CMD_SUCCESS;
718e3744 1189}
1190
508e53e2 1191DEFUN (show_ipv6_ospf6_route_match,
1192 show_ipv6_ospf6_route_match_cmd,
1d68dbfe 1193 "show ipv6 ospf6 route X:X::X:X/M <match|longer>",
718e3744 1194 SHOW_STR
1195 IP6_STR
1196 OSPF6_STR
508e53e2 1197 ROUTE_STR
1198 "Specify IPv6 prefix\n"
1199 "Display routes which match the specified route\n"
1d68dbfe 1200 "Display routes longer than the specified route\n")
718e3744 1201{
beadc736 1202 struct ospf6 *ospf6;
1203
1204 ospf6 = ospf6_lookup_by_vrf_name(VRF_DEFAULT_NAME);
1205 OSPF6_CMD_CHECK_RUNNING(ospf6);
b52a8a52 1206
d62a17ae 1207 ospf6_route_table_show(vty, 4, argc, argv, ospf6->route_table);
beadc736 1208
d62a17ae 1209 return CMD_SUCCESS;
718e3744 1210}
1211
508e53e2 1212DEFUN (show_ipv6_ospf6_route_match_detail,
1213 show_ipv6_ospf6_route_match_detail_cmd,
4846ef64 1214 "show ipv6 ospf6 route X:X::X:X/M match detail",
718e3744 1215 SHOW_STR
1216 IP6_STR
1217 OSPF6_STR
508e53e2 1218 ROUTE_STR
1219 "Specify IPv6 prefix\n"
1220 "Display routes which match the specified route\n"
718e3744 1221 "Detailed information\n"
1222 )
508e53e2 1223{
beadc736 1224 struct ospf6 *ospf6;
1225
1226 ospf6 = ospf6_lookup_by_vrf_name(VRF_DEFAULT_NAME);
1227 OSPF6_CMD_CHECK_RUNNING(ospf6);
b52a8a52 1228
d62a17ae 1229 ospf6_route_table_show(vty, 4, argc, argv, ospf6->route_table);
1230 return CMD_SUCCESS;
508e53e2 1231}
718e3744 1232
cb4b8845 1233
4846ef64 1234DEFUN (show_ipv6_ospf6_route_type_detail,
1235 show_ipv6_ospf6_route_type_detail_cmd,
6147e2c6 1236 "show ipv6 ospf6 route <intra-area|inter-area|external-1|external-2> detail",
4846ef64 1237 SHOW_STR
1238 IP6_STR
1239 OSPF6_STR
1240 ROUTE_STR
ea402198
DO
1241 "Display Intra-Area routes\n"
1242 "Display Inter-Area routes\n"
1243 "Display Type-1 External routes\n"
1244 "Display Type-2 External routes\n"
4846ef64 1245 "Detailed information\n"
1246 )
1247{
beadc736 1248 struct ospf6 *ospf6;
1249
1250 ospf6 = ospf6_lookup_by_vrf_name(VRF_DEFAULT_NAME);
1251 OSPF6_CMD_CHECK_RUNNING(ospf6);
b52a8a52 1252
d62a17ae 1253 ospf6_route_table_show(vty, 4, argc, argv, ospf6->route_table);
1254 return CMD_SUCCESS;
4846ef64 1255}
718e3744 1256
beadc736 1257static void ospf6_stub_router_config_write(struct vty *vty, struct ospf6 *ospf6)
f41b4a02 1258{
d62a17ae 1259 if (CHECK_FLAG(ospf6->flag, OSPF6_STUB_ROUTER)) {
1260 vty_out(vty, " stub-router administrative\n");
1261 }
1262 return;
f41b4a02
DD
1263}
1264
beadc736 1265static int ospf6_distance_config_write(struct vty *vty, struct ospf6 *ospf6)
baff583e 1266{
d62a17ae 1267 struct route_node *rn;
1268 struct ospf6_distance *odistance;
1269
1270 if (ospf6->distance_all)
1271 vty_out(vty, " distance %u\n", ospf6->distance_all);
1272
1273 if (ospf6->distance_intra || ospf6->distance_inter
1274 || ospf6->distance_external) {
1275 vty_out(vty, " distance ospf6");
1276
1277 if (ospf6->distance_intra)
1278 vty_out(vty, " intra-area %u", ospf6->distance_intra);
1279 if (ospf6->distance_inter)
1280 vty_out(vty, " inter-area %u", ospf6->distance_inter);
1281 if (ospf6->distance_external)
1282 vty_out(vty, " external %u", ospf6->distance_external);
1283
1284 vty_out(vty, "\n");
1285 }
1286
1287 for (rn = route_top(ospf6->distance_table); rn; rn = route_next(rn))
2dbe669b
DA
1288 if ((odistance = rn->info) != NULL)
1289 vty_out(vty, " distance %u %pFX %s\n",
1290 odistance->distance, &rn->p,
d62a17ae 1291 odistance->access_list ? odistance->access_list
1292 : "");
d62a17ae 1293 return 0;
baff583e
MZ
1294}
1295
508e53e2 1296/* OSPF configuration write function. */
d62a17ae 1297static int config_write_ospf6(struct vty *vty)
508e53e2 1298{
d62a17ae 1299 struct listnode *j, *k;
1300 struct ospf6_area *oa;
1301 struct ospf6_interface *oi;
beadc736 1302 struct ospf6 *ospf6;
1303 struct listnode *node, *nnode;
d62a17ae 1304
1305 /* OSPFv3 configuration. */
beadc736 1306 if (om6 == NULL)
d62a17ae 1307 return CMD_SUCCESS;
1308
beadc736 1309 for (ALL_LIST_ELEMENTS(om6->ospf6, node, nnode, ospf6)) {
1310 vty_out(vty, "router ospf6\n");
1311 if (ospf6->router_id_static != 0)
1312 vty_out(vty, " ospf6 router-id %pI4\n",
1313 &ospf6->router_id_static);
1314
1315 /* log-adjacency-changes flag print. */
1316 if (CHECK_FLAG(ospf6->config_flags,
1317 OSPF6_LOG_ADJACENCY_CHANGES)) {
1318 if (CHECK_FLAG(ospf6->config_flags,
1319 OSPF6_LOG_ADJACENCY_DETAIL))
1320 vty_out(vty, " log-adjacency-changes detail\n");
1321 else if (!SAVE_OSPF6_LOG_ADJACENCY_CHANGES)
1322 vty_out(vty, " log-adjacency-changes\n");
1323 } else if (SAVE_OSPF6_LOG_ADJACENCY_CHANGES) {
1324 vty_out(vty, " no log-adjacency-changes\n");
1325 }
d62a17ae 1326
beadc736 1327 if (ospf6->ref_bandwidth != OSPF6_REFERENCE_BANDWIDTH)
1328 vty_out(vty, " auto-cost reference-bandwidth %d\n",
1329 ospf6->ref_bandwidth);
1330
1331 /* LSA timers print. */
1332 if (ospf6->lsa_minarrival != OSPF_MIN_LS_ARRIVAL)
1333 vty_out(vty, " timers lsa min-arrival %d\n",
1334 ospf6->lsa_minarrival);
1335
1336 ospf6_stub_router_config_write(vty, ospf6);
1337 ospf6_redistribute_config_write(vty, ospf6);
1338 ospf6_area_config_write(vty, ospf6);
1339 ospf6_spf_config_write(vty, ospf6);
1340 ospf6_distance_config_write(vty, ospf6);
1341
1342 for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, j, oa)) {
1343 for (ALL_LIST_ELEMENTS_RO(oa->if_list, k, oi))
1344 vty_out(vty, " interface %s area %s\n",
1345 oi->interface->name, oa->name);
1346 }
1347 vty_out(vty, "!\n");
d62a17ae 1348 }
d62a17ae 1349 return 0;
508e53e2 1350}
1351
612c2c15 1352static int config_write_ospf6(struct vty *vty);
508e53e2 1353/* OSPF6 node structure. */
d62a17ae 1354static struct cmd_node ospf6_node = {
f4b8291f 1355 .name = "ospf6",
62b346ee 1356 .node = OSPF6_NODE,
24389580 1357 .parent_node = CONFIG_NODE,
62b346ee 1358 .prompt = "%s(config-ospf6)# ",
612c2c15 1359 .config_write = config_write_ospf6,
508e53e2 1360};
1361
1362/* Install ospf related commands. */
d62a17ae 1363void ospf6_top_init(void)
718e3744 1364{
d62a17ae 1365 /* Install ospf6 top node. */
612c2c15 1366 install_node(&ospf6_node);
d62a17ae 1367
1368 install_element(VIEW_NODE, &show_ipv6_ospf6_cmd);
1369 install_element(CONFIG_NODE, &router_ospf6_cmd);
1370 install_element(CONFIG_NODE, &no_router_ospf6_cmd);
1371
1372 install_element(VIEW_NODE, &show_ipv6_ospf6_route_cmd);
1373 install_element(VIEW_NODE, &show_ipv6_ospf6_route_match_cmd);
1374 install_element(VIEW_NODE, &show_ipv6_ospf6_route_match_detail_cmd);
1375 install_element(VIEW_NODE, &show_ipv6_ospf6_route_type_detail_cmd);
1376
1377 install_default(OSPF6_NODE);
1378 install_element(OSPF6_NODE, &ospf6_router_id_cmd);
5d1a2ee8 1379 install_element(OSPF6_NODE, &no_ospf6_router_id_cmd);
d62a17ae 1380 install_element(OSPF6_NODE, &ospf6_log_adjacency_changes_cmd);
1381 install_element(OSPF6_NODE, &ospf6_log_adjacency_changes_detail_cmd);
1382 install_element(OSPF6_NODE, &no_ospf6_log_adjacency_changes_cmd);
1383 install_element(OSPF6_NODE, &no_ospf6_log_adjacency_changes_detail_cmd);
1384
1385 /* LSA timers commands */
1386 install_element(OSPF6_NODE, &ospf6_timers_lsa_cmd);
1387 install_element(OSPF6_NODE, &no_ospf6_timers_lsa_cmd);
1388
1389 install_element(OSPF6_NODE, &ospf6_interface_area_cmd);
1390 install_element(OSPF6_NODE, &no_ospf6_interface_area_cmd);
1391 install_element(OSPF6_NODE, &ospf6_stub_router_admin_cmd);
1392 install_element(OSPF6_NODE, &no_ospf6_stub_router_admin_cmd);
1393/* For a later time */
34d5ef45 1394#if 0
f41b4a02
DD
1395 install_element (OSPF6_NODE, &ospf6_stub_router_startup_cmd);
1396 install_element (OSPF6_NODE, &no_ospf6_stub_router_startup_cmd);
1397 install_element (OSPF6_NODE, &ospf6_stub_router_shutdown_cmd);
1398 install_element (OSPF6_NODE, &no_ospf6_stub_router_shutdown_cmd);
34d5ef45 1399#endif
508e53e2 1400
d62a17ae 1401 install_element(OSPF6_NODE, &ospf6_distance_cmd);
1402 install_element(OSPF6_NODE, &no_ospf6_distance_cmd);
1403 install_element(OSPF6_NODE, &ospf6_distance_ospf6_cmd);
1404 install_element(OSPF6_NODE, &no_ospf6_distance_ospf6_cmd);
baff583e
MZ
1405#if 0
1406 install_element (OSPF6_NODE, &ospf6_distance_source_cmd);
1407 install_element (OSPF6_NODE, &no_ospf6_distance_source_cmd);
1408#endif
718e3744 1409}