]> git.proxmox.com Git - mirror_frr.git/blame - ospf6d/ospf6_top.c
bgpd: Convert vty_out to vty_json for JSON
[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"
0d1753a7 54#include "ospf6_gr.h"
eacd0828 55#include "lib/json.h"
ad500b22 56#include "ospf6_nssa.h"
718e3744 57
30043e4c
DL
58DEFINE_MTYPE_STATIC(OSPF6D, OSPF6_TOP, "OSPF6 top");
59
96244aca 60DEFINE_QOBJ_TYPE(ospf6);
ae19c240 61
c572fbfe 62FRR_CFG_DEFAULT_BOOL(OSPF6_LOG_ADJACENCY_CHANGES,
4c1458b5
DL
63 { .val_bool = true, .match_profile = "datacenter", },
64 { .val_bool = false },
67b0f40c 65);
c572fbfe 66
f71ed6df
YR
67#ifndef VTYSH_EXTRACT_PL
68#include "ospf6d/ospf6_top_clippy.c"
69#endif
70
718e3744 71/* global ospf6d variable */
78c6ba61
CS
72static struct ospf6_master ospf6_master;
73struct ospf6_master *om6;
718e3744 74
d62a17ae 75static void ospf6_disable(struct ospf6 *o);
ae2254aa 76
beadc736 77static void ospf6_add(struct ospf6 *ospf6)
78{
79 listnode_add(om6->ospf6, ospf6);
80}
81
82static void ospf6_del(struct ospf6 *ospf6)
83{
84 listnode_delete(om6->ospf6, ospf6);
85}
86
87const char *ospf6_vrf_id_to_name(vrf_id_t vrf_id)
88{
89 struct vrf *vrf = vrf_lookup_by_id(vrf_id);
90
91 return vrf ? vrf->name : "NIL";
92}
93
94/* Link OSPF instance to VRF. */
95void ospf6_vrf_link(struct ospf6 *ospf6, struct vrf *vrf)
96{
97 ospf6->vrf_id = vrf->vrf_id;
98 if (vrf->info != (void *)ospf6)
99 vrf->info = (void *)ospf6;
100}
101
102/* Unlink OSPF instance from VRF. */
103void ospf6_vrf_unlink(struct ospf6 *ospf6, struct vrf *vrf)
104{
105 if (vrf->info == (void *)ospf6)
106 vrf->info = NULL;
107 ospf6->vrf_id = VRF_UNKNOWN;
108}
109
110struct ospf6 *ospf6_lookup_by_vrf_id(vrf_id_t vrf_id)
111{
112 struct vrf *vrf = NULL;
113
114 vrf = vrf_lookup_by_id(vrf_id);
115 if (!vrf)
116 return NULL;
117 return (vrf->info) ? (struct ospf6 *)vrf->info : NULL;
118}
119
120struct ospf6 *ospf6_lookup_by_vrf_name(const char *name)
121{
122 struct ospf6 *o = NULL;
123 struct listnode *node, *nnode;
124
125 for (ALL_LIST_ELEMENTS(om6->ospf6, node, nnode, o)) {
126 if (((o->name == NULL && name == NULL)
127 || (o->name && name && strcmp(o->name, name) == 0)))
128 return o;
129 }
130 return NULL;
131}
132
4e8ccd92 133/* This is hook function for vrf create called as part of vrf_init */
134static int ospf6_vrf_new(struct vrf *vrf)
135{
136 return 0;
137}
138
139/* This is hook function for vrf delete call as part of vrf_init */
140static int ospf6_vrf_delete(struct vrf *vrf)
141{
142 return 0;
143}
144
145static void ospf6_set_redist_vrf_bitmaps(struct ospf6 *ospf6, bool set)
146{
147 int type;
148 struct list *red_list;
149
150 for (type = 0; type < ZEBRA_ROUTE_MAX; type++) {
151 red_list = ospf6->redist[type];
152 if (!red_list)
153 continue;
154 if (IS_OSPF6_DEBUG_ZEBRA(RECV))
155 zlog_debug(
156 "%s: setting redist vrf %d bitmap for type %d",
157 __func__, ospf6->vrf_id, type);
158 if (set)
159 vrf_bitmap_set(zclient->redist[AFI_IP6][type],
160 ospf6->vrf_id);
161 else
162 vrf_bitmap_unset(zclient->redist[AFI_IP6][type],
163 ospf6->vrf_id);
164 }
82bc4b8a
IR
165
166 red_list = ospf6->redist[DEFAULT_ROUTE];
167 if (red_list) {
168 if (set)
169 vrf_bitmap_set(zclient->default_information[AFI_IP6],
170 ospf6->vrf_id);
171 else
172 vrf_bitmap_unset(zclient->default_information[AFI_IP6],
173 ospf6->vrf_id);
174 }
4e8ccd92 175}
176
177/* Disable OSPF6 VRF instance */
178static int ospf6_vrf_disable(struct vrf *vrf)
179{
180 struct ospf6 *ospf6 = NULL;
181
182 if (vrf->vrf_id == VRF_DEFAULT)
183 return 0;
184
185 ospf6 = ospf6_lookup_by_vrf_name(vrf->name);
186 if (ospf6) {
187 ospf6_zebra_vrf_deregister(ospf6);
188
189 ospf6_set_redist_vrf_bitmaps(ospf6, false);
190
191 /* We have instance configured, unlink
192 * from VRF and make it "down".
193 */
194 ospf6_vrf_unlink(ospf6, vrf);
195 thread_cancel(&ospf6->t_ospf6_receive);
196 close(ospf6->fd);
197 ospf6->fd = -1;
198 }
199
200 /* Note: This is a callback, the VRF will be deleted by the caller. */
201 return 0;
202}
203
204/* Enable OSPF6 VRF instance */
205static int ospf6_vrf_enable(struct vrf *vrf)
206{
207 struct ospf6 *ospf6 = NULL;
208 vrf_id_t old_vrf_id;
209 int ret = 0;
210
211 ospf6 = ospf6_lookup_by_vrf_name(vrf->name);
212 if (ospf6) {
213 old_vrf_id = ospf6->vrf_id;
214 /* We have instance configured, link to VRF and make it "up". */
215 ospf6_vrf_link(ospf6, vrf);
216
217 if (old_vrf_id != ospf6->vrf_id) {
218 ospf6_set_redist_vrf_bitmaps(ospf6, true);
219
220 /* start zebra redist to us for new vrf */
221 ospf6_zebra_vrf_register(ospf6);
222
223 ret = ospf6_serv_sock(ospf6);
224 if (ret < 0 || ospf6->fd <= 0)
225 return 0;
226 thread_add_read(master, ospf6_receive, ospf6, ospf6->fd,
227 &ospf6->t_ospf6_receive);
228
436a55a1 229 ospf6_router_id_update(ospf6, true);
4e8ccd92 230 }
231 }
232
233 return 0;
234}
235
236void ospf6_vrf_init(void)
237{
238 vrf_init(ospf6_vrf_new, ospf6_vrf_enable, ospf6_vrf_disable,
239 ospf6_vrf_delete, ospf6_vrf_enable);
f5eef2d5 240
cfc369c4 241 vrf_cmd_init(NULL);
4e8ccd92 242}
beadc736 243
d62a17ae 244static void ospf6_top_lsdb_hook_add(struct ospf6_lsa *lsa)
718e3744 245{
d62a17ae 246 switch (ntohs(lsa->header->type)) {
247 case OSPF6_LSTYPE_AS_EXTERNAL:
f5f26b8f 248 ospf6_asbr_lsa_add(lsa);
d62a17ae 249 break;
250
251 default:
252 break;
253 }
718e3744 254}
255
d62a17ae 256static void ospf6_top_lsdb_hook_remove(struct ospf6_lsa *lsa)
718e3744 257{
d62a17ae 258 switch (ntohs(lsa->header->type)) {
259 case OSPF6_LSTYPE_AS_EXTERNAL:
07b37f93 260 ospf6_asbr_lsa_remove(lsa, NULL);
d62a17ae 261 break;
262
263 default:
264 break;
265 }
718e3744 266}
267
e285b70d 268static void ospf6_top_route_hook_add(struct ospf6_route *route)
049207c3 269{
ad500b22
K
270 struct ospf6 *ospf6 = NULL;
271 struct ospf6_area *oa = NULL;
272
273 if (route->table->scope_type == OSPF6_SCOPE_TYPE_GLOBAL)
274 ospf6 = route->table->scope;
275 else if (route->table->scope_type == OSPF6_SCOPE_TYPE_AREA) {
276 oa = (struct ospf6_area *)route->table->scope;
277 ospf6 = oa->ospf6;
0d882ec7
DS
278 } else {
279 if (IS_OSPF6_DEBUG_EXAMIN(AS_EXTERNAL)
280 || IS_OSPF6_DEBUG_BROUTER)
281 zlog_debug(
282 "%s: Route is not GLOBAL or scope is not of TYPE_AREA: %pFX",
283 __func__, &route->prefix);
284 return;
ad500b22 285 }
e285b70d 286
beadc736 287 ospf6_abr_originate_summary(route, ospf6);
288 ospf6_zebra_route_update_add(route, ospf6);
049207c3 289}
290
e285b70d 291static void ospf6_top_route_hook_remove(struct ospf6_route *route)
049207c3 292{
ad500b22
K
293 struct ospf6 *ospf6 = NULL;
294 struct ospf6_area *oa = NULL;
295
296 if (route->table->scope_type == OSPF6_SCOPE_TYPE_GLOBAL)
297 ospf6 = route->table->scope;
298 else if (route->table->scope_type == OSPF6_SCOPE_TYPE_AREA) {
299 oa = (struct ospf6_area *)route->table->scope;
300 ospf6 = oa->ospf6;
0d882ec7
DS
301 } else {
302 if (IS_OSPF6_DEBUG_EXAMIN(AS_EXTERNAL)
303 || IS_OSPF6_DEBUG_BROUTER)
304 zlog_debug(
305 "%s: Route is not GLOBAL or scope is not of TYPE_AREA: %pFX",
306 __func__, &route->prefix);
307 return;
ad500b22 308 }
e285b70d 309
d62a17ae 310 route->flag |= OSPF6_ROUTE_REMOVE;
beadc736 311 ospf6_abr_originate_summary(route, ospf6);
312 ospf6_zebra_route_update_remove(route, ospf6);
049207c3 313}
314
e285b70d 315static void ospf6_top_brouter_hook_add(struct ospf6_route *route)
6452df09 316{
e285b70d
IR
317 struct ospf6 *ospf6 = route->table->scope;
318
99ab28cb
CS
319 if (IS_OSPF6_DEBUG_EXAMIN(AS_EXTERNAL) ||
320 IS_OSPF6_DEBUG_BROUTER) {
07b37f93
CS
321 uint32_t brouter_id;
322 char brouter_name[16];
323
324 brouter_id = ADV_ROUTER_IN_PREFIX(&route->prefix);
325 inet_ntop(AF_INET, &brouter_id, brouter_name,
326 sizeof(brouter_name));
327 zlog_debug("%s: brouter %s add with adv router %x nh count %u",
15569c58 328 __func__, brouter_name,
07b37f93
CS
329 route->path.origin.adv_router,
330 listcount(route->nh_list));
064d4355 331 }
beadc736 332 ospf6_abr_examin_brouter(ADV_ROUTER_IN_PREFIX(&route->prefix), route,
333 ospf6);
334 ospf6_asbr_lsentry_add(route, ospf6);
335 ospf6_abr_originate_summary(route, ospf6);
6452df09 336}
337
e285b70d 338static void ospf6_top_brouter_hook_remove(struct ospf6_route *route)
6452df09 339{
e285b70d
IR
340 struct ospf6 *ospf6 = route->table->scope;
341
99ab28cb
CS
342 if (IS_OSPF6_DEBUG_EXAMIN(AS_EXTERNAL) ||
343 IS_OSPF6_DEBUG_BROUTER) {
07b37f93
CS
344 uint32_t brouter_id;
345 char brouter_name[16];
064d4355 346
07b37f93
CS
347 brouter_id = ADV_ROUTER_IN_PREFIX(&route->prefix);
348 inet_ntop(AF_INET, &brouter_id, brouter_name,
349 sizeof(brouter_name));
99ab28cb 350 zlog_debug("%s: brouter %p %s del with adv router %x nh %u",
15569c58 351 __func__, (void *)route, brouter_name,
99ab28cb 352 route->path.origin.adv_router,
07b37f93 353 listcount(route->nh_list));
064d4355 354 }
d62a17ae 355 route->flag |= OSPF6_ROUTE_REMOVE;
beadc736 356 ospf6_abr_examin_brouter(ADV_ROUTER_IN_PREFIX(&route->prefix), route,
357 ospf6);
358 ospf6_asbr_lsentry_remove(route, ospf6);
359 ospf6_abr_originate_summary(route, ospf6);
6452df09 360}
361
7df1f362 362static struct ospf6 *ospf6_create(const char *name)
718e3744 363{
d62a17ae 364 struct ospf6 *o;
7df1f362 365 struct vrf *vrf = NULL;
718e3744 366
d62a17ae 367 o = XCALLOC(MTYPE_OSPF6_TOP, sizeof(struct ospf6));
718e3744 368
7df1f362
K
369 vrf = vrf_lookup_by_name(name);
370 if (vrf) {
371 o->vrf_id = vrf->vrf_id;
beadc736 372 } else
373 o->vrf_id = VRF_UNKNOWN;
374
375 /* Freed in ospf6_delete */
376 o->name = XSTRDUP(MTYPE_OSPF6_TOP, name);
377 if (vrf)
378 ospf6_vrf_link(o, vrf);
379
380 ospf6_zebra_vrf_register(o);
381
d62a17ae 382 /* initialize */
383 monotime(&o->starttime);
384 o->area_list = list_new();
385 o->area_list->cmp = ospf6_area_cmp;
386 o->lsdb = ospf6_lsdb_create(o);
387 o->lsdb_self = ospf6_lsdb_create(o);
388 o->lsdb->hook_add = ospf6_top_lsdb_hook_add;
389 o->lsdb->hook_remove = ospf6_top_lsdb_hook_remove;
718e3744 390
d62a17ae 391 o->spf_delay = OSPF_SPF_DELAY_DEFAULT;
392 o->spf_holdtime = OSPF_SPF_HOLDTIME_DEFAULT;
393 o->spf_max_holdtime = OSPF_SPF_MAX_HOLDTIME_DEFAULT;
394 o->spf_hold_multiplier = 1;
3810e06e 395
b19502d3 396 o->default_originate = DEFAULT_ORIGINATE_NONE;
b8212e03 397 o->redistribute = 0;
d62a17ae 398 /* LSA timers value init */
399 o->lsa_minarrival = OSPF_MIN_LS_ARRIVAL;
b6927875 400
d62a17ae 401 o->route_table = OSPF6_ROUTE_TABLE_CREATE(GLOBAL, ROUTES);
402 o->route_table->scope = o;
403 o->route_table->hook_add = ospf6_top_route_hook_add;
404 o->route_table->hook_remove = ospf6_top_route_hook_remove;
718e3744 405
d62a17ae 406 o->brouter_table = OSPF6_ROUTE_TABLE_CREATE(GLOBAL, BORDER_ROUTERS);
407 o->brouter_table->scope = o;
408 o->brouter_table->hook_add = ospf6_top_brouter_hook_add;
409 o->brouter_table->hook_remove = ospf6_top_brouter_hook_remove;
049207c3 410
d62a17ae 411 o->external_table = OSPF6_ROUTE_TABLE_CREATE(GLOBAL, EXTERNAL_ROUTES);
412 o->external_table->scope = o;
4dc43886
MR
413 /* Setting this to 1, so that the LS ID 0 can be considered as invalid
414 * for self originated external LSAs. This helps in differentiating if
415 * an LSA is originated for any route or not in the route data.
416 * rt->route_option->id is by default 0
417 * Consider a route having id as 0 and prefix as 1::1, an external LSA
418 * is originated with ID 0.0.0.0. Now consider another route 2::2
419 * and for this LSA was not originated because of some configuration
420 * but the ID field rt->route_option->id is still 0.Consider now this
421 * 2::2 is being deleted, it will search LSA with LS ID as 0 and it
422 * will find the LSA and hence delete it but the LSA belonged to prefix
423 * 1::1, this happened because of LS ID 0.
424 */
425 o->external_id = OSPF6_EXT_INIT_LS_ID;
718e3744 426
78156066 427 o->write_oi_count = OSPF6_WRITE_INTERFACE_COUNT_DEFAULT;
d62a17ae 428 o->ref_bandwidth = OSPF6_REFERENCE_BANDWIDTH;
fd500689 429
d62a17ae 430 o->distance_table = route_table_init();
4dc43886
MR
431
432 o->rt_aggr_tbl = route_table_init();
433 o->aggr_delay_interval = OSPF6_EXTL_AGGR_DEFAULT_DELAY;
4dc43886
MR
434 o->aggr_action = OSPF6_ROUTE_AGGR_NONE;
435
7df1f362 436 o->fd = -1;
baff583e 437
1958143e
MR
438 o->max_multipath = MULTIPATH_NUM;
439
4f7bf1ab
PR
440 o->oi_write_q = list_new();
441
59790f52 442 ospf6_gr_helper_init(o);
d62a17ae 443 QOBJ_REG(o, ospf6);
692c7954 444
7df1f362
K
445 /* Make ospf protocol socket. */
446 ospf6_serv_sock(o);
447
d62a17ae 448 return o;
718e3744 449}
450
beadc736 451struct ospf6 *ospf6_instance_create(const char *name)
7df1f362 452{
beadc736 453 struct ospf6 *ospf6;
42cabc55
IR
454 struct vrf *vrf;
455 struct interface *ifp;
beadc736 456
7df1f362
K
457 ospf6 = ospf6_create(name);
458 if (DFLT_OSPF6_LOG_ADJACENCY_CHANGES)
459 SET_FLAG(ospf6->config_flags, OSPF6_LOG_ADJACENCY_CHANGES);
460 if (ospf6->router_id == 0)
436a55a1 461 ospf6_router_id_update(ospf6, true);
beadc736 462 ospf6_add(ospf6);
42cabc55
IR
463 if (ospf6->vrf_id != VRF_UNKNOWN) {
464 vrf = vrf_lookup_by_id(ospf6->vrf_id);
465 FOR_ALL_INTERFACES (vrf, ifp) {
466 if (ifp->info)
467 ospf6_interface_start(ifp->info);
468 }
469 }
4e8ccd92 470 if (ospf6->fd < 0)
471 return ospf6;
472
71165098
RW
473 /*
474 * Read from non-volatile memory whether this instance is performing a
475 * graceful restart or not.
476 */
477 ospf6_gr_nvm_read(ospf6);
478
7df1f362
K
479 thread_add_read(master, ospf6_receive, ospf6, ospf6->fd,
480 &ospf6->t_ospf6_receive);
beadc736 481
482 return ospf6;
7df1f362
K
483}
484
d62a17ae 485void ospf6_delete(struct ospf6 *o)
718e3744 486{
d62a17ae 487 struct listnode *node, *nnode;
4dc43886 488 struct route_node *rn = NULL;
d62a17ae 489 struct ospf6_area *oa;
92699b9b 490 struct vrf *vrf;
718e3744 491
d62a17ae 492 QOBJ_UNREG(o);
76249532 493
59790f52 494 ospf6_gr_helper_deinit(o);
71165098
RW
495 if (!o->gr_info.prepare_in_progress)
496 ospf6_flush_self_originated_lsas_now(o);
beadc736 497 ospf6_disable(o);
498 ospf6_del(o);
ae2254aa 499
4e8ccd92 500 ospf6_zebra_vrf_deregister(o);
501
d3136990
IR
502 ospf6_serv_close(&o->fd);
503
d62a17ae 504 for (ALL_LIST_ELEMENTS(o->area_list, node, nnode, oa))
505 ospf6_area_delete(oa);
d9628728
CF
506
507
6a154c88 508 list_delete(&o->area_list);
718e3744 509
d62a17ae 510 ospf6_lsdb_delete(o->lsdb);
511 ospf6_lsdb_delete(o->lsdb_self);
718e3744 512
e285b70d
IR
513 ospf6_route_table_delete(o->route_table);
514 ospf6_route_table_delete(o->brouter_table);
718e3744 515
e285b70d 516 ospf6_route_table_delete(o->external_table);
718e3744 517
d62a17ae 518 ospf6_distance_reset(o);
519 route_table_finish(o->distance_table);
4f7bf1ab 520 list_delete(&o->oi_write_q);
baff583e 521
92699b9b
IR
522 if (o->vrf_id != VRF_UNKNOWN) {
523 vrf = vrf_lookup_by_id(o->vrf_id);
524 if (vrf)
525 ospf6_vrf_unlink(o, vrf);
526 }
527
4dc43886
MR
528 for (rn = route_top(o->rt_aggr_tbl); rn; rn = route_next(rn))
529 if (rn->info)
530 ospf6_external_aggregator_free(rn->info);
531 route_table_finish(o->rt_aggr_tbl);
532
7df1f362 533 XFREE(MTYPE_OSPF6_TOP, o->name);
d62a17ae 534 XFREE(MTYPE_OSPF6_TOP, o);
508e53e2 535}
718e3744 536
d62a17ae 537static void ospf6_disable(struct ospf6 *o)
718e3744 538{
d62a17ae 539 struct listnode *node, *nnode;
540 struct ospf6_area *oa;
541
542 if (!CHECK_FLAG(o->flag, OSPF6_DISABLED)) {
543 SET_FLAG(o->flag, OSPF6_DISABLED);
544
545 for (ALL_LIST_ELEMENTS(o->area_list, node, nnode, oa))
546 ospf6_area_disable(oa);
547
548 /* XXX: This also changes persistent settings */
a069482f 549 /* Unregister redistribution */
f71ed6df 550 ospf6_asbr_redistribute_disable(o);
d62a17ae 551
552 ospf6_lsdb_remove_all(o->lsdb);
e285b70d
IR
553 ospf6_route_remove_all(o->route_table);
554 ospf6_route_remove_all(o->brouter_table);
d62a17ae 555
556 THREAD_OFF(o->maxage_remover);
557 THREAD_OFF(o->t_spf_calc);
558 THREAD_OFF(o->t_ase_calc);
856ae1eb 559 THREAD_OFF(o->t_distribute_update);
7df1f362 560 THREAD_OFF(o->t_ospf6_receive);
4dc43886 561 THREAD_OFF(o->t_external_aggr);
71165098 562 THREAD_OFF(o->gr_info.t_grace_period);
a8f692ed
DS
563 THREAD_OFF(o->t_write);
564 THREAD_OFF(o->t_abr_task);
d62a17ae 565 }
508e53e2 566}
718e3744 567
beadc736 568void ospf6_master_init(struct thread_master *master)
78c6ba61
CS
569{
570 memset(&ospf6_master, 0, sizeof(struct ospf6_master));
571
572 om6 = &ospf6_master;
beadc736 573 om6->ospf6 = list_new();
574 om6->master = master;
78c6ba61
CS
575}
576
d62a17ae 577static int ospf6_maxage_remover(struct thread *thread)
508e53e2 578{
d62a17ae 579 struct ospf6 *o = (struct ospf6 *)THREAD_ARG(thread);
580 struct ospf6_area *oa;
581 struct ospf6_interface *oi;
582 struct ospf6_neighbor *on;
583 struct listnode *i, *j, *k;
584 int reschedule = 0;
585
d62a17ae 586 for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa)) {
587 for (ALL_LIST_ELEMENTS_RO(oa->if_list, j, oi)) {
588 for (ALL_LIST_ELEMENTS_RO(oi->neighbor_list, k, on)) {
589 if (on->state != OSPF6_NEIGHBOR_EXCHANGE
590 && on->state != OSPF6_NEIGHBOR_LOADING)
591 continue;
592
593 ospf6_maxage_remove(o);
594 return 0;
595 }
596 }
2449fcd6 597 }
d62a17ae 598
599 for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa)) {
600 for (ALL_LIST_ELEMENTS_RO(oa->if_list, j, oi)) {
601 if (ospf6_lsdb_maxage_remover(oi->lsdb)) {
602 reschedule = 1;
603 }
604 }
605
606 if (ospf6_lsdb_maxage_remover(oa->lsdb)) {
607 reschedule = 1;
608 }
2449fcd6 609 }
2449fcd6 610
d62a17ae 611 if (ospf6_lsdb_maxage_remover(o->lsdb)) {
612 reschedule = 1;
613 }
2449fcd6 614
d62a17ae 615 if (reschedule) {
616 ospf6_maxage_remove(o);
617 }
508e53e2 618
d62a17ae 619 return 0;
718e3744 620}
621
d62a17ae 622void ospf6_maxage_remove(struct ospf6 *o)
718e3744 623{
d62a17ae 624 if (o)
625 thread_add_timer(master, ospf6_maxage_remover, o,
626 OSPF_LSA_MAXAGE_REMOVE_DELAY_DEFAULT,
627 &o->maxage_remover);
718e3744 628}
629
a3049476 630bool ospf6_router_id_update(struct ospf6 *ospf6, bool init)
78c6ba61 631{
436a55a1
LS
632 in_addr_t new_router_id;
633 struct listnode *node;
634 struct ospf6_area *oa;
635
78c6ba61 636 if (!ospf6)
a3049476 637 return true;
78c6ba61
CS
638
639 if (ospf6->router_id_static != 0)
436a55a1 640 new_router_id = ospf6->router_id_static;
78c6ba61 641 else
436a55a1
LS
642 new_router_id = ospf6->router_id_zebra;
643
644 if (ospf6->router_id == new_router_id)
a3049476 645 return true;
436a55a1
LS
646
647 if (!init)
648 for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, node, oa)) {
649 if (oa->full_nbrs) {
650 zlog_err(
e2874251 651 "%s: cannot update router-id. Run the \"clear ipv6 ospf6 process\" command",
436a55a1 652 __func__);
a3049476 653 return false;
436a55a1
LS
654 }
655 }
656
657 ospf6->router_id = new_router_id;
a3049476 658 return true;
78c6ba61
CS
659}
660
508e53e2 661/* start ospf6 */
d48ef099 662DEFUN_NOSH(router_ospf6, router_ospf6_cmd, "router ospf6 [vrf NAME]",
663 ROUTER_STR OSPF6_STR VRF_CMD_HELP_STR)
718e3744 664{
beadc736 665 struct ospf6 *ospf6;
d48ef099 666 const char *vrf_name = VRF_DEFAULT_NAME;
667 int idx_vrf = 0;
beadc736 668
d48ef099 669 if (argv_find(argv, argc, "vrf", &idx_vrf)) {
670 vrf_name = argv[idx_vrf + 1]->arg;
671 }
672
673 ospf6 = ospf6_lookup_by_vrf_name(vrf_name);
7df1f362 674 if (ospf6 == NULL)
d48ef099 675 ospf6 = ospf6_instance_create(vrf_name);
7df1f362 676
d62a17ae 677 /* set current ospf point. */
678 VTY_PUSH_CONTEXT(OSPF6_NODE, ospf6);
508e53e2 679
d62a17ae 680 return CMD_SUCCESS;
718e3744 681}
682
508e53e2 683/* stop ospf6 */
d48ef099 684DEFUN(no_router_ospf6, no_router_ospf6_cmd, "no router ospf6 [vrf NAME]",
685 NO_STR ROUTER_STR OSPF6_STR VRF_CMD_HELP_STR)
718e3744 686{
beadc736 687 struct ospf6 *ospf6;
d48ef099 688 const char *vrf_name = VRF_DEFAULT_NAME;
689 int idx_vrf = 0;
beadc736 690
d48ef099 691 if (argv_find(argv, argc, "vrf", &idx_vrf)) {
692 vrf_name = argv[idx_vrf + 1]->arg;
693 }
694
695 ospf6 = ospf6_lookup_by_vrf_name(vrf_name);
d62a17ae 696 if (ospf6 == NULL)
697 vty_out(vty, "OSPFv3 is not configured\n");
698 else {
699 ospf6_delete(ospf6);
700 ospf6 = NULL;
701 }
34288970 702
d62a17ae 703 /* return to config node . */
704 VTY_PUSH_CONTEXT_NULL(CONFIG_NODE);
508e53e2 705
d62a17ae 706 return CMD_SUCCESS;
718e3744 707}
708
f71ed6df
YR
709static void ospf6_db_clear(struct ospf6 *ospf6)
710{
711 struct ospf6_interface *oi;
712 struct interface *ifp;
713 struct vrf *vrf = vrf_lookup_by_id(ospf6->vrf_id);
714 struct listnode *node, *nnode;
715 struct ospf6_area *oa;
716
717 FOR_ALL_INTERFACES (vrf, ifp) {
718 if (if_is_operative(ifp) && ifp->info != NULL) {
719 oi = (struct ospf6_interface *)ifp->info;
720 ospf6_lsdb_remove_all(oi->lsdb);
721 ospf6_lsdb_remove_all(oi->lsdb_self);
722 ospf6_lsdb_remove_all(oi->lsupdate_list);
723 ospf6_lsdb_remove_all(oi->lsack_list);
724 }
725 }
726
727 for (ALL_LIST_ELEMENTS(ospf6->area_list, node, nnode, oa)) {
728 ospf6_lsdb_remove_all(oa->lsdb);
729 ospf6_lsdb_remove_all(oa->lsdb_self);
730
731 ospf6_spf_table_finish(oa->spf_table);
732 ospf6_route_remove_all(oa->route_table);
733 }
734
735 ospf6_lsdb_remove_all(ospf6->lsdb);
736 ospf6_lsdb_remove_all(ospf6->lsdb_self);
737 ospf6_route_remove_all(ospf6->route_table);
738 ospf6_route_remove_all(ospf6->brouter_table);
739}
740
741static void ospf6_process_reset(struct ospf6 *ospf6)
742{
743 struct interface *ifp;
744 struct vrf *vrf = vrf_lookup_by_id(ospf6->vrf_id);
745
c3a70f65 746 ospf6_unset_all_aggr_flag(ospf6);
f71ed6df
YR
747 ospf6_flush_self_originated_lsas_now(ospf6);
748 ospf6->inst_shutdown = 0;
749 ospf6_db_clear(ospf6);
750
f71ed6df
YR
751 ospf6_asbr_redistribute_reset(ospf6);
752 FOR_ALL_INTERFACES (vrf, ifp)
753 ospf6_interface_clear(ifp);
754}
755
756DEFPY (clear_router_ospf6,
757 clear_router_ospf6_cmd,
758 "clear ipv6 ospf6 process [vrf NAME$name]",
759 CLEAR_STR
760 IP6_STR
761 OSPF6_STR
762 "Reset OSPF Process\n"
763 VRF_CMD_HELP_STR)
764{
765 struct ospf6 *ospf6;
766 const char *vrf_name = VRF_DEFAULT_NAME;
767
768 if (name != NULL)
769 vrf_name = name;
770
771 ospf6 = ospf6_lookup_by_vrf_name(vrf_name);
078f6092 772 if (ospf6 == NULL) {
f71ed6df 773 vty_out(vty, "OSPFv3 is not configured\n");
078f6092
LS
774 } else {
775 ospf6_router_id_update(ospf6, true);
f71ed6df 776 ospf6_process_reset(ospf6);
078f6092 777 }
f71ed6df
YR
778
779 return CMD_SUCCESS;
780}
781
508e53e2 782/* change Router_ID commands. */
60466a63
QY
783DEFUN(ospf6_router_id,
784 ospf6_router_id_cmd,
785 "ospf6 router-id A.B.C.D",
786 OSPF6_STR
787 "Configure OSPF6 Router-ID\n"
788 V4NOTATION_STR)
718e3744 789{
d62a17ae 790 VTY_DECLVAR_CONTEXT(ospf6, o);
5d1a2ee8 791 int idx = 0;
d62a17ae 792 int ret;
5d1a2ee8 793 const char *router_id_str;
d7c0a89a 794 uint32_t router_id;
d62a17ae 795
5d1a2ee8
QY
796 argv_find(argv, argc, "A.B.C.D", &idx);
797 router_id_str = argv[idx]->arg;
798
799 ret = inet_pton(AF_INET, router_id_str, &router_id);
d62a17ae 800 if (ret == 0) {
60466a63 801 vty_out(vty, "malformed OSPF Router-ID: %s\n", router_id_str);
d62a17ae 802 return CMD_SUCCESS;
803 }
508e53e2 804
d62a17ae 805 o->router_id_static = router_id;
d6927cf3 806
078f6092
LS
807 if (ospf6_router_id_update(o, false))
808 ospf6_process_reset(o);
809 else
a3049476
LS
810 vty_out(vty,
811 "For this router-id change to take effect run the \"clear ipv6 ospf6 process\" command\n");
c8a440ec 812
d62a17ae 813 return CMD_SUCCESS;
718e3744 814}
815
60466a63
QY
816DEFUN(no_ospf6_router_id,
817 no_ospf6_router_id_cmd,
818 "no ospf6 router-id [A.B.C.D]",
819 NO_STR OSPF6_STR
820 "Configure OSPF6 Router-ID\n"
821 V4NOTATION_STR)
5d1a2ee8
QY
822{
823 VTY_DECLVAR_CONTEXT(ospf6, o);
d6927cf3 824
5d1a2ee8 825 o->router_id_static = 0;
d6927cf3 826
078f6092
LS
827
828 if (ospf6_router_id_update(o, false))
829 ospf6_process_reset(o);
830 else
a3049476
LS
831 vty_out(vty,
832 "For this router-id change to take effect run the \"clear ipv6 ospf6 process\" command\n");
5d1a2ee8
QY
833
834 return CMD_SUCCESS;
835}
836
3d35ca48
DD
837DEFUN (ospf6_log_adjacency_changes,
838 ospf6_log_adjacency_changes_cmd,
839 "log-adjacency-changes",
840 "Log changes in adjacency state\n")
841{
d62a17ae 842 VTY_DECLVAR_CONTEXT(ospf6, ospf6);
3d35ca48 843
d62a17ae 844 SET_FLAG(ospf6->config_flags, OSPF6_LOG_ADJACENCY_CHANGES);
845 UNSET_FLAG(ospf6->config_flags, OSPF6_LOG_ADJACENCY_DETAIL);
846 return CMD_SUCCESS;
3d35ca48
DD
847}
848
849DEFUN (ospf6_log_adjacency_changes_detail,
850 ospf6_log_adjacency_changes_detail_cmd,
851 "log-adjacency-changes detail",
692c7954 852 "Log changes in adjacency state\n"
3d35ca48
DD
853 "Log all state changes\n")
854{
d62a17ae 855 VTY_DECLVAR_CONTEXT(ospf6, ospf6);
3d35ca48 856
d62a17ae 857 SET_FLAG(ospf6->config_flags, OSPF6_LOG_ADJACENCY_CHANGES);
858 SET_FLAG(ospf6->config_flags, OSPF6_LOG_ADJACENCY_DETAIL);
859 return CMD_SUCCESS;
3d35ca48
DD
860}
861
862DEFUN (no_ospf6_log_adjacency_changes,
863 no_ospf6_log_adjacency_changes_cmd,
864 "no log-adjacency-changes",
692c7954 865 NO_STR
3d35ca48
DD
866 "Log changes in adjacency state\n")
867{
d62a17ae 868 VTY_DECLVAR_CONTEXT(ospf6, ospf6);
3d35ca48 869
d62a17ae 870 UNSET_FLAG(ospf6->config_flags, OSPF6_LOG_ADJACENCY_DETAIL);
871 UNSET_FLAG(ospf6->config_flags, OSPF6_LOG_ADJACENCY_CHANGES);
872 return CMD_SUCCESS;
3d35ca48
DD
873}
874
875DEFUN (no_ospf6_log_adjacency_changes_detail,
876 no_ospf6_log_adjacency_changes_detail_cmd,
877 "no log-adjacency-changes detail",
692c7954
DW
878 NO_STR
879 "Log changes in adjacency state\n"
3d35ca48
DD
880 "Log all state changes\n")
881{
d62a17ae 882 VTY_DECLVAR_CONTEXT(ospf6, ospf6);
3d35ca48 883
d62a17ae 884 UNSET_FLAG(ospf6->config_flags, OSPF6_LOG_ADJACENCY_DETAIL);
885 return CMD_SUCCESS;
3d35ca48
DD
886}
887
b6927875
DS
888DEFUN (ospf6_timers_lsa,
889 ospf6_timers_lsa_cmd,
6147e2c6 890 "timers lsa min-arrival (0-600000)",
b6927875
DS
891 "Adjust routing timers\n"
892 "OSPF6 LSA timers\n"
893 "Minimum delay in receiving new version of a LSA\n"
894 "Delay in milliseconds\n")
895{
d62a17ae 896 VTY_DECLVAR_CONTEXT(ospf6, ospf);
897 int idx_number = 3;
898 unsigned int minarrival;
b6927875 899
d62a17ae 900 minarrival = strtoul(argv[idx_number]->arg, NULL, 10);
901 ospf->lsa_minarrival = minarrival;
b6927875 902
d62a17ae 903 return CMD_SUCCESS;
b6927875
DS
904}
905
906DEFUN (no_ospf6_timers_lsa,
907 no_ospf6_timers_lsa_cmd,
1d68dbfe 908 "no timers lsa min-arrival [(0-600000)]",
b6927875
DS
909 NO_STR
910 "Adjust routing timers\n"
911 "OSPF6 LSA timers\n"
3a2d747c
QY
912 "Minimum delay in receiving new version of a LSA\n"
913 "Delay in milliseconds\n")
b6927875 914{
d62a17ae 915 VTY_DECLVAR_CONTEXT(ospf6, ospf);
916 int idx_number = 4;
917 unsigned int minarrival;
b6927875 918
d62a17ae 919 if (argc == 5) {
920 minarrival = strtoul(argv[idx_number]->arg, NULL, 10);
b6927875 921
d62a17ae 922 if (ospf->lsa_minarrival != minarrival
923 || minarrival == OSPF_MIN_LS_ARRIVAL)
924 return CMD_SUCCESS;
925 }
b6927875 926
d62a17ae 927 ospf->lsa_minarrival = OSPF_MIN_LS_ARRIVAL;
b6927875 928
d62a17ae 929 return CMD_SUCCESS;
b6927875
DS
930}
931
b6927875 932
baff583e
MZ
933DEFUN (ospf6_distance,
934 ospf6_distance_cmd,
39e92c06 935 "distance (1-255)",
baff583e
MZ
936 "Administrative distance\n"
937 "OSPF6 Administrative distance\n")
938{
d62a17ae 939 VTY_DECLVAR_CONTEXT(ospf6, o);
baff583e 940
d62a17ae 941 o->distance_all = atoi(argv[1]->arg);
baff583e 942
d62a17ae 943 return CMD_SUCCESS;
baff583e
MZ
944}
945
946DEFUN (no_ospf6_distance,
947 no_ospf6_distance_cmd,
39e92c06 948 "no distance (1-255)",
baff583e
MZ
949 NO_STR
950 "Administrative distance\n"
951 "OSPF6 Administrative distance\n")
952{
d62a17ae 953 VTY_DECLVAR_CONTEXT(ospf6, o);
baff583e 954
d62a17ae 955 o->distance_all = 0;
baff583e 956
d62a17ae 957 return CMD_SUCCESS;
baff583e
MZ
958}
959
960DEFUN (ospf6_distance_ospf6,
961 ospf6_distance_ospf6_cmd,
eaa1ae0d 962 "distance ospf6 {intra-area (1-255)|inter-area (1-255)|external (1-255)}",
baff583e 963 "Administrative distance\n"
eaa1ae0d 964 "OSPF6 administrative distance\n"
39e92c06
QY
965 "Intra-area routes\n"
966 "Distance for intra-area routes\n"
967 "Inter-area routes\n"
968 "Distance for inter-area routes\n"
969 "External routes\n"
baff583e
MZ
970 "Distance for external routes\n")
971{
d62a17ae 972 VTY_DECLVAR_CONTEXT(ospf6, o);
973 int idx = 0;
974
f89a449b
CS
975 o->distance_intra = 0;
976 o->distance_inter = 0;
977 o->distance_external = 0;
978
d62a17ae 979 if (argv_find(argv, argc, "intra-area", &idx))
980 o->distance_intra = atoi(argv[idx + 1]->arg);
981 idx = 0;
982 if (argv_find(argv, argc, "inter-area", &idx))
983 o->distance_inter = atoi(argv[idx + 1]->arg);
984 idx = 0;
985 if (argv_find(argv, argc, "external", &idx))
986 o->distance_external = atoi(argv[idx + 1]->arg);
39e92c06 987
d62a17ae 988 return CMD_SUCCESS;
baff583e
MZ
989}
990
991DEFUN (no_ospf6_distance_ospf6,
992 no_ospf6_distance_ospf6_cmd,
eaa1ae0d 993 "no distance ospf6 [{intra-area [(1-255)]|inter-area [(1-255)]|external [(1-255)]}]",
baff583e
MZ
994 NO_STR
995 "Administrative distance\n"
996 "OSPF6 distance\n"
997 "Intra-area routes\n"
998 "Distance for intra-area routes\n"
999 "Inter-area routes\n"
1000 "Distance for inter-area routes\n"
1001 "External routes\n"
1002 "Distance for external routes\n")
1003{
d62a17ae 1004 VTY_DECLVAR_CONTEXT(ospf6, o);
1005 int idx = 0;
baff583e 1006
d62a17ae 1007 if (argv_find(argv, argc, "intra-area", &idx) || argc == 3)
1008 idx = o->distance_intra = 0;
1009 if (argv_find(argv, argc, "inter-area", &idx) || argc == 3)
1010 idx = o->distance_inter = 0;
1011 if (argv_find(argv, argc, "external", &idx) || argc == 3)
1012 o->distance_external = 0;
baff583e 1013
d62a17ae 1014 return CMD_SUCCESS;
baff583e
MZ
1015}
1016
42cabc55 1017DEFUN_HIDDEN (ospf6_interface_area,
508e53e2 1018 ospf6_interface_area_cmd,
de842255 1019 "interface IFNAME area <A.B.C.D|(0-4294967295)>",
508e53e2 1020 "Enable routing on an IPv6 interface\n"
1021 IFNAME_STR
1022 "Specify the OSPF6 area ID\n"
1023 "OSPF6 area ID in IPv4 address notation\n"
de842255 1024 "OSPF6 area ID in decimal notation\n"
508e53e2 1025 )
718e3744 1026{
d48ef099 1027 VTY_DECLVAR_CONTEXT(ospf6, ospf6);
d62a17ae 1028 int idx_ifname = 1;
1029 int idx_ipv4 = 3;
1030 struct ospf6_area *oa;
1031 struct ospf6_interface *oi;
1032 struct interface *ifp;
42cabc55
IR
1033 uint32_t area_id;
1034 int format;
1035
1036 vty_out(vty,
1037 "This command is deprecated, because it is not VRF-aware.\n");
1038 vty_out(vty,
1039 "Please, use \"ipv6 ospf6 area\" on an interface instead.\n");
d62a17ae 1040
1041 /* find/create ospf6 interface */
f60a1188 1042 ifp = if_get_by_name(argv[idx_ifname]->arg, ospf6->vrf_id, ospf6->name);
d62a17ae 1043 oi = (struct ospf6_interface *)ifp->info;
1044 if (oi == NULL)
1045 oi = ospf6_interface_create(ifp);
1046 if (oi->area) {
1047 vty_out(vty, "%s already attached to Area %s\n",
1048 oi->interface->name, oi->area->name);
1049 return CMD_SUCCESS;
1050 }
6452df09 1051
42cabc55
IR
1052 if (str2area_id(argv[idx_ipv4]->arg, &area_id, &format)) {
1053 vty_out(vty, "Malformed Area-ID: %s\n", argv[idx_ipv4]->arg);
1054 return CMD_WARNING_CONFIG_FAILED;
1055 }
1056
1057 oi->area_id = area_id;
1058 oi->area_id_format = format;
1059
1060 oa = ospf6_area_lookup(area_id, ospf6);
1061 if (oa == NULL)
1062 oa = ospf6_area_create(area_id, ospf6, format);
d62a17ae 1063
1064 /* attach interface to area */
1065 listnode_add(oa->if_list, oi); /* sort ?? */
1066 oi->area = oa;
1067
1068 SET_FLAG(oa->flag, OSPF6_AREA_ENABLE);
1069
1070 /* ospf6 process is currently disabled, not much more to do */
beadc736 1071 if (CHECK_FLAG(ospf6->flag, OSPF6_DISABLED))
d62a17ae 1072 return CMD_SUCCESS;
1073
1074 /* start up */
1075 ospf6_interface_enable(oi);
1076
1077 /* If the router is ABR, originate summary routes */
95b3f03d 1078 if (ospf6_check_and_set_router_abr(ospf6)) {
d62a17ae 1079 ospf6_abr_enable_area(oa);
ad500b22
K
1080 ospf6_schedule_abr_task(oa->ospf6);
1081 }
d62a17ae 1082
1083 return CMD_SUCCESS;
718e3744 1084}
1085
42cabc55 1086DEFUN_HIDDEN (no_ospf6_interface_area,
508e53e2 1087 no_ospf6_interface_area_cmd,
de842255 1088 "no interface IFNAME area <A.B.C.D|(0-4294967295)>",
508e53e2 1089 NO_STR
1090 "Disable routing on an IPv6 interface\n"
1091 IFNAME_STR
1092 "Specify the OSPF6 area ID\n"
1093 "OSPF6 area ID in IPv4 address notation\n"
de842255 1094 "OSPF6 area ID in decimal notation\n"
508e53e2 1095 )
718e3744 1096{
d48ef099 1097 VTY_DECLVAR_CONTEXT(ospf6, ospf6);
d62a17ae 1098 int idx_ifname = 2;
1099 int idx_ipv4 = 4;
1100 struct ospf6_interface *oi;
1101 struct ospf6_area *oa;
1102 struct interface *ifp;
d7c0a89a 1103 uint32_t area_id;
d48ef099 1104
42cabc55
IR
1105 vty_out(vty,
1106 "This command is deprecated, because it is not VRF-aware.\n");
1107 vty_out(vty,
1108 "Please, use \"no ipv6 ospf6 area\" on an interface instead.\n");
1109
d48ef099 1110 /* find/create ospf6 interface */
f60a1188 1111 ifp = if_get_by_name(argv[idx_ifname]->arg, ospf6->vrf_id, ospf6->name);
d62a17ae 1112
d62a17ae 1113 if (ifp == NULL) {
1114 vty_out(vty, "No such interface %s\n", argv[idx_ifname]->arg);
1115 return CMD_SUCCESS;
1116 }
6452df09 1117
d62a17ae 1118 oi = (struct ospf6_interface *)ifp->info;
1119 if (oi == NULL) {
1120 vty_out(vty, "Interface %s not enabled\n", ifp->name);
1121 return CMD_SUCCESS;
1122 }
1123
1124 /* parse Area-ID */
de842255
PR
1125 if (inet_pton(AF_INET, argv[idx_ipv4]->arg, &area_id) != 1)
1126 area_id = htonl(strtoul(argv[idx_ipv4]->arg, NULL, 10));
d62a17ae 1127
1128 /* Verify Area */
1129 if (oi->area == NULL) {
800cc918 1130 vty_out(vty, "%s not attached to area %s\n",
f85a4112 1131 oi->interface->name, argv[idx_ipv4]->arg);
d62a17ae 1132 return CMD_SUCCESS;
1133 }
1134
1135 if (oi->area->area_id != area_id) {
1136 vty_out(vty, "Wrong Area-ID: %s is attached to area %s\n",
1137 oi->interface->name, oi->area->name);
1138 return CMD_SUCCESS;
1139 }
1140
4a30f056 1141 ospf6_interface_disable(oi);
d62a17ae 1142
1143 oa = oi->area;
1144 listnode_delete(oi->area->if_list, oi);
1145 oi->area = (struct ospf6_area *)NULL;
1146
1147 /* Withdraw inter-area routes from this area, if necessary */
1148 if (oa->if_list->count == 0) {
1149 UNSET_FLAG(oa->flag, OSPF6_AREA_ENABLE);
1150 ospf6_abr_disable_area(oa);
1151 }
1152
42cabc55
IR
1153 oi->area_id = 0;
1154 oi->area_id_format = OSPF6_AREA_FMT_UNSET;
1155
d62a17ae 1156 return CMD_SUCCESS;
718e3744 1157}
1158
f41b4a02
DD
1159DEFUN (ospf6_stub_router_admin,
1160 ospf6_stub_router_admin_cmd,
1161 "stub-router administrative",
1162 "Make router a stub router\n"
f41b4a02
DD
1163 "Administratively applied, for an indefinite period\n")
1164{
d62a17ae 1165 struct listnode *node;
1166 struct ospf6_area *oa;
1167
beadc736 1168 VTY_DECLVAR_CONTEXT(ospf6, ospf6);
1169
d62a17ae 1170 if (!CHECK_FLAG(ospf6->flag, OSPF6_STUB_ROUTER)) {
1171 for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, node, oa)) {
1172 OSPF6_OPT_CLEAR(oa->options, OSPF6_OPT_V6);
1173 OSPF6_OPT_CLEAR(oa->options, OSPF6_OPT_R);
1174 OSPF6_ROUTER_LSA_SCHEDULE(oa);
1175 }
1176 SET_FLAG(ospf6->flag, OSPF6_STUB_ROUTER);
f41b4a02 1177 }
f41b4a02 1178
d62a17ae 1179 return CMD_SUCCESS;
f41b4a02
DD
1180}
1181
1182DEFUN (no_ospf6_stub_router_admin,
1183 no_ospf6_stub_router_admin_cmd,
1184 "no stub-router administrative",
1185 NO_STR
1186 "Make router a stub router\n"
f41b4a02
DD
1187 "Administratively applied, for an indefinite period\n")
1188{
d62a17ae 1189 struct listnode *node;
1190 struct ospf6_area *oa;
1191
beadc736 1192 VTY_DECLVAR_CONTEXT(ospf6, ospf6);
d62a17ae 1193 if (CHECK_FLAG(ospf6->flag, OSPF6_STUB_ROUTER)) {
1194 for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, node, oa)) {
1195 OSPF6_OPT_SET(oa->options, OSPF6_OPT_V6);
1196 OSPF6_OPT_SET(oa->options, OSPF6_OPT_R);
1197 OSPF6_ROUTER_LSA_SCHEDULE(oa);
1198 }
1199 UNSET_FLAG(ospf6->flag, OSPF6_STUB_ROUTER);
f41b4a02 1200 }
f41b4a02 1201
d62a17ae 1202 return CMD_SUCCESS;
f41b4a02
DD
1203}
1204
1958143e
MR
1205/* Restart OSPF SPF algorithm*/
1206static void ospf6_restart_spf(struct ospf6 *ospf6)
1207{
1208 ospf6_route_remove_all(ospf6->route_table);
1209 ospf6_route_remove_all(ospf6->brouter_table);
1958143e
MR
1210
1211 /* Trigger SPF */
1212 ospf6_spf_schedule(ospf6, OSPF6_SPF_FLAGS_CONFIG_CHANGE);
1213}
1214
1215/* Set the max paths */
1216static void ospf6_maxpath_set(struct ospf6 *ospf6, uint16_t paths)
1217{
1218 if (ospf6->max_multipath == paths)
1219 return;
1220
1221 ospf6->max_multipath = paths;
1222
1223 /* Send deletion to zebra to delete all
1224 * ospf specific routes and reinitiate
1225 * SPF to reflect the new max multipath.
1226 */
1227 ospf6_restart_spf(ospf6);
1228}
1229
1230/* Ospf Maximum-paths config support */
1231DEFUN(ospf6_max_multipath,
1232 ospf6_max_multipath_cmd,
1233 "maximum-paths " CMD_RANGE_STR(1, MULTIPATH_NUM),
1234 "Max no of multiple paths for ECMP support\n"
1235 "Number of paths\n")
1236{
1237 VTY_DECLVAR_CONTEXT(ospf6, ospf6);
1238 int idx_number = 1;
1239 int maximum_paths = strtol(argv[idx_number]->arg, NULL, 10);
1240
1241 ospf6_maxpath_set(ospf6, maximum_paths);
1242
1243 return CMD_SUCCESS;
1244}
1245
1246DEFUN(no_ospf6_max_multipath,
1247 no_ospf6_max_multipath_cmd,
1248 "no maximum-paths [" CMD_RANGE_STR(1, MULTIPATH_NUM)"]",
1249 NO_STR
1250 "Max no of multiple paths for ECMP support\n"
1251 "Number of paths\n")
1252{
1253 VTY_DECLVAR_CONTEXT(ospf6, ospf6);
1254
1255 ospf6_maxpath_set(ospf6, MULTIPATH_NUM);
1256
1257 return CMD_SUCCESS;
1258}
1259
35a45dea 1260static void ospf6_show(struct vty *vty, struct ospf6 *o, json_object *json,
1261 bool use_json)
718e3744 1262{
d62a17ae 1263 struct listnode *n;
1264 struct ospf6_area *oa;
1265 char router_id[16], duration[32];
1266 struct timeval now, running, result;
1267 char buf[32], rbuf[32];
35a45dea 1268 json_object *json_areas = NULL;
1269 const char *adjacency;
1270
1271 if (use_json) {
1272 json_areas = json_object_new_object();
1273
1274 /* process id, router id */
1275 inet_ntop(AF_INET, &o->router_id, router_id, sizeof(router_id));
1276 json_object_string_add(json, "routerId", router_id);
1277
1278 /* running time */
1279 monotime(&now);
1280 timersub(&now, &o->starttime, &running);
1281 timerstring(&running, duration, sizeof(duration));
1282 json_object_string_add(json, "running", duration);
1283
1284 /* Redistribute configuration */
1285 /* XXX */
1286 json_object_int_add(json, "lsaMinimumArrivalMsecs",
1287 o->lsa_minarrival);
1288
1289 /* Show SPF parameters */
1290 json_object_int_add(json, "spfScheduleDelayMsecs",
1291 o->spf_delay);
1292 json_object_int_add(json, "holdTimeMinMsecs", o->spf_holdtime);
1293 json_object_int_add(json, "holdTimeMaxMsecs",
1294 o->spf_max_holdtime);
1295 json_object_int_add(json, "holdTimeMultiplier",
1296 o->spf_hold_multiplier);
1297
1958143e 1298 json_object_int_add(json, "maximumPaths", o->max_multipath);
35a45dea 1299
1300 if (o->ts_spf.tv_sec || o->ts_spf.tv_usec) {
1301 timersub(&now, &o->ts_spf, &result);
1302 timerstring(&result, buf, sizeof(buf));
1303 ospf6_spf_reason_string(o->last_spf_reason, rbuf,
1304 sizeof(rbuf));
1305 json_object_boolean_true_add(json, "spfHasRun");
1306 json_object_string_add(json, "spfLastExecutedMsecs",
1307 buf);
1308 json_object_string_add(json, "spfLastExecutedReason",
1309 rbuf);
1310
1311 json_object_int_add(
1312 json, "spfLastDurationSecs",
1313 (long long)o->ts_spf_duration.tv_sec);
1314
1315 json_object_int_add(
1316 json, "spfLastDurationMsecs",
1317 (long long)o->ts_spf_duration.tv_usec);
1318 } else
1319 json_object_boolean_false_add(json, "spfHasRun");
1320
1321
1322 threadtimer_string(now, o->t_spf_calc, buf, sizeof(buf));
1323 if (o->t_spf_calc) {
1324 long time_store;
1325
1326 json_object_boolean_true_add(json, "spfTimerActive");
1327 time_store =
1328 monotime_until(&o->t_spf_calc->u.sands, NULL)
1329 / 1000LL;
1330 json_object_int_add(json, "spfTimerDueInMsecs",
1331 time_store);
1332 } else
1333 json_object_boolean_false_add(json, "spfTimerActive");
1334
1335 json_object_boolean_add(json, "routerIsStubRouter",
1336 CHECK_FLAG(o->flag, OSPF6_STUB_ROUTER));
1337
1338 /* LSAs */
1339 json_object_int_add(json, "numberOfAsScopedLsa",
1340 o->lsdb->count);
1341 /* Areas */
1342 json_object_int_add(json, "numberOfAreaInRouter",
1343 listcount(o->area_list));
1344
1345 if (CHECK_FLAG(o->config_flags, OSPF6_LOG_ADJACENCY_CHANGES)) {
1346 if (CHECK_FLAG(o->config_flags,
1347 OSPF6_LOG_ADJACENCY_DETAIL))
1348 adjacency = "LoggedAll";
1349 else
1350 adjacency = "Logged";
1351 } else
1352 adjacency = "NotLogged";
1353 json_object_string_add(json, "adjacencyChanges", adjacency);
1354
1355 for (ALL_LIST_ELEMENTS_RO(o->area_list, n, oa))
1356 ospf6_area_show(vty, oa, json_areas, use_json);
1357
1358 json_object_object_add(json, "areas", json_areas);
1359
1360 vty_out(vty, "%s\n",
1361 json_object_to_json_string_ext(
1362 json, JSON_C_TO_STRING_PRETTY));
1363
1364 } else {
1365 /* process id, router id */
1366 inet_ntop(AF_INET, &o->router_id, router_id, sizeof(router_id));
1367 vty_out(vty, " OSPFv3 Routing Process (0) with Router-ID %s\n",
1368 router_id);
1369
1370 /* running time */
1371 monotime(&now);
1372 timersub(&now, &o->starttime, &running);
1373 timerstring(&running, duration, sizeof(duration));
1374 vty_out(vty, " Running %s\n", duration);
1375
1376 /* Redistribute configuration */
1377 /* XXX */
1378 vty_out(vty, " LSA minimum arrival %d msecs\n",
1379 o->lsa_minarrival);
1380
1958143e 1381 vty_out(vty, " Maximum-paths %u\n", o->max_multipath);
35a45dea 1382
1383 /* Show SPF parameters */
1384 vty_out(vty,
1385 " Initial SPF scheduling delay %d millisec(s)\n"
1386 " Minimum hold time between consecutive SPFs %d millsecond(s)\n"
1387 " Maximum hold time between consecutive SPFs %d millsecond(s)\n"
1388 " Hold time multiplier is currently %d\n",
1389 o->spf_delay, o->spf_holdtime, o->spf_max_holdtime,
1390 o->spf_hold_multiplier);
1391
1392
1393 vty_out(vty, " SPF algorithm ");
1394 if (o->ts_spf.tv_sec || o->ts_spf.tv_usec) {
1395 timersub(&now, &o->ts_spf, &result);
1396 timerstring(&result, buf, sizeof(buf));
1397 ospf6_spf_reason_string(o->last_spf_reason, rbuf,
1398 sizeof(rbuf));
1399 vty_out(vty, "last executed %s ago, reason %s\n", buf,
1400 rbuf);
1401 vty_out(vty, " Last SPF duration %lld sec %lld usec\n",
1402 (long long)o->ts_spf_duration.tv_sec,
1403 (long long)o->ts_spf_duration.tv_usec);
1404 } else
1405 vty_out(vty, "has not been run\n");
1406
1407 threadtimer_string(now, o->t_spf_calc, buf, sizeof(buf));
1408 vty_out(vty, " SPF timer %s%s\n",
1409 (o->t_spf_calc ? "due in " : "is "), buf);
1410
1411 if (CHECK_FLAG(o->flag, OSPF6_STUB_ROUTER))
1412 vty_out(vty, " Router Is Stub Router\n");
1413
1414 /* LSAs */
1415 vty_out(vty, " Number of AS scoped LSAs is %u\n",
1416 o->lsdb->count);
1417
1418 /* Areas */
1419 vty_out(vty, " Number of areas in this router is %u\n",
1420 listcount(o->area_list));
1421
1422 if (CHECK_FLAG(o->config_flags, OSPF6_LOG_ADJACENCY_CHANGES)) {
1423 if (CHECK_FLAG(o->config_flags,
1424 OSPF6_LOG_ADJACENCY_DETAIL))
1425 vty_out(vty,
1426 " All adjacency changes are logged\n");
1427 else
1428 vty_out(vty, " Adjacency changes are logged\n");
1429 }
d62a17ae 1430
d62a17ae 1431
35a45dea 1432 vty_out(vty, "\n");
d62a17ae 1433
35a45dea 1434 for (ALL_LIST_ELEMENTS_RO(o->area_list, n, oa))
1435 ospf6_area_show(vty, oa, json_areas, use_json);
1436 }
718e3744 1437}
1438
dd7fb1db
PG
1439DEFUN(show_ipv6_ospf6_vrfs, show_ipv6_ospf6_vrfs_cmd,
1440 "show ipv6 ospf6 vrfs [json]",
1441 SHOW_STR IP6_STR OSPF6_STR "Show OSPF6 VRFs \n" JSON_STR)
1442{
1443 bool uj = use_json(argc, argv);
1444 json_object *json = NULL;
1445 json_object *json_vrfs = NULL;
1446 struct ospf6 *ospf6 = NULL;
1447 struct listnode *node = NULL;
1448 int count = 0;
1449 char buf[PREFIX_STRLEN];
1450 static const char header[] =
1451 "Name Id RouterId ";
1452
1453 if (uj) {
1454 json = json_object_new_object();
1455 json_vrfs = json_object_new_object();
1456 }
1457
1458 for (ALL_LIST_ELEMENTS_RO(om6->ospf6, node, ospf6)) {
1459 json_object *json_vrf = NULL;
1460 const char *name = NULL;
1461 int64_t vrf_id_ui = 0;
1462 struct in_addr router_id;
1463
1464 router_id.s_addr = ospf6->router_id;
1465 count++;
1466
1467 if (!uj && count == 1)
1468 vty_out(vty, "%s\n", header);
1469 if (uj)
1470 json_vrf = json_object_new_object();
1471
1472 if (ospf6->vrf_id == VRF_DEFAULT)
1473 name = VRF_DEFAULT_NAME;
1474 else
1475 name = ospf6->name;
1476
1477 vrf_id_ui = (ospf6->vrf_id == VRF_UNKNOWN)
1478 ? -1
1479 : (int64_t)ospf6->vrf_id;
1480
1481 if (uj) {
1482 json_object_int_add(json_vrf, "vrfId", vrf_id_ui);
ce4b236f
DA
1483 json_object_string_addf(json_vrf, "routerId", "%pI4",
1484 &router_id);
dd7fb1db
PG
1485 json_object_object_add(json_vrfs, name, json_vrf);
1486
1487 } else {
1488 vty_out(vty, "%-25s %-5d %-16s \n", name,
1489 ospf6->vrf_id,
1490 inet_ntop(AF_INET, &router_id, buf,
1491 sizeof(buf)));
1492 }
1493 }
1494
1495 if (uj) {
1496 json_object_object_add(json, "vrfs", json_vrfs);
1497 json_object_int_add(json, "totalVrfs", count);
1498
5a6c232b 1499 vty_json(vty, json);
dd7fb1db
PG
1500 } else {
1501 if (count)
1502 vty_out(vty, "\nTotal number of OSPF VRFs: %d\n",
1503 count);
1504 }
1505
1506 return CMD_SUCCESS;
1507}
1508
508e53e2 1509/* show top level structures */
d48ef099 1510DEFUN(show_ipv6_ospf6, show_ipv6_ospf6_cmd,
1511 "show ipv6 ospf6 [vrf <NAME|all>] [json]",
1512 SHOW_STR IP6_STR OSPF6_STR VRF_CMD_HELP_STR "All VRFs\n" JSON_STR)
718e3744 1513{
beadc736 1514 struct ospf6 *ospf6;
d48ef099 1515 struct listnode *node;
1516 const char *vrf_name = NULL;
1517 bool all_vrf = false;
1518 int idx_vrf = 0;
1519
35a45dea 1520 bool uj = use_json(argc, argv);
1521 json_object *json = NULL;
508e53e2 1522
d48ef099 1523 OSPF6_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
35a45dea 1524
d48ef099 1525 for (ALL_LIST_ELEMENTS_RO(om6->ospf6, node, ospf6)) {
1526 if (all_vrf || strcmp(ospf6->name, vrf_name) == 0) {
1527 if (uj)
1528 json = json_object_new_object();
1529 ospf6_show(vty, ospf6, json, uj);
35a45dea 1530
d48ef099 1531 if (!all_vrf)
1532 break;
1533 }
1534 }
35a45dea 1535
1536 if (uj)
1537 json_object_free(json);
d48ef099 1538
d62a17ae 1539 return CMD_SUCCESS;
718e3744 1540}
1541
d48ef099 1542DEFUN(show_ipv6_ospf6_route, show_ipv6_ospf6_route_cmd,
1543 "show ipv6 ospf6 [vrf <NAME|all>] route [<intra-area|inter-area|external-1|external-2|X:X::X:X|X:X::X:X/M|detail|summary>] [json]",
1544 SHOW_STR IP6_STR OSPF6_STR VRF_CMD_HELP_STR
1545 "All VRFs\n" ROUTE_STR
1546 "Display Intra-Area routes\n"
1547 "Display Inter-Area routes\n"
1548 "Display Type-1 External routes\n"
1549 "Display Type-2 External routes\n"
1550 "Specify IPv6 address\n"
1551 "Specify IPv6 prefix\n"
1552 "Detailed information\n"
1553 "Summary of route table\n" JSON_STR)
718e3744 1554{
beadc736 1555 struct ospf6 *ospf6;
d48ef099 1556 struct listnode *node;
1557 const char *vrf_name = NULL;
1558 bool all_vrf = false;
1559 int idx_vrf = 0;
1560 int idx_arg_start = 4;
eacd0828 1561 bool uj = use_json(argc, argv);
beadc736 1562
d48ef099 1563 OSPF6_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
1564 if (idx_vrf > 0)
1565 idx_arg_start += 2;
1566
1567 for (ALL_LIST_ELEMENTS_RO(om6->ospf6, node, ospf6)) {
1568 if (all_vrf || strcmp(ospf6->name, vrf_name) == 0) {
1569 ospf6_route_table_show(vty, idx_arg_start, argc, argv,
1570 ospf6->route_table, uj);
1571
1572 if (!all_vrf)
1573 break;
1574 }
1575 }
b52a8a52 1576
d62a17ae 1577 return CMD_SUCCESS;
718e3744 1578}
1579
d48ef099 1580DEFUN(show_ipv6_ospf6_route_match, show_ipv6_ospf6_route_match_cmd,
1581 "show ipv6 ospf6 [vrf <NAME|all>] route X:X::X:X/M <match|longer> [json]",
1582 SHOW_STR IP6_STR OSPF6_STR VRF_CMD_HELP_STR
1583 "All VRFs\n" ROUTE_STR
1584 "Specify IPv6 prefix\n"
1585 "Display routes which match the specified route\n"
1586 "Display routes longer than the specified route\n" JSON_STR)
718e3744 1587{
beadc736 1588 struct ospf6 *ospf6;
d48ef099 1589 struct listnode *node;
1590 const char *vrf_name = NULL;
1591 bool all_vrf = false;
1592 int idx_vrf = 0;
1593 int idx_start_arg = 4;
eacd0828 1594 bool uj = use_json(argc, argv);
beadc736 1595
d48ef099 1596 OSPF6_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
1597 if (idx_vrf > 0)
1598 idx_start_arg += 2;
1599
1600 for (ALL_LIST_ELEMENTS_RO(om6->ospf6, node, ospf6)) {
1601 if (all_vrf || strcmp(ospf6->name, vrf_name) == 0) {
1602 ospf6_route_table_show(vty, idx_start_arg, argc, argv,
1603 ospf6->route_table, uj);
1604
1605 if (!all_vrf)
1606 break;
1607 }
1608 }
b52a8a52 1609
d62a17ae 1610 return CMD_SUCCESS;
718e3744 1611}
1612
d48ef099 1613DEFUN(show_ipv6_ospf6_route_match_detail,
1614 show_ipv6_ospf6_route_match_detail_cmd,
1615 "show ipv6 ospf6 [vrf <NAME|all>] route X:X::X:X/M match detail [json]",
1616 SHOW_STR IP6_STR OSPF6_STR VRF_CMD_HELP_STR
1617 "All VRFs\n" ROUTE_STR
1618 "Specify IPv6 prefix\n"
1619 "Display routes which match the specified route\n"
1620 "Detailed information\n" JSON_STR)
508e53e2 1621{
beadc736 1622 struct ospf6 *ospf6;
d48ef099 1623 struct listnode *node;
1624 const char *vrf_name = NULL;
1625 bool all_vrf = false;
1626 int idx_vrf = 0;
1627 int idx_start_arg = 4;
eacd0828 1628 bool uj = use_json(argc, argv);
beadc736 1629
d48ef099 1630 OSPF6_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
1631 if (idx_vrf > 0)
1632 idx_start_arg += 2;
1633
1634 for (ALL_LIST_ELEMENTS_RO(om6->ospf6, node, ospf6)) {
1635 if (all_vrf || strcmp(ospf6->name, vrf_name) == 0) {
1636 ospf6_route_table_show(vty, idx_start_arg, argc, argv,
1637 ospf6->route_table, uj);
1638
1639 if (!all_vrf)
1640 break;
1641 }
1642 }
b52a8a52 1643
d62a17ae 1644 return CMD_SUCCESS;
508e53e2 1645}
718e3744 1646
d48ef099 1647DEFUN(show_ipv6_ospf6_route_type_detail, show_ipv6_ospf6_route_type_detail_cmd,
1648 "show ipv6 ospf6 [vrf <NAME|all>] route <intra-area|inter-area|external-1|external-2> detail [json]",
1649 SHOW_STR IP6_STR OSPF6_STR VRF_CMD_HELP_STR
1650 "All VRFs\n" ROUTE_STR
1651 "Display Intra-Area routes\n"
1652 "Display Inter-Area routes\n"
1653 "Display Type-1 External routes\n"
1654 "Display Type-2 External routes\n"
1655 "Detailed information\n" JSON_STR)
4846ef64 1656{
beadc736 1657 struct ospf6 *ospf6;
d48ef099 1658 struct listnode *node;
1659 const char *vrf_name = NULL;
1660 bool all_vrf = false;
1661 int idx_vrf = 0;
1662 int idx_start_arg = 4;
eacd0828 1663 bool uj = use_json(argc, argv);
beadc736 1664
d48ef099 1665 OSPF6_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
1666 if (idx_vrf > 0)
1667 idx_start_arg += 2;
1668
1669 for (ALL_LIST_ELEMENTS_RO(om6->ospf6, node, ospf6)) {
1670 if (all_vrf || strcmp(ospf6->name, vrf_name) == 0) {
1671 ospf6_route_table_show(vty, idx_start_arg, argc, argv,
1672 ospf6->route_table, uj);
1673
1674 if (!all_vrf)
1675 break;
1676 }
1677 }
b52a8a52 1678
d62a17ae 1679 return CMD_SUCCESS;
4846ef64 1680}
718e3744 1681
4dc43886
MR
1682bool ospf6_is_valid_summary_addr(struct vty *vty, struct prefix *p)
1683{
1684 struct in6_addr addr_zero;
1685
1686 memset(&addr_zero, 0, sizeof(struct in6_addr));
1687
1688 /* Default prefix validation*/
1689 if ((is_default_prefix((struct prefix *)p))
1690 || (!memcmp(&p->u.prefix6, &addr_zero, sizeof(struct in6_addr)))) {
1691 vty_out(vty, "Default address should not be configured as summary address.\n");
1692 return false;
1693 }
1694
c3a70f65
MR
1695 /* Host route should not be configured as summary address */
1696 if (p->prefixlen == IPV6_MAX_BITLEN) {
4dc43886 1697 vty_out(vty, "Host route should not be configured as summary address.\n");
c3a70f65 1698 return false;
4dc43886
MR
1699 }
1700
c3a70f65 1701 return true;
4dc43886
MR
1702}
1703
1704/* External Route Aggregation */
1705DEFPY (ospf6_external_route_aggregation,
1706 ospf6_external_route_aggregation_cmd,
1707 "summary-address X:X::X:X/M$prefix [tag (1-4294967295)] [{metric (0-16777215) | metric-type (1-2)$mtype}]",
1708 "External summary address\n"
1709 "Specify IPv6 prefix\n"
1710 "Router tag \n"
1711 "Router tag value\n"
1712 "Metric \n"
1713 "Advertised metric for this route\n"
1714 "OSPFv3 exterior metric type for summarised routes\n"
1715 "Set OSPFv3 External Type 1/2 metrics\n")
1716{
1717 VTY_DECLVAR_CONTEXT(ospf6, ospf6);
1718
1719 struct prefix p;
1720 int ret = CMD_SUCCESS;
c3a70f65 1721
4dc43886
MR
1722 p.family = AF_INET6;
1723 ret = str2prefix(prefix_str, &p);
1724 if (ret == 0) {
1725 vty_out(vty, "Malformed prefix\n");
1726 return CMD_WARNING_CONFIG_FAILED;
1727 }
1728
1729 /* Apply mask for given prefix. */
1730 apply_mask((struct prefix *)&p);
1731
1732 if (!ospf6_is_valid_summary_addr(vty, &p))
1733 return CMD_WARNING_CONFIG_FAILED;
1734
1735 if (!tag_str)
1736 tag = 0;
1737
1738 if (!metric_str)
1739 metric = -1;
1740
1741 if (!mtype_str)
1742 mtype = DEFAULT_METRIC_TYPE;
1743
1744 ret = ospf6_external_aggr_config_set(ospf6, &p, tag, metric, mtype);
1745 if (ret == OSPF6_FAILURE) {
1746 vty_out(vty, "Invalid configuration!!\n");
1747 return CMD_WARNING_CONFIG_FAILED;
1748 }
1749
1750 return CMD_SUCCESS;
1751}
1752
1753DEFPY(no_ospf6_external_route_aggregation,
1754 no_ospf6_external_route_aggregation_cmd,
1755 "no summary-address X:X::X:X/M$prefix [tag (1-4294967295)] [{metric (0-16777215) | metric-type (1-2)}]",
1756 NO_STR
1757 "External summary address\n"
1758 "Specify IPv6 prefix\n"
1759 "Router tag\n"
1760 "Router tag value\n"
1761 "Metric \n"
1762 "Advertised metric for this route\n"
1763 "OSPFv3 exterior metric type for summarised routes\n"
1764 "Set OSPFv3 External Type 1/2 metrics\n")
1765{
1766 VTY_DECLVAR_CONTEXT(ospf6, ospf6);
1767
1768 struct prefix p;
1769 int ret = CMD_SUCCESS;
1770
1771 ret = str2prefix(prefix_str, &p);
1772 if (ret == 0) {
1773 vty_out(vty, "Malformed prefix\n");
1774 return CMD_WARNING_CONFIG_FAILED;
1775 }
1776
1777 /* Apply mask for given prefix. */
1778 apply_mask((struct prefix *)&p);
1779
1780 if (!ospf6_is_valid_summary_addr(vty, &p))
1781 return CMD_WARNING_CONFIG_FAILED;
1782
1783 ret = ospf6_external_aggr_config_unset(ospf6, &p);
1784 if (ret == OSPF6_INVALID)
1785 vty_out(vty, "Invalid configuration!!\n");
1786
1787 return CMD_SUCCESS;
1788}
1789
1790DEFPY (ospf6_external_route_aggregation_no_advertise,
1791 ospf6_external_route_aggregation_no_advertise_cmd,
1792 "summary-address X:X::X:X/M$prefix no-advertise",
1793 "External summary address\n"
1794 "Specify IPv6 prefix\n"
1795 "Don't advertise summary route \n")
1796{
1797 VTY_DECLVAR_CONTEXT(ospf6, ospf6);
1798
1799 struct prefix p;
1800 int ret = CMD_SUCCESS;
1801
1802 ret = str2prefix(prefix_str, &p);
1803 if (ret == 0) {
1804 vty_out(vty, "Malformed prefix\n");
1805 return CMD_WARNING_CONFIG_FAILED;
1806 }
1807
1808 /* Apply mask for given prefix. */
1809 apply_mask((struct prefix *)&p);
1810
1811 if (!ospf6_is_valid_summary_addr(vty, &p))
1812 return CMD_WARNING_CONFIG_FAILED;
1813
1814 ret = ospf6_asbr_external_rt_no_advertise(ospf6, &p);
1815 if (ret == OSPF6_INVALID)
1816 vty_out(vty, "!!Invalid configuration\n");
1817
c3a70f65 1818 return CMD_SUCCESS;
4dc43886
MR
1819}
1820
1821DEFPY (no_ospf6_external_route_aggregation_no_advertise,
1822 no_ospf6_external_route_aggregation_no_advertise_cmd,
1823 "no summary-address X:X::X:X/M$prefix no-advertise",
1824 NO_STR
1825 "External summary address\n"
1826 "Specify IPv6 prefix\n"
1827 "Adverise summary route to the AS \n")
1828{
1829 VTY_DECLVAR_CONTEXT(ospf6, ospf6);
1830
1831 struct prefix p;
1832 int ret = CMD_SUCCESS;
1833
1834 ret = str2prefix(prefix_str, &p);
1835 if (ret == 0) {
1836 vty_out(vty, "Malformed prefix\n");
1837 return CMD_WARNING_CONFIG_FAILED;
1838 }
1839
1840 /* Apply mask for given prefix. */
1841 apply_mask((struct prefix *)&p);
1842
1843 if (!ospf6_is_valid_summary_addr(vty, &p))
1844 return CMD_WARNING_CONFIG_FAILED;
1845
1846 ret = ospf6_asbr_external_rt_advertise(ospf6, &p);
1847 if (ret == OSPF6_INVALID)
1848 vty_out(vty, "!!Invalid configuration\n");
1849
1850 return CMD_SUCCESS;
1851}
1852
1853DEFPY (ospf6_route_aggregation_timer,
1854 ospf6_route_aggregation_timer_cmd,
1855 "aggregation timer (5-1800)",
1856 "External route aggregation\n"
1857 "Delay timer (in seconds)\n"
1858 "Timer interval(in seconds)\n")
1859{
1860 VTY_DECLVAR_CONTEXT(ospf6, ospf6);
1861
1862 ospf6_external_aggr_delay_timer_set(ospf6, timer);
1863
1864 return CMD_SUCCESS;
1865}
1866
1867DEFPY (no_ospf6_route_aggregation_timer,
1868 no_ospf6_route_aggregation_timer_cmd,
1869 "no aggregation timer [5-1800]",
1870 NO_STR
1871 "External route aggregation\n"
1872 "Delay timer\n"
1873 "Timer interval(in seconds)\n")
1874{
1875 VTY_DECLVAR_CONTEXT(ospf6, ospf6);
1876
1877 ospf6_external_aggr_delay_timer_set(ospf6,
1878 OSPF6_EXTL_AGGR_DEFAULT_DELAY);
1879 return CMD_SUCCESS;
1880}
1881
1882static int
1883ospf6_print_vty_external_routes_walkcb(struct hash_bucket *bucket, void *arg)
1884{
1885 struct ospf6_route *rt = bucket->data;
1886 struct vty *vty = (struct vty *)arg;
1887 static unsigned int count;
1888
1889 vty_out(vty, "%pFX ", &rt->prefix);
1890
1891 count++;
1892
1893 if (count%5 == 0)
1894 vty_out(vty, "\n");
1895
1896 if (OSPF6_EXTERNAL_RT_COUNT(rt->aggr_route) == count)
1897 count = 0;
1898
1899 return HASHWALK_CONTINUE;
1900}
1901
1902static int
1903ospf6_print_json_external_routes_walkcb(struct hash_bucket *bucket, void *arg)
1904{
1905 struct ospf6_route *rt = bucket->data;
1906 struct json_object *json = (struct json_object *)arg;
1907 char buf[PREFIX2STR_BUFFER];
1908 char exnalbuf[20];
1909 static unsigned int count;
1910
1911 prefix2str(&rt->prefix, buf, sizeof(buf));
1912
78982818 1913 snprintf(exnalbuf, sizeof(exnalbuf), "Exnl Addr-%d", count);
4dc43886
MR
1914
1915 json_object_string_add(json, exnalbuf, buf);
1916
1917 count++;
1918
1919 if (OSPF6_EXTERNAL_RT_COUNT(rt->aggr_route) == count)
1920 count = 0;
1921
1922 return HASHWALK_CONTINUE;
1923}
1924
ad21f6c2
MR
1925static void
1926ospf6_show_vrf_name(struct vty *vty, struct ospf6 *ospf6,
1927 json_object *json)
1928{
1929 if (json) {
1930 if (ospf6->vrf_id == VRF_DEFAULT)
1931 json_object_string_add(json, "vrfName",
1932 "default");
1933 else
1934 json_object_string_add(json, "vrfName",
1935 ospf6->name);
1936 json_object_int_add(json, "vrfId", ospf6->vrf_id);
1937 } else {
1938 if (ospf6->vrf_id == VRF_DEFAULT)
1939 vty_out(vty, "VRF Name: %s\n", "default");
1940 else if (ospf6->name)
1941 vty_out(vty, "VRF Name: %s\n", ospf6->name);
1942 }
1943}
1944
4dc43886
MR
1945static int
1946ospf6_show_summary_address(struct vty *vty, struct ospf6 *ospf6,
1947 json_object *json,
1948 bool uj, const char *detail)
1949{
1950 struct route_node *rn;
c3a70f65 1951 static const char header[] = "Summary-address Metric-type Metric Tag External_Rt_count\n";
ad21f6c2 1952 json_object *json_vrf = NULL;
4dc43886
MR
1953
1954 if (!uj) {
ad21f6c2 1955 ospf6_show_vrf_name(vty, ospf6, json_vrf);
4dc43886
MR
1956 vty_out(vty, "aggregation delay interval :%d(in seconds)\n\n",
1957 ospf6->aggr_delay_interval);
1958 vty_out(vty, "%s\n", header);
c3a70f65 1959 } else {
ad21f6c2
MR
1960 json_vrf = json_object_new_object();
1961
1962 ospf6_show_vrf_name(vty, ospf6, json_vrf);
1963
1964 json_object_int_add(json_vrf, "aggregation delay interval",
4dc43886 1965 ospf6->aggr_delay_interval);
c3a70f65 1966 }
4dc43886 1967
ad21f6c2 1968
78982818
MR
1969 for (rn = route_top(ospf6->rt_aggr_tbl); rn; rn = route_next(rn)) {
1970 if (!rn->info)
1971 continue;
4dc43886 1972
78982818
MR
1973 struct ospf6_external_aggr_rt *aggr = rn->info;
1974 json_object *json_aggr = NULL;
1975 char buf[PREFIX2STR_BUFFER];
4dc43886 1976
78982818 1977 prefix2str(&aggr->p, buf, sizeof(buf));
4dc43886 1978
78982818 1979 if (uj) {
4dc43886 1980
78982818 1981 json_aggr = json_object_new_object();
4dc43886 1982
ad21f6c2 1983 json_object_object_add(json_vrf,
78982818
MR
1984 buf,
1985 json_aggr);
4dc43886 1986
78982818
MR
1987 json_object_string_add(json_aggr,
1988 "Summary address",
1989 buf);
4dc43886 1990
78982818
MR
1991 json_object_string_add(
1992 json_aggr, "Metric-type",
4dc43886 1993 (aggr->mtype == DEFAULT_METRIC_TYPE)
78982818
MR
1994 ? "E2"
1995 : "E1");
1996
1997 json_object_int_add(json_aggr, "Metric",
1998 (aggr->metric != -1)
1999 ? aggr->metric
2000 : DEFAULT_DEFAULT_METRIC);
4dc43886 2001
78982818
MR
2002 json_object_int_add(json_aggr, "Tag",
2003 aggr->tag);
4dc43886 2004
78982818
MR
2005 json_object_int_add(json_aggr,
2006 "External route count",
4dc43886
MR
2007 OSPF6_EXTERNAL_RT_COUNT(aggr));
2008
78982818
MR
2009 if (OSPF6_EXTERNAL_RT_COUNT(aggr) && detail) {
2010 json_object_int_add(json_aggr, "ID",
2011 aggr->id);
2012 json_object_int_add(json_aggr, "Flags",
2013 aggr->aggrflags);
2014 hash_walk(aggr->match_extnl_hash,
2015 ospf6_print_json_external_routes_walkcb,
2016 json_aggr);
2017 }
2018
2019 } else {
2020 vty_out(vty, "%-22s", buf);
2021
2022 (aggr->mtype == DEFAULT_METRIC_TYPE)
2023 ? vty_out(vty, "%-16s", "E2")
2024 : vty_out(vty, "%-16s", "E1");
2025 vty_out(vty, "%-11d", (aggr->metric != -1)
2026 ? aggr->metric
2027 : DEFAULT_DEFAULT_METRIC);
2028
2029 vty_out(vty, "%-12u", aggr->tag);
4dc43886 2030
78982818
MR
2031 vty_out(vty, "%-5ld\n",
2032 OSPF6_EXTERNAL_RT_COUNT(aggr));
2033
2034 if (OSPF6_EXTERNAL_RT_COUNT(aggr) && detail) {
2035 vty_out(vty,
2036 "Matched External routes:\n");
2037 hash_walk(aggr->match_extnl_hash,
2038 ospf6_print_vty_external_routes_walkcb,
2039 vty);
4dc43886
MR
2040 vty_out(vty, "\n");
2041 }
78982818
MR
2042
2043 vty_out(vty, "\n");
4dc43886 2044 }
78982818 2045 }
4dc43886 2046
ad21f6c2
MR
2047 if (uj)
2048 json_object_object_add(json, ospf6->name,
2049 json_vrf);
2050
4dc43886
MR
2051 return CMD_SUCCESS;
2052}
2053
2054DEFPY (show_ipv6_ospf6_external_aggregator,
2055 show_ipv6_ospf6_external_aggregator_cmd,
ad21f6c2 2056 "show ipv6 ospf6 [vrf <NAME|all>] summary-address [detail$detail] [json]",
4dc43886
MR
2057 SHOW_STR
2058 IP6_STR
2059 OSPF6_STR
ad21f6c2
MR
2060 VRF_CMD_HELP_STR
2061 "All VRFs\n"
4dc43886
MR
2062 "Show external summary addresses\n"
2063 "detailed informtion\n"
2064 JSON_STR)
2065{
2066 bool uj = use_json(argc, argv);
2067 struct ospf6 *ospf6 = NULL;
c3a70f65 2068 json_object *json = NULL;
ad21f6c2
MR
2069 const char *vrf_name = NULL;
2070 struct listnode *node;
2071 bool all_vrf = false;
2072 int idx_vrf = 0;
4dc43886
MR
2073
2074 if (uj)
2075 json = json_object_new_object();
2076
ad21f6c2 2077 OSPF6_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
4dc43886 2078
ad21f6c2
MR
2079 for (ALL_LIST_ELEMENTS_RO(om6->ospf6, node, ospf6)) {
2080 if (all_vrf || strcmp(ospf6->name, vrf_name) == 0) {
4dc43886 2081
ad21f6c2
MR
2082 ospf6_show_summary_address(vty, ospf6, json, uj,
2083 detail);
2084
2085 if (!all_vrf)
2086 break;
2087 }
2088 }
4dc43886
MR
2089
2090 if (uj) {
5a6c232b 2091 vty_json(vty, json);
4dc43886
MR
2092 }
2093
2094 return CMD_SUCCESS;
2095}
2096
beadc736 2097static void ospf6_stub_router_config_write(struct vty *vty, struct ospf6 *ospf6)
f41b4a02 2098{
d62a17ae 2099 if (CHECK_FLAG(ospf6->flag, OSPF6_STUB_ROUTER)) {
2100 vty_out(vty, " stub-router administrative\n");
2101 }
2102 return;
f41b4a02
DD
2103}
2104
beadc736 2105static int ospf6_distance_config_write(struct vty *vty, struct ospf6 *ospf6)
baff583e 2106{
d62a17ae 2107 struct route_node *rn;
2108 struct ospf6_distance *odistance;
2109
2110 if (ospf6->distance_all)
2111 vty_out(vty, " distance %u\n", ospf6->distance_all);
2112
2113 if (ospf6->distance_intra || ospf6->distance_inter
2114 || ospf6->distance_external) {
2115 vty_out(vty, " distance ospf6");
2116
2117 if (ospf6->distance_intra)
2118 vty_out(vty, " intra-area %u", ospf6->distance_intra);
2119 if (ospf6->distance_inter)
2120 vty_out(vty, " inter-area %u", ospf6->distance_inter);
2121 if (ospf6->distance_external)
2122 vty_out(vty, " external %u", ospf6->distance_external);
2123
2124 vty_out(vty, "\n");
2125 }
2126
2127 for (rn = route_top(ospf6->distance_table); rn; rn = route_next(rn))
2dbe669b
DA
2128 if ((odistance = rn->info) != NULL)
2129 vty_out(vty, " distance %u %pFX %s\n",
2130 odistance->distance, &rn->p,
d62a17ae 2131 odistance->access_list ? odistance->access_list
2132 : "");
d62a17ae 2133 return 0;
baff583e
MZ
2134}
2135
4dc43886
MR
2136static int ospf6_asbr_summary_config_write(struct vty *vty, struct ospf6 *ospf6)
2137{
2138 struct route_node *rn;
2139 struct ospf6_external_aggr_rt *aggr;
2140 char buf[PREFIX2STR_BUFFER];
2141
2142 if (ospf6->aggr_delay_interval != OSPF6_EXTL_AGGR_DEFAULT_DELAY)
2143 vty_out(vty, " aggregation timer %u\n",
2144 ospf6->aggr_delay_interval);
2145
2146 /* print 'summary-address A:B::C:D/M' */
78982818
MR
2147 for (rn = route_top(ospf6->rt_aggr_tbl); rn; rn = route_next(rn)) {
2148 if (!rn->info)
2149 continue;
4dc43886 2150
78982818 2151 aggr = rn->info;
4dc43886 2152
78982818
MR
2153 prefix2str(&aggr->p, buf, sizeof(buf));
2154 vty_out(vty, " summary-address %s", buf);
2155 if (aggr->tag)
2156 vty_out(vty, " tag %u", aggr->tag);
4dc43886 2157
78982818
MR
2158 if (aggr->metric != -1)
2159 vty_out(vty, " metric %d", aggr->metric);
4dc43886 2160
78982818
MR
2161 if (aggr->mtype != DEFAULT_METRIC_TYPE)
2162 vty_out(vty, " metric-type %d", aggr->mtype);
2163
2164 if (CHECK_FLAG(aggr->aggrflags,
2165 OSPF6_EXTERNAL_AGGRT_NO_ADVERTISE))
2166 vty_out(vty, " no-advertise");
2167
2168 vty_out(vty, "\n");
2169 }
4dc43886
MR
2170
2171 return 0;
2172}
2173
508e53e2 2174/* OSPF configuration write function. */
d62a17ae 2175static int config_write_ospf6(struct vty *vty)
508e53e2 2176{
beadc736 2177 struct ospf6 *ospf6;
2178 struct listnode *node, *nnode;
d62a17ae 2179
2180 /* OSPFv3 configuration. */
beadc736 2181 if (om6 == NULL)
d62a17ae 2182 return CMD_SUCCESS;
2183
beadc736 2184 for (ALL_LIST_ELEMENTS(om6->ospf6, node, nnode, ospf6)) {
d48ef099 2185 if (ospf6->name && strcmp(ospf6->name, VRF_DEFAULT_NAME))
2186 vty_out(vty, "router ospf6 vrf %s\n", ospf6->name);
2187 else
2188 vty_out(vty, "router ospf6\n");
2189
beadc736 2190 if (ospf6->router_id_static != 0)
2191 vty_out(vty, " ospf6 router-id %pI4\n",
2192 &ospf6->router_id_static);
2193
2194 /* log-adjacency-changes flag print. */
2195 if (CHECK_FLAG(ospf6->config_flags,
2196 OSPF6_LOG_ADJACENCY_CHANGES)) {
2197 if (CHECK_FLAG(ospf6->config_flags,
2198 OSPF6_LOG_ADJACENCY_DETAIL))
2199 vty_out(vty, " log-adjacency-changes detail\n");
2200 else if (!SAVE_OSPF6_LOG_ADJACENCY_CHANGES)
2201 vty_out(vty, " log-adjacency-changes\n");
2202 } else if (SAVE_OSPF6_LOG_ADJACENCY_CHANGES) {
2203 vty_out(vty, " no log-adjacency-changes\n");
2204 }
d62a17ae 2205
beadc736 2206 if (ospf6->ref_bandwidth != OSPF6_REFERENCE_BANDWIDTH)
2207 vty_out(vty, " auto-cost reference-bandwidth %d\n",
2208 ospf6->ref_bandwidth);
2209
78156066
PR
2210 if (ospf6->write_oi_count
2211 != OSPF6_WRITE_INTERFACE_COUNT_DEFAULT)
2212 vty_out(vty, " write-multiplier %d\n",
2213 ospf6->write_oi_count);
2214
beadc736 2215 /* LSA timers print. */
2216 if (ospf6->lsa_minarrival != OSPF_MIN_LS_ARRIVAL)
2217 vty_out(vty, " timers lsa min-arrival %d\n",
2218 ospf6->lsa_minarrival);
2219
1958143e
MR
2220 /* ECMP max path config */
2221 if (ospf6->max_multipath != MULTIPATH_NUM)
2222 vty_out(vty, " maximum-paths %d\n",
2223 ospf6->max_multipath);
2224
beadc736 2225 ospf6_stub_router_config_write(vty, ospf6);
2226 ospf6_redistribute_config_write(vty, ospf6);
2227 ospf6_area_config_write(vty, ospf6);
2228 ospf6_spf_config_write(vty, ospf6);
2229 ospf6_distance_config_write(vty, ospf6);
b19502d3 2230 ospf6_distribute_config_write(vty, ospf6);
4dc43886 2231 ospf6_asbr_summary_config_write(vty, ospf6);
71165098 2232 config_write_ospf6_gr(vty, ospf6);
0fc3e113 2233 config_write_ospf6_gr_helper(vty, ospf6);
07679ad9
IR
2234
2235 vty_out(vty, "exit\n");
beadc736 2236 vty_out(vty, "!\n");
d62a17ae 2237 }
d62a17ae 2238 return 0;
508e53e2 2239}
2240
612c2c15 2241static int config_write_ospf6(struct vty *vty);
508e53e2 2242/* OSPF6 node structure. */
d62a17ae 2243static struct cmd_node ospf6_node = {
f4b8291f 2244 .name = "ospf6",
62b346ee 2245 .node = OSPF6_NODE,
24389580 2246 .parent_node = CONFIG_NODE,
62b346ee 2247 .prompt = "%s(config-ospf6)# ",
612c2c15 2248 .config_write = config_write_ospf6,
508e53e2 2249};
2250
f71ed6df
YR
2251void install_element_ospf6_clear_process(void)
2252{
2253 install_element(ENABLE_NODE, &clear_router_ospf6_cmd);
2254}
2255
508e53e2 2256/* Install ospf related commands. */
d62a17ae 2257void ospf6_top_init(void)
718e3744 2258{
d62a17ae 2259 /* Install ospf6 top node. */
612c2c15 2260 install_node(&ospf6_node);
d62a17ae 2261
2262 install_element(VIEW_NODE, &show_ipv6_ospf6_cmd);
dd7fb1db 2263 install_element(VIEW_NODE, &show_ipv6_ospf6_vrfs_cmd);
d62a17ae 2264 install_element(CONFIG_NODE, &router_ospf6_cmd);
2265 install_element(CONFIG_NODE, &no_router_ospf6_cmd);
2266
2267 install_element(VIEW_NODE, &show_ipv6_ospf6_route_cmd);
2268 install_element(VIEW_NODE, &show_ipv6_ospf6_route_match_cmd);
2269 install_element(VIEW_NODE, &show_ipv6_ospf6_route_match_detail_cmd);
2270 install_element(VIEW_NODE, &show_ipv6_ospf6_route_type_detail_cmd);
2271
2272 install_default(OSPF6_NODE);
2273 install_element(OSPF6_NODE, &ospf6_router_id_cmd);
5d1a2ee8 2274 install_element(OSPF6_NODE, &no_ospf6_router_id_cmd);
d62a17ae 2275 install_element(OSPF6_NODE, &ospf6_log_adjacency_changes_cmd);
2276 install_element(OSPF6_NODE, &ospf6_log_adjacency_changes_detail_cmd);
2277 install_element(OSPF6_NODE, &no_ospf6_log_adjacency_changes_cmd);
2278 install_element(OSPF6_NODE, &no_ospf6_log_adjacency_changes_detail_cmd);
2279
2280 /* LSA timers commands */
2281 install_element(OSPF6_NODE, &ospf6_timers_lsa_cmd);
2282 install_element(OSPF6_NODE, &no_ospf6_timers_lsa_cmd);
2283
2284 install_element(OSPF6_NODE, &ospf6_interface_area_cmd);
2285 install_element(OSPF6_NODE, &no_ospf6_interface_area_cmd);
2286 install_element(OSPF6_NODE, &ospf6_stub_router_admin_cmd);
2287 install_element(OSPF6_NODE, &no_ospf6_stub_router_admin_cmd);
508e53e2 2288
1958143e
MR
2289 /* maximum-paths command */
2290 install_element(OSPF6_NODE, &ospf6_max_multipath_cmd);
2291 install_element(OSPF6_NODE, &no_ospf6_max_multipath_cmd);
2292
4dc43886
MR
2293 /* ASBR Summarisation */
2294 install_element(OSPF6_NODE, &ospf6_external_route_aggregation_cmd);
2295 install_element(OSPF6_NODE, &no_ospf6_external_route_aggregation_cmd);
2296 install_element(OSPF6_NODE,
2297 &ospf6_external_route_aggregation_no_advertise_cmd);
2298 install_element(OSPF6_NODE,
2299 &no_ospf6_external_route_aggregation_no_advertise_cmd);
2300 install_element(OSPF6_NODE, &ospf6_route_aggregation_timer_cmd);
2301 install_element(OSPF6_NODE, &no_ospf6_route_aggregation_timer_cmd);
2302 install_element(VIEW_NODE, &show_ipv6_ospf6_external_aggregator_cmd);
2303
d62a17ae 2304 install_element(OSPF6_NODE, &ospf6_distance_cmd);
2305 install_element(OSPF6_NODE, &no_ospf6_distance_cmd);
2306 install_element(OSPF6_NODE, &ospf6_distance_ospf6_cmd);
2307 install_element(OSPF6_NODE, &no_ospf6_distance_ospf6_cmd);
718e3744 2308}