blob: c8168c90e1e635a10095fefd903d868ed05156ad [file] [log] [blame]
paul718e3742002-12-13 20:15:29 +00001/* 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 "if.h"
25#include "prefix.h"
26#include "command.h"
27#include "table.h"
28#include "rib.h"
29
30/* Return route type string for VTY output. */
31const char *
32route_type_str (u_char type)
33{
34 switch (type)
35 {
36 case ZEBRA_ROUTE_SYSTEM:
37 return "system";
38 case ZEBRA_ROUTE_KERNEL:
39 return "kernel";
40 case ZEBRA_ROUTE_CONNECT:
41 return "connected";
42 case ZEBRA_ROUTE_STATIC:
43 return "static";
44 case ZEBRA_ROUTE_RIP:
45 return "rip";
46 case ZEBRA_ROUTE_RIPNG:
47 return "rip";
48 case ZEBRA_ROUTE_OSPF:
49 return "ospf";
50 case ZEBRA_ROUTE_OSPF6:
51 return "ospf";
52 case ZEBRA_ROUTE_BGP:
53 return "bgp";
54 default:
55 return "unknown";
56 }
57};
58
59/* Return route type string for VTY output. */
60const char
61route_type_char (u_char type)
62{
63 switch (type)
64 {
65 case ZEBRA_ROUTE_SYSTEM:
66 return 'S';
67 case ZEBRA_ROUTE_KERNEL:
68 return 'K';
69 case ZEBRA_ROUTE_CONNECT:
70 return 'C';
71 case ZEBRA_ROUTE_STATIC:
72 return 'S';
73 case ZEBRA_ROUTE_RIP:
74 return 'R';
75 case ZEBRA_ROUTE_RIPNG:
76 return 'R';
77 case ZEBRA_ROUTE_OSPF:
78 return 'O';
79 case ZEBRA_ROUTE_OSPF6:
80 return 'O';
81 case ZEBRA_ROUTE_BGP:
82 return 'B';
83 default:
84 return '?';
85 }
86};
87
88/* General fucntion for static route. */
89int
90zebra_static_ipv4 (struct vty *vty, int add_cmd,
91 char *dest_str, char *mask_str, char *gate_str,
hasso81dfcaa2003-05-25 19:21:25 +000092 char *flag_str, char *distance_str)
paul718e3742002-12-13 20:15:29 +000093{
94 int ret;
95 u_char distance;
96 struct prefix p;
97 struct in_addr gate;
98 struct in_addr mask;
99 char *ifname;
hasso81dfcaa2003-05-25 19:21:25 +0000100 u_char flag = 0;
paul718e3742002-12-13 20:15:29 +0000101
102 ret = str2prefix (dest_str, &p);
103 if (ret <= 0)
104 {
105 vty_out (vty, "%% Malformed address%s", VTY_NEWLINE);
106 return CMD_WARNING;
107 }
108
109 /* Cisco like mask notation. */
110 if (mask_str)
111 {
112 ret = inet_aton (mask_str, &mask);
113 if (ret == 0)
paul595db7f2003-05-25 21:35:06 +0000114 {
115 vty_out (vty, "%% Malformed address%s", VTY_NEWLINE);
116 return CMD_WARNING;
117 }
paul718e3742002-12-13 20:15:29 +0000118 p.prefixlen = ip_masklen (mask);
119 }
120
121 /* Apply mask for given prefix. */
122 apply_mask (&p);
123
paul595db7f2003-05-25 21:35:06 +0000124 /* Administrative distance. */
125 if (distance_str)
126 distance = atoi (distance_str);
127 else
128 distance = ZEBRA_STATIC_DISTANCE_DEFAULT;
129
130 /* Null0 static route. */
131 if (strncasecmp (gate_str, "Null0", strlen (gate_str)) == 0)
132 {
133 if (flag_str)
134 {
135 vty_out (vty, "%% can not have flag %s with Null0%s", flag_str, VTY_NEWLINE);
136 return CMD_WARNING;
137 }
138 if (add_cmd)
139 static_add_ipv4 (&p, NULL, NULL, 0, distance, 0);
140 else
141 static_delete_ipv4 (&p, NULL, NULL, distance, 0);
142 return CMD_SUCCESS;
143 }
144
hasso81dfcaa2003-05-25 19:21:25 +0000145 /* Route flags */
146 if (flag_str) {
147 switch(flag_str[0]) {
148 case 'r':
149 case 'R': /* XXX */
150 SET_FLAG (flag, ZEBRA_FLAG_REJECT);
151 break;
152 case 'b':
153 case 'B': /* XXX */
154 SET_FLAG (flag, ZEBRA_FLAG_BLACKHOLE);
155 break;
156 default:
157 vty_out (vty, "%% Malformed flag %s %s", flag_str, VTY_NEWLINE);
paul595db7f2003-05-25 21:35:06 +0000158 return CMD_WARNING;
hasso81dfcaa2003-05-25 19:21:25 +0000159 }
160 }
161
paul718e3742002-12-13 20:15:29 +0000162 /* When gateway is A.B.C.D format, gate is treated as nexthop
163 address other case gate is treated as interface name. */
164 ret = inet_aton (gate_str, &gate);
165 if (ret)
166 ifname = NULL;
167 else
168 ifname = gate_str;
169
170 if (add_cmd)
hasso81dfcaa2003-05-25 19:21:25 +0000171 static_add_ipv4 (&p, ifname ? NULL : &gate, ifname, flag, distance, 0);
paul718e3742002-12-13 20:15:29 +0000172 else
173 static_delete_ipv4 (&p, ifname ? NULL : &gate, ifname, distance, 0);
174
175 return CMD_SUCCESS;
176}
177
178/* Static route configuration. */
179DEFUN (ip_route,
180 ip_route_cmd,
paul595db7f2003-05-25 21:35:06 +0000181 "ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0)",
hasso81dfcaa2003-05-25 19:21:25 +0000182 IP_STR
183 "Establish static routes\n"
184 "IP destination prefix (e.g. 10.0.0.0/8)\n"
185 "IP gateway address\n"
paul595db7f2003-05-25 21:35:06 +0000186 "IP gateway interface name\n"
187 "Null interface\n")
hasso81dfcaa2003-05-25 19:21:25 +0000188{
189 return zebra_static_ipv4 (vty, 1, argv[0], NULL, argv[1], NULL, NULL);
190}
191
192DEFUN (ip_route_flags,
193 ip_route_flags_cmd,
194 "ip route A.B.C.D/M (A.B.C.D|INTERFACE) (reject|blackhole)",
paul718e3742002-12-13 20:15:29 +0000195 IP_STR
196 "Establish static routes\n"
197 "IP destination prefix (e.g. 10.0.0.0/8)\n"
198 "IP gateway address\n"
199 "IP gateway interface name\n"
hasso81dfcaa2003-05-25 19:21:25 +0000200 "Emit an ICMP unreachable when matched\n"
201 "Silently discard pkts when matched\n")
paul718e3742002-12-13 20:15:29 +0000202{
hasso81dfcaa2003-05-25 19:21:25 +0000203 return zebra_static_ipv4 (vty, 1, argv[0], NULL, argv[1], argv[2], NULL);
paul718e3742002-12-13 20:15:29 +0000204}
205
206/* Mask as A.B.C.D format. */
207DEFUN (ip_route_mask,
208 ip_route_mask_cmd,
paul595db7f2003-05-25 21:35:06 +0000209 "ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0)",
hasso81dfcaa2003-05-25 19:21:25 +0000210 IP_STR
211 "Establish static routes\n"
212 "IP destination prefix\n"
213 "IP destination prefix mask\n"
214 "IP gateway address\n"
paul595db7f2003-05-25 21:35:06 +0000215 "IP gateway interface name\n"
216 "Null interface\n")
hasso81dfcaa2003-05-25 19:21:25 +0000217{
218 return zebra_static_ipv4 (vty, 1, argv[0], argv[1], argv[2], NULL, NULL);
219}
220
221DEFUN (ip_route_mask_flags,
222 ip_route_mask_flags_cmd,
223 "ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE) (reject|blackhole)",
paul718e3742002-12-13 20:15:29 +0000224 IP_STR
225 "Establish static routes\n"
226 "IP destination prefix\n"
227 "IP destination prefix mask\n"
228 "IP gateway address\n"
229 "IP gateway interface name\n"
hasso81dfcaa2003-05-25 19:21:25 +0000230 "Emit an ICMP unreachable when matched\n"
231 "Silently discard pkts when matched\n")
paul718e3742002-12-13 20:15:29 +0000232{
hasso81dfcaa2003-05-25 19:21:25 +0000233 return zebra_static_ipv4 (vty, 1, argv[0], argv[1], argv[2], argv[3], NULL);
paul718e3742002-12-13 20:15:29 +0000234}
235
236/* Distance option value. */
237DEFUN (ip_route_distance,
238 ip_route_distance_cmd,
paul595db7f2003-05-25 21:35:06 +0000239 "ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0) <1-255>",
paul718e3742002-12-13 20:15:29 +0000240 IP_STR
241 "Establish static routes\n"
242 "IP destination prefix (e.g. 10.0.0.0/8)\n"
243 "IP gateway address\n"
244 "IP gateway interface name\n"
paul595db7f2003-05-25 21:35:06 +0000245 "Null interface\n"
paul718e3742002-12-13 20:15:29 +0000246 "Distance value for this route\n")
247{
hasso81dfcaa2003-05-25 19:21:25 +0000248 return zebra_static_ipv4 (vty, 1, argv[0], NULL, argv[1], NULL, argv[2]);
249}
250
251DEFUN (ip_route_flags_distance,
252 ip_route_flags_distance_cmd,
253 "ip route A.B.C.D/M (A.B.C.D|INTERFACE) (reject|blackhole) <1-255>",
254 IP_STR
255 "Establish static routes\n"
256 "IP destination prefix (e.g. 10.0.0.0/8)\n"
257 "IP gateway address\n"
258 "IP gateway interface name\n"
259 "Emit an ICMP unreachable when matched\n"
260 "Silently discard pkts when matched\n"
261 "Distance value for this route\n")
262{
263 return zebra_static_ipv4 (vty, 1, argv[0], NULL, argv[1], argv[2], argv[3]);
paul718e3742002-12-13 20:15:29 +0000264}
265
266DEFUN (ip_route_mask_distance,
267 ip_route_mask_distance_cmd,
paul595db7f2003-05-25 21:35:06 +0000268 "ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0) <1-255>",
paul718e3742002-12-13 20:15:29 +0000269 IP_STR
270 "Establish static routes\n"
271 "IP destination prefix\n"
272 "IP destination prefix mask\n"
273 "IP gateway address\n"
274 "IP gateway interface name\n"
paul595db7f2003-05-25 21:35:06 +0000275 "Null interface\n"
paul718e3742002-12-13 20:15:29 +0000276 "Distance value for this route\n")
277{
hasso81dfcaa2003-05-25 19:21:25 +0000278 return zebra_static_ipv4 (vty, 1, argv[0], argv[1], argv[2], NULL, argv[3]);
279}
280
281DEFUN (ip_route_mask_flags_distance,
282 ip_route_mask_flags_distance_cmd,
283 "ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE) (reject|blackhole) <1-255>",
284 IP_STR
285 "Establish static routes\n"
286 "IP destination prefix\n"
287 "IP destination prefix mask\n"
288 "IP gateway address\n"
289 "IP gateway interface name\n"
290 "Distance value for this route\n"
291 "Emit an ICMP unreachable when matched\n"
292 "Silently discard pkts when matched\n")
293{
294 return zebra_static_ipv4 (vty, 1, argv[0], argv[1], argv[2], argv[3], argv[4]);
paul718e3742002-12-13 20:15:29 +0000295}
296
297DEFUN (no_ip_route,
298 no_ip_route_cmd,
paul595db7f2003-05-25 21:35:06 +0000299 "no ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0)",
hasso81dfcaa2003-05-25 19:21:25 +0000300 NO_STR
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"
paul595db7f2003-05-25 21:35:06 +0000305 "IP gateway interface name\n"
306 "Null interface\n")
hasso81dfcaa2003-05-25 19:21:25 +0000307{
308 return zebra_static_ipv4 (vty, 0, argv[0], NULL, argv[1], NULL, NULL);
309}
310
311ALIAS (no_ip_route,
312 no_ip_route_flags_cmd,
313 "no ip route A.B.C.D/M (A.B.C.D|INTERFACE) (reject|blackhole)",
paul718e3742002-12-13 20:15:29 +0000314 NO_STR
315 IP_STR
316 "Establish static routes\n"
317 "IP destination prefix (e.g. 10.0.0.0/8)\n"
318 "IP gateway address\n"
319 "IP gateway interface name\n"
hasso81dfcaa2003-05-25 19:21:25 +0000320 "Emit an ICMP unreachable when matched\n"
321 "Silently discard pkts when matched\n")
paul718e3742002-12-13 20:15:29 +0000322
323DEFUN (no_ip_route_mask,
324 no_ip_route_mask_cmd,
paul595db7f2003-05-25 21:35:06 +0000325 "no ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0)",
hasso81dfcaa2003-05-25 19:21:25 +0000326 NO_STR
327 IP_STR
328 "Establish static routes\n"
329 "IP destination prefix\n"
330 "IP destination prefix mask\n"
331 "IP gateway address\n"
paul595db7f2003-05-25 21:35:06 +0000332 "IP gateway interface name\n"
333 "Null interface\n")
hasso81dfcaa2003-05-25 19:21:25 +0000334{
335 return zebra_static_ipv4 (vty, 0, argv[0], argv[1], argv[2], NULL, NULL);
336}
337
338ALIAS (no_ip_route_mask,
339 no_ip_route_mask_flags_cmd,
340 "no ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE) (reject|blackhole)",
paul718e3742002-12-13 20:15:29 +0000341 NO_STR
342 IP_STR
343 "Establish static routes\n"
344 "IP destination prefix\n"
345 "IP destination prefix mask\n"
346 "IP gateway address\n"
347 "IP gateway interface name\n"
hasso81dfcaa2003-05-25 19:21:25 +0000348 "Emit an ICMP unreachable when matched\n"
349 "Silently discard pkts when matched\n")
paul718e3742002-12-13 20:15:29 +0000350
351DEFUN (no_ip_route_distance,
352 no_ip_route_distance_cmd,
paul595db7f2003-05-25 21:35:06 +0000353 "no ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0) <1-255>",
paul718e3742002-12-13 20:15:29 +0000354 NO_STR
355 IP_STR
356 "Establish static routes\n"
357 "IP destination prefix (e.g. 10.0.0.0/8)\n"
358 "IP gateway address\n"
359 "IP gateway interface name\n"
paul595db7f2003-05-25 21:35:06 +0000360 "Null interface\n"
paul718e3742002-12-13 20:15:29 +0000361 "Distance value for this route\n")
362{
hasso81dfcaa2003-05-25 19:21:25 +0000363 return zebra_static_ipv4 (vty, 0, argv[0], NULL, argv[1], NULL, argv[2]);
364}
365
366DEFUN (no_ip_route_flags_distance,
367 no_ip_route_flags_distance_cmd,
368 "no ip route A.B.C.D/M (A.B.C.D|INTERFACE) (reject|blackhole) <1-255>",
369 NO_STR
370 IP_STR
371 "Establish static routes\n"
372 "IP destination prefix (e.g. 10.0.0.0/8)\n"
373 "IP gateway address\n"
374 "IP gateway interface name\n"
375 "Emit an ICMP unreachable when matched\n"
376 "Silently discard pkts when matched\n"
377 "Distance value for this route\n")
378{
379 return zebra_static_ipv4 (vty, 0, argv[0], NULL, argv[1], argv[2], argv[3]);
paul718e3742002-12-13 20:15:29 +0000380}
381
382DEFUN (no_ip_route_mask_distance,
383 no_ip_route_mask_distance_cmd,
paul595db7f2003-05-25 21:35:06 +0000384 "no ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0) <1-255>",
paul718e3742002-12-13 20:15:29 +0000385 NO_STR
386 IP_STR
387 "Establish static routes\n"
388 "IP destination prefix\n"
389 "IP destination prefix mask\n"
390 "IP gateway address\n"
391 "IP gateway interface name\n"
paul595db7f2003-05-25 21:35:06 +0000392 "Null interface\n"
paul718e3742002-12-13 20:15:29 +0000393 "Distance value for this route\n")
394{
hasso81dfcaa2003-05-25 19:21:25 +0000395 return zebra_static_ipv4 (vty, 0, argv[0], argv[1], argv[2], NULL, argv[3]);
396}
397
398DEFUN (no_ip_route_mask_flags_distance,
399 no_ip_route_mask_flags_distance_cmd,
400 "no ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE) (reject|blackhole) <1-255>",
401 NO_STR
402 IP_STR
403 "Establish static routes\n"
404 "IP destination prefix\n"
405 "IP destination prefix mask\n"
406 "IP gateway address\n"
407 "IP gateway interface name\n"
408 "Emit an ICMP unreachable when matched\n"
409 "Silently discard pkts when matched\n"
410 "Distance value for this route\n")
411{
412 return zebra_static_ipv4 (vty, 0, argv[0], argv[1], argv[2], argv[3], argv[4]);
paul718e3742002-12-13 20:15:29 +0000413}
414
415/* New RIB. Detailed information for IPv4 route. */
416void
417vty_show_ip_route_detail (struct vty *vty, struct route_node *rn)
418{
419 struct rib *rib;
420 struct nexthop *nexthop;
421
422 for (rib = rn->info; rib; rib = rib->next)
423 {
424 vty_out (vty, "Routing entry for %s/%d%s",
425 inet_ntoa (rn->p.u.prefix4), rn->p.prefixlen,
426 VTY_NEWLINE);
427 vty_out (vty, " Known via \"%s\"", route_type_str (rib->type));
428 vty_out (vty, ", distance %d, metric %d", rib->distance, rib->metric);
429 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
430 vty_out (vty, ", best");
431 if (rib->refcnt)
432 vty_out (vty, ", refcnt %ld", rib->refcnt);
hasso81dfcaa2003-05-25 19:21:25 +0000433 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_BLACKHOLE))
434 vty_out (vty, ", blackhole");
435 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_REJECT))
436 vty_out (vty, ", reject");
paul718e3742002-12-13 20:15:29 +0000437 vty_out (vty, "%s", VTY_NEWLINE);
438
439#define ONE_DAY_SECOND 60*60*24
440#define ONE_WEEK_SECOND 60*60*24*7
441 if (rib->type == ZEBRA_ROUTE_RIP
442 || rib->type == ZEBRA_ROUTE_OSPF
443 || rib->type == ZEBRA_ROUTE_BGP)
444 {
445 time_t uptime;
446 struct tm *tm;
447
448 uptime = time (NULL);
449 uptime -= rib->uptime;
450 tm = gmtime (&uptime);
451
452 vty_out (vty, " Last update ");
453
454 if (uptime < ONE_DAY_SECOND)
455 vty_out (vty, "%02d:%02d:%02d",
456 tm->tm_hour, tm->tm_min, tm->tm_sec);
457 else if (uptime < ONE_WEEK_SECOND)
458 vty_out (vty, "%dd%02dh%02dm",
459 tm->tm_yday, tm->tm_hour, tm->tm_min);
460 else
461 vty_out (vty, "%02dw%dd%02dh",
462 tm->tm_yday/7,
463 tm->tm_yday - ((tm->tm_yday/7) * 7), tm->tm_hour);
464 vty_out (vty, " ago%s", VTY_NEWLINE);
465 }
466
467 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
468 {
469 vty_out (vty, " %c",
470 CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB) ? '*' : ' ');
471
472 switch (nexthop->type)
473 {
474 case NEXTHOP_TYPE_IPV4:
475 case NEXTHOP_TYPE_IPV4_IFINDEX:
476 vty_out (vty, " %s", inet_ntoa (nexthop->gate.ipv4));
477 if (nexthop->ifindex)
478 vty_out (vty, ", via %s", ifindex2ifname (nexthop->ifindex));
479 break;
480 case NEXTHOP_TYPE_IFINDEX:
481 vty_out (vty, " directly connected, %s",
482 ifindex2ifname (nexthop->ifindex));
483 break;
484 case NEXTHOP_TYPE_IFNAME:
485 vty_out (vty, " directly connected, %s", nexthop->ifname);
486 break;
paul595db7f2003-05-25 21:35:06 +0000487 case NEXTHOP_TYPE_BLACKHOLE:
488 vty_out (vty, " directly connected, via Null0");
489 break;
paul718e3742002-12-13 20:15:29 +0000490 default:
491 break;
492 }
493 if (! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
494 vty_out (vty, " inactive");
495
496 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
497 {
498 vty_out (vty, " (recursive");
499
500 switch (nexthop->rtype)
501 {
502 case NEXTHOP_TYPE_IPV4:
503 case NEXTHOP_TYPE_IPV4_IFINDEX:
504 vty_out (vty, " via %s)", inet_ntoa (nexthop->rgate.ipv4));
505 break;
506 case NEXTHOP_TYPE_IFINDEX:
507 case NEXTHOP_TYPE_IFNAME:
508 vty_out (vty, " is directly connected, %s)",
509 ifindex2ifname (nexthop->rifindex));
510 break;
511 default:
512 break;
513 }
514 }
515 vty_out (vty, "%s", VTY_NEWLINE);
516 }
517 vty_out (vty, "%s", VTY_NEWLINE);
518 }
519}
520
521void
522vty_show_ip_route (struct vty *vty, struct route_node *rn, struct rib *rib)
523{
524 struct nexthop *nexthop;
525 int len = 0;
526 char buf[BUFSIZ];
527
528 /* Nexthop information. */
529 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
530 {
531 if (nexthop == rib->nexthop)
532 {
533 /* Prefix information. */
534 len = vty_out (vty, "%c%c%c %s/%d",
535 route_type_char (rib->type),
536 CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED)
537 ? '>' : ' ',
538 CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)
539 ? '*' : ' ',
540 inet_ntop (AF_INET, &rn->p.u.prefix, buf, BUFSIZ),
541 rn->p.prefixlen);
542
543 /* Distance and metric display. */
544 if (rib->type != ZEBRA_ROUTE_CONNECT
545 && rib->type != ZEBRA_ROUTE_KERNEL)
546 len += vty_out (vty, " [%d/%d]", rib->distance,
547 rib->metric);
548 }
549 else
550 vty_out (vty, " %c%*c",
551 CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)
552 ? '*' : ' ',
553 len - 3, ' ');
554
555 switch (nexthop->type)
556 {
557 case NEXTHOP_TYPE_IPV4:
558 case NEXTHOP_TYPE_IPV4_IFINDEX:
559 vty_out (vty, " via %s", inet_ntoa (nexthop->gate.ipv4));
560 if (nexthop->ifindex)
561 vty_out (vty, ", %s", ifindex2ifname (nexthop->ifindex));
562 break;
563 case NEXTHOP_TYPE_IFINDEX:
564 vty_out (vty, " is directly connected, %s",
565 ifindex2ifname (nexthop->ifindex));
566 break;
567 case NEXTHOP_TYPE_IFNAME:
568 vty_out (vty, " is directly connected, %s", nexthop->ifname);
569 break;
paul595db7f2003-05-25 21:35:06 +0000570 case NEXTHOP_TYPE_BLACKHOLE:
571 vty_out (vty, " is directly connected, Null0");
572 break;
paul718e3742002-12-13 20:15:29 +0000573 default:
574 break;
575 }
576 if (! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
577 vty_out (vty, " inactive");
578
579 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
580 {
581 vty_out (vty, " (recursive");
582
583 switch (nexthop->rtype)
584 {
585 case NEXTHOP_TYPE_IPV4:
586 case NEXTHOP_TYPE_IPV4_IFINDEX:
587 vty_out (vty, " via %s)", inet_ntoa (nexthop->rgate.ipv4));
588 break;
589 case NEXTHOP_TYPE_IFINDEX:
590 case NEXTHOP_TYPE_IFNAME:
591 vty_out (vty, " is directly connected, %s)",
592 ifindex2ifname (nexthop->rifindex));
593 break;
594 default:
595 break;
596 }
597 }
598
hasso81dfcaa2003-05-25 19:21:25 +0000599 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_BLACKHOLE))
600 vty_out (vty, ", bh");
601 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_REJECT))
602 vty_out (vty, ", rej");
603
paul718e3742002-12-13 20:15:29 +0000604 if (rib->type == ZEBRA_ROUTE_RIP
605 || rib->type == ZEBRA_ROUTE_OSPF
606 || rib->type == ZEBRA_ROUTE_BGP)
607 {
608 time_t uptime;
609 struct tm *tm;
610
611 uptime = time (NULL);
612 uptime -= rib->uptime;
613 tm = gmtime (&uptime);
614
615#define ONE_DAY_SECOND 60*60*24
616#define ONE_WEEK_SECOND 60*60*24*7
617
618 if (uptime < ONE_DAY_SECOND)
619 vty_out (vty, ", %02d:%02d:%02d",
620 tm->tm_hour, tm->tm_min, tm->tm_sec);
621 else if (uptime < ONE_WEEK_SECOND)
622 vty_out (vty, ", %dd%02dh%02dm",
623 tm->tm_yday, tm->tm_hour, tm->tm_min);
624 else
625 vty_out (vty, ", %02dw%dd%02dh",
626 tm->tm_yday/7,
627 tm->tm_yday - ((tm->tm_yday/7) * 7), tm->tm_hour);
628 }
629 vty_out (vty, "%s", VTY_NEWLINE);
630 }
631}
632
633#define SHOW_ROUTE_V4_HEADER "Codes: K - kernel route, C - connected, S - static, R - RIP, O - OSPF,%s B - BGP, > - selected route, * - FIB route%s%s"
634
635DEFUN (show_ip_route,
636 show_ip_route_cmd,
637 "show ip route",
638 SHOW_STR
639 IP_STR
640 "IP routing table\n")
641{
642 struct route_table *table;
643 struct route_node *rn;
644 struct rib *rib;
645 int first = 1;
646
647 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
648 if (! table)
649 return CMD_SUCCESS;
650
651 /* Show all IPv4 routes. */
652 for (rn = route_top (table); rn; rn = route_next (rn))
653 for (rib = rn->info; rib; rib = rib->next)
654 {
655 if (first)
656 {
657 vty_out (vty, SHOW_ROUTE_V4_HEADER, VTY_NEWLINE, VTY_NEWLINE,
658 VTY_NEWLINE);
659 first = 0;
660 }
661 vty_show_ip_route (vty, rn, rib);
662 }
663 return CMD_SUCCESS;
664}
665
666DEFUN (show_ip_route_prefix_longer,
667 show_ip_route_prefix_longer_cmd,
668 "show ip route A.B.C.D/M longer-prefixes",
669 SHOW_STR
670 IP_STR
671 "IP routing table\n"
672 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
673 "Show route matching the specified Network/Mask pair only\n")
674{
675 struct route_table *table;
676 struct route_node *rn;
677 struct rib *rib;
678 struct prefix p;
679 int ret;
680 int first = 1;
681
682 ret = str2prefix (argv[0], &p);
683 if (! ret)
684 {
685 vty_out (vty, "%% Malformed Prefix%s", VTY_NEWLINE);
686 return CMD_WARNING;
687 }
688
689 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
690 if (! table)
691 return CMD_SUCCESS;
692
693 /* Show matched type IPv4 routes. */
694 for (rn = route_top (table); rn; rn = route_next (rn))
695 for (rib = rn->info; rib; rib = rib->next)
696 if (prefix_match (&p, &rn->p))
697 {
698 if (first)
699 {
700 vty_out (vty, SHOW_ROUTE_V4_HEADER, VTY_NEWLINE,
701 VTY_NEWLINE, VTY_NEWLINE);
702 first = 0;
703 }
704 vty_show_ip_route (vty, rn, rib);
705 }
706 return CMD_SUCCESS;
707}
708
709DEFUN (show_ip_route_supernets,
710 show_ip_route_supernets_cmd,
711 "show ip route supernets-only",
712 SHOW_STR
713 IP_STR
714 "IP routing table\n"
715 "Show supernet entries only\n")
716{
717 struct route_table *table;
718 struct route_node *rn;
719 struct rib *rib;
720 u_int32_t addr;
721 int first = 1;
722
723 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
724 if (! table)
725 return CMD_SUCCESS;
726
727 /* Show matched type IPv4 routes. */
728 for (rn = route_top (table); rn; rn = route_next (rn))
729 for (rib = rn->info; rib; rib = rib->next)
730 {
731 addr = ntohl (rn->p.u.prefix4.s_addr);
732
733 if ((IN_CLASSC (addr) && rn->p.prefixlen < 24)
734 || (IN_CLASSB (addr) && rn->p.prefixlen < 16)
735 || (IN_CLASSA (addr) && rn->p.prefixlen < 8))
736 {
737 if (first)
738 {
739 vty_out (vty, SHOW_ROUTE_V4_HEADER, VTY_NEWLINE,
740 VTY_NEWLINE, VTY_NEWLINE);
741 first = 0;
742 }
743 vty_show_ip_route (vty, rn, rib);
744 }
745 }
746 return CMD_SUCCESS;
747}
748
749DEFUN (show_ip_route_protocol,
750 show_ip_route_protocol_cmd,
751 "show ip route (bgp|connected|kernel|ospf|rip|static)",
752 SHOW_STR
753 IP_STR
754 "IP routing table\n"
755 "Border Gateway Protocol (BGP)\n"
756 "Connected\n"
757 "Kernel\n"
758 "Open Shortest Path First (OSPF)\n"
759 "Routing Information Protocol (RIP)\n"
760 "Static routes\n")
761{
762 int type;
763 struct route_table *table;
764 struct route_node *rn;
765 struct rib *rib;
766 int first = 1;
767
768 if (strncmp (argv[0], "b", 1) == 0)
769 type = ZEBRA_ROUTE_BGP;
770 else if (strncmp (argv[0], "c", 1) == 0)
771 type = ZEBRA_ROUTE_CONNECT;
772 else if (strncmp (argv[0], "k", 1) ==0)
773 type = ZEBRA_ROUTE_KERNEL;
774 else if (strncmp (argv[0], "o", 1) == 0)
775 type = ZEBRA_ROUTE_OSPF;
776 else if (strncmp (argv[0], "r", 1) == 0)
777 type = ZEBRA_ROUTE_RIP;
778 else if (strncmp (argv[0], "s", 1) == 0)
779 type = ZEBRA_ROUTE_STATIC;
780 else
781 {
782 vty_out (vty, "Unknown route type%s", VTY_NEWLINE);
783 return CMD_WARNING;
784 }
785
786 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
787 if (! table)
788 return CMD_SUCCESS;
789
790 /* Show matched type IPv4 routes. */
791 for (rn = route_top (table); rn; rn = route_next (rn))
792 for (rib = rn->info; rib; rib = rib->next)
793 if (rib->type == type)
794 {
795 if (first)
796 {
797 vty_out (vty, SHOW_ROUTE_V4_HEADER,
798 VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE);
799 first = 0;
800 }
801 vty_show_ip_route (vty, rn, rib);
802 }
803 return CMD_SUCCESS;
804}
805
806DEFUN (show_ip_route_addr,
807 show_ip_route_addr_cmd,
808 "show ip route A.B.C.D",
809 SHOW_STR
810 IP_STR
811 "IP routing table\n"
812 "Network in the IP routing table to display\n")
813{
814 int ret;
815 struct prefix_ipv4 p;
816 struct route_table *table;
817 struct route_node *rn;
818
819 ret = str2prefix_ipv4 (argv[0], &p);
820 if (ret <= 0)
821 {
822 vty_out (vty, "%% Malformed IPv4 address%s", VTY_NEWLINE);
823 return CMD_WARNING;
824 }
825
826 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
827 if (! table)
828 return CMD_SUCCESS;
829
830 rn = route_node_match (table, (struct prefix *) &p);
831 if (! rn)
832 {
833 vty_out (vty, "%% Network not in table%s", VTY_NEWLINE);
834 return CMD_WARNING;
835 }
836
837 vty_show_ip_route_detail (vty, rn);
838
839 route_unlock_node (rn);
840
841 return CMD_SUCCESS;
842}
843
844DEFUN (show_ip_route_prefix,
845 show_ip_route_prefix_cmd,
846 "show ip route A.B.C.D/M",
847 SHOW_STR
848 IP_STR
849 "IP routing table\n"
850 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n")
851{
852 int ret;
853 struct prefix_ipv4 p;
854 struct route_table *table;
855 struct route_node *rn;
856
857 ret = str2prefix_ipv4 (argv[0], &p);
858 if (ret <= 0)
859 {
860 vty_out (vty, "%% Malformed IPv4 address%s", VTY_NEWLINE);
861 return CMD_WARNING;
862 }
863
864 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
865 if (! table)
866 return CMD_SUCCESS;
867
868 rn = route_node_match (table, (struct prefix *) &p);
869 if (! rn || rn->p.prefixlen != p.prefixlen)
870 {
871 vty_out (vty, "%% Network not in table%s", VTY_NEWLINE);
872 return CMD_WARNING;
873 }
874
875 vty_show_ip_route_detail (vty, rn);
876
877 route_unlock_node (rn);
878
879 return CMD_SUCCESS;
880}
881
882void
883zebra_show_ip_route (struct vty *vty, struct vrf *vrf)
884{
885 vty_out (vty, "IP routing table name is %s(%d)%s",
886 vrf->name ? vrf->name : "", vrf->id, VTY_NEWLINE);
887
888 vty_out (vty, "Route Source Networks%s", VTY_NEWLINE);
889 vty_out (vty, "connected %d%s", 0, VTY_NEWLINE);
890 vty_out (vty, "static %d%s", 0, VTY_NEWLINE);
891 vty_out (vty, "rip %d%s", 0, VTY_NEWLINE);
892
893 vty_out (vty, "bgp %d%s", 0, VTY_NEWLINE);
894 vty_out (vty, " External: %d Internal: %d Local: %d%s",
895 0, 0, 0, VTY_NEWLINE);
896
897 vty_out (vty, "ospf %d%s", 0, VTY_NEWLINE);
898 vty_out (vty,
899 " Intra-area: %d Inter-area: %d External-1: %d External-2: %d%s",
900 0, 0, 0, 0, VTY_NEWLINE);
901 vty_out (vty, " NSSA External-1: %d NSSA External-2: %d%s",
902 0, 0, VTY_NEWLINE);
903
904 vty_out (vty, "internal %d%s", 0, VTY_NEWLINE);
905 vty_out (vty, "Total %d%s", 0, VTY_NEWLINE);
906}
907
908/* Show route summary. */
909DEFUN (show_ip_route_summary,
910 show_ip_route_summary_cmd,
911 "show ip route summary",
912 SHOW_STR
913 IP_STR
914 "IP routing table\n"
915 "Summary of all routes\n")
916{
917 struct vrf *vrf;
918
919 /* Default table id is zero. */
920 vrf = vrf_lookup (0);
921 if (! vrf)
922 {
923 vty_out (vty, "%% No Default-IP-Routing-Table%s", VTY_NEWLINE);
924 return CMD_WARNING;
925 }
926
927 zebra_show_ip_route (vty, vrf);
928
929 return CMD_SUCCESS;
930}
931
932/* Write IPv4 static route configuration. */
933int
934static_config_ipv4 (struct vty *vty)
935{
936 struct route_node *rn;
937 struct static_ipv4 *si;
938 struct route_table *stable;
939 int write;
940
941 write = 0;
942
943 /* Lookup table. */
944 stable = vrf_static_table (AFI_IP, SAFI_UNICAST, 0);
945 if (! stable)
946 return -1;
947
948 for (rn = route_top (stable); rn; rn = route_next (rn))
949 for (si = rn->info; si; si = si->next)
950 {
951 vty_out (vty, "ip route %s/%d", inet_ntoa (rn->p.u.prefix4),
952 rn->p.prefixlen);
953
954 switch (si->type)
955 {
956 case STATIC_IPV4_GATEWAY:
957 vty_out (vty, " %s", inet_ntoa (si->gate.ipv4));
958 break;
959 case STATIC_IPV4_IFNAME:
960 vty_out (vty, " %s", si->gate.ifname);
961 break;
paul595db7f2003-05-25 21:35:06 +0000962 case STATIC_IPV4_BLACKHOLE:
963 vty_out (vty, " Null0");
964 break;
paul718e3742002-12-13 20:15:29 +0000965 }
966
hasso81dfcaa2003-05-25 19:21:25 +0000967 if (CHECK_FLAG(si->flags, ZEBRA_FLAG_REJECT))
968 vty_out (vty, " %s", "reject");
969
970 if (CHECK_FLAG(si->flags, ZEBRA_FLAG_BLACKHOLE))
971 vty_out (vty, " %s", "blackhole");
972
paul718e3742002-12-13 20:15:29 +0000973 if (si->distance != ZEBRA_STATIC_DISTANCE_DEFAULT)
974 vty_out (vty, " %d", si->distance);
975 vty_out (vty, "%s", VTY_NEWLINE);
976
977 write = 1;
978 }
979 return write;
980}
981
982#ifdef HAVE_IPV6
983/* General fucntion for IPv6 static route. */
984int
985static_ipv6_func (struct vty *vty, int add_cmd, char *dest_str,
hasso81dfcaa2003-05-25 19:21:25 +0000986 char *gate_str, char *ifname, char *flag_str, char *distance_str)
paul718e3742002-12-13 20:15:29 +0000987{
988 int ret;
989 u_char distance;
990 struct prefix p;
991 struct in6_addr *gate = NULL;
992 struct in6_addr gate_addr;
993 u_char type = 0;
994 int table = 0;
hasso81dfcaa2003-05-25 19:21:25 +0000995 u_char flag = 0;
paul718e3742002-12-13 20:15:29 +0000996
997 ret = str2prefix (dest_str, &p);
998 if (ret <= 0)
999 {
1000 vty_out (vty, "%% Malformed address%s", VTY_NEWLINE);
1001 return CMD_WARNING;
1002 }
1003
1004 /* Apply mask for given prefix. */
1005 apply_mask (&p);
1006
hasso81dfcaa2003-05-25 19:21:25 +00001007 /* Route flags */
1008 if (flag_str) {
1009 switch(flag_str[0]) {
1010 case 'r':
1011 case 'R': /* XXX */
1012 SET_FLAG (flag, ZEBRA_FLAG_REJECT);
1013 break;
1014 case 'b':
1015 case 'B': /* XXX */
1016 SET_FLAG (flag, ZEBRA_FLAG_BLACKHOLE);
1017 break;
1018 default:
1019 vty_out (vty, "%% Malformed flag %s %s", flag_str, VTY_NEWLINE);
paul595db7f2003-05-25 21:35:06 +00001020 return CMD_WARNING;
hasso81dfcaa2003-05-25 19:21:25 +00001021 }
1022 }
1023
paul718e3742002-12-13 20:15:29 +00001024 /* Administrative distance. */
1025 if (distance_str)
1026 distance = atoi (distance_str);
1027 else
1028 distance = ZEBRA_STATIC_DISTANCE_DEFAULT;
1029
1030 /* When gateway is valid IPv6 addrees, then gate is treated as
1031 nexthop address other case gate is treated as interface name. */
1032 ret = inet_pton (AF_INET6, gate_str, &gate_addr);
1033
1034 if (ifname)
1035 {
1036 /* When ifname is specified. It must be come with gateway
1037 address. */
1038 if (ret != 1)
1039 {
1040 vty_out (vty, "%% Malformed address%s", VTY_NEWLINE);
1041 return CMD_WARNING;
1042 }
1043 type = STATIC_IPV6_GATEWAY_IFNAME;
1044 gate = &gate_addr;
1045 }
1046 else
1047 {
1048 if (ret == 1)
1049 {
1050 type = STATIC_IPV6_GATEWAY;
1051 gate = &gate_addr;
1052 }
1053 else
1054 {
1055 type = STATIC_IPV6_IFNAME;
1056 ifname = gate_str;
1057 }
1058 }
1059
1060 if (add_cmd)
hasso81dfcaa2003-05-25 19:21:25 +00001061 static_add_ipv6 (&p, type, gate, ifname, flag, distance, table);
paul718e3742002-12-13 20:15:29 +00001062 else
1063 static_delete_ipv6 (&p, type, gate, ifname, distance, table);
1064
1065 return CMD_SUCCESS;
1066}
1067
1068DEFUN (ipv6_route,
1069 ipv6_route_cmd,
1070 "ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE)",
1071 IP_STR
1072 "Establish static routes\n"
1073 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1074 "IPv6 gateway address\n"
1075 "IPv6 gateway interface name\n")
1076{
hasso81dfcaa2003-05-25 19:21:25 +00001077 return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, NULL, NULL);
1078}
1079
1080DEFUN (ipv6_route_flags,
1081 ipv6_route_flags_cmd,
1082 "ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) (reject|blackhole)",
1083 IP_STR
1084 "Establish static routes\n"
1085 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1086 "IPv6 gateway address\n"
1087 "IPv6 gateway interface name\n"
1088 "Emit an ICMP unreachable when matched\n"
1089 "Silently discard pkts when matched\n")
1090{
1091 return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, argv[2], NULL);
paul718e3742002-12-13 20:15:29 +00001092}
1093
1094DEFUN (ipv6_route_ifname,
1095 ipv6_route_ifname_cmd,
1096 "ipv6 route X:X::X:X/M X:X::X:X INTERFACE",
1097 IP_STR
1098 "Establish static routes\n"
1099 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1100 "IPv6 gateway address\n"
1101 "IPv6 gateway interface name\n")
1102{
hasso81dfcaa2003-05-25 19:21:25 +00001103 return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], NULL, NULL);
1104}
1105
1106DEFUN (ipv6_route_ifname_flags,
1107 ipv6_route_ifname_flags_cmd,
1108 "ipv6 route X:X::X:X/M X:X::X:X INTERFACE (reject|blackhole)",
1109 IP_STR
1110 "Establish static routes\n"
1111 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1112 "IPv6 gateway address\n"
1113 "IPv6 gateway interface name\n"
1114 "Emit an ICMP unreachable when matched\n"
1115 "Silently discard pkts when matched\n")
1116{
1117 return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], argv[3], NULL);
paul718e3742002-12-13 20:15:29 +00001118}
1119
1120DEFUN (ipv6_route_pref,
1121 ipv6_route_pref_cmd,
1122 "ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) <1-255>",
1123 IP_STR
1124 "Establish static routes\n"
1125 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1126 "IPv6 gateway address\n"
1127 "IPv6 gateway interface name\n"
1128 "Distance value for this prefix\n")
1129{
hasso81dfcaa2003-05-25 19:21:25 +00001130 return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, NULL, argv[2]);
1131}
1132
1133DEFUN (ipv6_route_flags_pref,
1134 ipv6_route_flags_pref_cmd,
1135 "ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) (reject|blackhole) <1-255>",
1136 IP_STR
1137 "Establish static routes\n"
1138 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1139 "IPv6 gateway address\n"
1140 "IPv6 gateway interface name\n"
1141 "Emit an ICMP unreachable when matched\n"
1142 "Silently discard pkts when matched\n"
1143 "Distance value for this prefix\n")
1144{
1145 return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, argv[2], argv[3]);
paul718e3742002-12-13 20:15:29 +00001146}
1147
1148DEFUN (ipv6_route_ifname_pref,
1149 ipv6_route_ifname_pref_cmd,
1150 "ipv6 route X:X::X:X/M X:X::X:X INTERFACE <1-255>",
1151 IP_STR
1152 "Establish static routes\n"
1153 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1154 "IPv6 gateway address\n"
1155 "IPv6 gateway interface name\n"
1156 "Distance value for this prefix\n")
1157{
hasso81dfcaa2003-05-25 19:21:25 +00001158 return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], NULL, argv[3]);
1159}
1160
1161DEFUN (ipv6_route_ifname_flags_pref,
1162 ipv6_route_ifname_flags_pref_cmd,
1163 "ipv6 route X:X::X:X/M X:X::X:X INTERFACE (reject|blackhole) <1-255>",
1164 IP_STR
1165 "Establish static routes\n"
1166 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1167 "IPv6 gateway address\n"
1168 "IPv6 gateway interface name\n"
1169 "Emit an ICMP unreachable when matched\n"
1170 "Silently discard pkts when matched\n"
1171 "Distance value for this prefix\n")
1172{
1173 return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], argv[3], argv[4]);
paul718e3742002-12-13 20:15:29 +00001174}
1175
1176DEFUN (no_ipv6_route,
1177 no_ipv6_route_cmd,
1178 "no ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE)",
1179 NO_STR
1180 IP_STR
1181 "Establish static routes\n"
1182 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1183 "IPv6 gateway address\n"
1184 "IPv6 gateway interface name\n")
1185{
hasso81dfcaa2003-05-25 19:21:25 +00001186 return static_ipv6_func (vty, 0, argv[0], argv[1], NULL, NULL, NULL);
paul718e3742002-12-13 20:15:29 +00001187}
1188
hasso81dfcaa2003-05-25 19:21:25 +00001189ALIAS (no_ipv6_route,
1190 no_ipv6_route_flags_cmd,
1191 "no ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) (reject|blackhole)",
1192 NO_STR
1193 IP_STR
1194 "Establish static routes\n"
1195 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1196 "IPv6 gateway address\n"
1197 "IPv6 gateway interface name\n"
1198 "Emit an ICMP unreachable when matched\n"
1199 "Silently discard pkts when matched\n")
1200
paul718e3742002-12-13 20:15:29 +00001201DEFUN (no_ipv6_route_ifname,
1202 no_ipv6_route_ifname_cmd,
1203 "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE",
1204 NO_STR
1205 IP_STR
1206 "Establish static routes\n"
1207 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1208 "IPv6 gateway address\n"
1209 "IPv6 gateway interface name\n")
1210{
hasso81dfcaa2003-05-25 19:21:25 +00001211 return static_ipv6_func (vty, 0, argv[0], argv[1], argv[2], NULL, NULL);
paul718e3742002-12-13 20:15:29 +00001212}
1213
hasso81dfcaa2003-05-25 19:21:25 +00001214ALIAS (no_ipv6_route_ifname,
1215 no_ipv6_route_ifname_flags_cmd,
1216 "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE (reject|blackhole)",
1217 NO_STR
1218 IP_STR
1219 "Establish static routes\n"
1220 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1221 "IPv6 gateway address\n"
1222 "IPv6 gateway interface name\n"
1223 "Emit an ICMP unreachable when matched\n"
1224 "Silently discard pkts when matched\n")
1225
paul718e3742002-12-13 20:15:29 +00001226DEFUN (no_ipv6_route_pref,
1227 no_ipv6_route_pref_cmd,
1228 "no ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) <1-255>",
1229 NO_STR
1230 IP_STR
1231 "Establish static routes\n"
1232 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1233 "IPv6 gateway address\n"
1234 "IPv6 gateway interface name\n"
1235 "Distance value for this prefix\n")
1236{
hasso81dfcaa2003-05-25 19:21:25 +00001237 return static_ipv6_func (vty, 0, argv[0], argv[1], NULL, NULL, argv[2]);
1238}
1239
1240DEFUN (no_ipv6_route_flags_pref,
1241 no_ipv6_route_flags_pref_cmd,
1242 "no ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) (reject|blackhole) <1-255>",
1243 NO_STR
1244 IP_STR
1245 "Establish static routes\n"
1246 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1247 "IPv6 gateway address\n"
1248 "IPv6 gateway interface name\n"
1249 "Emit an ICMP unreachable when matched\n"
1250 "Silently discard pkts when matched\n"
1251 "Distance value for this prefix\n")
1252{
1253 /* We do not care about argv[2] */
1254 return static_ipv6_func (vty, 0, argv[0], argv[1], NULL, argv[2], argv[3]);
paul718e3742002-12-13 20:15:29 +00001255}
1256
1257DEFUN (no_ipv6_route_ifname_pref,
1258 no_ipv6_route_ifname_pref_cmd,
1259 "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE <1-255>",
1260 NO_STR
1261 IP_STR
1262 "Establish static routes\n"
1263 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1264 "IPv6 gateway address\n"
1265 "IPv6 gateway interface name\n"
1266 "Distance value for this prefix\n")
1267{
hasso81dfcaa2003-05-25 19:21:25 +00001268 return static_ipv6_func (vty, 0, argv[0], argv[1], argv[2], NULL, argv[3]);
1269}
1270
1271DEFUN (no_ipv6_route_ifname_flags_pref,
1272 no_ipv6_route_ifname_flags_pref_cmd,
1273 "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE (reject|blackhole) <1-255>",
1274 NO_STR
1275 IP_STR
1276 "Establish static routes\n"
1277 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1278 "IPv6 gateway address\n"
1279 "IPv6 gateway interface name\n"
1280 "Emit an ICMP unreachable when matched\n"
1281 "Silently discard pkts when matched\n"
1282 "Distance value for this prefix\n")
1283{
1284 return static_ipv6_func (vty, 0, argv[0], argv[1], argv[2], argv[3], argv[4]);
paul718e3742002-12-13 20:15:29 +00001285}
1286
paul595db7f2003-05-25 21:35:06 +00001287/* New RIB. Detailed information for IPv6 route. */
paul718e3742002-12-13 20:15:29 +00001288void
1289vty_show_ipv6_route_detail (struct vty *vty, struct route_node *rn)
1290{
1291 struct rib *rib;
1292 struct nexthop *nexthop;
1293 char buf[BUFSIZ];
1294
1295 for (rib = rn->info; rib; rib = rib->next)
1296 {
1297 vty_out (vty, "Routing entry for %s/%d%s",
1298 inet_ntop (AF_INET6, &rn->p.u.prefix6, buf, BUFSIZ),
1299 rn->p.prefixlen,
1300 VTY_NEWLINE);
1301 vty_out (vty, " Known via \"%s\"", route_type_str (rib->type));
1302 vty_out (vty, ", distance %d, metric %d", rib->distance, rib->metric);
1303 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
1304 vty_out (vty, ", best");
1305 if (rib->refcnt)
1306 vty_out (vty, ", refcnt %ld", rib->refcnt);
hasso81dfcaa2003-05-25 19:21:25 +00001307 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_BLACKHOLE))
1308 vty_out (vty, ", blackhole");
1309 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_REJECT))
1310 vty_out (vty, ", reject");
paul718e3742002-12-13 20:15:29 +00001311 vty_out (vty, "%s", VTY_NEWLINE);
1312
1313#define ONE_DAY_SECOND 60*60*24
1314#define ONE_WEEK_SECOND 60*60*24*7
1315 if (rib->type == ZEBRA_ROUTE_RIPNG
1316 || rib->type == ZEBRA_ROUTE_OSPF6
1317 || rib->type == ZEBRA_ROUTE_BGP)
1318 {
1319 time_t uptime;
1320 struct tm *tm;
1321
1322 uptime = time (NULL);
1323 uptime -= rib->uptime;
1324 tm = gmtime (&uptime);
1325
1326 vty_out (vty, " Last update ");
1327
1328 if (uptime < ONE_DAY_SECOND)
1329 vty_out (vty, "%02d:%02d:%02d",
1330 tm->tm_hour, tm->tm_min, tm->tm_sec);
1331 else if (uptime < ONE_WEEK_SECOND)
1332 vty_out (vty, "%dd%02dh%02dm",
1333 tm->tm_yday, tm->tm_hour, tm->tm_min);
1334 else
1335 vty_out (vty, "%02dw%dd%02dh",
1336 tm->tm_yday/7,
1337 tm->tm_yday - ((tm->tm_yday/7) * 7), tm->tm_hour);
1338 vty_out (vty, " ago%s", VTY_NEWLINE);
1339 }
1340
1341 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1342 {
1343 vty_out (vty, " %c",
1344 CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB) ? '*' : ' ');
1345
1346 switch (nexthop->type)
1347 {
1348 case NEXTHOP_TYPE_IPV6:
1349 case NEXTHOP_TYPE_IPV6_IFINDEX:
1350 case NEXTHOP_TYPE_IPV6_IFNAME:
1351 vty_out (vty, " %s",
1352 inet_ntop (AF_INET6, &nexthop->gate.ipv6, buf, BUFSIZ));
1353 if (nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME)
1354 vty_out (vty, ", %s", nexthop->ifname);
1355 else if (nexthop->ifindex)
1356 vty_out (vty, ", via %s", ifindex2ifname (nexthop->ifindex));
1357 break;
1358 case NEXTHOP_TYPE_IFINDEX:
1359 vty_out (vty, " directly connected, %s",
1360 ifindex2ifname (nexthop->ifindex));
1361 break;
1362 case NEXTHOP_TYPE_IFNAME:
1363 vty_out (vty, " directly connected, %s",
1364 nexthop->ifname);
1365 break;
1366 default:
1367 break;
1368 }
1369 if (! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
1370 vty_out (vty, " inactive");
1371
1372 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
1373 {
1374 vty_out (vty, " (recursive");
1375
1376 switch (nexthop->rtype)
1377 {
1378 case NEXTHOP_TYPE_IPV6:
1379 case NEXTHOP_TYPE_IPV6_IFINDEX:
1380 case NEXTHOP_TYPE_IPV6_IFNAME:
1381 vty_out (vty, " via %s)",
1382 inet_ntop (AF_INET6, &nexthop->rgate.ipv6,
1383 buf, BUFSIZ));
1384 if (nexthop->rifindex)
1385 vty_out (vty, ", %s", ifindex2ifname (nexthop->rifindex));
1386 break;
1387 case NEXTHOP_TYPE_IFINDEX:
1388 case NEXTHOP_TYPE_IFNAME:
1389 vty_out (vty, " is directly connected, %s)",
1390 ifindex2ifname (nexthop->rifindex));
1391 break;
1392 default:
1393 break;
1394 }
1395 }
1396 vty_out (vty, "%s", VTY_NEWLINE);
1397 }
1398 vty_out (vty, "%s", VTY_NEWLINE);
1399 }
1400}
1401
1402void
1403vty_show_ipv6_route (struct vty *vty, struct route_node *rn,
1404 struct rib *rib)
1405{
1406 struct nexthop *nexthop;
1407 int len = 0;
1408 char buf[BUFSIZ];
1409
1410 /* Nexthop information. */
1411 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1412 {
1413 if (nexthop == rib->nexthop)
1414 {
1415 /* Prefix information. */
1416 len = vty_out (vty, "%c%c%c %s/%d",
1417 route_type_char (rib->type),
1418 CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED)
1419 ? '>' : ' ',
1420 CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)
1421 ? '*' : ' ',
1422 inet_ntop (AF_INET6, &rn->p.u.prefix6, buf, BUFSIZ),
1423 rn->p.prefixlen);
1424
1425 /* Distance and metric display. */
1426 if (rib->type != ZEBRA_ROUTE_CONNECT
1427 && rib->type != ZEBRA_ROUTE_KERNEL)
1428 len += vty_out (vty, " [%d/%d]", rib->distance,
1429 rib->metric);
1430 }
1431 else
1432 vty_out (vty, " %c%*c",
1433 CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)
1434 ? '*' : ' ',
1435 len - 3, ' ');
1436
1437 switch (nexthop->type)
1438 {
1439 case NEXTHOP_TYPE_IPV6:
1440 case NEXTHOP_TYPE_IPV6_IFINDEX:
1441 case NEXTHOP_TYPE_IPV6_IFNAME:
1442 vty_out (vty, " via %s",
1443 inet_ntop (AF_INET6, &nexthop->gate.ipv6, buf, BUFSIZ));
1444 if (nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME)
1445 vty_out (vty, ", %s", nexthop->ifname);
1446 else if (nexthop->ifindex)
1447 vty_out (vty, ", %s", ifindex2ifname (nexthop->ifindex));
1448 break;
1449 case NEXTHOP_TYPE_IFINDEX:
1450 vty_out (vty, " is directly connected, %s",
1451 ifindex2ifname (nexthop->ifindex));
1452 break;
1453 case NEXTHOP_TYPE_IFNAME:
1454 vty_out (vty, " is directly connected, %s",
1455 nexthop->ifname);
1456 break;
1457 default:
1458 break;
1459 }
1460 if (! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
1461 vty_out (vty, " inactive");
1462
1463 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
1464 {
1465 vty_out (vty, " (recursive");
1466
1467 switch (nexthop->rtype)
1468 {
1469 case NEXTHOP_TYPE_IPV6:
1470 case NEXTHOP_TYPE_IPV6_IFINDEX:
1471 case NEXTHOP_TYPE_IPV6_IFNAME:
1472 vty_out (vty, " via %s)",
1473 inet_ntop (AF_INET6, &nexthop->rgate.ipv6,
1474 buf, BUFSIZ));
1475 if (nexthop->rifindex)
1476 vty_out (vty, ", %s", ifindex2ifname (nexthop->rifindex));
1477 break;
1478 case NEXTHOP_TYPE_IFINDEX:
1479 case NEXTHOP_TYPE_IFNAME:
1480 vty_out (vty, " is directly connected, %s)",
1481 ifindex2ifname (nexthop->rifindex));
1482 break;
1483 default:
1484 break;
1485 }
1486 }
1487
hasso81dfcaa2003-05-25 19:21:25 +00001488 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_BLACKHOLE))
1489 vty_out (vty, ", bh");
1490 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_REJECT))
1491 vty_out (vty, ", rej");
1492
paul718e3742002-12-13 20:15:29 +00001493 if (rib->type == ZEBRA_ROUTE_RIPNG
1494 || rib->type == ZEBRA_ROUTE_OSPF6
1495 || rib->type == ZEBRA_ROUTE_BGP)
1496 {
1497 time_t uptime;
1498 struct tm *tm;
1499
1500 uptime = time (NULL);
1501 uptime -= rib->uptime;
1502 tm = gmtime (&uptime);
1503
1504#define ONE_DAY_SECOND 60*60*24
1505#define ONE_WEEK_SECOND 60*60*24*7
1506
1507 if (uptime < ONE_DAY_SECOND)
1508 vty_out (vty, ", %02d:%02d:%02d",
1509 tm->tm_hour, tm->tm_min, tm->tm_sec);
1510 else if (uptime < ONE_WEEK_SECOND)
1511 vty_out (vty, ", %dd%02dh%02dm",
1512 tm->tm_yday, tm->tm_hour, tm->tm_min);
1513 else
1514 vty_out (vty, ", %02dw%dd%02dh",
1515 tm->tm_yday/7,
1516 tm->tm_yday - ((tm->tm_yday/7) * 7), tm->tm_hour);
1517 }
1518 vty_out (vty, "%s", VTY_NEWLINE);
1519 }
1520}
1521
1522#define SHOW_ROUTE_V6_HEADER "Codes: K - kernel route, C - connected, S - static, R - RIPng, O - OSPFv3,%s B - BGP, * - FIB route.%s%s"
1523
1524DEFUN (show_ipv6_route,
1525 show_ipv6_route_cmd,
1526 "show ipv6 route",
1527 SHOW_STR
1528 IP_STR
1529 "IPv6 routing table\n")
1530{
1531 struct route_table *table;
1532 struct route_node *rn;
1533 struct rib *rib;
1534 int first = 1;
1535
1536 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
1537 if (! table)
1538 return CMD_SUCCESS;
1539
1540 /* Show all IPv6 route. */
1541 for (rn = route_top (table); rn; rn = route_next (rn))
1542 for (rib = rn->info; rib; rib = rib->next)
1543 {
1544 if (first)
1545 {
1546 vty_out (vty, SHOW_ROUTE_V6_HEADER, VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE);
1547 first = 0;
1548 }
1549 vty_show_ipv6_route (vty, rn, rib);
1550 }
1551 return CMD_SUCCESS;
1552}
1553
1554DEFUN (show_ipv6_route_prefix_longer,
1555 show_ipv6_route_prefix_longer_cmd,
1556 "show ipv6 route X:X::X:X/M longer-prefixes",
1557 SHOW_STR
1558 IP_STR
1559 "IPv6 routing table\n"
1560 "IPv6 prefix\n"
1561 "Show route matching the specified Network/Mask pair only\n")
1562{
1563 struct route_table *table;
1564 struct route_node *rn;
1565 struct rib *rib;
1566 struct prefix p;
1567 int ret;
1568 int first = 1;
1569
1570 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
1571 if (! table)
1572 return CMD_SUCCESS;
1573
1574 ret = str2prefix (argv[0], &p);
1575 if (! ret)
1576 {
1577 vty_out (vty, "%% Malformed Prefix%s", VTY_NEWLINE);
1578 return CMD_WARNING;
1579 }
1580
1581 /* Show matched type IPv6 routes. */
1582 for (rn = route_top (table); rn; rn = route_next (rn))
1583 for (rib = rn->info; rib; rib = rib->next)
1584 if (prefix_match (&p, &rn->p))
1585 {
1586 if (first)
1587 {
1588 vty_out (vty, SHOW_ROUTE_V6_HEADER, VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE);
1589 first = 0;
1590 }
1591 vty_show_ipv6_route (vty, rn, rib);
1592 }
1593 return CMD_SUCCESS;
1594}
1595
1596DEFUN (show_ipv6_route_protocol,
1597 show_ipv6_route_protocol_cmd,
1598 "show ipv6 route (bgp|connected|kernel|ospf6|ripng|static)",
1599 SHOW_STR
1600 IP_STR
1601 "IP routing table\n"
1602 "Border Gateway Protocol (BGP)\n"
1603 "Connected\n"
1604 "Kernel\n"
1605 "Open Shortest Path First (OSPFv3)\n"
1606 "Routing Information Protocol (RIPng)\n"
1607 "Static routes\n")
1608{
1609 int type;
1610 struct route_table *table;
1611 struct route_node *rn;
1612 struct rib *rib;
1613 int first = 1;
1614
1615 if (strncmp (argv[0], "b", 1) == 0)
1616 type = ZEBRA_ROUTE_BGP;
1617 else if (strncmp (argv[0], "c", 1) == 0)
1618 type = ZEBRA_ROUTE_CONNECT;
1619 else if (strncmp (argv[0], "k", 1) ==0)
1620 type = ZEBRA_ROUTE_KERNEL;
1621 else if (strncmp (argv[0], "o", 1) == 0)
1622 type = ZEBRA_ROUTE_OSPF6;
1623 else if (strncmp (argv[0], "r", 1) == 0)
1624 type = ZEBRA_ROUTE_RIPNG;
1625 else if (strncmp (argv[0], "s", 1) == 0)
1626 type = ZEBRA_ROUTE_STATIC;
1627 else
1628 {
1629 vty_out (vty, "Unknown route type%s", VTY_NEWLINE);
1630 return CMD_WARNING;
1631 }
1632
1633 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
1634 if (! table)
1635 return CMD_SUCCESS;
1636
1637 /* Show matched type IPv6 routes. */
1638 for (rn = route_top (table); rn; rn = route_next (rn))
1639 for (rib = rn->info; rib; rib = rib->next)
1640 if (rib->type == type)
1641 {
1642 if (first)
1643 {
1644 vty_out (vty, SHOW_ROUTE_V6_HEADER, VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE);
1645 first = 0;
1646 }
1647 vty_show_ipv6_route (vty, rn, rib);
1648 }
1649 return CMD_SUCCESS;
1650}
1651
1652DEFUN (show_ipv6_route_addr,
1653 show_ipv6_route_addr_cmd,
1654 "show ipv6 route X:X::X:X",
1655 SHOW_STR
1656 IP_STR
1657 "IPv6 routing table\n"
1658 "IPv6 Address\n")
1659{
1660 int ret;
1661 struct prefix_ipv6 p;
1662 struct route_table *table;
1663 struct route_node *rn;
1664
1665 ret = str2prefix_ipv6 (argv[0], &p);
1666 if (ret <= 0)
1667 {
1668 vty_out (vty, "Malformed IPv6 address%s", VTY_NEWLINE);
1669 return CMD_WARNING;
1670 }
1671
1672 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
1673 if (! table)
1674 return CMD_SUCCESS;
1675
1676 rn = route_node_match (table, (struct prefix *) &p);
1677 if (! rn)
1678 {
1679 vty_out (vty, "%% Network not in table%s", VTY_NEWLINE);
1680 return CMD_WARNING;
1681 }
1682
1683 vty_show_ipv6_route_detail (vty, rn);
1684
1685 route_unlock_node (rn);
1686
1687 return CMD_SUCCESS;
1688}
1689
1690DEFUN (show_ipv6_route_prefix,
1691 show_ipv6_route_prefix_cmd,
1692 "show ipv6 route X:X::X:X/M",
1693 SHOW_STR
1694 IP_STR
1695 "IPv6 routing table\n"
1696 "IPv6 prefix\n")
1697{
1698 int ret;
1699 struct prefix_ipv6 p;
1700 struct route_table *table;
1701 struct route_node *rn;
1702
1703 ret = str2prefix_ipv6 (argv[0], &p);
1704 if (ret <= 0)
1705 {
1706 vty_out (vty, "Malformed IPv6 prefix%s", VTY_NEWLINE);
1707 return CMD_WARNING;
1708 }
1709
1710 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
1711 if (! table)
1712 return CMD_SUCCESS;
1713
1714 rn = route_node_match (table, (struct prefix *) &p);
1715 if (! rn || rn->p.prefixlen != p.prefixlen)
1716 {
1717 vty_out (vty, "%% Network not in table%s", VTY_NEWLINE);
1718 return CMD_WARNING;
1719 }
1720
1721 vty_show_ipv6_route_detail (vty, rn);
1722
1723 route_unlock_node (rn);
1724
1725 return CMD_SUCCESS;
1726}
1727
1728
1729/* Write IPv6 static route configuration. */
1730int
1731static_config_ipv6 (struct vty *vty)
1732{
1733 struct route_node *rn;
1734 struct static_ipv6 *si;
1735 int write;
1736 char buf[BUFSIZ];
1737 struct route_table *stable;
1738
1739 write = 0;
1740
1741 /* Lookup table. */
1742 stable = vrf_static_table (AFI_IP6, SAFI_UNICAST, 0);
1743 if (! stable)
1744 return -1;
1745
1746 for (rn = route_top (stable); rn; rn = route_next (rn))
1747 for (si = rn->info; si; si = si->next)
1748 {
1749 vty_out (vty, "ipv6 route %s/%d",
1750 inet_ntop (AF_INET6, &rn->p.u.prefix6, buf, BUFSIZ),
1751 rn->p.prefixlen);
1752
1753 switch (si->type)
1754 {
1755 case STATIC_IPV6_GATEWAY:
1756 vty_out (vty, " %s", inet_ntop (AF_INET6, &si->ipv6, buf, BUFSIZ));
1757 break;
1758 case STATIC_IPV6_IFNAME:
1759 vty_out (vty, " %s", si->ifname);
1760 break;
1761 case STATIC_IPV6_GATEWAY_IFNAME:
1762 vty_out (vty, " %s %s",
1763 inet_ntop (AF_INET6, &si->ipv6, buf, BUFSIZ), si->ifname);
1764 break;
1765 }
1766
hasso81dfcaa2003-05-25 19:21:25 +00001767 if (CHECK_FLAG(si->flags, ZEBRA_FLAG_REJECT))
1768 vty_out (vty, " %s", "reject");
1769
1770 if (CHECK_FLAG(si->flags, ZEBRA_FLAG_BLACKHOLE))
1771 vty_out (vty, " %s", "blackhole");
1772
paul718e3742002-12-13 20:15:29 +00001773 if (si->distance != ZEBRA_STATIC_DISTANCE_DEFAULT)
1774 vty_out (vty, " %d", si->distance);
1775 vty_out (vty, "%s", VTY_NEWLINE);
1776
1777 write = 1;
1778 }
1779 return write;
1780}
1781#endif /* HAVE_IPV6 */
1782
1783/* Static ip route configuration write function. */
1784int
1785zebra_ip_config (struct vty *vty)
1786{
1787 int write = 0;
1788
1789 write += static_config_ipv4 (vty);
1790#ifdef HAVE_IPV6
1791 write += static_config_ipv6 (vty);
1792#endif /* HAVE_IPV6 */
1793
1794 return write;
1795}
1796
1797/* IP node for static routes. */
1798struct cmd_node ip_node = { IP_NODE, "", 1 };
1799
1800/* Route VTY. */
1801void
1802zebra_vty_route_init ()
1803{
1804 install_node (&ip_node, zebra_ip_config);
1805
1806 install_element (CONFIG_NODE, &ip_route_cmd);
hasso81dfcaa2003-05-25 19:21:25 +00001807 install_element (CONFIG_NODE, &ip_route_flags_cmd);
paul718e3742002-12-13 20:15:29 +00001808 install_element (CONFIG_NODE, &ip_route_mask_cmd);
hasso81dfcaa2003-05-25 19:21:25 +00001809 install_element (CONFIG_NODE, &ip_route_mask_flags_cmd);
paul718e3742002-12-13 20:15:29 +00001810 install_element (CONFIG_NODE, &no_ip_route_cmd);
hasso81dfcaa2003-05-25 19:21:25 +00001811 install_element (CONFIG_NODE, &no_ip_route_flags_cmd);
paul718e3742002-12-13 20:15:29 +00001812 install_element (CONFIG_NODE, &no_ip_route_mask_cmd);
hasso81dfcaa2003-05-25 19:21:25 +00001813 install_element (CONFIG_NODE, &no_ip_route_mask_flags_cmd);
paul718e3742002-12-13 20:15:29 +00001814 install_element (CONFIG_NODE, &ip_route_distance_cmd);
hasso81dfcaa2003-05-25 19:21:25 +00001815 install_element (CONFIG_NODE, &ip_route_flags_distance_cmd);
paul718e3742002-12-13 20:15:29 +00001816 install_element (CONFIG_NODE, &ip_route_mask_distance_cmd);
hasso81dfcaa2003-05-25 19:21:25 +00001817 install_element (CONFIG_NODE, &ip_route_mask_flags_distance_cmd);
paul718e3742002-12-13 20:15:29 +00001818 install_element (CONFIG_NODE, &no_ip_route_distance_cmd);
hasso81dfcaa2003-05-25 19:21:25 +00001819 install_element (CONFIG_NODE, &no_ip_route_flags_distance_cmd);
1820 install_element (CONFIG_NODE, &no_ip_route_mask_flags_distance_cmd);
paul718e3742002-12-13 20:15:29 +00001821
1822 install_element (VIEW_NODE, &show_ip_route_cmd);
1823 install_element (VIEW_NODE, &show_ip_route_addr_cmd);
1824 install_element (VIEW_NODE, &show_ip_route_prefix_cmd);
1825 install_element (VIEW_NODE, &show_ip_route_prefix_longer_cmd);
1826 install_element (VIEW_NODE, &show_ip_route_protocol_cmd);
1827 install_element (VIEW_NODE, &show_ip_route_supernets_cmd);
1828 install_element (ENABLE_NODE, &show_ip_route_cmd);
1829 install_element (ENABLE_NODE, &show_ip_route_addr_cmd);
1830 install_element (ENABLE_NODE, &show_ip_route_prefix_cmd);
1831 install_element (ENABLE_NODE, &show_ip_route_prefix_longer_cmd);
1832 install_element (ENABLE_NODE, &show_ip_route_protocol_cmd);
1833 install_element (ENABLE_NODE, &show_ip_route_supernets_cmd);
1834
1835#if 0
1836 install_element (VIEW_NODE, &show_ip_route_summary_cmd);
1837 install_element (ENABLE_NODE, &show_ip_route_summary_cmd);
1838#endif /* 0 */
1839
1840#ifdef HAVE_IPV6
1841 install_element (CONFIG_NODE, &ipv6_route_cmd);
hasso81dfcaa2003-05-25 19:21:25 +00001842 install_element (CONFIG_NODE, &ipv6_route_flags_cmd);
paul718e3742002-12-13 20:15:29 +00001843 install_element (CONFIG_NODE, &ipv6_route_ifname_cmd);
hasso81dfcaa2003-05-25 19:21:25 +00001844 install_element (CONFIG_NODE, &ipv6_route_ifname_flags_cmd);
paul718e3742002-12-13 20:15:29 +00001845 install_element (CONFIG_NODE, &no_ipv6_route_cmd);
hasso81dfcaa2003-05-25 19:21:25 +00001846 install_element (CONFIG_NODE, &no_ipv6_route_flags_cmd);
paul718e3742002-12-13 20:15:29 +00001847 install_element (CONFIG_NODE, &no_ipv6_route_ifname_cmd);
hasso81dfcaa2003-05-25 19:21:25 +00001848 install_element (CONFIG_NODE, &no_ipv6_route_ifname_flags_cmd);
paul718e3742002-12-13 20:15:29 +00001849 install_element (CONFIG_NODE, &ipv6_route_pref_cmd);
hasso81dfcaa2003-05-25 19:21:25 +00001850 install_element (CONFIG_NODE, &ipv6_route_flags_pref_cmd);
paul718e3742002-12-13 20:15:29 +00001851 install_element (CONFIG_NODE, &ipv6_route_ifname_pref_cmd);
hasso81dfcaa2003-05-25 19:21:25 +00001852 install_element (CONFIG_NODE, &ipv6_route_ifname_flags_pref_cmd);
paul718e3742002-12-13 20:15:29 +00001853 install_element (CONFIG_NODE, &no_ipv6_route_pref_cmd);
hasso81dfcaa2003-05-25 19:21:25 +00001854 install_element (CONFIG_NODE, &no_ipv6_route_flags_pref_cmd);
paul718e3742002-12-13 20:15:29 +00001855 install_element (CONFIG_NODE, &no_ipv6_route_ifname_pref_cmd);
hasso81dfcaa2003-05-25 19:21:25 +00001856 install_element (CONFIG_NODE, &no_ipv6_route_ifname_flags_pref_cmd);
paul718e3742002-12-13 20:15:29 +00001857 install_element (VIEW_NODE, &show_ipv6_route_cmd);
1858 install_element (VIEW_NODE, &show_ipv6_route_protocol_cmd);
1859 install_element (VIEW_NODE, &show_ipv6_route_addr_cmd);
1860 install_element (VIEW_NODE, &show_ipv6_route_prefix_cmd);
1861 install_element (VIEW_NODE, &show_ipv6_route_prefix_longer_cmd);
1862 install_element (ENABLE_NODE, &show_ipv6_route_cmd);
1863 install_element (ENABLE_NODE, &show_ipv6_route_protocol_cmd);
1864 install_element (ENABLE_NODE, &show_ipv6_route_addr_cmd);
1865 install_element (ENABLE_NODE, &show_ipv6_route_prefix_cmd);
1866 install_element (ENABLE_NODE, &show_ipv6_route_prefix_longer_cmd);
1867#endif /* HAVE_IPV6 */
1868}
1869
1870void
1871zebra_vty_init ()
1872{
1873 zebra_vty_route_init ();
1874}