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