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