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