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