]> git.proxmox.com Git - mirror_frr.git/blame - ospf6d/ospf6_top.c
Merge pull request #1676 from dslicenc/cm19322-bgp-json
[mirror_frr.git] / ospf6d / ospf6_top.c
CommitLineData
718e3744 1/*
508e53e2 2 * Copyright (C) 2003 Yasuhiro Ohara
718e3744 3 *
4 * This file is part of GNU Zebra.
5 *
6 * GNU Zebra is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2, or (at your option) any
9 * later version.
10 *
11 * GNU Zebra is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
896014f4
DL
16 * You should have received a copy of the GNU General Public License along
17 * with this program; see the file COPYING; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
718e3744 19 */
20
21#include <zebra.h>
22
23#include "log.h"
24#include "memory.h"
25#include "vty.h"
26#include "linklist.h"
27#include "prefix.h"
28#include "table.h"
29#include "thread.h"
30#include "command.h"
8efe88ea 31#include "defaults.h"
718e3744 32
718e3744 33#include "ospf6_proto.h"
508e53e2 34#include "ospf6_message.h"
718e3744 35#include "ospf6_lsa.h"
36#include "ospf6_lsdb.h"
718e3744 37#include "ospf6_route.h"
38#include "ospf6_zebra.h"
39
508e53e2 40#include "ospf6_top.h"
41#include "ospf6_area.h"
42#include "ospf6_interface.h"
43#include "ospf6_neighbor.h"
718e3744 44
6452df09 45#include "ospf6_flood.h"
508e53e2 46#include "ospf6_asbr.h"
049207c3 47#include "ospf6_abr.h"
6452df09 48#include "ospf6_intra.h"
3810e06e 49#include "ospf6_spf.h"
049207c3 50#include "ospf6d.h"
718e3744 51
ae19c240
DL
52DEFINE_QOBJ_TYPE(ospf6)
53
718e3744 54/* global ospf6d variable */
55struct ospf6 *ospf6;
56
d62a17ae 57static void ospf6_disable(struct ospf6 *o);
ae2254aa 58
d62a17ae 59static void ospf6_top_lsdb_hook_add(struct ospf6_lsa *lsa)
718e3744 60{
d62a17ae 61 switch (ntohs(lsa->header->type)) {
62 case OSPF6_LSTYPE_AS_EXTERNAL:
63 ospf6_asbr_lsa_add(lsa);
64 break;
65
66 default:
67 break;
68 }
718e3744 69}
70
d62a17ae 71static void ospf6_top_lsdb_hook_remove(struct ospf6_lsa *lsa)
718e3744 72{
d62a17ae 73 switch (ntohs(lsa->header->type)) {
74 case OSPF6_LSTYPE_AS_EXTERNAL:
75 ospf6_asbr_lsa_remove(lsa);
76 break;
77
78 default:
79 break;
80 }
718e3744 81}
82
d62a17ae 83static void ospf6_top_route_hook_add(struct ospf6_route *route)
049207c3 84{
d62a17ae 85 ospf6_abr_originate_summary(route);
86 ospf6_zebra_route_update_add(route);
049207c3 87}
88
d62a17ae 89static void ospf6_top_route_hook_remove(struct ospf6_route *route)
049207c3 90{
d62a17ae 91 route->flag |= OSPF6_ROUTE_REMOVE;
92 ospf6_abr_originate_summary(route);
93 ospf6_zebra_route_update_remove(route);
049207c3 94}
95
d62a17ae 96static void ospf6_top_brouter_hook_add(struct ospf6_route *route)
6452df09 97{
064d4355
CS
98 if (IS_OSPF6_DEBUG_EXAMIN(AS_EXTERNAL)) {
99 char buf[PREFIX2STR_BUFFER];
100
101 prefix2str(&route->prefix, buf, sizeof(buf));
102 zlog_debug("%s: brouter %s add with nh count %u",
103 __PRETTY_FUNCTION__, buf, listcount(route->nh_list));
104 }
d62a17ae 105 ospf6_abr_examin_brouter(ADV_ROUTER_IN_PREFIX(&route->prefix));
106 ospf6_asbr_lsentry_add(route);
107 ospf6_abr_originate_summary(route);
6452df09 108}
109
d62a17ae 110static void ospf6_top_brouter_hook_remove(struct ospf6_route *route)
6452df09 111{
064d4355
CS
112 if (IS_OSPF6_DEBUG_EXAMIN(AS_EXTERNAL)) {
113 char buf[PREFIX2STR_BUFFER];
114
115 prefix2str(&route->prefix, buf, sizeof(buf));
116 zlog_debug("%s: brouter %s del with nh count %u",
117 __PRETTY_FUNCTION__, buf, listcount(route->nh_list));
118 }
d62a17ae 119 route->flag |= OSPF6_ROUTE_REMOVE;
120 ospf6_abr_examin_brouter(ADV_ROUTER_IN_PREFIX(&route->prefix));
121 ospf6_asbr_lsentry_remove(route);
122 ospf6_abr_originate_summary(route);
6452df09 123}
124
d62a17ae 125static struct ospf6 *ospf6_create(void)
718e3744 126{
d62a17ae 127 struct ospf6 *o;
718e3744 128
d62a17ae 129 o = XCALLOC(MTYPE_OSPF6_TOP, sizeof(struct ospf6));
718e3744 130
d62a17ae 131 /* initialize */
132 monotime(&o->starttime);
133 o->area_list = list_new();
134 o->area_list->cmp = ospf6_area_cmp;
135 o->lsdb = ospf6_lsdb_create(o);
136 o->lsdb_self = ospf6_lsdb_create(o);
137 o->lsdb->hook_add = ospf6_top_lsdb_hook_add;
138 o->lsdb->hook_remove = ospf6_top_lsdb_hook_remove;
718e3744 139
d62a17ae 140 o->spf_delay = OSPF_SPF_DELAY_DEFAULT;
141 o->spf_holdtime = OSPF_SPF_HOLDTIME_DEFAULT;
142 o->spf_max_holdtime = OSPF_SPF_MAX_HOLDTIME_DEFAULT;
143 o->spf_hold_multiplier = 1;
3810e06e 144
d62a17ae 145 /* LSA timers value init */
146 o->lsa_minarrival = OSPF_MIN_LS_ARRIVAL;
b6927875 147
d62a17ae 148 o->route_table = OSPF6_ROUTE_TABLE_CREATE(GLOBAL, ROUTES);
149 o->route_table->scope = o;
150 o->route_table->hook_add = ospf6_top_route_hook_add;
151 o->route_table->hook_remove = ospf6_top_route_hook_remove;
718e3744 152
d62a17ae 153 o->brouter_table = OSPF6_ROUTE_TABLE_CREATE(GLOBAL, BORDER_ROUTERS);
154 o->brouter_table->scope = o;
155 o->brouter_table->hook_add = ospf6_top_brouter_hook_add;
156 o->brouter_table->hook_remove = ospf6_top_brouter_hook_remove;
049207c3 157
d62a17ae 158 o->external_table = OSPF6_ROUTE_TABLE_CREATE(GLOBAL, EXTERNAL_ROUTES);
159 o->external_table->scope = o;
cf1ce250 160
d62a17ae 161 o->external_id_table = route_table_init();
718e3744 162
d62a17ae 163 o->ref_bandwidth = OSPF6_REFERENCE_BANDWIDTH;
fd500689 164
d62a17ae 165 o->distance_table = route_table_init();
baff583e 166
d62a17ae 167/* Enable "log-adjacency-changes" */
8efe88ea 168#if DFLT_OSPF6_LOG_ADJACENCY_CHANGES
d62a17ae 169 SET_FLAG(o->config_flags, OSPF6_LOG_ADJACENCY_CHANGES);
8efe88ea 170#endif
692c7954 171
d62a17ae 172 QOBJ_REG(o, ospf6);
692c7954 173
d62a17ae 174 return o;
718e3744 175}
176
d62a17ae 177void ospf6_delete(struct ospf6 *o)
718e3744 178{
d62a17ae 179 struct listnode *node, *nnode;
180 struct ospf6_area *oa;
718e3744 181
d62a17ae 182 QOBJ_UNREG(o);
183 ospf6_disable(ospf6);
ae2254aa 184
d62a17ae 185 for (ALL_LIST_ELEMENTS(o->area_list, node, nnode, oa))
186 ospf6_area_delete(oa);
d9628728
CF
187
188
affe9e99 189 list_delete_and_null(&o->area_list);
718e3744 190
d62a17ae 191 ospf6_lsdb_delete(o->lsdb);
192 ospf6_lsdb_delete(o->lsdb_self);
718e3744 193
d62a17ae 194 ospf6_route_table_delete(o->route_table);
195 ospf6_route_table_delete(o->brouter_table);
718e3744 196
d62a17ae 197 ospf6_route_table_delete(o->external_table);
198 route_table_finish(o->external_id_table);
718e3744 199
d62a17ae 200 ospf6_distance_reset(o);
201 route_table_finish(o->distance_table);
baff583e 202
d62a17ae 203 XFREE(MTYPE_OSPF6_TOP, o);
508e53e2 204}
718e3744 205
d62a17ae 206static void ospf6_disable(struct ospf6 *o)
718e3744 207{
d62a17ae 208 struct listnode *node, *nnode;
209 struct ospf6_area *oa;
210
211 if (!CHECK_FLAG(o->flag, OSPF6_DISABLED)) {
212 SET_FLAG(o->flag, OSPF6_DISABLED);
213
214 for (ALL_LIST_ELEMENTS(o->area_list, node, nnode, oa))
215 ospf6_area_disable(oa);
216
217 /* XXX: This also changes persistent settings */
218 ospf6_asbr_redistribute_reset();
219
220 ospf6_lsdb_remove_all(o->lsdb);
221 ospf6_route_remove_all(o->route_table);
222 ospf6_route_remove_all(o->brouter_table);
223
224 THREAD_OFF(o->maxage_remover);
225 THREAD_OFF(o->t_spf_calc);
226 THREAD_OFF(o->t_ase_calc);
227 }
508e53e2 228}
718e3744 229
d62a17ae 230static int ospf6_maxage_remover(struct thread *thread)
508e53e2 231{
d62a17ae 232 struct ospf6 *o = (struct ospf6 *)THREAD_ARG(thread);
233 struct ospf6_area *oa;
234 struct ospf6_interface *oi;
235 struct ospf6_neighbor *on;
236 struct listnode *i, *j, *k;
237 int reschedule = 0;
238
239 o->maxage_remover = (struct thread *)NULL;
240
241 for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa)) {
242 for (ALL_LIST_ELEMENTS_RO(oa->if_list, j, oi)) {
243 for (ALL_LIST_ELEMENTS_RO(oi->neighbor_list, k, on)) {
244 if (on->state != OSPF6_NEIGHBOR_EXCHANGE
245 && on->state != OSPF6_NEIGHBOR_LOADING)
246 continue;
247
248 ospf6_maxage_remove(o);
249 return 0;
250 }
251 }
2449fcd6 252 }
d62a17ae 253
254 for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa)) {
255 for (ALL_LIST_ELEMENTS_RO(oa->if_list, j, oi)) {
256 if (ospf6_lsdb_maxage_remover(oi->lsdb)) {
257 reschedule = 1;
258 }
259 }
260
261 if (ospf6_lsdb_maxage_remover(oa->lsdb)) {
262 reschedule = 1;
263 }
2449fcd6 264 }
2449fcd6 265
d62a17ae 266 if (ospf6_lsdb_maxage_remover(o->lsdb)) {
267 reschedule = 1;
268 }
2449fcd6 269
d62a17ae 270 if (reschedule) {
271 ospf6_maxage_remove(o);
272 }
508e53e2 273
d62a17ae 274 return 0;
718e3744 275}
276
d62a17ae 277void ospf6_maxage_remove(struct ospf6 *o)
718e3744 278{
d62a17ae 279 if (o)
280 thread_add_timer(master, ospf6_maxage_remover, o,
281 OSPF_LSA_MAXAGE_REMOVE_DELAY_DEFAULT,
282 &o->maxage_remover);
718e3744 283}
284
508e53e2 285/* start ospf6 */
505e5056 286DEFUN_NOSH (router_ospf6,
508e53e2 287 router_ospf6_cmd,
288 "router ospf6",
289 ROUTER_STR
290 OSPF6_STR)
718e3744 291{
d62a17ae 292 if (ospf6 == NULL)
293 ospf6 = ospf6_create();
508e53e2 294
d62a17ae 295 /* set current ospf point. */
296 VTY_PUSH_CONTEXT(OSPF6_NODE, ospf6);
508e53e2 297
d62a17ae 298 return CMD_SUCCESS;
718e3744 299}
300
508e53e2 301/* stop ospf6 */
302DEFUN (no_router_ospf6,
303 no_router_ospf6_cmd,
304 "no router ospf6",
305 NO_STR
16cedbb0
QY
306 ROUTER_STR
307 OSPF6_STR)
718e3744 308{
d62a17ae 309 if (ospf6 == NULL)
310 vty_out(vty, "OSPFv3 is not configured\n");
311 else {
312 ospf6_delete(ospf6);
313 ospf6 = NULL;
314 }
34288970 315
d62a17ae 316 /* return to config node . */
317 VTY_PUSH_CONTEXT_NULL(CONFIG_NODE);
508e53e2 318
d62a17ae 319 return CMD_SUCCESS;
718e3744 320}
321
508e53e2 322/* change Router_ID commands. */
60466a63
QY
323DEFUN(ospf6_router_id,
324 ospf6_router_id_cmd,
325 "ospf6 router-id A.B.C.D",
326 OSPF6_STR
327 "Configure OSPF6 Router-ID\n"
328 V4NOTATION_STR)
718e3744 329{
d62a17ae 330 VTY_DECLVAR_CONTEXT(ospf6, o);
5d1a2ee8 331 int idx = 0;
d62a17ae 332 int ret;
5d1a2ee8 333 const char *router_id_str;
d62a17ae 334 u_int32_t router_id;
335
5d1a2ee8
QY
336 argv_find(argv, argc, "A.B.C.D", &idx);
337 router_id_str = argv[idx]->arg;
338
339 ret = inet_pton(AF_INET, router_id_str, &router_id);
d62a17ae 340 if (ret == 0) {
60466a63 341 vty_out(vty, "malformed OSPF Router-ID: %s\n", router_id_str);
d62a17ae 342 return CMD_SUCCESS;
343 }
508e53e2 344
d62a17ae 345 o->router_id_static = router_id;
346 if (o->router_id == 0)
347 o->router_id = router_id;
c8a440ec 348
d62a17ae 349 return CMD_SUCCESS;
718e3744 350}
351
60466a63
QY
352DEFUN(no_ospf6_router_id,
353 no_ospf6_router_id_cmd,
354 "no ospf6 router-id [A.B.C.D]",
355 NO_STR OSPF6_STR
356 "Configure OSPF6 Router-ID\n"
357 V4NOTATION_STR)
5d1a2ee8
QY
358{
359 VTY_DECLVAR_CONTEXT(ospf6, o);
360 o->router_id_static = 0;
361 o->router_id = 0;
362
363 return CMD_SUCCESS;
364}
365
366#if CONFDATE > 20180828
367CPP_NOTICE("ospf6: `router-id A.B.C.D` deprecated 2017/08/28")
368#endif
369ALIAS_HIDDEN(ospf6_router_id,
370 ospf6_router_id_hdn_cmd,
371 "router-id A.B.C.D",
372 "Configure OSPF6 Router-ID\n"
373 V4NOTATION_STR)
374
375#if CONFDATE > 20180828
376CPP_NOTICE("ospf6: `no router-id A.B.C.D` deprecated 2017/08/28")
377#endif
378ALIAS_HIDDEN(no_ospf6_router_id,
379 no_ospf6_router_id_hdn_cmd,
380 "no router-id [A.B.C.D]",
381 NO_STR
382 "Configure OSPF6 Router-ID\n"
383 V4NOTATION_STR)
384
3d35ca48
DD
385DEFUN (ospf6_log_adjacency_changes,
386 ospf6_log_adjacency_changes_cmd,
387 "log-adjacency-changes",
388 "Log changes in adjacency state\n")
389{
d62a17ae 390 VTY_DECLVAR_CONTEXT(ospf6, ospf6);
3d35ca48 391
d62a17ae 392 SET_FLAG(ospf6->config_flags, OSPF6_LOG_ADJACENCY_CHANGES);
393 UNSET_FLAG(ospf6->config_flags, OSPF6_LOG_ADJACENCY_DETAIL);
394 return CMD_SUCCESS;
3d35ca48
DD
395}
396
397DEFUN (ospf6_log_adjacency_changes_detail,
398 ospf6_log_adjacency_changes_detail_cmd,
399 "log-adjacency-changes detail",
692c7954 400 "Log changes in adjacency state\n"
3d35ca48
DD
401 "Log all state changes\n")
402{
d62a17ae 403 VTY_DECLVAR_CONTEXT(ospf6, ospf6);
3d35ca48 404
d62a17ae 405 SET_FLAG(ospf6->config_flags, OSPF6_LOG_ADJACENCY_CHANGES);
406 SET_FLAG(ospf6->config_flags, OSPF6_LOG_ADJACENCY_DETAIL);
407 return CMD_SUCCESS;
3d35ca48
DD
408}
409
410DEFUN (no_ospf6_log_adjacency_changes,
411 no_ospf6_log_adjacency_changes_cmd,
412 "no log-adjacency-changes",
692c7954 413 NO_STR
3d35ca48
DD
414 "Log changes in adjacency state\n")
415{
d62a17ae 416 VTY_DECLVAR_CONTEXT(ospf6, ospf6);
3d35ca48 417
d62a17ae 418 UNSET_FLAG(ospf6->config_flags, OSPF6_LOG_ADJACENCY_DETAIL);
419 UNSET_FLAG(ospf6->config_flags, OSPF6_LOG_ADJACENCY_CHANGES);
420 return CMD_SUCCESS;
3d35ca48
DD
421}
422
423DEFUN (no_ospf6_log_adjacency_changes_detail,
424 no_ospf6_log_adjacency_changes_detail_cmd,
425 "no log-adjacency-changes detail",
692c7954
DW
426 NO_STR
427 "Log changes in adjacency state\n"
3d35ca48
DD
428 "Log all state changes\n")
429{
d62a17ae 430 VTY_DECLVAR_CONTEXT(ospf6, ospf6);
3d35ca48 431
d62a17ae 432 UNSET_FLAG(ospf6->config_flags, OSPF6_LOG_ADJACENCY_DETAIL);
433 return CMD_SUCCESS;
3d35ca48
DD
434}
435
b6927875
DS
436DEFUN (ospf6_timers_lsa,
437 ospf6_timers_lsa_cmd,
6147e2c6 438 "timers lsa min-arrival (0-600000)",
b6927875
DS
439 "Adjust routing timers\n"
440 "OSPF6 LSA timers\n"
441 "Minimum delay in receiving new version of a LSA\n"
442 "Delay in milliseconds\n")
443{
d62a17ae 444 VTY_DECLVAR_CONTEXT(ospf6, ospf);
445 int idx_number = 3;
446 unsigned int minarrival;
b6927875 447
d62a17ae 448 minarrival = strtoul(argv[idx_number]->arg, NULL, 10);
449 ospf->lsa_minarrival = minarrival;
b6927875 450
d62a17ae 451 return CMD_SUCCESS;
b6927875
DS
452}
453
454DEFUN (no_ospf6_timers_lsa,
455 no_ospf6_timers_lsa_cmd,
1d68dbfe 456 "no timers lsa min-arrival [(0-600000)]",
b6927875
DS
457 NO_STR
458 "Adjust routing timers\n"
459 "OSPF6 LSA timers\n"
3a2d747c
QY
460 "Minimum delay in receiving new version of a LSA\n"
461 "Delay in milliseconds\n")
b6927875 462{
d62a17ae 463 VTY_DECLVAR_CONTEXT(ospf6, ospf);
464 int idx_number = 4;
465 unsigned int minarrival;
b6927875 466
d62a17ae 467 if (argc == 5) {
468 minarrival = strtoul(argv[idx_number]->arg, NULL, 10);
b6927875 469
d62a17ae 470 if (ospf->lsa_minarrival != minarrival
471 || minarrival == OSPF_MIN_LS_ARRIVAL)
472 return CMD_SUCCESS;
473 }
b6927875 474
d62a17ae 475 ospf->lsa_minarrival = OSPF_MIN_LS_ARRIVAL;
b6927875 476
d62a17ae 477 return CMD_SUCCESS;
b6927875
DS
478}
479
b6927875 480
baff583e
MZ
481DEFUN (ospf6_distance,
482 ospf6_distance_cmd,
39e92c06 483 "distance (1-255)",
baff583e
MZ
484 "Administrative distance\n"
485 "OSPF6 Administrative distance\n")
486{
d62a17ae 487 VTY_DECLVAR_CONTEXT(ospf6, o);
baff583e 488
d62a17ae 489 o->distance_all = atoi(argv[1]->arg);
baff583e 490
d62a17ae 491 return CMD_SUCCESS;
baff583e
MZ
492}
493
494DEFUN (no_ospf6_distance,
495 no_ospf6_distance_cmd,
39e92c06 496 "no distance (1-255)",
baff583e
MZ
497 NO_STR
498 "Administrative distance\n"
499 "OSPF6 Administrative distance\n")
500{
d62a17ae 501 VTY_DECLVAR_CONTEXT(ospf6, o);
baff583e 502
d62a17ae 503 o->distance_all = 0;
baff583e 504
d62a17ae 505 return CMD_SUCCESS;
baff583e
MZ
506}
507
508DEFUN (ospf6_distance_ospf6,
509 ospf6_distance_ospf6_cmd,
eaa1ae0d 510 "distance ospf6 {intra-area (1-255)|inter-area (1-255)|external (1-255)}",
baff583e 511 "Administrative distance\n"
eaa1ae0d 512 "OSPF6 administrative distance\n"
39e92c06
QY
513 "Intra-area routes\n"
514 "Distance for intra-area routes\n"
515 "Inter-area routes\n"
516 "Distance for inter-area routes\n"
517 "External routes\n"
baff583e
MZ
518 "Distance for external routes\n")
519{
d62a17ae 520 VTY_DECLVAR_CONTEXT(ospf6, o);
521 int idx = 0;
522
523 if (argv_find(argv, argc, "intra-area", &idx))
524 o->distance_intra = atoi(argv[idx + 1]->arg);
525 idx = 0;
526 if (argv_find(argv, argc, "inter-area", &idx))
527 o->distance_inter = atoi(argv[idx + 1]->arg);
528 idx = 0;
529 if (argv_find(argv, argc, "external", &idx))
530 o->distance_external = atoi(argv[idx + 1]->arg);
39e92c06 531
d62a17ae 532 return CMD_SUCCESS;
baff583e
MZ
533}
534
535DEFUN (no_ospf6_distance_ospf6,
536 no_ospf6_distance_ospf6_cmd,
eaa1ae0d 537 "no distance ospf6 [{intra-area [(1-255)]|inter-area [(1-255)]|external [(1-255)]}]",
baff583e
MZ
538 NO_STR
539 "Administrative distance\n"
540 "OSPF6 distance\n"
541 "Intra-area routes\n"
542 "Distance for intra-area routes\n"
543 "Inter-area routes\n"
544 "Distance for inter-area routes\n"
545 "External routes\n"
546 "Distance for external routes\n")
547{
d62a17ae 548 VTY_DECLVAR_CONTEXT(ospf6, o);
549 int idx = 0;
baff583e 550
d62a17ae 551 if (argv_find(argv, argc, "intra-area", &idx) || argc == 3)
552 idx = o->distance_intra = 0;
553 if (argv_find(argv, argc, "inter-area", &idx) || argc == 3)
554 idx = o->distance_inter = 0;
555 if (argv_find(argv, argc, "external", &idx) || argc == 3)
556 o->distance_external = 0;
baff583e 557
d62a17ae 558 return CMD_SUCCESS;
baff583e
MZ
559}
560
d7d73ffc 561#if 0
baff583e
MZ
562DEFUN (ospf6_distance_source,
563 ospf6_distance_source_cmd,
39e92c06 564 "distance (1-255) X:X::X:X/M [WORD]",
baff583e
MZ
565 "Administrative distance\n"
566 "Distance value\n"
567 "IP source prefix\n"
568 "Access list name\n")
569{
cdc2d765 570 VTY_DECLVAR_CONTEXT(ospf6, o);
39e92c06
QY
571 char *alname = (argc == 4) ? argv[3]->arg : NULL;
572 ospf6_distance_set (vty, o, argv[1]->arg, argv[2]->arg, alname);
baff583e
MZ
573
574 return CMD_SUCCESS;
575}
576
577DEFUN (no_ospf6_distance_source,
578 no_ospf6_distance_source_cmd,
39e92c06 579 "no distance (1-255) X:X::X:X/M [WORD]",
baff583e
MZ
580 NO_STR
581 "Administrative distance\n"
582 "Distance value\n"
583 "IP source prefix\n"
584 "Access list name\n")
585{
cdc2d765 586 VTY_DECLVAR_CONTEXT(ospf6, o);
39e92c06
QY
587 char *alname = (argc == 5) ? argv[4]->arg : NULL;
588 ospf6_distance_unset (vty, o, argv[2]->arg, argv[3]->arg, alname);
baff583e
MZ
589
590 return CMD_SUCCESS;
591}
d7d73ffc 592#endif
baff583e 593
508e53e2 594DEFUN (ospf6_interface_area,
595 ospf6_interface_area_cmd,
596 "interface IFNAME area A.B.C.D",
597 "Enable routing on an IPv6 interface\n"
598 IFNAME_STR
599 "Specify the OSPF6 area ID\n"
600 "OSPF6 area ID in IPv4 address notation\n"
601 )
718e3744 602{
d62a17ae 603 VTY_DECLVAR_CONTEXT(ospf6, o);
604 int idx_ifname = 1;
605 int idx_ipv4 = 3;
606 struct ospf6_area *oa;
607 struct ospf6_interface *oi;
608 struct interface *ifp;
609 u_int32_t area_id;
610
611 /* find/create ospf6 interface */
bcc24579 612 ifp = if_get_by_name(argv[idx_ifname]->arg, VRF_DEFAULT, 0);
d62a17ae 613 oi = (struct ospf6_interface *)ifp->info;
614 if (oi == NULL)
615 oi = ospf6_interface_create(ifp);
616 if (oi->area) {
617 vty_out(vty, "%s already attached to Area %s\n",
618 oi->interface->name, oi->area->name);
619 return CMD_SUCCESS;
620 }
6452df09 621
d62a17ae 622 /* parse Area-ID */
623 if (inet_pton(AF_INET, argv[idx_ipv4]->arg, &area_id) != 1) {
624 vty_out(vty, "Invalid Area-ID: %s\n", argv[idx_ipv4]->arg);
625 return CMD_SUCCESS;
626 }
627
628 /* find/create ospf6 area */
629 oa = ospf6_area_lookup(area_id, o);
630 if (oa == NULL)
631 oa = ospf6_area_create(area_id, o, OSPF6_AREA_FMT_DOTTEDQUAD);
632
633 /* attach interface to area */
634 listnode_add(oa->if_list, oi); /* sort ?? */
635 oi->area = oa;
636
637 SET_FLAG(oa->flag, OSPF6_AREA_ENABLE);
638
639 /* ospf6 process is currently disabled, not much more to do */
640 if (CHECK_FLAG(o->flag, OSPF6_DISABLED))
641 return CMD_SUCCESS;
642
643 /* start up */
644 ospf6_interface_enable(oi);
645
646 /* If the router is ABR, originate summary routes */
647 if (ospf6_is_router_abr(o))
648 ospf6_abr_enable_area(oa);
649
650 return CMD_SUCCESS;
718e3744 651}
652
508e53e2 653DEFUN (no_ospf6_interface_area,
654 no_ospf6_interface_area_cmd,
655 "no interface IFNAME area A.B.C.D",
656 NO_STR
657 "Disable routing on an IPv6 interface\n"
658 IFNAME_STR
659 "Specify the OSPF6 area ID\n"
660 "OSPF6 area ID in IPv4 address notation\n"
661 )
718e3744 662{
d62a17ae 663 int idx_ifname = 2;
664 int idx_ipv4 = 4;
665 struct ospf6_interface *oi;
666 struct ospf6_area *oa;
667 struct interface *ifp;
668 u_int32_t area_id;
669
670 ifp = if_lookup_by_name(argv[idx_ifname]->arg, VRF_DEFAULT);
671 if (ifp == NULL) {
672 vty_out(vty, "No such interface %s\n", argv[idx_ifname]->arg);
673 return CMD_SUCCESS;
674 }
6452df09 675
d62a17ae 676 oi = (struct ospf6_interface *)ifp->info;
677 if (oi == NULL) {
678 vty_out(vty, "Interface %s not enabled\n", ifp->name);
679 return CMD_SUCCESS;
680 }
681
682 /* parse Area-ID */
683 if (inet_pton(AF_INET, argv[idx_ipv4]->arg, &area_id) != 1) {
684 vty_out(vty, "Invalid Area-ID: %s\n", argv[idx_ipv4]->arg);
685 return CMD_SUCCESS;
686 }
687
688 /* Verify Area */
689 if (oi->area == NULL) {
690 vty_out(vty, "No such Area-ID: %s\n", argv[idx_ipv4]->arg);
691 return CMD_SUCCESS;
692 }
693
694 if (oi->area->area_id != area_id) {
695 vty_out(vty, "Wrong Area-ID: %s is attached to area %s\n",
696 oi->interface->name, oi->area->name);
697 return CMD_SUCCESS;
698 }
699
700 thread_execute(master, interface_down, oi, 0);
701
702 oa = oi->area;
703 listnode_delete(oi->area->if_list, oi);
704 oi->area = (struct ospf6_area *)NULL;
705
706 /* Withdraw inter-area routes from this area, if necessary */
707 if (oa->if_list->count == 0) {
708 UNSET_FLAG(oa->flag, OSPF6_AREA_ENABLE);
709 ospf6_abr_disable_area(oa);
710 }
711
712 return CMD_SUCCESS;
718e3744 713}
714
f41b4a02
DD
715DEFUN (ospf6_stub_router_admin,
716 ospf6_stub_router_admin_cmd,
717 "stub-router administrative",
718 "Make router a stub router\n"
f41b4a02
DD
719 "Administratively applied, for an indefinite period\n")
720{
d62a17ae 721 struct listnode *node;
722 struct ospf6_area *oa;
723
724 if (!CHECK_FLAG(ospf6->flag, OSPF6_STUB_ROUTER)) {
725 for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, node, oa)) {
726 OSPF6_OPT_CLEAR(oa->options, OSPF6_OPT_V6);
727 OSPF6_OPT_CLEAR(oa->options, OSPF6_OPT_R);
728 OSPF6_ROUTER_LSA_SCHEDULE(oa);
729 }
730 SET_FLAG(ospf6->flag, OSPF6_STUB_ROUTER);
f41b4a02 731 }
f41b4a02 732
d62a17ae 733 return CMD_SUCCESS;
f41b4a02
DD
734}
735
736DEFUN (no_ospf6_stub_router_admin,
737 no_ospf6_stub_router_admin_cmd,
738 "no stub-router administrative",
739 NO_STR
740 "Make router a stub router\n"
f41b4a02
DD
741 "Administratively applied, for an indefinite period\n")
742{
d62a17ae 743 struct listnode *node;
744 struct ospf6_area *oa;
745
746 if (CHECK_FLAG(ospf6->flag, OSPF6_STUB_ROUTER)) {
747 for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, node, oa)) {
748 OSPF6_OPT_SET(oa->options, OSPF6_OPT_V6);
749 OSPF6_OPT_SET(oa->options, OSPF6_OPT_R);
750 OSPF6_ROUTER_LSA_SCHEDULE(oa);
751 }
752 UNSET_FLAG(ospf6->flag, OSPF6_STUB_ROUTER);
f41b4a02 753 }
f41b4a02 754
d62a17ae 755 return CMD_SUCCESS;
f41b4a02
DD
756}
757
d7d73ffc 758#if 0
f41b4a02
DD
759DEFUN (ospf6_stub_router_startup,
760 ospf6_stub_router_startup_cmd,
6147e2c6 761 "stub-router on-startup (5-86400)",
f41b4a02
DD
762 "Make router a stub router\n"
763 "Advertise inability to be a transit router\n"
764 "Automatically advertise as stub-router on startup of OSPF6\n"
765 "Time (seconds) to advertise self as stub-router\n")
766{
767 return CMD_SUCCESS;
768}
769
770DEFUN (no_ospf6_stub_router_startup,
771 no_ospf6_stub_router_startup_cmd,
772 "no stub-router on-startup",
773 NO_STR
774 "Make router a stub router\n"
775 "Advertise inability to be a transit router\n"
776 "Automatically advertise as stub-router on startup of OSPF6\n"
777 "Time (seconds) to advertise self as stub-router\n")
778{
779 return CMD_SUCCESS;
780}
781
782DEFUN (ospf6_stub_router_shutdown,
783 ospf6_stub_router_shutdown_cmd,
6147e2c6 784 "stub-router on-shutdown (5-86400)",
f41b4a02
DD
785 "Make router a stub router\n"
786 "Advertise inability to be a transit router\n"
787 "Automatically advertise as stub-router before shutdown\n"
788 "Time (seconds) to advertise self as stub-router\n")
789{
790 return CMD_SUCCESS;
791}
792
793DEFUN (no_ospf6_stub_router_shutdown,
794 no_ospf6_stub_router_shutdown_cmd,
795 "no stub-router on-shutdown",
796 NO_STR
797 "Make router a stub router\n"
798 "Advertise inability to be a transit router\n"
799 "Automatically advertise as stub-router before shutdown\n"
800 "Time (seconds) to advertise self as stub-router\n")
801{
802 return CMD_SUCCESS;
803}
d7d73ffc 804#endif
f41b4a02 805
d62a17ae 806static void ospf6_show(struct vty *vty, struct ospf6 *o)
718e3744 807{
d62a17ae 808 struct listnode *n;
809 struct ospf6_area *oa;
810 char router_id[16], duration[32];
811 struct timeval now, running, result;
812 char buf[32], rbuf[32];
813
814 /* process id, router id */
815 inet_ntop(AF_INET, &o->router_id, router_id, sizeof(router_id));
816 vty_out(vty, " OSPFv3 Routing Process (0) with Router-ID %s\n",
817 router_id);
818
819 /* running time */
820 monotime(&now);
821 timersub(&now, &o->starttime, &running);
822 timerstring(&running, duration, sizeof(duration));
823 vty_out(vty, " Running %s\n", duration);
824
825 /* Redistribute configuration */
826 /* XXX */
827
828 vty_out(vty, " LSA minimum arrival %d msecs\n", o->lsa_minarrival);
829
830 /* Show SPF parameters */
831 vty_out(vty,
832 " Initial SPF scheduling delay %d millisec(s)\n"
833 " Minimum hold time between consecutive SPFs %d millsecond(s)\n"
834 " Maximum hold time between consecutive SPFs %d millsecond(s)\n"
835 " Hold time multiplier is currently %d\n",
836 o->spf_delay, o->spf_holdtime, o->spf_max_holdtime,
837 o->spf_hold_multiplier);
838
839 vty_out(vty, " SPF algorithm ");
840 if (o->ts_spf.tv_sec || o->ts_spf.tv_usec) {
841 timersub(&now, &o->ts_spf, &result);
842 timerstring(&result, buf, sizeof(buf));
843 ospf6_spf_reason_string(o->last_spf_reason, rbuf, sizeof(rbuf));
844 vty_out(vty, "last executed %s ago, reason %s\n", buf, rbuf);
845 vty_out(vty, " Last SPF duration %lld sec %lld usec\n",
846 (long long)o->ts_spf_duration.tv_sec,
847 (long long)o->ts_spf_duration.tv_usec);
848 } else
ab0f1135 849 vty_out(vty, "has not been run\n");
d62a17ae 850 threadtimer_string(now, o->t_spf_calc, buf, sizeof(buf));
851 vty_out(vty, " SPF timer %s%s\n", (o->t_spf_calc ? "due in " : "is "),
852 buf);
853
854 if (CHECK_FLAG(o->flag, OSPF6_STUB_ROUTER))
855 vty_out(vty, " Router Is Stub Router\n");
856
857 /* LSAs */
858 vty_out(vty, " Number of AS scoped LSAs is %u\n", o->lsdb->count);
859
860 /* Areas */
861 vty_out(vty, " Number of areas in this router is %u\n",
862 listcount(o->area_list));
863
864 if (CHECK_FLAG(o->config_flags, OSPF6_LOG_ADJACENCY_CHANGES)) {
865 if (CHECK_FLAG(o->config_flags, OSPF6_LOG_ADJACENCY_DETAIL))
866 vty_out(vty, " All adjacency changes are logged\n");
867 else
868 vty_out(vty, " Adjacency changes are logged\n");
869 }
870
871 vty_out(vty, "\n");
872
873 for (ALL_LIST_ELEMENTS_RO(o->area_list, n, oa))
874 ospf6_area_show(vty, oa);
718e3744 875}
876
508e53e2 877/* show top level structures */
878DEFUN (show_ipv6_ospf6,
879 show_ipv6_ospf6_cmd,
880 "show ipv6 ospf6",
881 SHOW_STR
882 IP6_STR
883 OSPF6_STR)
718e3744 884{
d62a17ae 885 OSPF6_CMD_CHECK_RUNNING();
508e53e2 886
d62a17ae 887 ospf6_show(vty, ospf6);
888 return CMD_SUCCESS;
718e3744 889}
890
891DEFUN (show_ipv6_ospf6_route,
892 show_ipv6_ospf6_route_cmd,
6de69f83 893 "show ipv6 ospf6 route [<intra-area|inter-area|external-1|external-2|X:X::X:X|X:X::X:X/M|detail|summary>]",
718e3744 894 SHOW_STR
895 IP6_STR
896 OSPF6_STR
508e53e2 897 ROUTE_STR
1d68dbfe
DW
898 "Display Intra-Area routes\n"
899 "Display Inter-Area routes\n"
900 "Display Type-1 External routes\n"
901 "Display Type-2 External routes\n"
902 "Specify IPv6 address\n"
903 "Specify IPv6 prefix\n"
904 "Detailed information\n"
905 "Summary of route table\n")
718e3744 906{
d62a17ae 907 OSPF6_CMD_CHECK_RUNNING();
b52a8a52 908
d62a17ae 909 ospf6_route_table_show(vty, 4, argc, argv, ospf6->route_table);
910 return CMD_SUCCESS;
718e3744 911}
912
508e53e2 913DEFUN (show_ipv6_ospf6_route_match,
914 show_ipv6_ospf6_route_match_cmd,
1d68dbfe 915 "show ipv6 ospf6 route X:X::X:X/M <match|longer>",
718e3744 916 SHOW_STR
917 IP6_STR
918 OSPF6_STR
508e53e2 919 ROUTE_STR
920 "Specify IPv6 prefix\n"
921 "Display routes which match the specified route\n"
1d68dbfe 922 "Display routes longer than the specified route\n")
718e3744 923{
d62a17ae 924 OSPF6_CMD_CHECK_RUNNING();
b52a8a52 925
d62a17ae 926 ospf6_route_table_show(vty, 4, argc, argv, ospf6->route_table);
927 return CMD_SUCCESS;
718e3744 928}
929
508e53e2 930DEFUN (show_ipv6_ospf6_route_match_detail,
931 show_ipv6_ospf6_route_match_detail_cmd,
4846ef64 932 "show ipv6 ospf6 route X:X::X:X/M match detail",
718e3744 933 SHOW_STR
934 IP6_STR
935 OSPF6_STR
508e53e2 936 ROUTE_STR
937 "Specify IPv6 prefix\n"
938 "Display routes which match the specified route\n"
718e3744 939 "Detailed information\n"
940 )
508e53e2 941{
d62a17ae 942 OSPF6_CMD_CHECK_RUNNING();
b52a8a52 943
d62a17ae 944 ospf6_route_table_show(vty, 4, argc, argv, ospf6->route_table);
945 return CMD_SUCCESS;
508e53e2 946}
718e3744 947
cb4b8845 948
4846ef64 949DEFUN (show_ipv6_ospf6_route_type_detail,
950 show_ipv6_ospf6_route_type_detail_cmd,
6147e2c6 951 "show ipv6 ospf6 route <intra-area|inter-area|external-1|external-2> detail",
4846ef64 952 SHOW_STR
953 IP6_STR
954 OSPF6_STR
955 ROUTE_STR
ea402198
DO
956 "Display Intra-Area routes\n"
957 "Display Inter-Area routes\n"
958 "Display Type-1 External routes\n"
959 "Display Type-2 External routes\n"
4846ef64 960 "Detailed information\n"
961 )
962{
d62a17ae 963 OSPF6_CMD_CHECK_RUNNING();
b52a8a52 964
d62a17ae 965 ospf6_route_table_show(vty, 4, argc, argv, ospf6->route_table);
966 return CMD_SUCCESS;
4846ef64 967}
718e3744 968
d62a17ae 969static void ospf6_stub_router_config_write(struct vty *vty)
f41b4a02 970{
d62a17ae 971 if (CHECK_FLAG(ospf6->flag, OSPF6_STUB_ROUTER)) {
972 vty_out(vty, " stub-router administrative\n");
973 }
974 return;
f41b4a02
DD
975}
976
d62a17ae 977static int ospf6_distance_config_write(struct vty *vty)
baff583e 978{
d62a17ae 979 struct route_node *rn;
980 struct ospf6_distance *odistance;
981
982 if (ospf6->distance_all)
983 vty_out(vty, " distance %u\n", ospf6->distance_all);
984
985 if (ospf6->distance_intra || ospf6->distance_inter
986 || ospf6->distance_external) {
987 vty_out(vty, " distance ospf6");
988
989 if (ospf6->distance_intra)
990 vty_out(vty, " intra-area %u", ospf6->distance_intra);
991 if (ospf6->distance_inter)
992 vty_out(vty, " inter-area %u", ospf6->distance_inter);
993 if (ospf6->distance_external)
994 vty_out(vty, " external %u", ospf6->distance_external);
995
996 vty_out(vty, "\n");
997 }
998
999 for (rn = route_top(ospf6->distance_table); rn; rn = route_next(rn))
1000 if ((odistance = rn->info) != NULL) {
1001 char buf[PREFIX_STRLEN];
1002
1003 vty_out(vty, " distance %u %s %s\n",
1004 odistance->distance,
1005 prefix2str(&rn->p, buf, sizeof(buf)),
1006 odistance->access_list ? odistance->access_list
1007 : "");
1008 }
1009 return 0;
baff583e
MZ
1010}
1011
508e53e2 1012/* OSPF configuration write function. */
d62a17ae 1013static int config_write_ospf6(struct vty *vty)
508e53e2 1014{
d62a17ae 1015 char router_id[16];
1016 struct listnode *j, *k;
1017 struct ospf6_area *oa;
1018 struct ospf6_interface *oi;
1019
1020 /* OSPFv3 configuration. */
1021 if (ospf6 == NULL)
1022 return CMD_SUCCESS;
1023
1024 inet_ntop(AF_INET, &ospf6->router_id_static, router_id,
1025 sizeof(router_id));
1026 vty_out(vty, "router ospf6\n");
1027 if (ospf6->router_id_static != 0)
5d1a2ee8 1028 vty_out(vty, " ospf6 router-id %s\n", router_id);
d62a17ae 1029
1030 /* log-adjacency-changes flag print. */
1031 if (CHECK_FLAG(ospf6->config_flags, OSPF6_LOG_ADJACENCY_CHANGES)) {
1032 if (CHECK_FLAG(ospf6->config_flags, OSPF6_LOG_ADJACENCY_DETAIL))
1033 vty_out(vty, " log-adjacency-changes detail\n");
1034 else if (!DFLT_OSPF6_LOG_ADJACENCY_CHANGES)
1035 vty_out(vty, " log-adjacency-changes\n");
1036 } else if (DFLT_OSPF6_LOG_ADJACENCY_CHANGES) {
1037 vty_out(vty, " no log-adjacency-changes\n");
1038 }
1039
1040 if (ospf6->ref_bandwidth != OSPF6_REFERENCE_BANDWIDTH)
1041 vty_out(vty, " auto-cost reference-bandwidth %d\n",
1042 ospf6->ref_bandwidth);
1043
1044 /* LSA timers print. */
1045 if (ospf6->lsa_minarrival != OSPF_MIN_LS_ARRIVAL)
1046 vty_out(vty, " timers lsa min-arrival %d\n",
1047 ospf6->lsa_minarrival);
1048
1049 ospf6_stub_router_config_write(vty);
1050 ospf6_redistribute_config_write(vty);
1051 ospf6_area_config_write(vty);
1052 ospf6_spf_config_write(vty);
1053 ospf6_distance_config_write(vty);
1054
1055 for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, j, oa)) {
1056 for (ALL_LIST_ELEMENTS_RO(oa->if_list, k, oi))
1057 vty_out(vty, " interface %s area %s\n",
1058 oi->interface->name, oa->name);
1059 }
1060 vty_out(vty, "!\n");
1061 return 0;
508e53e2 1062}
1063
1064/* OSPF6 node structure. */
d62a17ae 1065static struct cmd_node ospf6_node = {
1066 OSPF6_NODE, "%s(config-ospf6)# ", 1 /* VTYSH */
508e53e2 1067};
1068
1069/* Install ospf related commands. */
d62a17ae 1070void ospf6_top_init(void)
718e3744 1071{
d62a17ae 1072 /* Install ospf6 top node. */
1073 install_node(&ospf6_node, config_write_ospf6);
1074
1075 install_element(VIEW_NODE, &show_ipv6_ospf6_cmd);
1076 install_element(CONFIG_NODE, &router_ospf6_cmd);
1077 install_element(CONFIG_NODE, &no_router_ospf6_cmd);
1078
1079 install_element(VIEW_NODE, &show_ipv6_ospf6_route_cmd);
1080 install_element(VIEW_NODE, &show_ipv6_ospf6_route_match_cmd);
1081 install_element(VIEW_NODE, &show_ipv6_ospf6_route_match_detail_cmd);
1082 install_element(VIEW_NODE, &show_ipv6_ospf6_route_type_detail_cmd);
1083
1084 install_default(OSPF6_NODE);
1085 install_element(OSPF6_NODE, &ospf6_router_id_cmd);
5d1a2ee8
QY
1086 install_element(OSPF6_NODE, &no_ospf6_router_id_cmd);
1087 install_element(OSPF6_NODE, &ospf6_router_id_hdn_cmd);
1088 install_element(OSPF6_NODE, &no_ospf6_router_id_hdn_cmd);
d62a17ae 1089 install_element(OSPF6_NODE, &ospf6_log_adjacency_changes_cmd);
1090 install_element(OSPF6_NODE, &ospf6_log_adjacency_changes_detail_cmd);
1091 install_element(OSPF6_NODE, &no_ospf6_log_adjacency_changes_cmd);
1092 install_element(OSPF6_NODE, &no_ospf6_log_adjacency_changes_detail_cmd);
1093
1094 /* LSA timers commands */
1095 install_element(OSPF6_NODE, &ospf6_timers_lsa_cmd);
1096 install_element(OSPF6_NODE, &no_ospf6_timers_lsa_cmd);
1097
1098 install_element(OSPF6_NODE, &ospf6_interface_area_cmd);
1099 install_element(OSPF6_NODE, &no_ospf6_interface_area_cmd);
1100 install_element(OSPF6_NODE, &ospf6_stub_router_admin_cmd);
1101 install_element(OSPF6_NODE, &no_ospf6_stub_router_admin_cmd);
1102/* For a later time */
34d5ef45 1103#if 0
f41b4a02
DD
1104 install_element (OSPF6_NODE, &ospf6_stub_router_startup_cmd);
1105 install_element (OSPF6_NODE, &no_ospf6_stub_router_startup_cmd);
1106 install_element (OSPF6_NODE, &ospf6_stub_router_shutdown_cmd);
1107 install_element (OSPF6_NODE, &no_ospf6_stub_router_shutdown_cmd);
34d5ef45 1108#endif
508e53e2 1109
d62a17ae 1110 install_element(OSPF6_NODE, &ospf6_distance_cmd);
1111 install_element(OSPF6_NODE, &no_ospf6_distance_cmd);
1112 install_element(OSPF6_NODE, &ospf6_distance_ospf6_cmd);
1113 install_element(OSPF6_NODE, &no_ospf6_distance_ospf6_cmd);
baff583e
MZ
1114#if 0
1115 install_element (OSPF6_NODE, &ospf6_distance_source_cmd);
1116 install_element (OSPF6_NODE, &no_ospf6_distance_source_cmd);
1117#endif
718e3744 1118}