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