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