diff options
author | paul <paul> | 2002-12-13 20:15:29 +0000 |
---|---|---|
committer | paul <paul> | 2002-12-13 20:15:29 +0000 |
commit | 85f97d27207a5a29357da0c8a6abe8e48bf8ea2c (patch) | |
tree | d20e362762c4963f1150b224356643bd49df7dfb /zebra/zebra_vty.c | |
download | quagga-85f97d27207a5a29357da0c8a6abe8e48bf8ea2c.tar.bz2 quagga-85f97d27207a5a29357da0c8a6abe8e48bf8ea2c.tar.xz |
Initial revision
Diffstat (limited to 'zebra/zebra_vty.c')
-rw-r--r-- | zebra/zebra_vty.c | 1554 |
1 files changed, 1554 insertions, 0 deletions
diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c new file mode 100644 index 00000000..f6e7f51d --- /dev/null +++ b/zebra/zebra_vty.c @@ -0,0 +1,1554 @@ +/* Zebra VTY functions + * Copyright (C) 2002 Kunihiro Ishiguro + * + * This file is part of GNU Zebra. + * + * GNU Zebra is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * GNU Zebra is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Zebra; see the file COPYING. If not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include <zebra.h> + +#include "if.h" +#include "prefix.h" +#include "command.h" +#include "table.h" +#include "rib.h" + +/* Return route type string for VTY output. */ +const char * +route_type_str (u_char type) +{ + switch (type) + { + case ZEBRA_ROUTE_SYSTEM: + return "system"; + case ZEBRA_ROUTE_KERNEL: + return "kernel"; + case ZEBRA_ROUTE_CONNECT: + return "connected"; + case ZEBRA_ROUTE_STATIC: + return "static"; + case ZEBRA_ROUTE_RIP: + return "rip"; + case ZEBRA_ROUTE_RIPNG: + return "rip"; + case ZEBRA_ROUTE_OSPF: + return "ospf"; + case ZEBRA_ROUTE_OSPF6: + return "ospf"; + case ZEBRA_ROUTE_BGP: + return "bgp"; + default: + return "unknown"; + } +}; + +/* Return route type string for VTY output. */ +const char +route_type_char (u_char type) +{ + switch (type) + { + case ZEBRA_ROUTE_SYSTEM: + return 'S'; + case ZEBRA_ROUTE_KERNEL: + return 'K'; + case ZEBRA_ROUTE_CONNECT: + return 'C'; + case ZEBRA_ROUTE_STATIC: + return 'S'; + case ZEBRA_ROUTE_RIP: + return 'R'; + case ZEBRA_ROUTE_RIPNG: + return 'R'; + case ZEBRA_ROUTE_OSPF: + return 'O'; + case ZEBRA_ROUTE_OSPF6: + return 'O'; + case ZEBRA_ROUTE_BGP: + return 'B'; + default: + return '?'; + } +}; + +/* General fucntion for static route. */ +int +zebra_static_ipv4 (struct vty *vty, int add_cmd, + char *dest_str, char *mask_str, char *gate_str, + char *distance_str) +{ + int ret; + u_char distance; + struct prefix p; + struct in_addr gate; + struct in_addr mask; + char *ifname; + + ret = str2prefix (dest_str, &p); + if (ret <= 0) + { + vty_out (vty, "%% Malformed address%s", VTY_NEWLINE); + return CMD_WARNING; + } + + /* Cisco like mask notation. */ + if (mask_str) + { + ret = inet_aton (mask_str, &mask); + if (ret == 0) + { + vty_out (vty, "%% Malformed address%s", VTY_NEWLINE); + return CMD_WARNING; + } + p.prefixlen = ip_masklen (mask); + } + + /* Apply mask for given prefix. */ + apply_mask (&p); + + /* Administrative distance. */ + if (distance_str) + distance = atoi (distance_str); + else + distance = ZEBRA_STATIC_DISTANCE_DEFAULT; + + /* Null0 static route. */ + if (strncasecmp (gate_str, "Null0", strlen (gate_str)) == 0) + { + if (add_cmd) + static_add_ipv4 (&p, NULL, NULL, distance, 0); + else + static_delete_ipv4 (&p, NULL, NULL, distance, 0); + return CMD_SUCCESS; + } + + /* When gateway is A.B.C.D format, gate is treated as nexthop + address other case gate is treated as interface name. */ + ret = inet_aton (gate_str, &gate); + if (ret) + ifname = NULL; + else + ifname = gate_str; + + if (add_cmd) + static_add_ipv4 (&p, ifname ? NULL : &gate, ifname, distance, 0); + else + static_delete_ipv4 (&p, ifname ? NULL : &gate, ifname, distance, 0); + + return CMD_SUCCESS; +} + +/* Static route configuration. */ +DEFUN (ip_route, + ip_route_cmd, + "ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0)", + IP_STR + "Establish static routes\n" + "IP destination prefix (e.g. 10.0.0.0/8)\n" + "IP gateway address\n" + "IP gateway interface name\n" + "Null interface\n") +{ + return zebra_static_ipv4 (vty, 1, argv[0], NULL, argv[1], NULL); +} + +/* Mask as A.B.C.D format. */ +DEFUN (ip_route_mask, + ip_route_mask_cmd, + "ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0)", + IP_STR + "Establish static routes\n" + "IP destination prefix\n" + "IP destination prefix mask\n" + "IP gateway address\n" + "IP gateway interface name\n" + "Null interface\n") +{ + return zebra_static_ipv4 (vty, 1, argv[0], argv[1], argv[2], NULL); +} + +/* Distance option value. */ +DEFUN (ip_route_distance, + ip_route_distance_cmd, + "ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0) <1-255>", + IP_STR + "Establish static routes\n" + "IP destination prefix (e.g. 10.0.0.0/8)\n" + "IP gateway address\n" + "IP gateway interface name\n" + "Null interface\n" + "Distance value for this route\n") +{ + return zebra_static_ipv4 (vty, 1, argv[0], NULL, argv[1], argv[2]); +} + +DEFUN (ip_route_mask_distance, + ip_route_mask_distance_cmd, + "ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0) <1-255>", + IP_STR + "Establish static routes\n" + "IP destination prefix\n" + "IP destination prefix mask\n" + "IP gateway address\n" + "IP gateway interface name\n" + "Null interface\n" + "Distance value for this route\n") +{ + return zebra_static_ipv4 (vty, 1, argv[0], argv[1], argv[2], argv[3]); +} + +DEFUN (no_ip_route, + no_ip_route_cmd, + "no ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0)", + NO_STR + IP_STR + "Establish static routes\n" + "IP destination prefix (e.g. 10.0.0.0/8)\n" + "IP gateway address\n" + "IP gateway interface name\n" + "Null interface\n") +{ + return zebra_static_ipv4 (vty, 0, argv[0], NULL, argv[1], NULL); +} + +DEFUN (no_ip_route_mask, + no_ip_route_mask_cmd, + "no ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0)", + NO_STR + IP_STR + "Establish static routes\n" + "IP destination prefix\n" + "IP destination prefix mask\n" + "IP gateway address\n" + "IP gateway interface name\n" + "Null interface\n") +{ + return zebra_static_ipv4 (vty, 0, argv[0], argv[1], argv[2], NULL); +} + +DEFUN (no_ip_route_distance, + no_ip_route_distance_cmd, + "no ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0) <1-255>", + NO_STR + IP_STR + "Establish static routes\n" + "IP destination prefix (e.g. 10.0.0.0/8)\n" + "IP gateway address\n" + "IP gateway interface name\n" + "Null interface\n" + "Distance value for this route\n") +{ + return zebra_static_ipv4 (vty, 0, argv[0], NULL, argv[1], argv[2]); +} + +DEFUN (no_ip_route_mask_distance, + no_ip_route_mask_distance_cmd, + "no ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0) <1-255>", + NO_STR + IP_STR + "Establish static routes\n" + "IP destination prefix\n" + "IP destination prefix mask\n" + "IP gateway address\n" + "IP gateway interface name\n" + "Null interface\n" + "Distance value for this route\n") +{ + return zebra_static_ipv4 (vty, 0, argv[0], argv[1], argv[2], argv[3]); +} + +/* New RIB. Detailed information for IPv4 route. */ +void +vty_show_ip_route_detail (struct vty *vty, struct route_node *rn) +{ + struct rib *rib; + struct nexthop *nexthop; + + for (rib = rn->info; rib; rib = rib->next) + { + vty_out (vty, "Routing entry for %s/%d%s", + inet_ntoa (rn->p.u.prefix4), rn->p.prefixlen, + VTY_NEWLINE); + vty_out (vty, " Known via \"%s\"", route_type_str (rib->type)); + vty_out (vty, ", distance %d, metric %d", rib->distance, rib->metric); + if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED)) + vty_out (vty, ", best"); + if (rib->refcnt) + vty_out (vty, ", refcnt %ld", rib->refcnt); + vty_out (vty, "%s", VTY_NEWLINE); + +#define ONE_DAY_SECOND 60*60*24 +#define ONE_WEEK_SECOND 60*60*24*7 + if (rib->type == ZEBRA_ROUTE_RIP + || rib->type == ZEBRA_ROUTE_OSPF + || rib->type == ZEBRA_ROUTE_BGP) + { + time_t uptime; + struct tm *tm; + + uptime = time (NULL); + uptime -= rib->uptime; + tm = gmtime (&uptime); + + vty_out (vty, " Last update "); + + if (uptime < ONE_DAY_SECOND) + vty_out (vty, "%02d:%02d:%02d", + tm->tm_hour, tm->tm_min, tm->tm_sec); + else if (uptime < ONE_WEEK_SECOND) + vty_out (vty, "%dd%02dh%02dm", + tm->tm_yday, tm->tm_hour, tm->tm_min); + else + vty_out (vty, "%02dw%dd%02dh", + tm->tm_yday/7, + tm->tm_yday - ((tm->tm_yday/7) * 7), tm->tm_hour); + vty_out (vty, " ago%s", VTY_NEWLINE); + } + + for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next) + { + vty_out (vty, " %c", + CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB) ? '*' : ' '); + + switch (nexthop->type) + { + case NEXTHOP_TYPE_IPV4: + case NEXTHOP_TYPE_IPV4_IFINDEX: + vty_out (vty, " %s", inet_ntoa (nexthop->gate.ipv4)); + if (nexthop->ifindex) + vty_out (vty, ", via %s", ifindex2ifname (nexthop->ifindex)); + break; + case NEXTHOP_TYPE_IFINDEX: + vty_out (vty, " directly connected, %s", + ifindex2ifname (nexthop->ifindex)); + break; + case NEXTHOP_TYPE_IFNAME: + vty_out (vty, " directly connected, %s", nexthop->ifname); + break; + case NEXTHOP_TYPE_BLACKHOLE: + vty_out (vty, " directly connected, via Null0"); + break; + default: + break; + } + if (! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE)) + vty_out (vty, " inactive"); + + if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE)) + { + vty_out (vty, " (recursive"); + + switch (nexthop->rtype) + { + case NEXTHOP_TYPE_IPV4: + case NEXTHOP_TYPE_IPV4_IFINDEX: + vty_out (vty, " via %s)", inet_ntoa (nexthop->rgate.ipv4)); + break; + case NEXTHOP_TYPE_IFINDEX: + case NEXTHOP_TYPE_IFNAME: + vty_out (vty, " is directly connected, %s)", + ifindex2ifname (nexthop->rifindex)); + break; + default: + break; + } + } + vty_out (vty, "%s", VTY_NEWLINE); + } + vty_out (vty, "%s", VTY_NEWLINE); + } +} + +void +vty_show_ip_route (struct vty *vty, struct route_node *rn, struct rib *rib) +{ + struct nexthop *nexthop; + int len = 0; + char buf[BUFSIZ]; + + /* Nexthop information. */ + for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next) + { + if (nexthop == rib->nexthop) + { + /* Prefix information. */ + len = vty_out (vty, "%c%c%c %s/%d", + route_type_char (rib->type), + CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED) + ? '>' : ' ', + CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB) + ? '*' : ' ', + inet_ntop (AF_INET, &rn->p.u.prefix, buf, BUFSIZ), + rn->p.prefixlen); + + /* Distance and metric display. */ + if (rib->type != ZEBRA_ROUTE_CONNECT + && rib->type != ZEBRA_ROUTE_KERNEL) + len += vty_out (vty, " [%d/%d]", rib->distance, + rib->metric); + } + else + vty_out (vty, " %c%*c", + CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB) + ? '*' : ' ', + len - 3, ' '); + + switch (nexthop->type) + { + case NEXTHOP_TYPE_IPV4: + case NEXTHOP_TYPE_IPV4_IFINDEX: + vty_out (vty, " via %s", inet_ntoa (nexthop->gate.ipv4)); + if (nexthop->ifindex) + vty_out (vty, ", %s", ifindex2ifname (nexthop->ifindex)); + break; + case NEXTHOP_TYPE_IFINDEX: + vty_out (vty, " is directly connected, %s", + ifindex2ifname (nexthop->ifindex)); + break; + case NEXTHOP_TYPE_IFNAME: + vty_out (vty, " is directly connected, %s", nexthop->ifname); + break; + case NEXTHOP_TYPE_BLACKHOLE: + vty_out (vty, " is directly connected, Null0"); + default: + break; + } + if (! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE)) + vty_out (vty, " inactive"); + + if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE)) + { + vty_out (vty, " (recursive"); + + switch (nexthop->rtype) + { + case NEXTHOP_TYPE_IPV4: + case NEXTHOP_TYPE_IPV4_IFINDEX: + vty_out (vty, " via %s)", inet_ntoa (nexthop->rgate.ipv4)); + break; + case NEXTHOP_TYPE_IFINDEX: + case NEXTHOP_TYPE_IFNAME: + vty_out (vty, " is directly connected, %s)", + ifindex2ifname (nexthop->rifindex)); + break; + default: + break; + } + } + + if (rib->type == ZEBRA_ROUTE_RIP + || rib->type == ZEBRA_ROUTE_OSPF + || rib->type == ZEBRA_ROUTE_BGP) + { + time_t uptime; + struct tm *tm; + + uptime = time (NULL); + uptime -= rib->uptime; + tm = gmtime (&uptime); + +#define ONE_DAY_SECOND 60*60*24 +#define ONE_WEEK_SECOND 60*60*24*7 + + if (uptime < ONE_DAY_SECOND) + vty_out (vty, ", %02d:%02d:%02d", + tm->tm_hour, tm->tm_min, tm->tm_sec); + else if (uptime < ONE_WEEK_SECOND) + vty_out (vty, ", %dd%02dh%02dm", + tm->tm_yday, tm->tm_hour, tm->tm_min); + else + vty_out (vty, ", %02dw%dd%02dh", + tm->tm_yday/7, + tm->tm_yday - ((tm->tm_yday/7) * 7), tm->tm_hour); + } + vty_out (vty, "%s", VTY_NEWLINE); + } +} + +#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" + +DEFUN (show_ip_route, + show_ip_route_cmd, + "show ip route", + SHOW_STR + IP_STR + "IP routing table\n") +{ + struct route_table *table; + struct route_node *rn; + struct rib *rib; + int first = 1; + + table = vrf_table (AFI_IP, SAFI_UNICAST, 0); + if (! table) + return CMD_SUCCESS; + + /* Show all IPv4 routes. */ + for (rn = route_top (table); rn; rn = route_next (rn)) + for (rib = rn->info; rib; rib = rib->next) + { + if (first) + { + vty_out (vty, SHOW_ROUTE_V4_HEADER, VTY_NEWLINE, VTY_NEWLINE, + VTY_NEWLINE); + first = 0; + } + vty_show_ip_route (vty, rn, rib); + } + return CMD_SUCCESS; +} + +DEFUN (show_ip_route_prefix_longer, + show_ip_route_prefix_longer_cmd, + "show ip route A.B.C.D/M longer-prefixes", + SHOW_STR + IP_STR + "IP routing table\n" + "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n" + "Show route matching the specified Network/Mask pair only\n") +{ + struct route_table *table; + struct route_node *rn; + struct rib *rib; + struct prefix p; + int ret; + int first = 1; + + ret = str2prefix (argv[0], &p); + if (! ret) + { + vty_out (vty, "%% Malformed Prefix%s", VTY_NEWLINE); + return CMD_WARNING; + } + + table = vrf_table (AFI_IP, SAFI_UNICAST, 0); + if (! table) + return CMD_SUCCESS; + + /* Show matched type IPv4 routes. */ + for (rn = route_top (table); rn; rn = route_next (rn)) + for (rib = rn->info; rib; rib = rib->next) + if (prefix_match (&p, &rn->p)) + { + if (first) + { + vty_out (vty, SHOW_ROUTE_V4_HEADER, VTY_NEWLINE, + VTY_NEWLINE, VTY_NEWLINE); + first = 0; + } + vty_show_ip_route (vty, rn, rib); + } + return CMD_SUCCESS; +} + +DEFUN (show_ip_route_supernets, + show_ip_route_supernets_cmd, + "show ip route supernets-only", + SHOW_STR + IP_STR + "IP routing table\n" + "Show supernet entries only\n") +{ + struct route_table *table; + struct route_node *rn; + struct rib *rib; + u_int32_t addr; + int first = 1; + + table = vrf_table (AFI_IP, SAFI_UNICAST, 0); + if (! table) + return CMD_SUCCESS; + + /* Show matched type IPv4 routes. */ + for (rn = route_top (table); rn; rn = route_next (rn)) + for (rib = rn->info; rib; rib = rib->next) + { + addr = ntohl (rn->p.u.prefix4.s_addr); + + if ((IN_CLASSC (addr) && rn->p.prefixlen < 24) + || (IN_CLASSB (addr) && rn->p.prefixlen < 16) + || (IN_CLASSA (addr) && rn->p.prefixlen < 8)) + { + if (first) + { + vty_out (vty, SHOW_ROUTE_V4_HEADER, VTY_NEWLINE, + VTY_NEWLINE, VTY_NEWLINE); + first = 0; + } + vty_show_ip_route (vty, rn, rib); + } + } + return CMD_SUCCESS; +} + +DEFUN (show_ip_route_protocol, + show_ip_route_protocol_cmd, + "show ip route (bgp|connected|kernel|ospf|rip|static)", + SHOW_STR + IP_STR + "IP routing table\n" + "Border Gateway Protocol (BGP)\n" + "Connected\n" + "Kernel\n" + "Open Shortest Path First (OSPF)\n" + "Routing Information Protocol (RIP)\n" + "Static routes\n") +{ + int type; + struct route_table *table; + struct route_node *rn; + struct rib *rib; + int first = 1; + + if (strncmp (argv[0], "b", 1) == 0) + type = ZEBRA_ROUTE_BGP; + else if (strncmp (argv[0], "c", 1) == 0) + type = ZEBRA_ROUTE_CONNECT; + else if (strncmp (argv[0], "k", 1) ==0) + type = ZEBRA_ROUTE_KERNEL; + else if (strncmp (argv[0], "o", 1) == 0) + type = ZEBRA_ROUTE_OSPF; + else if (strncmp (argv[0], "r", 1) == 0) + type = ZEBRA_ROUTE_RIP; + else if (strncmp (argv[0], "s", 1) == 0) + type = ZEBRA_ROUTE_STATIC; + else + { + vty_out (vty, "Unknown route type%s", VTY_NEWLINE); + return CMD_WARNING; + } + + table = vrf_table (AFI_IP, SAFI_UNICAST, 0); + if (! table) + return CMD_SUCCESS; + + /* Show matched type IPv4 routes. */ + for (rn = route_top (table); rn; rn = route_next (rn)) + for (rib = rn->info; rib; rib = rib->next) + if (rib->type == type) + { + if (first) + { + vty_out (vty, SHOW_ROUTE_V4_HEADER, + VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE); + first = 0; + } + vty_show_ip_route (vty, rn, rib); + } + return CMD_SUCCESS; +} + +DEFUN (show_ip_route_addr, + show_ip_route_addr_cmd, + "show ip route A.B.C.D", + SHOW_STR + IP_STR + "IP routing table\n" + "Network in the IP routing table to display\n") +{ + int ret; + struct prefix_ipv4 p; + struct route_table *table; + struct route_node *rn; + + ret = str2prefix_ipv4 (argv[0], &p); + if (ret <= 0) + { + vty_out (vty, "%% Malformed IPv4 address%s", VTY_NEWLINE); + return CMD_WARNING; + } + + table = vrf_table (AFI_IP, SAFI_UNICAST, 0); + if (! table) + return CMD_SUCCESS; + + rn = route_node_match (table, (struct prefix *) &p); + if (! rn) + { + vty_out (vty, "%% Network not in table%s", VTY_NEWLINE); + return CMD_WARNING; + } + + vty_show_ip_route_detail (vty, rn); + + route_unlock_node (rn); + + return CMD_SUCCESS; +} + +DEFUN (show_ip_route_prefix, + show_ip_route_prefix_cmd, + "show ip route A.B.C.D/M", + SHOW_STR + IP_STR + "IP routing table\n" + "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n") +{ + int ret; + struct prefix_ipv4 p; + struct route_table *table; + struct route_node *rn; + + ret = str2prefix_ipv4 (argv[0], &p); + if (ret <= 0) + { + vty_out (vty, "%% Malformed IPv4 address%s", VTY_NEWLINE); + return CMD_WARNING; + } + + table = vrf_table (AFI_IP, SAFI_UNICAST, 0); + if (! table) + return CMD_SUCCESS; + + rn = route_node_match (table, (struct prefix *) &p); + if (! rn || rn->p.prefixlen != p.prefixlen) + { + vty_out (vty, "%% Network not in table%s", VTY_NEWLINE); + return CMD_WARNING; + } + + vty_show_ip_route_detail (vty, rn); + + route_unlock_node (rn); + + return CMD_SUCCESS; +} + +void +zebra_show_ip_route (struct vty *vty, struct vrf *vrf) +{ + vty_out (vty, "IP routing table name is %s(%d)%s", + vrf->name ? vrf->name : "", vrf->id, VTY_NEWLINE); + + vty_out (vty, "Route Source Networks%s", VTY_NEWLINE); + vty_out (vty, "connected %d%s", 0, VTY_NEWLINE); + vty_out (vty, "static %d%s", 0, VTY_NEWLINE); + vty_out (vty, "rip %d%s", 0, VTY_NEWLINE); + + vty_out (vty, "bgp %d%s", 0, VTY_NEWLINE); + vty_out (vty, " External: %d Internal: %d Local: %d%s", + 0, 0, 0, VTY_NEWLINE); + + vty_out (vty, "ospf %d%s", 0, VTY_NEWLINE); + vty_out (vty, + " Intra-area: %d Inter-area: %d External-1: %d External-2: %d%s", + 0, 0, 0, 0, VTY_NEWLINE); + vty_out (vty, " NSSA External-1: %d NSSA External-2: %d%s", + 0, 0, VTY_NEWLINE); + + vty_out (vty, "internal %d%s", 0, VTY_NEWLINE); + vty_out (vty, "Total %d%s", 0, VTY_NEWLINE); +} + +/* Show route summary. */ +DEFUN (show_ip_route_summary, + show_ip_route_summary_cmd, + "show ip route summary", + SHOW_STR + IP_STR + "IP routing table\n" + "Summary of all routes\n") +{ + struct vrf *vrf; + + /* Default table id is zero. */ + vrf = vrf_lookup (0); + if (! vrf) + { + vty_out (vty, "%% No Default-IP-Routing-Table%s", VTY_NEWLINE); + return CMD_WARNING; + } + + zebra_show_ip_route (vty, vrf); + + return CMD_SUCCESS; +} + +/* Write IPv4 static route configuration. */ +int +static_config_ipv4 (struct vty *vty) +{ + struct route_node *rn; + struct static_ipv4 *si; + struct route_table *stable; + int write; + + write = 0; + + /* Lookup table. */ + stable = vrf_static_table (AFI_IP, SAFI_UNICAST, 0); + if (! stable) + return -1; + + for (rn = route_top (stable); rn; rn = route_next (rn)) + for (si = rn->info; si; si = si->next) + { + vty_out (vty, "ip route %s/%d", inet_ntoa (rn->p.u.prefix4), + rn->p.prefixlen); + + switch (si->type) + { + case STATIC_IPV4_GATEWAY: + vty_out (vty, " %s", inet_ntoa (si->gate.ipv4)); + break; + case STATIC_IPV4_IFNAME: + vty_out (vty, " %s", si->gate.ifname); + break; + case STATIC_IPV4_BLACKHOLE: + vty_out (vty, " Null0"); + break; + } + + if (si->distance != ZEBRA_STATIC_DISTANCE_DEFAULT) + vty_out (vty, " %d", si->distance); + vty_out (vty, "%s", VTY_NEWLINE); + + write = 1; + } + return write; +} + +#ifdef HAVE_IPV6 +/* General fucntion for IPv6 static route. */ +int +static_ipv6_func (struct vty *vty, int add_cmd, char *dest_str, + char *gate_str, char *ifname, char *distance_str) +{ + int ret; + u_char distance; + struct prefix p; + struct in6_addr *gate = NULL; + struct in6_addr gate_addr; + u_char type = 0; + int table = 0; + + ret = str2prefix (dest_str, &p); + if (ret <= 0) + { + vty_out (vty, "%% Malformed address%s", VTY_NEWLINE); + return CMD_WARNING; + } + + /* Apply mask for given prefix. */ + apply_mask (&p); + + /* Administrative distance. */ + if (distance_str) + distance = atoi (distance_str); + else + distance = ZEBRA_STATIC_DISTANCE_DEFAULT; + + /* When gateway is valid IPv6 addrees, then gate is treated as + nexthop address other case gate is treated as interface name. */ + ret = inet_pton (AF_INET6, gate_str, &gate_addr); + + if (ifname) + { + /* When ifname is specified. It must be come with gateway + address. */ + if (ret != 1) + { + vty_out (vty, "%% Malformed address%s", VTY_NEWLINE); + return CMD_WARNING; + } + type = STATIC_IPV6_GATEWAY_IFNAME; + gate = &gate_addr; + } + else + { + if (ret == 1) + { + type = STATIC_IPV6_GATEWAY; + gate = &gate_addr; + } + else + { + type = STATIC_IPV6_IFNAME; + ifname = gate_str; + } + } + + if (add_cmd) + static_add_ipv6 (&p, type, gate, ifname, distance, table); + else + static_delete_ipv6 (&p, type, gate, ifname, distance, table); + + return CMD_SUCCESS; +} + +DEFUN (ipv6_route, + ipv6_route_cmd, + "ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE)", + IP_STR + "Establish static routes\n" + "IPv6 destination prefix (e.g. 3ffe:506::/32)\n" + "IPv6 gateway address\n" + "IPv6 gateway interface name\n") +{ + return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, NULL); +} + +DEFUN (ipv6_route_ifname, + ipv6_route_ifname_cmd, + "ipv6 route X:X::X:X/M X:X::X:X INTERFACE", + IP_STR + "Establish static routes\n" + "IPv6 destination prefix (e.g. 3ffe:506::/32)\n" + "IPv6 gateway address\n" + "IPv6 gateway interface name\n") +{ + return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], NULL); +} + +DEFUN (ipv6_route_pref, + ipv6_route_pref_cmd, + "ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) <1-255>", + IP_STR + "Establish static routes\n" + "IPv6 destination prefix (e.g. 3ffe:506::/32)\n" + "IPv6 gateway address\n" + "IPv6 gateway interface name\n" + "Distance value for this prefix\n") +{ + return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, argv[2]); +} + +DEFUN (ipv6_route_ifname_pref, + ipv6_route_ifname_pref_cmd, + "ipv6 route X:X::X:X/M X:X::X:X INTERFACE <1-255>", + IP_STR + "Establish static routes\n" + "IPv6 destination prefix (e.g. 3ffe:506::/32)\n" + "IPv6 gateway address\n" + "IPv6 gateway interface name\n" + "Distance value for this prefix\n") +{ + return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], argv[3]); +} + +DEFUN (no_ipv6_route, + no_ipv6_route_cmd, + "no ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE)", + NO_STR + IP_STR + "Establish static routes\n" + "IPv6 destination prefix (e.g. 3ffe:506::/32)\n" + "IPv6 gateway address\n" + "IPv6 gateway interface name\n") +{ + return static_ipv6_func (vty, 0, argv[0], argv[1], NULL, NULL); +} + +DEFUN (no_ipv6_route_ifname, + no_ipv6_route_ifname_cmd, + "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE", + NO_STR + IP_STR + "Establish static routes\n" + "IPv6 destination prefix (e.g. 3ffe:506::/32)\n" + "IPv6 gateway address\n" + "IPv6 gateway interface name\n") +{ + return static_ipv6_func (vty, 0, argv[0], argv[1], argv[2], NULL); +} + +DEFUN (no_ipv6_route_pref, + no_ipv6_route_pref_cmd, + "no ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) <1-255>", + NO_STR + IP_STR + "Establish static routes\n" + "IPv6 destination prefix (e.g. 3ffe:506::/32)\n" + "IPv6 gateway address\n" + "IPv6 gateway interface name\n" + "Distance value for this prefix\n") +{ + return static_ipv6_func (vty, 0, argv[0], argv[1], NULL, argv[2]); +} + +DEFUN (no_ipv6_route_ifname_pref, + no_ipv6_route_ifname_pref_cmd, + "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE <1-255>", + NO_STR + IP_STR + "Establish static routes\n" + "IPv6 destination prefix (e.g. 3ffe:506::/32)\n" + "IPv6 gateway address\n" + "IPv6 gateway interface name\n" + "Distance value for this prefix\n") +{ + return static_ipv6_func (vty, 0, argv[0], argv[1], argv[2], argv[3]); +} + +/* New RIB. Detailed information for IPv4 route. */ +void +vty_show_ipv6_route_detail (struct vty *vty, struct route_node *rn) +{ + struct rib *rib; + struct nexthop *nexthop; + char buf[BUFSIZ]; + + for (rib = rn->info; rib; rib = rib->next) + { + vty_out (vty, "Routing entry for %s/%d%s", + inet_ntop (AF_INET6, &rn->p.u.prefix6, buf, BUFSIZ), + rn->p.prefixlen, + VTY_NEWLINE); + vty_out (vty, " Known via \"%s\"", route_type_str (rib->type)); + vty_out (vty, ", distance %d, metric %d", rib->distance, rib->metric); + if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED)) + vty_out (vty, ", best"); + if (rib->refcnt) + vty_out (vty, ", refcnt %ld", rib->refcnt); + vty_out (vty, "%s", VTY_NEWLINE); + +#define ONE_DAY_SECOND 60*60*24 +#define ONE_WEEK_SECOND 60*60*24*7 + if (rib->type == ZEBRA_ROUTE_RIPNG + || rib->type == ZEBRA_ROUTE_OSPF6 + || rib->type == ZEBRA_ROUTE_BGP) + { + time_t uptime; + struct tm *tm; + + uptime = time (NULL); + uptime -= rib->uptime; + tm = gmtime (&uptime); + + vty_out (vty, " Last update "); + + if (uptime < ONE_DAY_SECOND) + vty_out (vty, "%02d:%02d:%02d", + tm->tm_hour, tm->tm_min, tm->tm_sec); + else if (uptime < ONE_WEEK_SECOND) + vty_out (vty, "%dd%02dh%02dm", + tm->tm_yday, tm->tm_hour, tm->tm_min); + else + vty_out (vty, "%02dw%dd%02dh", + tm->tm_yday/7, + tm->tm_yday - ((tm->tm_yday/7) * 7), tm->tm_hour); + vty_out (vty, " ago%s", VTY_NEWLINE); + } + + for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next) + { + vty_out (vty, " %c", + CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB) ? '*' : ' '); + + switch (nexthop->type) + { + case NEXTHOP_TYPE_IPV6: + case NEXTHOP_TYPE_IPV6_IFINDEX: + case NEXTHOP_TYPE_IPV6_IFNAME: + vty_out (vty, " %s", + inet_ntop (AF_INET6, &nexthop->gate.ipv6, buf, BUFSIZ)); + if (nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME) + vty_out (vty, ", %s", nexthop->ifname); + else if (nexthop->ifindex) + vty_out (vty, ", via %s", ifindex2ifname (nexthop->ifindex)); + break; + case NEXTHOP_TYPE_IFINDEX: + vty_out (vty, " directly connected, %s", + ifindex2ifname (nexthop->ifindex)); + break; + case NEXTHOP_TYPE_IFNAME: + vty_out (vty, " directly connected, %s", + nexthop->ifname); + break; + default: + break; + } + if (! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE)) + vty_out (vty, " inactive"); + + if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE)) + { + vty_out (vty, " (recursive"); + + switch (nexthop->rtype) + { + case NEXTHOP_TYPE_IPV6: + case NEXTHOP_TYPE_IPV6_IFINDEX: + case NEXTHOP_TYPE_IPV6_IFNAME: + vty_out (vty, " via %s)", + inet_ntop (AF_INET6, &nexthop->rgate.ipv6, + buf, BUFSIZ)); + if (nexthop->rifindex) + vty_out (vty, ", %s", ifindex2ifname (nexthop->rifindex)); + break; + case NEXTHOP_TYPE_IFINDEX: + case NEXTHOP_TYPE_IFNAME: + vty_out (vty, " is directly connected, %s)", + ifindex2ifname (nexthop->rifindex)); + break; + default: + break; + } + } + vty_out (vty, "%s", VTY_NEWLINE); + } + vty_out (vty, "%s", VTY_NEWLINE); + } +} + +void +vty_show_ipv6_route (struct vty *vty, struct route_node *rn, + struct rib *rib) +{ + struct nexthop *nexthop; + int len = 0; + char buf[BUFSIZ]; + + /* Nexthop information. */ + for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next) + { + if (nexthop == rib->nexthop) + { + /* Prefix information. */ + len = vty_out (vty, "%c%c%c %s/%d", + route_type_char (rib->type), + CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED) + ? '>' : ' ', + CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB) + ? '*' : ' ', + inet_ntop (AF_INET6, &rn->p.u.prefix6, buf, BUFSIZ), + rn->p.prefixlen); + + /* Distance and metric display. */ + if (rib->type != ZEBRA_ROUTE_CONNECT + && rib->type != ZEBRA_ROUTE_KERNEL) + len += vty_out (vty, " [%d/%d]", rib->distance, + rib->metric); + } + else + vty_out (vty, " %c%*c", + CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB) + ? '*' : ' ', + len - 3, ' '); + + switch (nexthop->type) + { + case NEXTHOP_TYPE_IPV6: + case NEXTHOP_TYPE_IPV6_IFINDEX: + case NEXTHOP_TYPE_IPV6_IFNAME: + vty_out (vty, " via %s", + inet_ntop (AF_INET6, &nexthop->gate.ipv6, buf, BUFSIZ)); + if (nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME) + vty_out (vty, ", %s", nexthop->ifname); + else if (nexthop->ifindex) + vty_out (vty, ", %s", ifindex2ifname (nexthop->ifindex)); + break; + case NEXTHOP_TYPE_IFINDEX: + vty_out (vty, " is directly connected, %s", + ifindex2ifname (nexthop->ifindex)); + break; + case NEXTHOP_TYPE_IFNAME: + vty_out (vty, " is directly connected, %s", + nexthop->ifname); + break; + default: + break; + } + if (! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE)) + vty_out (vty, " inactive"); + + if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE)) + { + vty_out (vty, " (recursive"); + + switch (nexthop->rtype) + { + case NEXTHOP_TYPE_IPV6: + case NEXTHOP_TYPE_IPV6_IFINDEX: + case NEXTHOP_TYPE_IPV6_IFNAME: + vty_out (vty, " via %s)", + inet_ntop (AF_INET6, &nexthop->rgate.ipv6, + buf, BUFSIZ)); + if (nexthop->rifindex) + vty_out (vty, ", %s", ifindex2ifname (nexthop->rifindex)); + break; + case NEXTHOP_TYPE_IFINDEX: + case NEXTHOP_TYPE_IFNAME: + vty_out (vty, " is directly connected, %s)", + ifindex2ifname (nexthop->rifindex)); + break; + default: + break; + } + } + + if (rib->type == ZEBRA_ROUTE_RIPNG + || rib->type == ZEBRA_ROUTE_OSPF6 + || rib->type == ZEBRA_ROUTE_BGP) + { + time_t uptime; + struct tm *tm; + + uptime = time (NULL); + uptime -= rib->uptime; + tm = gmtime (&uptime); + +#define ONE_DAY_SECOND 60*60*24 +#define ONE_WEEK_SECOND 60*60*24*7 + + if (uptime < ONE_DAY_SECOND) + vty_out (vty, ", %02d:%02d:%02d", + tm->tm_hour, tm->tm_min, tm->tm_sec); + else if (uptime < ONE_WEEK_SECOND) + vty_out (vty, ", %dd%02dh%02dm", + tm->tm_yday, tm->tm_hour, tm->tm_min); + else + vty_out (vty, ", %02dw%dd%02dh", + tm->tm_yday/7, + tm->tm_yday - ((tm->tm_yday/7) * 7), tm->tm_hour); + } + vty_out (vty, "%s", VTY_NEWLINE); + } +} + +#define SHOW_ROUTE_V6_HEADER "Codes: K - kernel route, C - connected, S - static, R - RIPng, O - OSPFv3,%s B - BGP, * - FIB route.%s%s" + +DEFUN (show_ipv6_route, + show_ipv6_route_cmd, + "show ipv6 route", + SHOW_STR + IP_STR + "IPv6 routing table\n") +{ + struct route_table *table; + struct route_node *rn; + struct rib *rib; + int first = 1; + + table = vrf_table (AFI_IP6, SAFI_UNICAST, 0); + if (! table) + return CMD_SUCCESS; + + /* Show all IPv6 route. */ + for (rn = route_top (table); rn; rn = route_next (rn)) + for (rib = rn->info; rib; rib = rib->next) + { + if (first) + { + vty_out (vty, SHOW_ROUTE_V6_HEADER, VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE); + first = 0; + } + vty_show_ipv6_route (vty, rn, rib); + } + return CMD_SUCCESS; +} + +DEFUN (show_ipv6_route_prefix_longer, + show_ipv6_route_prefix_longer_cmd, + "show ipv6 route X:X::X:X/M longer-prefixes", + SHOW_STR + IP_STR + "IPv6 routing table\n" + "IPv6 prefix\n" + "Show route matching the specified Network/Mask pair only\n") +{ + struct route_table *table; + struct route_node *rn; + struct rib *rib; + struct prefix p; + int ret; + int first = 1; + + table = vrf_table (AFI_IP6, SAFI_UNICAST, 0); + if (! table) + return CMD_SUCCESS; + + ret = str2prefix (argv[0], &p); + if (! ret) + { + vty_out (vty, "%% Malformed Prefix%s", VTY_NEWLINE); + return CMD_WARNING; + } + + /* Show matched type IPv6 routes. */ + for (rn = route_top (table); rn; rn = route_next (rn)) + for (rib = rn->info; rib; rib = rib->next) + if (prefix_match (&p, &rn->p)) + { + if (first) + { + vty_out (vty, SHOW_ROUTE_V6_HEADER, VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE); + first = 0; + } + vty_show_ipv6_route (vty, rn, rib); + } + return CMD_SUCCESS; +} + +DEFUN (show_ipv6_route_protocol, + show_ipv6_route_protocol_cmd, + "show ipv6 route (bgp|connected|kernel|ospf6|ripng|static)", + SHOW_STR + IP_STR + "IP routing table\n" + "Border Gateway Protocol (BGP)\n" + "Connected\n" + "Kernel\n" + "Open Shortest Path First (OSPFv3)\n" + "Routing Information Protocol (RIPng)\n" + "Static routes\n") +{ + int type; + struct route_table *table; + struct route_node *rn; + struct rib *rib; + int first = 1; + + if (strncmp (argv[0], "b", 1) == 0) + type = ZEBRA_ROUTE_BGP; + else if (strncmp (argv[0], "c", 1) == 0) + type = ZEBRA_ROUTE_CONNECT; + else if (strncmp (argv[0], "k", 1) ==0) + type = ZEBRA_ROUTE_KERNEL; + else if (strncmp (argv[0], "o", 1) == 0) + type = ZEBRA_ROUTE_OSPF6; + else if (strncmp (argv[0], "r", 1) == 0) + type = ZEBRA_ROUTE_RIPNG; + else if (strncmp (argv[0], "s", 1) == 0) + type = ZEBRA_ROUTE_STATIC; + else + { + vty_out (vty, "Unknown route type%s", VTY_NEWLINE); + return CMD_WARNING; + } + + table = vrf_table (AFI_IP6, SAFI_UNICAST, 0); + if (! table) + return CMD_SUCCESS; + + /* Show matched type IPv6 routes. */ + for (rn = route_top (table); rn; rn = route_next (rn)) + for (rib = rn->info; rib; rib = rib->next) + if (rib->type == type) + { + if (first) + { + vty_out (vty, SHOW_ROUTE_V6_HEADER, VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE); + first = 0; + } + vty_show_ipv6_route (vty, rn, rib); + } + return CMD_SUCCESS; +} + +DEFUN (show_ipv6_route_addr, + show_ipv6_route_addr_cmd, + "show ipv6 route X:X::X:X", + SHOW_STR + IP_STR + "IPv6 routing table\n" + "IPv6 Address\n") +{ + int ret; + struct prefix_ipv6 p; + struct route_table *table; + struct route_node *rn; + + ret = str2prefix_ipv6 (argv[0], &p); + if (ret <= 0) + { + vty_out (vty, "Malformed IPv6 address%s", VTY_NEWLINE); + return CMD_WARNING; + } + + table = vrf_table (AFI_IP6, SAFI_UNICAST, 0); + if (! table) + return CMD_SUCCESS; + + rn = route_node_match (table, (struct prefix *) &p); + if (! rn) + { + vty_out (vty, "%% Network not in table%s", VTY_NEWLINE); + return CMD_WARNING; + } + + vty_show_ipv6_route_detail (vty, rn); + + route_unlock_node (rn); + + return CMD_SUCCESS; +} + +DEFUN (show_ipv6_route_prefix, + show_ipv6_route_prefix_cmd, + "show ipv6 route X:X::X:X/M", + SHOW_STR + IP_STR + "IPv6 routing table\n" + "IPv6 prefix\n") +{ + int ret; + struct prefix_ipv6 p; + struct route_table *table; + struct route_node *rn; + + ret = str2prefix_ipv6 (argv[0], &p); + if (ret <= 0) + { + vty_out (vty, "Malformed IPv6 prefix%s", VTY_NEWLINE); + return CMD_WARNING; + } + + table = vrf_table (AFI_IP6, SAFI_UNICAST, 0); + if (! table) + return CMD_SUCCESS; + + rn = route_node_match (table, (struct prefix *) &p); + if (! rn || rn->p.prefixlen != p.prefixlen) + { + vty_out (vty, "%% Network not in table%s", VTY_NEWLINE); + return CMD_WARNING; + } + + vty_show_ipv6_route_detail (vty, rn); + + route_unlock_node (rn); + + return CMD_SUCCESS; +} + + +/* Write IPv6 static route configuration. */ +int +static_config_ipv6 (struct vty *vty) +{ + struct route_node *rn; + struct static_ipv6 *si; + int write; + char buf[BUFSIZ]; + struct route_table *stable; + + write = 0; + + /* Lookup table. */ + stable = vrf_static_table (AFI_IP6, SAFI_UNICAST, 0); + if (! stable) + return -1; + + for (rn = route_top (stable); rn; rn = route_next (rn)) + for (si = rn->info; si; si = si->next) + { + vty_out (vty, "ipv6 route %s/%d", + inet_ntop (AF_INET6, &rn->p.u.prefix6, buf, BUFSIZ), + rn->p.prefixlen); + + switch (si->type) + { + case STATIC_IPV6_GATEWAY: + vty_out (vty, " %s", inet_ntop (AF_INET6, &si->ipv6, buf, BUFSIZ)); + break; + case STATIC_IPV6_IFNAME: + vty_out (vty, " %s", si->ifname); + break; + case STATIC_IPV6_GATEWAY_IFNAME: + vty_out (vty, " %s %s", + inet_ntop (AF_INET6, &si->ipv6, buf, BUFSIZ), si->ifname); + break; + } + + if (si->distance != ZEBRA_STATIC_DISTANCE_DEFAULT) + vty_out (vty, " %d", si->distance); + vty_out (vty, "%s", VTY_NEWLINE); + + write = 1; + } + return write; +} +#endif /* HAVE_IPV6 */ + +/* Static ip route configuration write function. */ +int +zebra_ip_config (struct vty *vty) +{ + int write = 0; + + write += static_config_ipv4 (vty); +#ifdef HAVE_IPV6 + write += static_config_ipv6 (vty); +#endif /* HAVE_IPV6 */ + + return write; +} + +/* IP node for static routes. */ +struct cmd_node ip_node = { IP_NODE, "", 1 }; + +/* Route VTY. */ +void +zebra_vty_route_init () +{ + install_node (&ip_node, zebra_ip_config); + + install_element (CONFIG_NODE, &ip_route_cmd); + install_element (CONFIG_NODE, &ip_route_mask_cmd); + install_element (CONFIG_NODE, &no_ip_route_cmd); + install_element (CONFIG_NODE, &no_ip_route_mask_cmd); + install_element (CONFIG_NODE, &ip_route_distance_cmd); + install_element (CONFIG_NODE, &ip_route_mask_distance_cmd); + install_element (CONFIG_NODE, &no_ip_route_distance_cmd); + install_element (CONFIG_NODE, &no_ip_route_mask_distance_cmd); + + install_element (VIEW_NODE, &show_ip_route_cmd); + install_element (VIEW_NODE, &show_ip_route_addr_cmd); + install_element (VIEW_NODE, &show_ip_route_prefix_cmd); + install_element (VIEW_NODE, &show_ip_route_prefix_longer_cmd); + install_element (VIEW_NODE, &show_ip_route_protocol_cmd); + install_element (VIEW_NODE, &show_ip_route_supernets_cmd); + install_element (ENABLE_NODE, &show_ip_route_cmd); + install_element (ENABLE_NODE, &show_ip_route_addr_cmd); + install_element (ENABLE_NODE, &show_ip_route_prefix_cmd); + install_element (ENABLE_NODE, &show_ip_route_prefix_longer_cmd); + install_element (ENABLE_NODE, &show_ip_route_protocol_cmd); + install_element (ENABLE_NODE, &show_ip_route_supernets_cmd); + +#if 0 + install_element (VIEW_NODE, &show_ip_route_summary_cmd); + install_element (ENABLE_NODE, &show_ip_route_summary_cmd); +#endif /* 0 */ + +#ifdef HAVE_IPV6 + install_element (CONFIG_NODE, &ipv6_route_cmd); + install_element (CONFIG_NODE, &ipv6_route_ifname_cmd); + install_element (CONFIG_NODE, &no_ipv6_route_cmd); + install_element (CONFIG_NODE, &no_ipv6_route_ifname_cmd); + install_element (CONFIG_NODE, &ipv6_route_pref_cmd); + install_element (CONFIG_NODE, &ipv6_route_ifname_pref_cmd); + install_element (CONFIG_NODE, &no_ipv6_route_pref_cmd); + install_element (CONFIG_NODE, &no_ipv6_route_ifname_pref_cmd); + install_element (VIEW_NODE, &show_ipv6_route_cmd); + install_element (VIEW_NODE, &show_ipv6_route_protocol_cmd); + install_element (VIEW_NODE, &show_ipv6_route_addr_cmd); + install_element (VIEW_NODE, &show_ipv6_route_prefix_cmd); + install_element (VIEW_NODE, &show_ipv6_route_prefix_longer_cmd); + install_element (ENABLE_NODE, &show_ipv6_route_cmd); + install_element (ENABLE_NODE, &show_ipv6_route_protocol_cmd); + install_element (ENABLE_NODE, &show_ipv6_route_addr_cmd); + install_element (ENABLE_NODE, &show_ipv6_route_prefix_cmd); + install_element (ENABLE_NODE, &show_ipv6_route_prefix_longer_cmd); +#endif /* HAVE_IPV6 */ +} + +void +zebra_vty_init () +{ + zebra_vty_route_init (); +} |