blob: ae4083ed32a655352d80d75f4b5acb08799a3d4d [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";
jardin9e867fe2003-12-23 08:56:18 +000052 case ZEBRA_ROUTE_ISIS:
53 return "isis";
paul718e3742002-12-13 20:15:29 +000054 case ZEBRA_ROUTE_BGP:
55 return "bgp";
56 default:
57 return "unknown";
58 }
59};
60
61/* Return route type string for VTY output. */
hassoc9e52be2004-09-26 16:09:34 +000062char
paul718e3742002-12-13 20:15:29 +000063route_type_char (u_char type)
64{
65 switch (type)
66 {
67 case ZEBRA_ROUTE_SYSTEM:
68 return 'S';
69 case ZEBRA_ROUTE_KERNEL:
70 return 'K';
71 case ZEBRA_ROUTE_CONNECT:
72 return 'C';
73 case ZEBRA_ROUTE_STATIC:
74 return 'S';
75 case ZEBRA_ROUTE_RIP:
76 return 'R';
77 case ZEBRA_ROUTE_RIPNG:
78 return 'R';
79 case ZEBRA_ROUTE_OSPF:
80 return 'O';
81 case ZEBRA_ROUTE_OSPF6:
82 return 'O';
jardin9e867fe2003-12-23 08:56:18 +000083 case ZEBRA_ROUTE_ISIS:
84 return 'I';
paul718e3742002-12-13 20:15:29 +000085 case ZEBRA_ROUTE_BGP:
86 return 'B';
87 default:
88 return '?';
89 }
90};
91
92/* General fucntion for static route. */
93int
hasso39db97e2004-10-12 20:50:58 +000094zebra_static_ipv4 (struct vty *vty, int add_cmd, const char *dest_str,
95 const char *mask_str, const char *gate_str,
96 const char *flag_str, const char *distance_str)
paul718e3742002-12-13 20:15:29 +000097{
98 int ret;
99 u_char distance;
100 struct prefix p;
101 struct in_addr gate;
102 struct in_addr mask;
hasso39db97e2004-10-12 20:50:58 +0000103 const char *ifname;
hasso81dfcaa2003-05-25 19:21:25 +0000104 u_char flag = 0;
paul718e3742002-12-13 20:15:29 +0000105
106 ret = str2prefix (dest_str, &p);
107 if (ret <= 0)
108 {
109 vty_out (vty, "%% Malformed address%s", VTY_NEWLINE);
110 return CMD_WARNING;
111 }
112
113 /* Cisco like mask notation. */
114 if (mask_str)
115 {
116 ret = inet_aton (mask_str, &mask);
117 if (ret == 0)
paul595db7f2003-05-25 21:35:06 +0000118 {
119 vty_out (vty, "%% Malformed address%s", VTY_NEWLINE);
120 return CMD_WARNING;
121 }
paul718e3742002-12-13 20:15:29 +0000122 p.prefixlen = ip_masklen (mask);
123 }
124
125 /* Apply mask for given prefix. */
126 apply_mask (&p);
127
paul595db7f2003-05-25 21:35:06 +0000128 /* Administrative distance. */
129 if (distance_str)
130 distance = atoi (distance_str);
131 else
132 distance = ZEBRA_STATIC_DISTANCE_DEFAULT;
133
134 /* Null0 static route. */
hasso457ef552003-05-28 12:02:15 +0000135 if ((gate_str != NULL) && (strncasecmp (gate_str, "Null0", strlen (gate_str)) == 0))
paul595db7f2003-05-25 21:35:06 +0000136 {
137 if (flag_str)
138 {
139 vty_out (vty, "%% can not have flag %s with Null0%s", flag_str, VTY_NEWLINE);
140 return CMD_WARNING;
141 }
142 if (add_cmd)
paul7021c422003-07-15 12:52:22 +0000143 static_add_ipv4 (&p, NULL, NULL, ZEBRA_FLAG_BLACKHOLE, distance, 0);
paul595db7f2003-05-25 21:35:06 +0000144 else
145 static_delete_ipv4 (&p, NULL, NULL, distance, 0);
146 return CMD_SUCCESS;
147 }
148
hasso81dfcaa2003-05-25 19:21:25 +0000149 /* Route flags */
150 if (flag_str) {
151 switch(flag_str[0]) {
152 case 'r':
153 case 'R': /* XXX */
154 SET_FLAG (flag, ZEBRA_FLAG_REJECT);
155 break;
156 case 'b':
157 case 'B': /* XXX */
158 SET_FLAG (flag, ZEBRA_FLAG_BLACKHOLE);
159 break;
160 default:
161 vty_out (vty, "%% Malformed flag %s %s", flag_str, VTY_NEWLINE);
paul595db7f2003-05-25 21:35:06 +0000162 return CMD_WARNING;
hasso81dfcaa2003-05-25 19:21:25 +0000163 }
164 }
165
hasso457ef552003-05-28 12:02:15 +0000166 if (gate_str == NULL)
167 {
168 if (add_cmd)
169 static_add_ipv4 (&p, NULL, NULL, flag, distance, 0);
170 else
171 static_delete_ipv4 (&p, NULL, NULL, distance, 0);
172
173 return CMD_SUCCESS;
174 }
175
paul718e3742002-12-13 20:15:29 +0000176 /* When gateway is A.B.C.D format, gate is treated as nexthop
177 address other case gate is treated as interface name. */
178 ret = inet_aton (gate_str, &gate);
179 if (ret)
180 ifname = NULL;
181 else
182 ifname = gate_str;
183
184 if (add_cmd)
hasso81dfcaa2003-05-25 19:21:25 +0000185 static_add_ipv4 (&p, ifname ? NULL : &gate, ifname, flag, distance, 0);
paul718e3742002-12-13 20:15:29 +0000186 else
187 static_delete_ipv4 (&p, ifname ? NULL : &gate, ifname, distance, 0);
188
189 return CMD_SUCCESS;
190}
191
192/* Static route configuration. */
193DEFUN (ip_route,
194 ip_route_cmd,
paul595db7f2003-05-25 21:35:06 +0000195 "ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0)",
hasso81dfcaa2003-05-25 19:21:25 +0000196 IP_STR
197 "Establish static routes\n"
198 "IP destination prefix (e.g. 10.0.0.0/8)\n"
199 "IP gateway address\n"
paul595db7f2003-05-25 21:35:06 +0000200 "IP gateway interface name\n"
201 "Null interface\n")
hasso81dfcaa2003-05-25 19:21:25 +0000202{
203 return zebra_static_ipv4 (vty, 1, argv[0], NULL, argv[1], NULL, NULL);
204}
205
206DEFUN (ip_route_flags,
207 ip_route_flags_cmd,
208 "ip route A.B.C.D/M (A.B.C.D|INTERFACE) (reject|blackhole)",
paul718e3742002-12-13 20:15:29 +0000209 IP_STR
210 "Establish static routes\n"
211 "IP destination prefix (e.g. 10.0.0.0/8)\n"
212 "IP gateway address\n"
213 "IP gateway interface name\n"
hasso81dfcaa2003-05-25 19:21:25 +0000214 "Emit an ICMP unreachable when matched\n"
215 "Silently discard pkts when matched\n")
paul718e3742002-12-13 20:15:29 +0000216{
hasso81dfcaa2003-05-25 19:21:25 +0000217 return zebra_static_ipv4 (vty, 1, argv[0], NULL, argv[1], argv[2], NULL);
paul718e3742002-12-13 20:15:29 +0000218}
219
hasso457ef552003-05-28 12:02:15 +0000220DEFUN (ip_route_flags2,
221 ip_route_flags2_cmd,
222 "ip route A.B.C.D/M (reject|blackhole)",
223 IP_STR
224 "Establish static routes\n"
225 "IP destination prefix (e.g. 10.0.0.0/8)\n"
226 "Emit an ICMP unreachable when matched\n"
227 "Silently discard pkts when matched\n")
228{
229 return zebra_static_ipv4 (vty, 1, argv[0], NULL, NULL, argv[1], NULL);
230}
231
paul718e3742002-12-13 20:15:29 +0000232/* Mask as A.B.C.D format. */
233DEFUN (ip_route_mask,
234 ip_route_mask_cmd,
paul595db7f2003-05-25 21:35:06 +0000235 "ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0)",
hasso81dfcaa2003-05-25 19:21:25 +0000236 IP_STR
237 "Establish static routes\n"
238 "IP destination prefix\n"
239 "IP destination prefix mask\n"
240 "IP gateway address\n"
paul595db7f2003-05-25 21:35:06 +0000241 "IP gateway interface name\n"
242 "Null interface\n")
hasso81dfcaa2003-05-25 19:21:25 +0000243{
244 return zebra_static_ipv4 (vty, 1, argv[0], argv[1], argv[2], NULL, NULL);
245}
246
247DEFUN (ip_route_mask_flags,
248 ip_route_mask_flags_cmd,
249 "ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE) (reject|blackhole)",
paul718e3742002-12-13 20:15:29 +0000250 IP_STR
251 "Establish static routes\n"
252 "IP destination prefix\n"
253 "IP destination prefix mask\n"
254 "IP gateway address\n"
255 "IP gateway interface name\n"
hasso81dfcaa2003-05-25 19:21:25 +0000256 "Emit an ICMP unreachable when matched\n"
257 "Silently discard pkts when matched\n")
paul718e3742002-12-13 20:15:29 +0000258{
hasso81dfcaa2003-05-25 19:21:25 +0000259 return zebra_static_ipv4 (vty, 1, argv[0], argv[1], argv[2], argv[3], NULL);
paul718e3742002-12-13 20:15:29 +0000260}
261
hasso457ef552003-05-28 12:02:15 +0000262DEFUN (ip_route_mask_flags2,
263 ip_route_mask_flags2_cmd,
264 "ip route A.B.C.D A.B.C.D (reject|blackhole)",
265 IP_STR
266 "Establish static routes\n"
267 "IP destination prefix\n"
268 "IP destination prefix mask\n"
269 "Emit an ICMP unreachable when matched\n"
270 "Silently discard pkts when matched\n")
271{
272 return zebra_static_ipv4 (vty, 1, argv[0], argv[1], NULL, argv[2], NULL);
273}
274
paul718e3742002-12-13 20:15:29 +0000275/* Distance option value. */
276DEFUN (ip_route_distance,
277 ip_route_distance_cmd,
paul595db7f2003-05-25 21:35:06 +0000278 "ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0) <1-255>",
paul718e3742002-12-13 20:15:29 +0000279 IP_STR
280 "Establish static routes\n"
281 "IP destination prefix (e.g. 10.0.0.0/8)\n"
282 "IP gateway address\n"
283 "IP gateway interface name\n"
paul595db7f2003-05-25 21:35:06 +0000284 "Null interface\n"
paul718e3742002-12-13 20:15:29 +0000285 "Distance value for this route\n")
286{
hasso81dfcaa2003-05-25 19:21:25 +0000287 return zebra_static_ipv4 (vty, 1, argv[0], NULL, argv[1], NULL, argv[2]);
288}
289
290DEFUN (ip_route_flags_distance,
291 ip_route_flags_distance_cmd,
292 "ip route A.B.C.D/M (A.B.C.D|INTERFACE) (reject|blackhole) <1-255>",
293 IP_STR
294 "Establish static routes\n"
295 "IP destination prefix (e.g. 10.0.0.0/8)\n"
296 "IP gateway address\n"
297 "IP gateway interface name\n"
298 "Emit an ICMP unreachable when matched\n"
299 "Silently discard pkts when matched\n"
300 "Distance value for this route\n")
301{
302 return zebra_static_ipv4 (vty, 1, argv[0], NULL, argv[1], argv[2], argv[3]);
paul718e3742002-12-13 20:15:29 +0000303}
304
hasso457ef552003-05-28 12:02:15 +0000305DEFUN (ip_route_flags_distance2,
306 ip_route_flags_distance2_cmd,
307 "ip route A.B.C.D/M (reject|blackhole) <1-255>",
308 IP_STR
309 "Establish static routes\n"
310 "IP destination prefix (e.g. 10.0.0.0/8)\n"
311 "Emit an ICMP unreachable when matched\n"
312 "Silently discard pkts when matched\n"
313 "Distance value for this route\n")
314{
315 return zebra_static_ipv4 (vty, 1, argv[0], NULL, NULL, argv[1], argv[2]);
316}
317
paul718e3742002-12-13 20:15:29 +0000318DEFUN (ip_route_mask_distance,
319 ip_route_mask_distance_cmd,
paul595db7f2003-05-25 21:35:06 +0000320 "ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0) <1-255>",
paul718e3742002-12-13 20:15:29 +0000321 IP_STR
322 "Establish static routes\n"
323 "IP destination prefix\n"
324 "IP destination prefix mask\n"
325 "IP gateway address\n"
326 "IP gateway interface name\n"
paul595db7f2003-05-25 21:35:06 +0000327 "Null interface\n"
paul718e3742002-12-13 20:15:29 +0000328 "Distance value for this route\n")
329{
hasso81dfcaa2003-05-25 19:21:25 +0000330 return zebra_static_ipv4 (vty, 1, argv[0], argv[1], argv[2], NULL, argv[3]);
331}
332
333DEFUN (ip_route_mask_flags_distance,
334 ip_route_mask_flags_distance_cmd,
335 "ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE) (reject|blackhole) <1-255>",
336 IP_STR
337 "Establish static routes\n"
338 "IP destination prefix\n"
339 "IP destination prefix mask\n"
340 "IP gateway address\n"
341 "IP gateway interface name\n"
342 "Distance value for this route\n"
343 "Emit an ICMP unreachable when matched\n"
344 "Silently discard pkts when matched\n")
345{
346 return zebra_static_ipv4 (vty, 1, argv[0], argv[1], argv[2], argv[3], argv[4]);
paul718e3742002-12-13 20:15:29 +0000347}
348
hasso457ef552003-05-28 12:02:15 +0000349DEFUN (ip_route_mask_flags_distance2,
350 ip_route_mask_flags_distance2_cmd,
351 "ip route A.B.C.D A.B.C.D (reject|blackhole) <1-255>",
352 IP_STR
353 "Establish static routes\n"
354 "IP destination prefix\n"
355 "IP destination prefix mask\n"
356 "Distance value for this route\n"
357 "Emit an ICMP unreachable when matched\n"
358 "Silently discard pkts when matched\n")
359{
360 return zebra_static_ipv4 (vty, 1, argv[0], argv[1], NULL, argv[2], argv[3]);
361}
362
paul718e3742002-12-13 20:15:29 +0000363DEFUN (no_ip_route,
364 no_ip_route_cmd,
paul595db7f2003-05-25 21:35:06 +0000365 "no ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0)",
hasso81dfcaa2003-05-25 19:21:25 +0000366 NO_STR
367 IP_STR
368 "Establish static routes\n"
369 "IP destination prefix (e.g. 10.0.0.0/8)\n"
370 "IP gateway address\n"
paul595db7f2003-05-25 21:35:06 +0000371 "IP gateway interface name\n"
372 "Null interface\n")
hasso81dfcaa2003-05-25 19:21:25 +0000373{
374 return zebra_static_ipv4 (vty, 0, argv[0], NULL, argv[1], NULL, NULL);
375}
376
377ALIAS (no_ip_route,
378 no_ip_route_flags_cmd,
379 "no ip route A.B.C.D/M (A.B.C.D|INTERFACE) (reject|blackhole)",
paul718e3742002-12-13 20:15:29 +0000380 NO_STR
381 IP_STR
382 "Establish static routes\n"
383 "IP destination prefix (e.g. 10.0.0.0/8)\n"
384 "IP gateway address\n"
385 "IP gateway interface name\n"
hasso81dfcaa2003-05-25 19:21:25 +0000386 "Emit an ICMP unreachable when matched\n"
387 "Silently discard pkts when matched\n")
paul718e3742002-12-13 20:15:29 +0000388
hasso457ef552003-05-28 12:02:15 +0000389DEFUN (no_ip_route_flags2,
390 no_ip_route_flags2_cmd,
391 "no ip route A.B.C.D/M (reject|blackhole)",
392 NO_STR
393 IP_STR
394 "Establish static routes\n"
395 "IP destination prefix (e.g. 10.0.0.0/8)\n"
396 "Emit an ICMP unreachable when matched\n"
397 "Silently discard pkts when matched\n")
398{
399 return zebra_static_ipv4 (vty, 0, argv[0], NULL, NULL, NULL, NULL);
400}
401
paul718e3742002-12-13 20:15:29 +0000402DEFUN (no_ip_route_mask,
403 no_ip_route_mask_cmd,
paul595db7f2003-05-25 21:35:06 +0000404 "no ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0)",
hasso81dfcaa2003-05-25 19:21:25 +0000405 NO_STR
406 IP_STR
407 "Establish static routes\n"
408 "IP destination prefix\n"
409 "IP destination prefix mask\n"
410 "IP gateway address\n"
paul595db7f2003-05-25 21:35:06 +0000411 "IP gateway interface name\n"
412 "Null interface\n")
hasso81dfcaa2003-05-25 19:21:25 +0000413{
414 return zebra_static_ipv4 (vty, 0, argv[0], argv[1], argv[2], NULL, NULL);
415}
416
417ALIAS (no_ip_route_mask,
418 no_ip_route_mask_flags_cmd,
419 "no ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE) (reject|blackhole)",
paul718e3742002-12-13 20:15:29 +0000420 NO_STR
421 IP_STR
422 "Establish static routes\n"
423 "IP destination prefix\n"
424 "IP destination prefix mask\n"
425 "IP gateway address\n"
426 "IP gateway interface name\n"
hasso81dfcaa2003-05-25 19:21:25 +0000427 "Emit an ICMP unreachable when matched\n"
428 "Silently discard pkts when matched\n")
paul718e3742002-12-13 20:15:29 +0000429
hasso457ef552003-05-28 12:02:15 +0000430DEFUN (no_ip_route_mask_flags2,
431 no_ip_route_mask_flags2_cmd,
432 "no ip route A.B.C.D A.B.C.D (reject|blackhole)",
433 NO_STR
434 IP_STR
435 "Establish static routes\n"
436 "IP destination prefix\n"
437 "IP destination prefix mask\n"
438 "Emit an ICMP unreachable when matched\n"
439 "Silently discard pkts when matched\n")
440{
441 return zebra_static_ipv4 (vty, 0, argv[0], argv[1], NULL, NULL, NULL);
442}
443
paul718e3742002-12-13 20:15:29 +0000444DEFUN (no_ip_route_distance,
445 no_ip_route_distance_cmd,
paul595db7f2003-05-25 21:35:06 +0000446 "no ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0) <1-255>",
paul718e3742002-12-13 20:15:29 +0000447 NO_STR
448 IP_STR
449 "Establish static routes\n"
450 "IP destination prefix (e.g. 10.0.0.0/8)\n"
451 "IP gateway address\n"
452 "IP gateway interface name\n"
paul595db7f2003-05-25 21:35:06 +0000453 "Null interface\n"
paul718e3742002-12-13 20:15:29 +0000454 "Distance value for this route\n")
455{
hasso81dfcaa2003-05-25 19:21:25 +0000456 return zebra_static_ipv4 (vty, 0, argv[0], NULL, argv[1], NULL, argv[2]);
457}
458
459DEFUN (no_ip_route_flags_distance,
460 no_ip_route_flags_distance_cmd,
461 "no ip route A.B.C.D/M (A.B.C.D|INTERFACE) (reject|blackhole) <1-255>",
462 NO_STR
463 IP_STR
464 "Establish static routes\n"
465 "IP destination prefix (e.g. 10.0.0.0/8)\n"
466 "IP gateway address\n"
467 "IP gateway interface name\n"
468 "Emit an ICMP unreachable when matched\n"
469 "Silently discard pkts when matched\n"
470 "Distance value for this route\n")
471{
472 return zebra_static_ipv4 (vty, 0, argv[0], NULL, argv[1], argv[2], argv[3]);
paul718e3742002-12-13 20:15:29 +0000473}
474
hasso457ef552003-05-28 12:02:15 +0000475DEFUN (no_ip_route_flags_distance2,
476 no_ip_route_flags_distance2_cmd,
477 "no ip route A.B.C.D/M (reject|blackhole) <1-255>",
478 NO_STR
479 IP_STR
480 "Establish static routes\n"
481 "IP destination prefix (e.g. 10.0.0.0/8)\n"
482 "Emit an ICMP unreachable when matched\n"
483 "Silently discard pkts when matched\n"
484 "Distance value for this route\n")
485{
486 return zebra_static_ipv4 (vty, 0, argv[0], NULL, NULL, argv[1], argv[2]);
487}
488
paul718e3742002-12-13 20:15:29 +0000489DEFUN (no_ip_route_mask_distance,
490 no_ip_route_mask_distance_cmd,
paul595db7f2003-05-25 21:35:06 +0000491 "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 +0000492 NO_STR
493 IP_STR
494 "Establish static routes\n"
495 "IP destination prefix\n"
496 "IP destination prefix mask\n"
497 "IP gateway address\n"
498 "IP gateway interface name\n"
paul595db7f2003-05-25 21:35:06 +0000499 "Null interface\n"
paul718e3742002-12-13 20:15:29 +0000500 "Distance value for this route\n")
501{
hasso81dfcaa2003-05-25 19:21:25 +0000502 return zebra_static_ipv4 (vty, 0, argv[0], argv[1], argv[2], NULL, argv[3]);
503}
504
505DEFUN (no_ip_route_mask_flags_distance,
506 no_ip_route_mask_flags_distance_cmd,
507 "no ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE) (reject|blackhole) <1-255>",
508 NO_STR
509 IP_STR
510 "Establish static routes\n"
511 "IP destination prefix\n"
512 "IP destination prefix mask\n"
513 "IP gateway address\n"
514 "IP gateway interface name\n"
515 "Emit an ICMP unreachable when matched\n"
516 "Silently discard pkts when matched\n"
517 "Distance value for this route\n")
518{
519 return zebra_static_ipv4 (vty, 0, argv[0], argv[1], argv[2], argv[3], argv[4]);
paul718e3742002-12-13 20:15:29 +0000520}
521
hasso457ef552003-05-28 12:02:15 +0000522DEFUN (no_ip_route_mask_flags_distance2,
523 no_ip_route_mask_flags_distance2_cmd,
524 "no ip route A.B.C.D A.B.C.D (reject|blackhole) <1-255>",
525 NO_STR
526 IP_STR
527 "Establish static routes\n"
528 "IP destination prefix\n"
529 "IP destination prefix mask\n"
530 "Emit an ICMP unreachable when matched\n"
531 "Silently discard pkts when matched\n"
532 "Distance value for this route\n")
533{
534 return zebra_static_ipv4 (vty, 0, argv[0], argv[1], NULL, argv[2], argv[3]);
535}
536
paul718e3742002-12-13 20:15:29 +0000537/* New RIB. Detailed information for IPv4 route. */
538void
539vty_show_ip_route_detail (struct vty *vty, struct route_node *rn)
540{
541 struct rib *rib;
542 struct nexthop *nexthop;
543
544 for (rib = rn->info; rib; rib = rib->next)
545 {
546 vty_out (vty, "Routing entry for %s/%d%s",
547 inet_ntoa (rn->p.u.prefix4), rn->p.prefixlen,
548 VTY_NEWLINE);
549 vty_out (vty, " Known via \"%s\"", route_type_str (rib->type));
550 vty_out (vty, ", distance %d, metric %d", rib->distance, rib->metric);
551 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
552 vty_out (vty, ", best");
553 if (rib->refcnt)
554 vty_out (vty, ", refcnt %ld", rib->refcnt);
hasso81dfcaa2003-05-25 19:21:25 +0000555 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_BLACKHOLE))
556 vty_out (vty, ", blackhole");
557 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_REJECT))
558 vty_out (vty, ", reject");
paul718e3742002-12-13 20:15:29 +0000559 vty_out (vty, "%s", VTY_NEWLINE);
560
561#define ONE_DAY_SECOND 60*60*24
562#define ONE_WEEK_SECOND 60*60*24*7
563 if (rib->type == ZEBRA_ROUTE_RIP
564 || rib->type == ZEBRA_ROUTE_OSPF
jardin9e867fe2003-12-23 08:56:18 +0000565 || rib->type == ZEBRA_ROUTE_ISIS
paul718e3742002-12-13 20:15:29 +0000566 || rib->type == ZEBRA_ROUTE_BGP)
567 {
568 time_t uptime;
569 struct tm *tm;
570
571 uptime = time (NULL);
572 uptime -= rib->uptime;
573 tm = gmtime (&uptime);
574
575 vty_out (vty, " Last update ");
576
577 if (uptime < ONE_DAY_SECOND)
578 vty_out (vty, "%02d:%02d:%02d",
579 tm->tm_hour, tm->tm_min, tm->tm_sec);
580 else if (uptime < ONE_WEEK_SECOND)
581 vty_out (vty, "%dd%02dh%02dm",
582 tm->tm_yday, tm->tm_hour, tm->tm_min);
583 else
584 vty_out (vty, "%02dw%dd%02dh",
585 tm->tm_yday/7,
586 tm->tm_yday - ((tm->tm_yday/7) * 7), tm->tm_hour);
587 vty_out (vty, " ago%s", VTY_NEWLINE);
588 }
589
590 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
591 {
592 vty_out (vty, " %c",
593 CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB) ? '*' : ' ');
594
595 switch (nexthop->type)
596 {
597 case NEXTHOP_TYPE_IPV4:
598 case NEXTHOP_TYPE_IPV4_IFINDEX:
599 vty_out (vty, " %s", inet_ntoa (nexthop->gate.ipv4));
600 if (nexthop->ifindex)
601 vty_out (vty, ", via %s", ifindex2ifname (nexthop->ifindex));
602 break;
603 case NEXTHOP_TYPE_IFINDEX:
604 vty_out (vty, " directly connected, %s",
605 ifindex2ifname (nexthop->ifindex));
606 break;
607 case NEXTHOP_TYPE_IFNAME:
608 vty_out (vty, " directly connected, %s", nexthop->ifname);
609 break;
paul595db7f2003-05-25 21:35:06 +0000610 case NEXTHOP_TYPE_BLACKHOLE:
paul7021c422003-07-15 12:52:22 +0000611 vty_out (vty, " directly connected, Null0");
paul595db7f2003-05-25 21:35:06 +0000612 break;
paul7021c422003-07-15 12:52:22 +0000613 default:
paul718e3742002-12-13 20:15:29 +0000614 break;
615 }
616 if (! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
617 vty_out (vty, " inactive");
618
619 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
620 {
621 vty_out (vty, " (recursive");
622
623 switch (nexthop->rtype)
624 {
625 case NEXTHOP_TYPE_IPV4:
626 case NEXTHOP_TYPE_IPV4_IFINDEX:
627 vty_out (vty, " via %s)", inet_ntoa (nexthop->rgate.ipv4));
628 break;
629 case NEXTHOP_TYPE_IFINDEX:
630 case NEXTHOP_TYPE_IFNAME:
631 vty_out (vty, " is directly connected, %s)",
632 ifindex2ifname (nexthop->rifindex));
633 break;
634 default:
635 break;
636 }
637 }
638 vty_out (vty, "%s", VTY_NEWLINE);
639 }
640 vty_out (vty, "%s", VTY_NEWLINE);
641 }
642}
643
644void
645vty_show_ip_route (struct vty *vty, struct route_node *rn, struct rib *rib)
646{
647 struct nexthop *nexthop;
648 int len = 0;
649 char buf[BUFSIZ];
650
651 /* Nexthop information. */
652 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
653 {
654 if (nexthop == rib->nexthop)
655 {
656 /* Prefix information. */
657 len = vty_out (vty, "%c%c%c %s/%d",
658 route_type_char (rib->type),
659 CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED)
660 ? '>' : ' ',
661 CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)
662 ? '*' : ' ',
663 inet_ntop (AF_INET, &rn->p.u.prefix, buf, BUFSIZ),
664 rn->p.prefixlen);
665
666 /* Distance and metric display. */
667 if (rib->type != ZEBRA_ROUTE_CONNECT
668 && rib->type != ZEBRA_ROUTE_KERNEL)
669 len += vty_out (vty, " [%d/%d]", rib->distance,
670 rib->metric);
671 }
672 else
673 vty_out (vty, " %c%*c",
674 CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)
675 ? '*' : ' ',
676 len - 3, ' ');
677
678 switch (nexthop->type)
679 {
680 case NEXTHOP_TYPE_IPV4:
681 case NEXTHOP_TYPE_IPV4_IFINDEX:
682 vty_out (vty, " via %s", inet_ntoa (nexthop->gate.ipv4));
683 if (nexthop->ifindex)
684 vty_out (vty, ", %s", ifindex2ifname (nexthop->ifindex));
685 break;
686 case NEXTHOP_TYPE_IFINDEX:
687 vty_out (vty, " is directly connected, %s",
688 ifindex2ifname (nexthop->ifindex));
689 break;
690 case NEXTHOP_TYPE_IFNAME:
691 vty_out (vty, " is directly connected, %s", nexthop->ifname);
692 break;
paul595db7f2003-05-25 21:35:06 +0000693 case NEXTHOP_TYPE_BLACKHOLE:
paul7021c422003-07-15 12:52:22 +0000694 vty_out (vty, " is directly connected, Null0");
paul595db7f2003-05-25 21:35:06 +0000695 break;
paul7021c422003-07-15 12:52:22 +0000696 default:
paul718e3742002-12-13 20:15:29 +0000697 break;
698 }
699 if (! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
700 vty_out (vty, " inactive");
701
702 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
703 {
704 vty_out (vty, " (recursive");
705
706 switch (nexthop->rtype)
707 {
708 case NEXTHOP_TYPE_IPV4:
709 case NEXTHOP_TYPE_IPV4_IFINDEX:
710 vty_out (vty, " via %s)", inet_ntoa (nexthop->rgate.ipv4));
711 break;
712 case NEXTHOP_TYPE_IFINDEX:
713 case NEXTHOP_TYPE_IFNAME:
714 vty_out (vty, " is directly connected, %s)",
715 ifindex2ifname (nexthop->rifindex));
716 break;
717 default:
718 break;
719 }
720 }
721
hasso81dfcaa2003-05-25 19:21:25 +0000722 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_BLACKHOLE))
723 vty_out (vty, ", bh");
724 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_REJECT))
725 vty_out (vty, ", rej");
726
paul718e3742002-12-13 20:15:29 +0000727 if (rib->type == ZEBRA_ROUTE_RIP
728 || rib->type == ZEBRA_ROUTE_OSPF
jardin9e867fe2003-12-23 08:56:18 +0000729 || rib->type == ZEBRA_ROUTE_ISIS
paul718e3742002-12-13 20:15:29 +0000730 || rib->type == ZEBRA_ROUTE_BGP)
731 {
732 time_t uptime;
733 struct tm *tm;
734
735 uptime = time (NULL);
736 uptime -= rib->uptime;
737 tm = gmtime (&uptime);
738
739#define ONE_DAY_SECOND 60*60*24
740#define ONE_WEEK_SECOND 60*60*24*7
741
742 if (uptime < ONE_DAY_SECOND)
743 vty_out (vty, ", %02d:%02d:%02d",
744 tm->tm_hour, tm->tm_min, tm->tm_sec);
745 else if (uptime < ONE_WEEK_SECOND)
746 vty_out (vty, ", %dd%02dh%02dm",
747 tm->tm_yday, tm->tm_hour, tm->tm_min);
748 else
749 vty_out (vty, ", %02dw%dd%02dh",
750 tm->tm_yday/7,
751 tm->tm_yday - ((tm->tm_yday/7) * 7), tm->tm_hour);
752 }
753 vty_out (vty, "%s", VTY_NEWLINE);
754 }
755}
756
hasso39db97e2004-10-12 20:50:58 +0000757#define SHOW_ROUTE_V4_HEADER "Codes: K - kernel route, C - connected, " \
758 "S - static, R - RIP, O - OSPF,%s I - ISIS, B - BGP, " \
759 "> - selected route, * - FIB route%s%s"
paul718e3742002-12-13 20:15:29 +0000760
761DEFUN (show_ip_route,
762 show_ip_route_cmd,
763 "show ip route",
764 SHOW_STR
765 IP_STR
766 "IP routing table\n")
767{
768 struct route_table *table;
769 struct route_node *rn;
770 struct rib *rib;
771 int first = 1;
772
773 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
774 if (! table)
775 return CMD_SUCCESS;
776
777 /* Show all IPv4 routes. */
778 for (rn = route_top (table); rn; rn = route_next (rn))
779 for (rib = rn->info; rib; rib = rib->next)
780 {
781 if (first)
782 {
783 vty_out (vty, SHOW_ROUTE_V4_HEADER, VTY_NEWLINE, VTY_NEWLINE,
784 VTY_NEWLINE);
785 first = 0;
786 }
787 vty_show_ip_route (vty, rn, rib);
788 }
789 return CMD_SUCCESS;
790}
791
792DEFUN (show_ip_route_prefix_longer,
793 show_ip_route_prefix_longer_cmd,
794 "show ip route A.B.C.D/M longer-prefixes",
795 SHOW_STR
796 IP_STR
797 "IP routing table\n"
798 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
799 "Show route matching the specified Network/Mask pair only\n")
800{
801 struct route_table *table;
802 struct route_node *rn;
803 struct rib *rib;
804 struct prefix p;
805 int ret;
806 int first = 1;
807
808 ret = str2prefix (argv[0], &p);
809 if (! ret)
810 {
811 vty_out (vty, "%% Malformed Prefix%s", VTY_NEWLINE);
812 return CMD_WARNING;
813 }
814
815 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
816 if (! table)
817 return CMD_SUCCESS;
818
819 /* Show matched type IPv4 routes. */
820 for (rn = route_top (table); rn; rn = route_next (rn))
821 for (rib = rn->info; rib; rib = rib->next)
822 if (prefix_match (&p, &rn->p))
823 {
824 if (first)
825 {
826 vty_out (vty, SHOW_ROUTE_V4_HEADER, VTY_NEWLINE,
827 VTY_NEWLINE, VTY_NEWLINE);
828 first = 0;
829 }
830 vty_show_ip_route (vty, rn, rib);
831 }
832 return CMD_SUCCESS;
833}
834
835DEFUN (show_ip_route_supernets,
836 show_ip_route_supernets_cmd,
837 "show ip route supernets-only",
838 SHOW_STR
839 IP_STR
840 "IP routing table\n"
841 "Show supernet entries only\n")
842{
843 struct route_table *table;
844 struct route_node *rn;
845 struct rib *rib;
846 u_int32_t addr;
847 int first = 1;
848
849 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
850 if (! table)
851 return CMD_SUCCESS;
852
853 /* Show matched type IPv4 routes. */
854 for (rn = route_top (table); rn; rn = route_next (rn))
855 for (rib = rn->info; rib; rib = rib->next)
856 {
857 addr = ntohl (rn->p.u.prefix4.s_addr);
858
859 if ((IN_CLASSC (addr) && rn->p.prefixlen < 24)
860 || (IN_CLASSB (addr) && rn->p.prefixlen < 16)
861 || (IN_CLASSA (addr) && rn->p.prefixlen < 8))
862 {
863 if (first)
864 {
865 vty_out (vty, SHOW_ROUTE_V4_HEADER, VTY_NEWLINE,
866 VTY_NEWLINE, VTY_NEWLINE);
867 first = 0;
868 }
869 vty_show_ip_route (vty, rn, rib);
870 }
871 }
872 return CMD_SUCCESS;
873}
874
875DEFUN (show_ip_route_protocol,
876 show_ip_route_protocol_cmd,
hasso39ff11d2004-10-12 15:55:19 +0000877 "show ip route (bgp|connected|isis|kernel|ospf|rip|static)",
paul718e3742002-12-13 20:15:29 +0000878 SHOW_STR
879 IP_STR
880 "IP routing table\n"
881 "Border Gateway Protocol (BGP)\n"
882 "Connected\n"
hasso39ff11d2004-10-12 15:55:19 +0000883 "ISO IS-IS (ISIS)\n"
paul718e3742002-12-13 20:15:29 +0000884 "Kernel\n"
885 "Open Shortest Path First (OSPF)\n"
886 "Routing Information Protocol (RIP)\n"
887 "Static routes\n")
888{
889 int type;
890 struct route_table *table;
891 struct route_node *rn;
892 struct rib *rib;
893 int first = 1;
894
895 if (strncmp (argv[0], "b", 1) == 0)
896 type = ZEBRA_ROUTE_BGP;
897 else if (strncmp (argv[0], "c", 1) == 0)
898 type = ZEBRA_ROUTE_CONNECT;
899 else if (strncmp (argv[0], "k", 1) ==0)
900 type = ZEBRA_ROUTE_KERNEL;
901 else if (strncmp (argv[0], "o", 1) == 0)
902 type = ZEBRA_ROUTE_OSPF;
jardin9e867fe2003-12-23 08:56:18 +0000903 else if (strncmp (argv[0], "i", 1) == 0)
904 type = ZEBRA_ROUTE_ISIS;
paul718e3742002-12-13 20:15:29 +0000905 else if (strncmp (argv[0], "r", 1) == 0)
906 type = ZEBRA_ROUTE_RIP;
907 else if (strncmp (argv[0], "s", 1) == 0)
908 type = ZEBRA_ROUTE_STATIC;
909 else
910 {
911 vty_out (vty, "Unknown route type%s", VTY_NEWLINE);
912 return CMD_WARNING;
913 }
914
915 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
916 if (! table)
917 return CMD_SUCCESS;
918
919 /* Show matched type IPv4 routes. */
920 for (rn = route_top (table); rn; rn = route_next (rn))
921 for (rib = rn->info; rib; rib = rib->next)
922 if (rib->type == type)
923 {
924 if (first)
925 {
926 vty_out (vty, SHOW_ROUTE_V4_HEADER,
927 VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE);
928 first = 0;
929 }
930 vty_show_ip_route (vty, rn, rib);
931 }
932 return CMD_SUCCESS;
933}
934
935DEFUN (show_ip_route_addr,
936 show_ip_route_addr_cmd,
937 "show ip route A.B.C.D",
938 SHOW_STR
939 IP_STR
940 "IP routing table\n"
941 "Network in the IP routing table to display\n")
942{
943 int ret;
944 struct prefix_ipv4 p;
945 struct route_table *table;
946 struct route_node *rn;
947
948 ret = str2prefix_ipv4 (argv[0], &p);
949 if (ret <= 0)
950 {
951 vty_out (vty, "%% Malformed IPv4 address%s", VTY_NEWLINE);
952 return CMD_WARNING;
953 }
954
955 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
956 if (! table)
957 return CMD_SUCCESS;
958
959 rn = route_node_match (table, (struct prefix *) &p);
960 if (! rn)
961 {
962 vty_out (vty, "%% Network not in table%s", VTY_NEWLINE);
963 return CMD_WARNING;
964 }
965
966 vty_show_ip_route_detail (vty, rn);
967
968 route_unlock_node (rn);
969
970 return CMD_SUCCESS;
971}
972
973DEFUN (show_ip_route_prefix,
974 show_ip_route_prefix_cmd,
975 "show ip route A.B.C.D/M",
976 SHOW_STR
977 IP_STR
978 "IP routing table\n"
979 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n")
980{
981 int ret;
982 struct prefix_ipv4 p;
983 struct route_table *table;
984 struct route_node *rn;
985
986 ret = str2prefix_ipv4 (argv[0], &p);
987 if (ret <= 0)
988 {
989 vty_out (vty, "%% Malformed IPv4 address%s", VTY_NEWLINE);
990 return CMD_WARNING;
991 }
992
993 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
994 if (! table)
995 return CMD_SUCCESS;
996
997 rn = route_node_match (table, (struct prefix *) &p);
998 if (! rn || rn->p.prefixlen != p.prefixlen)
999 {
1000 vty_out (vty, "%% Network not in table%s", VTY_NEWLINE);
1001 return CMD_WARNING;
1002 }
1003
1004 vty_show_ip_route_detail (vty, rn);
1005
1006 route_unlock_node (rn);
1007
1008 return CMD_SUCCESS;
1009}
1010
1011void
1012zebra_show_ip_route (struct vty *vty, struct vrf *vrf)
1013{
1014 vty_out (vty, "IP routing table name is %s(%d)%s",
1015 vrf->name ? vrf->name : "", vrf->id, VTY_NEWLINE);
1016
1017 vty_out (vty, "Route Source Networks%s", VTY_NEWLINE);
1018 vty_out (vty, "connected %d%s", 0, VTY_NEWLINE);
1019 vty_out (vty, "static %d%s", 0, VTY_NEWLINE);
1020 vty_out (vty, "rip %d%s", 0, VTY_NEWLINE);
1021
1022 vty_out (vty, "bgp %d%s", 0, VTY_NEWLINE);
1023 vty_out (vty, " External: %d Internal: %d Local: %d%s",
1024 0, 0, 0, VTY_NEWLINE);
1025
1026 vty_out (vty, "ospf %d%s", 0, VTY_NEWLINE);
1027 vty_out (vty,
1028 " Intra-area: %d Inter-area: %d External-1: %d External-2: %d%s",
1029 0, 0, 0, 0, VTY_NEWLINE);
1030 vty_out (vty, " NSSA External-1: %d NSSA External-2: %d%s",
1031 0, 0, VTY_NEWLINE);
1032
1033 vty_out (vty, "internal %d%s", 0, VTY_NEWLINE);
1034 vty_out (vty, "Total %d%s", 0, VTY_NEWLINE);
1035}
1036
1037/* Show route summary. */
1038DEFUN (show_ip_route_summary,
1039 show_ip_route_summary_cmd,
1040 "show ip route summary",
1041 SHOW_STR
1042 IP_STR
1043 "IP routing table\n"
1044 "Summary of all routes\n")
1045{
1046 struct vrf *vrf;
1047
1048 /* Default table id is zero. */
1049 vrf = vrf_lookup (0);
1050 if (! vrf)
1051 {
1052 vty_out (vty, "%% No Default-IP-Routing-Table%s", VTY_NEWLINE);
1053 return CMD_WARNING;
1054 }
1055
1056 zebra_show_ip_route (vty, vrf);
1057
1058 return CMD_SUCCESS;
1059}
1060
1061/* Write IPv4 static route configuration. */
1062int
1063static_config_ipv4 (struct vty *vty)
1064{
1065 struct route_node *rn;
1066 struct static_ipv4 *si;
1067 struct route_table *stable;
1068 int write;
1069
1070 write = 0;
1071
1072 /* Lookup table. */
1073 stable = vrf_static_table (AFI_IP, SAFI_UNICAST, 0);
1074 if (! stable)
1075 return -1;
1076
1077 for (rn = route_top (stable); rn; rn = route_next (rn))
1078 for (si = rn->info; si; si = si->next)
1079 {
paul7021c422003-07-15 12:52:22 +00001080 vty_out (vty, "ip route %s/%d", inet_ntoa (rn->p.u.prefix4),
1081 rn->p.prefixlen);
paul718e3742002-12-13 20:15:29 +00001082
paul7021c422003-07-15 12:52:22 +00001083 switch (si->type)
1084 {
1085 case STATIC_IPV4_GATEWAY:
1086 vty_out (vty, " %s", inet_ntoa (si->gate.ipv4));
1087 break;
1088 case STATIC_IPV4_IFNAME:
1089 vty_out (vty, " %s", si->gate.ifname);
1090 break;
1091 case STATIC_IPV4_BLACKHOLE:
1092 vty_out (vty, " Null0");
1093 break;
1094 }
1095
1096 /* flags are incompatible with STATIC_IPV4_BLACKHOLE */
1097 if (si->type != STATIC_IPV4_BLACKHOLE)
1098 {
1099 if (CHECK_FLAG(si->flags, ZEBRA_FLAG_REJECT))
1100 vty_out (vty, " %s", "reject");
paul718e3742002-12-13 20:15:29 +00001101
paul7021c422003-07-15 12:52:22 +00001102 if (CHECK_FLAG(si->flags, ZEBRA_FLAG_BLACKHOLE))
1103 vty_out (vty, " %s", "blackhole");
1104 }
hasso81dfcaa2003-05-25 19:21:25 +00001105
paul7021c422003-07-15 12:52:22 +00001106 if (si->distance != ZEBRA_STATIC_DISTANCE_DEFAULT)
1107 vty_out (vty, " %d", si->distance);
hasso81dfcaa2003-05-25 19:21:25 +00001108
paul7021c422003-07-15 12:52:22 +00001109 vty_out (vty, "%s", VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00001110
paul7021c422003-07-15 12:52:22 +00001111 write = 1;
paul718e3742002-12-13 20:15:29 +00001112 }
1113 return write;
1114}
1115
1116#ifdef HAVE_IPV6
1117/* General fucntion for IPv6 static route. */
1118int
hasso39db97e2004-10-12 20:50:58 +00001119static_ipv6_func (struct vty *vty, int add_cmd, const char *dest_str,
1120 const char *gate_str, const char *ifname,
1121 const char *flag_str, const char *distance_str)
paul718e3742002-12-13 20:15:29 +00001122{
1123 int ret;
1124 u_char distance;
1125 struct prefix p;
1126 struct in6_addr *gate = NULL;
1127 struct in6_addr gate_addr;
1128 u_char type = 0;
1129 int table = 0;
hasso81dfcaa2003-05-25 19:21:25 +00001130 u_char flag = 0;
paul718e3742002-12-13 20:15:29 +00001131
1132 ret = str2prefix (dest_str, &p);
1133 if (ret <= 0)
1134 {
1135 vty_out (vty, "%% Malformed address%s", VTY_NEWLINE);
1136 return CMD_WARNING;
1137 }
1138
1139 /* Apply mask for given prefix. */
1140 apply_mask (&p);
1141
hasso81dfcaa2003-05-25 19:21:25 +00001142 /* Route flags */
1143 if (flag_str) {
1144 switch(flag_str[0]) {
1145 case 'r':
1146 case 'R': /* XXX */
1147 SET_FLAG (flag, ZEBRA_FLAG_REJECT);
1148 break;
1149 case 'b':
1150 case 'B': /* XXX */
1151 SET_FLAG (flag, ZEBRA_FLAG_BLACKHOLE);
1152 break;
1153 default:
1154 vty_out (vty, "%% Malformed flag %s %s", flag_str, VTY_NEWLINE);
paul595db7f2003-05-25 21:35:06 +00001155 return CMD_WARNING;
hasso81dfcaa2003-05-25 19:21:25 +00001156 }
1157 }
1158
paul718e3742002-12-13 20:15:29 +00001159 /* Administrative distance. */
1160 if (distance_str)
1161 distance = atoi (distance_str);
1162 else
1163 distance = ZEBRA_STATIC_DISTANCE_DEFAULT;
1164
1165 /* When gateway is valid IPv6 addrees, then gate is treated as
1166 nexthop address other case gate is treated as interface name. */
1167 ret = inet_pton (AF_INET6, gate_str, &gate_addr);
1168
1169 if (ifname)
1170 {
1171 /* When ifname is specified. It must be come with gateway
1172 address. */
1173 if (ret != 1)
1174 {
1175 vty_out (vty, "%% Malformed address%s", VTY_NEWLINE);
1176 return CMD_WARNING;
1177 }
1178 type = STATIC_IPV6_GATEWAY_IFNAME;
1179 gate = &gate_addr;
1180 }
1181 else
1182 {
1183 if (ret == 1)
1184 {
1185 type = STATIC_IPV6_GATEWAY;
1186 gate = &gate_addr;
1187 }
1188 else
1189 {
1190 type = STATIC_IPV6_IFNAME;
1191 ifname = gate_str;
1192 }
1193 }
1194
1195 if (add_cmd)
hasso81dfcaa2003-05-25 19:21:25 +00001196 static_add_ipv6 (&p, type, gate, ifname, flag, distance, table);
paul718e3742002-12-13 20:15:29 +00001197 else
1198 static_delete_ipv6 (&p, type, gate, ifname, distance, table);
1199
1200 return CMD_SUCCESS;
1201}
1202
1203DEFUN (ipv6_route,
1204 ipv6_route_cmd,
1205 "ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE)",
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{
hasso81dfcaa2003-05-25 19:21:25 +00001212 return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, NULL, NULL);
1213}
1214
1215DEFUN (ipv6_route_flags,
1216 ipv6_route_flags_cmd,
1217 "ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) (reject|blackhole)",
1218 IP_STR
1219 "Establish static routes\n"
1220 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1221 "IPv6 gateway address\n"
1222 "IPv6 gateway interface name\n"
1223 "Emit an ICMP unreachable when matched\n"
1224 "Silently discard pkts when matched\n")
1225{
1226 return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, argv[2], NULL);
paul718e3742002-12-13 20:15:29 +00001227}
1228
1229DEFUN (ipv6_route_ifname,
1230 ipv6_route_ifname_cmd,
1231 "ipv6 route X:X::X:X/M X:X::X:X INTERFACE",
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{
hasso81dfcaa2003-05-25 19:21:25 +00001238 return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], NULL, NULL);
1239}
1240
1241DEFUN (ipv6_route_ifname_flags,
1242 ipv6_route_ifname_flags_cmd,
1243 "ipv6 route X:X::X:X/M X:X::X:X INTERFACE (reject|blackhole)",
1244 IP_STR
1245 "Establish static routes\n"
1246 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1247 "IPv6 gateway address\n"
1248 "IPv6 gateway interface name\n"
1249 "Emit an ICMP unreachable when matched\n"
1250 "Silently discard pkts when matched\n")
1251{
1252 return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], argv[3], NULL);
paul718e3742002-12-13 20:15:29 +00001253}
1254
1255DEFUN (ipv6_route_pref,
1256 ipv6_route_pref_cmd,
1257 "ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) <1-255>",
1258 IP_STR
1259 "Establish static routes\n"
1260 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1261 "IPv6 gateway address\n"
1262 "IPv6 gateway interface name\n"
1263 "Distance value for this prefix\n")
1264{
hasso81dfcaa2003-05-25 19:21:25 +00001265 return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, NULL, argv[2]);
1266}
1267
1268DEFUN (ipv6_route_flags_pref,
1269 ipv6_route_flags_pref_cmd,
1270 "ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) (reject|blackhole) <1-255>",
1271 IP_STR
1272 "Establish static routes\n"
1273 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1274 "IPv6 gateway address\n"
1275 "IPv6 gateway interface name\n"
1276 "Emit an ICMP unreachable when matched\n"
1277 "Silently discard pkts when matched\n"
1278 "Distance value for this prefix\n")
1279{
1280 return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, argv[2], argv[3]);
paul718e3742002-12-13 20:15:29 +00001281}
1282
1283DEFUN (ipv6_route_ifname_pref,
1284 ipv6_route_ifname_pref_cmd,
1285 "ipv6 route X:X::X:X/M X:X::X:X INTERFACE <1-255>",
1286 IP_STR
1287 "Establish static routes\n"
1288 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1289 "IPv6 gateway address\n"
1290 "IPv6 gateway interface name\n"
1291 "Distance value for this prefix\n")
1292{
hasso81dfcaa2003-05-25 19:21:25 +00001293 return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], NULL, argv[3]);
1294}
1295
1296DEFUN (ipv6_route_ifname_flags_pref,
1297 ipv6_route_ifname_flags_pref_cmd,
1298 "ipv6 route X:X::X:X/M X:X::X:X INTERFACE (reject|blackhole) <1-255>",
1299 IP_STR
1300 "Establish static routes\n"
1301 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1302 "IPv6 gateway address\n"
1303 "IPv6 gateway interface name\n"
1304 "Emit an ICMP unreachable when matched\n"
1305 "Silently discard pkts when matched\n"
1306 "Distance value for this prefix\n")
1307{
1308 return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], argv[3], argv[4]);
paul718e3742002-12-13 20:15:29 +00001309}
1310
1311DEFUN (no_ipv6_route,
1312 no_ipv6_route_cmd,
1313 "no ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE)",
1314 NO_STR
1315 IP_STR
1316 "Establish static routes\n"
1317 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1318 "IPv6 gateway address\n"
1319 "IPv6 gateway interface name\n")
1320{
hasso81dfcaa2003-05-25 19:21:25 +00001321 return static_ipv6_func (vty, 0, argv[0], argv[1], NULL, NULL, NULL);
paul718e3742002-12-13 20:15:29 +00001322}
1323
hasso81dfcaa2003-05-25 19:21:25 +00001324ALIAS (no_ipv6_route,
1325 no_ipv6_route_flags_cmd,
1326 "no ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) (reject|blackhole)",
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 "Emit an ICMP unreachable when matched\n"
1334 "Silently discard pkts when matched\n")
1335
paul718e3742002-12-13 20:15:29 +00001336DEFUN (no_ipv6_route_ifname,
1337 no_ipv6_route_ifname_cmd,
1338 "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE",
1339 NO_STR
1340 IP_STR
1341 "Establish static routes\n"
1342 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1343 "IPv6 gateway address\n"
1344 "IPv6 gateway interface name\n")
1345{
hasso81dfcaa2003-05-25 19:21:25 +00001346 return static_ipv6_func (vty, 0, argv[0], argv[1], argv[2], NULL, NULL);
paul718e3742002-12-13 20:15:29 +00001347}
1348
hasso81dfcaa2003-05-25 19:21:25 +00001349ALIAS (no_ipv6_route_ifname,
1350 no_ipv6_route_ifname_flags_cmd,
1351 "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE (reject|blackhole)",
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 "Emit an ICMP unreachable when matched\n"
1359 "Silently discard pkts when matched\n")
1360
paul718e3742002-12-13 20:15:29 +00001361DEFUN (no_ipv6_route_pref,
1362 no_ipv6_route_pref_cmd,
1363 "no ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) <1-255>",
1364 NO_STR
1365 IP_STR
1366 "Establish static routes\n"
1367 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1368 "IPv6 gateway address\n"
1369 "IPv6 gateway interface name\n"
1370 "Distance value for this prefix\n")
1371{
hasso81dfcaa2003-05-25 19:21:25 +00001372 return static_ipv6_func (vty, 0, argv[0], argv[1], NULL, NULL, argv[2]);
1373}
1374
1375DEFUN (no_ipv6_route_flags_pref,
1376 no_ipv6_route_flags_pref_cmd,
1377 "no ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) (reject|blackhole) <1-255>",
1378 NO_STR
1379 IP_STR
1380 "Establish static routes\n"
1381 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1382 "IPv6 gateway address\n"
1383 "IPv6 gateway interface name\n"
1384 "Emit an ICMP unreachable when matched\n"
1385 "Silently discard pkts when matched\n"
1386 "Distance value for this prefix\n")
1387{
1388 /* We do not care about argv[2] */
1389 return static_ipv6_func (vty, 0, argv[0], argv[1], NULL, argv[2], argv[3]);
paul718e3742002-12-13 20:15:29 +00001390}
1391
1392DEFUN (no_ipv6_route_ifname_pref,
1393 no_ipv6_route_ifname_pref_cmd,
1394 "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE <1-255>",
1395 NO_STR
1396 IP_STR
1397 "Establish static routes\n"
1398 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1399 "IPv6 gateway address\n"
1400 "IPv6 gateway interface name\n"
1401 "Distance value for this prefix\n")
1402{
hasso81dfcaa2003-05-25 19:21:25 +00001403 return static_ipv6_func (vty, 0, argv[0], argv[1], argv[2], NULL, argv[3]);
1404}
1405
1406DEFUN (no_ipv6_route_ifname_flags_pref,
1407 no_ipv6_route_ifname_flags_pref_cmd,
1408 "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE (reject|blackhole) <1-255>",
1409 NO_STR
1410 IP_STR
1411 "Establish static routes\n"
1412 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1413 "IPv6 gateway address\n"
1414 "IPv6 gateway interface name\n"
1415 "Emit an ICMP unreachable when matched\n"
1416 "Silently discard pkts when matched\n"
1417 "Distance value for this prefix\n")
1418{
1419 return static_ipv6_func (vty, 0, argv[0], argv[1], argv[2], argv[3], argv[4]);
paul718e3742002-12-13 20:15:29 +00001420}
1421
paul595db7f2003-05-25 21:35:06 +00001422/* New RIB. Detailed information for IPv6 route. */
paul718e3742002-12-13 20:15:29 +00001423void
1424vty_show_ipv6_route_detail (struct vty *vty, struct route_node *rn)
1425{
1426 struct rib *rib;
1427 struct nexthop *nexthop;
1428 char buf[BUFSIZ];
1429
1430 for (rib = rn->info; rib; rib = rib->next)
1431 {
1432 vty_out (vty, "Routing entry for %s/%d%s",
1433 inet_ntop (AF_INET6, &rn->p.u.prefix6, buf, BUFSIZ),
1434 rn->p.prefixlen,
1435 VTY_NEWLINE);
1436 vty_out (vty, " Known via \"%s\"", route_type_str (rib->type));
1437 vty_out (vty, ", distance %d, metric %d", rib->distance, rib->metric);
1438 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
1439 vty_out (vty, ", best");
1440 if (rib->refcnt)
1441 vty_out (vty, ", refcnt %ld", rib->refcnt);
hasso81dfcaa2003-05-25 19:21:25 +00001442 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_BLACKHOLE))
1443 vty_out (vty, ", blackhole");
1444 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_REJECT))
1445 vty_out (vty, ", reject");
paul718e3742002-12-13 20:15:29 +00001446 vty_out (vty, "%s", VTY_NEWLINE);
1447
1448#define ONE_DAY_SECOND 60*60*24
1449#define ONE_WEEK_SECOND 60*60*24*7
1450 if (rib->type == ZEBRA_ROUTE_RIPNG
1451 || rib->type == ZEBRA_ROUTE_OSPF6
jardin9e867fe2003-12-23 08:56:18 +00001452 || rib->type == ZEBRA_ROUTE_ISIS
paul718e3742002-12-13 20:15:29 +00001453 || rib->type == ZEBRA_ROUTE_BGP)
1454 {
1455 time_t uptime;
1456 struct tm *tm;
1457
1458 uptime = time (NULL);
1459 uptime -= rib->uptime;
1460 tm = gmtime (&uptime);
1461
1462 vty_out (vty, " Last update ");
1463
1464 if (uptime < ONE_DAY_SECOND)
1465 vty_out (vty, "%02d:%02d:%02d",
1466 tm->tm_hour, tm->tm_min, tm->tm_sec);
1467 else if (uptime < ONE_WEEK_SECOND)
1468 vty_out (vty, "%dd%02dh%02dm",
1469 tm->tm_yday, tm->tm_hour, tm->tm_min);
1470 else
1471 vty_out (vty, "%02dw%dd%02dh",
1472 tm->tm_yday/7,
1473 tm->tm_yday - ((tm->tm_yday/7) * 7), tm->tm_hour);
1474 vty_out (vty, " ago%s", VTY_NEWLINE);
1475 }
1476
1477 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1478 {
1479 vty_out (vty, " %c",
1480 CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB) ? '*' : ' ');
1481
1482 switch (nexthop->type)
1483 {
1484 case NEXTHOP_TYPE_IPV6:
1485 case NEXTHOP_TYPE_IPV6_IFINDEX:
1486 case NEXTHOP_TYPE_IPV6_IFNAME:
1487 vty_out (vty, " %s",
1488 inet_ntop (AF_INET6, &nexthop->gate.ipv6, buf, BUFSIZ));
1489 if (nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME)
1490 vty_out (vty, ", %s", nexthop->ifname);
1491 else if (nexthop->ifindex)
1492 vty_out (vty, ", via %s", ifindex2ifname (nexthop->ifindex));
1493 break;
1494 case NEXTHOP_TYPE_IFINDEX:
1495 vty_out (vty, " directly connected, %s",
1496 ifindex2ifname (nexthop->ifindex));
1497 break;
1498 case NEXTHOP_TYPE_IFNAME:
1499 vty_out (vty, " directly connected, %s",
1500 nexthop->ifname);
1501 break;
1502 default:
1503 break;
1504 }
1505 if (! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
1506 vty_out (vty, " inactive");
1507
1508 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
1509 {
1510 vty_out (vty, " (recursive");
1511
1512 switch (nexthop->rtype)
1513 {
1514 case NEXTHOP_TYPE_IPV6:
1515 case NEXTHOP_TYPE_IPV6_IFINDEX:
1516 case NEXTHOP_TYPE_IPV6_IFNAME:
1517 vty_out (vty, " via %s)",
1518 inet_ntop (AF_INET6, &nexthop->rgate.ipv6,
1519 buf, BUFSIZ));
1520 if (nexthop->rifindex)
1521 vty_out (vty, ", %s", ifindex2ifname (nexthop->rifindex));
1522 break;
1523 case NEXTHOP_TYPE_IFINDEX:
1524 case NEXTHOP_TYPE_IFNAME:
1525 vty_out (vty, " is directly connected, %s)",
1526 ifindex2ifname (nexthop->rifindex));
1527 break;
1528 default:
1529 break;
1530 }
1531 }
1532 vty_out (vty, "%s", VTY_NEWLINE);
1533 }
1534 vty_out (vty, "%s", VTY_NEWLINE);
1535 }
1536}
1537
1538void
1539vty_show_ipv6_route (struct vty *vty, struct route_node *rn,
1540 struct rib *rib)
1541{
1542 struct nexthop *nexthop;
1543 int len = 0;
1544 char buf[BUFSIZ];
1545
1546 /* Nexthop information. */
1547 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1548 {
1549 if (nexthop == rib->nexthop)
1550 {
1551 /* Prefix information. */
1552 len = vty_out (vty, "%c%c%c %s/%d",
1553 route_type_char (rib->type),
1554 CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED)
1555 ? '>' : ' ',
1556 CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)
1557 ? '*' : ' ',
1558 inet_ntop (AF_INET6, &rn->p.u.prefix6, buf, BUFSIZ),
1559 rn->p.prefixlen);
1560
1561 /* Distance and metric display. */
1562 if (rib->type != ZEBRA_ROUTE_CONNECT
1563 && rib->type != ZEBRA_ROUTE_KERNEL)
1564 len += vty_out (vty, " [%d/%d]", rib->distance,
1565 rib->metric);
1566 }
1567 else
1568 vty_out (vty, " %c%*c",
1569 CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)
1570 ? '*' : ' ',
1571 len - 3, ' ');
1572
1573 switch (nexthop->type)
1574 {
1575 case NEXTHOP_TYPE_IPV6:
1576 case NEXTHOP_TYPE_IPV6_IFINDEX:
1577 case NEXTHOP_TYPE_IPV6_IFNAME:
1578 vty_out (vty, " via %s",
1579 inet_ntop (AF_INET6, &nexthop->gate.ipv6, buf, BUFSIZ));
1580 if (nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME)
1581 vty_out (vty, ", %s", nexthop->ifname);
1582 else if (nexthop->ifindex)
1583 vty_out (vty, ", %s", ifindex2ifname (nexthop->ifindex));
1584 break;
1585 case NEXTHOP_TYPE_IFINDEX:
1586 vty_out (vty, " is directly connected, %s",
1587 ifindex2ifname (nexthop->ifindex));
1588 break;
1589 case NEXTHOP_TYPE_IFNAME:
1590 vty_out (vty, " is directly connected, %s",
1591 nexthop->ifname);
1592 break;
1593 default:
1594 break;
1595 }
1596 if (! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
1597 vty_out (vty, " inactive");
1598
1599 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
1600 {
1601 vty_out (vty, " (recursive");
1602
1603 switch (nexthop->rtype)
1604 {
1605 case NEXTHOP_TYPE_IPV6:
1606 case NEXTHOP_TYPE_IPV6_IFINDEX:
1607 case NEXTHOP_TYPE_IPV6_IFNAME:
1608 vty_out (vty, " via %s)",
1609 inet_ntop (AF_INET6, &nexthop->rgate.ipv6,
1610 buf, BUFSIZ));
1611 if (nexthop->rifindex)
1612 vty_out (vty, ", %s", ifindex2ifname (nexthop->rifindex));
1613 break;
1614 case NEXTHOP_TYPE_IFINDEX:
1615 case NEXTHOP_TYPE_IFNAME:
1616 vty_out (vty, " is directly connected, %s)",
1617 ifindex2ifname (nexthop->rifindex));
1618 break;
1619 default:
1620 break;
1621 }
1622 }
1623
hasso81dfcaa2003-05-25 19:21:25 +00001624 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_BLACKHOLE))
1625 vty_out (vty, ", bh");
1626 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_REJECT))
1627 vty_out (vty, ", rej");
1628
paul718e3742002-12-13 20:15:29 +00001629 if (rib->type == ZEBRA_ROUTE_RIPNG
1630 || rib->type == ZEBRA_ROUTE_OSPF6
jardin9e867fe2003-12-23 08:56:18 +00001631 || rib->type == ZEBRA_ROUTE_ISIS
paul718e3742002-12-13 20:15:29 +00001632 || rib->type == ZEBRA_ROUTE_BGP)
1633 {
1634 time_t uptime;
1635 struct tm *tm;
1636
1637 uptime = time (NULL);
1638 uptime -= rib->uptime;
1639 tm = gmtime (&uptime);
1640
1641#define ONE_DAY_SECOND 60*60*24
1642#define ONE_WEEK_SECOND 60*60*24*7
1643
1644 if (uptime < ONE_DAY_SECOND)
1645 vty_out (vty, ", %02d:%02d:%02d",
1646 tm->tm_hour, tm->tm_min, tm->tm_sec);
1647 else if (uptime < ONE_WEEK_SECOND)
1648 vty_out (vty, ", %dd%02dh%02dm",
1649 tm->tm_yday, tm->tm_hour, tm->tm_min);
1650 else
1651 vty_out (vty, ", %02dw%dd%02dh",
1652 tm->tm_yday/7,
1653 tm->tm_yday - ((tm->tm_yday/7) * 7), tm->tm_hour);
1654 }
1655 vty_out (vty, "%s", VTY_NEWLINE);
1656 }
1657}
1658
jardin9e867fe2003-12-23 08:56:18 +00001659#define SHOW_ROUTE_V6_HEADER "Codes: K - kernel route, C - connected, S - static, R - RIPng, O - OSPFv3,%s I - ISIS, B - BGP, * - FIB route.%s%s"
paul718e3742002-12-13 20:15:29 +00001660
1661DEFUN (show_ipv6_route,
1662 show_ipv6_route_cmd,
1663 "show ipv6 route",
1664 SHOW_STR
1665 IP_STR
1666 "IPv6 routing table\n")
1667{
1668 struct route_table *table;
1669 struct route_node *rn;
1670 struct rib *rib;
1671 int first = 1;
1672
1673 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
1674 if (! table)
1675 return CMD_SUCCESS;
1676
1677 /* Show all IPv6 route. */
1678 for (rn = route_top (table); rn; rn = route_next (rn))
1679 for (rib = rn->info; rib; rib = rib->next)
1680 {
1681 if (first)
1682 {
1683 vty_out (vty, SHOW_ROUTE_V6_HEADER, VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE);
1684 first = 0;
1685 }
1686 vty_show_ipv6_route (vty, rn, rib);
1687 }
1688 return CMD_SUCCESS;
1689}
1690
1691DEFUN (show_ipv6_route_prefix_longer,
1692 show_ipv6_route_prefix_longer_cmd,
1693 "show ipv6 route X:X::X:X/M longer-prefixes",
1694 SHOW_STR
1695 IP_STR
1696 "IPv6 routing table\n"
1697 "IPv6 prefix\n"
1698 "Show route matching the specified Network/Mask pair only\n")
1699{
1700 struct route_table *table;
1701 struct route_node *rn;
1702 struct rib *rib;
1703 struct prefix p;
1704 int ret;
1705 int first = 1;
1706
1707 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
1708 if (! table)
1709 return CMD_SUCCESS;
1710
1711 ret = str2prefix (argv[0], &p);
1712 if (! ret)
1713 {
1714 vty_out (vty, "%% Malformed Prefix%s", VTY_NEWLINE);
1715 return CMD_WARNING;
1716 }
1717
1718 /* Show matched type IPv6 routes. */
1719 for (rn = route_top (table); rn; rn = route_next (rn))
1720 for (rib = rn->info; rib; rib = rib->next)
1721 if (prefix_match (&p, &rn->p))
1722 {
1723 if (first)
1724 {
1725 vty_out (vty, SHOW_ROUTE_V6_HEADER, VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE);
1726 first = 0;
1727 }
1728 vty_show_ipv6_route (vty, rn, rib);
1729 }
1730 return CMD_SUCCESS;
1731}
1732
1733DEFUN (show_ipv6_route_protocol,
1734 show_ipv6_route_protocol_cmd,
1735 "show ipv6 route (bgp|connected|kernel|ospf6|ripng|static)",
1736 SHOW_STR
1737 IP_STR
1738 "IP routing table\n"
1739 "Border Gateway Protocol (BGP)\n"
1740 "Connected\n"
1741 "Kernel\n"
1742 "Open Shortest Path First (OSPFv3)\n"
jardin9e867fe2003-12-23 08:56:18 +00001743 "ISO IS-IS (ISIS)\n"
paul718e3742002-12-13 20:15:29 +00001744 "Routing Information Protocol (RIPng)\n"
1745 "Static routes\n")
1746{
1747 int type;
1748 struct route_table *table;
1749 struct route_node *rn;
1750 struct rib *rib;
1751 int first = 1;
1752
1753 if (strncmp (argv[0], "b", 1) == 0)
1754 type = ZEBRA_ROUTE_BGP;
1755 else if (strncmp (argv[0], "c", 1) == 0)
1756 type = ZEBRA_ROUTE_CONNECT;
1757 else if (strncmp (argv[0], "k", 1) ==0)
1758 type = ZEBRA_ROUTE_KERNEL;
1759 else if (strncmp (argv[0], "o", 1) == 0)
1760 type = ZEBRA_ROUTE_OSPF6;
jardin9e867fe2003-12-23 08:56:18 +00001761 else if (strncmp (argv[0], "i", 1) == 0)
1762 type = ZEBRA_ROUTE_ISIS;
paul718e3742002-12-13 20:15:29 +00001763 else if (strncmp (argv[0], "r", 1) == 0)
1764 type = ZEBRA_ROUTE_RIPNG;
1765 else if (strncmp (argv[0], "s", 1) == 0)
1766 type = ZEBRA_ROUTE_STATIC;
1767 else
1768 {
1769 vty_out (vty, "Unknown route type%s", VTY_NEWLINE);
1770 return CMD_WARNING;
1771 }
1772
1773 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
1774 if (! table)
1775 return CMD_SUCCESS;
1776
1777 /* Show matched type IPv6 routes. */
1778 for (rn = route_top (table); rn; rn = route_next (rn))
1779 for (rib = rn->info; rib; rib = rib->next)
1780 if (rib->type == type)
1781 {
1782 if (first)
1783 {
1784 vty_out (vty, SHOW_ROUTE_V6_HEADER, VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE);
1785 first = 0;
1786 }
1787 vty_show_ipv6_route (vty, rn, rib);
1788 }
1789 return CMD_SUCCESS;
1790}
1791
1792DEFUN (show_ipv6_route_addr,
1793 show_ipv6_route_addr_cmd,
1794 "show ipv6 route X:X::X:X",
1795 SHOW_STR
1796 IP_STR
1797 "IPv6 routing table\n"
1798 "IPv6 Address\n")
1799{
1800 int ret;
1801 struct prefix_ipv6 p;
1802 struct route_table *table;
1803 struct route_node *rn;
1804
1805 ret = str2prefix_ipv6 (argv[0], &p);
1806 if (ret <= 0)
1807 {
1808 vty_out (vty, "Malformed IPv6 address%s", VTY_NEWLINE);
1809 return CMD_WARNING;
1810 }
1811
1812 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
1813 if (! table)
1814 return CMD_SUCCESS;
1815
1816 rn = route_node_match (table, (struct prefix *) &p);
1817 if (! rn)
1818 {
1819 vty_out (vty, "%% Network not in table%s", VTY_NEWLINE);
1820 return CMD_WARNING;
1821 }
1822
1823 vty_show_ipv6_route_detail (vty, rn);
1824
1825 route_unlock_node (rn);
1826
1827 return CMD_SUCCESS;
1828}
1829
1830DEFUN (show_ipv6_route_prefix,
1831 show_ipv6_route_prefix_cmd,
1832 "show ipv6 route X:X::X:X/M",
1833 SHOW_STR
1834 IP_STR
1835 "IPv6 routing table\n"
1836 "IPv6 prefix\n")
1837{
1838 int ret;
1839 struct prefix_ipv6 p;
1840 struct route_table *table;
1841 struct route_node *rn;
1842
1843 ret = str2prefix_ipv6 (argv[0], &p);
1844 if (ret <= 0)
1845 {
1846 vty_out (vty, "Malformed IPv6 prefix%s", VTY_NEWLINE);
1847 return CMD_WARNING;
1848 }
1849
1850 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
1851 if (! table)
1852 return CMD_SUCCESS;
1853
1854 rn = route_node_match (table, (struct prefix *) &p);
1855 if (! rn || rn->p.prefixlen != p.prefixlen)
1856 {
1857 vty_out (vty, "%% Network not in table%s", VTY_NEWLINE);
1858 return CMD_WARNING;
1859 }
1860
1861 vty_show_ipv6_route_detail (vty, rn);
1862
1863 route_unlock_node (rn);
1864
1865 return CMD_SUCCESS;
1866}
1867
1868
1869/* Write IPv6 static route configuration. */
1870int
1871static_config_ipv6 (struct vty *vty)
1872{
1873 struct route_node *rn;
1874 struct static_ipv6 *si;
1875 int write;
1876 char buf[BUFSIZ];
1877 struct route_table *stable;
1878
1879 write = 0;
1880
1881 /* Lookup table. */
1882 stable = vrf_static_table (AFI_IP6, SAFI_UNICAST, 0);
1883 if (! stable)
1884 return -1;
1885
1886 for (rn = route_top (stable); rn; rn = route_next (rn))
1887 for (si = rn->info; si; si = si->next)
1888 {
1889 vty_out (vty, "ipv6 route %s/%d",
1890 inet_ntop (AF_INET6, &rn->p.u.prefix6, buf, BUFSIZ),
1891 rn->p.prefixlen);
1892
1893 switch (si->type)
1894 {
1895 case STATIC_IPV6_GATEWAY:
1896 vty_out (vty, " %s", inet_ntop (AF_INET6, &si->ipv6, buf, BUFSIZ));
1897 break;
1898 case STATIC_IPV6_IFNAME:
1899 vty_out (vty, " %s", si->ifname);
1900 break;
1901 case STATIC_IPV6_GATEWAY_IFNAME:
1902 vty_out (vty, " %s %s",
1903 inet_ntop (AF_INET6, &si->ipv6, buf, BUFSIZ), si->ifname);
1904 break;
1905 }
1906
hasso81dfcaa2003-05-25 19:21:25 +00001907 if (CHECK_FLAG(si->flags, ZEBRA_FLAG_REJECT))
1908 vty_out (vty, " %s", "reject");
1909
1910 if (CHECK_FLAG(si->flags, ZEBRA_FLAG_BLACKHOLE))
1911 vty_out (vty, " %s", "blackhole");
1912
paul718e3742002-12-13 20:15:29 +00001913 if (si->distance != ZEBRA_STATIC_DISTANCE_DEFAULT)
1914 vty_out (vty, " %d", si->distance);
1915 vty_out (vty, "%s", VTY_NEWLINE);
1916
1917 write = 1;
1918 }
1919 return write;
1920}
1921#endif /* HAVE_IPV6 */
1922
1923/* Static ip route configuration write function. */
1924int
1925zebra_ip_config (struct vty *vty)
1926{
1927 int write = 0;
1928
1929 write += static_config_ipv4 (vty);
1930#ifdef HAVE_IPV6
1931 write += static_config_ipv6 (vty);
1932#endif /* HAVE_IPV6 */
1933
1934 return write;
1935}
1936
1937/* IP node for static routes. */
1938struct cmd_node ip_node = { IP_NODE, "", 1 };
1939
1940/* Route VTY. */
1941void
1942zebra_vty_route_init ()
1943{
1944 install_node (&ip_node, zebra_ip_config);
1945
1946 install_element (CONFIG_NODE, &ip_route_cmd);
hasso81dfcaa2003-05-25 19:21:25 +00001947 install_element (CONFIG_NODE, &ip_route_flags_cmd);
hasso457ef552003-05-28 12:02:15 +00001948 install_element (CONFIG_NODE, &ip_route_flags2_cmd);
paul718e3742002-12-13 20:15:29 +00001949 install_element (CONFIG_NODE, &ip_route_mask_cmd);
hasso81dfcaa2003-05-25 19:21:25 +00001950 install_element (CONFIG_NODE, &ip_route_mask_flags_cmd);
hasso457ef552003-05-28 12:02:15 +00001951 install_element (CONFIG_NODE, &ip_route_mask_flags2_cmd);
paul718e3742002-12-13 20:15:29 +00001952 install_element (CONFIG_NODE, &no_ip_route_cmd);
hasso81dfcaa2003-05-25 19:21:25 +00001953 install_element (CONFIG_NODE, &no_ip_route_flags_cmd);
hasso457ef552003-05-28 12:02:15 +00001954 install_element (CONFIG_NODE, &no_ip_route_flags2_cmd);
paul718e3742002-12-13 20:15:29 +00001955 install_element (CONFIG_NODE, &no_ip_route_mask_cmd);
hasso81dfcaa2003-05-25 19:21:25 +00001956 install_element (CONFIG_NODE, &no_ip_route_mask_flags_cmd);
hasso457ef552003-05-28 12:02:15 +00001957 install_element (CONFIG_NODE, &no_ip_route_mask_flags2_cmd);
paul718e3742002-12-13 20:15:29 +00001958 install_element (CONFIG_NODE, &ip_route_distance_cmd);
hasso81dfcaa2003-05-25 19:21:25 +00001959 install_element (CONFIG_NODE, &ip_route_flags_distance_cmd);
hasso457ef552003-05-28 12:02:15 +00001960 install_element (CONFIG_NODE, &ip_route_flags_distance2_cmd);
paul718e3742002-12-13 20:15:29 +00001961 install_element (CONFIG_NODE, &ip_route_mask_distance_cmd);
hasso81dfcaa2003-05-25 19:21:25 +00001962 install_element (CONFIG_NODE, &ip_route_mask_flags_distance_cmd);
hasso457ef552003-05-28 12:02:15 +00001963 install_element (CONFIG_NODE, &ip_route_mask_flags_distance2_cmd);
paul718e3742002-12-13 20:15:29 +00001964 install_element (CONFIG_NODE, &no_ip_route_distance_cmd);
hasso81dfcaa2003-05-25 19:21:25 +00001965 install_element (CONFIG_NODE, &no_ip_route_flags_distance_cmd);
hasso457ef552003-05-28 12:02:15 +00001966 install_element (CONFIG_NODE, &no_ip_route_flags_distance2_cmd);
hasso81dfcaa2003-05-25 19:21:25 +00001967 install_element (CONFIG_NODE, &no_ip_route_mask_flags_distance_cmd);
hasso457ef552003-05-28 12:02:15 +00001968 install_element (CONFIG_NODE, &no_ip_route_mask_flags_distance2_cmd);
paul718e3742002-12-13 20:15:29 +00001969
1970 install_element (VIEW_NODE, &show_ip_route_cmd);
1971 install_element (VIEW_NODE, &show_ip_route_addr_cmd);
1972 install_element (VIEW_NODE, &show_ip_route_prefix_cmd);
1973 install_element (VIEW_NODE, &show_ip_route_prefix_longer_cmd);
1974 install_element (VIEW_NODE, &show_ip_route_protocol_cmd);
1975 install_element (VIEW_NODE, &show_ip_route_supernets_cmd);
1976 install_element (ENABLE_NODE, &show_ip_route_cmd);
1977 install_element (ENABLE_NODE, &show_ip_route_addr_cmd);
1978 install_element (ENABLE_NODE, &show_ip_route_prefix_cmd);
1979 install_element (ENABLE_NODE, &show_ip_route_prefix_longer_cmd);
1980 install_element (ENABLE_NODE, &show_ip_route_protocol_cmd);
1981 install_element (ENABLE_NODE, &show_ip_route_supernets_cmd);
1982
1983#if 0
1984 install_element (VIEW_NODE, &show_ip_route_summary_cmd);
1985 install_element (ENABLE_NODE, &show_ip_route_summary_cmd);
1986#endif /* 0 */
1987
1988#ifdef HAVE_IPV6
1989 install_element (CONFIG_NODE, &ipv6_route_cmd);
hasso81dfcaa2003-05-25 19:21:25 +00001990 install_element (CONFIG_NODE, &ipv6_route_flags_cmd);
paul718e3742002-12-13 20:15:29 +00001991 install_element (CONFIG_NODE, &ipv6_route_ifname_cmd);
hasso81dfcaa2003-05-25 19:21:25 +00001992 install_element (CONFIG_NODE, &ipv6_route_ifname_flags_cmd);
paul718e3742002-12-13 20:15:29 +00001993 install_element (CONFIG_NODE, &no_ipv6_route_cmd);
hasso81dfcaa2003-05-25 19:21:25 +00001994 install_element (CONFIG_NODE, &no_ipv6_route_flags_cmd);
paul718e3742002-12-13 20:15:29 +00001995 install_element (CONFIG_NODE, &no_ipv6_route_ifname_cmd);
hasso81dfcaa2003-05-25 19:21:25 +00001996 install_element (CONFIG_NODE, &no_ipv6_route_ifname_flags_cmd);
paul718e3742002-12-13 20:15:29 +00001997 install_element (CONFIG_NODE, &ipv6_route_pref_cmd);
hasso81dfcaa2003-05-25 19:21:25 +00001998 install_element (CONFIG_NODE, &ipv6_route_flags_pref_cmd);
paul718e3742002-12-13 20:15:29 +00001999 install_element (CONFIG_NODE, &ipv6_route_ifname_pref_cmd);
hasso81dfcaa2003-05-25 19:21:25 +00002000 install_element (CONFIG_NODE, &ipv6_route_ifname_flags_pref_cmd);
paul718e3742002-12-13 20:15:29 +00002001 install_element (CONFIG_NODE, &no_ipv6_route_pref_cmd);
hasso81dfcaa2003-05-25 19:21:25 +00002002 install_element (CONFIG_NODE, &no_ipv6_route_flags_pref_cmd);
paul718e3742002-12-13 20:15:29 +00002003 install_element (CONFIG_NODE, &no_ipv6_route_ifname_pref_cmd);
hasso81dfcaa2003-05-25 19:21:25 +00002004 install_element (CONFIG_NODE, &no_ipv6_route_ifname_flags_pref_cmd);
paul718e3742002-12-13 20:15:29 +00002005 install_element (VIEW_NODE, &show_ipv6_route_cmd);
2006 install_element (VIEW_NODE, &show_ipv6_route_protocol_cmd);
2007 install_element (VIEW_NODE, &show_ipv6_route_addr_cmd);
2008 install_element (VIEW_NODE, &show_ipv6_route_prefix_cmd);
2009 install_element (VIEW_NODE, &show_ipv6_route_prefix_longer_cmd);
2010 install_element (ENABLE_NODE, &show_ipv6_route_cmd);
2011 install_element (ENABLE_NODE, &show_ipv6_route_protocol_cmd);
2012 install_element (ENABLE_NODE, &show_ipv6_route_addr_cmd);
2013 install_element (ENABLE_NODE, &show_ipv6_route_prefix_cmd);
2014 install_element (ENABLE_NODE, &show_ipv6_route_prefix_longer_cmd);
2015#endif /* HAVE_IPV6 */
2016}
2017
2018void
2019zebra_vty_init ()
2020{
2021 zebra_vty_route_init ();
2022}