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