]> git.proxmox.com Git - mirror_frr.git/blame - zebra/zebra_vty.c
[build] Improve portability by invoking gcc with -std=gnu99 instead of -std=c99
[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
24#include "if.h"
25#include "prefix.h"
26#include "command.h"
27#include "table.h"
28#include "rib.h"
29
a1ac18c4 30#include "zebra/zserv.h"
31
718e3744 32/* General fucntion for static route. */
a1ac18c4 33static int
39db97e4 34zebra_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)
718e3744 37{
38 int ret;
39 u_char distance;
40 struct prefix p;
41 struct in_addr gate;
42 struct in_addr mask;
39db97e4 43 const char *ifname;
81dfcaa2 44 u_char flag = 0;
718e3744 45
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)
595db7f1 58 {
59 vty_out (vty, "%% Malformed address%s", VTY_NEWLINE);
60 return CMD_WARNING;
61 }
718e3744 62 p.prefixlen = ip_masklen (mask);
63 }
64
65 /* Apply mask for given prefix. */
66 apply_mask (&p);
67
595db7f1 68 /* Administrative distance. */
69 if (distance_str)
70 distance = atoi (distance_str);
71 else
72 distance = ZEBRA_STATIC_DISTANCE_DEFAULT;
73
74 /* Null0 static route. */
457ef551 75 if ((gate_str != NULL) && (strncasecmp (gate_str, "Null0", strlen (gate_str)) == 0))
595db7f1 76 {
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)
7021c425 83 static_add_ipv4 (&p, NULL, NULL, ZEBRA_FLAG_BLACKHOLE, distance, 0);
595db7f1 84 else
85 static_delete_ipv4 (&p, NULL, NULL, distance, 0);
86 return CMD_SUCCESS;
87 }
88
81dfcaa2 89 /* 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);
595db7f1 102 return CMD_WARNING;
81dfcaa2 103 }
104 }
105
457ef551 106 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
718e3744 116 /* 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)
81dfcaa2 125 static_add_ipv4 (&p, ifname ? NULL : &gate, ifname, flag, distance, 0);
718e3744 126 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,
595db7f1 135 "ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0)",
81dfcaa2 136 IP_STR
137 "Establish static routes\n"
138 "IP destination prefix (e.g. 10.0.0.0/8)\n"
139 "IP gateway address\n"
595db7f1 140 "IP gateway interface name\n"
141 "Null interface\n")
81dfcaa2 142{
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)",
718e3744 149 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"
81dfcaa2 154 "Emit an ICMP unreachable when matched\n"
155 "Silently discard pkts when matched\n")
718e3744 156{
81dfcaa2 157 return zebra_static_ipv4 (vty, 1, argv[0], NULL, argv[1], argv[2], NULL);
718e3744 158}
159
457ef551 160DEFUN (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
718e3744 172/* Mask as A.B.C.D format. */
173DEFUN (ip_route_mask,
174 ip_route_mask_cmd,
595db7f1 175 "ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0)",
81dfcaa2 176 IP_STR
177 "Establish static routes\n"
178 "IP destination prefix\n"
179 "IP destination prefix mask\n"
180 "IP gateway address\n"
595db7f1 181 "IP gateway interface name\n"
182 "Null interface\n")
81dfcaa2 183{
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)",
718e3744 190 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"
81dfcaa2 196 "Emit an ICMP unreachable when matched\n"
197 "Silently discard pkts when matched\n")
718e3744 198{
81dfcaa2 199 return zebra_static_ipv4 (vty, 1, argv[0], argv[1], argv[2], argv[3], NULL);
718e3744 200}
201
457ef551 202DEFUN (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
718e3744 215/* Distance option value. */
216DEFUN (ip_route_distance,
217 ip_route_distance_cmd,
595db7f1 218 "ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0) <1-255>",
81dfcaa2 219 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"
595db7f1 224 "Null interface\n"
81dfcaa2 225 "Distance value for this route\n")
226{
227 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>",
718e3744 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"
81dfcaa2 238 "Emit an ICMP unreachable when matched\n"
239 "Silently discard pkts when matched\n"
718e3744 240 "Distance value for this route\n")
241{
81dfcaa2 242 return zebra_static_ipv4 (vty, 1, argv[0], NULL, argv[1], argv[2], argv[3]);
718e3744 243}
244
457ef551 245DEFUN (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
718e3744 258DEFUN (ip_route_mask_distance,
259 ip_route_mask_distance_cmd,
595db7f1 260 "ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0) <1-255>",
718e3744 261 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"
595db7f1 267 "Null interface\n"
718e3744 268 "Distance value for this route\n")
269{
81dfcaa2 270 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]);
718e3744 287}
288
457ef551 289DEFUN (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
718e3744 303DEFUN (no_ip_route,
304 no_ip_route_cmd,
595db7f1 305 "no ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0)",
718e3744 306 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"
595db7f1 311 "IP gateway interface name\n"
312 "Null interface\n")
718e3744 313{
81dfcaa2 314 return zebra_static_ipv4 (vty, 0, argv[0], NULL, argv[1], NULL, NULL);
718e3744 315}
316
81dfcaa2 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)",
320 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"
326 "Emit an ICMP unreachable when matched\n"
327 "Silently discard pkts when matched\n")
328
457ef551 329DEFUN (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
718e3744 342DEFUN (no_ip_route_mask,
343 no_ip_route_mask_cmd,
595db7f1 344 "no ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0)",
718e3744 345 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"
595db7f1 351 "IP gateway interface name\n"
352 "Null interface\n")
718e3744 353{
81dfcaa2 354 return zebra_static_ipv4 (vty, 0, argv[0], argv[1], argv[2], NULL, NULL);
718e3744 355}
356
81dfcaa2 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)",
360 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"
367 "Emit an ICMP unreachable when matched\n"
368 "Silently discard pkts when matched\n")
369
457ef551 370DEFUN (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
718e3744 384DEFUN (no_ip_route_distance,
385 no_ip_route_distance_cmd,
595db7f1 386 "no ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0) <1-255>",
81dfcaa2 387 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"
595db7f1 393 "Null interface\n"
81dfcaa2 394 "Distance value for this route\n")
395{
396 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>",
718e3744 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"
81dfcaa2 408 "Emit an ICMP unreachable when matched\n"
409 "Silently discard pkts when matched\n"
718e3744 410 "Distance value for this route\n")
411{
81dfcaa2 412 return zebra_static_ipv4 (vty, 0, argv[0], NULL, argv[1], argv[2], argv[3]);
718e3744 413}
414
457ef551 415DEFUN (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
718e3744 429DEFUN (no_ip_route_mask_distance,
430 no_ip_route_mask_distance_cmd,
595db7f1 431 "no ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0) <1-255>",
81dfcaa2 432 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"
595db7f1 439 "Null interface\n"
81dfcaa2 440 "Distance value for this route\n")
441{
442 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>",
718e3744 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"
81dfcaa2 455 "Emit an ICMP unreachable when matched\n"
456 "Silently discard pkts when matched\n"
718e3744 457 "Distance value for this route\n")
458{
81dfcaa2 459 return zebra_static_ipv4 (vty, 0, argv[0], argv[1], argv[2], argv[3], argv[4]);
718e3744 460}
461
457ef551 462DEFUN (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
718e3744 477/* New RIB. Detailed information for IPv4 route. */
a1ac18c4 478static void
718e3744 479vty_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);
f52d13cb 489 vty_out (vty, " Known via \"%s\"", zebra_route_string (rib->type));
718e3744 490 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);
81dfcaa2 495 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");
718e3744 499 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
9e867fe6 505 || rib->type == ZEBRA_ROUTE_ISIS
718e3744 506 || 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;
595db7f1 550 case NEXTHOP_TYPE_BLACKHOLE:
7021c425 551 vty_out (vty, " directly connected, Null0");
595db7f1 552 break;
7021c425 553 default:
718e3744 554 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
a1ac18c4 584static void
718e3744 585vty_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",
f52d13cb 598 zebra_route_char (rib->type),
718e3744 599 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;
595db7f1 633 case NEXTHOP_TYPE_BLACKHOLE:
7021c425 634 vty_out (vty, " is directly connected, Null0");
595db7f1 635 break;
7021c425 636 default:
718e3744 637 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
81dfcaa2 662 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
718e3744 667 if (rib->type == ZEBRA_ROUTE_RIP
668 || rib->type == ZEBRA_ROUTE_OSPF
9e867fe6 669 || rib->type == ZEBRA_ROUTE_ISIS
718e3744 670 || 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
39db97e4 697#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"
718e3744 700
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,
39ff11dc 817 "show ip route (bgp|connected|isis|kernel|ospf|rip|static)",
718e3744 818 SHOW_STR
819 IP_STR
820 "IP routing table\n"
821 "Border Gateway Protocol (BGP)\n"
822 "Connected\n"
39ff11dc 823 "ISO IS-IS (ISIS)\n"
718e3744 824 "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;
9e867fe6 843 else if (strncmp (argv[0], "i", 1) == 0)
844 type = ZEBRA_ROUTE_ISIS;
718e3744 845 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
a1ac18c4 951static void
718e3744 952zebra_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. */
a1ac18c4 1002static int
718e3744 1003static_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 {
7021c425 1020 vty_out (vty, "ip route %s/%d", inet_ntoa (rn->p.u.prefix4),
1021 rn->p.prefixlen);
1022
1023 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");
1041
1042 if (CHECK_FLAG(si->flags, ZEBRA_FLAG_BLACKHOLE))
1043 vty_out (vty, " %s", "blackhole");
1044 }
1045
1046 if (si->distance != ZEBRA_STATIC_DISTANCE_DEFAULT)
1047 vty_out (vty, " %d", si->distance);
1048
1049 vty_out (vty, "%s", VTY_NEWLINE);
1050
1051 write = 1;
718e3744 1052 }
1053 return write;
1054}
1055\f
1056#ifdef HAVE_IPV6
1057/* General fucntion for IPv6 static route. */
a1ac18c4 1058static int
39db97e4 1059static_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)
718e3744 1062{
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;
81dfcaa2 1070 u_char flag = 0;
718e3744 1071
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
81dfcaa2 1082 /* 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);
595db7f1 1095 return CMD_WARNING;
81dfcaa2 1096 }
1097 }
1098
718e3744 1099 /* 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)
81dfcaa2 1136 static_add_ipv6 (&p, type, gate, ifname, flag, distance, table);
718e3744 1137 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{
81dfcaa2 1152 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);
718e3744 1167}
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{
81dfcaa2 1178 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);
718e3744 1193}
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{
81dfcaa2 1205 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]);
718e3744 1221}
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{
81dfcaa2 1233 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]);
718e3744 1249}
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{
81dfcaa2 1261 return static_ipv6_func (vty, 0, argv[0], argv[1], NULL, NULL, NULL);
718e3744 1262}
1263
81dfcaa2 1264ALIAS (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
718e3744 1276DEFUN (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{
81dfcaa2 1286 return static_ipv6_func (vty, 0, argv[0], argv[1], argv[2], NULL, NULL);
718e3744 1287}
1288
81dfcaa2 1289ALIAS (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
718e3744 1301DEFUN (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{
81dfcaa2 1312 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]);
718e3744 1330}
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{
81dfcaa2 1343 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]);
718e3744 1360}
1361
595db7f1 1362/* New RIB. Detailed information for IPv6 route. */
a1ac18c4 1363static void
718e3744 1364vty_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);
f52d13cb 1376 vty_out (vty, " Known via \"%s\"", zebra_route_string (rib->type));
718e3744 1377 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);
81dfcaa2 1382 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");
718e3744 1386 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
9e867fe6 1392 || rib->type == ZEBRA_ROUTE_ISIS
718e3744 1393 || 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
a1ac18c4 1478static void
718e3744 1479vty_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",
f52d13cb 1493 zebra_route_char (rib->type),
718e3744 1494 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
81dfcaa2 1564 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
718e3744 1569 if (rib->type == ZEBRA_ROUTE_RIPNG
1570 || rib->type == ZEBRA_ROUTE_OSPF6
9e867fe6 1571 || rib->type == ZEBRA_ROUTE_ISIS
718e3744 1572 || 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
9e867fe6 1599#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"
718e3744 1600
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,
b8adec1f 1675 "show ipv6 route (bgp|connected|isis|kernel|ospf6|ripng|static)",
718e3744 1676 SHOW_STR
1677 IP_STR
1678 "IP routing table\n"
1679 "Border Gateway Protocol (BGP)\n"
1680 "Connected\n"
b8adec1f 1681 "ISO IS-IS (ISIS)\n"
718e3744 1682 "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;
9e867fe6 1701 else if (strncmp (argv[0], "i", 1) == 0)
1702 type = ZEBRA_ROUTE_ISIS;
718e3744 1703 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. */
a1ac18c4 1810static int
718e3744 1811static_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
81dfcaa2 1847 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
718e3744 1853 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. */
a1ac18c4 1864static int
718e3744 1865zebra_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
a1ac18c4 1882zebra_vty_init (void)
718e3744 1883{
1884 install_node (&ip_node, zebra_ip_config);
1885
1886 install_element (CONFIG_NODE, &ip_route_cmd);
81dfcaa2 1887 install_element (CONFIG_NODE, &ip_route_flags_cmd);
457ef551 1888 install_element (CONFIG_NODE, &ip_route_flags2_cmd);
718e3744 1889 install_element (CONFIG_NODE, &ip_route_mask_cmd);
81dfcaa2 1890 install_element (CONFIG_NODE, &ip_route_mask_flags_cmd);
457ef551 1891 install_element (CONFIG_NODE, &ip_route_mask_flags2_cmd);
718e3744 1892 install_element (CONFIG_NODE, &no_ip_route_cmd);
81dfcaa2 1893 install_element (CONFIG_NODE, &no_ip_route_flags_cmd);
457ef551 1894 install_element (CONFIG_NODE, &no_ip_route_flags2_cmd);
718e3744 1895 install_element (CONFIG_NODE, &no_ip_route_mask_cmd);
81dfcaa2 1896 install_element (CONFIG_NODE, &no_ip_route_mask_flags_cmd);
457ef551 1897 install_element (CONFIG_NODE, &no_ip_route_mask_flags2_cmd);
718e3744 1898 install_element (CONFIG_NODE, &ip_route_distance_cmd);
81dfcaa2 1899 install_element (CONFIG_NODE, &ip_route_flags_distance_cmd);
457ef551 1900 install_element (CONFIG_NODE, &ip_route_flags_distance2_cmd);
718e3744 1901 install_element (CONFIG_NODE, &ip_route_mask_distance_cmd);
81dfcaa2 1902 install_element (CONFIG_NODE, &ip_route_mask_flags_distance_cmd);
457ef551 1903 install_element (CONFIG_NODE, &ip_route_mask_flags_distance2_cmd);
718e3744 1904 install_element (CONFIG_NODE, &no_ip_route_distance_cmd);
81dfcaa2 1905 install_element (CONFIG_NODE, &no_ip_route_flags_distance_cmd);
457ef551 1906 install_element (CONFIG_NODE, &no_ip_route_flags_distance2_cmd);
81dfcaa2 1907 install_element (CONFIG_NODE, &no_ip_route_mask_flags_distance_cmd);
457ef551 1908 install_element (CONFIG_NODE, &no_ip_route_mask_flags_distance2_cmd);
718e3744 1909
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);
81dfcaa2 1930 install_element (CONFIG_NODE, &ipv6_route_flags_cmd);
718e3744 1931 install_element (CONFIG_NODE, &ipv6_route_ifname_cmd);
81dfcaa2 1932 install_element (CONFIG_NODE, &ipv6_route_ifname_flags_cmd);
718e3744 1933 install_element (CONFIG_NODE, &no_ipv6_route_cmd);
81dfcaa2 1934 install_element (CONFIG_NODE, &no_ipv6_route_flags_cmd);
718e3744 1935 install_element (CONFIG_NODE, &no_ipv6_route_ifname_cmd);
81dfcaa2 1936 install_element (CONFIG_NODE, &no_ipv6_route_ifname_flags_cmd);
718e3744 1937 install_element (CONFIG_NODE, &ipv6_route_pref_cmd);
81dfcaa2 1938 install_element (CONFIG_NODE, &ipv6_route_flags_pref_cmd);
718e3744 1939 install_element (CONFIG_NODE, &ipv6_route_ifname_pref_cmd);
81dfcaa2 1940 install_element (CONFIG_NODE, &ipv6_route_ifname_flags_pref_cmd);
718e3744 1941 install_element (CONFIG_NODE, &no_ipv6_route_pref_cmd);
81dfcaa2 1942 install_element (CONFIG_NODE, &no_ipv6_route_flags_pref_cmd);
718e3744 1943 install_element (CONFIG_NODE, &no_ipv6_route_ifname_pref_cmd);
81dfcaa2 1944 install_element (CONFIG_NODE, &no_ipv6_route_ifname_flags_pref_cmd);
718e3744 1945 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}