]> git.proxmox.com Git - mirror_frr.git/blame - zebra/zebra_vty.c
Merge pull request #8639 from idryzhov/isis-new-bfd-lib
[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"
718e3744 24#include "if.h"
25#include "prefix.h"
26#include "command.h"
27#include "table.h"
28#include "rib.h"
fb018d25 29#include "nexthop.h"
b72ede27 30#include "vrf.h"
4060008b 31#include "linklist.h"
7758e3f3 32#include "mpls.h"
4a1ab8e4 33#include "routemap.h"
05737783 34#include "srcdest_table.h"
cec2e17d 35#include "vxlan.h"
718e3744 36
89272910 37#include "zebra/zebra_router.h"
a1ac18c4 38#include "zebra/zserv.h"
7c551956 39#include "zebra/zebra_vrf.h"
7758e3f3 40#include "zebra/zebra_mpls.h"
fb018d25 41#include "zebra/zebra_rnh.h"
7a4bb9c5 42#include "zebra/redistribute.h"
6baf7bb8 43#include "zebra/zebra_routemap.h"
1d666fcb 44#include "lib/json.h"
cec2e17d 45#include "zebra/zebra_vxlan.h"
374b316c 46#include "zebra/zebra_evpn_mh.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"
21be1364 55#include "zebra/zebra_nhg.h"
41c809b2 56#include "zebra/zebra_evpn_mh.h"
1e9aad82 57#include "zebra/interface.h"
d36228c9 58#include "northbound_cli.h"
e2bcfa39 59#include "zebra/zebra_nb.h"
531c92b8 60#include "zebra/kernel_netlink.h"
6baf7bb8
DS
61
62extern int allow_delete;
a1ac18c4 63
8277d4b7
CG
64/* context to manage dumps in multiple tables or vrfs */
65struct route_show_ctx {
66 bool multi; /* dump multiple tables or vrf */
67 bool header_done; /* common header already displayed */
68};
69
d62a17ae 70static int do_show_ip_route(struct vty *vty, const char *vrf_name, afi_t afi,
9f049418 71 safi_t safi, bool use_fib, bool use_json,
ecffa493
RW
72 route_tag_t tag,
73 const struct prefix *longer_prefix_p,
d62a17ae 74 bool supernets_only, int type,
8277d4b7
CG
75 unsigned short ospf_instance_id, uint32_t tableid,
76 struct route_show_ctx *ctx);
d62a17ae 77static void vty_show_ip_route_detail(struct vty *vty, struct route_node *rn,
61d9ffe1 78 int mcast, bool use_fib, bool show_ng);
5ce91022 79static void vty_show_ip_route_summary(struct vty *vty,
e7deb7e7 80 struct route_table *table, bool use_json);
5ce91022 81static void vty_show_ip_route_summary_prefix(struct vty *vty,
e7deb7e7
DA
82 struct route_table *table,
83 bool use_json);
e95f6d21
MS
84/* Helper api to format a nexthop in the 'detailed' output path. */
85static void show_nexthop_detail_helper(struct vty *vty,
86 const struct route_entry *re,
87 const struct nexthop *nexthop,
88 bool is_backup);
89
b78a80d7 90
4623d897
DL
91DEFUN (ip_multicast_mode,
92 ip_multicast_mode_cmd,
6147e2c6 93 "ip multicast rpf-lookup-mode <urib-only|mrib-only|mrib-then-urib|lower-distance|longer-prefix>",
4623d897
DL
94 IP_STR
95 "Multicast options\n"
96 "RPF lookup behavior\n"
97 "Lookup in unicast RIB only\n"
98 "Lookup in multicast RIB only\n"
99 "Try multicast RIB first, fall back to unicast RIB\n"
100 "Lookup both, use entry with lower distance\n"
101 "Lookup both, use entry with longer prefix\n")
102{
d62a17ae 103 char *mode = argv[3]->text;
104
105 if (strmatch(mode, "urib-only"))
106 multicast_mode_ipv4_set(MCAST_URIB_ONLY);
107 else if (strmatch(mode, "mrib-only"))
108 multicast_mode_ipv4_set(MCAST_MRIB_ONLY);
109 else if (strmatch(mode, "mrib-then-urib"))
110 multicast_mode_ipv4_set(MCAST_MIX_MRIB_FIRST);
111 else if (strmatch(mode, "lower-distance"))
112 multicast_mode_ipv4_set(MCAST_MIX_DISTANCE);
113 else if (strmatch(mode, "longer-prefix"))
114 multicast_mode_ipv4_set(MCAST_MIX_PFXLEN);
115 else {
116 vty_out(vty, "Invalid mode specified\n");
117 return CMD_WARNING_CONFIG_FAILED;
118 }
4623d897 119
d62a17ae 120 return CMD_SUCCESS;
4623d897
DL
121}
122
123DEFUN (no_ip_multicast_mode,
124 no_ip_multicast_mode_cmd,
b62ecea5 125 "no ip multicast rpf-lookup-mode [<urib-only|mrib-only|mrib-then-urib|lower-distance|longer-prefix>]",
4623d897
DL
126 NO_STR
127 IP_STR
128 "Multicast options\n"
129 "RPF lookup behavior\n"
130 "Lookup in unicast RIB only\n"
131 "Lookup in multicast RIB only\n"
132 "Try multicast RIB first, fall back to unicast RIB\n"
133 "Lookup both, use entry with lower distance\n"
134 "Lookup both, use entry with longer prefix\n")
135{
d62a17ae 136 multicast_mode_ipv4_set(MCAST_NO_CONFIG);
137 return CMD_SUCCESS;
4623d897
DL
138}
139
4623d897 140
b78a80d7
EM
141DEFUN (show_ip_rpf,
142 show_ip_rpf_cmd,
acb25e73 143 "show ip rpf [json]",
b78a80d7
EM
144 SHOW_STR
145 IP_STR
acb25e73
DW
146 "Display RPF information for multicast source\n"
147 JSON_STR)
b78a80d7 148{
9f049418 149 bool uj = use_json(argc, argv);
8277d4b7
CG
150 struct route_show_ctx ctx = {
151 .multi = false,
152 };
153
d62a17ae 154 return do_show_ip_route(vty, VRF_DEFAULT_NAME, AFI_IP, SAFI_MULTICAST,
8277d4b7 155 false, uj, 0, NULL, false, 0, 0, 0, &ctx);
b78a80d7
EM
156}
157
65dd94cf
DL
158DEFUN (show_ip_rpf_addr,
159 show_ip_rpf_addr_cmd,
160 "show ip rpf A.B.C.D",
161 SHOW_STR
162 IP_STR
163 "Display RPF information for multicast source\n"
164 "IP multicast source address (e.g. 10.0.0.0)\n")
165{
d62a17ae 166 int idx_ipv4 = 3;
167 struct in_addr addr;
168 struct route_node *rn;
169 struct route_entry *re;
170 int ret;
171
172 ret = inet_aton(argv[idx_ipv4]->arg, &addr);
173 if (ret == 0) {
174 vty_out(vty, "%% Malformed address\n");
175 return CMD_WARNING;
176 }
177
178 re = rib_match_ipv4_multicast(VRF_DEFAULT, addr, &rn);
179
180 if (re)
61d9ffe1 181 vty_show_ip_route_detail(vty, rn, 1, false, false);
d62a17ae 182 else
183 vty_out(vty, "%% No match for RPF lookup\n");
184
185 return CMD_SUCCESS;
186}
187
accf6280 188static char re_status_output_char(const struct route_entry *re,
3c0e1622
MS
189 const struct nexthop *nhop,
190 bool is_fib)
4a2f796f 191{
677c1dd5 192 if (CHECK_FLAG(re->status, ROUTE_ENTRY_INSTALLED)) {
3c0e1622
MS
193 bool star_p = false;
194
195 if (nhop &&
196 !CHECK_FLAG(nhop->flags, NEXTHOP_FLAG_DUPLICATE) &&
197 !CHECK_FLAG(nhop->flags, NEXTHOP_FLAG_RECURSIVE)) {
198 /* More-specific test for 'fib' output */
199 if (is_fib) {
200 star_p = !!CHECK_FLAG(nhop->flags,
201 NEXTHOP_FLAG_FIB);
202 } else
203 star_p = true;
204 }
205
e4876266
DS
206 if (zrouter.asic_offloaded &&
207 CHECK_FLAG(re->status, ROUTE_ENTRY_QUEUED))
208 return 'q';
209
5a3cf853
DS
210 if (zrouter.asic_offloaded
211 && CHECK_FLAG(re->flags, ZEBRA_FLAG_TRAPPED))
212 return 't';
213
214 if (zrouter.asic_offloaded
0d32fbee 215 && CHECK_FLAG(re->flags, ZEBRA_FLAG_OFFLOAD_FAILED))
5a3cf853
DS
216 return 'o';
217
3c0e1622 218 if (star_p)
4a2f796f 219 return '*';
677c1dd5
DS
220 else
221 return ' ';
4a2f796f
DS
222 }
223
677c1dd5
DS
224 if (CHECK_FLAG(re->status, ROUTE_ENTRY_FAILED)) {
225 if (CHECK_FLAG(re->status, ROUTE_ENTRY_QUEUED))
226 return 'q';
227
b0538fc8 228 return 'r';
677c1dd5
DS
229 }
230
231 if (CHECK_FLAG(re->status, ROUTE_ENTRY_QUEUED))
232 return 'q';
233
4a2f796f
DS
234 return ' ';
235}
236
accf6280 237/*
e95f6d21 238 * Show backup nexthop info, in the 'detailed' output path
accf6280
MS
239 */
240static void show_nh_backup_helper(struct vty *vty,
e95f6d21 241 const struct route_entry *re,
accf6280
MS
242 const struct nexthop *nexthop)
243{
e95f6d21
MS
244 const struct nexthop *start, *backup, *temp;
245 int i, idx;
246
accf6280 247 /* Double-check that there _is_ a backup */
e95f6d21 248 if (!CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_HAS_BACKUP) ||
3c0e1622
MS
249 re->nhe->backup_info == NULL || re->nhe->backup_info->nhe == NULL ||
250 re->nhe->backup_info->nhe->nhg.nexthop == NULL)
accf6280
MS
251 return;
252
e95f6d21
MS
253 /* Locate the backup nexthop(s) */
254 start = re->nhe->backup_info->nhe->nhg.nexthop;
255 for (i = 0; i < nexthop->backup_num; i++) {
256 /* Format the backup(s) (indented) */
257 backup = start;
258 for (idx = 0; idx < nexthop->backup_idx[i]; idx++) {
259 backup = backup->next;
260 if (backup == NULL)
261 break;
262 }
accf6280 263
3c0e1622
MS
264 /* It's possible for backups to be recursive too,
265 * so walk the recursive resolution list if present.
266 */
e95f6d21
MS
267 temp = backup;
268 while (backup) {
269 vty_out(vty, " ");
270 show_nexthop_detail_helper(vty, re, backup,
271 true /*backup*/);
272 vty_out(vty, "\n");
273
274 if (backup->resolved && temp == backup)
275 backup = backup->resolved;
276 else
277 backup = nexthop_next(backup);
accf6280 278
e95f6d21
MS
279 if (backup == temp->next)
280 break;
281 }
282 }
accf6280
MS
283
284}
285
286/*
287 * Helper api to format output for a nexthop, used in the 'detailed'
288 * output path.
289 */
290static void show_nexthop_detail_helper(struct vty *vty,
291 const struct route_entry *re,
e95f6d21
MS
292 const struct nexthop *nexthop,
293 bool is_backup)
accf6280
MS
294{
295 char addrstr[32];
296 char buf[MPLS_LABEL_STRLEN];
e95f6d21 297 int i;
accf6280 298
e95f6d21
MS
299 if (is_backup)
300 vty_out(vty, " b%s",
301 nexthop->rparent ? " " : "");
302 else
303 vty_out(vty, " %c%s",
3c0e1622 304 re_status_output_char(re, nexthop, false),
e95f6d21 305 nexthop->rparent ? " " : "");
accf6280
MS
306
307 switch (nexthop->type) {
308 case NEXTHOP_TYPE_IPV4:
309 case NEXTHOP_TYPE_IPV4_IFINDEX:
9bcef951
MS
310 vty_out(vty, " %pI4",
311 &nexthop->gate.ipv4);
accf6280
MS
312 if (nexthop->ifindex)
313 vty_out(vty, ", via %s",
314 ifindex2ifname(
315 nexthop->ifindex,
316 nexthop->vrf_id));
317 break;
318 case NEXTHOP_TYPE_IPV6:
319 case NEXTHOP_TYPE_IPV6_IFINDEX:
320 vty_out(vty, " %s",
321 inet_ntop(AF_INET6, &nexthop->gate.ipv6,
322 buf, sizeof(buf)));
323 if (nexthop->ifindex)
324 vty_out(vty, ", via %s",
325 ifindex2ifname(
326 nexthop->ifindex,
327 nexthop->vrf_id));
328 break;
329
330 case NEXTHOP_TYPE_IFINDEX:
331 vty_out(vty, " directly connected, %s",
332 ifindex2ifname(nexthop->ifindex,
333 nexthop->vrf_id));
334 break;
335 case NEXTHOP_TYPE_BLACKHOLE:
336 vty_out(vty, " unreachable");
337 switch (nexthop->bh_type) {
338 case BLACKHOLE_REJECT:
339 vty_out(vty, " (ICMP unreachable)");
340 break;
341 case BLACKHOLE_ADMINPROHIB:
342 vty_out(vty,
343 " (ICMP admin-prohibited)");
344 break;
345 case BLACKHOLE_NULL:
346 vty_out(vty, " (blackhole)");
347 break;
348 case BLACKHOLE_UNSPEC:
349 break;
350 }
351 break;
352 default:
353 break;
354 }
355
356 if ((re->vrf_id != nexthop->vrf_id)
6ac94041
CG
357 && (nexthop->type != NEXTHOP_TYPE_BLACKHOLE))
358 vty_out(vty, "(vrf %s)", vrf_id_to_name(nexthop->vrf_id));
accf6280
MS
359
360 if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_DUPLICATE))
361 vty_out(vty, " (duplicate nexthop removed)");
362
363 if (!CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE))
364 vty_out(vty, " inactive");
365
366 if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ONLINK))
367 vty_out(vty, " onlink");
368
369 if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
370 vty_out(vty, " (recursive)");
371
372 /* Source specified? */
373 switch (nexthop->type) {
374 case NEXTHOP_TYPE_IPV4:
375 case NEXTHOP_TYPE_IPV4_IFINDEX:
376 if (nexthop->src.ipv4.s_addr) {
377 if (inet_ntop(AF_INET, &nexthop->src.ipv4,
378 addrstr, sizeof(addrstr)))
379 vty_out(vty, ", src %s",
380 addrstr);
381 }
382 break;
383
384 case NEXTHOP_TYPE_IPV6:
385 case NEXTHOP_TYPE_IPV6_IFINDEX:
386 if (!IPV6_ADDR_SAME(&nexthop->src.ipv6,
387 &in6addr_any)) {
388 if (inet_ntop(AF_INET6, &nexthop->src.ipv6,
389 addrstr, sizeof(addrstr)))
390 vty_out(vty, ", src %s",
391 addrstr);
392 }
393 break;
394
395 default:
396 break;
397 }
398
399 if (re->nexthop_mtu)
400 vty_out(vty, ", mtu %u", re->nexthop_mtu);
401
402 /* Label information */
403 if (nexthop->nh_label && nexthop->nh_label->num_labels) {
404 vty_out(vty, ", label %s",
405 mpls_label2str(nexthop->nh_label->num_labels,
406 nexthop->nh_label->label, buf,
407 sizeof(buf), 1 /*pretty*/));
408 }
409
410 if (nexthop->weight)
411 vty_out(vty, ", weight %u", nexthop->weight);
e95f6d21
MS
412
413 if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_HAS_BACKUP)) {
414 vty_out(vty, ", backup %d", nexthop->backup_idx[0]);
415
416 for (i = 1; i < nexthop->backup_num; i++)
417 vty_out(vty, ",%d", nexthop->backup_idx[i]);
418 }
accf6280
MS
419}
420
80a6ee90
DS
421static void zebra_show_ip_route_opaque(struct vty *vty, struct route_entry *re,
422 struct json_object *json)
423{
424 if (!re->opaque)
425 return;
426
427 switch (re->type) {
cfa2a35d
DS
428 case ZEBRA_ROUTE_SHARP:
429 if (json)
430 json_object_string_add(json, "opaque",
431 (char *)re->opaque->data);
432 else
433 vty_out(vty, " Opaque Data: %s",
434 (char *)re->opaque->data);
435 break;
e46723a5
DS
436 case ZEBRA_ROUTE_BGP:
437 if (json)
438 json_object_string_add(json, "asPath",
439 (char *)re->opaque->data);
440 else
441 vty_out(vty, " AS-Path: %s",
442 (char *)re->opaque->data);
80a6ee90
DS
443 default:
444 break;
445 }
446}
447
45691de9
SW
448static void uptime2str(time_t uptime, char *buf, size_t bufsize)
449{
450 time_t cur;
451
452 cur = monotime(NULL);
453 cur -= uptime;
454
455 frrtime_to_interval(cur, buf, bufsize);
456}
457
8f527c5e 458/* New RIB. Detailed information for IPv4 route. */
d62a17ae 459static void vty_show_ip_route_detail(struct vty *vty, struct route_node *rn,
61d9ffe1 460 int mcast, bool use_fib, bool show_ng)
d62a17ae 461{
462 struct route_entry *re;
463 struct nexthop *nexthop;
464 char buf[SRCDEST2STR_BUFFER];
465 struct zebra_vrf *zvrf;
6a794a7e
AD
466 rib_dest_t *dest;
467
468 dest = rib_dest_from_rnode(rn);
d62a17ae 469
a2addae8 470 RNODE_FOREACH_RE (rn, re) {
6a794a7e
AD
471 /*
472 * If re not selected for forwarding, skip re
473 * for "show ip/ipv6 fib <prefix>"
474 */
475 if (use_fib && re != dest->selected_fib)
476 continue;
477
d62a17ae 478 const char *mcast_info = "";
479 if (mcast) {
630d5962
DS
480 struct rib_table_info *info =
481 srcdest_rnode_table_info(rn);
d62a17ae 482 mcast_info = (info->safi == SAFI_MULTICAST)
483 ? " using Multicast RIB"
484 : " using Unicast RIB";
485 }
486
487 vty_out(vty, "Routing entry for %s%s\n",
488 srcdest_rnode2str(rn, buf, sizeof(buf)), mcast_info);
489 vty_out(vty, " Known via \"%s", zebra_route_string(re->type));
490 if (re->instance)
491 vty_out(vty, "[%d]", re->instance);
492 vty_out(vty, "\"");
493 vty_out(vty, ", distance %u, metric %u", re->distance,
494 re->metric);
0efb5e9b 495 if (re->tag) {
8526b842 496 vty_out(vty, ", tag %u", re->tag);
0efb5e9b
DS
497#if defined(SUPPORT_REALMS)
498 if (re->tag > 0 && re->tag <= 255)
499 vty_out(vty, "(realm)");
500#endif
501 }
d62a17ae 502 if (re->mtu)
503 vty_out(vty, ", mtu %u", re->mtu);
504 if (re->vrf_id != VRF_DEFAULT) {
505 zvrf = vrf_info_lookup(re->vrf_id);
506 vty_out(vty, ", vrf %s", zvrf_name(zvrf));
507 }
508 if (CHECK_FLAG(re->flags, ZEBRA_FLAG_SELECTED))
509 vty_out(vty, ", best");
d62a17ae 510 vty_out(vty, "\n");
511
45691de9 512 uptime2str(re->uptime, buf, sizeof(buf));
14a481d9 513
d0636ead 514 vty_out(vty, " Last update %s ago\n", buf);
d62a17ae 515
61d9ffe1
SW
516 if (show_ng)
517 vty_out(vty, " Nexthop Group ID: %u\n", re->nhe_id);
518
c415d895 519 for (ALL_NEXTHOPS(re->nhe->nhg, nexthop)) {
accf6280 520 /* Use helper to format each nexthop */
e95f6d21
MS
521 show_nexthop_detail_helper(vty, re, nexthop,
522 false /*not backup*/);
accf6280 523 vty_out(vty, "\n");
2793a098 524
e95f6d21 525 /* Include backup(s), if present */
accf6280 526 if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_HAS_BACKUP))
e95f6d21 527 show_nh_backup_helper(vty, re, nexthop);
accf6280 528 }
80a6ee90
DS
529 zebra_show_ip_route_opaque(vty, re, NULL);
530
accf6280
MS
531 vty_out(vty, "\n");
532 }
533}
2793a098 534
accf6280
MS
535/*
536 * Helper for nexthop output, used in the 'show ip route' path
537 */
538static void show_route_nexthop_helper(struct vty *vty,
539 const struct route_entry *re,
540 const struct nexthop *nexthop)
541{
542 char buf[MPLS_LABEL_STRLEN];
474aebd9 543 int i;
eaf5150f 544
accf6280
MS
545 switch (nexthop->type) {
546 case NEXTHOP_TYPE_IPV4:
547 case NEXTHOP_TYPE_IPV4_IFINDEX:
9bcef951 548 vty_out(vty, " via %pI4", &nexthop->gate.ipv4);
accf6280
MS
549 if (nexthop->ifindex)
550 vty_out(vty, ", %s",
551 ifindex2ifname(nexthop->ifindex,
552 nexthop->vrf_id));
553 break;
554 case NEXTHOP_TYPE_IPV6:
555 case NEXTHOP_TYPE_IPV6_IFINDEX:
556 vty_out(vty, " via %s",
557 inet_ntop(AF_INET6, &nexthop->gate.ipv6, buf,
558 sizeof(buf)));
559 if (nexthop->ifindex)
560 vty_out(vty, ", %s",
561 ifindex2ifname(nexthop->ifindex,
562 nexthop->vrf_id));
563 break;
d62a17ae 564
accf6280
MS
565 case NEXTHOP_TYPE_IFINDEX:
566 vty_out(vty, " is directly connected, %s",
567 ifindex2ifname(nexthop->ifindex,
568 nexthop->vrf_id));
569 break;
570 case NEXTHOP_TYPE_BLACKHOLE:
571 vty_out(vty, " unreachable");
572 switch (nexthop->bh_type) {
573 case BLACKHOLE_REJECT:
574 vty_out(vty, " (ICMP unreachable)");
575 break;
576 case BLACKHOLE_ADMINPROHIB:
577 vty_out(vty, " (ICMP admin-prohibited)");
578 break;
579 case BLACKHOLE_NULL:
580 vty_out(vty, " (blackhole)");
581 break;
582 case BLACKHOLE_UNSPEC:
583 break;
584 }
585 break;
586 default:
587 break;
588 }
d62a17ae 589
6ac94041
CG
590 if ((re == NULL || (nexthop->vrf_id != re->vrf_id))
591 && (nexthop->type != NEXTHOP_TYPE_BLACKHOLE))
592 vty_out(vty, " (vrf %s)", vrf_id_to_name(nexthop->vrf_id));
d62a17ae 593
accf6280
MS
594 if (!CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE))
595 vty_out(vty, " inactive");
1994ae60 596
accf6280
MS
597 if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ONLINK))
598 vty_out(vty, " onlink");
d62a17ae 599
accf6280
MS
600 if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
601 vty_out(vty, " (recursive)");
bd054c1a 602
accf6280
MS
603 switch (nexthop->type) {
604 case NEXTHOP_TYPE_IPV4:
605 case NEXTHOP_TYPE_IPV4_IFINDEX:
606 if (nexthop->src.ipv4.s_addr) {
607 if (inet_ntop(AF_INET, &nexthop->src.ipv4, buf,
608 sizeof(buf)))
609 vty_out(vty, ", src %s", buf);
31f937fb
SM
610 /* SR-TE information */
611 if (nexthop->srte_color)
612 vty_out(vty, ", SR-TE color %u",
613 nexthop->srte_color);
d62a17ae 614 }
accf6280
MS
615 break;
616 case NEXTHOP_TYPE_IPV6:
617 case NEXTHOP_TYPE_IPV6_IFINDEX:
618 if (!IPV6_ADDR_SAME(&nexthop->src.ipv6, &in6addr_any)) {
619 if (inet_ntop(AF_INET6, &nexthop->src.ipv6, buf,
620 sizeof(buf)))
621 vty_out(vty, ", src %s", buf);
622 }
623 break;
624 default:
625 break;
626 }
627
628 /* Label information */
629 if (nexthop->nh_label && nexthop->nh_label->num_labels) {
630 vty_out(vty, ", label %s",
631 mpls_label2str(nexthop->nh_label->num_labels,
632 nexthop->nh_label->label, buf,
633 sizeof(buf), 1));
d62a17ae 634 }
accf6280 635
65d413f4 636 if (nexthop->weight)
accf6280 637 vty_out(vty, ", weight %u", nexthop->weight);
65d413f4 638
474aebd9
MS
639 if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_HAS_BACKUP)) {
640 vty_out(vty, ", backup %d", nexthop->backup_idx[0]);
641
642 for (i = 1; i < nexthop->backup_num; i++)
e95f6d21 643 vty_out(vty, ",%d", nexthop->backup_idx[i]);
474aebd9 644 }
65d413f4
MS
645}
646
647/*
648 * Render a nexthop into a json object; the caller allocates and owns
649 * the json object memory.
650 */
651static void show_nexthop_json_helper(json_object *json_nexthop,
652 const struct nexthop *nexthop,
653 const struct route_entry *re)
654{
655 char buf[SRCDEST2STR_BUFFER];
65d413f4 656 json_object *json_labels = NULL;
474aebd9
MS
657 json_object *json_backups = NULL;
658 int i;
65d413f4
MS
659
660 json_object_int_add(json_nexthop, "flags",
661 nexthop->flags);
662
663 if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_DUPLICATE))
664 json_object_boolean_true_add(json_nexthop,
665 "duplicate");
666
667 if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB))
668 json_object_boolean_true_add(json_nexthop,
669 "fib");
670
671 switch (nexthop->type) {
672 case NEXTHOP_TYPE_IPV4:
673 case NEXTHOP_TYPE_IPV4_IFINDEX:
674 json_object_string_add(
675 json_nexthop, "ip",
9bcef951
MS
676 inet_ntop(AF_INET, &nexthop->gate.ipv4,
677 buf, sizeof(buf)));
65d413f4
MS
678 json_object_string_add(json_nexthop, "afi",
679 "ipv4");
680
681 if (nexthop->ifindex) {
682 json_object_int_add(json_nexthop,
683 "interfaceIndex",
684 nexthop->ifindex);
685 json_object_string_add(
686 json_nexthop, "interfaceName",
687 ifindex2ifname(
688 nexthop->ifindex,
689 nexthop->vrf_id));
690 }
691 break;
692 case NEXTHOP_TYPE_IPV6:
693 case NEXTHOP_TYPE_IPV6_IFINDEX:
694 json_object_string_add(
695 json_nexthop, "ip",
696 inet_ntop(AF_INET6, &nexthop->gate.ipv6,
697 buf, sizeof(buf)));
698 json_object_string_add(json_nexthop, "afi",
699 "ipv6");
700
701 if (nexthop->ifindex) {
702 json_object_int_add(json_nexthop,
703 "interfaceIndex",
704 nexthop->ifindex);
705 json_object_string_add(
706 json_nexthop, "interfaceName",
707 ifindex2ifname(
708 nexthop->ifindex,
709 nexthop->vrf_id));
710 }
711 break;
712
713 case NEXTHOP_TYPE_IFINDEX:
714 json_object_boolean_true_add(
715 json_nexthop, "directlyConnected");
716 json_object_int_add(json_nexthop,
717 "interfaceIndex",
718 nexthop->ifindex);
719 json_object_string_add(
720 json_nexthop, "interfaceName",
721 ifindex2ifname(nexthop->ifindex,
722 nexthop->vrf_id));
723 break;
724 case NEXTHOP_TYPE_BLACKHOLE:
725 json_object_boolean_true_add(json_nexthop,
726 "unreachable");
727 switch (nexthop->bh_type) {
728 case BLACKHOLE_REJECT:
729 json_object_boolean_true_add(
730 json_nexthop, "reject");
731 break;
732 case BLACKHOLE_ADMINPROHIB:
733 json_object_boolean_true_add(
734 json_nexthop,
735 "admin-prohibited");
736 break;
737 case BLACKHOLE_NULL:
738 json_object_boolean_true_add(
739 json_nexthop, "blackhole");
740 break;
741 case BLACKHOLE_UNSPEC:
742 break;
743 }
744 break;
745 default:
746 break;
747 }
748
749 if ((nexthop->vrf_id != re->vrf_id)
6ac94041 750 && (nexthop->type != NEXTHOP_TYPE_BLACKHOLE))
65d413f4 751 json_object_string_add(json_nexthop, "vrf",
6ac94041
CG
752 vrf_id_to_name(nexthop->vrf_id));
753
65d413f4
MS
754 if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_DUPLICATE))
755 json_object_boolean_true_add(json_nexthop,
756 "duplicate");
757
758 if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE))
759 json_object_boolean_true_add(json_nexthop,
760 "active");
761
762 if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ONLINK))
763 json_object_boolean_true_add(json_nexthop,
764 "onLink");
765
766 if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
767 json_object_boolean_true_add(json_nexthop,
768 "recursive");
769
474aebd9
MS
770 if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_HAS_BACKUP)) {
771 json_backups = json_object_new_array();
772 for (i = 0; i < nexthop->backup_num; i++) {
773 json_object_array_add(
774 json_backups,
775 json_object_new_int(nexthop->backup_idx[i]));
776 }
777
778 json_object_object_add(json_nexthop, "backupIndex",
779 json_backups);
780 }
65d413f4
MS
781
782 switch (nexthop->type) {
783 case NEXTHOP_TYPE_IPV4:
784 case NEXTHOP_TYPE_IPV4_IFINDEX:
785 if (nexthop->src.ipv4.s_addr) {
786 if (inet_ntop(AF_INET,
787 &nexthop->src.ipv4, buf,
788 sizeof(buf)))
789 json_object_string_add(
790 json_nexthop, "source",
791 buf);
792 }
793 break;
794 case NEXTHOP_TYPE_IPV6:
795 case NEXTHOP_TYPE_IPV6_IFINDEX:
796 if (!IPV6_ADDR_SAME(&nexthop->src.ipv6,
797 &in6addr_any)) {
798 if (inet_ntop(AF_INET6,
799 &nexthop->src.ipv6, buf,
800 sizeof(buf)))
801 json_object_string_add(
802 json_nexthop, "source",
803 buf);
804 }
805 break;
806 default:
807 break;
808 }
809
810 if (nexthop->nh_label
811 && nexthop->nh_label->num_labels) {
812 json_labels = json_object_new_array();
813
814 for (int label_index = 0;
815 label_index
816 < nexthop->nh_label->num_labels;
817 label_index++)
818 json_object_array_add(
819 json_labels,
820 json_object_new_int(
821 nexthop->nh_label->label
822 [label_index]));
823
824 json_object_object_add(json_nexthop, "labels",
825 json_labels);
826 }
827
828 if (nexthop->weight)
829 json_object_int_add(json_nexthop, "weight",
830 nexthop->weight);
831
31f937fb
SM
832 if (nexthop->srte_color)
833 json_object_int_add(json_nexthop, "srteColor",
834 nexthop->srte_color);
d62a17ae 835}
836
837static void vty_show_ip_route(struct vty *vty, struct route_node *rn,
941e261c
MS
838 struct route_entry *re, json_object *json,
839 bool is_fib)
d62a17ae 840{
3c0e1622 841 const struct nexthop *nexthop;
d62a17ae 842 int len = 0;
843 char buf[SRCDEST2STR_BUFFER];
844 json_object *json_nexthops = NULL;
845 json_object *json_nexthop = NULL;
846 json_object *json_route = NULL;
3c0e1622
MS
847 const rib_dest_t *dest = rib_dest_from_rnode(rn);
848 const struct nexthop_group *nhg;
d0636ead 849 char up_str[MONOTIME_STRLEN];
d532dd6d 850 bool first_p = true;
3c0e1622 851 bool nhg_from_backup = false;
14a481d9 852
45691de9 853 uptime2str(re->uptime, up_str, sizeof(up_str));
d62a17ae 854
941e261c
MS
855 /* If showing fib information, use the fib view of the
856 * nexthops.
857 */
858 if (is_fib)
65d413f4 859 nhg = rib_get_fib_nhg(re);
941e261c 860 else
c415d895 861 nhg = &(re->nhe->nhg);
941e261c 862
d62a17ae 863 if (json) {
864 json_route = json_object_new_object();
865 json_nexthops = json_object_new_array();
866
867 json_object_string_add(json_route, "prefix",
0d6f7fd6 868 srcdest_rnode2str(rn, buf, sizeof(buf)));
d62a17ae 869 json_object_string_add(json_route, "protocol",
870 zebra_route_string(re->type));
871
872 if (re->instance)
873 json_object_int_add(json_route, "instance",
874 re->instance);
875
d58b6f75
CG
876 json_object_int_add(json_route, "vrfId", re->vrf_id);
877 json_object_string_add(json_route, "vrfName",
878 vrf_id_to_name(re->vrf_id));
6ac94041 879
d62a17ae 880 if (CHECK_FLAG(re->flags, ZEBRA_FLAG_SELECTED))
881 json_object_boolean_true_add(json_route, "selected");
882
1e03ae0d
DS
883 if (dest->selected_fib == re)
884 json_object_boolean_true_add(json_route,
885 "destSelected");
886
059c79ba
AK
887 json_object_int_add(json_route, "distance",
888 re->distance);
889 json_object_int_add(json_route, "metric", re->metric);
d62a17ae 890
677c1dd5
DS
891 if (CHECK_FLAG(re->status, ROUTE_ENTRY_INSTALLED))
892 json_object_boolean_true_add(json_route, "installed");
893
894 if (CHECK_FLAG(re->status, ROUTE_ENTRY_FAILED))
895 json_object_boolean_true_add(json_route, "failed");
896
897 if (CHECK_FLAG(re->status, ROUTE_ENTRY_QUEUED))
898 json_object_boolean_true_add(json_route, "queued");
899
5a3cf853
DS
900 if (CHECK_FLAG(re->flags, ZEBRA_FLAG_TRAPPED))
901 json_object_boolean_true_add(json_route, "trapped");
902
903 if (CHECK_FLAG(re->flags, ZEBRA_FLAG_OFFLOADED))
904 json_object_boolean_true_add(json_route, "offloaded");
905
0d32fbee
DS
906 if (CHECK_FLAG(re->flags, ZEBRA_FLAG_OFFLOAD_FAILED))
907 json_object_boolean_false_add(json_route, "offloaded");
908
96d71e38
AD
909 if (re->tag)
910 json_object_int_add(json_route, "tag", re->tag);
911
234963a5
PG
912 if (re->table)
913 json_object_int_add(json_route, "table", re->table);
914
f03098f9
DS
915 json_object_int_add(json_route, "internalStatus",
916 re->status);
917 json_object_int_add(json_route, "internalFlags",
918 re->flags);
d4c7ac01 919 json_object_int_add(json_route, "internalNextHopNum",
c415d895 920 nexthop_group_nexthop_num(&(re->nhe->nhg)));
d4c7ac01 921 json_object_int_add(json_route, "internalNextHopActiveNum",
0eb97b86 922 nexthop_group_active_nexthop_num(
c415d895 923 &(re->nhe->nhg)));
14a481d9 924
d0636ead 925 json_object_string_add(json_route, "uptime", up_str);
d62a17ae 926
941e261c 927 for (ALL_NEXTHOPS_PTR(nhg, nexthop)) {
d62a17ae 928 json_nexthop = json_object_new_object();
3c0e1622
MS
929 show_nexthop_json_helper(json_nexthop,
930 nexthop, re);
d62a17ae 931
3c0e1622
MS
932 json_object_array_add(json_nexthops,
933 json_nexthop);
65d413f4 934 }
f03098f9 935
65d413f4 936 json_object_object_add(json_route, "nexthops", json_nexthops);
eaf5150f 937
65d413f4
MS
938 /* If there are backup nexthops, include them */
939 if (is_fib)
940 nhg = rib_get_fib_backup_nhg(re);
941 else
942 nhg = zebra_nhg_get_backup_nhg(re->nhe);
d62a17ae 943
3c0e1622 944 if (nhg && nhg->nexthop) {
65d413f4 945 json_nexthops = json_object_new_array();
d62a17ae 946
65d413f4
MS
947 for (ALL_NEXTHOPS_PTR(nhg, nexthop)) {
948 json_nexthop = json_object_new_object();
d62a17ae 949
65d413f4
MS
950 show_nexthop_json_helper(json_nexthop,
951 nexthop, re);
952 json_object_array_add(json_nexthops,
953 json_nexthop);
d62a17ae 954 }
955
65d413f4
MS
956 json_object_object_add(json_route, "backupNexthops",
957 json_nexthops);
d62a17ae 958 }
80a6ee90 959 zebra_show_ip_route_opaque(NULL, re, json_route);
d62a17ae 960
d62a17ae 961 json_object_array_add(json, json_route);
962 return;
963 }
964
3c0e1622
MS
965 /* Prefix information, and first nexthop. If we're showing 'fib',
966 * and there are no installed primary nexthops, see if there are any
967 * backup nexthops and start with those.
968 */
969 if (is_fib && nhg->nexthop == NULL) {
970 nhg = rib_get_fib_backup_nhg(re);
971 nhg_from_backup = true;
972 }
973
974 len = vty_out(vty, "%c", zebra_route_char(re->type));
975 if (re->instance)
976 len += vty_out(vty, "[%d]", re->instance);
977 if (nhg_from_backup && nhg->nexthop) {
978 len += vty_out(
979 vty, "%cb%c %s",
980 CHECK_FLAG(re->flags, ZEBRA_FLAG_SELECTED) ? '>' : ' ',
981 re_status_output_char(re, nhg->nexthop, is_fib),
982 srcdest_rnode2str(rn, buf, sizeof(buf)));
983 } else {
984 len += vty_out(
985 vty, "%c%c %s",
986 CHECK_FLAG(re->flags, ZEBRA_FLAG_SELECTED) ? '>' : ' ',
987 re_status_output_char(re, nhg->nexthop, is_fib),
988 srcdest_rnode2str(rn, buf, sizeof(buf)));
989 }
990
991 /* Distance and metric display. */
992 if (((re->type == ZEBRA_ROUTE_CONNECT) &&
993 (re->distance || re->metric)) ||
994 (re->type != ZEBRA_ROUTE_CONNECT))
995 len += vty_out(vty, " [%u/%u]", re->distance,
996 re->metric);
997
d62a17ae 998 /* Nexthop information. */
941e261c 999 for (ALL_NEXTHOPS_PTR(nhg, nexthop)) {
d532dd6d
JAG
1000 if (first_p) {
1001 first_p = false;
1002 } else if (nhg_from_backup) {
3c0e1622
MS
1003 vty_out(vty, " b%c%*c",
1004 re_status_output_char(re, nexthop, is_fib),
1005 len - 3 + (2 * nexthop_level(nexthop)), ' ');
eaf5150f 1006 } else {
d62a17ae 1007 vty_out(vty, " %c%*c",
3c0e1622 1008 re_status_output_char(re, nexthop, is_fib),
d62a17ae 1009 len - 3 + (2 * nexthop_level(nexthop)), ' ');
eaf5150f 1010 }
d62a17ae 1011
accf6280 1012 show_route_nexthop_helper(vty, re, nexthop);
accf6280 1013 vty_out(vty, ", %s\n", up_str);
65d413f4 1014 }
d62a17ae 1015
3c0e1622
MS
1016 /* If we only had backup nexthops, we're done */
1017 if (nhg_from_backup)
1018 return;
1019
1020 /* Check for backup nexthop info if present */
65d413f4
MS
1021 if (is_fib)
1022 nhg = rib_get_fib_backup_nhg(re);
1023 else
1024 nhg = zebra_nhg_get_backup_nhg(re->nhe);
d62a17ae 1025
65d413f4
MS
1026 if (nhg == NULL)
1027 return;
1028
1029 /* Print backup info */
1030 for (ALL_NEXTHOPS_PTR(nhg, nexthop)) {
1031 bool star_p = false;
1032
1033 if (is_fib)
1034 star_p = CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB);
1035
1036 /* TODO -- it'd be nice to be able to include
1037 * the entire list of backups, *and* include the
1038 * real installation state.
1039 */
1040 vty_out(vty, " b%c %*c",
1041 (star_p ? '*' : ' '),
1042 len - 3 + (2 * nexthop_level(nexthop)), ' ');
1043 show_route_nexthop_helper(vty, re, nexthop);
1044 vty_out(vty, "\n");
d62a17ae 1045 }
65d413f4 1046
d62a17ae 1047}
1048
96d71e38 1049static void vty_show_ip_route_detail_json(struct vty *vty,
accf6280 1050 struct route_node *rn, bool use_fib)
96d71e38
AD
1051{
1052 json_object *json = NULL;
1053 json_object *json_prefix = NULL;
1054 struct route_entry *re;
1055 char buf[BUFSIZ];
6a794a7e
AD
1056 rib_dest_t *dest;
1057
1058 dest = rib_dest_from_rnode(rn);
96d71e38
AD
1059
1060 json = json_object_new_object();
9e7cd6fd 1061 json_prefix = json_object_new_array();
96d71e38
AD
1062
1063 RNODE_FOREACH_RE (rn, re) {
6a794a7e
AD
1064 /*
1065 * If re not selected for forwarding, skip re
1066 * for "show ip/ipv6 fib <prefix> json"
1067 */
1068 if (use_fib && re != dest->selected_fib)
1069 continue;
941e261c 1070 vty_show_ip_route(vty, rn, re, json_prefix, use_fib);
96d71e38
AD
1071 }
1072
9e7cd6fd
DS
1073 prefix2str(&rn->p, buf, sizeof(buf));
1074 json_object_object_add(json, buf, json_prefix);
96d71e38
AD
1075 vty_out(vty, "%s\n", json_object_to_json_string_ext(
1076 json, JSON_C_TO_STRING_PRETTY));
1077 json_object_free(json);
1078}
1079
ae825b8b
DS
1080static void do_show_route_helper(struct vty *vty, struct zebra_vrf *zvrf,
1081 struct route_table *table, afi_t afi,
1082 bool use_fib, route_tag_t tag,
1083 const struct prefix *longer_prefix_p,
1084 bool supernets_only, int type,
234963a5 1085 unsigned short ospf_instance_id, bool use_json,
8277d4b7 1086 uint32_t tableid, struct route_show_ctx *ctx)
d62a17ae 1087{
d62a17ae 1088 struct route_node *rn;
1089 struct route_entry *re;
1090 int first = 1;
ae825b8b 1091 rib_dest_t *dest;
d62a17ae 1092 json_object *json = NULL;
1093 json_object *json_prefix = NULL;
ae825b8b
DS
1094 uint32_t addr;
1095 char buf[BUFSIZ];
d62a17ae 1096
8277d4b7
CG
1097 /*
1098 * ctx->multi indicates if we are dumping multiple tables or vrfs.
1099 * if set:
1100 * => display the common header at most once
1101 * => add newline at each call except first
1102 * => always display the VRF and table
1103 * else:
1104 * => display the common header if at least one entry is found
1105 * => display the VRF and table if specific
1106 */
1107
d62a17ae 1108 if (use_json)
1109 json = json_object_new_object();
1110
1111 /* Show all routes. */
c9591045 1112 for (rn = route_top(table); rn; rn = srcdest_route_next(rn)) {
5f7a4718
DS
1113 dest = rib_dest_from_rnode(rn);
1114
a2addae8 1115 RNODE_FOREACH_RE (rn, re) {
996c9314 1116 if (use_fib && re != dest->selected_fib)
d62a17ae 1117 continue;
1118
1119 if (tag && re->tag != tag)
1120 continue;
1121
1122 if (longer_prefix_p
1123 && !prefix_match(longer_prefix_p, &rn->p))
1124 continue;
1125
1126 /* This can only be true when the afi is IPv4 */
1127 if (supernets_only) {
1128 addr = ntohl(rn->p.u.prefix4.s_addr);
1129
1130 if (IN_CLASSC(addr) && rn->p.prefixlen >= 24)
1131 continue;
1132
1133 if (IN_CLASSB(addr) && rn->p.prefixlen >= 16)
1134 continue;
1135
1136 if (IN_CLASSA(addr) && rn->p.prefixlen >= 8)
1137 continue;
1138 }
1139
1140 if (type && re->type != type)
1141 continue;
1142
1143 if (ospf_instance_id
1144 && (re->type != ZEBRA_ROUTE_OSPF
1145 || re->instance != ospf_instance_id))
1146 continue;
1147
1148 if (use_json) {
1149 if (!json_prefix)
1150 json_prefix = json_object_new_array();
8277d4b7
CG
1151 } else if (first) {
1152 if (!ctx->header_done) {
d62a17ae 1153 if (afi == AFI_IP)
1154 vty_out(vty,
1155 SHOW_ROUTE_V4_HEADER);
1156 else
1157 vty_out(vty,
1158 SHOW_ROUTE_V6_HEADER);
8277d4b7
CG
1159 }
1160 if (ctx->multi && ctx->header_done)
1161 vty_out(vty, "\n");
1162 if (ctx->multi || zvrf_id(zvrf) != VRF_DEFAULT
1163 || tableid) {
1164 if (!tableid)
1165 vty_out(vty, "VRF %s:\n",
d62a17ae 1166 zvrf_name(zvrf));
8277d4b7
CG
1167 else
1168 vty_out(vty,
1169 "VRF %s table %u:\n",
1170 zvrf_name(zvrf),
1171 tableid);
d62a17ae 1172 }
8277d4b7
CG
1173 ctx->header_done = true;
1174 first = 0;
d62a17ae 1175 }
1176
941e261c 1177 vty_show_ip_route(vty, rn, re, json_prefix, use_fib);
d62a17ae 1178 }
1179
1180 if (json_prefix) {
96d71e38 1181 prefix2str(&rn->p, buf, sizeof(buf));
d62a17ae 1182 json_object_object_add(json, buf, json_prefix);
1183 json_prefix = NULL;
1184 }
1185 }
1186
1187 if (use_json) {
96d71e38
AD
1188 vty_out(vty, "%s\n", json_object_to_json_string_ext(json,
1189 JSON_C_TO_STRING_PRETTY));
d62a17ae 1190 json_object_free(json);
1191 }
ae825b8b
DS
1192}
1193
c5babc8c
MS
1194static void do_show_ip_route_all(struct vty *vty, struct zebra_vrf *zvrf,
1195 afi_t afi, bool use_fib, bool use_json,
7e0f48c7
TC
1196 route_tag_t tag,
1197 const struct prefix *longer_prefix_p,
1198 bool supernets_only, int type,
8277d4b7
CG
1199 unsigned short ospf_instance_id,
1200 struct route_show_ctx *ctx)
7e0f48c7
TC
1201{
1202 struct zebra_router_table *zrt;
630d5962 1203 struct rib_table_info *info;
7e0f48c7
TC
1204
1205 RB_FOREACH (zrt, zebra_router_table_head,
1206 &zrouter.tables) {
1207 info = route_table_get_info(zrt->table);
1208
1209 if (zvrf != info->zvrf)
1210 continue;
1211 if (zrt->afi != afi ||
1212 zrt->safi != SAFI_UNICAST)
1213 continue;
c5babc8c 1214
8277d4b7
CG
1215 do_show_ip_route(vty, zvrf_name(zvrf), afi, SAFI_UNICAST,
1216 use_fib, use_json, tag, longer_prefix_p,
1217 supernets_only, type, ospf_instance_id,
1218 zrt->tableid, ctx);
7e0f48c7
TC
1219 }
1220}
1221
ae825b8b 1222static int do_show_ip_route(struct vty *vty, const char *vrf_name, afi_t afi,
9f049418 1223 safi_t safi, bool use_fib, bool use_json,
ae825b8b
DS
1224 route_tag_t tag,
1225 const struct prefix *longer_prefix_p,
1226 bool supernets_only, int type,
8277d4b7
CG
1227 unsigned short ospf_instance_id, uint32_t tableid,
1228 struct route_show_ctx *ctx)
ae825b8b
DS
1229{
1230 struct route_table *table;
1231 struct zebra_vrf *zvrf = NULL;
1232
1233 if (!(zvrf = zebra_vrf_lookup_by_name(vrf_name))) {
1234 if (use_json)
1235 vty_out(vty, "{}\n");
1236 else
1237 vty_out(vty, "vrf %s not defined\n", vrf_name);
1238 return CMD_SUCCESS;
1239 }
1240
1241 if (zvrf_id(zvrf) == VRF_UNKNOWN) {
1242 if (use_json)
1243 vty_out(vty, "{}\n");
1244 else
1245 vty_out(vty, "vrf %s inactive\n", vrf_name);
1246 return CMD_SUCCESS;
1247 }
1248
7e0f48c7
TC
1249 if (tableid)
1250 table = zebra_router_find_table(zvrf, tableid, afi, SAFI_UNICAST);
1251 else
1252 table = zebra_vrf_table(afi, safi, zvrf_id(zvrf));
ae825b8b
DS
1253 if (!table) {
1254 if (use_json)
1255 vty_out(vty, "{}\n");
1256 return CMD_SUCCESS;
1257 }
1258
1259 do_show_route_helper(vty, zvrf, table, afi, use_fib, tag,
1260 longer_prefix_p, supernets_only, type,
8277d4b7 1261 ospf_instance_id, use_json, tableid, ctx);
d62a17ae 1262
1263 return CMD_SUCCESS;
abbda2d4 1264}
d511d7f1 1265
7004c67b 1266DEFPY (show_ip_nht,
8f527c5e 1267 show_ip_nht_cmd,
94a01fb2 1268 "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
1269 SHOW_STR
1270 IP_STR
7004c67b 1271 IP6_STR
9bf96c84 1272 "IP nexthop tracking table\n"
dbeca484
DS
1273 "IP import check tracking table\n"
1274 "IPv4 Address\n"
1275 "IPv6 Address\n"
7004c67b 1276 VRF_CMD_HELP_STR
dbeca484
DS
1277 "IPv4 Address\n"
1278 "IPv6 Address\n"
7004c67b 1279 VRF_ALL_CMD_HELP_STR)
8f527c5e 1280{
7004c67b 1281 afi_t afi = ipv4 ? AFI_IP : AFI_IP6;
d62a17ae 1282 vrf_id_t vrf_id = VRF_DEFAULT;
dbeca484 1283 struct prefix prefix, *p = NULL;
f9215571 1284 enum rnh_type rtype;
dbeca484
DS
1285
1286 if (strcmp(type, "nht") == 0)
1287 rtype = RNH_NEXTHOP_TYPE;
1288 else
1289 rtype = RNH_IMPORT_CHECK_TYPE;
12f6fb97 1290
7004c67b
RW
1291 if (vrf_all) {
1292 struct vrf *vrf;
1293 struct zebra_vrf *zvrf;
1294
1295 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
1296 if ((zvrf = vrf->info) != NULL) {
1297 vty_out(vty, "\nVRF %s:\n", zvrf_name(zvrf));
1298 zebra_print_rnh_table(zvrf_id(zvrf), afi, vty,
dbeca484 1299 rtype, NULL);
7004c67b
RW
1300 }
1301 return CMD_SUCCESS;
1302 }
1303 if (vrf_name)
1304 VRF_GET_ID(vrf_id, vrf_name, false);
12f6fb97 1305
dbeca484 1306 memset(&prefix, 0, sizeof(prefix));
dda33b6e 1307 if (addr) {
dbeca484 1308 p = sockunion2hostprefix(addr, &prefix);
dda33b6e
DS
1309 if (!p)
1310 return CMD_WARNING;
1311 }
0154d8ce 1312
dbeca484 1313 zebra_print_rnh_table(vrf_id, afi, vty, rtype, p);
b85c8275
PG
1314 return CMD_SUCCESS;
1315}
12f6fb97 1316
8f527c5e
FL
1317DEFUN (ip_nht_default_route,
1318 ip_nht_default_route_cmd,
1319 "ip nht resolve-via-default",
1320 IP_STR
1321 "Filter Next Hop tracking route resolution\n"
1322 "Resolve via default route\n")
1323{
214e5c26 1324 ZEBRA_DECLVAR_CONTEXT(vrf, zvrf);
6d53d7b1 1325
1326 if (!zvrf)
1327 return CMD_WARNING;
1328
5a0bdc78 1329 if (zvrf->zebra_rnh_ip_default_route)
214e5c26 1330 return CMD_SUCCESS;
1331
5a0bdc78 1332 zvrf->zebra_rnh_ip_default_route = 1;
214e5c26 1333
86723fe8 1334 zebra_evaluate_rnh(zvrf, AFI_IP, 0, RNH_NEXTHOP_TYPE, NULL);
d62a17ae 1335 return CMD_SUCCESS;
8f527c5e
FL
1336}
1337
1e9aad82
SW
1338static void show_nexthop_group_out(struct vty *vty, struct nhg_hash_entry *nhe)
1339{
df9069cd 1340 struct nexthop *nexthop = NULL;
1e9aad82 1341 struct nhg_connected *rb_node_dep = NULL;
eeafa8cd 1342 struct nexthop_group *backup_nhg;
45691de9
SW
1343 char up_str[MONOTIME_STRLEN];
1344
1345 uptime2str(nhe->uptime, up_str, sizeof(up_str));
1e9aad82 1346
0885b1e3 1347 vty_out(vty, "ID: %u (%s)\n", nhe->id, zebra_route_string(nhe->type));
45691de9
SW
1348 vty_out(vty, " RefCnt: %u\n", nhe->refcnt);
1349 vty_out(vty, " Uptime: %s\n", up_str);
6ac94041 1350 vty_out(vty, " VRF: %s\n", vrf_id_to_name(nhe->vrf_id));
df9069cd 1351
1e9aad82 1352 if (CHECK_FLAG(nhe->flags, NEXTHOP_GROUP_VALID)) {
df9069cd 1353 vty_out(vty, " Valid");
1e9aad82
SW
1354 if (CHECK_FLAG(nhe->flags, NEXTHOP_GROUP_INSTALLED))
1355 vty_out(vty, ", Installed");
1356 vty_out(vty, "\n");
1357 }
1358 if (nhe->ifp)
df9069cd 1359 vty_out(vty, " Interface Index: %d\n", nhe->ifp->ifindex);
1e9aad82
SW
1360
1361 if (!zebra_nhg_depends_is_empty(nhe)) {
df9069cd 1362 vty_out(vty, " Depends:");
fec211ad 1363 frr_each(nhg_connected_tree, &nhe->nhg_depends, rb_node_dep) {
1e9aad82
SW
1364 vty_out(vty, " (%u)", rb_node_dep->nhe->id);
1365 }
1366 vty_out(vty, "\n");
1367 }
df9069cd 1368
eeafa8cd 1369 /* Output nexthops */
c415d895 1370 for (ALL_NEXTHOPS(nhe->nhg, nexthop)) {
df9069cd
SW
1371 if (!CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
1372 vty_out(vty, " ");
1373 else
1374 /* Make recursive nexthops a bit more clear */
1375 vty_out(vty, " ");
1376
accf6280
MS
1377 show_route_nexthop_helper(vty, NULL, nexthop);
1378
1379 if (nhe->backup_info == NULL || nhe->backup_info->nhe == NULL) {
1380 if (CHECK_FLAG(nexthop->flags,
1381 NEXTHOP_FLAG_HAS_BACKUP))
1382 vty_out(vty, " [backup %d]",
474aebd9 1383 nexthop->backup_idx[0]);
accf6280
MS
1384
1385 vty_out(vty, "\n");
1386 continue;
1387 }
1388
1389 /* TODO -- print more useful backup info */
1390 if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_HAS_BACKUP)) {
accf6280
MS
1391 int i;
1392
474aebd9
MS
1393 vty_out(vty, "[backup");
1394 for (i = 0; i < nexthop->backup_num; i++)
1395 vty_out(vty, " %d", nexthop->backup_idx[i]);
accf6280 1396
474aebd9 1397 vty_out(vty, "]");
accf6280
MS
1398 }
1399
1400 vty_out(vty, "\n");
eeafa8cd 1401 }
df9069cd 1402
eeafa8cd
MS
1403 /* Output backup nexthops (if any) */
1404 backup_nhg = zebra_nhg_get_backup_nhg(nhe);
1405 if (backup_nhg) {
1406 vty_out(vty, " Backups:\n");
df9069cd 1407
eeafa8cd
MS
1408 for (ALL_NEXTHOPS_PTR(backup_nhg, nexthop)) {
1409 if (!CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
1410 vty_out(vty, " ");
1411 else
1412 /* Make recursive nexthops a bit more clear */
1413 vty_out(vty, " ");
df9069cd 1414
accf6280
MS
1415 show_route_nexthop_helper(vty, NULL, nexthop);
1416 vty_out(vty, "\n");
df9069cd 1417 }
df9069cd
SW
1418 }
1419
1e9aad82 1420 if (!zebra_nhg_dependents_is_empty(nhe)) {
df9069cd 1421 vty_out(vty, " Dependents:");
fec211ad 1422 frr_each(nhg_connected_tree, &nhe->nhg_dependents,
37c6708b 1423 rb_node_dep) {
1e9aad82
SW
1424 vty_out(vty, " (%u)", rb_node_dep->nhe->id);
1425 }
1426 vty_out(vty, "\n");
1427 }
1428
1e9aad82
SW
1429}
1430
1431static int show_nexthop_group_id_cmd_helper(struct vty *vty, uint32_t id)
1432{
1433 struct nhg_hash_entry *nhe = NULL;
1434
1435 nhe = zebra_nhg_lookup_id(id);
1436
1437 if (nhe)
1438 show_nexthop_group_out(vty, nhe);
1439 else {
1440 vty_out(vty, "Nexthop Group ID: %u does not exist\n", id);
1441 return CMD_WARNING;
1442 }
1443 return CMD_SUCCESS;
1444}
1445
b5e02d19
MS
1446/* Helper function for iteration through the hash of nexthop-groups/nhe-s */
1447
1448struct nhe_show_context {
1449 struct vty *vty;
1450 vrf_id_t vrf_id;
1451 afi_t afi;
a8ad9a89 1452 int type;
b5e02d19
MS
1453};
1454
1455static int nhe_show_walker(struct hash_bucket *bucket, void *arg)
21be1364 1456{
b5e02d19
MS
1457 struct nhe_show_context *ctx = arg;
1458 struct nhg_hash_entry *nhe;
21be1364 1459
b5e02d19 1460 nhe = bucket->data; /* We won't be offered NULL buckets */
21be1364 1461
b5e02d19
MS
1462 if (ctx->afi && nhe->afi != ctx->afi)
1463 goto done;
77b76fc9 1464
b5e02d19
MS
1465 if (ctx->vrf_id && nhe->vrf_id != ctx->vrf_id)
1466 goto done;
21be1364 1467
a8ad9a89
SW
1468 if (ctx->type && nhe->type != ctx->type)
1469 goto done;
1470
b5e02d19
MS
1471 show_nexthop_group_out(ctx->vty, nhe);
1472
1473done:
1474 return HASHWALK_CONTINUE;
1475}
1476
1477static void show_nexthop_group_cmd_helper(struct vty *vty,
a8ad9a89
SW
1478 struct zebra_vrf *zvrf, afi_t afi,
1479 int type)
b5e02d19
MS
1480{
1481 struct nhe_show_context ctx;
1482
1483 ctx.vty = vty;
1484 ctx.afi = afi;
1485 ctx.vrf_id = zvrf->vrf->vrf_id;
a8ad9a89 1486 ctx.type = type;
a15d4c00 1487
b5e02d19 1488 hash_walk(zrouter.nhgs_id, nhe_show_walker, &ctx);
1e9aad82
SW
1489}
1490
1491static void if_nexthop_group_dump_vty(struct vty *vty, struct interface *ifp)
1492{
1493 struct zebra_if *zebra_if = NULL;
1494 struct nhg_connected *rb_node_dep = NULL;
1495
1496 zebra_if = ifp->info;
1497
1498 if (!if_nhg_dependents_is_empty(ifp)) {
1499 vty_out(vty, "Interface %s:\n", ifp->name);
1500
fec211ad 1501 frr_each(nhg_connected_tree, &zebra_if->nhg_dependents,
37c6708b 1502 rb_node_dep) {
1e9aad82
SW
1503 vty_out(vty, " ");
1504 show_nexthop_group_out(vty, rb_node_dep->nhe);
cced3a2d 1505 }
1e9aad82
SW
1506 }
1507}
cced3a2d 1508
1e9aad82
SW
1509DEFPY (show_interface_nexthop_group,
1510 show_interface_nexthop_group_cmd,
1511 "show interface [IFNAME$if_name] nexthop-group",
1512 SHOW_STR
1513 "Interface status and configuration\n"
1514 "Interface name\n"
1515 "Show Nexthop Groups\n")
1516{
1517 struct vrf *vrf = NULL;
1518 struct interface *ifp = NULL;
1519 bool found = false;
1520
1521 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
1522 if (if_name) {
1523 ifp = if_lookup_by_name(if_name, vrf->vrf_id);
1524 if (ifp) {
1525 if_nexthop_group_dump_vty(vty, ifp);
1526 found = true;
1527 }
1528 } else {
1529 FOR_ALL_INTERFACES (vrf, ifp)
1530 if_nexthop_group_dump_vty(vty, ifp);
1531 found = true;
21be1364
DS
1532 }
1533 }
1534
1e9aad82
SW
1535 if (!found) {
1536 vty_out(vty, "%% Can't find interface %s\n", if_name);
1537 return CMD_WARNING;
1538 }
1539
1540 return CMD_SUCCESS;
21be1364
DS
1541}
1542
1543DEFPY (show_nexthop_group,
1544 show_nexthop_group_cmd,
a8ad9a89 1545 "show nexthop-group rib <(0-4294967295)$id|[singleton <ip$v4|ipv6$v6>] [<kernel|zebra|bgp|sharp>$type_str] [vrf <NAME$vrf_name|all$vrf_all>]>",
21be1364 1546 SHOW_STR
1e9aad82 1547 "Show Nexthop Groups\n"
2553fde1 1548 "RIB information\n"
1e9aad82 1549 "Nexthop Group ID\n"
417f01b7 1550 "Show Singleton Nexthop-Groups\n"
77b76fc9
SW
1551 IP_STR
1552 IP6_STR
a8ad9a89
SW
1553 "Kernel (not installed via the zebra RIB)\n"
1554 "Zebra (implicitly created by zebra)\n"
1555 "Border Gateway Protocol (BGP)\n"
1556 "Super Happy Advanced Routing Protocol (SHARP)\n"
21be1364
DS
1557 VRF_FULL_CMD_HELP_STR)
1558{
cced3a2d 1559
1e9aad82 1560 struct zebra_vrf *zvrf = NULL;
417f01b7 1561 afi_t afi = AFI_UNSPEC;
a8ad9a89 1562 int type = 0;
2d3c57e6 1563
1e9aad82
SW
1564 if (id)
1565 return show_nexthop_group_id_cmd_helper(vty, id);
1566
cced3a2d
SW
1567 if (v4)
1568 afi = AFI_IP;
1569 else if (v6)
1570 afi = AFI_IP6;
1571
a8ad9a89
SW
1572 if (type_str) {
1573 type = proto_redistnum((afi ? afi : AFI_IP), type_str);
1574 if (type < 0) {
1575 /* assume zebra */
1576 type = ZEBRA_ROUTE_NHG;
1577 }
1578 }
1579
2f90b900
PG
1580 if (!vrf_is_backend_netns() && (vrf_name || vrf_all)) {
1581 vty_out(vty,
1582 "VRF subcommand does not make any sense in l3mdev based vrf's\n");
88cafda7
DS
1583 return CMD_WARNING;
1584 }
1585
21be1364
DS
1586 if (vrf_all) {
1587 struct vrf *vrf;
1588
1589 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
1590 struct zebra_vrf *zvrf;
1591
1592 zvrf = vrf->info;
1593 if (!zvrf)
1594 continue;
1595
1596 vty_out(vty, "VRF: %s\n", vrf->name);
a8ad9a89 1597 show_nexthop_group_cmd_helper(vty, zvrf, afi, type);
21be1364
DS
1598 }
1599
1600 return CMD_SUCCESS;
1601 }
1602
1603 if (vrf_name)
1604 zvrf = zebra_vrf_lookup_by_name(vrf_name);
1605 else
1606 zvrf = zebra_vrf_lookup_by_name(VRF_DEFAULT_NAME);
1607
1608 if (!zvrf) {
b5e02d19
MS
1609 vty_out(vty, "%% VRF '%s' specified does not exist\n",
1610 vrf_name);
1e9aad82 1611 return CMD_WARNING;
21be1364
DS
1612 }
1613
a8ad9a89 1614 show_nexthop_group_cmd_helper(vty, zvrf, afi, type);
21be1364
DS
1615
1616 return CMD_SUCCESS;
1617}
1618
7c99d51b
MS
1619DEFPY_HIDDEN(nexthop_group_use_enable,
1620 nexthop_group_use_enable_cmd,
1621 "[no] zebra nexthop kernel enable",
1622 NO_STR
1623 ZEBRA_STR
1624 "Nexthop configuration \n"
1625 "Configure use of kernel nexthops\n"
1626 "Enable kernel nexthops\n")
1627{
1628 zebra_nhg_enable_kernel_nexthops(!no);
1629 return CMD_SUCCESS;
1630}
1631
ff9aca4f
SW
1632DEFPY_HIDDEN(proto_nexthop_group_only, proto_nexthop_group_only_cmd,
1633 "[no] zebra nexthop proto only",
1634 NO_STR ZEBRA_STR
1635 "Nexthop configuration\n"
1636 "Configure exclusive use of proto nexthops\n"
1637 "Only use proto nexthops\n")
6c67f41f
SW
1638{
1639 zebra_nhg_set_proto_nexthops_only(!no);
1640 return CMD_SUCCESS;
1641}
1642
aa458838
MS
1643DEFPY_HIDDEN(backup_nexthop_recursive_use_enable,
1644 backup_nexthop_recursive_use_enable_cmd,
1645 "[no] zebra nexthop resolve-via-backup",
1646 NO_STR
1647 ZEBRA_STR
1648 "Nexthop configuration \n"
1649 "Configure use of backup nexthops in recursive resolution\n")
1650{
1651 zebra_nhg_set_recursive_use_backups(!no);
1652 return CMD_SUCCESS;
1653}
1654
8f527c5e
FL
1655DEFUN (no_ip_nht_default_route,
1656 no_ip_nht_default_route_cmd,
1657 "no ip nht resolve-via-default",
1658 NO_STR
1659 IP_STR
1660 "Filter Next Hop tracking route resolution\n"
1661 "Resolve via default route\n")
1662{
214e5c26 1663 ZEBRA_DECLVAR_CONTEXT(vrf, zvrf);
6d53d7b1 1664
1665 if (!zvrf)
1666 return CMD_WARNING;
1667
5a0bdc78 1668 if (!zvrf->zebra_rnh_ip_default_route)
214e5c26 1669 return CMD_SUCCESS;
1670
5a0bdc78 1671 zvrf->zebra_rnh_ip_default_route = 0;
86723fe8 1672 zebra_evaluate_rnh(zvrf, AFI_IP, 0, RNH_NEXTHOP_TYPE, NULL);
d62a17ae 1673 return CMD_SUCCESS;
8f527c5e
FL
1674}
1675
1676DEFUN (ipv6_nht_default_route,
1677 ipv6_nht_default_route_cmd,
1678 "ipv6 nht resolve-via-default",
1679 IP6_STR
1680 "Filter Next Hop tracking route resolution\n"
1681 "Resolve via default route\n")
1682{
214e5c26 1683 ZEBRA_DECLVAR_CONTEXT(vrf, zvrf);
6d53d7b1 1684
1685 if (!zvrf)
1686 return CMD_WARNING;
1687
5a0bdc78 1688 if (zvrf->zebra_rnh_ipv6_default_route)
214e5c26 1689 return CMD_SUCCESS;
1690
5a0bdc78 1691 zvrf->zebra_rnh_ipv6_default_route = 1;
86723fe8 1692 zebra_evaluate_rnh(zvrf, AFI_IP6, 0, RNH_NEXTHOP_TYPE, NULL);
d62a17ae 1693 return CMD_SUCCESS;
8f527c5e
FL
1694}
1695
1696DEFUN (no_ipv6_nht_default_route,
1697 no_ipv6_nht_default_route_cmd,
1698 "no ipv6 nht resolve-via-default",
1699 NO_STR
1700 IP6_STR
1701 "Filter Next Hop tracking route resolution\n"
1702 "Resolve via default route\n")
1703{
8f527c5e 1704
214e5c26 1705 ZEBRA_DECLVAR_CONTEXT(vrf, zvrf);
6d53d7b1 1706
1707 if (!zvrf)
1708 return CMD_WARNING;
1709
5a0bdc78 1710 if (!zvrf->zebra_rnh_ipv6_default_route)
214e5c26 1711 return CMD_SUCCESS;
1712
5a0bdc78 1713 zvrf->zebra_rnh_ipv6_default_route = 0;
86723fe8 1714 zebra_evaluate_rnh(zvrf, AFI_IP6, 0, RNH_NEXTHOP_TYPE, NULL);
d62a17ae 1715 return CMD_SUCCESS;
8f527c5e
FL
1716}
1717
ecffa493
RW
1718DEFPY (show_route,
1719 show_route_cmd,
1720 "show\
1721 <\
7e0f48c7
TC
1722 ip$ipv4 <fib$fib|route> [table <(1-4294967295)$table|all$table_all>]\
1723 [vrf <NAME$vrf_name|all$vrf_all>]\
a3e13ef3 1724 [{\
ecffa493
RW
1725 tag (1-4294967295)\
1726 |A.B.C.D/M$prefix longer-prefixes\
1727 |supernets-only$supernets_only\
a3e13ef3
RW
1728 }]\
1729 [<\
1730 " FRR_IP_REDIST_STR_ZEBRA "$type_str\
ecffa493 1731 |ospf$type_str (1-65535)$ospf_instance_id\
a3e13ef3 1732 >]\
7e0f48c7
TC
1733 |ipv6$ipv6 <fib$fib|route> [table <(1-4294967295)$table|all$table_all>]\
1734 [vrf <NAME$vrf_name|all$vrf_all>]\
a3e13ef3 1735 [{\
ecffa493
RW
1736 tag (1-4294967295)\
1737 |X:X::X:X/M$prefix longer-prefixes\
a3e13ef3
RW
1738 }]\
1739 [" FRR_IP6_REDIST_STR_ZEBRA "$type_str]\
ecffa493
RW
1740 >\
1741 [json$json]",
8f527c5e
FL
1742 SHOW_STR
1743 IP_STR
87a88962 1744 "IP forwarding table\n"
8f527c5e 1745 "IP routing table\n"
7e0f48c7
TC
1746 "Table to display\n"
1747 "The table number to display\n"
1748 "All tables\n"
ecffa493 1749 VRF_FULL_CMD_HELP_STR
8f527c5e 1750 "Show only routes with tag\n"
acb25e73
DW
1751 "Tag value\n"
1752 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1753 "Show route matching the specified Network/Mask pair only\n"
1754 "Show supernet entries only\n"
1755 FRR_IP_REDIST_HELP_STR_ZEBRA
1756 "Open Shortest Path First (OSPFv2)\n"
1757 "Instance ID\n"
ecffa493
RW
1758 IPV6_STR
1759 "IP forwarding table\n"
1760 "IP routing table\n"
7e0f48c7
TC
1761 "Table to display\n"
1762 "The table number to display\n"
1763 "All tables\n"
ecffa493
RW
1764 VRF_FULL_CMD_HELP_STR
1765 "Show only routes with tag\n"
1766 "Tag value\n"
1767 "IPv6 prefix\n"
1768 "Show route matching the specified Network/Mask pair only\n"
1769 FRR_IP6_REDIST_HELP_STR_ZEBRA
acb25e73 1770 JSON_STR)
8f527c5e 1771{
ecffa493 1772 afi_t afi = ipv4 ? AFI_IP : AFI_IP6;
d62a17ae 1773 struct vrf *vrf;
d62a17ae 1774 int type = 0;
7e0f48c7 1775 struct zebra_vrf *zvrf;
8277d4b7
CG
1776 struct route_show_ctx ctx = {
1777 .multi = vrf_all || table_all,
1778 };
d62a17ae 1779
7e0f48c7
TC
1780 if (!vrf_is_backend_netns()) {
1781 if ((vrf_all || vrf_name) && (table || table_all)) {
1782 if (!!json)
1783 vty_out(vty, "{}\n");
1784 else {
1785 vty_out(vty, "Linux vrf backend already points to table id\n");
1786 vty_out(vty, "Either remove table parameter or vrf parameter\n");
1787 }
1788 return CMD_SUCCESS;
1789 }
1790 }
ecffa493
RW
1791 if (type_str) {
1792 type = proto_redistnum(afi, type_str);
d62a17ae 1793 if (type < 0) {
1794 vty_out(vty, "Unknown route type\n");
1795 return CMD_WARNING;
1796 }
1797 }
1798
1799 if (vrf_all) {
a2addae8 1800 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
d62a17ae 1801 if ((zvrf = vrf->info) == NULL
2acf1ad1 1802 || (zvrf->table[afi][SAFI_UNICAST] == NULL))
d62a17ae 1803 continue;
1804
7e0f48c7 1805 if (table_all)
8277d4b7
CG
1806 do_show_ip_route_all(vty, zvrf, afi, !!fib,
1807 !!json, tag,
1808 prefix_str ? prefix : NULL,
7e0f48c7 1809 !!supernets_only, type,
8277d4b7 1810 ospf_instance_id, &ctx);
7e0f48c7
TC
1811 else
1812 do_show_ip_route(vty, zvrf_name(zvrf), afi,
8277d4b7
CG
1813 SAFI_UNICAST, !!fib, !!json,
1814 tag,
7e0f48c7
TC
1815 prefix_str ? prefix : NULL,
1816 !!supernets_only, type,
8277d4b7 1817 ospf_instance_id, table, &ctx);
d62a17ae 1818 }
1819 } else {
ecffa493
RW
1820 vrf_id_t vrf_id = VRF_DEFAULT;
1821
1822 if (vrf_name)
ec1db588 1823 VRF_GET_ID(vrf_id, vrf_name, !!json);
d62a17ae 1824 vrf = vrf_lookup_by_id(vrf_id);
9ea714e1
DS
1825 if (!vrf)
1826 return CMD_SUCCESS;
1827
1828 zvrf = vrf->info;
1829 if (!zvrf)
7e0f48c7
TC
1830 return CMD_SUCCESS;
1831
1832 if (table_all)
8277d4b7
CG
1833 do_show_ip_route_all(vty, zvrf, afi, !!fib, !!json, tag,
1834 prefix_str ? prefix : NULL,
7e0f48c7 1835 !!supernets_only, type,
8277d4b7 1836 ospf_instance_id, &ctx);
7e0f48c7 1837 else
8277d4b7
CG
1838 do_show_ip_route(vty, vrf->name, afi, SAFI_UNICAST,
1839 !!fib, !!json, tag,
1840 prefix_str ? prefix : NULL,
1841 !!supernets_only, type,
1842 ospf_instance_id, table, &ctx);
d62a17ae 1843 }
ecffa493 1844
d62a17ae 1845 return CMD_SUCCESS;
8f527c5e
FL
1846}
1847
dc1c4362
SW
1848ALIAS_HIDDEN (show_route,
1849 show_ro_cmd,
1850 "show <ip$ipv4|ipv6$ipv6> ro",
1851 SHOW_STR
1852 IP_STR
1853 IPV6_STR
1854 "IP routing table\n");
1855
1856
5ce91022
RW
1857DEFPY (show_route_detail,
1858 show_route_detail_cmd,
1859 "show\
1860 <\
6a794a7e 1861 ip$ipv4 <fib$fib|route> [vrf <NAME$vrf_name|all$vrf_all>]\
5ce91022
RW
1862 <\
1863 A.B.C.D$address\
1864 |A.B.C.D/M$prefix\
1865 >\
6a794a7e 1866 |ipv6$ipv6 <fib$fib|route> [vrf <NAME$vrf_name|all$vrf_all>]\
5ce91022
RW
1867 <\
1868 X:X::X:X$address\
1869 |X:X::X:X/M$prefix\
1870 >\
96d71e38 1871 >\
61d9ffe1 1872 [json$json] [nexthop-group$ng]",
8f527c5e
FL
1873 SHOW_STR
1874 IP_STR
6a794a7e 1875 "IPv6 forwarding table\n"
8f527c5e 1876 "IP routing table\n"
5ce91022
RW
1877 VRF_FULL_CMD_HELP_STR
1878 "Network in the IP routing table to display\n"
1879 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1880 IP6_STR
6a794a7e
AD
1881 "IPv6 forwarding table\n"
1882 "IPv6 routing table\n"
5ce91022
RW
1883 VRF_FULL_CMD_HELP_STR
1884 "IPv6 Address\n"
96d71e38 1885 "IPv6 prefix\n"
61d9ffe1
SW
1886 JSON_STR
1887 "Nexthop Group Information\n")
8f527c5e 1888{
5ce91022 1889 afi_t afi = ipv4 ? AFI_IP : AFI_IP6;
d62a17ae 1890 struct route_table *table;
5ce91022 1891 struct prefix p;
d62a17ae 1892 struct route_node *rn;
3a3be633
AD
1893 bool use_fib = !!fib;
1894 rib_dest_t *dest;
ad2e7233 1895 bool network_found = false;
61d9ffe1 1896 bool show_ng = !!ng;
d511d7f1 1897
5ce91022
RW
1898 if (address_str)
1899 prefix_str = address_str;
1900 if (str2prefix(prefix_str, &p) < 0) {
1901 vty_out(vty, "%% Malformed address\n");
d62a17ae 1902 return CMD_WARNING;
1903 }
8f527c5e 1904
5ce91022
RW
1905 if (vrf_all) {
1906 struct vrf *vrf;
1907 struct zebra_vrf *zvrf;
8f527c5e 1908
996c9314 1909 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
5ce91022
RW
1910 if ((zvrf = vrf->info) == NULL
1911 || (table = zvrf->table[afi][SAFI_UNICAST]) == NULL)
1912 continue;
1913
1914 rn = route_node_match(table, &p);
1915 if (!rn)
1916 continue;
1917 if (!address_str && rn->p.prefixlen != p.prefixlen) {
1918 route_unlock_node(rn);
1919 continue;
1920 }
1921
ad2e7233
AD
1922 dest = rib_dest_from_rnode(rn);
1923 if (use_fib && !dest->selected_fib) {
1924 route_unlock_node(rn);
1925 continue;
1926 }
1927
1928 network_found = true;
96d71e38 1929 if (json)
61d9ffe1 1930 vty_show_ip_route_detail_json(vty, rn, use_fib);
96d71e38 1931 else
61d9ffe1
SW
1932 vty_show_ip_route_detail(vty, rn, 0, use_fib,
1933 show_ng);
5ce91022
RW
1934
1935 route_unlock_node(rn);
1936 }
ad2e7233
AD
1937
1938 if (!network_found) {
1939 if (json)
1940 vty_out(vty, "{}\n");
1941 else {
1942 if (use_fib)
1943 vty_out(vty,
1944 "%% Network not in FIB\n");
1945 else
1946 vty_out(vty,
1947 "%% Network not in RIB\n");
1948 }
1949 return CMD_WARNING;
1950 }
5ce91022
RW
1951 } else {
1952 vrf_id_t vrf_id = VRF_DEFAULT;
1953
1954 if (vrf_name)
ec1db588 1955 VRF_GET_ID(vrf_id, vrf_name, false);
5ce91022
RW
1956
1957 table = zebra_vrf_table(afi, SAFI_UNICAST, vrf_id);
1958 if (!table)
1959 return CMD_SUCCESS;
8f527c5e 1960
5ce91022 1961 rn = route_node_match(table, &p);
ad2e7233
AD
1962 if (rn)
1963 dest = rib_dest_from_rnode(rn);
1964
1965 if (!rn || (!address_str && rn->p.prefixlen != p.prefixlen) ||
1966 (use_fib && dest && !dest->selected_fib)) {
1967 if (json)
1968 vty_out(vty, "{}\n");
1969 else {
1970 if (use_fib)
1971 vty_out(vty,
1972 "%% Network not in FIB\n");
1973 else
1974 vty_out(vty,
1975 "%% Network not in table\n");
1976 }
1977 if (rn)
1978 route_unlock_node(rn);
5ce91022
RW
1979 return CMD_WARNING;
1980 }
8f527c5e 1981
96d71e38 1982 if (json)
3a3be633 1983 vty_show_ip_route_detail_json(vty, rn, use_fib);
96d71e38 1984 else
61d9ffe1 1985 vty_show_ip_route_detail(vty, rn, 0, use_fib, show_ng);
5ce91022
RW
1986
1987 route_unlock_node(rn);
1988 }
8f527c5e 1989
d62a17ae 1990 return CMD_SUCCESS;
8f527c5e
FL
1991}
1992
5ce91022
RW
1993DEFPY (show_route_summary,
1994 show_route_summary_cmd,
ae813e21 1995 "show <ip$ipv4|ipv6$ipv6> route [vrf <NAME$vrf_name|all$vrf_all>] \
e7deb7e7 1996 summary [table (1-4294967295)$table_id] [prefix$prefix] [json]",
8f527c5e
FL
1997 SHOW_STR
1998 IP_STR
5ce91022
RW
1999 IP6_STR
2000 "IP routing table\n"
2001 VRF_FULL_CMD_HELP_STR
2002 "Summary of all routes\n"
ae813e21
DS
2003 "Table to display summary for\n"
2004 "The table number\n"
e7deb7e7
DA
2005 "Prefix routes\n"
2006 JSON_STR)
8f527c5e 2007{
5ce91022 2008 afi_t afi = ipv4 ? AFI_IP : AFI_IP6;
d62a17ae 2009 struct route_table *table;
e7deb7e7 2010 bool uj = use_json(argc, argv);
d62a17ae 2011
5ce91022
RW
2012 if (vrf_all) {
2013 struct vrf *vrf;
2014 struct zebra_vrf *zvrf;
d511d7f1 2015
996c9314 2016 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
ae813e21
DS
2017 if ((zvrf = vrf->info) == NULL)
2018 continue;
2019
265ac74a
EDP
2020 if (table_id == 0)
2021 table = zebra_vrf_table(afi, SAFI_UNICAST,
2022 zvrf->vrf->vrf_id);
2023 else
2024 table = zebra_vrf_lookup_table_with_table_id(
2025 afi, SAFI_UNICAST, zvrf->vrf->vrf_id,
2026 table_id);
c7c0b007 2027
ae813e21 2028 if (!table)
5ce91022 2029 continue;
8f527c5e 2030
5ce91022 2031 if (prefix)
e7deb7e7
DA
2032 vty_show_ip_route_summary_prefix(vty, table,
2033 uj);
5ce91022 2034 else
e7deb7e7 2035 vty_show_ip_route_summary(vty, table, uj);
5ce91022
RW
2036 }
2037 } else {
2038 vrf_id_t vrf_id = VRF_DEFAULT;
8f527c5e 2039
5ce91022 2040 if (vrf_name)
ec1db588 2041 VRF_GET_ID(vrf_id, vrf_name, false);
8f527c5e 2042
265ac74a
EDP
2043 if (table_id == 0)
2044 table = zebra_vrf_table(afi, SAFI_UNICAST, vrf_id);
2045 else
2046 table = zebra_vrf_lookup_table_with_table_id(
2047 afi, SAFI_UNICAST, vrf_id, table_id);
5ce91022
RW
2048 if (!table)
2049 return CMD_SUCCESS;
8f527c5e 2050
5ce91022 2051 if (prefix)
e7deb7e7 2052 vty_show_ip_route_summary_prefix(vty, table, uj);
5ce91022 2053 else
e7deb7e7 2054 vty_show_ip_route_summary(vty, table, uj);
5ce91022 2055 }
8f527c5e 2056
d62a17ae 2057 return CMD_SUCCESS;
8f527c5e
FL
2058}
2059
d62a17ae 2060static void vty_show_ip_route_summary(struct vty *vty,
e7deb7e7 2061 struct route_table *table, bool use_json)
8f527c5e 2062{
d62a17ae 2063 struct route_node *rn;
2064 struct route_entry *re;
8f527c5e
FL
2065#define ZEBRA_ROUTE_IBGP ZEBRA_ROUTE_MAX
2066#define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1)
d7c0a89a
QY
2067 uint32_t rib_cnt[ZEBRA_ROUTE_TOTAL + 1];
2068 uint32_t fib_cnt[ZEBRA_ROUTE_TOTAL + 1];
f7a9d012
DS
2069 uint32_t offload_cnt[ZEBRA_ROUTE_TOTAL + 1];
2070 uint32_t trap_cnt[ZEBRA_ROUTE_TOTAL + 1];
d7c0a89a
QY
2071 uint32_t i;
2072 uint32_t is_ibgp;
e7deb7e7
DA
2073 json_object *json_route_summary = NULL;
2074 json_object *json_route_routes = NULL;
d62a17ae 2075
2076 memset(&rib_cnt, 0, sizeof(rib_cnt));
2077 memset(&fib_cnt, 0, sizeof(fib_cnt));
f7a9d012
DS
2078 memset(&offload_cnt, 0, sizeof(offload_cnt));
2079 memset(&trap_cnt, 0, sizeof(trap_cnt));
e7deb7e7
DA
2080
2081 if (use_json) {
2082 json_route_summary = json_object_new_object();
2083 json_route_routes = json_object_new_array();
2084 json_object_object_add(json_route_summary, "routes",
2085 json_route_routes);
2086 }
2087
d62a17ae 2088 for (rn = route_top(table); rn; rn = srcdest_route_next(rn))
a2addae8 2089 RNODE_FOREACH_RE (rn, re) {
d62a17ae 2090 is_ibgp = (re->type == ZEBRA_ROUTE_BGP
2091 && CHECK_FLAG(re->flags, ZEBRA_FLAG_IBGP));
2092
2093 rib_cnt[ZEBRA_ROUTE_TOTAL]++;
2094 if (is_ibgp)
2095 rib_cnt[ZEBRA_ROUTE_IBGP]++;
2096 else
2097 rib_cnt[re->type]++;
2098
6f875a36 2099 if (CHECK_FLAG(re->status, ROUTE_ENTRY_INSTALLED)) {
d62a17ae 2100 fib_cnt[ZEBRA_ROUTE_TOTAL]++;
2101
2102 if (is_ibgp)
2103 fib_cnt[ZEBRA_ROUTE_IBGP]++;
2104 else
2105 fib_cnt[re->type]++;
2106 }
f7a9d012
DS
2107
2108 if (CHECK_FLAG(re->flags, ZEBRA_FLAG_TRAPPED)) {
2109 if (is_ibgp)
2110 trap_cnt[ZEBRA_ROUTE_IBGP]++;
2111 else
2112 trap_cnt[re->type]++;
2113 }
2114
2115 if (CHECK_FLAG(re->flags, ZEBRA_FLAG_OFFLOADED)) {
2116 if (is_ibgp)
2117 offload_cnt[ZEBRA_ROUTE_IBGP]++;
2118 else
2119 offload_cnt[re->type]++;
2120 }
d62a17ae 2121 }
2122
e7deb7e7
DA
2123 if (!use_json)
2124 vty_out(vty, "%-20s %-20s %s (vrf %s)\n", "Route Source",
2125 "Routes", "FIB",
630d5962
DS
2126 zvrf_name(((struct rib_table_info *)
2127 route_table_get_info(table))
e7deb7e7 2128 ->zvrf));
d62a17ae 2129
2130 for (i = 0; i < ZEBRA_ROUTE_MAX; i++) {
9d303b37
DL
2131 if ((rib_cnt[i] > 0) || (i == ZEBRA_ROUTE_BGP
2132 && rib_cnt[ZEBRA_ROUTE_IBGP] > 0)) {
d62a17ae 2133 if (i == ZEBRA_ROUTE_BGP) {
e7deb7e7
DA
2134 if (use_json) {
2135 json_object *json_route_ebgp =
2136 json_object_new_object();
2137
2138 json_object_int_add(
2139 json_route_ebgp, "fib",
2140 fib_cnt[ZEBRA_ROUTE_BGP]);
2141 json_object_int_add(
2142 json_route_ebgp, "rib",
2143 rib_cnt[ZEBRA_ROUTE_BGP]);
f7a9d012
DS
2144 json_object_int_add(
2145 json_route_ebgp, "fibOffLoaded",
2146 offload_cnt[ZEBRA_ROUTE_BGP]);
2147 json_object_int_add(
2148 json_route_ebgp, "fibTrapped",
2149 trap_cnt[ZEBRA_ROUTE_BGP]);
2150
e7deb7e7
DA
2151 json_object_string_add(json_route_ebgp,
2152 "type", "ebgp");
2153 json_object_array_add(json_route_routes,
2154 json_route_ebgp);
2155
2156 json_object *json_route_ibgp =
2157 json_object_new_object();
2158
2159 json_object_int_add(
2160 json_route_ibgp, "fib",
2161 fib_cnt[ZEBRA_ROUTE_IBGP]);
2162 json_object_int_add(
2163 json_route_ibgp, "rib",
2164 rib_cnt[ZEBRA_ROUTE_IBGP]);
f7a9d012
DS
2165 json_object_int_add(
2166 json_route_ibgp, "fibOffLoaded",
2167 offload_cnt[ZEBRA_ROUTE_IBGP]);
2168 json_object_int_add(
2169 json_route_ibgp, "fibTrapped",
2170 trap_cnt[ZEBRA_ROUTE_IBGP]);
e7deb7e7
DA
2171 json_object_string_add(json_route_ibgp,
2172 "type", "ibgp");
2173 json_object_array_add(json_route_routes,
2174 json_route_ibgp);
2175 } else {
2176 vty_out(vty, "%-20s %-20d %-20d \n",
2177 "ebgp",
2178 rib_cnt[ZEBRA_ROUTE_BGP],
2179 fib_cnt[ZEBRA_ROUTE_BGP]);
2180 vty_out(vty, "%-20s %-20d %-20d \n",
2181 "ibgp",
2182 rib_cnt[ZEBRA_ROUTE_IBGP],
2183 fib_cnt[ZEBRA_ROUTE_IBGP]);
2184 }
2185 } else {
2186 if (use_json) {
2187 json_object *json_route_type =
2188 json_object_new_object();
2189
2190 json_object_int_add(json_route_type,
2191 "fib", fib_cnt[i]);
2192 json_object_int_add(json_route_type,
2193 "rib", rib_cnt[i]);
f7a9d012
DS
2194
2195 json_object_int_add(json_route_type,
2196 "fibOffLoaded",
2197 offload_cnt[i]);
2198 json_object_int_add(json_route_type,
2199 "fibTrapped",
2200 trap_cnt[i]);
e7deb7e7
DA
2201 json_object_string_add(
2202 json_route_type, "type",
2203 zebra_route_string(i));
2204 json_object_array_add(json_route_routes,
2205 json_route_type);
2206 } else
2207 vty_out(vty, "%-20s %-20d %-20d \n",
2208 zebra_route_string(i),
2209 rib_cnt[i], fib_cnt[i]);
2210 }
d62a17ae 2211 }
2212 }
2213
e7deb7e7
DA
2214 if (use_json) {
2215 json_object_int_add(json_route_summary, "routesTotal",
2216 rib_cnt[ZEBRA_ROUTE_TOTAL]);
2217 json_object_int_add(json_route_summary, "routesTotalFib",
2218 fib_cnt[ZEBRA_ROUTE_TOTAL]);
2219
2220 vty_out(vty, "%s\n",
2221 json_object_to_json_string_ext(
2222 json_route_summary, JSON_C_TO_STRING_PRETTY));
2223 json_object_free(json_route_summary);
2224 } else {
2225 vty_out(vty, "------\n");
2226 vty_out(vty, "%-20s %-20d %-20d \n", "Totals",
2227 rib_cnt[ZEBRA_ROUTE_TOTAL], fib_cnt[ZEBRA_ROUTE_TOTAL]);
2228 vty_out(vty, "\n");
2229 }
8f527c5e
FL
2230}
2231
2232/*
2233 * Implementation of the ip route summary prefix command.
2234 *
2235 * This command prints the primary prefixes that have been installed by various
2236 * protocols on the box.
2237 *
2238 */
d62a17ae 2239static void vty_show_ip_route_summary_prefix(struct vty *vty,
e7deb7e7
DA
2240 struct route_table *table,
2241 bool use_json)
8f527c5e 2242{
d62a17ae 2243 struct route_node *rn;
2244 struct route_entry *re;
2245 struct nexthop *nexthop;
8f527c5e
FL
2246#define ZEBRA_ROUTE_IBGP ZEBRA_ROUTE_MAX
2247#define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1)
d7c0a89a
QY
2248 uint32_t rib_cnt[ZEBRA_ROUTE_TOTAL + 1];
2249 uint32_t fib_cnt[ZEBRA_ROUTE_TOTAL + 1];
2250 uint32_t i;
d62a17ae 2251 int cnt;
e7deb7e7
DA
2252 json_object *json_route_summary = NULL;
2253 json_object *json_route_routes = NULL;
d62a17ae 2254
2255 memset(&rib_cnt, 0, sizeof(rib_cnt));
2256 memset(&fib_cnt, 0, sizeof(fib_cnt));
e7deb7e7
DA
2257
2258 if (use_json) {
2259 json_route_summary = json_object_new_object();
2260 json_route_routes = json_object_new_array();
2261 json_object_object_add(json_route_summary, "prefixRoutes",
2262 json_route_routes);
2263 }
2264
d62a17ae 2265 for (rn = route_top(table); rn; rn = srcdest_route_next(rn))
a2addae8 2266 RNODE_FOREACH_RE (rn, re) {
d62a17ae 2267
2268 /*
2269 * In case of ECMP, count only once.
2270 */
2271 cnt = 0;
677c1dd5
DS
2272 if (CHECK_FLAG(re->status, ROUTE_ENTRY_INSTALLED)) {
2273 fib_cnt[ZEBRA_ROUTE_TOTAL]++;
2274 fib_cnt[re->type]++;
2275 }
c415d895 2276 for (nexthop = re->nhe->nhg.nexthop; (!cnt && nexthop);
d62a17ae 2277 nexthop = nexthop->next) {
2278 cnt++;
2279 rib_cnt[ZEBRA_ROUTE_TOTAL]++;
2280 rib_cnt[re->type]++;
d62a17ae 2281 if (re->type == ZEBRA_ROUTE_BGP
2282 && CHECK_FLAG(re->flags, ZEBRA_FLAG_IBGP)) {
2283 rib_cnt[ZEBRA_ROUTE_IBGP]++;
677c1dd5
DS
2284 if (CHECK_FLAG(re->status,
2285 ROUTE_ENTRY_INSTALLED))
d62a17ae 2286 fib_cnt[ZEBRA_ROUTE_IBGP]++;
2287 }
2288 }
2289 }
2290
e7deb7e7
DA
2291 if (!use_json)
2292 vty_out(vty, "%-20s %-20s %s (vrf %s)\n", "Route Source",
2293 "Prefix Routes", "FIB",
630d5962
DS
2294 zvrf_name(((struct rib_table_info *)
2295 route_table_get_info(table))
e7deb7e7 2296 ->zvrf));
d62a17ae 2297
2298 for (i = 0; i < ZEBRA_ROUTE_MAX; i++) {
2299 if (rib_cnt[i] > 0) {
2300 if (i == ZEBRA_ROUTE_BGP) {
e7deb7e7
DA
2301 if (use_json) {
2302 json_object *json_route_ebgp =
2303 json_object_new_object();
2304
2305 json_object_int_add(
2306 json_route_ebgp, "fib",
2307 fib_cnt[ZEBRA_ROUTE_BGP]
2308 - fib_cnt[ZEBRA_ROUTE_IBGP]);
2309 json_object_int_add(
2310 json_route_ebgp, "rib",
2311 rib_cnt[ZEBRA_ROUTE_BGP]
2312 - rib_cnt[ZEBRA_ROUTE_IBGP]);
2313 json_object_string_add(json_route_ebgp,
2314 "type", "ebgp");
2315 json_object_array_add(json_route_routes,
2316 json_route_ebgp);
2317
2318 json_object *json_route_ibgp =
2319 json_object_new_object();
2320
2321 json_object_int_add(
2322 json_route_ibgp, "fib",
2323 fib_cnt[ZEBRA_ROUTE_IBGP]);
2324 json_object_int_add(
2325 json_route_ibgp, "rib",
2326 rib_cnt[ZEBRA_ROUTE_IBGP]);
2327 json_object_string_add(json_route_ibgp,
2328 "type", "ibgp");
2329 json_object_array_add(json_route_routes,
2330 json_route_ibgp);
2331 } else {
2332 vty_out(vty, "%-20s %-20d %-20d \n",
2333 "ebgp",
2334 rib_cnt[ZEBRA_ROUTE_BGP]
2335 - rib_cnt[ZEBRA_ROUTE_IBGP],
2336 fib_cnt[ZEBRA_ROUTE_BGP]
2337 - fib_cnt[ZEBRA_ROUTE_IBGP]);
2338 vty_out(vty, "%-20s %-20d %-20d \n",
2339 "ibgp",
2340 rib_cnt[ZEBRA_ROUTE_IBGP],
2341 fib_cnt[ZEBRA_ROUTE_IBGP]);
2342 }
2343 } else {
2344 if (use_json) {
2345 json_object *json_route_type =
2346 json_object_new_object();
2347
2348 json_object_int_add(json_route_type,
2349 "fib", fib_cnt[i]);
2350 json_object_int_add(json_route_type,
2351 "rib", rib_cnt[i]);
2352 json_object_string_add(
2353 json_route_type, "type",
2354 zebra_route_string(i));
2355 json_object_array_add(json_route_routes,
2356 json_route_type);
2357 } else
2358 vty_out(vty, "%-20s %-20d %-20d \n",
2359 zebra_route_string(i),
2360 rib_cnt[i], fib_cnt[i]);
2361 }
d62a17ae 2362 }
2363 }
2364
e7deb7e7
DA
2365 if (use_json) {
2366 json_object_int_add(json_route_summary, "prefixRoutesTotal",
2367 rib_cnt[ZEBRA_ROUTE_TOTAL]);
2368 json_object_int_add(json_route_summary, "prefixRoutesTotalFib",
2369 fib_cnt[ZEBRA_ROUTE_TOTAL]);
2370
2371 vty_out(vty, "%s\n",
2372 json_object_to_json_string_ext(
2373 json_route_summary, JSON_C_TO_STRING_PRETTY));
2374 json_object_free(json_route_summary);
2375 } else {
2376 vty_out(vty, "------\n");
2377 vty_out(vty, "%-20s %-20d %-20d \n", "Totals",
2378 rib_cnt[ZEBRA_ROUTE_TOTAL], fib_cnt[ZEBRA_ROUTE_TOTAL]);
2379 vty_out(vty, "\n");
2380 }
9343ce83
DS
2381}
2382
cddf391b
B
2383/*
2384 * Show IPv6 mroute command.Used to dump
2385 * the Multicast routing table.
2386 */
cddf391b
B
2387DEFUN (show_ipv6_mroute,
2388 show_ipv6_mroute_cmd,
9bf96c84 2389 "show ipv6 mroute [vrf NAME]",
cddf391b
B
2390 SHOW_STR
2391 IP_STR
9bf96c84
DW
2392 "IPv6 Multicast routing table\n"
2393 VRF_CMD_HELP_STR)
cddf391b 2394{
d62a17ae 2395 struct route_table *table;
2396 struct route_node *rn;
2397 struct route_entry *re;
2398 int first = 1;
2399 vrf_id_t vrf_id = VRF_DEFAULT;
2400
2401 if (argc == 5)
ec1db588 2402 VRF_GET_ID(vrf_id, argv[4]->arg, false);
d62a17ae 2403
2404 table = zebra_vrf_table(AFI_IP6, SAFI_MULTICAST, vrf_id);
2405 if (!table)
2406 return CMD_SUCCESS;
2407
2408 /* Show all IPv6 route. */
2409 for (rn = route_top(table); rn; rn = srcdest_route_next(rn))
a2addae8 2410 RNODE_FOREACH_RE (rn, re) {
d62a17ae 2411 if (first) {
2412 vty_out(vty, SHOW_ROUTE_V6_HEADER);
2413 first = 0;
2414 }
941e261c 2415 vty_show_ip_route(vty, rn, re, NULL, false);
d62a17ae 2416 }
2417 return CMD_SUCCESS;
cddf391b
B
2418}
2419
af41b63a
FL
2420DEFUN (show_ipv6_mroute_vrf_all,
2421 show_ipv6_mroute_vrf_all_cmd,
5bebf568 2422 "show ipv6 mroute vrf all",
af41b63a
FL
2423 SHOW_STR
2424 IP_STR
2425 "IPv6 Multicast routing table\n"
2426 VRF_ALL_CMD_HELP_STR)
2427{
d62a17ae 2428 struct route_table *table;
2429 struct route_node *rn;
2430 struct route_entry *re;
2431 struct vrf *vrf;
2432 struct zebra_vrf *zvrf;
2433 int first = 1;
2434
a2addae8 2435 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
d62a17ae 2436 if ((zvrf = vrf->info) == NULL
2437 || (table = zvrf->table[AFI_IP6][SAFI_MULTICAST]) == NULL)
2438 continue;
2439
2440 /* Show all IPv6 route. */
2441 for (rn = route_top(table); rn; rn = srcdest_route_next(rn))
a2addae8 2442 RNODE_FOREACH_RE (rn, re) {
d62a17ae 2443 if (first) {
2444 vty_out(vty, SHOW_ROUTE_V6_HEADER);
2445 first = 0;
2446 }
941e261c 2447 vty_show_ip_route(vty, rn, re, NULL, false);
d62a17ae 2448 }
2449 }
2450 return CMD_SUCCESS;
af41b63a
FL
2451}
2452
6baf7bb8
DS
2453DEFUN (allow_external_route_update,
2454 allow_external_route_update_cmd,
2455 "allow-external-route-update",
17d990c1 2456 "Allow FRR routes to be overwritten by external processes\n")
6baf7bb8 2457{
d62a17ae 2458 allow_delete = 1;
6baf7bb8 2459
d62a17ae 2460 return CMD_SUCCESS;
6baf7bb8
DS
2461}
2462
2463DEFUN (no_allow_external_route_update,
2464 no_allow_external_route_update_cmd,
2465 "no allow-external-route-update",
17d990c1
DS
2466 NO_STR
2467 "Allow FRR routes to be overwritten by external processes\n")
6baf7bb8 2468{
d62a17ae 2469 allow_delete = 0;
6baf7bb8 2470
d62a17ae 2471 return CMD_SUCCESS;
6baf7bb8
DS
2472}
2473
12f6fb97
DS
2474/* show vrf */
2475DEFUN (show_vrf,
2476 show_vrf_cmd,
2477 "show vrf",
2478 SHOW_STR
2479 "VRF\n")
2480{
d62a17ae 2481 struct vrf *vrf;
2482 struct zebra_vrf *zvrf;
12f6fb97 2483
b73823ef
PG
2484 if (vrf_is_backend_netns())
2485 vty_out(vty, "netns-based vrfs\n");
2486
a2addae8 2487 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
d62a17ae 2488 if (!(zvrf = vrf->info))
2489 continue;
90ac32c2 2490 if (zvrf_id(zvrf) == VRF_DEFAULT)
d62a17ae 2491 continue;
2492
2493 vty_out(vty, "vrf %s ", zvrf_name(zvrf));
996c9314 2494 if (zvrf_id(zvrf) == VRF_UNKNOWN || !zvrf_is_active(zvrf))
d62a17ae 2495 vty_out(vty, "inactive");
81c9005f 2496 else if (zvrf_ns_name(zvrf))
996c9314
LB
2497 vty_out(vty, "id %u netns %s", zvrf_id(zvrf),
2498 zvrf_ns_name(zvrf));
d62a17ae 2499 else
2500 vty_out(vty, "id %u table %u", zvrf_id(zvrf),
2501 zvrf->table_id);
22bd3e94 2502 if (vrf_is_user_cfged(vrf))
2503 vty_out(vty, " (configured)");
d62a17ae 2504 vty_out(vty, "\n");
2505 }
12f6fb97 2506
d62a17ae 2507 return CMD_SUCCESS;
12f6fb97
DS
2508}
2509
41c809b2
AK
2510DEFPY (evpn_mh_mac_holdtime,
2511 evpn_mh_mac_holdtime_cmd,
2512 "[no$no] evpn mh mac-holdtime (0-86400)$duration",
2513 NO_STR
2514 "EVPN\n"
2515 "Multihoming\n"
2516 "MAC hold time\n"
2517 "Duration in seconds\n")
2518{
2519 return zebra_evpn_mh_mac_holdtime_update(vty, duration,
2520 no ? true : false);
2521}
2522
2523DEFPY (evpn_mh_neigh_holdtime,
2524 evpn_mh_neigh_holdtime_cmd,
2525 "[no$no] evpn mh neigh-holdtime (0-86400)$duration",
2526 NO_STR
2527 "EVPN\n"
2528 "Multihoming\n"
2529 "Neighbor entry hold time\n"
2530 "Duration in seconds\n")
2531{
2532
2533 return zebra_evpn_mh_neigh_holdtime_update(vty, duration,
2534 no ? true : false);
2535}
2536
c36e442c
AK
2537DEFPY (evpn_mh_startup_delay,
2538 evpn_mh_startup_delay_cmd,
2539 "[no] evpn mh startup-delay(0-3600)$duration",
2540 NO_STR
2541 "EVPN\n"
2542 "Multihoming\n"
2543 "Startup delay\n"
2544 "duration in seconds\n")
2545{
2546
2547 return zebra_evpn_mh_startup_delay_update(vty, duration,
2548 no ? true : false);
2549}
2550
15400f95
AK
2551DEFPY(evpn_mh_redirect_off, evpn_mh_redirect_off_cmd,
2552 "[no$no] evpn mh redirect-off",
2553 NO_STR
2554 "EVPN\n"
2555 "Multihoming\n"
2556 "ES bond redirect for fast-failover off\n")
2557{
2558 bool redirect_off;
2559
2560 redirect_off = no ? false : true;
2561
2562 return zebra_evpn_mh_redirect_off(vty, redirect_off);
2563}
2564
8f2ff1b5 2565DEFUN (default_vrf_vni_mapping,
e8d26197 2566 default_vrf_vni_mapping_cmd,
c48d9f5f 2567 "vni " CMD_VNI_RANGE "[prefix-routes-only]",
e8d26197 2568 "VNI corresponding to the DEFAULT VRF\n"
c48d9f5f
MK
2569 "VNI-ID\n"
2570 "Prefix routes only \n")
e8d26197 2571{
9082b3eb 2572 char xpath[XPATH_MAXLEN];
e8d26197 2573 struct zebra_vrf *zvrf = NULL;
c48d9f5f 2574 int filter = 0;
e8d26197
MK
2575
2576 zvrf = vrf_info_lookup(VRF_DEFAULT);
2577 if (!zvrf)
2578 return CMD_WARNING;
2579
c48d9f5f
MK
2580 if (argc == 3)
2581 filter = 1;
2582
9082b3eb
IR
2583 snprintf(xpath, sizeof(xpath), FRR_VRF_KEY_XPATH "/frr-zebra:zebra",
2584 VRF_DEFAULT_NAME);
2585 nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
2586
2587 snprintf(xpath, sizeof(xpath),
2588 FRR_VRF_KEY_XPATH "/frr-zebra:zebra/l3vni-id",
2589 VRF_DEFAULT_NAME);
2590 nb_cli_enqueue_change(vty, xpath, NB_OP_MODIFY, argv[1]->arg);
2591
2592 if (filter) {
2593 snprintf(xpath, sizeof(xpath),
2594 FRR_VRF_KEY_XPATH "/frr-zebra:zebra/prefix-only",
2595 VRF_DEFAULT_NAME);
2596 nb_cli_enqueue_change(vty, xpath, NB_OP_MODIFY, "true");
e8d26197
MK
2597 }
2598
9082b3eb 2599 return nb_cli_apply_changes(vty, NULL);
e8d26197
MK
2600}
2601
8f2ff1b5 2602DEFUN (no_default_vrf_vni_mapping,
e8d26197 2603 no_default_vrf_vni_mapping_cmd,
9082b3eb 2604 "no vni " CMD_VNI_RANGE "[prefix-routes-only]",
e8d26197
MK
2605 NO_STR
2606 "VNI corresponding to DEFAULT VRF\n"
9082b3eb
IR
2607 "VNI-ID\n"
2608 "Prefix routes only \n")
e8d26197 2609{
9082b3eb
IR
2610 char xpath[XPATH_MAXLEN];
2611 int filter = 0;
e8d26197
MK
2612 vni_t vni = strtoul(argv[2]->arg, NULL, 10);
2613 struct zebra_vrf *zvrf = NULL;
2614
2615 zvrf = vrf_info_lookup(VRF_DEFAULT);
2616 if (!zvrf)
2617 return CMD_WARNING;
2618
9082b3eb
IR
2619 if (argc == 4)
2620 filter = 1;
2621
2622 if (zvrf->l3vni != vni) {
2623 vty_out(vty, "VNI %d doesn't exist in VRF: %s \n", vni,
2624 zvrf->vrf->name);
e8d26197
MK
2625 return CMD_WARNING;
2626 }
2627
9082b3eb
IR
2628 snprintf(xpath, sizeof(xpath),
2629 FRR_VRF_KEY_XPATH "/frr-zebra:zebra/l3vni-id",
2630 VRF_DEFAULT_NAME);
2631 nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, argv[2]->arg);
2632
2633 if (filter) {
2634 snprintf(xpath, sizeof(xpath),
2635 FRR_VRF_KEY_XPATH "/frr-zebra:zebra/prefix-only",
2636 VRF_DEFAULT_NAME);
2637 nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, "true");
2638 }
2639
2640 snprintf(xpath, sizeof(xpath), FRR_VRF_KEY_XPATH "/frr-zebra:zebra",
2641 VRF_DEFAULT_NAME);
2642 nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
2643
2644 return nb_cli_apply_changes(vty, NULL);
e8d26197
MK
2645}
2646
b7cfce93
MK
2647DEFUN (vrf_vni_mapping,
2648 vrf_vni_mapping_cmd,
c48d9f5f 2649 "vni " CMD_VNI_RANGE "[prefix-routes-only]",
e8d26197 2650 "VNI corresponding to tenant VRF\n"
c48d9f5f
MK
2651 "VNI-ID\n"
2652 "prefix-routes-only\n")
b7cfce93 2653{
c48d9f5f 2654 int filter = 0;
b7cfce93
MK
2655
2656 ZEBRA_DECLVAR_CONTEXT(vrf, zvrf);
b7cfce93
MK
2657
2658 assert(vrf);
2659 assert(zvrf);
2660
c48d9f5f
MK
2661 if (argc == 3)
2662 filter = 1;
2663
e2bcfa39
CS
2664 nb_cli_enqueue_change(vty, "./frr-zebra:zebra", NB_OP_CREATE, NULL);
2665 nb_cli_enqueue_change(vty, "./frr-zebra:zebra/l3vni-id", NB_OP_MODIFY,
2666 argv[1]->arg);
2667
2668 if (filter)
2669 nb_cli_enqueue_change(vty, "./frr-zebra:zebra/prefix-only",
2670 NB_OP_MODIFY, "true");
2671
9082b3eb 2672 return nb_cli_apply_changes(vty, NULL);
b7cfce93
MK
2673}
2674
2675DEFUN (no_vrf_vni_mapping,
2676 no_vrf_vni_mapping_cmd,
cf299714 2677 "no vni " CMD_VNI_RANGE "[prefix-routes-only]",
b7cfce93 2678 NO_STR
e8d26197 2679 "VNI corresponding to tenant VRF\n"
cf299714
MK
2680 "VNI-ID\n"
2681 "prefix-routes-only\n")
b7cfce93 2682{
cf299714 2683 int filter = 0;
b7cfce93
MK
2684
2685 ZEBRA_DECLVAR_CONTEXT(vrf, zvrf);
a5897c41 2686 vni_t vni = strtoul(argv[2]->arg, NULL, 10);
b7cfce93
MK
2687
2688 assert(vrf);
2689 assert(zvrf);
2690
cf299714
MK
2691 if (argc == 4)
2692 filter = 1;
2693
e2bcfa39
CS
2694 if (zvrf->l3vni != vni) {
2695 vty_out(vty, "VNI %d doesn't exist in VRF: %s \n", vni,
2696 zvrf->vrf->name);
b7cfce93
MK
2697 return CMD_WARNING;
2698 }
2699
e2bcfa39
CS
2700 nb_cli_enqueue_change(vty, "./frr-zebra:zebra/l3vni-id", NB_OP_DESTROY,
2701 argv[2]->arg);
2702
2703 if (filter)
2704 nb_cli_enqueue_change(vty, "./frr-zebra:zebra/prefix-only",
2705 NB_OP_DESTROY, "true");
2706
2707 nb_cli_enqueue_change(vty, "./frr-zebra:zebra", NB_OP_DESTROY, NULL);
2708
9082b3eb 2709 return nb_cli_apply_changes(vty, NULL);
b7cfce93
MK
2710}
2711
2712/* show vrf */
2713DEFUN (show_vrf_vni,
2714 show_vrf_vni_cmd,
35be5542 2715 "show vrf vni [json]",
b7cfce93
MK
2716 SHOW_STR
2717 "VRF\n"
35be5542
MK
2718 "VNI\n"
2719 JSON_STR)
b7cfce93
MK
2720{
2721 struct vrf *vrf;
2722 struct zebra_vrf *zvrf;
35be5542
MK
2723 json_object *json = NULL;
2724 json_object *json_vrfs = NULL;
9f049418 2725 bool uj = use_json(argc, argv);
35be5542
MK
2726
2727 if (uj) {
2728 json = json_object_new_object();
2729 json_vrfs = json_object_new_array();
2730 }
b7cfce93 2731
4cce389e 2732 if (!uj)
996c9314
LB
2733 vty_out(vty, "%-37s %-10s %-20s %-20s %-5s %-18s\n", "VRF",
2734 "VNI", "VxLAN IF", "L3-SVI", "State", "Rmac");
4cce389e 2735
996c9314 2736 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
b7cfce93
MK
2737 zvrf = vrf->info;
2738 if (!zvrf)
2739 continue;
2740
4cce389e 2741 zebra_vxlan_print_vrf_vni(vty, zvrf, json_vrfs);
35be5542
MK
2742 }
2743
2744 if (uj) {
2745 json_object_object_add(json, "vrfs", json_vrfs);
2746 vty_out(vty, "%s\n", json_object_to_json_string_ext(
2747 json, JSON_C_TO_STRING_PRETTY));
2748 json_object_free(json);
b7cfce93
MK
2749 }
2750
2751 return CMD_SUCCESS;
2752}
2753
4cce389e
MK
2754DEFUN (show_evpn_global,
2755 show_evpn_global_cmd,
2756 "show evpn [json]",
2757 SHOW_STR
2758 "EVPN\n"
2759 JSON_STR)
2760{
9f049418 2761 bool uj = use_json(argc, argv);
4cce389e
MK
2762
2763 zebra_vxlan_print_evpn(vty, uj);
2764 return CMD_SUCCESS;
2765}
2766
5de10c37
AK
2767DEFPY(show_evpn_l2_nh,
2768 show_evpn_l2_nh_cmd,
2769 "show evpn l2-nh [json$json]",
2770 SHOW_STR
2771 "EVPN\n"
2772 "Layer2 nexthops\n"
2773 JSON_STR)
2774{
2775 bool uj = !!json;
2776
2777 zebra_evpn_l2_nh_show(vty, uj);
2778
2779 return CMD_SUCCESS;
2780}
2781
374b316c
AK
2782DEFPY(show_evpn_es,
2783 show_evpn_es_cmd,
acffa256 2784 "show evpn es [NAME$esi_str|detail$detail] [json$json]",
374b316c
AK
2785 SHOW_STR
2786 "EVPN\n"
2787 "Ethernet Segment\n"
2788 "ES ID\n"
5de10c37
AK
2789 "Detailed information\n"
2790 JSON_STR)
374b316c
AK
2791{
2792 esi_t esi;
2793 bool uj = !!json;
2794
2795 if (esi_str) {
2796 if (!str_to_esi(esi_str, &esi)) {
2797 vty_out(vty, "%% Malformed ESI\n");
2798 return CMD_WARNING;
2799 }
2800 zebra_evpn_es_show_esi(vty, uj, &esi);
2801 } else {
2802 if (detail)
2803 zebra_evpn_es_show_detail(vty, uj);
2804 else
2805 zebra_evpn_es_show(vty, uj);
2806 }
2807
2808 return CMD_SUCCESS;
2809}
2810
2811DEFPY(show_evpn_es_evi,
2812 show_evpn_es_evi_cmd,
acffa256 2813 "show evpn es-evi [vni (1-16777215)$vni] [detail$detail] [json$json]",
374b316c
AK
2814 SHOW_STR
2815 "EVPN\n"
2816 "Ethernet Segment per EVI\n"
2817 "VxLAN Network Identifier\n"
2818 "VNI\n"
acffa256
AK
2819 "Detailed information\n"
2820 JSON_STR)
374b316c
AK
2821{
2822 bool uj = !!json;
2823 bool ud = !!detail;
2824
2825 if (vni)
2826 zebra_evpn_es_evi_show_vni(vty, uj, vni, ud);
2827 else
2828 zebra_evpn_es_evi_show(vty, uj, ud);
2829
2830 return CMD_SUCCESS;
2831}
2832
2833DEFPY(show_evpn_access_vlan,
2834 show_evpn_access_vlan_cmd,
acffa256 2835 "show evpn access-vlan [(1-4094)$vid | detail$detail] [json$json]",
374b316c
AK
2836 SHOW_STR
2837 "EVPN\n"
2838 "Access VLANs\n"
2839 "VLAN ID\n"
acffa256
AK
2840 "Detailed information\n"
2841 JSON_STR)
374b316c
AK
2842{
2843 bool uj = !!json;
2844
2845 if (vid) {
2846 zebra_evpn_acc_vl_show_vid(vty, uj, vid);
2847 } else {
2848 if (detail)
2849 zebra_evpn_acc_vl_show_detail(vty, uj);
2850 else
2851 zebra_evpn_acc_vl_show(vty, uj);
2852 }
2853
2854 return CMD_SUCCESS;
2855}
2856
cec2e17d 2857DEFUN (show_evpn_vni,
2858 show_evpn_vni_cmd,
cd233079 2859 "show evpn vni [json]",
cec2e17d 2860 SHOW_STR
2861 "EVPN\n"
09af6961 2862 "VxLAN Network Identifier\n"
bd592158 2863 JSON_STR)
cec2e17d 2864{
d62a17ae 2865 struct zebra_vrf *zvrf;
9f049418 2866 bool uj = use_json(argc, argv);
cec2e17d 2867
530db8dc 2868 zvrf = zebra_vrf_get_evpn();
cd233079 2869 zebra_vxlan_print_vnis(vty, zvrf, uj);
d62a17ae 2870 return CMD_SUCCESS;
cec2e17d 2871}
2872
09af6961
NS
2873DEFUN (show_evpn_vni_detail, show_evpn_vni_detail_cmd,
2874 "show evpn vni detail [json]",
2875 SHOW_STR
2876 "EVPN\n"
2877 "VxLAN Network Identifier\n"
2878 "Detailed Information On Each VNI\n"
2879 JSON_STR)
2880{
2881 struct zebra_vrf *zvrf;
2882 bool uj = use_json(argc, argv);
2883
530db8dc 2884 zvrf = zebra_vrf_get_evpn();
09af6961
NS
2885 zebra_vxlan_print_vnis_detail(vty, zvrf, uj);
2886 return CMD_SUCCESS;
2887}
2888
cec2e17d 2889DEFUN (show_evpn_vni_vni,
2890 show_evpn_vni_vni_cmd,
cd233079 2891 "show evpn vni " CMD_VNI_RANGE "[json]",
cec2e17d 2892 SHOW_STR
2893 "EVPN\n"
2894 "VxLAN Network Identifier\n"
cd233079 2895 "VNI number\n"
bd592158 2896 JSON_STR)
cec2e17d 2897{
d62a17ae 2898 struct zebra_vrf *zvrf;
2899 vni_t vni;
9f049418 2900 bool uj = use_json(argc, argv);
cec2e17d 2901
d62a17ae 2902 vni = strtoul(argv[3]->arg, NULL, 10);
530db8dc 2903 zvrf = zebra_vrf_get_evpn();
06931fdb 2904 zebra_vxlan_print_vni(vty, zvrf, vni, uj, NULL);
d62a17ae 2905 return CMD_SUCCESS;
cec2e17d 2906}
2907
4cce389e
MK
2908DEFUN (show_evpn_rmac_vni_mac,
2909 show_evpn_rmac_vni_mac_cmd,
2910 "show evpn rmac vni " CMD_VNI_RANGE " mac WORD [json]",
9aa741ea
MK
2911 SHOW_STR
2912 "EVPN\n"
2913 "RMAC\n"
4cce389e 2914 "L3 VNI\n"
9aa741ea
MK
2915 "VNI number\n"
2916 "MAC\n"
316f4ca4
MK
2917 "mac-address (e.g. 0a:0a:0a:0a:0a:0a)\n"
2918 JSON_STR)
9aa741ea
MK
2919{
2920 vni_t l3vni = 0;
2921 struct ethaddr mac;
9f049418 2922 bool uj = use_json(argc, argv);
9aa741ea
MK
2923
2924 l3vni = strtoul(argv[4]->arg, NULL, 10);
2925 if (!prefix_str2mac(argv[6]->arg, &mac)) {
2926 vty_out(vty, "%% Malformed MAC address\n");
2927 return CMD_WARNING;
2928 }
316f4ca4 2929 zebra_vxlan_print_specific_rmac_l3vni(vty, l3vni, &mac, uj);
9aa741ea
MK
2930 return CMD_SUCCESS;
2931}
2932
4cce389e
MK
2933DEFUN (show_evpn_rmac_vni,
2934 show_evpn_rmac_vni_cmd,
2935 "show evpn rmac vni " CMD_VNI_RANGE "[json]",
b7cfce93
MK
2936 SHOW_STR
2937 "EVPN\n"
2938 "RMAC\n"
4cce389e 2939 "L3 VNI\n"
b7cfce93
MK
2940 "VNI number\n"
2941 JSON_STR)
2942{
2943 vni_t l3vni = 0;
9f049418 2944 bool uj = use_json(argc, argv);
b7cfce93
MK
2945
2946 l3vni = strtoul(argv[4]->arg, NULL, 10);
2947 zebra_vxlan_print_rmacs_l3vni(vty, l3vni, uj);
2948
2949 return CMD_SUCCESS;
2950}
2951
4cce389e
MK
2952DEFUN (show_evpn_rmac_vni_all,
2953 show_evpn_rmac_vni_all_cmd,
2954 "show evpn rmac vni all [json]",
b7cfce93
MK
2955 SHOW_STR
2956 "EVPN\n"
2957 "RMAC addresses\n"
4cce389e 2958 "L3 VNI\n"
b7cfce93
MK
2959 "All VNIs\n"
2960 JSON_STR)
2961{
9f049418 2962 bool uj = use_json(argc, argv);
b7cfce93
MK
2963
2964 zebra_vxlan_print_rmacs_all_l3vni(vty, uj);
2965
2966 return CMD_SUCCESS;
2967}
2968
4cce389e
MK
2969DEFUN (show_evpn_nh_vni_ip,
2970 show_evpn_nh_vni_ip_cmd,
2971 "show evpn next-hops vni " CMD_VNI_RANGE " ip WORD [json]",
9aa741ea
MK
2972 SHOW_STR
2973 "EVPN\n"
2974 "Remote Vteps\n"
4cce389e 2975 "L3 VNI\n"
9aa741ea
MK
2976 "VNI number\n"
2977 "Ip address\n"
c0e519d3
MK
2978 "Host address (ipv4 or ipv6)\n"
2979 JSON_STR)
9aa741ea
MK
2980{
2981 vni_t l3vni;
9aa741ea 2982 struct ipaddr ip;
9f049418 2983 bool uj = use_json(argc, argv);
9aa741ea
MK
2984
2985 l3vni = strtoul(argv[4]->arg, NULL, 10);
2986 if (str2ipaddr(argv[6]->arg, &ip) != 0) {
2987 if (!uj)
2988 vty_out(vty, "%% Malformed Neighbor address\n");
2989 return CMD_WARNING;
2990 }
c0e519d3 2991 zebra_vxlan_print_specific_nh_l3vni(vty, l3vni, &ip, uj);
9aa741ea
MK
2992
2993 return CMD_SUCCESS;
2994}
2995
4cce389e
MK
2996DEFUN (show_evpn_nh_vni,
2997 show_evpn_nh_vni_cmd,
2998 "show evpn next-hops vni " CMD_VNI_RANGE "[json]",
b7cfce93
MK
2999 SHOW_STR
3000 "EVPN\n"
3001 "Remote Vteps\n"
4cce389e 3002 "L3 VNI\n"
b7cfce93
MK
3003 "VNI number\n"
3004 JSON_STR)
3005{
3006 vni_t l3vni;
9f049418 3007 bool uj = use_json(argc, argv);
b7cfce93
MK
3008
3009 l3vni = strtoul(argv[4]->arg, NULL, 10);
3010 zebra_vxlan_print_nh_l3vni(vty, l3vni, uj);
3011
3012 return CMD_SUCCESS;
3013}
3014
4cce389e
MK
3015DEFUN (show_evpn_nh_vni_all,
3016 show_evpn_nh_vni_all_cmd,
3017 "show evpn next-hops vni all [json]",
b7cfce93
MK
3018 SHOW_STR
3019 "EVPN\n"
3020 "Remote VTEPs\n"
4cce389e 3021 "L3 VNI\n"
b7cfce93
MK
3022 "All VNIs\n"
3023 JSON_STR)
3024{
9f049418 3025 bool uj = use_json(argc, argv);
b7cfce93
MK
3026
3027 zebra_vxlan_print_nh_all_l3vni(vty, uj);
3028
3029 return CMD_SUCCESS;
3030}
3031
cec2e17d 3032DEFUN (show_evpn_mac_vni,
3033 show_evpn_mac_vni_cmd,
cd233079 3034 "show evpn mac vni " CMD_VNI_RANGE "[json]",
cec2e17d 3035 SHOW_STR
3036 "EVPN\n"
3037 "MAC addresses\n"
3038 "VxLAN Network Identifier\n"
cd233079 3039 "VNI number\n"
bd592158 3040 JSON_STR)
cec2e17d 3041{
d62a17ae 3042 struct zebra_vrf *zvrf;
3043 vni_t vni;
9f049418 3044 bool uj = use_json(argc, argv);
cec2e17d 3045
d62a17ae 3046 vni = strtoul(argv[4]->arg, NULL, 10);
530db8dc 3047 zvrf = zebra_vrf_get_evpn();
cd233079 3048 zebra_vxlan_print_macs_vni(vty, zvrf, vni, uj);
d62a17ae 3049 return CMD_SUCCESS;
cec2e17d 3050}
3051
3052DEFUN (show_evpn_mac_vni_all,
3053 show_evpn_mac_vni_all_cmd,
cd233079 3054 "show evpn mac vni all [json]",
cec2e17d 3055 SHOW_STR
3056 "EVPN\n"
3057 "MAC addresses\n"
3058 "VxLAN Network Identifier\n"
cd233079 3059 "All VNIs\n"
bd592158 3060 JSON_STR)
cec2e17d 3061{
d62a17ae 3062 struct zebra_vrf *zvrf;
9f049418 3063 bool uj = use_json(argc, argv);
cec2e17d 3064
530db8dc 3065 zvrf = zebra_vrf_get_evpn();
1374d4db 3066 zebra_vxlan_print_macs_all_vni(vty, zvrf, false, uj);
d62a17ae 3067 return CMD_SUCCESS;
cec2e17d 3068}
3069
cffe7580
NS
3070DEFUN (show_evpn_mac_vni_all_detail, show_evpn_mac_vni_all_detail_cmd,
3071 "show evpn mac vni all detail [json]",
3072 SHOW_STR
3073 "EVPN\n"
3074 "MAC addresses\n"
3075 "VxLAN Network Identifier\n"
3076 "All VNIs\n"
3077 "Detailed Information On Each VNI MAC\n"
3078 JSON_STR)
3079{
3080 struct zebra_vrf *zvrf;
3081 bool uj = use_json(argc, argv);
3082
530db8dc 3083 zvrf = zebra_vrf_get_evpn();
cffe7580
NS
3084 zebra_vxlan_print_macs_all_vni_detail(vty, zvrf, false, uj);
3085 return CMD_SUCCESS;
3086}
3087
cec2e17d 3088DEFUN (show_evpn_mac_vni_all_vtep,
3089 show_evpn_mac_vni_all_vtep_cmd,
cd233079 3090 "show evpn mac vni all vtep A.B.C.D [json]",
cec2e17d 3091 SHOW_STR
3092 "EVPN\n"
3093 "MAC addresses\n"
3094 "VxLAN Network Identifier\n"
3095 "All VNIs\n"
3096 "Remote VTEP\n"
cd233079 3097 "Remote VTEP IP address\n"
bd592158 3098 JSON_STR)
cec2e17d 3099{
d62a17ae 3100 struct zebra_vrf *zvrf;
3101 struct in_addr vtep_ip;
9f049418 3102 bool uj = use_json(argc, argv);
cec2e17d 3103
d62a17ae 3104 if (!inet_aton(argv[6]->arg, &vtep_ip)) {
cd233079
CS
3105 if (!uj)
3106 vty_out(vty, "%% Malformed VTEP IP address\n");
d62a17ae 3107 return CMD_WARNING;
3108 }
530db8dc 3109 zvrf = zebra_vrf_get_evpn();
cd233079 3110 zebra_vxlan_print_macs_all_vni_vtep(vty, zvrf, vtep_ip, uj);
cec2e17d 3111
d62a17ae 3112 return CMD_SUCCESS;
cec2e17d 3113}
3114
3115
3116DEFUN (show_evpn_mac_vni_mac,
3117 show_evpn_mac_vni_mac_cmd,
24cdbd0d 3118 "show evpn mac vni " CMD_VNI_RANGE " mac WORD [json]",
cec2e17d 3119 SHOW_STR
3120 "EVPN\n"
3121 "MAC addresses\n"
3122 "VxLAN Network Identifier\n"
3123 "VNI number\n"
3124 "MAC\n"
24cdbd0d
DS
3125 "MAC address (e.g., 00:e0:ec:20:12:62)\n"
3126 JSON_STR)
3127
cec2e17d 3128{
d62a17ae 3129 struct zebra_vrf *zvrf;
3130 vni_t vni;
3131 struct ethaddr mac;
24cdbd0d 3132 bool uj = use_json(argc, argv);
cec2e17d 3133
d62a17ae 3134 vni = strtoul(argv[4]->arg, NULL, 10);
3135 if (!prefix_str2mac(argv[6]->arg, &mac)) {
3136 vty_out(vty, "%% Malformed MAC address");
3137 return CMD_WARNING;
3138 }
530db8dc 3139 zvrf = zebra_vrf_get_evpn();
24cdbd0d 3140 zebra_vxlan_print_specific_mac_vni(vty, zvrf, vni, &mac, uj);
d62a17ae 3141 return CMD_SUCCESS;
cec2e17d 3142}
3143
3144DEFUN (show_evpn_mac_vni_vtep,
3145 show_evpn_mac_vni_vtep_cmd,
cd233079 3146 "show evpn mac vni " CMD_VNI_RANGE " vtep A.B.C.D" "[json]",
cec2e17d 3147 SHOW_STR
3148 "EVPN\n"
3149 "MAC addresses\n"
3150 "VxLAN Network Identifier\n"
3151 "VNI number\n"
3152 "Remote VTEP\n"
cd233079 3153 "Remote VTEP IP address\n"
bd592158 3154 JSON_STR)
cec2e17d 3155{
d62a17ae 3156 struct zebra_vrf *zvrf;
3157 vni_t vni;
3158 struct in_addr vtep_ip;
9f049418 3159 bool uj = use_json(argc, argv);
cec2e17d 3160
d62a17ae 3161 vni = strtoul(argv[4]->arg, NULL, 10);
3162 if (!inet_aton(argv[6]->arg, &vtep_ip)) {
cd233079
CS
3163 if (!uj)
3164 vty_out(vty, "%% Malformed VTEP IP address\n");
d62a17ae 3165 return CMD_WARNING;
3166 }
cec2e17d 3167
530db8dc 3168 zvrf = zebra_vrf_get_evpn();
cd233079 3169 zebra_vxlan_print_macs_vni_vtep(vty, zvrf, vni, vtep_ip, uj);
d62a17ae 3170 return CMD_SUCCESS;
cec2e17d 3171}
3172
1374d4db
CS
3173DEFPY (show_evpn_mac_vni_all_dad,
3174 show_evpn_mac_vni_all_dad_cmd,
3175 "show evpn mac vni all duplicate [json]",
3176 SHOW_STR
3177 "EVPN\n"
3178 "MAC addresses\n"
3179 "VxLAN Network Identifier\n"
3180 "All VNIs\n"
3181 "Duplicate address list\n"
3182 JSON_STR)
3183{
3184 struct zebra_vrf *zvrf;
3185 bool uj = use_json(argc, argv);
3186
530db8dc 3187 zvrf = zebra_vrf_get_evpn();
1374d4db
CS
3188 zebra_vxlan_print_macs_all_vni(vty, zvrf, true, uj);
3189 return CMD_SUCCESS;
3190}
3191
3192
3193DEFPY (show_evpn_mac_vni_dad,
3194 show_evpn_mac_vni_dad_cmd,
b41b3f7b 3195 "show evpn mac vni " CMD_VNI_RANGE " duplicate [json]",
1374d4db
CS
3196 SHOW_STR
3197 "EVPN\n"
3198 "MAC addresses\n"
3199 "VxLAN Network Identifier\n"
3200 "VNI number\n"
3201 "Duplicate address list\n"
3202 JSON_STR)
3203{
3204 struct zebra_vrf *zvrf;
1374d4db
CS
3205 bool uj = use_json(argc, argv);
3206
530db8dc 3207 zvrf = zebra_vrf_get_evpn();
1374d4db
CS
3208
3209 zebra_vxlan_print_macs_vni_dad(vty, zvrf, vni, uj);
3210
3211 return CMD_SUCCESS;
3212}
3213
3214DEFPY (show_evpn_neigh_vni_dad,
3215 show_evpn_neigh_vni_dad_cmd,
b41b3f7b 3216 "show evpn arp-cache vni " CMD_VNI_RANGE "duplicate [json]",
1374d4db
CS
3217 SHOW_STR
3218 "EVPN\n"
3219 "ARP and ND cache\n"
3220 "VxLAN Network Identifier\n"
3221 "VNI number\n"
3222 "Duplicate address list\n"
3223 JSON_STR)
3224{
3225 struct zebra_vrf *zvrf;
1374d4db
CS
3226 bool uj = use_json(argc, argv);
3227
530db8dc 3228 zvrf = zebra_vrf_get_evpn();
1374d4db
CS
3229 zebra_vxlan_print_neigh_vni_dad(vty, zvrf, vni, uj);
3230 return CMD_SUCCESS;
3231}
3232
3233DEFPY (show_evpn_neigh_vni_all_dad,
3234 show_evpn_neigh_vni_all_dad_cmd,
3235 "show evpn arp-cache vni all duplicate [json]",
3236 SHOW_STR
3237 "EVPN\n"
3238 "ARP and ND cache\n"
3239 "VxLAN Network Identifier\n"
3240 "All VNIs\n"
3241 "Duplicate address list\n"
3242 JSON_STR)
3243{
3244 struct zebra_vrf *zvrf;
3245 bool uj = use_json(argc, argv);
3246
530db8dc 3247 zvrf = zebra_vrf_get_evpn();
1374d4db
CS
3248 zebra_vxlan_print_neigh_all_vni(vty, zvrf, true, uj);
3249 return CMD_SUCCESS;
3250}
3251
3252
cec2e17d 3253DEFUN (show_evpn_neigh_vni,
3254 show_evpn_neigh_vni_cmd,
cd233079 3255 "show evpn arp-cache vni " CMD_VNI_RANGE "[json]",
cec2e17d 3256 SHOW_STR
3257 "EVPN\n"
3258 "ARP and ND cache\n"
3259 "VxLAN Network Identifier\n"
cd233079 3260 "VNI number\n"
bd592158 3261 JSON_STR)
cec2e17d 3262{
d62a17ae 3263 struct zebra_vrf *zvrf;
3264 vni_t vni;
9f049418 3265 bool uj = use_json(argc, argv);
cec2e17d 3266
d62a17ae 3267 vni = strtoul(argv[4]->arg, NULL, 10);
530db8dc 3268 zvrf = zebra_vrf_get_evpn();
cd233079 3269 zebra_vxlan_print_neigh_vni(vty, zvrf, vni, uj);
d62a17ae 3270 return CMD_SUCCESS;
cec2e17d 3271}
3272
3273DEFUN (show_evpn_neigh_vni_all,
3274 show_evpn_neigh_vni_all_cmd,
cd233079 3275 "show evpn arp-cache vni all [json]",
cec2e17d 3276 SHOW_STR
3277 "EVPN\n"
3278 "ARP and ND cache\n"
3279 "VxLAN Network Identifier\n"
cd233079 3280 "All VNIs\n"
bd592158 3281 JSON_STR)
cec2e17d 3282{
d62a17ae 3283 struct zebra_vrf *zvrf;
9f049418 3284 bool uj = use_json(argc, argv);
cec2e17d 3285
530db8dc 3286 zvrf = zebra_vrf_get_evpn();
1374d4db 3287 zebra_vxlan_print_neigh_all_vni(vty, zvrf, false, uj);
d62a17ae 3288 return CMD_SUCCESS;
cec2e17d 3289}
3290
e3fac919
NS
3291DEFUN (show_evpn_neigh_vni_all_detail, show_evpn_neigh_vni_all_detail_cmd,
3292 "show evpn arp-cache vni all detail [json]",
3293 SHOW_STR
3294 "EVPN\n"
3295 "ARP and ND cache\n"
3296 "VxLAN Network Identifier\n"
3297 "All VNIs\n"
3298 "Neighbor details for all vnis in detail\n" JSON_STR)
3299{
3300 struct zebra_vrf *zvrf;
3301 bool uj = use_json(argc, argv);
3302
530db8dc 3303 zvrf = zebra_vrf_get_evpn();
e3fac919
NS
3304 zebra_vxlan_print_neigh_all_vni_detail(vty, zvrf, false, uj);
3305 return CMD_SUCCESS;
3306}
3307
cec2e17d 3308DEFUN (show_evpn_neigh_vni_neigh,
3309 show_evpn_neigh_vni_neigh_cmd,
cd233079 3310 "show evpn arp-cache vni " CMD_VNI_RANGE " ip WORD [json]",
cec2e17d 3311 SHOW_STR
3312 "EVPN\n"
3313 "ARP and ND cache\n"
3314 "VxLAN Network Identifier\n"
3315 "VNI number\n"
3316 "Neighbor\n"
cd233079 3317 "Neighbor address (IPv4 or IPv6 address)\n"
bd592158 3318 JSON_STR)
cec2e17d 3319{
d62a17ae 3320 struct zebra_vrf *zvrf;
3321 vni_t vni;
3322 struct ipaddr ip;
9f049418 3323 bool uj = use_json(argc, argv);
cec2e17d 3324
d62a17ae 3325 vni = strtoul(argv[4]->arg, NULL, 10);
3326 if (str2ipaddr(argv[6]->arg, &ip) != 0) {
cd233079
CS
3327 if (!uj)
3328 vty_out(vty, "%% Malformed Neighbor address\n");
d62a17ae 3329 return CMD_WARNING;
3330 }
530db8dc 3331 zvrf = zebra_vrf_get_evpn();
cd233079 3332 zebra_vxlan_print_specific_neigh_vni(vty, zvrf, vni, &ip, uj);
d62a17ae 3333 return CMD_SUCCESS;
cec2e17d 3334}
3335
3336DEFUN (show_evpn_neigh_vni_vtep,
3337 show_evpn_neigh_vni_vtep_cmd,
cd233079 3338 "show evpn arp-cache vni " CMD_VNI_RANGE " vtep A.B.C.D [json]",
cec2e17d 3339 SHOW_STR
3340 "EVPN\n"
3341 "ARP and ND cache\n"
3342 "VxLAN Network Identifier\n"
3343 "VNI number\n"
3344 "Remote VTEP\n"
cd233079 3345 "Remote VTEP IP address\n"
bd592158 3346 JSON_STR)
cec2e17d 3347{
d62a17ae 3348 struct zebra_vrf *zvrf;
3349 vni_t vni;
3350 struct in_addr vtep_ip;
9f049418 3351 bool uj = use_json(argc, argv);
cec2e17d 3352
d62a17ae 3353 vni = strtoul(argv[4]->arg, NULL, 10);
3354 if (!inet_aton(argv[6]->arg, &vtep_ip)) {
cd233079
CS
3355 if (!uj)
3356 vty_out(vty, "%% Malformed VTEP IP address\n");
d62a17ae 3357 return CMD_WARNING;
3358 }
cec2e17d 3359
530db8dc 3360 zvrf = zebra_vrf_get_evpn();
cd233079 3361 zebra_vxlan_print_neigh_vni_vtep(vty, zvrf, vni, vtep_ip, uj);
d62a17ae 3362 return CMD_SUCCESS;
cec2e17d 3363}
3364
586f4ccf
PG
3365/* policy routing contexts */
3366DEFUN (show_pbr_ipset,
3367 show_pbr_ipset_cmd,
3368 "show pbr ipset [WORD]",
3369 SHOW_STR
3370 "Policy-Based Routing\n"
3371 "IPset Context information\n"
3372 "IPset Name information\n")
3373{
3374 int idx = 0;
3375 int found = 0;
3376 found = argv_find(argv, argc, "WORD", &idx);
3377 if (!found)
3378 zebra_pbr_show_ipset_list(vty, NULL);
3379 else
3380 zebra_pbr_show_ipset_list(vty, argv[idx]->arg);
3381 return CMD_SUCCESS;
3382}
3383
3384/* policy routing contexts */
3385DEFUN (show_pbr_iptable,
3386 show_pbr_iptable_cmd,
7929821a 3387 "show pbr iptable [WORD]",
586f4ccf
PG
3388 SHOW_STR
3389 "Policy-Based Routing\n"
7929821a
PG
3390 "IPtable Context information\n"
3391 "IPtable Name information\n")
586f4ccf 3392{
7929821a
PG
3393 int idx = 0;
3394 int found = 0;
3395
3396 found = argv_find(argv, argc, "WORD", &idx);
3397 if (!found)
3398 zebra_pbr_show_iptable(vty, NULL);
3399 else
3400 zebra_pbr_show_iptable(vty, argv[idx]->arg);
586f4ccf
PG
3401 return CMD_SUCCESS;
3402}
3403
09de9258
CS
3404DEFPY (clear_evpn_dup_addr,
3405 clear_evpn_dup_addr_cmd,
f65d330c 3406 "clear evpn dup-addr vni <all$vni_all |" CMD_VNI_RANGE"$vni [mac X:X:X:X:X:X | ip <A.B.C.D|X:X::X:X>]>",
09de9258
CS
3407 CLEAR_STR
3408 "EVPN\n"
3409 "Duplicate address \n"
3410 "VxLAN Network Identifier\n"
3411 "VNI number\n"
3412 "All VNIs\n"
3413 "MAC\n"
3414 "MAC address (e.g., 00:e0:ec:20:12:62)\n"
3415 "IP\n"
3416 "IPv4 address\n"
3417 "IPv6 address\n")
3418{
09de9258 3419 struct ipaddr host_ip = {.ipa_type = IPADDR_NONE };
1883de66 3420 int ret = CMD_SUCCESS;
d36228c9
CS
3421 struct list *input;
3422 struct yang_data *yang_dup = NULL, *yang_dup_ip = NULL,
3423 *yang_dup_mac = NULL;
09de9258 3424
d36228c9
CS
3425 input = list_new();
3426
3427 if (!vni_str) {
3428 yang_dup = yang_data_new(
3429 "/frr-zebra:clear-evpn-dup-addr/input/clear-dup-choice",
3430 "all-case");
3431 } else {
3432 yang_dup = yang_data_new_uint32(
3433 "/frr-zebra:clear-evpn-dup-addr/input/clear-dup-choice/single-case/vni-id",
3434 vni);
155b4398 3435 if (!is_zero_mac(&mac->eth_addr)) {
d36228c9
CS
3436 yang_dup_mac = yang_data_new_mac(
3437 "/frr-zebra:clear-evpn-dup-addr/input/clear-dup-choice/single-case/vni-id/mac-addr",
3438 &mac->eth_addr);
3439 if (yang_dup_mac)
3440 listnode_add(input, yang_dup_mac);
e20755b2 3441 } else if (ip) {
09de9258
CS
3442 if (sockunion_family(ip) == AF_INET) {
3443 host_ip.ipa_type = IPADDR_V4;
3444 host_ip.ipaddr_v4.s_addr = sockunion2ip(ip);
3445 } else {
3446 host_ip.ipa_type = IPADDR_V6;
3447 memcpy(&host_ip.ipaddr_v6, &ip->sin6.sin6_addr,
3448 sizeof(struct in6_addr));
3449 }
09de9258 3450
d36228c9
CS
3451 yang_dup_ip = yang_data_new_ip(
3452 "/frr-zebra:clear-evpn-dup-addr/input/clear-dup-choice/single-case/vni-id/vni-ipaddr",
3453 &host_ip);
3454
3455 if (yang_dup_ip)
3456 listnode_add(input, yang_dup_ip);
3457 }
09de9258
CS
3458 }
3459
d36228c9
CS
3460 if (yang_dup) {
3461 listnode_add(input, yang_dup);
f63f5f19
CS
3462 ret = nb_cli_rpc(vty, "/frr-zebra:clear-evpn-dup-addr", input,
3463 NULL);
d36228c9
CS
3464 }
3465
3466 list_delete(&input);
3467
1883de66 3468 return ret;
09de9258
CS
3469}
3470
718e3744 3471/* Static ip route configuration write function. */
d62a17ae 3472static int zebra_ip_config(struct vty *vty)
718e3744 3473{
d62a17ae 3474 int write = 0;
718e3744 3475
fe257ae7 3476 write += zebra_import_table_config(vty, VRF_DEFAULT);
37728041 3477
d62a17ae 3478 return write;
718e3744 3479}
3480
7a4bb9c5
DS
3481DEFUN (ip_zebra_import_table_distance,
3482 ip_zebra_import_table_distance_cmd,
12dcf78e 3483 "ip import-table (1-252) [distance (1-255)] [route-map WORD]",
8902474b
DS
3484 IP_STR
3485 "import routes from non-main kernel table\n"
3486 "kernel routing table id\n"
3487 "Distance for imported routes\n"
3488 "Default distance value\n"
3489 "route-map for filtering\n"
3490 "route-map name\n")
3491{
d7c0a89a 3492 uint32_t table_id = 0;
8902474b 3493
d62a17ae 3494 table_id = strtoul(argv[2]->arg, NULL, 10);
3495 int distance = ZEBRA_TABLE_DISTANCE_DEFAULT;
3496 char *rmap =
3497 strmatch(argv[argc - 2]->text, "route-map")
3498 ? XSTRDUP(MTYPE_ROUTE_MAP_NAME, argv[argc - 1]->arg)
3499 : NULL;
3500 int ret;
d722f26e 3501
d62a17ae 3502 if (argc == 7 || (argc == 5 && !rmap))
3503 distance = strtoul(argv[4]->arg, NULL, 10);
8902474b 3504
d62a17ae 3505 if (!is_zebra_valid_kernel_table(table_id)) {
3506 vty_out(vty,
3507 "Invalid routing table ID, %d. Must be in range 1-252\n",
3508 table_id);
0af35d90
RW
3509 if (rmap)
3510 XFREE(MTYPE_ROUTE_MAP_NAME, rmap);
d62a17ae 3511 return CMD_WARNING;
3512 }
8902474b 3513
d62a17ae 3514 if (is_zebra_main_routing_table(table_id)) {
3515 vty_out(vty,
3516 "Invalid routing table ID, %d. Must be non-default table\n",
3517 table_id);
0af35d90
RW
3518 if (rmap)
3519 XFREE(MTYPE_ROUTE_MAP_NAME, rmap);
d62a17ae 3520 return CMD_WARNING;
3521 }
8902474b 3522
fe257ae7
DS
3523 ret = zebra_import_table(AFI_IP, VRF_DEFAULT, table_id,
3524 distance, rmap, 1);
d62a17ae 3525 if (rmap)
3526 XFREE(MTYPE_ROUTE_MAP_NAME, rmap);
d722f26e 3527
d62a17ae 3528 return ret;
8902474b
DS
3529}
3530
62d52ded
DS
3531DEFUN_HIDDEN (zebra_packet_process,
3532 zebra_packet_process_cmd,
3533 "zebra zapi-packets (1-10000)",
3534 ZEBRA_STR
3535 "Zapi Protocol\n"
3536 "Number of packets to process before relinquishing thread\n")
3537{
3538 uint32_t packets = strtoul(argv[2]->arg, NULL, 10);
3539
5ec5a716 3540 atomic_store_explicit(&zrouter.packets_to_process, packets,
ccd51bd2 3541 memory_order_relaxed);
62d52ded
DS
3542
3543 return CMD_SUCCESS;
3544}
3545
3546DEFUN_HIDDEN (no_zebra_packet_process,
3547 no_zebra_packet_process_cmd,
3548 "no zebra zapi-packets [(1-10000)]",
3549 NO_STR
3550 ZEBRA_STR
3551 "Zapi Protocol\n"
3552 "Number of packets to process before relinquishing thread\n")
3553{
5ec5a716 3554 atomic_store_explicit(&zrouter.packets_to_process,
ccd51bd2
QY
3555 ZEBRA_ZAPI_PACKETS_TO_PROCESS,
3556 memory_order_relaxed);
62d52ded
DS
3557
3558 return CMD_SUCCESS;
3559}
3560
3a30f50f
DS
3561DEFUN_HIDDEN (zebra_workqueue_timer,
3562 zebra_workqueue_timer_cmd,
3563 "zebra work-queue (0-10000)",
3564 ZEBRA_STR
3565 "Work Queue\n"
3566 "Time in milliseconds\n")
3567{
996c9314 3568 uint32_t timer = strtoul(argv[2]->arg, NULL, 10);
489a9614 3569 zrouter.ribq->spec.hold = timer;
3a30f50f 3570
996c9314 3571 return CMD_SUCCESS;
3a30f50f
DS
3572}
3573
3574DEFUN_HIDDEN (no_zebra_workqueue_timer,
3575 no_zebra_workqueue_timer_cmd,
3576 "no zebra work-queue [(0-10000)]",
3577 NO_STR
3578 ZEBRA_STR
3579 "Work Queue\n"
3580 "Time in milliseconds\n")
3581{
489a9614 3582 zrouter.ribq->spec.hold = ZEBRA_RIB_PROCESS_HOLD_TIME;
3a30f50f 3583
996c9314 3584 return CMD_SUCCESS;
3a30f50f
DS
3585}
3586
7a4bb9c5
DS
3587DEFUN (no_ip_zebra_import_table,
3588 no_ip_zebra_import_table_cmd,
b62ecea5 3589 "no ip import-table (1-252) [distance (1-255)] [route-map NAME]",
7a4bb9c5
DS
3590 NO_STR
3591 IP_STR
3592 "import routes from non-main kernel table\n"
3a2d747c
QY
3593 "kernel routing table id\n"
3594 "Distance for imported routes\n"
3595 "Default distance value\n"
3596 "route-map for filtering\n"
3597 "route-map name\n")
7a4bb9c5 3598{
d7c0a89a 3599 uint32_t table_id = 0;
d62a17ae 3600 table_id = strtoul(argv[3]->arg, NULL, 10);
7a4bb9c5 3601
d62a17ae 3602 if (!is_zebra_valid_kernel_table(table_id)) {
3603 vty_out(vty,
3604 "Invalid routing table ID. Must be in range 1-252\n");
3605 return CMD_WARNING;
3606 }
7a4bb9c5 3607
d62a17ae 3608 if (is_zebra_main_routing_table(table_id)) {
3609 vty_out(vty,
3610 "Invalid routing table ID, %d. Must be non-default table\n",
3611 table_id);
3612 return CMD_WARNING;
3613 }
7a4bb9c5 3614
fe257ae7 3615 if (!is_zebra_import_table_enabled(AFI_IP, VRF_DEFAULT, table_id))
d62a17ae 3616 return CMD_SUCCESS;
7a4bb9c5 3617
fe257ae7 3618 return (zebra_import_table(AFI_IP, VRF_DEFAULT, table_id, 0, NULL, 0));
7a4bb9c5
DS
3619}
3620
d62a17ae 3621static int config_write_protocol(struct vty *vty)
6baf7bb8 3622{
d62a17ae 3623 if (allow_delete)
3624 vty_out(vty, "allow-external-route-update\n");
6baf7bb8 3625
489a9614
DS
3626 if (zrouter.ribq->spec.hold != ZEBRA_RIB_PROCESS_HOLD_TIME)
3627 vty_out(vty, "zebra work-queue %u\n", zrouter.ribq->spec.hold);
3a30f50f 3628
5ec5a716 3629 if (zrouter.packets_to_process != ZEBRA_ZAPI_PACKETS_TO_PROCESS)
996c9314 3630 vty_out(vty, "zebra zapi-packets %u\n",
5ec5a716 3631 zrouter.packets_to_process);
62d52ded 3632
d62a17ae 3633 enum multicast_mode ipv4_multicast_mode = multicast_mode_ipv4_get();
4623d897 3634
d62a17ae 3635 if (ipv4_multicast_mode != MCAST_NO_CONFIG)
3636 vty_out(vty, "ip multicast rpf-lookup-mode %s\n",
3637 ipv4_multicast_mode == MCAST_URIB_ONLY
3638 ? "urib-only"
3639 : ipv4_multicast_mode == MCAST_MRIB_ONLY
3640 ? "mrib-only"
3641 : ipv4_multicast_mode
3642 == MCAST_MIX_MRIB_FIRST
3643 ? "mrib-then-urib"
3644 : ipv4_multicast_mode
3645 == MCAST_MIX_DISTANCE
3646 ? "lower-distance"
3647 : "longer-prefix");
f26730e1
MS
3648
3649 /* Include dataplane info */
3650 dplane_config_write_helper(vty);
3651
41c809b2
AK
3652 zebra_evpn_mh_config_write(vty);
3653
7c99d51b
MS
3654 /* Include nexthop-group config */
3655 if (!zebra_nhg_kernel_nexthops_enabled())
3656 vty_out(vty, "no zebra nexthop kernel enable\n");
3657
6c67f41f
SW
3658 if (zebra_nhg_proto_nexthops_only())
3659 vty_out(vty, "zebra nexthop proto only\n");
3660
aa458838
MS
3661 if (!zebra_nhg_recursive_use_backups())
3662 vty_out(vty, "no zebra nexthop resolve-via-backup\n");
3663
531c92b8
JU
3664#ifdef HAVE_NETLINK
3665 /* Include netlink info */
3666 netlink_config_write_helper(vty);
3667#endif /* HAVE_NETLINK */
3668
d62a17ae 3669 return 1;
6baf7bb8
DS
3670}
3671
c0d136ae
DS
3672DEFUN (show_zebra,
3673 show_zebra_cmd,
3674 "show zebra",
3675 SHOW_STR
3676 ZEBRA_STR)
3677{
3678 struct vrf *vrf;
3679
4c56ce1c
DS
3680 if (zrouter.asic_offloaded)
3681 vty_out(vty, "Asic Offload is being used\n");
3682
c0d136ae
DS
3683 vty_out(vty,
3684 " Route Route Neighbor LSP LSP\n");
3685 vty_out(vty,
3686 "VRF Installs Removals Updates Installs Removals\n");
3687
996c9314 3688 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
c0d136ae
DS
3689 struct zebra_vrf *zvrf = vrf->info;
3690
6cde4b45 3691 vty_out(vty, "%-25s %10" PRIu64 " %10" PRIu64 " %10" PRIu64" %10" PRIu64 " %10" PRIu64 "\n",
c0d136ae
DS
3692 vrf->name, zvrf->installs, zvrf->removals,
3693 zvrf->neigh_updates, zvrf->lsp_installs,
3694 zvrf->lsp_removals);
3695 }
3696
3697 return CMD_SUCCESS;
3698}
3699
3700DEFUN (ip_forwarding,
3701 ip_forwarding_cmd,
3702 "ip forwarding",
3703 IP_STR
3704 "Turn on IP forwarding\n")
3705{
3706 int ret;
3707
3708 ret = ipforward();
3709 if (ret == 0)
3710 ret = ipforward_on();
3711
3712 if (ret == 0) {
3713 vty_out(vty, "Can't turn on IP forwarding\n");
3714 return CMD_WARNING_CONFIG_FAILED;
3715 }
3716
3717 return CMD_SUCCESS;
3718}
3719
3720DEFUN (no_ip_forwarding,
3721 no_ip_forwarding_cmd,
3722 "no ip forwarding",
3723 NO_STR
3724 IP_STR
3725 "Turn off IP forwarding\n")
3726{
3727 int ret;
3728
3729 ret = ipforward();
3730 if (ret != 0)
3731 ret = ipforward_off();
3732
3733 if (ret != 0) {
3734 vty_out(vty, "Can't turn off IP forwarding\n");
3735 return CMD_WARNING_CONFIG_FAILED;
3736 }
3737
3738 return CMD_SUCCESS;
3739}
3740
3741/* Only display ip forwarding is enabled or not. */
3742DEFUN (show_ip_forwarding,
3743 show_ip_forwarding_cmd,
3744 "show ip forwarding",
3745 SHOW_STR
3746 IP_STR
3747 "IP forwarding status\n")
3748{
3749 int ret;
3750
3751 ret = ipforward();
3752
3753 if (ret == 0)
3754 vty_out(vty, "IP forwarding is off\n");
3755 else
3756 vty_out(vty, "IP forwarding is on\n");
3757 return CMD_SUCCESS;
3758}
3759
3760/* Only display ipv6 forwarding is enabled or not. */
3761DEFUN (show_ipv6_forwarding,
3762 show_ipv6_forwarding_cmd,
3763 "show ipv6 forwarding",
3764 SHOW_STR
3765 "IPv6 information\n"
3766 "Forwarding status\n")
3767{
3768 int ret;
3769
3770 ret = ipforward_ipv6();
3771
3772 switch (ret) {
3773 case -1:
3774 vty_out(vty, "ipv6 forwarding is unknown\n");
3775 break;
3776 case 0:
3777 vty_out(vty, "ipv6 forwarding is %s\n", "off");
3778 break;
3779 case 1:
3780 vty_out(vty, "ipv6 forwarding is %s\n", "on");
3781 break;
3782 default:
3783 vty_out(vty, "ipv6 forwarding is %s\n", "off");
3784 break;
3785 }
3786 return CMD_SUCCESS;
3787}
3788
3789DEFUN (ipv6_forwarding,
3790 ipv6_forwarding_cmd,
3791 "ipv6 forwarding",
3792 IPV6_STR
3793 "Turn on IPv6 forwarding\n")
3794{
3795 int ret;
3796
3797 ret = ipforward_ipv6();
3798 if (ret == 0)
3799 ret = ipforward_ipv6_on();
3800
3801 if (ret == 0) {
3802 vty_out(vty, "Can't turn on IPv6 forwarding\n");
3803 return CMD_WARNING_CONFIG_FAILED;
3804 }
3805
3806 return CMD_SUCCESS;
3807}
3808
3809DEFUN (no_ipv6_forwarding,
3810 no_ipv6_forwarding_cmd,
3811 "no ipv6 forwarding",
3812 NO_STR
3813 IPV6_STR
3814 "Turn off IPv6 forwarding\n")
3815{
3816 int ret;
3817
3818 ret = ipforward_ipv6();
3819 if (ret != 0)
3820 ret = ipforward_ipv6_off();
3821
3822 if (ret != 0) {
3823 vty_out(vty, "Can't turn off IPv6 forwarding\n");
3824 return CMD_WARNING_CONFIG_FAILED;
3825 }
3826
3827 return CMD_SUCCESS;
3828}
3829
1d11b21f
MS
3830/* Display dataplane info */
3831DEFUN (show_dataplane,
3832 show_dataplane_cmd,
3833 "show zebra dplane [detailed]",
3834 SHOW_STR
3835 ZEBRA_STR
3836 "Zebra dataplane information\n"
3837 "Detailed output\n")
3838{
3839 int idx = 0;
3840 bool detailed = false;
3841
3842 if (argv_find(argv, argc, "detailed", &idx))
3843 detailed = true;
3844
3845 return dplane_show_helper(vty, detailed);
3846}
3847
3848/* Display dataplane providers info */
3849DEFUN (show_dataplane_providers,
3850 show_dataplane_providers_cmd,
3851 "show zebra dplane providers [detailed]",
3852 SHOW_STR
3853 ZEBRA_STR
3854 "Zebra dataplane information\n"
3855 "Zebra dataplane provider information\n"
3856 "Detailed output\n")
3857{
3858 int idx = 0;
3859 bool detailed = false;
3860
3861 if (argv_find(argv, argc, "detailed", &idx))
3862 detailed = true;
3863
3864 return dplane_show_provs_helper(vty, detailed);
3865}
3866
91f16812
MS
3867/* Configure dataplane incoming queue limit */
3868DEFUN (zebra_dplane_queue_limit,
3869 zebra_dplane_queue_limit_cmd,
3870 "zebra dplane limit (0-10000)",
3871 ZEBRA_STR
3872 "Zebra dataplane\n"
3873 "Limit incoming queued updates\n"
3874 "Number of queued updates\n")
3875{
3876 uint32_t limit = 0;
3877
3878 limit = strtoul(argv[3]->arg, NULL, 10);
3879
3880 dplane_set_in_queue_limit(limit, true);
3881
3882 return CMD_SUCCESS;
3883}
3884
3885/* Reset dataplane queue limit to default value */
3886DEFUN (no_zebra_dplane_queue_limit,
3887 no_zebra_dplane_queue_limit_cmd,
3888 "no zebra dplane limit [(0-10000)]",
3889 NO_STR
3890 ZEBRA_STR
3891 "Zebra dataplane\n"
3892 "Limit incoming queued updates\n"
3893 "Number of queued updates\n")
3894{
3895 dplane_set_in_queue_limit(0, false);
3896
3897 return CMD_SUCCESS;
3898}
1d11b21f 3899
ac5aa23f
DS
3900DEFUN (zebra_show_routing_tables_summary,
3901 zebra_show_routing_tables_summary_cmd,
3902 "show zebra router table summary",
3903 SHOW_STR
3904 ZEBRA_STR
3905 "The Zebra Router Information\n"
3906 "Table Information about this Zebra Router\n"
3907 "Summary Information\n")
3908{
3909 zebra_router_show_table_summary(vty);
3910
3911 return CMD_SUCCESS;
3912}
3913
c0d136ae
DS
3914/* Table configuration write function. */
3915static int config_write_table(struct vty *vty)
3916{
c0d136ae
DS
3917 return 0;
3918}
3919
3920/* IPForwarding configuration write function. */
3921static int config_write_forwarding(struct vty *vty)
3922{
c0d136ae
DS
3923 if (!ipforward())
3924 vty_out(vty, "no ip forwarding\n");
3925 if (!ipforward_ipv6())
3926 vty_out(vty, "no ipv6 forwarding\n");
3927 vty_out(vty, "!\n");
3928 return 0;
3929}
3930
d2f5903b
DS
3931DEFUN_HIDDEN (show_frr,
3932 show_frr_cmd,
3933 "show frr",
3934 SHOW_STR
3935 "FRR\n")
3936{
3937 vty_out(vty, "........ .. . .. . ..... ...77:................................................\n");
3938 vty_out(vty, ".............................7777:..............................................\n");
3939 vty_out(vty, ".............................777777,............................................\n");
3940 vty_out(vty, "... .........................77777777,..........................................\n");
3941 vty_out(vty, "............................=7777777777:........................................\n");
3942 vty_out(vty, "........................:7777777777777777,......................................\n");
3943 vty_out(vty, ".................... ~7777777777777?~,..........................................\n");
3944 vty_out(vty, "...................I7777777777+.................................................\n");
3945 vty_out(vty, "................,777777777?............ .......................................\n");
3946 vty_out(vty, "..............:77777777?..........~?77777.......................................\n");
3947 vty_out(vty, ".............77777777~........=7777777777.......................................\n");
3948 vty_out(vty, ".......... +7777777,.......?7777777777777.......................................\n");
3949 vty_out(vty, "..........7777777~......:7777777777777777......77?,.............................\n");
3950 vty_out(vty, "........:777777?......+777777777777777777......777777I,.........................\n");
3951 vty_out(vty, ".......?777777,.....+77777777777777777777......777777777?.......................\n");
3952 vty_out(vty, "......?777777......7777777777777777777777......,?777777777?.....................\n");
3953 vty_out(vty, ".....?77777?.....=7777777777777777777I~............,I7777777~...................\n");
3954 vty_out(vty, "....+77777+.....I77777777777777777:...................+777777I..................\n");
3955 vty_out(vty, "...~77777+.....7777777777777777=........................?777777...... .......\n");
3956 vty_out(vty, "...77777I.....I77777777777777~.........:?................,777777.....I777.......\n");
3957 vty_out(vty, "..777777.....I7777777777777I .......?7777..................777777.....777?......\n");
3958 vty_out(vty, ".~77777,....=7777777777777:......,7777777..................,77777+....+777......\n");
3959 vty_out(vty, ".77777I.....7777777777777,......777777777.......ONNNN.......=77777.....777~.....\n");
3960 vty_out(vty, ",77777.....I777777777777,.....:7777777777......DNNNNNN.......77777+ ...7777.....\n");
3961 vty_out(vty, "I7777I.....777777777777=.....~77777777777......NNNNNNN~......=7777I....=777.....\n");
3962 vty_out(vty, "77777:....=777777777777.....,777777777777......$NNNNND ......:77777....:777.....\n");
3963 vty_out(vty, "77777. ...777777777777~.....7777777777777........7DZ,........:77777.....777.....\n");
3964 vty_out(vty, "????? . ..777777777777.....,7777777777777....................:77777I....777.....\n");
3965 vty_out(vty, "....... ..777777777777.....+7777777777777....................=7777777+...?7.....\n");
3966 vty_out(vty, "..........77777777777I.....I7777777777777....................7777777777:........\n");
3967 vty_out(vty, "..........77777777777I.....?7777777777777...................~777777777777.......\n");
3968 vty_out(vty, "..........777777777777.....~7777777777777..................,77777777777777+.....\n");
3969 vty_out(vty, "..........777777777777......7777777777777..................77777777777777777,...\n");
3970 vty_out(vty, "..... ....?77777777777I.....~777777777777................,777777.....,:+77777I..\n");
3971 vty_out(vty, "........ .:777777777777,.....?77777777777...............?777777..............,:=\n");
3972 vty_out(vty, ".......... 7777777777777..... ?7777777777.............=7777777.....~777I........\n");
3973 vty_out(vty, "...........:777777777777I......~777777777...........I7777777~.....+777I.........\n");
3974 vty_out(vty, "..... ......7777777777777I.......I7777777.......+777777777I......7777I..........\n");
3975 vty_out(vty, ".............77777777777777........?77777......777777777?......=7777=...........\n");
3976 vty_out(vty, ".............,77777777777777+.........~77......777777I,......:77777.............\n");
3977 vty_out(vty, "..............~777777777777777~................777777......:77777=..............\n");
3978 vty_out(vty, "...............:7777777777777777?..............:777777,.....=77=................\n");
3979 vty_out(vty, "................,777777777777777777?,...........,777777:.....,..................\n");
3980 vty_out(vty, "........... ......I777777777777777777777I.........777777~.......................\n");
3981 vty_out(vty, "...................,777777777777777777777..........777777+......................\n");
3982 vty_out(vty, ".....................+7777777777777777777...........777777?.....................\n");
3983 vty_out(vty, ".......................=77777777777777777............777777I....................\n");
3984 vty_out(vty, ".........................:777777777777777.............I77777I...................\n");
3985 vty_out(vty, "............................~777777777777..............+777777..................\n");
3986 vty_out(vty, "................................~77777777...............=777777.................\n");
3987 vty_out(vty, ".....................................:=?I................~777777................\n");
3988 vty_out(vty, "..........................................................:777777,..............\n");
3989 vty_out(vty, ".... ... ... . . .... ....... ....... ....................:777777..............\n");
3990
3991 return CMD_SUCCESS;
3992}
3993
531c92b8
JU
3994#ifdef HAVE_NETLINK
3995DEFUN_HIDDEN(zebra_kernel_netlink_batch_tx_buf,
3996 zebra_kernel_netlink_batch_tx_buf_cmd,
3997 "zebra kernel netlink batch-tx-buf (1-1048576) (1-1048576)",
3998 ZEBRA_STR
3999 "Zebra kernel interface\n"
4000 "Set Netlink parameters\n"
4001 "Set batch buffer size and send threshold\n"
4002 "Size of the buffer\n"
4003 "Send threshold\n")
4004{
4005 uint32_t bufsize = 0, threshold = 0;
4006
4007 bufsize = strtoul(argv[4]->arg, NULL, 10);
4008 threshold = strtoul(argv[5]->arg, NULL, 10);
4009
4010 netlink_set_batch_buffer_size(bufsize, threshold, true);
4011
4012 return CMD_SUCCESS;
4013}
4014
4015DEFUN_HIDDEN(no_zebra_kernel_netlink_batch_tx_buf,
4016 no_zebra_kernel_netlink_batch_tx_buf_cmd,
4017 "no zebra kernel netlink batch-tx-buf [(0-1048576)] [(0-1048576)]",
4018 NO_STR ZEBRA_STR
4019 "Zebra kernel interface\n"
4020 "Set Netlink parameters\n"
4021 "Set batch buffer size and send threshold\n"
4022 "Size of the buffer\n"
4023 "Send threshold\n")
4024{
4025 netlink_set_batch_buffer_size(0, 0, false);
4026
4027 return CMD_SUCCESS;
4028}
4029
4030#endif /* HAVE_NETLINK */
4031
718e3744 4032/* IP node for static routes. */
612c2c15 4033static int zebra_ip_config(struct vty *vty);
62b346ee 4034static struct cmd_node ip_node = {
f4b8291f 4035 .name = "static ip",
62b346ee
DL
4036 .node = IP_NODE,
4037 .prompt = "",
612c2c15 4038 .config_write = zebra_ip_config,
62b346ee 4039};
612c2c15 4040static int config_write_protocol(struct vty *vty);
62b346ee 4041static struct cmd_node protocol_node = {
f4b8291f 4042 .name = "protocol",
62b346ee
DL
4043 .node = PROTOCOL_NODE,
4044 .prompt = "",
612c2c15 4045 .config_write = config_write_protocol,
62b346ee 4046};
c0d136ae 4047/* table node for routing tables. */
612c2c15 4048static int config_write_table(struct vty *vty);
62b346ee 4049static struct cmd_node table_node = {
f4b8291f 4050 .name = "table",
62b346ee
DL
4051 .node = TABLE_NODE,
4052 .prompt = "",
612c2c15 4053 .config_write = config_write_table,
62b346ee 4054};
612c2c15 4055static int config_write_forwarding(struct vty *vty);
62b346ee 4056static struct cmd_node forwarding_node = {
f4b8291f 4057 .name = "forwarding",
62b346ee
DL
4058 .node = FORWARDING_NODE,
4059 .prompt = "",
612c2c15 4060 .config_write = config_write_forwarding,
62b346ee 4061};
718e3744 4062
4063/* Route VTY. */
d62a17ae 4064void zebra_vty_init(void)
4065{
c0d136ae 4066 /* Install configuration write function. */
612c2c15
DL
4067 install_node(&table_node);
4068 install_node(&forwarding_node);
c0d136ae
DS
4069
4070 install_element(VIEW_NODE, &show_ip_forwarding_cmd);
4071 install_element(CONFIG_NODE, &ip_forwarding_cmd);
4072 install_element(CONFIG_NODE, &no_ip_forwarding_cmd);
4073 install_element(ENABLE_NODE, &show_zebra_cmd);
4074
c0d136ae
DS
4075 install_element(VIEW_NODE, &show_ipv6_forwarding_cmd);
4076 install_element(CONFIG_NODE, &ipv6_forwarding_cmd);
4077 install_element(CONFIG_NODE, &no_ipv6_forwarding_cmd);
4078
4079 /* Route-map */
4080 zebra_route_map_init();
4081
612c2c15
DL
4082 install_node(&ip_node);
4083 install_node(&protocol_node);
d62a17ae 4084
4085 install_element(CONFIG_NODE, &allow_external_route_update_cmd);
4086 install_element(CONFIG_NODE, &no_allow_external_route_update_cmd);
7e24fdf3 4087
d62a17ae 4088 install_element(CONFIG_NODE, &ip_multicast_mode_cmd);
4089 install_element(CONFIG_NODE, &no_ip_multicast_mode_cmd);
b3b08602 4090
d62a17ae 4091 install_element(CONFIG_NODE, &ip_zebra_import_table_distance_cmd);
4092 install_element(CONFIG_NODE, &no_ip_zebra_import_table_cmd);
3a30f50f
DS
4093 install_element(CONFIG_NODE, &zebra_workqueue_timer_cmd);
4094 install_element(CONFIG_NODE, &no_zebra_workqueue_timer_cmd);
62d52ded
DS
4095 install_element(CONFIG_NODE, &zebra_packet_process_cmd);
4096 install_element(CONFIG_NODE, &no_zebra_packet_process_cmd);
7c99d51b 4097 install_element(CONFIG_NODE, &nexthop_group_use_enable_cmd);
6c67f41f 4098 install_element(CONFIG_NODE, &proto_nexthop_group_only_cmd);
aa458838 4099 install_element(CONFIG_NODE, &backup_nexthop_recursive_use_enable_cmd);
d62a17ae 4100
21be1364 4101 install_element(VIEW_NODE, &show_nexthop_group_cmd);
1e9aad82 4102 install_element(VIEW_NODE, &show_interface_nexthop_group_cmd);
21be1364 4103
d62a17ae 4104 install_element(VIEW_NODE, &show_vrf_cmd);
b7cfce93 4105 install_element(VIEW_NODE, &show_vrf_vni_cmd);
ecffa493 4106 install_element(VIEW_NODE, &show_route_cmd);
dc1c4362 4107 install_element(VIEW_NODE, &show_ro_cmd);
5ce91022
RW
4108 install_element(VIEW_NODE, &show_route_detail_cmd);
4109 install_element(VIEW_NODE, &show_route_summary_cmd);
d62a17ae 4110 install_element(VIEW_NODE, &show_ip_nht_cmd);
d62a17ae 4111
4112 install_element(VIEW_NODE, &show_ip_rpf_cmd);
4113 install_element(VIEW_NODE, &show_ip_rpf_addr_cmd);
4114
d62a17ae 4115 install_element(CONFIG_NODE, &ip_nht_default_route_cmd);
4116 install_element(CONFIG_NODE, &no_ip_nht_default_route_cmd);
4117 install_element(CONFIG_NODE, &ipv6_nht_default_route_cmd);
4118 install_element(CONFIG_NODE, &no_ipv6_nht_default_route_cmd);
214e5c26 4119 install_element(VRF_NODE, &ip_nht_default_route_cmd);
4120 install_element(VRF_NODE, &no_ip_nht_default_route_cmd);
4121 install_element(VRF_NODE, &ipv6_nht_default_route_cmd);
4122 install_element(VRF_NODE, &no_ipv6_nht_default_route_cmd);
d62a17ae 4123 install_element(VIEW_NODE, &show_ipv6_mroute_cmd);
4124
4125 /* Commands for VRF */
d62a17ae 4126 install_element(VIEW_NODE, &show_ipv6_mroute_vrf_all_cmd);
4127
d2f5903b 4128 install_element(VIEW_NODE, &show_frr_cmd);
4cce389e 4129 install_element(VIEW_NODE, &show_evpn_global_cmd);
d62a17ae 4130 install_element(VIEW_NODE, &show_evpn_vni_cmd);
09af6961 4131 install_element(VIEW_NODE, &show_evpn_vni_detail_cmd);
d62a17ae 4132 install_element(VIEW_NODE, &show_evpn_vni_vni_cmd);
5de10c37 4133 install_element(VIEW_NODE, &show_evpn_l2_nh_cmd);
374b316c
AK
4134 install_element(VIEW_NODE, &show_evpn_es_cmd);
4135 install_element(VIEW_NODE, &show_evpn_es_evi_cmd);
4136 install_element(VIEW_NODE, &show_evpn_access_vlan_cmd);
4cce389e
MK
4137 install_element(VIEW_NODE, &show_evpn_rmac_vni_mac_cmd);
4138 install_element(VIEW_NODE, &show_evpn_rmac_vni_cmd);
4139 install_element(VIEW_NODE, &show_evpn_rmac_vni_all_cmd);
4140 install_element(VIEW_NODE, &show_evpn_nh_vni_ip_cmd);
4141 install_element(VIEW_NODE, &show_evpn_nh_vni_cmd);
4142 install_element(VIEW_NODE, &show_evpn_nh_vni_all_cmd);
d62a17ae 4143 install_element(VIEW_NODE, &show_evpn_mac_vni_cmd);
4144 install_element(VIEW_NODE, &show_evpn_mac_vni_all_cmd);
cffe7580 4145 install_element(VIEW_NODE, &show_evpn_mac_vni_all_detail_cmd);
d62a17ae 4146 install_element(VIEW_NODE, &show_evpn_mac_vni_all_vtep_cmd);
4147 install_element(VIEW_NODE, &show_evpn_mac_vni_mac_cmd);
4148 install_element(VIEW_NODE, &show_evpn_mac_vni_vtep_cmd);
1374d4db
CS
4149 install_element(VIEW_NODE, &show_evpn_mac_vni_dad_cmd);
4150 install_element(VIEW_NODE, &show_evpn_mac_vni_all_dad_cmd);
d62a17ae 4151 install_element(VIEW_NODE, &show_evpn_neigh_vni_cmd);
4152 install_element(VIEW_NODE, &show_evpn_neigh_vni_all_cmd);
e3fac919 4153 install_element(VIEW_NODE, &show_evpn_neigh_vni_all_detail_cmd);
d62a17ae 4154 install_element(VIEW_NODE, &show_evpn_neigh_vni_neigh_cmd);
4155 install_element(VIEW_NODE, &show_evpn_neigh_vni_vtep_cmd);
1374d4db
CS
4156 install_element(VIEW_NODE, &show_evpn_neigh_vni_dad_cmd);
4157 install_element(VIEW_NODE, &show_evpn_neigh_vni_all_dad_cmd);
09de9258 4158 install_element(ENABLE_NODE, &clear_evpn_dup_addr_cmd);
b7cfce93 4159
586f4ccf
PG
4160 install_element(VIEW_NODE, &show_pbr_ipset_cmd);
4161 install_element(VIEW_NODE, &show_pbr_iptable_cmd);
4162
41c809b2
AK
4163 install_element(CONFIG_NODE, &evpn_mh_mac_holdtime_cmd);
4164 install_element(CONFIG_NODE, &evpn_mh_neigh_holdtime_cmd);
c36e442c 4165 install_element(CONFIG_NODE, &evpn_mh_startup_delay_cmd);
15400f95 4166 install_element(CONFIG_NODE, &evpn_mh_redirect_off_cmd);
e8d26197
MK
4167 install_element(CONFIG_NODE, &default_vrf_vni_mapping_cmd);
4168 install_element(CONFIG_NODE, &no_default_vrf_vni_mapping_cmd);
b7cfce93
MK
4169 install_element(VRF_NODE, &vrf_vni_mapping_cmd);
4170 install_element(VRF_NODE, &no_vrf_vni_mapping_cmd);
4060008b 4171
1d11b21f
MS
4172 install_element(VIEW_NODE, &show_dataplane_cmd);
4173 install_element(VIEW_NODE, &show_dataplane_providers_cmd);
91f16812
MS
4174 install_element(CONFIG_NODE, &zebra_dplane_queue_limit_cmd);
4175 install_element(CONFIG_NODE, &no_zebra_dplane_queue_limit_cmd);
ac5aa23f 4176
531c92b8
JU
4177#ifdef HAVE_NETLINK
4178 install_element(CONFIG_NODE, &zebra_kernel_netlink_batch_tx_buf_cmd);
4179 install_element(CONFIG_NODE, &no_zebra_kernel_netlink_batch_tx_buf_cmd);
4180#endif /* HAVE_NETLINK */
4181
ac5aa23f 4182 install_element(VIEW_NODE, &zebra_show_routing_tables_summary_cmd);
718e3744 4183}