]> git.proxmox.com Git - mirror_frr.git/blame - zebra/zebra_vty.c
lib: add cleanup hook to route table
[mirror_frr.git] / zebra / zebra_vty.c
CommitLineData
718e3744 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
e52702f2
QY
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.
718e3744 20 */
21
22#include <zebra.h>
23
7514fb77 24#include "memory.h"
4a1ab8e4 25#include "zebra_memory.h"
718e3744 26#include "if.h"
27#include "prefix.h"
28#include "command.h"
29#include "table.h"
30#include "rib.h"
fb018d25 31#include "nexthop.h"
b72ede27 32#include "vrf.h"
7758e3f3 33#include "mpls.h"
4a1ab8e4 34#include "routemap.h"
718e3744 35
a1ac18c4 36#include "zebra/zserv.h"
7c551956 37#include "zebra/zebra_vrf.h"
7758e3f3 38#include "zebra/zebra_mpls.h"
fb018d25 39#include "zebra/zebra_rnh.h"
7a4bb9c5 40#include "zebra/redistribute.h"
6baf7bb8 41#include "zebra/zebra_routemap.h"
28f6dde8 42#include "zebra/zebra_static.h"
1d666fcb 43#include "lib/json.h"
6baf7bb8
DS
44
45extern int allow_delete;
a1ac18c4 46
18a4ded2
DW
47static int do_show_ip_route(struct vty *vty, const char *vrf_name,
48 safi_t safi, u_char use_json);
65dd94cf
DL
49static void vty_show_ip_route_detail (struct vty *vty, struct route_node *rn,
50 int mcast);
b78a80d7 51
18a4ded2
DW
52#define ONE_DAY_SECOND 60*60*24
53#define ONE_WEEK_SECOND 60*60*24*7
54
b78a80d7 55/* General function for static route. */
41675b4c 56int
b78a80d7
EM
57zebra_static_ipv4 (struct vty *vty, safi_t safi, int add_cmd,
58 const char *dest_str, const char *mask_str,
59 const char *gate_str, const char *flag_str,
60 const char *tag_str, const char *distance_str,
a22f3f5d 61 const char *vrf_id_str, const char *label_str)
718e3744 62{
63 int ret;
64 u_char distance;
65 struct prefix p;
66 struct in_addr gate;
67 struct in_addr mask;
81dfcaa2 68 u_char flag = 0;
dc9ffce8 69 route_tag_t tag = 0;
b9f1114e 70 struct zebra_vrf *zvrf = NULL;
ba779241 71 unsigned int ifindex = 0;
a3d21ef3 72 const char *ifname = NULL;
882261e1 73 u_char type = STATIC_BLACKHOLE;
a22f3f5d 74 struct static_nh_label snh_label;
ba779241 75
a22f3f5d 76 memset (&snh_label, 0, sizeof (struct static_nh_label));
718e3744 77 ret = str2prefix (dest_str, &p);
78 if (ret <= 0)
79 {
80 vty_out (vty, "%% Malformed address%s", VTY_NEWLINE);
81 return CMD_WARNING;
82 }
83
84 /* Cisco like mask notation. */
85 if (mask_str)
86 {
87 ret = inet_aton (mask_str, &mask);
88 if (ret == 0)
595db7f1 89 {
90 vty_out (vty, "%% Malformed address%s", VTY_NEWLINE);
91 return CMD_WARNING;
92 }
718e3744 93 p.prefixlen = ip_masklen (mask);
94 }
95
96 /* Apply mask for given prefix. */
97 apply_mask (&p);
98
595db7f1 99 /* Administrative distance. */
100 if (distance_str)
101 distance = atoi (distance_str);
102 else
103 distance = ZEBRA_STATIC_DISTANCE_DEFAULT;
104
0d9551dc
DS
105 /* tag */
106 if (tag_str)
ec911825 107 VTY_GET_INTEGER_RANGE("tag", tag, tag_str, 0, 4294967295);
0d9551dc 108
8f527c5e 109 /* VRF id */
05e8e11e 110 zvrf = zebra_vrf_lookup_by_name (vrf_id_str);
b9f1114e
DS
111
112 if (!zvrf)
113 {
114 vty_out (vty, "%% vrf %s is not defined%s", vrf_id_str, VTY_NEWLINE);
115 return CMD_WARNING;
116 }
8f527c5e 117
a22f3f5d 118 /* Labels */
119 if (label_str)
120 {
c58418c1
DS
121 if (!mpls_enabled)
122 {
123 vty_out (vty, "%% MPLS not turned on in kernel, ignoring command%s",
124 VTY_NEWLINE);
125 return CMD_WARNING;
126 }
a22f3f5d 127 if (mpls_str2label (label_str, &snh_label.num_labels,
128 snh_label.label))
129 {
130 vty_out (vty, "%% Malformed label(s)%s", VTY_NEWLINE);
131 return CMD_WARNING;
132 }
133 }
134
595db7f1 135 /* Null0 static route. */
457ef551 136 if ((gate_str != NULL) && (strncasecmp (gate_str, "Null0", strlen (gate_str)) == 0))
595db7f1 137 {
138 if (flag_str)
139 {
140 vty_out (vty, "%% can not have flag %s with Null0%s", flag_str, VTY_NEWLINE);
141 return CMD_WARNING;
142 }
143 if (add_cmd)
a22f3f5d 144 static_add_route (AFI_IP, safi, type, &p, NULL, ifindex, ifname,
145 ZEBRA_FLAG_BLACKHOLE, tag, distance, zvrf, &snh_label);
595db7f1 146 else
a22f3f5d 147 static_delete_route (AFI_IP, safi, type, &p, NULL, ifindex, tag,
148 distance, zvrf, &snh_label);
595db7f1 149 return CMD_SUCCESS;
150 }
151
81dfcaa2 152 /* Route flags */
153 if (flag_str) {
154 switch(flag_str[0]) {
155 case 'r':
156 case 'R': /* XXX */
157 SET_FLAG (flag, ZEBRA_FLAG_REJECT);
158 break;
159 case 'b':
160 case 'B': /* XXX */
161 SET_FLAG (flag, ZEBRA_FLAG_BLACKHOLE);
162 break;
163 default:
164 vty_out (vty, "%% Malformed flag %s %s", flag_str, VTY_NEWLINE);
595db7f1 165 return CMD_WARNING;
81dfcaa2 166 }
167 }
168
457ef551 169 if (gate_str == NULL)
170 {
171 if (add_cmd)
a22f3f5d 172 static_add_route (AFI_IP, safi, type, &p, NULL, ifindex, ifname, flag,
173 tag, distance, zvrf, &snh_label);
457ef551 174 else
a22f3f5d 175 static_delete_route (AFI_IP, safi, type, &p, NULL, ifindex, tag, distance,
176 zvrf, &snh_label);
457ef551 177
178 return CMD_SUCCESS;
179 }
e52702f2 180
718e3744 181 /* When gateway is A.B.C.D format, gate is treated as nexthop
182 address other case gate is treated as interface name. */
183 ret = inet_aton (gate_str, &gate);
ba779241
DS
184 if (!ret)
185 {
661512bf 186 struct interface *ifp = if_lookup_by_name_vrf (gate_str, zvrf_id (zvrf));
ba779241 187 if (!ifp)
a3d21ef3 188 {
ba779241 189 vty_out (vty, "%% Unknown interface: %s%s", gate_str, VTY_NEWLINE);
a3d21ef3
DS
190 ifindex = IFINDEX_DELETED;
191 }
192 else
193 ifindex = ifp->ifindex;
194 ifname = gate_str;
c7cfcb75 195 type = STATIC_IFINDEX;
ba779241 196 }
c7cfcb75
DS
197 else
198 type = STATIC_IPV4_GATEWAY;
718e3744 199
200 if (add_cmd)
a22f3f5d 201 static_add_route (AFI_IP, safi, type, &p,
202 ifindex ? NULL : (union g_addr *)&gate, ifindex, ifname,
203 flag, tag, distance, zvrf, &snh_label);
718e3744 204 else
a22f3f5d 205 static_delete_route (AFI_IP, safi, type, &p,
206 ifindex ? NULL : (union g_addr *)&gate, ifindex, tag,
207 distance, zvrf, &snh_label);
718e3744 208
209 return CMD_SUCCESS;
210}
211
b78a80d7 212/* Static unicast routes for multicast RPF lookup. */
b8a96915
DL
213DEFUN (ip_mroute_dist,
214 ip_mroute_dist_cmd,
b62ecea5 215 "ip mroute A.B.C.D/M <A.B.C.D|INTERFACE> [(1-255)]",
b78a80d7
EM
216 IP_STR
217 "Configure static unicast route into MRIB for multicast RPF lookup\n"
218 "IP destination prefix (e.g. 10.0.0.0/8)\n"
219 "Nexthop address\n"
220 "Nexthop interface name\n"
221 "Distance\n")
222{
b62ecea5
QY
223 char *destprefix = argv[2]->arg;
224 char *nexthop = argv[3]->arg;
225 char *distance = (argc == 5) ? argv[4]->arg : NULL;
b78a80d7 226
e52702f2 227 return zebra_static_ipv4 (vty, SAFI_MULTICAST, 1, destprefix, NULL, nexthop, NULL, NULL, distance, NULL, NULL);
b62ecea5 228}
b8a96915
DL
229
230DEFUN (no_ip_mroute_dist,
231 no_ip_mroute_dist_cmd,
b62ecea5 232 "no ip mroute A.B.C.D/M <A.B.C.D|INTERFACE> [(1-255)]",
d7fa34c1 233 NO_STR
b78a80d7
EM
234 IP_STR
235 "Configure static unicast route into MRIB for multicast RPF lookup\n"
236 "IP destination prefix (e.g. 10.0.0.0/8)\n"
237 "Nexthop address\n"
238 "Nexthop interface name\n"
239 "Distance\n")
240{
6de69f83
DW
241 char *destprefix = argv[3]->arg;
242 char *nexthop = argv[4]->arg;
243 char *distance = (argc == 6) ? argv[5]->arg : NULL;
b78a80d7 244
e52702f2 245 return zebra_static_ipv4 (vty, SAFI_MULTICAST, 0, destprefix, NULL, nexthop, NULL, NULL, distance, NULL, NULL);
b62ecea5 246}
b8a96915 247
4623d897
DL
248DEFUN (ip_multicast_mode,
249 ip_multicast_mode_cmd,
6147e2c6 250 "ip multicast rpf-lookup-mode <urib-only|mrib-only|mrib-then-urib|lower-distance|longer-prefix>",
4623d897
DL
251 IP_STR
252 "Multicast options\n"
253 "RPF lookup behavior\n"
254 "Lookup in unicast RIB only\n"
255 "Lookup in multicast RIB only\n"
256 "Try multicast RIB first, fall back to unicast RIB\n"
257 "Lookup both, use entry with lower distance\n"
258 "Lookup both, use entry with longer prefix\n")
259{
b62ecea5 260 char *mode = argv[3]->text;
0b0668e6 261
b62ecea5 262 if (strmatch (mode, "urib-only"))
4623d897 263 multicast_mode_ipv4_set (MCAST_URIB_ONLY);
b62ecea5 264 else if (strmatch (mode, "mrib-only"))
4623d897 265 multicast_mode_ipv4_set (MCAST_MRIB_ONLY);
b62ecea5 266 else if (strmatch (mode, "mrib-then-urib"))
4623d897 267 multicast_mode_ipv4_set (MCAST_MIX_MRIB_FIRST);
b62ecea5 268 else if (strmatch (mode, "lower-distance"))
4623d897 269 multicast_mode_ipv4_set (MCAST_MIX_DISTANCE);
b62ecea5 270 else if (strmatch (mode, "longer-prefix"))
4623d897
DL
271 multicast_mode_ipv4_set (MCAST_MIX_PFXLEN);
272 else
273 {
274 vty_out (vty, "Invalid mode specified%s", VTY_NEWLINE);
275 return CMD_WARNING;
276 }
277
278 return CMD_SUCCESS;
279}
280
281DEFUN (no_ip_multicast_mode,
282 no_ip_multicast_mode_cmd,
b62ecea5 283 "no ip multicast rpf-lookup-mode [<urib-only|mrib-only|mrib-then-urib|lower-distance|longer-prefix>]",
4623d897
DL
284 NO_STR
285 IP_STR
286 "Multicast options\n"
287 "RPF lookup behavior\n"
288 "Lookup in unicast RIB only\n"
289 "Lookup in multicast RIB only\n"
290 "Try multicast RIB first, fall back to unicast RIB\n"
291 "Lookup both, use entry with lower distance\n"
292 "Lookup both, use entry with longer prefix\n")
293{
294 multicast_mode_ipv4_set (MCAST_NO_CONFIG);
295 return CMD_SUCCESS;
296}
297
4623d897 298
b78a80d7
EM
299DEFUN (show_ip_rpf,
300 show_ip_rpf_cmd,
301 "show ip rpf",
302 SHOW_STR
303 IP_STR
304 "Display RPF information for multicast source\n")
305{
18a4ded2 306 return do_show_ip_route(vty, VRF_DEFAULT_NAME, SAFI_MULTICAST, 0);
b78a80d7
EM
307}
308
65dd94cf
DL
309DEFUN (show_ip_rpf_addr,
310 show_ip_rpf_addr_cmd,
311 "show ip rpf A.B.C.D",
312 SHOW_STR
313 IP_STR
314 "Display RPF information for multicast source\n"
315 "IP multicast source address (e.g. 10.0.0.0)\n")
316{
7c022376 317 int idx_ipv4 = 3;
65dd94cf
DL
318 struct in_addr addr;
319 struct route_node *rn;
320 struct rib *rib;
321 int ret;
322
7c022376 323 ret = inet_aton (argv[idx_ipv4]->arg, &addr);
65dd94cf
DL
324 if (ret == 0)
325 {
326 vty_out (vty, "%% Malformed address%s", VTY_NEWLINE);
327 return CMD_WARNING;
328 }
329
f86a2b82 330 rib = rib_match_ipv4_multicast (VRF_DEFAULT, addr, &rn);
65dd94cf
DL
331
332 if (rib)
333 vty_show_ip_route_detail (vty, rn, 1);
334 else
335 vty_out (vty, "%% No match for RPF lookup%s", VTY_NEWLINE);
336
337 return CMD_SUCCESS;
338}
339
030721b7
DS
340static void
341zebra_vty_ip_route_tdv_helper (int argc, struct cmd_token *argv[],
342 int idx_curr, char **tag,
e52702f2 343 char **distance, char **vrf, char **labels)
81dfcaa2 344{
3c2caef9
QY
345 *distance = NULL;
346 while (idx_curr < argc)
347 {
348 if (strmatch (argv[idx_curr]->text, "tag"))
349 {
e52702f2
QY
350 if (tag)
351 *tag = argv[idx_curr+1]->arg;
3c2caef9
QY
352 idx_curr += 2;
353 }
354 else if (strmatch (argv[idx_curr]->text, "vrf"))
355 {
e52702f2
QY
356 if (vrf)
357 *vrf = argv[idx_curr+1]->arg;
358 idx_curr += 2;
359 }
360 else if (strmatch (argv[idx_curr]->text, "label"))
361 {
362 if (labels)
363 *labels = argv[idx_curr+1]->arg;
3c2caef9
QY
364 idx_curr += 2;
365 }
366 else
367 {
e52702f2
QY
368 if (distance)
369 *distance = argv[idx_curr]->arg;
3c2caef9
QY
370 idx_curr++;
371 }
372 }
030721b7
DS
373
374 return;
0d9551dc
DS
375}
376
030721b7
DS
377/* Static route configuration. */
378DEFUN (ip_route,
379 ip_route_cmd,
e52702f2 380 "ip route A.B.C.D/M <A.B.C.D|INTERFACE|null0> [tag (1-4294967295)] [(1-255)] [vrf NAME]",
0d9551dc
DS
381 IP_STR
382 "Establish static routes\n"
383 "IP destination prefix (e.g. 10.0.0.0/8)\n"
384 "IP gateway address\n"
385 "IP gateway interface name\n"
386 "Null interface\n"
387 "Set tag for this route\n"
030721b7
DS
388 "Tag value\n"
389 "Distance value for this route\n"
390 VRF_CMD_HELP_STR)
0d9551dc 391{
7c022376
DW
392 int idx_ipv4_prefixlen = 2;
393 int idx_ipv4_ifname_null = 3;
030721b7
DS
394 int idx_curr = 4;
395 char *tag, *distance, *vrf;
396
397 tag = distance = vrf = NULL;
e52702f2 398 zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
030721b7
DS
399
400 return zebra_static_ipv4 (vty, SAFI_UNICAST, 1,
401 argv[idx_ipv4_prefixlen]->arg,
402 NULL,
403 argv[idx_ipv4_ifname_null]->arg,
404 NULL,
e52702f2 405 tag, distance, vrf, NULL);
81dfcaa2 406}
407
408DEFUN (ip_route_flags,
409 ip_route_flags_cmd,
e52702f2 410 "ip route A.B.C.D/M <reject|blackhole> [tag (1-4294967295)] [(1-255)] [vrf NAME]",
0d9551dc
DS
411 IP_STR
412 "Establish static routes\n"
413 "IP destination prefix (e.g. 10.0.0.0/8)\n"
414 "Emit an ICMP unreachable when matched\n"
415 "Silently discard pkts when matched\n"
416 "Set tag for this route\n"
030721b7
DS
417 "Tag value\n"
418 "Distance value for this route\n"
e52702f2
QY
419 VRF_CMD_HELP_STR
420 "Specify labels for this route\n"
421 "One or more labels separated by '/'\n")
0d9551dc 422{
7c022376
DW
423 int idx_ipv4_prefixlen = 2;
424 int idx_reject_blackhole = 3;
030721b7
DS
425 int idx_curr = 4;
426 char *tag, *distance, *vrf;
427
428 tag = distance = vrf = NULL;
e52702f2 429 zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
030721b7
DS
430
431 return zebra_static_ipv4 (vty, SAFI_UNICAST, 1,
432 argv[idx_ipv4_prefixlen]->arg,
433 NULL,
434 NULL,
435 argv[idx_reject_blackhole]->arg,
e52702f2 436 tag, distance, vrf, NULL);
457ef551 437}
438
718e3744 439/* Mask as A.B.C.D format. */
440DEFUN (ip_route_mask,
441 ip_route_mask_cmd,
e52702f2 442 "ip route A.B.C.D A.B.C.D <A.B.C.D|INTERFACE|null0> [tag (1-4294967295)] [(1-255)] [vrf NAME]",
0d9551dc
DS
443 IP_STR
444 "Establish static routes\n"
445 "IP destination prefix\n"
446 "IP destination prefix mask\n"
447 "IP gateway address\n"
448 "IP gateway interface name\n"
449 "Null interface\n"
450 "Set tag for this route\n"
030721b7
DS
451 "Tag value\n"
452 "Distance value for this route\n"
e52702f2
QY
453 VRF_CMD_HELP_STR
454 "Specify labels for this route\n"
455 "One or more labels separated by '/'\n")
0d9551dc 456{
7c022376
DW
457 int idx_ipv4 = 2;
458 int idx_ipv4_2 = 3;
459 int idx_ipv4_ifname_null = 4;
030721b7
DS
460 int idx_curr = 5;
461 char *tag, *distance, *vrf;
462
463 tag = distance = vrf = NULL;
e52702f2 464 zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
030721b7
DS
465
466 return zebra_static_ipv4 (vty, SAFI_UNICAST, 1,
467 argv[idx_ipv4]->arg,
468 argv[idx_ipv4_2]->arg,
469 argv[idx_ipv4_ifname_null]->arg,
e52702f2 470 NULL, tag, distance, vrf, NULL);
81dfcaa2 471}
472
473DEFUN (ip_route_mask_flags,
474 ip_route_mask_flags_cmd,
e52702f2 475 "ip route A.B.C.D A.B.C.D <reject|blackhole> [tag (1-4294967295)] [(1-255)] [vrf NAME]",
0d9551dc
DS
476 IP_STR
477 "Establish static routes\n"
478 "IP destination prefix\n"
479 "IP destination prefix mask\n"
480 "Emit an ICMP unreachable when matched\n"
481 "Silently discard pkts when matched\n"
482 "Set tag for this route\n"
030721b7
DS
483 "Tag value\n"
484 "Distance value for this route\n"
e52702f2
QY
485 VRF_CMD_HELP_STR
486 "Specify labels for this route\n"
487 "One or more labels separated by '/'\n")
0d9551dc 488{
7c022376
DW
489 int idx_ipv4 = 2;
490 int idx_ipv4_2 = 3;
491 int idx_reject_blackhole = 4;
030721b7
DS
492 int idx_curr = 5;
493 char *tag, *distance, *vrf;
494
495 tag = distance = vrf = NULL;
e52702f2 496 zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
030721b7
DS
497
498 return zebra_static_ipv4 (vty, SAFI_UNICAST, 1,
499 argv[idx_ipv4]->arg,
500 argv[idx_ipv4_2]->arg,
501 NULL,
502 argv[idx_reject_blackhole]->arg,
e52702f2 503 tag, distance, vrf, NULL);
457ef551 504}
505
fb5b479d
DS
506DEFUN (no_ip_route,
507 no_ip_route_cmd,
e52702f2 508 "no ip route A.B.C.D/M <A.B.C.D|INTERFACE|null0> [tag (1-4294967295)] [(1-255)] [vrf NAME]",
8f527c5e
FL
509 NO_STR
510 IP_STR
511 "Establish static routes\n"
512 "IP destination prefix (e.g. 10.0.0.0/8)\n"
513 "IP gateway address\n"
514 "IP gateway interface name\n"
515 "Null interface\n"
516 "Tag of this route\n"
517 "Tag value\n"
518 "Distance value for this route\n"
e52702f2
QY
519 VRF_CMD_HELP_STR
520 "Specify labels for this route\n"
521 "One or more labels separated by '/'\n")
8f527c5e 522{
7c022376
DW
523 int idx_ipv4_prefixlen = 3;
524 int idx_ipv4_ifname_null = 4;
fb5b479d
DS
525 int idx_curr = 5;
526 char *tag, *distance, *vrf;
718e3744 527
fb5b479d 528 tag = distance = vrf = NULL;
e52702f2 529 zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
fb5b479d
DS
530
531 return zebra_static_ipv4 (vty, SAFI_UNICAST, 0,
532 argv[idx_ipv4_prefixlen]->arg,
533 NULL,
534 argv[idx_ipv4_ifname_null]->arg,
535 NULL,
e52702f2 536 tag, distance, vrf, NULL);
8f527c5e 537}
af41b63a 538
74d26346
QY
539DEFUN (no_ip_route_flags,
540 no_ip_route_flags_cmd,
e52702f2 541 "no ip route A.B.C.D/M <reject|blackhole> [tag (1-4294967295)] [(1-255)] [vrf NAME]",
8f527c5e 542 NO_STR
718e3744 543 IP_STR
8f527c5e
FL
544 "Establish static routes\n"
545 "IP destination prefix (e.g. 10.0.0.0/8)\n"
8f527c5e
FL
546 "Emit an ICMP unreachable when matched\n"
547 "Silently discard pkts when matched\n"
548 "Tag of this route\n"
549 "Tag value\n"
550 "Distance value for this route\n"
e52702f2
QY
551 VRF_CMD_HELP_STR
552 "Specify labels for this route\n"
553 "One or more labels separated by '/'\n")
718e3744 554{
7c022376 555 int idx_ipv4_prefixlen = 3;
fb5b479d
DS
556 int idx_curr = 5;
557 char *tag, *distance, *vrf;
718e3744 558
fb5b479d 559 tag = distance = vrf = NULL;
e52702f2 560 zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
718e3744 561
fb5b479d
DS
562 return zebra_static_ipv4 (vty, SAFI_UNICAST, 0,
563 argv[idx_ipv4_prefixlen]->arg,
564 NULL, NULL, NULL,
e52702f2 565 tag, distance, vrf, NULL);
8f527c5e 566}
af41b63a 567
fb5b479d
DS
568DEFUN (no_ip_route_mask,
569 no_ip_route_mask_cmd,
e52702f2 570 "no ip route A.B.C.D A.B.C.D <A.B.C.D|INTERFACE|null0> [tag (1-4294967295)] [(1-255)] [vrf NAME]",
8f527c5e
FL
571 NO_STR
572 IP_STR
573 "Establish static routes\n"
574 "IP destination prefix\n"
575 "IP destination prefix mask\n"
576 "IP gateway address\n"
577 "IP gateway interface name\n"
578 "Null interface\n"
fb5b479d
DS
579 "Tag of this route\n"
580 "Tag value\n"
8f527c5e 581 "Distance value for this route\n"
e52702f2
QY
582 VRF_CMD_HELP_STR
583 "Specify labels for this route\n"
584 "One or more labels separated by '/'\n")
8f527c5e 585{
7c022376
DW
586 int idx_ipv4 = 3;
587 int idx_ipv4_2 = 4;
588 int idx_ipv4_ifname_null = 5;
fb5b479d
DS
589 int idx_curr = 6;
590 char *tag, *distance, *vrf;
591
592 tag = distance = vrf = NULL;
e52702f2 593 zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
fb5b479d
DS
594
595 return zebra_static_ipv4 (vty, SAFI_UNICAST, 0,
596 argv[idx_ipv4]->arg,
597 argv[idx_ipv4_2]->arg,
598 argv[idx_ipv4_ifname_null]->arg,
599 NULL,
e52702f2 600 tag, distance, vrf, NULL);
8f527c5e 601}
718e3744 602
74d26346
QY
603DEFUN (no_ip_route_mask_flags,
604 no_ip_route_mask_flags_cmd,
e52702f2 605 "no ip route A.B.C.D A.B.C.D <reject|blackhole> [tag (1-4294967295)] [(1-255)] [vrf NAME]",
8f527c5e
FL
606 NO_STR
607 IP_STR
608 "Establish static routes\n"
609 "IP destination prefix\n"
610 "IP destination prefix mask\n"
fb5b479d
DS
611 "Emit an ICMP unreachable when matched\n"
612 "Silently discard pkts when matched\n"
8f527c5e
FL
613 "Tag of this route\n"
614 "Tag value\n"
615 "Distance value for this route\n"
e52702f2
QY
616 VRF_CMD_HELP_STR
617 "Specify labels for this route\n"
618 "One or more labels separated by '/'\n")
8f527c5e 619{
7c022376
DW
620 int idx_ipv4 = 3;
621 int idx_ipv4_2 = 4;
fb5b479d
DS
622 int idx_curr = 6;
623 char *tag, *distance, *vrf;
624
625 tag = distance = vrf = NULL;
e52702f2 626 zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
fb5b479d
DS
627
628 return zebra_static_ipv4 (vty, SAFI_UNICAST, 0,
629 argv[idx_ipv4]->arg,
630 argv[idx_ipv4_2]->arg,
631 NULL, NULL,
e52702f2 632 tag, distance, vrf, NULL);
8f527c5e 633}
718e3744 634
8f527c5e 635/* New RIB. Detailed information for IPv4 route. */
a1ac18c4 636static void
65dd94cf 637vty_show_ip_route_detail (struct vty *vty, struct route_node *rn, int mcast)
718e3744 638{
61691c91 639 struct rib *rib;
8f527c5e
FL
640 struct nexthop *nexthop, *tnexthop;
641 int recursing;
196aecef 642 char buf[PREFIX_STRLEN];
d511d7f1 643 struct zebra_vrf *zvrf;
61691c91 644
8f527c5e 645 RNODE_FOREACH_RIB (rn, rib)
61691c91 646 {
7d20b830 647 const char *mcast_info = "";
65dd94cf
DL
648 if (mcast)
649 {
650 rib_table_info_t *info = rn->table->info;
651 mcast_info = (info->safi == SAFI_MULTICAST)
652 ? " using Multicast RIB"
653 : " using Unicast RIB";
654 }
8f527c5e 655
196aecef
TT
656 vty_out (vty, "Routing entry for %s%s%s",
657 prefix2str (&rn->p, buf, sizeof(buf)), mcast_info,
8f527c5e
FL
658 VTY_NEWLINE);
659 vty_out (vty, " Known via \"%s", zebra_route_string (rib->type));
660 if (rib->instance)
661 vty_out (vty, "[%d]", rib->instance);
662 vty_out (vty, "\"");
663 vty_out (vty, ", distance %u, metric %u", rib->distance, rib->metric);
664 if (rib->tag)
665 vty_out (vty, ", tag %d", rib->tag);
c50ca33a
TT
666 if (rib->mtu)
667 vty_out (vty, ", mtu %u", rib->mtu);
d511d7f1
DS
668 if (rib->vrf_id != VRF_DEFAULT)
669 {
670 zvrf = vrf_info_lookup(rib->vrf_id);
53dc2b05 671 vty_out (vty, ", vrf %s", zvrf_name (zvrf));
d511d7f1 672 }
8f527c5e
FL
673 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
674 vty_out (vty, ", best");
675 if (rib->refcnt)
676 vty_out (vty, ", refcnt %ld", rib->refcnt);
677 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_BLACKHOLE))
678 vty_out (vty, ", blackhole");
679 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_REJECT))
680 vty_out (vty, ", reject");
681 vty_out (vty, "%s", VTY_NEWLINE);
61691c91 682
8f527c5e
FL
683 if (rib->type == ZEBRA_ROUTE_RIP
684 || rib->type == ZEBRA_ROUTE_OSPF
8f527c5e
FL
685 || rib->type == ZEBRA_ROUTE_ISIS
686 || rib->type == ZEBRA_ROUTE_TABLE
687 || rib->type == ZEBRA_ROUTE_BGP)
688 {
689 time_t uptime;
690 struct tm *tm;
718e3744 691
8f527c5e
FL
692 uptime = time (NULL);
693 uptime -= rib->uptime;
694 tm = gmtime (&uptime);
9343ce83 695
8f527c5e 696 vty_out (vty, " Last update ");
9343ce83 697
8f527c5e 698 if (uptime < ONE_DAY_SECOND)
e52702f2 699 vty_out (vty, "%02d:%02d:%02d",
8f527c5e
FL
700 tm->tm_hour, tm->tm_min, tm->tm_sec);
701 else if (uptime < ONE_WEEK_SECOND)
e52702f2 702 vty_out (vty, "%dd%02dh%02dm",
8f527c5e 703 tm->tm_yday, tm->tm_hour, tm->tm_min);
9343ce83 704 else
e52702f2 705 vty_out (vty, "%02dw%dd%02dh",
8f527c5e
FL
706 tm->tm_yday/7,
707 tm->tm_yday - ((tm->tm_yday/7) * 7), tm->tm_hour);
708 vty_out (vty, " ago%s", VTY_NEWLINE);
709 }
710
711 for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
712 {
713 char addrstr[32];
714
715 vty_out (vty, " %c%s",
716 CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB) ? '*' : ' ',
717 recursing ? " " : "");
718
719 switch (nexthop->type)
720 {
721 case NEXTHOP_TYPE_IPV4:
722 case NEXTHOP_TYPE_IPV4_IFINDEX:
723 vty_out (vty, " %s", inet_ntoa (nexthop->gate.ipv4));
724 if (nexthop->ifindex)
725 vty_out (vty, ", via %s",
726 ifindex2ifname_vrf (nexthop->ifindex, rib->vrf_id));
727 break;
8f527c5e
FL
728 case NEXTHOP_TYPE_IPV6:
729 case NEXTHOP_TYPE_IPV6_IFINDEX:
8f527c5e
FL
730 vty_out (vty, " %s",
731 inet_ntop (AF_INET6, &nexthop->gate.ipv6, buf, BUFSIZ));
3ee39b5b 732 if (nexthop->ifindex)
8f527c5e
FL
733 vty_out (vty, ", via %s",
734 ifindex2ifname_vrf (nexthop->ifindex, rib->vrf_id));
735 break;
8f527c5e
FL
736 case NEXTHOP_TYPE_IFINDEX:
737 vty_out (vty, " directly connected, %s",
738 ifindex2ifname_vrf (nexthop->ifindex, rib->vrf_id));
739 break;
196aecef
TT
740 case NEXTHOP_TYPE_BLACKHOLE:
741 vty_out (vty, " directly connected, Null0");
742 break;
743 default:
8f527c5e
FL
744 break;
745 }
746 if (! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
747 vty_out (vty, " inactive");
748
749 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ONLINK))
750 vty_out (vty, " onlink");
751
752 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
753 vty_out (vty, " (recursive)");
754
755 switch (nexthop->type)
756 {
757 case NEXTHOP_TYPE_IPV4:
758 case NEXTHOP_TYPE_IPV4_IFINDEX:
8f527c5e
FL
759 if (nexthop->src.ipv4.s_addr)
760 {
761 if (inet_ntop(AF_INET, &nexthop->src.ipv4, addrstr,
762 sizeof addrstr))
763 vty_out (vty, ", src %s", addrstr);
764 }
765 break;
8f527c5e
FL
766 case NEXTHOP_TYPE_IPV6:
767 case NEXTHOP_TYPE_IPV6_IFINDEX:
8f527c5e
FL
768 if (!IPV6_ADDR_SAME(&nexthop->src.ipv6, &in6addr_any))
769 {
770 if (inet_ntop(AF_INET6, &nexthop->src.ipv6, addrstr,
771 sizeof addrstr))
772 vty_out (vty, ", src %s", addrstr);
773 }
774 break;
8f527c5e
FL
775 default:
776 break;
777 }
e5dd4bef
RW
778
779 /* Label information */
780 if (nexthop->nh_label && nexthop->nh_label->num_labels)
781 {
782 vty_out (vty, " label %s",
783 mpls_label2str (nexthop->nh_label->num_labels,
784 nexthop->nh_label->label, buf, BUFSIZ));
785 }
786
8f527c5e
FL
787 vty_out (vty, "%s", VTY_NEWLINE);
788 }
789 vty_out (vty, "%s", VTY_NEWLINE);
790 }
791}
792
793static void
18a4ded2
DW
794vty_show_ip_route (struct vty *vty, struct route_node *rn, struct rib *rib,
795 json_object *json)
8f527c5e
FL
796{
797 struct nexthop *nexthop, *tnexthop;
798 int recursing;
799 int len = 0;
800 char buf[BUFSIZ];
18a4ded2
DW
801 json_object *json_nexthops = NULL;
802 json_object *json_nexthop = NULL;
803 json_object *json_route = NULL;
804
805 if (json)
806 {
807 json_route = json_object_new_object();
808 json_nexthops = json_object_new_array();
809
810 json_object_string_add(json_route, "prefix", prefix2str (&rn->p, buf, sizeof buf));
811 json_object_string_add(json_route, "protocol", zebra_route_string(rib->type));
812
813 if (rib->instance)
814 json_object_int_add(json_route, "instance", rib->instance);
815
816 if (rib->vrf_id)
817 json_object_int_add(json_route, "vrfId", rib->vrf_id);
818
819 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
820 json_object_boolean_true_add(json_route, "selected");
821
822 if (rib->type != ZEBRA_ROUTE_CONNECT && rib->type != ZEBRA_ROUTE_KERNEL)
823 {
824 json_object_int_add(json_route, "distance", rib->distance);
825 json_object_int_add(json_route, "metric", rib->metric);
826 }
827
828 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_BLACKHOLE))
829 json_object_boolean_true_add(json_route, "blackhole");
830
831 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_REJECT))
832 json_object_boolean_true_add(json_route, "reject");
833
834 if (rib->type == ZEBRA_ROUTE_RIP
835 || rib->type == ZEBRA_ROUTE_OSPF
836 || rib->type == ZEBRA_ROUTE_ISIS
837 || rib->type == ZEBRA_ROUTE_TABLE
838 || rib->type == ZEBRA_ROUTE_BGP)
839 {
840 time_t uptime;
841 struct tm *tm;
842
843 uptime = time (NULL);
844 uptime -= rib->uptime;
845 tm = gmtime (&uptime);
846
847 if (uptime < ONE_DAY_SECOND)
848 sprintf(buf, "%02d:%02d:%02d", tm->tm_hour, tm->tm_min, tm->tm_sec);
849 else if (uptime < ONE_WEEK_SECOND)
850 sprintf(buf, "%dd%02dh%02dm", tm->tm_yday, tm->tm_hour, tm->tm_min);
851 else
852 sprintf(buf, "%02dw%dd%02dh", tm->tm_yday/7, tm->tm_yday - ((tm->tm_yday/7) * 7), tm->tm_hour);
853
854 json_object_string_add(json_route, "uptime", buf);
855 }
856
857 for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
858 {
859 json_nexthop = json_object_new_object();
860
861 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
862 json_object_boolean_true_add(json_nexthop, "fib");
863
864 switch (nexthop->type)
865 {
866 case NEXTHOP_TYPE_IPV4:
867 case NEXTHOP_TYPE_IPV4_IFINDEX:
868 json_object_string_add(json_nexthop, "ip", inet_ntoa (nexthop->gate.ipv4));
869 json_object_string_add(json_nexthop, "afi", "ipv4");
870
871 if (nexthop->ifindex)
872 {
873 json_object_int_add(json_nexthop, "interfaceIndex", nexthop->ifindex);
874 json_object_string_add(json_nexthop, "interfaceName", ifindex2ifname_vrf (nexthop->ifindex, rib->vrf_id));
875 }
876 break;
877 case NEXTHOP_TYPE_IPV6:
878 case NEXTHOP_TYPE_IPV6_IFINDEX:
879 json_object_string_add(json_nexthop, "ip", inet_ntop (AF_INET6, &nexthop->gate.ipv6, buf, BUFSIZ));
880 json_object_string_add(json_nexthop, "afi", "ipv6");
881
882 if (nexthop->ifindex)
883 {
884 json_object_int_add(json_nexthop, "interfaceIndex", nexthop->ifindex);
885 json_object_string_add(json_nexthop, "interfaceName", ifindex2ifname_vrf (nexthop->ifindex, rib->vrf_id));
886 }
887 break;
888
889 case NEXTHOP_TYPE_IFINDEX:
890 json_object_boolean_true_add(json_nexthop, "directlyConnected");
891 json_object_int_add(json_nexthop, "interfaceIndex", nexthop->ifindex);
892 json_object_string_add(json_nexthop, "interfaceName", ifindex2ifname_vrf (nexthop->ifindex, rib->vrf_id));
893 break;
894 case NEXTHOP_TYPE_BLACKHOLE:
895 json_object_boolean_true_add(json_nexthop, "blackhole");
896 break;
897 default:
898 break;
899 }
900
901 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
902 json_object_boolean_true_add(json_nexthop, "active");
903
904 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ONLINK))
905 json_object_boolean_true_add(json_nexthop, "onLink");
906
907 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
908 json_object_boolean_true_add(json_nexthop, "recursive");
909
910 switch (nexthop->type)
911 {
912 case NEXTHOP_TYPE_IPV4:
913 case NEXTHOP_TYPE_IPV4_IFINDEX:
914 if (nexthop->src.ipv4.s_addr)
915 {
916 if (inet_ntop(AF_INET, &nexthop->src.ipv4, buf, sizeof buf))
917 json_object_string_add(json_nexthop, "source", buf);
918 }
919 break;
920 case NEXTHOP_TYPE_IPV6:
921 case NEXTHOP_TYPE_IPV6_IFINDEX:
922 if (!IPV6_ADDR_SAME(&nexthop->src.ipv6, &in6addr_any))
923 {
924 if (inet_ntop(AF_INET6, &nexthop->src.ipv6, buf, sizeof buf))
925 json_object_string_add(json_nexthop, "source", buf);
926 }
927 break;
928 default:
929 break;
930 }
931
932 json_object_array_add(json_nexthops, json_nexthop);
933 }
934
935 json_object_object_add(json_route, "nexthops", json_nexthops);
936 json_object_array_add(json, json_route);
937 return;
938 }
8f527c5e
FL
939
940 /* Nexthop information. */
941 for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
942 {
943 if (nexthop == rib->nexthop)
944 {
945 /* Prefix information. */
946 len = vty_out (vty, "%c", zebra_route_char (rib->type));
947 if (rib->instance)
948 len += vty_out (vty, "[%d]", rib->instance);
196aecef
TT
949 len += vty_out (vty, "%c%c %s",
950 CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED)
951 ? '>' : ' ',
952 CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)
953 ? '*' : ' ',
954 prefix2str (&rn->p, buf, sizeof buf));
8f527c5e
FL
955
956 /* Distance and metric display. */
e52702f2 957 if (rib->type != ZEBRA_ROUTE_CONNECT
8f527c5e
FL
958 && rib->type != ZEBRA_ROUTE_KERNEL)
959 len += vty_out (vty, " [%d/%d]", rib->distance,
960 rib->metric);
8f527c5e
FL
961 }
962 else
963 vty_out (vty, " %c%*c",
964 CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)
965 ? '*' : ' ',
966 len - 3 + (2 * recursing), ' ');
967
968 switch (nexthop->type)
969 {
970 case NEXTHOP_TYPE_IPV4:
971 case NEXTHOP_TYPE_IPV4_IFINDEX:
972 vty_out (vty, " via %s", inet_ntoa (nexthop->gate.ipv4));
973 if (nexthop->ifindex)
974 vty_out (vty, ", %s",
975 ifindex2ifname_vrf (nexthop->ifindex, rib->vrf_id));
976 break;
8f527c5e
FL
977 case NEXTHOP_TYPE_IPV6:
978 case NEXTHOP_TYPE_IPV6_IFINDEX:
8f527c5e
FL
979 vty_out (vty, " via %s",
980 inet_ntop (AF_INET6, &nexthop->gate.ipv6, buf, BUFSIZ));
3ee39b5b 981 if (nexthop->ifindex)
8f527c5e
FL
982 vty_out (vty, ", %s",
983 ifindex2ifname_vrf (nexthop->ifindex, rib->vrf_id));
984 break;
8f527c5e
FL
985
986 case NEXTHOP_TYPE_IFINDEX:
987 vty_out (vty, " is directly connected, %s",
988 ifindex2ifname_vrf (nexthop->ifindex, rib->vrf_id));
989 break;
196aecef
TT
990 case NEXTHOP_TYPE_BLACKHOLE:
991 vty_out (vty, " is directly connected, Null0");
992 break;
993 default:
8f527c5e
FL
994 break;
995 }
996 if (! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
997 vty_out (vty, " inactive");
998
999 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ONLINK))
1000 vty_out (vty, " onlink");
1001
1002 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
1003 vty_out (vty, " (recursive)");
1004
1005 switch (nexthop->type)
1006 {
1007 case NEXTHOP_TYPE_IPV4:
1008 case NEXTHOP_TYPE_IPV4_IFINDEX:
8f527c5e
FL
1009 if (nexthop->src.ipv4.s_addr)
1010 {
1011 if (inet_ntop(AF_INET, &nexthop->src.ipv4, buf, sizeof buf))
1012 vty_out (vty, ", src %s", buf);
1013 }
1014 break;
8f527c5e
FL
1015 case NEXTHOP_TYPE_IPV6:
1016 case NEXTHOP_TYPE_IPV6_IFINDEX:
8f527c5e
FL
1017 if (!IPV6_ADDR_SAME(&nexthop->src.ipv6, &in6addr_any))
1018 {
1019 if (inet_ntop(AF_INET6, &nexthop->src.ipv6, buf, sizeof buf))
1020 vty_out (vty, ", src %s", buf);
1021 }
1022 break;
8f527c5e
FL
1023 default:
1024 break;
1025 }
1026
e5dd4bef
RW
1027 /* Label information */
1028 if (nexthop->nh_label && nexthop->nh_label->num_labels)
1029 {
1030 vty_out (vty, " label %s",
1031 mpls_label2str (nexthop->nh_label->num_labels,
1032 nexthop->nh_label->label, buf, BUFSIZ));
1033 }
1034
8f527c5e
FL
1035 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_BLACKHOLE))
1036 vty_out (vty, ", bh");
1037 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_REJECT))
1038 vty_out (vty, ", rej");
1039
1040 if (rib->type == ZEBRA_ROUTE_RIP
1041 || rib->type == ZEBRA_ROUTE_OSPF
8f527c5e
FL
1042 || rib->type == ZEBRA_ROUTE_ISIS
1043 || rib->type == ZEBRA_ROUTE_TABLE
1044 || rib->type == ZEBRA_ROUTE_BGP)
1045 {
1046 time_t uptime;
1047 struct tm *tm;
1048
1049 uptime = time (NULL);
1050 uptime -= rib->uptime;
1051 tm = gmtime (&uptime);
1052
8f527c5e 1053 if (uptime < ONE_DAY_SECOND)
e52702f2 1054 vty_out (vty, ", %02d:%02d:%02d",
8f527c5e
FL
1055 tm->tm_hour, tm->tm_min, tm->tm_sec);
1056 else if (uptime < ONE_WEEK_SECOND)
e52702f2 1057 vty_out (vty, ", %dd%02dh%02dm",
8f527c5e
FL
1058 tm->tm_yday, tm->tm_hour, tm->tm_min);
1059 else
e52702f2 1060 vty_out (vty, ", %02dw%dd%02dh",
8f527c5e
FL
1061 tm->tm_yday/7,
1062 tm->tm_yday - ((tm->tm_yday/7) * 7), tm->tm_hour);
1063 }
1064 vty_out (vty, "%s", VTY_NEWLINE);
1065 }
1066}
1067
1068DEFUN (show_ip_route,
1069 show_ip_route_cmd,
b162fa78 1070 "show ip route [json]",
8f527c5e
FL
1071 SHOW_STR
1072 IP_STR
d7fa34c1 1073 "IP routing table\n"
9973d184 1074 JSON_STR)
b78a80d7 1075{
18a4ded2 1076 return do_show_ip_route (vty, VRF_DEFAULT_NAME, SAFI_UNICAST, use_json(argc, argv));
b78a80d7
EM
1077}
1078
1079static int
18a4ded2
DW
1080do_show_ip_route (struct vty *vty, const char *vrf_name, safi_t safi,
1081 u_char use_json)
8f527c5e
FL
1082{
1083 struct route_table *table;
1084 struct route_node *rn;
1085 struct rib *rib;
1086 int first = 1;
010c141f 1087 struct zebra_vrf *zvrf = NULL;
18a4ded2
DW
1088 char buf[BUFSIZ];
1089 json_object *json = NULL;
1090 json_object *json_prefix = NULL;
8f527c5e 1091
53dc2b05 1092 if (!(zvrf = zebra_vrf_lookup_by_name (vrf_name)))
010c141f 1093 {
18a4ded2
DW
1094 if (use_json)
1095 vty_out (vty, "{}%s", VTY_NEWLINE);
1096 else
1097 vty_out (vty, "vrf %s not defined%s", vrf_name, VTY_NEWLINE);
b78a80d7
EM
1098 return CMD_SUCCESS;
1099 }
010c141f 1100
53dc2b05 1101 if (zvrf_id (zvrf) == VRF_UNKNOWN)
b78a80d7 1102 {
18a4ded2
DW
1103 if (use_json)
1104 vty_out (vty, "{}%s", VTY_NEWLINE);
1105 else
1106 vty_out (vty, "vrf %s inactive%s", vrf_name, VTY_NEWLINE);
b78a80d7 1107 return CMD_SUCCESS;
010c141f 1108 }
12f6fb97 1109
53dc2b05 1110 table = zebra_vrf_table (AFI_IP, safi, zvrf_id (zvrf));
8f527c5e 1111 if (! table)
18a4ded2
DW
1112 {
1113 if (use_json)
1114 vty_out (vty, "{}%s", VTY_NEWLINE);
1115 return CMD_SUCCESS;
1116 }
1117
1118 if (use_json)
1119 {
1120 json = json_object_new_object();
1121
1122 /* Show all IPv4 routes. */
1123 for (rn = route_top (table); rn; rn = route_next (rn))
1124 {
1125 RNODE_FOREACH_RIB (rn, rib)
1126 {
1127 if (!json_prefix)
1128 json_prefix = json_object_new_array();
1129 vty_show_ip_route (vty, rn, rib, json_prefix);
1130 }
1131
1132 if (json_prefix)
1133 {
1134 prefix2str (&rn->p, buf, sizeof buf);
1135 json_object_object_add(json, buf, json_prefix);
1136 json_prefix = NULL;
1137 }
1138 }
1139
e52702f2 1140 vty_out (vty, "%s%s", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY), VTY_NEWLINE);
18a4ded2
DW
1141 json_object_free(json);
1142 }
1143 else
1144 {
1145 /* Show all IPv4 routes. */
1146 for (rn = route_top (table); rn; rn = route_next (rn))
1147 {
1148 RNODE_FOREACH_RIB (rn, rib)
1149 {
1150 if (first)
1151 {
1152 vty_out (vty, SHOW_ROUTE_V4_HEADER);
1153 first = 0;
1154 }
1155 vty_show_ip_route (vty, rn, rib, NULL);
1156 }
1157 }
1158 }
8f527c5e 1159
8f527c5e
FL
1160 return CMD_SUCCESS;
1161}
1162
abbda2d4 1163DEFUN (show_ip_route_vrf,
d511d7f1 1164 show_ip_route_vrf_cmd,
5bebf568 1165 "show ip route vrf NAME [json]",
d511d7f1
DS
1166 SHOW_STR
1167 IP_STR
1168 "IP routing table\n"
d7fa34c1 1169 VRF_CMD_HELP_STR
9973d184 1170 JSON_STR)
abbda2d4 1171{
00d7d2d3 1172 int idx_vrf = 4;
18a4ded2
DW
1173 u_char uj = use_json(argc, argv);
1174
00d7d2d3 1175 return do_show_ip_route (vty, argv[idx_vrf]->arg, SAFI_UNICAST, uj);
abbda2d4 1176}
d511d7f1 1177
8f527c5e
FL
1178DEFUN (show_ip_nht,
1179 show_ip_nht_cmd,
9bf96c84 1180 "show ip nht [vrf NAME]",
8f527c5e
FL
1181 SHOW_STR
1182 IP_STR
9bf96c84
DW
1183 "IP nexthop tracking table\n"
1184 VRF_CMD_HELP_STR)
8f527c5e 1185{
9bf96c84 1186 int idx_vrf = 4;
12f6fb97
DS
1187 vrf_id_t vrf_id = VRF_DEFAULT;
1188
9bf96c84
DW
1189 if (argc == 5)
1190 VRF_GET_ID (vrf_id, argv[idx_vrf]->arg);
12f6fb97
DS
1191
1192 zebra_print_rnh_table(vrf_id, AF_INET, vty, RNH_NEXTHOP_TYPE);
8f527c5e
FL
1193 return CMD_SUCCESS;
1194}
1195
12f6fb97 1196
d511d7f1
DS
1197DEFUN (show_ip_nht_vrf_all,
1198 show_ip_nht_vrf_all_cmd,
5bebf568 1199 "show ip nht vrf all",
d511d7f1
DS
1200 SHOW_STR
1201 IP_STR
1202 "IP nexthop tracking table\n"
1203 VRF_ALL_CMD_HELP_STR)
1204{
53dc2b05 1205 struct vrf *vrf;
d511d7f1 1206 struct zebra_vrf *zvrf;
d511d7f1 1207
53dc2b05
DL
1208 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
1209 if ((zvrf = vrf->info) != NULL)
d511d7f1 1210 {
53dc2b05
DL
1211 vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf_name (zvrf), VTY_NEWLINE);
1212 zebra_print_rnh_table(zvrf_id (zvrf), AF_INET, vty, RNH_NEXTHOP_TYPE);
d511d7f1
DS
1213 }
1214
1215 return CMD_SUCCESS;
1216}
1217
8f527c5e
FL
1218DEFUN (show_ipv6_nht,
1219 show_ipv6_nht_cmd,
9bf96c84 1220 "show ipv6 nht [vrf NAME]",
8f527c5e 1221 SHOW_STR
689e6694 1222 IPV6_STR
9bf96c84
DW
1223 "IPv6 nexthop tracking table\n"
1224 VRF_CMD_HELP_STR)
8f527c5e 1225{
9bf96c84 1226 int idx_vrf = 4;
12f6fb97
DS
1227 vrf_id_t vrf_id = VRF_DEFAULT;
1228
9bf96c84
DW
1229 if (argc == 5)
1230 VRF_GET_ID (vrf_id, argv[idx_vrf]->arg);
12f6fb97
DS
1231
1232 zebra_print_rnh_table(vrf_id, AF_INET6, vty, RNH_NEXTHOP_TYPE);
8f527c5e
FL
1233 return CMD_SUCCESS;
1234}
1235
12f6fb97 1236
d511d7f1
DS
1237DEFUN (show_ipv6_nht_vrf_all,
1238 show_ipv6_nht_vrf_all_cmd,
5bebf568 1239 "show ipv6 nht vrf all",
d511d7f1
DS
1240 SHOW_STR
1241 IP_STR
1242 "IPv6 nexthop tracking table\n"
1243 VRF_ALL_CMD_HELP_STR)
1244{
53dc2b05 1245 struct vrf *vrf;
d511d7f1 1246 struct zebra_vrf *zvrf;
d511d7f1 1247
53dc2b05
DL
1248 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
1249 if ((zvrf = vrf->info) != NULL)
d511d7f1 1250 {
53dc2b05
DL
1251 vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf_name (zvrf), VTY_NEWLINE);
1252 zebra_print_rnh_table(zvrf_id (zvrf), AF_INET6, vty, RNH_NEXTHOP_TYPE);
d511d7f1
DS
1253 }
1254
1255 return CMD_SUCCESS;
1256}
1257
8f527c5e
FL
1258DEFUN (ip_nht_default_route,
1259 ip_nht_default_route_cmd,
1260 "ip nht resolve-via-default",
1261 IP_STR
1262 "Filter Next Hop tracking route resolution\n"
1263 "Resolve via default route\n")
1264{
1265 if (zebra_rnh_ip_default_route)
1266 return CMD_SUCCESS;
1267
1268 zebra_rnh_ip_default_route = 1;
1269 zebra_evaluate_rnh(0, AF_INET, 1, RNH_NEXTHOP_TYPE, NULL);
1270 return CMD_SUCCESS;
1271}
1272
1273DEFUN (no_ip_nht_default_route,
1274 no_ip_nht_default_route_cmd,
1275 "no ip nht resolve-via-default",
1276 NO_STR
1277 IP_STR
1278 "Filter Next Hop tracking route resolution\n"
1279 "Resolve via default route\n")
1280{
1281 if (!zebra_rnh_ip_default_route)
1282 return CMD_SUCCESS;
1283
1284 zebra_rnh_ip_default_route = 0;
1285 zebra_evaluate_rnh(0, AF_INET, 1, RNH_NEXTHOP_TYPE, NULL);
1286 return CMD_SUCCESS;
1287}
1288
1289DEFUN (ipv6_nht_default_route,
1290 ipv6_nht_default_route_cmd,
1291 "ipv6 nht resolve-via-default",
1292 IP6_STR
1293 "Filter Next Hop tracking route resolution\n"
1294 "Resolve via default route\n")
1295{
1296 if (zebra_rnh_ipv6_default_route)
1297 return CMD_SUCCESS;
1298
1299 zebra_rnh_ipv6_default_route = 1;
1300 zebra_evaluate_rnh(0, AF_INET6, 1, RNH_NEXTHOP_TYPE, NULL);
1301 return CMD_SUCCESS;
1302}
1303
1304DEFUN (no_ipv6_nht_default_route,
1305 no_ipv6_nht_default_route_cmd,
1306 "no ipv6 nht resolve-via-default",
1307 NO_STR
1308 IP6_STR
1309 "Filter Next Hop tracking route resolution\n"
1310 "Resolve via default route\n")
1311{
1312 if (!zebra_rnh_ipv6_default_route)
1313 return CMD_SUCCESS;
1314
1315 zebra_rnh_ipv6_default_route = 0;
1316 zebra_evaluate_rnh(0, AF_INET6, 1, RNH_NEXTHOP_TYPE, NULL);
1317 return CMD_SUCCESS;
1318}
1319
8f527c5e
FL
1320DEFUN (show_ip_route_tag,
1321 show_ip_route_tag_cmd,
e52702f2 1322 "show ip route [vrf NAME] tag (1-4294967295)",
8f527c5e
FL
1323 SHOW_STR
1324 IP_STR
1325 "IP routing table\n"
9bf96c84 1326 VRF_CMD_HELP_STR
8f527c5e
FL
1327 "Show only routes with tag\n"
1328 "Tag value\n")
1329{
6de69f83
DW
1330 int idx_vrf = 3;
1331 int idx_name = 4;
1332 int idx_tag = 6;
8f527c5e
FL
1333 struct route_table *table;
1334 struct route_node *rn;
1335 struct rib *rib;
1336 int first = 1;
e52702f2 1337 route_tag_t tag = 0;
d511d7f1 1338 vrf_id_t vrf_id = VRF_DEFAULT;
af41b63a 1339
6de69f83 1340 if (strmatch(argv[idx_vrf]->text, "vrf"))
9bf96c84 1341 {
6de69f83 1342 VRF_GET_ID (vrf_id, argv[idx_name]->arg);
b6f1faf0 1343 VTY_GET_INTEGER_RANGE("tag", tag, argv[idx_tag]->arg, 0, 4294967295);
9bf96c84
DW
1344 }
1345 else
1346 {
6de69f83 1347 idx_tag -= 2;
b6f1faf0 1348 VTY_GET_INTEGER_RANGE("tag", tag, argv[idx_tag]->arg, 0, 4294967295);
9bf96c84 1349 }
8f527c5e 1350
d511d7f1 1351 table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id);
8f527c5e
FL
1352 if (! table)
1353 return CMD_SUCCESS;
1354
1355 /* Show all IPv4 routes with matching tag value. */
1356 for (rn = route_top (table); rn; rn = route_next (rn))
1357 RNODE_FOREACH_RIB (rn, rib)
1358 {
1359 if (rib->tag != tag)
1360 continue;
1361
1362 if (first)
1363 {
1364 vty_out (vty, SHOW_ROUTE_V4_HEADER);
1365 first = 0;
1366 }
18a4ded2 1367 vty_show_ip_route (vty, rn, rib, NULL);
8f527c5e
FL
1368 }
1369 return CMD_SUCCESS;
1370}
1371
8f527c5e
FL
1372DEFUN (show_ip_route_prefix_longer,
1373 show_ip_route_prefix_longer_cmd,
9bf96c84 1374 "show ip route [vrf NAME] A.B.C.D/M longer-prefixes",
8f527c5e
FL
1375 SHOW_STR
1376 IP_STR
1377 "IP routing table\n"
9bf96c84 1378 VRF_CMD_HELP_STR
8f527c5e
FL
1379 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1380 "Show route matching the specified Network/Mask pair only\n")
1381{
1382 struct route_table *table;
1383 struct route_node *rn;
1384 struct rib *rib;
1385 struct prefix p;
1386 int ret;
1387 int first = 1;
1388 vrf_id_t vrf_id = VRF_DEFAULT;
1389
412e5cd9 1390 if (strmatch(argv[3]->text, "vrf"))
d511d7f1 1391 {
9bf96c84
DW
1392 VRF_GET_ID (vrf_id, argv[4]->arg);
1393 ret = str2prefix (argv[5]->arg, &p);
d511d7f1
DS
1394 }
1395 else
9bf96c84
DW
1396 {
1397 ret = str2prefix (argv[3]->arg, &p);
1398 }
d511d7f1 1399
8f527c5e
FL
1400 if (! ret)
1401 {
1402 vty_out (vty, "%% Malformed Prefix%s", VTY_NEWLINE);
1403 return CMD_WARNING;
1404 }
1405
8f527c5e
FL
1406 table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id);
1407 if (! table)
1408 return CMD_SUCCESS;
1409
1410 /* Show matched type IPv4 routes. */
1411 for (rn = route_top (table); rn; rn = route_next (rn))
1412 RNODE_FOREACH_RIB (rn, rib)
1413 if (prefix_match (&p, &rn->p))
1414 {
1415 if (first)
1416 {
1417 vty_out (vty, SHOW_ROUTE_V4_HEADER);
1418 first = 0;
1419 }
18a4ded2 1420 vty_show_ip_route (vty, rn, rib, NULL);
8f527c5e
FL
1421 }
1422 return CMD_SUCCESS;
1423}
1424
8f527c5e
FL
1425DEFUN (show_ip_route_supernets,
1426 show_ip_route_supernets_cmd,
9bf96c84 1427 "show ip route [vrf NAME] supernets-only",
8f527c5e
FL
1428 SHOW_STR
1429 IP_STR
1430 "IP routing table\n"
9bf96c84 1431 VRF_CMD_HELP_STR
8f527c5e
FL
1432 "Show supernet entries only\n")
1433{
1434 struct route_table *table;
1435 struct route_node *rn;
1436 struct rib *rib;
1437 u_int32_t addr;
1438 int first = 1;
1439 vrf_id_t vrf_id = VRF_DEFAULT;
1440
412e5cd9 1441 if (strmatch(argv[3]->text, "vrf"))
9bf96c84 1442 VRF_GET_ID (vrf_id, argv[4]->arg);
8f527c5e
FL
1443
1444 table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id);
1445 if (! table)
1446 return CMD_SUCCESS;
1447
1448 /* Show matched type IPv4 routes. */
1449 for (rn = route_top (table); rn; rn = route_next (rn))
1450 RNODE_FOREACH_RIB (rn, rib)
1451 {
1452 addr = ntohl (rn->p.u.prefix4.s_addr);
1453
1454 if ((IN_CLASSC (addr) && rn->p.prefixlen < 24)
1455 || (IN_CLASSB (addr) && rn->p.prefixlen < 16)
1456 || (IN_CLASSA (addr) && rn->p.prefixlen < 8))
1457 {
1458 if (first)
1459 {
1460 vty_out (vty, SHOW_ROUTE_V4_HEADER);
1461 first = 0;
1462 }
18a4ded2 1463 vty_show_ip_route (vty, rn, rib, NULL);
8f527c5e
FL
1464 }
1465 }
1466 return CMD_SUCCESS;
1467}
1468
8f527c5e
FL
1469DEFUN (show_ip_route_protocol,
1470 show_ip_route_protocol_cmd,
40d1cbfb 1471 "show ip route [vrf NAME] " FRR_IP_REDIST_STR_ZEBRA,
8f527c5e
FL
1472 SHOW_STR
1473 IP_STR
1474 "IP routing table\n"
9bf96c84 1475 VRF_CMD_HELP_STR
3b14d86e 1476 FRR_IP_REDIST_HELP_STR_ZEBRA)
8f527c5e
FL
1477{
1478 int type;
1479 struct route_table *table;
1480 struct route_node *rn;
1481 struct rib *rib;
1482 int first = 1;
1483 vrf_id_t vrf_id = VRF_DEFAULT;
1484
6d681bd8
QY
1485 int idx = 0;
1486 if (argv_find (argv, argc, "NAME", &idx))
1487 VRF_GET_ID (vrf_id, argv[idx]->arg);
1488
1489 char *proto = argv[argc - 1]->text;
1490 type = proto_redistnum (AFI_IP, proto);
d511d7f1 1491
8f527c5e
FL
1492 if (type < 0)
1493 {
1494 vty_out (vty, "Unknown route type%s", VTY_NEWLINE);
1495 return CMD_WARNING;
1496 }
1497
8f527c5e
FL
1498 table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id);
1499 if (! table)
1500 return CMD_SUCCESS;
1501
1502 /* Show matched type IPv4 routes. */
1503 for (rn = route_top (table); rn; rn = route_next (rn))
1504 RNODE_FOREACH_RIB (rn, rib)
1505 if (rib->type == type)
1506 {
1507 if (first)
1508 {
1509 vty_out (vty, SHOW_ROUTE_V4_HEADER);
1510 first = 0;
1511 }
18a4ded2 1512 vty_show_ip_route (vty, rn, rib, NULL);
8f527c5e
FL
1513 }
1514 return CMD_SUCCESS;
1515}
1516
8f527c5e
FL
1517
1518DEFUN (show_ip_route_ospf_instance,
1519 show_ip_route_ospf_instance_cmd,
6147e2c6 1520 "show ip route ospf (1-65535)",
8f527c5e
FL
1521 SHOW_STR
1522 IP_STR
1523 "IP routing table\n"
1524 "Open Shortest Path First (OSPFv2)\n"
1525 "Instance ID\n")
1526{
7c022376 1527 int idx_number = 4;
8f527c5e
FL
1528 struct route_table *table;
1529 struct route_node *rn;
1530 struct rib *rib;
1531 int first = 1;
1532 u_short instance = 0;
1533
7c022376 1534 VTY_GET_INTEGER ("Instance", instance, argv[idx_number]->arg);
8f527c5e
FL
1535
1536 table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, VRF_DEFAULT);
1537 if (! table)
1538 return CMD_SUCCESS;
1539
1540 /* Show matched type IPv4 routes. */
1541 for (rn = route_top (table); rn; rn = route_next (rn))
1542 RNODE_FOREACH_RIB (rn, rib)
1543 if (rib->type == ZEBRA_ROUTE_OSPF && rib->instance == instance)
1544 {
1545 if (first)
1546 {
1547 vty_out (vty, SHOW_ROUTE_V4_HEADER);
1548 first = 0;
1549 }
18a4ded2 1550 vty_show_ip_route (vty, rn, rib, NULL);
8f527c5e
FL
1551 }
1552 return CMD_SUCCESS;
1553}
1554
1555DEFUN (show_ip_route_addr,
1556 show_ip_route_addr_cmd,
9bf96c84 1557 "show ip route [vrf NAME] A.B.C.D",
8f527c5e
FL
1558 SHOW_STR
1559 IP_STR
1560 "IP routing table\n"
9bf96c84 1561 VRF_CMD_HELP_STR
8f527c5e
FL
1562 "Network in the IP routing table to display\n")
1563{
1564 int ret;
1565 struct prefix_ipv4 p;
1566 struct route_table *table;
1567 struct route_node *rn;
1568 vrf_id_t vrf_id = VRF_DEFAULT;
1569
412e5cd9 1570 if (strmatch(argv[3]->text, "vrf"))
d511d7f1 1571 {
9bf96c84
DW
1572 VRF_GET_ID (vrf_id, argv[4]->arg);
1573 ret = str2prefix_ipv4 (argv[5]->arg, &p);
d511d7f1
DS
1574 }
1575 else
9bf96c84
DW
1576 {
1577 ret = str2prefix_ipv4 (argv[3]->arg, &p);
1578 }
d511d7f1 1579
8f527c5e
FL
1580 if (ret <= 0)
1581 {
1582 vty_out (vty, "%% Malformed IPv4 address%s", VTY_NEWLINE);
1583 return CMD_WARNING;
1584 }
1585
8f527c5e
FL
1586 table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id);
1587 if (! table)
1588 return CMD_SUCCESS;
1589
1590 rn = route_node_match (table, (struct prefix *) &p);
1591 if (! rn)
1592 {
1593 vty_out (vty, "%% Network not in table%s", VTY_NEWLINE);
1594 return CMD_WARNING;
1595 }
1596
65dd94cf 1597 vty_show_ip_route_detail (vty, rn, 0);
8f527c5e
FL
1598
1599 route_unlock_node (rn);
1600
1601 return CMD_SUCCESS;
1602}
1603
8f527c5e
FL
1604DEFUN (show_ip_route_prefix,
1605 show_ip_route_prefix_cmd,
9bf96c84 1606 "show ip route [vrf NAME] A.B.C.D/M",
8f527c5e
FL
1607 SHOW_STR
1608 IP_STR
1609 "IP routing table\n"
9bf96c84 1610 VRF_CMD_HELP_STR
8f527c5e
FL
1611 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n")
1612{
1613 int ret;
1614 struct prefix_ipv4 p;
1615 struct route_table *table;
1616 struct route_node *rn;
1617 vrf_id_t vrf_id = VRF_DEFAULT;
1618
412e5cd9 1619 if (strmatch(argv[3]->text, "vrf"))
d511d7f1 1620 {
9bf96c84
DW
1621 VRF_GET_ID (vrf_id, argv[4]->arg);
1622 ret = str2prefix_ipv4 (argv[5]->arg, &p);
d511d7f1
DS
1623 }
1624 else
9bf96c84
DW
1625 {
1626 ret = str2prefix_ipv4 (argv[3]->arg, &p);
1627 }
d511d7f1 1628
8f527c5e
FL
1629 if (ret <= 0)
1630 {
1631 vty_out (vty, "%% Malformed IPv4 address%s", VTY_NEWLINE);
1632 return CMD_WARNING;
1633 }
1634
8f527c5e
FL
1635 table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id);
1636 if (! table)
1637 return CMD_SUCCESS;
1638
1639 rn = route_node_match (table, (struct prefix *) &p);
1640 if (! rn || rn->p.prefixlen != p.prefixlen)
1641 {
1642 vty_out (vty, "%% Network not in table%s", VTY_NEWLINE);
1643 return CMD_WARNING;
1644 }
1645
65dd94cf 1646 vty_show_ip_route_detail (vty, rn, 0);
8f527c5e
FL
1647
1648 route_unlock_node (rn);
1649
1650 return CMD_SUCCESS;
1651}
1652
8f527c5e
FL
1653
1654static void
1655vty_show_ip_route_summary (struct vty *vty, struct route_table *table)
1656{
1657 struct route_node *rn;
1658 struct rib *rib;
8f527c5e
FL
1659#define ZEBRA_ROUTE_IBGP ZEBRA_ROUTE_MAX
1660#define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1)
1661 u_int32_t rib_cnt[ZEBRA_ROUTE_TOTAL + 1];
1662 u_int32_t fib_cnt[ZEBRA_ROUTE_TOTAL + 1];
1663 u_int32_t i;
1ff0858e 1664 u_int32_t is_ibgp;
8f527c5e
FL
1665
1666 memset (&rib_cnt, 0, sizeof(rib_cnt));
1667 memset (&fib_cnt, 0, sizeof(fib_cnt));
1668 for (rn = route_top (table); rn; rn = route_next (rn))
1669 RNODE_FOREACH_RIB (rn, rib)
1ff0858e
DD
1670 {
1671 is_ibgp = (rib->type == ZEBRA_ROUTE_BGP &&
1672 CHECK_FLAG (rib->flags, ZEBRA_FLAG_IBGP));
1673
1674 rib_cnt[ZEBRA_ROUTE_TOTAL]++;
1675 if (is_ibgp)
1676 rib_cnt[ZEBRA_ROUTE_IBGP]++;
1677 else
1678 rib_cnt[rib->type]++;
1679
1680 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
1681 {
1682 fib_cnt[ZEBRA_ROUTE_TOTAL]++;
1683
1684 if (is_ibgp)
1685 fib_cnt[ZEBRA_ROUTE_IBGP]++;
1686 else
1687 fib_cnt[rib->type]++;
1688 }
1689 }
8f527c5e 1690
5fe74770 1691 vty_out (vty, "%-20s %-20s %s (vrf %s)%s",
8f527c5e 1692 "Route Source", "Routes", "FIB",
53dc2b05 1693 zvrf_name (((rib_table_info_t *)table->info)->zvrf),
8f527c5e
FL
1694 VTY_NEWLINE);
1695
1ff0858e 1696 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
8f527c5e 1697 {
3ff86133
DS
1698 if ((rib_cnt[i] > 0) ||
1699 (i == ZEBRA_ROUTE_BGP && rib_cnt[ZEBRA_ROUTE_IBGP] > 0))
1ff0858e
DD
1700 {
1701 if (i == ZEBRA_ROUTE_BGP)
1702 {
1703 vty_out (vty, "%-20s %-20d %-20d %s", "ebgp",
00cbc1f5 1704 rib_cnt[ZEBRA_ROUTE_BGP], fib_cnt[ZEBRA_ROUTE_BGP],
1ff0858e
DD
1705 VTY_NEWLINE);
1706 vty_out (vty, "%-20s %-20d %-20d %s", "ibgp",
1707 rib_cnt[ZEBRA_ROUTE_IBGP], fib_cnt[ZEBRA_ROUTE_IBGP],
1708 VTY_NEWLINE);
1709 }
1710 else
1711 vty_out (vty, "%-20s %-20d %-20d %s", zebra_route_string(i),
1712 rib_cnt[i], fib_cnt[i], VTY_NEWLINE);
1713 }
8f527c5e
FL
1714 }
1715
1716 vty_out (vty, "------%s", VTY_NEWLINE);
1ff0858e
DD
1717 vty_out (vty, "%-20s %-20d %-20d %s", "Totals", rib_cnt[ZEBRA_ROUTE_TOTAL],
1718 fib_cnt[ZEBRA_ROUTE_TOTAL], VTY_NEWLINE);
8f527c5e
FL
1719 vty_out (vty, "%s", VTY_NEWLINE);
1720}
1721
1722/*
1723 * Implementation of the ip route summary prefix command.
1724 *
1725 * This command prints the primary prefixes that have been installed by various
1726 * protocols on the box.
1727 *
1728 */
1729static void
1730vty_show_ip_route_summary_prefix (struct vty *vty, struct route_table *table)
1731{
1732 struct route_node *rn;
1733 struct rib *rib;
1734 struct nexthop *nexthop;
1735#define ZEBRA_ROUTE_IBGP ZEBRA_ROUTE_MAX
1736#define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1)
1737 u_int32_t rib_cnt[ZEBRA_ROUTE_TOTAL + 1];
1738 u_int32_t fib_cnt[ZEBRA_ROUTE_TOTAL + 1];
1739 u_int32_t i;
1740 int cnt;
1741
1742 memset (&rib_cnt, 0, sizeof(rib_cnt));
1743 memset (&fib_cnt, 0, sizeof(fib_cnt));
1744 for (rn = route_top (table); rn; rn = route_next (rn))
1745 RNODE_FOREACH_RIB (rn, rib)
1746 {
1747
1748 /*
1749 * In case of ECMP, count only once.
1750 */
1751 cnt = 0;
1752 for (nexthop = rib->nexthop; (!cnt && nexthop); nexthop = nexthop->next)
1753 {
1754 cnt++;
1755 rib_cnt[ZEBRA_ROUTE_TOTAL]++;
1756 rib_cnt[rib->type]++;
9343ce83
DS
1757 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
1758 {
1759 fib_cnt[ZEBRA_ROUTE_TOTAL]++;
1760 fib_cnt[rib->type]++;
1761 }
1762 if (rib->type == ZEBRA_ROUTE_BGP &&
1763 CHECK_FLAG (rib->flags, ZEBRA_FLAG_IBGP))
1764 {
1765 rib_cnt[ZEBRA_ROUTE_IBGP]++;
1766 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
1767 fib_cnt[ZEBRA_ROUTE_IBGP]++;
1768 }
1769 }
1770 }
1771
d511d7f1 1772 vty_out (vty, "%-20s %-20s %s (vrf %s)%s",
af41b63a 1773 "Route Source", "Prefix Routes", "FIB",
53dc2b05 1774 zvrf_name (((rib_table_info_t *)table->info)->zvrf),
af41b63a 1775 VTY_NEWLINE);
9343ce83
DS
1776
1777 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
1778 {
1779 if (rib_cnt[i] > 0)
1780 {
1781 if (i == ZEBRA_ROUTE_BGP)
1782 {
1783 vty_out (vty, "%-20s %-20d %-20d %s", "ebgp",
1784 rib_cnt[ZEBRA_ROUTE_BGP] - rib_cnt[ZEBRA_ROUTE_IBGP],
1785 fib_cnt[ZEBRA_ROUTE_BGP] - fib_cnt[ZEBRA_ROUTE_IBGP],
1786 VTY_NEWLINE);
1787 vty_out (vty, "%-20s %-20d %-20d %s", "ibgp",
1788 rib_cnt[ZEBRA_ROUTE_IBGP], fib_cnt[ZEBRA_ROUTE_IBGP],
1789 VTY_NEWLINE);
1790 }
1791 else
1792 vty_out (vty, "%-20s %-20d %-20d %s", zebra_route_string(i),
1793 rib_cnt[i], fib_cnt[i], VTY_NEWLINE);
1794 }
1795 }
1796
1797 vty_out (vty, "------%s", VTY_NEWLINE);
1798 vty_out (vty, "%-20s %-20d %-20d %s", "Totals", rib_cnt[ZEBRA_ROUTE_TOTAL],
1799 fib_cnt[ZEBRA_ROUTE_TOTAL], VTY_NEWLINE);
af41b63a 1800 vty_out (vty, "%s", VTY_NEWLINE);
9343ce83
DS
1801}
1802
718e3744 1803/* Show route summary. */
1804DEFUN (show_ip_route_summary,
1805 show_ip_route_summary_cmd,
9bf96c84 1806 "show ip route [vrf NAME] summary",
718e3744 1807 SHOW_STR
1808 IP_STR
1809 "IP routing table\n"
9bf96c84 1810 VRF_CMD_HELP_STR
718e3744 1811 "Summary of all routes\n")
1812{
61691c91 1813 struct route_table *table;
af41b63a 1814 vrf_id_t vrf_id = VRF_DEFAULT;
718e3744 1815
412e5cd9 1816 if (strmatch(argv[3]->text, "vrf"))
9bf96c84 1817 VRF_GET_ID (vrf_id, argv[4]->arg);
af41b63a
FL
1818
1819 table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id);
61691c91
ST
1820 if (! table)
1821 return CMD_SUCCESS;
718e3744 1822
61691c91 1823 vty_show_ip_route_summary (vty, table);
718e3744 1824
1825 return CMD_SUCCESS;
1826}
1827
9343ce83
DS
1828/* Show route summary prefix. */
1829DEFUN (show_ip_route_summary_prefix,
1830 show_ip_route_summary_prefix_cmd,
9bf96c84 1831 "show ip route [vrf NAME] summary prefix",
9343ce83
DS
1832 SHOW_STR
1833 IP_STR
1834 "IP routing table\n"
9bf96c84 1835 VRF_CMD_HELP_STR
9343ce83
DS
1836 "Summary of all routes\n"
1837 "Prefix routes\n")
1838{
1839 struct route_table *table;
af41b63a 1840 vrf_id_t vrf_id = VRF_DEFAULT;
9343ce83 1841
412e5cd9 1842 if (strmatch(argv[3]->text, "vrf"))
9bf96c84 1843 VRF_GET_ID (vrf_id, argv[4]->arg);
af41b63a
FL
1844
1845 table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id);
9343ce83
DS
1846 if (! table)
1847 return CMD_SUCCESS;
1848
1849 vty_show_ip_route_summary_prefix (vty, table);
1850
1851 return CMD_SUCCESS;
1852}
1853
af41b63a
FL
1854
1855DEFUN (show_ip_route_vrf_all,
1856 show_ip_route_vrf_all_cmd,
5bebf568 1857 "show ip route vrf all",
af41b63a
FL
1858 SHOW_STR
1859 IP_STR
1860 "IP routing table\n"
1861 VRF_ALL_CMD_HELP_STR)
1862{
1863 struct route_table *table;
1864 struct route_node *rn;
1865 struct rib *rib;
53dc2b05 1866 struct vrf *vrf;
af41b63a 1867 struct zebra_vrf *zvrf;
af41b63a 1868 int first = 1;
d511d7f1 1869 int vrf_header = 1;
af41b63a 1870
53dc2b05 1871 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
af41b63a 1872 {
53dc2b05 1873 if ((zvrf = vrf->info) == NULL ||
af41b63a
FL
1874 (table = zvrf->table[AFI_IP][SAFI_UNICAST]) == NULL)
1875 continue;
1876
8f527c5e
FL
1877 /* Show all IPv4 routes. */
1878 for (rn = route_top (table); rn; rn = route_next (rn))
1879 RNODE_FOREACH_RIB (rn, rib)
1880 {
1881 if (first)
1882 {
1883 vty_out (vty, SHOW_ROUTE_V4_HEADER);
1884 first = 0;
1885 }
d511d7f1
DS
1886
1887 if (vrf_header)
1888 {
53dc2b05 1889 vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf_name (zvrf), VTY_NEWLINE);
d511d7f1
DS
1890 vrf_header = 0;
1891 }
18a4ded2 1892 vty_show_ip_route (vty, rn, rib, NULL);
8f527c5e 1893 }
d511d7f1 1894 vrf_header = 1;
8f527c5e
FL
1895 }
1896
1897 return CMD_SUCCESS;
1898}
1899
d511d7f1
DS
1900DEFUN (show_ip_route_vrf_all_tag,
1901 show_ip_route_vrf_all_tag_cmd,
e52702f2 1902 "show ip route vrf all tag (1-4294967295)",
8f527c5e
FL
1903 SHOW_STR
1904 IP_STR
1905 "IP routing table\n"
d511d7f1
DS
1906 VRF_ALL_CMD_HELP_STR
1907 "Show only routes with tag\n"
1908 "Tag value\n")
1909{
7c022376 1910 int idx_number = 6;
d511d7f1
DS
1911 struct route_table *table;
1912 struct route_node *rn;
1913 struct rib *rib;
53dc2b05 1914 struct vrf *vrf;
d511d7f1 1915 struct zebra_vrf *zvrf;
d511d7f1
DS
1916 int first = 1;
1917 int vrf_header = 1;
e52702f2 1918 route_tag_t tag = 0;
d511d7f1 1919
7c022376 1920 if (argv[idx_number]->arg)
b6f1faf0 1921 VTY_GET_INTEGER_RANGE("tag", tag, argv[idx_number]->arg, 0, 4294967295);
d511d7f1 1922
53dc2b05 1923 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
d511d7f1 1924 {
53dc2b05 1925 if ((zvrf = vrf->info) == NULL ||
d511d7f1
DS
1926 (table = zvrf->table[AFI_IP][SAFI_UNICAST]) == NULL)
1927 continue;
1928
1929 /* Show all IPv4 routes with matching tag value. */
1930 for (rn = route_top (table); rn; rn = route_next (rn))
1931 RNODE_FOREACH_RIB (rn, rib)
1932 {
1933 if (rib->tag != tag)
1934 continue;
1935
1936 if (first)
1937 {
1938 vty_out (vty, SHOW_ROUTE_V4_HEADER);
1939 first = 0;
1940 }
1941
1942 if (vrf_header)
1943 {
53dc2b05 1944 vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf_name (zvrf), VTY_NEWLINE);
d511d7f1
DS
1945 vrf_header = 0;
1946 }
18a4ded2 1947 vty_show_ip_route (vty, rn, rib, NULL);
d511d7f1
DS
1948 }
1949 vrf_header = 1;
1950 }
1951 return CMD_SUCCESS;
1952}
1953
1954DEFUN (show_ip_route_vrf_all_prefix_longer,
1955 show_ip_route_vrf_all_prefix_longer_cmd,
5bebf568 1956 "show ip route vrf all A.B.C.D/M longer-prefixes",
d511d7f1
DS
1957 SHOW_STR
1958 IP_STR
1959 "IP routing table\n"
1960 VRF_ALL_CMD_HELP_STR
8f527c5e 1961 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
d511d7f1 1962 "Show route matching the specified Network/Mask pair only\n")
8f527c5e 1963{
7c022376 1964 int idx_ipv4_prefixlen = 5;
8f527c5e
FL
1965 struct route_table *table;
1966 struct route_node *rn;
1967 struct rib *rib;
1968 struct prefix p;
53dc2b05 1969 struct vrf *vrf;
8f527c5e 1970 struct zebra_vrf *zvrf;
8f527c5e
FL
1971 int ret;
1972 int first = 1;
d511d7f1 1973 int vrf_header = 1;
8f527c5e 1974
7c022376 1975 ret = str2prefix (argv[idx_ipv4_prefixlen]->arg, &p);
8f527c5e
FL
1976 if (! ret)
1977 {
1978 vty_out (vty, "%% Malformed Prefix%s", VTY_NEWLINE);
1979 return CMD_WARNING;
1980 }
1981
53dc2b05 1982 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
8f527c5e 1983 {
53dc2b05 1984 if ((zvrf = vrf->info) == NULL ||
8f527c5e
FL
1985 (table = zvrf->table[AFI_IP][SAFI_UNICAST]) == NULL)
1986 continue;
1987
1988 /* Show matched type IPv4 routes. */
1989 for (rn = route_top (table); rn; rn = route_next (rn))
1990 RNODE_FOREACH_RIB (rn, rib)
1991 if (prefix_match (&p, &rn->p))
1992 {
1993 if (first)
1994 {
1995 vty_out (vty, SHOW_ROUTE_V4_HEADER);
1996 first = 0;
1997 }
d511d7f1
DS
1998
1999 if (vrf_header)
2000 {
53dc2b05 2001 vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf_name (zvrf), VTY_NEWLINE);
d511d7f1
DS
2002 vrf_header = 0;
2003 }
18a4ded2 2004 vty_show_ip_route (vty, rn, rib, NULL);
8f527c5e 2005 }
d511d7f1 2006 vrf_header = 1;
8f527c5e
FL
2007 }
2008
2009 return CMD_SUCCESS;
2010}
2011
d511d7f1
DS
2012DEFUN (show_ip_route_vrf_all_supernets,
2013 show_ip_route_vrf_all_supernets_cmd,
5bebf568 2014 "show ip route vrf all supernets-only",
8f527c5e
FL
2015 SHOW_STR
2016 IP_STR
2017 "IP routing table\n"
d511d7f1
DS
2018 VRF_ALL_CMD_HELP_STR
2019 "Show supernet entries only\n")
8f527c5e
FL
2020{
2021 struct route_table *table;
2022 struct route_node *rn;
2023 struct rib *rib;
53dc2b05 2024 struct vrf *vrf;
8f527c5e 2025 struct zebra_vrf *zvrf;
8f527c5e
FL
2026 u_int32_t addr;
2027 int first = 1;
d511d7f1 2028 int vrf_header = 1;
8f527c5e 2029
53dc2b05 2030 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
8f527c5e 2031 {
53dc2b05 2032 if ((zvrf = vrf->info) == NULL ||
8f527c5e
FL
2033 (table = zvrf->table[AFI_IP][SAFI_UNICAST]) == NULL)
2034 continue;
2035
2036 /* Show matched type IPv4 routes. */
af41b63a
FL
2037 for (rn = route_top (table); rn; rn = route_next (rn))
2038 RNODE_FOREACH_RIB (rn, rib)
2039 {
8f527c5e
FL
2040 addr = ntohl (rn->p.u.prefix4.s_addr);
2041
2042 if ((IN_CLASSC (addr) && rn->p.prefixlen < 24)
2043 || (IN_CLASSB (addr) && rn->p.prefixlen < 16)
2044 || (IN_CLASSA (addr) && rn->p.prefixlen < 8))
af41b63a 2045 {
8f527c5e
FL
2046 if (first)
2047 {
2048 vty_out (vty, SHOW_ROUTE_V4_HEADER);
2049 first = 0;
2050 }
d511d7f1
DS
2051 if (vrf_header)
2052 {
53dc2b05 2053 vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf_name (zvrf), VTY_NEWLINE);
d511d7f1
DS
2054 vrf_header = 0;
2055 }
18a4ded2 2056 vty_show_ip_route (vty, rn, rib, NULL);
af41b63a 2057 }
af41b63a 2058 }
d511d7f1 2059 vrf_header = 1;
af41b63a
FL
2060 }
2061
2062 return CMD_SUCCESS;
2063}
2064
d511d7f1
DS
2065DEFUN (show_ip_route_vrf_all_protocol,
2066 show_ip_route_vrf_all_protocol_cmd,
40d1cbfb 2067 "show ip route vrf all " FRR_IP_REDIST_STR_ZEBRA,
af41b63a
FL
2068 SHOW_STR
2069 IP_STR
2070 "IP routing table\n"
d511d7f1 2071 VRF_ALL_CMD_HELP_STR
3b14d86e 2072 FRR_IP_REDIST_HELP_STR_ZEBRA"\n")
af41b63a 2073{
8f527c5e 2074 int type;
af41b63a
FL
2075 struct route_table *table;
2076 struct route_node *rn;
2077 struct rib *rib;
1a1a7065 2078 struct vrf *vrf;
af41b63a 2079 struct zebra_vrf *zvrf;
af41b63a 2080 int first = 1;
d511d7f1 2081 int vrf_header = 1;
af41b63a 2082
6d681bd8
QY
2083 char *proto = argv[argc - 1]->text;
2084 type = proto_redistnum (AFI_IP, proto);
2085
8f527c5e 2086 if (type < 0)
af41b63a 2087 {
8f527c5e 2088 vty_out (vty, "Unknown route type%s", VTY_NEWLINE);
af41b63a
FL
2089 return CMD_WARNING;
2090 }
2091
53dc2b05 2092 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
af41b63a 2093 {
53dc2b05 2094 if ((zvrf = vrf->info) == NULL ||
af41b63a
FL
2095 (table = zvrf->table[AFI_IP][SAFI_UNICAST]) == NULL)
2096 continue;
2097
2098 /* Show matched type IPv4 routes. */
2099 for (rn = route_top (table); rn; rn = route_next (rn))
2100 RNODE_FOREACH_RIB (rn, rib)
8f527c5e 2101 if (rib->type == type)
af41b63a
FL
2102 {
2103 if (first)
2104 {
2105 vty_out (vty, SHOW_ROUTE_V4_HEADER);
2106 first = 0;
2107 }
d511d7f1
DS
2108
2109 if (vrf_header)
2110 {
53dc2b05 2111 vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf_name (zvrf), VTY_NEWLINE);
d511d7f1
DS
2112 vrf_header = 0;
2113 }
18a4ded2 2114 vty_show_ip_route (vty, rn, rib, NULL);
af41b63a 2115 }
d511d7f1 2116 vrf_header = 1;
af41b63a
FL
2117 }
2118
2119 return CMD_SUCCESS;
2120}
2121
d511d7f1
DS
2122DEFUN (show_ip_route_vrf_all_addr,
2123 show_ip_route_vrf_all_addr_cmd,
5bebf568 2124 "show ip route vrf all A.B.C.D",
af41b63a
FL
2125 SHOW_STR
2126 IP_STR
2127 "IP routing table\n"
d511d7f1
DS
2128 VRF_ALL_CMD_HELP_STR
2129 "Network in the IP routing table to display\n")
af41b63a 2130{
7c022376 2131 int idx_ipv4 = 5;
8f527c5e
FL
2132 int ret;
2133 struct prefix_ipv4 p;
af41b63a
FL
2134 struct route_table *table;
2135 struct route_node *rn;
1a1a7065 2136 struct vrf *vrf;
af41b63a 2137 struct zebra_vrf *zvrf;
8f527c5e 2138
7c022376 2139 ret = str2prefix_ipv4 (argv[idx_ipv4]->arg, &p);
8f527c5e
FL
2140 if (ret <= 0)
2141 {
2142 vty_out (vty, "%% Malformed IPv4 address%s", VTY_NEWLINE);
2143 return CMD_WARNING;
2144 }
af41b63a 2145
53dc2b05 2146 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
af41b63a 2147 {
53dc2b05 2148 if ((zvrf = vrf->info) == NULL ||
af41b63a
FL
2149 (table = zvrf->table[AFI_IP][SAFI_UNICAST]) == NULL)
2150 continue;
2151
8f527c5e
FL
2152 rn = route_node_match (table, (struct prefix *) &p);
2153 if (! rn)
2154 continue;
2155
65dd94cf 2156 vty_show_ip_route_detail (vty, rn, 0);
8f527c5e
FL
2157
2158 route_unlock_node (rn);
2159 }
2160
2161 return CMD_SUCCESS;
2162}
2163
d511d7f1
DS
2164DEFUN (show_ip_route_vrf_all_prefix,
2165 show_ip_route_vrf_all_prefix_cmd,
5bebf568 2166 "show ip route vrf all A.B.C.D/M",
8f527c5e
FL
2167 SHOW_STR
2168 IP_STR
2169 "IP routing table\n"
d511d7f1
DS
2170 VRF_ALL_CMD_HELP_STR
2171 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n")
8f527c5e 2172{
7c022376 2173 int idx_ipv4_prefixlen = 5;
8f527c5e
FL
2174 int ret;
2175 struct prefix_ipv4 p;
2176 struct route_table *table;
2177 struct route_node *rn;
53dc2b05 2178 struct vrf *vrf;
8f527c5e 2179 struct zebra_vrf *zvrf;
8f527c5e 2180
7c022376 2181 ret = str2prefix_ipv4 (argv[idx_ipv4_prefixlen]->arg, &p);
8f527c5e
FL
2182 if (ret <= 0)
2183 {
2184 vty_out (vty, "%% Malformed IPv4 address%s", VTY_NEWLINE);
2185 return CMD_WARNING;
2186 }
2187
53dc2b05 2188 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
8f527c5e 2189 {
53dc2b05 2190 if ((zvrf = vrf->info) == NULL ||
8f527c5e
FL
2191 (table = zvrf->table[AFI_IP][SAFI_UNICAST]) == NULL)
2192 continue;
2193
2194 rn = route_node_match (table, (struct prefix *) &p);
2195 if (! rn)
2196 continue;
2197 if (rn->p.prefixlen != p.prefixlen)
2198 {
2199 route_unlock_node (rn);
2200 continue;
2201 }
2202
65dd94cf 2203 vty_show_ip_route_detail (vty, rn, 0);
8f527c5e
FL
2204
2205 route_unlock_node (rn);
2206 }
2207
2208 return CMD_SUCCESS;
2209}
2210
d511d7f1
DS
2211DEFUN (show_ip_route_vrf_all_summary,
2212 show_ip_route_vrf_all_summary_cmd,
5bebf568 2213 "show ip route vrf all summary ",
8f527c5e
FL
2214 SHOW_STR
2215 IP_STR
2216 "IP routing table\n"
d511d7f1
DS
2217 VRF_ALL_CMD_HELP_STR
2218 "Summary of all routes\n")
8f527c5e 2219{
53dc2b05 2220 struct vrf *vrf;
8f527c5e 2221 struct zebra_vrf *zvrf;
8f527c5e 2222
53dc2b05
DL
2223 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
2224 if ((zvrf = vrf->info) != NULL)
8f527c5e
FL
2225 vty_show_ip_route_summary (vty, zvrf->table[AFI_IP][SAFI_UNICAST]);
2226
2227 return CMD_SUCCESS;
2228}
2229
d511d7f1
DS
2230DEFUN (show_ip_route_vrf_all_summary_prefix,
2231 show_ip_route_vrf_all_summary_prefix_cmd,
5bebf568 2232 "show ip route vrf all summary prefix",
8f527c5e
FL
2233 SHOW_STR
2234 IP_STR
2235 "IP routing table\n"
d511d7f1 2236 VRF_ALL_CMD_HELP_STR
8f527c5e 2237 "Summary of all routes\n"
d511d7f1 2238 "Prefix routes\n")
8f527c5e 2239{
53dc2b05 2240 struct vrf *vrf;
8f527c5e 2241 struct zebra_vrf *zvrf;
8f527c5e 2242
53dc2b05
DL
2243 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
2244 if ((zvrf = vrf->info) != NULL)
8f527c5e
FL
2245 vty_show_ip_route_summary_prefix (vty, zvrf->table[AFI_IP][SAFI_UNICAST]);
2246
2247 return CMD_SUCCESS;
2248}
2249
2250/* Write IPv4 static route configuration. */
2251static int
2252static_config_ipv4 (struct vty *vty, safi_t safi, const char *cmd)
2253{
2254 struct route_node *rn;
be5e48ab 2255 struct static_route *si;
8f527c5e 2256 struct route_table *stable;
53dc2b05 2257 struct vrf *vrf;
8f527c5e 2258 struct zebra_vrf *zvrf;
d64ff607 2259 char buf[BUFSIZ];
b9f1114e 2260 int write =0;
8f527c5e 2261
53dc2b05 2262 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
8f527c5e 2263 {
53dc2b05
DL
2264 if (!(zvrf = vrf->info))
2265 continue;
c1c747a8 2266 if ((stable = zvrf->stable[AFI_IP][safi]) == NULL)
8f527c5e
FL
2267 continue;
2268
2269 for (rn = route_top (stable); rn; rn = route_next (rn))
2270 for (si = rn->info; si; si = si->next)
af41b63a 2271 {
196aecef 2272 vty_out (vty, "%s %s", cmd, prefix2str (&rn->p, buf, sizeof buf));
af41b63a 2273
8f527c5e 2274 switch (si->type)
af41b63a 2275 {
8f527c5e 2276 case STATIC_IPV4_GATEWAY:
be5e48ab 2277 vty_out (vty, " %s", inet_ntoa (si->addr.ipv4));
8f527c5e 2278 break;
ba779241 2279 case STATIC_IFINDEX:
fb148af4 2280 vty_out (vty, " %s", si->ifname);
8f527c5e 2281 break;
e9e190f2 2282 case STATIC_BLACKHOLE:
8f527c5e
FL
2283 vty_out (vty, " Null0");
2284 break;
4b2792b5
DS
2285 case STATIC_IPV6_GATEWAY:
2286 vty_out (vty, " %s", inet_ntop (AF_INET6, &si->addr.ipv6, buf, BUFSIZ));
2287 break;
2288 case STATIC_IPV6_GATEWAY_IFINDEX:
2289 vty_out (vty, " %s %s",
2290 inet_ntop (AF_INET6, &si->addr.ipv6, buf, BUFSIZ),
2291 ifindex2ifname_vrf (si->ifindex, si->vrf_id));
2292 break;
8f527c5e
FL
2293 }
2294
e9e190f2
QY
2295 /* flags are incompatible with STATIC_BLACKHOLE */
2296 if (si->type != STATIC_BLACKHOLE)
8f527c5e
FL
2297 {
2298 if (CHECK_FLAG(si->flags, ZEBRA_FLAG_REJECT))
2299 vty_out (vty, " %s", "reject");
2300
2301 if (CHECK_FLAG(si->flags, ZEBRA_FLAG_BLACKHOLE))
2302 vty_out (vty, " %s", "blackhole");
af41b63a 2303 }
8f527c5e
FL
2304
2305 if (si->tag)
d64ff607 2306 vty_out (vty, " tag %"ROUTE_TAG_PRI, si->tag);
8f527c5e
FL
2307
2308 if (si->distance != ZEBRA_STATIC_DISTANCE_DEFAULT)
2309 vty_out (vty, " %d", si->distance);
2310
2311 if (si->vrf_id != VRF_DEFAULT)
53dc2b05 2312 vty_out (vty, " vrf %s", zvrf ? zvrf_name (zvrf) : "");
8f527c5e 2313
d64ff607
QY
2314 /* Label information */
2315 if (si->snh_label.num_labels)
2316 vty_out (vty, " label %s",
2317 mpls_label2str (si->snh_label.num_labels,
2318 si->snh_label.label, buf, sizeof buf));
2319
8f527c5e
FL
2320 vty_out (vty, "%s", VTY_NEWLINE);
2321
2322 write = 1;
af41b63a
FL
2323 }
2324 }
8f527c5e
FL
2325 return write;
2326}
2327
8f527c5e 2328/* General fucntion for IPv6 static route. */
e52702f2 2329int
8f527c5e 2330static_ipv6_func (struct vty *vty, int add_cmd, const char *dest_str,
e52702f2
QY
2331 const char *gate_str, const char *ifname,
2332 const char *flag_str, const char *tag_str,
2333 const char *distance_str, const char *vrf_id_str,
2334 const char *label_str)
af41b63a
FL
2335{
2336 int ret;
8f527c5e
FL
2337 u_char distance;
2338 struct prefix p;
2339 struct in6_addr *gate = NULL;
2340 struct in6_addr gate_addr;
e9e190f2 2341 u_char type = STATIC_BLACKHOLE;
8f527c5e 2342 u_char flag = 0;
e52702f2 2343 route_tag_t tag = 0;
ba779241
DS
2344 unsigned int ifindex = 0;
2345 struct interface *ifp = NULL;
b9f1114e 2346 struct zebra_vrf *zvrf;
e52702f2
QY
2347 struct static_nh_label snh_label;
2348
8f527c5e 2349 ret = str2prefix (dest_str, &p);
af41b63a
FL
2350 if (ret <= 0)
2351 {
8f527c5e 2352 vty_out (vty, "%% Malformed address%s", VTY_NEWLINE);
af41b63a
FL
2353 return CMD_WARNING;
2354 }
2355
8f527c5e
FL
2356 /* Apply mask for given prefix. */
2357 apply_mask (&p);
af41b63a 2358
8f527c5e
FL
2359 /* Administrative distance. */
2360 if (distance_str)
2361 distance = atoi (distance_str);
2362 else
2363 distance = ZEBRA_STATIC_DISTANCE_DEFAULT;
af41b63a 2364
d64ff607
QY
2365 /* tag */
2366 if (tag_str)
b6f1faf0 2367 VTY_GET_INTEGER_RANGE("tag", tag, tag_str, 0, 4294967295);
8f527c5e 2368
8f527c5e
FL
2369 /* When gateway is valid IPv6 addrees, then gate is treated as
2370 nexthop address other case gate is treated as interface name. */
2371 ret = inet_pton (AF_INET6, gate_str, &gate_addr);
2372
21efedeb 2373 /* VRF id */
53dc2b05 2374 zvrf = zebra_vrf_lookup_by_name (vrf_id_str);
b9f1114e
DS
2375
2376 if (!zvrf)
2377 {
2378 vty_out (vty, "%% vrf %s is not defined%s", vrf_id_str, VTY_NEWLINE);
2379 return CMD_WARNING;
2380 }
21efedeb 2381
e52702f2
QY
2382 /* Labels */
2383 memset (&snh_label, 0, sizeof (struct static_nh_label));
2384 if (label_str)
2385 {
d64ff607
QY
2386 if (!mpls_enabled)
2387 {
2388 vty_out (vty, "%% MPLS not turned on in kernel, ignoring command%s",
2389 VTY_NEWLINE);
2390 return CMD_WARNING;
2391 }
e52702f2
QY
2392 if (mpls_str2label (label_str, &snh_label.num_labels,
2393 snh_label.label))
2394 {
2395 vty_out (vty, "%% Malformed label(s)%s", VTY_NEWLINE);
2396 return CMD_WARNING;
2397 }
2398 }
2399
e9e190f2
QY
2400 /* Null0 static route. */
2401 if ((gate_str != NULL) && (strncasecmp (gate_str, "Null0", strlen (gate_str)) == 0))
2402 {
2403 if (flag_str)
2404 {
2405 vty_out (vty, "%% can not have flag %s with Null0%s", flag_str, VTY_NEWLINE);
2406 return CMD_WARNING;
2407 }
2408 if (add_cmd)
2409 static_add_route (AFI_IP6, SAFI_UNICAST, type, &p, NULL, ifindex, ifname,
2410 ZEBRA_FLAG_BLACKHOLE, tag, distance, zvrf, &snh_label);
2411 else
2412 static_delete_route (AFI_IP6, SAFI_UNICAST, type, &p, NULL, ifindex, tag,
2413 distance, zvrf, &snh_label);
2414 return CMD_SUCCESS;
2415 }
2416
2417 /* Route flags */
2418 if (flag_str) {
2419 switch(flag_str[0]) {
2420 case 'r':
2421 case 'R': /* XXX */
2422 SET_FLAG (flag, ZEBRA_FLAG_REJECT);
2423 break;
2424 case 'b':
2425 case 'B': /* XXX */
2426 SET_FLAG (flag, ZEBRA_FLAG_BLACKHOLE);
2427 break;
2428 default:
2429 vty_out (vty, "%% Malformed flag %s %s", flag_str, VTY_NEWLINE);
2430 return CMD_WARNING;
2431 }
2432 }
2433
d64ff607 2434 if (ifname)
8f527c5e
FL
2435 {
2436 /* When ifname is specified. It must be come with gateway
2437 address. */
2438 if (ret != 1)
e52702f2
QY
2439 {
2440 vty_out (vty, "%% Malformed address%s", VTY_NEWLINE);
2441 return CMD_WARNING;
2442 }
ba779241 2443 type = STATIC_IPV6_GATEWAY_IFINDEX;
8f527c5e 2444 gate = &gate_addr;
53dc2b05 2445 ifp = if_lookup_by_name_vrf (ifname, zvrf_id (zvrf));
ba779241 2446 if (!ifp)
e52702f2
QY
2447 {
2448 vty_out (vty, "%% Malformed Interface name %s%s", ifname, VTY_NEWLINE);
2449 return CMD_WARNING;
2450 }
ba779241 2451 ifindex = ifp->ifindex;
8f527c5e
FL
2452 }
2453 else
2454 {
2455 if (ret == 1)
e52702f2
QY
2456 {
2457 type = STATIC_IPV6_GATEWAY;
2458 gate = &gate_addr;
2459 }
8f527c5e 2460 else
e52702f2
QY
2461 {
2462 type = STATIC_IFINDEX;
53dc2b05 2463 ifp = if_lookup_by_name_vrf (gate_str, zvrf_id (zvrf));
e52702f2
QY
2464 if (!ifp)
2465 {
2466 vty_out (vty, "%% Malformed Interface name %s%s", gate_str, VTY_NEWLINE);
a3d21ef3 2467 ifindex = IFINDEX_DELETED;
e52702f2 2468 }
a3d21ef3 2469 else
e52702f2
QY
2470 ifindex = ifp->ifindex;
2471 ifname = gate_str;
2472 }
9343ce83
DS
2473 }
2474
8f527c5e 2475 if (add_cmd)
e52702f2
QY
2476 static_add_route (AFI_IP6, SAFI_UNICAST, type, &p, (union g_addr *)gate,
2477 ifindex, ifname, flag, tag, distance, zvrf, &snh_label);
8f527c5e 2478 else
e52702f2
QY
2479 static_delete_route (AFI_IP6, SAFI_UNICAST, type, &p, (union g_addr *)gate,
2480 ifindex, tag, distance, zvrf, &snh_label);
8f527c5e 2481
af41b63a 2482 return CMD_SUCCESS;
9343ce83
DS
2483}
2484
8f527c5e
FL
2485DEFUN (ipv6_route,
2486 ipv6_route_cmd,
e9e190f2 2487 "ipv6 route X:X::X:X/M <X:X::X:X|INTERFACE|null0> [tag (1-4294967295)] [(1-255)] [vrf NAME]",
8f527c5e
FL
2488 IP_STR
2489 "Establish static routes\n"
2490 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
2491 "IPv6 gateway address\n"
2492 "IPv6 gateway interface name\n"
e9e190f2
QY
2493 "Null interface\n"
2494 "Null interface\n"
8f527c5e 2495 "Set tag for this route\n"
96121d19
DS
2496 "Tag value\n"
2497 "Distance value for this prefix\n"
e52702f2
QY
2498 VRF_CMD_HELP_STR
2499 "Specify labels for this route\n"
2500 "One or more labels separated by '/'\n")
8f527c5e 2501{
7c022376
DW
2502 int idx_ipv6_prefixlen = 2;
2503 int idx_ipv6_ifname = 3;
96121d19
DS
2504 int idx_curr = 4;
2505 char *tag, *distance, *vrf;
af41b63a 2506
96121d19 2507 tag = distance = vrf = NULL;
e52702f2 2508 zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
af41b63a 2509
96121d19
DS
2510 return static_ipv6_func (vty, 1,
2511 argv[idx_ipv6_prefixlen]->arg,
2512 argv[idx_ipv6_ifname]->arg,
2513 NULL, NULL,
e52702f2 2514 tag, distance, vrf, NULL);
8f527c5e 2515}
af41b63a 2516
96121d19
DS
2517DEFUN (ipv6_route_flags,
2518 ipv6_route_flags_cmd,
e52702f2 2519 "ipv6 route X:X::X:X/M <X:X::X:X|INTERFACE> <reject|blackhole> [tag (1-4294967295)] [(1-255)] [vrf NAME]",
8f527c5e
FL
2520 IP_STR
2521 "Establish static routes\n"
2522 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
2523 "IPv6 gateway address\n"
2524 "IPv6 gateway interface name\n"
2525 "Emit an ICMP unreachable when matched\n"
2526 "Silently discard pkts when matched\n"
8f527c5e
FL
2527 "Silently discard pkts when matched\n"
2528 "Set tag for this route\n"
2529 "Tag value\n"
96121d19 2530 "Distance value for this prefix\n"
e52702f2
QY
2531 VRF_CMD_HELP_STR
2532 "Specify labels for this route\n"
2533 "One or more labels separated by '/'\n")
8f527c5e 2534{
7c022376
DW
2535 int idx_ipv6_prefixlen = 2;
2536 int idx_ipv6_ifname = 3;
2537 int idx_reject_blackhole = 4;
96121d19
DS
2538 int idx_curr = 5;
2539 char *tag, *distance, *vrf;
718e3744 2540
96121d19 2541 tag = distance = vrf = NULL;
e52702f2 2542 zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
96121d19
DS
2543
2544 return static_ipv6_func (vty, 1,
2545 argv[idx_ipv6_prefixlen]->arg,
2546 argv[idx_ipv6_ifname]->arg,
2547 NULL,
2548 argv[idx_reject_blackhole]->arg,
e52702f2 2549 tag, distance, vrf, NULL);
8f527c5e 2550}
7021c425 2551
96121d19
DS
2552DEFUN (ipv6_route_ifname,
2553 ipv6_route_ifname_cmd,
e52702f2 2554 "ipv6 route X:X::X:X/M X:X::X:X INTERFACE [tag (1-4294967295)] [(1-255)] [vrf NAME]",
8f527c5e
FL
2555 IP_STR
2556 "Establish static routes\n"
2557 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
2558 "IPv6 gateway address\n"
2559 "IPv6 gateway interface name\n"
2560 "Set tag for this route\n"
2561 "Tag value\n"
96121d19 2562 "Distance value for this prefix\n"
e52702f2
QY
2563 VRF_CMD_HELP_STR
2564 "Specify labels for this route\n"
2565 "One or more labels separated by '/'\n")
8f527c5e 2566{
7c022376
DW
2567 int idx_ipv6_prefixlen = 2;
2568 int idx_ipv6 = 3;
2569 int idx_interface = 4;
96121d19
DS
2570 int idx_curr = 5;
2571 char *tag, *distance, *vrf;
718e3744 2572
96121d19 2573 tag = distance = vrf = NULL;
e52702f2 2574 zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
96121d19
DS
2575
2576 return static_ipv6_func (vty, 1,
2577 argv[idx_ipv6_prefixlen]->arg,
2578 argv[idx_ipv6]->arg,
2579 argv[idx_interface]->arg,
2580 NULL,
e52702f2 2581 tag, distance, vrf, NULL);
9343ce83
DS
2582}
2583
96121d19
DS
2584DEFUN (ipv6_route_ifname_flags,
2585 ipv6_route_ifname_flags_cmd,
e52702f2 2586 "ipv6 route X:X::X:X/M X:X::X:X INTERFACE <reject|blackhole> [tag (1-4294967295)] [(1-255)] [vrf NAME]",
8f527c5e
FL
2587 IP_STR
2588 "Establish static routes\n"
2589 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
2590 "IPv6 gateway address\n"
2591 "IPv6 gateway interface name\n"
2592 "Emit an ICMP unreachable when matched\n"
2593 "Silently discard pkts when matched\n"
2594 "Set tag for this route\n"
2595 "Tag value\n"
96121d19 2596 "Distance value for this prefix\n"
e52702f2
QY
2597 VRF_CMD_HELP_STR
2598 "Specify labels for this route\n"
2599 "One or more labels separated by '/'\n")
718e3744 2600{
7c022376
DW
2601 int idx_ipv6_prefixlen = 2;
2602 int idx_ipv6 = 3;
2603 int idx_interface = 4;
2604 int idx_reject_blackhole = 5;
96121d19
DS
2605 int idx_curr = 6;
2606 char *tag, *distance, *vrf;
2607
2608 tag = distance = vrf = NULL;
e52702f2 2609 zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
96121d19
DS
2610
2611 return static_ipv6_func (vty, 1,
2612 argv[idx_ipv6_prefixlen]->arg,
2613 argv[idx_ipv6]->arg,
2614 argv[idx_interface]->arg,
2615 argv[idx_reject_blackhole]->arg,
e52702f2 2616 tag, distance, vrf, NULL);
8f527c5e 2617}
7021c425 2618
8f527c5e
FL
2619DEFUN (no_ipv6_route,
2620 no_ipv6_route_cmd,
e9e190f2 2621 "no ipv6 route X:X::X:X/M <X:X::X:X|INTERFACE|null0> [tag (1-4294967295)] [(1-255)] [vrf NAME]",
81dfcaa2 2622 NO_STR
2623 IP_STR
2624 "Establish static routes\n"
2625 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
2626 "IPv6 gateway address\n"
2627 "IPv6 gateway interface name\n"
e9e190f2 2628 "Null interface\n"
0d9551dc 2629 "Set tag for this route\n"
8f527c5e 2630 "Tag value\n"
8f527c5e 2631 "Distance value for this prefix\n"
e52702f2
QY
2632 VRF_CMD_HELP_STR
2633 "Specify labels for this route\n"
2634 "One or more labels separated by '/'\n")
718e3744 2635{
7c022376
DW
2636 int idx_ipv6_prefixlen = 3;
2637 int idx_ipv6_ifname = 4;
28dadafc
DS
2638 int idx_curr = 5;
2639 char *tag, *distance, *vrf;
0d9551dc 2640
28dadafc 2641 tag = distance = vrf = NULL;
e52702f2 2642 zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
81dfcaa2 2643
28dadafc
DS
2644 return static_ipv6_func (vty, 0,
2645 argv[idx_ipv6_prefixlen]->arg,
2646 argv[idx_ipv6_ifname]->arg,
2647 NULL, NULL,
e52702f2 2648 tag, distance, vrf, NULL);
0d9551dc
DS
2649}
2650
28dadafc
DS
2651DEFUN (no_ipv6_route_flags,
2652 no_ipv6_route_flags_cmd,
e52702f2 2653 "no ipv6 route X:X::X:X/M <X:X::X:X|INTERFACE> <reject|blackhole> [tag (1-4294967295)] [(1-255)] [vrf NAME]",
0d9551dc
DS
2654 NO_STR
2655 IP_STR
2656 "Establish static routes\n"
2657 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
2658 "IPv6 gateway address\n"
2659 "IPv6 gateway interface name\n"
2660 "Emit an ICMP unreachable when matched\n"
2661 "Silently discard pkts when matched\n"
2662 "Set tag for this route\n"
2663 "Tag value\n"
8f527c5e 2664 "Distance value for this prefix\n"
e52702f2
QY
2665 VRF_CMD_HELP_STR
2666 "Specify labels for this route\n"
2667 "One or more labels separated by '/'\n")
0d9551dc 2668{
7c022376
DW
2669 int idx_ipv6_prefixlen = 3;
2670 int idx_ipv6_ifname = 4;
2671 int idx_reject_blackhole = 5;
6fa4ca06 2672 int idx_curr = 6;
28dadafc 2673 char *tag, *distance, *vrf;
718e3744 2674
28dadafc 2675 tag = distance = vrf = NULL;
e52702f2 2676 zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
28dadafc
DS
2677
2678 return static_ipv6_func (vty, 0,
2679 argv[idx_ipv6_prefixlen]->arg,
2680 argv[idx_ipv6_ifname]->arg,
2681 NULL,
2682 argv[idx_reject_blackhole]->arg,
e52702f2 2683 tag, distance, vrf, NULL);
0d9551dc
DS
2684}
2685
28dadafc
DS
2686DEFUN (no_ipv6_route_ifname,
2687 no_ipv6_route_ifname_cmd,
e52702f2 2688 "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE [tag (1-4294967295)] [(1-255)] [vrf NAME]",
0d9551dc
DS
2689 NO_STR
2690 IP_STR
2691 "Establish static routes\n"
2692 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
2693 "IPv6 gateway address\n"
2694 "IPv6 gateway interface name\n"
2695 "Set tag for this route\n"
2696 "Tag value\n"
8f527c5e 2697 "Distance value for this prefix\n"
e52702f2
QY
2698 VRF_CMD_HELP_STR
2699 "Specify labels for this route\n"
2700 "One or more labels separated by '/'\n")
0d9551dc 2701{
7c022376
DW
2702 int idx_ipv6_prefixlen = 3;
2703 int idx_ipv6 = 4;
2704 int idx_interface = 5;
28dadafc
DS
2705 int idx_curr = 6;
2706 char *tag, *distance, *vrf;
81dfcaa2 2707
28dadafc 2708 tag = distance = vrf = NULL;
e52702f2 2709 zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
28dadafc
DS
2710
2711 return static_ipv6_func (vty, 0,
2712 argv[idx_ipv6_prefixlen]->arg,
2713 argv[idx_ipv6]->arg,
2714 argv[idx_interface]->arg,
2715 NULL,
e52702f2 2716 tag, distance, vrf, NULL);
0d9551dc
DS
2717}
2718
28dadafc
DS
2719DEFUN (no_ipv6_route_ifname_flags,
2720 no_ipv6_route_ifname_flags_cmd,
e52702f2 2721 "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE <reject|blackhole> [tag (1-4294967295)] [(1-255)] [vrf NAME]",
0d9551dc
DS
2722 NO_STR
2723 IP_STR
2724 "Establish static routes\n"
2725 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
2726 "IPv6 gateway address\n"
2727 "IPv6 gateway interface name\n"
2728 "Emit an ICMP unreachable when matched\n"
2729 "Silently discard pkts when matched\n"
2730 "Set tag for this route\n"
2731 "Tag value\n"
8f527c5e 2732 "Distance value for this prefix\n"
e52702f2
QY
2733 VRF_CMD_HELP_STR
2734 "Specify labels for this route\n"
2735 "One or more labels separated by '/'\n")
0d9551dc 2736{
7c022376
DW
2737 int idx_ipv6_prefixlen = 3;
2738 int idx_ipv6 = 4;
2739 int idx_interface = 5;
2740 int idx_reject_blackhole = 6;
28dadafc
DS
2741 int idx_curr = 7;
2742 char *tag, *distance, *vrf;
2743
2744 tag = distance = vrf = NULL;
e52702f2 2745 zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
28dadafc
DS
2746
2747 return static_ipv6_func (vty, 0,
2748 argv[idx_ipv6_prefixlen]->arg,
2749 argv[idx_ipv6]->arg,
2750 argv[idx_interface]->arg,
2751 argv[idx_reject_blackhole]->arg,
e52702f2 2752 tag, distance, vrf, NULL);
718e3744 2753}
2754
718e3744 2755DEFUN (show_ipv6_route,
2756 show_ipv6_route_cmd,
b62ecea5 2757 "show ipv6 route [vrf NAME] [json]",
718e3744 2758 SHOW_STR
2759 IP_STR
b62ecea5
QY
2760 "IPv6 routing table\n"
2761 VRF_CMD_HELP_STR
2762 "Output JSON\n")
718e3744 2763{
2764 struct route_table *table;
2765 struct route_node *rn;
2766 struct rib *rib;
2767 int first = 1;
af41b63a 2768 vrf_id_t vrf_id = VRF_DEFAULT;
010c141f 2769 struct zebra_vrf *zvrf = NULL;
18a4ded2
DW
2770 char buf[BUFSIZ];
2771 json_object *json = NULL;
2772 json_object *json_prefix = NULL;
718e3744 2773
b62ecea5
QY
2774 int vrf = (argc > 3 && strmatch (argv[3]->text, "vrf"));
2775 int uj = vrf ? argc == 6 : argc == 4;
2776 char *vrfname = vrf ? argv[4]->arg : NULL;
010c141f 2777
b62ecea5
QY
2778 if (vrf)
2779 {
53dc2b05 2780 if (!(zvrf = zebra_vrf_lookup_by_name (vrfname)))
b62ecea5
QY
2781 {
2782 if (uj)
2783 vty_out (vty, "{}%s", VTY_NEWLINE);
2784 else
2785 vty_out (vty, "vrf %s not defined%s", vrfname, VTY_NEWLINE);
2786 return CMD_SUCCESS;
2787 }
2788
53dc2b05 2789 if (zvrf_id (zvrf) == VRF_UNKNOWN)
b62ecea5
QY
2790 {
2791 if (uj)
2792 vty_out (vty, "{}%s", VTY_NEWLINE);
2793 else
2794 vty_out (vty, "vrf %s inactive%s", vrfname, VTY_NEWLINE);
2795 return CMD_SUCCESS;
2796 }
2797 else
53dc2b05 2798 vrf_id = zvrf_id (zvrf);
b62ecea5 2799 }
af41b63a
FL
2800
2801 table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, vrf_id);
b62ecea5 2802 if (!table)
18a4ded2
DW
2803 {
2804 if (uj)
2805 vty_out (vty, "{}%s", VTY_NEWLINE);
2806 return CMD_SUCCESS;
2807 }
2808
2809 if (uj)
2810 {
2811 json = json_object_new_object();
2812
2813 /* Show all IPv6 route. */
2814 for (rn = route_top (table); rn; rn = route_next (rn))
2815 {
2816 RNODE_FOREACH_RIB (rn, rib)
2817 {
2818 if (!json_prefix)
2819 json_prefix = json_object_new_array();
2820 vty_show_ip_route (vty, rn, rib, json_prefix);
2821 }
2822
2823 if (json_prefix)
2824 {
2825 prefix2str (&rn->p, buf, sizeof buf);
2826 json_object_object_add(json, buf, json_prefix);
2827 json_prefix = NULL;
2828 }
2829 }
2830
2aac5767 2831 vty_out (vty, "%s%s", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY), VTY_NEWLINE);
18a4ded2
DW
2832 json_object_free(json);
2833 }
2834 else
2835 {
2836 /* Show all IPv6 route. */
2837 for (rn = route_top (table); rn; rn = route_next (rn))
2838 {
2839 RNODE_FOREACH_RIB (rn, rib)
2840 {
2841 if (first)
2842 {
2843 vty_out (vty, SHOW_ROUTE_V6_HEADER);
2844 first = 0;
2845 }
2846 vty_show_ip_route (vty, rn, rib, NULL);
2847 }
2848 }
2849 }
718e3744 2850
718e3744 2851 return CMD_SUCCESS;
2852}
2853
0d9551dc
DS
2854DEFUN (show_ipv6_route_tag,
2855 show_ipv6_route_tag_cmd,
e52702f2 2856 "show ipv6 route [vrf NAME] tag (1-4294967295)",
0d9551dc
DS
2857 SHOW_STR
2858 IP_STR
2859 "IPv6 routing table\n"
9bf96c84 2860 VRF_CMD_HELP_STR
0d9551dc
DS
2861 "Show only routes with tag\n"
2862 "Tag value\n")
2863{
6de69f83
DW
2864 int idx_vrf = 3;
2865 int idx_name = 4;
2866 int idx_tag = 6;
0d9551dc
DS
2867 struct route_table *table;
2868 struct route_node *rn;
2869 struct rib *rib;
2870 int first = 1;
dc9ffce8 2871 route_tag_t tag = 0;
d511d7f1 2872 vrf_id_t vrf_id = VRF_DEFAULT;
0d9551dc 2873
6de69f83 2874 if (strmatch(argv[idx_vrf]->text, "vrf"))
d511d7f1 2875 {
6de69f83 2876 VRF_GET_ID (vrf_id, argv[idx_name]->arg);
b6f1faf0 2877 VTY_GET_INTEGER_RANGE("tag", tag, argv[idx_tag]->arg, 0, 4294967295);
d511d7f1
DS
2878 }
2879 else
9bf96c84 2880 {
6de69f83 2881 idx_tag -= 2;
b6f1faf0 2882 VTY_GET_INTEGER_RANGE("tag", tag, argv[idx_tag]->arg, 0, 4294967295);
9bf96c84 2883 }
0d9551dc 2884
d511d7f1 2885 table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, vrf_id);
0d9551dc
DS
2886 if (! table)
2887 return CMD_SUCCESS;
2888
2889 /* Show all IPv6 routes with matching tag value. */
2890 for (rn = route_top (table); rn; rn = route_next (rn))
2891 RNODE_FOREACH_RIB (rn, rib)
2892 {
2893 if (rib->tag != tag)
2894 continue;
2895
2896 if (first)
2897 {
2898 vty_out (vty, SHOW_ROUTE_V6_HEADER);
2899 first = 0;
2900 }
18a4ded2 2901 vty_show_ip_route (vty, rn, rib, NULL);
0d9551dc
DS
2902 }
2903 return CMD_SUCCESS;
2904}
2905
718e3744 2906DEFUN (show_ipv6_route_prefix_longer,
2907 show_ipv6_route_prefix_longer_cmd,
9bf96c84 2908 "show ipv6 route [vrf NAME] X:X::X:X/M longer-prefixes",
718e3744 2909 SHOW_STR
2910 IP_STR
2911 "IPv6 routing table\n"
9bf96c84 2912 VRF_CMD_HELP_STR
718e3744 2913 "IPv6 prefix\n"
2914 "Show route matching the specified Network/Mask pair only\n")
2915{
2916 struct route_table *table;
2917 struct route_node *rn;
2918 struct rib *rib;
2919 struct prefix p;
2920 int ret;
2921 int first = 1;
af41b63a 2922 vrf_id_t vrf_id = VRF_DEFAULT;
718e3744 2923
412e5cd9 2924 if (strmatch(argv[3]->text, "vrf"))
d511d7f1 2925 {
9bf96c84
DW
2926 VRF_GET_ID (vrf_id, argv[4]->arg);
2927 ret = str2prefix (argv[5]->arg, &p);
d511d7f1
DS
2928 }
2929 else
9bf96c84
DW
2930 {
2931 ret = str2prefix (argv[3]->arg, &p);
2932 }
d511d7f1 2933
718e3744 2934 if (! ret)
2935 {
2936 vty_out (vty, "%% Malformed Prefix%s", VTY_NEWLINE);
2937 return CMD_WARNING;
2938 }
2939
af41b63a
FL
2940 table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, vrf_id);
2941 if (! table)
2942 return CMD_SUCCESS;
2943
718e3744 2944 /* Show matched type IPv6 routes. */
2945 for (rn = route_top (table); rn; rn = route_next (rn))
9fd92e3c 2946 RNODE_FOREACH_RIB (rn, rib)
718e3744 2947 if (prefix_match (&p, &rn->p))
2948 {
2949 if (first)
2950 {
e0ca5fde 2951 vty_out (vty, SHOW_ROUTE_V6_HEADER);
718e3744 2952 first = 0;
2953 }
18a4ded2 2954 vty_show_ip_route (vty, rn, rib, NULL);
718e3744 2955 }
2956 return CMD_SUCCESS;
2957}
2958
2959DEFUN (show_ipv6_route_protocol,
2960 show_ipv6_route_protocol_cmd,
40d1cbfb 2961 "show ipv6 route [vrf NAME] " FRR_IP6_REDIST_STR_ZEBRA,
718e3744 2962 SHOW_STR
2963 IP_STR
2964 "IP routing table\n"
b62ecea5 2965 VRF_CMD_HELP_STR
3b14d86e 2966 FRR_IP6_REDIST_HELP_STR_ZEBRA)
718e3744 2967{
2968 int type;
2969 struct route_table *table;
2970 struct route_node *rn;
2971 struct rib *rib;
2972 int first = 1;
af41b63a 2973 vrf_id_t vrf_id = VRF_DEFAULT;
718e3744 2974
6d681bd8
QY
2975 int idx = 0;
2976 if (argv_find (argv, argc, "NAME", &idx))
2977 VRF_GET_ID (vrf_id, argv[idx]->arg);
b62ecea5 2978
6d681bd8
QY
2979 char *proto = argv[argc - 1]->text;
2980 type = proto_redistnum (AFI_IP, proto);
d511d7f1 2981
e0ca5fde 2982 if (type < 0)
718e3744 2983 {
2984 vty_out (vty, "Unknown route type%s", VTY_NEWLINE);
2985 return CMD_WARNING;
2986 }
af41b63a 2987
af41b63a 2988 table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, vrf_id);
718e3744 2989 if (! table)
2990 return CMD_SUCCESS;
2991
2992 /* Show matched type IPv6 routes. */
2993 for (rn = route_top (table); rn; rn = route_next (rn))
9fd92e3c 2994 RNODE_FOREACH_RIB (rn, rib)
718e3744 2995 if (rib->type == type)
2996 {
2997 if (first)
2998 {
e0ca5fde 2999 vty_out (vty, SHOW_ROUTE_V6_HEADER);
718e3744 3000 first = 0;
3001 }
18a4ded2 3002 vty_show_ip_route (vty, rn, rib, NULL);
718e3744 3003 }
3004 return CMD_SUCCESS;
3005}
3006
3007DEFUN (show_ipv6_route_addr,
3008 show_ipv6_route_addr_cmd,
9bf96c84 3009 "show ipv6 route [vrf NAME] X:X::X:X",
718e3744 3010 SHOW_STR
3011 IP_STR
3012 "IPv6 routing table\n"
9bf96c84 3013 VRF_CMD_HELP_STR
718e3744 3014 "IPv6 Address\n")
3015{
3016 int ret;
3017 struct prefix_ipv6 p;
3018 struct route_table *table;
3019 struct route_node *rn;
af41b63a 3020 vrf_id_t vrf_id = VRF_DEFAULT;
718e3744 3021
412e5cd9 3022 if (strmatch(argv[3]->text, "vrf"))
d511d7f1 3023 {
9bf96c84
DW
3024 VRF_GET_ID (vrf_id, argv[4]->arg);
3025 ret = str2prefix_ipv6 (argv[5]->arg, &p);
d511d7f1
DS
3026 }
3027 else
9bf96c84
DW
3028 {
3029 ret = str2prefix_ipv6 (argv[3]->arg, &p);
3030 }
d511d7f1 3031
718e3744 3032 if (ret <= 0)
3033 {
3034 vty_out (vty, "Malformed IPv6 address%s", VTY_NEWLINE);
3035 return CMD_WARNING;
3036 }
3037
af41b63a 3038 table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, vrf_id);
718e3744 3039 if (! table)
3040 return CMD_SUCCESS;
3041
3042 rn = route_node_match (table, (struct prefix *) &p);
3043 if (! rn)
3044 {
3045 vty_out (vty, "%% Network not in table%s", VTY_NEWLINE);
3046 return CMD_WARNING;
3047 }
3048
196aecef 3049 vty_show_ip_route_detail (vty, rn, 0);
718e3744 3050
3051 route_unlock_node (rn);
3052
3053 return CMD_SUCCESS;
3054}
3055
3056DEFUN (show_ipv6_route_prefix,
3057 show_ipv6_route_prefix_cmd,
9bf96c84 3058 "show ipv6 route [vrf NAME] X:X::X:X/M",
718e3744 3059 SHOW_STR
3060 IP_STR
3061 "IPv6 routing table\n"
9bf96c84 3062 VRF_CMD_HELP_STR
718e3744 3063 "IPv6 prefix\n")
3064{
3065 int ret;
3066 struct prefix_ipv6 p;
3067 struct route_table *table;
3068 struct route_node *rn;
af41b63a 3069 vrf_id_t vrf_id = VRF_DEFAULT;
718e3744 3070
412e5cd9 3071 if (strmatch(argv[3]->text, "vrf"))
d511d7f1 3072 {
9bf96c84
DW
3073 VRF_GET_ID (vrf_id, argv[4]->arg);
3074 ret = str2prefix_ipv6 (argv[5]->arg, &p);
d511d7f1
DS
3075 }
3076 else
9bf96c84 3077 ret = str2prefix_ipv6 (argv[3]->arg, &p);
d511d7f1 3078
718e3744 3079 if (ret <= 0)
3080 {
3081 vty_out (vty, "Malformed IPv6 prefix%s", VTY_NEWLINE);
3082 return CMD_WARNING;
3083 }
3084
af41b63a 3085 table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, vrf_id);
718e3744 3086 if (! table)
3087 return CMD_SUCCESS;
3088
3089 rn = route_node_match (table, (struct prefix *) &p);
3090 if (! rn || rn->p.prefixlen != p.prefixlen)
3091 {
3092 vty_out (vty, "%% Network not in table%s", VTY_NEWLINE);
3093 return CMD_WARNING;
3094 }
3095
196aecef 3096 vty_show_ip_route_detail (vty, rn, 0);
718e3744 3097
3098 route_unlock_node (rn);
3099
3100 return CMD_SUCCESS;
3101}
3102
af41b63a 3103
61691c91
ST
3104/* Show route summary. */
3105DEFUN (show_ipv6_route_summary,
3106 show_ipv6_route_summary_cmd,
9bf96c84 3107 "show ipv6 route [vrf NAME] summary",
61691c91
ST
3108 SHOW_STR
3109 IP_STR
3110 "IPv6 routing table\n"
9bf96c84 3111 VRF_CMD_HELP_STR
61691c91
ST
3112 "Summary of all IPv6 routes\n")
3113{
3114 struct route_table *table;
af41b63a 3115 vrf_id_t vrf_id = VRF_DEFAULT;
61691c91 3116
412e5cd9 3117 if (strmatch(argv[3]->text, "vrf"))
9bf96c84 3118 VRF_GET_ID (vrf_id, argv[4]->arg);
61691c91 3119
af41b63a 3120 table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, vrf_id);
61691c91
ST
3121 if (! table)
3122 return CMD_SUCCESS;
3123
3124 vty_show_ip_route_summary (vty, table);
3125
3126 return CMD_SUCCESS;
3127}
3128
af41b63a 3129
9343ce83
DS
3130/* Show ipv6 route summary prefix. */
3131DEFUN (show_ipv6_route_summary_prefix,
3132 show_ipv6_route_summary_prefix_cmd,
9bf96c84 3133 "show ipv6 route [vrf NAME] summary prefix",
9343ce83
DS
3134 SHOW_STR
3135 IP_STR
3136 "IPv6 routing table\n"
9bf96c84 3137 VRF_CMD_HELP_STR
9343ce83
DS
3138 "Summary of all IPv6 routes\n"
3139 "Prefix routes\n")
3140{
3141 struct route_table *table;
af41b63a 3142 vrf_id_t vrf_id = VRF_DEFAULT;
9343ce83 3143
412e5cd9 3144 if (strmatch(argv[3]->text, "vrf"))
9bf96c84 3145 VRF_GET_ID (vrf_id, argv[4]->arg);
9343ce83 3146
af41b63a 3147 table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, vrf_id);
9343ce83
DS
3148 if (! table)
3149 return CMD_SUCCESS;
3150
3151 vty_show_ip_route_summary_prefix (vty, table);
3152
3153 return CMD_SUCCESS;
3154}
3155
af41b63a 3156
cddf391b
B
3157/*
3158 * Show IPv6 mroute command.Used to dump
3159 * the Multicast routing table.
3160 */
cddf391b
B
3161DEFUN (show_ipv6_mroute,
3162 show_ipv6_mroute_cmd,
9bf96c84 3163 "show ipv6 mroute [vrf NAME]",
cddf391b
B
3164 SHOW_STR
3165 IP_STR
9bf96c84
DW
3166 "IPv6 Multicast routing table\n"
3167 VRF_CMD_HELP_STR)
cddf391b
B
3168{
3169 struct route_table *table;
3170 struct route_node *rn;
3171 struct rib *rib;
3172 int first = 1;
af41b63a
FL
3173 vrf_id_t vrf_id = VRF_DEFAULT;
3174
412e5cd9 3175 if (strmatch(argv[3]->text, "vrf"))
9bf96c84 3176 VRF_GET_ID (vrf_id, argv[4]->arg);
cddf391b 3177
af41b63a 3178 table = zebra_vrf_table (AFI_IP6, SAFI_MULTICAST, vrf_id);
cddf391b
B
3179 if (! table)
3180 return CMD_SUCCESS;
3181
3182 /* Show all IPv6 route. */
3183 for (rn = route_top (table); rn; rn = route_next (rn))
9fd92e3c 3184 RNODE_FOREACH_RIB (rn, rib)
cddf391b
B
3185 {
3186 if (first)
3187 {
cb32fd69 3188 vty_out (vty, SHOW_ROUTE_V6_HEADER);
cddf391b
B
3189 first = 0;
3190 }
18a4ded2 3191 vty_show_ip_route (vty, rn, rib, NULL);
cddf391b
B
3192 }
3193 return CMD_SUCCESS;
3194}
3195
af41b63a
FL
3196
3197DEFUN (show_ipv6_route_vrf_all,
3198 show_ipv6_route_vrf_all_cmd,
5bebf568 3199 "show ipv6 route vrf all",
af41b63a
FL
3200 SHOW_STR
3201 IP_STR
3202 "IPv6 routing table\n"
3203 VRF_ALL_CMD_HELP_STR)
3204{
3205 struct route_table *table;
3206 struct route_node *rn;
3207 struct rib *rib;
1a1a7065 3208 struct vrf *vrf;
af41b63a 3209 struct zebra_vrf *zvrf;
af41b63a 3210 int first = 1;
d511d7f1 3211 int vrf_header = 1;
af41b63a 3212
a62c4901 3213 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
af41b63a 3214 {
1a1a7065 3215 if ((zvrf = vrf->info) == NULL ||
af41b63a
FL
3216 (table = zvrf->table[AFI_IP6][SAFI_UNICAST]) == NULL)
3217 continue;
3218
3219 /* Show all IPv6 route. */
3220 for (rn = route_top (table); rn; rn = route_next (rn))
3221 RNODE_FOREACH_RIB (rn, rib)
3222 {
3223 if (first)
3224 {
3225 vty_out (vty, SHOW_ROUTE_V6_HEADER);
3226 first = 0;
3227 }
d511d7f1
DS
3228
3229 if (vrf_header)
3230 {
661512bf 3231 vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf_name (zvrf), VTY_NEWLINE);
d511d7f1
DS
3232 vrf_header = 0;
3233 }
18a4ded2 3234 vty_show_ip_route (vty, rn, rib, NULL);
af41b63a 3235 }
d511d7f1 3236 vrf_header = 1;
af41b63a
FL
3237 }
3238
3239 return CMD_SUCCESS;
3240}
3241
d511d7f1
DS
3242DEFUN (show_ipv6_route_vrf_all_tag,
3243 show_ipv6_route_vrf_all_tag_cmd,
e52702f2 3244 "show ipv6 route vrf all tag (1-4294967295)",
af41b63a
FL
3245 SHOW_STR
3246 IP_STR
3247 "IPv6 routing table\n"
d511d7f1
DS
3248 VRF_ALL_CMD_HELP_STR
3249 "Show only routes with tag\n"
3250 "Tag value\n")
3251{
7c022376 3252 int idx_number = 6;
d511d7f1
DS
3253 struct route_table *table;
3254 struct route_node *rn;
3255 struct rib *rib;
1a1a7065 3256 struct vrf *vrf;
d511d7f1 3257 struct zebra_vrf *zvrf;
d511d7f1
DS
3258 int first = 1;
3259 int vrf_header = 1;
dc9ffce8 3260 route_tag_t tag = 0;
d511d7f1 3261
7c022376 3262 if (argv[idx_number]->arg)
b6f1faf0 3263 VTY_GET_INTEGER_RANGE("tag", tag, argv[idx_number]->arg, 0, 4294967295);
d511d7f1 3264
a62c4901 3265 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
d511d7f1 3266 {
1a1a7065 3267 if ((zvrf = vrf->info) == NULL ||
d511d7f1
DS
3268 (table = zvrf->table[AFI_IP][SAFI_UNICAST]) == NULL)
3269 continue;
3270
3271 /* Show all IPv6 routes with matching tag value. */
3272 for (rn = route_top (table); rn; rn = route_next (rn))
3273 RNODE_FOREACH_RIB (rn, rib)
3274 {
3275 if (rib->tag != tag)
3276 continue;
3277
3278 if (first)
3279 {
3280 vty_out (vty, SHOW_ROUTE_V6_HEADER);
3281 first = 0;
3282 }
3283
3284 if (vrf_header)
3285 {
661512bf 3286 vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf_name (zvrf), VTY_NEWLINE);
d511d7f1
DS
3287 vrf_header = 0;
3288 }
18a4ded2 3289 vty_show_ip_route (vty, rn, rib, NULL);
d511d7f1
DS
3290 }
3291 vrf_header = 1;
3292 }
3293
3294 return CMD_SUCCESS;
3295}
3296
3297DEFUN (show_ipv6_route_vrf_all_prefix_longer,
3298 show_ipv6_route_vrf_all_prefix_longer_cmd,
5bebf568 3299 "show ipv6 route vrf all X:X::X:X/M longer-prefixes",
d511d7f1
DS
3300 SHOW_STR
3301 IP_STR
3302 "IPv6 routing table\n"
3303 VRF_ALL_CMD_HELP_STR
af41b63a 3304 "IPv6 prefix\n"
d511d7f1 3305 "Show route matching the specified Network/Mask pair only\n")
af41b63a 3306{
7c022376 3307 int idx_ipv6_prefixlen = 5;
af41b63a
FL
3308 struct route_table *table;
3309 struct route_node *rn;
3310 struct rib *rib;
3311 struct prefix p;
1a1a7065 3312 struct vrf *vrf;
af41b63a 3313 struct zebra_vrf *zvrf;
af41b63a
FL
3314 int ret;
3315 int first = 1;
d511d7f1 3316 int vrf_header = 1;
af41b63a 3317
7c022376 3318 ret = str2prefix (argv[idx_ipv6_prefixlen]->arg, &p);
af41b63a
FL
3319 if (! ret)
3320 {
3321 vty_out (vty, "%% Malformed Prefix%s", VTY_NEWLINE);
3322 return CMD_WARNING;
3323 }
3324
a62c4901 3325 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
af41b63a 3326 {
1a1a7065 3327 if ((zvrf = vrf->info) == NULL ||
af41b63a
FL
3328 (table = zvrf->table[AFI_IP6][SAFI_UNICAST]) == NULL)
3329 continue;
3330
3331 /* Show matched type IPv6 routes. */
3332 for (rn = route_top (table); rn; rn = route_next (rn))
3333 RNODE_FOREACH_RIB (rn, rib)
3334 if (prefix_match (&p, &rn->p))
3335 {
3336 if (first)
3337 {
3338 vty_out (vty, SHOW_ROUTE_V6_HEADER);
3339 first = 0;
3340 }
d511d7f1
DS
3341
3342 if (vrf_header)
3343 {
661512bf 3344 vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf_name (zvrf), VTY_NEWLINE);
d511d7f1
DS
3345 vrf_header = 0;
3346 }
18a4ded2 3347 vty_show_ip_route (vty, rn, rib, NULL);
af41b63a 3348 }
d511d7f1 3349 vrf_header = 1;
af41b63a
FL
3350 }
3351
3352 return CMD_SUCCESS;
3353}
3354
d511d7f1
DS
3355DEFUN (show_ipv6_route_vrf_all_protocol,
3356 show_ipv6_route_vrf_all_protocol_cmd,
40d1cbfb 3357 "show ipv6 route vrf all " FRR_IP6_REDIST_STR_ZEBRA,
af41b63a
FL
3358 SHOW_STR
3359 IP_STR
3360 "IP routing table\n"
d511d7f1 3361 VRF_ALL_CMD_HELP_STR
ab0181ee 3362 FRR_IP6_REDIST_HELP_STR_ZEBRA)
af41b63a
FL
3363{
3364 int type;
3365 struct route_table *table;
3366 struct route_node *rn;
3367 struct rib *rib;
1a1a7065 3368 struct vrf *vrf;
af41b63a 3369 struct zebra_vrf *zvrf;
af41b63a 3370 int first = 1;
d511d7f1 3371 int vrf_header = 1;
af41b63a 3372
6d681bd8
QY
3373 char *proto = argv[argc - 1]->text;
3374 type = proto_redistnum (AFI_IP, proto);
3375
af41b63a
FL
3376 if (type < 0)
3377 {
3378 vty_out (vty, "Unknown route type%s", VTY_NEWLINE);
3379 return CMD_WARNING;
3380 }
3381
a62c4901 3382 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
af41b63a 3383 {
1a1a7065 3384 if ((zvrf = vrf->info) == NULL ||
af41b63a
FL
3385 (table = zvrf->table[AFI_IP6][SAFI_UNICAST]) == NULL)
3386 continue;
3387
3388 /* Show matched type IPv6 routes. */
3389 for (rn = route_top (table); rn; rn = route_next (rn))
3390 RNODE_FOREACH_RIB (rn, rib)
3391 if (rib->type == type)
3392 {
3393 if (first)
3394 {
3395 vty_out (vty, SHOW_ROUTE_V6_HEADER);
3396 first = 0;
3397 }
d511d7f1
DS
3398
3399 if (vrf_header)
3400 {
661512bf 3401 vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf_name (zvrf), VTY_NEWLINE);
d511d7f1
DS
3402 vrf_header = 0;
3403 }
18a4ded2 3404 vty_show_ip_route (vty, rn, rib, NULL);
af41b63a 3405 }
d511d7f1 3406 vrf_header = 1;
af41b63a
FL
3407 }
3408
3409 return CMD_SUCCESS;
3410}
3411
d511d7f1
DS
3412DEFUN (show_ipv6_route_vrf_all_addr,
3413 show_ipv6_route_vrf_all_addr_cmd,
5bebf568 3414 "show ipv6 route vrf all X:X::X:X",
af41b63a
FL
3415 SHOW_STR
3416 IP_STR
3417 "IPv6 routing table\n"
d511d7f1
DS
3418 VRF_ALL_CMD_HELP_STR
3419 "IPv6 Address\n")
af41b63a 3420{
7c022376 3421 int idx_ipv6 = 5;
af41b63a
FL
3422 int ret;
3423 struct prefix_ipv6 p;
3424 struct route_table *table;
3425 struct route_node *rn;
1a1a7065 3426 struct vrf *vrf;
af41b63a 3427 struct zebra_vrf *zvrf;
af41b63a 3428
7c022376 3429 ret = str2prefix_ipv6 (argv[idx_ipv6]->arg, &p);
af41b63a
FL
3430 if (ret <= 0)
3431 {
3432 vty_out (vty, "Malformed IPv6 address%s", VTY_NEWLINE);
3433 return CMD_WARNING;
3434 }
3435
a62c4901 3436 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
af41b63a 3437 {
1a1a7065 3438 if ((zvrf = vrf->info) == NULL ||
af41b63a
FL
3439 (table = zvrf->table[AFI_IP6][SAFI_UNICAST]) == NULL)
3440 continue;
3441
3442 rn = route_node_match (table, (struct prefix *) &p);
3443 if (! rn)
3444 continue;
3445
196aecef 3446 vty_show_ip_route_detail (vty, rn, 0);
af41b63a
FL
3447
3448 route_unlock_node (rn);
3449 }
3450
3451 return CMD_SUCCESS;
3452}
3453
d511d7f1
DS
3454DEFUN (show_ipv6_route_vrf_all_prefix,
3455 show_ipv6_route_vrf_all_prefix_cmd,
5bebf568 3456 "show ipv6 route vrf all X:X::X:X/M",
af41b63a
FL
3457 SHOW_STR
3458 IP_STR
3459 "IPv6 routing table\n"
d511d7f1
DS
3460 VRF_ALL_CMD_HELP_STR
3461 "IPv6 prefix\n")
af41b63a 3462{
7c022376 3463 int idx_ipv6_prefixlen = 5;
af41b63a
FL
3464 int ret;
3465 struct prefix_ipv6 p;
3466 struct route_table *table;
3467 struct route_node *rn;
1a1a7065 3468 struct vrf *vrf;
af41b63a 3469 struct zebra_vrf *zvrf;
af41b63a 3470
7c022376 3471 ret = str2prefix_ipv6 (argv[idx_ipv6_prefixlen]->arg, &p);
af41b63a
FL
3472 if (ret <= 0)
3473 {
3474 vty_out (vty, "Malformed IPv6 prefix%s", VTY_NEWLINE);
3475 return CMD_WARNING;
3476 }
3477
a62c4901 3478 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
af41b63a 3479 {
1a1a7065 3480 if ((zvrf = vrf->info) == NULL ||
af41b63a
FL
3481 (table = zvrf->table[AFI_IP6][SAFI_UNICAST]) == NULL)
3482 continue;
3483
3484 rn = route_node_match (table, (struct prefix *) &p);
3485 if (! rn)
3486 continue;
3487 if (rn->p.prefixlen != p.prefixlen)
3488 {
3489 route_unlock_node (rn);
3490 continue;
3491 }
3492
196aecef 3493 vty_show_ip_route_detail (vty, rn, 0);
af41b63a
FL
3494
3495 route_unlock_node (rn);
3496 }
3497
3498 return CMD_SUCCESS;
3499}
3500
d511d7f1
DS
3501DEFUN (show_ipv6_route_vrf_all_summary,
3502 show_ipv6_route_vrf_all_summary_cmd,
5bebf568 3503 "show ipv6 route vrf all summary",
af41b63a
FL
3504 SHOW_STR
3505 IP_STR
3506 "IPv6 routing table\n"
d511d7f1
DS
3507 VRF_ALL_CMD_HELP_STR
3508 "Summary of all IPv6 routes\n")
af41b63a 3509{
1a1a7065 3510 struct vrf *vrf;
af41b63a 3511 struct zebra_vrf *zvrf;
af41b63a 3512
a62c4901 3513 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
1a1a7065 3514 if ((zvrf = vrf->info) != NULL)
af41b63a
FL
3515 vty_show_ip_route_summary (vty, zvrf->table[AFI_IP6][SAFI_UNICAST]);
3516
3517 return CMD_SUCCESS;
3518}
3519
3520DEFUN (show_ipv6_mroute_vrf_all,
3521 show_ipv6_mroute_vrf_all_cmd,
5bebf568 3522 "show ipv6 mroute vrf all",
af41b63a
FL
3523 SHOW_STR
3524 IP_STR
3525 "IPv6 Multicast routing table\n"
3526 VRF_ALL_CMD_HELP_STR)
3527{
3528 struct route_table *table;
3529 struct route_node *rn;
3530 struct rib *rib;
1a1a7065 3531 struct vrf *vrf;
af41b63a 3532 struct zebra_vrf *zvrf;
af41b63a
FL
3533 int first = 1;
3534
a62c4901 3535 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
af41b63a 3536 {
1a1a7065 3537 if ((zvrf = vrf->info) == NULL ||
af41b63a
FL
3538 (table = zvrf->table[AFI_IP6][SAFI_UNICAST]) == NULL)
3539 continue;
3540
3541 /* Show all IPv6 route. */
3542 for (rn = route_top (table); rn; rn = route_next (rn))
3543 RNODE_FOREACH_RIB (rn, rib)
3544 {
3545 if (first)
3546 {
3547 vty_out (vty, SHOW_ROUTE_V6_HEADER);
3548 first = 0;
3549 }
18a4ded2 3550 vty_show_ip_route (vty, rn, rib, NULL);
af41b63a
FL
3551 }
3552 }
3553 return CMD_SUCCESS;
3554}
3555
d511d7f1
DS
3556DEFUN (show_ipv6_route_vrf_all_summary_prefix,
3557 show_ipv6_route_vrf_all_summary_prefix_cmd,
5bebf568 3558 "show ipv6 route vrf all summary prefix",
af41b63a
FL
3559 SHOW_STR
3560 IP_STR
3561 "IPv6 routing table\n"
d511d7f1 3562 VRF_ALL_CMD_HELP_STR
af41b63a 3563 "Summary of all IPv6 routes\n"
d511d7f1 3564 "Prefix routes\n")
af41b63a 3565{
1a1a7065 3566 struct vrf *vrf;
af41b63a 3567 struct zebra_vrf *zvrf;
af41b63a 3568
a62c4901 3569 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
1a1a7065 3570 if ((zvrf = vrf->info) != NULL)
af41b63a
FL
3571 vty_show_ip_route_summary_prefix (vty, zvrf->table[AFI_IP6][SAFI_UNICAST]);
3572
3573 return CMD_SUCCESS;
3574}
3575
718e3744 3576/* Write IPv6 static route configuration. */
a1ac18c4 3577static int
718e3744 3578static_config_ipv6 (struct vty *vty)
3579{
3580 struct route_node *rn;
c0551cbb 3581 struct static_route *si;
825649bd 3582 int write = 0;
196aecef 3583 char buf[PREFIX_STRLEN];
718e3744 3584 struct route_table *stable;
51bdc5f8 3585 struct vrf *vrf;
8f527c5e 3586 struct zebra_vrf *zvrf;
718e3744 3587
806f8760 3588 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
8f527c5e 3589 {
53dc2b05
DL
3590 if (!(zvrf = vrf->info))
3591 continue;
c1c747a8 3592 if ((stable = zvrf->stable[AFI_IP6][SAFI_UNICAST]) == NULL)
8f527c5e 3593 continue;
718e3744 3594
8f527c5e
FL
3595 for (rn = route_top (stable); rn; rn = route_next (rn))
3596 for (si = rn->info; si; si = si->next)
3597 {
3598 vty_out (vty, "ipv6 route %s", prefix2str (&rn->p, buf, sizeof buf));
718e3744 3599
be5e48ab
DS
3600 switch (si->type)
3601 {
4b2792b5
DS
3602 case STATIC_IPV4_GATEWAY:
3603 vty_out (vty, " %s", inet_ntoa (si->addr.ipv4));
3604 break;
be5e48ab
DS
3605 case STATIC_IPV6_GATEWAY:
3606 vty_out (vty, " %s", inet_ntop (AF_INET6, &si->addr.ipv6, buf, BUFSIZ));
3607 break;
ba779241 3608 case STATIC_IFINDEX:
fb148af4 3609 vty_out (vty, " %s", si->ifname);
be5e48ab 3610 break;
61a091c5
DS
3611 case STATIC_BLACKHOLE:
3612 vty_out (vty, " Null0" );
3613 break;
ba779241 3614 case STATIC_IPV6_GATEWAY_IFINDEX:
be5e48ab 3615 vty_out (vty, " %s %s",
ba779241
DS
3616 inet_ntop (AF_INET6, &si->addr.ipv6, buf, BUFSIZ),
3617 ifindex2ifname_vrf (si->ifindex, si->vrf_id));
be5e48ab
DS
3618 break;
3619 }
718e3744 3620
61a091c5
DS
3621 /* flags are incompatible with STATIC_BLACKHOLE */
3622 if (si->type != STATIC_BLACKHOLE)
3623 {
3624 if (CHECK_FLAG(si->flags, ZEBRA_FLAG_REJECT))
3625 vty_out (vty, " %s", "reject");
3626 if (CHECK_FLAG(si->flags, ZEBRA_FLAG_BLACKHOLE))
3627 vty_out (vty, " %s", "blackhole");
3628 }
81dfcaa2 3629
8f527c5e 3630 if (si->tag)
dc9ffce8 3631 vty_out (vty, " tag %"ROUTE_TAG_PRI, si->tag);
0d9551dc 3632
8f527c5e
FL
3633 if (si->distance != ZEBRA_STATIC_DISTANCE_DEFAULT)
3634 vty_out (vty, " %d", si->distance);
718e3744 3635
8f527c5e 3636 if (si->vrf_id != VRF_DEFAULT)
4a141882 3637 {
661512bf 3638 vty_out (vty, " vrf %s", zvrf_name (zvrf));
4a141882 3639 }
0d9551dc 3640
17d38ab7
RW
3641 /* Label information */
3642 if (si->snh_label.num_labels)
3643 vty_out (vty, " label %s",
3644 mpls_label2str (si->snh_label.num_labels,
3645 si->snh_label.label, buf, sizeof buf));
3646
8f527c5e 3647 vty_out (vty, "%s", VTY_NEWLINE);
718e3744 3648
8f527c5e
FL
3649 write = 1;
3650 }
3651 }
718e3744 3652 return write;
3653}
718e3744 3654
6baf7bb8
DS
3655DEFUN (allow_external_route_update,
3656 allow_external_route_update_cmd,
3657 "allow-external-route-update",
3658 "Allow Quagga routes to be overwritten by external processes")
3659{
3660 allow_delete = 1;
3661
3662 return CMD_SUCCESS;
3663}
3664
3665DEFUN (no_allow_external_route_update,
3666 no_allow_external_route_update_cmd,
3667 "no allow-external-route-update",
3668 "Allow Quagga routes to be overwritten by external processes")
3669{
3670 allow_delete = 0;
3671
3672 return CMD_SUCCESS;
3673}
3674
12f6fb97
DS
3675/* show vrf */
3676DEFUN (show_vrf,
3677 show_vrf_cmd,
3678 "show vrf",
3679 SHOW_STR
3680 "VRF\n")
3681{
51bdc5f8 3682 struct vrf *vrf;
12f6fb97 3683 struct zebra_vrf *zvrf;
12f6fb97 3684
806f8760 3685 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
12f6fb97 3686 {
53dc2b05
DL
3687 if (!(zvrf = vrf->info))
3688 continue;
3689 if (!zvrf_id (zvrf))
12f6fb97
DS
3690 continue;
3691
661512bf
RW
3692 vty_out (vty, "vrf %s ", zvrf_name (zvrf));
3693 if (zvrf_id (zvrf) == VRF_UNKNOWN)
825649bd 3694 vty_out (vty, "inactive");
3695 else
661512bf 3696 vty_out (vty, "id %u table %u", zvrf_id (zvrf), zvrf->table_id);
825649bd 3697 vty_out (vty, "%s", VTY_NEWLINE);
12f6fb97
DS
3698
3699 }
3700
3701 return CMD_SUCCESS;
3702}
3703
718e3744 3704/* Static ip route configuration write function. */
a1ac18c4 3705static int
718e3744 3706zebra_ip_config (struct vty *vty)
3707{
3708 int write = 0;
3709
af41b63a 3710 write += static_config_ipv4 (vty, SAFI_UNICAST, "ip route");
b78a80d7 3711 write += static_config_ipv4 (vty, SAFI_MULTICAST, "ip mroute");
718e3744 3712 write += static_config_ipv6 (vty);
718e3744 3713
7a4bb9c5 3714 write += zebra_import_table_config (vty);
718e3744 3715 return write;
3716}
3717
7a4bb9c5
DS
3718DEFUN (ip_zebra_import_table_distance,
3719 ip_zebra_import_table_distance_cmd,
12dcf78e 3720 "ip import-table (1-252) [distance (1-255)] [route-map WORD]",
8902474b
DS
3721 IP_STR
3722 "import routes from non-main kernel table\n"
3723 "kernel routing table id\n"
3724 "Distance for imported routes\n"
3725 "Default distance value\n"
3726 "route-map for filtering\n"
3727 "route-map name\n")
3728{
3729 u_int32_t table_id = 0;
8902474b 3730
b62ecea5
QY
3731 VTY_GET_INTEGER("table", table_id, argv[2]->arg);
3732 int distance = ZEBRA_TABLE_DISTANCE_DEFAULT;
3733 char *rmap = strmatch (argv[argc - 2]->text, "route-map") ?
3734 XSTRDUP(MTYPE_ROUTE_MAP_NAME, argv[argc - 1]->arg) : NULL;
3735 if (argc == 7 || (argc == 5 && !rmap))
3736 VTY_GET_INTEGER_RANGE("distance", distance, argv[4]->arg, 1, 255);
8902474b
DS
3737
3738 if (!is_zebra_valid_kernel_table(table_id))
3739 {
3740 vty_out(vty, "Invalid routing table ID, %d. Must be in range 1-252%s",
3741 table_id, VTY_NEWLINE);
3742 return CMD_WARNING;
3743 }
3744
3745 if (is_zebra_main_routing_table(table_id))
3746 {
3747 vty_out(vty, "Invalid routing table ID, %d. Must be non-default table%s",
b62ecea5 3748 table_id, VTY_NEWLINE);
8902474b
DS
3749 return CMD_WARNING;
3750 }
3751
b62ecea5 3752 return (zebra_import_table(AFI_IP, table_id, distance, rmap, 1));
8902474b
DS
3753}
3754
7a4bb9c5
DS
3755DEFUN (no_ip_zebra_import_table,
3756 no_ip_zebra_import_table_cmd,
b62ecea5 3757 "no ip import-table (1-252) [distance (1-255)] [route-map NAME]",
7a4bb9c5
DS
3758 NO_STR
3759 IP_STR
3760 "import routes from non-main kernel table\n"
3a2d747c
QY
3761 "kernel routing table id\n"
3762 "Distance for imported routes\n"
3763 "Default distance value\n"
3764 "route-map for filtering\n"
3765 "route-map name\n")
7a4bb9c5
DS
3766{
3767 u_int32_t table_id = 0;
b62ecea5 3768 VTY_GET_INTEGER("table", table_id, argv[3]->arg);
7a4bb9c5
DS
3769
3770 if (!is_zebra_valid_kernel_table(table_id))
3771 {
3772 vty_out(vty, "Invalid routing table ID. Must be in range 1-252%s",
3773 VTY_NEWLINE);
3774 return CMD_WARNING;
3775 }
3776
3777 if (is_zebra_main_routing_table(table_id))
3778 {
3779 vty_out(vty, "Invalid routing table ID, %d. Must be non-default table%s",
3780 table_id, VTY_NEWLINE);
3781 return CMD_WARNING;
3782 }
3783
3784 if (!is_zebra_import_table_enabled(AFI_IP, table_id))
3785 return CMD_SUCCESS;
3786
8902474b 3787 return (zebra_import_table(AFI_IP, table_id, 0, NULL, 0));
7a4bb9c5
DS
3788}
3789
6baf7bb8
DS
3790static int
3791config_write_protocol (struct vty *vty)
3792{
3793 if (allow_delete)
3794 vty_out(vty, "allow-external-route-update%s", VTY_NEWLINE);
3795
3796 if (zebra_rnh_ip_default_route)
3797 vty_out(vty, "ip nht resolve-via-default%s", VTY_NEWLINE);
3798
3799 if (zebra_rnh_ipv6_default_route)
3800 vty_out(vty, "ipv6 nht resolve-via-default%s", VTY_NEWLINE);
3801
4623d897
DL
3802 enum multicast_mode ipv4_multicast_mode = multicast_mode_ipv4_get ();
3803
3804 if (ipv4_multicast_mode != MCAST_NO_CONFIG)
3805 vty_out (vty, "ip multicast rpf-lookup-mode %s%s",
3806 ipv4_multicast_mode == MCAST_URIB_ONLY ? "urib-only" :
3807 ipv4_multicast_mode == MCAST_MRIB_ONLY ? "mrib-only" :
3808 ipv4_multicast_mode == MCAST_MIX_MRIB_FIRST ? "mrib-then-urib" :
3809 ipv4_multicast_mode == MCAST_MIX_DISTANCE ? "lower-distance" :
3810 "longer-prefix",
3811 VTY_NEWLINE);
3812
6baf7bb8
DS
3813 zebra_routemap_config_write_protocol(vty);
3814
3815 return 1;
3816}
3817
718e3744 3818/* IP node for static routes. */
7fc626de 3819static struct cmd_node ip_node = { IP_NODE, "", 1 };
6baf7bb8 3820static struct cmd_node protocol_node = { PROTOCOL_NODE, "", 1 };
718e3744 3821
3822/* Route VTY. */
3823void
a1ac18c4 3824zebra_vty_init (void)
718e3744 3825{
3826 install_node (&ip_node, zebra_ip_config);
6baf7bb8 3827 install_node (&protocol_node, config_write_protocol);
718e3744 3828
6baf7bb8
DS
3829 install_element (CONFIG_NODE, &allow_external_route_update_cmd);
3830 install_element (CONFIG_NODE, &no_allow_external_route_update_cmd);
b8a96915 3831 install_element (CONFIG_NODE, &ip_mroute_dist_cmd);
b8a96915 3832 install_element (CONFIG_NODE, &no_ip_mroute_dist_cmd);
4623d897
DL
3833 install_element (CONFIG_NODE, &ip_multicast_mode_cmd);
3834 install_element (CONFIG_NODE, &no_ip_multicast_mode_cmd);
718e3744 3835 install_element (CONFIG_NODE, &ip_route_cmd);
81dfcaa2 3836 install_element (CONFIG_NODE, &ip_route_flags_cmd);
718e3744 3837 install_element (CONFIG_NODE, &ip_route_mask_cmd);
81dfcaa2 3838 install_element (CONFIG_NODE, &ip_route_mask_flags_cmd);
718e3744 3839 install_element (CONFIG_NODE, &no_ip_route_cmd);
3840 install_element (CONFIG_NODE, &no_ip_route_mask_cmd);
7a4bb9c5
DS
3841 install_element (CONFIG_NODE, &ip_zebra_import_table_distance_cmd);
3842 install_element (CONFIG_NODE, &no_ip_zebra_import_table_cmd);
718e3744 3843
12f6fb97 3844 install_element (VIEW_NODE, &show_vrf_cmd);
718e3744 3845 install_element (VIEW_NODE, &show_ip_route_cmd);
7c8ff89e 3846 install_element (VIEW_NODE, &show_ip_route_ospf_instance_cmd);
0d9551dc 3847 install_element (VIEW_NODE, &show_ip_route_tag_cmd);
fb018d25 3848 install_element (VIEW_NODE, &show_ip_nht_cmd);
d511d7f1 3849 install_element (VIEW_NODE, &show_ip_nht_vrf_all_cmd);
fb018d25 3850 install_element (VIEW_NODE, &show_ipv6_nht_cmd);
d511d7f1 3851 install_element (VIEW_NODE, &show_ipv6_nht_vrf_all_cmd);
718e3744 3852 install_element (VIEW_NODE, &show_ip_route_addr_cmd);
3853 install_element (VIEW_NODE, &show_ip_route_prefix_cmd);
3854 install_element (VIEW_NODE, &show_ip_route_prefix_longer_cmd);
3855 install_element (VIEW_NODE, &show_ip_route_protocol_cmd);
3856 install_element (VIEW_NODE, &show_ip_route_supernets_cmd);
61691c91 3857 install_element (VIEW_NODE, &show_ip_route_summary_cmd);
9343ce83 3858 install_element (VIEW_NODE, &show_ip_route_summary_prefix_cmd);
718e3744 3859
b78a80d7 3860 install_element (VIEW_NODE, &show_ip_rpf_cmd);
65dd94cf 3861 install_element (VIEW_NODE, &show_ip_rpf_addr_cmd);
cddf391b 3862
af41b63a
FL
3863 /* Commands for VRF */
3864
fb5b479d
DS
3865 install_element (CONFIG_NODE, &no_ip_route_flags_cmd);
3866 install_element (CONFIG_NODE, &no_ip_route_mask_flags_cmd);
8f527c5e 3867
e52702f2 3868 install_element (VIEW_NODE, &show_ip_route_vrf_cmd);
af41b63a
FL
3869
3870 install_element (VIEW_NODE, &show_ip_route_vrf_all_cmd);
d511d7f1
DS
3871 install_element (VIEW_NODE, &show_ip_route_vrf_all_tag_cmd);
3872 install_element (VIEW_NODE, &show_ip_route_vrf_all_addr_cmd);
3873 install_element (VIEW_NODE, &show_ip_route_vrf_all_prefix_cmd);
3874 install_element (VIEW_NODE, &show_ip_route_vrf_all_prefix_longer_cmd);
3875 install_element (VIEW_NODE, &show_ip_route_vrf_all_protocol_cmd);
3876 install_element (VIEW_NODE, &show_ip_route_vrf_all_supernets_cmd);
3877 install_element (VIEW_NODE, &show_ip_route_vrf_all_summary_cmd);
3878 install_element (VIEW_NODE, &show_ip_route_vrf_all_summary_prefix_cmd);
af41b63a 3879
718e3744 3880 install_element (CONFIG_NODE, &ipv6_route_cmd);
81dfcaa2 3881 install_element (CONFIG_NODE, &ipv6_route_flags_cmd);
718e3744 3882 install_element (CONFIG_NODE, &ipv6_route_ifname_cmd);
81dfcaa2 3883 install_element (CONFIG_NODE, &ipv6_route_ifname_flags_cmd);
718e3744 3884 install_element (CONFIG_NODE, &no_ipv6_route_cmd);
81dfcaa2 3885 install_element (CONFIG_NODE, &no_ipv6_route_flags_cmd);
718e3744 3886 install_element (CONFIG_NODE, &no_ipv6_route_ifname_cmd);
81dfcaa2 3887 install_element (CONFIG_NODE, &no_ipv6_route_ifname_flags_cmd);
a50b580a
DS
3888 install_element (CONFIG_NODE, &ip_nht_default_route_cmd);
3889 install_element (CONFIG_NODE, &no_ip_nht_default_route_cmd);
3890 install_element (CONFIG_NODE, &ipv6_nht_default_route_cmd);
3891 install_element (CONFIG_NODE, &no_ipv6_nht_default_route_cmd);
718e3744 3892 install_element (VIEW_NODE, &show_ipv6_route_cmd);
0d9551dc 3893 install_element (VIEW_NODE, &show_ipv6_route_tag_cmd);
61691c91 3894 install_element (VIEW_NODE, &show_ipv6_route_summary_cmd);
9343ce83 3895 install_element (VIEW_NODE, &show_ipv6_route_summary_prefix_cmd);
718e3744 3896 install_element (VIEW_NODE, &show_ipv6_route_protocol_cmd);
3897 install_element (VIEW_NODE, &show_ipv6_route_addr_cmd);
3898 install_element (VIEW_NODE, &show_ipv6_route_prefix_cmd);
3899 install_element (VIEW_NODE, &show_ipv6_route_prefix_longer_cmd);
cddf391b
B
3900
3901 install_element (VIEW_NODE, &show_ipv6_mroute_cmd);
af41b63a
FL
3902
3903 /* Commands for VRF */
af41b63a 3904 install_element (VIEW_NODE, &show_ipv6_route_vrf_all_cmd);
d511d7f1
DS
3905 install_element (VIEW_NODE, &show_ipv6_route_vrf_all_tag_cmd);
3906 install_element (VIEW_NODE, &show_ipv6_route_vrf_all_summary_cmd);
3907 install_element (VIEW_NODE, &show_ipv6_route_vrf_all_summary_prefix_cmd);
3908 install_element (VIEW_NODE, &show_ipv6_route_vrf_all_protocol_cmd);
3909 install_element (VIEW_NODE, &show_ipv6_route_vrf_all_addr_cmd);
3910 install_element (VIEW_NODE, &show_ipv6_route_vrf_all_prefix_cmd);
3911 install_element (VIEW_NODE, &show_ipv6_route_vrf_all_prefix_longer_cmd);
af41b63a 3912
af41b63a 3913 install_element (VIEW_NODE, &show_ipv6_mroute_vrf_all_cmd);
718e3744 3914}