File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / quagga / zebra / zebra_vty.c
Revision 1.1.1.3 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Sun Jul 21 23:54:41 2013 UTC (11 years ago) by misho
Branches: quagga, MAIN
CVS tags: v0_99_22p0, v0_99_22, HEAD
0.99.22

    1: /* Zebra VTY functions
    2:  * Copyright (C) 2002 Kunihiro Ishiguro
    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 "memory.h"
   25: #include "if.h"
   26: #include "prefix.h"
   27: #include "command.h"
   28: #include "table.h"
   29: #include "rib.h"
   30: 
   31: #include "zebra/zserv.h"
   32: 
   33: /* General fucntion for static route. */
   34: static int
   35: zebra_static_ipv4 (struct vty *vty, int add_cmd, const char *dest_str,
   36: 		   const char *mask_str, const char *gate_str,
   37: 		   const char *flag_str, const char *distance_str)
   38: {
   39:   int ret;
   40:   u_char distance;
   41:   struct prefix p;
   42:   struct in_addr gate;
   43:   struct in_addr mask;
   44:   const char *ifname;
   45:   u_char flag = 0;
   46:   
   47:   ret = str2prefix (dest_str, &p);
   48:   if (ret <= 0)
   49:     {
   50:       vty_out (vty, "%% Malformed address%s", VTY_NEWLINE);
   51:       return CMD_WARNING;
   52:     }
   53: 
   54:   /* Cisco like mask notation. */
   55:   if (mask_str)
   56:     {
   57:       ret = inet_aton (mask_str, &mask);
   58:       if (ret == 0)
   59:         {
   60:           vty_out (vty, "%% Malformed address%s", VTY_NEWLINE);
   61:           return CMD_WARNING;
   62:         }
   63:       p.prefixlen = ip_masklen (mask);
   64:     }
   65: 
   66:   /* Apply mask for given prefix. */
   67:   apply_mask (&p);
   68: 
   69:   /* Administrative distance. */
   70:   if (distance_str)
   71:     distance = atoi (distance_str);
   72:   else
   73:     distance = ZEBRA_STATIC_DISTANCE_DEFAULT;
   74: 
   75:   /* Null0 static route.  */
   76:   if ((gate_str != NULL) && (strncasecmp (gate_str, "Null0", strlen (gate_str)) == 0))
   77:     {
   78:       if (flag_str)
   79:         {
   80:           vty_out (vty, "%% can not have flag %s with Null0%s", flag_str, VTY_NEWLINE);
   81:           return CMD_WARNING;
   82:         }
   83:       if (add_cmd)
   84:         static_add_ipv4 (&p, NULL, NULL, ZEBRA_FLAG_BLACKHOLE, distance, 0);
   85:       else
   86:         static_delete_ipv4 (&p, NULL, NULL, distance, 0);
   87:       return CMD_SUCCESS;
   88:     }
   89: 
   90:   /* Route flags */
   91:   if (flag_str) {
   92:     switch(flag_str[0]) {
   93:       case 'r':
   94:       case 'R': /* XXX */
   95:         SET_FLAG (flag, ZEBRA_FLAG_REJECT);
   96:         break;
   97:       case 'b':
   98:       case 'B': /* XXX */
   99:         SET_FLAG (flag, ZEBRA_FLAG_BLACKHOLE);
  100:         break;
  101:       default:
  102:         vty_out (vty, "%% Malformed flag %s %s", flag_str, VTY_NEWLINE);
  103:         return CMD_WARNING;
  104:     }
  105:   }
  106: 
  107:   if (gate_str == NULL)
  108:   {
  109:     if (add_cmd)
  110:       static_add_ipv4 (&p, NULL, NULL, flag, distance, 0);
  111:     else
  112:       static_delete_ipv4 (&p, NULL, NULL, distance, 0);
  113: 
  114:     return CMD_SUCCESS;
  115:   }
  116:   
  117:   /* When gateway is A.B.C.D format, gate is treated as nexthop
  118:      address other case gate is treated as interface name. */
  119:   ret = inet_aton (gate_str, &gate);
  120:   if (ret)
  121:     ifname = NULL;
  122:   else
  123:     ifname = gate_str;
  124: 
  125:   if (add_cmd)
  126:     static_add_ipv4 (&p, ifname ? NULL : &gate, ifname, flag, distance, 0);
  127:   else
  128:     static_delete_ipv4 (&p, ifname ? NULL : &gate, ifname, distance, 0);
  129: 
  130:   return CMD_SUCCESS;
  131: }
  132: 
  133: /* Static route configuration.  */
  134: DEFUN (ip_route, 
  135:        ip_route_cmd,
  136:        "ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0)",
  137:        IP_STR
  138:        "Establish static routes\n"
  139:        "IP destination prefix (e.g. 10.0.0.0/8)\n"
  140:        "IP gateway address\n"
  141:        "IP gateway interface name\n"
  142:        "Null interface\n")
  143: {
  144:   return zebra_static_ipv4 (vty, 1, argv[0], NULL, argv[1], NULL, NULL);
  145: }
  146: 
  147: DEFUN (ip_route_flags,
  148:        ip_route_flags_cmd,
  149:        "ip route A.B.C.D/M (A.B.C.D|INTERFACE) (reject|blackhole)",
  150:        IP_STR
  151:        "Establish static routes\n"
  152:        "IP destination prefix (e.g. 10.0.0.0/8)\n"
  153:        "IP gateway address\n"
  154:        "IP gateway interface name\n"
  155:        "Emit an ICMP unreachable when matched\n"
  156:        "Silently discard pkts when matched\n")
  157: {
  158:   return zebra_static_ipv4 (vty, 1, argv[0], NULL, argv[1], argv[2], NULL);
  159: }
  160: 
  161: DEFUN (ip_route_flags2,
  162:        ip_route_flags2_cmd,
  163:        "ip route A.B.C.D/M (reject|blackhole)",
  164:        IP_STR
  165:        "Establish static routes\n"
  166:        "IP destination prefix (e.g. 10.0.0.0/8)\n"
  167:        "Emit an ICMP unreachable when matched\n"
  168:        "Silently discard pkts when matched\n")
  169: {
  170:   return zebra_static_ipv4 (vty, 1, argv[0], NULL, NULL, argv[1], NULL);
  171: }
  172: 
  173: /* Mask as A.B.C.D format.  */
  174: DEFUN (ip_route_mask,
  175:        ip_route_mask_cmd,
  176:        "ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0)",
  177:        IP_STR
  178:        "Establish static routes\n"
  179:        "IP destination prefix\n"
  180:        "IP destination prefix mask\n"
  181:        "IP gateway address\n"
  182:        "IP gateway interface name\n"
  183:        "Null interface\n")
  184: {
  185:   return zebra_static_ipv4 (vty, 1, argv[0], argv[1], argv[2], NULL, NULL);
  186: }
  187: 
  188: DEFUN (ip_route_mask_flags,
  189:        ip_route_mask_flags_cmd,
  190:        "ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE) (reject|blackhole)",
  191:        IP_STR
  192:        "Establish static routes\n"
  193:        "IP destination prefix\n"
  194:        "IP destination prefix mask\n"
  195:        "IP gateway address\n"
  196:        "IP gateway interface name\n"
  197:        "Emit an ICMP unreachable when matched\n"
  198:        "Silently discard pkts when matched\n")
  199: {
  200:   return zebra_static_ipv4 (vty, 1, argv[0], argv[1], argv[2], argv[3], NULL);
  201: }
  202: 
  203: DEFUN (ip_route_mask_flags2,
  204:        ip_route_mask_flags2_cmd,
  205:        "ip route A.B.C.D A.B.C.D (reject|blackhole)",
  206:        IP_STR
  207:        "Establish static routes\n"
  208:        "IP destination prefix\n"
  209:        "IP destination prefix mask\n"
  210:        "Emit an ICMP unreachable when matched\n"
  211:        "Silently discard pkts when matched\n")
  212: {
  213:   return zebra_static_ipv4 (vty, 1, argv[0], argv[1], NULL, argv[2], NULL);
  214: }
  215: 
  216: /* Distance option value.  */
  217: DEFUN (ip_route_distance,
  218:        ip_route_distance_cmd,
  219:        "ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0) <1-255>",
  220:        IP_STR
  221:        "Establish static routes\n"
  222:        "IP destination prefix (e.g. 10.0.0.0/8)\n"
  223:        "IP gateway address\n"
  224:        "IP gateway interface name\n"
  225:        "Null interface\n"
  226:        "Distance value for this route\n")
  227: {
  228:   return zebra_static_ipv4 (vty, 1, argv[0], NULL, argv[1], NULL, argv[2]);
  229: }
  230: 
  231: DEFUN (ip_route_flags_distance,
  232:        ip_route_flags_distance_cmd,
  233:        "ip route A.B.C.D/M (A.B.C.D|INTERFACE) (reject|blackhole) <1-255>",
  234:        IP_STR
  235:        "Establish static routes\n"
  236:        "IP destination prefix (e.g. 10.0.0.0/8)\n"
  237:        "IP gateway address\n"
  238:        "IP gateway interface name\n"
  239:        "Emit an ICMP unreachable when matched\n"
  240:        "Silently discard pkts when matched\n"
  241:        "Distance value for this route\n")
  242: {
  243:   return zebra_static_ipv4 (vty, 1, argv[0], NULL, argv[1], argv[2], argv[3]);
  244: }
  245: 
  246: DEFUN (ip_route_flags_distance2,
  247:        ip_route_flags_distance2_cmd,
  248:        "ip route A.B.C.D/M (reject|blackhole) <1-255>",
  249:        IP_STR
  250:        "Establish static routes\n"
  251:        "IP destination prefix (e.g. 10.0.0.0/8)\n"
  252:        "Emit an ICMP unreachable when matched\n"
  253:        "Silently discard pkts when matched\n"
  254:        "Distance value for this route\n")
  255: {
  256:   return zebra_static_ipv4 (vty, 1, argv[0], NULL, NULL, argv[1], argv[2]);
  257: }
  258: 
  259: DEFUN (ip_route_mask_distance,
  260:        ip_route_mask_distance_cmd,
  261:        "ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0) <1-255>",
  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")
  270: {
  271:   return zebra_static_ipv4 (vty, 1, argv[0], argv[1], argv[2], NULL, argv[3]);
  272: }
  273: 
  274: DEFUN (ip_route_mask_flags_distance,
  275:        ip_route_mask_flags_distance_cmd,
  276:        "ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE) (reject|blackhole) <1-255>",
  277:        IP_STR
  278:        "Establish static routes\n"
  279:        "IP destination prefix\n"
  280:        "IP destination prefix mask\n"
  281:        "IP gateway address\n"
  282:        "IP gateway interface name\n"
  283:        "Distance value for this route\n"
  284:        "Emit an ICMP unreachable when matched\n"
  285:        "Silently discard pkts when matched\n")
  286: {
  287:   return zebra_static_ipv4 (vty, 1, argv[0], argv[1], argv[2], argv[3], argv[4]);
  288: }
  289: 
  290: DEFUN (ip_route_mask_flags_distance2,
  291:        ip_route_mask_flags_distance2_cmd,
  292:        "ip route A.B.C.D A.B.C.D (reject|blackhole) <1-255>",
  293:        IP_STR
  294:        "Establish static routes\n"
  295:        "IP destination prefix\n"
  296:        "IP destination prefix mask\n"
  297:        "Distance value for this route\n"
  298:        "Emit an ICMP unreachable when matched\n"
  299:        "Silently discard pkts when matched\n")
  300: {
  301:   return zebra_static_ipv4 (vty, 1, argv[0], argv[1], NULL, argv[2], argv[3]);
  302: }
  303: 
  304: DEFUN (no_ip_route, 
  305:        no_ip_route_cmd,
  306:        "no ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0)",
  307:        NO_STR
  308:        IP_STR
  309:        "Establish static routes\n"
  310:        "IP destination prefix (e.g. 10.0.0.0/8)\n"
  311:        "IP gateway address\n"
  312:        "IP gateway interface name\n"
  313:        "Null interface\n")
  314: {
  315:   return zebra_static_ipv4 (vty, 0, argv[0], NULL, argv[1], NULL, NULL);
  316: }
  317: 
  318: ALIAS (no_ip_route,
  319:        no_ip_route_flags_cmd,
  320:        "no ip route A.B.C.D/M (A.B.C.D|INTERFACE) (reject|blackhole)",
  321:        NO_STR
  322:        IP_STR
  323:        "Establish static routes\n"
  324:        "IP destination prefix (e.g. 10.0.0.0/8)\n"
  325:        "IP gateway address\n"
  326:        "IP gateway interface name\n"
  327:        "Emit an ICMP unreachable when matched\n"
  328:        "Silently discard pkts when matched\n")
  329: 
  330: DEFUN (no_ip_route_flags2,
  331:        no_ip_route_flags2_cmd,
  332:        "no ip route A.B.C.D/M (reject|blackhole)",
  333:        NO_STR
  334:        IP_STR
  335:        "Establish static routes\n"
  336:        "IP destination prefix (e.g. 10.0.0.0/8)\n"
  337:        "Emit an ICMP unreachable when matched\n"
  338:        "Silently discard pkts when matched\n")
  339: {
  340:   return zebra_static_ipv4 (vty, 0, argv[0], NULL, NULL, NULL, NULL);
  341: }
  342: 
  343: DEFUN (no_ip_route_mask,
  344:        no_ip_route_mask_cmd,
  345:        "no ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0)",
  346:        NO_STR
  347:        IP_STR
  348:        "Establish static routes\n"
  349:        "IP destination prefix\n"
  350:        "IP destination prefix mask\n"
  351:        "IP gateway address\n"
  352:        "IP gateway interface name\n"
  353:        "Null interface\n")
  354: {
  355:   return zebra_static_ipv4 (vty, 0, argv[0], argv[1], argv[2], NULL, NULL);
  356: }
  357: 
  358: ALIAS (no_ip_route_mask,
  359:        no_ip_route_mask_flags_cmd,
  360:        "no ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE) (reject|blackhole)",
  361:        NO_STR
  362:        IP_STR
  363:        "Establish static routes\n"
  364:        "IP destination prefix\n"
  365:        "IP destination prefix mask\n"
  366:        "IP gateway address\n"
  367:        "IP gateway interface name\n"
  368:        "Emit an ICMP unreachable when matched\n"
  369:        "Silently discard pkts when matched\n")
  370: 
  371: DEFUN (no_ip_route_mask_flags2,
  372:        no_ip_route_mask_flags2_cmd,
  373:        "no ip route A.B.C.D A.B.C.D (reject|blackhole)",
  374:        NO_STR
  375:        IP_STR
  376:        "Establish static routes\n"
  377:        "IP destination prefix\n"
  378:        "IP destination prefix mask\n"
  379:        "Emit an ICMP unreachable when matched\n"
  380:        "Silently discard pkts when matched\n")
  381: {
  382:   return zebra_static_ipv4 (vty, 0, argv[0], argv[1], NULL, NULL, NULL);
  383: }
  384: 
  385: DEFUN (no_ip_route_distance,
  386:        no_ip_route_distance_cmd,
  387:        "no ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0) <1-255>",
  388:        NO_STR
  389:        IP_STR
  390:        "Establish static routes\n"
  391:        "IP destination prefix (e.g. 10.0.0.0/8)\n"
  392:        "IP gateway address\n"
  393:        "IP gateway interface name\n"
  394:        "Null interface\n"
  395:        "Distance value for this route\n")
  396: {
  397:   return zebra_static_ipv4 (vty, 0, argv[0], NULL, argv[1], NULL, argv[2]);
  398: }
  399: 
  400: DEFUN (no_ip_route_flags_distance,
  401:        no_ip_route_flags_distance_cmd,
  402:        "no ip route A.B.C.D/M (A.B.C.D|INTERFACE) (reject|blackhole) <1-255>",
  403:        NO_STR
  404:        IP_STR
  405:        "Establish static routes\n"
  406:        "IP destination prefix (e.g. 10.0.0.0/8)\n"
  407:        "IP gateway address\n"
  408:        "IP gateway interface name\n"
  409:        "Emit an ICMP unreachable when matched\n"
  410:        "Silently discard pkts when matched\n"
  411:        "Distance value for this route\n")
  412: {
  413:   return zebra_static_ipv4 (vty, 0, argv[0], NULL, argv[1], argv[2], argv[3]);
  414: }
  415: 
  416: DEFUN (no_ip_route_flags_distance2,
  417:        no_ip_route_flags_distance2_cmd,
  418:        "no ip route A.B.C.D/M (reject|blackhole) <1-255>",
  419:        NO_STR
  420:        IP_STR
  421:        "Establish static routes\n"
  422:        "IP destination prefix (e.g. 10.0.0.0/8)\n"
  423:        "Emit an ICMP unreachable when matched\n"
  424:        "Silently discard pkts when matched\n"
  425:        "Distance value for this route\n")
  426: {
  427:   return zebra_static_ipv4 (vty, 0, argv[0], NULL, NULL, argv[1], argv[2]);
  428: }
  429: 
  430: DEFUN (no_ip_route_mask_distance,
  431:        no_ip_route_mask_distance_cmd,
  432:        "no ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0) <1-255>",
  433:        NO_STR
  434:        IP_STR
  435:        "Establish static routes\n"
  436:        "IP destination prefix\n"
  437:        "IP destination prefix mask\n"
  438:        "IP gateway address\n"
  439:        "IP gateway interface name\n"
  440:        "Null interface\n"
  441:        "Distance value for this route\n")
  442: {
  443:   return zebra_static_ipv4 (vty, 0, argv[0], argv[1], argv[2], NULL, argv[3]);
  444: }
  445: 
  446: DEFUN (no_ip_route_mask_flags_distance,
  447:        no_ip_route_mask_flags_distance_cmd,
  448:        "no ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE) (reject|blackhole) <1-255>",
  449:        NO_STR
  450:        IP_STR
  451:        "Establish static routes\n"
  452:        "IP destination prefix\n"
  453:        "IP destination prefix mask\n"
  454:        "IP gateway address\n"
  455:        "IP gateway interface name\n"
  456:        "Emit an ICMP unreachable when matched\n"
  457:        "Silently discard pkts when matched\n"
  458:        "Distance value for this route\n")
  459: {
  460:   return zebra_static_ipv4 (vty, 0, argv[0], argv[1], argv[2], argv[3], argv[4]);
  461: }
  462: 
  463: DEFUN (no_ip_route_mask_flags_distance2,
  464:        no_ip_route_mask_flags_distance2_cmd,
  465:        "no ip route A.B.C.D A.B.C.D (reject|blackhole) <1-255>",
  466:        NO_STR
  467:        IP_STR
  468:        "Establish static routes\n"
  469:        "IP destination prefix\n"
  470:        "IP destination prefix mask\n"
  471:        "Emit an ICMP unreachable when matched\n"
  472:        "Silently discard pkts when matched\n"
  473:        "Distance value for this route\n")
  474: {
  475:   return zebra_static_ipv4 (vty, 0, argv[0], argv[1], NULL, argv[2], argv[3]);
  476: }
  477: 
  478: char *proto_rm[AFI_MAX][ZEBRA_ROUTE_MAX+1];	/* "any" == ZEBRA_ROUTE_MAX */
  479: 
  480: DEFUN (ip_protocol,
  481:        ip_protocol_cmd,
  482:        "ip protocol PROTO route-map ROUTE-MAP",
  483:        NO_STR
  484:        "Apply route map to PROTO\n"
  485:        "Protocol name\n"
  486:        "Route map name\n")
  487: {
  488:   int i;
  489: 
  490:   if (strcasecmp(argv[0], "any") == 0)
  491:     i = ZEBRA_ROUTE_MAX;
  492:   else
  493:     i = proto_name2num(argv[0]);
  494:   if (i < 0)
  495:     {
  496:       vty_out (vty, "invalid protocol name \"%s\"%s", argv[0] ? argv[0] : "",
  497:                VTY_NEWLINE);
  498:       return CMD_WARNING;
  499:     }
  500:   if (proto_rm[AFI_IP][i])
  501:     XFREE (MTYPE_ROUTE_MAP_NAME, proto_rm[AFI_IP][i]);
  502:   proto_rm[AFI_IP][i] = XSTRDUP (MTYPE_ROUTE_MAP_NAME, argv[1]);
  503:   return CMD_SUCCESS;
  504: }
  505: 
  506: DEFUN (no_ip_protocol,
  507:        no_ip_protocol_cmd,
  508:        "no ip protocol PROTO",
  509:        NO_STR
  510:        "Remove route map from PROTO\n"
  511:        "Protocol name\n")
  512: {
  513:   int i;
  514: 
  515:   if (strcasecmp(argv[0], "any") == 0)
  516:     i = ZEBRA_ROUTE_MAX;
  517:   else
  518:     i = proto_name2num(argv[0]);
  519:   if (i < 0)
  520:     {
  521:       vty_out (vty, "invalid protocol name \"%s\"%s", argv[0] ? argv[0] : "",
  522:                VTY_NEWLINE);
  523:      return CMD_WARNING;
  524:     }
  525:   if (proto_rm[AFI_IP][i])
  526:     XFREE (MTYPE_ROUTE_MAP_NAME, proto_rm[AFI_IP][i]);
  527:   proto_rm[AFI_IP][i] = NULL;
  528:   return CMD_SUCCESS;
  529: }
  530: 
  531: /* New RIB.  Detailed information for IPv4 route. */
  532: static void
  533: vty_show_ip_route_detail (struct vty *vty, struct route_node *rn)
  534: {
  535:   struct rib *rib;
  536:   struct nexthop *nexthop;
  537: 
  538:   RNODE_FOREACH_RIB (rn, rib)
  539:     {
  540:       vty_out (vty, "Routing entry for %s/%d%s", 
  541: 	       inet_ntoa (rn->p.u.prefix4), rn->p.prefixlen,
  542: 	       VTY_NEWLINE);
  543:       vty_out (vty, "  Known via \"%s\"", zebra_route_string (rib->type));
  544:       vty_out (vty, ", distance %u, metric %u", rib->distance, rib->metric);
  545:       if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
  546: 	vty_out (vty, ", best");
  547:       if (rib->refcnt)
  548: 	vty_out (vty, ", refcnt %ld", rib->refcnt);
  549:       if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_BLACKHOLE))
  550:        vty_out (vty, ", blackhole");
  551:       if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_REJECT))
  552:        vty_out (vty, ", reject");
  553:       vty_out (vty, "%s", VTY_NEWLINE);
  554: 
  555: #define ONE_DAY_SECOND 60*60*24
  556: #define ONE_WEEK_SECOND 60*60*24*7
  557:       if (rib->type == ZEBRA_ROUTE_RIP
  558: 	  || rib->type == ZEBRA_ROUTE_OSPF
  559: 	  || rib->type == ZEBRA_ROUTE_BABEL
  560: 	  || rib->type == ZEBRA_ROUTE_ISIS
  561: 	  || rib->type == ZEBRA_ROUTE_BGP)
  562: 	{
  563: 	  time_t uptime;
  564: 	  struct tm *tm;
  565: 
  566: 	  uptime = time (NULL);
  567: 	  uptime -= rib->uptime;
  568: 	  tm = gmtime (&uptime);
  569: 
  570: 	  vty_out (vty, "  Last update ");
  571: 
  572: 	  if (uptime < ONE_DAY_SECOND)
  573: 	    vty_out (vty,  "%02d:%02d:%02d", 
  574: 		     tm->tm_hour, tm->tm_min, tm->tm_sec);
  575: 	  else if (uptime < ONE_WEEK_SECOND)
  576: 	    vty_out (vty, "%dd%02dh%02dm", 
  577: 		     tm->tm_yday, tm->tm_hour, tm->tm_min);
  578: 	  else
  579: 	    vty_out (vty, "%02dw%dd%02dh", 
  580: 		     tm->tm_yday/7,
  581: 		     tm->tm_yday - ((tm->tm_yday/7) * 7), tm->tm_hour);
  582: 	  vty_out (vty, " ago%s", VTY_NEWLINE);
  583: 	}
  584: 
  585:       for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
  586: 	{
  587:           char addrstr[32];
  588: 
  589: 	  vty_out (vty, "  %c",
  590: 		   CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB) ? '*' : ' ');
  591: 
  592: 	  switch (nexthop->type)
  593: 	    {
  594: 	    case NEXTHOP_TYPE_IPV4:
  595: 	    case NEXTHOP_TYPE_IPV4_IFINDEX:
  596: 	      vty_out (vty, " %s", inet_ntoa (nexthop->gate.ipv4));
  597: 	      if (nexthop->ifindex)
  598: 		vty_out (vty, ", via %s", ifindex2ifname (nexthop->ifindex));
  599: 	      break;
  600: 	    case NEXTHOP_TYPE_IFINDEX:
  601: 	      vty_out (vty, " directly connected, %s",
  602: 		       ifindex2ifname (nexthop->ifindex));
  603: 	      break;
  604: 	    case NEXTHOP_TYPE_IFNAME:
  605: 	      vty_out (vty, " directly connected, %s", nexthop->ifname);
  606: 	      break;
  607:       case NEXTHOP_TYPE_BLACKHOLE:
  608:         vty_out (vty, " directly connected, Null0");
  609:         break;
  610:       default:
  611: 	      break;
  612: 	    }
  613: 	  if (! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
  614: 	    vty_out (vty, " inactive");
  615: 
  616: 	  if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
  617: 	    {
  618: 	      vty_out (vty, " (recursive");
  619: 		
  620: 	      switch (nexthop->rtype)
  621: 		{
  622: 		case NEXTHOP_TYPE_IPV4:
  623: 		case NEXTHOP_TYPE_IPV4_IFINDEX:
  624: 		  vty_out (vty, " via %s)", inet_ntoa (nexthop->rgate.ipv4));
  625: 		  break;
  626: 		case NEXTHOP_TYPE_IFINDEX:
  627: 		case NEXTHOP_TYPE_IFNAME:
  628: 		  vty_out (vty, " is directly connected, %s)",
  629: 			   ifindex2ifname (nexthop->rifindex));
  630: 		  break;
  631: 		default:
  632: 		  break;
  633: 		}
  634: 	    }
  635: 	  switch (nexthop->type)
  636:             {
  637:             case NEXTHOP_TYPE_IPV4:
  638:             case NEXTHOP_TYPE_IPV4_IFINDEX:
  639:             case NEXTHOP_TYPE_IPV4_IFNAME:
  640:               if (nexthop->src.ipv4.s_addr)
  641:                 {
  642: 		  if (inet_ntop(AF_INET, &nexthop->src.ipv4, addrstr,
  643: 		      sizeof addrstr))
  644:                     vty_out (vty, ", src %s", addrstr);
  645:                 }
  646:               break;
  647: #ifdef HAVE_IPV6
  648:             case NEXTHOP_TYPE_IPV6:
  649:             case NEXTHOP_TYPE_IPV6_IFINDEX:
  650:             case NEXTHOP_TYPE_IPV6_IFNAME:
  651:               if (!IPV6_ADDR_SAME(&nexthop->src.ipv6, &in6addr_any))
  652:                 {
  653: 		  if (inet_ntop(AF_INET6, &nexthop->src.ipv6, addrstr,
  654: 		      sizeof addrstr))
  655:                     vty_out (vty, ", src %s", addrstr);
  656:                 }
  657:               break;
  658: #endif /* HAVE_IPV6 */
  659:             default:
  660: 	       break;
  661:             }
  662: 	  vty_out (vty, "%s", VTY_NEWLINE);
  663: 	}
  664:       vty_out (vty, "%s", VTY_NEWLINE);
  665:     }
  666: }
  667: 
  668: static void
  669: vty_show_ip_route (struct vty *vty, struct route_node *rn, struct rib *rib)
  670: {
  671:   struct nexthop *nexthop;
  672:   int len = 0;
  673:   char buf[BUFSIZ];
  674: 
  675:   /* Nexthop information. */
  676:   for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
  677:     {
  678:       if (nexthop == rib->nexthop)
  679: 	{
  680: 	  /* Prefix information. */
  681: 	  len = vty_out (vty, "%c%c%c %s/%d",
  682: 			 zebra_route_char (rib->type),
  683: 			 CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED)
  684: 			 ? '>' : ' ',
  685: 			 CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)
  686: 			 ? '*' : ' ',
  687: 			 inet_ntop (AF_INET, &rn->p.u.prefix, buf, BUFSIZ),
  688: 			 rn->p.prefixlen);
  689: 		
  690: 	  /* Distance and metric display. */
  691: 	  if (rib->type != ZEBRA_ROUTE_CONNECT 
  692: 	      && rib->type != ZEBRA_ROUTE_KERNEL)
  693: 	    len += vty_out (vty, " [%d/%d]", rib->distance,
  694: 			    rib->metric);
  695: 	}
  696:       else
  697: 	vty_out (vty, "  %c%*c",
  698: 		 CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)
  699: 		 ? '*' : ' ',
  700: 		 len - 3, ' ');
  701: 
  702:       switch (nexthop->type)
  703: 	{
  704: 	case NEXTHOP_TYPE_IPV4:
  705: 	case NEXTHOP_TYPE_IPV4_IFINDEX:
  706: 	  vty_out (vty, " via %s", inet_ntoa (nexthop->gate.ipv4));
  707: 	  if (nexthop->ifindex)
  708: 	    vty_out (vty, ", %s", ifindex2ifname (nexthop->ifindex));
  709: 	  break;
  710: 	case NEXTHOP_TYPE_IFINDEX:
  711: 	  vty_out (vty, " is directly connected, %s",
  712: 		   ifindex2ifname (nexthop->ifindex));
  713: 	  break;
  714: 	case NEXTHOP_TYPE_IFNAME:
  715: 	  vty_out (vty, " is directly connected, %s", nexthop->ifname);
  716: 	  break;
  717:   case NEXTHOP_TYPE_BLACKHOLE:
  718:     vty_out (vty, " is directly connected, Null0");
  719:     break;
  720:   default:
  721: 	  break;
  722: 	}
  723:       if (! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
  724: 	vty_out (vty, " inactive");
  725: 
  726:       if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
  727: 	{
  728: 	  vty_out (vty, " (recursive");
  729: 		
  730: 	  switch (nexthop->rtype)
  731: 	    {
  732: 	    case NEXTHOP_TYPE_IPV4:
  733: 	    case NEXTHOP_TYPE_IPV4_IFINDEX:
  734: 	      vty_out (vty, " via %s)", inet_ntoa (nexthop->rgate.ipv4));
  735: 	      break;
  736: 	    case NEXTHOP_TYPE_IFINDEX:
  737: 	    case NEXTHOP_TYPE_IFNAME:
  738: 	      vty_out (vty, " is directly connected, %s)",
  739: 		       ifindex2ifname (nexthop->rifindex));
  740: 	      break;
  741: 	    default:
  742: 	      break;
  743: 	    }
  744: 	}
  745:       switch (nexthop->type)
  746:         {
  747:           case NEXTHOP_TYPE_IPV4:
  748:           case NEXTHOP_TYPE_IPV4_IFINDEX:
  749:           case NEXTHOP_TYPE_IPV4_IFNAME:
  750:             if (nexthop->src.ipv4.s_addr)
  751:               {
  752: 		if (inet_ntop(AF_INET, &nexthop->src.ipv4, buf, sizeof buf))
  753:                   vty_out (vty, ", src %s", buf);
  754:               }
  755:             break;
  756: #ifdef HAVE_IPV6
  757:           case NEXTHOP_TYPE_IPV6:
  758:           case NEXTHOP_TYPE_IPV6_IFINDEX:
  759:           case NEXTHOP_TYPE_IPV6_IFNAME:
  760:             if (!IPV6_ADDR_SAME(&nexthop->src.ipv6, &in6addr_any))
  761:               {
  762: 		if (inet_ntop(AF_INET6, &nexthop->src.ipv6, buf, sizeof buf))
  763:                   vty_out (vty, ", src %s", buf);
  764:               }
  765:             break;
  766: #endif /* HAVE_IPV6 */
  767:           default:
  768: 	    break;
  769:         }
  770: 
  771:       if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_BLACKHOLE))
  772:                vty_out (vty, ", bh");
  773:       if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_REJECT))
  774:                vty_out (vty, ", rej");
  775: 
  776:       if (rib->type == ZEBRA_ROUTE_RIP
  777: 	  || rib->type == ZEBRA_ROUTE_OSPF
  778: 	  || rib->type == ZEBRA_ROUTE_BABEL
  779: 	  || rib->type == ZEBRA_ROUTE_ISIS
  780: 	  || rib->type == ZEBRA_ROUTE_BGP)
  781: 	{
  782: 	  time_t uptime;
  783: 	  struct tm *tm;
  784: 
  785: 	  uptime = time (NULL);
  786: 	  uptime -= rib->uptime;
  787: 	  tm = gmtime (&uptime);
  788: 
  789: #define ONE_DAY_SECOND 60*60*24
  790: #define ONE_WEEK_SECOND 60*60*24*7
  791: 
  792: 	  if (uptime < ONE_DAY_SECOND)
  793: 	    vty_out (vty,  ", %02d:%02d:%02d", 
  794: 		     tm->tm_hour, tm->tm_min, tm->tm_sec);
  795: 	  else if (uptime < ONE_WEEK_SECOND)
  796: 	    vty_out (vty, ", %dd%02dh%02dm", 
  797: 		     tm->tm_yday, tm->tm_hour, tm->tm_min);
  798: 	  else
  799: 	    vty_out (vty, ", %02dw%dd%02dh", 
  800: 		     tm->tm_yday/7,
  801: 		     tm->tm_yday - ((tm->tm_yday/7) * 7), tm->tm_hour);
  802: 	}
  803:       vty_out (vty, "%s", VTY_NEWLINE);
  804:     }
  805: }
  806: 
  807: DEFUN (show_ip_route,
  808:        show_ip_route_cmd,
  809:        "show ip route",
  810:        SHOW_STR
  811:        IP_STR
  812:        "IP routing table\n")
  813: {
  814:   struct route_table *table;
  815:   struct route_node *rn;
  816:   struct rib *rib;
  817:   int first = 1;
  818: 
  819:   table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
  820:   if (! table)
  821:     return CMD_SUCCESS;
  822: 
  823:   /* Show all IPv4 routes. */
  824:   for (rn = route_top (table); rn; rn = route_next (rn))
  825:     RNODE_FOREACH_RIB (rn, rib)
  826:       {
  827: 	if (first)
  828: 	  {
  829: 	    vty_out (vty, SHOW_ROUTE_V4_HEADER);
  830: 	    first = 0;
  831: 	  }
  832: 	vty_show_ip_route (vty, rn, rib);
  833:       }
  834:   return CMD_SUCCESS;
  835: }
  836: 
  837: DEFUN (show_ip_route_prefix_longer,
  838:        show_ip_route_prefix_longer_cmd,
  839:        "show ip route A.B.C.D/M longer-prefixes",
  840:        SHOW_STR
  841:        IP_STR
  842:        "IP routing table\n"
  843:        "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
  844:        "Show route matching the specified Network/Mask pair only\n")
  845: {
  846:   struct route_table *table;
  847:   struct route_node *rn;
  848:   struct rib *rib;
  849:   struct prefix p;
  850:   int ret;
  851:   int first = 1;
  852: 
  853:   ret = str2prefix (argv[0], &p);
  854:   if (! ret)
  855:     {
  856:       vty_out (vty, "%% Malformed Prefix%s", VTY_NEWLINE);
  857:       return CMD_WARNING;
  858:     }
  859:   
  860:   table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
  861:   if (! table)
  862:     return CMD_SUCCESS;
  863: 
  864:   /* Show matched type IPv4 routes. */
  865:   for (rn = route_top (table); rn; rn = route_next (rn))
  866:     RNODE_FOREACH_RIB (rn, rib)
  867:       if (prefix_match (&p, &rn->p))
  868: 	{
  869: 	  if (first)
  870: 	    {
  871: 	      vty_out (vty, SHOW_ROUTE_V4_HEADER);
  872: 	      first = 0;
  873: 	    }
  874: 	  vty_show_ip_route (vty, rn, rib);
  875: 	}
  876:   return CMD_SUCCESS;
  877: }
  878: 
  879: DEFUN (show_ip_route_supernets,
  880:        show_ip_route_supernets_cmd,
  881:        "show ip route supernets-only",
  882:        SHOW_STR
  883:        IP_STR
  884:        "IP routing table\n"
  885:        "Show supernet entries only\n")
  886: {
  887:   struct route_table *table;
  888:   struct route_node *rn;
  889:   struct rib *rib;
  890:   u_int32_t addr; 
  891:   int first = 1;
  892: 
  893:   table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
  894:   if (! table)
  895:     return CMD_SUCCESS;
  896: 
  897:   /* Show matched type IPv4 routes. */
  898:   for (rn = route_top (table); rn; rn = route_next (rn))
  899:     RNODE_FOREACH_RIB (rn, rib)
  900:       {
  901: 	addr = ntohl (rn->p.u.prefix4.s_addr);
  902: 
  903: 	if ((IN_CLASSC (addr) && rn->p.prefixlen < 24)
  904: 	   || (IN_CLASSB (addr) && rn->p.prefixlen < 16)
  905: 	   || (IN_CLASSA (addr) && rn->p.prefixlen < 8)) 
  906: 	  {
  907: 	    if (first)
  908: 	      {
  909: 		vty_out (vty, SHOW_ROUTE_V4_HEADER);
  910: 		first = 0;
  911: 	      }
  912: 	    vty_show_ip_route (vty, rn, rib);
  913: 	  }
  914:       }
  915:   return CMD_SUCCESS;
  916: }
  917: 
  918: DEFUN (show_ip_route_protocol,
  919:        show_ip_route_protocol_cmd,
  920:        "show ip route " QUAGGA_IP_REDIST_STR_ZEBRA,
  921:        SHOW_STR
  922:        IP_STR
  923:        "IP routing table\n"
  924:        QUAGGA_IP_REDIST_HELP_STR_ZEBRA)
  925: {
  926:   int type;
  927:   struct route_table *table;
  928:   struct route_node *rn;
  929:   struct rib *rib;
  930:   int first = 1;
  931: 
  932:   type = proto_redistnum (AFI_IP, argv[0]);
  933:   if (type < 0)
  934:     {
  935:       vty_out (vty, "Unknown route type%s", VTY_NEWLINE);
  936:       return CMD_WARNING;
  937:     }
  938:   
  939:   table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
  940:   if (! table)
  941:     return CMD_SUCCESS;
  942: 
  943:   /* Show matched type IPv4 routes. */
  944:   for (rn = route_top (table); rn; rn = route_next (rn))
  945:     RNODE_FOREACH_RIB (rn, rib)
  946:       if (rib->type == type)
  947: 	{
  948: 	  if (first)
  949: 	    {
  950: 	      vty_out (vty, SHOW_ROUTE_V4_HEADER);
  951: 	      first = 0;
  952: 	    }
  953: 	  vty_show_ip_route (vty, rn, rib);
  954: 	}
  955:   return CMD_SUCCESS;
  956: }
  957: 
  958: DEFUN (show_ip_route_addr,
  959:        show_ip_route_addr_cmd,
  960:        "show ip route A.B.C.D",
  961:        SHOW_STR
  962:        IP_STR
  963:        "IP routing table\n"
  964:        "Network in the IP routing table to display\n")
  965: {
  966:   int ret;
  967:   struct prefix_ipv4 p;
  968:   struct route_table *table;
  969:   struct route_node *rn;
  970: 
  971:   ret = str2prefix_ipv4 (argv[0], &p);
  972:   if (ret <= 0)
  973:     {
  974:       vty_out (vty, "%% Malformed IPv4 address%s", VTY_NEWLINE);
  975:       return CMD_WARNING;
  976:     }
  977: 
  978:   table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
  979:   if (! table)
  980:     return CMD_SUCCESS;
  981: 
  982:   rn = route_node_match (table, (struct prefix *) &p);
  983:   if (! rn)
  984:     {
  985:       vty_out (vty, "%% Network not in table%s", VTY_NEWLINE);
  986:       return CMD_WARNING;
  987:     }
  988: 
  989:   vty_show_ip_route_detail (vty, rn);
  990: 
  991:   route_unlock_node (rn);
  992: 
  993:   return CMD_SUCCESS;
  994: }
  995: 
  996: DEFUN (show_ip_route_prefix,
  997:        show_ip_route_prefix_cmd,
  998:        "show ip route A.B.C.D/M",
  999:        SHOW_STR
 1000:        IP_STR
 1001:        "IP routing table\n"
 1002:        "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n")
 1003: {
 1004:   int ret;
 1005:   struct prefix_ipv4 p;
 1006:   struct route_table *table;
 1007:   struct route_node *rn;
 1008: 
 1009:   ret = str2prefix_ipv4 (argv[0], &p);
 1010:   if (ret <= 0)
 1011:     {
 1012:       vty_out (vty, "%% Malformed IPv4 address%s", VTY_NEWLINE);
 1013:       return CMD_WARNING;
 1014:     }
 1015: 
 1016:   table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
 1017:   if (! table)
 1018:     return CMD_SUCCESS;
 1019: 
 1020:   rn = route_node_match (table, (struct prefix *) &p);
 1021:   if (! rn || rn->p.prefixlen != p.prefixlen)
 1022:     {
 1023:       vty_out (vty, "%% Network not in table%s", VTY_NEWLINE);
 1024:       return CMD_WARNING;
 1025:     }
 1026: 
 1027:   vty_show_ip_route_detail (vty, rn);
 1028: 
 1029:   route_unlock_node (rn);
 1030: 
 1031:   return CMD_SUCCESS;
 1032: }
 1033: 
 1034: static void
 1035: vty_show_ip_route_summary (struct vty *vty, struct route_table *table)
 1036: {
 1037:   struct route_node *rn;
 1038:   struct rib *rib;
 1039:   struct nexthop *nexthop;
 1040: #define ZEBRA_ROUTE_IBGP  ZEBRA_ROUTE_MAX
 1041: #define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1)
 1042:   u_int32_t rib_cnt[ZEBRA_ROUTE_TOTAL + 1];
 1043:   u_int32_t fib_cnt[ZEBRA_ROUTE_TOTAL + 1];
 1044:   u_int32_t i;
 1045: 
 1046:   memset (&rib_cnt, 0, sizeof(rib_cnt));
 1047:   memset (&fib_cnt, 0, sizeof(fib_cnt));
 1048:   for (rn = route_top (table); rn; rn = route_next (rn))
 1049:     RNODE_FOREACH_RIB (rn, rib)
 1050:       for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
 1051:         {
 1052: 	  rib_cnt[ZEBRA_ROUTE_TOTAL]++;
 1053: 	  rib_cnt[rib->type]++;
 1054: 	  if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)) 
 1055: 	    {
 1056: 	      fib_cnt[ZEBRA_ROUTE_TOTAL]++;
 1057: 	      fib_cnt[rib->type]++;
 1058: 	    }
 1059: 	  if (rib->type == ZEBRA_ROUTE_BGP && 
 1060: 	      CHECK_FLAG (rib->flags, ZEBRA_FLAG_IBGP)) 
 1061: 	    {
 1062: 	      rib_cnt[ZEBRA_ROUTE_IBGP]++;
 1063: 	      if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)) 
 1064: 		fib_cnt[ZEBRA_ROUTE_IBGP]++;
 1065: 	    }
 1066: 	}
 1067: 
 1068:   vty_out (vty, "%-20s %-20s %-20s %s", 
 1069: 	   "Route Source", "Routes", "FIB", VTY_NEWLINE);
 1070: 
 1071:   for (i = 0; i < ZEBRA_ROUTE_MAX; i++) 
 1072:     {
 1073:       if (rib_cnt[i] > 0)
 1074: 	{
 1075: 	  if (i == ZEBRA_ROUTE_BGP)
 1076: 	    {
 1077: 	      vty_out (vty, "%-20s %-20d %-20d %s", "ebgp", 
 1078: 		       rib_cnt[ZEBRA_ROUTE_BGP] - rib_cnt[ZEBRA_ROUTE_IBGP],
 1079: 		       fib_cnt[ZEBRA_ROUTE_BGP] - fib_cnt[ZEBRA_ROUTE_IBGP],
 1080: 		       VTY_NEWLINE);
 1081: 	      vty_out (vty, "%-20s %-20d %-20d %s", "ibgp", 
 1082: 		       rib_cnt[ZEBRA_ROUTE_IBGP], fib_cnt[ZEBRA_ROUTE_IBGP],
 1083: 		       VTY_NEWLINE);
 1084: 	    }
 1085: 	  else 
 1086: 	    vty_out (vty, "%-20s %-20d %-20d %s", zebra_route_string(i), 
 1087: 		     rib_cnt[i], fib_cnt[i], VTY_NEWLINE);
 1088: 	}
 1089:     }
 1090: 
 1091:   vty_out (vty, "------%s", VTY_NEWLINE);
 1092:   vty_out (vty, "%-20s %-20d %-20d %s", "Totals", rib_cnt[ZEBRA_ROUTE_TOTAL], 
 1093: 	   fib_cnt[ZEBRA_ROUTE_TOTAL], VTY_NEWLINE);  
 1094: }
 1095: 
 1096: /* Show route summary.  */
 1097: DEFUN (show_ip_route_summary,
 1098:        show_ip_route_summary_cmd,
 1099:        "show ip route summary",
 1100:        SHOW_STR
 1101:        IP_STR
 1102:        "IP routing table\n"
 1103:        "Summary of all routes\n")
 1104: {
 1105:   struct route_table *table;
 1106: 
 1107:   table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
 1108:   if (! table)
 1109:     return CMD_SUCCESS;
 1110: 
 1111:   vty_show_ip_route_summary (vty, table);
 1112: 
 1113:   return CMD_SUCCESS;
 1114: }
 1115: 
 1116: /* Write IPv4 static route configuration. */
 1117: static int
 1118: static_config_ipv4 (struct vty *vty)
 1119: {
 1120:   struct route_node *rn;
 1121:   struct static_ipv4 *si;  
 1122:   struct route_table *stable;
 1123:   int write;
 1124: 
 1125:   write = 0;
 1126: 
 1127:   /* Lookup table.  */
 1128:   stable = vrf_static_table (AFI_IP, SAFI_UNICAST, 0);
 1129:   if (! stable)
 1130:     return -1;
 1131: 
 1132:   for (rn = route_top (stable); rn; rn = route_next (rn))
 1133:     for (si = rn->info; si; si = si->next)
 1134:       {
 1135:         vty_out (vty, "ip route %s/%d", inet_ntoa (rn->p.u.prefix4),
 1136:                  rn->p.prefixlen);
 1137: 
 1138:         switch (si->type)
 1139:           {
 1140:             case STATIC_IPV4_GATEWAY:
 1141:               vty_out (vty, " %s", inet_ntoa (si->gate.ipv4));
 1142:               break;
 1143:             case STATIC_IPV4_IFNAME:
 1144:               vty_out (vty, " %s", si->gate.ifname);
 1145:               break;
 1146:             case STATIC_IPV4_BLACKHOLE:
 1147:               vty_out (vty, " Null0");
 1148:               break;
 1149:           }
 1150:         
 1151:         /* flags are incompatible with STATIC_IPV4_BLACKHOLE */
 1152:         if (si->type != STATIC_IPV4_BLACKHOLE)
 1153:           {
 1154:             if (CHECK_FLAG(si->flags, ZEBRA_FLAG_REJECT))
 1155:               vty_out (vty, " %s", "reject");
 1156: 
 1157:             if (CHECK_FLAG(si->flags, ZEBRA_FLAG_BLACKHOLE))
 1158:               vty_out (vty, " %s", "blackhole");
 1159:           }
 1160: 
 1161:         if (si->distance != ZEBRA_STATIC_DISTANCE_DEFAULT)
 1162:           vty_out (vty, " %d", si->distance);
 1163: 
 1164:         vty_out (vty, "%s", VTY_NEWLINE);
 1165: 
 1166:         write = 1;
 1167:       }
 1168:   return write;
 1169: }
 1170: 
 1171: DEFUN (show_ip_protocol,
 1172:        show_ip_protocol_cmd,
 1173:        "show ip protocol",
 1174:         SHOW_STR
 1175:         IP_STR
 1176:        "IP protocol filtering status\n")
 1177: {
 1178:     int i; 
 1179: 
 1180:     vty_out(vty, "Protocol    : route-map %s", VTY_NEWLINE);
 1181:     vty_out(vty, "------------------------%s", VTY_NEWLINE);
 1182:     for (i=0;i<ZEBRA_ROUTE_MAX;i++)
 1183:     {
 1184:         if (proto_rm[AFI_IP][i])
 1185:           vty_out (vty, "%-10s  : %-10s%s", zebra_route_string(i),
 1186: 					proto_rm[AFI_IP][i],
 1187: 					VTY_NEWLINE);
 1188:         else
 1189:           vty_out (vty, "%-10s  : none%s", zebra_route_string(i), VTY_NEWLINE);
 1190:     }
 1191:     if (proto_rm[AFI_IP][i])
 1192:       vty_out (vty, "%-10s  : %-10s%s", "any", proto_rm[AFI_IP][i],
 1193: 					VTY_NEWLINE);
 1194:     else
 1195:       vty_out (vty, "%-10s  : none%s", "any", VTY_NEWLINE);
 1196: 
 1197:     return CMD_SUCCESS;
 1198: }
 1199: 
 1200: /*
 1201:  * Show IP mroute command to dump the BGP Multicast
 1202:  * routing table
 1203:  */
 1204: DEFUN (show_ip_mroute,
 1205:        show_ip_mroute_cmd,
 1206:        "show ip mroute",
 1207:        SHOW_STR
 1208:        IP_STR
 1209:        "IP Multicast routing table\n")
 1210: {
 1211:   struct route_table *table;
 1212:   struct route_node *rn;
 1213:   struct rib *rib;
 1214:   int first = 1;
 1215: 
 1216:   table = vrf_table (AFI_IP, SAFI_MULTICAST, 0);
 1217:   if (! table)
 1218:     return CMD_SUCCESS;
 1219: 
 1220:   /* Show all IPv4 routes. */
 1221:   for (rn = route_top (table); rn; rn = route_next (rn))
 1222:     RNODE_FOREACH_RIB (rn, rib)
 1223:       {
 1224:        if (first)
 1225:          {
 1226: 	   vty_out (vty, SHOW_ROUTE_V4_HEADER);
 1227:            first = 0;
 1228:          }
 1229:        vty_show_ip_route (vty, rn, rib);
 1230:       }
 1231:   return CMD_SUCCESS;
 1232: }
 1233: 
 1234: 
 1235: #ifdef HAVE_IPV6
 1236: /* General fucntion for IPv6 static route. */
 1237: static int
 1238: static_ipv6_func (struct vty *vty, int add_cmd, const char *dest_str,
 1239: 		  const char *gate_str, const char *ifname,
 1240: 		  const char *flag_str, const char *distance_str)
 1241: {
 1242:   int ret;
 1243:   u_char distance;
 1244:   struct prefix p;
 1245:   struct in6_addr *gate = NULL;
 1246:   struct in6_addr gate_addr;
 1247:   u_char type = 0;
 1248:   int table = 0;
 1249:   u_char flag = 0;
 1250:   
 1251:   ret = str2prefix (dest_str, &p);
 1252:   if (ret <= 0)
 1253:     {
 1254:       vty_out (vty, "%% Malformed address%s", VTY_NEWLINE);
 1255:       return CMD_WARNING;
 1256:     }
 1257: 
 1258:   /* Apply mask for given prefix. */
 1259:   apply_mask (&p);
 1260: 
 1261:   /* Route flags */
 1262:   if (flag_str) {
 1263:     switch(flag_str[0]) {
 1264:       case 'r':
 1265:       case 'R': /* XXX */
 1266:         SET_FLAG (flag, ZEBRA_FLAG_REJECT);
 1267:         break;
 1268:       case 'b':
 1269:       case 'B': /* XXX */
 1270:         SET_FLAG (flag, ZEBRA_FLAG_BLACKHOLE);
 1271:         break;
 1272:       default:
 1273:         vty_out (vty, "%% Malformed flag %s %s", flag_str, VTY_NEWLINE);
 1274:         return CMD_WARNING;
 1275:     }
 1276:   }
 1277: 
 1278:   /* Administrative distance. */
 1279:   if (distance_str)
 1280:     distance = atoi (distance_str);
 1281:   else
 1282:     distance = ZEBRA_STATIC_DISTANCE_DEFAULT;
 1283: 
 1284:   /* When gateway is valid IPv6 addrees, then gate is treated as
 1285:      nexthop address other case gate is treated as interface name. */
 1286:   ret = inet_pton (AF_INET6, gate_str, &gate_addr);
 1287: 
 1288:   if (ifname)
 1289:     {
 1290:       /* When ifname is specified.  It must be come with gateway
 1291:          address. */
 1292:       if (ret != 1)
 1293: 	{
 1294: 	  vty_out (vty, "%% Malformed address%s", VTY_NEWLINE);
 1295: 	  return CMD_WARNING;
 1296: 	}
 1297:       type = STATIC_IPV6_GATEWAY_IFNAME;
 1298:       gate = &gate_addr;
 1299:     }
 1300:   else
 1301:     {
 1302:       if (ret == 1)
 1303: 	{
 1304: 	  type = STATIC_IPV6_GATEWAY;
 1305: 	  gate = &gate_addr;
 1306: 	}
 1307:       else
 1308: 	{
 1309: 	  type = STATIC_IPV6_IFNAME;
 1310: 	  ifname = gate_str;
 1311: 	}
 1312:     }
 1313: 
 1314:   if (add_cmd)
 1315:     static_add_ipv6 (&p, type, gate, ifname, flag, distance, table);
 1316:   else
 1317:     static_delete_ipv6 (&p, type, gate, ifname, distance, table);
 1318: 
 1319:   return CMD_SUCCESS;
 1320: }
 1321: 
 1322: DEFUN (ipv6_route,
 1323:        ipv6_route_cmd,
 1324:        "ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE)",
 1325:        IP_STR
 1326:        "Establish static routes\n"
 1327:        "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
 1328:        "IPv6 gateway address\n"
 1329:        "IPv6 gateway interface name\n")
 1330: {
 1331:   return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, NULL, NULL);
 1332: }
 1333: 
 1334: DEFUN (ipv6_route_flags,
 1335:        ipv6_route_flags_cmd,
 1336:        "ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) (reject|blackhole)",
 1337:        IP_STR
 1338:        "Establish static routes\n"
 1339:        "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
 1340:        "IPv6 gateway address\n"
 1341:        "IPv6 gateway interface name\n"
 1342:        "Emit an ICMP unreachable when matched\n"
 1343:        "Silently discard pkts when matched\n")
 1344: {
 1345:   return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, argv[2], NULL);
 1346: }
 1347: 
 1348: DEFUN (ipv6_route_ifname,
 1349:        ipv6_route_ifname_cmd,
 1350:        "ipv6 route X:X::X:X/M X:X::X:X INTERFACE",
 1351:        IP_STR
 1352:        "Establish static routes\n"
 1353:        "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
 1354:        "IPv6 gateway address\n"
 1355:        "IPv6 gateway interface name\n")
 1356: {
 1357:   return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], NULL, NULL);
 1358: }
 1359: 
 1360: DEFUN (ipv6_route_ifname_flags,
 1361:        ipv6_route_ifname_flags_cmd,
 1362:        "ipv6 route X:X::X:X/M X:X::X:X INTERFACE (reject|blackhole)",
 1363:        IP_STR
 1364:        "Establish static routes\n"
 1365:        "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
 1366:        "IPv6 gateway address\n"
 1367:        "IPv6 gateway interface name\n"
 1368:        "Emit an ICMP unreachable when matched\n"
 1369:        "Silently discard pkts when matched\n")
 1370: {
 1371:   return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], argv[3], NULL);
 1372: }
 1373: 
 1374: DEFUN (ipv6_route_pref,
 1375:        ipv6_route_pref_cmd,
 1376:        "ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) <1-255>",
 1377:        IP_STR
 1378:        "Establish static routes\n"
 1379:        "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
 1380:        "IPv6 gateway address\n"
 1381:        "IPv6 gateway interface name\n"
 1382:        "Distance value for this prefix\n")
 1383: {
 1384:   return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, NULL, argv[2]);
 1385: }
 1386: 
 1387: DEFUN (ipv6_route_flags_pref,
 1388:        ipv6_route_flags_pref_cmd,
 1389:        "ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) (reject|blackhole) <1-255>",
 1390:        IP_STR
 1391:        "Establish static routes\n"
 1392:        "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
 1393:        "IPv6 gateway address\n"
 1394:        "IPv6 gateway interface name\n"
 1395:        "Emit an ICMP unreachable when matched\n"
 1396:        "Silently discard pkts when matched\n"
 1397:        "Distance value for this prefix\n")
 1398: {
 1399:   return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, argv[2], argv[3]);
 1400: }
 1401: 
 1402: DEFUN (ipv6_route_ifname_pref,
 1403:        ipv6_route_ifname_pref_cmd,
 1404:        "ipv6 route X:X::X:X/M X:X::X:X INTERFACE <1-255>",
 1405:        IP_STR
 1406:        "Establish static routes\n"
 1407:        "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
 1408:        "IPv6 gateway address\n"
 1409:        "IPv6 gateway interface name\n"
 1410:        "Distance value for this prefix\n")
 1411: {
 1412:   return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], NULL, argv[3]);
 1413: }
 1414: 
 1415: DEFUN (ipv6_route_ifname_flags_pref,
 1416:        ipv6_route_ifname_flags_pref_cmd,
 1417:        "ipv6 route X:X::X:X/M X:X::X:X INTERFACE (reject|blackhole) <1-255>",
 1418:        IP_STR
 1419:        "Establish static routes\n"
 1420:        "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
 1421:        "IPv6 gateway address\n"
 1422:        "IPv6 gateway interface name\n"
 1423:        "Emit an ICMP unreachable when matched\n"
 1424:        "Silently discard pkts when matched\n"
 1425:        "Distance value for this prefix\n")
 1426: {
 1427:   return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], argv[3], argv[4]);
 1428: }
 1429: 
 1430: DEFUN (no_ipv6_route,
 1431:        no_ipv6_route_cmd,
 1432:        "no ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE)",
 1433:        NO_STR
 1434:        IP_STR
 1435:        "Establish static routes\n"
 1436:        "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
 1437:        "IPv6 gateway address\n"
 1438:        "IPv6 gateway interface name\n")
 1439: {
 1440:   return static_ipv6_func (vty, 0, argv[0], argv[1], NULL, NULL, NULL);
 1441: }
 1442: 
 1443: ALIAS (no_ipv6_route,
 1444:        no_ipv6_route_flags_cmd,
 1445:        "no ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) (reject|blackhole)",
 1446:        NO_STR
 1447:        IP_STR
 1448:        "Establish static routes\n"
 1449:        "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
 1450:        "IPv6 gateway address\n"
 1451:        "IPv6 gateway interface name\n"
 1452:        "Emit an ICMP unreachable when matched\n"
 1453:        "Silently discard pkts when matched\n")
 1454: 
 1455: DEFUN (no_ipv6_route_ifname,
 1456:        no_ipv6_route_ifname_cmd,
 1457:        "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE",
 1458:        NO_STR
 1459:        IP_STR
 1460:        "Establish static routes\n"
 1461:        "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
 1462:        "IPv6 gateway address\n"
 1463:        "IPv6 gateway interface name\n")
 1464: {
 1465:   return static_ipv6_func (vty, 0, argv[0], argv[1], argv[2], NULL, NULL);
 1466: }
 1467: 
 1468: ALIAS (no_ipv6_route_ifname,
 1469:        no_ipv6_route_ifname_flags_cmd,
 1470:        "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE (reject|blackhole)",
 1471:        NO_STR
 1472:        IP_STR
 1473:        "Establish static routes\n"
 1474:        "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
 1475:        "IPv6 gateway address\n"
 1476:        "IPv6 gateway interface name\n"
 1477:        "Emit an ICMP unreachable when matched\n"
 1478:        "Silently discard pkts when matched\n")
 1479: 
 1480: DEFUN (no_ipv6_route_pref,
 1481:        no_ipv6_route_pref_cmd,
 1482:        "no ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) <1-255>",
 1483:        NO_STR
 1484:        IP_STR
 1485:        "Establish static routes\n"
 1486:        "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
 1487:        "IPv6 gateway address\n"
 1488:        "IPv6 gateway interface name\n"
 1489:        "Distance value for this prefix\n")
 1490: {
 1491:   return static_ipv6_func (vty, 0, argv[0], argv[1], NULL, NULL, argv[2]);
 1492: }
 1493: 
 1494: DEFUN (no_ipv6_route_flags_pref,
 1495:        no_ipv6_route_flags_pref_cmd,
 1496:        "no ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) (reject|blackhole) <1-255>",
 1497:        NO_STR
 1498:        IP_STR
 1499:        "Establish static routes\n"
 1500:        "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
 1501:        "IPv6 gateway address\n"
 1502:        "IPv6 gateway interface name\n"
 1503:        "Emit an ICMP unreachable when matched\n"
 1504:        "Silently discard pkts when matched\n"
 1505:        "Distance value for this prefix\n")
 1506: {
 1507:   /* We do not care about argv[2] */
 1508:   return static_ipv6_func (vty, 0, argv[0], argv[1], NULL, argv[2], argv[3]);
 1509: }
 1510: 
 1511: DEFUN (no_ipv6_route_ifname_pref,
 1512:        no_ipv6_route_ifname_pref_cmd,
 1513:        "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE <1-255>",
 1514:        NO_STR
 1515:        IP_STR
 1516:        "Establish static routes\n"
 1517:        "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
 1518:        "IPv6 gateway address\n"
 1519:        "IPv6 gateway interface name\n"
 1520:        "Distance value for this prefix\n")
 1521: {
 1522:   return static_ipv6_func (vty, 0, argv[0], argv[1], argv[2], NULL, argv[3]);
 1523: }
 1524: 
 1525: DEFUN (no_ipv6_route_ifname_flags_pref,
 1526:        no_ipv6_route_ifname_flags_pref_cmd,
 1527:        "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE (reject|blackhole) <1-255>",
 1528:        NO_STR
 1529:        IP_STR
 1530:        "Establish static routes\n"
 1531:        "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
 1532:        "IPv6 gateway address\n"
 1533:        "IPv6 gateway interface name\n"
 1534:        "Emit an ICMP unreachable when matched\n"
 1535:        "Silently discard pkts when matched\n"
 1536:        "Distance value for this prefix\n")
 1537: {
 1538:   return static_ipv6_func (vty, 0, argv[0], argv[1], argv[2], argv[3], argv[4]);
 1539: }
 1540: 
 1541: /* New RIB.  Detailed information for IPv6 route. */
 1542: static void
 1543: vty_show_ipv6_route_detail (struct vty *vty, struct route_node *rn)
 1544: {
 1545:   struct rib *rib;
 1546:   struct nexthop *nexthop;
 1547:   char buf[BUFSIZ];
 1548: 
 1549:   RNODE_FOREACH_RIB (rn, rib)
 1550:     {
 1551:       vty_out (vty, "Routing entry for %s/%d%s", 
 1552: 	       inet_ntop (AF_INET6, &rn->p.u.prefix6, buf, BUFSIZ),
 1553: 	       rn->p.prefixlen,
 1554: 	       VTY_NEWLINE);
 1555:       vty_out (vty, "  Known via \"%s\"", zebra_route_string (rib->type));
 1556:       vty_out (vty, ", distance %u, metric %u", rib->distance, rib->metric);
 1557:       if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
 1558: 	vty_out (vty, ", best");
 1559:       if (rib->refcnt)
 1560: 	vty_out (vty, ", refcnt %ld", rib->refcnt);
 1561:       if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_BLACKHOLE))
 1562:        vty_out (vty, ", blackhole");
 1563:       if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_REJECT))
 1564:        vty_out (vty, ", reject");
 1565:       vty_out (vty, "%s", VTY_NEWLINE);
 1566: 
 1567: #define ONE_DAY_SECOND 60*60*24
 1568: #define ONE_WEEK_SECOND 60*60*24*7
 1569:       if (rib->type == ZEBRA_ROUTE_RIPNG
 1570: 	  || rib->type == ZEBRA_ROUTE_OSPF6
 1571: 	  || rib->type == ZEBRA_ROUTE_BABEL
 1572: 	  || rib->type == ZEBRA_ROUTE_ISIS
 1573: 	  || rib->type == ZEBRA_ROUTE_BGP)
 1574: 	{
 1575: 	  time_t uptime;
 1576: 	  struct tm *tm;
 1577: 
 1578: 	  uptime = time (NULL);
 1579: 	  uptime -= rib->uptime;
 1580: 	  tm = gmtime (&uptime);
 1581: 
 1582: 	  vty_out (vty, "  Last update ");
 1583: 
 1584: 	  if (uptime < ONE_DAY_SECOND)
 1585: 	    vty_out (vty,  "%02d:%02d:%02d", 
 1586: 		     tm->tm_hour, tm->tm_min, tm->tm_sec);
 1587: 	  else if (uptime < ONE_WEEK_SECOND)
 1588: 	    vty_out (vty, "%dd%02dh%02dm", 
 1589: 		     tm->tm_yday, tm->tm_hour, tm->tm_min);
 1590: 	  else
 1591: 	    vty_out (vty, "%02dw%dd%02dh", 
 1592: 		     tm->tm_yday/7,
 1593: 		     tm->tm_yday - ((tm->tm_yday/7) * 7), tm->tm_hour);
 1594: 	  vty_out (vty, " ago%s", VTY_NEWLINE);
 1595: 	}
 1596: 
 1597:       for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
 1598: 	{
 1599: 	  vty_out (vty, "  %c",
 1600: 		   CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB) ? '*' : ' ');
 1601: 
 1602: 	  switch (nexthop->type)
 1603: 	    {
 1604: 	    case NEXTHOP_TYPE_IPV6:
 1605: 	    case NEXTHOP_TYPE_IPV6_IFINDEX:
 1606: 	    case NEXTHOP_TYPE_IPV6_IFNAME:
 1607: 	      vty_out (vty, " %s",
 1608: 		       inet_ntop (AF_INET6, &nexthop->gate.ipv6, buf, BUFSIZ));
 1609: 	      if (nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME)
 1610: 		vty_out (vty, ", %s", nexthop->ifname);
 1611: 	      else if (nexthop->ifindex)
 1612: 		vty_out (vty, ", via %s", ifindex2ifname (nexthop->ifindex));
 1613: 	      break;
 1614: 	    case NEXTHOP_TYPE_IFINDEX:
 1615: 	      vty_out (vty, " directly connected, %s",
 1616: 		       ifindex2ifname (nexthop->ifindex));
 1617: 	      break;
 1618: 	    case NEXTHOP_TYPE_IFNAME:
 1619: 	      vty_out (vty, " directly connected, %s",
 1620: 		       nexthop->ifname);
 1621: 	      break;
 1622: 	    default:
 1623: 	      break;
 1624: 	    }
 1625: 	  if (! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
 1626: 	    vty_out (vty, " inactive");
 1627: 
 1628: 	  if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
 1629: 	    {
 1630: 	      vty_out (vty, " (recursive");
 1631: 		
 1632: 	      switch (nexthop->rtype)
 1633: 		{
 1634: 		case NEXTHOP_TYPE_IPV6:
 1635: 		case NEXTHOP_TYPE_IPV6_IFINDEX:
 1636: 		case NEXTHOP_TYPE_IPV6_IFNAME:
 1637: 		  vty_out (vty, " via %s)",
 1638: 			   inet_ntop (AF_INET6, &nexthop->rgate.ipv6,
 1639: 				      buf, BUFSIZ));
 1640: 		  if (nexthop->rifindex)
 1641: 		    vty_out (vty, ", %s", ifindex2ifname (nexthop->rifindex));
 1642: 		  break;
 1643: 		case NEXTHOP_TYPE_IFINDEX:
 1644: 		case NEXTHOP_TYPE_IFNAME:
 1645: 		  vty_out (vty, " is directly connected, %s)",
 1646: 			   ifindex2ifname (nexthop->rifindex));
 1647: 		  break;
 1648: 		default:
 1649: 		  break;
 1650: 		}
 1651: 	    }
 1652: 	  vty_out (vty, "%s", VTY_NEWLINE);
 1653: 	}
 1654:       vty_out (vty, "%s", VTY_NEWLINE);
 1655:     }
 1656: }
 1657: 
 1658: static void
 1659: vty_show_ipv6_route (struct vty *vty, struct route_node *rn,
 1660: 		     struct rib *rib)
 1661: {
 1662:   struct nexthop *nexthop;
 1663:   int len = 0;
 1664:   char buf[BUFSIZ];
 1665: 
 1666:   /* Nexthop information. */
 1667:   for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
 1668:     {
 1669:       if (nexthop == rib->nexthop)
 1670: 	{
 1671: 	  /* Prefix information. */
 1672: 	  len = vty_out (vty, "%c%c%c %s/%d",
 1673: 			 zebra_route_char (rib->type),
 1674: 			 CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED)
 1675: 			 ? '>' : ' ',
 1676: 			 CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)
 1677: 			 ? '*' : ' ',
 1678: 			 inet_ntop (AF_INET6, &rn->p.u.prefix6, buf, BUFSIZ),
 1679: 			 rn->p.prefixlen);
 1680: 
 1681: 	  /* Distance and metric display. */
 1682: 	  if (rib->type != ZEBRA_ROUTE_CONNECT 
 1683: 	      && rib->type != ZEBRA_ROUTE_KERNEL)
 1684: 	    len += vty_out (vty, " [%d/%d]", rib->distance,
 1685: 			    rib->metric);
 1686: 	}
 1687:       else
 1688: 	vty_out (vty, "  %c%*c",
 1689: 		 CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)
 1690: 		 ? '*' : ' ',
 1691: 		 len - 3, ' ');
 1692: 
 1693:       switch (nexthop->type)
 1694: 	{
 1695: 	case NEXTHOP_TYPE_IPV6:
 1696: 	case NEXTHOP_TYPE_IPV6_IFINDEX:
 1697: 	case NEXTHOP_TYPE_IPV6_IFNAME:
 1698: 	  vty_out (vty, " via %s",
 1699: 		   inet_ntop (AF_INET6, &nexthop->gate.ipv6, buf, BUFSIZ));
 1700: 	  if (nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME)
 1701: 	    vty_out (vty, ", %s", nexthop->ifname);
 1702: 	  else if (nexthop->ifindex)
 1703: 	    vty_out (vty, ", %s", ifindex2ifname (nexthop->ifindex));
 1704: 	  break;
 1705: 	case NEXTHOP_TYPE_IFINDEX:
 1706: 	  vty_out (vty, " is directly connected, %s",
 1707: 		   ifindex2ifname (nexthop->ifindex));
 1708: 	  break;
 1709: 	case NEXTHOP_TYPE_IFNAME:
 1710: 	  vty_out (vty, " is directly connected, %s",
 1711: 		   nexthop->ifname);
 1712: 	  break;
 1713: 	default:
 1714: 	  break;
 1715: 	}
 1716:       if (! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
 1717: 	vty_out (vty, " inactive");
 1718: 
 1719:       if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
 1720: 	{
 1721: 	  vty_out (vty, " (recursive");
 1722: 		
 1723: 	  switch (nexthop->rtype)
 1724: 	    {
 1725: 	    case NEXTHOP_TYPE_IPV6:
 1726: 	    case NEXTHOP_TYPE_IPV6_IFINDEX:
 1727: 	    case NEXTHOP_TYPE_IPV6_IFNAME:
 1728: 	      vty_out (vty, " via %s)",
 1729: 		       inet_ntop (AF_INET6, &nexthop->rgate.ipv6,
 1730: 				  buf, BUFSIZ));
 1731: 	      if (nexthop->rifindex)
 1732: 		vty_out (vty, ", %s", ifindex2ifname (nexthop->rifindex));
 1733: 	      break;
 1734: 	    case NEXTHOP_TYPE_IFINDEX:
 1735: 	    case NEXTHOP_TYPE_IFNAME:
 1736: 	      vty_out (vty, " is directly connected, %s)",
 1737: 		       ifindex2ifname (nexthop->rifindex));
 1738: 	      break;
 1739: 	    default:
 1740: 	      break;
 1741: 	    }
 1742: 	}
 1743: 
 1744:       if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_BLACKHOLE))
 1745:        vty_out (vty, ", bh");
 1746:       if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_REJECT))
 1747:        vty_out (vty, ", rej");
 1748:       
 1749:       if (rib->type == ZEBRA_ROUTE_RIPNG
 1750: 	  || rib->type == ZEBRA_ROUTE_OSPF6
 1751: 	  || rib->type == ZEBRA_ROUTE_BABEL
 1752: 	  || rib->type == ZEBRA_ROUTE_ISIS
 1753: 	  || rib->type == ZEBRA_ROUTE_BGP)
 1754: 	{
 1755: 	  time_t uptime;
 1756: 	  struct tm *tm;
 1757: 
 1758: 	  uptime = time (NULL);
 1759: 	  uptime -= rib->uptime;
 1760: 	  tm = gmtime (&uptime);
 1761: 
 1762: #define ONE_DAY_SECOND 60*60*24
 1763: #define ONE_WEEK_SECOND 60*60*24*7
 1764: 
 1765: 	  if (uptime < ONE_DAY_SECOND)
 1766: 	    vty_out (vty,  ", %02d:%02d:%02d", 
 1767: 		     tm->tm_hour, tm->tm_min, tm->tm_sec);
 1768: 	  else if (uptime < ONE_WEEK_SECOND)
 1769: 	    vty_out (vty, ", %dd%02dh%02dm", 
 1770: 		     tm->tm_yday, tm->tm_hour, tm->tm_min);
 1771: 	  else
 1772: 	    vty_out (vty, ", %02dw%dd%02dh", 
 1773: 		     tm->tm_yday/7,
 1774: 		     tm->tm_yday - ((tm->tm_yday/7) * 7), tm->tm_hour);
 1775: 	}
 1776:       vty_out (vty, "%s", VTY_NEWLINE);
 1777:     }
 1778: }
 1779: 
 1780: DEFUN (show_ipv6_route,
 1781:        show_ipv6_route_cmd,
 1782:        "show ipv6 route",
 1783:        SHOW_STR
 1784:        IP_STR
 1785:        "IPv6 routing table\n")
 1786: {
 1787:   struct route_table *table;
 1788:   struct route_node *rn;
 1789:   struct rib *rib;
 1790:   int first = 1;
 1791: 
 1792:   table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
 1793:   if (! table)
 1794:     return CMD_SUCCESS;
 1795: 
 1796:   /* Show all IPv6 route. */
 1797:   for (rn = route_top (table); rn; rn = route_next (rn))
 1798:     RNODE_FOREACH_RIB (rn, rib)
 1799:       {
 1800: 	if (first)
 1801: 	  {
 1802: 	    vty_out (vty, SHOW_ROUTE_V6_HEADER);
 1803: 	    first = 0;
 1804: 	  }
 1805: 	vty_show_ipv6_route (vty, rn, rib);
 1806:       }
 1807:   return CMD_SUCCESS;
 1808: }
 1809: 
 1810: DEFUN (show_ipv6_route_prefix_longer,
 1811:        show_ipv6_route_prefix_longer_cmd,
 1812:        "show ipv6 route X:X::X:X/M longer-prefixes",
 1813:        SHOW_STR
 1814:        IP_STR
 1815:        "IPv6 routing table\n"
 1816:        "IPv6 prefix\n"
 1817:        "Show route matching the specified Network/Mask pair only\n")
 1818: {
 1819:   struct route_table *table;
 1820:   struct route_node *rn;
 1821:   struct rib *rib;
 1822:   struct prefix p;
 1823:   int ret;
 1824:   int first = 1;
 1825: 
 1826:   table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
 1827:   if (! table)
 1828:     return CMD_SUCCESS;
 1829: 
 1830:   ret = str2prefix (argv[0], &p);
 1831:   if (! ret)
 1832:     {
 1833:       vty_out (vty, "%% Malformed Prefix%s", VTY_NEWLINE);
 1834:       return CMD_WARNING;
 1835:     }
 1836: 
 1837:   /* Show matched type IPv6 routes. */
 1838:   for (rn = route_top (table); rn; rn = route_next (rn))
 1839:     RNODE_FOREACH_RIB (rn, rib)
 1840:       if (prefix_match (&p, &rn->p))
 1841: 	{
 1842: 	  if (first)
 1843: 	    {
 1844: 	      vty_out (vty, SHOW_ROUTE_V6_HEADER);
 1845: 	      first = 0;
 1846: 	    }
 1847: 	  vty_show_ipv6_route (vty, rn, rib);
 1848: 	}
 1849:   return CMD_SUCCESS;
 1850: }
 1851: 
 1852: DEFUN (show_ipv6_route_protocol,
 1853:        show_ipv6_route_protocol_cmd,
 1854:        "show ipv6 route " QUAGGA_IP6_REDIST_STR_ZEBRA,
 1855:        SHOW_STR
 1856:        IP_STR
 1857:        "IP routing table\n"
 1858: 	QUAGGA_IP6_REDIST_HELP_STR_ZEBRA)
 1859: {
 1860:   int type;
 1861:   struct route_table *table;
 1862:   struct route_node *rn;
 1863:   struct rib *rib;
 1864:   int first = 1;
 1865: 
 1866:   type = proto_redistnum (AFI_IP6, argv[0]);
 1867:   if (type < 0)
 1868:     {
 1869:       vty_out (vty, "Unknown route type%s", VTY_NEWLINE);
 1870:       return CMD_WARNING;
 1871:     }
 1872:   
 1873:   table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
 1874:   if (! table)
 1875:     return CMD_SUCCESS;
 1876: 
 1877:   /* Show matched type IPv6 routes. */
 1878:   for (rn = route_top (table); rn; rn = route_next (rn))
 1879:     RNODE_FOREACH_RIB (rn, rib)
 1880:       if (rib->type == type)
 1881: 	{
 1882: 	  if (first)
 1883: 	    {
 1884: 	      vty_out (vty, SHOW_ROUTE_V6_HEADER);
 1885: 	      first = 0;
 1886: 	    }
 1887: 	  vty_show_ipv6_route (vty, rn, rib);
 1888: 	}
 1889:   return CMD_SUCCESS;
 1890: }
 1891: 
 1892: DEFUN (show_ipv6_route_addr,
 1893:        show_ipv6_route_addr_cmd,
 1894:        "show ipv6 route X:X::X:X",
 1895:        SHOW_STR
 1896:        IP_STR
 1897:        "IPv6 routing table\n"
 1898:        "IPv6 Address\n")
 1899: {
 1900:   int ret;
 1901:   struct prefix_ipv6 p;
 1902:   struct route_table *table;
 1903:   struct route_node *rn;
 1904: 
 1905:   ret = str2prefix_ipv6 (argv[0], &p);
 1906:   if (ret <= 0)
 1907:     {
 1908:       vty_out (vty, "Malformed IPv6 address%s", VTY_NEWLINE);
 1909:       return CMD_WARNING;
 1910:     }
 1911: 
 1912:   table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
 1913:   if (! table)
 1914:     return CMD_SUCCESS;
 1915: 
 1916:   rn = route_node_match (table, (struct prefix *) &p);
 1917:   if (! rn)
 1918:     {
 1919:       vty_out (vty, "%% Network not in table%s", VTY_NEWLINE);
 1920:       return CMD_WARNING;
 1921:     }
 1922: 
 1923:   vty_show_ipv6_route_detail (vty, rn);
 1924: 
 1925:   route_unlock_node (rn);
 1926: 
 1927:   return CMD_SUCCESS;
 1928: }
 1929: 
 1930: DEFUN (show_ipv6_route_prefix,
 1931:        show_ipv6_route_prefix_cmd,
 1932:        "show ipv6 route X:X::X:X/M",
 1933:        SHOW_STR
 1934:        IP_STR
 1935:        "IPv6 routing table\n"
 1936:        "IPv6 prefix\n")
 1937: {
 1938:   int ret;
 1939:   struct prefix_ipv6 p;
 1940:   struct route_table *table;
 1941:   struct route_node *rn;
 1942: 
 1943:   ret = str2prefix_ipv6 (argv[0], &p);
 1944:   if (ret <= 0)
 1945:     {
 1946:       vty_out (vty, "Malformed IPv6 prefix%s", VTY_NEWLINE);
 1947:       return CMD_WARNING;
 1948:     }
 1949: 
 1950:   table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
 1951:   if (! table)
 1952:     return CMD_SUCCESS;
 1953: 
 1954:   rn = route_node_match (table, (struct prefix *) &p);
 1955:   if (! rn || rn->p.prefixlen != p.prefixlen)
 1956:     {
 1957:       vty_out (vty, "%% Network not in table%s", VTY_NEWLINE);
 1958:       return CMD_WARNING;
 1959:     }
 1960: 
 1961:   vty_show_ipv6_route_detail (vty, rn);
 1962: 
 1963:   route_unlock_node (rn);
 1964: 
 1965:   return CMD_SUCCESS;
 1966: }
 1967: 
 1968: /* Show route summary.  */
 1969: DEFUN (show_ipv6_route_summary,
 1970:        show_ipv6_route_summary_cmd,
 1971:        "show ipv6 route summary",
 1972:        SHOW_STR
 1973:        IP_STR
 1974:        "IPv6 routing table\n"
 1975:        "Summary of all IPv6 routes\n")
 1976: {
 1977:   struct route_table *table;
 1978: 
 1979:   table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
 1980:   if (! table)
 1981:     return CMD_SUCCESS;
 1982: 
 1983:   vty_show_ip_route_summary (vty, table);
 1984: 
 1985:   return CMD_SUCCESS;
 1986: }
 1987: 
 1988: /*
 1989:  * Show IPv6 mroute command.Used to dump
 1990:  * the Multicast routing table.
 1991:  */
 1992: 
 1993: DEFUN (show_ipv6_mroute,
 1994:        show_ipv6_mroute_cmd,
 1995:        "show ipv6 mroute",
 1996:        SHOW_STR
 1997:        IP_STR
 1998:        "IPv6 Multicast routing table\n")
 1999: {
 2000:   struct route_table *table;
 2001:   struct route_node *rn;
 2002:   struct rib *rib;
 2003:   int first = 1;
 2004: 
 2005:   table = vrf_table (AFI_IP6, SAFI_MULTICAST, 0);
 2006:   if (! table)
 2007:     return CMD_SUCCESS;
 2008: 
 2009:   /* Show all IPv6 route. */
 2010:   for (rn = route_top (table); rn; rn = route_next (rn))
 2011:     RNODE_FOREACH_RIB (rn, rib)
 2012:       {
 2013:        if (first)
 2014:          {
 2015: 	   vty_out (vty, SHOW_ROUTE_V6_HEADER);
 2016:            first = 0;
 2017:          }
 2018:        vty_show_ipv6_route (vty, rn, rib);
 2019:       }
 2020:   return CMD_SUCCESS;
 2021: }
 2022: 
 2023: /* Write IPv6 static route configuration. */
 2024: static int
 2025: static_config_ipv6 (struct vty *vty)
 2026: {
 2027:   struct route_node *rn;
 2028:   struct static_ipv6 *si;  
 2029:   int write;
 2030:   char buf[BUFSIZ];
 2031:   struct route_table *stable;
 2032: 
 2033:   write = 0;
 2034: 
 2035:   /* Lookup table.  */
 2036:   stable = vrf_static_table (AFI_IP6, SAFI_UNICAST, 0);
 2037:   if (! stable)
 2038:     return -1;
 2039: 
 2040:   for (rn = route_top (stable); rn; rn = route_next (rn))
 2041:     for (si = rn->info; si; si = si->next)
 2042:       {
 2043: 	vty_out (vty, "ipv6 route %s/%d",
 2044: 		 inet_ntop (AF_INET6, &rn->p.u.prefix6, buf, BUFSIZ),
 2045: 		 rn->p.prefixlen);
 2046: 
 2047: 	switch (si->type)
 2048: 	  {
 2049: 	  case STATIC_IPV6_GATEWAY:
 2050: 	    vty_out (vty, " %s", inet_ntop (AF_INET6, &si->ipv6, buf, BUFSIZ));
 2051: 	    break;
 2052: 	  case STATIC_IPV6_IFNAME:
 2053: 	    vty_out (vty, " %s", si->ifname);
 2054: 	    break;
 2055: 	  case STATIC_IPV6_GATEWAY_IFNAME:
 2056: 	    vty_out (vty, " %s %s",
 2057: 		     inet_ntop (AF_INET6, &si->ipv6, buf, BUFSIZ), si->ifname);
 2058: 	    break;
 2059: 	  }
 2060: 
 2061:        if (CHECK_FLAG(si->flags, ZEBRA_FLAG_REJECT))
 2062:                vty_out (vty, " %s", "reject");
 2063: 
 2064:        if (CHECK_FLAG(si->flags, ZEBRA_FLAG_BLACKHOLE))
 2065:                vty_out (vty, " %s", "blackhole");
 2066: 
 2067: 	if (si->distance != ZEBRA_STATIC_DISTANCE_DEFAULT)
 2068: 	  vty_out (vty, " %d", si->distance);
 2069: 	vty_out (vty, "%s", VTY_NEWLINE);
 2070: 
 2071: 	write = 1;
 2072:       }
 2073:   return write;
 2074: }
 2075: #endif /* HAVE_IPV6 */
 2076: 
 2077: /* Static ip route configuration write function. */
 2078: static int
 2079: zebra_ip_config (struct vty *vty)
 2080: {
 2081:   int write = 0;
 2082: 
 2083:   write += static_config_ipv4 (vty);
 2084: #ifdef HAVE_IPV6
 2085:   write += static_config_ipv6 (vty);
 2086: #endif /* HAVE_IPV6 */
 2087: 
 2088:   return write;
 2089: }
 2090: 
 2091: /* ip protocol configuration write function */
 2092: static int config_write_protocol(struct vty *vty)
 2093: {  
 2094:   int i;
 2095: 
 2096:   for (i=0;i<ZEBRA_ROUTE_MAX;i++)
 2097:     {
 2098:       if (proto_rm[AFI_IP][i])
 2099:         vty_out (vty, "ip protocol %s route-map %s%s", zebra_route_string(i),
 2100:                  proto_rm[AFI_IP][i], VTY_NEWLINE);
 2101:     }
 2102:   if (proto_rm[AFI_IP][ZEBRA_ROUTE_MAX])
 2103:       vty_out (vty, "ip protocol %s route-map %s%s", "any",
 2104:                proto_rm[AFI_IP][ZEBRA_ROUTE_MAX], VTY_NEWLINE);
 2105: 
 2106:   return 1;
 2107: }   
 2108: 
 2109: /* table node for protocol filtering */
 2110: static struct cmd_node protocol_node = { PROTOCOL_NODE, "", 1 };
 2111: 
 2112: /* IP node for static routes. */
 2113: static struct cmd_node ip_node = { IP_NODE,  "",  1 };
 2114: 
 2115: /* Route VTY.  */
 2116: void
 2117: zebra_vty_init (void)
 2118: {
 2119:   install_node (&ip_node, zebra_ip_config);
 2120:   install_node (&protocol_node, config_write_protocol);
 2121: 
 2122:   install_element (CONFIG_NODE, &ip_protocol_cmd);
 2123:   install_element (CONFIG_NODE, &no_ip_protocol_cmd);
 2124:   install_element (VIEW_NODE, &show_ip_protocol_cmd);
 2125:   install_element (ENABLE_NODE, &show_ip_protocol_cmd);
 2126:   install_element (CONFIG_NODE, &ip_route_cmd);
 2127:   install_element (CONFIG_NODE, &ip_route_flags_cmd);
 2128:   install_element (CONFIG_NODE, &ip_route_flags2_cmd);
 2129:   install_element (CONFIG_NODE, &ip_route_mask_cmd);
 2130:   install_element (CONFIG_NODE, &ip_route_mask_flags_cmd);
 2131:   install_element (CONFIG_NODE, &ip_route_mask_flags2_cmd);
 2132:   install_element (CONFIG_NODE, &no_ip_route_cmd);
 2133:   install_element (CONFIG_NODE, &no_ip_route_flags_cmd);
 2134:   install_element (CONFIG_NODE, &no_ip_route_flags2_cmd);
 2135:   install_element (CONFIG_NODE, &no_ip_route_mask_cmd);
 2136:   install_element (CONFIG_NODE, &no_ip_route_mask_flags_cmd);
 2137:   install_element (CONFIG_NODE, &no_ip_route_mask_flags2_cmd);
 2138:   install_element (CONFIG_NODE, &ip_route_distance_cmd);
 2139:   install_element (CONFIG_NODE, &ip_route_flags_distance_cmd);
 2140:   install_element (CONFIG_NODE, &ip_route_flags_distance2_cmd);
 2141:   install_element (CONFIG_NODE, &ip_route_mask_distance_cmd);
 2142:   install_element (CONFIG_NODE, &ip_route_mask_flags_distance_cmd);
 2143:   install_element (CONFIG_NODE, &ip_route_mask_flags_distance2_cmd);
 2144:   install_element (CONFIG_NODE, &no_ip_route_distance_cmd);
 2145:   install_element (CONFIG_NODE, &no_ip_route_flags_distance_cmd);
 2146:   install_element (CONFIG_NODE, &no_ip_route_flags_distance2_cmd);
 2147:   install_element (CONFIG_NODE, &no_ip_route_mask_flags_distance_cmd);
 2148:   install_element (CONFIG_NODE, &no_ip_route_mask_flags_distance2_cmd);
 2149: 
 2150:   install_element (VIEW_NODE, &show_ip_route_cmd);
 2151:   install_element (VIEW_NODE, &show_ip_route_addr_cmd);
 2152:   install_element (VIEW_NODE, &show_ip_route_prefix_cmd);
 2153:   install_element (VIEW_NODE, &show_ip_route_prefix_longer_cmd);
 2154:   install_element (VIEW_NODE, &show_ip_route_protocol_cmd);
 2155:   install_element (VIEW_NODE, &show_ip_route_supernets_cmd);
 2156:   install_element (VIEW_NODE, &show_ip_route_summary_cmd);
 2157:   install_element (ENABLE_NODE, &show_ip_route_cmd);
 2158:   install_element (ENABLE_NODE, &show_ip_route_addr_cmd);
 2159:   install_element (ENABLE_NODE, &show_ip_route_prefix_cmd);
 2160:   install_element (ENABLE_NODE, &show_ip_route_prefix_longer_cmd);
 2161:   install_element (ENABLE_NODE, &show_ip_route_protocol_cmd);
 2162:   install_element (ENABLE_NODE, &show_ip_route_supernets_cmd);
 2163:   install_element (ENABLE_NODE, &show_ip_route_summary_cmd);
 2164: 
 2165:   install_element (VIEW_NODE, &show_ip_mroute_cmd);
 2166:   install_element (ENABLE_NODE, &show_ip_mroute_cmd);
 2167: 
 2168: 
 2169: #ifdef HAVE_IPV6
 2170:   install_element (CONFIG_NODE, &ipv6_route_cmd);
 2171:   install_element (CONFIG_NODE, &ipv6_route_flags_cmd);
 2172:   install_element (CONFIG_NODE, &ipv6_route_ifname_cmd);
 2173:   install_element (CONFIG_NODE, &ipv6_route_ifname_flags_cmd);
 2174:   install_element (CONFIG_NODE, &no_ipv6_route_cmd);
 2175:   install_element (CONFIG_NODE, &no_ipv6_route_flags_cmd);
 2176:   install_element (CONFIG_NODE, &no_ipv6_route_ifname_cmd);
 2177:   install_element (CONFIG_NODE, &no_ipv6_route_ifname_flags_cmd);
 2178:   install_element (CONFIG_NODE, &ipv6_route_pref_cmd);
 2179:   install_element (CONFIG_NODE, &ipv6_route_flags_pref_cmd);
 2180:   install_element (CONFIG_NODE, &ipv6_route_ifname_pref_cmd);
 2181:   install_element (CONFIG_NODE, &ipv6_route_ifname_flags_pref_cmd);
 2182:   install_element (CONFIG_NODE, &no_ipv6_route_pref_cmd);
 2183:   install_element (CONFIG_NODE, &no_ipv6_route_flags_pref_cmd);
 2184:   install_element (CONFIG_NODE, &no_ipv6_route_ifname_pref_cmd);
 2185:   install_element (CONFIG_NODE, &no_ipv6_route_ifname_flags_pref_cmd);
 2186:   install_element (VIEW_NODE, &show_ipv6_route_cmd);
 2187:   install_element (VIEW_NODE, &show_ipv6_route_summary_cmd);
 2188:   install_element (VIEW_NODE, &show_ipv6_route_protocol_cmd);
 2189:   install_element (VIEW_NODE, &show_ipv6_route_addr_cmd);
 2190:   install_element (VIEW_NODE, &show_ipv6_route_prefix_cmd);
 2191:   install_element (VIEW_NODE, &show_ipv6_route_prefix_longer_cmd);
 2192:   install_element (ENABLE_NODE, &show_ipv6_route_cmd);
 2193:   install_element (ENABLE_NODE, &show_ipv6_route_protocol_cmd);
 2194:   install_element (ENABLE_NODE, &show_ipv6_route_addr_cmd);
 2195:   install_element (ENABLE_NODE, &show_ipv6_route_prefix_cmd);
 2196:   install_element (ENABLE_NODE, &show_ipv6_route_prefix_longer_cmd);
 2197:   install_element (ENABLE_NODE, &show_ipv6_route_summary_cmd);
 2198: 
 2199:   install_element (VIEW_NODE, &show_ipv6_mroute_cmd);
 2200:   install_element (ENABLE_NODE, &show_ipv6_mroute_cmd);
 2201: #endif /* HAVE_IPV6 */
 2202: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>