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