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