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