blob: 044448e13cd265eed5508b03cca90907caff741e [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
94zebra_static_ipv4 (struct vty *vty, int add_cmd,
95 char *dest_str, char *mask_str, char *gate_str,
hasso81dfcaa2003-05-25 19:21:25 +000096 char *flag_str, 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;
103 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
jardin9e867fe2003-12-23 08:56:18 +0000757#define SHOW_ROUTE_V4_HEADER "Codes: K - kernel route, C - connected, S - static, R - RIP, O - OSPF,%s I - ISIS, B - BGP, > - selected route, * - FIB route%s%s"
paul718e3742002-12-13 20:15:29 +0000758
759DEFUN (show_ip_route,
760 show_ip_route_cmd,
761 "show ip route",
762 SHOW_STR
763 IP_STR
764 "IP routing table\n")
765{
766 struct route_table *table;
767 struct route_node *rn;
768 struct rib *rib;
769 int first = 1;
770
771 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
772 if (! table)
773 return CMD_SUCCESS;
774
775 /* Show all IPv4 routes. */
776 for (rn = route_top (table); rn; rn = route_next (rn))
777 for (rib = rn->info; rib; rib = rib->next)
778 {
779 if (first)
780 {
781 vty_out (vty, SHOW_ROUTE_V4_HEADER, VTY_NEWLINE, VTY_NEWLINE,
782 VTY_NEWLINE);
783 first = 0;
784 }
785 vty_show_ip_route (vty, rn, rib);
786 }
787 return CMD_SUCCESS;
788}
789
790DEFUN (show_ip_route_prefix_longer,
791 show_ip_route_prefix_longer_cmd,
792 "show ip route A.B.C.D/M longer-prefixes",
793 SHOW_STR
794 IP_STR
795 "IP routing table\n"
796 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
797 "Show route matching the specified Network/Mask pair only\n")
798{
799 struct route_table *table;
800 struct route_node *rn;
801 struct rib *rib;
802 struct prefix p;
803 int ret;
804 int first = 1;
805
806 ret = str2prefix (argv[0], &p);
807 if (! ret)
808 {
809 vty_out (vty, "%% Malformed Prefix%s", VTY_NEWLINE);
810 return CMD_WARNING;
811 }
812
813 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
814 if (! table)
815 return CMD_SUCCESS;
816
817 /* Show matched type IPv4 routes. */
818 for (rn = route_top (table); rn; rn = route_next (rn))
819 for (rib = rn->info; rib; rib = rib->next)
820 if (prefix_match (&p, &rn->p))
821 {
822 if (first)
823 {
824 vty_out (vty, SHOW_ROUTE_V4_HEADER, VTY_NEWLINE,
825 VTY_NEWLINE, VTY_NEWLINE);
826 first = 0;
827 }
828 vty_show_ip_route (vty, rn, rib);
829 }
830 return CMD_SUCCESS;
831}
832
833DEFUN (show_ip_route_supernets,
834 show_ip_route_supernets_cmd,
835 "show ip route supernets-only",
836 SHOW_STR
837 IP_STR
838 "IP routing table\n"
839 "Show supernet entries only\n")
840{
841 struct route_table *table;
842 struct route_node *rn;
843 struct rib *rib;
844 u_int32_t addr;
845 int first = 1;
846
847 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
848 if (! table)
849 return CMD_SUCCESS;
850
851 /* Show matched type IPv4 routes. */
852 for (rn = route_top (table); rn; rn = route_next (rn))
853 for (rib = rn->info; rib; rib = rib->next)
854 {
855 addr = ntohl (rn->p.u.prefix4.s_addr);
856
857 if ((IN_CLASSC (addr) && rn->p.prefixlen < 24)
858 || (IN_CLASSB (addr) && rn->p.prefixlen < 16)
859 || (IN_CLASSA (addr) && rn->p.prefixlen < 8))
860 {
861 if (first)
862 {
863 vty_out (vty, SHOW_ROUTE_V4_HEADER, VTY_NEWLINE,
864 VTY_NEWLINE, VTY_NEWLINE);
865 first = 0;
866 }
867 vty_show_ip_route (vty, rn, rib);
868 }
869 }
870 return CMD_SUCCESS;
871}
872
873DEFUN (show_ip_route_protocol,
874 show_ip_route_protocol_cmd,
hasso39ff11d2004-10-12 15:55:19 +0000875 "show ip route (bgp|connected|isis|kernel|ospf|rip|static)",
paul718e3742002-12-13 20:15:29 +0000876 SHOW_STR
877 IP_STR
878 "IP routing table\n"
879 "Border Gateway Protocol (BGP)\n"
880 "Connected\n"
hasso39ff11d2004-10-12 15:55:19 +0000881 "ISO IS-IS (ISIS)\n"
paul718e3742002-12-13 20:15:29 +0000882 "Kernel\n"
883 "Open Shortest Path First (OSPF)\n"
884 "Routing Information Protocol (RIP)\n"
885 "Static routes\n")
886{
887 int type;
888 struct route_table *table;
889 struct route_node *rn;
890 struct rib *rib;
891 int first = 1;
892
893 if (strncmp (argv[0], "b", 1) == 0)
894 type = ZEBRA_ROUTE_BGP;
895 else if (strncmp (argv[0], "c", 1) == 0)
896 type = ZEBRA_ROUTE_CONNECT;
897 else if (strncmp (argv[0], "k", 1) ==0)
898 type = ZEBRA_ROUTE_KERNEL;
899 else if (strncmp (argv[0], "o", 1) == 0)
900 type = ZEBRA_ROUTE_OSPF;
jardin9e867fe2003-12-23 08:56:18 +0000901 else if (strncmp (argv[0], "i", 1) == 0)
902 type = ZEBRA_ROUTE_ISIS;
paul718e3742002-12-13 20:15:29 +0000903 else if (strncmp (argv[0], "r", 1) == 0)
904 type = ZEBRA_ROUTE_RIP;
905 else if (strncmp (argv[0], "s", 1) == 0)
906 type = ZEBRA_ROUTE_STATIC;
907 else
908 {
909 vty_out (vty, "Unknown route type%s", VTY_NEWLINE);
910 return CMD_WARNING;
911 }
912
913 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
914 if (! table)
915 return CMD_SUCCESS;
916
917 /* Show matched type IPv4 routes. */
918 for (rn = route_top (table); rn; rn = route_next (rn))
919 for (rib = rn->info; rib; rib = rib->next)
920 if (rib->type == type)
921 {
922 if (first)
923 {
924 vty_out (vty, SHOW_ROUTE_V4_HEADER,
925 VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE);
926 first = 0;
927 }
928 vty_show_ip_route (vty, rn, rib);
929 }
930 return CMD_SUCCESS;
931}
932
933DEFUN (show_ip_route_addr,
934 show_ip_route_addr_cmd,
935 "show ip route A.B.C.D",
936 SHOW_STR
937 IP_STR
938 "IP routing table\n"
939 "Network in the IP routing table to display\n")
940{
941 int ret;
942 struct prefix_ipv4 p;
943 struct route_table *table;
944 struct route_node *rn;
945
946 ret = str2prefix_ipv4 (argv[0], &p);
947 if (ret <= 0)
948 {
949 vty_out (vty, "%% Malformed IPv4 address%s", VTY_NEWLINE);
950 return CMD_WARNING;
951 }
952
953 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
954 if (! table)
955 return CMD_SUCCESS;
956
957 rn = route_node_match (table, (struct prefix *) &p);
958 if (! rn)
959 {
960 vty_out (vty, "%% Network not in table%s", VTY_NEWLINE);
961 return CMD_WARNING;
962 }
963
964 vty_show_ip_route_detail (vty, rn);
965
966 route_unlock_node (rn);
967
968 return CMD_SUCCESS;
969}
970
971DEFUN (show_ip_route_prefix,
972 show_ip_route_prefix_cmd,
973 "show ip route A.B.C.D/M",
974 SHOW_STR
975 IP_STR
976 "IP routing table\n"
977 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n")
978{
979 int ret;
980 struct prefix_ipv4 p;
981 struct route_table *table;
982 struct route_node *rn;
983
984 ret = str2prefix_ipv4 (argv[0], &p);
985 if (ret <= 0)
986 {
987 vty_out (vty, "%% Malformed IPv4 address%s", VTY_NEWLINE);
988 return CMD_WARNING;
989 }
990
991 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
992 if (! table)
993 return CMD_SUCCESS;
994
995 rn = route_node_match (table, (struct prefix *) &p);
996 if (! rn || rn->p.prefixlen != p.prefixlen)
997 {
998 vty_out (vty, "%% Network not in table%s", VTY_NEWLINE);
999 return CMD_WARNING;
1000 }
1001
1002 vty_show_ip_route_detail (vty, rn);
1003
1004 route_unlock_node (rn);
1005
1006 return CMD_SUCCESS;
1007}
1008
1009void
1010zebra_show_ip_route (struct vty *vty, struct vrf *vrf)
1011{
1012 vty_out (vty, "IP routing table name is %s(%d)%s",
1013 vrf->name ? vrf->name : "", vrf->id, VTY_NEWLINE);
1014
1015 vty_out (vty, "Route Source Networks%s", VTY_NEWLINE);
1016 vty_out (vty, "connected %d%s", 0, VTY_NEWLINE);
1017 vty_out (vty, "static %d%s", 0, VTY_NEWLINE);
1018 vty_out (vty, "rip %d%s", 0, VTY_NEWLINE);
1019
1020 vty_out (vty, "bgp %d%s", 0, VTY_NEWLINE);
1021 vty_out (vty, " External: %d Internal: %d Local: %d%s",
1022 0, 0, 0, VTY_NEWLINE);
1023
1024 vty_out (vty, "ospf %d%s", 0, VTY_NEWLINE);
1025 vty_out (vty,
1026 " Intra-area: %d Inter-area: %d External-1: %d External-2: %d%s",
1027 0, 0, 0, 0, VTY_NEWLINE);
1028 vty_out (vty, " NSSA External-1: %d NSSA External-2: %d%s",
1029 0, 0, VTY_NEWLINE);
1030
1031 vty_out (vty, "internal %d%s", 0, VTY_NEWLINE);
1032 vty_out (vty, "Total %d%s", 0, VTY_NEWLINE);
1033}
1034
1035/* Show route summary. */
1036DEFUN (show_ip_route_summary,
1037 show_ip_route_summary_cmd,
1038 "show ip route summary",
1039 SHOW_STR
1040 IP_STR
1041 "IP routing table\n"
1042 "Summary of all routes\n")
1043{
1044 struct vrf *vrf;
1045
1046 /* Default table id is zero. */
1047 vrf = vrf_lookup (0);
1048 if (! vrf)
1049 {
1050 vty_out (vty, "%% No Default-IP-Routing-Table%s", VTY_NEWLINE);
1051 return CMD_WARNING;
1052 }
1053
1054 zebra_show_ip_route (vty, vrf);
1055
1056 return CMD_SUCCESS;
1057}
1058
1059/* Write IPv4 static route configuration. */
1060int
1061static_config_ipv4 (struct vty *vty)
1062{
1063 struct route_node *rn;
1064 struct static_ipv4 *si;
1065 struct route_table *stable;
1066 int write;
1067
1068 write = 0;
1069
1070 /* Lookup table. */
1071 stable = vrf_static_table (AFI_IP, SAFI_UNICAST, 0);
1072 if (! stable)
1073 return -1;
1074
1075 for (rn = route_top (stable); rn; rn = route_next (rn))
1076 for (si = rn->info; si; si = si->next)
1077 {
paul7021c422003-07-15 12:52:22 +00001078 vty_out (vty, "ip route %s/%d", inet_ntoa (rn->p.u.prefix4),
1079 rn->p.prefixlen);
paul718e3742002-12-13 20:15:29 +00001080
paul7021c422003-07-15 12:52:22 +00001081 switch (si->type)
1082 {
1083 case STATIC_IPV4_GATEWAY:
1084 vty_out (vty, " %s", inet_ntoa (si->gate.ipv4));
1085 break;
1086 case STATIC_IPV4_IFNAME:
1087 vty_out (vty, " %s", si->gate.ifname);
1088 break;
1089 case STATIC_IPV4_BLACKHOLE:
1090 vty_out (vty, " Null0");
1091 break;
1092 }
1093
1094 /* flags are incompatible with STATIC_IPV4_BLACKHOLE */
1095 if (si->type != STATIC_IPV4_BLACKHOLE)
1096 {
1097 if (CHECK_FLAG(si->flags, ZEBRA_FLAG_REJECT))
1098 vty_out (vty, " %s", "reject");
paul718e3742002-12-13 20:15:29 +00001099
paul7021c422003-07-15 12:52:22 +00001100 if (CHECK_FLAG(si->flags, ZEBRA_FLAG_BLACKHOLE))
1101 vty_out (vty, " %s", "blackhole");
1102 }
hasso81dfcaa2003-05-25 19:21:25 +00001103
paul7021c422003-07-15 12:52:22 +00001104 if (si->distance != ZEBRA_STATIC_DISTANCE_DEFAULT)
1105 vty_out (vty, " %d", si->distance);
hasso81dfcaa2003-05-25 19:21:25 +00001106
paul7021c422003-07-15 12:52:22 +00001107 vty_out (vty, "%s", VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00001108
paul7021c422003-07-15 12:52:22 +00001109 write = 1;
paul718e3742002-12-13 20:15:29 +00001110 }
1111 return write;
1112}
1113
1114#ifdef HAVE_IPV6
1115/* General fucntion for IPv6 static route. */
1116int
1117static_ipv6_func (struct vty *vty, int add_cmd, char *dest_str,
hasso81dfcaa2003-05-25 19:21:25 +00001118 char *gate_str, char *ifname, char *flag_str, char *distance_str)
paul718e3742002-12-13 20:15:29 +00001119{
1120 int ret;
1121 u_char distance;
1122 struct prefix p;
1123 struct in6_addr *gate = NULL;
1124 struct in6_addr gate_addr;
1125 u_char type = 0;
1126 int table = 0;
hasso81dfcaa2003-05-25 19:21:25 +00001127 u_char flag = 0;
paul718e3742002-12-13 20:15:29 +00001128
1129 ret = str2prefix (dest_str, &p);
1130 if (ret <= 0)
1131 {
1132 vty_out (vty, "%% Malformed address%s", VTY_NEWLINE);
1133 return CMD_WARNING;
1134 }
1135
1136 /* Apply mask for given prefix. */
1137 apply_mask (&p);
1138
hasso81dfcaa2003-05-25 19:21:25 +00001139 /* Route flags */
1140 if (flag_str) {
1141 switch(flag_str[0]) {
1142 case 'r':
1143 case 'R': /* XXX */
1144 SET_FLAG (flag, ZEBRA_FLAG_REJECT);
1145 break;
1146 case 'b':
1147 case 'B': /* XXX */
1148 SET_FLAG (flag, ZEBRA_FLAG_BLACKHOLE);
1149 break;
1150 default:
1151 vty_out (vty, "%% Malformed flag %s %s", flag_str, VTY_NEWLINE);
paul595db7f2003-05-25 21:35:06 +00001152 return CMD_WARNING;
hasso81dfcaa2003-05-25 19:21:25 +00001153 }
1154 }
1155
paul718e3742002-12-13 20:15:29 +00001156 /* Administrative distance. */
1157 if (distance_str)
1158 distance = atoi (distance_str);
1159 else
1160 distance = ZEBRA_STATIC_DISTANCE_DEFAULT;
1161
1162 /* When gateway is valid IPv6 addrees, then gate is treated as
1163 nexthop address other case gate is treated as interface name. */
1164 ret = inet_pton (AF_INET6, gate_str, &gate_addr);
1165
1166 if (ifname)
1167 {
1168 /* When ifname is specified. It must be come with gateway
1169 address. */
1170 if (ret != 1)
1171 {
1172 vty_out (vty, "%% Malformed address%s", VTY_NEWLINE);
1173 return CMD_WARNING;
1174 }
1175 type = STATIC_IPV6_GATEWAY_IFNAME;
1176 gate = &gate_addr;
1177 }
1178 else
1179 {
1180 if (ret == 1)
1181 {
1182 type = STATIC_IPV6_GATEWAY;
1183 gate = &gate_addr;
1184 }
1185 else
1186 {
1187 type = STATIC_IPV6_IFNAME;
1188 ifname = gate_str;
1189 }
1190 }
1191
1192 if (add_cmd)
hasso81dfcaa2003-05-25 19:21:25 +00001193 static_add_ipv6 (&p, type, gate, ifname, flag, distance, table);
paul718e3742002-12-13 20:15:29 +00001194 else
1195 static_delete_ipv6 (&p, type, gate, ifname, distance, table);
1196
1197 return CMD_SUCCESS;
1198}
1199
1200DEFUN (ipv6_route,
1201 ipv6_route_cmd,
1202 "ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE)",
1203 IP_STR
1204 "Establish static routes\n"
1205 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1206 "IPv6 gateway address\n"
1207 "IPv6 gateway interface name\n")
1208{
hasso81dfcaa2003-05-25 19:21:25 +00001209 return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, NULL, NULL);
1210}
1211
1212DEFUN (ipv6_route_flags,
1213 ipv6_route_flags_cmd,
1214 "ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) (reject|blackhole)",
1215 IP_STR
1216 "Establish static routes\n"
1217 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1218 "IPv6 gateway address\n"
1219 "IPv6 gateway interface name\n"
1220 "Emit an ICMP unreachable when matched\n"
1221 "Silently discard pkts when matched\n")
1222{
1223 return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, argv[2], NULL);
paul718e3742002-12-13 20:15:29 +00001224}
1225
1226DEFUN (ipv6_route_ifname,
1227 ipv6_route_ifname_cmd,
1228 "ipv6 route X:X::X:X/M X:X::X:X INTERFACE",
1229 IP_STR
1230 "Establish static routes\n"
1231 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1232 "IPv6 gateway address\n"
1233 "IPv6 gateway interface name\n")
1234{
hasso81dfcaa2003-05-25 19:21:25 +00001235 return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], NULL, NULL);
1236}
1237
1238DEFUN (ipv6_route_ifname_flags,
1239 ipv6_route_ifname_flags_cmd,
1240 "ipv6 route X:X::X:X/M X:X::X:X INTERFACE (reject|blackhole)",
1241 IP_STR
1242 "Establish static routes\n"
1243 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1244 "IPv6 gateway address\n"
1245 "IPv6 gateway interface name\n"
1246 "Emit an ICMP unreachable when matched\n"
1247 "Silently discard pkts when matched\n")
1248{
1249 return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], argv[3], NULL);
paul718e3742002-12-13 20:15:29 +00001250}
1251
1252DEFUN (ipv6_route_pref,
1253 ipv6_route_pref_cmd,
1254 "ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) <1-255>",
1255 IP_STR
1256 "Establish static routes\n"
1257 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1258 "IPv6 gateway address\n"
1259 "IPv6 gateway interface name\n"
1260 "Distance value for this prefix\n")
1261{
hasso81dfcaa2003-05-25 19:21:25 +00001262 return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, NULL, argv[2]);
1263}
1264
1265DEFUN (ipv6_route_flags_pref,
1266 ipv6_route_flags_pref_cmd,
1267 "ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) (reject|blackhole) <1-255>",
1268 IP_STR
1269 "Establish static routes\n"
1270 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1271 "IPv6 gateway address\n"
1272 "IPv6 gateway interface name\n"
1273 "Emit an ICMP unreachable when matched\n"
1274 "Silently discard pkts when matched\n"
1275 "Distance value for this prefix\n")
1276{
1277 return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, argv[2], argv[3]);
paul718e3742002-12-13 20:15:29 +00001278}
1279
1280DEFUN (ipv6_route_ifname_pref,
1281 ipv6_route_ifname_pref_cmd,
1282 "ipv6 route X:X::X:X/M X:X::X:X INTERFACE <1-255>",
1283 IP_STR
1284 "Establish static routes\n"
1285 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1286 "IPv6 gateway address\n"
1287 "IPv6 gateway interface name\n"
1288 "Distance value for this prefix\n")
1289{
hasso81dfcaa2003-05-25 19:21:25 +00001290 return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], NULL, argv[3]);
1291}
1292
1293DEFUN (ipv6_route_ifname_flags_pref,
1294 ipv6_route_ifname_flags_pref_cmd,
1295 "ipv6 route X:X::X:X/M X:X::X:X INTERFACE (reject|blackhole) <1-255>",
1296 IP_STR
1297 "Establish static routes\n"
1298 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1299 "IPv6 gateway address\n"
1300 "IPv6 gateway interface name\n"
1301 "Emit an ICMP unreachable when matched\n"
1302 "Silently discard pkts when matched\n"
1303 "Distance value for this prefix\n")
1304{
1305 return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], argv[3], argv[4]);
paul718e3742002-12-13 20:15:29 +00001306}
1307
1308DEFUN (no_ipv6_route,
1309 no_ipv6_route_cmd,
1310 "no ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE)",
1311 NO_STR
1312 IP_STR
1313 "Establish static routes\n"
1314 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1315 "IPv6 gateway address\n"
1316 "IPv6 gateway interface name\n")
1317{
hasso81dfcaa2003-05-25 19:21:25 +00001318 return static_ipv6_func (vty, 0, argv[0], argv[1], NULL, NULL, NULL);
paul718e3742002-12-13 20:15:29 +00001319}
1320
hasso81dfcaa2003-05-25 19:21:25 +00001321ALIAS (no_ipv6_route,
1322 no_ipv6_route_flags_cmd,
1323 "no ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) (reject|blackhole)",
1324 NO_STR
1325 IP_STR
1326 "Establish static routes\n"
1327 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1328 "IPv6 gateway address\n"
1329 "IPv6 gateway interface name\n"
1330 "Emit an ICMP unreachable when matched\n"
1331 "Silently discard pkts when matched\n")
1332
paul718e3742002-12-13 20:15:29 +00001333DEFUN (no_ipv6_route_ifname,
1334 no_ipv6_route_ifname_cmd,
1335 "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE",
1336 NO_STR
1337 IP_STR
1338 "Establish static routes\n"
1339 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1340 "IPv6 gateway address\n"
1341 "IPv6 gateway interface name\n")
1342{
hasso81dfcaa2003-05-25 19:21:25 +00001343 return static_ipv6_func (vty, 0, argv[0], argv[1], argv[2], NULL, NULL);
paul718e3742002-12-13 20:15:29 +00001344}
1345
hasso81dfcaa2003-05-25 19:21:25 +00001346ALIAS (no_ipv6_route_ifname,
1347 no_ipv6_route_ifname_flags_cmd,
1348 "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE (reject|blackhole)",
1349 NO_STR
1350 IP_STR
1351 "Establish static routes\n"
1352 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1353 "IPv6 gateway address\n"
1354 "IPv6 gateway interface name\n"
1355 "Emit an ICMP unreachable when matched\n"
1356 "Silently discard pkts when matched\n")
1357
paul718e3742002-12-13 20:15:29 +00001358DEFUN (no_ipv6_route_pref,
1359 no_ipv6_route_pref_cmd,
1360 "no ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) <1-255>",
1361 NO_STR
1362 IP_STR
1363 "Establish static routes\n"
1364 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1365 "IPv6 gateway address\n"
1366 "IPv6 gateway interface name\n"
1367 "Distance value for this prefix\n")
1368{
hasso81dfcaa2003-05-25 19:21:25 +00001369 return static_ipv6_func (vty, 0, argv[0], argv[1], NULL, NULL, argv[2]);
1370}
1371
1372DEFUN (no_ipv6_route_flags_pref,
1373 no_ipv6_route_flags_pref_cmd,
1374 "no ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) (reject|blackhole) <1-255>",
1375 NO_STR
1376 IP_STR
1377 "Establish static routes\n"
1378 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1379 "IPv6 gateway address\n"
1380 "IPv6 gateway interface name\n"
1381 "Emit an ICMP unreachable when matched\n"
1382 "Silently discard pkts when matched\n"
1383 "Distance value for this prefix\n")
1384{
1385 /* We do not care about argv[2] */
1386 return static_ipv6_func (vty, 0, argv[0], argv[1], NULL, argv[2], argv[3]);
paul718e3742002-12-13 20:15:29 +00001387}
1388
1389DEFUN (no_ipv6_route_ifname_pref,
1390 no_ipv6_route_ifname_pref_cmd,
1391 "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE <1-255>",
1392 NO_STR
1393 IP_STR
1394 "Establish static routes\n"
1395 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1396 "IPv6 gateway address\n"
1397 "IPv6 gateway interface name\n"
1398 "Distance value for this prefix\n")
1399{
hasso81dfcaa2003-05-25 19:21:25 +00001400 return static_ipv6_func (vty, 0, argv[0], argv[1], argv[2], NULL, argv[3]);
1401}
1402
1403DEFUN (no_ipv6_route_ifname_flags_pref,
1404 no_ipv6_route_ifname_flags_pref_cmd,
1405 "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE (reject|blackhole) <1-255>",
1406 NO_STR
1407 IP_STR
1408 "Establish static routes\n"
1409 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1410 "IPv6 gateway address\n"
1411 "IPv6 gateway interface name\n"
1412 "Emit an ICMP unreachable when matched\n"
1413 "Silently discard pkts when matched\n"
1414 "Distance value for this prefix\n")
1415{
1416 return static_ipv6_func (vty, 0, argv[0], argv[1], argv[2], argv[3], argv[4]);
paul718e3742002-12-13 20:15:29 +00001417}
1418
paul595db7f2003-05-25 21:35:06 +00001419/* New RIB. Detailed information for IPv6 route. */
paul718e3742002-12-13 20:15:29 +00001420void
1421vty_show_ipv6_route_detail (struct vty *vty, struct route_node *rn)
1422{
1423 struct rib *rib;
1424 struct nexthop *nexthop;
1425 char buf[BUFSIZ];
1426
1427 for (rib = rn->info; rib; rib = rib->next)
1428 {
1429 vty_out (vty, "Routing entry for %s/%d%s",
1430 inet_ntop (AF_INET6, &rn->p.u.prefix6, buf, BUFSIZ),
1431 rn->p.prefixlen,
1432 VTY_NEWLINE);
1433 vty_out (vty, " Known via \"%s\"", route_type_str (rib->type));
1434 vty_out (vty, ", distance %d, metric %d", rib->distance, rib->metric);
1435 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
1436 vty_out (vty, ", best");
1437 if (rib->refcnt)
1438 vty_out (vty, ", refcnt %ld", rib->refcnt);
hasso81dfcaa2003-05-25 19:21:25 +00001439 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_BLACKHOLE))
1440 vty_out (vty, ", blackhole");
1441 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_REJECT))
1442 vty_out (vty, ", reject");
paul718e3742002-12-13 20:15:29 +00001443 vty_out (vty, "%s", VTY_NEWLINE);
1444
1445#define ONE_DAY_SECOND 60*60*24
1446#define ONE_WEEK_SECOND 60*60*24*7
1447 if (rib->type == ZEBRA_ROUTE_RIPNG
1448 || rib->type == ZEBRA_ROUTE_OSPF6
jardin9e867fe2003-12-23 08:56:18 +00001449 || rib->type == ZEBRA_ROUTE_ISIS
paul718e3742002-12-13 20:15:29 +00001450 || rib->type == ZEBRA_ROUTE_BGP)
1451 {
1452 time_t uptime;
1453 struct tm *tm;
1454
1455 uptime = time (NULL);
1456 uptime -= rib->uptime;
1457 tm = gmtime (&uptime);
1458
1459 vty_out (vty, " Last update ");
1460
1461 if (uptime < ONE_DAY_SECOND)
1462 vty_out (vty, "%02d:%02d:%02d",
1463 tm->tm_hour, tm->tm_min, tm->tm_sec);
1464 else if (uptime < ONE_WEEK_SECOND)
1465 vty_out (vty, "%dd%02dh%02dm",
1466 tm->tm_yday, tm->tm_hour, tm->tm_min);
1467 else
1468 vty_out (vty, "%02dw%dd%02dh",
1469 tm->tm_yday/7,
1470 tm->tm_yday - ((tm->tm_yday/7) * 7), tm->tm_hour);
1471 vty_out (vty, " ago%s", VTY_NEWLINE);
1472 }
1473
1474 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1475 {
1476 vty_out (vty, " %c",
1477 CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB) ? '*' : ' ');
1478
1479 switch (nexthop->type)
1480 {
1481 case NEXTHOP_TYPE_IPV6:
1482 case NEXTHOP_TYPE_IPV6_IFINDEX:
1483 case NEXTHOP_TYPE_IPV6_IFNAME:
1484 vty_out (vty, " %s",
1485 inet_ntop (AF_INET6, &nexthop->gate.ipv6, buf, BUFSIZ));
1486 if (nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME)
1487 vty_out (vty, ", %s", nexthop->ifname);
1488 else if (nexthop->ifindex)
1489 vty_out (vty, ", via %s", ifindex2ifname (nexthop->ifindex));
1490 break;
1491 case NEXTHOP_TYPE_IFINDEX:
1492 vty_out (vty, " directly connected, %s",
1493 ifindex2ifname (nexthop->ifindex));
1494 break;
1495 case NEXTHOP_TYPE_IFNAME:
1496 vty_out (vty, " directly connected, %s",
1497 nexthop->ifname);
1498 break;
1499 default:
1500 break;
1501 }
1502 if (! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
1503 vty_out (vty, " inactive");
1504
1505 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
1506 {
1507 vty_out (vty, " (recursive");
1508
1509 switch (nexthop->rtype)
1510 {
1511 case NEXTHOP_TYPE_IPV6:
1512 case NEXTHOP_TYPE_IPV6_IFINDEX:
1513 case NEXTHOP_TYPE_IPV6_IFNAME:
1514 vty_out (vty, " via %s)",
1515 inet_ntop (AF_INET6, &nexthop->rgate.ipv6,
1516 buf, BUFSIZ));
1517 if (nexthop->rifindex)
1518 vty_out (vty, ", %s", ifindex2ifname (nexthop->rifindex));
1519 break;
1520 case NEXTHOP_TYPE_IFINDEX:
1521 case NEXTHOP_TYPE_IFNAME:
1522 vty_out (vty, " is directly connected, %s)",
1523 ifindex2ifname (nexthop->rifindex));
1524 break;
1525 default:
1526 break;
1527 }
1528 }
1529 vty_out (vty, "%s", VTY_NEWLINE);
1530 }
1531 vty_out (vty, "%s", VTY_NEWLINE);
1532 }
1533}
1534
1535void
1536vty_show_ipv6_route (struct vty *vty, struct route_node *rn,
1537 struct rib *rib)
1538{
1539 struct nexthop *nexthop;
1540 int len = 0;
1541 char buf[BUFSIZ];
1542
1543 /* Nexthop information. */
1544 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1545 {
1546 if (nexthop == rib->nexthop)
1547 {
1548 /* Prefix information. */
1549 len = vty_out (vty, "%c%c%c %s/%d",
1550 route_type_char (rib->type),
1551 CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED)
1552 ? '>' : ' ',
1553 CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)
1554 ? '*' : ' ',
1555 inet_ntop (AF_INET6, &rn->p.u.prefix6, buf, BUFSIZ),
1556 rn->p.prefixlen);
1557
1558 /* Distance and metric display. */
1559 if (rib->type != ZEBRA_ROUTE_CONNECT
1560 && rib->type != ZEBRA_ROUTE_KERNEL)
1561 len += vty_out (vty, " [%d/%d]", rib->distance,
1562 rib->metric);
1563 }
1564 else
1565 vty_out (vty, " %c%*c",
1566 CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)
1567 ? '*' : ' ',
1568 len - 3, ' ');
1569
1570 switch (nexthop->type)
1571 {
1572 case NEXTHOP_TYPE_IPV6:
1573 case NEXTHOP_TYPE_IPV6_IFINDEX:
1574 case NEXTHOP_TYPE_IPV6_IFNAME:
1575 vty_out (vty, " via %s",
1576 inet_ntop (AF_INET6, &nexthop->gate.ipv6, buf, BUFSIZ));
1577 if (nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME)
1578 vty_out (vty, ", %s", nexthop->ifname);
1579 else if (nexthop->ifindex)
1580 vty_out (vty, ", %s", ifindex2ifname (nexthop->ifindex));
1581 break;
1582 case NEXTHOP_TYPE_IFINDEX:
1583 vty_out (vty, " is directly connected, %s",
1584 ifindex2ifname (nexthop->ifindex));
1585 break;
1586 case NEXTHOP_TYPE_IFNAME:
1587 vty_out (vty, " is directly connected, %s",
1588 nexthop->ifname);
1589 break;
1590 default:
1591 break;
1592 }
1593 if (! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
1594 vty_out (vty, " inactive");
1595
1596 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
1597 {
1598 vty_out (vty, " (recursive");
1599
1600 switch (nexthop->rtype)
1601 {
1602 case NEXTHOP_TYPE_IPV6:
1603 case NEXTHOP_TYPE_IPV6_IFINDEX:
1604 case NEXTHOP_TYPE_IPV6_IFNAME:
1605 vty_out (vty, " via %s)",
1606 inet_ntop (AF_INET6, &nexthop->rgate.ipv6,
1607 buf, BUFSIZ));
1608 if (nexthop->rifindex)
1609 vty_out (vty, ", %s", ifindex2ifname (nexthop->rifindex));
1610 break;
1611 case NEXTHOP_TYPE_IFINDEX:
1612 case NEXTHOP_TYPE_IFNAME:
1613 vty_out (vty, " is directly connected, %s)",
1614 ifindex2ifname (nexthop->rifindex));
1615 break;
1616 default:
1617 break;
1618 }
1619 }
1620
hasso81dfcaa2003-05-25 19:21:25 +00001621 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_BLACKHOLE))
1622 vty_out (vty, ", bh");
1623 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_REJECT))
1624 vty_out (vty, ", rej");
1625
paul718e3742002-12-13 20:15:29 +00001626 if (rib->type == ZEBRA_ROUTE_RIPNG
1627 || rib->type == ZEBRA_ROUTE_OSPF6
jardin9e867fe2003-12-23 08:56:18 +00001628 || rib->type == ZEBRA_ROUTE_ISIS
paul718e3742002-12-13 20:15:29 +00001629 || rib->type == ZEBRA_ROUTE_BGP)
1630 {
1631 time_t uptime;
1632 struct tm *tm;
1633
1634 uptime = time (NULL);
1635 uptime -= rib->uptime;
1636 tm = gmtime (&uptime);
1637
1638#define ONE_DAY_SECOND 60*60*24
1639#define ONE_WEEK_SECOND 60*60*24*7
1640
1641 if (uptime < ONE_DAY_SECOND)
1642 vty_out (vty, ", %02d:%02d:%02d",
1643 tm->tm_hour, tm->tm_min, tm->tm_sec);
1644 else if (uptime < ONE_WEEK_SECOND)
1645 vty_out (vty, ", %dd%02dh%02dm",
1646 tm->tm_yday, tm->tm_hour, tm->tm_min);
1647 else
1648 vty_out (vty, ", %02dw%dd%02dh",
1649 tm->tm_yday/7,
1650 tm->tm_yday - ((tm->tm_yday/7) * 7), tm->tm_hour);
1651 }
1652 vty_out (vty, "%s", VTY_NEWLINE);
1653 }
1654}
1655
jardin9e867fe2003-12-23 08:56:18 +00001656#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 +00001657
1658DEFUN (show_ipv6_route,
1659 show_ipv6_route_cmd,
1660 "show ipv6 route",
1661 SHOW_STR
1662 IP_STR
1663 "IPv6 routing table\n")
1664{
1665 struct route_table *table;
1666 struct route_node *rn;
1667 struct rib *rib;
1668 int first = 1;
1669
1670 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
1671 if (! table)
1672 return CMD_SUCCESS;
1673
1674 /* Show all IPv6 route. */
1675 for (rn = route_top (table); rn; rn = route_next (rn))
1676 for (rib = rn->info; rib; rib = rib->next)
1677 {
1678 if (first)
1679 {
1680 vty_out (vty, SHOW_ROUTE_V6_HEADER, VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE);
1681 first = 0;
1682 }
1683 vty_show_ipv6_route (vty, rn, rib);
1684 }
1685 return CMD_SUCCESS;
1686}
1687
1688DEFUN (show_ipv6_route_prefix_longer,
1689 show_ipv6_route_prefix_longer_cmd,
1690 "show ipv6 route X:X::X:X/M longer-prefixes",
1691 SHOW_STR
1692 IP_STR
1693 "IPv6 routing table\n"
1694 "IPv6 prefix\n"
1695 "Show route matching the specified Network/Mask pair only\n")
1696{
1697 struct route_table *table;
1698 struct route_node *rn;
1699 struct rib *rib;
1700 struct prefix p;
1701 int ret;
1702 int first = 1;
1703
1704 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
1705 if (! table)
1706 return CMD_SUCCESS;
1707
1708 ret = str2prefix (argv[0], &p);
1709 if (! ret)
1710 {
1711 vty_out (vty, "%% Malformed Prefix%s", VTY_NEWLINE);
1712 return CMD_WARNING;
1713 }
1714
1715 /* Show matched type IPv6 routes. */
1716 for (rn = route_top (table); rn; rn = route_next (rn))
1717 for (rib = rn->info; rib; rib = rib->next)
1718 if (prefix_match (&p, &rn->p))
1719 {
1720 if (first)
1721 {
1722 vty_out (vty, SHOW_ROUTE_V6_HEADER, VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE);
1723 first = 0;
1724 }
1725 vty_show_ipv6_route (vty, rn, rib);
1726 }
1727 return CMD_SUCCESS;
1728}
1729
1730DEFUN (show_ipv6_route_protocol,
1731 show_ipv6_route_protocol_cmd,
1732 "show ipv6 route (bgp|connected|kernel|ospf6|ripng|static)",
1733 SHOW_STR
1734 IP_STR
1735 "IP routing table\n"
1736 "Border Gateway Protocol (BGP)\n"
1737 "Connected\n"
1738 "Kernel\n"
1739 "Open Shortest Path First (OSPFv3)\n"
jardin9e867fe2003-12-23 08:56:18 +00001740 "ISO IS-IS (ISIS)\n"
paul718e3742002-12-13 20:15:29 +00001741 "Routing Information Protocol (RIPng)\n"
1742 "Static routes\n")
1743{
1744 int type;
1745 struct route_table *table;
1746 struct route_node *rn;
1747 struct rib *rib;
1748 int first = 1;
1749
1750 if (strncmp (argv[0], "b", 1) == 0)
1751 type = ZEBRA_ROUTE_BGP;
1752 else if (strncmp (argv[0], "c", 1) == 0)
1753 type = ZEBRA_ROUTE_CONNECT;
1754 else if (strncmp (argv[0], "k", 1) ==0)
1755 type = ZEBRA_ROUTE_KERNEL;
1756 else if (strncmp (argv[0], "o", 1) == 0)
1757 type = ZEBRA_ROUTE_OSPF6;
jardin9e867fe2003-12-23 08:56:18 +00001758 else if (strncmp (argv[0], "i", 1) == 0)
1759 type = ZEBRA_ROUTE_ISIS;
paul718e3742002-12-13 20:15:29 +00001760 else if (strncmp (argv[0], "r", 1) == 0)
1761 type = ZEBRA_ROUTE_RIPNG;
1762 else if (strncmp (argv[0], "s", 1) == 0)
1763 type = ZEBRA_ROUTE_STATIC;
1764 else
1765 {
1766 vty_out (vty, "Unknown route type%s", VTY_NEWLINE);
1767 return CMD_WARNING;
1768 }
1769
1770 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
1771 if (! table)
1772 return CMD_SUCCESS;
1773
1774 /* Show matched type IPv6 routes. */
1775 for (rn = route_top (table); rn; rn = route_next (rn))
1776 for (rib = rn->info; rib; rib = rib->next)
1777 if (rib->type == type)
1778 {
1779 if (first)
1780 {
1781 vty_out (vty, SHOW_ROUTE_V6_HEADER, VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE);
1782 first = 0;
1783 }
1784 vty_show_ipv6_route (vty, rn, rib);
1785 }
1786 return CMD_SUCCESS;
1787}
1788
1789DEFUN (show_ipv6_route_addr,
1790 show_ipv6_route_addr_cmd,
1791 "show ipv6 route X:X::X:X",
1792 SHOW_STR
1793 IP_STR
1794 "IPv6 routing table\n"
1795 "IPv6 Address\n")
1796{
1797 int ret;
1798 struct prefix_ipv6 p;
1799 struct route_table *table;
1800 struct route_node *rn;
1801
1802 ret = str2prefix_ipv6 (argv[0], &p);
1803 if (ret <= 0)
1804 {
1805 vty_out (vty, "Malformed IPv6 address%s", VTY_NEWLINE);
1806 return CMD_WARNING;
1807 }
1808
1809 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
1810 if (! table)
1811 return CMD_SUCCESS;
1812
1813 rn = route_node_match (table, (struct prefix *) &p);
1814 if (! rn)
1815 {
1816 vty_out (vty, "%% Network not in table%s", VTY_NEWLINE);
1817 return CMD_WARNING;
1818 }
1819
1820 vty_show_ipv6_route_detail (vty, rn);
1821
1822 route_unlock_node (rn);
1823
1824 return CMD_SUCCESS;
1825}
1826
1827DEFUN (show_ipv6_route_prefix,
1828 show_ipv6_route_prefix_cmd,
1829 "show ipv6 route X:X::X:X/M",
1830 SHOW_STR
1831 IP_STR
1832 "IPv6 routing table\n"
1833 "IPv6 prefix\n")
1834{
1835 int ret;
1836 struct prefix_ipv6 p;
1837 struct route_table *table;
1838 struct route_node *rn;
1839
1840 ret = str2prefix_ipv6 (argv[0], &p);
1841 if (ret <= 0)
1842 {
1843 vty_out (vty, "Malformed IPv6 prefix%s", VTY_NEWLINE);
1844 return CMD_WARNING;
1845 }
1846
1847 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
1848 if (! table)
1849 return CMD_SUCCESS;
1850
1851 rn = route_node_match (table, (struct prefix *) &p);
1852 if (! rn || rn->p.prefixlen != p.prefixlen)
1853 {
1854 vty_out (vty, "%% Network not in table%s", VTY_NEWLINE);
1855 return CMD_WARNING;
1856 }
1857
1858 vty_show_ipv6_route_detail (vty, rn);
1859
1860 route_unlock_node (rn);
1861
1862 return CMD_SUCCESS;
1863}
1864
1865
1866/* Write IPv6 static route configuration. */
1867int
1868static_config_ipv6 (struct vty *vty)
1869{
1870 struct route_node *rn;
1871 struct static_ipv6 *si;
1872 int write;
1873 char buf[BUFSIZ];
1874 struct route_table *stable;
1875
1876 write = 0;
1877
1878 /* Lookup table. */
1879 stable = vrf_static_table (AFI_IP6, SAFI_UNICAST, 0);
1880 if (! stable)
1881 return -1;
1882
1883 for (rn = route_top (stable); rn; rn = route_next (rn))
1884 for (si = rn->info; si; si = si->next)
1885 {
1886 vty_out (vty, "ipv6 route %s/%d",
1887 inet_ntop (AF_INET6, &rn->p.u.prefix6, buf, BUFSIZ),
1888 rn->p.prefixlen);
1889
1890 switch (si->type)
1891 {
1892 case STATIC_IPV6_GATEWAY:
1893 vty_out (vty, " %s", inet_ntop (AF_INET6, &si->ipv6, buf, BUFSIZ));
1894 break;
1895 case STATIC_IPV6_IFNAME:
1896 vty_out (vty, " %s", si->ifname);
1897 break;
1898 case STATIC_IPV6_GATEWAY_IFNAME:
1899 vty_out (vty, " %s %s",
1900 inet_ntop (AF_INET6, &si->ipv6, buf, BUFSIZ), si->ifname);
1901 break;
1902 }
1903
hasso81dfcaa2003-05-25 19:21:25 +00001904 if (CHECK_FLAG(si->flags, ZEBRA_FLAG_REJECT))
1905 vty_out (vty, " %s", "reject");
1906
1907 if (CHECK_FLAG(si->flags, ZEBRA_FLAG_BLACKHOLE))
1908 vty_out (vty, " %s", "blackhole");
1909
paul718e3742002-12-13 20:15:29 +00001910 if (si->distance != ZEBRA_STATIC_DISTANCE_DEFAULT)
1911 vty_out (vty, " %d", si->distance);
1912 vty_out (vty, "%s", VTY_NEWLINE);
1913
1914 write = 1;
1915 }
1916 return write;
1917}
1918#endif /* HAVE_IPV6 */
1919
1920/* Static ip route configuration write function. */
1921int
1922zebra_ip_config (struct vty *vty)
1923{
1924 int write = 0;
1925
1926 write += static_config_ipv4 (vty);
1927#ifdef HAVE_IPV6
1928 write += static_config_ipv6 (vty);
1929#endif /* HAVE_IPV6 */
1930
1931 return write;
1932}
1933
1934/* IP node for static routes. */
1935struct cmd_node ip_node = { IP_NODE, "", 1 };
1936
1937/* Route VTY. */
1938void
1939zebra_vty_route_init ()
1940{
1941 install_node (&ip_node, zebra_ip_config);
1942
1943 install_element (CONFIG_NODE, &ip_route_cmd);
hasso81dfcaa2003-05-25 19:21:25 +00001944 install_element (CONFIG_NODE, &ip_route_flags_cmd);
hasso457ef552003-05-28 12:02:15 +00001945 install_element (CONFIG_NODE, &ip_route_flags2_cmd);
paul718e3742002-12-13 20:15:29 +00001946 install_element (CONFIG_NODE, &ip_route_mask_cmd);
hasso81dfcaa2003-05-25 19:21:25 +00001947 install_element (CONFIG_NODE, &ip_route_mask_flags_cmd);
hasso457ef552003-05-28 12:02:15 +00001948 install_element (CONFIG_NODE, &ip_route_mask_flags2_cmd);
paul718e3742002-12-13 20:15:29 +00001949 install_element (CONFIG_NODE, &no_ip_route_cmd);
hasso81dfcaa2003-05-25 19:21:25 +00001950 install_element (CONFIG_NODE, &no_ip_route_flags_cmd);
hasso457ef552003-05-28 12:02:15 +00001951 install_element (CONFIG_NODE, &no_ip_route_flags2_cmd);
paul718e3742002-12-13 20:15:29 +00001952 install_element (CONFIG_NODE, &no_ip_route_mask_cmd);
hasso81dfcaa2003-05-25 19:21:25 +00001953 install_element (CONFIG_NODE, &no_ip_route_mask_flags_cmd);
hasso457ef552003-05-28 12:02:15 +00001954 install_element (CONFIG_NODE, &no_ip_route_mask_flags2_cmd);
paul718e3742002-12-13 20:15:29 +00001955 install_element (CONFIG_NODE, &ip_route_distance_cmd);
hasso81dfcaa2003-05-25 19:21:25 +00001956 install_element (CONFIG_NODE, &ip_route_flags_distance_cmd);
hasso457ef552003-05-28 12:02:15 +00001957 install_element (CONFIG_NODE, &ip_route_flags_distance2_cmd);
paul718e3742002-12-13 20:15:29 +00001958 install_element (CONFIG_NODE, &ip_route_mask_distance_cmd);
hasso81dfcaa2003-05-25 19:21:25 +00001959 install_element (CONFIG_NODE, &ip_route_mask_flags_distance_cmd);
hasso457ef552003-05-28 12:02:15 +00001960 install_element (CONFIG_NODE, &ip_route_mask_flags_distance2_cmd);
paul718e3742002-12-13 20:15:29 +00001961 install_element (CONFIG_NODE, &no_ip_route_distance_cmd);
hasso81dfcaa2003-05-25 19:21:25 +00001962 install_element (CONFIG_NODE, &no_ip_route_flags_distance_cmd);
hasso457ef552003-05-28 12:02:15 +00001963 install_element (CONFIG_NODE, &no_ip_route_flags_distance2_cmd);
hasso81dfcaa2003-05-25 19:21:25 +00001964 install_element (CONFIG_NODE, &no_ip_route_mask_flags_distance_cmd);
hasso457ef552003-05-28 12:02:15 +00001965 install_element (CONFIG_NODE, &no_ip_route_mask_flags_distance2_cmd);
paul718e3742002-12-13 20:15:29 +00001966
1967 install_element (VIEW_NODE, &show_ip_route_cmd);
1968 install_element (VIEW_NODE, &show_ip_route_addr_cmd);
1969 install_element (VIEW_NODE, &show_ip_route_prefix_cmd);
1970 install_element (VIEW_NODE, &show_ip_route_prefix_longer_cmd);
1971 install_element (VIEW_NODE, &show_ip_route_protocol_cmd);
1972 install_element (VIEW_NODE, &show_ip_route_supernets_cmd);
1973 install_element (ENABLE_NODE, &show_ip_route_cmd);
1974 install_element (ENABLE_NODE, &show_ip_route_addr_cmd);
1975 install_element (ENABLE_NODE, &show_ip_route_prefix_cmd);
1976 install_element (ENABLE_NODE, &show_ip_route_prefix_longer_cmd);
1977 install_element (ENABLE_NODE, &show_ip_route_protocol_cmd);
1978 install_element (ENABLE_NODE, &show_ip_route_supernets_cmd);
1979
1980#if 0
1981 install_element (VIEW_NODE, &show_ip_route_summary_cmd);
1982 install_element (ENABLE_NODE, &show_ip_route_summary_cmd);
1983#endif /* 0 */
1984
1985#ifdef HAVE_IPV6
1986 install_element (CONFIG_NODE, &ipv6_route_cmd);
hasso81dfcaa2003-05-25 19:21:25 +00001987 install_element (CONFIG_NODE, &ipv6_route_flags_cmd);
paul718e3742002-12-13 20:15:29 +00001988 install_element (CONFIG_NODE, &ipv6_route_ifname_cmd);
hasso81dfcaa2003-05-25 19:21:25 +00001989 install_element (CONFIG_NODE, &ipv6_route_ifname_flags_cmd);
paul718e3742002-12-13 20:15:29 +00001990 install_element (CONFIG_NODE, &no_ipv6_route_cmd);
hasso81dfcaa2003-05-25 19:21:25 +00001991 install_element (CONFIG_NODE, &no_ipv6_route_flags_cmd);
paul718e3742002-12-13 20:15:29 +00001992 install_element (CONFIG_NODE, &no_ipv6_route_ifname_cmd);
hasso81dfcaa2003-05-25 19:21:25 +00001993 install_element (CONFIG_NODE, &no_ipv6_route_ifname_flags_cmd);
paul718e3742002-12-13 20:15:29 +00001994 install_element (CONFIG_NODE, &ipv6_route_pref_cmd);
hasso81dfcaa2003-05-25 19:21:25 +00001995 install_element (CONFIG_NODE, &ipv6_route_flags_pref_cmd);
paul718e3742002-12-13 20:15:29 +00001996 install_element (CONFIG_NODE, &ipv6_route_ifname_pref_cmd);
hasso81dfcaa2003-05-25 19:21:25 +00001997 install_element (CONFIG_NODE, &ipv6_route_ifname_flags_pref_cmd);
paul718e3742002-12-13 20:15:29 +00001998 install_element (CONFIG_NODE, &no_ipv6_route_pref_cmd);
hasso81dfcaa2003-05-25 19:21:25 +00001999 install_element (CONFIG_NODE, &no_ipv6_route_flags_pref_cmd);
paul718e3742002-12-13 20:15:29 +00002000 install_element (CONFIG_NODE, &no_ipv6_route_ifname_pref_cmd);
hasso81dfcaa2003-05-25 19:21:25 +00002001 install_element (CONFIG_NODE, &no_ipv6_route_ifname_flags_pref_cmd);
paul718e3742002-12-13 20:15:29 +00002002 install_element (VIEW_NODE, &show_ipv6_route_cmd);
2003 install_element (VIEW_NODE, &show_ipv6_route_protocol_cmd);
2004 install_element (VIEW_NODE, &show_ipv6_route_addr_cmd);
2005 install_element (VIEW_NODE, &show_ipv6_route_prefix_cmd);
2006 install_element (VIEW_NODE, &show_ipv6_route_prefix_longer_cmd);
2007 install_element (ENABLE_NODE, &show_ipv6_route_cmd);
2008 install_element (ENABLE_NODE, &show_ipv6_route_protocol_cmd);
2009 install_element (ENABLE_NODE, &show_ipv6_route_addr_cmd);
2010 install_element (ENABLE_NODE, &show_ipv6_route_prefix_cmd);
2011 install_element (ENABLE_NODE, &show_ipv6_route_prefix_longer_cmd);
2012#endif /* HAVE_IPV6 */
2013}
2014
2015void
2016zebra_vty_init ()
2017{
2018 zebra_vty_route_init ();
2019}