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