]> git.proxmox.com Git - mirror_frr.git/blame - zebra/zebra_vty.c
Merge pull request #5789 from donaldsharp/bgp_ebgp_reason
[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)
b5e02d19
MS
1126 vty_out(vty, " VRF: %s AFI: %s\n", nhe_vrf->name,
1127 afi2str(nhe->afi));
df9069cd 1128 else
b5e02d19
MS
1129 vty_out(vty, " VRF: UNKNOWN AFI: %s\n",
1130 afi2str(nhe->afi));
df9069cd 1131
c1da832a 1132 if (CHECK_FLAG(nhe->flags, NEXTHOP_GROUP_UNHASHABLE))
df9069cd 1133 vty_out(vty, " Duplicate - from kernel not hashable\n");
fec211ad 1134
1e9aad82 1135 if (CHECK_FLAG(nhe->flags, NEXTHOP_GROUP_VALID)) {
df9069cd 1136 vty_out(vty, " Valid");
1e9aad82
SW
1137 if (CHECK_FLAG(nhe->flags, NEXTHOP_GROUP_INSTALLED))
1138 vty_out(vty, ", Installed");
1139 vty_out(vty, "\n");
1140 }
1141 if (nhe->ifp)
df9069cd 1142 vty_out(vty, " Interface Index: %d\n", nhe->ifp->ifindex);
1e9aad82
SW
1143
1144 if (!zebra_nhg_depends_is_empty(nhe)) {
df9069cd 1145 vty_out(vty, " Depends:");
fec211ad 1146 frr_each(nhg_connected_tree, &nhe->nhg_depends, rb_node_dep) {
1e9aad82
SW
1147 vty_out(vty, " (%u)", rb_node_dep->nhe->id);
1148 }
1149 vty_out(vty, "\n");
1150 }
df9069cd
SW
1151
1152 for (ALL_NEXTHOPS_PTR(nhe->nhg, nexthop)) {
1153 if (!CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
1154 vty_out(vty, " ");
1155 else
1156 /* Make recursive nexthops a bit more clear */
1157 vty_out(vty, " ");
1158
1159 switch (nexthop->type) {
1160 case NEXTHOP_TYPE_IPV4:
1161 case NEXTHOP_TYPE_IPV4_IFINDEX:
1162 vty_out(vty, " %s", inet_ntoa(nexthop->gate.ipv4));
1163 if (nexthop->ifindex)
1164 vty_out(vty, ", %s",
1165 ifindex2ifname(nexthop->ifindex,
1166 nexthop->vrf_id));
1167 break;
1168 case NEXTHOP_TYPE_IPV6:
1169 case NEXTHOP_TYPE_IPV6_IFINDEX:
1170 vty_out(vty, " %s",
1171 inet_ntop(AF_INET6, &nexthop->gate.ipv6, buf,
fec211ad 1172 sizeof(buf)));
df9069cd
SW
1173 if (nexthop->ifindex)
1174 vty_out(vty, ", %s",
1175 ifindex2ifname(nexthop->ifindex,
1176 nexthop->vrf_id));
1177 break;
1178
1179 case NEXTHOP_TYPE_IFINDEX:
1180 vty_out(vty, " directly connected %s",
1181 ifindex2ifname(nexthop->ifindex,
1182 nexthop->vrf_id));
1183 break;
1184 case NEXTHOP_TYPE_BLACKHOLE:
1185 vty_out(vty, " unreachable");
1186 switch (nexthop->bh_type) {
1187 case BLACKHOLE_REJECT:
1188 vty_out(vty, " (ICMP unreachable)");
1189 break;
1190 case BLACKHOLE_ADMINPROHIB:
1191 vty_out(vty, " (ICMP admin-prohibited)");
1192 break;
1193 case BLACKHOLE_NULL:
1194 vty_out(vty, " (blackhole)");
1195 break;
1196 case BLACKHOLE_UNSPEC:
1197 break;
1198 }
1199 break;
1200 default:
1201 break;
1202 }
1203
1204 struct vrf *vrf = vrf_lookup_by_id(nexthop->vrf_id);
1205
1206 if (vrf)
1207 vty_out(vty, " (vrf %s)", vrf->name);
1208 else
1209 vty_out(vty, " (vrf UNKNOWN)");
1210
1211 if (!CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE))
1212 vty_out(vty, " inactive");
1213
1214 if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ONLINK))
1215 vty_out(vty, " onlink");
1216
1217 if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
1218 vty_out(vty, " (recursive)");
1219
1220 switch (nexthop->type) {
1221 case NEXTHOP_TYPE_IPV4:
1222 case NEXTHOP_TYPE_IPV4_IFINDEX:
1223 if (nexthop->src.ipv4.s_addr) {
1224 if (inet_ntop(AF_INET, &nexthop->src.ipv4, buf,
fec211ad 1225 sizeof(buf)))
df9069cd
SW
1226 vty_out(vty, ", src %s", buf);
1227 }
1228 break;
1229 case NEXTHOP_TYPE_IPV6:
1230 case NEXTHOP_TYPE_IPV6_IFINDEX:
1231 if (!IPV6_ADDR_SAME(&nexthop->src.ipv6, &in6addr_any)) {
1232 if (inet_ntop(AF_INET6, &nexthop->src.ipv6, buf,
fec211ad 1233 sizeof(buf)))
df9069cd
SW
1234 vty_out(vty, ", src %s", buf);
1235 }
1236 break;
1237 default:
1238 break;
1239 }
1240
1241 /* Label information */
1242 if (nexthop->nh_label && nexthop->nh_label->num_labels) {
1243 vty_out(vty, ", label %s",
1244 mpls_label2str(nexthop->nh_label->num_labels,
1245 nexthop->nh_label->label, buf,
fec211ad 1246 sizeof(buf), 1));
df9069cd
SW
1247 }
1248
bd054c1a
DS
1249 if (nexthop->weight)
1250 vty_out(vty, ", weight %u", nexthop->weight);
1251
df9069cd
SW
1252 vty_out(vty, "\n");
1253 }
1254
1e9aad82 1255 if (!zebra_nhg_dependents_is_empty(nhe)) {
df9069cd 1256 vty_out(vty, " Dependents:");
fec211ad 1257 frr_each(nhg_connected_tree, &nhe->nhg_dependents,
37c6708b 1258 rb_node_dep) {
1e9aad82
SW
1259 vty_out(vty, " (%u)", rb_node_dep->nhe->id);
1260 }
1261 vty_out(vty, "\n");
1262 }
1263
1e9aad82
SW
1264}
1265
1266static int show_nexthop_group_id_cmd_helper(struct vty *vty, uint32_t id)
1267{
1268 struct nhg_hash_entry *nhe = NULL;
1269
1270 nhe = zebra_nhg_lookup_id(id);
1271
1272 if (nhe)
1273 show_nexthop_group_out(vty, nhe);
1274 else {
1275 vty_out(vty, "Nexthop Group ID: %u does not exist\n", id);
1276 return CMD_WARNING;
1277 }
1278 return CMD_SUCCESS;
1279}
1280
b5e02d19
MS
1281/* Helper function for iteration through the hash of nexthop-groups/nhe-s */
1282
1283struct nhe_show_context {
1284 struct vty *vty;
1285 vrf_id_t vrf_id;
1286 afi_t afi;
1287};
1288
1289static int nhe_show_walker(struct hash_bucket *bucket, void *arg)
21be1364 1290{
b5e02d19
MS
1291 struct nhe_show_context *ctx = arg;
1292 struct nhg_hash_entry *nhe;
21be1364 1293
b5e02d19 1294 nhe = bucket->data; /* We won't be offered NULL buckets */
21be1364 1295
b5e02d19
MS
1296 if (ctx->afi && nhe->afi != ctx->afi)
1297 goto done;
77b76fc9 1298
b5e02d19
MS
1299 if (ctx->vrf_id && nhe->vrf_id != ctx->vrf_id)
1300 goto done;
21be1364 1301
b5e02d19
MS
1302 show_nexthop_group_out(ctx->vty, nhe);
1303
1304done:
1305 return HASHWALK_CONTINUE;
1306}
1307
1308static void show_nexthop_group_cmd_helper(struct vty *vty,
1309 struct zebra_vrf *zvrf,
1310 afi_t afi)
1311{
1312 struct nhe_show_context ctx;
1313
1314 ctx.vty = vty;
1315 ctx.afi = afi;
1316 ctx.vrf_id = zvrf->vrf->vrf_id;
a15d4c00 1317
b5e02d19 1318 hash_walk(zrouter.nhgs_id, nhe_show_walker, &ctx);
1e9aad82
SW
1319}
1320
1321static void if_nexthop_group_dump_vty(struct vty *vty, struct interface *ifp)
1322{
1323 struct zebra_if *zebra_if = NULL;
1324 struct nhg_connected *rb_node_dep = NULL;
1325
1326 zebra_if = ifp->info;
1327
1328 if (!if_nhg_dependents_is_empty(ifp)) {
1329 vty_out(vty, "Interface %s:\n", ifp->name);
1330
fec211ad 1331 frr_each(nhg_connected_tree, &zebra_if->nhg_dependents,
37c6708b 1332 rb_node_dep) {
1e9aad82
SW
1333 vty_out(vty, " ");
1334 show_nexthop_group_out(vty, rb_node_dep->nhe);
cced3a2d 1335 }
1e9aad82
SW
1336 }
1337}
cced3a2d 1338
1e9aad82
SW
1339DEFPY (show_interface_nexthop_group,
1340 show_interface_nexthop_group_cmd,
1341 "show interface [IFNAME$if_name] nexthop-group",
1342 SHOW_STR
1343 "Interface status and configuration\n"
1344 "Interface name\n"
1345 "Show Nexthop Groups\n")
1346{
1347 struct vrf *vrf = NULL;
1348 struct interface *ifp = NULL;
1349 bool found = false;
1350
1351 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
1352 if (if_name) {
1353 ifp = if_lookup_by_name(if_name, vrf->vrf_id);
1354 if (ifp) {
1355 if_nexthop_group_dump_vty(vty, ifp);
1356 found = true;
1357 }
1358 } else {
1359 FOR_ALL_INTERFACES (vrf, ifp)
1360 if_nexthop_group_dump_vty(vty, ifp);
1361 found = true;
21be1364
DS
1362 }
1363 }
1364
1e9aad82
SW
1365 if (!found) {
1366 vty_out(vty, "%% Can't find interface %s\n", if_name);
1367 return CMD_WARNING;
1368 }
1369
1370 return CMD_SUCCESS;
21be1364
DS
1371}
1372
1373DEFPY (show_nexthop_group,
1374 show_nexthop_group_cmd,
417f01b7 1375 "show nexthop-group rib <(0-4294967295)$id|[singleton <ip$v4|ipv6$v6>] [vrf <NAME$vrf_name|all$vrf_all>]>",
21be1364 1376 SHOW_STR
1e9aad82 1377 "Show Nexthop Groups\n"
2553fde1 1378 "RIB information\n"
1e9aad82 1379 "Nexthop Group ID\n"
417f01b7 1380 "Show Singleton Nexthop-Groups\n"
77b76fc9
SW
1381 IP_STR
1382 IP6_STR
21be1364
DS
1383 VRF_FULL_CMD_HELP_STR)
1384{
cced3a2d 1385
1e9aad82 1386 struct zebra_vrf *zvrf = NULL;
417f01b7 1387 afi_t afi = AFI_UNSPEC;
2d3c57e6 1388
1e9aad82
SW
1389 if (id)
1390 return show_nexthop_group_id_cmd_helper(vty, id);
1391
cced3a2d
SW
1392 if (v4)
1393 afi = AFI_IP;
1394 else if (v6)
1395 afi = AFI_IP6;
1396
88cafda7
DS
1397 if (vrf_is_backend_netns() && (vrf_name || vrf_all)) {
1398 vty_out(vty, "VRF subcommand does not make any sense in l3mdev based vrf's");
1399 return CMD_WARNING;
1400 }
1401
21be1364
DS
1402 if (vrf_all) {
1403 struct vrf *vrf;
1404
1405 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
1406 struct zebra_vrf *zvrf;
1407
1408 zvrf = vrf->info;
1409 if (!zvrf)
1410 continue;
1411
1412 vty_out(vty, "VRF: %s\n", vrf->name);
77b76fc9 1413 show_nexthop_group_cmd_helper(vty, zvrf, afi);
21be1364
DS
1414 }
1415
1416 return CMD_SUCCESS;
1417 }
1418
1419 if (vrf_name)
1420 zvrf = zebra_vrf_lookup_by_name(vrf_name);
1421 else
1422 zvrf = zebra_vrf_lookup_by_name(VRF_DEFAULT_NAME);
1423
1424 if (!zvrf) {
b5e02d19
MS
1425 vty_out(vty, "%% VRF '%s' specified does not exist\n",
1426 vrf_name);
1e9aad82 1427 return CMD_WARNING;
21be1364
DS
1428 }
1429
77b76fc9 1430 show_nexthop_group_cmd_helper(vty, zvrf, afi);
21be1364
DS
1431
1432 return CMD_SUCCESS;
1433}
1434
7c99d51b
MS
1435DEFPY_HIDDEN(nexthop_group_use_enable,
1436 nexthop_group_use_enable_cmd,
1437 "[no] zebra nexthop kernel enable",
1438 NO_STR
1439 ZEBRA_STR
1440 "Nexthop configuration \n"
1441 "Configure use of kernel nexthops\n"
1442 "Enable kernel nexthops\n")
1443{
1444 zebra_nhg_enable_kernel_nexthops(!no);
1445 return CMD_SUCCESS;
1446}
1447
8f527c5e
FL
1448DEFUN (no_ip_nht_default_route,
1449 no_ip_nht_default_route_cmd,
1450 "no ip nht resolve-via-default",
1451 NO_STR
1452 IP_STR
1453 "Filter Next Hop tracking route resolution\n"
1454 "Resolve via default route\n")
1455{
214e5c26 1456 ZEBRA_DECLVAR_CONTEXT(vrf, zvrf);
6d53d7b1 1457
1458 if (!zvrf)
1459 return CMD_WARNING;
1460
5a0bdc78 1461 if (!zvrf->zebra_rnh_ip_default_route)
214e5c26 1462 return CMD_SUCCESS;
1463
5a0bdc78 1464 zvrf->zebra_rnh_ip_default_route = 0;
73bf60a0 1465 zebra_evaluate_rnh(zvrf, AFI_IP, 1, RNH_NEXTHOP_TYPE, NULL);
d62a17ae 1466 return CMD_SUCCESS;
8f527c5e
FL
1467}
1468
1469DEFUN (ipv6_nht_default_route,
1470 ipv6_nht_default_route_cmd,
1471 "ipv6 nht resolve-via-default",
1472 IP6_STR
1473 "Filter Next Hop tracking route resolution\n"
1474 "Resolve via default route\n")
1475{
214e5c26 1476 ZEBRA_DECLVAR_CONTEXT(vrf, zvrf);
6d53d7b1 1477
1478 if (!zvrf)
1479 return CMD_WARNING;
1480
5a0bdc78 1481 if (zvrf->zebra_rnh_ipv6_default_route)
214e5c26 1482 return CMD_SUCCESS;
1483
5a0bdc78 1484 zvrf->zebra_rnh_ipv6_default_route = 1;
73bf60a0 1485 zebra_evaluate_rnh(zvrf, AFI_IP6, 1, RNH_NEXTHOP_TYPE, NULL);
d62a17ae 1486 return CMD_SUCCESS;
8f527c5e
FL
1487}
1488
1489DEFUN (no_ipv6_nht_default_route,
1490 no_ipv6_nht_default_route_cmd,
1491 "no ipv6 nht resolve-via-default",
1492 NO_STR
1493 IP6_STR
1494 "Filter Next Hop tracking route resolution\n"
1495 "Resolve via default route\n")
1496{
8f527c5e 1497
214e5c26 1498 ZEBRA_DECLVAR_CONTEXT(vrf, zvrf);
6d53d7b1 1499
1500 if (!zvrf)
1501 return CMD_WARNING;
1502
5a0bdc78 1503 if (!zvrf->zebra_rnh_ipv6_default_route)
214e5c26 1504 return CMD_SUCCESS;
1505
5a0bdc78 1506 zvrf->zebra_rnh_ipv6_default_route = 0;
73bf60a0 1507 zebra_evaluate_rnh(zvrf, AFI_IP6, 1, RNH_NEXTHOP_TYPE, NULL);
d62a17ae 1508 return CMD_SUCCESS;
8f527c5e
FL
1509}
1510
ecffa493
RW
1511DEFPY (show_route,
1512 show_route_cmd,
1513 "show\
1514 <\
1515 ip$ipv4 <fib$fib|route> [vrf <NAME$vrf_name|all$vrf_all>]\
a3e13ef3 1516 [{\
ecffa493
RW
1517 tag (1-4294967295)\
1518 |A.B.C.D/M$prefix longer-prefixes\
1519 |supernets-only$supernets_only\
a3e13ef3
RW
1520 }]\
1521 [<\
1522 " FRR_IP_REDIST_STR_ZEBRA "$type_str\
ecffa493 1523 |ospf$type_str (1-65535)$ospf_instance_id\
a3e13ef3 1524 >]\
ecffa493 1525 |ipv6$ipv6 <fib$fib|route> [vrf <NAME$vrf_name|all$vrf_all>]\
a3e13ef3 1526 [{\
ecffa493
RW
1527 tag (1-4294967295)\
1528 |X:X::X:X/M$prefix longer-prefixes\
a3e13ef3
RW
1529 }]\
1530 [" FRR_IP6_REDIST_STR_ZEBRA "$type_str]\
ecffa493
RW
1531 >\
1532 [json$json]",
8f527c5e
FL
1533 SHOW_STR
1534 IP_STR
87a88962 1535 "IP forwarding table\n"
8f527c5e 1536 "IP routing table\n"
ecffa493 1537 VRF_FULL_CMD_HELP_STR
8f527c5e 1538 "Show only routes with tag\n"
acb25e73
DW
1539 "Tag value\n"
1540 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1541 "Show route matching the specified Network/Mask pair only\n"
1542 "Show supernet entries only\n"
1543 FRR_IP_REDIST_HELP_STR_ZEBRA
1544 "Open Shortest Path First (OSPFv2)\n"
1545 "Instance ID\n"
ecffa493
RW
1546 IPV6_STR
1547 "IP forwarding table\n"
1548 "IP routing table\n"
1549 VRF_FULL_CMD_HELP_STR
1550 "Show only routes with tag\n"
1551 "Tag value\n"
1552 "IPv6 prefix\n"
1553 "Show route matching the specified Network/Mask pair only\n"
1554 FRR_IP6_REDIST_HELP_STR_ZEBRA
acb25e73 1555 JSON_STR)
8f527c5e 1556{
ecffa493 1557 afi_t afi = ipv4 ? AFI_IP : AFI_IP6;
d62a17ae 1558 struct vrf *vrf;
d62a17ae 1559 int type = 0;
d62a17ae 1560
ecffa493
RW
1561 if (type_str) {
1562 type = proto_redistnum(afi, type_str);
d62a17ae 1563 if (type < 0) {
1564 vty_out(vty, "Unknown route type\n");
1565 return CMD_WARNING;
1566 }
1567 }
1568
1569 if (vrf_all) {
a2addae8 1570 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
ecffa493
RW
1571 struct zebra_vrf *zvrf;
1572 struct route_table *table;
1573
d62a17ae 1574 if ((zvrf = vrf->info) == NULL
ecffa493 1575 || (table = zvrf->table[afi][SAFI_UNICAST]) == NULL)
d62a17ae 1576 continue;
1577
1578 do_show_ip_route(
ecffa493
RW
1579 vty, zvrf_name(zvrf), afi, SAFI_UNICAST, !!fib,
1580 !!json, tag, prefix_str ? prefix : NULL,
1581 !!supernets_only, type, ospf_instance_id);
d62a17ae 1582 }
1583 } else {
ecffa493
RW
1584 vrf_id_t vrf_id = VRF_DEFAULT;
1585
1586 if (vrf_name)
ec1db588 1587 VRF_GET_ID(vrf_id, vrf_name, !!json);
d62a17ae 1588 vrf = vrf_lookup_by_id(vrf_id);
ecffa493
RW
1589 do_show_ip_route(vty, vrf->name, afi, SAFI_UNICAST, !!fib,
1590 !!json, tag, prefix_str ? prefix : NULL,
1591 !!supernets_only, type, ospf_instance_id);
d62a17ae 1592 }
ecffa493 1593
d62a17ae 1594 return CMD_SUCCESS;
8f527c5e
FL
1595}
1596
5ce91022
RW
1597DEFPY (show_route_detail,
1598 show_route_detail_cmd,
1599 "show\
1600 <\
6a794a7e 1601 ip$ipv4 <fib$fib|route> [vrf <NAME$vrf_name|all$vrf_all>]\
5ce91022
RW
1602 <\
1603 A.B.C.D$address\
1604 |A.B.C.D/M$prefix\
1605 >\
6a794a7e 1606 |ipv6$ipv6 <fib$fib|route> [vrf <NAME$vrf_name|all$vrf_all>]\
5ce91022
RW
1607 <\
1608 X:X::X:X$address\
1609 |X:X::X:X/M$prefix\
1610 >\
96d71e38 1611 >\
61d9ffe1 1612 [json$json] [nexthop-group$ng]",
8f527c5e
FL
1613 SHOW_STR
1614 IP_STR
6a794a7e 1615 "IPv6 forwarding table\n"
8f527c5e 1616 "IP routing table\n"
5ce91022
RW
1617 VRF_FULL_CMD_HELP_STR
1618 "Network in the IP routing table to display\n"
1619 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1620 IP6_STR
6a794a7e
AD
1621 "IPv6 forwarding table\n"
1622 "IPv6 routing table\n"
5ce91022
RW
1623 VRF_FULL_CMD_HELP_STR
1624 "IPv6 Address\n"
96d71e38 1625 "IPv6 prefix\n"
61d9ffe1
SW
1626 JSON_STR
1627 "Nexthop Group Information\n")
8f527c5e 1628{
5ce91022 1629 afi_t afi = ipv4 ? AFI_IP : AFI_IP6;
d62a17ae 1630 struct route_table *table;
5ce91022 1631 struct prefix p;
d62a17ae 1632 struct route_node *rn;
3a3be633
AD
1633 bool use_fib = !!fib;
1634 rib_dest_t *dest;
ad2e7233 1635 bool network_found = false;
61d9ffe1 1636 bool show_ng = !!ng;
d511d7f1 1637
5ce91022
RW
1638 if (address_str)
1639 prefix_str = address_str;
1640 if (str2prefix(prefix_str, &p) < 0) {
1641 vty_out(vty, "%% Malformed address\n");
d62a17ae 1642 return CMD_WARNING;
1643 }
8f527c5e 1644
5ce91022
RW
1645 if (vrf_all) {
1646 struct vrf *vrf;
1647 struct zebra_vrf *zvrf;
8f527c5e 1648
996c9314 1649 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
5ce91022
RW
1650 if ((zvrf = vrf->info) == NULL
1651 || (table = zvrf->table[afi][SAFI_UNICAST]) == NULL)
1652 continue;
1653
1654 rn = route_node_match(table, &p);
1655 if (!rn)
1656 continue;
1657 if (!address_str && rn->p.prefixlen != p.prefixlen) {
1658 route_unlock_node(rn);
1659 continue;
1660 }
1661
ad2e7233
AD
1662 dest = rib_dest_from_rnode(rn);
1663 if (use_fib && !dest->selected_fib) {
1664 route_unlock_node(rn);
1665 continue;
1666 }
1667
1668 network_found = true;
96d71e38 1669 if (json)
61d9ffe1 1670 vty_show_ip_route_detail_json(vty, rn, use_fib);
96d71e38 1671 else
61d9ffe1
SW
1672 vty_show_ip_route_detail(vty, rn, 0, use_fib,
1673 show_ng);
5ce91022
RW
1674
1675 route_unlock_node(rn);
1676 }
ad2e7233
AD
1677
1678 if (!network_found) {
1679 if (json)
1680 vty_out(vty, "{}\n");
1681 else {
1682 if (use_fib)
1683 vty_out(vty,
1684 "%% Network not in FIB\n");
1685 else
1686 vty_out(vty,
1687 "%% Network not in RIB\n");
1688 }
1689 return CMD_WARNING;
1690 }
5ce91022
RW
1691 } else {
1692 vrf_id_t vrf_id = VRF_DEFAULT;
1693
1694 if (vrf_name)
ec1db588 1695 VRF_GET_ID(vrf_id, vrf_name, false);
5ce91022
RW
1696
1697 table = zebra_vrf_table(afi, SAFI_UNICAST, vrf_id);
1698 if (!table)
1699 return CMD_SUCCESS;
8f527c5e 1700
5ce91022 1701 rn = route_node_match(table, &p);
ad2e7233
AD
1702 if (rn)
1703 dest = rib_dest_from_rnode(rn);
1704
1705 if (!rn || (!address_str && rn->p.prefixlen != p.prefixlen) ||
1706 (use_fib && dest && !dest->selected_fib)) {
1707 if (json)
1708 vty_out(vty, "{}\n");
1709 else {
1710 if (use_fib)
1711 vty_out(vty,
1712 "%% Network not in FIB\n");
1713 else
1714 vty_out(vty,
1715 "%% Network not in table\n");
1716 }
1717 if (rn)
1718 route_unlock_node(rn);
5ce91022
RW
1719 return CMD_WARNING;
1720 }
8f527c5e 1721
96d71e38 1722 if (json)
3a3be633 1723 vty_show_ip_route_detail_json(vty, rn, use_fib);
96d71e38 1724 else
61d9ffe1 1725 vty_show_ip_route_detail(vty, rn, 0, use_fib, show_ng);
5ce91022
RW
1726
1727 route_unlock_node(rn);
1728 }
8f527c5e 1729
d62a17ae 1730 return CMD_SUCCESS;
8f527c5e
FL
1731}
1732
5ce91022
RW
1733DEFPY (show_route_summary,
1734 show_route_summary_cmd,
ae813e21 1735 "show <ip$ipv4|ipv6$ipv6> route [vrf <NAME$vrf_name|all$vrf_all>] \
e7deb7e7 1736 summary [table (1-4294967295)$table_id] [prefix$prefix] [json]",
8f527c5e
FL
1737 SHOW_STR
1738 IP_STR
5ce91022
RW
1739 IP6_STR
1740 "IP routing table\n"
1741 VRF_FULL_CMD_HELP_STR
1742 "Summary of all routes\n"
ae813e21
DS
1743 "Table to display summary for\n"
1744 "The table number\n"
e7deb7e7
DA
1745 "Prefix routes\n"
1746 JSON_STR)
8f527c5e 1747{
5ce91022 1748 afi_t afi = ipv4 ? AFI_IP : AFI_IP6;
d62a17ae 1749 struct route_table *table;
e7deb7e7 1750 bool uj = use_json(argc, argv);
d62a17ae 1751
ae813e21
DS
1752 if (table_id == 0)
1753 table_id = RT_TABLE_MAIN;
1754
5ce91022
RW
1755 if (vrf_all) {
1756 struct vrf *vrf;
1757 struct zebra_vrf *zvrf;
d511d7f1 1758
996c9314 1759 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
ae813e21
DS
1760 if ((zvrf = vrf->info) == NULL)
1761 continue;
1762
c7c0b007
SW
1763 table = zebra_vrf_lookup_table_with_table_id(
1764 afi, SAFI_UNICAST, zvrf->vrf->vrf_id, table_id);
1765
ae813e21 1766 if (!table)
5ce91022 1767 continue;
8f527c5e 1768
5ce91022 1769 if (prefix)
e7deb7e7
DA
1770 vty_show_ip_route_summary_prefix(vty, table,
1771 uj);
5ce91022 1772 else
e7deb7e7 1773 vty_show_ip_route_summary(vty, table, uj);
5ce91022
RW
1774 }
1775 } else {
1776 vrf_id_t vrf_id = VRF_DEFAULT;
8f527c5e 1777
5ce91022 1778 if (vrf_name)
ec1db588 1779 VRF_GET_ID(vrf_id, vrf_name, false);
8f527c5e 1780
c7c0b007
SW
1781 table = zebra_vrf_lookup_table_with_table_id(afi, SAFI_UNICAST,
1782 vrf_id, table_id);
5ce91022
RW
1783 if (!table)
1784 return CMD_SUCCESS;
8f527c5e 1785
5ce91022 1786 if (prefix)
e7deb7e7 1787 vty_show_ip_route_summary_prefix(vty, table, uj);
5ce91022 1788 else
e7deb7e7 1789 vty_show_ip_route_summary(vty, table, uj);
5ce91022 1790 }
8f527c5e 1791
d62a17ae 1792 return CMD_SUCCESS;
8f527c5e
FL
1793}
1794
d62a17ae 1795static void vty_show_ip_route_summary(struct vty *vty,
e7deb7e7 1796 struct route_table *table, bool use_json)
8f527c5e 1797{
d62a17ae 1798 struct route_node *rn;
1799 struct route_entry *re;
8f527c5e
FL
1800#define ZEBRA_ROUTE_IBGP ZEBRA_ROUTE_MAX
1801#define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1)
d7c0a89a
QY
1802 uint32_t rib_cnt[ZEBRA_ROUTE_TOTAL + 1];
1803 uint32_t fib_cnt[ZEBRA_ROUTE_TOTAL + 1];
1804 uint32_t i;
1805 uint32_t is_ibgp;
e7deb7e7
DA
1806 json_object *json_route_summary = NULL;
1807 json_object *json_route_routes = NULL;
d62a17ae 1808
1809 memset(&rib_cnt, 0, sizeof(rib_cnt));
1810 memset(&fib_cnt, 0, sizeof(fib_cnt));
e7deb7e7
DA
1811
1812 if (use_json) {
1813 json_route_summary = json_object_new_object();
1814 json_route_routes = json_object_new_array();
1815 json_object_object_add(json_route_summary, "routes",
1816 json_route_routes);
1817 }
1818
d62a17ae 1819 for (rn = route_top(table); rn; rn = srcdest_route_next(rn))
a2addae8 1820 RNODE_FOREACH_RE (rn, re) {
d62a17ae 1821 is_ibgp = (re->type == ZEBRA_ROUTE_BGP
1822 && CHECK_FLAG(re->flags, ZEBRA_FLAG_IBGP));
1823
1824 rib_cnt[ZEBRA_ROUTE_TOTAL]++;
1825 if (is_ibgp)
1826 rib_cnt[ZEBRA_ROUTE_IBGP]++;
1827 else
1828 rib_cnt[re->type]++;
1829
6f875a36 1830 if (CHECK_FLAG(re->status, ROUTE_ENTRY_INSTALLED)) {
d62a17ae 1831 fib_cnt[ZEBRA_ROUTE_TOTAL]++;
1832
1833 if (is_ibgp)
1834 fib_cnt[ZEBRA_ROUTE_IBGP]++;
1835 else
1836 fib_cnt[re->type]++;
1837 }
1838 }
1839
e7deb7e7
DA
1840 if (!use_json)
1841 vty_out(vty, "%-20s %-20s %s (vrf %s)\n", "Route Source",
1842 "Routes", "FIB",
1843 zvrf_name(((rib_table_info_t *)route_table_get_info(
1844 table))
1845 ->zvrf));
d62a17ae 1846
1847 for (i = 0; i < ZEBRA_ROUTE_MAX; i++) {
9d303b37
DL
1848 if ((rib_cnt[i] > 0) || (i == ZEBRA_ROUTE_BGP
1849 && rib_cnt[ZEBRA_ROUTE_IBGP] > 0)) {
d62a17ae 1850 if (i == ZEBRA_ROUTE_BGP) {
e7deb7e7
DA
1851 if (use_json) {
1852 json_object *json_route_ebgp =
1853 json_object_new_object();
1854
1855 json_object_int_add(
1856 json_route_ebgp, "fib",
1857 fib_cnt[ZEBRA_ROUTE_BGP]);
1858 json_object_int_add(
1859 json_route_ebgp, "rib",
1860 rib_cnt[ZEBRA_ROUTE_BGP]);
1861 json_object_string_add(json_route_ebgp,
1862 "type", "ebgp");
1863 json_object_array_add(json_route_routes,
1864 json_route_ebgp);
1865
1866 json_object *json_route_ibgp =
1867 json_object_new_object();
1868
1869 json_object_int_add(
1870 json_route_ibgp, "fib",
1871 fib_cnt[ZEBRA_ROUTE_IBGP]);
1872 json_object_int_add(
1873 json_route_ibgp, "rib",
1874 rib_cnt[ZEBRA_ROUTE_IBGP]);
1875 json_object_string_add(json_route_ibgp,
1876 "type", "ibgp");
1877 json_object_array_add(json_route_routes,
1878 json_route_ibgp);
1879 } else {
1880 vty_out(vty, "%-20s %-20d %-20d \n",
1881 "ebgp",
1882 rib_cnt[ZEBRA_ROUTE_BGP],
1883 fib_cnt[ZEBRA_ROUTE_BGP]);
1884 vty_out(vty, "%-20s %-20d %-20d \n",
1885 "ibgp",
1886 rib_cnt[ZEBRA_ROUTE_IBGP],
1887 fib_cnt[ZEBRA_ROUTE_IBGP]);
1888 }
1889 } else {
1890 if (use_json) {
1891 json_object *json_route_type =
1892 json_object_new_object();
1893
1894 json_object_int_add(json_route_type,
1895 "fib", fib_cnt[i]);
1896 json_object_int_add(json_route_type,
1897 "rib", rib_cnt[i]);
1898 json_object_string_add(
1899 json_route_type, "type",
1900 zebra_route_string(i));
1901 json_object_array_add(json_route_routes,
1902 json_route_type);
1903 } else
1904 vty_out(vty, "%-20s %-20d %-20d \n",
1905 zebra_route_string(i),
1906 rib_cnt[i], fib_cnt[i]);
1907 }
d62a17ae 1908 }
1909 }
1910
e7deb7e7
DA
1911 if (use_json) {
1912 json_object_int_add(json_route_summary, "routesTotal",
1913 rib_cnt[ZEBRA_ROUTE_TOTAL]);
1914 json_object_int_add(json_route_summary, "routesTotalFib",
1915 fib_cnt[ZEBRA_ROUTE_TOTAL]);
1916
1917 vty_out(vty, "%s\n",
1918 json_object_to_json_string_ext(
1919 json_route_summary, JSON_C_TO_STRING_PRETTY));
1920 json_object_free(json_route_summary);
1921 } else {
1922 vty_out(vty, "------\n");
1923 vty_out(vty, "%-20s %-20d %-20d \n", "Totals",
1924 rib_cnt[ZEBRA_ROUTE_TOTAL], fib_cnt[ZEBRA_ROUTE_TOTAL]);
1925 vty_out(vty, "\n");
1926 }
8f527c5e
FL
1927}
1928
1929/*
1930 * Implementation of the ip route summary prefix command.
1931 *
1932 * This command prints the primary prefixes that have been installed by various
1933 * protocols on the box.
1934 *
1935 */
d62a17ae 1936static void vty_show_ip_route_summary_prefix(struct vty *vty,
e7deb7e7
DA
1937 struct route_table *table,
1938 bool use_json)
8f527c5e 1939{
d62a17ae 1940 struct route_node *rn;
1941 struct route_entry *re;
1942 struct nexthop *nexthop;
8f527c5e
FL
1943#define ZEBRA_ROUTE_IBGP ZEBRA_ROUTE_MAX
1944#define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1)
d7c0a89a
QY
1945 uint32_t rib_cnt[ZEBRA_ROUTE_TOTAL + 1];
1946 uint32_t fib_cnt[ZEBRA_ROUTE_TOTAL + 1];
1947 uint32_t i;
d62a17ae 1948 int cnt;
e7deb7e7
DA
1949 json_object *json_route_summary = NULL;
1950 json_object *json_route_routes = NULL;
d62a17ae 1951
1952 memset(&rib_cnt, 0, sizeof(rib_cnt));
1953 memset(&fib_cnt, 0, sizeof(fib_cnt));
e7deb7e7
DA
1954
1955 if (use_json) {
1956 json_route_summary = json_object_new_object();
1957 json_route_routes = json_object_new_array();
1958 json_object_object_add(json_route_summary, "prefixRoutes",
1959 json_route_routes);
1960 }
1961
d62a17ae 1962 for (rn = route_top(table); rn; rn = srcdest_route_next(rn))
a2addae8 1963 RNODE_FOREACH_RE (rn, re) {
d62a17ae 1964
1965 /*
1966 * In case of ECMP, count only once.
1967 */
1968 cnt = 0;
677c1dd5
DS
1969 if (CHECK_FLAG(re->status, ROUTE_ENTRY_INSTALLED)) {
1970 fib_cnt[ZEBRA_ROUTE_TOTAL]++;
1971 fib_cnt[re->type]++;
1972 }
0eb97b86 1973 for (nexthop = re->nhe->nhg->nexthop; (!cnt && nexthop);
d62a17ae 1974 nexthop = nexthop->next) {
1975 cnt++;
1976 rib_cnt[ZEBRA_ROUTE_TOTAL]++;
1977 rib_cnt[re->type]++;
d62a17ae 1978 if (re->type == ZEBRA_ROUTE_BGP
1979 && CHECK_FLAG(re->flags, ZEBRA_FLAG_IBGP)) {
1980 rib_cnt[ZEBRA_ROUTE_IBGP]++;
677c1dd5
DS
1981 if (CHECK_FLAG(re->status,
1982 ROUTE_ENTRY_INSTALLED))
d62a17ae 1983 fib_cnt[ZEBRA_ROUTE_IBGP]++;
1984 }
1985 }
1986 }
1987
e7deb7e7
DA
1988 if (!use_json)
1989 vty_out(vty, "%-20s %-20s %s (vrf %s)\n", "Route Source",
1990 "Prefix Routes", "FIB",
1991 zvrf_name(((rib_table_info_t *)route_table_get_info(
1992 table))
1993 ->zvrf));
d62a17ae 1994
1995 for (i = 0; i < ZEBRA_ROUTE_MAX; i++) {
1996 if (rib_cnt[i] > 0) {
1997 if (i == ZEBRA_ROUTE_BGP) {
e7deb7e7
DA
1998 if (use_json) {
1999 json_object *json_route_ebgp =
2000 json_object_new_object();
2001
2002 json_object_int_add(
2003 json_route_ebgp, "fib",
2004 fib_cnt[ZEBRA_ROUTE_BGP]
2005 - fib_cnt[ZEBRA_ROUTE_IBGP]);
2006 json_object_int_add(
2007 json_route_ebgp, "rib",
2008 rib_cnt[ZEBRA_ROUTE_BGP]
2009 - rib_cnt[ZEBRA_ROUTE_IBGP]);
2010 json_object_string_add(json_route_ebgp,
2011 "type", "ebgp");
2012 json_object_array_add(json_route_routes,
2013 json_route_ebgp);
2014
2015 json_object *json_route_ibgp =
2016 json_object_new_object();
2017
2018 json_object_int_add(
2019 json_route_ibgp, "fib",
2020 fib_cnt[ZEBRA_ROUTE_IBGP]);
2021 json_object_int_add(
2022 json_route_ibgp, "rib",
2023 rib_cnt[ZEBRA_ROUTE_IBGP]);
2024 json_object_string_add(json_route_ibgp,
2025 "type", "ibgp");
2026 json_object_array_add(json_route_routes,
2027 json_route_ibgp);
2028 } else {
2029 vty_out(vty, "%-20s %-20d %-20d \n",
2030 "ebgp",
2031 rib_cnt[ZEBRA_ROUTE_BGP]
2032 - rib_cnt[ZEBRA_ROUTE_IBGP],
2033 fib_cnt[ZEBRA_ROUTE_BGP]
2034 - fib_cnt[ZEBRA_ROUTE_IBGP]);
2035 vty_out(vty, "%-20s %-20d %-20d \n",
2036 "ibgp",
2037 rib_cnt[ZEBRA_ROUTE_IBGP],
2038 fib_cnt[ZEBRA_ROUTE_IBGP]);
2039 }
2040 } else {
2041 if (use_json) {
2042 json_object *json_route_type =
2043 json_object_new_object();
2044
2045 json_object_int_add(json_route_type,
2046 "fib", fib_cnt[i]);
2047 json_object_int_add(json_route_type,
2048 "rib", rib_cnt[i]);
2049 json_object_string_add(
2050 json_route_type, "type",
2051 zebra_route_string(i));
2052 json_object_array_add(json_route_routes,
2053 json_route_type);
2054 } else
2055 vty_out(vty, "%-20s %-20d %-20d \n",
2056 zebra_route_string(i),
2057 rib_cnt[i], fib_cnt[i]);
2058 }
d62a17ae 2059 }
2060 }
2061
e7deb7e7
DA
2062 if (use_json) {
2063 json_object_int_add(json_route_summary, "prefixRoutesTotal",
2064 rib_cnt[ZEBRA_ROUTE_TOTAL]);
2065 json_object_int_add(json_route_summary, "prefixRoutesTotalFib",
2066 fib_cnt[ZEBRA_ROUTE_TOTAL]);
2067
2068 vty_out(vty, "%s\n",
2069 json_object_to_json_string_ext(
2070 json_route_summary, JSON_C_TO_STRING_PRETTY));
2071 json_object_free(json_route_summary);
2072 } else {
2073 vty_out(vty, "------\n");
2074 vty_out(vty, "%-20s %-20d %-20d \n", "Totals",
2075 rib_cnt[ZEBRA_ROUTE_TOTAL], fib_cnt[ZEBRA_ROUTE_TOTAL]);
2076 vty_out(vty, "\n");
2077 }
9343ce83
DS
2078}
2079
cddf391b
B
2080/*
2081 * Show IPv6 mroute command.Used to dump
2082 * the Multicast routing table.
2083 */
cddf391b
B
2084DEFUN (show_ipv6_mroute,
2085 show_ipv6_mroute_cmd,
9bf96c84 2086 "show ipv6 mroute [vrf NAME]",
cddf391b
B
2087 SHOW_STR
2088 IP_STR
9bf96c84
DW
2089 "IPv6 Multicast routing table\n"
2090 VRF_CMD_HELP_STR)
cddf391b 2091{
d62a17ae 2092 struct route_table *table;
2093 struct route_node *rn;
2094 struct route_entry *re;
2095 int first = 1;
2096 vrf_id_t vrf_id = VRF_DEFAULT;
2097
2098 if (argc == 5)
ec1db588 2099 VRF_GET_ID(vrf_id, argv[4]->arg, false);
d62a17ae 2100
2101 table = zebra_vrf_table(AFI_IP6, SAFI_MULTICAST, vrf_id);
2102 if (!table)
2103 return CMD_SUCCESS;
2104
2105 /* Show all IPv6 route. */
2106 for (rn = route_top(table); rn; rn = srcdest_route_next(rn))
a2addae8 2107 RNODE_FOREACH_RE (rn, re) {
d62a17ae 2108 if (first) {
2109 vty_out(vty, SHOW_ROUTE_V6_HEADER);
2110 first = 0;
2111 }
941e261c 2112 vty_show_ip_route(vty, rn, re, NULL, false);
d62a17ae 2113 }
2114 return CMD_SUCCESS;
cddf391b
B
2115}
2116
af41b63a
FL
2117DEFUN (show_ipv6_mroute_vrf_all,
2118 show_ipv6_mroute_vrf_all_cmd,
5bebf568 2119 "show ipv6 mroute vrf all",
af41b63a
FL
2120 SHOW_STR
2121 IP_STR
2122 "IPv6 Multicast routing table\n"
2123 VRF_ALL_CMD_HELP_STR)
2124{
d62a17ae 2125 struct route_table *table;
2126 struct route_node *rn;
2127 struct route_entry *re;
2128 struct vrf *vrf;
2129 struct zebra_vrf *zvrf;
2130 int first = 1;
2131
a2addae8 2132 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
d62a17ae 2133 if ((zvrf = vrf->info) == NULL
2134 || (table = zvrf->table[AFI_IP6][SAFI_MULTICAST]) == NULL)
2135 continue;
2136
2137 /* Show all IPv6 route. */
2138 for (rn = route_top(table); rn; rn = srcdest_route_next(rn))
a2addae8 2139 RNODE_FOREACH_RE (rn, re) {
d62a17ae 2140 if (first) {
2141 vty_out(vty, SHOW_ROUTE_V6_HEADER);
2142 first = 0;
2143 }
941e261c 2144 vty_show_ip_route(vty, rn, re, NULL, false);
d62a17ae 2145 }
2146 }
2147 return CMD_SUCCESS;
af41b63a
FL
2148}
2149
6baf7bb8
DS
2150DEFUN (allow_external_route_update,
2151 allow_external_route_update_cmd,
2152 "allow-external-route-update",
17d990c1 2153 "Allow FRR routes to be overwritten by external processes\n")
6baf7bb8 2154{
d62a17ae 2155 allow_delete = 1;
6baf7bb8 2156
d62a17ae 2157 return CMD_SUCCESS;
6baf7bb8
DS
2158}
2159
2160DEFUN (no_allow_external_route_update,
2161 no_allow_external_route_update_cmd,
2162 "no allow-external-route-update",
17d990c1
DS
2163 NO_STR
2164 "Allow FRR routes to be overwritten by external processes\n")
6baf7bb8 2165{
d62a17ae 2166 allow_delete = 0;
6baf7bb8 2167
d62a17ae 2168 return CMD_SUCCESS;
6baf7bb8
DS
2169}
2170
12f6fb97
DS
2171/* show vrf */
2172DEFUN (show_vrf,
2173 show_vrf_cmd,
2174 "show vrf",
2175 SHOW_STR
2176 "VRF\n")
2177{
d62a17ae 2178 struct vrf *vrf;
2179 struct zebra_vrf *zvrf;
12f6fb97 2180
b73823ef
PG
2181 if (vrf_is_backend_netns())
2182 vty_out(vty, "netns-based vrfs\n");
2183
a2addae8 2184 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
d62a17ae 2185 if (!(zvrf = vrf->info))
2186 continue;
90ac32c2 2187 if (zvrf_id(zvrf) == VRF_DEFAULT)
d62a17ae 2188 continue;
2189
2190 vty_out(vty, "vrf %s ", zvrf_name(zvrf));
996c9314 2191 if (zvrf_id(zvrf) == VRF_UNKNOWN || !zvrf_is_active(zvrf))
d62a17ae 2192 vty_out(vty, "inactive");
81c9005f 2193 else if (zvrf_ns_name(zvrf))
996c9314
LB
2194 vty_out(vty, "id %u netns %s", zvrf_id(zvrf),
2195 zvrf_ns_name(zvrf));
d62a17ae 2196 else
2197 vty_out(vty, "id %u table %u", zvrf_id(zvrf),
2198 zvrf->table_id);
22bd3e94 2199 if (vrf_is_user_cfged(vrf))
2200 vty_out(vty, " (configured)");
d62a17ae 2201 vty_out(vty, "\n");
2202 }
12f6fb97 2203
d62a17ae 2204 return CMD_SUCCESS;
12f6fb97
DS
2205}
2206
8f2ff1b5 2207DEFUN (default_vrf_vni_mapping,
e8d26197 2208 default_vrf_vni_mapping_cmd,
c48d9f5f 2209 "vni " CMD_VNI_RANGE "[prefix-routes-only]",
e8d26197 2210 "VNI corresponding to the DEFAULT VRF\n"
c48d9f5f
MK
2211 "VNI-ID\n"
2212 "Prefix routes only \n")
e8d26197
MK
2213{
2214 int ret = 0;
2215 char err[ERR_STR_SZ];
2216 struct zebra_vrf *zvrf = NULL;
2217 vni_t vni = strtoul(argv[1]->arg, NULL, 10);
c48d9f5f 2218 int filter = 0;
e8d26197
MK
2219
2220 zvrf = vrf_info_lookup(VRF_DEFAULT);
2221 if (!zvrf)
2222 return CMD_WARNING;
2223
c48d9f5f
MK
2224 if (argc == 3)
2225 filter = 1;
2226
2227 ret = zebra_vxlan_process_vrf_vni_cmd(zvrf, vni, err, ERR_STR_SZ,
2228 filter, 1);
e8d26197
MK
2229 if (ret != 0) {
2230 vty_out(vty, "%s\n", err);
2231 return CMD_WARNING;
2232 }
2233
2234 return CMD_SUCCESS;
2235}
2236
8f2ff1b5 2237DEFUN (no_default_vrf_vni_mapping,
e8d26197
MK
2238 no_default_vrf_vni_mapping_cmd,
2239 "no vni " CMD_VNI_RANGE,
2240 NO_STR
2241 "VNI corresponding to DEFAULT VRF\n"
2242 "VNI-ID")
2243{
2244 int ret = 0;
2245 char err[ERR_STR_SZ];
2246 vni_t vni = strtoul(argv[2]->arg, NULL, 10);
2247 struct zebra_vrf *zvrf = NULL;
2248
2249 zvrf = vrf_info_lookup(VRF_DEFAULT);
2250 if (!zvrf)
2251 return CMD_WARNING;
2252
c48d9f5f 2253 ret = zebra_vxlan_process_vrf_vni_cmd(zvrf, vni, err, ERR_STR_SZ, 0, 0);
e8d26197
MK
2254 if (ret != 0) {
2255 vty_out(vty, "%s\n", err);
2256 return CMD_WARNING;
2257 }
2258
2259 return CMD_SUCCESS;
2260}
2261
b7cfce93
MK
2262DEFUN (vrf_vni_mapping,
2263 vrf_vni_mapping_cmd,
c48d9f5f 2264 "vni " CMD_VNI_RANGE "[prefix-routes-only]",
e8d26197 2265 "VNI corresponding to tenant VRF\n"
c48d9f5f
MK
2266 "VNI-ID\n"
2267 "prefix-routes-only\n")
b7cfce93
MK
2268{
2269 int ret = 0;
c48d9f5f 2270 int filter = 0;
b7cfce93
MK
2271
2272 ZEBRA_DECLVAR_CONTEXT(vrf, zvrf);
2273 vni_t vni = strtoul(argv[1]->arg, NULL, 10);
2274 char err[ERR_STR_SZ];
2275
2276 assert(vrf);
2277 assert(zvrf);
2278
c48d9f5f
MK
2279 if (argc == 3)
2280 filter = 1;
2281
317f1fe0 2282 /* Mark as having FRR configuration */
2283 vrf_set_user_cfged(vrf);
c48d9f5f
MK
2284 ret = zebra_vxlan_process_vrf_vni_cmd(zvrf, vni, err, ERR_STR_SZ,
2285 filter, 1);
b7cfce93
MK
2286 if (ret != 0) {
2287 vty_out(vty, "%s\n", err);
2288 return CMD_WARNING;
2289 }
2290
2291 return CMD_SUCCESS;
2292}
2293
2294DEFUN (no_vrf_vni_mapping,
2295 no_vrf_vni_mapping_cmd,
cf299714 2296 "no vni " CMD_VNI_RANGE "[prefix-routes-only]",
b7cfce93 2297 NO_STR
e8d26197 2298 "VNI corresponding to tenant VRF\n"
cf299714
MK
2299 "VNI-ID\n"
2300 "prefix-routes-only\n")
b7cfce93
MK
2301{
2302 int ret = 0;
cf299714 2303 int filter = 0;
b7cfce93
MK
2304 char err[ERR_STR_SZ];
2305 vni_t vni = strtoul(argv[2]->arg, NULL, 10);
2306
2307 ZEBRA_DECLVAR_CONTEXT(vrf, zvrf);
2308
2309 assert(vrf);
2310 assert(zvrf);
2311
cf299714
MK
2312 if (argc == 4)
2313 filter = 1;
2314
2315 ret = zebra_vxlan_process_vrf_vni_cmd(zvrf, vni, err,
2316 ERR_STR_SZ, filter, 0);
b7cfce93
MK
2317 if (ret != 0) {
2318 vty_out(vty, "%s\n", err);
2319 return CMD_WARNING;
2320 }
2321
22bd3e94 2322 /* If no other FRR config for this VRF, mark accordingly. */
2323 if (!zebra_vrf_has_config(zvrf))
2324 vrf_reset_user_cfged(vrf);
2325
b7cfce93
MK
2326 return CMD_SUCCESS;
2327}
2328
2329/* show vrf */
2330DEFUN (show_vrf_vni,
2331 show_vrf_vni_cmd,
35be5542 2332 "show vrf vni [json]",
b7cfce93
MK
2333 SHOW_STR
2334 "VRF\n"
35be5542
MK
2335 "VNI\n"
2336 JSON_STR)
b7cfce93
MK
2337{
2338 struct vrf *vrf;
2339 struct zebra_vrf *zvrf;
35be5542
MK
2340 json_object *json = NULL;
2341 json_object *json_vrfs = NULL;
9f049418 2342 bool uj = use_json(argc, argv);
35be5542
MK
2343
2344 if (uj) {
2345 json = json_object_new_object();
2346 json_vrfs = json_object_new_array();
2347 }
b7cfce93 2348
4cce389e 2349 if (!uj)
996c9314
LB
2350 vty_out(vty, "%-37s %-10s %-20s %-20s %-5s %-18s\n", "VRF",
2351 "VNI", "VxLAN IF", "L3-SVI", "State", "Rmac");
4cce389e 2352
996c9314 2353 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
b7cfce93
MK
2354 zvrf = vrf->info;
2355 if (!zvrf)
2356 continue;
2357
4cce389e 2358 zebra_vxlan_print_vrf_vni(vty, zvrf, json_vrfs);
35be5542
MK
2359 }
2360
2361 if (uj) {
2362 json_object_object_add(json, "vrfs", json_vrfs);
2363 vty_out(vty, "%s\n", json_object_to_json_string_ext(
2364 json, JSON_C_TO_STRING_PRETTY));
2365 json_object_free(json);
b7cfce93
MK
2366 }
2367
2368 return CMD_SUCCESS;
2369}
2370
4cce389e
MK
2371DEFUN (show_evpn_global,
2372 show_evpn_global_cmd,
2373 "show evpn [json]",
2374 SHOW_STR
2375 "EVPN\n"
2376 JSON_STR)
2377{
9f049418 2378 bool uj = use_json(argc, argv);
4cce389e
MK
2379
2380 zebra_vxlan_print_evpn(vty, uj);
2381 return CMD_SUCCESS;
2382}
2383
cec2e17d 2384DEFUN (show_evpn_vni,
2385 show_evpn_vni_cmd,
cd233079 2386 "show evpn vni [json]",
cec2e17d 2387 SHOW_STR
2388 "EVPN\n"
09af6961 2389 "VxLAN Network Identifier\n"
bd592158 2390 JSON_STR)
cec2e17d 2391{
d62a17ae 2392 struct zebra_vrf *zvrf;
9f049418 2393 bool uj = use_json(argc, argv);
cec2e17d 2394
530db8dc 2395 zvrf = zebra_vrf_get_evpn();
cd233079 2396 zebra_vxlan_print_vnis(vty, zvrf, uj);
d62a17ae 2397 return CMD_SUCCESS;
cec2e17d 2398}
2399
09af6961
NS
2400DEFUN (show_evpn_vni_detail, show_evpn_vni_detail_cmd,
2401 "show evpn vni detail [json]",
2402 SHOW_STR
2403 "EVPN\n"
2404 "VxLAN Network Identifier\n"
2405 "Detailed Information On Each VNI\n"
2406 JSON_STR)
2407{
2408 struct zebra_vrf *zvrf;
2409 bool uj = use_json(argc, argv);
2410
530db8dc 2411 zvrf = zebra_vrf_get_evpn();
09af6961
NS
2412 zebra_vxlan_print_vnis_detail(vty, zvrf, uj);
2413 return CMD_SUCCESS;
2414}
2415
cec2e17d 2416DEFUN (show_evpn_vni_vni,
2417 show_evpn_vni_vni_cmd,
cd233079 2418 "show evpn vni " CMD_VNI_RANGE "[json]",
cec2e17d 2419 SHOW_STR
2420 "EVPN\n"
2421 "VxLAN Network Identifier\n"
cd233079 2422 "VNI number\n"
bd592158 2423 JSON_STR)
cec2e17d 2424{
d62a17ae 2425 struct zebra_vrf *zvrf;
2426 vni_t vni;
9f049418 2427 bool uj = use_json(argc, argv);
cec2e17d 2428
d62a17ae 2429 vni = strtoul(argv[3]->arg, NULL, 10);
530db8dc 2430 zvrf = zebra_vrf_get_evpn();
06931fdb 2431 zebra_vxlan_print_vni(vty, zvrf, vni, uj, NULL);
d62a17ae 2432 return CMD_SUCCESS;
cec2e17d 2433}
2434
4cce389e
MK
2435DEFUN (show_evpn_rmac_vni_mac,
2436 show_evpn_rmac_vni_mac_cmd,
2437 "show evpn rmac vni " CMD_VNI_RANGE " mac WORD [json]",
9aa741ea
MK
2438 SHOW_STR
2439 "EVPN\n"
2440 "RMAC\n"
4cce389e 2441 "L3 VNI\n"
9aa741ea
MK
2442 "VNI number\n"
2443 "MAC\n"
316f4ca4
MK
2444 "mac-address (e.g. 0a:0a:0a:0a:0a:0a)\n"
2445 JSON_STR)
9aa741ea
MK
2446{
2447 vni_t l3vni = 0;
2448 struct ethaddr mac;
9f049418 2449 bool uj = use_json(argc, argv);
9aa741ea
MK
2450
2451 l3vni = strtoul(argv[4]->arg, NULL, 10);
2452 if (!prefix_str2mac(argv[6]->arg, &mac)) {
2453 vty_out(vty, "%% Malformed MAC address\n");
2454 return CMD_WARNING;
2455 }
316f4ca4 2456 zebra_vxlan_print_specific_rmac_l3vni(vty, l3vni, &mac, uj);
9aa741ea
MK
2457 return CMD_SUCCESS;
2458}
2459
4cce389e
MK
2460DEFUN (show_evpn_rmac_vni,
2461 show_evpn_rmac_vni_cmd,
2462 "show evpn rmac vni " CMD_VNI_RANGE "[json]",
b7cfce93
MK
2463 SHOW_STR
2464 "EVPN\n"
2465 "RMAC\n"
4cce389e 2466 "L3 VNI\n"
b7cfce93
MK
2467 "VNI number\n"
2468 JSON_STR)
2469{
2470 vni_t l3vni = 0;
9f049418 2471 bool uj = use_json(argc, argv);
b7cfce93
MK
2472
2473 l3vni = strtoul(argv[4]->arg, NULL, 10);
2474 zebra_vxlan_print_rmacs_l3vni(vty, l3vni, uj);
2475
2476 return CMD_SUCCESS;
2477}
2478
4cce389e
MK
2479DEFUN (show_evpn_rmac_vni_all,
2480 show_evpn_rmac_vni_all_cmd,
2481 "show evpn rmac vni all [json]",
b7cfce93
MK
2482 SHOW_STR
2483 "EVPN\n"
2484 "RMAC addresses\n"
4cce389e 2485 "L3 VNI\n"
b7cfce93
MK
2486 "All VNIs\n"
2487 JSON_STR)
2488{
9f049418 2489 bool uj = use_json(argc, argv);
b7cfce93
MK
2490
2491 zebra_vxlan_print_rmacs_all_l3vni(vty, uj);
2492
2493 return CMD_SUCCESS;
2494}
2495
4cce389e
MK
2496DEFUN (show_evpn_nh_vni_ip,
2497 show_evpn_nh_vni_ip_cmd,
2498 "show evpn next-hops vni " CMD_VNI_RANGE " ip WORD [json]",
9aa741ea
MK
2499 SHOW_STR
2500 "EVPN\n"
2501 "Remote Vteps\n"
4cce389e 2502 "L3 VNI\n"
9aa741ea
MK
2503 "VNI number\n"
2504 "Ip address\n"
c0e519d3
MK
2505 "Host address (ipv4 or ipv6)\n"
2506 JSON_STR)
9aa741ea
MK
2507{
2508 vni_t l3vni;
9aa741ea 2509 struct ipaddr ip;
9f049418 2510 bool uj = use_json(argc, argv);
9aa741ea
MK
2511
2512 l3vni = strtoul(argv[4]->arg, NULL, 10);
2513 if (str2ipaddr(argv[6]->arg, &ip) != 0) {
2514 if (!uj)
2515 vty_out(vty, "%% Malformed Neighbor address\n");
2516 return CMD_WARNING;
2517 }
c0e519d3 2518 zebra_vxlan_print_specific_nh_l3vni(vty, l3vni, &ip, uj);
9aa741ea
MK
2519
2520 return CMD_SUCCESS;
2521}
2522
4cce389e
MK
2523DEFUN (show_evpn_nh_vni,
2524 show_evpn_nh_vni_cmd,
2525 "show evpn next-hops vni " CMD_VNI_RANGE "[json]",
b7cfce93
MK
2526 SHOW_STR
2527 "EVPN\n"
2528 "Remote Vteps\n"
4cce389e 2529 "L3 VNI\n"
b7cfce93
MK
2530 "VNI number\n"
2531 JSON_STR)
2532{
2533 vni_t l3vni;
9f049418 2534 bool uj = use_json(argc, argv);
b7cfce93
MK
2535
2536 l3vni = strtoul(argv[4]->arg, NULL, 10);
2537 zebra_vxlan_print_nh_l3vni(vty, l3vni, uj);
2538
2539 return CMD_SUCCESS;
2540}
2541
4cce389e
MK
2542DEFUN (show_evpn_nh_vni_all,
2543 show_evpn_nh_vni_all_cmd,
2544 "show evpn next-hops vni all [json]",
b7cfce93
MK
2545 SHOW_STR
2546 "EVPN\n"
2547 "Remote VTEPs\n"
4cce389e 2548 "L3 VNI\n"
b7cfce93
MK
2549 "All VNIs\n"
2550 JSON_STR)
2551{
9f049418 2552 bool uj = use_json(argc, argv);
b7cfce93
MK
2553
2554 zebra_vxlan_print_nh_all_l3vni(vty, uj);
2555
2556 return CMD_SUCCESS;
2557}
2558
cec2e17d 2559DEFUN (show_evpn_mac_vni,
2560 show_evpn_mac_vni_cmd,
cd233079 2561 "show evpn mac vni " CMD_VNI_RANGE "[json]",
cec2e17d 2562 SHOW_STR
2563 "EVPN\n"
2564 "MAC addresses\n"
2565 "VxLAN Network Identifier\n"
cd233079 2566 "VNI number\n"
bd592158 2567 JSON_STR)
cec2e17d 2568{
d62a17ae 2569 struct zebra_vrf *zvrf;
2570 vni_t vni;
9f049418 2571 bool uj = use_json(argc, argv);
cec2e17d 2572
d62a17ae 2573 vni = strtoul(argv[4]->arg, NULL, 10);
530db8dc 2574 zvrf = zebra_vrf_get_evpn();
cd233079 2575 zebra_vxlan_print_macs_vni(vty, zvrf, vni, uj);
d62a17ae 2576 return CMD_SUCCESS;
cec2e17d 2577}
2578
2579DEFUN (show_evpn_mac_vni_all,
2580 show_evpn_mac_vni_all_cmd,
cd233079 2581 "show evpn mac vni all [json]",
cec2e17d 2582 SHOW_STR
2583 "EVPN\n"
2584 "MAC addresses\n"
2585 "VxLAN Network Identifier\n"
cd233079 2586 "All VNIs\n"
bd592158 2587 JSON_STR)
cec2e17d 2588{
d62a17ae 2589 struct zebra_vrf *zvrf;
9f049418 2590 bool uj = use_json(argc, argv);
cec2e17d 2591
530db8dc 2592 zvrf = zebra_vrf_get_evpn();
1374d4db 2593 zebra_vxlan_print_macs_all_vni(vty, zvrf, false, uj);
d62a17ae 2594 return CMD_SUCCESS;
cec2e17d 2595}
2596
cffe7580
NS
2597DEFUN (show_evpn_mac_vni_all_detail, show_evpn_mac_vni_all_detail_cmd,
2598 "show evpn mac vni all detail [json]",
2599 SHOW_STR
2600 "EVPN\n"
2601 "MAC addresses\n"
2602 "VxLAN Network Identifier\n"
2603 "All VNIs\n"
2604 "Detailed Information On Each VNI MAC\n"
2605 JSON_STR)
2606{
2607 struct zebra_vrf *zvrf;
2608 bool uj = use_json(argc, argv);
2609
530db8dc 2610 zvrf = zebra_vrf_get_evpn();
cffe7580
NS
2611 zebra_vxlan_print_macs_all_vni_detail(vty, zvrf, false, uj);
2612 return CMD_SUCCESS;
2613}
2614
cec2e17d 2615DEFUN (show_evpn_mac_vni_all_vtep,
2616 show_evpn_mac_vni_all_vtep_cmd,
cd233079 2617 "show evpn mac vni all vtep A.B.C.D [json]",
cec2e17d 2618 SHOW_STR
2619 "EVPN\n"
2620 "MAC addresses\n"
2621 "VxLAN Network Identifier\n"
2622 "All VNIs\n"
2623 "Remote VTEP\n"
cd233079 2624 "Remote VTEP IP address\n"
bd592158 2625 JSON_STR)
cec2e17d 2626{
d62a17ae 2627 struct zebra_vrf *zvrf;
2628 struct in_addr vtep_ip;
9f049418 2629 bool uj = use_json(argc, argv);
cec2e17d 2630
d62a17ae 2631 if (!inet_aton(argv[6]->arg, &vtep_ip)) {
cd233079
CS
2632 if (!uj)
2633 vty_out(vty, "%% Malformed VTEP IP address\n");
d62a17ae 2634 return CMD_WARNING;
2635 }
530db8dc 2636 zvrf = zebra_vrf_get_evpn();
cd233079 2637 zebra_vxlan_print_macs_all_vni_vtep(vty, zvrf, vtep_ip, uj);
cec2e17d 2638
d62a17ae 2639 return CMD_SUCCESS;
cec2e17d 2640}
2641
2642
2643DEFUN (show_evpn_mac_vni_mac,
2644 show_evpn_mac_vni_mac_cmd,
24cdbd0d 2645 "show evpn mac vni " CMD_VNI_RANGE " mac WORD [json]",
cec2e17d 2646 SHOW_STR
2647 "EVPN\n"
2648 "MAC addresses\n"
2649 "VxLAN Network Identifier\n"
2650 "VNI number\n"
2651 "MAC\n"
24cdbd0d
DS
2652 "MAC address (e.g., 00:e0:ec:20:12:62)\n"
2653 JSON_STR)
2654
cec2e17d 2655{
d62a17ae 2656 struct zebra_vrf *zvrf;
2657 vni_t vni;
2658 struct ethaddr mac;
24cdbd0d 2659 bool uj = use_json(argc, argv);
cec2e17d 2660
d62a17ae 2661 vni = strtoul(argv[4]->arg, NULL, 10);
2662 if (!prefix_str2mac(argv[6]->arg, &mac)) {
2663 vty_out(vty, "%% Malformed MAC address");
2664 return CMD_WARNING;
2665 }
530db8dc 2666 zvrf = zebra_vrf_get_evpn();
24cdbd0d 2667 zebra_vxlan_print_specific_mac_vni(vty, zvrf, vni, &mac, uj);
d62a17ae 2668 return CMD_SUCCESS;
cec2e17d 2669}
2670
2671DEFUN (show_evpn_mac_vni_vtep,
2672 show_evpn_mac_vni_vtep_cmd,
cd233079 2673 "show evpn mac vni " CMD_VNI_RANGE " vtep A.B.C.D" "[json]",
cec2e17d 2674 SHOW_STR
2675 "EVPN\n"
2676 "MAC addresses\n"
2677 "VxLAN Network Identifier\n"
2678 "VNI number\n"
2679 "Remote VTEP\n"
cd233079 2680 "Remote VTEP IP address\n"
bd592158 2681 JSON_STR)
cec2e17d 2682{
d62a17ae 2683 struct zebra_vrf *zvrf;
2684 vni_t vni;
2685 struct in_addr vtep_ip;
9f049418 2686 bool uj = use_json(argc, argv);
cec2e17d 2687
d62a17ae 2688 vni = strtoul(argv[4]->arg, NULL, 10);
2689 if (!inet_aton(argv[6]->arg, &vtep_ip)) {
cd233079
CS
2690 if (!uj)
2691 vty_out(vty, "%% Malformed VTEP IP address\n");
d62a17ae 2692 return CMD_WARNING;
2693 }
cec2e17d 2694
530db8dc 2695 zvrf = zebra_vrf_get_evpn();
cd233079 2696 zebra_vxlan_print_macs_vni_vtep(vty, zvrf, vni, vtep_ip, uj);
d62a17ae 2697 return CMD_SUCCESS;
cec2e17d 2698}
2699
1374d4db
CS
2700DEFPY (show_evpn_mac_vni_all_dad,
2701 show_evpn_mac_vni_all_dad_cmd,
2702 "show evpn mac vni all duplicate [json]",
2703 SHOW_STR
2704 "EVPN\n"
2705 "MAC addresses\n"
2706 "VxLAN Network Identifier\n"
2707 "All VNIs\n"
2708 "Duplicate address list\n"
2709 JSON_STR)
2710{
2711 struct zebra_vrf *zvrf;
2712 bool uj = use_json(argc, argv);
2713
530db8dc 2714 zvrf = zebra_vrf_get_evpn();
1374d4db
CS
2715 zebra_vxlan_print_macs_all_vni(vty, zvrf, true, uj);
2716 return CMD_SUCCESS;
2717}
2718
2719
2720DEFPY (show_evpn_mac_vni_dad,
2721 show_evpn_mac_vni_dad_cmd,
b41b3f7b 2722 "show evpn mac vni " CMD_VNI_RANGE " duplicate [json]",
1374d4db
CS
2723 SHOW_STR
2724 "EVPN\n"
2725 "MAC addresses\n"
2726 "VxLAN Network Identifier\n"
2727 "VNI number\n"
2728 "Duplicate address list\n"
2729 JSON_STR)
2730{
2731 struct zebra_vrf *zvrf;
1374d4db
CS
2732 bool uj = use_json(argc, argv);
2733
530db8dc 2734 zvrf = zebra_vrf_get_evpn();
1374d4db
CS
2735
2736 zebra_vxlan_print_macs_vni_dad(vty, zvrf, vni, uj);
2737
2738 return CMD_SUCCESS;
2739}
2740
2741DEFPY (show_evpn_neigh_vni_dad,
2742 show_evpn_neigh_vni_dad_cmd,
b41b3f7b 2743 "show evpn arp-cache vni " CMD_VNI_RANGE "duplicate [json]",
1374d4db
CS
2744 SHOW_STR
2745 "EVPN\n"
2746 "ARP and ND cache\n"
2747 "VxLAN Network Identifier\n"
2748 "VNI number\n"
2749 "Duplicate address list\n"
2750 JSON_STR)
2751{
2752 struct zebra_vrf *zvrf;
1374d4db
CS
2753 bool uj = use_json(argc, argv);
2754
530db8dc 2755 zvrf = zebra_vrf_get_evpn();
1374d4db
CS
2756 zebra_vxlan_print_neigh_vni_dad(vty, zvrf, vni, uj);
2757 return CMD_SUCCESS;
2758}
2759
2760DEFPY (show_evpn_neigh_vni_all_dad,
2761 show_evpn_neigh_vni_all_dad_cmd,
2762 "show evpn arp-cache vni all duplicate [json]",
2763 SHOW_STR
2764 "EVPN\n"
2765 "ARP and ND cache\n"
2766 "VxLAN Network Identifier\n"
2767 "All VNIs\n"
2768 "Duplicate address list\n"
2769 JSON_STR)
2770{
2771 struct zebra_vrf *zvrf;
2772 bool uj = use_json(argc, argv);
2773
530db8dc 2774 zvrf = zebra_vrf_get_evpn();
1374d4db
CS
2775 zebra_vxlan_print_neigh_all_vni(vty, zvrf, true, uj);
2776 return CMD_SUCCESS;
2777}
2778
2779
cec2e17d 2780DEFUN (show_evpn_neigh_vni,
2781 show_evpn_neigh_vni_cmd,
cd233079 2782 "show evpn arp-cache vni " CMD_VNI_RANGE "[json]",
cec2e17d 2783 SHOW_STR
2784 "EVPN\n"
2785 "ARP and ND cache\n"
2786 "VxLAN Network Identifier\n"
cd233079 2787 "VNI number\n"
bd592158 2788 JSON_STR)
cec2e17d 2789{
d62a17ae 2790 struct zebra_vrf *zvrf;
2791 vni_t vni;
9f049418 2792 bool uj = use_json(argc, argv);
cec2e17d 2793
d62a17ae 2794 vni = strtoul(argv[4]->arg, NULL, 10);
530db8dc 2795 zvrf = zebra_vrf_get_evpn();
cd233079 2796 zebra_vxlan_print_neigh_vni(vty, zvrf, vni, uj);
d62a17ae 2797 return CMD_SUCCESS;
cec2e17d 2798}
2799
2800DEFUN (show_evpn_neigh_vni_all,
2801 show_evpn_neigh_vni_all_cmd,
cd233079 2802 "show evpn arp-cache vni all [json]",
cec2e17d 2803 SHOW_STR
2804 "EVPN\n"
2805 "ARP and ND cache\n"
2806 "VxLAN Network Identifier\n"
cd233079 2807 "All VNIs\n"
bd592158 2808 JSON_STR)
cec2e17d 2809{
d62a17ae 2810 struct zebra_vrf *zvrf;
9f049418 2811 bool uj = use_json(argc, argv);
cec2e17d 2812
530db8dc 2813 zvrf = zebra_vrf_get_evpn();
1374d4db 2814 zebra_vxlan_print_neigh_all_vni(vty, zvrf, false, uj);
d62a17ae 2815 return CMD_SUCCESS;
cec2e17d 2816}
2817
e3fac919
NS
2818DEFUN (show_evpn_neigh_vni_all_detail, show_evpn_neigh_vni_all_detail_cmd,
2819 "show evpn arp-cache vni all detail [json]",
2820 SHOW_STR
2821 "EVPN\n"
2822 "ARP and ND cache\n"
2823 "VxLAN Network Identifier\n"
2824 "All VNIs\n"
2825 "Neighbor details for all vnis in detail\n" JSON_STR)
2826{
2827 struct zebra_vrf *zvrf;
2828 bool uj = use_json(argc, argv);
2829
530db8dc 2830 zvrf = zebra_vrf_get_evpn();
e3fac919
NS
2831 zebra_vxlan_print_neigh_all_vni_detail(vty, zvrf, false, uj);
2832 return CMD_SUCCESS;
2833}
2834
cec2e17d 2835DEFUN (show_evpn_neigh_vni_neigh,
2836 show_evpn_neigh_vni_neigh_cmd,
cd233079 2837 "show evpn arp-cache vni " CMD_VNI_RANGE " ip WORD [json]",
cec2e17d 2838 SHOW_STR
2839 "EVPN\n"
2840 "ARP and ND cache\n"
2841 "VxLAN Network Identifier\n"
2842 "VNI number\n"
2843 "Neighbor\n"
cd233079 2844 "Neighbor address (IPv4 or IPv6 address)\n"
bd592158 2845 JSON_STR)
cec2e17d 2846{
d62a17ae 2847 struct zebra_vrf *zvrf;
2848 vni_t vni;
2849 struct ipaddr ip;
9f049418 2850 bool uj = use_json(argc, argv);
cec2e17d 2851
d62a17ae 2852 vni = strtoul(argv[4]->arg, NULL, 10);
2853 if (str2ipaddr(argv[6]->arg, &ip) != 0) {
cd233079
CS
2854 if (!uj)
2855 vty_out(vty, "%% Malformed Neighbor address\n");
d62a17ae 2856 return CMD_WARNING;
2857 }
530db8dc 2858 zvrf = zebra_vrf_get_evpn();
cd233079 2859 zebra_vxlan_print_specific_neigh_vni(vty, zvrf, vni, &ip, uj);
d62a17ae 2860 return CMD_SUCCESS;
cec2e17d 2861}
2862
2863DEFUN (show_evpn_neigh_vni_vtep,
2864 show_evpn_neigh_vni_vtep_cmd,
cd233079 2865 "show evpn arp-cache vni " CMD_VNI_RANGE " vtep A.B.C.D [json]",
cec2e17d 2866 SHOW_STR
2867 "EVPN\n"
2868 "ARP and ND cache\n"
2869 "VxLAN Network Identifier\n"
2870 "VNI number\n"
2871 "Remote VTEP\n"
cd233079 2872 "Remote VTEP IP address\n"
bd592158 2873 JSON_STR)
cec2e17d 2874{
d62a17ae 2875 struct zebra_vrf *zvrf;
2876 vni_t vni;
2877 struct in_addr vtep_ip;
9f049418 2878 bool uj = use_json(argc, argv);
cec2e17d 2879
d62a17ae 2880 vni = strtoul(argv[4]->arg, NULL, 10);
2881 if (!inet_aton(argv[6]->arg, &vtep_ip)) {
cd233079
CS
2882 if (!uj)
2883 vty_out(vty, "%% Malformed VTEP IP address\n");
d62a17ae 2884 return CMD_WARNING;
2885 }
cec2e17d 2886
530db8dc 2887 zvrf = zebra_vrf_get_evpn();
cd233079 2888 zebra_vxlan_print_neigh_vni_vtep(vty, zvrf, vni, vtep_ip, uj);
d62a17ae 2889 return CMD_SUCCESS;
cec2e17d 2890}
2891
586f4ccf
PG
2892/* policy routing contexts */
2893DEFUN (show_pbr_ipset,
2894 show_pbr_ipset_cmd,
2895 "show pbr ipset [WORD]",
2896 SHOW_STR
2897 "Policy-Based Routing\n"
2898 "IPset Context information\n"
2899 "IPset Name information\n")
2900{
2901 int idx = 0;
2902 int found = 0;
2903 found = argv_find(argv, argc, "WORD", &idx);
2904 if (!found)
2905 zebra_pbr_show_ipset_list(vty, NULL);
2906 else
2907 zebra_pbr_show_ipset_list(vty, argv[idx]->arg);
2908 return CMD_SUCCESS;
2909}
2910
2911/* policy routing contexts */
2912DEFUN (show_pbr_iptable,
2913 show_pbr_iptable_cmd,
7929821a 2914 "show pbr iptable [WORD]",
586f4ccf
PG
2915 SHOW_STR
2916 "Policy-Based Routing\n"
7929821a
PG
2917 "IPtable Context information\n"
2918 "IPtable Name information\n")
586f4ccf 2919{
7929821a
PG
2920 int idx = 0;
2921 int found = 0;
2922
2923 found = argv_find(argv, argc, "WORD", &idx);
2924 if (!found)
2925 zebra_pbr_show_iptable(vty, NULL);
2926 else
2927 zebra_pbr_show_iptable(vty, argv[idx]->arg);
586f4ccf
PG
2928 return CMD_SUCCESS;
2929}
2930
09de9258
CS
2931DEFPY (clear_evpn_dup_addr,
2932 clear_evpn_dup_addr_cmd,
f65d330c 2933 "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
2934 CLEAR_STR
2935 "EVPN\n"
2936 "Duplicate address \n"
2937 "VxLAN Network Identifier\n"
2938 "VNI number\n"
2939 "All VNIs\n"
2940 "MAC\n"
2941 "MAC address (e.g., 00:e0:ec:20:12:62)\n"
2942 "IP\n"
2943 "IPv4 address\n"
2944 "IPv6 address\n")
2945{
2946 struct zebra_vrf *zvrf;
09de9258 2947 struct ipaddr host_ip = {.ipa_type = IPADDR_NONE };
1883de66 2948 int ret = CMD_SUCCESS;
09de9258 2949
530db8dc 2950 zvrf = zebra_vrf_get_evpn();
b41b3f7b 2951 if (vni_str) {
155b4398 2952 if (!is_zero_mac(&mac->eth_addr)) {
1883de66
CS
2953 ret = zebra_vxlan_clear_dup_detect_vni_mac(vty, zvrf,
2954 vni,
f65d330c 2955 &mac->eth_addr);
1883de66 2956 } else if (ip) {
09de9258
CS
2957 if (sockunion_family(ip) == AF_INET) {
2958 host_ip.ipa_type = IPADDR_V4;
2959 host_ip.ipaddr_v4.s_addr = sockunion2ip(ip);
2960 } else {
2961 host_ip.ipa_type = IPADDR_V6;
2962 memcpy(&host_ip.ipaddr_v6, &ip->sin6.sin6_addr,
2963 sizeof(struct in6_addr));
2964 }
1883de66
CS
2965 ret = zebra_vxlan_clear_dup_detect_vni_ip(vty, zvrf,
2966 vni,
2967 &host_ip);
09de9258 2968 } else
1883de66 2969 ret = zebra_vxlan_clear_dup_detect_vni(vty, zvrf, vni);
09de9258
CS
2970
2971 } else {
1883de66 2972 ret = zebra_vxlan_clear_dup_detect_vni_all(vty, zvrf);
09de9258
CS
2973 }
2974
1883de66 2975 return ret;
09de9258
CS
2976}
2977
718e3744 2978/* Static ip route configuration write function. */
d62a17ae 2979static int zebra_ip_config(struct vty *vty)
718e3744 2980{
d62a17ae 2981 int write = 0;
718e3744 2982
fe257ae7 2983 write += zebra_import_table_config(vty, VRF_DEFAULT);
37728041 2984
d62a17ae 2985 return write;
718e3744 2986}
2987
7a4bb9c5
DS
2988DEFUN (ip_zebra_import_table_distance,
2989 ip_zebra_import_table_distance_cmd,
12dcf78e 2990 "ip import-table (1-252) [distance (1-255)] [route-map WORD]",
8902474b
DS
2991 IP_STR
2992 "import routes from non-main kernel table\n"
2993 "kernel routing table id\n"
2994 "Distance for imported routes\n"
2995 "Default distance value\n"
2996 "route-map for filtering\n"
2997 "route-map name\n")
2998{
d7c0a89a 2999 uint32_t table_id = 0;
8902474b 3000
d62a17ae 3001 table_id = strtoul(argv[2]->arg, NULL, 10);
3002 int distance = ZEBRA_TABLE_DISTANCE_DEFAULT;
3003 char *rmap =
3004 strmatch(argv[argc - 2]->text, "route-map")
3005 ? XSTRDUP(MTYPE_ROUTE_MAP_NAME, argv[argc - 1]->arg)
3006 : NULL;
3007 int ret;
d722f26e 3008
d62a17ae 3009 if (argc == 7 || (argc == 5 && !rmap))
3010 distance = strtoul(argv[4]->arg, NULL, 10);
8902474b 3011
d62a17ae 3012 if (!is_zebra_valid_kernel_table(table_id)) {
3013 vty_out(vty,
3014 "Invalid routing table ID, %d. Must be in range 1-252\n",
3015 table_id);
0af35d90
RW
3016 if (rmap)
3017 XFREE(MTYPE_ROUTE_MAP_NAME, rmap);
d62a17ae 3018 return CMD_WARNING;
3019 }
8902474b 3020
d62a17ae 3021 if (is_zebra_main_routing_table(table_id)) {
3022 vty_out(vty,
3023 "Invalid routing table ID, %d. Must be non-default table\n",
3024 table_id);
0af35d90
RW
3025 if (rmap)
3026 XFREE(MTYPE_ROUTE_MAP_NAME, rmap);
d62a17ae 3027 return CMD_WARNING;
3028 }
8902474b 3029
fe257ae7
DS
3030 ret = zebra_import_table(AFI_IP, VRF_DEFAULT, table_id,
3031 distance, rmap, 1);
d62a17ae 3032 if (rmap)
3033 XFREE(MTYPE_ROUTE_MAP_NAME, rmap);
d722f26e 3034
d62a17ae 3035 return ret;
8902474b
DS
3036}
3037
62d52ded
DS
3038DEFUN_HIDDEN (zebra_packet_process,
3039 zebra_packet_process_cmd,
3040 "zebra zapi-packets (1-10000)",
3041 ZEBRA_STR
3042 "Zapi Protocol\n"
3043 "Number of packets to process before relinquishing thread\n")
3044{
3045 uint32_t packets = strtoul(argv[2]->arg, NULL, 10);
3046
5ec5a716 3047 atomic_store_explicit(&zrouter.packets_to_process, packets,
ccd51bd2 3048 memory_order_relaxed);
62d52ded
DS
3049
3050 return CMD_SUCCESS;
3051}
3052
3053DEFUN_HIDDEN (no_zebra_packet_process,
3054 no_zebra_packet_process_cmd,
3055 "no zebra zapi-packets [(1-10000)]",
3056 NO_STR
3057 ZEBRA_STR
3058 "Zapi Protocol\n"
3059 "Number of packets to process before relinquishing thread\n")
3060{
5ec5a716 3061 atomic_store_explicit(&zrouter.packets_to_process,
ccd51bd2
QY
3062 ZEBRA_ZAPI_PACKETS_TO_PROCESS,
3063 memory_order_relaxed);
62d52ded
DS
3064
3065 return CMD_SUCCESS;
3066}
3067
3a30f50f
DS
3068DEFUN_HIDDEN (zebra_workqueue_timer,
3069 zebra_workqueue_timer_cmd,
3070 "zebra work-queue (0-10000)",
3071 ZEBRA_STR
3072 "Work Queue\n"
3073 "Time in milliseconds\n")
3074{
996c9314 3075 uint32_t timer = strtoul(argv[2]->arg, NULL, 10);
489a9614 3076 zrouter.ribq->spec.hold = timer;
3a30f50f 3077
996c9314 3078 return CMD_SUCCESS;
3a30f50f
DS
3079}
3080
3081DEFUN_HIDDEN (no_zebra_workqueue_timer,
3082 no_zebra_workqueue_timer_cmd,
3083 "no zebra work-queue [(0-10000)]",
3084 NO_STR
3085 ZEBRA_STR
3086 "Work Queue\n"
3087 "Time in milliseconds\n")
3088{
489a9614 3089 zrouter.ribq->spec.hold = ZEBRA_RIB_PROCESS_HOLD_TIME;
3a30f50f 3090
996c9314 3091 return CMD_SUCCESS;
3a30f50f
DS
3092}
3093
7a4bb9c5
DS
3094DEFUN (no_ip_zebra_import_table,
3095 no_ip_zebra_import_table_cmd,
b62ecea5 3096 "no ip import-table (1-252) [distance (1-255)] [route-map NAME]",
7a4bb9c5
DS
3097 NO_STR
3098 IP_STR
3099 "import routes from non-main kernel table\n"
3a2d747c
QY
3100 "kernel routing table id\n"
3101 "Distance for imported routes\n"
3102 "Default distance value\n"
3103 "route-map for filtering\n"
3104 "route-map name\n")
7a4bb9c5 3105{
d7c0a89a 3106 uint32_t table_id = 0;
d62a17ae 3107 table_id = strtoul(argv[3]->arg, NULL, 10);
7a4bb9c5 3108
d62a17ae 3109 if (!is_zebra_valid_kernel_table(table_id)) {
3110 vty_out(vty,
3111 "Invalid routing table ID. Must be in range 1-252\n");
3112 return CMD_WARNING;
3113 }
7a4bb9c5 3114
d62a17ae 3115 if (is_zebra_main_routing_table(table_id)) {
3116 vty_out(vty,
3117 "Invalid routing table ID, %d. Must be non-default table\n",
3118 table_id);
3119 return CMD_WARNING;
3120 }
7a4bb9c5 3121
fe257ae7 3122 if (!is_zebra_import_table_enabled(AFI_IP, VRF_DEFAULT, table_id))
d62a17ae 3123 return CMD_SUCCESS;
7a4bb9c5 3124
fe257ae7 3125 return (zebra_import_table(AFI_IP, VRF_DEFAULT, table_id, 0, NULL, 0));
7a4bb9c5
DS
3126}
3127
d62a17ae 3128static int config_write_protocol(struct vty *vty)
6baf7bb8 3129{
d62a17ae 3130 if (allow_delete)
3131 vty_out(vty, "allow-external-route-update\n");
6baf7bb8 3132
489a9614
DS
3133 if (zrouter.ribq->spec.hold != ZEBRA_RIB_PROCESS_HOLD_TIME)
3134 vty_out(vty, "zebra work-queue %u\n", zrouter.ribq->spec.hold);
3a30f50f 3135
5ec5a716 3136 if (zrouter.packets_to_process != ZEBRA_ZAPI_PACKETS_TO_PROCESS)
996c9314 3137 vty_out(vty, "zebra zapi-packets %u\n",
5ec5a716 3138 zrouter.packets_to_process);
62d52ded 3139
d62a17ae 3140 enum multicast_mode ipv4_multicast_mode = multicast_mode_ipv4_get();
4623d897 3141
d62a17ae 3142 if (ipv4_multicast_mode != MCAST_NO_CONFIG)
3143 vty_out(vty, "ip multicast rpf-lookup-mode %s\n",
3144 ipv4_multicast_mode == MCAST_URIB_ONLY
3145 ? "urib-only"
3146 : ipv4_multicast_mode == MCAST_MRIB_ONLY
3147 ? "mrib-only"
3148 : ipv4_multicast_mode
3149 == MCAST_MIX_MRIB_FIRST
3150 ? "mrib-then-urib"
3151 : ipv4_multicast_mode
3152 == MCAST_MIX_DISTANCE
3153 ? "lower-distance"
3154 : "longer-prefix");
f26730e1
MS
3155
3156 /* Include dataplane info */
3157 dplane_config_write_helper(vty);
3158
7c99d51b
MS
3159 /* Include nexthop-group config */
3160 if (!zebra_nhg_kernel_nexthops_enabled())
3161 vty_out(vty, "no zebra nexthop kernel enable\n");
3162
d62a17ae 3163 return 1;
6baf7bb8
DS
3164}
3165
c0d136ae
DS
3166DEFUN (show_zebra,
3167 show_zebra_cmd,
3168 "show zebra",
3169 SHOW_STR
3170 ZEBRA_STR)
3171{
3172 struct vrf *vrf;
3173
3174 vty_out(vty,
3175 " Route Route Neighbor LSP LSP\n");
3176 vty_out(vty,
3177 "VRF Installs Removals Updates Installs Removals\n");
3178
996c9314 3179 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
c0d136ae
DS
3180 struct zebra_vrf *zvrf = vrf->info;
3181
3182 vty_out(vty, "%-25s %10" PRIu64 " %10" PRIu64 " %10" PRIu64
3183 " %10" PRIu64 " %10" PRIu64 "\n",
3184 vrf->name, zvrf->installs, zvrf->removals,
3185 zvrf->neigh_updates, zvrf->lsp_installs,
3186 zvrf->lsp_removals);
3187 }
3188
3189 return CMD_SUCCESS;
3190}
3191
3192DEFUN (ip_forwarding,
3193 ip_forwarding_cmd,
3194 "ip forwarding",
3195 IP_STR
3196 "Turn on IP forwarding\n")
3197{
3198 int ret;
3199
3200 ret = ipforward();
3201 if (ret == 0)
3202 ret = ipforward_on();
3203
3204 if (ret == 0) {
3205 vty_out(vty, "Can't turn on IP forwarding\n");
3206 return CMD_WARNING_CONFIG_FAILED;
3207 }
3208
3209 return CMD_SUCCESS;
3210}
3211
3212DEFUN (no_ip_forwarding,
3213 no_ip_forwarding_cmd,
3214 "no ip forwarding",
3215 NO_STR
3216 IP_STR
3217 "Turn off IP forwarding\n")
3218{
3219 int ret;
3220
3221 ret = ipforward();
3222 if (ret != 0)
3223 ret = ipforward_off();
3224
3225 if (ret != 0) {
3226 vty_out(vty, "Can't turn off IP forwarding\n");
3227 return CMD_WARNING_CONFIG_FAILED;
3228 }
3229
3230 return CMD_SUCCESS;
3231}
3232
3233/* Only display ip forwarding is enabled or not. */
3234DEFUN (show_ip_forwarding,
3235 show_ip_forwarding_cmd,
3236 "show ip forwarding",
3237 SHOW_STR
3238 IP_STR
3239 "IP forwarding status\n")
3240{
3241 int ret;
3242
3243 ret = ipforward();
3244
3245 if (ret == 0)
3246 vty_out(vty, "IP forwarding is off\n");
3247 else
3248 vty_out(vty, "IP forwarding is on\n");
3249 return CMD_SUCCESS;
3250}
3251
3252/* Only display ipv6 forwarding is enabled or not. */
3253DEFUN (show_ipv6_forwarding,
3254 show_ipv6_forwarding_cmd,
3255 "show ipv6 forwarding",
3256 SHOW_STR
3257 "IPv6 information\n"
3258 "Forwarding status\n")
3259{
3260 int ret;
3261
3262 ret = ipforward_ipv6();
3263
3264 switch (ret) {
3265 case -1:
3266 vty_out(vty, "ipv6 forwarding is unknown\n");
3267 break;
3268 case 0:
3269 vty_out(vty, "ipv6 forwarding is %s\n", "off");
3270 break;
3271 case 1:
3272 vty_out(vty, "ipv6 forwarding is %s\n", "on");
3273 break;
3274 default:
3275 vty_out(vty, "ipv6 forwarding is %s\n", "off");
3276 break;
3277 }
3278 return CMD_SUCCESS;
3279}
3280
3281DEFUN (ipv6_forwarding,
3282 ipv6_forwarding_cmd,
3283 "ipv6 forwarding",
3284 IPV6_STR
3285 "Turn on IPv6 forwarding\n")
3286{
3287 int ret;
3288
3289 ret = ipforward_ipv6();
3290 if (ret == 0)
3291 ret = ipforward_ipv6_on();
3292
3293 if (ret == 0) {
3294 vty_out(vty, "Can't turn on IPv6 forwarding\n");
3295 return CMD_WARNING_CONFIG_FAILED;
3296 }
3297
3298 return CMD_SUCCESS;
3299}
3300
3301DEFUN (no_ipv6_forwarding,
3302 no_ipv6_forwarding_cmd,
3303 "no ipv6 forwarding",
3304 NO_STR
3305 IPV6_STR
3306 "Turn off IPv6 forwarding\n")
3307{
3308 int ret;
3309
3310 ret = ipforward_ipv6();
3311 if (ret != 0)
3312 ret = ipforward_ipv6_off();
3313
3314 if (ret != 0) {
3315 vty_out(vty, "Can't turn off IPv6 forwarding\n");
3316 return CMD_WARNING_CONFIG_FAILED;
3317 }
3318
3319 return CMD_SUCCESS;
3320}
3321
1d11b21f
MS
3322/* Display dataplane info */
3323DEFUN (show_dataplane,
3324 show_dataplane_cmd,
3325 "show zebra dplane [detailed]",
3326 SHOW_STR
3327 ZEBRA_STR
3328 "Zebra dataplane information\n"
3329 "Detailed output\n")
3330{
3331 int idx = 0;
3332 bool detailed = false;
3333
3334 if (argv_find(argv, argc, "detailed", &idx))
3335 detailed = true;
3336
3337 return dplane_show_helper(vty, detailed);
3338}
3339
3340/* Display dataplane providers info */
3341DEFUN (show_dataplane_providers,
3342 show_dataplane_providers_cmd,
3343 "show zebra dplane providers [detailed]",
3344 SHOW_STR
3345 ZEBRA_STR
3346 "Zebra dataplane information\n"
3347 "Zebra dataplane provider information\n"
3348 "Detailed output\n")
3349{
3350 int idx = 0;
3351 bool detailed = false;
3352
3353 if (argv_find(argv, argc, "detailed", &idx))
3354 detailed = true;
3355
3356 return dplane_show_provs_helper(vty, detailed);
3357}
3358
91f16812
MS
3359/* Configure dataplane incoming queue limit */
3360DEFUN (zebra_dplane_queue_limit,
3361 zebra_dplane_queue_limit_cmd,
3362 "zebra dplane limit (0-10000)",
3363 ZEBRA_STR
3364 "Zebra dataplane\n"
3365 "Limit incoming queued updates\n"
3366 "Number of queued updates\n")
3367{
3368 uint32_t limit = 0;
3369
3370 limit = strtoul(argv[3]->arg, NULL, 10);
3371
3372 dplane_set_in_queue_limit(limit, true);
3373
3374 return CMD_SUCCESS;
3375}
3376
3377/* Reset dataplane queue limit to default value */
3378DEFUN (no_zebra_dplane_queue_limit,
3379 no_zebra_dplane_queue_limit_cmd,
3380 "no zebra dplane limit [(0-10000)]",
3381 NO_STR
3382 ZEBRA_STR
3383 "Zebra dataplane\n"
3384 "Limit incoming queued updates\n"
3385 "Number of queued updates\n")
3386{
3387 dplane_set_in_queue_limit(0, false);
3388
3389 return CMD_SUCCESS;
3390}
1d11b21f 3391
ac5aa23f
DS
3392DEFUN (zebra_show_routing_tables_summary,
3393 zebra_show_routing_tables_summary_cmd,
3394 "show zebra router table summary",
3395 SHOW_STR
3396 ZEBRA_STR
3397 "The Zebra Router Information\n"
3398 "Table Information about this Zebra Router\n"
3399 "Summary Information\n")
3400{
3401 zebra_router_show_table_summary(vty);
3402
3403 return CMD_SUCCESS;
3404}
3405
c0d136ae
DS
3406/* Table configuration write function. */
3407static int config_write_table(struct vty *vty)
3408{
c0d136ae
DS
3409 return 0;
3410}
3411
3412/* IPForwarding configuration write function. */
3413static int config_write_forwarding(struct vty *vty)
3414{
3415 /* FIXME: Find better place for that. */
3416 router_id_write(vty);
3417
3418 if (!ipforward())
3419 vty_out(vty, "no ip forwarding\n");
3420 if (!ipforward_ipv6())
3421 vty_out(vty, "no ipv6 forwarding\n");
3422 vty_out(vty, "!\n");
3423 return 0;
3424}
3425
d2f5903b
DS
3426DEFUN_HIDDEN (show_frr,
3427 show_frr_cmd,
3428 "show frr",
3429 SHOW_STR
3430 "FRR\n")
3431{
3432 vty_out(vty, "........ .. . .. . ..... ...77:................................................\n");
3433 vty_out(vty, ".............................7777:..............................................\n");
3434 vty_out(vty, ".............................777777,............................................\n");
3435 vty_out(vty, "... .........................77777777,..........................................\n");
3436 vty_out(vty, "............................=7777777777:........................................\n");
3437 vty_out(vty, "........................:7777777777777777,......................................\n");
3438 vty_out(vty, ".................... ~7777777777777?~,..........................................\n");
3439 vty_out(vty, "...................I7777777777+.................................................\n");
3440 vty_out(vty, "................,777777777?............ .......................................\n");
3441 vty_out(vty, "..............:77777777?..........~?77777.......................................\n");
3442 vty_out(vty, ".............77777777~........=7777777777.......................................\n");
3443 vty_out(vty, ".......... +7777777,.......?7777777777777.......................................\n");
3444 vty_out(vty, "..........7777777~......:7777777777777777......77?,.............................\n");
3445 vty_out(vty, "........:777777?......+777777777777777777......777777I,.........................\n");
3446 vty_out(vty, ".......?777777,.....+77777777777777777777......777777777?.......................\n");
3447 vty_out(vty, "......?777777......7777777777777777777777......,?777777777?.....................\n");
3448 vty_out(vty, ".....?77777?.....=7777777777777777777I~............,I7777777~...................\n");
3449 vty_out(vty, "....+77777+.....I77777777777777777:...................+777777I..................\n");
3450 vty_out(vty, "...~77777+.....7777777777777777=........................?777777...... .......\n");
3451 vty_out(vty, "...77777I.....I77777777777777~.........:?................,777777.....I777.......\n");
3452 vty_out(vty, "..777777.....I7777777777777I .......?7777..................777777.....777?......\n");
3453 vty_out(vty, ".~77777,....=7777777777777:......,7777777..................,77777+....+777......\n");
3454 vty_out(vty, ".77777I.....7777777777777,......777777777.......ONNNN.......=77777.....777~.....\n");
3455 vty_out(vty, ",77777.....I777777777777,.....:7777777777......DNNNNNN.......77777+ ...7777.....\n");
3456 vty_out(vty, "I7777I.....777777777777=.....~77777777777......NNNNNNN~......=7777I....=777.....\n");
3457 vty_out(vty, "77777:....=777777777777.....,777777777777......$NNNNND ......:77777....:777.....\n");
3458 vty_out(vty, "77777. ...777777777777~.....7777777777777........7DZ,........:77777.....777.....\n");
3459 vty_out(vty, "????? . ..777777777777.....,7777777777777....................:77777I....777.....\n");
3460 vty_out(vty, "....... ..777777777777.....+7777777777777....................=7777777+...?7.....\n");
3461 vty_out(vty, "..........77777777777I.....I7777777777777....................7777777777:........\n");
3462 vty_out(vty, "..........77777777777I.....?7777777777777...................~777777777777.......\n");
3463 vty_out(vty, "..........777777777777.....~7777777777777..................,77777777777777+.....\n");
3464 vty_out(vty, "..........777777777777......7777777777777..................77777777777777777,...\n");
3465 vty_out(vty, "..... ....?77777777777I.....~777777777777................,777777.....,:+77777I..\n");
3466 vty_out(vty, "........ .:777777777777,.....?77777777777...............?777777..............,:=\n");
3467 vty_out(vty, ".......... 7777777777777..... ?7777777777.............=7777777.....~777I........\n");
3468 vty_out(vty, "...........:777777777777I......~777777777...........I7777777~.....+777I.........\n");
3469 vty_out(vty, "..... ......7777777777777I.......I7777777.......+777777777I......7777I..........\n");
3470 vty_out(vty, ".............77777777777777........?77777......777777777?......=7777=...........\n");
3471 vty_out(vty, ".............,77777777777777+.........~77......777777I,......:77777.............\n");
3472 vty_out(vty, "..............~777777777777777~................777777......:77777=..............\n");
3473 vty_out(vty, "...............:7777777777777777?..............:777777,.....=77=................\n");
3474 vty_out(vty, "................,777777777777777777?,...........,777777:.....,..................\n");
3475 vty_out(vty, "........... ......I777777777777777777777I.........777777~.......................\n");
3476 vty_out(vty, "...................,777777777777777777777..........777777+......................\n");
3477 vty_out(vty, ".....................+7777777777777777777...........777777?.....................\n");
3478 vty_out(vty, ".......................=77777777777777777............777777I....................\n");
3479 vty_out(vty, ".........................:777777777777777.............I77777I...................\n");
3480 vty_out(vty, "............................~777777777777..............+777777..................\n");
3481 vty_out(vty, "................................~77777777...............=777777.................\n");
3482 vty_out(vty, ".....................................:=?I................~777777................\n");
3483 vty_out(vty, "..........................................................:777777,..............\n");
3484 vty_out(vty, ".... ... ... . . .... ....... ....... ....................:777777..............\n");
3485
3486 return CMD_SUCCESS;
3487}
3488
718e3744 3489/* IP node for static routes. */
d62a17ae 3490static struct cmd_node ip_node = {IP_NODE, "", 1};
3491static struct cmd_node protocol_node = {PROTOCOL_NODE, "", 1};
c0d136ae
DS
3492/* table node for routing tables. */
3493static struct cmd_node table_node = {TABLE_NODE,
3494 "", /* This node has no interface. */
3495 1};
3496static struct cmd_node forwarding_node = {FORWARDING_NODE,
3497 "", /* This node has no interface. */
3498 1};
718e3744 3499
3500/* Route VTY. */
d62a17ae 3501void zebra_vty_init(void)
3502{
c0d136ae
DS
3503 /* Install configuration write function. */
3504 install_node(&table_node, config_write_table);
3505 install_node(&forwarding_node, config_write_forwarding);
3506
3507 install_element(VIEW_NODE, &show_ip_forwarding_cmd);
3508 install_element(CONFIG_NODE, &ip_forwarding_cmd);
3509 install_element(CONFIG_NODE, &no_ip_forwarding_cmd);
3510 install_element(ENABLE_NODE, &show_zebra_cmd);
3511
c0d136ae
DS
3512 install_element(VIEW_NODE, &show_ipv6_forwarding_cmd);
3513 install_element(CONFIG_NODE, &ipv6_forwarding_cmd);
3514 install_element(CONFIG_NODE, &no_ipv6_forwarding_cmd);
3515
3516 /* Route-map */
3517 zebra_route_map_init();
3518
d62a17ae 3519 install_node(&ip_node, zebra_ip_config);
3520 install_node(&protocol_node, config_write_protocol);
3521
3522 install_element(CONFIG_NODE, &allow_external_route_update_cmd);
3523 install_element(CONFIG_NODE, &no_allow_external_route_update_cmd);
7e24fdf3 3524
d62a17ae 3525 install_element(CONFIG_NODE, &ip_multicast_mode_cmd);
3526 install_element(CONFIG_NODE, &no_ip_multicast_mode_cmd);
b3b08602 3527
d62a17ae 3528 install_element(CONFIG_NODE, &ip_zebra_import_table_distance_cmd);
3529 install_element(CONFIG_NODE, &no_ip_zebra_import_table_cmd);
3a30f50f
DS
3530 install_element(CONFIG_NODE, &zebra_workqueue_timer_cmd);
3531 install_element(CONFIG_NODE, &no_zebra_workqueue_timer_cmd);
62d52ded
DS
3532 install_element(CONFIG_NODE, &zebra_packet_process_cmd);
3533 install_element(CONFIG_NODE, &no_zebra_packet_process_cmd);
7c99d51b 3534 install_element(CONFIG_NODE, &nexthop_group_use_enable_cmd);
d62a17ae 3535
21be1364 3536 install_element(VIEW_NODE, &show_nexthop_group_cmd);
1e9aad82 3537 install_element(VIEW_NODE, &show_interface_nexthop_group_cmd);
21be1364 3538
d62a17ae 3539 install_element(VIEW_NODE, &show_vrf_cmd);
b7cfce93 3540 install_element(VIEW_NODE, &show_vrf_vni_cmd);
ecffa493 3541 install_element(VIEW_NODE, &show_route_cmd);
ae825b8b 3542 install_element(VIEW_NODE, &show_route_table_cmd);
87d6ac7a
PG
3543 if (vrf_is_backend_netns())
3544 install_element(VIEW_NODE, &show_route_table_vrf_cmd);
16c42fba 3545 install_element(VIEW_NODE, &show_route_all_table_vrf_cmd);
5ce91022
RW
3546 install_element(VIEW_NODE, &show_route_detail_cmd);
3547 install_element(VIEW_NODE, &show_route_summary_cmd);
d62a17ae 3548 install_element(VIEW_NODE, &show_ip_nht_cmd);
d62a17ae 3549
3550 install_element(VIEW_NODE, &show_ip_rpf_cmd);
3551 install_element(VIEW_NODE, &show_ip_rpf_addr_cmd);
3552
d62a17ae 3553 install_element(CONFIG_NODE, &ip_nht_default_route_cmd);
3554 install_element(CONFIG_NODE, &no_ip_nht_default_route_cmd);
3555 install_element(CONFIG_NODE, &ipv6_nht_default_route_cmd);
3556 install_element(CONFIG_NODE, &no_ipv6_nht_default_route_cmd);
214e5c26 3557 install_element(VRF_NODE, &ip_nht_default_route_cmd);
3558 install_element(VRF_NODE, &no_ip_nht_default_route_cmd);
3559 install_element(VRF_NODE, &ipv6_nht_default_route_cmd);
3560 install_element(VRF_NODE, &no_ipv6_nht_default_route_cmd);
d62a17ae 3561 install_element(VIEW_NODE, &show_ipv6_mroute_cmd);
3562
3563 /* Commands for VRF */
d62a17ae 3564 install_element(VIEW_NODE, &show_ipv6_mroute_vrf_all_cmd);
3565
d2f5903b 3566 install_element(VIEW_NODE, &show_frr_cmd);
4cce389e 3567 install_element(VIEW_NODE, &show_evpn_global_cmd);
d62a17ae 3568 install_element(VIEW_NODE, &show_evpn_vni_cmd);
09af6961 3569 install_element(VIEW_NODE, &show_evpn_vni_detail_cmd);
d62a17ae 3570 install_element(VIEW_NODE, &show_evpn_vni_vni_cmd);
4cce389e
MK
3571 install_element(VIEW_NODE, &show_evpn_rmac_vni_mac_cmd);
3572 install_element(VIEW_NODE, &show_evpn_rmac_vni_cmd);
3573 install_element(VIEW_NODE, &show_evpn_rmac_vni_all_cmd);
3574 install_element(VIEW_NODE, &show_evpn_nh_vni_ip_cmd);
3575 install_element(VIEW_NODE, &show_evpn_nh_vni_cmd);
3576 install_element(VIEW_NODE, &show_evpn_nh_vni_all_cmd);
d62a17ae 3577 install_element(VIEW_NODE, &show_evpn_mac_vni_cmd);
3578 install_element(VIEW_NODE, &show_evpn_mac_vni_all_cmd);
cffe7580 3579 install_element(VIEW_NODE, &show_evpn_mac_vni_all_detail_cmd);
d62a17ae 3580 install_element(VIEW_NODE, &show_evpn_mac_vni_all_vtep_cmd);
3581 install_element(VIEW_NODE, &show_evpn_mac_vni_mac_cmd);
3582 install_element(VIEW_NODE, &show_evpn_mac_vni_vtep_cmd);
1374d4db
CS
3583 install_element(VIEW_NODE, &show_evpn_mac_vni_dad_cmd);
3584 install_element(VIEW_NODE, &show_evpn_mac_vni_all_dad_cmd);
d62a17ae 3585 install_element(VIEW_NODE, &show_evpn_neigh_vni_cmd);
3586 install_element(VIEW_NODE, &show_evpn_neigh_vni_all_cmd);
e3fac919 3587 install_element(VIEW_NODE, &show_evpn_neigh_vni_all_detail_cmd);
d62a17ae 3588 install_element(VIEW_NODE, &show_evpn_neigh_vni_neigh_cmd);
3589 install_element(VIEW_NODE, &show_evpn_neigh_vni_vtep_cmd);
1374d4db
CS
3590 install_element(VIEW_NODE, &show_evpn_neigh_vni_dad_cmd);
3591 install_element(VIEW_NODE, &show_evpn_neigh_vni_all_dad_cmd);
09de9258 3592 install_element(ENABLE_NODE, &clear_evpn_dup_addr_cmd);
b7cfce93 3593
586f4ccf
PG
3594 install_element(VIEW_NODE, &show_pbr_ipset_cmd);
3595 install_element(VIEW_NODE, &show_pbr_iptable_cmd);
3596
e8d26197
MK
3597 install_element(CONFIG_NODE, &default_vrf_vni_mapping_cmd);
3598 install_element(CONFIG_NODE, &no_default_vrf_vni_mapping_cmd);
b7cfce93
MK
3599 install_element(VRF_NODE, &vrf_vni_mapping_cmd);
3600 install_element(VRF_NODE, &no_vrf_vni_mapping_cmd);
4060008b 3601
1d11b21f
MS
3602 install_element(VIEW_NODE, &show_dataplane_cmd);
3603 install_element(VIEW_NODE, &show_dataplane_providers_cmd);
91f16812
MS
3604 install_element(CONFIG_NODE, &zebra_dplane_queue_limit_cmd);
3605 install_element(CONFIG_NODE, &no_zebra_dplane_queue_limit_cmd);
ac5aa23f
DS
3606
3607 install_element(VIEW_NODE, &zebra_show_routing_tables_summary_cmd);
718e3744 3608}