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