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