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