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