blob: 19ec3ae8abbfde6430c99df9149007819bc2402b [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. */
hasso457ef552003-05-28 12:02:15 +0000131 if ((gate_str != NULL) && (strncasecmp (gate_str, "Null0", strlen (gate_str)) == 0))
paul595db7f2003-05-25 21:35:06 +0000132 {
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
hasso457ef552003-05-28 12:02:15 +0000162 if (gate_str == NULL)
163 {
164 if (add_cmd)
165 static_add_ipv4 (&p, NULL, NULL, flag, distance, 0);
166 else
167 static_delete_ipv4 (&p, NULL, NULL, distance, 0);
168
169 return CMD_SUCCESS;
170 }
171
paul718e3742002-12-13 20:15:29 +0000172 /* When gateway is A.B.C.D format, gate is treated as nexthop
173 address other case gate is treated as interface name. */
174 ret = inet_aton (gate_str, &gate);
175 if (ret)
176 ifname = NULL;
177 else
178 ifname = gate_str;
179
180 if (add_cmd)
hasso81dfcaa2003-05-25 19:21:25 +0000181 static_add_ipv4 (&p, ifname ? NULL : &gate, ifname, flag, distance, 0);
paul718e3742002-12-13 20:15:29 +0000182 else
183 static_delete_ipv4 (&p, ifname ? NULL : &gate, ifname, distance, 0);
184
185 return CMD_SUCCESS;
186}
187
188/* Static route configuration. */
189DEFUN (ip_route,
190 ip_route_cmd,
paul595db7f2003-05-25 21:35:06 +0000191 "ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0)",
hasso81dfcaa2003-05-25 19:21:25 +0000192 IP_STR
193 "Establish static routes\n"
194 "IP destination prefix (e.g. 10.0.0.0/8)\n"
195 "IP gateway address\n"
paul595db7f2003-05-25 21:35:06 +0000196 "IP gateway interface name\n"
197 "Null interface\n")
hasso81dfcaa2003-05-25 19:21:25 +0000198{
199 return zebra_static_ipv4 (vty, 1, argv[0], NULL, argv[1], NULL, NULL);
200}
201
202DEFUN (ip_route_flags,
203 ip_route_flags_cmd,
204 "ip route A.B.C.D/M (A.B.C.D|INTERFACE) (reject|blackhole)",
paul718e3742002-12-13 20:15:29 +0000205 IP_STR
206 "Establish static routes\n"
207 "IP destination prefix (e.g. 10.0.0.0/8)\n"
208 "IP gateway address\n"
209 "IP gateway interface name\n"
hasso81dfcaa2003-05-25 19:21:25 +0000210 "Emit an ICMP unreachable when matched\n"
211 "Silently discard pkts when matched\n")
paul718e3742002-12-13 20:15:29 +0000212{
hasso81dfcaa2003-05-25 19:21:25 +0000213 return zebra_static_ipv4 (vty, 1, argv[0], NULL, argv[1], argv[2], NULL);
paul718e3742002-12-13 20:15:29 +0000214}
215
hasso457ef552003-05-28 12:02:15 +0000216DEFUN (ip_route_flags2,
217 ip_route_flags2_cmd,
218 "ip route A.B.C.D/M (reject|blackhole)",
219 IP_STR
220 "Establish static routes\n"
221 "IP destination prefix (e.g. 10.0.0.0/8)\n"
222 "Emit an ICMP unreachable when matched\n"
223 "Silently discard pkts when matched\n")
224{
225 return zebra_static_ipv4 (vty, 1, argv[0], NULL, NULL, argv[1], NULL);
226}
227
paul718e3742002-12-13 20:15:29 +0000228/* Mask as A.B.C.D format. */
229DEFUN (ip_route_mask,
230 ip_route_mask_cmd,
paul595db7f2003-05-25 21:35:06 +0000231 "ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0)",
hasso81dfcaa2003-05-25 19:21:25 +0000232 IP_STR
233 "Establish static routes\n"
234 "IP destination prefix\n"
235 "IP destination prefix mask\n"
236 "IP gateway address\n"
paul595db7f2003-05-25 21:35:06 +0000237 "IP gateway interface name\n"
238 "Null interface\n")
hasso81dfcaa2003-05-25 19:21:25 +0000239{
240 return zebra_static_ipv4 (vty, 1, argv[0], argv[1], argv[2], NULL, NULL);
241}
242
243DEFUN (ip_route_mask_flags,
244 ip_route_mask_flags_cmd,
245 "ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE) (reject|blackhole)",
paul718e3742002-12-13 20:15:29 +0000246 IP_STR
247 "Establish static routes\n"
248 "IP destination prefix\n"
249 "IP destination prefix mask\n"
250 "IP gateway address\n"
251 "IP gateway interface name\n"
hasso81dfcaa2003-05-25 19:21:25 +0000252 "Emit an ICMP unreachable when matched\n"
253 "Silently discard pkts when matched\n")
paul718e3742002-12-13 20:15:29 +0000254{
hasso81dfcaa2003-05-25 19:21:25 +0000255 return zebra_static_ipv4 (vty, 1, argv[0], argv[1], argv[2], argv[3], NULL);
paul718e3742002-12-13 20:15:29 +0000256}
257
hasso457ef552003-05-28 12:02:15 +0000258DEFUN (ip_route_mask_flags2,
259 ip_route_mask_flags2_cmd,
260 "ip route A.B.C.D A.B.C.D (reject|blackhole)",
261 IP_STR
262 "Establish static routes\n"
263 "IP destination prefix\n"
264 "IP destination prefix mask\n"
265 "Emit an ICMP unreachable when matched\n"
266 "Silently discard pkts when matched\n")
267{
268 return zebra_static_ipv4 (vty, 1, argv[0], argv[1], NULL, argv[2], NULL);
269}
270
paul718e3742002-12-13 20:15:29 +0000271/* Distance option value. */
272DEFUN (ip_route_distance,
273 ip_route_distance_cmd,
paul595db7f2003-05-25 21:35:06 +0000274 "ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0) <1-255>",
paul718e3742002-12-13 20:15:29 +0000275 IP_STR
276 "Establish static routes\n"
277 "IP destination prefix (e.g. 10.0.0.0/8)\n"
278 "IP gateway address\n"
279 "IP gateway interface name\n"
paul595db7f2003-05-25 21:35:06 +0000280 "Null interface\n"
paul718e3742002-12-13 20:15:29 +0000281 "Distance value for this route\n")
282{
hasso81dfcaa2003-05-25 19:21:25 +0000283 return zebra_static_ipv4 (vty, 1, argv[0], NULL, argv[1], NULL, argv[2]);
284}
285
286DEFUN (ip_route_flags_distance,
287 ip_route_flags_distance_cmd,
288 "ip route A.B.C.D/M (A.B.C.D|INTERFACE) (reject|blackhole) <1-255>",
289 IP_STR
290 "Establish static routes\n"
291 "IP destination prefix (e.g. 10.0.0.0/8)\n"
292 "IP gateway address\n"
293 "IP gateway interface name\n"
294 "Emit an ICMP unreachable when matched\n"
295 "Silently discard pkts when matched\n"
296 "Distance value for this route\n")
297{
298 return zebra_static_ipv4 (vty, 1, argv[0], NULL, argv[1], argv[2], argv[3]);
paul718e3742002-12-13 20:15:29 +0000299}
300
hasso457ef552003-05-28 12:02:15 +0000301DEFUN (ip_route_flags_distance2,
302 ip_route_flags_distance2_cmd,
303 "ip route A.B.C.D/M (reject|blackhole) <1-255>",
304 IP_STR
305 "Establish static routes\n"
306 "IP destination prefix (e.g. 10.0.0.0/8)\n"
307 "Emit an ICMP unreachable when matched\n"
308 "Silently discard pkts when matched\n"
309 "Distance value for this route\n")
310{
311 return zebra_static_ipv4 (vty, 1, argv[0], NULL, NULL, argv[1], argv[2]);
312}
313
paul718e3742002-12-13 20:15:29 +0000314DEFUN (ip_route_mask_distance,
315 ip_route_mask_distance_cmd,
paul595db7f2003-05-25 21:35:06 +0000316 "ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0) <1-255>",
paul718e3742002-12-13 20:15:29 +0000317 IP_STR
318 "Establish static routes\n"
319 "IP destination prefix\n"
320 "IP destination prefix mask\n"
321 "IP gateway address\n"
322 "IP gateway interface name\n"
paul595db7f2003-05-25 21:35:06 +0000323 "Null interface\n"
paul718e3742002-12-13 20:15:29 +0000324 "Distance value for this route\n")
325{
hasso81dfcaa2003-05-25 19:21:25 +0000326 return zebra_static_ipv4 (vty, 1, argv[0], argv[1], argv[2], NULL, argv[3]);
327}
328
329DEFUN (ip_route_mask_flags_distance,
330 ip_route_mask_flags_distance_cmd,
331 "ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE) (reject|blackhole) <1-255>",
332 IP_STR
333 "Establish static routes\n"
334 "IP destination prefix\n"
335 "IP destination prefix mask\n"
336 "IP gateway address\n"
337 "IP gateway interface name\n"
338 "Distance value for this route\n"
339 "Emit an ICMP unreachable when matched\n"
340 "Silently discard pkts when matched\n")
341{
342 return zebra_static_ipv4 (vty, 1, argv[0], argv[1], argv[2], argv[3], argv[4]);
paul718e3742002-12-13 20:15:29 +0000343}
344
hasso457ef552003-05-28 12:02:15 +0000345DEFUN (ip_route_mask_flags_distance2,
346 ip_route_mask_flags_distance2_cmd,
347 "ip route A.B.C.D A.B.C.D (reject|blackhole) <1-255>",
348 IP_STR
349 "Establish static routes\n"
350 "IP destination prefix\n"
351 "IP destination prefix mask\n"
352 "Distance value for this route\n"
353 "Emit an ICMP unreachable when matched\n"
354 "Silently discard pkts when matched\n")
355{
356 return zebra_static_ipv4 (vty, 1, argv[0], argv[1], NULL, argv[2], argv[3]);
357}
358
paul718e3742002-12-13 20:15:29 +0000359DEFUN (no_ip_route,
360 no_ip_route_cmd,
paul595db7f2003-05-25 21:35:06 +0000361 "no ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0)",
hasso81dfcaa2003-05-25 19:21:25 +0000362 NO_STR
363 IP_STR
364 "Establish static routes\n"
365 "IP destination prefix (e.g. 10.0.0.0/8)\n"
366 "IP gateway address\n"
paul595db7f2003-05-25 21:35:06 +0000367 "IP gateway interface name\n"
368 "Null interface\n")
hasso81dfcaa2003-05-25 19:21:25 +0000369{
370 return zebra_static_ipv4 (vty, 0, argv[0], NULL, argv[1], NULL, NULL);
371}
372
373ALIAS (no_ip_route,
374 no_ip_route_flags_cmd,
375 "no ip route A.B.C.D/M (A.B.C.D|INTERFACE) (reject|blackhole)",
paul718e3742002-12-13 20:15:29 +0000376 NO_STR
377 IP_STR
378 "Establish static routes\n"
379 "IP destination prefix (e.g. 10.0.0.0/8)\n"
380 "IP gateway address\n"
381 "IP gateway interface name\n"
hasso81dfcaa2003-05-25 19:21:25 +0000382 "Emit an ICMP unreachable when matched\n"
383 "Silently discard pkts when matched\n")
paul718e3742002-12-13 20:15:29 +0000384
hasso457ef552003-05-28 12:02:15 +0000385DEFUN (no_ip_route_flags2,
386 no_ip_route_flags2_cmd,
387 "no ip route A.B.C.D/M (reject|blackhole)",
388 NO_STR
389 IP_STR
390 "Establish static routes\n"
391 "IP destination prefix (e.g. 10.0.0.0/8)\n"
392 "Emit an ICMP unreachable when matched\n"
393 "Silently discard pkts when matched\n")
394{
395 return zebra_static_ipv4 (vty, 0, argv[0], NULL, NULL, NULL, NULL);
396}
397
paul718e3742002-12-13 20:15:29 +0000398DEFUN (no_ip_route_mask,
399 no_ip_route_mask_cmd,
paul595db7f2003-05-25 21:35:06 +0000400 "no ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0)",
hasso81dfcaa2003-05-25 19:21:25 +0000401 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"
paul595db7f2003-05-25 21:35:06 +0000407 "IP gateway interface name\n"
408 "Null interface\n")
hasso81dfcaa2003-05-25 19:21:25 +0000409{
410 return zebra_static_ipv4 (vty, 0, argv[0], argv[1], argv[2], NULL, NULL);
411}
412
413ALIAS (no_ip_route_mask,
414 no_ip_route_mask_flags_cmd,
415 "no ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE) (reject|blackhole)",
paul718e3742002-12-13 20:15:29 +0000416 NO_STR
417 IP_STR
418 "Establish static routes\n"
419 "IP destination prefix\n"
420 "IP destination prefix mask\n"
421 "IP gateway address\n"
422 "IP gateway interface name\n"
hasso81dfcaa2003-05-25 19:21:25 +0000423 "Emit an ICMP unreachable when matched\n"
424 "Silently discard pkts when matched\n")
paul718e3742002-12-13 20:15:29 +0000425
hasso457ef552003-05-28 12:02:15 +0000426DEFUN (no_ip_route_mask_flags2,
427 no_ip_route_mask_flags2_cmd,
428 "no ip route A.B.C.D A.B.C.D (reject|blackhole)",
429 NO_STR
430 IP_STR
431 "Establish static routes\n"
432 "IP destination prefix\n"
433 "IP destination prefix mask\n"
434 "Emit an ICMP unreachable when matched\n"
435 "Silently discard pkts when matched\n")
436{
437 return zebra_static_ipv4 (vty, 0, argv[0], argv[1], NULL, NULL, NULL);
438}
439
paul718e3742002-12-13 20:15:29 +0000440DEFUN (no_ip_route_distance,
441 no_ip_route_distance_cmd,
paul595db7f2003-05-25 21:35:06 +0000442 "no ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0) <1-255>",
paul718e3742002-12-13 20:15:29 +0000443 NO_STR
444 IP_STR
445 "Establish static routes\n"
446 "IP destination prefix (e.g. 10.0.0.0/8)\n"
447 "IP gateway address\n"
448 "IP gateway interface name\n"
paul595db7f2003-05-25 21:35:06 +0000449 "Null interface\n"
paul718e3742002-12-13 20:15:29 +0000450 "Distance value for this route\n")
451{
hasso81dfcaa2003-05-25 19:21:25 +0000452 return zebra_static_ipv4 (vty, 0, argv[0], NULL, argv[1], NULL, argv[2]);
453}
454
455DEFUN (no_ip_route_flags_distance,
456 no_ip_route_flags_distance_cmd,
457 "no ip route A.B.C.D/M (A.B.C.D|INTERFACE) (reject|blackhole) <1-255>",
458 NO_STR
459 IP_STR
460 "Establish static routes\n"
461 "IP destination prefix (e.g. 10.0.0.0/8)\n"
462 "IP gateway address\n"
463 "IP gateway interface name\n"
464 "Emit an ICMP unreachable when matched\n"
465 "Silently discard pkts when matched\n"
466 "Distance value for this route\n")
467{
468 return zebra_static_ipv4 (vty, 0, argv[0], NULL, argv[1], argv[2], argv[3]);
paul718e3742002-12-13 20:15:29 +0000469}
470
hasso457ef552003-05-28 12:02:15 +0000471DEFUN (no_ip_route_flags_distance2,
472 no_ip_route_flags_distance2_cmd,
473 "no ip route A.B.C.D/M (reject|blackhole) <1-255>",
474 NO_STR
475 IP_STR
476 "Establish static routes\n"
477 "IP destination prefix (e.g. 10.0.0.0/8)\n"
478 "Emit an ICMP unreachable when matched\n"
479 "Silently discard pkts when matched\n"
480 "Distance value for this route\n")
481{
482 return zebra_static_ipv4 (vty, 0, argv[0], NULL, NULL, argv[1], argv[2]);
483}
484
paul718e3742002-12-13 20:15:29 +0000485DEFUN (no_ip_route_mask_distance,
486 no_ip_route_mask_distance_cmd,
paul595db7f2003-05-25 21:35:06 +0000487 "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 +0000488 NO_STR
489 IP_STR
490 "Establish static routes\n"
491 "IP destination prefix\n"
492 "IP destination prefix mask\n"
493 "IP gateway address\n"
494 "IP gateway interface name\n"
paul595db7f2003-05-25 21:35:06 +0000495 "Null interface\n"
paul718e3742002-12-13 20:15:29 +0000496 "Distance value for this route\n")
497{
hasso81dfcaa2003-05-25 19:21:25 +0000498 return zebra_static_ipv4 (vty, 0, argv[0], argv[1], argv[2], NULL, argv[3]);
499}
500
501DEFUN (no_ip_route_mask_flags_distance,
502 no_ip_route_mask_flags_distance_cmd,
503 "no ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE) (reject|blackhole) <1-255>",
504 NO_STR
505 IP_STR
506 "Establish static routes\n"
507 "IP destination prefix\n"
508 "IP destination prefix mask\n"
509 "IP gateway address\n"
510 "IP gateway interface name\n"
511 "Emit an ICMP unreachable when matched\n"
512 "Silently discard pkts when matched\n"
513 "Distance value for this route\n")
514{
515 return zebra_static_ipv4 (vty, 0, argv[0], argv[1], argv[2], argv[3], argv[4]);
paul718e3742002-12-13 20:15:29 +0000516}
517
hasso457ef552003-05-28 12:02:15 +0000518DEFUN (no_ip_route_mask_flags_distance2,
519 no_ip_route_mask_flags_distance2_cmd,
520 "no ip route A.B.C.D A.B.C.D (reject|blackhole) <1-255>",
521 NO_STR
522 IP_STR
523 "Establish static routes\n"
524 "IP destination prefix\n"
525 "IP destination prefix mask\n"
526 "Emit an ICMP unreachable when matched\n"
527 "Silently discard pkts when matched\n"
528 "Distance value for this route\n")
529{
530 return zebra_static_ipv4 (vty, 0, argv[0], argv[1], NULL, argv[2], argv[3]);
531}
532
paul718e3742002-12-13 20:15:29 +0000533/* New RIB. Detailed information for IPv4 route. */
534void
535vty_show_ip_route_detail (struct vty *vty, struct route_node *rn)
536{
537 struct rib *rib;
538 struct nexthop *nexthop;
539
540 for (rib = rn->info; rib; rib = rib->next)
541 {
542 vty_out (vty, "Routing entry for %s/%d%s",
543 inet_ntoa (rn->p.u.prefix4), rn->p.prefixlen,
544 VTY_NEWLINE);
545 vty_out (vty, " Known via \"%s\"", route_type_str (rib->type));
546 vty_out (vty, ", distance %d, metric %d", rib->distance, rib->metric);
547 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
548 vty_out (vty, ", best");
549 if (rib->refcnt)
550 vty_out (vty, ", refcnt %ld", rib->refcnt);
hasso81dfcaa2003-05-25 19:21:25 +0000551 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_BLACKHOLE))
552 vty_out (vty, ", blackhole");
553 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_REJECT))
554 vty_out (vty, ", reject");
paul718e3742002-12-13 20:15:29 +0000555 vty_out (vty, "%s", VTY_NEWLINE);
556
557#define ONE_DAY_SECOND 60*60*24
558#define ONE_WEEK_SECOND 60*60*24*7
559 if (rib->type == ZEBRA_ROUTE_RIP
560 || rib->type == ZEBRA_ROUTE_OSPF
561 || rib->type == ZEBRA_ROUTE_BGP)
562 {
563 time_t uptime;
564 struct tm *tm;
565
566 uptime = time (NULL);
567 uptime -= rib->uptime;
568 tm = gmtime (&uptime);
569
570 vty_out (vty, " Last update ");
571
572 if (uptime < ONE_DAY_SECOND)
573 vty_out (vty, "%02d:%02d:%02d",
574 tm->tm_hour, tm->tm_min, tm->tm_sec);
575 else if (uptime < ONE_WEEK_SECOND)
576 vty_out (vty, "%dd%02dh%02dm",
577 tm->tm_yday, tm->tm_hour, tm->tm_min);
578 else
579 vty_out (vty, "%02dw%dd%02dh",
580 tm->tm_yday/7,
581 tm->tm_yday - ((tm->tm_yday/7) * 7), tm->tm_hour);
582 vty_out (vty, " ago%s", VTY_NEWLINE);
583 }
584
585 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
586 {
587 vty_out (vty, " %c",
588 CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB) ? '*' : ' ');
589
590 switch (nexthop->type)
591 {
592 case NEXTHOP_TYPE_IPV4:
593 case NEXTHOP_TYPE_IPV4_IFINDEX:
594 vty_out (vty, " %s", inet_ntoa (nexthop->gate.ipv4));
595 if (nexthop->ifindex)
596 vty_out (vty, ", via %s", ifindex2ifname (nexthop->ifindex));
597 break;
598 case NEXTHOP_TYPE_IFINDEX:
599 vty_out (vty, " directly connected, %s",
600 ifindex2ifname (nexthop->ifindex));
601 break;
602 case NEXTHOP_TYPE_IFNAME:
603 vty_out (vty, " directly connected, %s", nexthop->ifname);
604 break;
paul595db7f2003-05-25 21:35:06 +0000605 case NEXTHOP_TYPE_BLACKHOLE:
hasso457ef552003-05-28 12:02:15 +0000606 vty_out (vty, " directly connected");
607 if (!rib->flags)
608 vty_out (vty, ", Null0");
paul595db7f2003-05-25 21:35:06 +0000609 break;
paul718e3742002-12-13 20:15:29 +0000610 default:
611 break;
612 }
613 if (! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
614 vty_out (vty, " inactive");
615
616 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
617 {
618 vty_out (vty, " (recursive");
619
620 switch (nexthop->rtype)
621 {
622 case NEXTHOP_TYPE_IPV4:
623 case NEXTHOP_TYPE_IPV4_IFINDEX:
624 vty_out (vty, " via %s)", inet_ntoa (nexthop->rgate.ipv4));
625 break;
626 case NEXTHOP_TYPE_IFINDEX:
627 case NEXTHOP_TYPE_IFNAME:
628 vty_out (vty, " is directly connected, %s)",
629 ifindex2ifname (nexthop->rifindex));
630 break;
631 default:
632 break;
633 }
634 }
635 vty_out (vty, "%s", VTY_NEWLINE);
636 }
637 vty_out (vty, "%s", VTY_NEWLINE);
638 }
639}
640
641void
642vty_show_ip_route (struct vty *vty, struct route_node *rn, struct rib *rib)
643{
644 struct nexthop *nexthop;
645 int len = 0;
646 char buf[BUFSIZ];
647
648 /* Nexthop information. */
649 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
650 {
651 if (nexthop == rib->nexthop)
652 {
653 /* Prefix information. */
654 len = vty_out (vty, "%c%c%c %s/%d",
655 route_type_char (rib->type),
656 CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED)
657 ? '>' : ' ',
658 CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)
659 ? '*' : ' ',
660 inet_ntop (AF_INET, &rn->p.u.prefix, buf, BUFSIZ),
661 rn->p.prefixlen);
662
663 /* Distance and metric display. */
664 if (rib->type != ZEBRA_ROUTE_CONNECT
665 && rib->type != ZEBRA_ROUTE_KERNEL)
666 len += vty_out (vty, " [%d/%d]", rib->distance,
667 rib->metric);
668 }
669 else
670 vty_out (vty, " %c%*c",
671 CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)
672 ? '*' : ' ',
673 len - 3, ' ');
674
675 switch (nexthop->type)
676 {
677 case NEXTHOP_TYPE_IPV4:
678 case NEXTHOP_TYPE_IPV4_IFINDEX:
679 vty_out (vty, " via %s", inet_ntoa (nexthop->gate.ipv4));
680 if (nexthop->ifindex)
681 vty_out (vty, ", %s", ifindex2ifname (nexthop->ifindex));
682 break;
683 case NEXTHOP_TYPE_IFINDEX:
684 vty_out (vty, " is directly connected, %s",
685 ifindex2ifname (nexthop->ifindex));
686 break;
687 case NEXTHOP_TYPE_IFNAME:
688 vty_out (vty, " is directly connected, %s", nexthop->ifname);
689 break;
paul595db7f2003-05-25 21:35:06 +0000690 case NEXTHOP_TYPE_BLACKHOLE:
hasso457ef552003-05-28 12:02:15 +0000691 vty_out (vty, " is directly connected");
692 if (!rib->flags)
693 vty_out (vty, ", Null0");
paul595db7f2003-05-25 21:35:06 +0000694 break;
paul718e3742002-12-13 20:15:29 +0000695 default:
696 break;
697 }
698 if (! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
699 vty_out (vty, " inactive");
700
701 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
702 {
703 vty_out (vty, " (recursive");
704
705 switch (nexthop->rtype)
706 {
707 case NEXTHOP_TYPE_IPV4:
708 case NEXTHOP_TYPE_IPV4_IFINDEX:
709 vty_out (vty, " via %s)", inet_ntoa (nexthop->rgate.ipv4));
710 break;
711 case NEXTHOP_TYPE_IFINDEX:
712 case NEXTHOP_TYPE_IFNAME:
713 vty_out (vty, " is directly connected, %s)",
714 ifindex2ifname (nexthop->rifindex));
715 break;
716 default:
717 break;
718 }
719 }
720
hasso81dfcaa2003-05-25 19:21:25 +0000721 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_BLACKHOLE))
722 vty_out (vty, ", bh");
723 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_REJECT))
724 vty_out (vty, ", rej");
725
paul718e3742002-12-13 20:15:29 +0000726 if (rib->type == ZEBRA_ROUTE_RIP
727 || rib->type == ZEBRA_ROUTE_OSPF
728 || rib->type == ZEBRA_ROUTE_BGP)
729 {
730 time_t uptime;
731 struct tm *tm;
732
733 uptime = time (NULL);
734 uptime -= rib->uptime;
735 tm = gmtime (&uptime);
736
737#define ONE_DAY_SECOND 60*60*24
738#define ONE_WEEK_SECOND 60*60*24*7
739
740 if (uptime < ONE_DAY_SECOND)
741 vty_out (vty, ", %02d:%02d:%02d",
742 tm->tm_hour, tm->tm_min, tm->tm_sec);
743 else if (uptime < ONE_WEEK_SECOND)
744 vty_out (vty, ", %dd%02dh%02dm",
745 tm->tm_yday, tm->tm_hour, tm->tm_min);
746 else
747 vty_out (vty, ", %02dw%dd%02dh",
748 tm->tm_yday/7,
749 tm->tm_yday - ((tm->tm_yday/7) * 7), tm->tm_hour);
750 }
751 vty_out (vty, "%s", VTY_NEWLINE);
752 }
753}
754
755#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"
756
757DEFUN (show_ip_route,
758 show_ip_route_cmd,
759 "show ip route",
760 SHOW_STR
761 IP_STR
762 "IP routing table\n")
763{
764 struct route_table *table;
765 struct route_node *rn;
766 struct rib *rib;
767 int first = 1;
768
769 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
770 if (! table)
771 return CMD_SUCCESS;
772
773 /* Show all IPv4 routes. */
774 for (rn = route_top (table); rn; rn = route_next (rn))
775 for (rib = rn->info; rib; rib = rib->next)
776 {
777 if (first)
778 {
779 vty_out (vty, SHOW_ROUTE_V4_HEADER, VTY_NEWLINE, VTY_NEWLINE,
780 VTY_NEWLINE);
781 first = 0;
782 }
783 vty_show_ip_route (vty, rn, rib);
784 }
785 return CMD_SUCCESS;
786}
787
788DEFUN (show_ip_route_prefix_longer,
789 show_ip_route_prefix_longer_cmd,
790 "show ip route A.B.C.D/M longer-prefixes",
791 SHOW_STR
792 IP_STR
793 "IP routing table\n"
794 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
795 "Show route matching the specified Network/Mask pair only\n")
796{
797 struct route_table *table;
798 struct route_node *rn;
799 struct rib *rib;
800 struct prefix p;
801 int ret;
802 int first = 1;
803
804 ret = str2prefix (argv[0], &p);
805 if (! ret)
806 {
807 vty_out (vty, "%% Malformed Prefix%s", VTY_NEWLINE);
808 return CMD_WARNING;
809 }
810
811 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
812 if (! table)
813 return CMD_SUCCESS;
814
815 /* Show matched type IPv4 routes. */
816 for (rn = route_top (table); rn; rn = route_next (rn))
817 for (rib = rn->info; rib; rib = rib->next)
818 if (prefix_match (&p, &rn->p))
819 {
820 if (first)
821 {
822 vty_out (vty, SHOW_ROUTE_V4_HEADER, VTY_NEWLINE,
823 VTY_NEWLINE, VTY_NEWLINE);
824 first = 0;
825 }
826 vty_show_ip_route (vty, rn, rib);
827 }
828 return CMD_SUCCESS;
829}
830
831DEFUN (show_ip_route_supernets,
832 show_ip_route_supernets_cmd,
833 "show ip route supernets-only",
834 SHOW_STR
835 IP_STR
836 "IP routing table\n"
837 "Show supernet entries only\n")
838{
839 struct route_table *table;
840 struct route_node *rn;
841 struct rib *rib;
842 u_int32_t addr;
843 int first = 1;
844
845 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
846 if (! table)
847 return CMD_SUCCESS;
848
849 /* Show matched type IPv4 routes. */
850 for (rn = route_top (table); rn; rn = route_next (rn))
851 for (rib = rn->info; rib; rib = rib->next)
852 {
853 addr = ntohl (rn->p.u.prefix4.s_addr);
854
855 if ((IN_CLASSC (addr) && rn->p.prefixlen < 24)
856 || (IN_CLASSB (addr) && rn->p.prefixlen < 16)
857 || (IN_CLASSA (addr) && rn->p.prefixlen < 8))
858 {
859 if (first)
860 {
861 vty_out (vty, SHOW_ROUTE_V4_HEADER, VTY_NEWLINE,
862 VTY_NEWLINE, VTY_NEWLINE);
863 first = 0;
864 }
865 vty_show_ip_route (vty, rn, rib);
866 }
867 }
868 return CMD_SUCCESS;
869}
870
871DEFUN (show_ip_route_protocol,
872 show_ip_route_protocol_cmd,
873 "show ip route (bgp|connected|kernel|ospf|rip|static)",
874 SHOW_STR
875 IP_STR
876 "IP routing table\n"
877 "Border Gateway Protocol (BGP)\n"
878 "Connected\n"
879 "Kernel\n"
880 "Open Shortest Path First (OSPF)\n"
881 "Routing Information Protocol (RIP)\n"
882 "Static routes\n")
883{
884 int type;
885 struct route_table *table;
886 struct route_node *rn;
887 struct rib *rib;
888 int first = 1;
889
890 if (strncmp (argv[0], "b", 1) == 0)
891 type = ZEBRA_ROUTE_BGP;
892 else if (strncmp (argv[0], "c", 1) == 0)
893 type = ZEBRA_ROUTE_CONNECT;
894 else if (strncmp (argv[0], "k", 1) ==0)
895 type = ZEBRA_ROUTE_KERNEL;
896 else if (strncmp (argv[0], "o", 1) == 0)
897 type = ZEBRA_ROUTE_OSPF;
898 else if (strncmp (argv[0], "r", 1) == 0)
899 type = ZEBRA_ROUTE_RIP;
900 else if (strncmp (argv[0], "s", 1) == 0)
901 type = ZEBRA_ROUTE_STATIC;
902 else
903 {
904 vty_out (vty, "Unknown route type%s", VTY_NEWLINE);
905 return CMD_WARNING;
906 }
907
908 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
909 if (! table)
910 return CMD_SUCCESS;
911
912 /* Show matched type IPv4 routes. */
913 for (rn = route_top (table); rn; rn = route_next (rn))
914 for (rib = rn->info; rib; rib = rib->next)
915 if (rib->type == type)
916 {
917 if (first)
918 {
919 vty_out (vty, SHOW_ROUTE_V4_HEADER,
920 VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE);
921 first = 0;
922 }
923 vty_show_ip_route (vty, rn, rib);
924 }
925 return CMD_SUCCESS;
926}
927
928DEFUN (show_ip_route_addr,
929 show_ip_route_addr_cmd,
930 "show ip route A.B.C.D",
931 SHOW_STR
932 IP_STR
933 "IP routing table\n"
934 "Network in the IP routing table to display\n")
935{
936 int ret;
937 struct prefix_ipv4 p;
938 struct route_table *table;
939 struct route_node *rn;
940
941 ret = str2prefix_ipv4 (argv[0], &p);
942 if (ret <= 0)
943 {
944 vty_out (vty, "%% Malformed IPv4 address%s", VTY_NEWLINE);
945 return CMD_WARNING;
946 }
947
948 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
949 if (! table)
950 return CMD_SUCCESS;
951
952 rn = route_node_match (table, (struct prefix *) &p);
953 if (! rn)
954 {
955 vty_out (vty, "%% Network not in table%s", VTY_NEWLINE);
956 return CMD_WARNING;
957 }
958
959 vty_show_ip_route_detail (vty, rn);
960
961 route_unlock_node (rn);
962
963 return CMD_SUCCESS;
964}
965
966DEFUN (show_ip_route_prefix,
967 show_ip_route_prefix_cmd,
968 "show ip route A.B.C.D/M",
969 SHOW_STR
970 IP_STR
971 "IP routing table\n"
972 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n")
973{
974 int ret;
975 struct prefix_ipv4 p;
976 struct route_table *table;
977 struct route_node *rn;
978
979 ret = str2prefix_ipv4 (argv[0], &p);
980 if (ret <= 0)
981 {
982 vty_out (vty, "%% Malformed IPv4 address%s", VTY_NEWLINE);
983 return CMD_WARNING;
984 }
985
986 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
987 if (! table)
988 return CMD_SUCCESS;
989
990 rn = route_node_match (table, (struct prefix *) &p);
991 if (! rn || rn->p.prefixlen != p.prefixlen)
992 {
993 vty_out (vty, "%% Network not in table%s", VTY_NEWLINE);
994 return CMD_WARNING;
995 }
996
997 vty_show_ip_route_detail (vty, rn);
998
999 route_unlock_node (rn);
1000
1001 return CMD_SUCCESS;
1002}
1003
1004void
1005zebra_show_ip_route (struct vty *vty, struct vrf *vrf)
1006{
1007 vty_out (vty, "IP routing table name is %s(%d)%s",
1008 vrf->name ? vrf->name : "", vrf->id, VTY_NEWLINE);
1009
1010 vty_out (vty, "Route Source Networks%s", VTY_NEWLINE);
1011 vty_out (vty, "connected %d%s", 0, VTY_NEWLINE);
1012 vty_out (vty, "static %d%s", 0, VTY_NEWLINE);
1013 vty_out (vty, "rip %d%s", 0, VTY_NEWLINE);
1014
1015 vty_out (vty, "bgp %d%s", 0, VTY_NEWLINE);
1016 vty_out (vty, " External: %d Internal: %d Local: %d%s",
1017 0, 0, 0, VTY_NEWLINE);
1018
1019 vty_out (vty, "ospf %d%s", 0, VTY_NEWLINE);
1020 vty_out (vty,
1021 " Intra-area: %d Inter-area: %d External-1: %d External-2: %d%s",
1022 0, 0, 0, 0, VTY_NEWLINE);
1023 vty_out (vty, " NSSA External-1: %d NSSA External-2: %d%s",
1024 0, 0, VTY_NEWLINE);
1025
1026 vty_out (vty, "internal %d%s", 0, VTY_NEWLINE);
1027 vty_out (vty, "Total %d%s", 0, VTY_NEWLINE);
1028}
1029
1030/* Show route summary. */
1031DEFUN (show_ip_route_summary,
1032 show_ip_route_summary_cmd,
1033 "show ip route summary",
1034 SHOW_STR
1035 IP_STR
1036 "IP routing table\n"
1037 "Summary of all routes\n")
1038{
1039 struct vrf *vrf;
1040
1041 /* Default table id is zero. */
1042 vrf = vrf_lookup (0);
1043 if (! vrf)
1044 {
1045 vty_out (vty, "%% No Default-IP-Routing-Table%s", VTY_NEWLINE);
1046 return CMD_WARNING;
1047 }
1048
1049 zebra_show_ip_route (vty, vrf);
1050
1051 return CMD_SUCCESS;
1052}
1053
1054/* Write IPv4 static route configuration. */
1055int
1056static_config_ipv4 (struct vty *vty)
1057{
1058 struct route_node *rn;
1059 struct static_ipv4 *si;
1060 struct route_table *stable;
1061 int write;
1062
1063 write = 0;
1064
1065 /* Lookup table. */
1066 stable = vrf_static_table (AFI_IP, SAFI_UNICAST, 0);
1067 if (! stable)
1068 return -1;
1069
1070 for (rn = route_top (stable); rn; rn = route_next (rn))
1071 for (si = rn->info; si; si = si->next)
1072 {
1073 vty_out (vty, "ip route %s/%d", inet_ntoa (rn->p.u.prefix4),
1074 rn->p.prefixlen);
1075
1076 switch (si->type)
1077 {
1078 case STATIC_IPV4_GATEWAY:
1079 vty_out (vty, " %s", inet_ntoa (si->gate.ipv4));
1080 break;
1081 case STATIC_IPV4_IFNAME:
1082 vty_out (vty, " %s", si->gate.ifname);
1083 break;
paul595db7f2003-05-25 21:35:06 +00001084 case STATIC_IPV4_BLACKHOLE:
hasso457ef552003-05-28 12:02:15 +00001085 if (!si->flags)
1086 vty_out (vty, " Null0");
paul595db7f2003-05-25 21:35:06 +00001087 break;
paul718e3742002-12-13 20:15:29 +00001088 }
1089
hasso81dfcaa2003-05-25 19:21:25 +00001090 if (CHECK_FLAG(si->flags, ZEBRA_FLAG_REJECT))
1091 vty_out (vty, " %s", "reject");
1092
1093 if (CHECK_FLAG(si->flags, ZEBRA_FLAG_BLACKHOLE))
1094 vty_out (vty, " %s", "blackhole");
1095
paul718e3742002-12-13 20:15:29 +00001096 if (si->distance != ZEBRA_STATIC_DISTANCE_DEFAULT)
1097 vty_out (vty, " %d", si->distance);
1098 vty_out (vty, "%s", VTY_NEWLINE);
1099
1100 write = 1;
1101 }
1102 return write;
1103}
1104
1105#ifdef HAVE_IPV6
1106/* General fucntion for IPv6 static route. */
1107int
1108static_ipv6_func (struct vty *vty, int add_cmd, char *dest_str,
hasso81dfcaa2003-05-25 19:21:25 +00001109 char *gate_str, char *ifname, char *flag_str, char *distance_str)
paul718e3742002-12-13 20:15:29 +00001110{
1111 int ret;
1112 u_char distance;
1113 struct prefix p;
1114 struct in6_addr *gate = NULL;
1115 struct in6_addr gate_addr;
1116 u_char type = 0;
1117 int table = 0;
hasso81dfcaa2003-05-25 19:21:25 +00001118 u_char flag = 0;
paul718e3742002-12-13 20:15:29 +00001119
1120 ret = str2prefix (dest_str, &p);
1121 if (ret <= 0)
1122 {
1123 vty_out (vty, "%% Malformed address%s", VTY_NEWLINE);
1124 return CMD_WARNING;
1125 }
1126
1127 /* Apply mask for given prefix. */
1128 apply_mask (&p);
1129
hasso81dfcaa2003-05-25 19:21:25 +00001130 /* Route flags */
1131 if (flag_str) {
1132 switch(flag_str[0]) {
1133 case 'r':
1134 case 'R': /* XXX */
1135 SET_FLAG (flag, ZEBRA_FLAG_REJECT);
1136 break;
1137 case 'b':
1138 case 'B': /* XXX */
1139 SET_FLAG (flag, ZEBRA_FLAG_BLACKHOLE);
1140 break;
1141 default:
1142 vty_out (vty, "%% Malformed flag %s %s", flag_str, VTY_NEWLINE);
paul595db7f2003-05-25 21:35:06 +00001143 return CMD_WARNING;
hasso81dfcaa2003-05-25 19:21:25 +00001144 }
1145 }
1146
paul718e3742002-12-13 20:15:29 +00001147 /* Administrative distance. */
1148 if (distance_str)
1149 distance = atoi (distance_str);
1150 else
1151 distance = ZEBRA_STATIC_DISTANCE_DEFAULT;
1152
1153 /* When gateway is valid IPv6 addrees, then gate is treated as
1154 nexthop address other case gate is treated as interface name. */
1155 ret = inet_pton (AF_INET6, gate_str, &gate_addr);
1156
1157 if (ifname)
1158 {
1159 /* When ifname is specified. It must be come with gateway
1160 address. */
1161 if (ret != 1)
1162 {
1163 vty_out (vty, "%% Malformed address%s", VTY_NEWLINE);
1164 return CMD_WARNING;
1165 }
1166 type = STATIC_IPV6_GATEWAY_IFNAME;
1167 gate = &gate_addr;
1168 }
1169 else
1170 {
1171 if (ret == 1)
1172 {
1173 type = STATIC_IPV6_GATEWAY;
1174 gate = &gate_addr;
1175 }
1176 else
1177 {
1178 type = STATIC_IPV6_IFNAME;
1179 ifname = gate_str;
1180 }
1181 }
1182
1183 if (add_cmd)
hasso81dfcaa2003-05-25 19:21:25 +00001184 static_add_ipv6 (&p, type, gate, ifname, flag, distance, table);
paul718e3742002-12-13 20:15:29 +00001185 else
1186 static_delete_ipv6 (&p, type, gate, ifname, distance, table);
1187
1188 return CMD_SUCCESS;
1189}
1190
1191DEFUN (ipv6_route,
1192 ipv6_route_cmd,
1193 "ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE)",
1194 IP_STR
1195 "Establish static routes\n"
1196 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1197 "IPv6 gateway address\n"
1198 "IPv6 gateway interface name\n")
1199{
hasso81dfcaa2003-05-25 19:21:25 +00001200 return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, NULL, NULL);
1201}
1202
1203DEFUN (ipv6_route_flags,
1204 ipv6_route_flags_cmd,
1205 "ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) (reject|blackhole)",
1206 IP_STR
1207 "Establish static routes\n"
1208 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1209 "IPv6 gateway address\n"
1210 "IPv6 gateway interface name\n"
1211 "Emit an ICMP unreachable when matched\n"
1212 "Silently discard pkts when matched\n")
1213{
1214 return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, argv[2], NULL);
paul718e3742002-12-13 20:15:29 +00001215}
1216
1217DEFUN (ipv6_route_ifname,
1218 ipv6_route_ifname_cmd,
1219 "ipv6 route X:X::X:X/M X:X::X:X INTERFACE",
1220 IP_STR
1221 "Establish static routes\n"
1222 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1223 "IPv6 gateway address\n"
1224 "IPv6 gateway interface name\n")
1225{
hasso81dfcaa2003-05-25 19:21:25 +00001226 return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], NULL, NULL);
1227}
1228
1229DEFUN (ipv6_route_ifname_flags,
1230 ipv6_route_ifname_flags_cmd,
1231 "ipv6 route X:X::X:X/M X:X::X:X INTERFACE (reject|blackhole)",
1232 IP_STR
1233 "Establish static routes\n"
1234 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1235 "IPv6 gateway address\n"
1236 "IPv6 gateway interface name\n"
1237 "Emit an ICMP unreachable when matched\n"
1238 "Silently discard pkts when matched\n")
1239{
1240 return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], argv[3], NULL);
paul718e3742002-12-13 20:15:29 +00001241}
1242
1243DEFUN (ipv6_route_pref,
1244 ipv6_route_pref_cmd,
1245 "ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) <1-255>",
1246 IP_STR
1247 "Establish static routes\n"
1248 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1249 "IPv6 gateway address\n"
1250 "IPv6 gateway interface name\n"
1251 "Distance value for this prefix\n")
1252{
hasso81dfcaa2003-05-25 19:21:25 +00001253 return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, NULL, argv[2]);
1254}
1255
1256DEFUN (ipv6_route_flags_pref,
1257 ipv6_route_flags_pref_cmd,
1258 "ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) (reject|blackhole) <1-255>",
1259 IP_STR
1260 "Establish static routes\n"
1261 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1262 "IPv6 gateway address\n"
1263 "IPv6 gateway interface name\n"
1264 "Emit an ICMP unreachable when matched\n"
1265 "Silently discard pkts when matched\n"
1266 "Distance value for this prefix\n")
1267{
1268 return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, argv[2], argv[3]);
paul718e3742002-12-13 20:15:29 +00001269}
1270
1271DEFUN (ipv6_route_ifname_pref,
1272 ipv6_route_ifname_pref_cmd,
1273 "ipv6 route X:X::X:X/M X:X::X:X INTERFACE <1-255>",
1274 IP_STR
1275 "Establish static routes\n"
1276 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1277 "IPv6 gateway address\n"
1278 "IPv6 gateway interface name\n"
1279 "Distance value for this prefix\n")
1280{
hasso81dfcaa2003-05-25 19:21:25 +00001281 return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], NULL, argv[3]);
1282}
1283
1284DEFUN (ipv6_route_ifname_flags_pref,
1285 ipv6_route_ifname_flags_pref_cmd,
1286 "ipv6 route X:X::X:X/M X:X::X:X INTERFACE (reject|blackhole) <1-255>",
1287 IP_STR
1288 "Establish static routes\n"
1289 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1290 "IPv6 gateway address\n"
1291 "IPv6 gateway interface name\n"
1292 "Emit an ICMP unreachable when matched\n"
1293 "Silently discard pkts when matched\n"
1294 "Distance value for this prefix\n")
1295{
1296 return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], argv[3], argv[4]);
paul718e3742002-12-13 20:15:29 +00001297}
1298
1299DEFUN (no_ipv6_route,
1300 no_ipv6_route_cmd,
1301 "no ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE)",
1302 NO_STR
1303 IP_STR
1304 "Establish static routes\n"
1305 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1306 "IPv6 gateway address\n"
1307 "IPv6 gateway interface name\n")
1308{
hasso81dfcaa2003-05-25 19:21:25 +00001309 return static_ipv6_func (vty, 0, argv[0], argv[1], NULL, NULL, NULL);
paul718e3742002-12-13 20:15:29 +00001310}
1311
hasso81dfcaa2003-05-25 19:21:25 +00001312ALIAS (no_ipv6_route,
1313 no_ipv6_route_flags_cmd,
1314 "no ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) (reject|blackhole)",
1315 NO_STR
1316 IP_STR
1317 "Establish static routes\n"
1318 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1319 "IPv6 gateway address\n"
1320 "IPv6 gateway interface name\n"
1321 "Emit an ICMP unreachable when matched\n"
1322 "Silently discard pkts when matched\n")
1323
paul718e3742002-12-13 20:15:29 +00001324DEFUN (no_ipv6_route_ifname,
1325 no_ipv6_route_ifname_cmd,
1326 "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE",
1327 NO_STR
1328 IP_STR
1329 "Establish static routes\n"
1330 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1331 "IPv6 gateway address\n"
1332 "IPv6 gateway interface name\n")
1333{
hasso81dfcaa2003-05-25 19:21:25 +00001334 return static_ipv6_func (vty, 0, argv[0], argv[1], argv[2], NULL, NULL);
paul718e3742002-12-13 20:15:29 +00001335}
1336
hasso81dfcaa2003-05-25 19:21:25 +00001337ALIAS (no_ipv6_route_ifname,
1338 no_ipv6_route_ifname_flags_cmd,
1339 "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE (reject|blackhole)",
1340 NO_STR
1341 IP_STR
1342 "Establish static routes\n"
1343 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1344 "IPv6 gateway address\n"
1345 "IPv6 gateway interface name\n"
1346 "Emit an ICMP unreachable when matched\n"
1347 "Silently discard pkts when matched\n")
1348
paul718e3742002-12-13 20:15:29 +00001349DEFUN (no_ipv6_route_pref,
1350 no_ipv6_route_pref_cmd,
1351 "no ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) <1-255>",
1352 NO_STR
1353 IP_STR
1354 "Establish static routes\n"
1355 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1356 "IPv6 gateway address\n"
1357 "IPv6 gateway interface name\n"
1358 "Distance value for this prefix\n")
1359{
hasso81dfcaa2003-05-25 19:21:25 +00001360 return static_ipv6_func (vty, 0, argv[0], argv[1], NULL, NULL, argv[2]);
1361}
1362
1363DEFUN (no_ipv6_route_flags_pref,
1364 no_ipv6_route_flags_pref_cmd,
1365 "no ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) (reject|blackhole) <1-255>",
1366 NO_STR
1367 IP_STR
1368 "Establish static routes\n"
1369 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1370 "IPv6 gateway address\n"
1371 "IPv6 gateway interface name\n"
1372 "Emit an ICMP unreachable when matched\n"
1373 "Silently discard pkts when matched\n"
1374 "Distance value for this prefix\n")
1375{
1376 /* We do not care about argv[2] */
1377 return static_ipv6_func (vty, 0, argv[0], argv[1], NULL, argv[2], argv[3]);
paul718e3742002-12-13 20:15:29 +00001378}
1379
1380DEFUN (no_ipv6_route_ifname_pref,
1381 no_ipv6_route_ifname_pref_cmd,
1382 "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE <1-255>",
1383 NO_STR
1384 IP_STR
1385 "Establish static routes\n"
1386 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1387 "IPv6 gateway address\n"
1388 "IPv6 gateway interface name\n"
1389 "Distance value for this prefix\n")
1390{
hasso81dfcaa2003-05-25 19:21:25 +00001391 return static_ipv6_func (vty, 0, argv[0], argv[1], argv[2], NULL, argv[3]);
1392}
1393
1394DEFUN (no_ipv6_route_ifname_flags_pref,
1395 no_ipv6_route_ifname_flags_pref_cmd,
1396 "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE (reject|blackhole) <1-255>",
1397 NO_STR
1398 IP_STR
1399 "Establish static routes\n"
1400 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1401 "IPv6 gateway address\n"
1402 "IPv6 gateway interface name\n"
1403 "Emit an ICMP unreachable when matched\n"
1404 "Silently discard pkts when matched\n"
1405 "Distance value for this prefix\n")
1406{
1407 return static_ipv6_func (vty, 0, argv[0], argv[1], argv[2], argv[3], argv[4]);
paul718e3742002-12-13 20:15:29 +00001408}
1409
paul595db7f2003-05-25 21:35:06 +00001410/* New RIB. Detailed information for IPv6 route. */
paul718e3742002-12-13 20:15:29 +00001411void
1412vty_show_ipv6_route_detail (struct vty *vty, struct route_node *rn)
1413{
1414 struct rib *rib;
1415 struct nexthop *nexthop;
1416 char buf[BUFSIZ];
1417
1418 for (rib = rn->info; rib; rib = rib->next)
1419 {
1420 vty_out (vty, "Routing entry for %s/%d%s",
1421 inet_ntop (AF_INET6, &rn->p.u.prefix6, buf, BUFSIZ),
1422 rn->p.prefixlen,
1423 VTY_NEWLINE);
1424 vty_out (vty, " Known via \"%s\"", route_type_str (rib->type));
1425 vty_out (vty, ", distance %d, metric %d", rib->distance, rib->metric);
1426 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
1427 vty_out (vty, ", best");
1428 if (rib->refcnt)
1429 vty_out (vty, ", refcnt %ld", rib->refcnt);
hasso81dfcaa2003-05-25 19:21:25 +00001430 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_BLACKHOLE))
1431 vty_out (vty, ", blackhole");
1432 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_REJECT))
1433 vty_out (vty, ", reject");
paul718e3742002-12-13 20:15:29 +00001434 vty_out (vty, "%s", VTY_NEWLINE);
1435
1436#define ONE_DAY_SECOND 60*60*24
1437#define ONE_WEEK_SECOND 60*60*24*7
1438 if (rib->type == ZEBRA_ROUTE_RIPNG
1439 || rib->type == ZEBRA_ROUTE_OSPF6
1440 || rib->type == ZEBRA_ROUTE_BGP)
1441 {
1442 time_t uptime;
1443 struct tm *tm;
1444
1445 uptime = time (NULL);
1446 uptime -= rib->uptime;
1447 tm = gmtime (&uptime);
1448
1449 vty_out (vty, " Last update ");
1450
1451 if (uptime < ONE_DAY_SECOND)
1452 vty_out (vty, "%02d:%02d:%02d",
1453 tm->tm_hour, tm->tm_min, tm->tm_sec);
1454 else if (uptime < ONE_WEEK_SECOND)
1455 vty_out (vty, "%dd%02dh%02dm",
1456 tm->tm_yday, tm->tm_hour, tm->tm_min);
1457 else
1458 vty_out (vty, "%02dw%dd%02dh",
1459 tm->tm_yday/7,
1460 tm->tm_yday - ((tm->tm_yday/7) * 7), tm->tm_hour);
1461 vty_out (vty, " ago%s", VTY_NEWLINE);
1462 }
1463
1464 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1465 {
1466 vty_out (vty, " %c",
1467 CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB) ? '*' : ' ');
1468
1469 switch (nexthop->type)
1470 {
1471 case NEXTHOP_TYPE_IPV6:
1472 case NEXTHOP_TYPE_IPV6_IFINDEX:
1473 case NEXTHOP_TYPE_IPV6_IFNAME:
1474 vty_out (vty, " %s",
1475 inet_ntop (AF_INET6, &nexthop->gate.ipv6, buf, BUFSIZ));
1476 if (nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME)
1477 vty_out (vty, ", %s", nexthop->ifname);
1478 else if (nexthop->ifindex)
1479 vty_out (vty, ", via %s", ifindex2ifname (nexthop->ifindex));
1480 break;
1481 case NEXTHOP_TYPE_IFINDEX:
1482 vty_out (vty, " directly connected, %s",
1483 ifindex2ifname (nexthop->ifindex));
1484 break;
1485 case NEXTHOP_TYPE_IFNAME:
1486 vty_out (vty, " directly connected, %s",
1487 nexthop->ifname);
1488 break;
1489 default:
1490 break;
1491 }
1492 if (! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
1493 vty_out (vty, " inactive");
1494
1495 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
1496 {
1497 vty_out (vty, " (recursive");
1498
1499 switch (nexthop->rtype)
1500 {
1501 case NEXTHOP_TYPE_IPV6:
1502 case NEXTHOP_TYPE_IPV6_IFINDEX:
1503 case NEXTHOP_TYPE_IPV6_IFNAME:
1504 vty_out (vty, " via %s)",
1505 inet_ntop (AF_INET6, &nexthop->rgate.ipv6,
1506 buf, BUFSIZ));
1507 if (nexthop->rifindex)
1508 vty_out (vty, ", %s", ifindex2ifname (nexthop->rifindex));
1509 break;
1510 case NEXTHOP_TYPE_IFINDEX:
1511 case NEXTHOP_TYPE_IFNAME:
1512 vty_out (vty, " is directly connected, %s)",
1513 ifindex2ifname (nexthop->rifindex));
1514 break;
1515 default:
1516 break;
1517 }
1518 }
1519 vty_out (vty, "%s", VTY_NEWLINE);
1520 }
1521 vty_out (vty, "%s", VTY_NEWLINE);
1522 }
1523}
1524
1525void
1526vty_show_ipv6_route (struct vty *vty, struct route_node *rn,
1527 struct rib *rib)
1528{
1529 struct nexthop *nexthop;
1530 int len = 0;
1531 char buf[BUFSIZ];
1532
1533 /* Nexthop information. */
1534 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1535 {
1536 if (nexthop == rib->nexthop)
1537 {
1538 /* Prefix information. */
1539 len = vty_out (vty, "%c%c%c %s/%d",
1540 route_type_char (rib->type),
1541 CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED)
1542 ? '>' : ' ',
1543 CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)
1544 ? '*' : ' ',
1545 inet_ntop (AF_INET6, &rn->p.u.prefix6, buf, BUFSIZ),
1546 rn->p.prefixlen);
1547
1548 /* Distance and metric display. */
1549 if (rib->type != ZEBRA_ROUTE_CONNECT
1550 && rib->type != ZEBRA_ROUTE_KERNEL)
1551 len += vty_out (vty, " [%d/%d]", rib->distance,
1552 rib->metric);
1553 }
1554 else
1555 vty_out (vty, " %c%*c",
1556 CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)
1557 ? '*' : ' ',
1558 len - 3, ' ');
1559
1560 switch (nexthop->type)
1561 {
1562 case NEXTHOP_TYPE_IPV6:
1563 case NEXTHOP_TYPE_IPV6_IFINDEX:
1564 case NEXTHOP_TYPE_IPV6_IFNAME:
1565 vty_out (vty, " via %s",
1566 inet_ntop (AF_INET6, &nexthop->gate.ipv6, buf, BUFSIZ));
1567 if (nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME)
1568 vty_out (vty, ", %s", nexthop->ifname);
1569 else if (nexthop->ifindex)
1570 vty_out (vty, ", %s", ifindex2ifname (nexthop->ifindex));
1571 break;
1572 case NEXTHOP_TYPE_IFINDEX:
1573 vty_out (vty, " is directly connected, %s",
1574 ifindex2ifname (nexthop->ifindex));
1575 break;
1576 case NEXTHOP_TYPE_IFNAME:
1577 vty_out (vty, " is directly connected, %s",
1578 nexthop->ifname);
1579 break;
1580 default:
1581 break;
1582 }
1583 if (! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
1584 vty_out (vty, " inactive");
1585
1586 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
1587 {
1588 vty_out (vty, " (recursive");
1589
1590 switch (nexthop->rtype)
1591 {
1592 case NEXTHOP_TYPE_IPV6:
1593 case NEXTHOP_TYPE_IPV6_IFINDEX:
1594 case NEXTHOP_TYPE_IPV6_IFNAME:
1595 vty_out (vty, " via %s)",
1596 inet_ntop (AF_INET6, &nexthop->rgate.ipv6,
1597 buf, BUFSIZ));
1598 if (nexthop->rifindex)
1599 vty_out (vty, ", %s", ifindex2ifname (nexthop->rifindex));
1600 break;
1601 case NEXTHOP_TYPE_IFINDEX:
1602 case NEXTHOP_TYPE_IFNAME:
1603 vty_out (vty, " is directly connected, %s)",
1604 ifindex2ifname (nexthop->rifindex));
1605 break;
1606 default:
1607 break;
1608 }
1609 }
1610
hasso81dfcaa2003-05-25 19:21:25 +00001611 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_BLACKHOLE))
1612 vty_out (vty, ", bh");
1613 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_REJECT))
1614 vty_out (vty, ", rej");
1615
paul718e3742002-12-13 20:15:29 +00001616 if (rib->type == ZEBRA_ROUTE_RIPNG
1617 || rib->type == ZEBRA_ROUTE_OSPF6
1618 || rib->type == ZEBRA_ROUTE_BGP)
1619 {
1620 time_t uptime;
1621 struct tm *tm;
1622
1623 uptime = time (NULL);
1624 uptime -= rib->uptime;
1625 tm = gmtime (&uptime);
1626
1627#define ONE_DAY_SECOND 60*60*24
1628#define ONE_WEEK_SECOND 60*60*24*7
1629
1630 if (uptime < ONE_DAY_SECOND)
1631 vty_out (vty, ", %02d:%02d:%02d",
1632 tm->tm_hour, tm->tm_min, tm->tm_sec);
1633 else if (uptime < ONE_WEEK_SECOND)
1634 vty_out (vty, ", %dd%02dh%02dm",
1635 tm->tm_yday, tm->tm_hour, tm->tm_min);
1636 else
1637 vty_out (vty, ", %02dw%dd%02dh",
1638 tm->tm_yday/7,
1639 tm->tm_yday - ((tm->tm_yday/7) * 7), tm->tm_hour);
1640 }
1641 vty_out (vty, "%s", VTY_NEWLINE);
1642 }
1643}
1644
1645#define SHOW_ROUTE_V6_HEADER "Codes: K - kernel route, C - connected, S - static, R - RIPng, O - OSPFv3,%s B - BGP, * - FIB route.%s%s"
1646
1647DEFUN (show_ipv6_route,
1648 show_ipv6_route_cmd,
1649 "show ipv6 route",
1650 SHOW_STR
1651 IP_STR
1652 "IPv6 routing table\n")
1653{
1654 struct route_table *table;
1655 struct route_node *rn;
1656 struct rib *rib;
1657 int first = 1;
1658
1659 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
1660 if (! table)
1661 return CMD_SUCCESS;
1662
1663 /* Show all IPv6 route. */
1664 for (rn = route_top (table); rn; rn = route_next (rn))
1665 for (rib = rn->info; rib; rib = rib->next)
1666 {
1667 if (first)
1668 {
1669 vty_out (vty, SHOW_ROUTE_V6_HEADER, VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE);
1670 first = 0;
1671 }
1672 vty_show_ipv6_route (vty, rn, rib);
1673 }
1674 return CMD_SUCCESS;
1675}
1676
1677DEFUN (show_ipv6_route_prefix_longer,
1678 show_ipv6_route_prefix_longer_cmd,
1679 "show ipv6 route X:X::X:X/M longer-prefixes",
1680 SHOW_STR
1681 IP_STR
1682 "IPv6 routing table\n"
1683 "IPv6 prefix\n"
1684 "Show route matching the specified Network/Mask pair only\n")
1685{
1686 struct route_table *table;
1687 struct route_node *rn;
1688 struct rib *rib;
1689 struct prefix p;
1690 int ret;
1691 int first = 1;
1692
1693 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
1694 if (! table)
1695 return CMD_SUCCESS;
1696
1697 ret = str2prefix (argv[0], &p);
1698 if (! ret)
1699 {
1700 vty_out (vty, "%% Malformed Prefix%s", VTY_NEWLINE);
1701 return CMD_WARNING;
1702 }
1703
1704 /* Show matched type IPv6 routes. */
1705 for (rn = route_top (table); rn; rn = route_next (rn))
1706 for (rib = rn->info; rib; rib = rib->next)
1707 if (prefix_match (&p, &rn->p))
1708 {
1709 if (first)
1710 {
1711 vty_out (vty, SHOW_ROUTE_V6_HEADER, VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE);
1712 first = 0;
1713 }
1714 vty_show_ipv6_route (vty, rn, rib);
1715 }
1716 return CMD_SUCCESS;
1717}
1718
1719DEFUN (show_ipv6_route_protocol,
1720 show_ipv6_route_protocol_cmd,
1721 "show ipv6 route (bgp|connected|kernel|ospf6|ripng|static)",
1722 SHOW_STR
1723 IP_STR
1724 "IP routing table\n"
1725 "Border Gateway Protocol (BGP)\n"
1726 "Connected\n"
1727 "Kernel\n"
1728 "Open Shortest Path First (OSPFv3)\n"
1729 "Routing Information Protocol (RIPng)\n"
1730 "Static routes\n")
1731{
1732 int type;
1733 struct route_table *table;
1734 struct route_node *rn;
1735 struct rib *rib;
1736 int first = 1;
1737
1738 if (strncmp (argv[0], "b", 1) == 0)
1739 type = ZEBRA_ROUTE_BGP;
1740 else if (strncmp (argv[0], "c", 1) == 0)
1741 type = ZEBRA_ROUTE_CONNECT;
1742 else if (strncmp (argv[0], "k", 1) ==0)
1743 type = ZEBRA_ROUTE_KERNEL;
1744 else if (strncmp (argv[0], "o", 1) == 0)
1745 type = ZEBRA_ROUTE_OSPF6;
1746 else if (strncmp (argv[0], "r", 1) == 0)
1747 type = ZEBRA_ROUTE_RIPNG;
1748 else if (strncmp (argv[0], "s", 1) == 0)
1749 type = ZEBRA_ROUTE_STATIC;
1750 else
1751 {
1752 vty_out (vty, "Unknown route type%s", VTY_NEWLINE);
1753 return CMD_WARNING;
1754 }
1755
1756 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
1757 if (! table)
1758 return CMD_SUCCESS;
1759
1760 /* Show matched type IPv6 routes. */
1761 for (rn = route_top (table); rn; rn = route_next (rn))
1762 for (rib = rn->info; rib; rib = rib->next)
1763 if (rib->type == type)
1764 {
1765 if (first)
1766 {
1767 vty_out (vty, SHOW_ROUTE_V6_HEADER, VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE);
1768 first = 0;
1769 }
1770 vty_show_ipv6_route (vty, rn, rib);
1771 }
1772 return CMD_SUCCESS;
1773}
1774
1775DEFUN (show_ipv6_route_addr,
1776 show_ipv6_route_addr_cmd,
1777 "show ipv6 route X:X::X:X",
1778 SHOW_STR
1779 IP_STR
1780 "IPv6 routing table\n"
1781 "IPv6 Address\n")
1782{
1783 int ret;
1784 struct prefix_ipv6 p;
1785 struct route_table *table;
1786 struct route_node *rn;
1787
1788 ret = str2prefix_ipv6 (argv[0], &p);
1789 if (ret <= 0)
1790 {
1791 vty_out (vty, "Malformed IPv6 address%s", VTY_NEWLINE);
1792 return CMD_WARNING;
1793 }
1794
1795 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
1796 if (! table)
1797 return CMD_SUCCESS;
1798
1799 rn = route_node_match (table, (struct prefix *) &p);
1800 if (! rn)
1801 {
1802 vty_out (vty, "%% Network not in table%s", VTY_NEWLINE);
1803 return CMD_WARNING;
1804 }
1805
1806 vty_show_ipv6_route_detail (vty, rn);
1807
1808 route_unlock_node (rn);
1809
1810 return CMD_SUCCESS;
1811}
1812
1813DEFUN (show_ipv6_route_prefix,
1814 show_ipv6_route_prefix_cmd,
1815 "show ipv6 route X:X::X:X/M",
1816 SHOW_STR
1817 IP_STR
1818 "IPv6 routing table\n"
1819 "IPv6 prefix\n")
1820{
1821 int ret;
1822 struct prefix_ipv6 p;
1823 struct route_table *table;
1824 struct route_node *rn;
1825
1826 ret = str2prefix_ipv6 (argv[0], &p);
1827 if (ret <= 0)
1828 {
1829 vty_out (vty, "Malformed IPv6 prefix%s", VTY_NEWLINE);
1830 return CMD_WARNING;
1831 }
1832
1833 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
1834 if (! table)
1835 return CMD_SUCCESS;
1836
1837 rn = route_node_match (table, (struct prefix *) &p);
1838 if (! rn || rn->p.prefixlen != p.prefixlen)
1839 {
1840 vty_out (vty, "%% Network not in table%s", VTY_NEWLINE);
1841 return CMD_WARNING;
1842 }
1843
1844 vty_show_ipv6_route_detail (vty, rn);
1845
1846 route_unlock_node (rn);
1847
1848 return CMD_SUCCESS;
1849}
1850
1851
1852/* Write IPv6 static route configuration. */
1853int
1854static_config_ipv6 (struct vty *vty)
1855{
1856 struct route_node *rn;
1857 struct static_ipv6 *si;
1858 int write;
1859 char buf[BUFSIZ];
1860 struct route_table *stable;
1861
1862 write = 0;
1863
1864 /* Lookup table. */
1865 stable = vrf_static_table (AFI_IP6, SAFI_UNICAST, 0);
1866 if (! stable)
1867 return -1;
1868
1869 for (rn = route_top (stable); rn; rn = route_next (rn))
1870 for (si = rn->info; si; si = si->next)
1871 {
1872 vty_out (vty, "ipv6 route %s/%d",
1873 inet_ntop (AF_INET6, &rn->p.u.prefix6, buf, BUFSIZ),
1874 rn->p.prefixlen);
1875
1876 switch (si->type)
1877 {
1878 case STATIC_IPV6_GATEWAY:
1879 vty_out (vty, " %s", inet_ntop (AF_INET6, &si->ipv6, buf, BUFSIZ));
1880 break;
1881 case STATIC_IPV6_IFNAME:
1882 vty_out (vty, " %s", si->ifname);
1883 break;
1884 case STATIC_IPV6_GATEWAY_IFNAME:
1885 vty_out (vty, " %s %s",
1886 inet_ntop (AF_INET6, &si->ipv6, buf, BUFSIZ), si->ifname);
1887 break;
1888 }
1889
hasso81dfcaa2003-05-25 19:21:25 +00001890 if (CHECK_FLAG(si->flags, ZEBRA_FLAG_REJECT))
1891 vty_out (vty, " %s", "reject");
1892
1893 if (CHECK_FLAG(si->flags, ZEBRA_FLAG_BLACKHOLE))
1894 vty_out (vty, " %s", "blackhole");
1895
paul718e3742002-12-13 20:15:29 +00001896 if (si->distance != ZEBRA_STATIC_DISTANCE_DEFAULT)
1897 vty_out (vty, " %d", si->distance);
1898 vty_out (vty, "%s", VTY_NEWLINE);
1899
1900 write = 1;
1901 }
1902 return write;
1903}
1904#endif /* HAVE_IPV6 */
1905
1906/* Static ip route configuration write function. */
1907int
1908zebra_ip_config (struct vty *vty)
1909{
1910 int write = 0;
1911
1912 write += static_config_ipv4 (vty);
1913#ifdef HAVE_IPV6
1914 write += static_config_ipv6 (vty);
1915#endif /* HAVE_IPV6 */
1916
1917 return write;
1918}
1919
1920/* IP node for static routes. */
1921struct cmd_node ip_node = { IP_NODE, "", 1 };
1922
1923/* Route VTY. */
1924void
1925zebra_vty_route_init ()
1926{
1927 install_node (&ip_node, zebra_ip_config);
1928
1929 install_element (CONFIG_NODE, &ip_route_cmd);
hasso81dfcaa2003-05-25 19:21:25 +00001930 install_element (CONFIG_NODE, &ip_route_flags_cmd);
hasso457ef552003-05-28 12:02:15 +00001931 install_element (CONFIG_NODE, &ip_route_flags2_cmd);
paul718e3742002-12-13 20:15:29 +00001932 install_element (CONFIG_NODE, &ip_route_mask_cmd);
hasso81dfcaa2003-05-25 19:21:25 +00001933 install_element (CONFIG_NODE, &ip_route_mask_flags_cmd);
hasso457ef552003-05-28 12:02:15 +00001934 install_element (CONFIG_NODE, &ip_route_mask_flags2_cmd);
paul718e3742002-12-13 20:15:29 +00001935 install_element (CONFIG_NODE, &no_ip_route_cmd);
hasso81dfcaa2003-05-25 19:21:25 +00001936 install_element (CONFIG_NODE, &no_ip_route_flags_cmd);
hasso457ef552003-05-28 12:02:15 +00001937 install_element (CONFIG_NODE, &no_ip_route_flags2_cmd);
paul718e3742002-12-13 20:15:29 +00001938 install_element (CONFIG_NODE, &no_ip_route_mask_cmd);
hasso81dfcaa2003-05-25 19:21:25 +00001939 install_element (CONFIG_NODE, &no_ip_route_mask_flags_cmd);
hasso457ef552003-05-28 12:02:15 +00001940 install_element (CONFIG_NODE, &no_ip_route_mask_flags2_cmd);
paul718e3742002-12-13 20:15:29 +00001941 install_element (CONFIG_NODE, &ip_route_distance_cmd);
hasso81dfcaa2003-05-25 19:21:25 +00001942 install_element (CONFIG_NODE, &ip_route_flags_distance_cmd);
hasso457ef552003-05-28 12:02:15 +00001943 install_element (CONFIG_NODE, &ip_route_flags_distance2_cmd);
paul718e3742002-12-13 20:15:29 +00001944 install_element (CONFIG_NODE, &ip_route_mask_distance_cmd);
hasso81dfcaa2003-05-25 19:21:25 +00001945 install_element (CONFIG_NODE, &ip_route_mask_flags_distance_cmd);
hasso457ef552003-05-28 12:02:15 +00001946 install_element (CONFIG_NODE, &ip_route_mask_flags_distance2_cmd);
paul718e3742002-12-13 20:15:29 +00001947 install_element (CONFIG_NODE, &no_ip_route_distance_cmd);
hasso81dfcaa2003-05-25 19:21:25 +00001948 install_element (CONFIG_NODE, &no_ip_route_flags_distance_cmd);
hasso457ef552003-05-28 12:02:15 +00001949 install_element (CONFIG_NODE, &no_ip_route_flags_distance2_cmd);
hasso81dfcaa2003-05-25 19:21:25 +00001950 install_element (CONFIG_NODE, &no_ip_route_mask_flags_distance_cmd);
hasso457ef552003-05-28 12:02:15 +00001951 install_element (CONFIG_NODE, &no_ip_route_mask_flags_distance2_cmd);
paul718e3742002-12-13 20:15:29 +00001952
1953 install_element (VIEW_NODE, &show_ip_route_cmd);
1954 install_element (VIEW_NODE, &show_ip_route_addr_cmd);
1955 install_element (VIEW_NODE, &show_ip_route_prefix_cmd);
1956 install_element (VIEW_NODE, &show_ip_route_prefix_longer_cmd);
1957 install_element (VIEW_NODE, &show_ip_route_protocol_cmd);
1958 install_element (VIEW_NODE, &show_ip_route_supernets_cmd);
1959 install_element (ENABLE_NODE, &show_ip_route_cmd);
1960 install_element (ENABLE_NODE, &show_ip_route_addr_cmd);
1961 install_element (ENABLE_NODE, &show_ip_route_prefix_cmd);
1962 install_element (ENABLE_NODE, &show_ip_route_prefix_longer_cmd);
1963 install_element (ENABLE_NODE, &show_ip_route_protocol_cmd);
1964 install_element (ENABLE_NODE, &show_ip_route_supernets_cmd);
1965
1966#if 0
1967 install_element (VIEW_NODE, &show_ip_route_summary_cmd);
1968 install_element (ENABLE_NODE, &show_ip_route_summary_cmd);
1969#endif /* 0 */
1970
1971#ifdef HAVE_IPV6
1972 install_element (CONFIG_NODE, &ipv6_route_cmd);
hasso81dfcaa2003-05-25 19:21:25 +00001973 install_element (CONFIG_NODE, &ipv6_route_flags_cmd);
paul718e3742002-12-13 20:15:29 +00001974 install_element (CONFIG_NODE, &ipv6_route_ifname_cmd);
hasso81dfcaa2003-05-25 19:21:25 +00001975 install_element (CONFIG_NODE, &ipv6_route_ifname_flags_cmd);
paul718e3742002-12-13 20:15:29 +00001976 install_element (CONFIG_NODE, &no_ipv6_route_cmd);
hasso81dfcaa2003-05-25 19:21:25 +00001977 install_element (CONFIG_NODE, &no_ipv6_route_flags_cmd);
paul718e3742002-12-13 20:15:29 +00001978 install_element (CONFIG_NODE, &no_ipv6_route_ifname_cmd);
hasso81dfcaa2003-05-25 19:21:25 +00001979 install_element (CONFIG_NODE, &no_ipv6_route_ifname_flags_cmd);
paul718e3742002-12-13 20:15:29 +00001980 install_element (CONFIG_NODE, &ipv6_route_pref_cmd);
hasso81dfcaa2003-05-25 19:21:25 +00001981 install_element (CONFIG_NODE, &ipv6_route_flags_pref_cmd);
paul718e3742002-12-13 20:15:29 +00001982 install_element (CONFIG_NODE, &ipv6_route_ifname_pref_cmd);
hasso81dfcaa2003-05-25 19:21:25 +00001983 install_element (CONFIG_NODE, &ipv6_route_ifname_flags_pref_cmd);
paul718e3742002-12-13 20:15:29 +00001984 install_element (CONFIG_NODE, &no_ipv6_route_pref_cmd);
hasso81dfcaa2003-05-25 19:21:25 +00001985 install_element (CONFIG_NODE, &no_ipv6_route_flags_pref_cmd);
paul718e3742002-12-13 20:15:29 +00001986 install_element (CONFIG_NODE, &no_ipv6_route_ifname_pref_cmd);
hasso81dfcaa2003-05-25 19:21:25 +00001987 install_element (CONFIG_NODE, &no_ipv6_route_ifname_flags_pref_cmd);
paul718e3742002-12-13 20:15:29 +00001988 install_element (VIEW_NODE, &show_ipv6_route_cmd);
1989 install_element (VIEW_NODE, &show_ipv6_route_protocol_cmd);
1990 install_element (VIEW_NODE, &show_ipv6_route_addr_cmd);
1991 install_element (VIEW_NODE, &show_ipv6_route_prefix_cmd);
1992 install_element (VIEW_NODE, &show_ipv6_route_prefix_longer_cmd);
1993 install_element (ENABLE_NODE, &show_ipv6_route_cmd);
1994 install_element (ENABLE_NODE, &show_ipv6_route_protocol_cmd);
1995 install_element (ENABLE_NODE, &show_ipv6_route_addr_cmd);
1996 install_element (ENABLE_NODE, &show_ipv6_route_prefix_cmd);
1997 install_element (ENABLE_NODE, &show_ipv6_route_prefix_longer_cmd);
1998#endif /* HAVE_IPV6 */
1999}
2000
2001void
2002zebra_vty_init ()
2003{
2004 zebra_vty_route_init ();
2005}