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