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