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