MiniDLNA update: 1.0.19.1 to 1.0.20
[tomato.git] / release / src / router / zebra / zebra / zebra_vty.c
blob6bc509fb571ffc2270e39406f0156634d75db7e6
1 /* Zebra VTY functions
2 * Copyright (C) 2002 Kunihiro Ishiguro
4 * This file is part of GNU Zebra.
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.
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.
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.
22 #include <zebra.h>
24 #include "if.h"
25 #include "prefix.h"
26 #include "command.h"
27 #include "table.h"
28 #include "rib.h"
30 /* Return route type string for VTY output. */
31 const char *
32 route_type_str (u_char type)
34 switch (type)
36 case ZEBRA_ROUTE_SYSTEM:
37 return "system";
38 case ZEBRA_ROUTE_KERNEL:
39 return "kernel";
40 case ZEBRA_ROUTE_CONNECT:
41 return "connected";
42 case ZEBRA_ROUTE_STATIC:
43 return "static";
44 case ZEBRA_ROUTE_RIP:
45 return "rip";
46 case ZEBRA_ROUTE_RIPNG:
47 return "rip";
48 case ZEBRA_ROUTE_OSPF:
49 return "ospf";
50 case ZEBRA_ROUTE_OSPF6:
51 return "ospf";
52 case ZEBRA_ROUTE_BGP:
53 return "bgp";
54 default:
55 return "unknown";
59 /* Return route type string for VTY output. */
60 const char
61 route_type_char (u_char type)
63 switch (type)
65 case ZEBRA_ROUTE_SYSTEM:
66 return 'S';
67 case ZEBRA_ROUTE_KERNEL:
68 return 'K';
69 case ZEBRA_ROUTE_CONNECT:
70 return 'C';
71 case ZEBRA_ROUTE_STATIC:
72 return 'S';
73 case ZEBRA_ROUTE_RIP:
74 return 'R';
75 case ZEBRA_ROUTE_RIPNG:
76 return 'R';
77 case ZEBRA_ROUTE_OSPF:
78 return 'O';
79 case ZEBRA_ROUTE_OSPF6:
80 return 'O';
81 case ZEBRA_ROUTE_BGP:
82 return 'B';
83 default:
84 return '?';
88 /* General fucntion for static route. */
89 int
90 zebra_static_ipv4 (struct vty *vty, int add_cmd,
91 char *dest_str, char *mask_str, char *gate_str,
92 char *distance_str)
94 int ret;
95 u_char distance;
96 struct prefix p;
97 struct in_addr gate;
98 struct in_addr mask;
99 char *ifname;
101 ret = str2prefix (dest_str, &p);
102 if (ret <= 0)
104 vty_out (vty, "%% Malformed address%s", VTY_NEWLINE);
105 return CMD_WARNING;
108 /* Cisco like mask notation. */
109 if (mask_str)
111 ret = inet_aton (mask_str, &mask);
112 if (ret == 0)
114 vty_out (vty, "%% Malformed address%s", VTY_NEWLINE);
115 return CMD_WARNING;
117 p.prefixlen = ip_masklen (mask);
120 /* Apply mask for given prefix. */
121 apply_mask (&p);
123 /* Administrative distance. */
124 if (distance_str)
125 distance = atoi (distance_str);
126 else
127 distance = ZEBRA_STATIC_DISTANCE_DEFAULT;
129 /* Null0 static route. */
130 if (strncasecmp (gate_str, "Null0", strlen (gate_str)) == 0)
132 if (add_cmd)
133 static_add_ipv4 (&p, NULL, NULL, distance, 0);
134 else
135 static_delete_ipv4 (&p, NULL, NULL, distance, 0);
136 return CMD_SUCCESS;
139 /* When gateway is A.B.C.D format, gate is treated as nexthop
140 address other case gate is treated as interface name. */
141 ret = inet_aton (gate_str, &gate);
142 if (ret)
143 ifname = NULL;
144 else
145 ifname = gate_str;
147 if (add_cmd)
148 static_add_ipv4 (&p, ifname ? NULL : &gate, ifname, distance, 0);
149 else
150 static_delete_ipv4 (&p, ifname ? NULL : &gate, ifname, distance, 0);
152 return CMD_SUCCESS;
155 /* Static route configuration. */
156 DEFUN (ip_route,
157 ip_route_cmd,
158 "ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0)",
159 IP_STR
160 "Establish static routes\n"
161 "IP destination prefix (e.g. 10.0.0.0/8)\n"
162 "IP gateway address\n"
163 "IP gateway interface name\n"
164 "Null interface\n")
166 return zebra_static_ipv4 (vty, 1, argv[0], NULL, argv[1], NULL);
169 /* Mask as A.B.C.D format. */
170 DEFUN (ip_route_mask,
171 ip_route_mask_cmd,
172 "ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0)",
173 IP_STR
174 "Establish static routes\n"
175 "IP destination prefix\n"
176 "IP destination prefix mask\n"
177 "IP gateway address\n"
178 "IP gateway interface name\n"
179 "Null interface\n")
181 return zebra_static_ipv4 (vty, 1, argv[0], argv[1], argv[2], NULL);
184 /* Distance option value. */
185 DEFUN (ip_route_distance,
186 ip_route_distance_cmd,
187 "ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0) <1-255>",
188 IP_STR
189 "Establish static routes\n"
190 "IP destination prefix (e.g. 10.0.0.0/8)\n"
191 "IP gateway address\n"
192 "IP gateway interface name\n"
193 "Null interface\n"
194 "Distance value for this route\n")
196 return zebra_static_ipv4 (vty, 1, argv[0], NULL, argv[1], argv[2]);
199 DEFUN (ip_route_mask_distance,
200 ip_route_mask_distance_cmd,
201 "ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0) <1-255>",
202 IP_STR
203 "Establish static routes\n"
204 "IP destination prefix\n"
205 "IP destination prefix mask\n"
206 "IP gateway address\n"
207 "IP gateway interface name\n"
208 "Null interface\n"
209 "Distance value for this route\n")
211 return zebra_static_ipv4 (vty, 1, argv[0], argv[1], argv[2], argv[3]);
214 DEFUN (no_ip_route,
215 no_ip_route_cmd,
216 "no ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0)",
217 NO_STR
218 IP_STR
219 "Establish static routes\n"
220 "IP destination prefix (e.g. 10.0.0.0/8)\n"
221 "IP gateway address\n"
222 "IP gateway interface name\n"
223 "Null interface\n")
225 return zebra_static_ipv4 (vty, 0, argv[0], NULL, argv[1], NULL);
228 DEFUN (no_ip_route_mask,
229 no_ip_route_mask_cmd,
230 "no ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0)",
231 NO_STR
232 IP_STR
233 "Establish static routes\n"
234 "IP destination prefix\n"
235 "IP destination prefix mask\n"
236 "IP gateway address\n"
237 "IP gateway interface name\n"
238 "Null interface\n")
240 return zebra_static_ipv4 (vty, 0, argv[0], argv[1], argv[2], NULL);
243 DEFUN (no_ip_route_distance,
244 no_ip_route_distance_cmd,
245 "no ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0) <1-255>",
246 NO_STR
247 IP_STR
248 "Establish static routes\n"
249 "IP destination prefix (e.g. 10.0.0.0/8)\n"
250 "IP gateway address\n"
251 "IP gateway interface name\n"
252 "Null interface\n"
253 "Distance value for this route\n")
255 return zebra_static_ipv4 (vty, 0, argv[0], NULL, argv[1], argv[2]);
258 DEFUN (no_ip_route_mask_distance,
259 no_ip_route_mask_distance_cmd,
260 "no ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0) <1-255>",
261 NO_STR
262 IP_STR
263 "Establish static routes\n"
264 "IP destination prefix\n"
265 "IP destination prefix mask\n"
266 "IP gateway address\n"
267 "IP gateway interface name\n"
268 "Null interface\n"
269 "Distance value for this route\n")
271 return zebra_static_ipv4 (vty, 0, argv[0], argv[1], argv[2], argv[3]);
274 /* New RIB. Detailed information for IPv4 route. */
275 void
276 vty_show_ip_route_detail (struct vty *vty, struct route_node *rn)
278 struct rib *rib;
279 struct nexthop *nexthop;
281 for (rib = rn->info; rib; rib = rib->next)
283 vty_out (vty, "Routing entry for %s/%d%s",
284 inet_ntoa (rn->p.u.prefix4), rn->p.prefixlen,
285 VTY_NEWLINE);
286 vty_out (vty, " Known via \"%s\"", route_type_str (rib->type));
287 vty_out (vty, ", distance %d, metric %d", rib->distance, rib->metric);
288 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
289 vty_out (vty, ", best");
290 if (rib->refcnt)
291 vty_out (vty, ", refcnt %ld", rib->refcnt);
292 vty_out (vty, "%s", VTY_NEWLINE);
294 #define ONE_DAY_SECOND 60*60*24
295 #define ONE_WEEK_SECOND 60*60*24*7
296 if (rib->type == ZEBRA_ROUTE_RIP
297 || rib->type == ZEBRA_ROUTE_OSPF
298 || rib->type == ZEBRA_ROUTE_BGP)
300 time_t uptime;
301 struct tm *tm;
303 uptime = time (NULL);
304 uptime -= rib->uptime;
305 tm = gmtime (&uptime);
307 vty_out (vty, " Last update ");
309 if (uptime < ONE_DAY_SECOND)
310 vty_out (vty, "%02d:%02d:%02d",
311 tm->tm_hour, tm->tm_min, tm->tm_sec);
312 else if (uptime < ONE_WEEK_SECOND)
313 vty_out (vty, "%dd%02dh%02dm",
314 tm->tm_yday, tm->tm_hour, tm->tm_min);
315 else
316 vty_out (vty, "%02dw%dd%02dh",
317 tm->tm_yday/7,
318 tm->tm_yday - ((tm->tm_yday/7) * 7), tm->tm_hour);
319 vty_out (vty, " ago%s", VTY_NEWLINE);
322 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
324 vty_out (vty, " %c",
325 CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB) ? '*' : ' ');
327 switch (nexthop->type)
329 case NEXTHOP_TYPE_IPV4:
330 case NEXTHOP_TYPE_IPV4_IFINDEX:
331 vty_out (vty, " %s", inet_ntoa (nexthop->gate.ipv4));
332 if (nexthop->ifindex)
333 vty_out (vty, ", via %s", ifindex2ifname (nexthop->ifindex));
334 break;
335 case NEXTHOP_TYPE_IFINDEX:
336 vty_out (vty, " directly connected, %s",
337 ifindex2ifname (nexthop->ifindex));
338 break;
339 case NEXTHOP_TYPE_IFNAME:
340 vty_out (vty, " directly connected, %s", nexthop->ifname);
341 break;
342 case NEXTHOP_TYPE_BLACKHOLE:
343 vty_out (vty, " directly connected, via Null0");
344 break;
345 default:
346 break;
348 if (! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
349 vty_out (vty, " inactive");
351 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
353 vty_out (vty, " (recursive");
355 switch (nexthop->rtype)
357 case NEXTHOP_TYPE_IPV4:
358 case NEXTHOP_TYPE_IPV4_IFINDEX:
359 vty_out (vty, " via %s)", inet_ntoa (nexthop->rgate.ipv4));
360 break;
361 case NEXTHOP_TYPE_IFINDEX:
362 case NEXTHOP_TYPE_IFNAME:
363 vty_out (vty, " is directly connected, %s)",
364 ifindex2ifname (nexthop->rifindex));
365 break;
366 default:
367 break;
370 vty_out (vty, "%s", VTY_NEWLINE);
372 vty_out (vty, "%s", VTY_NEWLINE);
376 void
377 vty_show_ip_route (struct vty *vty, struct route_node *rn, struct rib *rib)
379 struct nexthop *nexthop;
380 int len = 0;
381 char buf[BUFSIZ];
383 /* Nexthop information. */
384 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
386 if (nexthop == rib->nexthop)
388 /* Prefix information. */
389 len = vty_out (vty, "%c%c%c %s/%d",
390 route_type_char (rib->type),
391 CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED)
392 ? '>' : ' ',
393 CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)
394 ? '*' : ' ',
395 inet_ntop (AF_INET, &rn->p.u.prefix, buf, BUFSIZ),
396 rn->p.prefixlen);
398 /* Distance and metric display. */
399 if (rib->type != ZEBRA_ROUTE_CONNECT
400 && rib->type != ZEBRA_ROUTE_KERNEL)
401 len += vty_out (vty, " [%d/%d]", rib->distance,
402 rib->metric);
404 else
405 vty_out (vty, " %c%*c",
406 CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)
407 ? '*' : ' ',
408 len - 3, ' ');
410 switch (nexthop->type)
412 case NEXTHOP_TYPE_IPV4:
413 case NEXTHOP_TYPE_IPV4_IFINDEX:
414 vty_out (vty, " via %s", inet_ntoa (nexthop->gate.ipv4));
415 if (nexthop->ifindex)
416 vty_out (vty, ", %s", ifindex2ifname (nexthop->ifindex));
417 break;
418 case NEXTHOP_TYPE_IFINDEX:
419 vty_out (vty, " is directly connected, %s",
420 ifindex2ifname (nexthop->ifindex));
421 break;
422 case NEXTHOP_TYPE_IFNAME:
423 vty_out (vty, " is directly connected, %s", nexthop->ifname);
424 break;
425 case NEXTHOP_TYPE_BLACKHOLE:
426 vty_out (vty, " is directly connected, Null0");
427 default:
428 break;
430 if (! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
431 vty_out (vty, " inactive");
433 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
435 vty_out (vty, " (recursive");
437 switch (nexthop->rtype)
439 case NEXTHOP_TYPE_IPV4:
440 case NEXTHOP_TYPE_IPV4_IFINDEX:
441 vty_out (vty, " via %s)", inet_ntoa (nexthop->rgate.ipv4));
442 break;
443 case NEXTHOP_TYPE_IFINDEX:
444 case NEXTHOP_TYPE_IFNAME:
445 vty_out (vty, " is directly connected, %s)",
446 ifindex2ifname (nexthop->rifindex));
447 break;
448 default:
449 break;
453 if (rib->type == ZEBRA_ROUTE_RIP
454 || rib->type == ZEBRA_ROUTE_OSPF
455 || rib->type == ZEBRA_ROUTE_BGP)
457 time_t uptime;
458 struct tm *tm;
460 uptime = time (NULL);
461 uptime -= rib->uptime;
462 tm = gmtime (&uptime);
464 #define ONE_DAY_SECOND 60*60*24
465 #define ONE_WEEK_SECOND 60*60*24*7
467 if (uptime < ONE_DAY_SECOND)
468 vty_out (vty, ", %02d:%02d:%02d",
469 tm->tm_hour, tm->tm_min, tm->tm_sec);
470 else if (uptime < ONE_WEEK_SECOND)
471 vty_out (vty, ", %dd%02dh%02dm",
472 tm->tm_yday, tm->tm_hour, tm->tm_min);
473 else
474 vty_out (vty, ", %02dw%dd%02dh",
475 tm->tm_yday/7,
476 tm->tm_yday - ((tm->tm_yday/7) * 7), tm->tm_hour);
478 vty_out (vty, "%s", VTY_NEWLINE);
482 #define SHOW_ROUTE_V4_HEADER "Codes: K - kernel route, C - connected, S - static, R - RIP, O - OSPF,%s B - BGP, > - selected route, * - FIB route%s%s"
484 DEFUN (show_ip_route,
485 show_ip_route_cmd,
486 "show ip route",
487 SHOW_STR
488 IP_STR
489 "IP routing table\n")
491 struct route_table *table;
492 struct route_node *rn;
493 struct rib *rib;
494 int first = 1;
496 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
497 if (! table)
498 return CMD_SUCCESS;
500 /* Show all IPv4 routes. */
501 for (rn = route_top (table); rn; rn = route_next (rn))
502 for (rib = rn->info; rib; rib = rib->next)
504 if (first)
506 vty_out (vty, SHOW_ROUTE_V4_HEADER, VTY_NEWLINE, VTY_NEWLINE,
507 VTY_NEWLINE);
508 first = 0;
510 vty_show_ip_route (vty, rn, rib);
512 return CMD_SUCCESS;
515 DEFUN (show_ip_route_prefix_longer,
516 show_ip_route_prefix_longer_cmd,
517 "show ip route A.B.C.D/M longer-prefixes",
518 SHOW_STR
519 IP_STR
520 "IP routing table\n"
521 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
522 "Show route matching the specified Network/Mask pair only\n")
524 struct route_table *table;
525 struct route_node *rn;
526 struct rib *rib;
527 struct prefix p;
528 int ret;
529 int first = 1;
531 ret = str2prefix (argv[0], &p);
532 if (! ret)
534 vty_out (vty, "%% Malformed Prefix%s", VTY_NEWLINE);
535 return CMD_WARNING;
538 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
539 if (! table)
540 return CMD_SUCCESS;
542 /* Show matched type IPv4 routes. */
543 for (rn = route_top (table); rn; rn = route_next (rn))
544 for (rib = rn->info; rib; rib = rib->next)
545 if (prefix_match (&p, &rn->p))
547 if (first)
549 vty_out (vty, SHOW_ROUTE_V4_HEADER, VTY_NEWLINE,
550 VTY_NEWLINE, VTY_NEWLINE);
551 first = 0;
553 vty_show_ip_route (vty, rn, rib);
555 return CMD_SUCCESS;
558 DEFUN (show_ip_route_supernets,
559 show_ip_route_supernets_cmd,
560 "show ip route supernets-only",
561 SHOW_STR
562 IP_STR
563 "IP routing table\n"
564 "Show supernet entries only\n")
566 struct route_table *table;
567 struct route_node *rn;
568 struct rib *rib;
569 u_int32_t addr;
570 int first = 1;
572 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
573 if (! table)
574 return CMD_SUCCESS;
576 /* Show matched type IPv4 routes. */
577 for (rn = route_top (table); rn; rn = route_next (rn))
578 for (rib = rn->info; rib; rib = rib->next)
580 addr = ntohl (rn->p.u.prefix4.s_addr);
582 if ((IN_CLASSC (addr) && rn->p.prefixlen < 24)
583 || (IN_CLASSB (addr) && rn->p.prefixlen < 16)
584 || (IN_CLASSA (addr) && rn->p.prefixlen < 8))
586 if (first)
588 vty_out (vty, SHOW_ROUTE_V4_HEADER, VTY_NEWLINE,
589 VTY_NEWLINE, VTY_NEWLINE);
590 first = 0;
592 vty_show_ip_route (vty, rn, rib);
595 return CMD_SUCCESS;
598 DEFUN (show_ip_route_protocol,
599 show_ip_route_protocol_cmd,
600 "show ip route (bgp|connected|kernel|ospf|rip|static)",
601 SHOW_STR
602 IP_STR
603 "IP routing table\n"
604 "Border Gateway Protocol (BGP)\n"
605 "Connected\n"
606 "Kernel\n"
607 "Open Shortest Path First (OSPF)\n"
608 "Routing Information Protocol (RIP)\n"
609 "Static routes\n")
611 int type;
612 struct route_table *table;
613 struct route_node *rn;
614 struct rib *rib;
615 int first = 1;
617 if (strncmp (argv[0], "b", 1) == 0)
618 type = ZEBRA_ROUTE_BGP;
619 else if (strncmp (argv[0], "c", 1) == 0)
620 type = ZEBRA_ROUTE_CONNECT;
621 else if (strncmp (argv[0], "k", 1) ==0)
622 type = ZEBRA_ROUTE_KERNEL;
623 else if (strncmp (argv[0], "o", 1) == 0)
624 type = ZEBRA_ROUTE_OSPF;
625 else if (strncmp (argv[0], "r", 1) == 0)
626 type = ZEBRA_ROUTE_RIP;
627 else if (strncmp (argv[0], "s", 1) == 0)
628 type = ZEBRA_ROUTE_STATIC;
629 else
631 vty_out (vty, "Unknown route type%s", VTY_NEWLINE);
632 return CMD_WARNING;
635 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
636 if (! table)
637 return CMD_SUCCESS;
639 /* Show matched type IPv4 routes. */
640 for (rn = route_top (table); rn; rn = route_next (rn))
641 for (rib = rn->info; rib; rib = rib->next)
642 if (rib->type == type)
644 if (first)
646 vty_out (vty, SHOW_ROUTE_V4_HEADER,
647 VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE);
648 first = 0;
650 vty_show_ip_route (vty, rn, rib);
652 return CMD_SUCCESS;
655 DEFUN (show_ip_route_addr,
656 show_ip_route_addr_cmd,
657 "show ip route A.B.C.D",
658 SHOW_STR
659 IP_STR
660 "IP routing table\n"
661 "Network in the IP routing table to display\n")
663 int ret;
664 struct prefix_ipv4 p;
665 struct route_table *table;
666 struct route_node *rn;
668 ret = str2prefix_ipv4 (argv[0], &p);
669 if (ret <= 0)
671 vty_out (vty, "%% Malformed IPv4 address%s", VTY_NEWLINE);
672 return CMD_WARNING;
675 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
676 if (! table)
677 return CMD_SUCCESS;
679 rn = route_node_match (table, (struct prefix *) &p);
680 if (! rn)
682 vty_out (vty, "%% Network not in table%s", VTY_NEWLINE);
683 return CMD_WARNING;
686 vty_show_ip_route_detail (vty, rn);
688 route_unlock_node (rn);
690 return CMD_SUCCESS;
693 DEFUN (show_ip_route_prefix,
694 show_ip_route_prefix_cmd,
695 "show ip route A.B.C.D/M",
696 SHOW_STR
697 IP_STR
698 "IP routing table\n"
699 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n")
701 int ret;
702 struct prefix_ipv4 p;
703 struct route_table *table;
704 struct route_node *rn;
706 ret = str2prefix_ipv4 (argv[0], &p);
707 if (ret <= 0)
709 vty_out (vty, "%% Malformed IPv4 address%s", VTY_NEWLINE);
710 return CMD_WARNING;
713 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
714 if (! table)
715 return CMD_SUCCESS;
717 rn = route_node_match (table, (struct prefix *) &p);
718 if (! rn || rn->p.prefixlen != p.prefixlen)
720 vty_out (vty, "%% Network not in table%s", VTY_NEWLINE);
721 return CMD_WARNING;
724 vty_show_ip_route_detail (vty, rn);
726 route_unlock_node (rn);
728 return CMD_SUCCESS;
731 void
732 zebra_show_ip_route (struct vty *vty, struct vrf *vrf)
734 vty_out (vty, "IP routing table name is %s(%d)%s",
735 vrf->name ? vrf->name : "", vrf->id, VTY_NEWLINE);
737 vty_out (vty, "Route Source Networks%s", VTY_NEWLINE);
738 vty_out (vty, "connected %d%s", 0, VTY_NEWLINE);
739 vty_out (vty, "static %d%s", 0, VTY_NEWLINE);
740 vty_out (vty, "rip %d%s", 0, VTY_NEWLINE);
742 vty_out (vty, "bgp %d%s", 0, VTY_NEWLINE);
743 vty_out (vty, " External: %d Internal: %d Local: %d%s",
744 0, 0, 0, VTY_NEWLINE);
746 vty_out (vty, "ospf %d%s", 0, VTY_NEWLINE);
747 vty_out (vty,
748 " Intra-area: %d Inter-area: %d External-1: %d External-2: %d%s",
749 0, 0, 0, 0, VTY_NEWLINE);
750 vty_out (vty, " NSSA External-1: %d NSSA External-2: %d%s",
751 0, 0, VTY_NEWLINE);
753 vty_out (vty, "internal %d%s", 0, VTY_NEWLINE);
754 vty_out (vty, "Total %d%s", 0, VTY_NEWLINE);
757 /* Show route summary. */
758 DEFUN (show_ip_route_summary,
759 show_ip_route_summary_cmd,
760 "show ip route summary",
761 SHOW_STR
762 IP_STR
763 "IP routing table\n"
764 "Summary of all routes\n")
766 struct vrf *vrf;
768 /* Default table id is zero. */
769 vrf = vrf_lookup (0);
770 if (! vrf)
772 vty_out (vty, "%% No Default-IP-Routing-Table%s", VTY_NEWLINE);
773 return CMD_WARNING;
776 zebra_show_ip_route (vty, vrf);
778 return CMD_SUCCESS;
781 /* Write IPv4 static route configuration. */
783 static_config_ipv4 (struct vty *vty)
785 struct route_node *rn;
786 struct static_ipv4 *si;
787 struct route_table *stable;
788 int write;
790 write = 0;
792 /* Lookup table. */
793 stable = vrf_static_table (AFI_IP, SAFI_UNICAST, 0);
794 if (! stable)
795 return -1;
797 for (rn = route_top (stable); rn; rn = route_next (rn))
798 for (si = rn->info; si; si = si->next)
800 vty_out (vty, "ip route %s/%d", inet_ntoa (rn->p.u.prefix4),
801 rn->p.prefixlen);
803 switch (si->type)
805 case STATIC_IPV4_GATEWAY:
806 vty_out (vty, " %s", inet_ntoa (si->gate.ipv4));
807 break;
808 case STATIC_IPV4_IFNAME:
809 vty_out (vty, " %s", si->gate.ifname);
810 break;
811 case STATIC_IPV4_BLACKHOLE:
812 vty_out (vty, " Null0");
813 break;
816 if (si->distance != ZEBRA_STATIC_DISTANCE_DEFAULT)
817 vty_out (vty, " %d", si->distance);
818 vty_out (vty, "%s", VTY_NEWLINE);
820 write = 1;
822 return write;
825 #ifdef HAVE_IPV6
826 /* General fucntion for IPv6 static route. */
828 static_ipv6_func (struct vty *vty, int add_cmd, char *dest_str,
829 char *gate_str, char *ifname, char *distance_str)
831 int ret;
832 u_char distance;
833 struct prefix p;
834 struct in6_addr *gate = NULL;
835 struct in6_addr gate_addr;
836 u_char type = 0;
837 int table = 0;
839 ret = str2prefix (dest_str, &p);
840 if (ret <= 0)
842 vty_out (vty, "%% Malformed address%s", VTY_NEWLINE);
843 return CMD_WARNING;
846 /* Apply mask for given prefix. */
847 apply_mask (&p);
849 /* Administrative distance. */
850 if (distance_str)
851 distance = atoi (distance_str);
852 else
853 distance = ZEBRA_STATIC_DISTANCE_DEFAULT;
855 /* Null0 static route. */
856 if (strncasecmp (gate_str, "Null0", strlen (gate_str)) == 0)
858 type = STATIC_IPV6_BLACKHOLE;
859 if (add_cmd)
860 static_add_ipv6 (&p, type, NULL, NULL, distance, 0);
861 else
862 static_delete_ipv6 (&p, type, NULL, NULL, distance, 0);
863 return CMD_SUCCESS;
866 /* When gateway is valid IPv6 addrees, then gate is treated as
867 nexthop address other case gate is treated as interface name. */
868 ret = inet_pton (AF_INET6, gate_str, &gate_addr);
870 if (ifname)
872 /* When ifname is specified. It must be come with gateway
873 address. */
874 if (ret != 1)
876 vty_out (vty, "%% Malformed address%s", VTY_NEWLINE);
877 return CMD_WARNING;
879 type = STATIC_IPV6_GATEWAY_IFNAME;
880 gate = &gate_addr;
882 else
884 if (ret == 1)
886 type = STATIC_IPV6_GATEWAY;
887 gate = &gate_addr;
889 else
891 type = STATIC_IPV6_IFNAME;
892 ifname = gate_str;
896 if (add_cmd)
897 static_add_ipv6 (&p, type, gate, ifname, distance, table);
898 else
899 static_delete_ipv6 (&p, type, gate, ifname, distance, table);
901 return CMD_SUCCESS;
904 DEFUN (ipv6_route,
905 ipv6_route_cmd,
906 "ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE|null0)",
907 IP_STR
908 "Establish static routes\n"
909 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
910 "IPv6 gateway address\n"
911 "IPv6 gateway interface name\n")
913 return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, NULL);
916 DEFUN (ipv6_route_ifname,
917 ipv6_route_ifname_cmd,
918 "ipv6 route X:X::X:X/M X:X::X:X INTERFACE",
919 IP_STR
920 "Establish static routes\n"
921 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
922 "IPv6 gateway address\n"
923 "IPv6 gateway interface name\n")
925 return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], NULL);
928 DEFUN (ipv6_route_pref,
929 ipv6_route_pref_cmd,
930 "ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE|null0) <1-255>",
931 IP_STR
932 "Establish static routes\n"
933 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
934 "IPv6 gateway address\n"
935 "IPv6 gateway interface name\n"
936 "Distance value for this prefix\n")
938 return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, argv[2]);
941 DEFUN (ipv6_route_ifname_pref,
942 ipv6_route_ifname_pref_cmd,
943 "ipv6 route X:X::X:X/M X:X::X:X INTERFACE <1-255>",
944 IP_STR
945 "Establish static routes\n"
946 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
947 "IPv6 gateway address\n"
948 "IPv6 gateway interface name\n"
949 "Distance value for this prefix\n")
951 return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], argv[3]);
954 DEFUN (no_ipv6_route,
955 no_ipv6_route_cmd,
956 "no ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE|null0)",
957 NO_STR
958 IP_STR
959 "Establish static routes\n"
960 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
961 "IPv6 gateway address\n"
962 "IPv6 gateway interface name\n")
964 return static_ipv6_func (vty, 0, argv[0], argv[1], NULL, NULL);
967 DEFUN (no_ipv6_route_ifname,
968 no_ipv6_route_ifname_cmd,
969 "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE",
970 NO_STR
971 IP_STR
972 "Establish static routes\n"
973 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
974 "IPv6 gateway address\n"
975 "IPv6 gateway interface name\n")
977 return static_ipv6_func (vty, 0, argv[0], argv[1], argv[2], NULL);
980 DEFUN (no_ipv6_route_pref,
981 no_ipv6_route_pref_cmd,
982 "no ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE|null0) <1-255>",
983 NO_STR
984 IP_STR
985 "Establish static routes\n"
986 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
987 "IPv6 gateway address\n"
988 "IPv6 gateway interface name\n"
989 "Distance value for this prefix\n")
991 return static_ipv6_func (vty, 0, argv[0], argv[1], NULL, argv[2]);
994 DEFUN (no_ipv6_route_ifname_pref,
995 no_ipv6_route_ifname_pref_cmd,
996 "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE <1-255>",
997 NO_STR
998 IP_STR
999 "Establish static routes\n"
1000 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1001 "IPv6 gateway address\n"
1002 "IPv6 gateway interface name\n"
1003 "Distance value for this prefix\n")
1005 return static_ipv6_func (vty, 0, argv[0], argv[1], argv[2], argv[3]);
1008 /* New RIB. Detailed information for IPv6 route. */
1009 void
1010 vty_show_ipv6_route_detail (struct vty *vty, struct route_node *rn)
1012 struct rib *rib;
1013 struct nexthop *nexthop;
1014 char buf[BUFSIZ];
1016 for (rib = rn->info; rib; rib = rib->next)
1018 vty_out (vty, "Routing entry for %s/%d%s",
1019 inet_ntop (AF_INET6, &rn->p.u.prefix6, buf, BUFSIZ),
1020 rn->p.prefixlen,
1021 VTY_NEWLINE);
1022 vty_out (vty, " Known via \"%s\"", route_type_str (rib->type));
1023 vty_out (vty, ", distance %d, metric %d", rib->distance, rib->metric);
1024 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
1025 vty_out (vty, ", best");
1026 if (rib->refcnt)
1027 vty_out (vty, ", refcnt %ld", rib->refcnt);
1028 vty_out (vty, "%s", VTY_NEWLINE);
1030 #define ONE_DAY_SECOND 60*60*24
1031 #define ONE_WEEK_SECOND 60*60*24*7
1032 if (rib->type == ZEBRA_ROUTE_RIPNG
1033 || rib->type == ZEBRA_ROUTE_OSPF6
1034 || rib->type == ZEBRA_ROUTE_BGP)
1036 time_t uptime;
1037 struct tm *tm;
1039 uptime = time (NULL);
1040 uptime -= rib->uptime;
1041 tm = gmtime (&uptime);
1043 vty_out (vty, " Last update ");
1045 if (uptime < ONE_DAY_SECOND)
1046 vty_out (vty, "%02d:%02d:%02d",
1047 tm->tm_hour, tm->tm_min, tm->tm_sec);
1048 else if (uptime < ONE_WEEK_SECOND)
1049 vty_out (vty, "%dd%02dh%02dm",
1050 tm->tm_yday, tm->tm_hour, tm->tm_min);
1051 else
1052 vty_out (vty, "%02dw%dd%02dh",
1053 tm->tm_yday/7,
1054 tm->tm_yday - ((tm->tm_yday/7) * 7), tm->tm_hour);
1055 vty_out (vty, " ago%s", VTY_NEWLINE);
1058 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1060 vty_out (vty, " %c",
1061 CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB) ? '*' : ' ');
1063 switch (nexthop->type)
1065 case NEXTHOP_TYPE_IPV6:
1066 case NEXTHOP_TYPE_IPV6_IFINDEX:
1067 case NEXTHOP_TYPE_IPV6_IFNAME:
1068 vty_out (vty, " %s",
1069 inet_ntop (AF_INET6, &nexthop->gate.ipv6, buf, BUFSIZ));
1070 if (nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME)
1071 vty_out (vty, ", %s", nexthop->ifname);
1072 else if (nexthop->ifindex)
1073 vty_out (vty, ", via %s", ifindex2ifname (nexthop->ifindex));
1074 break;
1075 case NEXTHOP_TYPE_IFINDEX:
1076 vty_out (vty, " directly connected, %s",
1077 ifindex2ifname (nexthop->ifindex));
1078 break;
1079 case NEXTHOP_TYPE_IFNAME:
1080 vty_out (vty, " directly connected, %s",
1081 nexthop->ifname);
1082 break;
1083 case NEXTHOP_TYPE_BLACKHOLE:
1084 vty_out (vty, " directly connected, via Null0");
1085 break;
1086 default:
1087 break;
1089 if (! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
1090 vty_out (vty, " inactive");
1092 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
1094 vty_out (vty, " (recursive");
1096 switch (nexthop->rtype)
1098 case NEXTHOP_TYPE_IPV6:
1099 case NEXTHOP_TYPE_IPV6_IFINDEX:
1100 case NEXTHOP_TYPE_IPV6_IFNAME:
1101 vty_out (vty, " via %s)",
1102 inet_ntop (AF_INET6, &nexthop->rgate.ipv6,
1103 buf, BUFSIZ));
1104 if (nexthop->rifindex)
1105 vty_out (vty, ", %s", ifindex2ifname (nexthop->rifindex));
1106 break;
1107 case NEXTHOP_TYPE_IFINDEX:
1108 case NEXTHOP_TYPE_IFNAME:
1109 vty_out (vty, " is directly connected, %s)",
1110 ifindex2ifname (nexthop->rifindex));
1111 break;
1112 default:
1113 break;
1116 vty_out (vty, "%s", VTY_NEWLINE);
1118 vty_out (vty, "%s", VTY_NEWLINE);
1122 void
1123 vty_show_ipv6_route (struct vty *vty, struct route_node *rn,
1124 struct rib *rib)
1126 struct nexthop *nexthop;
1127 int len = 0;
1128 char buf[BUFSIZ];
1130 /* Nexthop information. */
1131 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1133 if (nexthop == rib->nexthop)
1135 /* Prefix information. */
1136 len = vty_out (vty, "%c%c%c %s/%d",
1137 route_type_char (rib->type),
1138 CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED)
1139 ? '>' : ' ',
1140 CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)
1141 ? '*' : ' ',
1142 inet_ntop (AF_INET6, &rn->p.u.prefix6, buf, BUFSIZ),
1143 rn->p.prefixlen);
1145 /* Distance and metric display. */
1146 if (rib->type != ZEBRA_ROUTE_CONNECT
1147 && rib->type != ZEBRA_ROUTE_KERNEL)
1148 len += vty_out (vty, " [%d/%d]", rib->distance,
1149 rib->metric);
1151 else
1152 vty_out (vty, " %c%*c",
1153 CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)
1154 ? '*' : ' ',
1155 len - 3, ' ');
1157 switch (nexthop->type)
1159 case NEXTHOP_TYPE_IPV6:
1160 case NEXTHOP_TYPE_IPV6_IFINDEX:
1161 case NEXTHOP_TYPE_IPV6_IFNAME:
1162 vty_out (vty, " via %s",
1163 inet_ntop (AF_INET6, &nexthop->gate.ipv6, buf, BUFSIZ));
1164 if (nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME)
1165 vty_out (vty, ", %s", nexthop->ifname);
1166 else if (nexthop->ifindex)
1167 vty_out (vty, ", %s", ifindex2ifname (nexthop->ifindex));
1168 break;
1169 case NEXTHOP_TYPE_IFINDEX:
1170 vty_out (vty, " is directly connected, %s",
1171 ifindex2ifname (nexthop->ifindex));
1172 break;
1173 case NEXTHOP_TYPE_IFNAME:
1174 vty_out (vty, " is directly connected, %s",
1175 nexthop->ifname);
1176 break;
1177 case NEXTHOP_TYPE_BLACKHOLE:
1178 vty_out (vty, " is directly connected, Null0");
1179 default:
1180 break;
1182 if (! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
1183 vty_out (vty, " inactive");
1185 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
1187 vty_out (vty, " (recursive");
1189 switch (nexthop->rtype)
1191 case NEXTHOP_TYPE_IPV6:
1192 case NEXTHOP_TYPE_IPV6_IFINDEX:
1193 case NEXTHOP_TYPE_IPV6_IFNAME:
1194 vty_out (vty, " via %s)",
1195 inet_ntop (AF_INET6, &nexthop->rgate.ipv6,
1196 buf, BUFSIZ));
1197 if (nexthop->rifindex)
1198 vty_out (vty, ", %s", ifindex2ifname (nexthop->rifindex));
1199 break;
1200 case NEXTHOP_TYPE_IFINDEX:
1201 case NEXTHOP_TYPE_IFNAME:
1202 vty_out (vty, " is directly connected, %s)",
1203 ifindex2ifname (nexthop->rifindex));
1204 break;
1205 default:
1206 break;
1210 if (rib->type == ZEBRA_ROUTE_RIPNG
1211 || rib->type == ZEBRA_ROUTE_OSPF6
1212 || rib->type == ZEBRA_ROUTE_BGP)
1214 time_t uptime;
1215 struct tm *tm;
1217 uptime = time (NULL);
1218 uptime -= rib->uptime;
1219 tm = gmtime (&uptime);
1221 #define ONE_DAY_SECOND 60*60*24
1222 #define ONE_WEEK_SECOND 60*60*24*7
1224 if (uptime < ONE_DAY_SECOND)
1225 vty_out (vty, ", %02d:%02d:%02d",
1226 tm->tm_hour, tm->tm_min, tm->tm_sec);
1227 else if (uptime < ONE_WEEK_SECOND)
1228 vty_out (vty, ", %dd%02dh%02dm",
1229 tm->tm_yday, tm->tm_hour, tm->tm_min);
1230 else
1231 vty_out (vty, ", %02dw%dd%02dh",
1232 tm->tm_yday/7,
1233 tm->tm_yday - ((tm->tm_yday/7) * 7), tm->tm_hour);
1235 vty_out (vty, "%s", VTY_NEWLINE);
1239 #define SHOW_ROUTE_V6_HEADER "Codes: K - kernel route, C - connected, S - static, R - RIPng, O - OSPFv3,%s B - BGP, * - FIB route.%s%s"
1241 DEFUN (show_ipv6_route,
1242 show_ipv6_route_cmd,
1243 "show ipv6 route",
1244 SHOW_STR
1245 IP_STR
1246 "IPv6 routing table\n")
1248 struct route_table *table;
1249 struct route_node *rn;
1250 struct rib *rib;
1251 int first = 1;
1253 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
1254 if (! table)
1255 return CMD_SUCCESS;
1257 /* Show all IPv6 route. */
1258 for (rn = route_top (table); rn; rn = route_next (rn))
1259 for (rib = rn->info; rib; rib = rib->next)
1261 if (first)
1263 vty_out (vty, SHOW_ROUTE_V6_HEADER, VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE);
1264 first = 0;
1266 vty_show_ipv6_route (vty, rn, rib);
1268 return CMD_SUCCESS;
1271 DEFUN (show_ipv6_route_prefix_longer,
1272 show_ipv6_route_prefix_longer_cmd,
1273 "show ipv6 route X:X::X:X/M longer-prefixes",
1274 SHOW_STR
1275 IP_STR
1276 "IPv6 routing table\n"
1277 "IPv6 prefix\n"
1278 "Show route matching the specified Network/Mask pair only\n")
1280 struct route_table *table;
1281 struct route_node *rn;
1282 struct rib *rib;
1283 struct prefix p;
1284 int ret;
1285 int first = 1;
1287 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
1288 if (! table)
1289 return CMD_SUCCESS;
1291 ret = str2prefix (argv[0], &p);
1292 if (! ret)
1294 vty_out (vty, "%% Malformed Prefix%s", VTY_NEWLINE);
1295 return CMD_WARNING;
1298 /* Show matched type IPv6 routes. */
1299 for (rn = route_top (table); rn; rn = route_next (rn))
1300 for (rib = rn->info; rib; rib = rib->next)
1301 if (prefix_match (&p, &rn->p))
1303 if (first)
1305 vty_out (vty, SHOW_ROUTE_V6_HEADER, VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE);
1306 first = 0;
1308 vty_show_ipv6_route (vty, rn, rib);
1310 return CMD_SUCCESS;
1313 DEFUN (show_ipv6_route_protocol,
1314 show_ipv6_route_protocol_cmd,
1315 "show ipv6 route (bgp|connected|kernel|ospf6|ripng|static)",
1316 SHOW_STR
1317 IP_STR
1318 "IP routing table\n"
1319 "Border Gateway Protocol (BGP)\n"
1320 "Connected\n"
1321 "Kernel\n"
1322 "Open Shortest Path First (OSPFv3)\n"
1323 "Routing Information Protocol (RIPng)\n"
1324 "Static routes\n")
1326 int type;
1327 struct route_table *table;
1328 struct route_node *rn;
1329 struct rib *rib;
1330 int first = 1;
1332 if (strncmp (argv[0], "b", 1) == 0)
1333 type = ZEBRA_ROUTE_BGP;
1334 else if (strncmp (argv[0], "c", 1) == 0)
1335 type = ZEBRA_ROUTE_CONNECT;
1336 else if (strncmp (argv[0], "k", 1) ==0)
1337 type = ZEBRA_ROUTE_KERNEL;
1338 else if (strncmp (argv[0], "o", 1) == 0)
1339 type = ZEBRA_ROUTE_OSPF6;
1340 else if (strncmp (argv[0], "r", 1) == 0)
1341 type = ZEBRA_ROUTE_RIPNG;
1342 else if (strncmp (argv[0], "s", 1) == 0)
1343 type = ZEBRA_ROUTE_STATIC;
1344 else
1346 vty_out (vty, "Unknown route type%s", VTY_NEWLINE);
1347 return CMD_WARNING;
1350 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
1351 if (! table)
1352 return CMD_SUCCESS;
1354 /* Show matched type IPv6 routes. */
1355 for (rn = route_top (table); rn; rn = route_next (rn))
1356 for (rib = rn->info; rib; rib = rib->next)
1357 if (rib->type == type)
1359 if (first)
1361 vty_out (vty, SHOW_ROUTE_V6_HEADER, VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE);
1362 first = 0;
1364 vty_show_ipv6_route (vty, rn, rib);
1366 return CMD_SUCCESS;
1369 DEFUN (show_ipv6_route_addr,
1370 show_ipv6_route_addr_cmd,
1371 "show ipv6 route X:X::X:X",
1372 SHOW_STR
1373 IP_STR
1374 "IPv6 routing table\n"
1375 "IPv6 Address\n")
1377 int ret;
1378 struct prefix_ipv6 p;
1379 struct route_table *table;
1380 struct route_node *rn;
1382 ret = str2prefix_ipv6 (argv[0], &p);
1383 if (ret <= 0)
1385 vty_out (vty, "Malformed IPv6 address%s", VTY_NEWLINE);
1386 return CMD_WARNING;
1389 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
1390 if (! table)
1391 return CMD_SUCCESS;
1393 rn = route_node_match (table, (struct prefix *) &p);
1394 if (! rn)
1396 vty_out (vty, "%% Network not in table%s", VTY_NEWLINE);
1397 return CMD_WARNING;
1400 vty_show_ipv6_route_detail (vty, rn);
1402 route_unlock_node (rn);
1404 return CMD_SUCCESS;
1407 DEFUN (show_ipv6_route_prefix,
1408 show_ipv6_route_prefix_cmd,
1409 "show ipv6 route X:X::X:X/M",
1410 SHOW_STR
1411 IP_STR
1412 "IPv6 routing table\n"
1413 "IPv6 prefix\n")
1415 int ret;
1416 struct prefix_ipv6 p;
1417 struct route_table *table;
1418 struct route_node *rn;
1420 ret = str2prefix_ipv6 (argv[0], &p);
1421 if (ret <= 0)
1423 vty_out (vty, "Malformed IPv6 prefix%s", VTY_NEWLINE);
1424 return CMD_WARNING;
1427 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
1428 if (! table)
1429 return CMD_SUCCESS;
1431 rn = route_node_match (table, (struct prefix *) &p);
1432 if (! rn || rn->p.prefixlen != p.prefixlen)
1434 vty_out (vty, "%% Network not in table%s", VTY_NEWLINE);
1435 return CMD_WARNING;
1438 vty_show_ipv6_route_detail (vty, rn);
1440 route_unlock_node (rn);
1442 return CMD_SUCCESS;
1446 /* Write IPv6 static route configuration. */
1448 static_config_ipv6 (struct vty *vty)
1450 struct route_node *rn;
1451 struct static_ipv6 *si;
1452 int write;
1453 char buf[BUFSIZ];
1454 struct route_table *stable;
1456 write = 0;
1458 /* Lookup table. */
1459 stable = vrf_static_table (AFI_IP6, SAFI_UNICAST, 0);
1460 if (! stable)
1461 return -1;
1463 for (rn = route_top (stable); rn; rn = route_next (rn))
1464 for (si = rn->info; si; si = si->next)
1466 vty_out (vty, "ipv6 route %s/%d",
1467 inet_ntop (AF_INET6, &rn->p.u.prefix6, buf, BUFSIZ),
1468 rn->p.prefixlen);
1470 switch (si->type)
1472 case STATIC_IPV6_GATEWAY:
1473 vty_out (vty, " %s", inet_ntop (AF_INET6, &si->ipv6, buf, BUFSIZ));
1474 break;
1475 case STATIC_IPV6_IFNAME:
1476 vty_out (vty, " %s", si->ifname);
1477 break;
1478 case STATIC_IPV6_GATEWAY_IFNAME:
1479 vty_out (vty, " %s %s",
1480 inet_ntop (AF_INET6, &si->ipv6, buf, BUFSIZ), si->ifname);
1481 break;
1482 case STATIC_IPV6_BLACKHOLE:
1483 vty_out (vty, " Null0");
1484 break;
1487 if (si->distance != ZEBRA_STATIC_DISTANCE_DEFAULT)
1488 vty_out (vty, " %d", si->distance);
1489 vty_out (vty, "%s", VTY_NEWLINE);
1491 write = 1;
1493 return write;
1495 #endif /* HAVE_IPV6 */
1497 /* Static ip route configuration write function. */
1499 zebra_ip_config (struct vty *vty)
1501 int write = 0;
1503 write += static_config_ipv4 (vty);
1504 #ifdef HAVE_IPV6
1505 write += static_config_ipv6 (vty);
1506 #endif /* HAVE_IPV6 */
1508 return write;
1511 /* IP node for static routes. */
1512 struct cmd_node ip_node = { IP_NODE, "", 1 };
1514 /* Route VTY. */
1515 void
1516 zebra_vty_route_init ()
1518 install_node (&ip_node, zebra_ip_config);
1520 install_element (CONFIG_NODE, &ip_route_cmd);
1521 install_element (CONFIG_NODE, &ip_route_mask_cmd);
1522 install_element (CONFIG_NODE, &no_ip_route_cmd);
1523 install_element (CONFIG_NODE, &no_ip_route_mask_cmd);
1524 install_element (CONFIG_NODE, &ip_route_distance_cmd);
1525 install_element (CONFIG_NODE, &ip_route_mask_distance_cmd);
1526 install_element (CONFIG_NODE, &no_ip_route_distance_cmd);
1527 install_element (CONFIG_NODE, &no_ip_route_mask_distance_cmd);
1529 install_element (VIEW_NODE, &show_ip_route_cmd);
1530 install_element (VIEW_NODE, &show_ip_route_addr_cmd);
1531 install_element (VIEW_NODE, &show_ip_route_prefix_cmd);
1532 install_element (VIEW_NODE, &show_ip_route_prefix_longer_cmd);
1533 install_element (VIEW_NODE, &show_ip_route_protocol_cmd);
1534 install_element (VIEW_NODE, &show_ip_route_supernets_cmd);
1535 install_element (ENABLE_NODE, &show_ip_route_cmd);
1536 install_element (ENABLE_NODE, &show_ip_route_addr_cmd);
1537 install_element (ENABLE_NODE, &show_ip_route_prefix_cmd);
1538 install_element (ENABLE_NODE, &show_ip_route_prefix_longer_cmd);
1539 install_element (ENABLE_NODE, &show_ip_route_protocol_cmd);
1540 install_element (ENABLE_NODE, &show_ip_route_supernets_cmd);
1542 #if 0
1543 install_element (VIEW_NODE, &show_ip_route_summary_cmd);
1544 install_element (ENABLE_NODE, &show_ip_route_summary_cmd);
1545 #endif /* 0 */
1547 #ifdef HAVE_IPV6
1548 install_element (CONFIG_NODE, &ipv6_route_cmd);
1549 install_element (CONFIG_NODE, &ipv6_route_ifname_cmd);
1550 install_element (CONFIG_NODE, &no_ipv6_route_cmd);
1551 install_element (CONFIG_NODE, &no_ipv6_route_ifname_cmd);
1552 install_element (CONFIG_NODE, &ipv6_route_pref_cmd);
1553 install_element (CONFIG_NODE, &ipv6_route_ifname_pref_cmd);
1554 install_element (CONFIG_NODE, &no_ipv6_route_pref_cmd);
1555 install_element (CONFIG_NODE, &no_ipv6_route_ifname_pref_cmd);
1556 install_element (VIEW_NODE, &show_ipv6_route_cmd);
1557 install_element (VIEW_NODE, &show_ipv6_route_protocol_cmd);
1558 install_element (VIEW_NODE, &show_ipv6_route_addr_cmd);
1559 install_element (VIEW_NODE, &show_ipv6_route_prefix_cmd);
1560 install_element (VIEW_NODE, &show_ipv6_route_prefix_longer_cmd);
1561 install_element (ENABLE_NODE, &show_ipv6_route_cmd);
1562 install_element (ENABLE_NODE, &show_ipv6_route_protocol_cmd);
1563 install_element (ENABLE_NODE, &show_ipv6_route_addr_cmd);
1564 install_element (ENABLE_NODE, &show_ipv6_route_prefix_cmd);
1565 install_element (ENABLE_NODE, &show_ipv6_route_prefix_longer_cmd);
1566 #endif /* HAVE_IPV6 */
1569 void
1570 zebra_vty_init ()
1572 zebra_vty_route_init ();