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