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