]> git.proxmox.com Git - mirror_frr.git/blame - ospf6d/ospf6_top.c
ospf6: get instance from route table scope
[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{
beadc736 127 struct ospf6 *ospf6 = NULL;
128
d62a17ae 129 switch (ntohs(lsa->header->type)) {
130 case OSPF6_LSTYPE_AS_EXTERNAL:
beadc736 131 ospf6 = ospf6_get_by_lsdb(lsa);
132 ospf6_asbr_lsa_add(lsa, ospf6);
d62a17ae 133 break;
134
135 default:
136 break;
137 }
718e3744 138}
139
d62a17ae 140static void ospf6_top_lsdb_hook_remove(struct ospf6_lsa *lsa)
718e3744 141{
d62a17ae 142 switch (ntohs(lsa->header->type)) {
143 case OSPF6_LSTYPE_AS_EXTERNAL:
07b37f93 144 ospf6_asbr_lsa_remove(lsa, NULL);
d62a17ae 145 break;
146
147 default:
148 break;
149 }
718e3744 150}
151
e285b70d 152static void ospf6_top_route_hook_add(struct ospf6_route *route)
049207c3 153{
e285b70d
IR
154 struct ospf6 *ospf6 = route->table->scope;
155
beadc736 156 ospf6_abr_originate_summary(route, ospf6);
157 ospf6_zebra_route_update_add(route, ospf6);
049207c3 158}
159
e285b70d 160static void ospf6_top_route_hook_remove(struct ospf6_route *route)
049207c3 161{
e285b70d
IR
162 struct ospf6 *ospf6 = route->table->scope;
163
d62a17ae 164 route->flag |= OSPF6_ROUTE_REMOVE;
beadc736 165 ospf6_abr_originate_summary(route, ospf6);
166 ospf6_zebra_route_update_remove(route, ospf6);
049207c3 167}
168
e285b70d 169static void ospf6_top_brouter_hook_add(struct ospf6_route *route)
6452df09 170{
e285b70d
IR
171 struct ospf6 *ospf6 = route->table->scope;
172
99ab28cb
CS
173 if (IS_OSPF6_DEBUG_EXAMIN(AS_EXTERNAL) ||
174 IS_OSPF6_DEBUG_BROUTER) {
07b37f93
CS
175 uint32_t brouter_id;
176 char brouter_name[16];
177
178 brouter_id = ADV_ROUTER_IN_PREFIX(&route->prefix);
179 inet_ntop(AF_INET, &brouter_id, brouter_name,
180 sizeof(brouter_name));
181 zlog_debug("%s: brouter %s add with adv router %x nh count %u",
15569c58 182 __func__, brouter_name,
07b37f93
CS
183 route->path.origin.adv_router,
184 listcount(route->nh_list));
064d4355 185 }
beadc736 186 ospf6_abr_examin_brouter(ADV_ROUTER_IN_PREFIX(&route->prefix), route,
187 ospf6);
188 ospf6_asbr_lsentry_add(route, ospf6);
189 ospf6_abr_originate_summary(route, ospf6);
6452df09 190}
191
e285b70d 192static void ospf6_top_brouter_hook_remove(struct ospf6_route *route)
6452df09 193{
e285b70d
IR
194 struct ospf6 *ospf6 = route->table->scope;
195
99ab28cb
CS
196 if (IS_OSPF6_DEBUG_EXAMIN(AS_EXTERNAL) ||
197 IS_OSPF6_DEBUG_BROUTER) {
07b37f93
CS
198 uint32_t brouter_id;
199 char brouter_name[16];
064d4355 200
07b37f93
CS
201 brouter_id = ADV_ROUTER_IN_PREFIX(&route->prefix);
202 inet_ntop(AF_INET, &brouter_id, brouter_name,
203 sizeof(brouter_name));
99ab28cb 204 zlog_debug("%s: brouter %p %s del with adv router %x nh %u",
15569c58 205 __func__, (void *)route, brouter_name,
99ab28cb 206 route->path.origin.adv_router,
07b37f93 207 listcount(route->nh_list));
064d4355 208 }
d62a17ae 209 route->flag |= OSPF6_ROUTE_REMOVE;
beadc736 210 ospf6_abr_examin_brouter(ADV_ROUTER_IN_PREFIX(&route->prefix), route,
211 ospf6);
212 ospf6_asbr_lsentry_remove(route, ospf6);
213 ospf6_abr_originate_summary(route, ospf6);
6452df09 214}
215
7df1f362 216static struct ospf6 *ospf6_create(const char *name)
718e3744 217{
d62a17ae 218 struct ospf6 *o;
7df1f362 219 struct vrf *vrf = NULL;
718e3744 220
d62a17ae 221 o = XCALLOC(MTYPE_OSPF6_TOP, sizeof(struct ospf6));
718e3744 222
7df1f362
K
223 vrf = vrf_lookup_by_name(name);
224 if (vrf) {
225 o->vrf_id = vrf->vrf_id;
beadc736 226 } else
227 o->vrf_id = VRF_UNKNOWN;
228
229 /* Freed in ospf6_delete */
230 o->name = XSTRDUP(MTYPE_OSPF6_TOP, name);
231 if (vrf)
232 ospf6_vrf_link(o, vrf);
233
234 ospf6_zebra_vrf_register(o);
235
d62a17ae 236 /* initialize */
237 monotime(&o->starttime);
238 o->area_list = list_new();
239 o->area_list->cmp = ospf6_area_cmp;
240 o->lsdb = ospf6_lsdb_create(o);
241 o->lsdb_self = ospf6_lsdb_create(o);
242 o->lsdb->hook_add = ospf6_top_lsdb_hook_add;
243 o->lsdb->hook_remove = ospf6_top_lsdb_hook_remove;
718e3744 244
d62a17ae 245 o->spf_delay = OSPF_SPF_DELAY_DEFAULT;
246 o->spf_holdtime = OSPF_SPF_HOLDTIME_DEFAULT;
247 o->spf_max_holdtime = OSPF_SPF_MAX_HOLDTIME_DEFAULT;
248 o->spf_hold_multiplier = 1;
3810e06e 249
d62a17ae 250 /* LSA timers value init */
251 o->lsa_minarrival = OSPF_MIN_LS_ARRIVAL;
b6927875 252
d62a17ae 253 o->route_table = OSPF6_ROUTE_TABLE_CREATE(GLOBAL, ROUTES);
254 o->route_table->scope = o;
255 o->route_table->hook_add = ospf6_top_route_hook_add;
256 o->route_table->hook_remove = ospf6_top_route_hook_remove;
718e3744 257
d62a17ae 258 o->brouter_table = OSPF6_ROUTE_TABLE_CREATE(GLOBAL, BORDER_ROUTERS);
259 o->brouter_table->scope = o;
260 o->brouter_table->hook_add = ospf6_top_brouter_hook_add;
261 o->brouter_table->hook_remove = ospf6_top_brouter_hook_remove;
049207c3 262
d62a17ae 263 o->external_table = OSPF6_ROUTE_TABLE_CREATE(GLOBAL, EXTERNAL_ROUTES);
264 o->external_table->scope = o;
cf1ce250 265
d62a17ae 266 o->external_id_table = route_table_init();
718e3744 267
d62a17ae 268 o->ref_bandwidth = OSPF6_REFERENCE_BANDWIDTH;
fd500689 269
d62a17ae 270 o->distance_table = route_table_init();
7df1f362 271 o->fd = -1;
baff583e 272
d62a17ae 273 QOBJ_REG(o, ospf6);
692c7954 274
7df1f362
K
275 /* Make ospf protocol socket. */
276 ospf6_serv_sock(o);
277
d62a17ae 278 return o;
718e3744 279}
280
beadc736 281struct ospf6 *ospf6_instance_create(const char *name)
7df1f362 282{
beadc736 283 struct ospf6 *ospf6;
284
7df1f362
K
285 ospf6 = ospf6_create(name);
286 if (DFLT_OSPF6_LOG_ADJACENCY_CHANGES)
287 SET_FLAG(ospf6->config_flags, OSPF6_LOG_ADJACENCY_CHANGES);
288 if (ospf6->router_id == 0)
beadc736 289 ospf6_router_id_update(ospf6);
290 ospf6_add(ospf6);
7df1f362
K
291 thread_add_read(master, ospf6_receive, ospf6, ospf6->fd,
292 &ospf6->t_ospf6_receive);
beadc736 293
294 return ospf6;
7df1f362
K
295}
296
d62a17ae 297void ospf6_delete(struct ospf6 *o)
718e3744 298{
d62a17ae 299 struct listnode *node, *nnode;
300 struct ospf6_area *oa;
718e3744 301
d62a17ae 302 QOBJ_UNREG(o);
76249532 303
beadc736 304 ospf6_flush_self_originated_lsas_now(o);
305 ospf6_disable(o);
306 ospf6_del(o);
ae2254aa 307
d62a17ae 308 for (ALL_LIST_ELEMENTS(o->area_list, node, nnode, oa))
309 ospf6_area_delete(oa);
d9628728
CF
310
311
6a154c88 312 list_delete(&o->area_list);
718e3744 313
d62a17ae 314 ospf6_lsdb_delete(o->lsdb);
315 ospf6_lsdb_delete(o->lsdb_self);
718e3744 316
e285b70d
IR
317 ospf6_route_table_delete(o->route_table);
318 ospf6_route_table_delete(o->brouter_table);
718e3744 319
e285b70d 320 ospf6_route_table_delete(o->external_table);
d62a17ae 321 route_table_finish(o->external_id_table);
718e3744 322
d62a17ae 323 ospf6_distance_reset(o);
324 route_table_finish(o->distance_table);
baff583e 325
7df1f362 326 XFREE(MTYPE_OSPF6_TOP, o->name);
d62a17ae 327 XFREE(MTYPE_OSPF6_TOP, o);
508e53e2 328}
718e3744 329
d62a17ae 330static void ospf6_disable(struct ospf6 *o)
718e3744 331{
d62a17ae 332 struct listnode *node, *nnode;
333 struct ospf6_area *oa;
334
335 if (!CHECK_FLAG(o->flag, OSPF6_DISABLED)) {
336 SET_FLAG(o->flag, OSPF6_DISABLED);
337
338 for (ALL_LIST_ELEMENTS(o->area_list, node, nnode, oa))
339 ospf6_area_disable(oa);
340
341 /* XXX: This also changes persistent settings */
c5d28568 342 ospf6_asbr_redistribute_reset(o->vrf_id);
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 {
7df1f362 464 ospf6_serv_close(&ospf6->fd);
d62a17ae 465 ospf6_delete(ospf6);
466 ospf6 = NULL;
467 }
34288970 468
d62a17ae 469 /* return to config node . */
470 VTY_PUSH_CONTEXT_NULL(CONFIG_NODE);
508e53e2 471
d62a17ae 472 return CMD_SUCCESS;
718e3744 473}
474
508e53e2 475/* change Router_ID commands. */
60466a63
QY
476DEFUN(ospf6_router_id,
477 ospf6_router_id_cmd,
478 "ospf6 router-id A.B.C.D",
479 OSPF6_STR
480 "Configure OSPF6 Router-ID\n"
481 V4NOTATION_STR)
718e3744 482{
d62a17ae 483 VTY_DECLVAR_CONTEXT(ospf6, o);
5d1a2ee8 484 int idx = 0;
d62a17ae 485 int ret;
5d1a2ee8 486 const char *router_id_str;
d7c0a89a 487 uint32_t router_id;
d6927cf3
CS
488 struct ospf6_area *oa;
489 struct listnode *node;
d62a17ae 490
5d1a2ee8
QY
491 argv_find(argv, argc, "A.B.C.D", &idx);
492 router_id_str = argv[idx]->arg;
493
494 ret = inet_pton(AF_INET, router_id_str, &router_id);
d62a17ae 495 if (ret == 0) {
60466a63 496 vty_out(vty, "malformed OSPF Router-ID: %s\n", router_id_str);
d62a17ae 497 return CMD_SUCCESS;
498 }
508e53e2 499
d62a17ae 500 o->router_id_static = router_id;
d6927cf3
CS
501
502 for (ALL_LIST_ELEMENTS_RO(o->area_list, node, oa)) {
503 if (oa->full_nbrs) {
504 vty_out(vty,
3efd0893 505 "For this router-id change to take effect, save config and restart ospf6d\n");
d6927cf3
CS
506 return CMD_SUCCESS;
507 }
508 }
509
510 o->router_id = router_id;
c8a440ec 511
d62a17ae 512 return CMD_SUCCESS;
718e3744 513}
514
60466a63
QY
515DEFUN(no_ospf6_router_id,
516 no_ospf6_router_id_cmd,
517 "no ospf6 router-id [A.B.C.D]",
518 NO_STR OSPF6_STR
519 "Configure OSPF6 Router-ID\n"
520 V4NOTATION_STR)
5d1a2ee8
QY
521{
522 VTY_DECLVAR_CONTEXT(ospf6, o);
d6927cf3
CS
523 struct ospf6_area *oa;
524 struct listnode *node;
525
5d1a2ee8 526 o->router_id_static = 0;
d6927cf3
CS
527
528 for (ALL_LIST_ELEMENTS_RO(o->area_list, node, oa)) {
529 if (oa->full_nbrs) {
530 vty_out(vty,
3efd0893 531 "For this router-id change to take effect, save config and restart ospf6d\n");
d6927cf3
CS
532 return CMD_SUCCESS;
533 }
534 }
5d1a2ee8 535 o->router_id = 0;
d6927cf3
CS
536 if (o->router_id_zebra.s_addr)
537 o->router_id = (uint32_t)o->router_id_zebra.s_addr;
5d1a2ee8
QY
538
539 return CMD_SUCCESS;
540}
541
3d35ca48
DD
542DEFUN (ospf6_log_adjacency_changes,
543 ospf6_log_adjacency_changes_cmd,
544 "log-adjacency-changes",
545 "Log changes in adjacency state\n")
546{
d62a17ae 547 VTY_DECLVAR_CONTEXT(ospf6, ospf6);
3d35ca48 548
d62a17ae 549 SET_FLAG(ospf6->config_flags, OSPF6_LOG_ADJACENCY_CHANGES);
550 UNSET_FLAG(ospf6->config_flags, OSPF6_LOG_ADJACENCY_DETAIL);
551 return CMD_SUCCESS;
3d35ca48
DD
552}
553
554DEFUN (ospf6_log_adjacency_changes_detail,
555 ospf6_log_adjacency_changes_detail_cmd,
556 "log-adjacency-changes detail",
692c7954 557 "Log changes in adjacency state\n"
3d35ca48
DD
558 "Log all state changes\n")
559{
d62a17ae 560 VTY_DECLVAR_CONTEXT(ospf6, ospf6);
3d35ca48 561
d62a17ae 562 SET_FLAG(ospf6->config_flags, OSPF6_LOG_ADJACENCY_CHANGES);
563 SET_FLAG(ospf6->config_flags, OSPF6_LOG_ADJACENCY_DETAIL);
564 return CMD_SUCCESS;
3d35ca48
DD
565}
566
567DEFUN (no_ospf6_log_adjacency_changes,
568 no_ospf6_log_adjacency_changes_cmd,
569 "no log-adjacency-changes",
692c7954 570 NO_STR
3d35ca48
DD
571 "Log changes in adjacency state\n")
572{
d62a17ae 573 VTY_DECLVAR_CONTEXT(ospf6, ospf6);
3d35ca48 574
d62a17ae 575 UNSET_FLAG(ospf6->config_flags, OSPF6_LOG_ADJACENCY_DETAIL);
576 UNSET_FLAG(ospf6->config_flags, OSPF6_LOG_ADJACENCY_CHANGES);
577 return CMD_SUCCESS;
3d35ca48
DD
578}
579
580DEFUN (no_ospf6_log_adjacency_changes_detail,
581 no_ospf6_log_adjacency_changes_detail_cmd,
582 "no log-adjacency-changes detail",
692c7954
DW
583 NO_STR
584 "Log changes in adjacency state\n"
3d35ca48
DD
585 "Log all state changes\n")
586{
d62a17ae 587 VTY_DECLVAR_CONTEXT(ospf6, ospf6);
3d35ca48 588
d62a17ae 589 UNSET_FLAG(ospf6->config_flags, OSPF6_LOG_ADJACENCY_DETAIL);
590 return CMD_SUCCESS;
3d35ca48
DD
591}
592
b6927875
DS
593DEFUN (ospf6_timers_lsa,
594 ospf6_timers_lsa_cmd,
6147e2c6 595 "timers lsa min-arrival (0-600000)",
b6927875
DS
596 "Adjust routing timers\n"
597 "OSPF6 LSA timers\n"
598 "Minimum delay in receiving new version of a LSA\n"
599 "Delay in milliseconds\n")
600{
d62a17ae 601 VTY_DECLVAR_CONTEXT(ospf6, ospf);
602 int idx_number = 3;
603 unsigned int minarrival;
b6927875 604
d62a17ae 605 minarrival = strtoul(argv[idx_number]->arg, NULL, 10);
606 ospf->lsa_minarrival = minarrival;
b6927875 607
d62a17ae 608 return CMD_SUCCESS;
b6927875
DS
609}
610
611DEFUN (no_ospf6_timers_lsa,
612 no_ospf6_timers_lsa_cmd,
1d68dbfe 613 "no timers lsa min-arrival [(0-600000)]",
b6927875
DS
614 NO_STR
615 "Adjust routing timers\n"
616 "OSPF6 LSA timers\n"
3a2d747c
QY
617 "Minimum delay in receiving new version of a LSA\n"
618 "Delay in milliseconds\n")
b6927875 619{
d62a17ae 620 VTY_DECLVAR_CONTEXT(ospf6, ospf);
621 int idx_number = 4;
622 unsigned int minarrival;
b6927875 623
d62a17ae 624 if (argc == 5) {
625 minarrival = strtoul(argv[idx_number]->arg, NULL, 10);
b6927875 626
d62a17ae 627 if (ospf->lsa_minarrival != minarrival
628 || minarrival == OSPF_MIN_LS_ARRIVAL)
629 return CMD_SUCCESS;
630 }
b6927875 631
d62a17ae 632 ospf->lsa_minarrival = OSPF_MIN_LS_ARRIVAL;
b6927875 633
d62a17ae 634 return CMD_SUCCESS;
b6927875
DS
635}
636
b6927875 637
baff583e
MZ
638DEFUN (ospf6_distance,
639 ospf6_distance_cmd,
39e92c06 640 "distance (1-255)",
baff583e
MZ
641 "Administrative distance\n"
642 "OSPF6 Administrative distance\n")
643{
d62a17ae 644 VTY_DECLVAR_CONTEXT(ospf6, o);
baff583e 645
d62a17ae 646 o->distance_all = atoi(argv[1]->arg);
baff583e 647
d62a17ae 648 return CMD_SUCCESS;
baff583e
MZ
649}
650
651DEFUN (no_ospf6_distance,
652 no_ospf6_distance_cmd,
39e92c06 653 "no distance (1-255)",
baff583e
MZ
654 NO_STR
655 "Administrative distance\n"
656 "OSPF6 Administrative distance\n")
657{
d62a17ae 658 VTY_DECLVAR_CONTEXT(ospf6, o);
baff583e 659
d62a17ae 660 o->distance_all = 0;
baff583e 661
d62a17ae 662 return CMD_SUCCESS;
baff583e
MZ
663}
664
665DEFUN (ospf6_distance_ospf6,
666 ospf6_distance_ospf6_cmd,
eaa1ae0d 667 "distance ospf6 {intra-area (1-255)|inter-area (1-255)|external (1-255)}",
baff583e 668 "Administrative distance\n"
eaa1ae0d 669 "OSPF6 administrative distance\n"
39e92c06
QY
670 "Intra-area routes\n"
671 "Distance for intra-area routes\n"
672 "Inter-area routes\n"
673 "Distance for inter-area routes\n"
674 "External routes\n"
baff583e
MZ
675 "Distance for external routes\n")
676{
d62a17ae 677 VTY_DECLVAR_CONTEXT(ospf6, o);
678 int idx = 0;
679
f89a449b
CS
680 o->distance_intra = 0;
681 o->distance_inter = 0;
682 o->distance_external = 0;
683
d62a17ae 684 if (argv_find(argv, argc, "intra-area", &idx))
685 o->distance_intra = atoi(argv[idx + 1]->arg);
686 idx = 0;
687 if (argv_find(argv, argc, "inter-area", &idx))
688 o->distance_inter = atoi(argv[idx + 1]->arg);
689 idx = 0;
690 if (argv_find(argv, argc, "external", &idx))
691 o->distance_external = atoi(argv[idx + 1]->arg);
39e92c06 692
d62a17ae 693 return CMD_SUCCESS;
baff583e
MZ
694}
695
696DEFUN (no_ospf6_distance_ospf6,
697 no_ospf6_distance_ospf6_cmd,
eaa1ae0d 698 "no distance ospf6 [{intra-area [(1-255)]|inter-area [(1-255)]|external [(1-255)]}]",
baff583e
MZ
699 NO_STR
700 "Administrative distance\n"
701 "OSPF6 distance\n"
702 "Intra-area routes\n"
703 "Distance for intra-area routes\n"
704 "Inter-area routes\n"
705 "Distance for inter-area routes\n"
706 "External routes\n"
707 "Distance for external routes\n")
708{
d62a17ae 709 VTY_DECLVAR_CONTEXT(ospf6, o);
710 int idx = 0;
baff583e 711
d62a17ae 712 if (argv_find(argv, argc, "intra-area", &idx) || argc == 3)
713 idx = o->distance_intra = 0;
714 if (argv_find(argv, argc, "inter-area", &idx) || argc == 3)
715 idx = o->distance_inter = 0;
716 if (argv_find(argv, argc, "external", &idx) || argc == 3)
717 o->distance_external = 0;
baff583e 718
d62a17ae 719 return CMD_SUCCESS;
baff583e
MZ
720}
721
d7d73ffc 722#if 0
baff583e
MZ
723DEFUN (ospf6_distance_source,
724 ospf6_distance_source_cmd,
39e92c06 725 "distance (1-255) X:X::X:X/M [WORD]",
baff583e
MZ
726 "Administrative distance\n"
727 "Distance value\n"
728 "IP source prefix\n"
729 "Access list name\n")
730{
cdc2d765 731 VTY_DECLVAR_CONTEXT(ospf6, o);
39e92c06
QY
732 char *alname = (argc == 4) ? argv[3]->arg : NULL;
733 ospf6_distance_set (vty, o, argv[1]->arg, argv[2]->arg, alname);
baff583e
MZ
734
735 return CMD_SUCCESS;
736}
737
738DEFUN (no_ospf6_distance_source,
739 no_ospf6_distance_source_cmd,
39e92c06 740 "no distance (1-255) X:X::X:X/M [WORD]",
baff583e
MZ
741 NO_STR
742 "Administrative distance\n"
743 "Distance value\n"
744 "IP source prefix\n"
745 "Access list name\n")
746{
cdc2d765 747 VTY_DECLVAR_CONTEXT(ospf6, o);
39e92c06
QY
748 char *alname = (argc == 5) ? argv[4]->arg : NULL;
749 ospf6_distance_unset (vty, o, argv[2]->arg, argv[3]->arg, alname);
baff583e
MZ
750
751 return CMD_SUCCESS;
752}
d7d73ffc 753#endif
baff583e 754
508e53e2 755DEFUN (ospf6_interface_area,
756 ospf6_interface_area_cmd,
de842255 757 "interface IFNAME area <A.B.C.D|(0-4294967295)>",
508e53e2 758 "Enable routing on an IPv6 interface\n"
759 IFNAME_STR
760 "Specify the OSPF6 area ID\n"
761 "OSPF6 area ID in IPv4 address notation\n"
de842255 762 "OSPF6 area ID in decimal notation\n"
508e53e2 763 )
718e3744 764{
d62a17ae 765 int idx_ifname = 1;
766 int idx_ipv4 = 3;
767 struct ospf6_area *oa;
768 struct ospf6_interface *oi;
769 struct interface *ifp;
d62a17ae 770
beadc736 771 VTY_DECLVAR_CONTEXT(ospf6, ospf6);
772
d62a17ae 773 /* find/create ospf6 interface */
a36898e7 774 ifp = if_get_by_name(argv[idx_ifname]->arg, VRF_DEFAULT);
d62a17ae 775 oi = (struct ospf6_interface *)ifp->info;
776 if (oi == NULL)
777 oi = ospf6_interface_create(ifp);
778 if (oi->area) {
779 vty_out(vty, "%s already attached to Area %s\n",
780 oi->interface->name, oi->area->name);
781 return CMD_SUCCESS;
782 }
6452df09 783
d62a17ae 784 /* parse Area-ID */
beadc736 785 OSPF6_CMD_AREA_GET(argv[idx_ipv4]->arg, oa, ospf6);
d62a17ae 786
787 /* attach interface to area */
788 listnode_add(oa->if_list, oi); /* sort ?? */
789 oi->area = oa;
790
791 SET_FLAG(oa->flag, OSPF6_AREA_ENABLE);
792
793 /* ospf6 process is currently disabled, not much more to do */
beadc736 794 if (CHECK_FLAG(ospf6->flag, OSPF6_DISABLED))
d62a17ae 795 return CMD_SUCCESS;
796
797 /* start up */
798 ospf6_interface_enable(oi);
799
800 /* If the router is ABR, originate summary routes */
beadc736 801 if (ospf6_is_router_abr(ospf6))
d62a17ae 802 ospf6_abr_enable_area(oa);
803
804 return CMD_SUCCESS;
718e3744 805}
806
508e53e2 807DEFUN (no_ospf6_interface_area,
808 no_ospf6_interface_area_cmd,
de842255 809 "no interface IFNAME area <A.B.C.D|(0-4294967295)>",
508e53e2 810 NO_STR
811 "Disable routing on an IPv6 interface\n"
812 IFNAME_STR
813 "Specify the OSPF6 area ID\n"
814 "OSPF6 area ID in IPv4 address notation\n"
de842255 815 "OSPF6 area ID in decimal notation\n"
508e53e2 816 )
718e3744 817{
d62a17ae 818 int idx_ifname = 2;
819 int idx_ipv4 = 4;
820 struct ospf6_interface *oi;
821 struct ospf6_area *oa;
822 struct interface *ifp;
d7c0a89a 823 uint32_t area_id;
d62a17ae 824
a36898e7 825 ifp = if_lookup_by_name(argv[idx_ifname]->arg, VRF_DEFAULT);
d62a17ae 826 if (ifp == NULL) {
827 vty_out(vty, "No such interface %s\n", argv[idx_ifname]->arg);
828 return CMD_SUCCESS;
829 }
6452df09 830
d62a17ae 831 oi = (struct ospf6_interface *)ifp->info;
832 if (oi == NULL) {
833 vty_out(vty, "Interface %s not enabled\n", ifp->name);
834 return CMD_SUCCESS;
835 }
836
837 /* parse Area-ID */
de842255
PR
838 if (inet_pton(AF_INET, argv[idx_ipv4]->arg, &area_id) != 1)
839 area_id = htonl(strtoul(argv[idx_ipv4]->arg, NULL, 10));
d62a17ae 840
841 /* Verify Area */
842 if (oi->area == NULL) {
843 vty_out(vty, "No such Area-ID: %s\n", argv[idx_ipv4]->arg);
844 return CMD_SUCCESS;
845 }
846
847 if (oi->area->area_id != area_id) {
848 vty_out(vty, "Wrong Area-ID: %s is attached to area %s\n",
849 oi->interface->name, oi->area->name);
850 return CMD_SUCCESS;
851 }
852
853 thread_execute(master, interface_down, oi, 0);
854
855 oa = oi->area;
856 listnode_delete(oi->area->if_list, oi);
857 oi->area = (struct ospf6_area *)NULL;
858
859 /* Withdraw inter-area routes from this area, if necessary */
860 if (oa->if_list->count == 0) {
861 UNSET_FLAG(oa->flag, OSPF6_AREA_ENABLE);
862 ospf6_abr_disable_area(oa);
863 }
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}