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