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