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