blob: ebb36941a282f0ebcc4ef4df88a84b2173699529 [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)
paul7021c422003-07-15 12:52:22 +0000139 static_add_ipv4 (&p, NULL, NULL, ZEBRA_FLAG_BLACKHOLE, distance, 0);
paul595db7f2003-05-25 21:35:06 +0000140 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:
paul7021c422003-07-15 12:52:22 +0000606 vty_out (vty, " directly connected, Null0");
paul595db7f2003-05-25 21:35:06 +0000607 break;
paul7021c422003-07-15 12:52:22 +0000608 default:
paul718e3742002-12-13 20:15:29 +0000609 break;
610 }
611 if (! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
612 vty_out (vty, " inactive");
613
614 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
615 {
616 vty_out (vty, " (recursive");
617
618 switch (nexthop->rtype)
619 {
620 case NEXTHOP_TYPE_IPV4:
621 case NEXTHOP_TYPE_IPV4_IFINDEX:
622 vty_out (vty, " via %s)", inet_ntoa (nexthop->rgate.ipv4));
623 break;
624 case NEXTHOP_TYPE_IFINDEX:
625 case NEXTHOP_TYPE_IFNAME:
626 vty_out (vty, " is directly connected, %s)",
627 ifindex2ifname (nexthop->rifindex));
628 break;
629 default:
630 break;
631 }
632 }
633 vty_out (vty, "%s", VTY_NEWLINE);
634 }
635 vty_out (vty, "%s", VTY_NEWLINE);
636 }
637}
638
639void
640vty_show_ip_route (struct vty *vty, struct route_node *rn, struct rib *rib)
641{
642 struct nexthop *nexthop;
643 int len = 0;
644 char buf[BUFSIZ];
645
646 /* Nexthop information. */
647 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
648 {
649 if (nexthop == rib->nexthop)
650 {
651 /* Prefix information. */
652 len = vty_out (vty, "%c%c%c %s/%d",
653 route_type_char (rib->type),
654 CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED)
655 ? '>' : ' ',
656 CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)
657 ? '*' : ' ',
658 inet_ntop (AF_INET, &rn->p.u.prefix, buf, BUFSIZ),
659 rn->p.prefixlen);
660
661 /* Distance and metric display. */
662 if (rib->type != ZEBRA_ROUTE_CONNECT
663 && rib->type != ZEBRA_ROUTE_KERNEL)
664 len += vty_out (vty, " [%d/%d]", rib->distance,
665 rib->metric);
666 }
667 else
668 vty_out (vty, " %c%*c",
669 CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)
670 ? '*' : ' ',
671 len - 3, ' ');
672
673 switch (nexthop->type)
674 {
675 case NEXTHOP_TYPE_IPV4:
676 case NEXTHOP_TYPE_IPV4_IFINDEX:
677 vty_out (vty, " via %s", inet_ntoa (nexthop->gate.ipv4));
678 if (nexthop->ifindex)
679 vty_out (vty, ", %s", ifindex2ifname (nexthop->ifindex));
680 break;
681 case NEXTHOP_TYPE_IFINDEX:
682 vty_out (vty, " is directly connected, %s",
683 ifindex2ifname (nexthop->ifindex));
684 break;
685 case NEXTHOP_TYPE_IFNAME:
686 vty_out (vty, " is directly connected, %s", nexthop->ifname);
687 break;
paul595db7f2003-05-25 21:35:06 +0000688 case NEXTHOP_TYPE_BLACKHOLE:
paul7021c422003-07-15 12:52:22 +0000689 vty_out (vty, " is directly connected, Null0");
paul595db7f2003-05-25 21:35:06 +0000690 break;
paul7021c422003-07-15 12:52:22 +0000691 default:
paul718e3742002-12-13 20:15:29 +0000692 break;
693 }
694 if (! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
695 vty_out (vty, " inactive");
696
697 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
698 {
699 vty_out (vty, " (recursive");
700
701 switch (nexthop->rtype)
702 {
703 case NEXTHOP_TYPE_IPV4:
704 case NEXTHOP_TYPE_IPV4_IFINDEX:
705 vty_out (vty, " via %s)", inet_ntoa (nexthop->rgate.ipv4));
706 break;
707 case NEXTHOP_TYPE_IFINDEX:
708 case NEXTHOP_TYPE_IFNAME:
709 vty_out (vty, " is directly connected, %s)",
710 ifindex2ifname (nexthop->rifindex));
711 break;
712 default:
713 break;
714 }
715 }
716
hasso81dfcaa2003-05-25 19:21:25 +0000717 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_BLACKHOLE))
718 vty_out (vty, ", bh");
719 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_REJECT))
720 vty_out (vty, ", rej");
721
paul718e3742002-12-13 20:15:29 +0000722 if (rib->type == ZEBRA_ROUTE_RIP
723 || rib->type == ZEBRA_ROUTE_OSPF
724 || rib->type == ZEBRA_ROUTE_BGP)
725 {
726 time_t uptime;
727 struct tm *tm;
728
729 uptime = time (NULL);
730 uptime -= rib->uptime;
731 tm = gmtime (&uptime);
732
733#define ONE_DAY_SECOND 60*60*24
734#define ONE_WEEK_SECOND 60*60*24*7
735
736 if (uptime < ONE_DAY_SECOND)
737 vty_out (vty, ", %02d:%02d:%02d",
738 tm->tm_hour, tm->tm_min, tm->tm_sec);
739 else if (uptime < ONE_WEEK_SECOND)
740 vty_out (vty, ", %dd%02dh%02dm",
741 tm->tm_yday, tm->tm_hour, tm->tm_min);
742 else
743 vty_out (vty, ", %02dw%dd%02dh",
744 tm->tm_yday/7,
745 tm->tm_yday - ((tm->tm_yday/7) * 7), tm->tm_hour);
746 }
747 vty_out (vty, "%s", VTY_NEWLINE);
748 }
749}
750
751#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"
752
753DEFUN (show_ip_route,
754 show_ip_route_cmd,
755 "show ip route",
756 SHOW_STR
757 IP_STR
758 "IP routing table\n")
759{
760 struct route_table *table;
761 struct route_node *rn;
762 struct rib *rib;
763 int first = 1;
764
765 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
766 if (! table)
767 return CMD_SUCCESS;
768
769 /* Show all IPv4 routes. */
770 for (rn = route_top (table); rn; rn = route_next (rn))
771 for (rib = rn->info; rib; rib = rib->next)
772 {
773 if (first)
774 {
775 vty_out (vty, SHOW_ROUTE_V4_HEADER, VTY_NEWLINE, VTY_NEWLINE,
776 VTY_NEWLINE);
777 first = 0;
778 }
779 vty_show_ip_route (vty, rn, rib);
780 }
781 return CMD_SUCCESS;
782}
783
784DEFUN (show_ip_route_prefix_longer,
785 show_ip_route_prefix_longer_cmd,
786 "show ip route A.B.C.D/M longer-prefixes",
787 SHOW_STR
788 IP_STR
789 "IP routing table\n"
790 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
791 "Show route matching the specified Network/Mask pair only\n")
792{
793 struct route_table *table;
794 struct route_node *rn;
795 struct rib *rib;
796 struct prefix p;
797 int ret;
798 int first = 1;
799
800 ret = str2prefix (argv[0], &p);
801 if (! ret)
802 {
803 vty_out (vty, "%% Malformed Prefix%s", VTY_NEWLINE);
804 return CMD_WARNING;
805 }
806
807 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
808 if (! table)
809 return CMD_SUCCESS;
810
811 /* Show matched type IPv4 routes. */
812 for (rn = route_top (table); rn; rn = route_next (rn))
813 for (rib = rn->info; rib; rib = rib->next)
814 if (prefix_match (&p, &rn->p))
815 {
816 if (first)
817 {
818 vty_out (vty, SHOW_ROUTE_V4_HEADER, VTY_NEWLINE,
819 VTY_NEWLINE, VTY_NEWLINE);
820 first = 0;
821 }
822 vty_show_ip_route (vty, rn, rib);
823 }
824 return CMD_SUCCESS;
825}
826
827DEFUN (show_ip_route_supernets,
828 show_ip_route_supernets_cmd,
829 "show ip route supernets-only",
830 SHOW_STR
831 IP_STR
832 "IP routing table\n"
833 "Show supernet entries only\n")
834{
835 struct route_table *table;
836 struct route_node *rn;
837 struct rib *rib;
838 u_int32_t addr;
839 int first = 1;
840
841 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
842 if (! table)
843 return CMD_SUCCESS;
844
845 /* Show matched type IPv4 routes. */
846 for (rn = route_top (table); rn; rn = route_next (rn))
847 for (rib = rn->info; rib; rib = rib->next)
848 {
849 addr = ntohl (rn->p.u.prefix4.s_addr);
850
851 if ((IN_CLASSC (addr) && rn->p.prefixlen < 24)
852 || (IN_CLASSB (addr) && rn->p.prefixlen < 16)
853 || (IN_CLASSA (addr) && rn->p.prefixlen < 8))
854 {
855 if (first)
856 {
857 vty_out (vty, SHOW_ROUTE_V4_HEADER, VTY_NEWLINE,
858 VTY_NEWLINE, VTY_NEWLINE);
859 first = 0;
860 }
861 vty_show_ip_route (vty, rn, rib);
862 }
863 }
864 return CMD_SUCCESS;
865}
866
867DEFUN (show_ip_route_protocol,
868 show_ip_route_protocol_cmd,
869 "show ip route (bgp|connected|kernel|ospf|rip|static)",
870 SHOW_STR
871 IP_STR
872 "IP routing table\n"
873 "Border Gateway Protocol (BGP)\n"
874 "Connected\n"
875 "Kernel\n"
876 "Open Shortest Path First (OSPF)\n"
877 "Routing Information Protocol (RIP)\n"
878 "Static routes\n")
879{
880 int type;
881 struct route_table *table;
882 struct route_node *rn;
883 struct rib *rib;
884 int first = 1;
885
886 if (strncmp (argv[0], "b", 1) == 0)
887 type = ZEBRA_ROUTE_BGP;
888 else if (strncmp (argv[0], "c", 1) == 0)
889 type = ZEBRA_ROUTE_CONNECT;
890 else if (strncmp (argv[0], "k", 1) ==0)
891 type = ZEBRA_ROUTE_KERNEL;
892 else if (strncmp (argv[0], "o", 1) == 0)
893 type = ZEBRA_ROUTE_OSPF;
894 else if (strncmp (argv[0], "r", 1) == 0)
895 type = ZEBRA_ROUTE_RIP;
896 else if (strncmp (argv[0], "s", 1) == 0)
897 type = ZEBRA_ROUTE_STATIC;
898 else
899 {
900 vty_out (vty, "Unknown route type%s", VTY_NEWLINE);
901 return CMD_WARNING;
902 }
903
904 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
905 if (! table)
906 return CMD_SUCCESS;
907
908 /* Show matched type IPv4 routes. */
909 for (rn = route_top (table); rn; rn = route_next (rn))
910 for (rib = rn->info; rib; rib = rib->next)
911 if (rib->type == type)
912 {
913 if (first)
914 {
915 vty_out (vty, SHOW_ROUTE_V4_HEADER,
916 VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE);
917 first = 0;
918 }
919 vty_show_ip_route (vty, rn, rib);
920 }
921 return CMD_SUCCESS;
922}
923
924DEFUN (show_ip_route_addr,
925 show_ip_route_addr_cmd,
926 "show ip route A.B.C.D",
927 SHOW_STR
928 IP_STR
929 "IP routing table\n"
930 "Network in the IP routing table to display\n")
931{
932 int ret;
933 struct prefix_ipv4 p;
934 struct route_table *table;
935 struct route_node *rn;
936
937 ret = str2prefix_ipv4 (argv[0], &p);
938 if (ret <= 0)
939 {
940 vty_out (vty, "%% Malformed IPv4 address%s", VTY_NEWLINE);
941 return CMD_WARNING;
942 }
943
944 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
945 if (! table)
946 return CMD_SUCCESS;
947
948 rn = route_node_match (table, (struct prefix *) &p);
949 if (! rn)
950 {
951 vty_out (vty, "%% Network not in table%s", VTY_NEWLINE);
952 return CMD_WARNING;
953 }
954
955 vty_show_ip_route_detail (vty, rn);
956
957 route_unlock_node (rn);
958
959 return CMD_SUCCESS;
960}
961
962DEFUN (show_ip_route_prefix,
963 show_ip_route_prefix_cmd,
964 "show ip route A.B.C.D/M",
965 SHOW_STR
966 IP_STR
967 "IP routing table\n"
968 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n")
969{
970 int ret;
971 struct prefix_ipv4 p;
972 struct route_table *table;
973 struct route_node *rn;
974
975 ret = str2prefix_ipv4 (argv[0], &p);
976 if (ret <= 0)
977 {
978 vty_out (vty, "%% Malformed IPv4 address%s", VTY_NEWLINE);
979 return CMD_WARNING;
980 }
981
982 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
983 if (! table)
984 return CMD_SUCCESS;
985
986 rn = route_node_match (table, (struct prefix *) &p);
987 if (! rn || rn->p.prefixlen != p.prefixlen)
988 {
989 vty_out (vty, "%% Network not in table%s", VTY_NEWLINE);
990 return CMD_WARNING;
991 }
992
993 vty_show_ip_route_detail (vty, rn);
994
995 route_unlock_node (rn);
996
997 return CMD_SUCCESS;
998}
999
1000void
1001zebra_show_ip_route (struct vty *vty, struct vrf *vrf)
1002{
1003 vty_out (vty, "IP routing table name is %s(%d)%s",
1004 vrf->name ? vrf->name : "", vrf->id, VTY_NEWLINE);
1005
1006 vty_out (vty, "Route Source Networks%s", VTY_NEWLINE);
1007 vty_out (vty, "connected %d%s", 0, VTY_NEWLINE);
1008 vty_out (vty, "static %d%s", 0, VTY_NEWLINE);
1009 vty_out (vty, "rip %d%s", 0, VTY_NEWLINE);
1010
1011 vty_out (vty, "bgp %d%s", 0, VTY_NEWLINE);
1012 vty_out (vty, " External: %d Internal: %d Local: %d%s",
1013 0, 0, 0, VTY_NEWLINE);
1014
1015 vty_out (vty, "ospf %d%s", 0, VTY_NEWLINE);
1016 vty_out (vty,
1017 " Intra-area: %d Inter-area: %d External-1: %d External-2: %d%s",
1018 0, 0, 0, 0, VTY_NEWLINE);
1019 vty_out (vty, " NSSA External-1: %d NSSA External-2: %d%s",
1020 0, 0, VTY_NEWLINE);
1021
1022 vty_out (vty, "internal %d%s", 0, VTY_NEWLINE);
1023 vty_out (vty, "Total %d%s", 0, VTY_NEWLINE);
1024}
1025
1026/* Show route summary. */
1027DEFUN (show_ip_route_summary,
1028 show_ip_route_summary_cmd,
1029 "show ip route summary",
1030 SHOW_STR
1031 IP_STR
1032 "IP routing table\n"
1033 "Summary of all routes\n")
1034{
1035 struct vrf *vrf;
1036
1037 /* Default table id is zero. */
1038 vrf = vrf_lookup (0);
1039 if (! vrf)
1040 {
1041 vty_out (vty, "%% No Default-IP-Routing-Table%s", VTY_NEWLINE);
1042 return CMD_WARNING;
1043 }
1044
1045 zebra_show_ip_route (vty, vrf);
1046
1047 return CMD_SUCCESS;
1048}
1049
1050/* Write IPv4 static route configuration. */
1051int
1052static_config_ipv4 (struct vty *vty)
1053{
1054 struct route_node *rn;
1055 struct static_ipv4 *si;
1056 struct route_table *stable;
1057 int write;
1058
1059 write = 0;
1060
1061 /* Lookup table. */
1062 stable = vrf_static_table (AFI_IP, SAFI_UNICAST, 0);
1063 if (! stable)
1064 return -1;
1065
1066 for (rn = route_top (stable); rn; rn = route_next (rn))
1067 for (si = rn->info; si; si = si->next)
1068 {
paul7021c422003-07-15 12:52:22 +00001069 vty_out (vty, "ip route %s/%d", inet_ntoa (rn->p.u.prefix4),
1070 rn->p.prefixlen);
paul718e3742002-12-13 20:15:29 +00001071
paul7021c422003-07-15 12:52:22 +00001072 switch (si->type)
1073 {
1074 case STATIC_IPV4_GATEWAY:
1075 vty_out (vty, " %s", inet_ntoa (si->gate.ipv4));
1076 break;
1077 case STATIC_IPV4_IFNAME:
1078 vty_out (vty, " %s", si->gate.ifname);
1079 break;
1080 case STATIC_IPV4_BLACKHOLE:
1081 vty_out (vty, " Null0");
1082 break;
1083 }
1084
1085 /* flags are incompatible with STATIC_IPV4_BLACKHOLE */
1086 if (si->type != STATIC_IPV4_BLACKHOLE)
1087 {
1088 if (CHECK_FLAG(si->flags, ZEBRA_FLAG_REJECT))
1089 vty_out (vty, " %s", "reject");
paul718e3742002-12-13 20:15:29 +00001090
paul7021c422003-07-15 12:52:22 +00001091 if (CHECK_FLAG(si->flags, ZEBRA_FLAG_BLACKHOLE))
1092 vty_out (vty, " %s", "blackhole");
1093 }
hasso81dfcaa2003-05-25 19:21:25 +00001094
paul7021c422003-07-15 12:52:22 +00001095 if (si->distance != ZEBRA_STATIC_DISTANCE_DEFAULT)
1096 vty_out (vty, " %d", si->distance);
hasso81dfcaa2003-05-25 19:21:25 +00001097
paul7021c422003-07-15 12:52:22 +00001098 vty_out (vty, "%s", VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00001099
paul7021c422003-07-15 12:52:22 +00001100 write = 1;
paul718e3742002-12-13 20:15:29 +00001101 }
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}