Annotation of embedaddon/quagga/zebra/zebra_vty.c, revision 1.1.1.1
1.1 misho 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: vty_show_ip_route_summary (struct vty *vty, struct route_table *table)
1061: {
1062: struct route_node *rn;
1063: struct rib *rib;
1064: struct nexthop *nexthop;
1065: #define ZEBRA_ROUTE_IBGP ZEBRA_ROUTE_MAX
1066: #define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1)
1067: u_int32_t rib_cnt[ZEBRA_ROUTE_TOTAL + 1];
1068: u_int32_t fib_cnt[ZEBRA_ROUTE_TOTAL + 1];
1069: u_int32_t i;
1070:
1071: memset (&rib_cnt, 0, sizeof(rib_cnt));
1072: memset (&fib_cnt, 0, sizeof(fib_cnt));
1073: for (rn = route_top (table); rn; rn = route_next (rn))
1074: for (rib = rn->info; rib; rib = rib->next)
1075: for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1076: {
1077: rib_cnt[ZEBRA_ROUTE_TOTAL]++;
1078: rib_cnt[rib->type]++;
1079: if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
1080: {
1081: fib_cnt[ZEBRA_ROUTE_TOTAL]++;
1082: fib_cnt[rib->type]++;
1083: }
1084: if (rib->type == ZEBRA_ROUTE_BGP &&
1085: CHECK_FLAG (rib->flags, ZEBRA_FLAG_IBGP))
1086: {
1087: rib_cnt[ZEBRA_ROUTE_IBGP]++;
1088: if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
1089: fib_cnt[ZEBRA_ROUTE_IBGP]++;
1090: }
1091: }
1092:
1093: vty_out (vty, "%-20s %-20s %-20s %s",
1094: "Route Source", "Routes", "FIB", VTY_NEWLINE);
1095:
1096: for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
1097: {
1098: if (rib_cnt[i] > 0)
1099: {
1100: if (i == ZEBRA_ROUTE_BGP)
1101: {
1102: vty_out (vty, "%-20s %-20d %-20d %s", "ebgp",
1103: rib_cnt[ZEBRA_ROUTE_BGP] - rib_cnt[ZEBRA_ROUTE_IBGP],
1104: fib_cnt[ZEBRA_ROUTE_BGP] - fib_cnt[ZEBRA_ROUTE_IBGP],
1105: VTY_NEWLINE);
1106: vty_out (vty, "%-20s %-20d %-20d %s", "ibgp",
1107: rib_cnt[ZEBRA_ROUTE_IBGP], fib_cnt[ZEBRA_ROUTE_IBGP],
1108: VTY_NEWLINE);
1109: }
1110: else
1111: vty_out (vty, "%-20s %-20d %-20d %s", zebra_route_string(i),
1112: rib_cnt[i], fib_cnt[i], VTY_NEWLINE);
1113: }
1114: }
1115:
1116: vty_out (vty, "------%s", VTY_NEWLINE);
1117: vty_out (vty, "%-20s %-20d %-20d %s", "Totals", rib_cnt[ZEBRA_ROUTE_TOTAL],
1118: fib_cnt[ZEBRA_ROUTE_TOTAL], VTY_NEWLINE);
1119: }
1120:
1121: /* Show route summary. */
1122: DEFUN (show_ip_route_summary,
1123: show_ip_route_summary_cmd,
1124: "show ip route summary",
1125: SHOW_STR
1126: IP_STR
1127: "IP routing table\n"
1128: "Summary of all routes\n")
1129: {
1130: struct route_table *table;
1131:
1132: table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
1133: if (! table)
1134: return CMD_SUCCESS;
1135:
1136: vty_show_ip_route_summary (vty, table);
1137:
1138: return CMD_SUCCESS;
1139: }
1140:
1141: /* Write IPv4 static route configuration. */
1142: static int
1143: static_config_ipv4 (struct vty *vty)
1144: {
1145: struct route_node *rn;
1146: struct static_ipv4 *si;
1147: struct route_table *stable;
1148: int write;
1149:
1150: write = 0;
1151:
1152: /* Lookup table. */
1153: stable = vrf_static_table (AFI_IP, SAFI_UNICAST, 0);
1154: if (! stable)
1155: return -1;
1156:
1157: for (rn = route_top (stable); rn; rn = route_next (rn))
1158: for (si = rn->info; si; si = si->next)
1159: {
1160: vty_out (vty, "ip route %s/%d", inet_ntoa (rn->p.u.prefix4),
1161: rn->p.prefixlen);
1162:
1163: switch (si->type)
1164: {
1165: case STATIC_IPV4_GATEWAY:
1166: vty_out (vty, " %s", inet_ntoa (si->gate.ipv4));
1167: break;
1168: case STATIC_IPV4_IFNAME:
1169: vty_out (vty, " %s", si->gate.ifname);
1170: break;
1171: case STATIC_IPV4_BLACKHOLE:
1172: vty_out (vty, " Null0");
1173: break;
1174: }
1175:
1176: /* flags are incompatible with STATIC_IPV4_BLACKHOLE */
1177: if (si->type != STATIC_IPV4_BLACKHOLE)
1178: {
1179: if (CHECK_FLAG(si->flags, ZEBRA_FLAG_REJECT))
1180: vty_out (vty, " %s", "reject");
1181:
1182: if (CHECK_FLAG(si->flags, ZEBRA_FLAG_BLACKHOLE))
1183: vty_out (vty, " %s", "blackhole");
1184: }
1185:
1186: if (si->distance != ZEBRA_STATIC_DISTANCE_DEFAULT)
1187: vty_out (vty, " %d", si->distance);
1188:
1189: vty_out (vty, "%s", VTY_NEWLINE);
1190:
1191: write = 1;
1192: }
1193: return write;
1194: }
1195:
1196: DEFUN (show_ip_protocol,
1197: show_ip_protocol_cmd,
1198: "show ip protocol",
1199: SHOW_STR
1200: IP_STR
1201: "IP protocol filtering status\n")
1202: {
1203: int i;
1204:
1205: vty_out(vty, "Protocol : route-map %s", VTY_NEWLINE);
1206: vty_out(vty, "------------------------%s", VTY_NEWLINE);
1207: for (i=0;i<ZEBRA_ROUTE_MAX;i++)
1208: {
1209: if (proto_rm[AFI_IP][i])
1210: vty_out (vty, "%-10s : %-10s%s", zebra_route_string(i),
1211: proto_rm[AFI_IP][i],
1212: VTY_NEWLINE);
1213: else
1214: vty_out (vty, "%-10s : none%s", zebra_route_string(i), VTY_NEWLINE);
1215: }
1216: if (proto_rm[AFI_IP][i])
1217: vty_out (vty, "%-10s : %-10s%s", "any", proto_rm[AFI_IP][i],
1218: VTY_NEWLINE);
1219: else
1220: vty_out (vty, "%-10s : none%s", "any", VTY_NEWLINE);
1221:
1222: return CMD_SUCCESS;
1223: }
1224:
1225:
1226: #ifdef HAVE_IPV6
1227: /* General fucntion for IPv6 static route. */
1228: static int
1229: static_ipv6_func (struct vty *vty, int add_cmd, const char *dest_str,
1230: const char *gate_str, const char *ifname,
1231: const char *flag_str, const char *distance_str)
1232: {
1233: int ret;
1234: u_char distance;
1235: struct prefix p;
1236: struct in6_addr *gate = NULL;
1237: struct in6_addr gate_addr;
1238: u_char type = 0;
1239: int table = 0;
1240: u_char flag = 0;
1241:
1242: ret = str2prefix (dest_str, &p);
1243: if (ret <= 0)
1244: {
1245: vty_out (vty, "%% Malformed address%s", VTY_NEWLINE);
1246: return CMD_WARNING;
1247: }
1248:
1249: /* Apply mask for given prefix. */
1250: apply_mask (&p);
1251:
1252: /* Route flags */
1253: if (flag_str) {
1254: switch(flag_str[0]) {
1255: case 'r':
1256: case 'R': /* XXX */
1257: SET_FLAG (flag, ZEBRA_FLAG_REJECT);
1258: break;
1259: case 'b':
1260: case 'B': /* XXX */
1261: SET_FLAG (flag, ZEBRA_FLAG_BLACKHOLE);
1262: break;
1263: default:
1264: vty_out (vty, "%% Malformed flag %s %s", flag_str, VTY_NEWLINE);
1265: return CMD_WARNING;
1266: }
1267: }
1268:
1269: /* Administrative distance. */
1270: if (distance_str)
1271: distance = atoi (distance_str);
1272: else
1273: distance = ZEBRA_STATIC_DISTANCE_DEFAULT;
1274:
1275: /* When gateway is valid IPv6 addrees, then gate is treated as
1276: nexthop address other case gate is treated as interface name. */
1277: ret = inet_pton (AF_INET6, gate_str, &gate_addr);
1278:
1279: if (ifname)
1280: {
1281: /* When ifname is specified. It must be come with gateway
1282: address. */
1283: if (ret != 1)
1284: {
1285: vty_out (vty, "%% Malformed address%s", VTY_NEWLINE);
1286: return CMD_WARNING;
1287: }
1288: type = STATIC_IPV6_GATEWAY_IFNAME;
1289: gate = &gate_addr;
1290: }
1291: else
1292: {
1293: if (ret == 1)
1294: {
1295: type = STATIC_IPV6_GATEWAY;
1296: gate = &gate_addr;
1297: }
1298: else
1299: {
1300: type = STATIC_IPV6_IFNAME;
1301: ifname = gate_str;
1302: }
1303: }
1304:
1305: if (add_cmd)
1306: static_add_ipv6 (&p, type, gate, ifname, flag, distance, table);
1307: else
1308: static_delete_ipv6 (&p, type, gate, ifname, distance, table);
1309:
1310: return CMD_SUCCESS;
1311: }
1312:
1313: DEFUN (ipv6_route,
1314: ipv6_route_cmd,
1315: "ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE)",
1316: IP_STR
1317: "Establish static routes\n"
1318: "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1319: "IPv6 gateway address\n"
1320: "IPv6 gateway interface name\n")
1321: {
1322: return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, NULL, NULL);
1323: }
1324:
1325: DEFUN (ipv6_route_flags,
1326: ipv6_route_flags_cmd,
1327: "ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) (reject|blackhole)",
1328: IP_STR
1329: "Establish static routes\n"
1330: "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1331: "IPv6 gateway address\n"
1332: "IPv6 gateway interface name\n"
1333: "Emit an ICMP unreachable when matched\n"
1334: "Silently discard pkts when matched\n")
1335: {
1336: return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, argv[2], NULL);
1337: }
1338:
1339: DEFUN (ipv6_route_ifname,
1340: ipv6_route_ifname_cmd,
1341: "ipv6 route X:X::X:X/M X:X::X:X INTERFACE",
1342: IP_STR
1343: "Establish static routes\n"
1344: "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1345: "IPv6 gateway address\n"
1346: "IPv6 gateway interface name\n")
1347: {
1348: return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], NULL, NULL);
1349: }
1350:
1351: DEFUN (ipv6_route_ifname_flags,
1352: ipv6_route_ifname_flags_cmd,
1353: "ipv6 route X:X::X:X/M X:X::X:X INTERFACE (reject|blackhole)",
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: {
1362: return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], argv[3], NULL);
1363: }
1364:
1365: DEFUN (ipv6_route_pref,
1366: ipv6_route_pref_cmd,
1367: "ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) <1-255>",
1368: IP_STR
1369: "Establish static routes\n"
1370: "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1371: "IPv6 gateway address\n"
1372: "IPv6 gateway interface name\n"
1373: "Distance value for this prefix\n")
1374: {
1375: return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, NULL, argv[2]);
1376: }
1377:
1378: DEFUN (ipv6_route_flags_pref,
1379: ipv6_route_flags_pref_cmd,
1380: "ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) (reject|blackhole) <1-255>",
1381: IP_STR
1382: "Establish static routes\n"
1383: "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1384: "IPv6 gateway address\n"
1385: "IPv6 gateway interface name\n"
1386: "Emit an ICMP unreachable when matched\n"
1387: "Silently discard pkts when matched\n"
1388: "Distance value for this prefix\n")
1389: {
1390: return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, argv[2], argv[3]);
1391: }
1392:
1393: DEFUN (ipv6_route_ifname_pref,
1394: ipv6_route_ifname_pref_cmd,
1395: "ipv6 route X:X::X:X/M X:X::X:X INTERFACE <1-255>",
1396: IP_STR
1397: "Establish static routes\n"
1398: "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1399: "IPv6 gateway address\n"
1400: "IPv6 gateway interface name\n"
1401: "Distance value for this prefix\n")
1402: {
1403: return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], NULL, argv[3]);
1404: }
1405:
1406: DEFUN (ipv6_route_ifname_flags_pref,
1407: ipv6_route_ifname_flags_pref_cmd,
1408: "ipv6 route X:X::X:X/M X:X::X:X INTERFACE (reject|blackhole) <1-255>",
1409: IP_STR
1410: "Establish static routes\n"
1411: "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1412: "IPv6 gateway address\n"
1413: "IPv6 gateway interface name\n"
1414: "Emit an ICMP unreachable when matched\n"
1415: "Silently discard pkts when matched\n"
1416: "Distance value for this prefix\n")
1417: {
1418: return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], argv[3], argv[4]);
1419: }
1420:
1421: DEFUN (no_ipv6_route,
1422: no_ipv6_route_cmd,
1423: "no ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE)",
1424: NO_STR
1425: IP_STR
1426: "Establish static routes\n"
1427: "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1428: "IPv6 gateway address\n"
1429: "IPv6 gateway interface name\n")
1430: {
1431: return static_ipv6_func (vty, 0, argv[0], argv[1], NULL, NULL, NULL);
1432: }
1433:
1434: ALIAS (no_ipv6_route,
1435: no_ipv6_route_flags_cmd,
1436: "no ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) (reject|blackhole)",
1437: NO_STR
1438: IP_STR
1439: "Establish static routes\n"
1440: "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1441: "IPv6 gateway address\n"
1442: "IPv6 gateway interface name\n"
1443: "Emit an ICMP unreachable when matched\n"
1444: "Silently discard pkts when matched\n")
1445:
1446: DEFUN (no_ipv6_route_ifname,
1447: no_ipv6_route_ifname_cmd,
1448: "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE",
1449: NO_STR
1450: IP_STR
1451: "Establish static routes\n"
1452: "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1453: "IPv6 gateway address\n"
1454: "IPv6 gateway interface name\n")
1455: {
1456: return static_ipv6_func (vty, 0, argv[0], argv[1], argv[2], NULL, NULL);
1457: }
1458:
1459: ALIAS (no_ipv6_route_ifname,
1460: no_ipv6_route_ifname_flags_cmd,
1461: "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE (reject|blackhole)",
1462: NO_STR
1463: IP_STR
1464: "Establish static routes\n"
1465: "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1466: "IPv6 gateway address\n"
1467: "IPv6 gateway interface name\n"
1468: "Emit an ICMP unreachable when matched\n"
1469: "Silently discard pkts when matched\n")
1470:
1471: DEFUN (no_ipv6_route_pref,
1472: no_ipv6_route_pref_cmd,
1473: "no ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) <1-255>",
1474: NO_STR
1475: IP_STR
1476: "Establish static routes\n"
1477: "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1478: "IPv6 gateway address\n"
1479: "IPv6 gateway interface name\n"
1480: "Distance value for this prefix\n")
1481: {
1482: return static_ipv6_func (vty, 0, argv[0], argv[1], NULL, NULL, argv[2]);
1483: }
1484:
1485: DEFUN (no_ipv6_route_flags_pref,
1486: no_ipv6_route_flags_pref_cmd,
1487: "no ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) (reject|blackhole) <1-255>",
1488: NO_STR
1489: IP_STR
1490: "Establish static routes\n"
1491: "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1492: "IPv6 gateway address\n"
1493: "IPv6 gateway interface name\n"
1494: "Emit an ICMP unreachable when matched\n"
1495: "Silently discard pkts when matched\n"
1496: "Distance value for this prefix\n")
1497: {
1498: /* We do not care about argv[2] */
1499: return static_ipv6_func (vty, 0, argv[0], argv[1], NULL, argv[2], argv[3]);
1500: }
1501:
1502: DEFUN (no_ipv6_route_ifname_pref,
1503: no_ipv6_route_ifname_pref_cmd,
1504: "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE <1-255>",
1505: NO_STR
1506: IP_STR
1507: "Establish static routes\n"
1508: "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1509: "IPv6 gateway address\n"
1510: "IPv6 gateway interface name\n"
1511: "Distance value for this prefix\n")
1512: {
1513: return static_ipv6_func (vty, 0, argv[0], argv[1], argv[2], NULL, argv[3]);
1514: }
1515:
1516: DEFUN (no_ipv6_route_ifname_flags_pref,
1517: no_ipv6_route_ifname_flags_pref_cmd,
1518: "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE (reject|blackhole) <1-255>",
1519: NO_STR
1520: IP_STR
1521: "Establish static routes\n"
1522: "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1523: "IPv6 gateway address\n"
1524: "IPv6 gateway interface name\n"
1525: "Emit an ICMP unreachable when matched\n"
1526: "Silently discard pkts when matched\n"
1527: "Distance value for this prefix\n")
1528: {
1529: return static_ipv6_func (vty, 0, argv[0], argv[1], argv[2], argv[3], argv[4]);
1530: }
1531:
1532: /* New RIB. Detailed information for IPv6 route. */
1533: static void
1534: vty_show_ipv6_route_detail (struct vty *vty, struct route_node *rn)
1535: {
1536: struct rib *rib;
1537: struct nexthop *nexthop;
1538: char buf[BUFSIZ];
1539:
1540: for (rib = rn->info; rib; rib = rib->next)
1541: {
1542: vty_out (vty, "Routing entry for %s/%d%s",
1543: inet_ntop (AF_INET6, &rn->p.u.prefix6, buf, BUFSIZ),
1544: rn->p.prefixlen,
1545: VTY_NEWLINE);
1546: vty_out (vty, " Known via \"%s\"", zebra_route_string (rib->type));
1547: vty_out (vty, ", distance %d, metric %d", rib->distance, rib->metric);
1548: if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
1549: vty_out (vty, ", best");
1550: if (rib->refcnt)
1551: vty_out (vty, ", refcnt %ld", rib->refcnt);
1552: if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_BLACKHOLE))
1553: vty_out (vty, ", blackhole");
1554: if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_REJECT))
1555: vty_out (vty, ", reject");
1556: vty_out (vty, "%s", VTY_NEWLINE);
1557:
1558: #define ONE_DAY_SECOND 60*60*24
1559: #define ONE_WEEK_SECOND 60*60*24*7
1560: if (rib->type == ZEBRA_ROUTE_RIPNG
1561: || rib->type == ZEBRA_ROUTE_OSPF6
1562: || rib->type == ZEBRA_ROUTE_ISIS
1563: || rib->type == ZEBRA_ROUTE_BGP)
1564: {
1565: time_t uptime;
1566: struct tm *tm;
1567:
1568: uptime = time (NULL);
1569: uptime -= rib->uptime;
1570: tm = gmtime (&uptime);
1571:
1572: vty_out (vty, " Last update ");
1573:
1574: if (uptime < ONE_DAY_SECOND)
1575: vty_out (vty, "%02d:%02d:%02d",
1576: tm->tm_hour, tm->tm_min, tm->tm_sec);
1577: else if (uptime < ONE_WEEK_SECOND)
1578: vty_out (vty, "%dd%02dh%02dm",
1579: tm->tm_yday, tm->tm_hour, tm->tm_min);
1580: else
1581: vty_out (vty, "%02dw%dd%02dh",
1582: tm->tm_yday/7,
1583: tm->tm_yday - ((tm->tm_yday/7) * 7), tm->tm_hour);
1584: vty_out (vty, " ago%s", VTY_NEWLINE);
1585: }
1586:
1587: for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1588: {
1589: vty_out (vty, " %c",
1590: CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB) ? '*' : ' ');
1591:
1592: switch (nexthop->type)
1593: {
1594: case NEXTHOP_TYPE_IPV6:
1595: case NEXTHOP_TYPE_IPV6_IFINDEX:
1596: case NEXTHOP_TYPE_IPV6_IFNAME:
1597: vty_out (vty, " %s",
1598: inet_ntop (AF_INET6, &nexthop->gate.ipv6, buf, BUFSIZ));
1599: if (nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME)
1600: vty_out (vty, ", %s", nexthop->ifname);
1601: else if (nexthop->ifindex)
1602: vty_out (vty, ", via %s", ifindex2ifname (nexthop->ifindex));
1603: break;
1604: case NEXTHOP_TYPE_IFINDEX:
1605: vty_out (vty, " directly connected, %s",
1606: ifindex2ifname (nexthop->ifindex));
1607: break;
1608: case NEXTHOP_TYPE_IFNAME:
1609: vty_out (vty, " directly connected, %s",
1610: nexthop->ifname);
1611: break;
1612: default:
1613: break;
1614: }
1615: if (! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
1616: vty_out (vty, " inactive");
1617:
1618: if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
1619: {
1620: vty_out (vty, " (recursive");
1621:
1622: switch (nexthop->rtype)
1623: {
1624: case NEXTHOP_TYPE_IPV6:
1625: case NEXTHOP_TYPE_IPV6_IFINDEX:
1626: case NEXTHOP_TYPE_IPV6_IFNAME:
1627: vty_out (vty, " via %s)",
1628: inet_ntop (AF_INET6, &nexthop->rgate.ipv6,
1629: buf, BUFSIZ));
1630: if (nexthop->rifindex)
1631: vty_out (vty, ", %s", ifindex2ifname (nexthop->rifindex));
1632: break;
1633: case NEXTHOP_TYPE_IFINDEX:
1634: case NEXTHOP_TYPE_IFNAME:
1635: vty_out (vty, " is directly connected, %s)",
1636: ifindex2ifname (nexthop->rifindex));
1637: break;
1638: default:
1639: break;
1640: }
1641: }
1642: vty_out (vty, "%s", VTY_NEWLINE);
1643: }
1644: vty_out (vty, "%s", VTY_NEWLINE);
1645: }
1646: }
1647:
1648: static void
1649: vty_show_ipv6_route (struct vty *vty, struct route_node *rn,
1650: struct rib *rib)
1651: {
1652: struct nexthop *nexthop;
1653: int len = 0;
1654: char buf[BUFSIZ];
1655:
1656: /* Nexthop information. */
1657: for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1658: {
1659: if (nexthop == rib->nexthop)
1660: {
1661: /* Prefix information. */
1662: len = vty_out (vty, "%c%c%c %s/%d",
1663: zebra_route_char (rib->type),
1664: CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED)
1665: ? '>' : ' ',
1666: CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)
1667: ? '*' : ' ',
1668: inet_ntop (AF_INET6, &rn->p.u.prefix6, buf, BUFSIZ),
1669: rn->p.prefixlen);
1670:
1671: /* Distance and metric display. */
1672: if (rib->type != ZEBRA_ROUTE_CONNECT
1673: && rib->type != ZEBRA_ROUTE_KERNEL)
1674: len += vty_out (vty, " [%d/%d]", rib->distance,
1675: rib->metric);
1676: }
1677: else
1678: vty_out (vty, " %c%*c",
1679: CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)
1680: ? '*' : ' ',
1681: len - 3, ' ');
1682:
1683: switch (nexthop->type)
1684: {
1685: case NEXTHOP_TYPE_IPV6:
1686: case NEXTHOP_TYPE_IPV6_IFINDEX:
1687: case NEXTHOP_TYPE_IPV6_IFNAME:
1688: vty_out (vty, " via %s",
1689: inet_ntop (AF_INET6, &nexthop->gate.ipv6, buf, BUFSIZ));
1690: if (nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME)
1691: vty_out (vty, ", %s", nexthop->ifname);
1692: else if (nexthop->ifindex)
1693: vty_out (vty, ", %s", ifindex2ifname (nexthop->ifindex));
1694: break;
1695: case NEXTHOP_TYPE_IFINDEX:
1696: vty_out (vty, " is directly connected, %s",
1697: ifindex2ifname (nexthop->ifindex));
1698: break;
1699: case NEXTHOP_TYPE_IFNAME:
1700: vty_out (vty, " is directly connected, %s",
1701: nexthop->ifname);
1702: break;
1703: default:
1704: break;
1705: }
1706: if (! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
1707: vty_out (vty, " inactive");
1708:
1709: if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
1710: {
1711: vty_out (vty, " (recursive");
1712:
1713: switch (nexthop->rtype)
1714: {
1715: case NEXTHOP_TYPE_IPV6:
1716: case NEXTHOP_TYPE_IPV6_IFINDEX:
1717: case NEXTHOP_TYPE_IPV6_IFNAME:
1718: vty_out (vty, " via %s)",
1719: inet_ntop (AF_INET6, &nexthop->rgate.ipv6,
1720: buf, BUFSIZ));
1721: if (nexthop->rifindex)
1722: vty_out (vty, ", %s", ifindex2ifname (nexthop->rifindex));
1723: break;
1724: case NEXTHOP_TYPE_IFINDEX:
1725: case NEXTHOP_TYPE_IFNAME:
1726: vty_out (vty, " is directly connected, %s)",
1727: ifindex2ifname (nexthop->rifindex));
1728: break;
1729: default:
1730: break;
1731: }
1732: }
1733:
1734: if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_BLACKHOLE))
1735: vty_out (vty, ", bh");
1736: if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_REJECT))
1737: vty_out (vty, ", rej");
1738:
1739: if (rib->type == ZEBRA_ROUTE_RIPNG
1740: || rib->type == ZEBRA_ROUTE_OSPF6
1741: || rib->type == ZEBRA_ROUTE_ISIS
1742: || rib->type == ZEBRA_ROUTE_BGP)
1743: {
1744: time_t uptime;
1745: struct tm *tm;
1746:
1747: uptime = time (NULL);
1748: uptime -= rib->uptime;
1749: tm = gmtime (&uptime);
1750:
1751: #define ONE_DAY_SECOND 60*60*24
1752: #define ONE_WEEK_SECOND 60*60*24*7
1753:
1754: if (uptime < ONE_DAY_SECOND)
1755: vty_out (vty, ", %02d:%02d:%02d",
1756: tm->tm_hour, tm->tm_min, tm->tm_sec);
1757: else if (uptime < ONE_WEEK_SECOND)
1758: vty_out (vty, ", %dd%02dh%02dm",
1759: tm->tm_yday, tm->tm_hour, tm->tm_min);
1760: else
1761: vty_out (vty, ", %02dw%dd%02dh",
1762: tm->tm_yday/7,
1763: tm->tm_yday - ((tm->tm_yday/7) * 7), tm->tm_hour);
1764: }
1765: vty_out (vty, "%s", VTY_NEWLINE);
1766: }
1767: }
1768:
1769: #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"
1770:
1771: DEFUN (show_ipv6_route,
1772: show_ipv6_route_cmd,
1773: "show ipv6 route",
1774: SHOW_STR
1775: IP_STR
1776: "IPv6 routing table\n")
1777: {
1778: struct route_table *table;
1779: struct route_node *rn;
1780: struct rib *rib;
1781: int first = 1;
1782:
1783: table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
1784: if (! table)
1785: return CMD_SUCCESS;
1786:
1787: /* Show all IPv6 route. */
1788: for (rn = route_top (table); rn; rn = route_next (rn))
1789: for (rib = rn->info; rib; rib = rib->next)
1790: {
1791: if (first)
1792: {
1793: vty_out (vty, SHOW_ROUTE_V6_HEADER, VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE);
1794: first = 0;
1795: }
1796: vty_show_ipv6_route (vty, rn, rib);
1797: }
1798: return CMD_SUCCESS;
1799: }
1800:
1801: DEFUN (show_ipv6_route_prefix_longer,
1802: show_ipv6_route_prefix_longer_cmd,
1803: "show ipv6 route X:X::X:X/M longer-prefixes",
1804: SHOW_STR
1805: IP_STR
1806: "IPv6 routing table\n"
1807: "IPv6 prefix\n"
1808: "Show route matching the specified Network/Mask pair only\n")
1809: {
1810: struct route_table *table;
1811: struct route_node *rn;
1812: struct rib *rib;
1813: struct prefix p;
1814: int ret;
1815: int first = 1;
1816:
1817: table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
1818: if (! table)
1819: return CMD_SUCCESS;
1820:
1821: ret = str2prefix (argv[0], &p);
1822: if (! ret)
1823: {
1824: vty_out (vty, "%% Malformed Prefix%s", VTY_NEWLINE);
1825: return CMD_WARNING;
1826: }
1827:
1828: /* Show matched type IPv6 routes. */
1829: for (rn = route_top (table); rn; rn = route_next (rn))
1830: for (rib = rn->info; rib; rib = rib->next)
1831: if (prefix_match (&p, &rn->p))
1832: {
1833: if (first)
1834: {
1835: vty_out (vty, SHOW_ROUTE_V6_HEADER, VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE);
1836: first = 0;
1837: }
1838: vty_show_ipv6_route (vty, rn, rib);
1839: }
1840: return CMD_SUCCESS;
1841: }
1842:
1843: DEFUN (show_ipv6_route_protocol,
1844: show_ipv6_route_protocol_cmd,
1845: "show ipv6 route (bgp|connected|isis|kernel|ospf6|ripng|static)",
1846: SHOW_STR
1847: IP_STR
1848: "IP routing table\n"
1849: "Border Gateway Protocol (BGP)\n"
1850: "Connected\n"
1851: "ISO IS-IS (ISIS)\n"
1852: "Kernel\n"
1853: "Open Shortest Path First (OSPFv3)\n"
1854: "Routing Information Protocol (RIPng)\n"
1855: "Static routes\n")
1856: {
1857: int type;
1858: struct route_table *table;
1859: struct route_node *rn;
1860: struct rib *rib;
1861: int first = 1;
1862:
1863: if (strncmp (argv[0], "b", 1) == 0)
1864: type = ZEBRA_ROUTE_BGP;
1865: else if (strncmp (argv[0], "c", 1) == 0)
1866: type = ZEBRA_ROUTE_CONNECT;
1867: else if (strncmp (argv[0], "k", 1) ==0)
1868: type = ZEBRA_ROUTE_KERNEL;
1869: else if (strncmp (argv[0], "o", 1) == 0)
1870: type = ZEBRA_ROUTE_OSPF6;
1871: else if (strncmp (argv[0], "i", 1) == 0)
1872: type = ZEBRA_ROUTE_ISIS;
1873: else if (strncmp (argv[0], "r", 1) == 0)
1874: type = ZEBRA_ROUTE_RIPNG;
1875: else if (strncmp (argv[0], "s", 1) == 0)
1876: type = ZEBRA_ROUTE_STATIC;
1877: else
1878: {
1879: vty_out (vty, "Unknown route type%s", VTY_NEWLINE);
1880: return CMD_WARNING;
1881: }
1882:
1883: table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
1884: if (! table)
1885: return CMD_SUCCESS;
1886:
1887: /* Show matched type IPv6 routes. */
1888: for (rn = route_top (table); rn; rn = route_next (rn))
1889: for (rib = rn->info; rib; rib = rib->next)
1890: if (rib->type == type)
1891: {
1892: if (first)
1893: {
1894: vty_out (vty, SHOW_ROUTE_V6_HEADER, VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE);
1895: first = 0;
1896: }
1897: vty_show_ipv6_route (vty, rn, rib);
1898: }
1899: return CMD_SUCCESS;
1900: }
1901:
1902: DEFUN (show_ipv6_route_addr,
1903: show_ipv6_route_addr_cmd,
1904: "show ipv6 route X:X::X:X",
1905: SHOW_STR
1906: IP_STR
1907: "IPv6 routing table\n"
1908: "IPv6 Address\n")
1909: {
1910: int ret;
1911: struct prefix_ipv6 p;
1912: struct route_table *table;
1913: struct route_node *rn;
1914:
1915: ret = str2prefix_ipv6 (argv[0], &p);
1916: if (ret <= 0)
1917: {
1918: vty_out (vty, "Malformed IPv6 address%s", VTY_NEWLINE);
1919: return CMD_WARNING;
1920: }
1921:
1922: table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
1923: if (! table)
1924: return CMD_SUCCESS;
1925:
1926: rn = route_node_match (table, (struct prefix *) &p);
1927: if (! rn)
1928: {
1929: vty_out (vty, "%% Network not in table%s", VTY_NEWLINE);
1930: return CMD_WARNING;
1931: }
1932:
1933: vty_show_ipv6_route_detail (vty, rn);
1934:
1935: route_unlock_node (rn);
1936:
1937: return CMD_SUCCESS;
1938: }
1939:
1940: DEFUN (show_ipv6_route_prefix,
1941: show_ipv6_route_prefix_cmd,
1942: "show ipv6 route X:X::X:X/M",
1943: SHOW_STR
1944: IP_STR
1945: "IPv6 routing table\n"
1946: "IPv6 prefix\n")
1947: {
1948: int ret;
1949: struct prefix_ipv6 p;
1950: struct route_table *table;
1951: struct route_node *rn;
1952:
1953: ret = str2prefix_ipv6 (argv[0], &p);
1954: if (ret <= 0)
1955: {
1956: vty_out (vty, "Malformed IPv6 prefix%s", VTY_NEWLINE);
1957: return CMD_WARNING;
1958: }
1959:
1960: table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
1961: if (! table)
1962: return CMD_SUCCESS;
1963:
1964: rn = route_node_match (table, (struct prefix *) &p);
1965: if (! rn || rn->p.prefixlen != p.prefixlen)
1966: {
1967: vty_out (vty, "%% Network not in table%s", VTY_NEWLINE);
1968: return CMD_WARNING;
1969: }
1970:
1971: vty_show_ipv6_route_detail (vty, rn);
1972:
1973: route_unlock_node (rn);
1974:
1975: return CMD_SUCCESS;
1976: }
1977:
1978: /* Show route summary. */
1979: DEFUN (show_ipv6_route_summary,
1980: show_ipv6_route_summary_cmd,
1981: "show ipv6 route summary",
1982: SHOW_STR
1983: IP_STR
1984: "IPv6 routing table\n"
1985: "Summary of all IPv6 routes\n")
1986: {
1987: struct route_table *table;
1988:
1989: table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
1990: if (! table)
1991: return CMD_SUCCESS;
1992:
1993: vty_show_ip_route_summary (vty, table);
1994:
1995: return CMD_SUCCESS;
1996: }
1997:
1998: /* Write IPv6 static route configuration. */
1999: static int
2000: static_config_ipv6 (struct vty *vty)
2001: {
2002: struct route_node *rn;
2003: struct static_ipv6 *si;
2004: int write;
2005: char buf[BUFSIZ];
2006: struct route_table *stable;
2007:
2008: write = 0;
2009:
2010: /* Lookup table. */
2011: stable = vrf_static_table (AFI_IP6, SAFI_UNICAST, 0);
2012: if (! stable)
2013: return -1;
2014:
2015: for (rn = route_top (stable); rn; rn = route_next (rn))
2016: for (si = rn->info; si; si = si->next)
2017: {
2018: vty_out (vty, "ipv6 route %s/%d",
2019: inet_ntop (AF_INET6, &rn->p.u.prefix6, buf, BUFSIZ),
2020: rn->p.prefixlen);
2021:
2022: switch (si->type)
2023: {
2024: case STATIC_IPV6_GATEWAY:
2025: vty_out (vty, " %s", inet_ntop (AF_INET6, &si->ipv6, buf, BUFSIZ));
2026: break;
2027: case STATIC_IPV6_IFNAME:
2028: vty_out (vty, " %s", si->ifname);
2029: break;
2030: case STATIC_IPV6_GATEWAY_IFNAME:
2031: vty_out (vty, " %s %s",
2032: inet_ntop (AF_INET6, &si->ipv6, buf, BUFSIZ), si->ifname);
2033: break;
2034: }
2035:
2036: if (CHECK_FLAG(si->flags, ZEBRA_FLAG_REJECT))
2037: vty_out (vty, " %s", "reject");
2038:
2039: if (CHECK_FLAG(si->flags, ZEBRA_FLAG_BLACKHOLE))
2040: vty_out (vty, " %s", "blackhole");
2041:
2042: if (si->distance != ZEBRA_STATIC_DISTANCE_DEFAULT)
2043: vty_out (vty, " %d", si->distance);
2044: vty_out (vty, "%s", VTY_NEWLINE);
2045:
2046: write = 1;
2047: }
2048: return write;
2049: }
2050: #endif /* HAVE_IPV6 */
2051:
2052: /* Static ip route configuration write function. */
2053: static int
2054: zebra_ip_config (struct vty *vty)
2055: {
2056: int write = 0;
2057:
2058: write += static_config_ipv4 (vty);
2059: #ifdef HAVE_IPV6
2060: write += static_config_ipv6 (vty);
2061: #endif /* HAVE_IPV6 */
2062:
2063: return write;
2064: }
2065:
2066: /* ip protocol configuration write function */
2067: static int config_write_protocol(struct vty *vty)
2068: {
2069: int i;
2070:
2071: for (i=0;i<ZEBRA_ROUTE_MAX;i++)
2072: {
2073: if (proto_rm[AFI_IP][i])
2074: vty_out (vty, "ip protocol %s route-map %s%s", zebra_route_string(i),
2075: proto_rm[AFI_IP][i], VTY_NEWLINE);
2076: }
2077: if (proto_rm[AFI_IP][ZEBRA_ROUTE_MAX])
2078: vty_out (vty, "ip protocol %s route-map %s%s", "any",
2079: proto_rm[AFI_IP][ZEBRA_ROUTE_MAX], VTY_NEWLINE);
2080:
2081: return 1;
2082: }
2083:
2084: /* table node for protocol filtering */
2085: static struct cmd_node protocol_node = { PROTOCOL_NODE, "", 1 };
2086:
2087: /* IP node for static routes. */
2088: static struct cmd_node ip_node = { IP_NODE, "", 1 };
2089:
2090: /* Route VTY. */
2091: void
2092: zebra_vty_init (void)
2093: {
2094: install_node (&ip_node, zebra_ip_config);
2095: install_node (&protocol_node, config_write_protocol);
2096:
2097: install_element (CONFIG_NODE, &ip_protocol_cmd);
2098: install_element (CONFIG_NODE, &no_ip_protocol_cmd);
2099: install_element (VIEW_NODE, &show_ip_protocol_cmd);
2100: install_element (ENABLE_NODE, &show_ip_protocol_cmd);
2101: install_element (CONFIG_NODE, &ip_route_cmd);
2102: install_element (CONFIG_NODE, &ip_route_flags_cmd);
2103: install_element (CONFIG_NODE, &ip_route_flags2_cmd);
2104: install_element (CONFIG_NODE, &ip_route_mask_cmd);
2105: install_element (CONFIG_NODE, &ip_route_mask_flags_cmd);
2106: install_element (CONFIG_NODE, &ip_route_mask_flags2_cmd);
2107: install_element (CONFIG_NODE, &no_ip_route_cmd);
2108: install_element (CONFIG_NODE, &no_ip_route_flags_cmd);
2109: install_element (CONFIG_NODE, &no_ip_route_flags2_cmd);
2110: install_element (CONFIG_NODE, &no_ip_route_mask_cmd);
2111: install_element (CONFIG_NODE, &no_ip_route_mask_flags_cmd);
2112: install_element (CONFIG_NODE, &no_ip_route_mask_flags2_cmd);
2113: install_element (CONFIG_NODE, &ip_route_distance_cmd);
2114: install_element (CONFIG_NODE, &ip_route_flags_distance_cmd);
2115: install_element (CONFIG_NODE, &ip_route_flags_distance2_cmd);
2116: install_element (CONFIG_NODE, &ip_route_mask_distance_cmd);
2117: install_element (CONFIG_NODE, &ip_route_mask_flags_distance_cmd);
2118: install_element (CONFIG_NODE, &ip_route_mask_flags_distance2_cmd);
2119: install_element (CONFIG_NODE, &no_ip_route_distance_cmd);
2120: install_element (CONFIG_NODE, &no_ip_route_flags_distance_cmd);
2121: install_element (CONFIG_NODE, &no_ip_route_flags_distance2_cmd);
2122: install_element (CONFIG_NODE, &no_ip_route_mask_flags_distance_cmd);
2123: install_element (CONFIG_NODE, &no_ip_route_mask_flags_distance2_cmd);
2124:
2125: install_element (VIEW_NODE, &show_ip_route_cmd);
2126: install_element (VIEW_NODE, &show_ip_route_addr_cmd);
2127: install_element (VIEW_NODE, &show_ip_route_prefix_cmd);
2128: install_element (VIEW_NODE, &show_ip_route_prefix_longer_cmd);
2129: install_element (VIEW_NODE, &show_ip_route_protocol_cmd);
2130: install_element (VIEW_NODE, &show_ip_route_supernets_cmd);
2131: install_element (VIEW_NODE, &show_ip_route_summary_cmd);
2132: install_element (ENABLE_NODE, &show_ip_route_cmd);
2133: install_element (ENABLE_NODE, &show_ip_route_addr_cmd);
2134: install_element (ENABLE_NODE, &show_ip_route_prefix_cmd);
2135: install_element (ENABLE_NODE, &show_ip_route_prefix_longer_cmd);
2136: install_element (ENABLE_NODE, &show_ip_route_protocol_cmd);
2137: install_element (ENABLE_NODE, &show_ip_route_supernets_cmd);
2138: install_element (ENABLE_NODE, &show_ip_route_summary_cmd);
2139:
2140: #ifdef HAVE_IPV6
2141: install_element (CONFIG_NODE, &ipv6_route_cmd);
2142: install_element (CONFIG_NODE, &ipv6_route_flags_cmd);
2143: install_element (CONFIG_NODE, &ipv6_route_ifname_cmd);
2144: install_element (CONFIG_NODE, &ipv6_route_ifname_flags_cmd);
2145: install_element (CONFIG_NODE, &no_ipv6_route_cmd);
2146: install_element (CONFIG_NODE, &no_ipv6_route_flags_cmd);
2147: install_element (CONFIG_NODE, &no_ipv6_route_ifname_cmd);
2148: install_element (CONFIG_NODE, &no_ipv6_route_ifname_flags_cmd);
2149: install_element (CONFIG_NODE, &ipv6_route_pref_cmd);
2150: install_element (CONFIG_NODE, &ipv6_route_flags_pref_cmd);
2151: install_element (CONFIG_NODE, &ipv6_route_ifname_pref_cmd);
2152: install_element (CONFIG_NODE, &ipv6_route_ifname_flags_pref_cmd);
2153: install_element (CONFIG_NODE, &no_ipv6_route_pref_cmd);
2154: install_element (CONFIG_NODE, &no_ipv6_route_flags_pref_cmd);
2155: install_element (CONFIG_NODE, &no_ipv6_route_ifname_pref_cmd);
2156: install_element (CONFIG_NODE, &no_ipv6_route_ifname_flags_pref_cmd);
2157: install_element (VIEW_NODE, &show_ipv6_route_cmd);
2158: install_element (VIEW_NODE, &show_ipv6_route_summary_cmd);
2159: install_element (VIEW_NODE, &show_ipv6_route_protocol_cmd);
2160: install_element (VIEW_NODE, &show_ipv6_route_addr_cmd);
2161: install_element (VIEW_NODE, &show_ipv6_route_prefix_cmd);
2162: install_element (VIEW_NODE, &show_ipv6_route_prefix_longer_cmd);
2163: install_element (ENABLE_NODE, &show_ipv6_route_cmd);
2164: install_element (ENABLE_NODE, &show_ipv6_route_protocol_cmd);
2165: install_element (ENABLE_NODE, &show_ipv6_route_addr_cmd);
2166: install_element (ENABLE_NODE, &show_ipv6_route_prefix_cmd);
2167: install_element (ENABLE_NODE, &show_ipv6_route_prefix_longer_cmd);
2168: install_element (ENABLE_NODE, &show_ipv6_route_summary_cmd);
2169: #endif /* HAVE_IPV6 */
2170: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>