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