]> git.proxmox.com Git - mirror_frr.git/blame - zebra/zebra_vty.c
Merge branch 'quagga' into google-bgp-multipath
[mirror_frr.git] / zebra / zebra_vty.c
CommitLineData
718e3744 1/* 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
7514fb77 24#include "memory.h"
718e3744 25#include "if.h"
26#include "prefix.h"
27#include "command.h"
28#include "table.h"
29#include "rib.h"
30
a1ac18c4 31#include "zebra/zserv.h"
32
718e3744 33/* General fucntion for static route. */
a1ac18c4 34static int
39db97e4 35zebra_static_ipv4 (struct vty *vty, int add_cmd, const char *dest_str,
36 const char *mask_str, const char *gate_str,
37 const char *flag_str, const char *distance_str)
718e3744 38{
39 int ret;
40 u_char distance;
41 struct prefix p;
42 struct in_addr gate;
43 struct in_addr mask;
39db97e4 44 const char *ifname;
81dfcaa2 45 u_char flag = 0;
718e3744 46
47 ret = str2prefix (dest_str, &p);
48 if (ret <= 0)
49 {
50 vty_out (vty, "%% Malformed address%s", VTY_NEWLINE);
51 return CMD_WARNING;
52 }
53
54 /* Cisco like mask notation. */
55 if (mask_str)
56 {
57 ret = inet_aton (mask_str, &mask);
58 if (ret == 0)
595db7f1 59 {
60 vty_out (vty, "%% Malformed address%s", VTY_NEWLINE);
61 return CMD_WARNING;
62 }
718e3744 63 p.prefixlen = ip_masklen (mask);
64 }
65
66 /* Apply mask for given prefix. */
67 apply_mask (&p);
68
595db7f1 69 /* Administrative distance. */
70 if (distance_str)
71 distance = atoi (distance_str);
72 else
73 distance = ZEBRA_STATIC_DISTANCE_DEFAULT;
74
75 /* Null0 static route. */
457ef551 76 if ((gate_str != NULL) && (strncasecmp (gate_str, "Null0", strlen (gate_str)) == 0))
595db7f1 77 {
78 if (flag_str)
79 {
80 vty_out (vty, "%% can not have flag %s with Null0%s", flag_str, VTY_NEWLINE);
81 return CMD_WARNING;
82 }
83 if (add_cmd)
7021c425 84 static_add_ipv4 (&p, NULL, NULL, ZEBRA_FLAG_BLACKHOLE, distance, 0);
595db7f1 85 else
86 static_delete_ipv4 (&p, NULL, NULL, distance, 0);
87 return CMD_SUCCESS;
88 }
89
81dfcaa2 90 /* Route flags */
91 if (flag_str) {
92 switch(flag_str[0]) {
93 case 'r':
94 case 'R': /* XXX */
95 SET_FLAG (flag, ZEBRA_FLAG_REJECT);
96 break;
97 case 'b':
98 case 'B': /* XXX */
99 SET_FLAG (flag, ZEBRA_FLAG_BLACKHOLE);
100 break;
101 default:
102 vty_out (vty, "%% Malformed flag %s %s", flag_str, VTY_NEWLINE);
595db7f1 103 return CMD_WARNING;
81dfcaa2 104 }
105 }
106
457ef551 107 if (gate_str == NULL)
108 {
109 if (add_cmd)
110 static_add_ipv4 (&p, NULL, NULL, flag, distance, 0);
111 else
112 static_delete_ipv4 (&p, NULL, NULL, distance, 0);
113
114 return CMD_SUCCESS;
115 }
116
718e3744 117 /* When gateway is A.B.C.D format, gate is treated as nexthop
118 address other case gate is treated as interface name. */
119 ret = inet_aton (gate_str, &gate);
120 if (ret)
121 ifname = NULL;
122 else
123 ifname = gate_str;
124
125 if (add_cmd)
81dfcaa2 126 static_add_ipv4 (&p, ifname ? NULL : &gate, ifname, flag, distance, 0);
718e3744 127 else
128 static_delete_ipv4 (&p, ifname ? NULL : &gate, ifname, distance, 0);
129
130 return CMD_SUCCESS;
131}
132
133/* Static route configuration. */
134DEFUN (ip_route,
135 ip_route_cmd,
595db7f1 136 "ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0)",
81dfcaa2 137 IP_STR
138 "Establish static routes\n"
139 "IP destination prefix (e.g. 10.0.0.0/8)\n"
140 "IP gateway address\n"
595db7f1 141 "IP gateway interface name\n"
142 "Null interface\n")
81dfcaa2 143{
144 return zebra_static_ipv4 (vty, 1, argv[0], NULL, argv[1], NULL, NULL);
145}
146
147DEFUN (ip_route_flags,
148 ip_route_flags_cmd,
149 "ip route A.B.C.D/M (A.B.C.D|INTERFACE) (reject|blackhole)",
718e3744 150 IP_STR
151 "Establish static routes\n"
152 "IP destination prefix (e.g. 10.0.0.0/8)\n"
153 "IP gateway address\n"
154 "IP gateway interface name\n"
81dfcaa2 155 "Emit an ICMP unreachable when matched\n"
156 "Silently discard pkts when matched\n")
718e3744 157{
81dfcaa2 158 return zebra_static_ipv4 (vty, 1, argv[0], NULL, argv[1], argv[2], NULL);
718e3744 159}
160
457ef551 161DEFUN (ip_route_flags2,
162 ip_route_flags2_cmd,
163 "ip route A.B.C.D/M (reject|blackhole)",
164 IP_STR
165 "Establish static routes\n"
166 "IP destination prefix (e.g. 10.0.0.0/8)\n"
167 "Emit an ICMP unreachable when matched\n"
168 "Silently discard pkts when matched\n")
169{
170 return zebra_static_ipv4 (vty, 1, argv[0], NULL, NULL, argv[1], NULL);
171}
172
718e3744 173/* Mask as A.B.C.D format. */
174DEFUN (ip_route_mask,
175 ip_route_mask_cmd,
595db7f1 176 "ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0)",
81dfcaa2 177 IP_STR
178 "Establish static routes\n"
179 "IP destination prefix\n"
180 "IP destination prefix mask\n"
181 "IP gateway address\n"
595db7f1 182 "IP gateway interface name\n"
183 "Null interface\n")
81dfcaa2 184{
185 return zebra_static_ipv4 (vty, 1, argv[0], argv[1], argv[2], NULL, NULL);
186}
187
188DEFUN (ip_route_mask_flags,
189 ip_route_mask_flags_cmd,
190 "ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE) (reject|blackhole)",
718e3744 191 IP_STR
192 "Establish static routes\n"
193 "IP destination prefix\n"
194 "IP destination prefix mask\n"
195 "IP gateway address\n"
196 "IP gateway interface name\n"
81dfcaa2 197 "Emit an ICMP unreachable when matched\n"
198 "Silently discard pkts when matched\n")
718e3744 199{
81dfcaa2 200 return zebra_static_ipv4 (vty, 1, argv[0], argv[1], argv[2], argv[3], NULL);
718e3744 201}
202
457ef551 203DEFUN (ip_route_mask_flags2,
204 ip_route_mask_flags2_cmd,
205 "ip route A.B.C.D A.B.C.D (reject|blackhole)",
206 IP_STR
207 "Establish static routes\n"
208 "IP destination prefix\n"
209 "IP destination prefix mask\n"
210 "Emit an ICMP unreachable when matched\n"
211 "Silently discard pkts when matched\n")
212{
213 return zebra_static_ipv4 (vty, 1, argv[0], argv[1], NULL, argv[2], NULL);
214}
215
718e3744 216/* Distance option value. */
217DEFUN (ip_route_distance,
218 ip_route_distance_cmd,
595db7f1 219 "ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0) <1-255>",
81dfcaa2 220 IP_STR
221 "Establish static routes\n"
222 "IP destination prefix (e.g. 10.0.0.0/8)\n"
223 "IP gateway address\n"
224 "IP gateway interface name\n"
595db7f1 225 "Null interface\n"
81dfcaa2 226 "Distance value for this route\n")
227{
228 return zebra_static_ipv4 (vty, 1, argv[0], NULL, argv[1], NULL, argv[2]);
229}
230
231DEFUN (ip_route_flags_distance,
232 ip_route_flags_distance_cmd,
233 "ip route A.B.C.D/M (A.B.C.D|INTERFACE) (reject|blackhole) <1-255>",
718e3744 234 IP_STR
235 "Establish static routes\n"
236 "IP destination prefix (e.g. 10.0.0.0/8)\n"
237 "IP gateway address\n"
238 "IP gateway interface name\n"
81dfcaa2 239 "Emit an ICMP unreachable when matched\n"
240 "Silently discard pkts when matched\n"
718e3744 241 "Distance value for this route\n")
242{
81dfcaa2 243 return zebra_static_ipv4 (vty, 1, argv[0], NULL, argv[1], argv[2], argv[3]);
718e3744 244}
245
457ef551 246DEFUN (ip_route_flags_distance2,
247 ip_route_flags_distance2_cmd,
248 "ip route A.B.C.D/M (reject|blackhole) <1-255>",
249 IP_STR
250 "Establish static routes\n"
251 "IP destination prefix (e.g. 10.0.0.0/8)\n"
252 "Emit an ICMP unreachable when matched\n"
253 "Silently discard pkts when matched\n"
254 "Distance value for this route\n")
255{
256 return zebra_static_ipv4 (vty, 1, argv[0], NULL, NULL, argv[1], argv[2]);
257}
258
718e3744 259DEFUN (ip_route_mask_distance,
260 ip_route_mask_distance_cmd,
595db7f1 261 "ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0) <1-255>",
718e3744 262 IP_STR
263 "Establish static routes\n"
264 "IP destination prefix\n"
265 "IP destination prefix mask\n"
266 "IP gateway address\n"
267 "IP gateway interface name\n"
595db7f1 268 "Null interface\n"
718e3744 269 "Distance value for this route\n")
270{
81dfcaa2 271 return zebra_static_ipv4 (vty, 1, argv[0], argv[1], argv[2], NULL, argv[3]);
272}
273
274DEFUN (ip_route_mask_flags_distance,
275 ip_route_mask_flags_distance_cmd,
276 "ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE) (reject|blackhole) <1-255>",
277 IP_STR
278 "Establish static routes\n"
279 "IP destination prefix\n"
280 "IP destination prefix mask\n"
281 "IP gateway address\n"
282 "IP gateway interface name\n"
283 "Distance value for this route\n"
284 "Emit an ICMP unreachable when matched\n"
285 "Silently discard pkts when matched\n")
286{
287 return zebra_static_ipv4 (vty, 1, argv[0], argv[1], argv[2], argv[3], argv[4]);
718e3744 288}
289
457ef551 290DEFUN (ip_route_mask_flags_distance2,
291 ip_route_mask_flags_distance2_cmd,
292 "ip route A.B.C.D A.B.C.D (reject|blackhole) <1-255>",
293 IP_STR
294 "Establish static routes\n"
295 "IP destination prefix\n"
296 "IP destination prefix mask\n"
297 "Distance value for this route\n"
298 "Emit an ICMP unreachable when matched\n"
299 "Silently discard pkts when matched\n")
300{
301 return zebra_static_ipv4 (vty, 1, argv[0], argv[1], NULL, argv[2], argv[3]);
302}
303
718e3744 304DEFUN (no_ip_route,
305 no_ip_route_cmd,
595db7f1 306 "no ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0)",
718e3744 307 NO_STR
308 IP_STR
309 "Establish static routes\n"
310 "IP destination prefix (e.g. 10.0.0.0/8)\n"
311 "IP gateway address\n"
595db7f1 312 "IP gateway interface name\n"
313 "Null interface\n")
718e3744 314{
81dfcaa2 315 return zebra_static_ipv4 (vty, 0, argv[0], NULL, argv[1], NULL, NULL);
718e3744 316}
317
81dfcaa2 318ALIAS (no_ip_route,
319 no_ip_route_flags_cmd,
320 "no ip route A.B.C.D/M (A.B.C.D|INTERFACE) (reject|blackhole)",
321 NO_STR
322 IP_STR
323 "Establish static routes\n"
324 "IP destination prefix (e.g. 10.0.0.0/8)\n"
325 "IP gateway address\n"
326 "IP gateway interface name\n"
327 "Emit an ICMP unreachable when matched\n"
328 "Silently discard pkts when matched\n")
329
457ef551 330DEFUN (no_ip_route_flags2,
331 no_ip_route_flags2_cmd,
332 "no ip route A.B.C.D/M (reject|blackhole)",
333 NO_STR
334 IP_STR
335 "Establish static routes\n"
336 "IP destination prefix (e.g. 10.0.0.0/8)\n"
337 "Emit an ICMP unreachable when matched\n"
338 "Silently discard pkts when matched\n")
339{
340 return zebra_static_ipv4 (vty, 0, argv[0], NULL, NULL, NULL, NULL);
341}
342
718e3744 343DEFUN (no_ip_route_mask,
344 no_ip_route_mask_cmd,
595db7f1 345 "no ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0)",
718e3744 346 NO_STR
347 IP_STR
348 "Establish static routes\n"
349 "IP destination prefix\n"
350 "IP destination prefix mask\n"
351 "IP gateway address\n"
595db7f1 352 "IP gateway interface name\n"
353 "Null interface\n")
718e3744 354{
81dfcaa2 355 return zebra_static_ipv4 (vty, 0, argv[0], argv[1], argv[2], NULL, NULL);
718e3744 356}
357
81dfcaa2 358ALIAS (no_ip_route_mask,
359 no_ip_route_mask_flags_cmd,
360 "no ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE) (reject|blackhole)",
361 NO_STR
362 IP_STR
363 "Establish static routes\n"
364 "IP destination prefix\n"
365 "IP destination prefix mask\n"
366 "IP gateway address\n"
367 "IP gateway interface name\n"
368 "Emit an ICMP unreachable when matched\n"
369 "Silently discard pkts when matched\n")
370
457ef551 371DEFUN (no_ip_route_mask_flags2,
372 no_ip_route_mask_flags2_cmd,
373 "no ip route A.B.C.D A.B.C.D (reject|blackhole)",
374 NO_STR
375 IP_STR
376 "Establish static routes\n"
377 "IP destination prefix\n"
378 "IP destination prefix mask\n"
379 "Emit an ICMP unreachable when matched\n"
380 "Silently discard pkts when matched\n")
381{
382 return zebra_static_ipv4 (vty, 0, argv[0], argv[1], NULL, NULL, NULL);
383}
384
718e3744 385DEFUN (no_ip_route_distance,
386 no_ip_route_distance_cmd,
595db7f1 387 "no ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0) <1-255>",
81dfcaa2 388 NO_STR
389 IP_STR
390 "Establish static routes\n"
391 "IP destination prefix (e.g. 10.0.0.0/8)\n"
392 "IP gateway address\n"
393 "IP gateway interface name\n"
595db7f1 394 "Null interface\n"
81dfcaa2 395 "Distance value for this route\n")
396{
397 return zebra_static_ipv4 (vty, 0, argv[0], NULL, argv[1], NULL, argv[2]);
398}
399
400DEFUN (no_ip_route_flags_distance,
401 no_ip_route_flags_distance_cmd,
402 "no ip route A.B.C.D/M (A.B.C.D|INTERFACE) (reject|blackhole) <1-255>",
718e3744 403 NO_STR
404 IP_STR
405 "Establish static routes\n"
406 "IP destination prefix (e.g. 10.0.0.0/8)\n"
407 "IP gateway address\n"
408 "IP gateway interface name\n"
81dfcaa2 409 "Emit an ICMP unreachable when matched\n"
410 "Silently discard pkts when matched\n"
718e3744 411 "Distance value for this route\n")
412{
81dfcaa2 413 return zebra_static_ipv4 (vty, 0, argv[0], NULL, argv[1], argv[2], argv[3]);
718e3744 414}
415
457ef551 416DEFUN (no_ip_route_flags_distance2,
417 no_ip_route_flags_distance2_cmd,
418 "no ip route A.B.C.D/M (reject|blackhole) <1-255>",
419 NO_STR
420 IP_STR
421 "Establish static routes\n"
422 "IP destination prefix (e.g. 10.0.0.0/8)\n"
423 "Emit an ICMP unreachable when matched\n"
424 "Silently discard pkts when matched\n"
425 "Distance value for this route\n")
426{
427 return zebra_static_ipv4 (vty, 0, argv[0], NULL, NULL, argv[1], argv[2]);
428}
429
718e3744 430DEFUN (no_ip_route_mask_distance,
431 no_ip_route_mask_distance_cmd,
595db7f1 432 "no ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0) <1-255>",
81dfcaa2 433 NO_STR
434 IP_STR
435 "Establish static routes\n"
436 "IP destination prefix\n"
437 "IP destination prefix mask\n"
438 "IP gateway address\n"
439 "IP gateway interface name\n"
595db7f1 440 "Null interface\n"
81dfcaa2 441 "Distance value for this route\n")
442{
443 return zebra_static_ipv4 (vty, 0, argv[0], argv[1], argv[2], NULL, argv[3]);
444}
445
446DEFUN (no_ip_route_mask_flags_distance,
447 no_ip_route_mask_flags_distance_cmd,
448 "no ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE) (reject|blackhole) <1-255>",
718e3744 449 NO_STR
450 IP_STR
451 "Establish static routes\n"
452 "IP destination prefix\n"
453 "IP destination prefix mask\n"
454 "IP gateway address\n"
455 "IP gateway interface name\n"
81dfcaa2 456 "Emit an ICMP unreachable when matched\n"
457 "Silently discard pkts when matched\n"
718e3744 458 "Distance value for this route\n")
459{
81dfcaa2 460 return zebra_static_ipv4 (vty, 0, argv[0], argv[1], argv[2], argv[3], argv[4]);
718e3744 461}
462
457ef551 463DEFUN (no_ip_route_mask_flags_distance2,
464 no_ip_route_mask_flags_distance2_cmd,
465 "no ip route A.B.C.D A.B.C.D (reject|blackhole) <1-255>",
466 NO_STR
467 IP_STR
468 "Establish static routes\n"
469 "IP destination prefix\n"
470 "IP destination prefix mask\n"
471 "Emit an ICMP unreachable when matched\n"
472 "Silently discard pkts when matched\n"
473 "Distance value for this route\n")
474{
475 return zebra_static_ipv4 (vty, 0, argv[0], argv[1], NULL, argv[2], argv[3]);
476}
477
7514fb77
PJ
478char *proto_rm[AFI_MAX][ZEBRA_ROUTE_MAX+1]; /* "any" == ZEBRA_ROUTE_MAX */
479
480DEFUN (ip_protocol,
481 ip_protocol_cmd,
482 "ip protocol PROTO route-map ROUTE-MAP",
483 NO_STR
484 "Apply route map to PROTO\n"
485 "Protocol name\n"
486 "Route map name\n")
487{
488 int i;
489
490 if (strcasecmp(argv[0], "any") == 0)
491 i = ZEBRA_ROUTE_MAX;
492 else
493 i = proto_name2num(argv[0]);
494 if (i < 0)
495 {
496 vty_out (vty, "invalid protocol name \"%s\"%s", argv[0] ? argv[0] : "",
497 VTY_NEWLINE);
498 return CMD_WARNING;
499 }
500 if (proto_rm[AFI_IP][i])
501 XFREE (MTYPE_ROUTE_MAP_NAME, proto_rm[AFI_IP][i]);
502 proto_rm[AFI_IP][i] = XSTRDUP (MTYPE_ROUTE_MAP_NAME, argv[1]);
503 return CMD_SUCCESS;
504}
505
506DEFUN (no_ip_protocol,
507 no_ip_protocol_cmd,
508 "no ip protocol PROTO",
509 NO_STR
510 "Remove route map from PROTO\n"
511 "Protocol name\n")
512{
513 int i;
514
515 if (strcasecmp(argv[0], "any") == 0)
516 i = ZEBRA_ROUTE_MAX;
517 else
518 i = proto_name2num(argv[0]);
519 if (i < 0)
520 {
521 vty_out (vty, "invalid protocol name \"%s\"%s", argv[0] ? argv[0] : "",
522 VTY_NEWLINE);
523 return CMD_WARNING;
524 }
525 if (proto_rm[AFI_IP][i])
526 XFREE (MTYPE_ROUTE_MAP_NAME, proto_rm[AFI_IP][i]);
527 proto_rm[AFI_IP][i] = NULL;
528 return CMD_SUCCESS;
529}
530
718e3744 531/* New RIB. Detailed information for IPv4 route. */
a1ac18c4 532static void
718e3744 533vty_show_ip_route_detail (struct vty *vty, struct route_node *rn)
534{
535 struct rib *rib;
536 struct nexthop *nexthop;
537
538 for (rib = rn->info; rib; rib = rib->next)
539 {
540 vty_out (vty, "Routing entry for %s/%d%s",
541 inet_ntoa (rn->p.u.prefix4), rn->p.prefixlen,
542 VTY_NEWLINE);
f52d13cb 543 vty_out (vty, " Known via \"%s\"", zebra_route_string (rib->type));
718e3744 544 vty_out (vty, ", distance %d, metric %d", rib->distance, rib->metric);
545 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
546 vty_out (vty, ", best");
547 if (rib->refcnt)
548 vty_out (vty, ", refcnt %ld", rib->refcnt);
81dfcaa2 549 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_BLACKHOLE))
550 vty_out (vty, ", blackhole");
551 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_REJECT))
552 vty_out (vty, ", reject");
718e3744 553 vty_out (vty, "%s", VTY_NEWLINE);
554
555#define ONE_DAY_SECOND 60*60*24
556#define ONE_WEEK_SECOND 60*60*24*7
557 if (rib->type == ZEBRA_ROUTE_RIP
558 || rib->type == ZEBRA_ROUTE_OSPF
578ce371 559 || rib->type == ZEBRA_ROUTE_BABEL
9e867fe6 560 || rib->type == ZEBRA_ROUTE_ISIS
718e3744 561 || rib->type == ZEBRA_ROUTE_BGP)
562 {
563 time_t uptime;
564 struct tm *tm;
565
566 uptime = time (NULL);
567 uptime -= rib->uptime;
568 tm = gmtime (&uptime);
569
570 vty_out (vty, " Last update ");
571
572 if (uptime < ONE_DAY_SECOND)
573 vty_out (vty, "%02d:%02d:%02d",
574 tm->tm_hour, tm->tm_min, tm->tm_sec);
575 else if (uptime < ONE_WEEK_SECOND)
576 vty_out (vty, "%dd%02dh%02dm",
577 tm->tm_yday, tm->tm_hour, tm->tm_min);
578 else
579 vty_out (vty, "%02dw%dd%02dh",
580 tm->tm_yday/7,
581 tm->tm_yday - ((tm->tm_yday/7) * 7), tm->tm_hour);
582 vty_out (vty, " ago%s", VTY_NEWLINE);
583 }
584
585 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
586 {
7514fb77
PJ
587 char addrstr[32];
588
718e3744 589 vty_out (vty, " %c",
590 CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB) ? '*' : ' ');
591
592 switch (nexthop->type)
593 {
594 case NEXTHOP_TYPE_IPV4:
595 case NEXTHOP_TYPE_IPV4_IFINDEX:
596 vty_out (vty, " %s", inet_ntoa (nexthop->gate.ipv4));
597 if (nexthop->ifindex)
598 vty_out (vty, ", via %s", ifindex2ifname (nexthop->ifindex));
599 break;
600 case NEXTHOP_TYPE_IFINDEX:
601 vty_out (vty, " directly connected, %s",
602 ifindex2ifname (nexthop->ifindex));
603 break;
604 case NEXTHOP_TYPE_IFNAME:
605 vty_out (vty, " directly connected, %s", nexthop->ifname);
606 break;
595db7f1 607 case NEXTHOP_TYPE_BLACKHOLE:
7021c425 608 vty_out (vty, " directly connected, Null0");
595db7f1 609 break;
7021c425 610 default:
718e3744 611 break;
612 }
613 if (! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
614 vty_out (vty, " inactive");
615
616 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
617 {
618 vty_out (vty, " (recursive");
619
620 switch (nexthop->rtype)
621 {
622 case NEXTHOP_TYPE_IPV4:
623 case NEXTHOP_TYPE_IPV4_IFINDEX:
624 vty_out (vty, " via %s)", inet_ntoa (nexthop->rgate.ipv4));
625 break;
626 case NEXTHOP_TYPE_IFINDEX:
627 case NEXTHOP_TYPE_IFNAME:
628 vty_out (vty, " is directly connected, %s)",
629 ifindex2ifname (nexthop->rifindex));
630 break;
631 default:
632 break;
633 }
634 }
7514fb77
PJ
635 switch (nexthop->type)
636 {
637 case NEXTHOP_TYPE_IPV4:
638 case NEXTHOP_TYPE_IPV4_IFINDEX:
639 case NEXTHOP_TYPE_IPV4_IFNAME:
640 if (nexthop->src.ipv4.s_addr)
641 {
642 if (inet_ntop(AF_INET, &nexthop->src.ipv4, addrstr,
643 sizeof addrstr))
644 vty_out (vty, ", src %s", addrstr);
645 }
646 break;
09303314 647#ifdef HAVE_IPV6
7514fb77
PJ
648 case NEXTHOP_TYPE_IPV6:
649 case NEXTHOP_TYPE_IPV6_IFINDEX:
650 case NEXTHOP_TYPE_IPV6_IFNAME:
651 if (!IPV6_ADDR_SAME(&nexthop->src.ipv6, &in6addr_any))
652 {
653 if (inet_ntop(AF_INET6, &nexthop->src.ipv6, addrstr,
654 sizeof addrstr))
655 vty_out (vty, ", src %s", addrstr);
656 }
657 break;
09303314 658#endif /* HAVE_IPV6 */
7514fb77
PJ
659 default:
660 break;
661 }
718e3744 662 vty_out (vty, "%s", VTY_NEWLINE);
663 }
664 vty_out (vty, "%s", VTY_NEWLINE);
665 }
666}
667
a1ac18c4 668static void
718e3744 669vty_show_ip_route (struct vty *vty, struct route_node *rn, struct rib *rib)
670{
671 struct nexthop *nexthop;
672 int len = 0;
673 char buf[BUFSIZ];
674
675 /* Nexthop information. */
676 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
677 {
678 if (nexthop == rib->nexthop)
679 {
680 /* Prefix information. */
681 len = vty_out (vty, "%c%c%c %s/%d",
f52d13cb 682 zebra_route_char (rib->type),
718e3744 683 CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED)
684 ? '>' : ' ',
685 CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)
686 ? '*' : ' ',
687 inet_ntop (AF_INET, &rn->p.u.prefix, buf, BUFSIZ),
688 rn->p.prefixlen);
689
690 /* Distance and metric display. */
691 if (rib->type != ZEBRA_ROUTE_CONNECT
692 && rib->type != ZEBRA_ROUTE_KERNEL)
693 len += vty_out (vty, " [%d/%d]", rib->distance,
694 rib->metric);
695 }
696 else
697 vty_out (vty, " %c%*c",
698 CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)
699 ? '*' : ' ',
700 len - 3, ' ');
701
702 switch (nexthop->type)
703 {
704 case NEXTHOP_TYPE_IPV4:
705 case NEXTHOP_TYPE_IPV4_IFINDEX:
706 vty_out (vty, " via %s", inet_ntoa (nexthop->gate.ipv4));
707 if (nexthop->ifindex)
708 vty_out (vty, ", %s", ifindex2ifname (nexthop->ifindex));
709 break;
710 case NEXTHOP_TYPE_IFINDEX:
711 vty_out (vty, " is directly connected, %s",
712 ifindex2ifname (nexthop->ifindex));
713 break;
714 case NEXTHOP_TYPE_IFNAME:
715 vty_out (vty, " is directly connected, %s", nexthop->ifname);
716 break;
595db7f1 717 case NEXTHOP_TYPE_BLACKHOLE:
7021c425 718 vty_out (vty, " is directly connected, Null0");
595db7f1 719 break;
7021c425 720 default:
718e3744 721 break;
722 }
723 if (! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
724 vty_out (vty, " inactive");
725
726 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
727 {
728 vty_out (vty, " (recursive");
729
730 switch (nexthop->rtype)
731 {
732 case NEXTHOP_TYPE_IPV4:
733 case NEXTHOP_TYPE_IPV4_IFINDEX:
734 vty_out (vty, " via %s)", inet_ntoa (nexthop->rgate.ipv4));
735 break;
736 case NEXTHOP_TYPE_IFINDEX:
737 case NEXTHOP_TYPE_IFNAME:
738 vty_out (vty, " is directly connected, %s)",
739 ifindex2ifname (nexthop->rifindex));
740 break;
741 default:
742 break;
743 }
744 }
7514fb77
PJ
745 switch (nexthop->type)
746 {
747 case NEXTHOP_TYPE_IPV4:
748 case NEXTHOP_TYPE_IPV4_IFINDEX:
749 case NEXTHOP_TYPE_IPV4_IFNAME:
750 if (nexthop->src.ipv4.s_addr)
751 {
752 if (inet_ntop(AF_INET, &nexthop->src.ipv4, buf, sizeof buf))
753 vty_out (vty, ", src %s", buf);
754 }
755 break;
09303314 756#ifdef HAVE_IPV6
7514fb77
PJ
757 case NEXTHOP_TYPE_IPV6:
758 case NEXTHOP_TYPE_IPV6_IFINDEX:
759 case NEXTHOP_TYPE_IPV6_IFNAME:
760 if (!IPV6_ADDR_SAME(&nexthop->src.ipv6, &in6addr_any))
761 {
762 if (inet_ntop(AF_INET6, &nexthop->src.ipv6, buf, sizeof buf))
763 vty_out (vty, ", src %s", buf);
764 }
765 break;
09303314 766#endif /* HAVE_IPV6 */
7514fb77
PJ
767 default:
768 break;
769 }
718e3744 770
81dfcaa2 771 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_BLACKHOLE))
772 vty_out (vty, ", bh");
773 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_REJECT))
774 vty_out (vty, ", rej");
775
718e3744 776 if (rib->type == ZEBRA_ROUTE_RIP
777 || rib->type == ZEBRA_ROUTE_OSPF
578ce371 778 || rib->type == ZEBRA_ROUTE_BABEL
9e867fe6 779 || rib->type == ZEBRA_ROUTE_ISIS
718e3744 780 || rib->type == ZEBRA_ROUTE_BGP)
781 {
782 time_t uptime;
783 struct tm *tm;
784
785 uptime = time (NULL);
786 uptime -= rib->uptime;
787 tm = gmtime (&uptime);
788
789#define ONE_DAY_SECOND 60*60*24
790#define ONE_WEEK_SECOND 60*60*24*7
791
792 if (uptime < ONE_DAY_SECOND)
793 vty_out (vty, ", %02d:%02d:%02d",
794 tm->tm_hour, tm->tm_min, tm->tm_sec);
795 else if (uptime < ONE_WEEK_SECOND)
796 vty_out (vty, ", %dd%02dh%02dm",
797 tm->tm_yday, tm->tm_hour, tm->tm_min);
798 else
799 vty_out (vty, ", %02dw%dd%02dh",
800 tm->tm_yday/7,
801 tm->tm_yday - ((tm->tm_yday/7) * 7), tm->tm_hour);
802 }
803 vty_out (vty, "%s", VTY_NEWLINE);
804 }
805}
806
718e3744 807DEFUN (show_ip_route,
808 show_ip_route_cmd,
809 "show ip route",
810 SHOW_STR
811 IP_STR
812 "IP routing table\n")
813{
814 struct route_table *table;
815 struct route_node *rn;
816 struct rib *rib;
817 int first = 1;
818
819 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
820 if (! table)
821 return CMD_SUCCESS;
822
823 /* Show all IPv4 routes. */
824 for (rn = route_top (table); rn; rn = route_next (rn))
825 for (rib = rn->info; rib; rib = rib->next)
826 {
827 if (first)
828 {
e0ca5fde 829 vty_out (vty, SHOW_ROUTE_V4_HEADER);
718e3744 830 first = 0;
831 }
832 vty_show_ip_route (vty, rn, rib);
833 }
834 return CMD_SUCCESS;
835}
836
837DEFUN (show_ip_route_prefix_longer,
838 show_ip_route_prefix_longer_cmd,
839 "show ip route A.B.C.D/M longer-prefixes",
840 SHOW_STR
841 IP_STR
842 "IP routing table\n"
843 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
844 "Show route matching the specified Network/Mask pair only\n")
845{
846 struct route_table *table;
847 struct route_node *rn;
848 struct rib *rib;
849 struct prefix p;
850 int ret;
851 int first = 1;
852
853 ret = str2prefix (argv[0], &p);
854 if (! ret)
855 {
856 vty_out (vty, "%% Malformed Prefix%s", VTY_NEWLINE);
857 return CMD_WARNING;
858 }
859
860 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
861 if (! table)
862 return CMD_SUCCESS;
863
864 /* Show matched type IPv4 routes. */
865 for (rn = route_top (table); rn; rn = route_next (rn))
866 for (rib = rn->info; rib; rib = rib->next)
867 if (prefix_match (&p, &rn->p))
868 {
869 if (first)
870 {
e0ca5fde 871 vty_out (vty, SHOW_ROUTE_V4_HEADER);
718e3744 872 first = 0;
873 }
874 vty_show_ip_route (vty, rn, rib);
875 }
876 return CMD_SUCCESS;
877}
878
879DEFUN (show_ip_route_supernets,
880 show_ip_route_supernets_cmd,
881 "show ip route supernets-only",
882 SHOW_STR
883 IP_STR
884 "IP routing table\n"
885 "Show supernet entries only\n")
886{
887 struct route_table *table;
888 struct route_node *rn;
889 struct rib *rib;
890 u_int32_t addr;
891 int first = 1;
892
893 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
894 if (! table)
895 return CMD_SUCCESS;
896
897 /* Show matched type IPv4 routes. */
898 for (rn = route_top (table); rn; rn = route_next (rn))
899 for (rib = rn->info; rib; rib = rib->next)
900 {
901 addr = ntohl (rn->p.u.prefix4.s_addr);
902
903 if ((IN_CLASSC (addr) && rn->p.prefixlen < 24)
904 || (IN_CLASSB (addr) && rn->p.prefixlen < 16)
905 || (IN_CLASSA (addr) && rn->p.prefixlen < 8))
906 {
907 if (first)
908 {
e0ca5fde 909 vty_out (vty, SHOW_ROUTE_V4_HEADER);
718e3744 910 first = 0;
911 }
912 vty_show_ip_route (vty, rn, rib);
913 }
914 }
915 return CMD_SUCCESS;
916}
917
918DEFUN (show_ip_route_protocol,
919 show_ip_route_protocol_cmd,
e0ca5fde 920 "show ip route " QUAGGA_IP_REDIST_STR_ZEBRA,
718e3744 921 SHOW_STR
922 IP_STR
923 "IP routing table\n"
e0ca5fde 924 QUAGGA_IP_REDIST_HELP_STR_ZEBRA)
718e3744 925{
926 int type;
927 struct route_table *table;
928 struct route_node *rn;
929 struct rib *rib;
930 int first = 1;
931
e0ca5fde
DL
932 type = proto_redistnum (AFI_IP, argv[0]);
933 if (type < 0)
718e3744 934 {
935 vty_out (vty, "Unknown route type%s", VTY_NEWLINE);
936 return CMD_WARNING;
937 }
938
939 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
940 if (! table)
941 return CMD_SUCCESS;
942
943 /* Show matched type IPv4 routes. */
944 for (rn = route_top (table); rn; rn = route_next (rn))
945 for (rib = rn->info; rib; rib = rib->next)
946 if (rib->type == type)
947 {
948 if (first)
949 {
e0ca5fde 950 vty_out (vty, SHOW_ROUTE_V4_HEADER);
718e3744 951 first = 0;
952 }
953 vty_show_ip_route (vty, rn, rib);
954 }
955 return CMD_SUCCESS;
956}
957
958DEFUN (show_ip_route_addr,
959 show_ip_route_addr_cmd,
960 "show ip route A.B.C.D",
961 SHOW_STR
962 IP_STR
963 "IP routing table\n"
964 "Network in the IP routing table to display\n")
965{
966 int ret;
967 struct prefix_ipv4 p;
968 struct route_table *table;
969 struct route_node *rn;
970
971 ret = str2prefix_ipv4 (argv[0], &p);
972 if (ret <= 0)
973 {
974 vty_out (vty, "%% Malformed IPv4 address%s", VTY_NEWLINE);
975 return CMD_WARNING;
976 }
977
978 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
979 if (! table)
980 return CMD_SUCCESS;
981
982 rn = route_node_match (table, (struct prefix *) &p);
983 if (! rn)
984 {
985 vty_out (vty, "%% Network not in table%s", VTY_NEWLINE);
986 return CMD_WARNING;
987 }
988
989 vty_show_ip_route_detail (vty, rn);
990
991 route_unlock_node (rn);
992
993 return CMD_SUCCESS;
994}
995
996DEFUN (show_ip_route_prefix,
997 show_ip_route_prefix_cmd,
998 "show ip route A.B.C.D/M",
999 SHOW_STR
1000 IP_STR
1001 "IP routing table\n"
1002 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n")
1003{
1004 int ret;
1005 struct prefix_ipv4 p;
1006 struct route_table *table;
1007 struct route_node *rn;
1008
1009 ret = str2prefix_ipv4 (argv[0], &p);
1010 if (ret <= 0)
1011 {
1012 vty_out (vty, "%% Malformed IPv4 address%s", VTY_NEWLINE);
1013 return CMD_WARNING;
1014 }
1015
1016 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
1017 if (! table)
1018 return CMD_SUCCESS;
1019
1020 rn = route_node_match (table, (struct prefix *) &p);
1021 if (! rn || rn->p.prefixlen != p.prefixlen)
1022 {
1023 vty_out (vty, "%% Network not in table%s", VTY_NEWLINE);
1024 return CMD_WARNING;
1025 }
1026
1027 vty_show_ip_route_detail (vty, rn);
1028
1029 route_unlock_node (rn);
1030
1031 return CMD_SUCCESS;
1032}
1033
a1ac18c4 1034static void
61691c91 1035vty_show_ip_route_summary (struct vty *vty, struct route_table *table)
718e3744 1036{
61691c91
ST
1037 struct route_node *rn;
1038 struct rib *rib;
1039 struct nexthop *nexthop;
1040#define ZEBRA_ROUTE_IBGP ZEBRA_ROUTE_MAX
1041#define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1)
1042 u_int32_t rib_cnt[ZEBRA_ROUTE_TOTAL + 1];
1043 u_int32_t fib_cnt[ZEBRA_ROUTE_TOTAL + 1];
1044 u_int32_t i;
1045
1046 memset (&rib_cnt, 0, sizeof(rib_cnt));
1047 memset (&fib_cnt, 0, sizeof(fib_cnt));
1048 for (rn = route_top (table); rn; rn = route_next (rn))
1049 for (rib = rn->info; rib; rib = rib->next)
1050 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1051 {
1052 rib_cnt[ZEBRA_ROUTE_TOTAL]++;
1053 rib_cnt[rib->type]++;
1054 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
1055 {
1056 fib_cnt[ZEBRA_ROUTE_TOTAL]++;
1057 fib_cnt[rib->type]++;
1058 }
1059 if (rib->type == ZEBRA_ROUTE_BGP &&
1060 CHECK_FLAG (rib->flags, ZEBRA_FLAG_IBGP))
1061 {
1062 rib_cnt[ZEBRA_ROUTE_IBGP]++;
1063 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
1064 fib_cnt[ZEBRA_ROUTE_IBGP]++;
1065 }
1066 }
1067
1068 vty_out (vty, "%-20s %-20s %-20s %s",
1069 "Route Source", "Routes", "FIB", VTY_NEWLINE);
1070
1071 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
1072 {
1073 if (rib_cnt[i] > 0)
1074 {
1075 if (i == ZEBRA_ROUTE_BGP)
1076 {
1077 vty_out (vty, "%-20s %-20d %-20d %s", "ebgp",
1078 rib_cnt[ZEBRA_ROUTE_BGP] - rib_cnt[ZEBRA_ROUTE_IBGP],
1079 fib_cnt[ZEBRA_ROUTE_BGP] - fib_cnt[ZEBRA_ROUTE_IBGP],
1080 VTY_NEWLINE);
1081 vty_out (vty, "%-20s %-20d %-20d %s", "ibgp",
1082 rib_cnt[ZEBRA_ROUTE_IBGP], fib_cnt[ZEBRA_ROUTE_IBGP],
1083 VTY_NEWLINE);
1084 }
1085 else
1086 vty_out (vty, "%-20s %-20d %-20d %s", zebra_route_string(i),
1087 rib_cnt[i], fib_cnt[i], VTY_NEWLINE);
1088 }
1089 }
1090
1091 vty_out (vty, "------%s", VTY_NEWLINE);
1092 vty_out (vty, "%-20s %-20d %-20d %s", "Totals", rib_cnt[ZEBRA_ROUTE_TOTAL],
1093 fib_cnt[ZEBRA_ROUTE_TOTAL], VTY_NEWLINE);
718e3744 1094}
1095
1096/* Show route summary. */
1097DEFUN (show_ip_route_summary,
1098 show_ip_route_summary_cmd,
1099 "show ip route summary",
1100 SHOW_STR
1101 IP_STR
1102 "IP routing table\n"
1103 "Summary of all routes\n")
1104{
61691c91 1105 struct route_table *table;
718e3744 1106
61691c91
ST
1107 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
1108 if (! table)
1109 return CMD_SUCCESS;
718e3744 1110
61691c91 1111 vty_show_ip_route_summary (vty, table);
718e3744 1112
1113 return CMD_SUCCESS;
1114}
1115
1116/* Write IPv4 static route configuration. */
a1ac18c4 1117static int
718e3744 1118static_config_ipv4 (struct vty *vty)
1119{
1120 struct route_node *rn;
1121 struct static_ipv4 *si;
1122 struct route_table *stable;
1123 int write;
1124
1125 write = 0;
1126
1127 /* Lookup table. */
1128 stable = vrf_static_table (AFI_IP, SAFI_UNICAST, 0);
1129 if (! stable)
1130 return -1;
1131
1132 for (rn = route_top (stable); rn; rn = route_next (rn))
1133 for (si = rn->info; si; si = si->next)
1134 {
7021c425 1135 vty_out (vty, "ip route %s/%d", inet_ntoa (rn->p.u.prefix4),
1136 rn->p.prefixlen);
1137
1138 switch (si->type)
1139 {
1140 case STATIC_IPV4_GATEWAY:
1141 vty_out (vty, " %s", inet_ntoa (si->gate.ipv4));
1142 break;
1143 case STATIC_IPV4_IFNAME:
1144 vty_out (vty, " %s", si->gate.ifname);
1145 break;
1146 case STATIC_IPV4_BLACKHOLE:
1147 vty_out (vty, " Null0");
1148 break;
1149 }
1150
1151 /* flags are incompatible with STATIC_IPV4_BLACKHOLE */
1152 if (si->type != STATIC_IPV4_BLACKHOLE)
1153 {
1154 if (CHECK_FLAG(si->flags, ZEBRA_FLAG_REJECT))
1155 vty_out (vty, " %s", "reject");
1156
1157 if (CHECK_FLAG(si->flags, ZEBRA_FLAG_BLACKHOLE))
1158 vty_out (vty, " %s", "blackhole");
1159 }
1160
1161 if (si->distance != ZEBRA_STATIC_DISTANCE_DEFAULT)
1162 vty_out (vty, " %d", si->distance);
1163
1164 vty_out (vty, "%s", VTY_NEWLINE);
1165
1166 write = 1;
718e3744 1167 }
1168 return write;
1169}
09303314
AS
1170
1171DEFUN (show_ip_protocol,
1172 show_ip_protocol_cmd,
1173 "show ip protocol",
1174 SHOW_STR
1175 IP_STR
1176 "IP protocol filtering status\n")
1177{
1178 int i;
1179
1180 vty_out(vty, "Protocol : route-map %s", VTY_NEWLINE);
1181 vty_out(vty, "------------------------%s", VTY_NEWLINE);
1182 for (i=0;i<ZEBRA_ROUTE_MAX;i++)
1183 {
1184 if (proto_rm[AFI_IP][i])
1185 vty_out (vty, "%-10s : %-10s%s", zebra_route_string(i),
1186 proto_rm[AFI_IP][i],
1187 VTY_NEWLINE);
1188 else
1189 vty_out (vty, "%-10s : none%s", zebra_route_string(i), VTY_NEWLINE);
1190 }
1191 if (proto_rm[AFI_IP][i])
1192 vty_out (vty, "%-10s : %-10s%s", "any", proto_rm[AFI_IP][i],
1193 VTY_NEWLINE);
1194 else
1195 vty_out (vty, "%-10s : none%s", "any", VTY_NEWLINE);
1196
1197 return CMD_SUCCESS;
1198}
1199
718e3744 1200\f
1201#ifdef HAVE_IPV6
1202/* General fucntion for IPv6 static route. */
a1ac18c4 1203static int
39db97e4 1204static_ipv6_func (struct vty *vty, int add_cmd, const char *dest_str,
1205 const char *gate_str, const char *ifname,
1206 const char *flag_str, const char *distance_str)
718e3744 1207{
1208 int ret;
1209 u_char distance;
1210 struct prefix p;
1211 struct in6_addr *gate = NULL;
1212 struct in6_addr gate_addr;
1213 u_char type = 0;
1214 int table = 0;
81dfcaa2 1215 u_char flag = 0;
718e3744 1216
1217 ret = str2prefix (dest_str, &p);
1218 if (ret <= 0)
1219 {
1220 vty_out (vty, "%% Malformed address%s", VTY_NEWLINE);
1221 return CMD_WARNING;
1222 }
1223
1224 /* Apply mask for given prefix. */
1225 apply_mask (&p);
1226
81dfcaa2 1227 /* Route flags */
1228 if (flag_str) {
1229 switch(flag_str[0]) {
1230 case 'r':
1231 case 'R': /* XXX */
1232 SET_FLAG (flag, ZEBRA_FLAG_REJECT);
1233 break;
1234 case 'b':
1235 case 'B': /* XXX */
1236 SET_FLAG (flag, ZEBRA_FLAG_BLACKHOLE);
1237 break;
1238 default:
1239 vty_out (vty, "%% Malformed flag %s %s", flag_str, VTY_NEWLINE);
595db7f1 1240 return CMD_WARNING;
81dfcaa2 1241 }
1242 }
1243
718e3744 1244 /* Administrative distance. */
1245 if (distance_str)
1246 distance = atoi (distance_str);
1247 else
1248 distance = ZEBRA_STATIC_DISTANCE_DEFAULT;
1249
1250 /* When gateway is valid IPv6 addrees, then gate is treated as
1251 nexthop address other case gate is treated as interface name. */
1252 ret = inet_pton (AF_INET6, gate_str, &gate_addr);
1253
1254 if (ifname)
1255 {
1256 /* When ifname is specified. It must be come with gateway
1257 address. */
1258 if (ret != 1)
1259 {
1260 vty_out (vty, "%% Malformed address%s", VTY_NEWLINE);
1261 return CMD_WARNING;
1262 }
1263 type = STATIC_IPV6_GATEWAY_IFNAME;
1264 gate = &gate_addr;
1265 }
1266 else
1267 {
1268 if (ret == 1)
1269 {
1270 type = STATIC_IPV6_GATEWAY;
1271 gate = &gate_addr;
1272 }
1273 else
1274 {
1275 type = STATIC_IPV6_IFNAME;
1276 ifname = gate_str;
1277 }
1278 }
1279
1280 if (add_cmd)
81dfcaa2 1281 static_add_ipv6 (&p, type, gate, ifname, flag, distance, table);
718e3744 1282 else
1283 static_delete_ipv6 (&p, type, gate, ifname, distance, table);
1284
1285 return CMD_SUCCESS;
1286}
1287
1288DEFUN (ipv6_route,
1289 ipv6_route_cmd,
1290 "ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE)",
1291 IP_STR
1292 "Establish static routes\n"
1293 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1294 "IPv6 gateway address\n"
1295 "IPv6 gateway interface name\n")
1296{
81dfcaa2 1297 return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, NULL, NULL);
1298}
1299
1300DEFUN (ipv6_route_flags,
1301 ipv6_route_flags_cmd,
1302 "ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) (reject|blackhole)",
1303 IP_STR
1304 "Establish static routes\n"
1305 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1306 "IPv6 gateway address\n"
1307 "IPv6 gateway interface name\n"
1308 "Emit an ICMP unreachable when matched\n"
1309 "Silently discard pkts when matched\n")
1310{
1311 return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, argv[2], NULL);
718e3744 1312}
1313
1314DEFUN (ipv6_route_ifname,
1315 ipv6_route_ifname_cmd,
1316 "ipv6 route X:X::X:X/M X:X::X:X INTERFACE",
1317 IP_STR
1318 "Establish static routes\n"
1319 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1320 "IPv6 gateway address\n"
1321 "IPv6 gateway interface name\n")
1322{
81dfcaa2 1323 return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], NULL, NULL);
1324}
1325
1326DEFUN (ipv6_route_ifname_flags,
1327 ipv6_route_ifname_flags_cmd,
1328 "ipv6 route X:X::X:X/M X:X::X:X INTERFACE (reject|blackhole)",
1329 IP_STR
1330 "Establish static routes\n"
1331 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1332 "IPv6 gateway address\n"
1333 "IPv6 gateway interface name\n"
1334 "Emit an ICMP unreachable when matched\n"
1335 "Silently discard pkts when matched\n")
1336{
1337 return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], argv[3], NULL);
718e3744 1338}
1339
1340DEFUN (ipv6_route_pref,
1341 ipv6_route_pref_cmd,
1342 "ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) <1-255>",
1343 IP_STR
1344 "Establish static routes\n"
1345 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1346 "IPv6 gateway address\n"
1347 "IPv6 gateway interface name\n"
1348 "Distance value for this prefix\n")
1349{
81dfcaa2 1350 return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, NULL, argv[2]);
1351}
1352
1353DEFUN (ipv6_route_flags_pref,
1354 ipv6_route_flags_pref_cmd,
1355 "ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) (reject|blackhole) <1-255>",
1356 IP_STR
1357 "Establish static routes\n"
1358 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1359 "IPv6 gateway address\n"
1360 "IPv6 gateway interface name\n"
1361 "Emit an ICMP unreachable when matched\n"
1362 "Silently discard pkts when matched\n"
1363 "Distance value for this prefix\n")
1364{
1365 return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, argv[2], argv[3]);
718e3744 1366}
1367
1368DEFUN (ipv6_route_ifname_pref,
1369 ipv6_route_ifname_pref_cmd,
1370 "ipv6 route X:X::X:X/M X:X::X:X INTERFACE <1-255>",
1371 IP_STR
1372 "Establish static routes\n"
1373 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1374 "IPv6 gateway address\n"
1375 "IPv6 gateway interface name\n"
1376 "Distance value for this prefix\n")
1377{
81dfcaa2 1378 return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], NULL, argv[3]);
1379}
1380
1381DEFUN (ipv6_route_ifname_flags_pref,
1382 ipv6_route_ifname_flags_pref_cmd,
1383 "ipv6 route X:X::X:X/M X:X::X:X INTERFACE (reject|blackhole) <1-255>",
1384 IP_STR
1385 "Establish static routes\n"
1386 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1387 "IPv6 gateway address\n"
1388 "IPv6 gateway interface name\n"
1389 "Emit an ICMP unreachable when matched\n"
1390 "Silently discard pkts when matched\n"
1391 "Distance value for this prefix\n")
1392{
1393 return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], argv[3], argv[4]);
718e3744 1394}
1395
1396DEFUN (no_ipv6_route,
1397 no_ipv6_route_cmd,
1398 "no ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE)",
1399 NO_STR
1400 IP_STR
1401 "Establish static routes\n"
1402 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1403 "IPv6 gateway address\n"
1404 "IPv6 gateway interface name\n")
1405{
81dfcaa2 1406 return static_ipv6_func (vty, 0, argv[0], argv[1], NULL, NULL, NULL);
718e3744 1407}
1408
81dfcaa2 1409ALIAS (no_ipv6_route,
1410 no_ipv6_route_flags_cmd,
1411 "no ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) (reject|blackhole)",
1412 NO_STR
1413 IP_STR
1414 "Establish static routes\n"
1415 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1416 "IPv6 gateway address\n"
1417 "IPv6 gateway interface name\n"
1418 "Emit an ICMP unreachable when matched\n"
1419 "Silently discard pkts when matched\n")
1420
718e3744 1421DEFUN (no_ipv6_route_ifname,
1422 no_ipv6_route_ifname_cmd,
1423 "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE",
1424 NO_STR
1425 IP_STR
1426 "Establish static routes\n"
1427 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1428 "IPv6 gateway address\n"
1429 "IPv6 gateway interface name\n")
1430{
81dfcaa2 1431 return static_ipv6_func (vty, 0, argv[0], argv[1], argv[2], NULL, NULL);
718e3744 1432}
1433
81dfcaa2 1434ALIAS (no_ipv6_route_ifname,
1435 no_ipv6_route_ifname_flags_cmd,
1436 "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE (reject|blackhole)",
1437 NO_STR
1438 IP_STR
1439 "Establish static routes\n"
1440 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1441 "IPv6 gateway address\n"
1442 "IPv6 gateway interface name\n"
1443 "Emit an ICMP unreachable when matched\n"
1444 "Silently discard pkts when matched\n")
1445
718e3744 1446DEFUN (no_ipv6_route_pref,
1447 no_ipv6_route_pref_cmd,
1448 "no ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) <1-255>",
1449 NO_STR
1450 IP_STR
1451 "Establish static routes\n"
1452 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1453 "IPv6 gateway address\n"
1454 "IPv6 gateway interface name\n"
1455 "Distance value for this prefix\n")
1456{
81dfcaa2 1457 return static_ipv6_func (vty, 0, argv[0], argv[1], NULL, NULL, argv[2]);
1458}
1459
1460DEFUN (no_ipv6_route_flags_pref,
1461 no_ipv6_route_flags_pref_cmd,
1462 "no ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) (reject|blackhole) <1-255>",
1463 NO_STR
1464 IP_STR
1465 "Establish static routes\n"
1466 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1467 "IPv6 gateway address\n"
1468 "IPv6 gateway interface name\n"
1469 "Emit an ICMP unreachable when matched\n"
1470 "Silently discard pkts when matched\n"
1471 "Distance value for this prefix\n")
1472{
1473 /* We do not care about argv[2] */
1474 return static_ipv6_func (vty, 0, argv[0], argv[1], NULL, argv[2], argv[3]);
718e3744 1475}
1476
1477DEFUN (no_ipv6_route_ifname_pref,
1478 no_ipv6_route_ifname_pref_cmd,
1479 "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE <1-255>",
1480 NO_STR
1481 IP_STR
1482 "Establish static routes\n"
1483 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1484 "IPv6 gateway address\n"
1485 "IPv6 gateway interface name\n"
1486 "Distance value for this prefix\n")
1487{
81dfcaa2 1488 return static_ipv6_func (vty, 0, argv[0], argv[1], argv[2], NULL, argv[3]);
1489}
1490
1491DEFUN (no_ipv6_route_ifname_flags_pref,
1492 no_ipv6_route_ifname_flags_pref_cmd,
1493 "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE (reject|blackhole) <1-255>",
1494 NO_STR
1495 IP_STR
1496 "Establish static routes\n"
1497 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1498 "IPv6 gateway address\n"
1499 "IPv6 gateway interface name\n"
1500 "Emit an ICMP unreachable when matched\n"
1501 "Silently discard pkts when matched\n"
1502 "Distance value for this prefix\n")
1503{
1504 return static_ipv6_func (vty, 0, argv[0], argv[1], argv[2], argv[3], argv[4]);
718e3744 1505}
1506
595db7f1 1507/* New RIB. Detailed information for IPv6 route. */
a1ac18c4 1508static void
718e3744 1509vty_show_ipv6_route_detail (struct vty *vty, struct route_node *rn)
1510{
1511 struct rib *rib;
1512 struct nexthop *nexthop;
1513 char buf[BUFSIZ];
1514
1515 for (rib = rn->info; rib; rib = rib->next)
1516 {
1517 vty_out (vty, "Routing entry for %s/%d%s",
1518 inet_ntop (AF_INET6, &rn->p.u.prefix6, buf, BUFSIZ),
1519 rn->p.prefixlen,
1520 VTY_NEWLINE);
f52d13cb 1521 vty_out (vty, " Known via \"%s\"", zebra_route_string (rib->type));
718e3744 1522 vty_out (vty, ", distance %d, metric %d", rib->distance, rib->metric);
1523 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
1524 vty_out (vty, ", best");
1525 if (rib->refcnt)
1526 vty_out (vty, ", refcnt %ld", rib->refcnt);
81dfcaa2 1527 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_BLACKHOLE))
1528 vty_out (vty, ", blackhole");
1529 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_REJECT))
1530 vty_out (vty, ", reject");
718e3744 1531 vty_out (vty, "%s", VTY_NEWLINE);
1532
1533#define ONE_DAY_SECOND 60*60*24
1534#define ONE_WEEK_SECOND 60*60*24*7
1535 if (rib->type == ZEBRA_ROUTE_RIPNG
1536 || rib->type == ZEBRA_ROUTE_OSPF6
578ce371 1537 || rib->type == ZEBRA_ROUTE_BABEL
9e867fe6 1538 || rib->type == ZEBRA_ROUTE_ISIS
718e3744 1539 || rib->type == ZEBRA_ROUTE_BGP)
1540 {
1541 time_t uptime;
1542 struct tm *tm;
1543
1544 uptime = time (NULL);
1545 uptime -= rib->uptime;
1546 tm = gmtime (&uptime);
1547
1548 vty_out (vty, " Last update ");
1549
1550 if (uptime < ONE_DAY_SECOND)
1551 vty_out (vty, "%02d:%02d:%02d",
1552 tm->tm_hour, tm->tm_min, tm->tm_sec);
1553 else if (uptime < ONE_WEEK_SECOND)
1554 vty_out (vty, "%dd%02dh%02dm",
1555 tm->tm_yday, tm->tm_hour, tm->tm_min);
1556 else
1557 vty_out (vty, "%02dw%dd%02dh",
1558 tm->tm_yday/7,
1559 tm->tm_yday - ((tm->tm_yday/7) * 7), tm->tm_hour);
1560 vty_out (vty, " ago%s", VTY_NEWLINE);
1561 }
1562
1563 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1564 {
1565 vty_out (vty, " %c",
1566 CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB) ? '*' : ' ');
1567
1568 switch (nexthop->type)
1569 {
1570 case NEXTHOP_TYPE_IPV6:
1571 case NEXTHOP_TYPE_IPV6_IFINDEX:
1572 case NEXTHOP_TYPE_IPV6_IFNAME:
1573 vty_out (vty, " %s",
1574 inet_ntop (AF_INET6, &nexthop->gate.ipv6, buf, BUFSIZ));
1575 if (nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME)
1576 vty_out (vty, ", %s", nexthop->ifname);
1577 else if (nexthop->ifindex)
1578 vty_out (vty, ", via %s", ifindex2ifname (nexthop->ifindex));
1579 break;
1580 case NEXTHOP_TYPE_IFINDEX:
1581 vty_out (vty, " directly connected, %s",
1582 ifindex2ifname (nexthop->ifindex));
1583 break;
1584 case NEXTHOP_TYPE_IFNAME:
1585 vty_out (vty, " directly connected, %s",
1586 nexthop->ifname);
1587 break;
1588 default:
1589 break;
1590 }
1591 if (! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
1592 vty_out (vty, " inactive");
1593
1594 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
1595 {
1596 vty_out (vty, " (recursive");
1597
1598 switch (nexthop->rtype)
1599 {
1600 case NEXTHOP_TYPE_IPV6:
1601 case NEXTHOP_TYPE_IPV6_IFINDEX:
1602 case NEXTHOP_TYPE_IPV6_IFNAME:
1603 vty_out (vty, " via %s)",
1604 inet_ntop (AF_INET6, &nexthop->rgate.ipv6,
1605 buf, BUFSIZ));
1606 if (nexthop->rifindex)
1607 vty_out (vty, ", %s", ifindex2ifname (nexthop->rifindex));
1608 break;
1609 case NEXTHOP_TYPE_IFINDEX:
1610 case NEXTHOP_TYPE_IFNAME:
1611 vty_out (vty, " is directly connected, %s)",
1612 ifindex2ifname (nexthop->rifindex));
1613 break;
1614 default:
1615 break;
1616 }
1617 }
1618 vty_out (vty, "%s", VTY_NEWLINE);
1619 }
1620 vty_out (vty, "%s", VTY_NEWLINE);
1621 }
1622}
1623
a1ac18c4 1624static void
718e3744 1625vty_show_ipv6_route (struct vty *vty, struct route_node *rn,
1626 struct rib *rib)
1627{
1628 struct nexthop *nexthop;
1629 int len = 0;
1630 char buf[BUFSIZ];
1631
1632 /* Nexthop information. */
1633 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1634 {
1635 if (nexthop == rib->nexthop)
1636 {
1637 /* Prefix information. */
1638 len = vty_out (vty, "%c%c%c %s/%d",
f52d13cb 1639 zebra_route_char (rib->type),
718e3744 1640 CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED)
1641 ? '>' : ' ',
1642 CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)
1643 ? '*' : ' ',
1644 inet_ntop (AF_INET6, &rn->p.u.prefix6, buf, BUFSIZ),
1645 rn->p.prefixlen);
1646
1647 /* Distance and metric display. */
1648 if (rib->type != ZEBRA_ROUTE_CONNECT
1649 && rib->type != ZEBRA_ROUTE_KERNEL)
1650 len += vty_out (vty, " [%d/%d]", rib->distance,
1651 rib->metric);
1652 }
1653 else
1654 vty_out (vty, " %c%*c",
1655 CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)
1656 ? '*' : ' ',
1657 len - 3, ' ');
1658
1659 switch (nexthop->type)
1660 {
1661 case NEXTHOP_TYPE_IPV6:
1662 case NEXTHOP_TYPE_IPV6_IFINDEX:
1663 case NEXTHOP_TYPE_IPV6_IFNAME:
1664 vty_out (vty, " via %s",
1665 inet_ntop (AF_INET6, &nexthop->gate.ipv6, buf, BUFSIZ));
1666 if (nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME)
1667 vty_out (vty, ", %s", nexthop->ifname);
1668 else if (nexthop->ifindex)
1669 vty_out (vty, ", %s", ifindex2ifname (nexthop->ifindex));
1670 break;
1671 case NEXTHOP_TYPE_IFINDEX:
1672 vty_out (vty, " is directly connected, %s",
1673 ifindex2ifname (nexthop->ifindex));
1674 break;
1675 case NEXTHOP_TYPE_IFNAME:
1676 vty_out (vty, " is directly connected, %s",
1677 nexthop->ifname);
1678 break;
1679 default:
1680 break;
1681 }
1682 if (! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
1683 vty_out (vty, " inactive");
1684
1685 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
1686 {
1687 vty_out (vty, " (recursive");
1688
1689 switch (nexthop->rtype)
1690 {
1691 case NEXTHOP_TYPE_IPV6:
1692 case NEXTHOP_TYPE_IPV6_IFINDEX:
1693 case NEXTHOP_TYPE_IPV6_IFNAME:
1694 vty_out (vty, " via %s)",
1695 inet_ntop (AF_INET6, &nexthop->rgate.ipv6,
1696 buf, BUFSIZ));
1697 if (nexthop->rifindex)
1698 vty_out (vty, ", %s", ifindex2ifname (nexthop->rifindex));
1699 break;
1700 case NEXTHOP_TYPE_IFINDEX:
1701 case NEXTHOP_TYPE_IFNAME:
1702 vty_out (vty, " is directly connected, %s)",
1703 ifindex2ifname (nexthop->rifindex));
1704 break;
1705 default:
1706 break;
1707 }
1708 }
1709
81dfcaa2 1710 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_BLACKHOLE))
1711 vty_out (vty, ", bh");
1712 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_REJECT))
1713 vty_out (vty, ", rej");
1714
718e3744 1715 if (rib->type == ZEBRA_ROUTE_RIPNG
1716 || rib->type == ZEBRA_ROUTE_OSPF6
578ce371 1717 || rib->type == ZEBRA_ROUTE_BABEL
9e867fe6 1718 || rib->type == ZEBRA_ROUTE_ISIS
718e3744 1719 || rib->type == ZEBRA_ROUTE_BGP)
1720 {
1721 time_t uptime;
1722 struct tm *tm;
1723
1724 uptime = time (NULL);
1725 uptime -= rib->uptime;
1726 tm = gmtime (&uptime);
1727
1728#define ONE_DAY_SECOND 60*60*24
1729#define ONE_WEEK_SECOND 60*60*24*7
1730
1731 if (uptime < ONE_DAY_SECOND)
1732 vty_out (vty, ", %02d:%02d:%02d",
1733 tm->tm_hour, tm->tm_min, tm->tm_sec);
1734 else if (uptime < ONE_WEEK_SECOND)
1735 vty_out (vty, ", %dd%02dh%02dm",
1736 tm->tm_yday, tm->tm_hour, tm->tm_min);
1737 else
1738 vty_out (vty, ", %02dw%dd%02dh",
1739 tm->tm_yday/7,
1740 tm->tm_yday - ((tm->tm_yday/7) * 7), tm->tm_hour);
1741 }
1742 vty_out (vty, "%s", VTY_NEWLINE);
1743 }
1744}
1745
718e3744 1746DEFUN (show_ipv6_route,
1747 show_ipv6_route_cmd,
1748 "show ipv6 route",
1749 SHOW_STR
1750 IP_STR
1751 "IPv6 routing table\n")
1752{
1753 struct route_table *table;
1754 struct route_node *rn;
1755 struct rib *rib;
1756 int first = 1;
1757
1758 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
1759 if (! table)
1760 return CMD_SUCCESS;
1761
1762 /* Show all IPv6 route. */
1763 for (rn = route_top (table); rn; rn = route_next (rn))
1764 for (rib = rn->info; rib; rib = rib->next)
1765 {
1766 if (first)
1767 {
e0ca5fde 1768 vty_out (vty, SHOW_ROUTE_V6_HEADER);
718e3744 1769 first = 0;
1770 }
1771 vty_show_ipv6_route (vty, rn, rib);
1772 }
1773 return CMD_SUCCESS;
1774}
1775
1776DEFUN (show_ipv6_route_prefix_longer,
1777 show_ipv6_route_prefix_longer_cmd,
1778 "show ipv6 route X:X::X:X/M longer-prefixes",
1779 SHOW_STR
1780 IP_STR
1781 "IPv6 routing table\n"
1782 "IPv6 prefix\n"
1783 "Show route matching the specified Network/Mask pair only\n")
1784{
1785 struct route_table *table;
1786 struct route_node *rn;
1787 struct rib *rib;
1788 struct prefix p;
1789 int ret;
1790 int first = 1;
1791
1792 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
1793 if (! table)
1794 return CMD_SUCCESS;
1795
1796 ret = str2prefix (argv[0], &p);
1797 if (! ret)
1798 {
1799 vty_out (vty, "%% Malformed Prefix%s", VTY_NEWLINE);
1800 return CMD_WARNING;
1801 }
1802
1803 /* Show matched type IPv6 routes. */
1804 for (rn = route_top (table); rn; rn = route_next (rn))
1805 for (rib = rn->info; rib; rib = rib->next)
1806 if (prefix_match (&p, &rn->p))
1807 {
1808 if (first)
1809 {
e0ca5fde 1810 vty_out (vty, SHOW_ROUTE_V6_HEADER);
718e3744 1811 first = 0;
1812 }
1813 vty_show_ipv6_route (vty, rn, rib);
1814 }
1815 return CMD_SUCCESS;
1816}
1817
1818DEFUN (show_ipv6_route_protocol,
1819 show_ipv6_route_protocol_cmd,
e0ca5fde 1820 "show ipv6 route " QUAGGA_IP6_REDIST_STR_ZEBRA,
718e3744 1821 SHOW_STR
1822 IP_STR
1823 "IP routing table\n"
e0ca5fde 1824 QUAGGA_IP6_REDIST_HELP_STR_ZEBRA)
718e3744 1825{
1826 int type;
1827 struct route_table *table;
1828 struct route_node *rn;
1829 struct rib *rib;
1830 int first = 1;
1831
e0ca5fde
DL
1832 type = proto_redistnum (AFI_IP6, argv[0]);
1833 if (type < 0)
718e3744 1834 {
1835 vty_out (vty, "Unknown route type%s", VTY_NEWLINE);
1836 return CMD_WARNING;
1837 }
1838
1839 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
1840 if (! table)
1841 return CMD_SUCCESS;
1842
1843 /* Show matched type IPv6 routes. */
1844 for (rn = route_top (table); rn; rn = route_next (rn))
1845 for (rib = rn->info; rib; rib = rib->next)
1846 if (rib->type == type)
1847 {
1848 if (first)
1849 {
e0ca5fde 1850 vty_out (vty, SHOW_ROUTE_V6_HEADER);
718e3744 1851 first = 0;
1852 }
1853 vty_show_ipv6_route (vty, rn, rib);
1854 }
1855 return CMD_SUCCESS;
1856}
1857
1858DEFUN (show_ipv6_route_addr,
1859 show_ipv6_route_addr_cmd,
1860 "show ipv6 route X:X::X:X",
1861 SHOW_STR
1862 IP_STR
1863 "IPv6 routing table\n"
1864 "IPv6 Address\n")
1865{
1866 int ret;
1867 struct prefix_ipv6 p;
1868 struct route_table *table;
1869 struct route_node *rn;
1870
1871 ret = str2prefix_ipv6 (argv[0], &p);
1872 if (ret <= 0)
1873 {
1874 vty_out (vty, "Malformed IPv6 address%s", VTY_NEWLINE);
1875 return CMD_WARNING;
1876 }
1877
1878 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
1879 if (! table)
1880 return CMD_SUCCESS;
1881
1882 rn = route_node_match (table, (struct prefix *) &p);
1883 if (! rn)
1884 {
1885 vty_out (vty, "%% Network not in table%s", VTY_NEWLINE);
1886 return CMD_WARNING;
1887 }
1888
1889 vty_show_ipv6_route_detail (vty, rn);
1890
1891 route_unlock_node (rn);
1892
1893 return CMD_SUCCESS;
1894}
1895
1896DEFUN (show_ipv6_route_prefix,
1897 show_ipv6_route_prefix_cmd,
1898 "show ipv6 route X:X::X:X/M",
1899 SHOW_STR
1900 IP_STR
1901 "IPv6 routing table\n"
1902 "IPv6 prefix\n")
1903{
1904 int ret;
1905 struct prefix_ipv6 p;
1906 struct route_table *table;
1907 struct route_node *rn;
1908
1909 ret = str2prefix_ipv6 (argv[0], &p);
1910 if (ret <= 0)
1911 {
1912 vty_out (vty, "Malformed IPv6 prefix%s", VTY_NEWLINE);
1913 return CMD_WARNING;
1914 }
1915
1916 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
1917 if (! table)
1918 return CMD_SUCCESS;
1919
1920 rn = route_node_match (table, (struct prefix *) &p);
1921 if (! rn || rn->p.prefixlen != p.prefixlen)
1922 {
1923 vty_out (vty, "%% Network not in table%s", VTY_NEWLINE);
1924 return CMD_WARNING;
1925 }
1926
1927 vty_show_ipv6_route_detail (vty, rn);
1928
1929 route_unlock_node (rn);
1930
1931 return CMD_SUCCESS;
1932}
1933
61691c91
ST
1934/* Show route summary. */
1935DEFUN (show_ipv6_route_summary,
1936 show_ipv6_route_summary_cmd,
1937 "show ipv6 route summary",
1938 SHOW_STR
1939 IP_STR
1940 "IPv6 routing table\n"
1941 "Summary of all IPv6 routes\n")
1942{
1943 struct route_table *table;
1944
1945 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
1946 if (! table)
1947 return CMD_SUCCESS;
1948
1949 vty_show_ip_route_summary (vty, table);
1950
1951 return CMD_SUCCESS;
1952}
1953
cddf391b
B
1954/*
1955 * Show IP mroute command to dump the BGP Multicast
1956 * routing table
1957 */
1958DEFUN (show_ip_mroute,
1959 show_ip_mroute_cmd,
1960 "show ip mroute",
1961 SHOW_STR
1962 IP_STR
1963 "IP Multicast routing table\n")
1964{
1965 struct route_table *table;
1966 struct route_node *rn;
1967 struct rib *rib;
1968 int first = 1;
1969
1970 table = vrf_table (AFI_IP, SAFI_MULTICAST, 0);
1971 if (! table)
1972 return CMD_SUCCESS;
1973
1974 /* Show all IPv4 routes. */
1975 for (rn = route_top (table); rn; rn = route_next (rn))
1976 for (rib = rn->info; rib; rib = rib->next)
1977 {
1978 if (first)
1979 {
cb32fd69 1980 vty_out (vty, SHOW_ROUTE_V4_HEADER);
cddf391b
B
1981 first = 0;
1982 }
1983 vty_show_ip_route (vty, rn, rib);
1984 }
1985 return CMD_SUCCESS;
1986}
1987
1988/*
1989 * Show IPv6 mroute command.Used to dump
1990 * the Multicast routing table.
1991 */
1992
1993DEFUN (show_ipv6_mroute,
1994 show_ipv6_mroute_cmd,
1995 "show ipv6 mroute",
1996 SHOW_STR
1997 IP_STR
1998 "IPv6 Multicast routing table\n")
1999{
2000 struct route_table *table;
2001 struct route_node *rn;
2002 struct rib *rib;
2003 int first = 1;
2004
2005 table = vrf_table (AFI_IP6, SAFI_MULTICAST, 0);
2006 if (! table)
2007 return CMD_SUCCESS;
2008
2009 /* Show all IPv6 route. */
2010 for (rn = route_top (table); rn; rn = route_next (rn))
2011 for (rib = rn->info; rib; rib = rib->next)
2012 {
2013 if (first)
2014 {
cb32fd69 2015 vty_out (vty, SHOW_ROUTE_V6_HEADER);
cddf391b
B
2016 first = 0;
2017 }
2018 vty_show_ipv6_route (vty, rn, rib);
2019 }
2020 return CMD_SUCCESS;
2021}
2022
2023
2024
2025
2026
2027
718e3744 2028/* Write IPv6 static route configuration. */
a1ac18c4 2029static int
718e3744 2030static_config_ipv6 (struct vty *vty)
2031{
2032 struct route_node *rn;
2033 struct static_ipv6 *si;
2034 int write;
2035 char buf[BUFSIZ];
2036 struct route_table *stable;
2037
2038 write = 0;
2039
2040 /* Lookup table. */
2041 stable = vrf_static_table (AFI_IP6, SAFI_UNICAST, 0);
2042 if (! stable)
2043 return -1;
2044
2045 for (rn = route_top (stable); rn; rn = route_next (rn))
2046 for (si = rn->info; si; si = si->next)
2047 {
2048 vty_out (vty, "ipv6 route %s/%d",
2049 inet_ntop (AF_INET6, &rn->p.u.prefix6, buf, BUFSIZ),
2050 rn->p.prefixlen);
2051
2052 switch (si->type)
2053 {
2054 case STATIC_IPV6_GATEWAY:
2055 vty_out (vty, " %s", inet_ntop (AF_INET6, &si->ipv6, buf, BUFSIZ));
2056 break;
2057 case STATIC_IPV6_IFNAME:
2058 vty_out (vty, " %s", si->ifname);
2059 break;
2060 case STATIC_IPV6_GATEWAY_IFNAME:
2061 vty_out (vty, " %s %s",
2062 inet_ntop (AF_INET6, &si->ipv6, buf, BUFSIZ), si->ifname);
2063 break;
2064 }
2065
81dfcaa2 2066 if (CHECK_FLAG(si->flags, ZEBRA_FLAG_REJECT))
2067 vty_out (vty, " %s", "reject");
2068
2069 if (CHECK_FLAG(si->flags, ZEBRA_FLAG_BLACKHOLE))
2070 vty_out (vty, " %s", "blackhole");
2071
718e3744 2072 if (si->distance != ZEBRA_STATIC_DISTANCE_DEFAULT)
2073 vty_out (vty, " %d", si->distance);
2074 vty_out (vty, "%s", VTY_NEWLINE);
2075
2076 write = 1;
2077 }
2078 return write;
2079}
2080#endif /* HAVE_IPV6 */
2081
2082/* Static ip route configuration write function. */
a1ac18c4 2083static int
718e3744 2084zebra_ip_config (struct vty *vty)
2085{
2086 int write = 0;
2087
2088 write += static_config_ipv4 (vty);
2089#ifdef HAVE_IPV6
2090 write += static_config_ipv6 (vty);
2091#endif /* HAVE_IPV6 */
2092
2093 return write;
2094}
2095
7514fb77
PJ
2096/* ip protocol configuration write function */
2097static int config_write_protocol(struct vty *vty)
2098{
2099 int i;
2100
2101 for (i=0;i<ZEBRA_ROUTE_MAX;i++)
2102 {
2103 if (proto_rm[AFI_IP][i])
2104 vty_out (vty, "ip protocol %s route-map %s%s", zebra_route_string(i),
2105 proto_rm[AFI_IP][i], VTY_NEWLINE);
2106 }
2107 if (proto_rm[AFI_IP][ZEBRA_ROUTE_MAX])
2108 vty_out (vty, "ip protocol %s route-map %s%s", "any",
2109 proto_rm[AFI_IP][ZEBRA_ROUTE_MAX], VTY_NEWLINE);
2110
2111 return 1;
2112}
2113
2114/* table node for protocol filtering */
7fc626de 2115static struct cmd_node protocol_node = { PROTOCOL_NODE, "", 1 };
7514fb77 2116
718e3744 2117/* IP node for static routes. */
7fc626de 2118static struct cmd_node ip_node = { IP_NODE, "", 1 };
718e3744 2119
2120/* Route VTY. */
2121void
a1ac18c4 2122zebra_vty_init (void)
718e3744 2123{
2124 install_node (&ip_node, zebra_ip_config);
7514fb77 2125 install_node (&protocol_node, config_write_protocol);
718e3744 2126
7514fb77
PJ
2127 install_element (CONFIG_NODE, &ip_protocol_cmd);
2128 install_element (CONFIG_NODE, &no_ip_protocol_cmd);
2129 install_element (VIEW_NODE, &show_ip_protocol_cmd);
2130 install_element (ENABLE_NODE, &show_ip_protocol_cmd);
718e3744 2131 install_element (CONFIG_NODE, &ip_route_cmd);
81dfcaa2 2132 install_element (CONFIG_NODE, &ip_route_flags_cmd);
457ef551 2133 install_element (CONFIG_NODE, &ip_route_flags2_cmd);
718e3744 2134 install_element (CONFIG_NODE, &ip_route_mask_cmd);
81dfcaa2 2135 install_element (CONFIG_NODE, &ip_route_mask_flags_cmd);
457ef551 2136 install_element (CONFIG_NODE, &ip_route_mask_flags2_cmd);
718e3744 2137 install_element (CONFIG_NODE, &no_ip_route_cmd);
81dfcaa2 2138 install_element (CONFIG_NODE, &no_ip_route_flags_cmd);
457ef551 2139 install_element (CONFIG_NODE, &no_ip_route_flags2_cmd);
718e3744 2140 install_element (CONFIG_NODE, &no_ip_route_mask_cmd);
81dfcaa2 2141 install_element (CONFIG_NODE, &no_ip_route_mask_flags_cmd);
457ef551 2142 install_element (CONFIG_NODE, &no_ip_route_mask_flags2_cmd);
718e3744 2143 install_element (CONFIG_NODE, &ip_route_distance_cmd);
81dfcaa2 2144 install_element (CONFIG_NODE, &ip_route_flags_distance_cmd);
457ef551 2145 install_element (CONFIG_NODE, &ip_route_flags_distance2_cmd);
718e3744 2146 install_element (CONFIG_NODE, &ip_route_mask_distance_cmd);
81dfcaa2 2147 install_element (CONFIG_NODE, &ip_route_mask_flags_distance_cmd);
457ef551 2148 install_element (CONFIG_NODE, &ip_route_mask_flags_distance2_cmd);
718e3744 2149 install_element (CONFIG_NODE, &no_ip_route_distance_cmd);
81dfcaa2 2150 install_element (CONFIG_NODE, &no_ip_route_flags_distance_cmd);
457ef551 2151 install_element (CONFIG_NODE, &no_ip_route_flags_distance2_cmd);
81dfcaa2 2152 install_element (CONFIG_NODE, &no_ip_route_mask_flags_distance_cmd);
457ef551 2153 install_element (CONFIG_NODE, &no_ip_route_mask_flags_distance2_cmd);
718e3744 2154
2155 install_element (VIEW_NODE, &show_ip_route_cmd);
2156 install_element (VIEW_NODE, &show_ip_route_addr_cmd);
2157 install_element (VIEW_NODE, &show_ip_route_prefix_cmd);
2158 install_element (VIEW_NODE, &show_ip_route_prefix_longer_cmd);
2159 install_element (VIEW_NODE, &show_ip_route_protocol_cmd);
2160 install_element (VIEW_NODE, &show_ip_route_supernets_cmd);
61691c91 2161 install_element (VIEW_NODE, &show_ip_route_summary_cmd);
718e3744 2162 install_element (ENABLE_NODE, &show_ip_route_cmd);
2163 install_element (ENABLE_NODE, &show_ip_route_addr_cmd);
2164 install_element (ENABLE_NODE, &show_ip_route_prefix_cmd);
2165 install_element (ENABLE_NODE, &show_ip_route_prefix_longer_cmd);
2166 install_element (ENABLE_NODE, &show_ip_route_protocol_cmd);
2167 install_element (ENABLE_NODE, &show_ip_route_supernets_cmd);
718e3744 2168 install_element (ENABLE_NODE, &show_ip_route_summary_cmd);
718e3744 2169
cddf391b
B
2170 install_element (VIEW_NODE, &show_ip_mroute_cmd);
2171 install_element (ENABLE_NODE, &show_ip_mroute_cmd);
2172
2173
718e3744 2174#ifdef HAVE_IPV6
2175 install_element (CONFIG_NODE, &ipv6_route_cmd);
81dfcaa2 2176 install_element (CONFIG_NODE, &ipv6_route_flags_cmd);
718e3744 2177 install_element (CONFIG_NODE, &ipv6_route_ifname_cmd);
81dfcaa2 2178 install_element (CONFIG_NODE, &ipv6_route_ifname_flags_cmd);
718e3744 2179 install_element (CONFIG_NODE, &no_ipv6_route_cmd);
81dfcaa2 2180 install_element (CONFIG_NODE, &no_ipv6_route_flags_cmd);
718e3744 2181 install_element (CONFIG_NODE, &no_ipv6_route_ifname_cmd);
81dfcaa2 2182 install_element (CONFIG_NODE, &no_ipv6_route_ifname_flags_cmd);
718e3744 2183 install_element (CONFIG_NODE, &ipv6_route_pref_cmd);
81dfcaa2 2184 install_element (CONFIG_NODE, &ipv6_route_flags_pref_cmd);
718e3744 2185 install_element (CONFIG_NODE, &ipv6_route_ifname_pref_cmd);
81dfcaa2 2186 install_element (CONFIG_NODE, &ipv6_route_ifname_flags_pref_cmd);
718e3744 2187 install_element (CONFIG_NODE, &no_ipv6_route_pref_cmd);
81dfcaa2 2188 install_element (CONFIG_NODE, &no_ipv6_route_flags_pref_cmd);
718e3744 2189 install_element (CONFIG_NODE, &no_ipv6_route_ifname_pref_cmd);
81dfcaa2 2190 install_element (CONFIG_NODE, &no_ipv6_route_ifname_flags_pref_cmd);
718e3744 2191 install_element (VIEW_NODE, &show_ipv6_route_cmd);
61691c91 2192 install_element (VIEW_NODE, &show_ipv6_route_summary_cmd);
718e3744 2193 install_element (VIEW_NODE, &show_ipv6_route_protocol_cmd);
2194 install_element (VIEW_NODE, &show_ipv6_route_addr_cmd);
2195 install_element (VIEW_NODE, &show_ipv6_route_prefix_cmd);
2196 install_element (VIEW_NODE, &show_ipv6_route_prefix_longer_cmd);
2197 install_element (ENABLE_NODE, &show_ipv6_route_cmd);
2198 install_element (ENABLE_NODE, &show_ipv6_route_protocol_cmd);
2199 install_element (ENABLE_NODE, &show_ipv6_route_addr_cmd);
2200 install_element (ENABLE_NODE, &show_ipv6_route_prefix_cmd);
2201 install_element (ENABLE_NODE, &show_ipv6_route_prefix_longer_cmd);
61691c91 2202 install_element (ENABLE_NODE, &show_ipv6_route_summary_cmd);
cddf391b
B
2203
2204 install_element (VIEW_NODE, &show_ipv6_mroute_cmd);
2205 install_element (ENABLE_NODE, &show_ipv6_mroute_cmd);
718e3744 2206#endif /* HAVE_IPV6 */
2207}