blob: 68e6f920795f58ef7612e2bd43f8b97abd629b31 [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
paula1ac18c2005-06-28 17:17:12 +000030#include "zebra/zserv.h"
31
paul718e3742002-12-13 20:15:29 +000032/* General fucntion for static route. */
paula1ac18c2005-06-28 17:17:12 +000033static int
hasso39db97e2004-10-12 20:50:58 +000034zebra_static_ipv4 (struct vty *vty, int add_cmd, const char *dest_str,
35 const char *mask_str, const char *gate_str,
36 const char *flag_str, const char *distance_str)
paul718e3742002-12-13 20:15:29 +000037{
38 int ret;
39 u_char distance;
40 struct prefix p;
41 struct in_addr gate;
42 struct in_addr mask;
hasso39db97e2004-10-12 20:50:58 +000043 const char *ifname;
hasso81dfcaa2003-05-25 19:21:25 +000044 u_char flag = 0;
paul718e3742002-12-13 20:15:29 +000045
46 ret = str2prefix (dest_str, &p);
47 if (ret <= 0)
48 {
49 vty_out (vty, "%% Malformed address%s", VTY_NEWLINE);
50 return CMD_WARNING;
51 }
52
53 /* Cisco like mask notation. */
54 if (mask_str)
55 {
56 ret = inet_aton (mask_str, &mask);
57 if (ret == 0)
paul595db7f2003-05-25 21:35:06 +000058 {
59 vty_out (vty, "%% Malformed address%s", VTY_NEWLINE);
60 return CMD_WARNING;
61 }
paul718e3742002-12-13 20:15:29 +000062 p.prefixlen = ip_masklen (mask);
63 }
64
65 /* Apply mask for given prefix. */
66 apply_mask (&p);
67
paul595db7f2003-05-25 21:35:06 +000068 /* Administrative distance. */
69 if (distance_str)
70 distance = atoi (distance_str);
71 else
72 distance = ZEBRA_STATIC_DISTANCE_DEFAULT;
73
74 /* Null0 static route. */
hasso457ef552003-05-28 12:02:15 +000075 if ((gate_str != NULL) && (strncasecmp (gate_str, "Null0", strlen (gate_str)) == 0))
paul595db7f2003-05-25 21:35:06 +000076 {
77 if (flag_str)
78 {
79 vty_out (vty, "%% can not have flag %s with Null0%s", flag_str, VTY_NEWLINE);
80 return CMD_WARNING;
81 }
82 if (add_cmd)
paul7021c422003-07-15 12:52:22 +000083 static_add_ipv4 (&p, NULL, NULL, ZEBRA_FLAG_BLACKHOLE, distance, 0);
paul595db7f2003-05-25 21:35:06 +000084 else
85 static_delete_ipv4 (&p, NULL, NULL, distance, 0);
86 return CMD_SUCCESS;
87 }
88
hasso81dfcaa2003-05-25 19:21:25 +000089 /* Route flags */
90 if (flag_str) {
91 switch(flag_str[0]) {
92 case 'r':
93 case 'R': /* XXX */
94 SET_FLAG (flag, ZEBRA_FLAG_REJECT);
95 break;
96 case 'b':
97 case 'B': /* XXX */
98 SET_FLAG (flag, ZEBRA_FLAG_BLACKHOLE);
99 break;
100 default:
101 vty_out (vty, "%% Malformed flag %s %s", flag_str, VTY_NEWLINE);
paul595db7f2003-05-25 21:35:06 +0000102 return CMD_WARNING;
hasso81dfcaa2003-05-25 19:21:25 +0000103 }
104 }
105
hasso457ef552003-05-28 12:02:15 +0000106 if (gate_str == NULL)
107 {
108 if (add_cmd)
109 static_add_ipv4 (&p, NULL, NULL, flag, distance, 0);
110 else
111 static_delete_ipv4 (&p, NULL, NULL, distance, 0);
112
113 return CMD_SUCCESS;
114 }
115
paul718e3742002-12-13 20:15:29 +0000116 /* When gateway is A.B.C.D format, gate is treated as nexthop
117 address other case gate is treated as interface name. */
118 ret = inet_aton (gate_str, &gate);
119 if (ret)
120 ifname = NULL;
121 else
122 ifname = gate_str;
123
124 if (add_cmd)
hasso81dfcaa2003-05-25 19:21:25 +0000125 static_add_ipv4 (&p, ifname ? NULL : &gate, ifname, flag, distance, 0);
paul718e3742002-12-13 20:15:29 +0000126 else
127 static_delete_ipv4 (&p, ifname ? NULL : &gate, ifname, distance, 0);
128
129 return CMD_SUCCESS;
130}
131
132/* Static route configuration. */
133DEFUN (ip_route,
134 ip_route_cmd,
paul595db7f2003-05-25 21:35:06 +0000135 "ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0)",
hasso81dfcaa2003-05-25 19:21:25 +0000136 IP_STR
137 "Establish static routes\n"
138 "IP destination prefix (e.g. 10.0.0.0/8)\n"
139 "IP gateway address\n"
paul595db7f2003-05-25 21:35:06 +0000140 "IP gateway interface name\n"
141 "Null interface\n")
hasso81dfcaa2003-05-25 19:21:25 +0000142{
143 return zebra_static_ipv4 (vty, 1, argv[0], NULL, argv[1], NULL, NULL);
144}
145
146DEFUN (ip_route_flags,
147 ip_route_flags_cmd,
148 "ip route A.B.C.D/M (A.B.C.D|INTERFACE) (reject|blackhole)",
paul718e3742002-12-13 20:15:29 +0000149 IP_STR
150 "Establish static routes\n"
151 "IP destination prefix (e.g. 10.0.0.0/8)\n"
152 "IP gateway address\n"
153 "IP gateway interface name\n"
hasso81dfcaa2003-05-25 19:21:25 +0000154 "Emit an ICMP unreachable when matched\n"
155 "Silently discard pkts when matched\n")
paul718e3742002-12-13 20:15:29 +0000156{
hasso81dfcaa2003-05-25 19:21:25 +0000157 return zebra_static_ipv4 (vty, 1, argv[0], NULL, argv[1], argv[2], NULL);
paul718e3742002-12-13 20:15:29 +0000158}
159
hasso457ef552003-05-28 12:02:15 +0000160DEFUN (ip_route_flags2,
161 ip_route_flags2_cmd,
162 "ip route A.B.C.D/M (reject|blackhole)",
163 IP_STR
164 "Establish static routes\n"
165 "IP destination prefix (e.g. 10.0.0.0/8)\n"
166 "Emit an ICMP unreachable when matched\n"
167 "Silently discard pkts when matched\n")
168{
169 return zebra_static_ipv4 (vty, 1, argv[0], NULL, NULL, argv[1], NULL);
170}
171
paul718e3742002-12-13 20:15:29 +0000172/* Mask as A.B.C.D format. */
173DEFUN (ip_route_mask,
174 ip_route_mask_cmd,
paul595db7f2003-05-25 21:35:06 +0000175 "ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0)",
hasso81dfcaa2003-05-25 19:21:25 +0000176 IP_STR
177 "Establish static routes\n"
178 "IP destination prefix\n"
179 "IP destination prefix mask\n"
180 "IP gateway address\n"
paul595db7f2003-05-25 21:35:06 +0000181 "IP gateway interface name\n"
182 "Null interface\n")
hasso81dfcaa2003-05-25 19:21:25 +0000183{
184 return zebra_static_ipv4 (vty, 1, argv[0], argv[1], argv[2], NULL, NULL);
185}
186
187DEFUN (ip_route_mask_flags,
188 ip_route_mask_flags_cmd,
189 "ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE) (reject|blackhole)",
paul718e3742002-12-13 20:15:29 +0000190 IP_STR
191 "Establish static routes\n"
192 "IP destination prefix\n"
193 "IP destination prefix mask\n"
194 "IP gateway address\n"
195 "IP gateway interface name\n"
hasso81dfcaa2003-05-25 19:21:25 +0000196 "Emit an ICMP unreachable when matched\n"
197 "Silently discard pkts when matched\n")
paul718e3742002-12-13 20:15:29 +0000198{
hasso81dfcaa2003-05-25 19:21:25 +0000199 return zebra_static_ipv4 (vty, 1, argv[0], argv[1], argv[2], argv[3], NULL);
paul718e3742002-12-13 20:15:29 +0000200}
201
hasso457ef552003-05-28 12:02:15 +0000202DEFUN (ip_route_mask_flags2,
203 ip_route_mask_flags2_cmd,
204 "ip route A.B.C.D A.B.C.D (reject|blackhole)",
205 IP_STR
206 "Establish static routes\n"
207 "IP destination prefix\n"
208 "IP destination prefix mask\n"
209 "Emit an ICMP unreachable when matched\n"
210 "Silently discard pkts when matched\n")
211{
212 return zebra_static_ipv4 (vty, 1, argv[0], argv[1], NULL, argv[2], NULL);
213}
214
paul718e3742002-12-13 20:15:29 +0000215/* Distance option value. */
216DEFUN (ip_route_distance,
217 ip_route_distance_cmd,
paul595db7f2003-05-25 21:35:06 +0000218 "ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0) <1-255>",
paul718e3742002-12-13 20:15:29 +0000219 IP_STR
220 "Establish static routes\n"
221 "IP destination prefix (e.g. 10.0.0.0/8)\n"
222 "IP gateway address\n"
223 "IP gateway interface name\n"
paul595db7f2003-05-25 21:35:06 +0000224 "Null interface\n"
paul718e3742002-12-13 20:15:29 +0000225 "Distance value for this route\n")
226{
hasso81dfcaa2003-05-25 19:21:25 +0000227 return zebra_static_ipv4 (vty, 1, argv[0], NULL, argv[1], NULL, argv[2]);
228}
229
230DEFUN (ip_route_flags_distance,
231 ip_route_flags_distance_cmd,
232 "ip route A.B.C.D/M (A.B.C.D|INTERFACE) (reject|blackhole) <1-255>",
233 IP_STR
234 "Establish static routes\n"
235 "IP destination prefix (e.g. 10.0.0.0/8)\n"
236 "IP gateway address\n"
237 "IP gateway interface name\n"
238 "Emit an ICMP unreachable when matched\n"
239 "Silently discard pkts when matched\n"
240 "Distance value for this route\n")
241{
242 return zebra_static_ipv4 (vty, 1, argv[0], NULL, argv[1], argv[2], argv[3]);
paul718e3742002-12-13 20:15:29 +0000243}
244
hasso457ef552003-05-28 12:02:15 +0000245DEFUN (ip_route_flags_distance2,
246 ip_route_flags_distance2_cmd,
247 "ip route A.B.C.D/M (reject|blackhole) <1-255>",
248 IP_STR
249 "Establish static routes\n"
250 "IP destination prefix (e.g. 10.0.0.0/8)\n"
251 "Emit an ICMP unreachable when matched\n"
252 "Silently discard pkts when matched\n"
253 "Distance value for this route\n")
254{
255 return zebra_static_ipv4 (vty, 1, argv[0], NULL, NULL, argv[1], argv[2]);
256}
257
paul718e3742002-12-13 20:15:29 +0000258DEFUN (ip_route_mask_distance,
259 ip_route_mask_distance_cmd,
paul595db7f2003-05-25 21:35:06 +0000260 "ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0) <1-255>",
paul718e3742002-12-13 20:15:29 +0000261 IP_STR
262 "Establish static routes\n"
263 "IP destination prefix\n"
264 "IP destination prefix mask\n"
265 "IP gateway address\n"
266 "IP gateway interface name\n"
paul595db7f2003-05-25 21:35:06 +0000267 "Null interface\n"
paul718e3742002-12-13 20:15:29 +0000268 "Distance value for this route\n")
269{
hasso81dfcaa2003-05-25 19:21:25 +0000270 return zebra_static_ipv4 (vty, 1, argv[0], argv[1], argv[2], NULL, argv[3]);
271}
272
273DEFUN (ip_route_mask_flags_distance,
274 ip_route_mask_flags_distance_cmd,
275 "ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE) (reject|blackhole) <1-255>",
276 IP_STR
277 "Establish static routes\n"
278 "IP destination prefix\n"
279 "IP destination prefix mask\n"
280 "IP gateway address\n"
281 "IP gateway interface name\n"
282 "Distance value for this route\n"
283 "Emit an ICMP unreachable when matched\n"
284 "Silently discard pkts when matched\n")
285{
286 return zebra_static_ipv4 (vty, 1, argv[0], argv[1], argv[2], argv[3], argv[4]);
paul718e3742002-12-13 20:15:29 +0000287}
288
hasso457ef552003-05-28 12:02:15 +0000289DEFUN (ip_route_mask_flags_distance2,
290 ip_route_mask_flags_distance2_cmd,
291 "ip route A.B.C.D A.B.C.D (reject|blackhole) <1-255>",
292 IP_STR
293 "Establish static routes\n"
294 "IP destination prefix\n"
295 "IP destination prefix mask\n"
296 "Distance value for this route\n"
297 "Emit an ICMP unreachable when matched\n"
298 "Silently discard pkts when matched\n")
299{
300 return zebra_static_ipv4 (vty, 1, argv[0], argv[1], NULL, argv[2], argv[3]);
301}
302
paul718e3742002-12-13 20:15:29 +0000303DEFUN (no_ip_route,
304 no_ip_route_cmd,
paul595db7f2003-05-25 21:35:06 +0000305 "no ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0)",
hasso81dfcaa2003-05-25 19:21:25 +0000306 NO_STR
307 IP_STR
308 "Establish static routes\n"
309 "IP destination prefix (e.g. 10.0.0.0/8)\n"
310 "IP gateway address\n"
paul595db7f2003-05-25 21:35:06 +0000311 "IP gateway interface name\n"
312 "Null interface\n")
hasso81dfcaa2003-05-25 19:21:25 +0000313{
314 return zebra_static_ipv4 (vty, 0, argv[0], NULL, argv[1], NULL, NULL);
315}
316
317ALIAS (no_ip_route,
318 no_ip_route_flags_cmd,
319 "no ip route A.B.C.D/M (A.B.C.D|INTERFACE) (reject|blackhole)",
paul718e3742002-12-13 20:15:29 +0000320 NO_STR
321 IP_STR
322 "Establish static routes\n"
323 "IP destination prefix (e.g. 10.0.0.0/8)\n"
324 "IP gateway address\n"
325 "IP gateway interface name\n"
hasso81dfcaa2003-05-25 19:21:25 +0000326 "Emit an ICMP unreachable when matched\n"
327 "Silently discard pkts when matched\n")
paul718e3742002-12-13 20:15:29 +0000328
hasso457ef552003-05-28 12:02:15 +0000329DEFUN (no_ip_route_flags2,
330 no_ip_route_flags2_cmd,
331 "no ip route A.B.C.D/M (reject|blackhole)",
332 NO_STR
333 IP_STR
334 "Establish static routes\n"
335 "IP destination prefix (e.g. 10.0.0.0/8)\n"
336 "Emit an ICMP unreachable when matched\n"
337 "Silently discard pkts when matched\n")
338{
339 return zebra_static_ipv4 (vty, 0, argv[0], NULL, NULL, NULL, NULL);
340}
341
paul718e3742002-12-13 20:15:29 +0000342DEFUN (no_ip_route_mask,
343 no_ip_route_mask_cmd,
paul595db7f2003-05-25 21:35:06 +0000344 "no ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0)",
hasso81dfcaa2003-05-25 19:21:25 +0000345 NO_STR
346 IP_STR
347 "Establish static routes\n"
348 "IP destination prefix\n"
349 "IP destination prefix mask\n"
350 "IP gateway address\n"
paul595db7f2003-05-25 21:35:06 +0000351 "IP gateway interface name\n"
352 "Null interface\n")
hasso81dfcaa2003-05-25 19:21:25 +0000353{
354 return zebra_static_ipv4 (vty, 0, argv[0], argv[1], argv[2], NULL, NULL);
355}
356
357ALIAS (no_ip_route_mask,
358 no_ip_route_mask_flags_cmd,
359 "no ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE) (reject|blackhole)",
paul718e3742002-12-13 20:15:29 +0000360 NO_STR
361 IP_STR
362 "Establish static routes\n"
363 "IP destination prefix\n"
364 "IP destination prefix mask\n"
365 "IP gateway address\n"
366 "IP gateway interface name\n"
hasso81dfcaa2003-05-25 19:21:25 +0000367 "Emit an ICMP unreachable when matched\n"
368 "Silently discard pkts when matched\n")
paul718e3742002-12-13 20:15:29 +0000369
hasso457ef552003-05-28 12:02:15 +0000370DEFUN (no_ip_route_mask_flags2,
371 no_ip_route_mask_flags2_cmd,
372 "no ip route A.B.C.D A.B.C.D (reject|blackhole)",
373 NO_STR
374 IP_STR
375 "Establish static routes\n"
376 "IP destination prefix\n"
377 "IP destination prefix mask\n"
378 "Emit an ICMP unreachable when matched\n"
379 "Silently discard pkts when matched\n")
380{
381 return zebra_static_ipv4 (vty, 0, argv[0], argv[1], NULL, NULL, NULL);
382}
383
paul718e3742002-12-13 20:15:29 +0000384DEFUN (no_ip_route_distance,
385 no_ip_route_distance_cmd,
paul595db7f2003-05-25 21:35:06 +0000386 "no ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0) <1-255>",
paul718e3742002-12-13 20:15:29 +0000387 NO_STR
388 IP_STR
389 "Establish static routes\n"
390 "IP destination prefix (e.g. 10.0.0.0/8)\n"
391 "IP gateway address\n"
392 "IP gateway interface name\n"
paul595db7f2003-05-25 21:35:06 +0000393 "Null interface\n"
paul718e3742002-12-13 20:15:29 +0000394 "Distance value for this route\n")
395{
hasso81dfcaa2003-05-25 19:21:25 +0000396 return zebra_static_ipv4 (vty, 0, argv[0], NULL, argv[1], NULL, argv[2]);
397}
398
399DEFUN (no_ip_route_flags_distance,
400 no_ip_route_flags_distance_cmd,
401 "no ip route A.B.C.D/M (A.B.C.D|INTERFACE) (reject|blackhole) <1-255>",
402 NO_STR
403 IP_STR
404 "Establish static routes\n"
405 "IP destination prefix (e.g. 10.0.0.0/8)\n"
406 "IP gateway address\n"
407 "IP gateway interface name\n"
408 "Emit an ICMP unreachable when matched\n"
409 "Silently discard pkts when matched\n"
410 "Distance value for this route\n")
411{
412 return zebra_static_ipv4 (vty, 0, argv[0], NULL, argv[1], argv[2], argv[3]);
paul718e3742002-12-13 20:15:29 +0000413}
414
hasso457ef552003-05-28 12:02:15 +0000415DEFUN (no_ip_route_flags_distance2,
416 no_ip_route_flags_distance2_cmd,
417 "no ip route A.B.C.D/M (reject|blackhole) <1-255>",
418 NO_STR
419 IP_STR
420 "Establish static routes\n"
421 "IP destination prefix (e.g. 10.0.0.0/8)\n"
422 "Emit an ICMP unreachable when matched\n"
423 "Silently discard pkts when matched\n"
424 "Distance value for this route\n")
425{
426 return zebra_static_ipv4 (vty, 0, argv[0], NULL, NULL, argv[1], argv[2]);
427}
428
paul718e3742002-12-13 20:15:29 +0000429DEFUN (no_ip_route_mask_distance,
430 no_ip_route_mask_distance_cmd,
paul595db7f2003-05-25 21:35:06 +0000431 "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 +0000432 NO_STR
433 IP_STR
434 "Establish static routes\n"
435 "IP destination prefix\n"
436 "IP destination prefix mask\n"
437 "IP gateway address\n"
438 "IP gateway interface name\n"
paul595db7f2003-05-25 21:35:06 +0000439 "Null interface\n"
paul718e3742002-12-13 20:15:29 +0000440 "Distance value for this route\n")
441{
hasso81dfcaa2003-05-25 19:21:25 +0000442 return zebra_static_ipv4 (vty, 0, argv[0], argv[1], argv[2], NULL, argv[3]);
443}
444
445DEFUN (no_ip_route_mask_flags_distance,
446 no_ip_route_mask_flags_distance_cmd,
447 "no ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE) (reject|blackhole) <1-255>",
448 NO_STR
449 IP_STR
450 "Establish static routes\n"
451 "IP destination prefix\n"
452 "IP destination prefix mask\n"
453 "IP gateway address\n"
454 "IP gateway interface name\n"
455 "Emit an ICMP unreachable when matched\n"
456 "Silently discard pkts when matched\n"
457 "Distance value for this route\n")
458{
459 return zebra_static_ipv4 (vty, 0, argv[0], argv[1], argv[2], argv[3], argv[4]);
paul718e3742002-12-13 20:15:29 +0000460}
461
hasso457ef552003-05-28 12:02:15 +0000462DEFUN (no_ip_route_mask_flags_distance2,
463 no_ip_route_mask_flags_distance2_cmd,
464 "no ip route A.B.C.D A.B.C.D (reject|blackhole) <1-255>",
465 NO_STR
466 IP_STR
467 "Establish static routes\n"
468 "IP destination prefix\n"
469 "IP destination prefix mask\n"
470 "Emit an ICMP unreachable when matched\n"
471 "Silently discard pkts when matched\n"
472 "Distance value for this route\n")
473{
474 return zebra_static_ipv4 (vty, 0, argv[0], argv[1], NULL, argv[2], argv[3]);
475}
476
paul718e3742002-12-13 20:15:29 +0000477/* New RIB. Detailed information for IPv4 route. */
paula1ac18c2005-06-28 17:17:12 +0000478static void
paul718e3742002-12-13 20:15:29 +0000479vty_show_ip_route_detail (struct vty *vty, struct route_node *rn)
480{
481 struct rib *rib;
482 struct nexthop *nexthop;
483
484 for (rib = rn->info; rib; rib = rib->next)
485 {
486 vty_out (vty, "Routing entry for %s/%d%s",
487 inet_ntoa (rn->p.u.prefix4), rn->p.prefixlen,
488 VTY_NEWLINE);
ajsf52d13c2005-10-01 17:38:06 +0000489 vty_out (vty, " Known via \"%s\"", zebra_route_string (rib->type));
paul718e3742002-12-13 20:15:29 +0000490 vty_out (vty, ", distance %d, metric %d", rib->distance, rib->metric);
491 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
492 vty_out (vty, ", best");
493 if (rib->refcnt)
494 vty_out (vty, ", refcnt %ld", rib->refcnt);
hasso81dfcaa2003-05-25 19:21:25 +0000495 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_BLACKHOLE))
496 vty_out (vty, ", blackhole");
497 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_REJECT))
498 vty_out (vty, ", reject");
paul718e3742002-12-13 20:15:29 +0000499 vty_out (vty, "%s", VTY_NEWLINE);
500
501#define ONE_DAY_SECOND 60*60*24
502#define ONE_WEEK_SECOND 60*60*24*7
503 if (rib->type == ZEBRA_ROUTE_RIP
504 || rib->type == ZEBRA_ROUTE_OSPF
jardin9e867fe2003-12-23 08:56:18 +0000505 || rib->type == ZEBRA_ROUTE_ISIS
paul718e3742002-12-13 20:15:29 +0000506 || rib->type == ZEBRA_ROUTE_BGP)
507 {
508 time_t uptime;
509 struct tm *tm;
510
511 uptime = time (NULL);
512 uptime -= rib->uptime;
513 tm = gmtime (&uptime);
514
515 vty_out (vty, " Last update ");
516
517 if (uptime < ONE_DAY_SECOND)
518 vty_out (vty, "%02d:%02d:%02d",
519 tm->tm_hour, tm->tm_min, tm->tm_sec);
520 else if (uptime < ONE_WEEK_SECOND)
521 vty_out (vty, "%dd%02dh%02dm",
522 tm->tm_yday, tm->tm_hour, tm->tm_min);
523 else
524 vty_out (vty, "%02dw%dd%02dh",
525 tm->tm_yday/7,
526 tm->tm_yday - ((tm->tm_yday/7) * 7), tm->tm_hour);
527 vty_out (vty, " ago%s", VTY_NEWLINE);
528 }
529
530 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
531 {
532 vty_out (vty, " %c",
533 CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB) ? '*' : ' ');
534
535 switch (nexthop->type)
536 {
537 case NEXTHOP_TYPE_IPV4:
538 case NEXTHOP_TYPE_IPV4_IFINDEX:
539 vty_out (vty, " %s", inet_ntoa (nexthop->gate.ipv4));
540 if (nexthop->ifindex)
541 vty_out (vty, ", via %s", ifindex2ifname (nexthop->ifindex));
542 break;
543 case NEXTHOP_TYPE_IFINDEX:
544 vty_out (vty, " directly connected, %s",
545 ifindex2ifname (nexthop->ifindex));
546 break;
547 case NEXTHOP_TYPE_IFNAME:
548 vty_out (vty, " directly connected, %s", nexthop->ifname);
549 break;
paul595db7f2003-05-25 21:35:06 +0000550 case NEXTHOP_TYPE_BLACKHOLE:
paul7021c422003-07-15 12:52:22 +0000551 vty_out (vty, " directly connected, Null0");
paul595db7f2003-05-25 21:35:06 +0000552 break;
paul7021c422003-07-15 12:52:22 +0000553 default:
paul718e3742002-12-13 20:15:29 +0000554 break;
555 }
556 if (! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
557 vty_out (vty, " inactive");
558
559 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
560 {
561 vty_out (vty, " (recursive");
562
563 switch (nexthop->rtype)
564 {
565 case NEXTHOP_TYPE_IPV4:
566 case NEXTHOP_TYPE_IPV4_IFINDEX:
567 vty_out (vty, " via %s)", inet_ntoa (nexthop->rgate.ipv4));
568 break;
569 case NEXTHOP_TYPE_IFINDEX:
570 case NEXTHOP_TYPE_IFNAME:
571 vty_out (vty, " is directly connected, %s)",
572 ifindex2ifname (nexthop->rifindex));
573 break;
574 default:
575 break;
576 }
577 }
578 vty_out (vty, "%s", VTY_NEWLINE);
579 }
580 vty_out (vty, "%s", VTY_NEWLINE);
581 }
582}
583
paula1ac18c2005-06-28 17:17:12 +0000584static void
paul718e3742002-12-13 20:15:29 +0000585vty_show_ip_route (struct vty *vty, struct route_node *rn, struct rib *rib)
586{
587 struct nexthop *nexthop;
588 int len = 0;
589 char buf[BUFSIZ];
590
591 /* Nexthop information. */
592 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
593 {
594 if (nexthop == rib->nexthop)
595 {
596 /* Prefix information. */
597 len = vty_out (vty, "%c%c%c %s/%d",
ajsf52d13c2005-10-01 17:38:06 +0000598 zebra_route_char (rib->type),
paul718e3742002-12-13 20:15:29 +0000599 CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED)
600 ? '>' : ' ',
601 CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)
602 ? '*' : ' ',
603 inet_ntop (AF_INET, &rn->p.u.prefix, buf, BUFSIZ),
604 rn->p.prefixlen);
605
606 /* Distance and metric display. */
607 if (rib->type != ZEBRA_ROUTE_CONNECT
608 && rib->type != ZEBRA_ROUTE_KERNEL)
609 len += vty_out (vty, " [%d/%d]", rib->distance,
610 rib->metric);
611 }
612 else
613 vty_out (vty, " %c%*c",
614 CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)
615 ? '*' : ' ',
616 len - 3, ' ');
617
618 switch (nexthop->type)
619 {
620 case NEXTHOP_TYPE_IPV4:
621 case NEXTHOP_TYPE_IPV4_IFINDEX:
622 vty_out (vty, " via %s", inet_ntoa (nexthop->gate.ipv4));
623 if (nexthop->ifindex)
624 vty_out (vty, ", %s", ifindex2ifname (nexthop->ifindex));
625 break;
626 case NEXTHOP_TYPE_IFINDEX:
627 vty_out (vty, " is directly connected, %s",
628 ifindex2ifname (nexthop->ifindex));
629 break;
630 case NEXTHOP_TYPE_IFNAME:
631 vty_out (vty, " is directly connected, %s", nexthop->ifname);
632 break;
paul595db7f2003-05-25 21:35:06 +0000633 case NEXTHOP_TYPE_BLACKHOLE:
paul7021c422003-07-15 12:52:22 +0000634 vty_out (vty, " is directly connected, Null0");
paul595db7f2003-05-25 21:35:06 +0000635 break;
paul7021c422003-07-15 12:52:22 +0000636 default:
paul718e3742002-12-13 20:15:29 +0000637 break;
638 }
639 if (! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
640 vty_out (vty, " inactive");
641
642 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
643 {
644 vty_out (vty, " (recursive");
645
646 switch (nexthop->rtype)
647 {
648 case NEXTHOP_TYPE_IPV4:
649 case NEXTHOP_TYPE_IPV4_IFINDEX:
650 vty_out (vty, " via %s)", inet_ntoa (nexthop->rgate.ipv4));
651 break;
652 case NEXTHOP_TYPE_IFINDEX:
653 case NEXTHOP_TYPE_IFNAME:
654 vty_out (vty, " is directly connected, %s)",
655 ifindex2ifname (nexthop->rifindex));
656 break;
657 default:
658 break;
659 }
660 }
661
hasso81dfcaa2003-05-25 19:21:25 +0000662 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_BLACKHOLE))
663 vty_out (vty, ", bh");
664 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_REJECT))
665 vty_out (vty, ", rej");
666
paul718e3742002-12-13 20:15:29 +0000667 if (rib->type == ZEBRA_ROUTE_RIP
668 || rib->type == ZEBRA_ROUTE_OSPF
jardin9e867fe2003-12-23 08:56:18 +0000669 || rib->type == ZEBRA_ROUTE_ISIS
paul718e3742002-12-13 20:15:29 +0000670 || rib->type == ZEBRA_ROUTE_BGP)
671 {
672 time_t uptime;
673 struct tm *tm;
674
675 uptime = time (NULL);
676 uptime -= rib->uptime;
677 tm = gmtime (&uptime);
678
679#define ONE_DAY_SECOND 60*60*24
680#define ONE_WEEK_SECOND 60*60*24*7
681
682 if (uptime < ONE_DAY_SECOND)
683 vty_out (vty, ", %02d:%02d:%02d",
684 tm->tm_hour, tm->tm_min, tm->tm_sec);
685 else if (uptime < ONE_WEEK_SECOND)
686 vty_out (vty, ", %dd%02dh%02dm",
687 tm->tm_yday, tm->tm_hour, tm->tm_min);
688 else
689 vty_out (vty, ", %02dw%dd%02dh",
690 tm->tm_yday/7,
691 tm->tm_yday - ((tm->tm_yday/7) * 7), tm->tm_hour);
692 }
693 vty_out (vty, "%s", VTY_NEWLINE);
694 }
695}
696
hasso39db97e2004-10-12 20:50:58 +0000697#define SHOW_ROUTE_V4_HEADER "Codes: K - kernel route, C - connected, " \
698 "S - static, R - RIP, O - OSPF,%s I - ISIS, B - BGP, " \
699 "> - selected route, * - FIB route%s%s"
paul718e3742002-12-13 20:15:29 +0000700
701DEFUN (show_ip_route,
702 show_ip_route_cmd,
703 "show ip route",
704 SHOW_STR
705 IP_STR
706 "IP routing table\n")
707{
708 struct route_table *table;
709 struct route_node *rn;
710 struct rib *rib;
711 int first = 1;
712
713 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
714 if (! table)
715 return CMD_SUCCESS;
716
717 /* Show all IPv4 routes. */
718 for (rn = route_top (table); rn; rn = route_next (rn))
719 for (rib = rn->info; rib; rib = rib->next)
720 {
721 if (first)
722 {
723 vty_out (vty, SHOW_ROUTE_V4_HEADER, VTY_NEWLINE, VTY_NEWLINE,
724 VTY_NEWLINE);
725 first = 0;
726 }
727 vty_show_ip_route (vty, rn, rib);
728 }
729 return CMD_SUCCESS;
730}
731
732DEFUN (show_ip_route_prefix_longer,
733 show_ip_route_prefix_longer_cmd,
734 "show ip route A.B.C.D/M longer-prefixes",
735 SHOW_STR
736 IP_STR
737 "IP routing table\n"
738 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
739 "Show route matching the specified Network/Mask pair only\n")
740{
741 struct route_table *table;
742 struct route_node *rn;
743 struct rib *rib;
744 struct prefix p;
745 int ret;
746 int first = 1;
747
748 ret = str2prefix (argv[0], &p);
749 if (! ret)
750 {
751 vty_out (vty, "%% Malformed Prefix%s", VTY_NEWLINE);
752 return CMD_WARNING;
753 }
754
755 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
756 if (! table)
757 return CMD_SUCCESS;
758
759 /* Show matched type IPv4 routes. */
760 for (rn = route_top (table); rn; rn = route_next (rn))
761 for (rib = rn->info; rib; rib = rib->next)
762 if (prefix_match (&p, &rn->p))
763 {
764 if (first)
765 {
766 vty_out (vty, SHOW_ROUTE_V4_HEADER, VTY_NEWLINE,
767 VTY_NEWLINE, VTY_NEWLINE);
768 first = 0;
769 }
770 vty_show_ip_route (vty, rn, rib);
771 }
772 return CMD_SUCCESS;
773}
774
775DEFUN (show_ip_route_supernets,
776 show_ip_route_supernets_cmd,
777 "show ip route supernets-only",
778 SHOW_STR
779 IP_STR
780 "IP routing table\n"
781 "Show supernet entries only\n")
782{
783 struct route_table *table;
784 struct route_node *rn;
785 struct rib *rib;
786 u_int32_t addr;
787 int first = 1;
788
789 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
790 if (! table)
791 return CMD_SUCCESS;
792
793 /* Show matched type IPv4 routes. */
794 for (rn = route_top (table); rn; rn = route_next (rn))
795 for (rib = rn->info; rib; rib = rib->next)
796 {
797 addr = ntohl (rn->p.u.prefix4.s_addr);
798
799 if ((IN_CLASSC (addr) && rn->p.prefixlen < 24)
800 || (IN_CLASSB (addr) && rn->p.prefixlen < 16)
801 || (IN_CLASSA (addr) && rn->p.prefixlen < 8))
802 {
803 if (first)
804 {
805 vty_out (vty, SHOW_ROUTE_V4_HEADER, VTY_NEWLINE,
806 VTY_NEWLINE, VTY_NEWLINE);
807 first = 0;
808 }
809 vty_show_ip_route (vty, rn, rib);
810 }
811 }
812 return CMD_SUCCESS;
813}
814
815DEFUN (show_ip_route_protocol,
816 show_ip_route_protocol_cmd,
hasso39ff11d2004-10-12 15:55:19 +0000817 "show ip route (bgp|connected|isis|kernel|ospf|rip|static)",
paul718e3742002-12-13 20:15:29 +0000818 SHOW_STR
819 IP_STR
820 "IP routing table\n"
821 "Border Gateway Protocol (BGP)\n"
822 "Connected\n"
hasso39ff11d2004-10-12 15:55:19 +0000823 "ISO IS-IS (ISIS)\n"
paul718e3742002-12-13 20:15:29 +0000824 "Kernel\n"
825 "Open Shortest Path First (OSPF)\n"
826 "Routing Information Protocol (RIP)\n"
827 "Static routes\n")
828{
829 int type;
830 struct route_table *table;
831 struct route_node *rn;
832 struct rib *rib;
833 int first = 1;
834
835 if (strncmp (argv[0], "b", 1) == 0)
836 type = ZEBRA_ROUTE_BGP;
837 else if (strncmp (argv[0], "c", 1) == 0)
838 type = ZEBRA_ROUTE_CONNECT;
839 else if (strncmp (argv[0], "k", 1) ==0)
840 type = ZEBRA_ROUTE_KERNEL;
841 else if (strncmp (argv[0], "o", 1) == 0)
842 type = ZEBRA_ROUTE_OSPF;
jardin9e867fe2003-12-23 08:56:18 +0000843 else if (strncmp (argv[0], "i", 1) == 0)
844 type = ZEBRA_ROUTE_ISIS;
paul718e3742002-12-13 20:15:29 +0000845 else if (strncmp (argv[0], "r", 1) == 0)
846 type = ZEBRA_ROUTE_RIP;
847 else if (strncmp (argv[0], "s", 1) == 0)
848 type = ZEBRA_ROUTE_STATIC;
849 else
850 {
851 vty_out (vty, "Unknown route type%s", VTY_NEWLINE);
852 return CMD_WARNING;
853 }
854
855 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
856 if (! table)
857 return CMD_SUCCESS;
858
859 /* Show matched type IPv4 routes. */
860 for (rn = route_top (table); rn; rn = route_next (rn))
861 for (rib = rn->info; rib; rib = rib->next)
862 if (rib->type == type)
863 {
864 if (first)
865 {
866 vty_out (vty, SHOW_ROUTE_V4_HEADER,
867 VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE);
868 first = 0;
869 }
870 vty_show_ip_route (vty, rn, rib);
871 }
872 return CMD_SUCCESS;
873}
874
875DEFUN (show_ip_route_addr,
876 show_ip_route_addr_cmd,
877 "show ip route A.B.C.D",
878 SHOW_STR
879 IP_STR
880 "IP routing table\n"
881 "Network in the IP routing table to display\n")
882{
883 int ret;
884 struct prefix_ipv4 p;
885 struct route_table *table;
886 struct route_node *rn;
887
888 ret = str2prefix_ipv4 (argv[0], &p);
889 if (ret <= 0)
890 {
891 vty_out (vty, "%% Malformed IPv4 address%s", VTY_NEWLINE);
892 return CMD_WARNING;
893 }
894
895 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
896 if (! table)
897 return CMD_SUCCESS;
898
899 rn = route_node_match (table, (struct prefix *) &p);
900 if (! rn)
901 {
902 vty_out (vty, "%% Network not in table%s", VTY_NEWLINE);
903 return CMD_WARNING;
904 }
905
906 vty_show_ip_route_detail (vty, rn);
907
908 route_unlock_node (rn);
909
910 return CMD_SUCCESS;
911}
912
913DEFUN (show_ip_route_prefix,
914 show_ip_route_prefix_cmd,
915 "show ip route A.B.C.D/M",
916 SHOW_STR
917 IP_STR
918 "IP routing table\n"
919 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n")
920{
921 int ret;
922 struct prefix_ipv4 p;
923 struct route_table *table;
924 struct route_node *rn;
925
926 ret = str2prefix_ipv4 (argv[0], &p);
927 if (ret <= 0)
928 {
929 vty_out (vty, "%% Malformed IPv4 address%s", VTY_NEWLINE);
930 return CMD_WARNING;
931 }
932
933 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
934 if (! table)
935 return CMD_SUCCESS;
936
937 rn = route_node_match (table, (struct prefix *) &p);
938 if (! rn || rn->p.prefixlen != p.prefixlen)
939 {
940 vty_out (vty, "%% Network not in table%s", VTY_NEWLINE);
941 return CMD_WARNING;
942 }
943
944 vty_show_ip_route_detail (vty, rn);
945
946 route_unlock_node (rn);
947
948 return CMD_SUCCESS;
949}
950
paula1ac18c2005-06-28 17:17:12 +0000951static void
paul718e3742002-12-13 20:15:29 +0000952zebra_show_ip_route (struct vty *vty, struct vrf *vrf)
953{
954 vty_out (vty, "IP routing table name is %s(%d)%s",
955 vrf->name ? vrf->name : "", vrf->id, VTY_NEWLINE);
956
957 vty_out (vty, "Route Source Networks%s", VTY_NEWLINE);
958 vty_out (vty, "connected %d%s", 0, VTY_NEWLINE);
959 vty_out (vty, "static %d%s", 0, VTY_NEWLINE);
960 vty_out (vty, "rip %d%s", 0, VTY_NEWLINE);
961
962 vty_out (vty, "bgp %d%s", 0, VTY_NEWLINE);
963 vty_out (vty, " External: %d Internal: %d Local: %d%s",
964 0, 0, 0, VTY_NEWLINE);
965
966 vty_out (vty, "ospf %d%s", 0, VTY_NEWLINE);
967 vty_out (vty,
968 " Intra-area: %d Inter-area: %d External-1: %d External-2: %d%s",
969 0, 0, 0, 0, VTY_NEWLINE);
970 vty_out (vty, " NSSA External-1: %d NSSA External-2: %d%s",
971 0, 0, VTY_NEWLINE);
972
973 vty_out (vty, "internal %d%s", 0, VTY_NEWLINE);
974 vty_out (vty, "Total %d%s", 0, VTY_NEWLINE);
975}
976
977/* Show route summary. */
978DEFUN (show_ip_route_summary,
979 show_ip_route_summary_cmd,
980 "show ip route summary",
981 SHOW_STR
982 IP_STR
983 "IP routing table\n"
984 "Summary of all routes\n")
985{
986 struct vrf *vrf;
987
988 /* Default table id is zero. */
989 vrf = vrf_lookup (0);
990 if (! vrf)
991 {
992 vty_out (vty, "%% No Default-IP-Routing-Table%s", VTY_NEWLINE);
993 return CMD_WARNING;
994 }
995
996 zebra_show_ip_route (vty, vrf);
997
998 return CMD_SUCCESS;
999}
1000
1001/* Write IPv4 static route configuration. */
paula1ac18c2005-06-28 17:17:12 +00001002static int
paul718e3742002-12-13 20:15:29 +00001003static_config_ipv4 (struct vty *vty)
1004{
1005 struct route_node *rn;
1006 struct static_ipv4 *si;
1007 struct route_table *stable;
1008 int write;
1009
1010 write = 0;
1011
1012 /* Lookup table. */
1013 stable = vrf_static_table (AFI_IP, SAFI_UNICAST, 0);
1014 if (! stable)
1015 return -1;
1016
1017 for (rn = route_top (stable); rn; rn = route_next (rn))
1018 for (si = rn->info; si; si = si->next)
1019 {
paul7021c422003-07-15 12:52:22 +00001020 vty_out (vty, "ip route %s/%d", inet_ntoa (rn->p.u.prefix4),
1021 rn->p.prefixlen);
paul718e3742002-12-13 20:15:29 +00001022
paul7021c422003-07-15 12:52:22 +00001023 switch (si->type)
1024 {
1025 case STATIC_IPV4_GATEWAY:
1026 vty_out (vty, " %s", inet_ntoa (si->gate.ipv4));
1027 break;
1028 case STATIC_IPV4_IFNAME:
1029 vty_out (vty, " %s", si->gate.ifname);
1030 break;
1031 case STATIC_IPV4_BLACKHOLE:
1032 vty_out (vty, " Null0");
1033 break;
1034 }
1035
1036 /* flags are incompatible with STATIC_IPV4_BLACKHOLE */
1037 if (si->type != STATIC_IPV4_BLACKHOLE)
1038 {
1039 if (CHECK_FLAG(si->flags, ZEBRA_FLAG_REJECT))
1040 vty_out (vty, " %s", "reject");
paul718e3742002-12-13 20:15:29 +00001041
paul7021c422003-07-15 12:52:22 +00001042 if (CHECK_FLAG(si->flags, ZEBRA_FLAG_BLACKHOLE))
1043 vty_out (vty, " %s", "blackhole");
1044 }
hasso81dfcaa2003-05-25 19:21:25 +00001045
paul7021c422003-07-15 12:52:22 +00001046 if (si->distance != ZEBRA_STATIC_DISTANCE_DEFAULT)
1047 vty_out (vty, " %d", si->distance);
hasso81dfcaa2003-05-25 19:21:25 +00001048
paul7021c422003-07-15 12:52:22 +00001049 vty_out (vty, "%s", VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00001050
paul7021c422003-07-15 12:52:22 +00001051 write = 1;
paul718e3742002-12-13 20:15:29 +00001052 }
1053 return write;
1054}
1055
1056#ifdef HAVE_IPV6
1057/* General fucntion for IPv6 static route. */
paula1ac18c2005-06-28 17:17:12 +00001058static int
hasso39db97e2004-10-12 20:50:58 +00001059static_ipv6_func (struct vty *vty, int add_cmd, const char *dest_str,
1060 const char *gate_str, const char *ifname,
1061 const char *flag_str, const char *distance_str)
paul718e3742002-12-13 20:15:29 +00001062{
1063 int ret;
1064 u_char distance;
1065 struct prefix p;
1066 struct in6_addr *gate = NULL;
1067 struct in6_addr gate_addr;
1068 u_char type = 0;
1069 int table = 0;
hasso81dfcaa2003-05-25 19:21:25 +00001070 u_char flag = 0;
paul718e3742002-12-13 20:15:29 +00001071
1072 ret = str2prefix (dest_str, &p);
1073 if (ret <= 0)
1074 {
1075 vty_out (vty, "%% Malformed address%s", VTY_NEWLINE);
1076 return CMD_WARNING;
1077 }
1078
1079 /* Apply mask for given prefix. */
1080 apply_mask (&p);
1081
hasso81dfcaa2003-05-25 19:21:25 +00001082 /* Route flags */
1083 if (flag_str) {
1084 switch(flag_str[0]) {
1085 case 'r':
1086 case 'R': /* XXX */
1087 SET_FLAG (flag, ZEBRA_FLAG_REJECT);
1088 break;
1089 case 'b':
1090 case 'B': /* XXX */
1091 SET_FLAG (flag, ZEBRA_FLAG_BLACKHOLE);
1092 break;
1093 default:
1094 vty_out (vty, "%% Malformed flag %s %s", flag_str, VTY_NEWLINE);
paul595db7f2003-05-25 21:35:06 +00001095 return CMD_WARNING;
hasso81dfcaa2003-05-25 19:21:25 +00001096 }
1097 }
1098
paul718e3742002-12-13 20:15:29 +00001099 /* Administrative distance. */
1100 if (distance_str)
1101 distance = atoi (distance_str);
1102 else
1103 distance = ZEBRA_STATIC_DISTANCE_DEFAULT;
1104
1105 /* When gateway is valid IPv6 addrees, then gate is treated as
1106 nexthop address other case gate is treated as interface name. */
1107 ret = inet_pton (AF_INET6, gate_str, &gate_addr);
1108
1109 if (ifname)
1110 {
1111 /* When ifname is specified. It must be come with gateway
1112 address. */
1113 if (ret != 1)
1114 {
1115 vty_out (vty, "%% Malformed address%s", VTY_NEWLINE);
1116 return CMD_WARNING;
1117 }
1118 type = STATIC_IPV6_GATEWAY_IFNAME;
1119 gate = &gate_addr;
1120 }
1121 else
1122 {
1123 if (ret == 1)
1124 {
1125 type = STATIC_IPV6_GATEWAY;
1126 gate = &gate_addr;
1127 }
1128 else
1129 {
1130 type = STATIC_IPV6_IFNAME;
1131 ifname = gate_str;
1132 }
1133 }
1134
1135 if (add_cmd)
hasso81dfcaa2003-05-25 19:21:25 +00001136 static_add_ipv6 (&p, type, gate, ifname, flag, distance, table);
paul718e3742002-12-13 20:15:29 +00001137 else
1138 static_delete_ipv6 (&p, type, gate, ifname, distance, table);
1139
1140 return CMD_SUCCESS;
1141}
1142
1143DEFUN (ipv6_route,
1144 ipv6_route_cmd,
1145 "ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE)",
1146 IP_STR
1147 "Establish static routes\n"
1148 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1149 "IPv6 gateway address\n"
1150 "IPv6 gateway interface name\n")
1151{
hasso81dfcaa2003-05-25 19:21:25 +00001152 return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, NULL, NULL);
1153}
1154
1155DEFUN (ipv6_route_flags,
1156 ipv6_route_flags_cmd,
1157 "ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) (reject|blackhole)",
1158 IP_STR
1159 "Establish static routes\n"
1160 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1161 "IPv6 gateway address\n"
1162 "IPv6 gateway interface name\n"
1163 "Emit an ICMP unreachable when matched\n"
1164 "Silently discard pkts when matched\n")
1165{
1166 return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, argv[2], NULL);
paul718e3742002-12-13 20:15:29 +00001167}
1168
1169DEFUN (ipv6_route_ifname,
1170 ipv6_route_ifname_cmd,
1171 "ipv6 route X:X::X:X/M X:X::X:X INTERFACE",
1172 IP_STR
1173 "Establish static routes\n"
1174 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1175 "IPv6 gateway address\n"
1176 "IPv6 gateway interface name\n")
1177{
hasso81dfcaa2003-05-25 19:21:25 +00001178 return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], NULL, NULL);
1179}
1180
1181DEFUN (ipv6_route_ifname_flags,
1182 ipv6_route_ifname_flags_cmd,
1183 "ipv6 route X:X::X:X/M X:X::X:X INTERFACE (reject|blackhole)",
1184 IP_STR
1185 "Establish static routes\n"
1186 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1187 "IPv6 gateway address\n"
1188 "IPv6 gateway interface name\n"
1189 "Emit an ICMP unreachable when matched\n"
1190 "Silently discard pkts when matched\n")
1191{
1192 return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], argv[3], NULL);
paul718e3742002-12-13 20:15:29 +00001193}
1194
1195DEFUN (ipv6_route_pref,
1196 ipv6_route_pref_cmd,
1197 "ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) <1-255>",
1198 IP_STR
1199 "Establish static routes\n"
1200 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1201 "IPv6 gateway address\n"
1202 "IPv6 gateway interface name\n"
1203 "Distance value for this prefix\n")
1204{
hasso81dfcaa2003-05-25 19:21:25 +00001205 return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, NULL, argv[2]);
1206}
1207
1208DEFUN (ipv6_route_flags_pref,
1209 ipv6_route_flags_pref_cmd,
1210 "ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) (reject|blackhole) <1-255>",
1211 IP_STR
1212 "Establish static routes\n"
1213 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1214 "IPv6 gateway address\n"
1215 "IPv6 gateway interface name\n"
1216 "Emit an ICMP unreachable when matched\n"
1217 "Silently discard pkts when matched\n"
1218 "Distance value for this prefix\n")
1219{
1220 return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, argv[2], argv[3]);
paul718e3742002-12-13 20:15:29 +00001221}
1222
1223DEFUN (ipv6_route_ifname_pref,
1224 ipv6_route_ifname_pref_cmd,
1225 "ipv6 route X:X::X:X/M X:X::X:X INTERFACE <1-255>",
1226 IP_STR
1227 "Establish static routes\n"
1228 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1229 "IPv6 gateway address\n"
1230 "IPv6 gateway interface name\n"
1231 "Distance value for this prefix\n")
1232{
hasso81dfcaa2003-05-25 19:21:25 +00001233 return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], NULL, argv[3]);
1234}
1235
1236DEFUN (ipv6_route_ifname_flags_pref,
1237 ipv6_route_ifname_flags_pref_cmd,
1238 "ipv6 route X:X::X:X/M X:X::X:X INTERFACE (reject|blackhole) <1-255>",
1239 IP_STR
1240 "Establish static routes\n"
1241 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1242 "IPv6 gateway address\n"
1243 "IPv6 gateway interface name\n"
1244 "Emit an ICMP unreachable when matched\n"
1245 "Silently discard pkts when matched\n"
1246 "Distance value for this prefix\n")
1247{
1248 return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], argv[3], argv[4]);
paul718e3742002-12-13 20:15:29 +00001249}
1250
1251DEFUN (no_ipv6_route,
1252 no_ipv6_route_cmd,
1253 "no ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE)",
1254 NO_STR
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{
hasso81dfcaa2003-05-25 19:21:25 +00001261 return static_ipv6_func (vty, 0, argv[0], argv[1], NULL, NULL, NULL);
paul718e3742002-12-13 20:15:29 +00001262}
1263
hasso81dfcaa2003-05-25 19:21:25 +00001264ALIAS (no_ipv6_route,
1265 no_ipv6_route_flags_cmd,
1266 "no ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) (reject|blackhole)",
1267 NO_STR
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
paul718e3742002-12-13 20:15:29 +00001276DEFUN (no_ipv6_route_ifname,
1277 no_ipv6_route_ifname_cmd,
1278 "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE",
1279 NO_STR
1280 IP_STR
1281 "Establish static routes\n"
1282 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1283 "IPv6 gateway address\n"
1284 "IPv6 gateway interface name\n")
1285{
hasso81dfcaa2003-05-25 19:21:25 +00001286 return static_ipv6_func (vty, 0, argv[0], argv[1], argv[2], NULL, NULL);
paul718e3742002-12-13 20:15:29 +00001287}
1288
hasso81dfcaa2003-05-25 19:21:25 +00001289ALIAS (no_ipv6_route_ifname,
1290 no_ipv6_route_ifname_flags_cmd,
1291 "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE (reject|blackhole)",
1292 NO_STR
1293 IP_STR
1294 "Establish static routes\n"
1295 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1296 "IPv6 gateway address\n"
1297 "IPv6 gateway interface name\n"
1298 "Emit an ICMP unreachable when matched\n"
1299 "Silently discard pkts when matched\n")
1300
paul718e3742002-12-13 20:15:29 +00001301DEFUN (no_ipv6_route_pref,
1302 no_ipv6_route_pref_cmd,
1303 "no ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) <1-255>",
1304 NO_STR
1305 IP_STR
1306 "Establish static routes\n"
1307 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1308 "IPv6 gateway address\n"
1309 "IPv6 gateway interface name\n"
1310 "Distance value for this prefix\n")
1311{
hasso81dfcaa2003-05-25 19:21:25 +00001312 return static_ipv6_func (vty, 0, argv[0], argv[1], NULL, NULL, argv[2]);
1313}
1314
1315DEFUN (no_ipv6_route_flags_pref,
1316 no_ipv6_route_flags_pref_cmd,
1317 "no ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) (reject|blackhole) <1-255>",
1318 NO_STR
1319 IP_STR
1320 "Establish static routes\n"
1321 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1322 "IPv6 gateway address\n"
1323 "IPv6 gateway interface name\n"
1324 "Emit an ICMP unreachable when matched\n"
1325 "Silently discard pkts when matched\n"
1326 "Distance value for this prefix\n")
1327{
1328 /* We do not care about argv[2] */
1329 return static_ipv6_func (vty, 0, argv[0], argv[1], NULL, argv[2], argv[3]);
paul718e3742002-12-13 20:15:29 +00001330}
1331
1332DEFUN (no_ipv6_route_ifname_pref,
1333 no_ipv6_route_ifname_pref_cmd,
1334 "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE <1-255>",
1335 NO_STR
1336 IP_STR
1337 "Establish static routes\n"
1338 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1339 "IPv6 gateway address\n"
1340 "IPv6 gateway interface name\n"
1341 "Distance value for this prefix\n")
1342{
hasso81dfcaa2003-05-25 19:21:25 +00001343 return static_ipv6_func (vty, 0, argv[0], argv[1], argv[2], NULL, argv[3]);
1344}
1345
1346DEFUN (no_ipv6_route_ifname_flags_pref,
1347 no_ipv6_route_ifname_flags_pref_cmd,
1348 "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE (reject|blackhole) <1-255>",
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 "Distance value for this prefix\n")
1358{
1359 return static_ipv6_func (vty, 0, argv[0], argv[1], argv[2], argv[3], argv[4]);
paul718e3742002-12-13 20:15:29 +00001360}
1361
paul595db7f2003-05-25 21:35:06 +00001362/* New RIB. Detailed information for IPv6 route. */
paula1ac18c2005-06-28 17:17:12 +00001363static void
paul718e3742002-12-13 20:15:29 +00001364vty_show_ipv6_route_detail (struct vty *vty, struct route_node *rn)
1365{
1366 struct rib *rib;
1367 struct nexthop *nexthop;
1368 char buf[BUFSIZ];
1369
1370 for (rib = rn->info; rib; rib = rib->next)
1371 {
1372 vty_out (vty, "Routing entry for %s/%d%s",
1373 inet_ntop (AF_INET6, &rn->p.u.prefix6, buf, BUFSIZ),
1374 rn->p.prefixlen,
1375 VTY_NEWLINE);
ajsf52d13c2005-10-01 17:38:06 +00001376 vty_out (vty, " Known via \"%s\"", zebra_route_string (rib->type));
paul718e3742002-12-13 20:15:29 +00001377 vty_out (vty, ", distance %d, metric %d", rib->distance, rib->metric);
1378 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
1379 vty_out (vty, ", best");
1380 if (rib->refcnt)
1381 vty_out (vty, ", refcnt %ld", rib->refcnt);
hasso81dfcaa2003-05-25 19:21:25 +00001382 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_BLACKHOLE))
1383 vty_out (vty, ", blackhole");
1384 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_REJECT))
1385 vty_out (vty, ", reject");
paul718e3742002-12-13 20:15:29 +00001386 vty_out (vty, "%s", VTY_NEWLINE);
1387
1388#define ONE_DAY_SECOND 60*60*24
1389#define ONE_WEEK_SECOND 60*60*24*7
1390 if (rib->type == ZEBRA_ROUTE_RIPNG
1391 || rib->type == ZEBRA_ROUTE_OSPF6
jardin9e867fe2003-12-23 08:56:18 +00001392 || rib->type == ZEBRA_ROUTE_ISIS
paul718e3742002-12-13 20:15:29 +00001393 || rib->type == ZEBRA_ROUTE_BGP)
1394 {
1395 time_t uptime;
1396 struct tm *tm;
1397
1398 uptime = time (NULL);
1399 uptime -= rib->uptime;
1400 tm = gmtime (&uptime);
1401
1402 vty_out (vty, " Last update ");
1403
1404 if (uptime < ONE_DAY_SECOND)
1405 vty_out (vty, "%02d:%02d:%02d",
1406 tm->tm_hour, tm->tm_min, tm->tm_sec);
1407 else if (uptime < ONE_WEEK_SECOND)
1408 vty_out (vty, "%dd%02dh%02dm",
1409 tm->tm_yday, tm->tm_hour, tm->tm_min);
1410 else
1411 vty_out (vty, "%02dw%dd%02dh",
1412 tm->tm_yday/7,
1413 tm->tm_yday - ((tm->tm_yday/7) * 7), tm->tm_hour);
1414 vty_out (vty, " ago%s", VTY_NEWLINE);
1415 }
1416
1417 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1418 {
1419 vty_out (vty, " %c",
1420 CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB) ? '*' : ' ');
1421
1422 switch (nexthop->type)
1423 {
1424 case NEXTHOP_TYPE_IPV6:
1425 case NEXTHOP_TYPE_IPV6_IFINDEX:
1426 case NEXTHOP_TYPE_IPV6_IFNAME:
1427 vty_out (vty, " %s",
1428 inet_ntop (AF_INET6, &nexthop->gate.ipv6, buf, BUFSIZ));
1429 if (nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME)
1430 vty_out (vty, ", %s", nexthop->ifname);
1431 else if (nexthop->ifindex)
1432 vty_out (vty, ", via %s", ifindex2ifname (nexthop->ifindex));
1433 break;
1434 case NEXTHOP_TYPE_IFINDEX:
1435 vty_out (vty, " directly connected, %s",
1436 ifindex2ifname (nexthop->ifindex));
1437 break;
1438 case NEXTHOP_TYPE_IFNAME:
1439 vty_out (vty, " directly connected, %s",
1440 nexthop->ifname);
1441 break;
1442 default:
1443 break;
1444 }
1445 if (! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
1446 vty_out (vty, " inactive");
1447
1448 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
1449 {
1450 vty_out (vty, " (recursive");
1451
1452 switch (nexthop->rtype)
1453 {
1454 case NEXTHOP_TYPE_IPV6:
1455 case NEXTHOP_TYPE_IPV6_IFINDEX:
1456 case NEXTHOP_TYPE_IPV6_IFNAME:
1457 vty_out (vty, " via %s)",
1458 inet_ntop (AF_INET6, &nexthop->rgate.ipv6,
1459 buf, BUFSIZ));
1460 if (nexthop->rifindex)
1461 vty_out (vty, ", %s", ifindex2ifname (nexthop->rifindex));
1462 break;
1463 case NEXTHOP_TYPE_IFINDEX:
1464 case NEXTHOP_TYPE_IFNAME:
1465 vty_out (vty, " is directly connected, %s)",
1466 ifindex2ifname (nexthop->rifindex));
1467 break;
1468 default:
1469 break;
1470 }
1471 }
1472 vty_out (vty, "%s", VTY_NEWLINE);
1473 }
1474 vty_out (vty, "%s", VTY_NEWLINE);
1475 }
1476}
1477
paula1ac18c2005-06-28 17:17:12 +00001478static void
paul718e3742002-12-13 20:15:29 +00001479vty_show_ipv6_route (struct vty *vty, struct route_node *rn,
1480 struct rib *rib)
1481{
1482 struct nexthop *nexthop;
1483 int len = 0;
1484 char buf[BUFSIZ];
1485
1486 /* Nexthop information. */
1487 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1488 {
1489 if (nexthop == rib->nexthop)
1490 {
1491 /* Prefix information. */
1492 len = vty_out (vty, "%c%c%c %s/%d",
ajsf52d13c2005-10-01 17:38:06 +00001493 zebra_route_char (rib->type),
paul718e3742002-12-13 20:15:29 +00001494 CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED)
1495 ? '>' : ' ',
1496 CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)
1497 ? '*' : ' ',
1498 inet_ntop (AF_INET6, &rn->p.u.prefix6, buf, BUFSIZ),
1499 rn->p.prefixlen);
1500
1501 /* Distance and metric display. */
1502 if (rib->type != ZEBRA_ROUTE_CONNECT
1503 && rib->type != ZEBRA_ROUTE_KERNEL)
1504 len += vty_out (vty, " [%d/%d]", rib->distance,
1505 rib->metric);
1506 }
1507 else
1508 vty_out (vty, " %c%*c",
1509 CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)
1510 ? '*' : ' ',
1511 len - 3, ' ');
1512
1513 switch (nexthop->type)
1514 {
1515 case NEXTHOP_TYPE_IPV6:
1516 case NEXTHOP_TYPE_IPV6_IFINDEX:
1517 case NEXTHOP_TYPE_IPV6_IFNAME:
1518 vty_out (vty, " via %s",
1519 inet_ntop (AF_INET6, &nexthop->gate.ipv6, buf, BUFSIZ));
1520 if (nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME)
1521 vty_out (vty, ", %s", nexthop->ifname);
1522 else if (nexthop->ifindex)
1523 vty_out (vty, ", %s", ifindex2ifname (nexthop->ifindex));
1524 break;
1525 case NEXTHOP_TYPE_IFINDEX:
1526 vty_out (vty, " is directly connected, %s",
1527 ifindex2ifname (nexthop->ifindex));
1528 break;
1529 case NEXTHOP_TYPE_IFNAME:
1530 vty_out (vty, " is directly connected, %s",
1531 nexthop->ifname);
1532 break;
1533 default:
1534 break;
1535 }
1536 if (! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
1537 vty_out (vty, " inactive");
1538
1539 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
1540 {
1541 vty_out (vty, " (recursive");
1542
1543 switch (nexthop->rtype)
1544 {
1545 case NEXTHOP_TYPE_IPV6:
1546 case NEXTHOP_TYPE_IPV6_IFINDEX:
1547 case NEXTHOP_TYPE_IPV6_IFNAME:
1548 vty_out (vty, " via %s)",
1549 inet_ntop (AF_INET6, &nexthop->rgate.ipv6,
1550 buf, BUFSIZ));
1551 if (nexthop->rifindex)
1552 vty_out (vty, ", %s", ifindex2ifname (nexthop->rifindex));
1553 break;
1554 case NEXTHOP_TYPE_IFINDEX:
1555 case NEXTHOP_TYPE_IFNAME:
1556 vty_out (vty, " is directly connected, %s)",
1557 ifindex2ifname (nexthop->rifindex));
1558 break;
1559 default:
1560 break;
1561 }
1562 }
1563
hasso81dfcaa2003-05-25 19:21:25 +00001564 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_BLACKHOLE))
1565 vty_out (vty, ", bh");
1566 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_REJECT))
1567 vty_out (vty, ", rej");
1568
paul718e3742002-12-13 20:15:29 +00001569 if (rib->type == ZEBRA_ROUTE_RIPNG
1570 || rib->type == ZEBRA_ROUTE_OSPF6
jardin9e867fe2003-12-23 08:56:18 +00001571 || rib->type == ZEBRA_ROUTE_ISIS
paul718e3742002-12-13 20:15:29 +00001572 || rib->type == ZEBRA_ROUTE_BGP)
1573 {
1574 time_t uptime;
1575 struct tm *tm;
1576
1577 uptime = time (NULL);
1578 uptime -= rib->uptime;
1579 tm = gmtime (&uptime);
1580
1581#define ONE_DAY_SECOND 60*60*24
1582#define ONE_WEEK_SECOND 60*60*24*7
1583
1584 if (uptime < ONE_DAY_SECOND)
1585 vty_out (vty, ", %02d:%02d:%02d",
1586 tm->tm_hour, tm->tm_min, tm->tm_sec);
1587 else if (uptime < ONE_WEEK_SECOND)
1588 vty_out (vty, ", %dd%02dh%02dm",
1589 tm->tm_yday, tm->tm_hour, tm->tm_min);
1590 else
1591 vty_out (vty, ", %02dw%dd%02dh",
1592 tm->tm_yday/7,
1593 tm->tm_yday - ((tm->tm_yday/7) * 7), tm->tm_hour);
1594 }
1595 vty_out (vty, "%s", VTY_NEWLINE);
1596 }
1597}
1598
jardin9e867fe2003-12-23 08:56:18 +00001599#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 +00001600
1601DEFUN (show_ipv6_route,
1602 show_ipv6_route_cmd,
1603 "show ipv6 route",
1604 SHOW_STR
1605 IP_STR
1606 "IPv6 routing table\n")
1607{
1608 struct route_table *table;
1609 struct route_node *rn;
1610 struct rib *rib;
1611 int first = 1;
1612
1613 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
1614 if (! table)
1615 return CMD_SUCCESS;
1616
1617 /* Show all IPv6 route. */
1618 for (rn = route_top (table); rn; rn = route_next (rn))
1619 for (rib = rn->info; rib; rib = rib->next)
1620 {
1621 if (first)
1622 {
1623 vty_out (vty, SHOW_ROUTE_V6_HEADER, VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE);
1624 first = 0;
1625 }
1626 vty_show_ipv6_route (vty, rn, rib);
1627 }
1628 return CMD_SUCCESS;
1629}
1630
1631DEFUN (show_ipv6_route_prefix_longer,
1632 show_ipv6_route_prefix_longer_cmd,
1633 "show ipv6 route X:X::X:X/M longer-prefixes",
1634 SHOW_STR
1635 IP_STR
1636 "IPv6 routing table\n"
1637 "IPv6 prefix\n"
1638 "Show route matching the specified Network/Mask pair only\n")
1639{
1640 struct route_table *table;
1641 struct route_node *rn;
1642 struct rib *rib;
1643 struct prefix p;
1644 int ret;
1645 int first = 1;
1646
1647 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
1648 if (! table)
1649 return CMD_SUCCESS;
1650
1651 ret = str2prefix (argv[0], &p);
1652 if (! ret)
1653 {
1654 vty_out (vty, "%% Malformed Prefix%s", VTY_NEWLINE);
1655 return CMD_WARNING;
1656 }
1657
1658 /* Show matched type IPv6 routes. */
1659 for (rn = route_top (table); rn; rn = route_next (rn))
1660 for (rib = rn->info; rib; rib = rib->next)
1661 if (prefix_match (&p, &rn->p))
1662 {
1663 if (first)
1664 {
1665 vty_out (vty, SHOW_ROUTE_V6_HEADER, VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE);
1666 first = 0;
1667 }
1668 vty_show_ipv6_route (vty, rn, rib);
1669 }
1670 return CMD_SUCCESS;
1671}
1672
1673DEFUN (show_ipv6_route_protocol,
1674 show_ipv6_route_protocol_cmd,
hassob8adec12004-12-18 16:03:28 +00001675 "show ipv6 route (bgp|connected|isis|kernel|ospf6|ripng|static)",
paul718e3742002-12-13 20:15:29 +00001676 SHOW_STR
1677 IP_STR
1678 "IP routing table\n"
1679 "Border Gateway Protocol (BGP)\n"
1680 "Connected\n"
hassob8adec12004-12-18 16:03:28 +00001681 "ISO IS-IS (ISIS)\n"
paul718e3742002-12-13 20:15:29 +00001682 "Kernel\n"
1683 "Open Shortest Path First (OSPFv3)\n"
1684 "Routing Information Protocol (RIPng)\n"
1685 "Static routes\n")
1686{
1687 int type;
1688 struct route_table *table;
1689 struct route_node *rn;
1690 struct rib *rib;
1691 int first = 1;
1692
1693 if (strncmp (argv[0], "b", 1) == 0)
1694 type = ZEBRA_ROUTE_BGP;
1695 else if (strncmp (argv[0], "c", 1) == 0)
1696 type = ZEBRA_ROUTE_CONNECT;
1697 else if (strncmp (argv[0], "k", 1) ==0)
1698 type = ZEBRA_ROUTE_KERNEL;
1699 else if (strncmp (argv[0], "o", 1) == 0)
1700 type = ZEBRA_ROUTE_OSPF6;
jardin9e867fe2003-12-23 08:56:18 +00001701 else if (strncmp (argv[0], "i", 1) == 0)
1702 type = ZEBRA_ROUTE_ISIS;
paul718e3742002-12-13 20:15:29 +00001703 else if (strncmp (argv[0], "r", 1) == 0)
1704 type = ZEBRA_ROUTE_RIPNG;
1705 else if (strncmp (argv[0], "s", 1) == 0)
1706 type = ZEBRA_ROUTE_STATIC;
1707 else
1708 {
1709 vty_out (vty, "Unknown route type%s", VTY_NEWLINE);
1710 return CMD_WARNING;
1711 }
1712
1713 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
1714 if (! table)
1715 return CMD_SUCCESS;
1716
1717 /* Show matched type IPv6 routes. */
1718 for (rn = route_top (table); rn; rn = route_next (rn))
1719 for (rib = rn->info; rib; rib = rib->next)
1720 if (rib->type == type)
1721 {
1722 if (first)
1723 {
1724 vty_out (vty, SHOW_ROUTE_V6_HEADER, VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE);
1725 first = 0;
1726 }
1727 vty_show_ipv6_route (vty, rn, rib);
1728 }
1729 return CMD_SUCCESS;
1730}
1731
1732DEFUN (show_ipv6_route_addr,
1733 show_ipv6_route_addr_cmd,
1734 "show ipv6 route X:X::X:X",
1735 SHOW_STR
1736 IP_STR
1737 "IPv6 routing table\n"
1738 "IPv6 Address\n")
1739{
1740 int ret;
1741 struct prefix_ipv6 p;
1742 struct route_table *table;
1743 struct route_node *rn;
1744
1745 ret = str2prefix_ipv6 (argv[0], &p);
1746 if (ret <= 0)
1747 {
1748 vty_out (vty, "Malformed IPv6 address%s", VTY_NEWLINE);
1749 return CMD_WARNING;
1750 }
1751
1752 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
1753 if (! table)
1754 return CMD_SUCCESS;
1755
1756 rn = route_node_match (table, (struct prefix *) &p);
1757 if (! rn)
1758 {
1759 vty_out (vty, "%% Network not in table%s", VTY_NEWLINE);
1760 return CMD_WARNING;
1761 }
1762
1763 vty_show_ipv6_route_detail (vty, rn);
1764
1765 route_unlock_node (rn);
1766
1767 return CMD_SUCCESS;
1768}
1769
1770DEFUN (show_ipv6_route_prefix,
1771 show_ipv6_route_prefix_cmd,
1772 "show ipv6 route X:X::X:X/M",
1773 SHOW_STR
1774 IP_STR
1775 "IPv6 routing table\n"
1776 "IPv6 prefix\n")
1777{
1778 int ret;
1779 struct prefix_ipv6 p;
1780 struct route_table *table;
1781 struct route_node *rn;
1782
1783 ret = str2prefix_ipv6 (argv[0], &p);
1784 if (ret <= 0)
1785 {
1786 vty_out (vty, "Malformed IPv6 prefix%s", VTY_NEWLINE);
1787 return CMD_WARNING;
1788 }
1789
1790 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
1791 if (! table)
1792 return CMD_SUCCESS;
1793
1794 rn = route_node_match (table, (struct prefix *) &p);
1795 if (! rn || rn->p.prefixlen != p.prefixlen)
1796 {
1797 vty_out (vty, "%% Network not in table%s", VTY_NEWLINE);
1798 return CMD_WARNING;
1799 }
1800
1801 vty_show_ipv6_route_detail (vty, rn);
1802
1803 route_unlock_node (rn);
1804
1805 return CMD_SUCCESS;
1806}
1807
1808
1809/* Write IPv6 static route configuration. */
paula1ac18c2005-06-28 17:17:12 +00001810static int
paul718e3742002-12-13 20:15:29 +00001811static_config_ipv6 (struct vty *vty)
1812{
1813 struct route_node *rn;
1814 struct static_ipv6 *si;
1815 int write;
1816 char buf[BUFSIZ];
1817 struct route_table *stable;
1818
1819 write = 0;
1820
1821 /* Lookup table. */
1822 stable = vrf_static_table (AFI_IP6, SAFI_UNICAST, 0);
1823 if (! stable)
1824 return -1;
1825
1826 for (rn = route_top (stable); rn; rn = route_next (rn))
1827 for (si = rn->info; si; si = si->next)
1828 {
1829 vty_out (vty, "ipv6 route %s/%d",
1830 inet_ntop (AF_INET6, &rn->p.u.prefix6, buf, BUFSIZ),
1831 rn->p.prefixlen);
1832
1833 switch (si->type)
1834 {
1835 case STATIC_IPV6_GATEWAY:
1836 vty_out (vty, " %s", inet_ntop (AF_INET6, &si->ipv6, buf, BUFSIZ));
1837 break;
1838 case STATIC_IPV6_IFNAME:
1839 vty_out (vty, " %s", si->ifname);
1840 break;
1841 case STATIC_IPV6_GATEWAY_IFNAME:
1842 vty_out (vty, " %s %s",
1843 inet_ntop (AF_INET6, &si->ipv6, buf, BUFSIZ), si->ifname);
1844 break;
1845 }
1846
hasso81dfcaa2003-05-25 19:21:25 +00001847 if (CHECK_FLAG(si->flags, ZEBRA_FLAG_REJECT))
1848 vty_out (vty, " %s", "reject");
1849
1850 if (CHECK_FLAG(si->flags, ZEBRA_FLAG_BLACKHOLE))
1851 vty_out (vty, " %s", "blackhole");
1852
paul718e3742002-12-13 20:15:29 +00001853 if (si->distance != ZEBRA_STATIC_DISTANCE_DEFAULT)
1854 vty_out (vty, " %d", si->distance);
1855 vty_out (vty, "%s", VTY_NEWLINE);
1856
1857 write = 1;
1858 }
1859 return write;
1860}
1861#endif /* HAVE_IPV6 */
1862
1863/* Static ip route configuration write function. */
paula1ac18c2005-06-28 17:17:12 +00001864static int
paul718e3742002-12-13 20:15:29 +00001865zebra_ip_config (struct vty *vty)
1866{
1867 int write = 0;
1868
1869 write += static_config_ipv4 (vty);
1870#ifdef HAVE_IPV6
1871 write += static_config_ipv6 (vty);
1872#endif /* HAVE_IPV6 */
1873
1874 return write;
1875}
1876
1877/* IP node for static routes. */
1878struct cmd_node ip_node = { IP_NODE, "", 1 };
1879
1880/* Route VTY. */
1881void
paula1ac18c2005-06-28 17:17:12 +00001882zebra_vty_init (void)
paul718e3742002-12-13 20:15:29 +00001883{
1884 install_node (&ip_node, zebra_ip_config);
1885
1886 install_element (CONFIG_NODE, &ip_route_cmd);
hasso81dfcaa2003-05-25 19:21:25 +00001887 install_element (CONFIG_NODE, &ip_route_flags_cmd);
hasso457ef552003-05-28 12:02:15 +00001888 install_element (CONFIG_NODE, &ip_route_flags2_cmd);
paul718e3742002-12-13 20:15:29 +00001889 install_element (CONFIG_NODE, &ip_route_mask_cmd);
hasso81dfcaa2003-05-25 19:21:25 +00001890 install_element (CONFIG_NODE, &ip_route_mask_flags_cmd);
hasso457ef552003-05-28 12:02:15 +00001891 install_element (CONFIG_NODE, &ip_route_mask_flags2_cmd);
paul718e3742002-12-13 20:15:29 +00001892 install_element (CONFIG_NODE, &no_ip_route_cmd);
hasso81dfcaa2003-05-25 19:21:25 +00001893 install_element (CONFIG_NODE, &no_ip_route_flags_cmd);
hasso457ef552003-05-28 12:02:15 +00001894 install_element (CONFIG_NODE, &no_ip_route_flags2_cmd);
paul718e3742002-12-13 20:15:29 +00001895 install_element (CONFIG_NODE, &no_ip_route_mask_cmd);
hasso81dfcaa2003-05-25 19:21:25 +00001896 install_element (CONFIG_NODE, &no_ip_route_mask_flags_cmd);
hasso457ef552003-05-28 12:02:15 +00001897 install_element (CONFIG_NODE, &no_ip_route_mask_flags2_cmd);
paul718e3742002-12-13 20:15:29 +00001898 install_element (CONFIG_NODE, &ip_route_distance_cmd);
hasso81dfcaa2003-05-25 19:21:25 +00001899 install_element (CONFIG_NODE, &ip_route_flags_distance_cmd);
hasso457ef552003-05-28 12:02:15 +00001900 install_element (CONFIG_NODE, &ip_route_flags_distance2_cmd);
paul718e3742002-12-13 20:15:29 +00001901 install_element (CONFIG_NODE, &ip_route_mask_distance_cmd);
hasso81dfcaa2003-05-25 19:21:25 +00001902 install_element (CONFIG_NODE, &ip_route_mask_flags_distance_cmd);
hasso457ef552003-05-28 12:02:15 +00001903 install_element (CONFIG_NODE, &ip_route_mask_flags_distance2_cmd);
paul718e3742002-12-13 20:15:29 +00001904 install_element (CONFIG_NODE, &no_ip_route_distance_cmd);
hasso81dfcaa2003-05-25 19:21:25 +00001905 install_element (CONFIG_NODE, &no_ip_route_flags_distance_cmd);
hasso457ef552003-05-28 12:02:15 +00001906 install_element (CONFIG_NODE, &no_ip_route_flags_distance2_cmd);
hasso81dfcaa2003-05-25 19:21:25 +00001907 install_element (CONFIG_NODE, &no_ip_route_mask_flags_distance_cmd);
hasso457ef552003-05-28 12:02:15 +00001908 install_element (CONFIG_NODE, &no_ip_route_mask_flags_distance2_cmd);
paul718e3742002-12-13 20:15:29 +00001909
1910 install_element (VIEW_NODE, &show_ip_route_cmd);
1911 install_element (VIEW_NODE, &show_ip_route_addr_cmd);
1912 install_element (VIEW_NODE, &show_ip_route_prefix_cmd);
1913 install_element (VIEW_NODE, &show_ip_route_prefix_longer_cmd);
1914 install_element (VIEW_NODE, &show_ip_route_protocol_cmd);
1915 install_element (VIEW_NODE, &show_ip_route_supernets_cmd);
1916 install_element (ENABLE_NODE, &show_ip_route_cmd);
1917 install_element (ENABLE_NODE, &show_ip_route_addr_cmd);
1918 install_element (ENABLE_NODE, &show_ip_route_prefix_cmd);
1919 install_element (ENABLE_NODE, &show_ip_route_prefix_longer_cmd);
1920 install_element (ENABLE_NODE, &show_ip_route_protocol_cmd);
1921 install_element (ENABLE_NODE, &show_ip_route_supernets_cmd);
1922
1923#if 0
1924 install_element (VIEW_NODE, &show_ip_route_summary_cmd);
1925 install_element (ENABLE_NODE, &show_ip_route_summary_cmd);
1926#endif /* 0 */
1927
1928#ifdef HAVE_IPV6
1929 install_element (CONFIG_NODE, &ipv6_route_cmd);
hasso81dfcaa2003-05-25 19:21:25 +00001930 install_element (CONFIG_NODE, &ipv6_route_flags_cmd);
paul718e3742002-12-13 20:15:29 +00001931 install_element (CONFIG_NODE, &ipv6_route_ifname_cmd);
hasso81dfcaa2003-05-25 19:21:25 +00001932 install_element (CONFIG_NODE, &ipv6_route_ifname_flags_cmd);
paul718e3742002-12-13 20:15:29 +00001933 install_element (CONFIG_NODE, &no_ipv6_route_cmd);
hasso81dfcaa2003-05-25 19:21:25 +00001934 install_element (CONFIG_NODE, &no_ipv6_route_flags_cmd);
paul718e3742002-12-13 20:15:29 +00001935 install_element (CONFIG_NODE, &no_ipv6_route_ifname_cmd);
hasso81dfcaa2003-05-25 19:21:25 +00001936 install_element (CONFIG_NODE, &no_ipv6_route_ifname_flags_cmd);
paul718e3742002-12-13 20:15:29 +00001937 install_element (CONFIG_NODE, &ipv6_route_pref_cmd);
hasso81dfcaa2003-05-25 19:21:25 +00001938 install_element (CONFIG_NODE, &ipv6_route_flags_pref_cmd);
paul718e3742002-12-13 20:15:29 +00001939 install_element (CONFIG_NODE, &ipv6_route_ifname_pref_cmd);
hasso81dfcaa2003-05-25 19:21:25 +00001940 install_element (CONFIG_NODE, &ipv6_route_ifname_flags_pref_cmd);
paul718e3742002-12-13 20:15:29 +00001941 install_element (CONFIG_NODE, &no_ipv6_route_pref_cmd);
hasso81dfcaa2003-05-25 19:21:25 +00001942 install_element (CONFIG_NODE, &no_ipv6_route_flags_pref_cmd);
paul718e3742002-12-13 20:15:29 +00001943 install_element (CONFIG_NODE, &no_ipv6_route_ifname_pref_cmd);
hasso81dfcaa2003-05-25 19:21:25 +00001944 install_element (CONFIG_NODE, &no_ipv6_route_ifname_flags_pref_cmd);
paul718e3742002-12-13 20:15:29 +00001945 install_element (VIEW_NODE, &show_ipv6_route_cmd);
1946 install_element (VIEW_NODE, &show_ipv6_route_protocol_cmd);
1947 install_element (VIEW_NODE, &show_ipv6_route_addr_cmd);
1948 install_element (VIEW_NODE, &show_ipv6_route_prefix_cmd);
1949 install_element (VIEW_NODE, &show_ipv6_route_prefix_longer_cmd);
1950 install_element (ENABLE_NODE, &show_ipv6_route_cmd);
1951 install_element (ENABLE_NODE, &show_ipv6_route_protocol_cmd);
1952 install_element (ENABLE_NODE, &show_ipv6_route_addr_cmd);
1953 install_element (ENABLE_NODE, &show_ipv6_route_prefix_cmd);
1954 install_element (ENABLE_NODE, &show_ipv6_route_prefix_longer_cmd);
1955#endif /* HAVE_IPV6 */
1956}