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