]> git.proxmox.com Git - mirror_frr.git/blob - zebra/zebra_vty.c
quagga: option "-z" ("--socket <path>") added
[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;
537
538 for (rib = rn->info; rib; rib = rib->next)
539 {
540 vty_out (vty, "Routing entry for %s/%d%s",
541 inet_ntoa (rn->p.u.prefix4), rn->p.prefixlen,
542 VTY_NEWLINE);
543 vty_out (vty, " Known via \"%s\"", zebra_route_string (rib->type));
544 vty_out (vty, ", distance %d, metric %d", rib->distance, rib->metric);
545 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
546 vty_out (vty, ", best");
547 if (rib->refcnt)
548 vty_out (vty, ", refcnt %ld", rib->refcnt);
549 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_BLACKHOLE))
550 vty_out (vty, ", blackhole");
551 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_REJECT))
552 vty_out (vty, ", reject");
553 vty_out (vty, "%s", VTY_NEWLINE);
554
555 #define ONE_DAY_SECOND 60*60*24
556 #define ONE_WEEK_SECOND 60*60*24*7
557 if (rib->type == ZEBRA_ROUTE_RIP
558 || rib->type == ZEBRA_ROUTE_OSPF
559 || rib->type == ZEBRA_ROUTE_ISIS
560 || rib->type == ZEBRA_ROUTE_BGP)
561 {
562 time_t uptime;
563 struct tm *tm;
564
565 uptime = time (NULL);
566 uptime -= rib->uptime;
567 tm = gmtime (&uptime);
568
569 vty_out (vty, " Last update ");
570
571 if (uptime < ONE_DAY_SECOND)
572 vty_out (vty, "%02d:%02d:%02d",
573 tm->tm_hour, tm->tm_min, tm->tm_sec);
574 else if (uptime < ONE_WEEK_SECOND)
575 vty_out (vty, "%dd%02dh%02dm",
576 tm->tm_yday, tm->tm_hour, tm->tm_min);
577 else
578 vty_out (vty, "%02dw%dd%02dh",
579 tm->tm_yday/7,
580 tm->tm_yday - ((tm->tm_yday/7) * 7), tm->tm_hour);
581 vty_out (vty, " ago%s", VTY_NEWLINE);
582 }
583
584 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
585 {
586 char addrstr[32];
587
588 vty_out (vty, " %c",
589 CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB) ? '*' : ' ');
590
591 switch (nexthop->type)
592 {
593 case NEXTHOP_TYPE_IPV4:
594 case NEXTHOP_TYPE_IPV4_IFINDEX:
595 vty_out (vty, " %s", inet_ntoa (nexthop->gate.ipv4));
596 if (nexthop->ifindex)
597 vty_out (vty, ", via %s", ifindex2ifname (nexthop->ifindex));
598 break;
599 case NEXTHOP_TYPE_IFINDEX:
600 vty_out (vty, " directly connected, %s",
601 ifindex2ifname (nexthop->ifindex));
602 break;
603 case NEXTHOP_TYPE_IFNAME:
604 vty_out (vty, " directly connected, %s", nexthop->ifname);
605 break;
606 case NEXTHOP_TYPE_BLACKHOLE:
607 vty_out (vty, " directly connected, Null0");
608 break;
609 default:
610 break;
611 }
612 if (! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
613 vty_out (vty, " inactive");
614
615 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
616 {
617 vty_out (vty, " (recursive");
618
619 switch (nexthop->rtype)
620 {
621 case NEXTHOP_TYPE_IPV4:
622 case NEXTHOP_TYPE_IPV4_IFINDEX:
623 vty_out (vty, " via %s)", inet_ntoa (nexthop->rgate.ipv4));
624 break;
625 case NEXTHOP_TYPE_IFINDEX:
626 case NEXTHOP_TYPE_IFNAME:
627 vty_out (vty, " is directly connected, %s)",
628 ifindex2ifname (nexthop->rifindex));
629 break;
630 default:
631 break;
632 }
633 }
634 switch (nexthop->type)
635 {
636 case NEXTHOP_TYPE_IPV4:
637 case NEXTHOP_TYPE_IPV4_IFINDEX:
638 case NEXTHOP_TYPE_IPV4_IFNAME:
639 if (nexthop->src.ipv4.s_addr)
640 {
641 if (inet_ntop(AF_INET, &nexthop->src.ipv4, addrstr,
642 sizeof addrstr))
643 vty_out (vty, ", src %s", addrstr);
644 }
645 break;
646 #ifdef HAVE_IPV6
647 case NEXTHOP_TYPE_IPV6:
648 case NEXTHOP_TYPE_IPV6_IFINDEX:
649 case NEXTHOP_TYPE_IPV6_IFNAME:
650 if (!IPV6_ADDR_SAME(&nexthop->src.ipv6, &in6addr_any))
651 {
652 if (inet_ntop(AF_INET6, &nexthop->src.ipv6, addrstr,
653 sizeof addrstr))
654 vty_out (vty, ", src %s", addrstr);
655 }
656 break;
657 #endif /* HAVE_IPV6 */
658 default:
659 break;
660 }
661 vty_out (vty, "%s", VTY_NEWLINE);
662 }
663 vty_out (vty, "%s", VTY_NEWLINE);
664 }
665 }
666
667 static void
668 vty_show_ip_route (struct vty *vty, struct route_node *rn, struct rib *rib)
669 {
670 struct nexthop *nexthop;
671 int len = 0;
672 char buf[BUFSIZ];
673
674 /* Nexthop information. */
675 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
676 {
677 if (nexthop == rib->nexthop)
678 {
679 /* Prefix information. */
680 len = vty_out (vty, "%c%c%c %s/%d",
681 zebra_route_char (rib->type),
682 CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED)
683 ? '>' : ' ',
684 CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)
685 ? '*' : ' ',
686 inet_ntop (AF_INET, &rn->p.u.prefix, buf, BUFSIZ),
687 rn->p.prefixlen);
688
689 /* Distance and metric display. */
690 if (rib->type != ZEBRA_ROUTE_CONNECT
691 && rib->type != ZEBRA_ROUTE_KERNEL)
692 len += vty_out (vty, " [%d/%d]", rib->distance,
693 rib->metric);
694 }
695 else
696 vty_out (vty, " %c%*c",
697 CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)
698 ? '*' : ' ',
699 len - 3, ' ');
700
701 switch (nexthop->type)
702 {
703 case NEXTHOP_TYPE_IPV4:
704 case NEXTHOP_TYPE_IPV4_IFINDEX:
705 vty_out (vty, " via %s", inet_ntoa (nexthop->gate.ipv4));
706 if (nexthop->ifindex)
707 vty_out (vty, ", %s", ifindex2ifname (nexthop->ifindex));
708 break;
709 case NEXTHOP_TYPE_IFINDEX:
710 vty_out (vty, " is directly connected, %s",
711 ifindex2ifname (nexthop->ifindex));
712 break;
713 case NEXTHOP_TYPE_IFNAME:
714 vty_out (vty, " is directly connected, %s", nexthop->ifname);
715 break;
716 case NEXTHOP_TYPE_BLACKHOLE:
717 vty_out (vty, " is directly connected, Null0");
718 break;
719 default:
720 break;
721 }
722 if (! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
723 vty_out (vty, " inactive");
724
725 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
726 {
727 vty_out (vty, " (recursive");
728
729 switch (nexthop->rtype)
730 {
731 case NEXTHOP_TYPE_IPV4:
732 case NEXTHOP_TYPE_IPV4_IFINDEX:
733 vty_out (vty, " via %s)", inet_ntoa (nexthop->rgate.ipv4));
734 break;
735 case NEXTHOP_TYPE_IFINDEX:
736 case NEXTHOP_TYPE_IFNAME:
737 vty_out (vty, " is directly connected, %s)",
738 ifindex2ifname (nexthop->rifindex));
739 break;
740 default:
741 break;
742 }
743 }
744 switch (nexthop->type)
745 {
746 case NEXTHOP_TYPE_IPV4:
747 case NEXTHOP_TYPE_IPV4_IFINDEX:
748 case NEXTHOP_TYPE_IPV4_IFNAME:
749 if (nexthop->src.ipv4.s_addr)
750 {
751 if (inet_ntop(AF_INET, &nexthop->src.ipv4, buf, sizeof buf))
752 vty_out (vty, ", src %s", buf);
753 }
754 break;
755 #ifdef HAVE_IPV6
756 case NEXTHOP_TYPE_IPV6:
757 case NEXTHOP_TYPE_IPV6_IFINDEX:
758 case NEXTHOP_TYPE_IPV6_IFNAME:
759 if (!IPV6_ADDR_SAME(&nexthop->src.ipv6, &in6addr_any))
760 {
761 if (inet_ntop(AF_INET6, &nexthop->src.ipv6, buf, sizeof buf))
762 vty_out (vty, ", src %s", buf);
763 }
764 break;
765 #endif /* HAVE_IPV6 */
766 default:
767 break;
768 }
769
770 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_BLACKHOLE))
771 vty_out (vty, ", bh");
772 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_REJECT))
773 vty_out (vty, ", rej");
774
775 if (rib->type == ZEBRA_ROUTE_RIP
776 || rib->type == ZEBRA_ROUTE_OSPF
777 || rib->type == ZEBRA_ROUTE_ISIS
778 || rib->type == ZEBRA_ROUTE_BGP)
779 {
780 time_t uptime;
781 struct tm *tm;
782
783 uptime = time (NULL);
784 uptime -= rib->uptime;
785 tm = gmtime (&uptime);
786
787 #define ONE_DAY_SECOND 60*60*24
788 #define ONE_WEEK_SECOND 60*60*24*7
789
790 if (uptime < ONE_DAY_SECOND)
791 vty_out (vty, ", %02d:%02d:%02d",
792 tm->tm_hour, tm->tm_min, tm->tm_sec);
793 else if (uptime < ONE_WEEK_SECOND)
794 vty_out (vty, ", %dd%02dh%02dm",
795 tm->tm_yday, tm->tm_hour, tm->tm_min);
796 else
797 vty_out (vty, ", %02dw%dd%02dh",
798 tm->tm_yday/7,
799 tm->tm_yday - ((tm->tm_yday/7) * 7), tm->tm_hour);
800 }
801 vty_out (vty, "%s", VTY_NEWLINE);
802 }
803 }
804
805 DEFUN (show_ip_route,
806 show_ip_route_cmd,
807 "show ip route",
808 SHOW_STR
809 IP_STR
810 "IP routing table\n")
811 {
812 struct route_table *table;
813 struct route_node *rn;
814 struct rib *rib;
815 int first = 1;
816
817 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
818 if (! table)
819 return CMD_SUCCESS;
820
821 /* Show all IPv4 routes. */
822 for (rn = route_top (table); rn; rn = route_next (rn))
823 for (rib = rn->info; rib; rib = rib->next)
824 {
825 if (first)
826 {
827 vty_out (vty, SHOW_ROUTE_V4_HEADER);
828 first = 0;
829 }
830 vty_show_ip_route (vty, rn, rib);
831 }
832 return CMD_SUCCESS;
833 }
834
835 DEFUN (show_ip_route_prefix_longer,
836 show_ip_route_prefix_longer_cmd,
837 "show ip route A.B.C.D/M longer-prefixes",
838 SHOW_STR
839 IP_STR
840 "IP routing table\n"
841 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
842 "Show route matching the specified Network/Mask pair only\n")
843 {
844 struct route_table *table;
845 struct route_node *rn;
846 struct rib *rib;
847 struct prefix p;
848 int ret;
849 int first = 1;
850
851 ret = str2prefix (argv[0], &p);
852 if (! ret)
853 {
854 vty_out (vty, "%% Malformed Prefix%s", VTY_NEWLINE);
855 return CMD_WARNING;
856 }
857
858 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
859 if (! table)
860 return CMD_SUCCESS;
861
862 /* Show matched type IPv4 routes. */
863 for (rn = route_top (table); rn; rn = route_next (rn))
864 for (rib = rn->info; rib; rib = rib->next)
865 if (prefix_match (&p, &rn->p))
866 {
867 if (first)
868 {
869 vty_out (vty, SHOW_ROUTE_V4_HEADER);
870 first = 0;
871 }
872 vty_show_ip_route (vty, rn, rib);
873 }
874 return CMD_SUCCESS;
875 }
876
877 DEFUN (show_ip_route_supernets,
878 show_ip_route_supernets_cmd,
879 "show ip route supernets-only",
880 SHOW_STR
881 IP_STR
882 "IP routing table\n"
883 "Show supernet entries only\n")
884 {
885 struct route_table *table;
886 struct route_node *rn;
887 struct rib *rib;
888 u_int32_t addr;
889 int first = 1;
890
891 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
892 if (! table)
893 return CMD_SUCCESS;
894
895 /* Show matched type IPv4 routes. */
896 for (rn = route_top (table); rn; rn = route_next (rn))
897 for (rib = rn->info; rib; rib = rib->next)
898 {
899 addr = ntohl (rn->p.u.prefix4.s_addr);
900
901 if ((IN_CLASSC (addr) && rn->p.prefixlen < 24)
902 || (IN_CLASSB (addr) && rn->p.prefixlen < 16)
903 || (IN_CLASSA (addr) && rn->p.prefixlen < 8))
904 {
905 if (first)
906 {
907 vty_out (vty, SHOW_ROUTE_V4_HEADER);
908 first = 0;
909 }
910 vty_show_ip_route (vty, rn, rib);
911 }
912 }
913 return CMD_SUCCESS;
914 }
915
916 DEFUN (show_ip_route_protocol,
917 show_ip_route_protocol_cmd,
918 "show ip route " QUAGGA_IP_REDIST_STR_ZEBRA,
919 SHOW_STR
920 IP_STR
921 "IP routing table\n"
922 QUAGGA_IP_REDIST_HELP_STR_ZEBRA)
923 {
924 int type;
925 struct route_table *table;
926 struct route_node *rn;
927 struct rib *rib;
928 int first = 1;
929
930 type = proto_redistnum (AFI_IP, argv[0]);
931 if (type < 0)
932 {
933 vty_out (vty, "Unknown route type%s", VTY_NEWLINE);
934 return CMD_WARNING;
935 }
936
937 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
938 if (! table)
939 return CMD_SUCCESS;
940
941 /* Show matched type IPv4 routes. */
942 for (rn = route_top (table); rn; rn = route_next (rn))
943 for (rib = rn->info; rib; rib = rib->next)
944 if (rib->type == type)
945 {
946 if (first)
947 {
948 vty_out (vty, SHOW_ROUTE_V4_HEADER);
949 first = 0;
950 }
951 vty_show_ip_route (vty, rn, rib);
952 }
953 return CMD_SUCCESS;
954 }
955
956 DEFUN (show_ip_route_addr,
957 show_ip_route_addr_cmd,
958 "show ip route A.B.C.D",
959 SHOW_STR
960 IP_STR
961 "IP routing table\n"
962 "Network in the IP routing table to display\n")
963 {
964 int ret;
965 struct prefix_ipv4 p;
966 struct route_table *table;
967 struct route_node *rn;
968
969 ret = str2prefix_ipv4 (argv[0], &p);
970 if (ret <= 0)
971 {
972 vty_out (vty, "%% Malformed IPv4 address%s", VTY_NEWLINE);
973 return CMD_WARNING;
974 }
975
976 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
977 if (! table)
978 return CMD_SUCCESS;
979
980 rn = route_node_match (table, (struct prefix *) &p);
981 if (! rn)
982 {
983 vty_out (vty, "%% Network not in table%s", VTY_NEWLINE);
984 return CMD_WARNING;
985 }
986
987 vty_show_ip_route_detail (vty, rn);
988
989 route_unlock_node (rn);
990
991 return CMD_SUCCESS;
992 }
993
994 DEFUN (show_ip_route_prefix,
995 show_ip_route_prefix_cmd,
996 "show ip route A.B.C.D/M",
997 SHOW_STR
998 IP_STR
999 "IP routing table\n"
1000 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n")
1001 {
1002 int ret;
1003 struct prefix_ipv4 p;
1004 struct route_table *table;
1005 struct route_node *rn;
1006
1007 ret = str2prefix_ipv4 (argv[0], &p);
1008 if (ret <= 0)
1009 {
1010 vty_out (vty, "%% Malformed IPv4 address%s", VTY_NEWLINE);
1011 return CMD_WARNING;
1012 }
1013
1014 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
1015 if (! table)
1016 return CMD_SUCCESS;
1017
1018 rn = route_node_match (table, (struct prefix *) &p);
1019 if (! rn || rn->p.prefixlen != p.prefixlen)
1020 {
1021 vty_out (vty, "%% Network not in table%s", VTY_NEWLINE);
1022 return CMD_WARNING;
1023 }
1024
1025 vty_show_ip_route_detail (vty, rn);
1026
1027 route_unlock_node (rn);
1028
1029 return CMD_SUCCESS;
1030 }
1031
1032 static void
1033 vty_show_ip_route_summary (struct vty *vty, struct route_table *table)
1034 {
1035 struct route_node *rn;
1036 struct rib *rib;
1037 struct nexthop *nexthop;
1038 #define ZEBRA_ROUTE_IBGP ZEBRA_ROUTE_MAX
1039 #define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1)
1040 u_int32_t rib_cnt[ZEBRA_ROUTE_TOTAL + 1];
1041 u_int32_t fib_cnt[ZEBRA_ROUTE_TOTAL + 1];
1042 u_int32_t i;
1043
1044 memset (&rib_cnt, 0, sizeof(rib_cnt));
1045 memset (&fib_cnt, 0, sizeof(fib_cnt));
1046 for (rn = route_top (table); rn; rn = route_next (rn))
1047 for (rib = rn->info; rib; rib = rib->next)
1048 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1049 {
1050 rib_cnt[ZEBRA_ROUTE_TOTAL]++;
1051 rib_cnt[rib->type]++;
1052 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
1053 {
1054 fib_cnt[ZEBRA_ROUTE_TOTAL]++;
1055 fib_cnt[rib->type]++;
1056 }
1057 if (rib->type == ZEBRA_ROUTE_BGP &&
1058 CHECK_FLAG (rib->flags, ZEBRA_FLAG_IBGP))
1059 {
1060 rib_cnt[ZEBRA_ROUTE_IBGP]++;
1061 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
1062 fib_cnt[ZEBRA_ROUTE_IBGP]++;
1063 }
1064 }
1065
1066 vty_out (vty, "%-20s %-20s %-20s %s",
1067 "Route Source", "Routes", "FIB", VTY_NEWLINE);
1068
1069 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
1070 {
1071 if (rib_cnt[i] > 0)
1072 {
1073 if (i == ZEBRA_ROUTE_BGP)
1074 {
1075 vty_out (vty, "%-20s %-20d %-20d %s", "ebgp",
1076 rib_cnt[ZEBRA_ROUTE_BGP] - rib_cnt[ZEBRA_ROUTE_IBGP],
1077 fib_cnt[ZEBRA_ROUTE_BGP] - fib_cnt[ZEBRA_ROUTE_IBGP],
1078 VTY_NEWLINE);
1079 vty_out (vty, "%-20s %-20d %-20d %s", "ibgp",
1080 rib_cnt[ZEBRA_ROUTE_IBGP], fib_cnt[ZEBRA_ROUTE_IBGP],
1081 VTY_NEWLINE);
1082 }
1083 else
1084 vty_out (vty, "%-20s %-20d %-20d %s", zebra_route_string(i),
1085 rib_cnt[i], fib_cnt[i], VTY_NEWLINE);
1086 }
1087 }
1088
1089 vty_out (vty, "------%s", VTY_NEWLINE);
1090 vty_out (vty, "%-20s %-20d %-20d %s", "Totals", rib_cnt[ZEBRA_ROUTE_TOTAL],
1091 fib_cnt[ZEBRA_ROUTE_TOTAL], VTY_NEWLINE);
1092 }
1093
1094 /* Show route summary. */
1095 DEFUN (show_ip_route_summary,
1096 show_ip_route_summary_cmd,
1097 "show ip route summary",
1098 SHOW_STR
1099 IP_STR
1100 "IP routing table\n"
1101 "Summary of all routes\n")
1102 {
1103 struct route_table *table;
1104
1105 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
1106 if (! table)
1107 return CMD_SUCCESS;
1108
1109 vty_show_ip_route_summary (vty, table);
1110
1111 return CMD_SUCCESS;
1112 }
1113
1114 /* Write IPv4 static route configuration. */
1115 static int
1116 static_config_ipv4 (struct vty *vty)
1117 {
1118 struct route_node *rn;
1119 struct static_ipv4 *si;
1120 struct route_table *stable;
1121 int write;
1122
1123 write = 0;
1124
1125 /* Lookup table. */
1126 stable = vrf_static_table (AFI_IP, SAFI_UNICAST, 0);
1127 if (! stable)
1128 return -1;
1129
1130 for (rn = route_top (stable); rn; rn = route_next (rn))
1131 for (si = rn->info; si; si = si->next)
1132 {
1133 vty_out (vty, "ip route %s/%d", inet_ntoa (rn->p.u.prefix4),
1134 rn->p.prefixlen);
1135
1136 switch (si->type)
1137 {
1138 case STATIC_IPV4_GATEWAY:
1139 vty_out (vty, " %s", inet_ntoa (si->gate.ipv4));
1140 break;
1141 case STATIC_IPV4_IFNAME:
1142 vty_out (vty, " %s", si->gate.ifname);
1143 break;
1144 case STATIC_IPV4_BLACKHOLE:
1145 vty_out (vty, " Null0");
1146 break;
1147 }
1148
1149 /* flags are incompatible with STATIC_IPV4_BLACKHOLE */
1150 if (si->type != STATIC_IPV4_BLACKHOLE)
1151 {
1152 if (CHECK_FLAG(si->flags, ZEBRA_FLAG_REJECT))
1153 vty_out (vty, " %s", "reject");
1154
1155 if (CHECK_FLAG(si->flags, ZEBRA_FLAG_BLACKHOLE))
1156 vty_out (vty, " %s", "blackhole");
1157 }
1158
1159 if (si->distance != ZEBRA_STATIC_DISTANCE_DEFAULT)
1160 vty_out (vty, " %d", si->distance);
1161
1162 vty_out (vty, "%s", VTY_NEWLINE);
1163
1164 write = 1;
1165 }
1166 return write;
1167 }
1168
1169 DEFUN (show_ip_protocol,
1170 show_ip_protocol_cmd,
1171 "show ip protocol",
1172 SHOW_STR
1173 IP_STR
1174 "IP protocol filtering status\n")
1175 {
1176 int i;
1177
1178 vty_out(vty, "Protocol : route-map %s", VTY_NEWLINE);
1179 vty_out(vty, "------------------------%s", VTY_NEWLINE);
1180 for (i=0;i<ZEBRA_ROUTE_MAX;i++)
1181 {
1182 if (proto_rm[AFI_IP][i])
1183 vty_out (vty, "%-10s : %-10s%s", zebra_route_string(i),
1184 proto_rm[AFI_IP][i],
1185 VTY_NEWLINE);
1186 else
1187 vty_out (vty, "%-10s : none%s", zebra_route_string(i), VTY_NEWLINE);
1188 }
1189 if (proto_rm[AFI_IP][i])
1190 vty_out (vty, "%-10s : %-10s%s", "any", proto_rm[AFI_IP][i],
1191 VTY_NEWLINE);
1192 else
1193 vty_out (vty, "%-10s : none%s", "any", VTY_NEWLINE);
1194
1195 return CMD_SUCCESS;
1196 }
1197
1198 \f
1199 #ifdef HAVE_IPV6
1200 /* General fucntion for IPv6 static route. */
1201 static int
1202 static_ipv6_func (struct vty *vty, int add_cmd, const char *dest_str,
1203 const char *gate_str, const char *ifname,
1204 const char *flag_str, const char *distance_str)
1205 {
1206 int ret;
1207 u_char distance;
1208 struct prefix p;
1209 struct in6_addr *gate = NULL;
1210 struct in6_addr gate_addr;
1211 u_char type = 0;
1212 int table = 0;
1213 u_char flag = 0;
1214
1215 ret = str2prefix (dest_str, &p);
1216 if (ret <= 0)
1217 {
1218 vty_out (vty, "%% Malformed address%s", VTY_NEWLINE);
1219 return CMD_WARNING;
1220 }
1221
1222 /* Apply mask for given prefix. */
1223 apply_mask (&p);
1224
1225 /* Route flags */
1226 if (flag_str) {
1227 switch(flag_str[0]) {
1228 case 'r':
1229 case 'R': /* XXX */
1230 SET_FLAG (flag, ZEBRA_FLAG_REJECT);
1231 break;
1232 case 'b':
1233 case 'B': /* XXX */
1234 SET_FLAG (flag, ZEBRA_FLAG_BLACKHOLE);
1235 break;
1236 default:
1237 vty_out (vty, "%% Malformed flag %s %s", flag_str, VTY_NEWLINE);
1238 return CMD_WARNING;
1239 }
1240 }
1241
1242 /* Administrative distance. */
1243 if (distance_str)
1244 distance = atoi (distance_str);
1245 else
1246 distance = ZEBRA_STATIC_DISTANCE_DEFAULT;
1247
1248 /* When gateway is valid IPv6 addrees, then gate is treated as
1249 nexthop address other case gate is treated as interface name. */
1250 ret = inet_pton (AF_INET6, gate_str, &gate_addr);
1251
1252 if (ifname)
1253 {
1254 /* When ifname is specified. It must be come with gateway
1255 address. */
1256 if (ret != 1)
1257 {
1258 vty_out (vty, "%% Malformed address%s", VTY_NEWLINE);
1259 return CMD_WARNING;
1260 }
1261 type = STATIC_IPV6_GATEWAY_IFNAME;
1262 gate = &gate_addr;
1263 }
1264 else
1265 {
1266 if (ret == 1)
1267 {
1268 type = STATIC_IPV6_GATEWAY;
1269 gate = &gate_addr;
1270 }
1271 else
1272 {
1273 type = STATIC_IPV6_IFNAME;
1274 ifname = gate_str;
1275 }
1276 }
1277
1278 if (add_cmd)
1279 static_add_ipv6 (&p, type, gate, ifname, flag, distance, table);
1280 else
1281 static_delete_ipv6 (&p, type, gate, ifname, distance, table);
1282
1283 return CMD_SUCCESS;
1284 }
1285
1286 DEFUN (ipv6_route,
1287 ipv6_route_cmd,
1288 "ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE)",
1289 IP_STR
1290 "Establish static routes\n"
1291 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1292 "IPv6 gateway address\n"
1293 "IPv6 gateway interface name\n")
1294 {
1295 return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, NULL, NULL);
1296 }
1297
1298 DEFUN (ipv6_route_flags,
1299 ipv6_route_flags_cmd,
1300 "ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) (reject|blackhole)",
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 {
1309 return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, argv[2], NULL);
1310 }
1311
1312 DEFUN (ipv6_route_ifname,
1313 ipv6_route_ifname_cmd,
1314 "ipv6 route X:X::X:X/M X:X::X:X INTERFACE",
1315 IP_STR
1316 "Establish static routes\n"
1317 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1318 "IPv6 gateway address\n"
1319 "IPv6 gateway interface name\n")
1320 {
1321 return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], NULL, NULL);
1322 }
1323
1324 DEFUN (ipv6_route_ifname_flags,
1325 ipv6_route_ifname_flags_cmd,
1326 "ipv6 route X:X::X:X/M X:X::X:X INTERFACE (reject|blackhole)",
1327 IP_STR
1328 "Establish static routes\n"
1329 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1330 "IPv6 gateway address\n"
1331 "IPv6 gateway interface name\n"
1332 "Emit an ICMP unreachable when matched\n"
1333 "Silently discard pkts when matched\n")
1334 {
1335 return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], argv[3], NULL);
1336 }
1337
1338 DEFUN (ipv6_route_pref,
1339 ipv6_route_pref_cmd,
1340 "ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) <1-255>",
1341 IP_STR
1342 "Establish static routes\n"
1343 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1344 "IPv6 gateway address\n"
1345 "IPv6 gateway interface name\n"
1346 "Distance value for this prefix\n")
1347 {
1348 return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, NULL, argv[2]);
1349 }
1350
1351 DEFUN (ipv6_route_flags_pref,
1352 ipv6_route_flags_pref_cmd,
1353 "ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) (reject|blackhole) <1-255>",
1354 IP_STR
1355 "Establish static routes\n"
1356 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1357 "IPv6 gateway address\n"
1358 "IPv6 gateway interface name\n"
1359 "Emit an ICMP unreachable when matched\n"
1360 "Silently discard pkts when matched\n"
1361 "Distance value for this prefix\n")
1362 {
1363 return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, argv[2], argv[3]);
1364 }
1365
1366 DEFUN (ipv6_route_ifname_pref,
1367 ipv6_route_ifname_pref_cmd,
1368 "ipv6 route X:X::X:X/M X:X::X:X INTERFACE <1-255>",
1369 IP_STR
1370 "Establish static routes\n"
1371 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1372 "IPv6 gateway address\n"
1373 "IPv6 gateway interface name\n"
1374 "Distance value for this prefix\n")
1375 {
1376 return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], NULL, argv[3]);
1377 }
1378
1379 DEFUN (ipv6_route_ifname_flags_pref,
1380 ipv6_route_ifname_flags_pref_cmd,
1381 "ipv6 route X:X::X:X/M X:X::X:X INTERFACE (reject|blackhole) <1-255>",
1382 IP_STR
1383 "Establish static routes\n"
1384 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1385 "IPv6 gateway address\n"
1386 "IPv6 gateway interface name\n"
1387 "Emit an ICMP unreachable when matched\n"
1388 "Silently discard pkts when matched\n"
1389 "Distance value for this prefix\n")
1390 {
1391 return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], argv[3], argv[4]);
1392 }
1393
1394 DEFUN (no_ipv6_route,
1395 no_ipv6_route_cmd,
1396 "no ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE)",
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 {
1404 return static_ipv6_func (vty, 0, argv[0], argv[1], NULL, NULL, NULL);
1405 }
1406
1407 ALIAS (no_ipv6_route,
1408 no_ipv6_route_flags_cmd,
1409 "no ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) (reject|blackhole)",
1410 NO_STR
1411 IP_STR
1412 "Establish static routes\n"
1413 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1414 "IPv6 gateway address\n"
1415 "IPv6 gateway interface name\n"
1416 "Emit an ICMP unreachable when matched\n"
1417 "Silently discard pkts when matched\n")
1418
1419 DEFUN (no_ipv6_route_ifname,
1420 no_ipv6_route_ifname_cmd,
1421 "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE",
1422 NO_STR
1423 IP_STR
1424 "Establish static routes\n"
1425 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1426 "IPv6 gateway address\n"
1427 "IPv6 gateway interface name\n")
1428 {
1429 return static_ipv6_func (vty, 0, argv[0], argv[1], argv[2], NULL, NULL);
1430 }
1431
1432 ALIAS (no_ipv6_route_ifname,
1433 no_ipv6_route_ifname_flags_cmd,
1434 "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE (reject|blackhole)",
1435 NO_STR
1436 IP_STR
1437 "Establish static routes\n"
1438 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1439 "IPv6 gateway address\n"
1440 "IPv6 gateway interface name\n"
1441 "Emit an ICMP unreachable when matched\n"
1442 "Silently discard pkts when matched\n")
1443
1444 DEFUN (no_ipv6_route_pref,
1445 no_ipv6_route_pref_cmd,
1446 "no ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) <1-255>",
1447 NO_STR
1448 IP_STR
1449 "Establish static routes\n"
1450 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1451 "IPv6 gateway address\n"
1452 "IPv6 gateway interface name\n"
1453 "Distance value for this prefix\n")
1454 {
1455 return static_ipv6_func (vty, 0, argv[0], argv[1], NULL, NULL, argv[2]);
1456 }
1457
1458 DEFUN (no_ipv6_route_flags_pref,
1459 no_ipv6_route_flags_pref_cmd,
1460 "no ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) (reject|blackhole) <1-255>",
1461 NO_STR
1462 IP_STR
1463 "Establish static routes\n"
1464 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1465 "IPv6 gateway address\n"
1466 "IPv6 gateway interface name\n"
1467 "Emit an ICMP unreachable when matched\n"
1468 "Silently discard pkts when matched\n"
1469 "Distance value for this prefix\n")
1470 {
1471 /* We do not care about argv[2] */
1472 return static_ipv6_func (vty, 0, argv[0], argv[1], NULL, argv[2], argv[3]);
1473 }
1474
1475 DEFUN (no_ipv6_route_ifname_pref,
1476 no_ipv6_route_ifname_pref_cmd,
1477 "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE <1-255>",
1478 NO_STR
1479 IP_STR
1480 "Establish static routes\n"
1481 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1482 "IPv6 gateway address\n"
1483 "IPv6 gateway interface name\n"
1484 "Distance value for this prefix\n")
1485 {
1486 return static_ipv6_func (vty, 0, argv[0], argv[1], argv[2], NULL, argv[3]);
1487 }
1488
1489 DEFUN (no_ipv6_route_ifname_flags_pref,
1490 no_ipv6_route_ifname_flags_pref_cmd,
1491 "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE (reject|blackhole) <1-255>",
1492 NO_STR
1493 IP_STR
1494 "Establish static routes\n"
1495 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1496 "IPv6 gateway address\n"
1497 "IPv6 gateway interface name\n"
1498 "Emit an ICMP unreachable when matched\n"
1499 "Silently discard pkts when matched\n"
1500 "Distance value for this prefix\n")
1501 {
1502 return static_ipv6_func (vty, 0, argv[0], argv[1], argv[2], argv[3], argv[4]);
1503 }
1504
1505 /* New RIB. Detailed information for IPv6 route. */
1506 static void
1507 vty_show_ipv6_route_detail (struct vty *vty, struct route_node *rn)
1508 {
1509 struct rib *rib;
1510 struct nexthop *nexthop;
1511 char buf[BUFSIZ];
1512
1513 for (rib = rn->info; rib; rib = rib->next)
1514 {
1515 vty_out (vty, "Routing entry for %s/%d%s",
1516 inet_ntop (AF_INET6, &rn->p.u.prefix6, buf, BUFSIZ),
1517 rn->p.prefixlen,
1518 VTY_NEWLINE);
1519 vty_out (vty, " Known via \"%s\"", zebra_route_string (rib->type));
1520 vty_out (vty, ", distance %d, metric %d", rib->distance, rib->metric);
1521 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
1522 vty_out (vty, ", best");
1523 if (rib->refcnt)
1524 vty_out (vty, ", refcnt %ld", rib->refcnt);
1525 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_BLACKHOLE))
1526 vty_out (vty, ", blackhole");
1527 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_REJECT))
1528 vty_out (vty, ", reject");
1529 vty_out (vty, "%s", VTY_NEWLINE);
1530
1531 #define ONE_DAY_SECOND 60*60*24
1532 #define ONE_WEEK_SECOND 60*60*24*7
1533 if (rib->type == ZEBRA_ROUTE_RIPNG
1534 || rib->type == ZEBRA_ROUTE_OSPF6
1535 || rib->type == ZEBRA_ROUTE_ISIS
1536 || rib->type == ZEBRA_ROUTE_BGP)
1537 {
1538 time_t uptime;
1539 struct tm *tm;
1540
1541 uptime = time (NULL);
1542 uptime -= rib->uptime;
1543 tm = gmtime (&uptime);
1544
1545 vty_out (vty, " Last update ");
1546
1547 if (uptime < ONE_DAY_SECOND)
1548 vty_out (vty, "%02d:%02d:%02d",
1549 tm->tm_hour, tm->tm_min, tm->tm_sec);
1550 else if (uptime < ONE_WEEK_SECOND)
1551 vty_out (vty, "%dd%02dh%02dm",
1552 tm->tm_yday, tm->tm_hour, tm->tm_min);
1553 else
1554 vty_out (vty, "%02dw%dd%02dh",
1555 tm->tm_yday/7,
1556 tm->tm_yday - ((tm->tm_yday/7) * 7), tm->tm_hour);
1557 vty_out (vty, " ago%s", VTY_NEWLINE);
1558 }
1559
1560 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1561 {
1562 vty_out (vty, " %c",
1563 CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB) ? '*' : ' ');
1564
1565 switch (nexthop->type)
1566 {
1567 case NEXTHOP_TYPE_IPV6:
1568 case NEXTHOP_TYPE_IPV6_IFINDEX:
1569 case NEXTHOP_TYPE_IPV6_IFNAME:
1570 vty_out (vty, " %s",
1571 inet_ntop (AF_INET6, &nexthop->gate.ipv6, buf, BUFSIZ));
1572 if (nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME)
1573 vty_out (vty, ", %s", nexthop->ifname);
1574 else if (nexthop->ifindex)
1575 vty_out (vty, ", via %s", ifindex2ifname (nexthop->ifindex));
1576 break;
1577 case NEXTHOP_TYPE_IFINDEX:
1578 vty_out (vty, " directly connected, %s",
1579 ifindex2ifname (nexthop->ifindex));
1580 break;
1581 case NEXTHOP_TYPE_IFNAME:
1582 vty_out (vty, " directly connected, %s",
1583 nexthop->ifname);
1584 break;
1585 default:
1586 break;
1587 }
1588 if (! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
1589 vty_out (vty, " inactive");
1590
1591 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
1592 {
1593 vty_out (vty, " (recursive");
1594
1595 switch (nexthop->rtype)
1596 {
1597 case NEXTHOP_TYPE_IPV6:
1598 case NEXTHOP_TYPE_IPV6_IFINDEX:
1599 case NEXTHOP_TYPE_IPV6_IFNAME:
1600 vty_out (vty, " via %s)",
1601 inet_ntop (AF_INET6, &nexthop->rgate.ipv6,
1602 buf, BUFSIZ));
1603 if (nexthop->rifindex)
1604 vty_out (vty, ", %s", ifindex2ifname (nexthop->rifindex));
1605 break;
1606 case NEXTHOP_TYPE_IFINDEX:
1607 case NEXTHOP_TYPE_IFNAME:
1608 vty_out (vty, " is directly connected, %s)",
1609 ifindex2ifname (nexthop->rifindex));
1610 break;
1611 default:
1612 break;
1613 }
1614 }
1615 vty_out (vty, "%s", VTY_NEWLINE);
1616 }
1617 vty_out (vty, "%s", VTY_NEWLINE);
1618 }
1619 }
1620
1621 static void
1622 vty_show_ipv6_route (struct vty *vty, struct route_node *rn,
1623 struct rib *rib)
1624 {
1625 struct nexthop *nexthop;
1626 int len = 0;
1627 char buf[BUFSIZ];
1628
1629 /* Nexthop information. */
1630 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1631 {
1632 if (nexthop == rib->nexthop)
1633 {
1634 /* Prefix information. */
1635 len = vty_out (vty, "%c%c%c %s/%d",
1636 zebra_route_char (rib->type),
1637 CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED)
1638 ? '>' : ' ',
1639 CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)
1640 ? '*' : ' ',
1641 inet_ntop (AF_INET6, &rn->p.u.prefix6, buf, BUFSIZ),
1642 rn->p.prefixlen);
1643
1644 /* Distance and metric display. */
1645 if (rib->type != ZEBRA_ROUTE_CONNECT
1646 && rib->type != ZEBRA_ROUTE_KERNEL)
1647 len += vty_out (vty, " [%d/%d]", rib->distance,
1648 rib->metric);
1649 }
1650 else
1651 vty_out (vty, " %c%*c",
1652 CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)
1653 ? '*' : ' ',
1654 len - 3, ' ');
1655
1656 switch (nexthop->type)
1657 {
1658 case NEXTHOP_TYPE_IPV6:
1659 case NEXTHOP_TYPE_IPV6_IFINDEX:
1660 case NEXTHOP_TYPE_IPV6_IFNAME:
1661 vty_out (vty, " via %s",
1662 inet_ntop (AF_INET6, &nexthop->gate.ipv6, buf, BUFSIZ));
1663 if (nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME)
1664 vty_out (vty, ", %s", nexthop->ifname);
1665 else if (nexthop->ifindex)
1666 vty_out (vty, ", %s", ifindex2ifname (nexthop->ifindex));
1667 break;
1668 case NEXTHOP_TYPE_IFINDEX:
1669 vty_out (vty, " is directly connected, %s",
1670 ifindex2ifname (nexthop->ifindex));
1671 break;
1672 case NEXTHOP_TYPE_IFNAME:
1673 vty_out (vty, " is directly connected, %s",
1674 nexthop->ifname);
1675 break;
1676 default:
1677 break;
1678 }
1679 if (! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
1680 vty_out (vty, " inactive");
1681
1682 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
1683 {
1684 vty_out (vty, " (recursive");
1685
1686 switch (nexthop->rtype)
1687 {
1688 case NEXTHOP_TYPE_IPV6:
1689 case NEXTHOP_TYPE_IPV6_IFINDEX:
1690 case NEXTHOP_TYPE_IPV6_IFNAME:
1691 vty_out (vty, " via %s)",
1692 inet_ntop (AF_INET6, &nexthop->rgate.ipv6,
1693 buf, BUFSIZ));
1694 if (nexthop->rifindex)
1695 vty_out (vty, ", %s", ifindex2ifname (nexthop->rifindex));
1696 break;
1697 case NEXTHOP_TYPE_IFINDEX:
1698 case NEXTHOP_TYPE_IFNAME:
1699 vty_out (vty, " is directly connected, %s)",
1700 ifindex2ifname (nexthop->rifindex));
1701 break;
1702 default:
1703 break;
1704 }
1705 }
1706
1707 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_BLACKHOLE))
1708 vty_out (vty, ", bh");
1709 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_REJECT))
1710 vty_out (vty, ", rej");
1711
1712 if (rib->type == ZEBRA_ROUTE_RIPNG
1713 || rib->type == ZEBRA_ROUTE_OSPF6
1714 || rib->type == ZEBRA_ROUTE_ISIS
1715 || rib->type == ZEBRA_ROUTE_BGP)
1716 {
1717 time_t uptime;
1718 struct tm *tm;
1719
1720 uptime = time (NULL);
1721 uptime -= rib->uptime;
1722 tm = gmtime (&uptime);
1723
1724 #define ONE_DAY_SECOND 60*60*24
1725 #define ONE_WEEK_SECOND 60*60*24*7
1726
1727 if (uptime < ONE_DAY_SECOND)
1728 vty_out (vty, ", %02d:%02d:%02d",
1729 tm->tm_hour, tm->tm_min, tm->tm_sec);
1730 else if (uptime < ONE_WEEK_SECOND)
1731 vty_out (vty, ", %dd%02dh%02dm",
1732 tm->tm_yday, tm->tm_hour, tm->tm_min);
1733 else
1734 vty_out (vty, ", %02dw%dd%02dh",
1735 tm->tm_yday/7,
1736 tm->tm_yday - ((tm->tm_yday/7) * 7), tm->tm_hour);
1737 }
1738 vty_out (vty, "%s", VTY_NEWLINE);
1739 }
1740 }
1741
1742 DEFUN (show_ipv6_route,
1743 show_ipv6_route_cmd,
1744 "show ipv6 route",
1745 SHOW_STR
1746 IP_STR
1747 "IPv6 routing table\n")
1748 {
1749 struct route_table *table;
1750 struct route_node *rn;
1751 struct rib *rib;
1752 int first = 1;
1753
1754 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
1755 if (! table)
1756 return CMD_SUCCESS;
1757
1758 /* Show all IPv6 route. */
1759 for (rn = route_top (table); rn; rn = route_next (rn))
1760 for (rib = rn->info; rib; rib = rib->next)
1761 {
1762 if (first)
1763 {
1764 vty_out (vty, SHOW_ROUTE_V6_HEADER);
1765 first = 0;
1766 }
1767 vty_show_ipv6_route (vty, rn, rib);
1768 }
1769 return CMD_SUCCESS;
1770 }
1771
1772 DEFUN (show_ipv6_route_prefix_longer,
1773 show_ipv6_route_prefix_longer_cmd,
1774 "show ipv6 route X:X::X:X/M longer-prefixes",
1775 SHOW_STR
1776 IP_STR
1777 "IPv6 routing table\n"
1778 "IPv6 prefix\n"
1779 "Show route matching the specified Network/Mask pair only\n")
1780 {
1781 struct route_table *table;
1782 struct route_node *rn;
1783 struct rib *rib;
1784 struct prefix p;
1785 int ret;
1786 int first = 1;
1787
1788 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
1789 if (! table)
1790 return CMD_SUCCESS;
1791
1792 ret = str2prefix (argv[0], &p);
1793 if (! ret)
1794 {
1795 vty_out (vty, "%% Malformed Prefix%s", VTY_NEWLINE);
1796 return CMD_WARNING;
1797 }
1798
1799 /* Show matched type IPv6 routes. */
1800 for (rn = route_top (table); rn; rn = route_next (rn))
1801 for (rib = rn->info; rib; rib = rib->next)
1802 if (prefix_match (&p, &rn->p))
1803 {
1804 if (first)
1805 {
1806 vty_out (vty, SHOW_ROUTE_V6_HEADER);
1807 first = 0;
1808 }
1809 vty_show_ipv6_route (vty, rn, rib);
1810 }
1811 return CMD_SUCCESS;
1812 }
1813
1814 DEFUN (show_ipv6_route_protocol,
1815 show_ipv6_route_protocol_cmd,
1816 "show ipv6 route " QUAGGA_IP6_REDIST_STR_ZEBRA,
1817 SHOW_STR
1818 IP_STR
1819 "IP routing table\n"
1820 QUAGGA_IP6_REDIST_HELP_STR_ZEBRA)
1821 {
1822 int type;
1823 struct route_table *table;
1824 struct route_node *rn;
1825 struct rib *rib;
1826 int first = 1;
1827
1828 type = proto_redistnum (AFI_IP6, argv[0]);
1829 if (type < 0)
1830 {
1831 vty_out (vty, "Unknown route type%s", VTY_NEWLINE);
1832 return CMD_WARNING;
1833 }
1834
1835 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
1836 if (! table)
1837 return CMD_SUCCESS;
1838
1839 /* Show matched type IPv6 routes. */
1840 for (rn = route_top (table); rn; rn = route_next (rn))
1841 for (rib = rn->info; rib; rib = rib->next)
1842 if (rib->type == type)
1843 {
1844 if (first)
1845 {
1846 vty_out (vty, SHOW_ROUTE_V6_HEADER);
1847 first = 0;
1848 }
1849 vty_show_ipv6_route (vty, rn, rib);
1850 }
1851 return CMD_SUCCESS;
1852 }
1853
1854 DEFUN (show_ipv6_route_addr,
1855 show_ipv6_route_addr_cmd,
1856 "show ipv6 route X:X::X:X",
1857 SHOW_STR
1858 IP_STR
1859 "IPv6 routing table\n"
1860 "IPv6 Address\n")
1861 {
1862 int ret;
1863 struct prefix_ipv6 p;
1864 struct route_table *table;
1865 struct route_node *rn;
1866
1867 ret = str2prefix_ipv6 (argv[0], &p);
1868 if (ret <= 0)
1869 {
1870 vty_out (vty, "Malformed IPv6 address%s", VTY_NEWLINE);
1871 return CMD_WARNING;
1872 }
1873
1874 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
1875 if (! table)
1876 return CMD_SUCCESS;
1877
1878 rn = route_node_match (table, (struct prefix *) &p);
1879 if (! rn)
1880 {
1881 vty_out (vty, "%% Network not in table%s", VTY_NEWLINE);
1882 return CMD_WARNING;
1883 }
1884
1885 vty_show_ipv6_route_detail (vty, rn);
1886
1887 route_unlock_node (rn);
1888
1889 return CMD_SUCCESS;
1890 }
1891
1892 DEFUN (show_ipv6_route_prefix,
1893 show_ipv6_route_prefix_cmd,
1894 "show ipv6 route X:X::X:X/M",
1895 SHOW_STR
1896 IP_STR
1897 "IPv6 routing table\n"
1898 "IPv6 prefix\n")
1899 {
1900 int ret;
1901 struct prefix_ipv6 p;
1902 struct route_table *table;
1903 struct route_node *rn;
1904
1905 ret = str2prefix_ipv6 (argv[0], &p);
1906 if (ret <= 0)
1907 {
1908 vty_out (vty, "Malformed IPv6 prefix%s", VTY_NEWLINE);
1909 return CMD_WARNING;
1910 }
1911
1912 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
1913 if (! table)
1914 return CMD_SUCCESS;
1915
1916 rn = route_node_match (table, (struct prefix *) &p);
1917 if (! rn || rn->p.prefixlen != p.prefixlen)
1918 {
1919 vty_out (vty, "%% Network not in table%s", VTY_NEWLINE);
1920 return CMD_WARNING;
1921 }
1922
1923 vty_show_ipv6_route_detail (vty, rn);
1924
1925 route_unlock_node (rn);
1926
1927 return CMD_SUCCESS;
1928 }
1929
1930 /* Show route summary. */
1931 DEFUN (show_ipv6_route_summary,
1932 show_ipv6_route_summary_cmd,
1933 "show ipv6 route summary",
1934 SHOW_STR
1935 IP_STR
1936 "IPv6 routing table\n"
1937 "Summary of all IPv6 routes\n")
1938 {
1939 struct route_table *table;
1940
1941 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
1942 if (! table)
1943 return CMD_SUCCESS;
1944
1945 vty_show_ip_route_summary (vty, table);
1946
1947 return CMD_SUCCESS;
1948 }
1949
1950 /* Write IPv6 static route configuration. */
1951 static int
1952 static_config_ipv6 (struct vty *vty)
1953 {
1954 struct route_node *rn;
1955 struct static_ipv6 *si;
1956 int write;
1957 char buf[BUFSIZ];
1958 struct route_table *stable;
1959
1960 write = 0;
1961
1962 /* Lookup table. */
1963 stable = vrf_static_table (AFI_IP6, SAFI_UNICAST, 0);
1964 if (! stable)
1965 return -1;
1966
1967 for (rn = route_top (stable); rn; rn = route_next (rn))
1968 for (si = rn->info; si; si = si->next)
1969 {
1970 vty_out (vty, "ipv6 route %s/%d",
1971 inet_ntop (AF_INET6, &rn->p.u.prefix6, buf, BUFSIZ),
1972 rn->p.prefixlen);
1973
1974 switch (si->type)
1975 {
1976 case STATIC_IPV6_GATEWAY:
1977 vty_out (vty, " %s", inet_ntop (AF_INET6, &si->ipv6, buf, BUFSIZ));
1978 break;
1979 case STATIC_IPV6_IFNAME:
1980 vty_out (vty, " %s", si->ifname);
1981 break;
1982 case STATIC_IPV6_GATEWAY_IFNAME:
1983 vty_out (vty, " %s %s",
1984 inet_ntop (AF_INET6, &si->ipv6, buf, BUFSIZ), si->ifname);
1985 break;
1986 }
1987
1988 if (CHECK_FLAG(si->flags, ZEBRA_FLAG_REJECT))
1989 vty_out (vty, " %s", "reject");
1990
1991 if (CHECK_FLAG(si->flags, ZEBRA_FLAG_BLACKHOLE))
1992 vty_out (vty, " %s", "blackhole");
1993
1994 if (si->distance != ZEBRA_STATIC_DISTANCE_DEFAULT)
1995 vty_out (vty, " %d", si->distance);
1996 vty_out (vty, "%s", VTY_NEWLINE);
1997
1998 write = 1;
1999 }
2000 return write;
2001 }
2002 #endif /* HAVE_IPV6 */
2003
2004 /* Static ip route configuration write function. */
2005 static int
2006 zebra_ip_config (struct vty *vty)
2007 {
2008 int write = 0;
2009
2010 write += static_config_ipv4 (vty);
2011 #ifdef HAVE_IPV6
2012 write += static_config_ipv6 (vty);
2013 #endif /* HAVE_IPV6 */
2014
2015 return write;
2016 }
2017
2018 /* ip protocol configuration write function */
2019 static int config_write_protocol(struct vty *vty)
2020 {
2021 int i;
2022
2023 for (i=0;i<ZEBRA_ROUTE_MAX;i++)
2024 {
2025 if (proto_rm[AFI_IP][i])
2026 vty_out (vty, "ip protocol %s route-map %s%s", zebra_route_string(i),
2027 proto_rm[AFI_IP][i], VTY_NEWLINE);
2028 }
2029 if (proto_rm[AFI_IP][ZEBRA_ROUTE_MAX])
2030 vty_out (vty, "ip protocol %s route-map %s%s", "any",
2031 proto_rm[AFI_IP][ZEBRA_ROUTE_MAX], VTY_NEWLINE);
2032
2033 return 1;
2034 }
2035
2036 /* table node for protocol filtering */
2037 static struct cmd_node protocol_node = { PROTOCOL_NODE, "", 1 };
2038
2039 /* IP node for static routes. */
2040 static struct cmd_node ip_node = { IP_NODE, "", 1 };
2041
2042 /* Route VTY. */
2043 void
2044 zebra_vty_init (void)
2045 {
2046 install_node (&ip_node, zebra_ip_config);
2047 install_node (&protocol_node, config_write_protocol);
2048
2049 install_element (CONFIG_NODE, &ip_protocol_cmd);
2050 install_element (CONFIG_NODE, &no_ip_protocol_cmd);
2051 install_element (VIEW_NODE, &show_ip_protocol_cmd);
2052 install_element (ENABLE_NODE, &show_ip_protocol_cmd);
2053 install_element (CONFIG_NODE, &ip_route_cmd);
2054 install_element (CONFIG_NODE, &ip_route_flags_cmd);
2055 install_element (CONFIG_NODE, &ip_route_flags2_cmd);
2056 install_element (CONFIG_NODE, &ip_route_mask_cmd);
2057 install_element (CONFIG_NODE, &ip_route_mask_flags_cmd);
2058 install_element (CONFIG_NODE, &ip_route_mask_flags2_cmd);
2059 install_element (CONFIG_NODE, &no_ip_route_cmd);
2060 install_element (CONFIG_NODE, &no_ip_route_flags_cmd);
2061 install_element (CONFIG_NODE, &no_ip_route_flags2_cmd);
2062 install_element (CONFIG_NODE, &no_ip_route_mask_cmd);
2063 install_element (CONFIG_NODE, &no_ip_route_mask_flags_cmd);
2064 install_element (CONFIG_NODE, &no_ip_route_mask_flags2_cmd);
2065 install_element (CONFIG_NODE, &ip_route_distance_cmd);
2066 install_element (CONFIG_NODE, &ip_route_flags_distance_cmd);
2067 install_element (CONFIG_NODE, &ip_route_flags_distance2_cmd);
2068 install_element (CONFIG_NODE, &ip_route_mask_distance_cmd);
2069 install_element (CONFIG_NODE, &ip_route_mask_flags_distance_cmd);
2070 install_element (CONFIG_NODE, &ip_route_mask_flags_distance2_cmd);
2071 install_element (CONFIG_NODE, &no_ip_route_distance_cmd);
2072 install_element (CONFIG_NODE, &no_ip_route_flags_distance_cmd);
2073 install_element (CONFIG_NODE, &no_ip_route_flags_distance2_cmd);
2074 install_element (CONFIG_NODE, &no_ip_route_mask_flags_distance_cmd);
2075 install_element (CONFIG_NODE, &no_ip_route_mask_flags_distance2_cmd);
2076
2077 install_element (VIEW_NODE, &show_ip_route_cmd);
2078 install_element (VIEW_NODE, &show_ip_route_addr_cmd);
2079 install_element (VIEW_NODE, &show_ip_route_prefix_cmd);
2080 install_element (VIEW_NODE, &show_ip_route_prefix_longer_cmd);
2081 install_element (VIEW_NODE, &show_ip_route_protocol_cmd);
2082 install_element (VIEW_NODE, &show_ip_route_supernets_cmd);
2083 install_element (VIEW_NODE, &show_ip_route_summary_cmd);
2084 install_element (ENABLE_NODE, &show_ip_route_cmd);
2085 install_element (ENABLE_NODE, &show_ip_route_addr_cmd);
2086 install_element (ENABLE_NODE, &show_ip_route_prefix_cmd);
2087 install_element (ENABLE_NODE, &show_ip_route_prefix_longer_cmd);
2088 install_element (ENABLE_NODE, &show_ip_route_protocol_cmd);
2089 install_element (ENABLE_NODE, &show_ip_route_supernets_cmd);
2090 install_element (ENABLE_NODE, &show_ip_route_summary_cmd);
2091
2092 #ifdef HAVE_IPV6
2093 install_element (CONFIG_NODE, &ipv6_route_cmd);
2094 install_element (CONFIG_NODE, &ipv6_route_flags_cmd);
2095 install_element (CONFIG_NODE, &ipv6_route_ifname_cmd);
2096 install_element (CONFIG_NODE, &ipv6_route_ifname_flags_cmd);
2097 install_element (CONFIG_NODE, &no_ipv6_route_cmd);
2098 install_element (CONFIG_NODE, &no_ipv6_route_flags_cmd);
2099 install_element (CONFIG_NODE, &no_ipv6_route_ifname_cmd);
2100 install_element (CONFIG_NODE, &no_ipv6_route_ifname_flags_cmd);
2101 install_element (CONFIG_NODE, &ipv6_route_pref_cmd);
2102 install_element (CONFIG_NODE, &ipv6_route_flags_pref_cmd);
2103 install_element (CONFIG_NODE, &ipv6_route_ifname_pref_cmd);
2104 install_element (CONFIG_NODE, &ipv6_route_ifname_flags_pref_cmd);
2105 install_element (CONFIG_NODE, &no_ipv6_route_pref_cmd);
2106 install_element (CONFIG_NODE, &no_ipv6_route_flags_pref_cmd);
2107 install_element (CONFIG_NODE, &no_ipv6_route_ifname_pref_cmd);
2108 install_element (CONFIG_NODE, &no_ipv6_route_ifname_flags_pref_cmd);
2109 install_element (VIEW_NODE, &show_ipv6_route_cmd);
2110 install_element (VIEW_NODE, &show_ipv6_route_summary_cmd);
2111 install_element (VIEW_NODE, &show_ipv6_route_protocol_cmd);
2112 install_element (VIEW_NODE, &show_ipv6_route_addr_cmd);
2113 install_element (VIEW_NODE, &show_ipv6_route_prefix_cmd);
2114 install_element (VIEW_NODE, &show_ipv6_route_prefix_longer_cmd);
2115 install_element (ENABLE_NODE, &show_ipv6_route_cmd);
2116 install_element (ENABLE_NODE, &show_ipv6_route_protocol_cmd);
2117 install_element (ENABLE_NODE, &show_ipv6_route_addr_cmd);
2118 install_element (ENABLE_NODE, &show_ipv6_route_prefix_cmd);
2119 install_element (ENABLE_NODE, &show_ipv6_route_prefix_longer_cmd);
2120 install_element (ENABLE_NODE, &show_ipv6_route_summary_cmd);
2121 #endif /* HAVE_IPV6 */
2122 }