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