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