blob: 78e73669b10007dbe5ce4e3ee185ab1ee1294f78 [file] [log] [blame]
paul718e3742002-12-13 20:15:29 +00001/* 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
Paul Jakma7514fb72007-05-02 16:05:35 +000024#include "memory.h"
paul718e3742002-12-13 20:15:29 +000025#include "if.h"
26#include "prefix.h"
27#include "command.h"
28#include "table.h"
29#include "rib.h"
Feng Lu41f44a22015-05-22 11:39:56 +020030#include "vrf.h"
paul718e3742002-12-13 20:15:29 +000031
paula1ac18c2005-06-28 17:17:12 +000032#include "zebra/zserv.h"
33
Everton Marques33d86db2014-07-14 11:19:00 -030034static int do_show_ip_route(struct vty *vty, safi_t safi);
David Lamparter3b02fe82015-01-22 19:12:35 +010035static void vty_show_ip_route_detail (struct vty *vty, struct route_node *rn,
36 int mcast);
Everton Marques33d86db2014-07-14 11:19:00 -030037
38/* General function for static route. */
paula1ac18c2005-06-28 17:17:12 +000039static int
Everton Marques33d86db2014-07-14 11:19:00 -030040zebra_static_ipv4_safi (struct vty *vty, safi_t safi, int add_cmd,
41 const char *dest_str, const char *mask_str,
42 const char *gate_str, const char *flag_str,
43 const char *distance_str)
paul718e3742002-12-13 20:15:29 +000044{
45 int ret;
46 u_char distance;
47 struct prefix p;
48 struct in_addr gate;
49 struct in_addr mask;
hasso39db97e2004-10-12 20:50:58 +000050 const char *ifname;
hasso81dfcaa2003-05-25 19:21:25 +000051 u_char flag = 0;
paul718e3742002-12-13 20:15:29 +000052
53 ret = str2prefix (dest_str, &p);
54 if (ret <= 0)
55 {
56 vty_out (vty, "%% Malformed address%s", VTY_NEWLINE);
57 return CMD_WARNING;
58 }
59
60 /* Cisco like mask notation. */
61 if (mask_str)
62 {
63 ret = inet_aton (mask_str, &mask);
64 if (ret == 0)
paul595db7f2003-05-25 21:35:06 +000065 {
66 vty_out (vty, "%% Malformed address%s", VTY_NEWLINE);
67 return CMD_WARNING;
68 }
paul718e3742002-12-13 20:15:29 +000069 p.prefixlen = ip_masklen (mask);
70 }
71
72 /* Apply mask for given prefix. */
73 apply_mask (&p);
74
paul595db7f2003-05-25 21:35:06 +000075 /* Administrative distance. */
76 if (distance_str)
77 distance = atoi (distance_str);
78 else
79 distance = ZEBRA_STATIC_DISTANCE_DEFAULT;
80
81 /* Null0 static route. */
hasso457ef552003-05-28 12:02:15 +000082 if ((gate_str != NULL) && (strncasecmp (gate_str, "Null0", strlen (gate_str)) == 0))
paul595db7f2003-05-25 21:35:06 +000083 {
84 if (flag_str)
85 {
86 vty_out (vty, "%% can not have flag %s with Null0%s", flag_str, VTY_NEWLINE);
87 return CMD_WARNING;
88 }
89 if (add_cmd)
Everton Marques33d86db2014-07-14 11:19:00 -030090 static_add_ipv4_safi (safi, &p, NULL, NULL, ZEBRA_FLAG_BLACKHOLE, distance, 0);
paul595db7f2003-05-25 21:35:06 +000091 else
Everton Marques33d86db2014-07-14 11:19:00 -030092 static_delete_ipv4_safi (safi, &p, NULL, NULL, distance, 0);
paul595db7f2003-05-25 21:35:06 +000093 return CMD_SUCCESS;
94 }
95
hasso81dfcaa2003-05-25 19:21:25 +000096 /* Route flags */
97 if (flag_str) {
98 switch(flag_str[0]) {
99 case 'r':
100 case 'R': /* XXX */
101 SET_FLAG (flag, ZEBRA_FLAG_REJECT);
102 break;
103 case 'b':
104 case 'B': /* XXX */
105 SET_FLAG (flag, ZEBRA_FLAG_BLACKHOLE);
106 break;
107 default:
108 vty_out (vty, "%% Malformed flag %s %s", flag_str, VTY_NEWLINE);
paul595db7f2003-05-25 21:35:06 +0000109 return CMD_WARNING;
hasso81dfcaa2003-05-25 19:21:25 +0000110 }
111 }
112
hasso457ef552003-05-28 12:02:15 +0000113 if (gate_str == NULL)
114 {
115 if (add_cmd)
Everton Marques33d86db2014-07-14 11:19:00 -0300116 static_add_ipv4_safi (safi, &p, NULL, NULL, flag, distance, 0);
hasso457ef552003-05-28 12:02:15 +0000117 else
Everton Marques33d86db2014-07-14 11:19:00 -0300118 static_delete_ipv4_safi (safi, &p, NULL, NULL, distance, 0);
hasso457ef552003-05-28 12:02:15 +0000119
120 return CMD_SUCCESS;
121 }
122
paul718e3742002-12-13 20:15:29 +0000123 /* When gateway is A.B.C.D format, gate is treated as nexthop
124 address other case gate is treated as interface name. */
125 ret = inet_aton (gate_str, &gate);
126 if (ret)
127 ifname = NULL;
128 else
129 ifname = gate_str;
130
131 if (add_cmd)
Everton Marques33d86db2014-07-14 11:19:00 -0300132 static_add_ipv4_safi (safi, &p, ifname ? NULL : &gate, ifname, flag, distance, 0);
paul718e3742002-12-13 20:15:29 +0000133 else
Everton Marques33d86db2014-07-14 11:19:00 -0300134 static_delete_ipv4_safi (safi, &p, ifname ? NULL : &gate, ifname, distance, 0);
paul718e3742002-12-13 20:15:29 +0000135
136 return CMD_SUCCESS;
137}
138
Everton Marques33d86db2014-07-14 11:19:00 -0300139static int
140zebra_static_ipv4 (struct vty *vty, int add_cmd, const char *dest_str,
141 const char *mask_str, const char *gate_str,
142 const char *flag_str, const char *distance_str)
143{
144 return zebra_static_ipv4_safi(vty, SAFI_UNICAST, add_cmd, dest_str, mask_str, gate_str, flag_str, distance_str);
145}
146
147/* Static unicast routes for multicast RPF lookup. */
David Lampartera76681b2015-01-22 19:03:53 +0100148DEFUN (ip_mroute_dist,
149 ip_mroute_dist_cmd,
150 "ip mroute A.B.C.D/M (A.B.C.D|INTERFACE) <1-255>",
Everton Marques33d86db2014-07-14 11:19:00 -0300151 IP_STR
152 "Configure static unicast route into MRIB for multicast RPF lookup\n"
153 "IP destination prefix (e.g. 10.0.0.0/8)\n"
154 "Nexthop address\n"
155 "Nexthop interface name\n"
156 "Distance\n")
157{
David Lamparter863f20c2015-01-27 20:24:15 +0100158 VTY_WARN_EXPERIMENTAL();
David Lampartera76681b2015-01-22 19:03:53 +0100159 return zebra_static_ipv4_safi(vty, SAFI_MULTICAST, 1, argv[0], NULL, argv[1],
160 NULL, argc > 2 ? argv[2] : NULL);
Everton Marques33d86db2014-07-14 11:19:00 -0300161}
162
David Lampartera76681b2015-01-22 19:03:53 +0100163ALIAS (ip_mroute_dist,
164 ip_mroute_cmd,
165 "ip mroute A.B.C.D/M (A.B.C.D|INTERFACE)",
166 IP_STR
167 "Configure static unicast route into MRIB for multicast RPF lookup\n"
168 "IP destination prefix (e.g. 10.0.0.0/8)\n"
169 "Nexthop address\n"
170 "Nexthop interface name\n")
171
172DEFUN (no_ip_mroute_dist,
173 no_ip_mroute_dist_cmd,
174 "no ip mroute A.B.C.D/M (A.B.C.D|INTERFACE) <1-255>",
Everton Marques33d86db2014-07-14 11:19:00 -0300175 IP_STR
176 "Configure static unicast route into MRIB for multicast RPF lookup\n"
177 "IP destination prefix (e.g. 10.0.0.0/8)\n"
178 "Nexthop address\n"
179 "Nexthop interface name\n"
180 "Distance\n")
181{
David Lamparter863f20c2015-01-27 20:24:15 +0100182 VTY_WARN_EXPERIMENTAL();
David Lampartera76681b2015-01-22 19:03:53 +0100183 return zebra_static_ipv4_safi(vty, SAFI_MULTICAST, 0, argv[0], NULL, argv[1],
184 NULL, argc > 2 ? argv[2] : NULL);
Everton Marques33d86db2014-07-14 11:19:00 -0300185}
186
David Lampartera76681b2015-01-22 19:03:53 +0100187ALIAS (no_ip_mroute_dist,
188 no_ip_mroute_cmd,
189 "no ip mroute A.B.C.D/M (A.B.C.D|INTERFACE)",
190 NO_STR
191 IP_STR
192 "Configure static unicast route into MRIB for multicast RPF lookup\n"
193 "IP destination prefix (e.g. 10.0.0.0/8)\n"
194 "Nexthop address\n"
195 "Nexthop interface name\n")
196
David Lamparterbd078122015-01-06 19:53:24 +0100197DEFUN (ip_multicast_mode,
198 ip_multicast_mode_cmd,
199 "ip multicast rpf-lookup-mode (urib-only|mrib-only|mrib-then-urib|lower-distance|longer-prefix)",
200 IP_STR
201 "Multicast options\n"
202 "RPF lookup behavior\n"
203 "Lookup in unicast RIB only\n"
204 "Lookup in multicast RIB only\n"
205 "Try multicast RIB first, fall back to unicast RIB\n"
206 "Lookup both, use entry with lower distance\n"
207 "Lookup both, use entry with longer prefix\n")
208{
David Lamparter863f20c2015-01-27 20:24:15 +0100209 VTY_WARN_EXPERIMENTAL();
210
David Lamparterbd078122015-01-06 19:53:24 +0100211 if (!strncmp (argv[0], "u", 1))
212 multicast_mode_ipv4_set (MCAST_URIB_ONLY);
213 else if (!strncmp (argv[0], "mrib-o", 6))
214 multicast_mode_ipv4_set (MCAST_MRIB_ONLY);
215 else if (!strncmp (argv[0], "mrib-t", 6))
216 multicast_mode_ipv4_set (MCAST_MIX_MRIB_FIRST);
217 else if (!strncmp (argv[0], "low", 3))
218 multicast_mode_ipv4_set (MCAST_MIX_DISTANCE);
219 else if (!strncmp (argv[0], "lon", 3))
220 multicast_mode_ipv4_set (MCAST_MIX_PFXLEN);
221 else
222 {
223 vty_out (vty, "Invalid mode specified%s", VTY_NEWLINE);
224 return CMD_WARNING;
225 }
226
227 return CMD_SUCCESS;
228}
229
230DEFUN (no_ip_multicast_mode,
231 no_ip_multicast_mode_cmd,
232 "no ip multicast rpf-lookup-mode (urib-only|mrib-only|mrib-then-urib|lower-distance|longer-prefix)",
233 NO_STR
234 IP_STR
235 "Multicast options\n"
236 "RPF lookup behavior\n"
237 "Lookup in unicast RIB only\n"
238 "Lookup in multicast RIB only\n"
239 "Try multicast RIB first, fall back to unicast RIB\n"
240 "Lookup both, use entry with lower distance\n"
241 "Lookup both, use entry with longer prefix\n")
242{
243 multicast_mode_ipv4_set (MCAST_NO_CONFIG);
244 return CMD_SUCCESS;
245}
246
247ALIAS (no_ip_multicast_mode,
248 no_ip_multicast_mode_noarg_cmd,
249 "no ip multicast rpf-lookup-mode",
250 NO_STR
251 IP_STR
252 "Multicast options\n"
253 "RPF lookup behavior\n")
254
Everton Marques33d86db2014-07-14 11:19:00 -0300255DEFUN (show_ip_rpf,
256 show_ip_rpf_cmd,
257 "show ip rpf",
258 SHOW_STR
259 IP_STR
260 "Display RPF information for multicast source\n")
261{
David Lamparter863f20c2015-01-27 20:24:15 +0100262 VTY_WARN_EXPERIMENTAL();
Everton Marques33d86db2014-07-14 11:19:00 -0300263 return do_show_ip_route(vty, SAFI_MULTICAST);
264}
265
David Lamparter3b02fe82015-01-22 19:12:35 +0100266DEFUN (show_ip_rpf_addr,
267 show_ip_rpf_addr_cmd,
268 "show ip rpf A.B.C.D",
269 SHOW_STR
270 IP_STR
271 "Display RPF information for multicast source\n"
272 "IP multicast source address (e.g. 10.0.0.0)\n")
273{
274 struct in_addr addr;
275 struct route_node *rn;
276 struct rib *rib;
277 int ret;
278
David Lamparter863f20c2015-01-27 20:24:15 +0100279 VTY_WARN_EXPERIMENTAL();
280
David Lamparter3b02fe82015-01-22 19:12:35 +0100281 ret = inet_aton (argv[0], &addr);
282 if (ret == 0)
283 {
284 vty_out (vty, "%% Malformed address%s", VTY_NEWLINE);
285 return CMD_WARNING;
286 }
287
Feng Lu0d0686f2015-05-22 11:40:02 +0200288 rib = rib_match_ipv4_multicast (addr, &rn, VRF_DEFAULT);
David Lamparter3b02fe82015-01-22 19:12:35 +0100289
290 if (rib)
291 vty_show_ip_route_detail (vty, rn, 1);
292 else
293 vty_out (vty, "%% No match for RPF lookup%s", VTY_NEWLINE);
294
295 return CMD_SUCCESS;
296}
297
paul718e3742002-12-13 20:15:29 +0000298/* Static route configuration. */
299DEFUN (ip_route,
300 ip_route_cmd,
paul595db7f2003-05-25 21:35:06 +0000301 "ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0)",
hasso81dfcaa2003-05-25 19:21:25 +0000302 IP_STR
303 "Establish static routes\n"
304 "IP destination prefix (e.g. 10.0.0.0/8)\n"
305 "IP gateway address\n"
paul595db7f2003-05-25 21:35:06 +0000306 "IP gateway interface name\n"
307 "Null interface\n")
hasso81dfcaa2003-05-25 19:21:25 +0000308{
309 return zebra_static_ipv4 (vty, 1, argv[0], NULL, argv[1], NULL, NULL);
310}
311
312DEFUN (ip_route_flags,
313 ip_route_flags_cmd,
314 "ip route A.B.C.D/M (A.B.C.D|INTERFACE) (reject|blackhole)",
paul718e3742002-12-13 20:15:29 +0000315 IP_STR
316 "Establish static routes\n"
317 "IP destination prefix (e.g. 10.0.0.0/8)\n"
318 "IP gateway address\n"
319 "IP gateway interface name\n"
hasso81dfcaa2003-05-25 19:21:25 +0000320 "Emit an ICMP unreachable when matched\n"
321 "Silently discard pkts when matched\n")
paul718e3742002-12-13 20:15:29 +0000322{
hasso81dfcaa2003-05-25 19:21:25 +0000323 return zebra_static_ipv4 (vty, 1, argv[0], NULL, argv[1], argv[2], NULL);
paul718e3742002-12-13 20:15:29 +0000324}
325
hasso457ef552003-05-28 12:02:15 +0000326DEFUN (ip_route_flags2,
327 ip_route_flags2_cmd,
328 "ip route A.B.C.D/M (reject|blackhole)",
329 IP_STR
330 "Establish static routes\n"
331 "IP destination prefix (e.g. 10.0.0.0/8)\n"
332 "Emit an ICMP unreachable when matched\n"
333 "Silently discard pkts when matched\n")
334{
335 return zebra_static_ipv4 (vty, 1, argv[0], NULL, NULL, argv[1], NULL);
336}
337
paul718e3742002-12-13 20:15:29 +0000338/* Mask as A.B.C.D format. */
339DEFUN (ip_route_mask,
340 ip_route_mask_cmd,
paul595db7f2003-05-25 21:35:06 +0000341 "ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0)",
hasso81dfcaa2003-05-25 19:21:25 +0000342 IP_STR
343 "Establish static routes\n"
344 "IP destination prefix\n"
345 "IP destination prefix mask\n"
346 "IP gateway address\n"
paul595db7f2003-05-25 21:35:06 +0000347 "IP gateway interface name\n"
348 "Null interface\n")
hasso81dfcaa2003-05-25 19:21:25 +0000349{
350 return zebra_static_ipv4 (vty, 1, argv[0], argv[1], argv[2], NULL, NULL);
351}
352
353DEFUN (ip_route_mask_flags,
354 ip_route_mask_flags_cmd,
355 "ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE) (reject|blackhole)",
paul718e3742002-12-13 20:15:29 +0000356 IP_STR
357 "Establish static routes\n"
358 "IP destination prefix\n"
359 "IP destination prefix mask\n"
360 "IP gateway address\n"
361 "IP gateway interface name\n"
hasso81dfcaa2003-05-25 19:21:25 +0000362 "Emit an ICMP unreachable when matched\n"
363 "Silently discard pkts when matched\n")
paul718e3742002-12-13 20:15:29 +0000364{
hasso81dfcaa2003-05-25 19:21:25 +0000365 return zebra_static_ipv4 (vty, 1, argv[0], argv[1], argv[2], argv[3], NULL);
paul718e3742002-12-13 20:15:29 +0000366}
367
hasso457ef552003-05-28 12:02:15 +0000368DEFUN (ip_route_mask_flags2,
369 ip_route_mask_flags2_cmd,
370 "ip route A.B.C.D A.B.C.D (reject|blackhole)",
371 IP_STR
372 "Establish static routes\n"
373 "IP destination prefix\n"
374 "IP destination prefix mask\n"
375 "Emit an ICMP unreachable when matched\n"
376 "Silently discard pkts when matched\n")
377{
378 return zebra_static_ipv4 (vty, 1, argv[0], argv[1], NULL, argv[2], NULL);
379}
380
paul718e3742002-12-13 20:15:29 +0000381/* Distance option value. */
382DEFUN (ip_route_distance,
383 ip_route_distance_cmd,
paul595db7f2003-05-25 21:35:06 +0000384 "ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0) <1-255>",
paul718e3742002-12-13 20:15:29 +0000385 IP_STR
386 "Establish static routes\n"
387 "IP destination prefix (e.g. 10.0.0.0/8)\n"
388 "IP gateway address\n"
389 "IP gateway interface name\n"
paul595db7f2003-05-25 21:35:06 +0000390 "Null interface\n"
paul718e3742002-12-13 20:15:29 +0000391 "Distance value for this route\n")
392{
hasso81dfcaa2003-05-25 19:21:25 +0000393 return zebra_static_ipv4 (vty, 1, argv[0], NULL, argv[1], NULL, argv[2]);
394}
395
396DEFUN (ip_route_flags_distance,
397 ip_route_flags_distance_cmd,
398 "ip route A.B.C.D/M (A.B.C.D|INTERFACE) (reject|blackhole) <1-255>",
399 IP_STR
400 "Establish static routes\n"
401 "IP destination prefix (e.g. 10.0.0.0/8)\n"
402 "IP gateway address\n"
403 "IP gateway interface name\n"
404 "Emit an ICMP unreachable when matched\n"
405 "Silently discard pkts when matched\n"
406 "Distance value for this route\n")
407{
408 return zebra_static_ipv4 (vty, 1, argv[0], NULL, argv[1], argv[2], argv[3]);
paul718e3742002-12-13 20:15:29 +0000409}
410
hasso457ef552003-05-28 12:02:15 +0000411DEFUN (ip_route_flags_distance2,
412 ip_route_flags_distance2_cmd,
413 "ip route A.B.C.D/M (reject|blackhole) <1-255>",
414 IP_STR
415 "Establish static routes\n"
416 "IP destination prefix (e.g. 10.0.0.0/8)\n"
417 "Emit an ICMP unreachable when matched\n"
418 "Silently discard pkts when matched\n"
419 "Distance value for this route\n")
420{
421 return zebra_static_ipv4 (vty, 1, argv[0], NULL, NULL, argv[1], argv[2]);
422}
423
paul718e3742002-12-13 20:15:29 +0000424DEFUN (ip_route_mask_distance,
425 ip_route_mask_distance_cmd,
paul595db7f2003-05-25 21:35:06 +0000426 "ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0) <1-255>",
paul718e3742002-12-13 20:15:29 +0000427 IP_STR
428 "Establish static routes\n"
429 "IP destination prefix\n"
430 "IP destination prefix mask\n"
431 "IP gateway address\n"
432 "IP gateway interface name\n"
paul595db7f2003-05-25 21:35:06 +0000433 "Null interface\n"
paul718e3742002-12-13 20:15:29 +0000434 "Distance value for this route\n")
435{
hasso81dfcaa2003-05-25 19:21:25 +0000436 return zebra_static_ipv4 (vty, 1, argv[0], argv[1], argv[2], NULL, argv[3]);
437}
438
439DEFUN (ip_route_mask_flags_distance,
440 ip_route_mask_flags_distance_cmd,
441 "ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE) (reject|blackhole) <1-255>",
442 IP_STR
443 "Establish static routes\n"
444 "IP destination prefix\n"
445 "IP destination prefix mask\n"
446 "IP gateway address\n"
447 "IP gateway interface name\n"
hasso81dfcaa2003-05-25 19:21:25 +0000448 "Emit an ICMP unreachable when matched\n"
Christian Franke2b005152013-09-30 12:27:49 +0000449 "Silently discard pkts when matched\n"
450 "Distance value for this route\n")
hasso81dfcaa2003-05-25 19:21:25 +0000451{
452 return zebra_static_ipv4 (vty, 1, argv[0], argv[1], argv[2], argv[3], argv[4]);
paul718e3742002-12-13 20:15:29 +0000453}
454
hasso457ef552003-05-28 12:02:15 +0000455DEFUN (ip_route_mask_flags_distance2,
456 ip_route_mask_flags_distance2_cmd,
457 "ip route A.B.C.D A.B.C.D (reject|blackhole) <1-255>",
458 IP_STR
459 "Establish static routes\n"
460 "IP destination prefix\n"
461 "IP destination prefix mask\n"
hasso457ef552003-05-28 12:02:15 +0000462 "Emit an ICMP unreachable when matched\n"
Christian Franke2b005152013-09-30 12:27:49 +0000463 "Silently discard pkts when matched\n"
464 "Distance value for this route\n")
hasso457ef552003-05-28 12:02:15 +0000465{
466 return zebra_static_ipv4 (vty, 1, argv[0], argv[1], NULL, argv[2], argv[3]);
467}
468
paul718e3742002-12-13 20:15:29 +0000469DEFUN (no_ip_route,
470 no_ip_route_cmd,
paul595db7f2003-05-25 21:35:06 +0000471 "no ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0)",
hasso81dfcaa2003-05-25 19:21:25 +0000472 NO_STR
473 IP_STR
474 "Establish static routes\n"
475 "IP destination prefix (e.g. 10.0.0.0/8)\n"
476 "IP gateway address\n"
paul595db7f2003-05-25 21:35:06 +0000477 "IP gateway interface name\n"
478 "Null interface\n")
hasso81dfcaa2003-05-25 19:21:25 +0000479{
480 return zebra_static_ipv4 (vty, 0, argv[0], NULL, argv[1], NULL, NULL);
481}
482
483ALIAS (no_ip_route,
484 no_ip_route_flags_cmd,
485 "no ip route A.B.C.D/M (A.B.C.D|INTERFACE) (reject|blackhole)",
paul718e3742002-12-13 20:15:29 +0000486 NO_STR
487 IP_STR
488 "Establish static routes\n"
489 "IP destination prefix (e.g. 10.0.0.0/8)\n"
490 "IP gateway address\n"
491 "IP gateway interface name\n"
hasso81dfcaa2003-05-25 19:21:25 +0000492 "Emit an ICMP unreachable when matched\n"
493 "Silently discard pkts when matched\n")
paul718e3742002-12-13 20:15:29 +0000494
hasso457ef552003-05-28 12:02:15 +0000495DEFUN (no_ip_route_flags2,
496 no_ip_route_flags2_cmd,
497 "no ip route A.B.C.D/M (reject|blackhole)",
498 NO_STR
499 IP_STR
500 "Establish static routes\n"
501 "IP destination prefix (e.g. 10.0.0.0/8)\n"
502 "Emit an ICMP unreachable when matched\n"
503 "Silently discard pkts when matched\n")
504{
505 return zebra_static_ipv4 (vty, 0, argv[0], NULL, NULL, NULL, NULL);
506}
507
paul718e3742002-12-13 20:15:29 +0000508DEFUN (no_ip_route_mask,
509 no_ip_route_mask_cmd,
paul595db7f2003-05-25 21:35:06 +0000510 "no ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0)",
hasso81dfcaa2003-05-25 19:21:25 +0000511 NO_STR
512 IP_STR
513 "Establish static routes\n"
514 "IP destination prefix\n"
515 "IP destination prefix mask\n"
516 "IP gateway address\n"
paul595db7f2003-05-25 21:35:06 +0000517 "IP gateway interface name\n"
518 "Null interface\n")
hasso81dfcaa2003-05-25 19:21:25 +0000519{
520 return zebra_static_ipv4 (vty, 0, argv[0], argv[1], argv[2], NULL, NULL);
521}
522
523ALIAS (no_ip_route_mask,
524 no_ip_route_mask_flags_cmd,
525 "no ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE) (reject|blackhole)",
paul718e3742002-12-13 20:15:29 +0000526 NO_STR
527 IP_STR
528 "Establish static routes\n"
529 "IP destination prefix\n"
530 "IP destination prefix mask\n"
531 "IP gateway address\n"
532 "IP gateway interface name\n"
hasso81dfcaa2003-05-25 19:21:25 +0000533 "Emit an ICMP unreachable when matched\n"
534 "Silently discard pkts when matched\n")
paul718e3742002-12-13 20:15:29 +0000535
hasso457ef552003-05-28 12:02:15 +0000536DEFUN (no_ip_route_mask_flags2,
537 no_ip_route_mask_flags2_cmd,
538 "no ip route A.B.C.D A.B.C.D (reject|blackhole)",
539 NO_STR
540 IP_STR
541 "Establish static routes\n"
542 "IP destination prefix\n"
543 "IP destination prefix mask\n"
544 "Emit an ICMP unreachable when matched\n"
545 "Silently discard pkts when matched\n")
546{
547 return zebra_static_ipv4 (vty, 0, argv[0], argv[1], NULL, NULL, NULL);
548}
549
paul718e3742002-12-13 20:15:29 +0000550DEFUN (no_ip_route_distance,
551 no_ip_route_distance_cmd,
paul595db7f2003-05-25 21:35:06 +0000552 "no ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0) <1-255>",
paul718e3742002-12-13 20:15:29 +0000553 NO_STR
554 IP_STR
555 "Establish static routes\n"
556 "IP destination prefix (e.g. 10.0.0.0/8)\n"
557 "IP gateway address\n"
558 "IP gateway interface name\n"
paul595db7f2003-05-25 21:35:06 +0000559 "Null interface\n"
paul718e3742002-12-13 20:15:29 +0000560 "Distance value for this route\n")
561{
hasso81dfcaa2003-05-25 19:21:25 +0000562 return zebra_static_ipv4 (vty, 0, argv[0], NULL, argv[1], NULL, argv[2]);
563}
564
565DEFUN (no_ip_route_flags_distance,
566 no_ip_route_flags_distance_cmd,
567 "no ip route A.B.C.D/M (A.B.C.D|INTERFACE) (reject|blackhole) <1-255>",
568 NO_STR
569 IP_STR
570 "Establish static routes\n"
571 "IP destination prefix (e.g. 10.0.0.0/8)\n"
572 "IP gateway address\n"
573 "IP gateway interface name\n"
574 "Emit an ICMP unreachable when matched\n"
575 "Silently discard pkts when matched\n"
576 "Distance value for this route\n")
577{
578 return zebra_static_ipv4 (vty, 0, argv[0], NULL, argv[1], argv[2], argv[3]);
paul718e3742002-12-13 20:15:29 +0000579}
580
hasso457ef552003-05-28 12:02:15 +0000581DEFUN (no_ip_route_flags_distance2,
582 no_ip_route_flags_distance2_cmd,
583 "no ip route A.B.C.D/M (reject|blackhole) <1-255>",
584 NO_STR
585 IP_STR
586 "Establish static routes\n"
587 "IP destination prefix (e.g. 10.0.0.0/8)\n"
588 "Emit an ICMP unreachable when matched\n"
589 "Silently discard pkts when matched\n"
590 "Distance value for this route\n")
591{
592 return zebra_static_ipv4 (vty, 0, argv[0], NULL, NULL, argv[1], argv[2]);
593}
594
paul718e3742002-12-13 20:15:29 +0000595DEFUN (no_ip_route_mask_distance,
596 no_ip_route_mask_distance_cmd,
paul595db7f2003-05-25 21:35:06 +0000597 "no ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0) <1-255>",
paul718e3742002-12-13 20:15:29 +0000598 NO_STR
599 IP_STR
600 "Establish static routes\n"
601 "IP destination prefix\n"
602 "IP destination prefix mask\n"
603 "IP gateway address\n"
604 "IP gateway interface name\n"
paul595db7f2003-05-25 21:35:06 +0000605 "Null interface\n"
paul718e3742002-12-13 20:15:29 +0000606 "Distance value for this route\n")
607{
hasso81dfcaa2003-05-25 19:21:25 +0000608 return zebra_static_ipv4 (vty, 0, argv[0], argv[1], argv[2], NULL, argv[3]);
609}
610
611DEFUN (no_ip_route_mask_flags_distance,
612 no_ip_route_mask_flags_distance_cmd,
613 "no ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE) (reject|blackhole) <1-255>",
614 NO_STR
615 IP_STR
616 "Establish static routes\n"
617 "IP destination prefix\n"
618 "IP destination prefix mask\n"
619 "IP gateway address\n"
620 "IP gateway interface name\n"
621 "Emit an ICMP unreachable when matched\n"
622 "Silently discard pkts when matched\n"
623 "Distance value for this route\n")
624{
625 return zebra_static_ipv4 (vty, 0, argv[0], argv[1], argv[2], argv[3], argv[4]);
paul718e3742002-12-13 20:15:29 +0000626}
627
hasso457ef552003-05-28 12:02:15 +0000628DEFUN (no_ip_route_mask_flags_distance2,
629 no_ip_route_mask_flags_distance2_cmd,
630 "no ip route A.B.C.D A.B.C.D (reject|blackhole) <1-255>",
631 NO_STR
632 IP_STR
633 "Establish static routes\n"
634 "IP destination prefix\n"
635 "IP destination prefix mask\n"
636 "Emit an ICMP unreachable when matched\n"
637 "Silently discard pkts when matched\n"
638 "Distance value for this route\n")
639{
640 return zebra_static_ipv4 (vty, 0, argv[0], argv[1], NULL, argv[2], argv[3]);
641}
642
Paul Jakma7514fb72007-05-02 16:05:35 +0000643char *proto_rm[AFI_MAX][ZEBRA_ROUTE_MAX+1]; /* "any" == ZEBRA_ROUTE_MAX */
644
645DEFUN (ip_protocol,
646 ip_protocol_cmd,
647 "ip protocol PROTO route-map ROUTE-MAP",
648 NO_STR
649 "Apply route map to PROTO\n"
650 "Protocol name\n"
651 "Route map name\n")
652{
653 int i;
654
655 if (strcasecmp(argv[0], "any") == 0)
656 i = ZEBRA_ROUTE_MAX;
657 else
658 i = proto_name2num(argv[0]);
659 if (i < 0)
660 {
661 vty_out (vty, "invalid protocol name \"%s\"%s", argv[0] ? argv[0] : "",
662 VTY_NEWLINE);
663 return CMD_WARNING;
664 }
665 if (proto_rm[AFI_IP][i])
666 XFREE (MTYPE_ROUTE_MAP_NAME, proto_rm[AFI_IP][i]);
667 proto_rm[AFI_IP][i] = XSTRDUP (MTYPE_ROUTE_MAP_NAME, argv[1]);
668 return CMD_SUCCESS;
669}
670
671DEFUN (no_ip_protocol,
672 no_ip_protocol_cmd,
673 "no ip protocol PROTO",
674 NO_STR
675 "Remove route map from PROTO\n"
676 "Protocol name\n")
677{
678 int i;
679
680 if (strcasecmp(argv[0], "any") == 0)
681 i = ZEBRA_ROUTE_MAX;
682 else
683 i = proto_name2num(argv[0]);
684 if (i < 0)
685 {
686 vty_out (vty, "invalid protocol name \"%s\"%s", argv[0] ? argv[0] : "",
687 VTY_NEWLINE);
688 return CMD_WARNING;
689 }
690 if (proto_rm[AFI_IP][i])
691 XFREE (MTYPE_ROUTE_MAP_NAME, proto_rm[AFI_IP][i]);
692 proto_rm[AFI_IP][i] = NULL;
693 return CMD_SUCCESS;
694}
695
paul718e3742002-12-13 20:15:29 +0000696/* New RIB. Detailed information for IPv4 route. */
paula1ac18c2005-06-28 17:17:12 +0000697static void
David Lamparter3b02fe82015-01-22 19:12:35 +0100698vty_show_ip_route_detail (struct vty *vty, struct route_node *rn, int mcast)
paul718e3742002-12-13 20:15:29 +0000699{
700 struct rib *rib;
Christian Frankefa713d92013-07-05 15:35:37 +0000701 struct nexthop *nexthop, *tnexthop;
702 int recursing;
Timo Teräs53a5c392015-05-23 11:08:40 +0300703 char buf[PREFIX_STRLEN];
paul718e3742002-12-13 20:15:29 +0000704
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +0000705 RNODE_FOREACH_RIB (rn, rib)
paul718e3742002-12-13 20:15:29 +0000706 {
David Lamparterb7cce952015-03-07 08:40:48 +0100707 const char *mcast_info = "";
David Lamparter3b02fe82015-01-22 19:12:35 +0100708 if (mcast)
709 {
710 rib_table_info_t *info = rn->table->info;
711 mcast_info = (info->safi == SAFI_MULTICAST)
712 ? " using Multicast RIB"
713 : " using Unicast RIB";
714 }
Timo Teräs53a5c392015-05-23 11:08:40 +0300715 vty_out (vty, "Routing entry for %s%s%s",
716 prefix2str (&rn->p, buf, sizeof(buf)), mcast_info,
717 VTY_NEWLINE);
ajsf52d13c2005-10-01 17:38:06 +0000718 vty_out (vty, " Known via \"%s\"", zebra_route_string (rib->type));
Jorge Boncompte [DTI2]ddc943d2012-04-13 13:46:07 +0200719 vty_out (vty, ", distance %u, metric %u", rib->distance, rib->metric);
paul718e3742002-12-13 20:15:29 +0000720 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
Timo Teräs53a5c392015-05-23 11:08:40 +0300721 vty_out (vty, ", best");
paul718e3742002-12-13 20:15:29 +0000722 if (rib->refcnt)
Timo Teräs53a5c392015-05-23 11:08:40 +0300723 vty_out (vty, ", refcnt %ld", rib->refcnt);
hasso81dfcaa2003-05-25 19:21:25 +0000724 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_BLACKHOLE))
725 vty_out (vty, ", blackhole");
726 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_REJECT))
727 vty_out (vty, ", reject");
paul718e3742002-12-13 20:15:29 +0000728 vty_out (vty, "%s", VTY_NEWLINE);
729
730#define ONE_DAY_SECOND 60*60*24
731#define ONE_WEEK_SECOND 60*60*24*7
732 if (rib->type == ZEBRA_ROUTE_RIP
Timo Teräs53a5c392015-05-23 11:08:40 +0300733 || rib->type == ZEBRA_ROUTE_RIPNG
734 || rib->type == ZEBRA_ROUTE_OSPF
735 || rib->type == ZEBRA_ROUTE_OSPF6
736 || rib->type == ZEBRA_ROUTE_BABEL
737 || rib->type == ZEBRA_ROUTE_ISIS
738 || rib->type == ZEBRA_ROUTE_BGP)
paul718e3742002-12-13 20:15:29 +0000739 {
740 time_t uptime;
741 struct tm *tm;
742
743 uptime = time (NULL);
744 uptime -= rib->uptime;
745 tm = gmtime (&uptime);
746
747 vty_out (vty, " Last update ");
748
749 if (uptime < ONE_DAY_SECOND)
750 vty_out (vty, "%02d:%02d:%02d",
751 tm->tm_hour, tm->tm_min, tm->tm_sec);
752 else if (uptime < ONE_WEEK_SECOND)
753 vty_out (vty, "%dd%02dh%02dm",
754 tm->tm_yday, tm->tm_hour, tm->tm_min);
755 else
756 vty_out (vty, "%02dw%dd%02dh",
757 tm->tm_yday/7,
758 tm->tm_yday - ((tm->tm_yday/7) * 7), tm->tm_hour);
759 vty_out (vty, " ago%s", VTY_NEWLINE);
760 }
761
Christian Frankefa713d92013-07-05 15:35:37 +0000762 for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
Timo Teräs53a5c392015-05-23 11:08:40 +0300763 {
764 vty_out (vty, " %c%s",
765 CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB) ? '*' : ' ',
766 recursing ? " " : "");
Paul Jakma7514fb72007-05-02 16:05:35 +0000767
Timo Teräs53a5c392015-05-23 11:08:40 +0300768 switch (nexthop->type)
769 {
770 case NEXTHOP_TYPE_IPV4:
771 case NEXTHOP_TYPE_IPV4_IFINDEX:
772 vty_out (vty, " %s", inet_ntoa (nexthop->gate.ipv4));
773 if (nexthop->ifindex)
Feng Lu0d0686f2015-05-22 11:40:02 +0200774 vty_out (vty, ", via %s",
775 ifindex2ifname_vrf (nexthop->ifindex, rib->vrf_id));
Timo Teräs53a5c392015-05-23 11:08:40 +0300776 break;
777 case NEXTHOP_TYPE_IPV6:
778 case NEXTHOP_TYPE_IPV6_IFINDEX:
779 case NEXTHOP_TYPE_IPV6_IFNAME:
780 vty_out (vty, " %s",
781 inet_ntop (AF_INET6, &nexthop->gate.ipv6, buf, sizeof(buf)));
782 if (nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME)
783 vty_out (vty, ", %s", nexthop->ifname);
784 else if (nexthop->ifindex)
Feng Lu0d0686f2015-05-22 11:40:02 +0200785 vty_out (vty, ", via %s",
786 ifindex2ifname_vrf (nexthop->ifindex, rib->vrf_id));
Timo Teräs53a5c392015-05-23 11:08:40 +0300787 break;
788 case NEXTHOP_TYPE_IFINDEX:
789 vty_out (vty, " directly connected, %s",
Feng Lu0d0686f2015-05-22 11:40:02 +0200790 ifindex2ifname_vrf (nexthop->ifindex, rib->vrf_id));
Timo Teräs53a5c392015-05-23 11:08:40 +0300791 break;
792 case NEXTHOP_TYPE_IFNAME:
793 vty_out (vty, " directly connected, %s", nexthop->ifname);
794 break;
795 case NEXTHOP_TYPE_BLACKHOLE:
796 vty_out (vty, " directly connected, Null0");
797 break;
798 default:
799 break;
800 }
801 if (! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
802 vty_out (vty, " inactive");
paul718e3742002-12-13 20:15:29 +0000803
Timo Teräs53a5c392015-05-23 11:08:40 +0300804 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ONLINK))
805 vty_out (vty, " onlink");
paul718e3742002-12-13 20:15:29 +0000806
Timo Teräs53a5c392015-05-23 11:08:40 +0300807 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
808 vty_out (vty, " (recursive)");
Christian Frankee8d3d292013-07-05 15:35:39 +0000809
Timo Teräs53a5c392015-05-23 11:08:40 +0300810 switch (nexthop->type)
Paul Jakma7514fb72007-05-02 16:05:35 +0000811 {
812 case NEXTHOP_TYPE_IPV4:
813 case NEXTHOP_TYPE_IPV4_IFINDEX:
814 case NEXTHOP_TYPE_IPV4_IFNAME:
815 if (nexthop->src.ipv4.s_addr)
816 {
Timo Teräs53a5c392015-05-23 11:08:40 +0300817 if (inet_ntop(AF_INET, &nexthop->src.ipv4, buf, sizeof buf))
818 vty_out (vty, ", src %s", buf);
Paul Jakma7514fb72007-05-02 16:05:35 +0000819 }
820 break;
Andrew J. Schorr09303312007-05-30 20:10:34 +0000821#ifdef HAVE_IPV6
Paul Jakma7514fb72007-05-02 16:05:35 +0000822 case NEXTHOP_TYPE_IPV6:
823 case NEXTHOP_TYPE_IPV6_IFINDEX:
824 case NEXTHOP_TYPE_IPV6_IFNAME:
825 if (!IPV6_ADDR_SAME(&nexthop->src.ipv6, &in6addr_any))
826 {
Timo Teräs53a5c392015-05-23 11:08:40 +0300827 if (inet_ntop(AF_INET6, &nexthop->src.ipv6, buf, sizeof buf))
828 vty_out (vty, ", src %s", buf);
Paul Jakma7514fb72007-05-02 16:05:35 +0000829 }
830 break;
Andrew J. Schorr09303312007-05-30 20:10:34 +0000831#endif /* HAVE_IPV6 */
Paul Jakma7514fb72007-05-02 16:05:35 +0000832 default:
Timo Teräs53a5c392015-05-23 11:08:40 +0300833 break;
Paul Jakma7514fb72007-05-02 16:05:35 +0000834 }
Timo Teräs53a5c392015-05-23 11:08:40 +0300835 vty_out (vty, "%s", VTY_NEWLINE);
836 }
paul718e3742002-12-13 20:15:29 +0000837 vty_out (vty, "%s", VTY_NEWLINE);
838 }
839}
840
paula1ac18c2005-06-28 17:17:12 +0000841static void
paul718e3742002-12-13 20:15:29 +0000842vty_show_ip_route (struct vty *vty, struct route_node *rn, struct rib *rib)
843{
Christian Frankefa713d92013-07-05 15:35:37 +0000844 struct nexthop *nexthop, *tnexthop;
845 int recursing;
paul718e3742002-12-13 20:15:29 +0000846 int len = 0;
847 char buf[BUFSIZ];
848
849 /* Nexthop information. */
Christian Frankefa713d92013-07-05 15:35:37 +0000850 for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
paul718e3742002-12-13 20:15:29 +0000851 {
852 if (nexthop == rib->nexthop)
853 {
854 /* Prefix information. */
Timo Teräs53a5c392015-05-23 11:08:40 +0300855 len = vty_out (vty, "%c%c%c %s",
ajsf52d13c2005-10-01 17:38:06 +0000856 zebra_route_char (rib->type),
paul718e3742002-12-13 20:15:29 +0000857 CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED)
858 ? '>' : ' ',
859 CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)
860 ? '*' : ' ',
Timo Teräs53a5c392015-05-23 11:08:40 +0300861 prefix2str (&rn->p, buf, sizeof buf));
paul718e3742002-12-13 20:15:29 +0000862
863 /* Distance and metric display. */
864 if (rib->type != ZEBRA_ROUTE_CONNECT
865 && rib->type != ZEBRA_ROUTE_KERNEL)
866 len += vty_out (vty, " [%d/%d]", rib->distance,
867 rib->metric);
868 }
869 else
870 vty_out (vty, " %c%*c",
871 CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)
872 ? '*' : ' ',
Christian Frankefa713d92013-07-05 15:35:37 +0000873 len - 3 + (2 * recursing), ' ');
paul718e3742002-12-13 20:15:29 +0000874
875 switch (nexthop->type)
Timo Teräs53a5c392015-05-23 11:08:40 +0300876 {
877 case NEXTHOP_TYPE_IPV4:
878 case NEXTHOP_TYPE_IPV4_IFINDEX:
879 vty_out (vty, " via %s", inet_ntoa (nexthop->gate.ipv4));
880 if (nexthop->ifindex)
Feng Lu0d0686f2015-05-22 11:40:02 +0200881 vty_out (vty, ", %s",
882 ifindex2ifname_vrf (nexthop->ifindex, rib->vrf_id));
Timo Teräs53a5c392015-05-23 11:08:40 +0300883 break;
884 case NEXTHOP_TYPE_IPV6:
885 case NEXTHOP_TYPE_IPV6_IFINDEX:
886 case NEXTHOP_TYPE_IPV6_IFNAME:
887 vty_out (vty, " via %s",
888 inet_ntop (AF_INET6, &nexthop->gate.ipv6, buf, BUFSIZ));
889 if (nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME)
890 vty_out (vty, ", %s", nexthop->ifname);
891 else if (nexthop->ifindex)
Feng Lu0d0686f2015-05-22 11:40:02 +0200892 vty_out (vty, ", %s",
893 ifindex2ifname_vrf (nexthop->ifindex, rib->vrf_id));
Timo Teräs53a5c392015-05-23 11:08:40 +0300894 break;
895 case NEXTHOP_TYPE_IFINDEX:
896 vty_out (vty, " is directly connected, %s",
Feng Lu0d0686f2015-05-22 11:40:02 +0200897 ifindex2ifname_vrf (nexthop->ifindex, rib->vrf_id));
Timo Teräs53a5c392015-05-23 11:08:40 +0300898 break;
899 case NEXTHOP_TYPE_IFNAME:
900 vty_out (vty, " is directly connected, %s", nexthop->ifname);
901 break;
902 case NEXTHOP_TYPE_BLACKHOLE:
903 vty_out (vty, " is directly connected, Null0");
904 break;
905 default:
906 break;
907 }
paul718e3742002-12-13 20:15:29 +0000908 if (! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
Timo Teräs53a5c392015-05-23 11:08:40 +0300909 vty_out (vty, " inactive");
paul718e3742002-12-13 20:15:29 +0000910
Christian Frankee8d3d292013-07-05 15:35:39 +0000911 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ONLINK))
Timo Teräs53a5c392015-05-23 11:08:40 +0300912 vty_out (vty, " onlink");
Christian Frankee8d3d292013-07-05 15:35:39 +0000913
paul718e3742002-12-13 20:15:29 +0000914 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
Timo Teräs53a5c392015-05-23 11:08:40 +0300915 vty_out (vty, " (recursive)");
Christian Frankefa713d92013-07-05 15:35:37 +0000916
Paul Jakma7514fb72007-05-02 16:05:35 +0000917 switch (nexthop->type)
918 {
919 case NEXTHOP_TYPE_IPV4:
920 case NEXTHOP_TYPE_IPV4_IFINDEX:
921 case NEXTHOP_TYPE_IPV4_IFNAME:
922 if (nexthop->src.ipv4.s_addr)
923 {
Timo Teräs53a5c392015-05-23 11:08:40 +0300924 if (inet_ntop(AF_INET, &nexthop->src.ipv4, buf, sizeof buf))
Paul Jakma7514fb72007-05-02 16:05:35 +0000925 vty_out (vty, ", src %s", buf);
926 }
927 break;
Andrew J. Schorr09303312007-05-30 20:10:34 +0000928#ifdef HAVE_IPV6
Paul Jakma7514fb72007-05-02 16:05:35 +0000929 case NEXTHOP_TYPE_IPV6:
930 case NEXTHOP_TYPE_IPV6_IFINDEX:
931 case NEXTHOP_TYPE_IPV6_IFNAME:
932 if (!IPV6_ADDR_SAME(&nexthop->src.ipv6, &in6addr_any))
933 {
Timo Teräs53a5c392015-05-23 11:08:40 +0300934 if (inet_ntop(AF_INET6, &nexthop->src.ipv6, buf, sizeof buf))
Paul Jakma7514fb72007-05-02 16:05:35 +0000935 vty_out (vty, ", src %s", buf);
936 }
937 break;
Andrew J. Schorr09303312007-05-30 20:10:34 +0000938#endif /* HAVE_IPV6 */
Paul Jakma7514fb72007-05-02 16:05:35 +0000939 default:
Timo Teräs53a5c392015-05-23 11:08:40 +0300940 break;
Paul Jakma7514fb72007-05-02 16:05:35 +0000941 }
paul718e3742002-12-13 20:15:29 +0000942
hasso81dfcaa2003-05-25 19:21:25 +0000943 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_BLACKHOLE))
944 vty_out (vty, ", bh");
945 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_REJECT))
946 vty_out (vty, ", rej");
947
paul718e3742002-12-13 20:15:29 +0000948 if (rib->type == ZEBRA_ROUTE_RIP
Timo Teräs53a5c392015-05-23 11:08:40 +0300949 || rib->type == ZEBRA_ROUTE_RIPNG
950 || rib->type == ZEBRA_ROUTE_OSPF
951 || rib->type == ZEBRA_ROUTE_OSPF6
952 || rib->type == ZEBRA_ROUTE_BABEL
953 || rib->type == ZEBRA_ROUTE_ISIS
954 || rib->type == ZEBRA_ROUTE_BGP)
paul718e3742002-12-13 20:15:29 +0000955 {
956 time_t uptime;
957 struct tm *tm;
958
959 uptime = time (NULL);
960 uptime -= rib->uptime;
961 tm = gmtime (&uptime);
962
963#define ONE_DAY_SECOND 60*60*24
964#define ONE_WEEK_SECOND 60*60*24*7
965
966 if (uptime < ONE_DAY_SECOND)
967 vty_out (vty, ", %02d:%02d:%02d",
968 tm->tm_hour, tm->tm_min, tm->tm_sec);
969 else if (uptime < ONE_WEEK_SECOND)
970 vty_out (vty, ", %dd%02dh%02dm",
971 tm->tm_yday, tm->tm_hour, tm->tm_min);
972 else
973 vty_out (vty, ", %02dw%dd%02dh",
974 tm->tm_yday/7,
975 tm->tm_yday - ((tm->tm_yday/7) * 7), tm->tm_hour);
976 }
977 vty_out (vty, "%s", VTY_NEWLINE);
978 }
979}
980
paul718e3742002-12-13 20:15:29 +0000981DEFUN (show_ip_route,
982 show_ip_route_cmd,
983 "show ip route",
984 SHOW_STR
985 IP_STR
986 "IP routing table\n")
987{
Everton Marques33d86db2014-07-14 11:19:00 -0300988 return do_show_ip_route(vty, SAFI_UNICAST);
989}
990
991static int do_show_ip_route(struct vty *vty, safi_t safi) {
paul718e3742002-12-13 20:15:29 +0000992 struct route_table *table;
993 struct route_node *rn;
994 struct rib *rib;
995 int first = 1;
996
Feng Lu41f44a22015-05-22 11:39:56 +0200997 table = zebra_vrf_table (AFI_IP, safi, VRF_DEFAULT);
paul718e3742002-12-13 20:15:29 +0000998 if (! table)
999 return CMD_SUCCESS;
1000
1001 /* Show all IPv4 routes. */
1002 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001003 RNODE_FOREACH_RIB (rn, rib)
paul718e3742002-12-13 20:15:29 +00001004 {
1005 if (first)
1006 {
David Lampartere0ca5fd2009-09-16 01:52:42 +02001007 vty_out (vty, SHOW_ROUTE_V4_HEADER);
paul718e3742002-12-13 20:15:29 +00001008 first = 0;
1009 }
1010 vty_show_ip_route (vty, rn, rib);
1011 }
1012 return CMD_SUCCESS;
1013}
1014
1015DEFUN (show_ip_route_prefix_longer,
1016 show_ip_route_prefix_longer_cmd,
1017 "show ip route A.B.C.D/M longer-prefixes",
1018 SHOW_STR
1019 IP_STR
1020 "IP routing table\n"
1021 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1022 "Show route matching the specified Network/Mask pair only\n")
1023{
1024 struct route_table *table;
1025 struct route_node *rn;
1026 struct rib *rib;
1027 struct prefix p;
1028 int ret;
1029 int first = 1;
1030
1031 ret = str2prefix (argv[0], &p);
1032 if (! ret)
1033 {
1034 vty_out (vty, "%% Malformed Prefix%s", VTY_NEWLINE);
1035 return CMD_WARNING;
1036 }
1037
Feng Lu41f44a22015-05-22 11:39:56 +02001038 table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, VRF_DEFAULT);
paul718e3742002-12-13 20:15:29 +00001039 if (! table)
1040 return CMD_SUCCESS;
1041
1042 /* Show matched type IPv4 routes. */
1043 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001044 RNODE_FOREACH_RIB (rn, rib)
paul718e3742002-12-13 20:15:29 +00001045 if (prefix_match (&p, &rn->p))
1046 {
1047 if (first)
1048 {
David Lampartere0ca5fd2009-09-16 01:52:42 +02001049 vty_out (vty, SHOW_ROUTE_V4_HEADER);
paul718e3742002-12-13 20:15:29 +00001050 first = 0;
1051 }
1052 vty_show_ip_route (vty, rn, rib);
1053 }
1054 return CMD_SUCCESS;
1055}
1056
1057DEFUN (show_ip_route_supernets,
1058 show_ip_route_supernets_cmd,
1059 "show ip route supernets-only",
1060 SHOW_STR
1061 IP_STR
1062 "IP routing table\n"
1063 "Show supernet entries only\n")
1064{
1065 struct route_table *table;
1066 struct route_node *rn;
1067 struct rib *rib;
1068 u_int32_t addr;
1069 int first = 1;
1070
Feng Lu41f44a22015-05-22 11:39:56 +02001071 table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, VRF_DEFAULT);
paul718e3742002-12-13 20:15:29 +00001072 if (! table)
1073 return CMD_SUCCESS;
1074
1075 /* Show matched type IPv4 routes. */
1076 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001077 RNODE_FOREACH_RIB (rn, rib)
paul718e3742002-12-13 20:15:29 +00001078 {
1079 addr = ntohl (rn->p.u.prefix4.s_addr);
1080
1081 if ((IN_CLASSC (addr) && rn->p.prefixlen < 24)
1082 || (IN_CLASSB (addr) && rn->p.prefixlen < 16)
1083 || (IN_CLASSA (addr) && rn->p.prefixlen < 8))
1084 {
1085 if (first)
1086 {
David Lampartere0ca5fd2009-09-16 01:52:42 +02001087 vty_out (vty, SHOW_ROUTE_V4_HEADER);
paul718e3742002-12-13 20:15:29 +00001088 first = 0;
1089 }
1090 vty_show_ip_route (vty, rn, rib);
1091 }
1092 }
1093 return CMD_SUCCESS;
1094}
1095
1096DEFUN (show_ip_route_protocol,
1097 show_ip_route_protocol_cmd,
David Lampartere0ca5fd2009-09-16 01:52:42 +02001098 "show ip route " QUAGGA_IP_REDIST_STR_ZEBRA,
paul718e3742002-12-13 20:15:29 +00001099 SHOW_STR
1100 IP_STR
1101 "IP routing table\n"
David Lampartere0ca5fd2009-09-16 01:52:42 +02001102 QUAGGA_IP_REDIST_HELP_STR_ZEBRA)
paul718e3742002-12-13 20:15:29 +00001103{
1104 int type;
1105 struct route_table *table;
1106 struct route_node *rn;
1107 struct rib *rib;
1108 int first = 1;
1109
David Lampartere0ca5fd2009-09-16 01:52:42 +02001110 type = proto_redistnum (AFI_IP, argv[0]);
1111 if (type < 0)
paul718e3742002-12-13 20:15:29 +00001112 {
1113 vty_out (vty, "Unknown route type%s", VTY_NEWLINE);
1114 return CMD_WARNING;
1115 }
1116
Feng Lu41f44a22015-05-22 11:39:56 +02001117 table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, VRF_DEFAULT);
paul718e3742002-12-13 20:15:29 +00001118 if (! table)
1119 return CMD_SUCCESS;
1120
1121 /* Show matched type IPv4 routes. */
1122 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001123 RNODE_FOREACH_RIB (rn, rib)
paul718e3742002-12-13 20:15:29 +00001124 if (rib->type == type)
1125 {
1126 if (first)
1127 {
David Lampartere0ca5fd2009-09-16 01:52:42 +02001128 vty_out (vty, SHOW_ROUTE_V4_HEADER);
paul718e3742002-12-13 20:15:29 +00001129 first = 0;
1130 }
1131 vty_show_ip_route (vty, rn, rib);
1132 }
1133 return CMD_SUCCESS;
1134}
1135
1136DEFUN (show_ip_route_addr,
1137 show_ip_route_addr_cmd,
1138 "show ip route A.B.C.D",
1139 SHOW_STR
1140 IP_STR
1141 "IP routing table\n"
1142 "Network in the IP routing table to display\n")
1143{
1144 int ret;
1145 struct prefix_ipv4 p;
1146 struct route_table *table;
1147 struct route_node *rn;
1148
1149 ret = str2prefix_ipv4 (argv[0], &p);
1150 if (ret <= 0)
1151 {
1152 vty_out (vty, "%% Malformed IPv4 address%s", VTY_NEWLINE);
1153 return CMD_WARNING;
1154 }
1155
Feng Lu41f44a22015-05-22 11:39:56 +02001156 table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, VRF_DEFAULT);
paul718e3742002-12-13 20:15:29 +00001157 if (! table)
1158 return CMD_SUCCESS;
1159
1160 rn = route_node_match (table, (struct prefix *) &p);
1161 if (! rn)
1162 {
1163 vty_out (vty, "%% Network not in table%s", VTY_NEWLINE);
1164 return CMD_WARNING;
1165 }
1166
David Lamparter3b02fe82015-01-22 19:12:35 +01001167 vty_show_ip_route_detail (vty, rn, 0);
paul718e3742002-12-13 20:15:29 +00001168
1169 route_unlock_node (rn);
1170
1171 return CMD_SUCCESS;
1172}
1173
1174DEFUN (show_ip_route_prefix,
1175 show_ip_route_prefix_cmd,
1176 "show ip route A.B.C.D/M",
1177 SHOW_STR
1178 IP_STR
1179 "IP routing table\n"
1180 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n")
1181{
1182 int ret;
1183 struct prefix_ipv4 p;
1184 struct route_table *table;
1185 struct route_node *rn;
1186
1187 ret = str2prefix_ipv4 (argv[0], &p);
1188 if (ret <= 0)
1189 {
1190 vty_out (vty, "%% Malformed IPv4 address%s", VTY_NEWLINE);
1191 return CMD_WARNING;
1192 }
1193
Feng Lu41f44a22015-05-22 11:39:56 +02001194 table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, VRF_DEFAULT);
paul718e3742002-12-13 20:15:29 +00001195 if (! table)
1196 return CMD_SUCCESS;
1197
1198 rn = route_node_match (table, (struct prefix *) &p);
1199 if (! rn || rn->p.prefixlen != p.prefixlen)
1200 {
1201 vty_out (vty, "%% Network not in table%s", VTY_NEWLINE);
Lu Feng969d3552014-10-21 06:24:07 +00001202 if (rn)
1203 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00001204 return CMD_WARNING;
1205 }
1206
David Lamparter3b02fe82015-01-22 19:12:35 +01001207 vty_show_ip_route_detail (vty, rn, 0);
paul718e3742002-12-13 20:15:29 +00001208
1209 route_unlock_node (rn);
1210
1211 return CMD_SUCCESS;
1212}
1213
paula1ac18c2005-06-28 17:17:12 +00001214static void
Stig Thormodsrud61691c92008-11-04 15:45:07 -08001215vty_show_ip_route_summary (struct vty *vty, struct route_table *table)
paul718e3742002-12-13 20:15:29 +00001216{
Stig Thormodsrud61691c92008-11-04 15:45:07 -08001217 struct route_node *rn;
1218 struct rib *rib;
1219 struct nexthop *nexthop;
1220#define ZEBRA_ROUTE_IBGP ZEBRA_ROUTE_MAX
1221#define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1)
1222 u_int32_t rib_cnt[ZEBRA_ROUTE_TOTAL + 1];
1223 u_int32_t fib_cnt[ZEBRA_ROUTE_TOTAL + 1];
1224 u_int32_t i;
paul718e3742002-12-13 20:15:29 +00001225
Stig Thormodsrud61691c92008-11-04 15:45:07 -08001226 memset (&rib_cnt, 0, sizeof(rib_cnt));
1227 memset (&fib_cnt, 0, sizeof(fib_cnt));
1228 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001229 RNODE_FOREACH_RIB (rn, rib)
Stig Thormodsrud61691c92008-11-04 15:45:07 -08001230 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1231 {
1232 rib_cnt[ZEBRA_ROUTE_TOTAL]++;
1233 rib_cnt[rib->type]++;
Christian Frankefa713d92013-07-05 15:35:37 +00001234 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)
1235 || nexthop_has_fib_child(nexthop))
Stig Thormodsrud61691c92008-11-04 15:45:07 -08001236 {
1237 fib_cnt[ZEBRA_ROUTE_TOTAL]++;
1238 fib_cnt[rib->type]++;
1239 }
1240 if (rib->type == ZEBRA_ROUTE_BGP &&
1241 CHECK_FLAG (rib->flags, ZEBRA_FLAG_IBGP))
1242 {
1243 rib_cnt[ZEBRA_ROUTE_IBGP]++;
Christian Frankefa713d92013-07-05 15:35:37 +00001244 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)
1245 || nexthop_has_fib_child(nexthop))
Stig Thormodsrud61691c92008-11-04 15:45:07 -08001246 fib_cnt[ZEBRA_ROUTE_IBGP]++;
1247 }
1248 }
paul718e3742002-12-13 20:15:29 +00001249
Stig Thormodsrud61691c92008-11-04 15:45:07 -08001250 vty_out (vty, "%-20s %-20s %-20s %s",
1251 "Route Source", "Routes", "FIB", VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00001252
Stig Thormodsrud61691c92008-11-04 15:45:07 -08001253 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
1254 {
1255 if (rib_cnt[i] > 0)
1256 {
1257 if (i == ZEBRA_ROUTE_BGP)
1258 {
1259 vty_out (vty, "%-20s %-20d %-20d %s", "ebgp",
1260 rib_cnt[ZEBRA_ROUTE_BGP] - rib_cnt[ZEBRA_ROUTE_IBGP],
1261 fib_cnt[ZEBRA_ROUTE_BGP] - fib_cnt[ZEBRA_ROUTE_IBGP],
1262 VTY_NEWLINE);
1263 vty_out (vty, "%-20s %-20d %-20d %s", "ibgp",
1264 rib_cnt[ZEBRA_ROUTE_IBGP], fib_cnt[ZEBRA_ROUTE_IBGP],
1265 VTY_NEWLINE);
1266 }
1267 else
1268 vty_out (vty, "%-20s %-20d %-20d %s", zebra_route_string(i),
1269 rib_cnt[i], fib_cnt[i], VTY_NEWLINE);
1270 }
1271 }
paul718e3742002-12-13 20:15:29 +00001272
Stig Thormodsrud61691c92008-11-04 15:45:07 -08001273 vty_out (vty, "------%s", VTY_NEWLINE);
1274 vty_out (vty, "%-20s %-20d %-20d %s", "Totals", rib_cnt[ZEBRA_ROUTE_TOTAL],
1275 fib_cnt[ZEBRA_ROUTE_TOTAL], VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00001276}
1277
Dinesh G Dutt56a5f772014-09-30 12:58:04 -07001278/*
1279 * Implementation of the ip route summary prefix command.
1280 *
1281 * This command prints the primary prefixes that have been installed by various
1282 * protocols on the box.
1283 *
1284 */
1285static void
1286vty_show_ip_route_summary_prefix (struct vty *vty, struct route_table *table)
1287{
1288 struct route_node *rn;
1289 struct rib *rib;
1290 struct nexthop *nexthop;
1291#define ZEBRA_ROUTE_IBGP ZEBRA_ROUTE_MAX
1292#define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1)
1293 u_int32_t rib_cnt[ZEBRA_ROUTE_TOTAL + 1];
1294 u_int32_t fib_cnt[ZEBRA_ROUTE_TOTAL + 1];
1295 u_int32_t i;
1296 int cnt;
1297
1298 memset (&rib_cnt, 0, sizeof(rib_cnt));
1299 memset (&fib_cnt, 0, sizeof(fib_cnt));
1300 for (rn = route_top (table); rn; rn = route_next (rn))
1301 RNODE_FOREACH_RIB (rn, rib)
1302 {
1303
1304 /*
1305 * In case of ECMP, count only once.
1306 */
1307 cnt = 0;
1308 for (nexthop = rib->nexthop; (!cnt && nexthop); nexthop = nexthop->next)
1309 {
1310 cnt++;
1311 rib_cnt[ZEBRA_ROUTE_TOTAL]++;
1312 rib_cnt[rib->type]++;
1313 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
1314 {
1315 fib_cnt[ZEBRA_ROUTE_TOTAL]++;
1316 fib_cnt[rib->type]++;
1317 }
1318 if (rib->type == ZEBRA_ROUTE_BGP &&
1319 CHECK_FLAG (rib->flags, ZEBRA_FLAG_IBGP))
1320 {
1321 rib_cnt[ZEBRA_ROUTE_IBGP]++;
1322 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
1323 fib_cnt[ZEBRA_ROUTE_IBGP]++;
1324 }
1325 }
1326 }
1327
1328 vty_out (vty, "%-20s %-20s %-20s %s",
1329 "Route Source", "Prefix Routes", "FIB", VTY_NEWLINE);
1330
1331 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
1332 {
1333 if (rib_cnt[i] > 0)
1334 {
1335 if (i == ZEBRA_ROUTE_BGP)
1336 {
1337 vty_out (vty, "%-20s %-20d %-20d %s", "ebgp",
1338 rib_cnt[ZEBRA_ROUTE_BGP] - rib_cnt[ZEBRA_ROUTE_IBGP],
1339 fib_cnt[ZEBRA_ROUTE_BGP] - fib_cnt[ZEBRA_ROUTE_IBGP],
1340 VTY_NEWLINE);
1341 vty_out (vty, "%-20s %-20d %-20d %s", "ibgp",
1342 rib_cnt[ZEBRA_ROUTE_IBGP], fib_cnt[ZEBRA_ROUTE_IBGP],
1343 VTY_NEWLINE);
1344 }
1345 else
1346 vty_out (vty, "%-20s %-20d %-20d %s", zebra_route_string(i),
1347 rib_cnt[i], fib_cnt[i], VTY_NEWLINE);
1348 }
1349 }
1350
1351 vty_out (vty, "------%s", VTY_NEWLINE);
1352 vty_out (vty, "%-20s %-20d %-20d %s", "Totals", rib_cnt[ZEBRA_ROUTE_TOTAL],
1353 fib_cnt[ZEBRA_ROUTE_TOTAL], VTY_NEWLINE);
1354}
1355
paul718e3742002-12-13 20:15:29 +00001356/* Show route summary. */
1357DEFUN (show_ip_route_summary,
1358 show_ip_route_summary_cmd,
1359 "show ip route summary",
1360 SHOW_STR
1361 IP_STR
1362 "IP routing table\n"
1363 "Summary of all routes\n")
1364{
Stig Thormodsrud61691c92008-11-04 15:45:07 -08001365 struct route_table *table;
paul718e3742002-12-13 20:15:29 +00001366
Feng Lu41f44a22015-05-22 11:39:56 +02001367 table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, VRF_DEFAULT);
Stig Thormodsrud61691c92008-11-04 15:45:07 -08001368 if (! table)
1369 return CMD_SUCCESS;
paul718e3742002-12-13 20:15:29 +00001370
Stig Thormodsrud61691c92008-11-04 15:45:07 -08001371 vty_show_ip_route_summary (vty, table);
paul718e3742002-12-13 20:15:29 +00001372
1373 return CMD_SUCCESS;
1374}
1375
Dinesh G Dutt56a5f772014-09-30 12:58:04 -07001376/* Show route summary prefix. */
1377DEFUN (show_ip_route_summary_prefix,
1378 show_ip_route_summary_prefix_cmd,
1379 "show ip route summary prefix",
1380 SHOW_STR
1381 IP_STR
1382 "IP routing table\n"
1383 "Summary of all routes\n"
1384 "Prefix routes\n")
1385{
1386 struct route_table *table;
1387
Feng Lu41f44a22015-05-22 11:39:56 +02001388 table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, VRF_DEFAULT);
Dinesh G Dutt56a5f772014-09-30 12:58:04 -07001389 if (! table)
1390 return CMD_SUCCESS;
1391
1392 vty_show_ip_route_summary_prefix (vty, table);
1393
1394 return CMD_SUCCESS;
1395}
1396
paul718e3742002-12-13 20:15:29 +00001397/* Write IPv4 static route configuration. */
paula1ac18c2005-06-28 17:17:12 +00001398static int
Everton Marques33d86db2014-07-14 11:19:00 -03001399static_config_ipv4 (struct vty *vty, safi_t safi, const char *cmd)
paul718e3742002-12-13 20:15:29 +00001400{
1401 struct route_node *rn;
1402 struct static_ipv4 *si;
1403 struct route_table *stable;
Timo Teräs53a5c392015-05-23 11:08:40 +03001404 char buf[PREFIX_STRLEN];
paul718e3742002-12-13 20:15:29 +00001405 int write;
1406
1407 write = 0;
1408
1409 /* Lookup table. */
Feng Lu41f44a22015-05-22 11:39:56 +02001410 stable = zebra_vrf_static_table (AFI_IP, safi, VRF_DEFAULT);
paul718e3742002-12-13 20:15:29 +00001411 if (! stable)
1412 return -1;
1413
1414 for (rn = route_top (stable); rn; rn = route_next (rn))
1415 for (si = rn->info; si; si = si->next)
1416 {
Timo Teräs53a5c392015-05-23 11:08:40 +03001417 vty_out (vty, "%s %s", cmd, prefix2str (&rn->p, buf, sizeof buf));
paul718e3742002-12-13 20:15:29 +00001418
paul7021c422003-07-15 12:52:22 +00001419 switch (si->type)
1420 {
1421 case STATIC_IPV4_GATEWAY:
1422 vty_out (vty, " %s", inet_ntoa (si->gate.ipv4));
1423 break;
1424 case STATIC_IPV4_IFNAME:
1425 vty_out (vty, " %s", si->gate.ifname);
1426 break;
1427 case STATIC_IPV4_BLACKHOLE:
1428 vty_out (vty, " Null0");
1429 break;
1430 }
1431
1432 /* flags are incompatible with STATIC_IPV4_BLACKHOLE */
1433 if (si->type != STATIC_IPV4_BLACKHOLE)
1434 {
1435 if (CHECK_FLAG(si->flags, ZEBRA_FLAG_REJECT))
1436 vty_out (vty, " %s", "reject");
paul718e3742002-12-13 20:15:29 +00001437
paul7021c422003-07-15 12:52:22 +00001438 if (CHECK_FLAG(si->flags, ZEBRA_FLAG_BLACKHOLE))
1439 vty_out (vty, " %s", "blackhole");
1440 }
hasso81dfcaa2003-05-25 19:21:25 +00001441
paul7021c422003-07-15 12:52:22 +00001442 if (si->distance != ZEBRA_STATIC_DISTANCE_DEFAULT)
1443 vty_out (vty, " %d", si->distance);
hasso81dfcaa2003-05-25 19:21:25 +00001444
paul7021c422003-07-15 12:52:22 +00001445 vty_out (vty, "%s", VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00001446
paul7021c422003-07-15 12:52:22 +00001447 write = 1;
paul718e3742002-12-13 20:15:29 +00001448 }
1449 return write;
1450}
Andrew J. Schorr09303312007-05-30 20:10:34 +00001451
1452DEFUN (show_ip_protocol,
1453 show_ip_protocol_cmd,
1454 "show ip protocol",
1455 SHOW_STR
1456 IP_STR
1457 "IP protocol filtering status\n")
1458{
1459 int i;
1460
1461 vty_out(vty, "Protocol : route-map %s", VTY_NEWLINE);
1462 vty_out(vty, "------------------------%s", VTY_NEWLINE);
1463 for (i=0;i<ZEBRA_ROUTE_MAX;i++)
1464 {
1465 if (proto_rm[AFI_IP][i])
1466 vty_out (vty, "%-10s : %-10s%s", zebra_route_string(i),
1467 proto_rm[AFI_IP][i],
1468 VTY_NEWLINE);
1469 else
1470 vty_out (vty, "%-10s : none%s", zebra_route_string(i), VTY_NEWLINE);
1471 }
1472 if (proto_rm[AFI_IP][i])
1473 vty_out (vty, "%-10s : %-10s%s", "any", proto_rm[AFI_IP][i],
1474 VTY_NEWLINE);
1475 else
1476 vty_out (vty, "%-10s : none%s", "any", VTY_NEWLINE);
1477
1478 return CMD_SUCCESS;
1479}
1480
Joachim Nilsson36735ed2012-05-09 13:38:36 +02001481/*
1482 * Show IP mroute command to dump the BGP Multicast
1483 * routing table
1484 */
1485DEFUN (show_ip_mroute,
1486 show_ip_mroute_cmd,
1487 "show ip mroute",
1488 SHOW_STR
1489 IP_STR
1490 "IP Multicast routing table\n")
1491{
1492 struct route_table *table;
1493 struct route_node *rn;
1494 struct rib *rib;
1495 int first = 1;
1496
Feng Lu41f44a22015-05-22 11:39:56 +02001497 table = zebra_vrf_table (AFI_IP, SAFI_MULTICAST, VRF_DEFAULT);
Joachim Nilsson36735ed2012-05-09 13:38:36 +02001498 if (! table)
1499 return CMD_SUCCESS;
1500
1501 /* Show all IPv4 routes. */
1502 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001503 RNODE_FOREACH_RIB (rn, rib)
Joachim Nilsson36735ed2012-05-09 13:38:36 +02001504 {
1505 if (first)
1506 {
1507 vty_out (vty, SHOW_ROUTE_V4_HEADER);
1508 first = 0;
1509 }
1510 vty_show_ip_route (vty, rn, rib);
1511 }
1512 return CMD_SUCCESS;
1513}
1514
David Lamparter6b0655a2014-06-04 06:53:35 +02001515
paul718e3742002-12-13 20:15:29 +00001516#ifdef HAVE_IPV6
1517/* General fucntion for IPv6 static route. */
paula1ac18c2005-06-28 17:17:12 +00001518static int
hasso39db97e2004-10-12 20:50:58 +00001519static_ipv6_func (struct vty *vty, int add_cmd, const char *dest_str,
1520 const char *gate_str, const char *ifname,
1521 const char *flag_str, const char *distance_str)
paul718e3742002-12-13 20:15:29 +00001522{
1523 int ret;
1524 u_char distance;
1525 struct prefix p;
1526 struct in6_addr *gate = NULL;
1527 struct in6_addr gate_addr;
1528 u_char type = 0;
1529 int table = 0;
hasso81dfcaa2003-05-25 19:21:25 +00001530 u_char flag = 0;
paul718e3742002-12-13 20:15:29 +00001531
1532 ret = str2prefix (dest_str, &p);
1533 if (ret <= 0)
1534 {
1535 vty_out (vty, "%% Malformed address%s", VTY_NEWLINE);
1536 return CMD_WARNING;
1537 }
1538
1539 /* Apply mask for given prefix. */
1540 apply_mask (&p);
1541
hasso81dfcaa2003-05-25 19:21:25 +00001542 /* Route flags */
1543 if (flag_str) {
1544 switch(flag_str[0]) {
1545 case 'r':
1546 case 'R': /* XXX */
1547 SET_FLAG (flag, ZEBRA_FLAG_REJECT);
1548 break;
1549 case 'b':
1550 case 'B': /* XXX */
1551 SET_FLAG (flag, ZEBRA_FLAG_BLACKHOLE);
1552 break;
1553 default:
1554 vty_out (vty, "%% Malformed flag %s %s", flag_str, VTY_NEWLINE);
paul595db7f2003-05-25 21:35:06 +00001555 return CMD_WARNING;
hasso81dfcaa2003-05-25 19:21:25 +00001556 }
1557 }
1558
paul718e3742002-12-13 20:15:29 +00001559 /* Administrative distance. */
1560 if (distance_str)
1561 distance = atoi (distance_str);
1562 else
1563 distance = ZEBRA_STATIC_DISTANCE_DEFAULT;
1564
1565 /* When gateway is valid IPv6 addrees, then gate is treated as
1566 nexthop address other case gate is treated as interface name. */
1567 ret = inet_pton (AF_INET6, gate_str, &gate_addr);
1568
1569 if (ifname)
1570 {
1571 /* When ifname is specified. It must be come with gateway
1572 address. */
1573 if (ret != 1)
1574 {
1575 vty_out (vty, "%% Malformed address%s", VTY_NEWLINE);
1576 return CMD_WARNING;
1577 }
1578 type = STATIC_IPV6_GATEWAY_IFNAME;
1579 gate = &gate_addr;
1580 }
1581 else
1582 {
1583 if (ret == 1)
1584 {
1585 type = STATIC_IPV6_GATEWAY;
1586 gate = &gate_addr;
1587 }
1588 else
1589 {
1590 type = STATIC_IPV6_IFNAME;
1591 ifname = gate_str;
1592 }
1593 }
1594
1595 if (add_cmd)
hasso81dfcaa2003-05-25 19:21:25 +00001596 static_add_ipv6 (&p, type, gate, ifname, flag, distance, table);
paul718e3742002-12-13 20:15:29 +00001597 else
1598 static_delete_ipv6 (&p, type, gate, ifname, distance, table);
1599
1600 return CMD_SUCCESS;
1601}
1602
1603DEFUN (ipv6_route,
1604 ipv6_route_cmd,
1605 "ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE)",
1606 IP_STR
1607 "Establish static routes\n"
1608 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1609 "IPv6 gateway address\n"
1610 "IPv6 gateway interface name\n")
1611{
hasso81dfcaa2003-05-25 19:21:25 +00001612 return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, NULL, NULL);
1613}
1614
1615DEFUN (ipv6_route_flags,
1616 ipv6_route_flags_cmd,
1617 "ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) (reject|blackhole)",
1618 IP_STR
1619 "Establish static routes\n"
1620 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1621 "IPv6 gateway address\n"
1622 "IPv6 gateway interface name\n"
1623 "Emit an ICMP unreachable when matched\n"
1624 "Silently discard pkts when matched\n")
1625{
1626 return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, argv[2], NULL);
paul718e3742002-12-13 20:15:29 +00001627}
1628
1629DEFUN (ipv6_route_ifname,
1630 ipv6_route_ifname_cmd,
1631 "ipv6 route X:X::X:X/M X:X::X:X INTERFACE",
1632 IP_STR
1633 "Establish static routes\n"
1634 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1635 "IPv6 gateway address\n"
1636 "IPv6 gateway interface name\n")
1637{
hasso81dfcaa2003-05-25 19:21:25 +00001638 return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], NULL, NULL);
1639}
1640
1641DEFUN (ipv6_route_ifname_flags,
1642 ipv6_route_ifname_flags_cmd,
1643 "ipv6 route X:X::X:X/M X:X::X:X INTERFACE (reject|blackhole)",
1644 IP_STR
1645 "Establish static routes\n"
1646 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1647 "IPv6 gateway address\n"
1648 "IPv6 gateway interface name\n"
1649 "Emit an ICMP unreachable when matched\n"
1650 "Silently discard pkts when matched\n")
1651{
1652 return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], argv[3], NULL);
paul718e3742002-12-13 20:15:29 +00001653}
1654
1655DEFUN (ipv6_route_pref,
1656 ipv6_route_pref_cmd,
1657 "ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) <1-255>",
1658 IP_STR
1659 "Establish static routes\n"
1660 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1661 "IPv6 gateway address\n"
1662 "IPv6 gateway interface name\n"
1663 "Distance value for this prefix\n")
1664{
hasso81dfcaa2003-05-25 19:21:25 +00001665 return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, NULL, argv[2]);
1666}
1667
1668DEFUN (ipv6_route_flags_pref,
1669 ipv6_route_flags_pref_cmd,
1670 "ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) (reject|blackhole) <1-255>",
1671 IP_STR
1672 "Establish static routes\n"
1673 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1674 "IPv6 gateway address\n"
1675 "IPv6 gateway interface name\n"
1676 "Emit an ICMP unreachable when matched\n"
1677 "Silently discard pkts when matched\n"
1678 "Distance value for this prefix\n")
1679{
1680 return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, argv[2], argv[3]);
paul718e3742002-12-13 20:15:29 +00001681}
1682
1683DEFUN (ipv6_route_ifname_pref,
1684 ipv6_route_ifname_pref_cmd,
1685 "ipv6 route X:X::X:X/M X:X::X:X INTERFACE <1-255>",
1686 IP_STR
1687 "Establish static routes\n"
1688 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1689 "IPv6 gateway address\n"
1690 "IPv6 gateway interface name\n"
1691 "Distance value for this prefix\n")
1692{
hasso81dfcaa2003-05-25 19:21:25 +00001693 return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], NULL, argv[3]);
1694}
1695
1696DEFUN (ipv6_route_ifname_flags_pref,
1697 ipv6_route_ifname_flags_pref_cmd,
1698 "ipv6 route X:X::X:X/M X:X::X:X INTERFACE (reject|blackhole) <1-255>",
1699 IP_STR
1700 "Establish static routes\n"
1701 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1702 "IPv6 gateway address\n"
1703 "IPv6 gateway interface name\n"
1704 "Emit an ICMP unreachable when matched\n"
1705 "Silently discard pkts when matched\n"
1706 "Distance value for this prefix\n")
1707{
1708 return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], argv[3], argv[4]);
paul718e3742002-12-13 20:15:29 +00001709}
1710
1711DEFUN (no_ipv6_route,
1712 no_ipv6_route_cmd,
1713 "no ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE)",
1714 NO_STR
1715 IP_STR
1716 "Establish static routes\n"
1717 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1718 "IPv6 gateway address\n"
1719 "IPv6 gateway interface name\n")
1720{
hasso81dfcaa2003-05-25 19:21:25 +00001721 return static_ipv6_func (vty, 0, argv[0], argv[1], NULL, NULL, NULL);
paul718e3742002-12-13 20:15:29 +00001722}
1723
hasso81dfcaa2003-05-25 19:21:25 +00001724ALIAS (no_ipv6_route,
1725 no_ipv6_route_flags_cmd,
1726 "no ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) (reject|blackhole)",
1727 NO_STR
1728 IP_STR
1729 "Establish static routes\n"
1730 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1731 "IPv6 gateway address\n"
1732 "IPv6 gateway interface name\n"
1733 "Emit an ICMP unreachable when matched\n"
1734 "Silently discard pkts when matched\n")
1735
paul718e3742002-12-13 20:15:29 +00001736DEFUN (no_ipv6_route_ifname,
1737 no_ipv6_route_ifname_cmd,
1738 "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE",
1739 NO_STR
1740 IP_STR
1741 "Establish static routes\n"
1742 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1743 "IPv6 gateway address\n"
1744 "IPv6 gateway interface name\n")
1745{
hasso81dfcaa2003-05-25 19:21:25 +00001746 return static_ipv6_func (vty, 0, argv[0], argv[1], argv[2], NULL, NULL);
paul718e3742002-12-13 20:15:29 +00001747}
1748
hasso81dfcaa2003-05-25 19:21:25 +00001749ALIAS (no_ipv6_route_ifname,
1750 no_ipv6_route_ifname_flags_cmd,
1751 "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE (reject|blackhole)",
1752 NO_STR
1753 IP_STR
1754 "Establish static routes\n"
1755 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1756 "IPv6 gateway address\n"
1757 "IPv6 gateway interface name\n"
1758 "Emit an ICMP unreachable when matched\n"
1759 "Silently discard pkts when matched\n")
1760
paul718e3742002-12-13 20:15:29 +00001761DEFUN (no_ipv6_route_pref,
1762 no_ipv6_route_pref_cmd,
1763 "no ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) <1-255>",
1764 NO_STR
1765 IP_STR
1766 "Establish static routes\n"
1767 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1768 "IPv6 gateway address\n"
1769 "IPv6 gateway interface name\n"
1770 "Distance value for this prefix\n")
1771{
hasso81dfcaa2003-05-25 19:21:25 +00001772 return static_ipv6_func (vty, 0, argv[0], argv[1], NULL, NULL, argv[2]);
1773}
1774
1775DEFUN (no_ipv6_route_flags_pref,
1776 no_ipv6_route_flags_pref_cmd,
1777 "no ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) (reject|blackhole) <1-255>",
1778 NO_STR
1779 IP_STR
1780 "Establish static routes\n"
1781 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1782 "IPv6 gateway address\n"
1783 "IPv6 gateway interface name\n"
1784 "Emit an ICMP unreachable when matched\n"
1785 "Silently discard pkts when matched\n"
1786 "Distance value for this prefix\n")
1787{
1788 /* We do not care about argv[2] */
1789 return static_ipv6_func (vty, 0, argv[0], argv[1], NULL, argv[2], argv[3]);
paul718e3742002-12-13 20:15:29 +00001790}
1791
1792DEFUN (no_ipv6_route_ifname_pref,
1793 no_ipv6_route_ifname_pref_cmd,
1794 "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE <1-255>",
1795 NO_STR
1796 IP_STR
1797 "Establish static routes\n"
1798 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1799 "IPv6 gateway address\n"
1800 "IPv6 gateway interface name\n"
1801 "Distance value for this prefix\n")
1802{
hasso81dfcaa2003-05-25 19:21:25 +00001803 return static_ipv6_func (vty, 0, argv[0], argv[1], argv[2], NULL, argv[3]);
1804}
1805
1806DEFUN (no_ipv6_route_ifname_flags_pref,
1807 no_ipv6_route_ifname_flags_pref_cmd,
1808 "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE (reject|blackhole) <1-255>",
1809 NO_STR
1810 IP_STR
1811 "Establish static routes\n"
1812 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1813 "IPv6 gateway address\n"
1814 "IPv6 gateway interface name\n"
1815 "Emit an ICMP unreachable when matched\n"
1816 "Silently discard pkts when matched\n"
1817 "Distance value for this prefix\n")
1818{
1819 return static_ipv6_func (vty, 0, argv[0], argv[1], argv[2], argv[3], argv[4]);
paul718e3742002-12-13 20:15:29 +00001820}
1821
paul718e3742002-12-13 20:15:29 +00001822DEFUN (show_ipv6_route,
1823 show_ipv6_route_cmd,
1824 "show ipv6 route",
1825 SHOW_STR
1826 IP_STR
1827 "IPv6 routing table\n")
1828{
1829 struct route_table *table;
1830 struct route_node *rn;
1831 struct rib *rib;
1832 int first = 1;
1833
Feng Lu41f44a22015-05-22 11:39:56 +02001834 table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, VRF_DEFAULT);
paul718e3742002-12-13 20:15:29 +00001835 if (! table)
1836 return CMD_SUCCESS;
1837
1838 /* Show all IPv6 route. */
1839 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001840 RNODE_FOREACH_RIB (rn, rib)
paul718e3742002-12-13 20:15:29 +00001841 {
1842 if (first)
1843 {
David Lampartere0ca5fd2009-09-16 01:52:42 +02001844 vty_out (vty, SHOW_ROUTE_V6_HEADER);
paul718e3742002-12-13 20:15:29 +00001845 first = 0;
1846 }
Timo Teräs53a5c392015-05-23 11:08:40 +03001847 vty_show_ip_route (vty, rn, rib);
paul718e3742002-12-13 20:15:29 +00001848 }
1849 return CMD_SUCCESS;
1850}
1851
1852DEFUN (show_ipv6_route_prefix_longer,
1853 show_ipv6_route_prefix_longer_cmd,
1854 "show ipv6 route X:X::X:X/M longer-prefixes",
1855 SHOW_STR
1856 IP_STR
1857 "IPv6 routing table\n"
1858 "IPv6 prefix\n"
1859 "Show route matching the specified Network/Mask pair only\n")
1860{
1861 struct route_table *table;
1862 struct route_node *rn;
1863 struct rib *rib;
1864 struct prefix p;
1865 int ret;
1866 int first = 1;
1867
Feng Lu41f44a22015-05-22 11:39:56 +02001868 table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, VRF_DEFAULT);
paul718e3742002-12-13 20:15:29 +00001869 if (! table)
1870 return CMD_SUCCESS;
1871
1872 ret = str2prefix (argv[0], &p);
1873 if (! ret)
1874 {
1875 vty_out (vty, "%% Malformed Prefix%s", VTY_NEWLINE);
1876 return CMD_WARNING;
1877 }
1878
1879 /* Show matched type IPv6 routes. */
1880 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001881 RNODE_FOREACH_RIB (rn, rib)
paul718e3742002-12-13 20:15:29 +00001882 if (prefix_match (&p, &rn->p))
1883 {
1884 if (first)
1885 {
David Lampartere0ca5fd2009-09-16 01:52:42 +02001886 vty_out (vty, SHOW_ROUTE_V6_HEADER);
paul718e3742002-12-13 20:15:29 +00001887 first = 0;
1888 }
Timo Teräs53a5c392015-05-23 11:08:40 +03001889 vty_show_ip_route (vty, rn, rib);
paul718e3742002-12-13 20:15:29 +00001890 }
1891 return CMD_SUCCESS;
1892}
1893
1894DEFUN (show_ipv6_route_protocol,
1895 show_ipv6_route_protocol_cmd,
David Lampartere0ca5fd2009-09-16 01:52:42 +02001896 "show ipv6 route " QUAGGA_IP6_REDIST_STR_ZEBRA,
paul718e3742002-12-13 20:15:29 +00001897 SHOW_STR
1898 IP_STR
1899 "IP routing table\n"
David Lampartere0ca5fd2009-09-16 01:52:42 +02001900 QUAGGA_IP6_REDIST_HELP_STR_ZEBRA)
paul718e3742002-12-13 20:15:29 +00001901{
1902 int type;
1903 struct route_table *table;
1904 struct route_node *rn;
1905 struct rib *rib;
1906 int first = 1;
1907
David Lampartere0ca5fd2009-09-16 01:52:42 +02001908 type = proto_redistnum (AFI_IP6, argv[0]);
1909 if (type < 0)
paul718e3742002-12-13 20:15:29 +00001910 {
1911 vty_out (vty, "Unknown route type%s", VTY_NEWLINE);
1912 return CMD_WARNING;
1913 }
1914
Feng Lu41f44a22015-05-22 11:39:56 +02001915 table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, VRF_DEFAULT);
paul718e3742002-12-13 20:15:29 +00001916 if (! table)
1917 return CMD_SUCCESS;
1918
1919 /* Show matched type IPv6 routes. */
1920 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00001921 RNODE_FOREACH_RIB (rn, rib)
paul718e3742002-12-13 20:15:29 +00001922 if (rib->type == type)
1923 {
1924 if (first)
1925 {
David Lampartere0ca5fd2009-09-16 01:52:42 +02001926 vty_out (vty, SHOW_ROUTE_V6_HEADER);
paul718e3742002-12-13 20:15:29 +00001927 first = 0;
1928 }
Timo Teräs53a5c392015-05-23 11:08:40 +03001929 vty_show_ip_route (vty, rn, rib);
paul718e3742002-12-13 20:15:29 +00001930 }
1931 return CMD_SUCCESS;
1932}
1933
1934DEFUN (show_ipv6_route_addr,
1935 show_ipv6_route_addr_cmd,
1936 "show ipv6 route X:X::X:X",
1937 SHOW_STR
1938 IP_STR
1939 "IPv6 routing table\n"
1940 "IPv6 Address\n")
1941{
1942 int ret;
1943 struct prefix_ipv6 p;
1944 struct route_table *table;
1945 struct route_node *rn;
1946
1947 ret = str2prefix_ipv6 (argv[0], &p);
1948 if (ret <= 0)
1949 {
1950 vty_out (vty, "Malformed IPv6 address%s", VTY_NEWLINE);
1951 return CMD_WARNING;
1952 }
1953
Feng Lu41f44a22015-05-22 11:39:56 +02001954 table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, VRF_DEFAULT);
paul718e3742002-12-13 20:15:29 +00001955 if (! table)
1956 return CMD_SUCCESS;
1957
1958 rn = route_node_match (table, (struct prefix *) &p);
1959 if (! rn)
1960 {
1961 vty_out (vty, "%% Network not in table%s", VTY_NEWLINE);
1962 return CMD_WARNING;
1963 }
1964
Timo Teräs53a5c392015-05-23 11:08:40 +03001965 vty_show_ip_route_detail (vty, rn, 0);
paul718e3742002-12-13 20:15:29 +00001966
1967 route_unlock_node (rn);
1968
1969 return CMD_SUCCESS;
1970}
1971
1972DEFUN (show_ipv6_route_prefix,
1973 show_ipv6_route_prefix_cmd,
1974 "show ipv6 route X:X::X:X/M",
1975 SHOW_STR
1976 IP_STR
1977 "IPv6 routing table\n"
1978 "IPv6 prefix\n")
1979{
1980 int ret;
1981 struct prefix_ipv6 p;
1982 struct route_table *table;
1983 struct route_node *rn;
1984
1985 ret = str2prefix_ipv6 (argv[0], &p);
1986 if (ret <= 0)
1987 {
1988 vty_out (vty, "Malformed IPv6 prefix%s", VTY_NEWLINE);
1989 return CMD_WARNING;
1990 }
1991
Feng Lu41f44a22015-05-22 11:39:56 +02001992 table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, VRF_DEFAULT);
paul718e3742002-12-13 20:15:29 +00001993 if (! table)
1994 return CMD_SUCCESS;
1995
1996 rn = route_node_match (table, (struct prefix *) &p);
1997 if (! rn || rn->p.prefixlen != p.prefixlen)
1998 {
1999 vty_out (vty, "%% Network not in table%s", VTY_NEWLINE);
Lu Feng969d3552014-10-21 06:24:07 +00002000 if (rn)
2001 route_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +00002002 return CMD_WARNING;
2003 }
2004
Timo Teräs53a5c392015-05-23 11:08:40 +03002005 vty_show_ip_route_detail (vty, rn, 0);
paul718e3742002-12-13 20:15:29 +00002006
2007 route_unlock_node (rn);
2008
2009 return CMD_SUCCESS;
2010}
2011
Stig Thormodsrud61691c92008-11-04 15:45:07 -08002012/* Show route summary. */
2013DEFUN (show_ipv6_route_summary,
2014 show_ipv6_route_summary_cmd,
2015 "show ipv6 route summary",
2016 SHOW_STR
2017 IP_STR
2018 "IPv6 routing table\n"
2019 "Summary of all IPv6 routes\n")
2020{
2021 struct route_table *table;
2022
Feng Lu41f44a22015-05-22 11:39:56 +02002023 table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, VRF_DEFAULT);
Stig Thormodsrud61691c92008-11-04 15:45:07 -08002024 if (! table)
2025 return CMD_SUCCESS;
2026
2027 vty_show_ip_route_summary (vty, table);
2028
2029 return CMD_SUCCESS;
2030}
2031
Dinesh G Dutt56a5f772014-09-30 12:58:04 -07002032/* Show ipv6 route summary prefix. */
2033DEFUN (show_ipv6_route_summary_prefix,
2034 show_ipv6_route_summary_prefix_cmd,
2035 "show ipv6 route summary prefix",
2036 SHOW_STR
2037 IP_STR
2038 "IPv6 routing table\n"
2039 "Summary of all IPv6 routes\n"
2040 "Prefix routes\n")
2041{
2042 struct route_table *table;
2043
Feng Lu41f44a22015-05-22 11:39:56 +02002044 table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, VRF_DEFAULT);
Dinesh G Dutt56a5f772014-09-30 12:58:04 -07002045 if (! table)
2046 return CMD_SUCCESS;
2047
2048 vty_show_ip_route_summary_prefix (vty, table);
2049
2050 return CMD_SUCCESS;
2051}
2052
G.Balajicddf3912011-11-26 21:59:32 +04002053/*
G.Balajicddf3912011-11-26 21:59:32 +04002054 * Show IPv6 mroute command.Used to dump
2055 * the Multicast routing table.
2056 */
2057
2058DEFUN (show_ipv6_mroute,
2059 show_ipv6_mroute_cmd,
2060 "show ipv6 mroute",
2061 SHOW_STR
2062 IP_STR
2063 "IPv6 Multicast routing table\n")
2064{
2065 struct route_table *table;
2066 struct route_node *rn;
2067 struct rib *rib;
2068 int first = 1;
2069
Feng Lu41f44a22015-05-22 11:39:56 +02002070 table = zebra_vrf_table (AFI_IP6, SAFI_MULTICAST, VRF_DEFAULT);
G.Balajicddf3912011-11-26 21:59:32 +04002071 if (! table)
2072 return CMD_SUCCESS;
2073
2074 /* Show all IPv6 route. */
2075 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +00002076 RNODE_FOREACH_RIB (rn, rib)
G.Balajicddf3912011-11-26 21:59:32 +04002077 {
2078 if (first)
2079 {
G.Balajicb32fd62011-11-27 20:09:40 +05302080 vty_out (vty, SHOW_ROUTE_V6_HEADER);
G.Balajicddf3912011-11-26 21:59:32 +04002081 first = 0;
2082 }
Timo Teräs53a5c392015-05-23 11:08:40 +03002083 vty_show_ip_route (vty, rn, rib);
G.Balajicddf3912011-11-26 21:59:32 +04002084 }
2085 return CMD_SUCCESS;
2086}
2087
paul718e3742002-12-13 20:15:29 +00002088/* Write IPv6 static route configuration. */
paula1ac18c2005-06-28 17:17:12 +00002089static int
paul718e3742002-12-13 20:15:29 +00002090static_config_ipv6 (struct vty *vty)
2091{
2092 struct route_node *rn;
2093 struct static_ipv6 *si;
2094 int write;
2095 char buf[BUFSIZ];
2096 struct route_table *stable;
2097
2098 write = 0;
2099
2100 /* Lookup table. */
Feng Lu41f44a22015-05-22 11:39:56 +02002101 stable = zebra_vrf_static_table (AFI_IP6, SAFI_UNICAST, VRF_DEFAULT);
paul718e3742002-12-13 20:15:29 +00002102 if (! stable)
2103 return -1;
2104
2105 for (rn = route_top (stable); rn; rn = route_next (rn))
2106 for (si = rn->info; si; si = si->next)
2107 {
Timo Teräs53a5c392015-05-23 11:08:40 +03002108 vty_out (vty, "ipv6 route %s", prefix2str (&rn->p, buf, sizeof buf));
paul718e3742002-12-13 20:15:29 +00002109
2110 switch (si->type)
2111 {
2112 case STATIC_IPV6_GATEWAY:
2113 vty_out (vty, " %s", inet_ntop (AF_INET6, &si->ipv6, buf, BUFSIZ));
2114 break;
2115 case STATIC_IPV6_IFNAME:
2116 vty_out (vty, " %s", si->ifname);
2117 break;
2118 case STATIC_IPV6_GATEWAY_IFNAME:
2119 vty_out (vty, " %s %s",
2120 inet_ntop (AF_INET6, &si->ipv6, buf, BUFSIZ), si->ifname);
2121 break;
2122 }
2123
hasso81dfcaa2003-05-25 19:21:25 +00002124 if (CHECK_FLAG(si->flags, ZEBRA_FLAG_REJECT))
2125 vty_out (vty, " %s", "reject");
2126
2127 if (CHECK_FLAG(si->flags, ZEBRA_FLAG_BLACKHOLE))
2128 vty_out (vty, " %s", "blackhole");
2129
paul718e3742002-12-13 20:15:29 +00002130 if (si->distance != ZEBRA_STATIC_DISTANCE_DEFAULT)
2131 vty_out (vty, " %d", si->distance);
2132 vty_out (vty, "%s", VTY_NEWLINE);
2133
2134 write = 1;
2135 }
2136 return write;
2137}
2138#endif /* HAVE_IPV6 */
2139
2140/* Static ip route configuration write function. */
paula1ac18c2005-06-28 17:17:12 +00002141static int
paul718e3742002-12-13 20:15:29 +00002142zebra_ip_config (struct vty *vty)
2143{
2144 int write = 0;
2145
Everton Marques33d86db2014-07-14 11:19:00 -03002146 write += static_config_ipv4 (vty, SAFI_UNICAST, "ip route");
2147 write += static_config_ipv4 (vty, SAFI_MULTICAST, "ip mroute");
paul718e3742002-12-13 20:15:29 +00002148#ifdef HAVE_IPV6
2149 write += static_config_ipv6 (vty);
2150#endif /* HAVE_IPV6 */
2151
2152 return write;
2153}
2154
David Lamparterbd078122015-01-06 19:53:24 +01002155static int config_write_vty(struct vty *vty)
2156{
Paul Jakma7514fb72007-05-02 16:05:35 +00002157 int i;
David Lamparterbd078122015-01-06 19:53:24 +01002158 enum multicast_mode ipv4_multicast_mode = multicast_mode_ipv4_get ();
2159
2160 if (ipv4_multicast_mode != MCAST_NO_CONFIG)
2161 vty_out (vty, "ip multicast rpf-lookup-mode %s%s",
2162 ipv4_multicast_mode == MCAST_URIB_ONLY ? "urib-only" :
2163 ipv4_multicast_mode == MCAST_MRIB_ONLY ? "mrib-only" :
2164 ipv4_multicast_mode == MCAST_MIX_MRIB_FIRST ? "mrib-then-urib" :
2165 ipv4_multicast_mode == MCAST_MIX_DISTANCE ? "lower-distance" :
2166 "longer-prefix",
2167 VTY_NEWLINE);
Paul Jakma7514fb72007-05-02 16:05:35 +00002168
2169 for (i=0;i<ZEBRA_ROUTE_MAX;i++)
2170 {
2171 if (proto_rm[AFI_IP][i])
2172 vty_out (vty, "ip protocol %s route-map %s%s", zebra_route_string(i),
2173 proto_rm[AFI_IP][i], VTY_NEWLINE);
2174 }
2175 if (proto_rm[AFI_IP][ZEBRA_ROUTE_MAX])
2176 vty_out (vty, "ip protocol %s route-map %s%s", "any",
2177 proto_rm[AFI_IP][ZEBRA_ROUTE_MAX], VTY_NEWLINE);
2178
2179 return 1;
2180}
2181
2182/* table node for protocol filtering */
Stephen Hemminger7fc626d2008-12-01 11:10:34 -08002183static struct cmd_node protocol_node = { PROTOCOL_NODE, "", 1 };
Paul Jakma7514fb72007-05-02 16:05:35 +00002184
paul718e3742002-12-13 20:15:29 +00002185/* IP node for static routes. */
Stephen Hemminger7fc626d2008-12-01 11:10:34 -08002186static struct cmd_node ip_node = { IP_NODE, "", 1 };
paul718e3742002-12-13 20:15:29 +00002187
2188/* Route VTY. */
2189void
paula1ac18c2005-06-28 17:17:12 +00002190zebra_vty_init (void)
paul718e3742002-12-13 20:15:29 +00002191{
2192 install_node (&ip_node, zebra_ip_config);
David Lamparterbd078122015-01-06 19:53:24 +01002193 install_node (&protocol_node, config_write_vty);
paul718e3742002-12-13 20:15:29 +00002194
Everton Marques33d86db2014-07-14 11:19:00 -03002195 install_element (CONFIG_NODE, &ip_mroute_cmd);
David Lampartera76681b2015-01-22 19:03:53 +01002196 install_element (CONFIG_NODE, &ip_mroute_dist_cmd);
Everton Marques33d86db2014-07-14 11:19:00 -03002197 install_element (CONFIG_NODE, &no_ip_mroute_cmd);
David Lampartera76681b2015-01-22 19:03:53 +01002198 install_element (CONFIG_NODE, &no_ip_mroute_dist_cmd);
David Lamparterbd078122015-01-06 19:53:24 +01002199 install_element (CONFIG_NODE, &ip_multicast_mode_cmd);
2200 install_element (CONFIG_NODE, &no_ip_multicast_mode_cmd);
2201 install_element (CONFIG_NODE, &no_ip_multicast_mode_noarg_cmd);
Paul Jakma7514fb72007-05-02 16:05:35 +00002202 install_element (CONFIG_NODE, &ip_protocol_cmd);
2203 install_element (CONFIG_NODE, &no_ip_protocol_cmd);
2204 install_element (VIEW_NODE, &show_ip_protocol_cmd);
2205 install_element (ENABLE_NODE, &show_ip_protocol_cmd);
paul718e3742002-12-13 20:15:29 +00002206 install_element (CONFIG_NODE, &ip_route_cmd);
hasso81dfcaa2003-05-25 19:21:25 +00002207 install_element (CONFIG_NODE, &ip_route_flags_cmd);
hasso457ef552003-05-28 12:02:15 +00002208 install_element (CONFIG_NODE, &ip_route_flags2_cmd);
paul718e3742002-12-13 20:15:29 +00002209 install_element (CONFIG_NODE, &ip_route_mask_cmd);
hasso81dfcaa2003-05-25 19:21:25 +00002210 install_element (CONFIG_NODE, &ip_route_mask_flags_cmd);
hasso457ef552003-05-28 12:02:15 +00002211 install_element (CONFIG_NODE, &ip_route_mask_flags2_cmd);
paul718e3742002-12-13 20:15:29 +00002212 install_element (CONFIG_NODE, &no_ip_route_cmd);
hasso81dfcaa2003-05-25 19:21:25 +00002213 install_element (CONFIG_NODE, &no_ip_route_flags_cmd);
hasso457ef552003-05-28 12:02:15 +00002214 install_element (CONFIG_NODE, &no_ip_route_flags2_cmd);
paul718e3742002-12-13 20:15:29 +00002215 install_element (CONFIG_NODE, &no_ip_route_mask_cmd);
hasso81dfcaa2003-05-25 19:21:25 +00002216 install_element (CONFIG_NODE, &no_ip_route_mask_flags_cmd);
hasso457ef552003-05-28 12:02:15 +00002217 install_element (CONFIG_NODE, &no_ip_route_mask_flags2_cmd);
paul718e3742002-12-13 20:15:29 +00002218 install_element (CONFIG_NODE, &ip_route_distance_cmd);
hasso81dfcaa2003-05-25 19:21:25 +00002219 install_element (CONFIG_NODE, &ip_route_flags_distance_cmd);
hasso457ef552003-05-28 12:02:15 +00002220 install_element (CONFIG_NODE, &ip_route_flags_distance2_cmd);
paul718e3742002-12-13 20:15:29 +00002221 install_element (CONFIG_NODE, &ip_route_mask_distance_cmd);
hasso81dfcaa2003-05-25 19:21:25 +00002222 install_element (CONFIG_NODE, &ip_route_mask_flags_distance_cmd);
hasso457ef552003-05-28 12:02:15 +00002223 install_element (CONFIG_NODE, &ip_route_mask_flags_distance2_cmd);
paul718e3742002-12-13 20:15:29 +00002224 install_element (CONFIG_NODE, &no_ip_route_distance_cmd);
hasso81dfcaa2003-05-25 19:21:25 +00002225 install_element (CONFIG_NODE, &no_ip_route_flags_distance_cmd);
hasso457ef552003-05-28 12:02:15 +00002226 install_element (CONFIG_NODE, &no_ip_route_flags_distance2_cmd);
hasso81dfcaa2003-05-25 19:21:25 +00002227 install_element (CONFIG_NODE, &no_ip_route_mask_flags_distance_cmd);
hasso457ef552003-05-28 12:02:15 +00002228 install_element (CONFIG_NODE, &no_ip_route_mask_flags_distance2_cmd);
paul718e3742002-12-13 20:15:29 +00002229
2230 install_element (VIEW_NODE, &show_ip_route_cmd);
2231 install_element (VIEW_NODE, &show_ip_route_addr_cmd);
2232 install_element (VIEW_NODE, &show_ip_route_prefix_cmd);
2233 install_element (VIEW_NODE, &show_ip_route_prefix_longer_cmd);
2234 install_element (VIEW_NODE, &show_ip_route_protocol_cmd);
2235 install_element (VIEW_NODE, &show_ip_route_supernets_cmd);
Stig Thormodsrud61691c92008-11-04 15:45:07 -08002236 install_element (VIEW_NODE, &show_ip_route_summary_cmd);
Dinesh G Dutt56a5f772014-09-30 12:58:04 -07002237 install_element (VIEW_NODE, &show_ip_route_summary_prefix_cmd);
paul718e3742002-12-13 20:15:29 +00002238 install_element (ENABLE_NODE, &show_ip_route_cmd);
2239 install_element (ENABLE_NODE, &show_ip_route_addr_cmd);
2240 install_element (ENABLE_NODE, &show_ip_route_prefix_cmd);
2241 install_element (ENABLE_NODE, &show_ip_route_prefix_longer_cmd);
2242 install_element (ENABLE_NODE, &show_ip_route_protocol_cmd);
2243 install_element (ENABLE_NODE, &show_ip_route_supernets_cmd);
paul718e3742002-12-13 20:15:29 +00002244 install_element (ENABLE_NODE, &show_ip_route_summary_cmd);
Dinesh G Dutt56a5f772014-09-30 12:58:04 -07002245 install_element (ENABLE_NODE, &show_ip_route_summary_prefix_cmd);
paul718e3742002-12-13 20:15:29 +00002246
G.Balajicddf3912011-11-26 21:59:32 +04002247 install_element (VIEW_NODE, &show_ip_mroute_cmd);
2248 install_element (ENABLE_NODE, &show_ip_mroute_cmd);
2249
Everton Marques33d86db2014-07-14 11:19:00 -03002250 install_element (VIEW_NODE, &show_ip_rpf_cmd);
2251 install_element (ENABLE_NODE, &show_ip_rpf_cmd);
David Lamparter3b02fe82015-01-22 19:12:35 +01002252 install_element (VIEW_NODE, &show_ip_rpf_addr_cmd);
2253 install_element (ENABLE_NODE, &show_ip_rpf_addr_cmd);
G.Balajicddf3912011-11-26 21:59:32 +04002254
paul718e3742002-12-13 20:15:29 +00002255#ifdef HAVE_IPV6
2256 install_element (CONFIG_NODE, &ipv6_route_cmd);
hasso81dfcaa2003-05-25 19:21:25 +00002257 install_element (CONFIG_NODE, &ipv6_route_flags_cmd);
paul718e3742002-12-13 20:15:29 +00002258 install_element (CONFIG_NODE, &ipv6_route_ifname_cmd);
hasso81dfcaa2003-05-25 19:21:25 +00002259 install_element (CONFIG_NODE, &ipv6_route_ifname_flags_cmd);
paul718e3742002-12-13 20:15:29 +00002260 install_element (CONFIG_NODE, &no_ipv6_route_cmd);
hasso81dfcaa2003-05-25 19:21:25 +00002261 install_element (CONFIG_NODE, &no_ipv6_route_flags_cmd);
paul718e3742002-12-13 20:15:29 +00002262 install_element (CONFIG_NODE, &no_ipv6_route_ifname_cmd);
hasso81dfcaa2003-05-25 19:21:25 +00002263 install_element (CONFIG_NODE, &no_ipv6_route_ifname_flags_cmd);
paul718e3742002-12-13 20:15:29 +00002264 install_element (CONFIG_NODE, &ipv6_route_pref_cmd);
hasso81dfcaa2003-05-25 19:21:25 +00002265 install_element (CONFIG_NODE, &ipv6_route_flags_pref_cmd);
paul718e3742002-12-13 20:15:29 +00002266 install_element (CONFIG_NODE, &ipv6_route_ifname_pref_cmd);
hasso81dfcaa2003-05-25 19:21:25 +00002267 install_element (CONFIG_NODE, &ipv6_route_ifname_flags_pref_cmd);
paul718e3742002-12-13 20:15:29 +00002268 install_element (CONFIG_NODE, &no_ipv6_route_pref_cmd);
hasso81dfcaa2003-05-25 19:21:25 +00002269 install_element (CONFIG_NODE, &no_ipv6_route_flags_pref_cmd);
paul718e3742002-12-13 20:15:29 +00002270 install_element (CONFIG_NODE, &no_ipv6_route_ifname_pref_cmd);
hasso81dfcaa2003-05-25 19:21:25 +00002271 install_element (CONFIG_NODE, &no_ipv6_route_ifname_flags_pref_cmd);
paul718e3742002-12-13 20:15:29 +00002272 install_element (VIEW_NODE, &show_ipv6_route_cmd);
Stig Thormodsrud61691c92008-11-04 15:45:07 -08002273 install_element (VIEW_NODE, &show_ipv6_route_summary_cmd);
Dinesh G Dutt56a5f772014-09-30 12:58:04 -07002274 install_element (VIEW_NODE, &show_ipv6_route_summary_prefix_cmd);
paul718e3742002-12-13 20:15:29 +00002275 install_element (VIEW_NODE, &show_ipv6_route_protocol_cmd);
2276 install_element (VIEW_NODE, &show_ipv6_route_addr_cmd);
2277 install_element (VIEW_NODE, &show_ipv6_route_prefix_cmd);
2278 install_element (VIEW_NODE, &show_ipv6_route_prefix_longer_cmd);
2279 install_element (ENABLE_NODE, &show_ipv6_route_cmd);
2280 install_element (ENABLE_NODE, &show_ipv6_route_protocol_cmd);
2281 install_element (ENABLE_NODE, &show_ipv6_route_addr_cmd);
2282 install_element (ENABLE_NODE, &show_ipv6_route_prefix_cmd);
2283 install_element (ENABLE_NODE, &show_ipv6_route_prefix_longer_cmd);
Stig Thormodsrud61691c92008-11-04 15:45:07 -08002284 install_element (ENABLE_NODE, &show_ipv6_route_summary_cmd);
Dinesh G Dutt56a5f772014-09-30 12:58:04 -07002285 install_element (ENABLE_NODE, &show_ipv6_route_summary_prefix_cmd);
G.Balajicddf3912011-11-26 21:59:32 +04002286
2287 install_element (VIEW_NODE, &show_ipv6_mroute_cmd);
2288 install_element (ENABLE_NODE, &show_ipv6_mroute_cmd);
paul718e3742002-12-13 20:15:29 +00002289#endif /* HAVE_IPV6 */
2290}