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